From 843d7607ef8d984ed53fcf8432792b3f852b7594 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:00 -0500 Subject: [PATCH 001/459] txscript: Add benchmark for CalcSignatureHash --- txscript/bench_test.go | 52 ++++++++++++++++++++++++++++++++ txscript/data/many_inputs_tx.hex | 1 + 2 files changed, 53 insertions(+) create mode 100644 txscript/bench_test.go create mode 100644 txscript/data/many_inputs_tx.hex diff --git a/txscript/bench_test.go b/txscript/bench_test.go new file mode 100644 index 00000000..b129b803 --- /dev/null +++ b/txscript/bench_test.go @@ -0,0 +1,52 @@ +// Copyright (c) 2018-2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package txscript + +import ( + "bytes" + "fmt" + "io/ioutil" + "testing" + + "github.com/btcsuite/btcd/wire" +) + +var ( + // manyInputsBenchTx is a transaction that contains a lot of inputs which is + // useful for benchmarking signature hash calculation. + manyInputsBenchTx wire.MsgTx + + // A mock previous output script to use in the signing benchmark. + prevOutScript = hexToBytes("a914f5916158e3e2c4551c1796708db8367207ed13bb87") +) + +func init() { + // tx 620f57c92cf05a7f7e7f7d28255d5f7089437bc48e34dcfebf7751d08b7fb8f5 + txHex, err := ioutil.ReadFile("data/many_inputs_tx.hex") + if err != nil { + panic(fmt.Sprintf("unable to read benchmark tx file: %v", err)) + } + + txBytes := hexToBytes(string(txHex)) + err = manyInputsBenchTx.Deserialize(bytes.NewReader(txBytes)) + if err != nil { + panic(err) + } +} + +// BenchmarkCalcSigHash benchmarks how long it takes to calculate the signature +// hashes for all inputs of a transaction with many inputs. +func BenchmarkCalcSigHash(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + for j := 0; j < len(manyInputsBenchTx.TxIn); j++ { + _, err := CalcSignatureHash(prevOutScript, SigHashAll, + &manyInputsBenchTx, j) + if err != nil { + b.Fatalf("failed to calc signature hash: %v", err) + } + } + } +} diff --git a/txscript/data/many_inputs_tx.hex b/txscript/data/many_inputs_tx.hex new file mode 100644 index 00000000..2f9833de --- /dev/null +++ b/txscript/data/many_inputs_tx.hex @@ -0,0 +1 @@ +010000005901fa054079e69a46e5aacd8b57f94c3c99744d68c6097957eaa9021c344141a90000000000ffffffff020706fa6444e4c9d110274488a4641161165370cd11a208ad3a3a00178e1d9c0000000000ffffffff0210805cd4cceae0873daaf8b81d2eb7122cdcdf2dfae5a90569378f847e293c0000000000ffffffff021d93a6970f13f10f6b8b1b5763f772f1f37350f893cb305005319a76069f5a0000000000ffffffff021fa71c8d5f8c455820e6d83c6fca218ed2e70391c7dfba4119168c7ebc68c30000000000ffffffff0227b4b9041f1c8ac86ea16f48909c94adac7081b26a36ed5863e4c53175262b0000000000ffffffff0228a49d6e91275b9d0d8aa5f6e81d4e1e9cd957ecfdabd6df68fe6f4970a0b60000000000ffffffff022db9dd2128b6d1f1eba30a681f062f6eaad362e58b23e6cadcd2cb8d65d6880000000000ffffffff0243411baa5b4b3357849e505310dbd29a8a50e6324c4655e403043ac07ce9d10000000000ffffffff024b630ce631441c527d555c237bb68b694d50010b7723957ef4537185eef6c40000000000ffffffff025312b6a2f95a25a109b4f0b46fb35abd74b15a39241291dd3673f1dd58fd3b0000000000ffffffff02554f0d7fe6df9454c8152c6f46429596abc08b57d7cfbc7f5f22db8a0787e00000000000ffffffff025793409101621f48c0f9ebdef0867088c015c5e412ccbdd1d32a5de62ae1b80000000000ffffffff025b53aa8359a7a3fd92d69ef96be30dfed1ea99fa03db0050f3f6d3b9e2b7320000000000ffffffff025cfc35711a57b373b807bbfaadf0950b81a74d0215a0508f2e62989bdbb4aa0000000000ffffffff025ddd8921db66b54f1ad8ef2eae70913d22e5579e2781a1e485fc6a555f6e410000000000ffffffff026466da9b3ebf93b07e7de704789d5ae04f584fa39043716a9830edf5bf99140000000000ffffffff027904d29d4cb521d7c884325b1d42434bc99b6d712681e5e254597821a944550000000000ffffffff027c662f67150bca47a7b23f0fb7c50956b21a4f46b9f4c4a304d51ce9c5900f0000000000ffffffff027ef5afdeab2ec6515a739dc00c2ef8994303c19a74fd0512f8306fb601d10f0000000000ffffffff0284cdef7bdd0c45efdecb2a3a68079d7e01ccc8e229a3e72160ec93218b1ad90000000000ffffffff028885c672656acd03755167361be6ccd94ad72c5e3890773f11a5c627f046890000000000ffffffff028b372c55109471551db0aa772aa66321862fb3a11e4cd7a31cdc4ed989436d0000000000ffffffff0290198f3a73a8febae55d559676303ae495acbad11dde304c21483a951078270000000000ffffffff0298dc5698fb1823ee1ec7469936e0b9b71e69e843d993b2c0096ac3c1d86bb20000000000ffffffff029c5d6da641328e356368383951c5dad56398f29f58a922eb54afaf888e41430000000000ffffffff02d702320af97f4f498aedf0886cd6123692f6d7b6f0b1da3910703648bc80c40000000000ffffffff02d90670fc2d34b7fcfce03ecb3a3650a4cd384eca645c2b05263721e9a5c19f0000000000ffffffff02de1f9e03b532c0bd6a28a7066c81b7abf0f9dc7e40003f638b9a872fa9a74c0000000000ffffffff02ded955aaf74a935a479fb08d4e8ded2a99664cb2235bc617627616e0e313630000000000ffffffff02e3f8ded8a0d2716817259e4144faa83facd27a5c9550c7c65835cc2c93738a0000000000ffffffff03012cf75972966f2c7abb609b43c7e85dd65cada0ee20118c80d92d766a32400000000000ffffffff0307efdd04c2f3e033a0294aaa894b4245695876fc76c12b8523d448ef05e6620000000000ffffffff030db2a3d8afa67b68f0ae663cc88bee0af0a8900e88f099d2ee648603e7b0e30000000000ffffffff03133fb852424925f55c8a660fdec8a10dce9bb9b500bf07bc73e2641f1a55310000000000ffffffff0313954647c73d9c63e4e83d36e337b17797be10eb0d641deaff0c768aa6db060000000000ffffffff031bfd6a0bfc310e204fc0eb5e1c83b9d21dab82847b909db111a371ffdcb5a20000000000ffffffff032588268e35fbd648c621638633ef8188e8b946ebd3d5833a18d9bae556ee5c0000000000ffffffff03378677fc365f67102c2559a2a4300344d41a63920e7450951fc6d8d63fb0110000000000ffffffff033c9955351d351b4f5ac398adce94b2a7ed3ab14a1c790c8e4742b1558c6b200000000000ffffffff034061cfcca9fb77d28d2411f4502c3696e0aa28b040f6780a4bd00c3fa8a02b0000000000ffffffff034b063b587eb75409e56b5ff2f9cc24a994e3ecbf9de56bd46983443067e81b0000000000ffffffff034cb2f8a145b3a55bb07dcdb904859808b29a5f53a01ba3a3cd707211afb7190000000000ffffffff034f96fa5e134b5310731b23fa9235aad58008c7c61f1b8128542b51622a52250000000000ffffffff0357236d19aef1428f117c3067a89adbecfe234ef32d744acdd6b6a5107a95e90000000000ffffffff0362504fcc65272e50ba6cc4583b4b1486592b59d943ab375ea7d6f44ba8038c0000000000ffffffff0369b02dad4259759408f8a3b1fad3c24df0873b767a9d0f1d50bd68f18c789d0000000000ffffffff036e080ba3f983e5bd7d8700dfd4b510a502231d0112c38e804b59d8a84026230000000000ffffffff038298149c290f73c535c3a184d181316ef695146a58d3bb3d2e61ed993cc11c0000000000ffffffff038538c9d6b8200609e4ca2443910daa6d9bbe772b2793e11fcf1763202c998b0000000000ffffffff038aad027dade93191c546648f7125bda82c895f1d80bf174d9637e533e12a1a0000000000ffffffff03960708a37a5654abd75755d1b8f49a84cdbde4676e14fd4863b125a94e9fc40000000000ffffffff03b0e09c55ecabf221c30a086c812e35bc9b586547cde8a83961a7ffa9067cb20000000000ffffffff03b28e682c13e7ada60cb905f8070109ec5a7800a0424c5f7afb6bd3039d48cd0000000000ffffffff03b7e8adc6174ca369ec31b4f944a6b74231d09254fde6b2bfe3416f3c6096ad0000000000ffffffff03c4f1eef6176ce6a2114dce78dd292f6db20fdae7c534d22cbada58befad6cf0000000000ffffffff03c7b5bf7fef69ae11c467f68fb551d58424e8723d05ce3ccf88385187898a710000000000ffffffff03d5150f5295b1e817f44fa34cade950c13789c4129e98eb32634aaad2abe13e0000000000ffffffff03d8250c9557188c7672009c4b14f37f96528e3f9c6889607b2e25299efe08720000000000ffffffff03de1dc49d0146dcc0cdbeb84c68a14ecb7075aba67d6494a5c8d098147843640000000000ffffffff03df8c8392bc17eddab688530697c2c221420464eb643ca8edfd30d7371ed5460000000000ffffffff03ea1dbbe72e20229648695a9b01e09b6080fb1c4632931fb810c5bfbe4b4eed0000000000ffffffff03ebf599f34a7d2cfe7bda1722f76e3df5c7fe299fd5c6e4099cfec4f551f46b0000000000ffffffff03edf95bb2c93c07d734ee8b3b1de4d4085c6b65cdbc3ca23eceec0c4d2b29a00000000000ffffffff03fe259ab7c4c03447011200d7d5236f4b1eeffd075926b78650cf1a59d570590000000000ffffffff040f71baef9c5273ac67fcba44ab29456a820274654624255c27e53ff62fdf8e0000000000ffffffff042938cae95e712592060f872cca771dfcd0218562928311c81127c3170a57bc0000000000ffffffff043a09d788547db3d1bfd8512000f9ad8bb3caab6fc24fd186663542c9f06d750000000000ffffffff043fe8a5586d0309c8dad9277bfba04fb27e7a39d279c0c9a2232e2927874d470000000000ffffffff04426f1fb4981529c32ba5756f59a2211ee9d2b9cab2c5de06a07680e833c33c0000000000ffffffff04454fa62f2c03d785307982ae406224025343f19f183e0fdff83d8e1d4cc1500000000000ffffffff04496141484d641e3b0a661210b225df50221b13bcbcb3cb8c86786890c745db0000000000ffffffff045731a8be6bfab1f9d62d2b2158591029cae655fbde8c8bdee80f183e72ca4e0000000000ffffffff04610a21533b98d3360a6f2c65be5685a1bb3a43f67da08dc1674a0f517618990000000000ffffffff0471b7883558587879bd53e13694069d95acc0d809fd0a65125ba3acdcfd66900000000000ffffffff04729b78d9b706fcb20c9cbb49ec1baf5fa782ff44d45d9a23868bcbdcbca1330000000000ffffffff04747b056b7cdd34c9891845220c2b7227a7c7c4f90e1ced6f36fd2197b26af90000000000ffffffff047a37d63a2a17986896072c77fa2e068f6e593dc64bf2ad8e180fde729fe3250000000000ffffffff04875cf5c94486e6596beaffbd7d08cf5e3111df06a89f59d65989d1485949190000000000ffffffff048944d4aa4d42ae9e864bea755a4c934713c63ce1c61d177a1ef03fd679ee330000000000ffffffff0489d5c9638a3f689c232fc1b9b59e5f82bd2e720744c4405d6537d7931edb030000000000ffffffff04a206bfdb054b041ddca180111aad2abf7b31813e4551da3a29bfb16c03534c0000000000ffffffff04a5feab7629e0cd9569aa62ea70f7ab3fdd58d3aa9bf73e8f76ac32a949d31a0000000000ffffffff04a70237d798a0b48b5abf682b806f31ff425406d93e74cde1ab4b9939ce9bc20000000000ffffffff04acd550baa26049b3dc52fb9efef1cca0b8dfa228c64482440d7217a81e587a0000000000ffffffff04b1caf936f5746da6d683eb00ae36b885fd031a8928df91e3172b1ca17f4e520000000000ffffffff04c45bd25f17cc765d8a67ca80a801c1f1c2131eb51b7b8ceb71eb898582b0380000000000ffffffff04c99a8ab69a640f9891aff371876a9d0c9043cda0430cbd436145c5574c124b0000000000ffffffff04cc0c4723cf9952c0a51db275c9d11370a95f478de98dce603d09de8e3d8e680000000000ffffffff02c6afbe970400000000001976a914c055f905fe8d14a2766801307a418f1e03ba566e88ac5ee85e0d00000000000017a914f5916158e3e2c4551c1796708db8367207ed13bb8700000000000000005923aaa80d0000000018f6020000000000fd4301473044022044e60dc7ff9d720bdc8329f97c5b321a84e0846fed248b23d399d222a074bff402204aaab1ed5df1e4b94d627d8b06171df51140e65eb056536e91103b75d032cacf0147304402200fcc38b7bff890fbd390f4bd1057c72df74c2487a3cd20edee80a20d6b2ce02902200b7893fa29f24e09358b6777a946d40166bc71c25f8e5f850059a1914e25959401473044022006430580bc312023db40b6928ba0c39141a8a59bb0613c5f6feca1c1f9b2bce90220055ffd441357bc34c246024281a7b394c7ee6a2a3c013689d95a3b9dbbb98d9e014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000009503030000000000fd4501473044022059a8f1680e80b50cb8a9180c1fabe8a66e84b34fb6c10912715fa71a5bc0f9770220531c0836d4de61d8e291c517cda25919a8b822b80b5737068120411976e5577e01483045022100a48b720930c142235cc5585a97a11d20e73a81049791526cdcee34d36f92fcef02204d2523393dfc4ba21451fa563b08f53df7c7115b65a9f2f01fd578474d308eaa01483045022100a73d3ebefadefc6dd9c7041b32bf7a3a25e49afd41bb3251c502ae6fef89316102201652f9ee39ef09335f5c8e83b3fc7591b592ff0651c5e8c4786875710cb9d1bb014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006113030000000000fd4501483045022100a5af3c72e2e15539caf81189fa020cd4b3ac5432c512dc48772d825dfca7c60802203ad5f3caaf54593b8068ce50db67111ac166c2efb73b52b30dfb7884682faadc0147304402207796a265903387a8a612cf47a8df0aae7c251a339590b24b6d813fb4cfb2dacc022076df8e67ec560d8fb74ec7ed0cd368a4da09c98846635c662e5484f5ac5b862101483045022100eb3318b340dd14f8fb797af81d8c1784668f082e54e58cd59c1224890d7f6c19022064ce22ff6bb93806930dd34dcbc846d38028db4d4d4b9c5527b6d493dba01cbd014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000099f2020000000000fd460148304502210081e68619898e8b0f9eadf2b5a324fdd7a684f935bf2cb72eef221e4310631ebc02206c7d5f1067d2980a95bfdf3b8530898ee94138dd99715c44e30b0894a5a6031b01483045022100f675ced0b828f2bae7a8046b41869ff865c081a79e32cbd400baa8ad99a975cb022075f347b57272df25c5d49c810af71fd1ba515b27166e61ad0c2bcbbd746a818101483045022100f271a0a0a8c5cfd149bf99411c4504d9905e6f9ce9f9787744c9593cab7f1c1b0220527057676ffcdd60caf0812b20b08b94ee1f935b44614b29bb9ab59e5bc0080c014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000001b02030000000000fd4401483045022100d068f2da5ba187b9d16b06dc87f1ff241063efaa786e07668abd06f8c2bea77e02206c541479ba49347104b386c36df7e14bc087bff7a17bd9c4096356a8c780fb2701473044022027336ad739d3ae08d1d136a9b7002a97873199d82abdd4bfd0531d62294116a9022001925305ccab8a328b873126baf7977b51154b4f0436685fc21f483ad347fb8b01473044022031a20fbdd66cf2a0d59ed37eda8ac50772c25adc62035b53ea675200fc85cc1c02204c1ab7d35c53ab9a5086fbcb669452367d68c8a3f07e47843c8fc2e2dbbbccc2014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000c7f9020000000000fd4301473044022022bfa36e676571479c3dff1d1a5a5c0cee3677b5ac45c14314d242bee32664270220736875bcd0807c93c3a542dbf98c753c7164ad6830acec833cc43e157eb665180147304402203c2d6ce11bff536cd9bd4f58a930649f708a5735a26971dfd8d4efa7748c48b302201e4c69309d99c41d1c19ee200fe23547f1972173f0954e8833b8ba8ecedb6aca0147304402200e9ac49f352071840f13104f247d1a506a637d898495ffcc4aec7743ca56a2e702203e279aea8208e3128dc27173a6cfbab2bd8c2bc8f273794028ac77a129d5cab7014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000005210030000000000fd4401483045022100d8e2743e7051807e428574f9c881781b40daf0ec572dcc30357350c48683fd84022032a131a11df9571b53284a2cdceb7668e7b6442897fbfd54dfc7e26f8a3a19130147304402207798db2d9031f37eca9788b63869a91b100abfff8ba9966c91c42636e43c56bc0220499af71936bfae1579f6ae8d88dd6ff980ae1dc4fa8d1c5585d08a6461ce1e1301473044022062d193f3c5f74685fbccdd8795515f67b88c8a9aac089591fdc07a8238cbf5390220200f0d61cf48c33f7800150c8af578107c20875846b4a0f2af2a4aff9d2b172e014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000dcfb020000000000fd4501483045022100e4711a4de4d6cb64e8cdaae2a4a5033c1ae87549c8d419b42b8170ee5217e04602202784ec57a6591083dbabaabd49dea7cddd3f8a32d9497e23d4b4219a56a9395f01483045022100fd776ca1d482c1d39e3a414bd0e6d353637ef626929ca5ee37db62e3dbe3501802202abe2e1279e5a354745fc5c8f8dcf367c616d82f91052925b1e2880f3906e7670147304402201976bceee0c3bb19da53e80a10a92dd6d135c86e581f349268f58b7d6b387bb5022042616ed8eee7f19ba7bee1fd5ae5415b521615aae99c45d56f9bde39d2577b9c014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000008f00030000000000fd4501483045022100fda77866c51a7ded28a6e12d3459e32b33401b1c0426f3c727ba4542ded40d1302205981be0eafc9b2c702038844769765df04bef8e17c80d1fef65c2bdba0a8e6ca01473044022018343c7eb59ef103fe102361f9ab8c789dadcfb3e60dc9b25b429165a9625af10220367f3f95f988ae6bc29c8a400687ffd70d009fe0b650994f48c1875620440fe501483045022100ac63791400e4ab5fee7f8c8ac602017409764dd7ef7ffc07d793298277661a2202200c3de5c22cad718ae83c101e987b66f31f62cc3364e8c8505407ebf11b392b66014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006211030000000000fd4501473044022029a09ec85ea2c7741cdab03fb1185d94029a5511bbe830d11ac22dfa7f21f452022060d4039356c9cf06be106dc81390025735cde670de5c0a5a38e3946cca95211e01483045022100ca82755fa0c2a23e207c665099d102d13a393ace8cfabee79b1a6f97ffb001a2022014e2ef964e3fb5e90743c54e620d40d79ef111be1299d917f762c442d40c2f770148304502210094e9d5926748124f8c215fb006ec2bec55e4cf469a7f8579a339c08a267ed2540220323b0224d9964cd55b9ccc3f1dd919073d83edb293d022b00497b8681624bec3014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000b009030000000000fd4501483045022100a308d49610b603e9ff378fb40620f255216f3325aedc8d9a909f9c5e8983cd4e02205c93d14a43aa5d4cf7a3d4d483c6d47ccb8c2c4b78647e6cbe490ca6e03cfad601473044022004b8e60724ecba532e2677411e2617cbc49ba42cd4843423d724797aed8ba60f0220198d033cf732b5451d5ef00666ecd19bf4ea8a08f6c5fc16f4e153f1759021ba01483045022100e6217183d6869b431befccd5f4b12372028e7975640cebaeefd5f5172b871ad10220152db2015f3a8c16129f34e2488a4cf19a85f26956e3818f2cf76fdc9c43fd35014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000005805030000000000fd4401473044022011d6116b37d985ed52d59aa4fee1c67a44668f55d2db37fcecc3cf89245994a002202ecb47c384e42351995cfac7ee0fa8f55053dbaa11784a1890be84c164a5cdfd01483045022100922746c881c2becbadee3859902d93c9f623d1ccf3cdc0231d31e3ee806a1db90220715d1689faa159f4abe4959063e4dd8f108b4dae79167367843dc31e0fd46e97014730440220280556147f23f8cad1907869154a98b025baae29367cc80c6d23a3a0d3b6443e02207a62c31f1331459885ee236245d3e122013b77b304ed512914b05acd1886ce79014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000004bff020000000000fd45014730440220053f5cb6b633930fc7ccd1abd012292cee5b64d6d5c25220f9d9f22ab16d1df40220430e464f5823ee503616dfbfca55fdd01949cca336c8586f4e1de72ec3f3063201483045022100e16f4708245ca99bb01ab257f495d6a33b2db4ee9ee5089a6a2074ea9070d8f602201d3302d14c85f11b2f42af10e2ac31739f085036f26aa1723c3cfd2d4b35b2b501483045022100a0be245e53ce42f783481e3ff658c13ac850eda7ad21b8206bb48fa20fa2bc5d022072963db0ace1449652a083be585dc75574490248d1069c0a48f7f7a6902fddc2014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000001703030000000000fd4401473044022029960cfa720d3818d4d2d7a55fb1a68323e34678a2a8fa3e68505cd78184cf9d0220723861ca8cee7eaed1f503a9668d9866ccae44f15a3e9da77e4dd23679715e4201483045022100f3054837f1aa88101e983b28466b679fc43fac26c48d0359c4b881ed3cf8e73b02204f4579fffdb2a96fc82b0ede6bb5eab53a86b0bc04e1ea0fc1bae9953ff5a7f90147304402207e3132303406ca2924ad934d49e4027f52083638f08d73bed7138b6d267948ea022018720dc7f47cb13d3d37555c0abeca90cb00060ce1308a3de317d63da5d1f4f1014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000002f3020000000000fd4301473044022012cdbabc4d98705db72c8a6448d8b5e5483b404ce0ff26fad16b3751ccd667be022044bda8f743f51515281b41e7b7a0347e8d52e9aff07ad0c4c84486034b2257a201473044022021e2029bd87c699931a5eb4f997e56f1efe1dcc26a7fb8c8147a762bbea389ac02202ff5feed06720f5bba0c12107dca3d83c349a35c43256429b8f12eacc6b5df16014730440220269980cf3256b87c9ff83b29e3005b6af9c85c5a8fb7a501055b486bb51fe3e0022073196474be83c9cc24a843777835b97c4eca0ddf7956547f6cdc48a1cb42ddb3014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000030f9020000000000fd450147304402204442fa3cbc6d9ca9a217069f984e8fa1bda35a825d6bf39804c92faed97f2b8d02200976a8fa7653918fa23dc3adf15408d09a8069b033f4addb723a028f9928fbda01483045022100a36c038f7e49fea33c9f2a26a4d8e510095d42912ba1cabdd7da19ceccd2466802203b78e02c86e2fec18eea2ae2b94f1e6736dfa7a3453be9ee571c90832978509901483045022100af4a52bf94e8618d387c8f54feccdf0ef49b6b5503102cd405ab28c48c6597ea022031053ae17323c0fb24dc2cbd3107ca374279cac0b54c4a6633747effec83fc9c014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006508030000000000fd440147304402206391486dc686a643c26e9b43038b2cb1b465ee6ba81ba9203d0d82f9550bd26602202ca9ebd53b20a6238c3d8abd4236b10d9ca304f5e5808db4d5004ab9ede10ad101483045022100e419233679a71a3380b662425657eca9ad26cb425a8aaaceb10de1847b3957ae02206780b4b428765f9bcee90443aaa497ade22fb813951205fd53c999f7ae27c168014730440220656dd7808be7db3a7e448608ccd3b8696cdefb687de8a4e37a58a2a0db8c714b022044683a0d0299b6eaed1ef4162d85f563aced9306d3e4a84961a301604234649d014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000cb13030000000000fd440147304402200ec0afc3a6b07063c61400fdd53e5419bb755bfcc99b1d6d2cf275b3f6848c75022036fa64742979454ce0c6b2e16963dca1d4509360cd35cb85fe533982a2ad9e690147304402206ca03acffd0198c7ea1d78e713eb45812dd0a296929bd679137dfe56f3f0601702201b9d6b25d85e86bc747b8c9d19a1a2329b02ca9de22a914419cec25bcd68e6fe01483045022100d22e473e19fda86e31314fedde03e1710f5de93efa284dab5f86817c99c9417602200bc43a59bee8a46bbc813ce52cdc76066903820af43d4caf173000543f672c6d014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000005efd020000000000fd440147304402205b7ef22035cfb0b11b62354d91f97910937de864369708e3e35376d4f620a1780220496aa95cdab061367e571568269afdc2d0a8fbb83b1bfd08c062d057041fada001483045022100db48444eda15deaab63bc6f3f5f31546d3b44a5a9412323445eb3e0853b440c80220201d7c95c47b5beed4a1139c27a79dbcd30f288ac106a208f43c61a0989f3e0801473044022040693ca2c95a33d5e8e7218b99a6df8507e9b8bf72014d19cae77d489b57b76102201883ef3c9df0b017e8fcf5b0af1bfbd61556d5bf347d77544e3bd263641fcd1c014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000046fb020000000000fd4301473044022005b50050f39f996b5f91e8e2c297e66521d5f72f2f4bec9993dbc44908f662be022001734f6df9a192f00e131fd8627b37b2afdbac8afafc38513b02c52ff305efad014730440220749ef2b72f235127bcc7c949f171ccfcc1ee87a9979543df9b568b323d9707260220440ae76846f8691bc471aa479e876a5fe01ce0e1f8311045cd8de1e7e58e4f890147304402201f5d4ea7f8fe9f08dac2020f4a2242645b27541b3cc591235fe927bfeed375a8022077627f400a799de27063ca0f2ea2d3ba5b8398bbac368a0501066097ad649e3a014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000009a09030000000000fd4501483045022100b83b84be0a0e613dd5e9dd7c6bec573a81bf95f83b546a4a717e3b708cc18bc802204bf97f877e03608103e30aeb9aab39c8f8d6e22cd9e89e66e7be74277bd7b7e201483045022100a9fe153e507bdebaf820f73e016ca8c7c61e3a07cfe7c79d74d674219c3aeb94022030abb047356650b8bb79d9eee45a9030c5cc55466568285e6d6f97cd6be577830147304402203da91297cb8e456b0089bbae43ad02d636f3f3777017c5b0224da4cf31ac5e5c022002a0ab0167395ee04f8e0f37fa261a80bff532c118a6f9fef229c5a9315115bb014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000cd0e030000000000fd4401473044022002012e7841bfd2dca62a5667f9bda8cc9b9e4ef86f8d0d6cca322b5bdb06a9b702206d5428e45ed0e18cb980b385cebc86eb6dcac59ee19f84afdc0c95ef0e782bfd01473044022073c34e5025fda812d8990f1f8cb16fbd4665554e8c467527b2c5c21132fbdf0b02206c22e854f2b704932e8134c46c40c738fc65939b2a516cceeafadd0c80f85efe01483045022100d808f0812a4a124c074166d87084bb3a38a6c632846a8ab4be7c69bda49b880702201a3625f5641c6a3a414196dc3b356f59b9bb8a44cd7623d601f28cb03691cd39014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000007fb020000000000fd4401483045022100e5357e2b20252b028d10d746c386959ba296630f08d94906a36251bf331073b102202c55e9e3a482e27326731821d25fa4c09103ec60c4cdced3f6774e6f1bc929970147304402202e58674ad455a4172f87439beaee82f59842d0c4565a88a358ebe8db35e2204702203cbffea9df59094f823f598cdb252927b1af451f522c8ca24d52274baa2c5f440147304402201a078f0959625258d4ef1bf7918b852bcf1629f8e79e2a95c1e6ffca017b7417022071dfe182e18f1debf0163e85ece438f1f3326e2eae39eab8d9c7a6cd8f179bd6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000043fc020000000000fd450147304402201d697bdcd56006044872b398bac35b2c736f6bc22080ba7c81f5038de6a87a3702204c832224547a5bd89dbc5639e763dba74e3b35e77234078b425b7157b67f401e01483045022100bd54f0d2fdb584b15215e1eb8af08a2094f9ebabe0db8b01e107d0d6ca7c55f402204b1c9e9d368361903fe3cc99e48d045672818ae5ee15b3fc46e1c84049ed1c7a01483045022100e62ff90682934ec550ea89646de3a8d8bad4919bfd7d04a343aa490ca380d49d022046b3c4d8354661d6061798201cdec35744471b61bc55d83fa403d1aa6aa3b2b0014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000000cf6020000000000fd450147304402202d47018ec27c8d18a170cf22fa9f16df5da26c9ec85b5e7ab1220d7619d3bfb80220391bce1206a19b54496101317aa853f59fe8685f4ef1080525ec13149bfbe0e801483045022100ebab59d9714232e70788b14713364d8fa9c6284e0c2f173a3376521fffcdc80e0220624b5b801a7127e41c4378582026262e917a35c69ddb6fdf0de7ecaa26017904014830450221008905e07026703b5c1f6793fa9d749981369235d540fe0127be7b5d8cd18e401f022017b7e658adf3ad47487dc49c6aa8e88cc4d3b97f87ed0771299ef4026a8d8995014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aea4a2d10a00000000c506030000000000fd4401483045022100c73924d67aaa9977d5b85fbad560b5315d36a657a402913be2aa90a1d12300e2022048b79577559462b4fd8c348a0b4d98caa20cff2c8a0363eda46037fd11782432014730440220345499c9d88b6989f158f7f980fa6f78f0a4b57d70f159739bf631b788fdbd3702207340e0fb636061cd9b7de0723d196b5f406d24120cb84f1236e3873f6e2fd6540147304402203332474e7a96938334a32052a802abb131d7a5000fb8fe1b903ca2474217d514022022533f3d58829d55689671efa27901878cfb75b20f5c696bb00ef4fcabde125f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000002afd020000000000fd4601483045022100e7e10b3fa44e3bac1a8a5baa89ee3f34f437a37572a111d75ebc323007220956022007332c4fa0a81b99711a87342f7e13e720d09122f6f8d91ba093346d17cacbbf01483045022100d8f075435a1f1e6b3352beb482e899b95ee611551a499539c0004d703588a4cc02201b339915bf5cc5b1f4ca95d507576e58dfe20b2a2a3f9e97adc37c8f1f2921b301483045022100a25df71a3f33e602652db2a3ea88a65522edaf1e05c0900c87ef7149dafa9ed80220300d23d4abf09c979ad36916da78de09656f4c38a4fdac72454a888babc3f22b014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000b90f030000000000fd4501483045022100b6240b6c0f35b38bfc074939789eb53550f6c570487245666cdb825c13b95fe002200789f35de73db6342d1a3fd381ae55f5e801e1d170e7c9672c8179ddb7c9738101483045022100fb1a47917fef805908d2e02ff317a685a9550e5edc0aa8ef8568282575d4f6c802204a6b7a54338332ccff52ba21310cb0dca6a6b97370f1a621566c9214e03b49d20147304402203ef5647f608b1e921ed139dc54bfaf5e5ac3d959b88f3dc7a2ade0729f62818002205df3b44fab36a105bcecbe1f6b2794f692e0fe65eaa6d78126279c52db2a438e014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000004b10030000000000fd450147304402204cdd0d63816bd37ceaf959d323788b35a629d6b167cb2337ac81c0adae1366450220271435beb70cd8a18ddbcf98356de296ec16847a7a3e1a7c36d400f332374af601483045022100842dbb08884f9834eae867feedfa0ed158175348ee671aca1b470a9c5a723ee202201b9c8ffb52dc70fde054f18ab5a0419b603880bba4c9dec47d46bafb25c061dc01483045022100848c18295767444c5e0670930a0e0436fad251964bd4884ff5671db1a3f19d76022016edbdb3e65f99cdede5e957a941f3f35889342818f6805e0126e715a335aefe014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000001402030000000000fd430147304402202b7fe153e0a3f19123f677cfde86578aa546f8a46550806758b053d0b45b89710220792803175b29dab2c6e8c751436b30213a3b409c8d7cb0299f29a69522b120880147304402204e67807d8a30c8358cec44173c7a0727f542b4dc131f9701f2555a27cc17b628022044487b404d9edc2e2e8f553ac874c5dc549d9b261694752759d101ec00cc44c10147304402206d537d0aa88752db936ee48e986afd68338411ff68797ee2f80ce537bbf41d9002201d276c24365b68d18ce4020792c5d9558c7134495af96bcc55721d795c7662c2014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aee854ed0a00000000f1fe020000000000fd4501483045022100a53176fb86d2190592abe80725917bfd5ab910b942d6f9648510e91730f3986b02205db19b272d2a2be3e315f2c9526a02c23f043c7b643128284faf734ce1d8930401483045022100be116b856b1f0ecac3c621c21a09d484a4bb86468a93e37f7c6d684c74c9031202205bcb65f89495e4575a1e5babb08cbd2aa21b200bbb9af1bd789b2a5b68c804f50147304402202a0dffdd955e6a5764e06113b5b712e789e956e7b6bcfaa225da8ef66e446c1b0220455f54d546976dd492b94f1693aa9d7e76dfffe3a7e861cec5f809fd5ac18caa014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000b305030000000000fd450148304502210098e4071de0540dd5d502e71a962803452695d3033ae1df83855e238197e2073e02202b825fb2190c784c050c375e1f520c0a2a85f9925fb43ffe58cdd25708e2877701483045022100892cb91af82982c870671e956805fa7aec721b82962311f4c51f959889ca8efc022051766e50a95d2ac480851b98f129889a4dd566c69b6ecda9654b3d4064aa40760147304402206ad1b9cd9af3c1e69ce32f42f1eb9ceab84e99b9f04cd14ab8842ad065a5589e022020b98e515e17d59e415d11b1be3e4fc34783d547200960ec96a4f67b6741aa58014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000018f8020000000000fd4501483045022100e500b89edaca4c2408069dd40b9645eec796f536ed10811016aceaaeba48b9b102201bc364c56b9647a7c6c53b235418a78c8d8faddf793bf3ffdbba41818b9a401601483045022100a9695d1776c81442dfc4931a960188be256f58c46ff546d1e872015c8ddf56a2022012443c230d3257b64bc8ee05d18269c211becf4b9ed3a5c7a3b63e2e216dabd8014730440220073a21f37e0d3cf9d706dde6e4fc2232395f4bf1982785ed04c61b1144f7c00f02202c7b18f4893413590bb4fb139896826bba6fc3e1205fa43fae30d8e7cce48edc014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000fe08030000000000fd4401483045022100ed3f9d7fedec8c9f8bbf1afb2b7b1edb3e4e8b9dfaf789f1effe19a32dea4728022046cba3fe18f0c1107d3fe2436d037aa8fee47e830cef788fa86541c84ac02a490147304402207326ffc63de54f4554f56a7da2072cb4bf89479bbdcf22d00169f4c3d7054a5c0220717c3c86a5470ad7f7a4900cc13e05a0a929ecc00e3ad58ac5850508ebcf7a6a01473044022052cfcc5fcd981d38c150af8897bbad4541a8aa2742d31369bf0c37c4670ec5eb02206031643bea000d5d33e180a75627cfa7bacd9eedc0926eaec773e529255c6262014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aea4a2d10a00000000e001030000000000fd450147304402206c7e38bf498a7ff831513413e5bf283b93fa456993162fb698a88933e1451fa60220669d5f75d9817f3ec08607f4b3b0ffc3f4190b5f7cbfa3336f1b64dac28178f001483045022100d8a58946dc73974ead5766e023a11eb2f32d3b7d7e482ff92255137fa6aede21022040c02e902a208a25b10296ee0a5466c6a8ce211ae2a6e2b7a541d2ea69fa4fbb014830450221009bafaf344ef873797281daf907d4e1171d8220e47bac5888e5cc72f3e219ef85022029773c52b7785abb77d72c22fbda1f9cc2a8536ccca43ec756bc9655ce6a9a84014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000980a030000000000fd45014830450221009be858cd5d4a8bce15d433d040be529a38cf38d9358919a9c04a1ca26127e3e402203de44aed9159f37e4b04ca449621d82040eab2528e2cdb7539708574899175c80147304402207271dd94d087a7b2174f3c3ccea7b92e29c84c6471224269f30faea34f2b77bb022000c9e94e92ea9f311d7a6260a2283f879115eb84d319d0da3cdb724b2b66da890148304502210093397c395481625411641fec29b5f8c37b4163e6bf886843080082f14dc716c402202f1b776d07f69ac148ec36a257ed43a2a016cc3257b091f1180bdffe9fb8fd39014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aee854ed0a0000000047f3020000000000fd4401483045022100e59a2bba52457cd3a884568aefb50a2500309e0262243553b31da735cd281d1402201c238950f19cff6cecb3e75a7308c6a0e9addb39001b36e12454575dd695ef07014730440220679cb79f57fdabea76ea42e3f145aea59f3cfd4401c4c5b1693b2ba03a2054b202205e3e2accd4d889e6fe4ce0a4ee8d6618dc79aa1f3b2d3bfb664d83d25d6562b501473044022043b80b0e55ea34ff22377a57c4633c1c5fdb57d53d04176c1673cc67e56d63a802207081bacf923edaa05c4848a11fbac160eaf3a33bb495c26361f85f3ff1fc482b014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000be08030000000000fd4601483045022100ebac21191cfac6123e0a66e7c6af7febc1a1ce2e63c4e6fa1e4f75d6d2f39dab02203d592a16f40f8c8c88817d0788457d66bdb35dde14b02b90c7c353d040d4af9101483045022100827b7e2ef669a5d1407b98562a4cd45f302f6e2489c1bef3b8bdc6a0592bd922022036fd1961511848f84c9e8c633044033501091c5e756e28a4787846156cb00f9201483045022100e330508c7b1072b3644bdaab4a6219a7cd7ddd364ec0729534385e2e6e7fdf5502200dfa2bc091014c8cc134728c60c40f21f737203e5c5c04740fbea54bba8eed04014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000f5f2020000000000fd45014830450221009db0475dc62ee80b8b49bac4d0138de52f985642f5ac40b75f46b643e4115767022042a464c53ebf57bfcefa05634ceb14e7669b86e94bea517c68e2264d676c70f80147304402205e563709bdcb24975892a67eddf3958a31d3a58471c6c0e0cb6891be80b9eeb802203c69bdf9042af7429f1555cba2180108834b3d3b139514274fe5c30aeb9f054901483045022100f792db494bef64ca96ec49891434bd33f511db09d214a3ac323343d758e2d3c702203a86fd817a81cb84610fb948d6b3ec7f4d4fed24da15ae9ee245606c4f5c42ab014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000bef8020000000000fd4501483045022100ca7a5b358614ba7615381667ed1d6ee7b2332d520caa6c5c6c1b4aab12fc4bd9022062990a8aef2fa44dc073cafaa2f3e95c3534ee075ba998beb716756f985b8f4601483045022100eb982763c3fdacf7bb59642df124f090cc5e55287b28c206a47c8a3ec8f08add0220668510362e0da663f117235f3aacdfa7fce13abfdd2c54425cf63d1b32c0b56d014730440220447bb198dc7466bfcf815e6b91e2431b970f6eba34a02260c224e503622e126902207c8fd1e1bdd32def46f7442df011f58a561b04477b372da26888c2a38d2bbb53014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000580a030000000000fd45014730440220702dd862dda92c7b3b214909a1f9dab7653a2f9103b7a62d6646d02c651b34e7022022e3c90cbf41c1fa2a5aa89ee139eee2e656a640947e8431c63c54e1e944763501483045022100f0781151a884d97b3de74df629265914f8d0253581e789a2eb511ef76568a4d602200f33782718c74ed75c25d66426f2037690d0ef3734fd06017bbd65d992b68bbe014830450221009d56003be4df82e009e4584088807d5f4a4322151865681dd04645c63b7a5a010220584ade2f5b18756f6c3cec7dd391cd174fa9103c747c8ea0d0fdf6877a4fc882014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006407030000000000fd440147304402205d00ab5aa7656681bcde46fb484802c2a304249dddee6555e680067577805f2b02207541b235dbef5e123e7b392c63497ea074c26f08d004e766a7711dca4e2696ec01483045022100fed3c2fa5de22702bfb31075897e03b433fa593ae0fb80794103566c490a595102203f5b01c8e7296be4e2f1a836b9be4d073bd2378816ed09baf416188d9b25c3b00147304402202cc6e2988cf32e02b25b2a2d853a507857ff6eac50427c4def421f20aa36e9cc02201313060f0fedb86d1dc00b41b437705fae3e5e3df23b254a2343afde89e17ee9014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000074f3020000000000fd44014730440220681a9e9bcbffa35a8328fbbdb173d803042ab1a858c4ca9ed0e4f5a67d453c8e02205820f9fcbb4414d41c28e3509806443a869168cd1e17b428549ec2495161f5180147304402201339021529c4f6eb6dd22b56752ad5b2df7e1e8d978439c9578f0e907974711002202c63c6b1386bea4536364610c38ac0994ae863f9f35bef25850d6173901f794701483045022100bb021e7846352c38f3fd4fd21179b448a8d34295de73fa41c57a5f972e91c355022008f06f8bd66571e4027556cfa9124b4e1e518a9e82470261db3f0a3972efbcb6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000e1f8020000000000fd4601483045022100f30681d06bbe18241bfeeb7cdd484bfb44efcd579f2c2e2ae53cdb68fa5032e202200d96812f571f9d8e8fa0756e351c7a779c46cf4ac62a6825f14a5020b771988c01483045022100996344d3a16c60b94789cd5ae4d3cfd8f0b660520c8e7602e0f8a7aae705b127022008d6d5577a2b90e2462bbccb88c79cfa2936d001e1b14ea530261235460c0778014830450221009a64402bdfdaaa64d429576b0c77601e8da643dab7437e8cfd27db5a56c05d2002202d263058b96116381e1879ad483c664341174f341537665c1ba7b8a33e378e75014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000086f9020000000000fd46014830450221009b8535b0fbf8f854787cd30b5109010183dae5807fa34e66e15cd6066dcb6b2502200783da464daec7780b546c0b6a4c274afe5f4698987820d36d6f9d5798ba2b7b01483045022100ccf647bcc6a89c6cca668aa5d4cb8577b8b1ebde8caf476c4270d96c631f6b8b022072e9d434ae2130352841477494a39168fda21ba51af04f372416a12b2a3eeb3601483045022100b71cf0b31f05baf22586a01f0e1869e8a37c9fb50e1470c6d82f0e8c7e709bff022050bb9d7638620264be1f8d69a477be454dd753beaf0ad6dd92f3d996f62910ac014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000007e08030000000000fd44014730440220563b7ed04dfec4aa05efd0911b384ae4995b1ec21be2572013f924268db89c9902205b3c939ecf522cfcd9d4678bcbfe23a31a3fab94043725be1d1e0c2a1ac6faf001483045022100bcfa16f8de773f97dbf9dcab27ead17ac1b3bfaeb16733d1bc355380595730a7022000d0125f418f48606a41c8b6f3e7dbcc21fd45f8c64be25513d58f56a0cbb0bc01473044022038b52dabadc8e617c7efaea42019fb8732a1bec5fa7a696c4c050b36968b637f02205b0bb3befba6a9fad35b34b99280523ebc37c20ba2eb9996d91c3f25a8d2a933014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000001c0b030000000000fd4601483045022100df6c07633b6669c8a73e33a004924e1a1e488329a165bf73871a6153cd222b9b0220240131a2687dcb6ce091ddb241d9e533362b29e351a7e181180b09a6c395a3e301483045022100884e519da7405180a348e67a6f9065d6a28520168924cebdc291f00aa28901e402204ff72a4d9bdb0f4fe667eeb0ef658a0414fe978c71193649235251ec99e0ea1d01483045022100c54d7fc08cca52150fe97c943e8d174306f125a459f3e71b489e7d497cea63270220101d71cd023d9131e98a1630a1566ba445b8e006aed4171d09f859aedbfb010a014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000befa020000000000fd4401483045022100e1c1a88390bc698025e6e40d1005a028e02f48f4708a2d8adb6b388e8ff83c33022013afc0b581e7b70d7f515d32bb1c7da68ff84dd741dbfb35855213467fc04cd30147304402205775454f05bf5fdd98df0d27b91eeb68955477768b9f50015f41a79b6f55b67002206861d59d11023c98d3a8df4edbc30a6008f615624fb18bc7d09c76d91f3abace01473044022055e4148ace2edcef6fd14e2aa7524ba7cdc397eaa025d2decfe8dff9ef93cfd402203cbdf55e08018990bcea1255149f31661fd568f1542c3c34ad9865161382a845014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000005507030000000000fd4501483045022100db1d65c4c10c62a9a727e8702730347528a810c18734666efbb8a9fb372d553c02205e3c8dee1c43ada5aab36e5e91291129dc06bca5dbcb2f72b143e98bbf8b506a01483045022100c824496528cf45264250c975ad4926e216c51a757aafe4d374b43d20fc3f108802205f3555d6c1c819be780e0fdb0b73e90727a9ffd86620c2eae6e71dba4bbb696001473044022045e218224cb0e51b36a8fedba5309d4bd0e0f3b3c89eaca58c1100a658f5370702202aefbb0c45f6044af9e8f873909e122f317c0d70872374308b6a4506ca4918fe014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000ba10030000000000fd4501483045022100a5ad7fa4026ee61e4c1e390a9d7cad33e7a23c8e84eac552ed5bd226350f2cec0220053a68add02401a90cbe70dd3ca95e02f7f3fa9c7554c9b85eb2ef9dbd7570d3014730440220458d2a918740dd329e7d3cfdb2035251503a472138b9ab19f18361ba1c05c40e0220523a8a265bbab021a019d54934bbccf0d7070342acf3ddbfb4c4d85671b34fcb01483045022100f8a7da4ff094abe375185b727847cbcf4dfb9edc7aa2c7d067153c6e4f59a479022001e0b4d4b71c818e3790accac1fcc7ab94c7949c9942224ab8146f31fe5b1fd8014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000003d0b030000000000fd44014830450221009ff8642e68b10e870a62eef426786fd90385f27ad7aeb2ed86313ef5572cf69202206ae5e31a87ee7537329c5a791ad06666797542d0d53e5e803565c46e850fdbe10147304402206477af187868ba99a2fd16ef32c5718e0710e497cf3b63c8d0451fc91aa2973e0220756a79e9d3c7ab5478caaa194c620ef6c5cb051105cd8d5906d2234226bf17420147304402200b6bec9b2956c32bdc2d39dd77790ee8469253cbed7ae4b1006eea6786bff7ab02207fde3b16eb595c5cbe2c022907f157a64a5d8dde2ce2a354228f6bf447a7b874014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aea4a2d10a00000000f301030000000000fd4601483045022100b927e3f030945624fb57a1c78083dd5ecbd16bee095f1427fee2dcd8fe3571b4022059fae4cbe0bea4848e4d1e398f4d2aa4b2a17614fdbad4f1448a920cf73e189001483045022100f7fff756ed604f5239b0312d195e67880242c4090d92df66c2ee925c88acad9e02201aa1785336c8bdb7c604ba39809d889fcf5ee8eb63c90f4a04fe2726c58418fa01483045022100bda45c1641278939fa116163fbefbe1977628506882f873768a3c478739727d802200498f9e44d1e820ebc8e5d77e961aaf889bb72935b9274085fed3fa15f77e2f2014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000078f7020000000000fd440147304402207d4a786eaf1b2a169916850e5452c4e220b790fb3f2ad669a75aa54aed1a469c02205bce95b79ea705713d6c78fed676d2f0a0af31e4716b3d91f4f3722ac571357a01483045022100e5aa71c4430cc8acbec03d7a666c90e675df226bfd9e64f36e72da3fa3615a1c022038b8e99f6a16de52780723ee3f2b72ecd193002222df75db1035629ecce2a03b014730440220097f37a7c2996aa2e49aa2f36dc1669912a4cf2e5dd092751ed9df53188e078c0220676faaa01133f821bb044cf2d6f50a459c25c4b19eaf0145b4430967db73b01d014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aee854ed0a00000000dcfd020000000000fd4501483045022100e60da48ef5ba5b29ab98cbe2ef99ff0a2bc92cd85024e49e5ca3597f12bcf300022048e6b0090e5c8057477dd7eb3789ae0b8fbdf5362421eda08c76d859ad7b544b01483045022100b4cdbbd212bbda1f70d6793d9956039d7edaa8fd70bfea7fb6a04bed7319e3780220425f48e5b29e7452107e19fddaec28e5846e04a2df14b80fc143bfd71e6266df014730440220279c65bad108d0007d821385aaad55ecad775a436de2b4e32988815020764847022067a86c7c33ece430d743102f84a9c48b29b9de9da821b6666929b13fb34e96e0014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000000f8020000000000fd4501483045022100e0d21364935dc638b62cc87e9a198a47afaa348143c28c35e3c1d4424bdf4121022008bd790132b5f6192ea6187f5cb5a9ffc6435eff720357382739d1a961fd9d890147304402203aab999b99e7753f39e2ef8d450241b911f6ffc4d9e858ca6743b2a5b7ff236802206344c728587b60b56672c4ada3fa58778cf4905697d46d026e1019eba70d1e3d014830450221009525cca77d25075ea465237b5259c3227c2924507e74851db33a71d6434a90fa02207fad277b64c89ade6a42a682f049b462e8257be13ee27cd16145b52bf60847ec014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000004ef5020000000000fd430147304402205879477cf645049300fbcb532853fd3672c4f00ebe8866df4479feec600e4217022021e95feaf3015d9d03fe78b3a0b5b61003e4182709aa7db198a050d9ca6d54be0147304402202df5b7711a3ca99433ca9a6bc6894e95ee4f1c5c94811f771e22fc7eba8514ed02206a2763d0ccd7a641d2bbca36110a4d0972bf5ab2e4660306bf8af866117759670147304402202a22e0d36d9f55d479414abfdba71a933083f44704997d0eeafca51a3dd8d37802201a4ec8031ee9325834f31805fa8bd50e5f9fa165b965f2027500ef0ee0b8138d014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aea4a2d10a000000004412030000000000fd43014730440220221ca9f2149986b521ded423d8bf044b33502c128d5820c7ef6ea240a5bac8cb0220567cfd17e603a28a961f2a2ee88443ae709f5fab0d3cea9aa6232f5ea2570e000147304402202e38267764d91a348d25b328c11ad05323228bb3769334527418cc83df6815b7022072d856c6d2d45b1947f99e9c8e695da78c97e956eec9d75e2ac2f7cb450ae4240147304402202baa2f128838ad113ebdd95bd16db144ccd1f29be98fe435f145e7ca954c44b40220279934a60ff066f77c05031d6624cd1c7de4e120835162a2d43021526ad84bd1014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006c0a030000000000fd4601483045022100c858877b7ebab9df2f7b0681239c92e6c03e95d963e42a075fad8c452e045b3a02202e04bbef330e7fbec49a7ba9859a6cadfd61830ab858362a2a695ad4db84ec8c014830450221009139aef771bb21f6ccd0b357d5e62f0991f98e67039b4ef146ca74c7a95883a00220268ea8e98573e4199ddaa75d2bb08f6b694af8bd383614f59e8699eacd7850be014830450221009694018de0f453d6732941e22309064ef42127d412ad135808acd9031e058fbd02202b4d893c63a553fe2401c983d4ab5a2f1ae9d411c195470be7d895ea4284b86f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000ed10030000000000fd450147304402204a295e4d135f4f6421bea46bdd97d452b23b262408d77fe38c1f090f5f88651f02206f79e3a47f198091c92cf5733f9ab0acb3347e21f1d66ebc53e01db3dbd6845701483045022100a606efb31d0eb4cc4112721878cc3bf2fd0fa2b2cd3337a98cd3304e0cd2e38c02204b6117547daae39c06d7477c8f5e9e0e0d767007326df7b027cf80ec36282af1014830450221009d3a3360ead284b47ccc8a13eb1ad8de55563dbc5ff0a98744fde8947ff5484202203c350ab88bd4650aaa762bb1379022abedfd9316e9771e3c516190d07fce0349014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000be09030000000000fd4501483045022100bc76c0450c83c1a704cebf734d36f64e1ecdc76fdc1cd6e5f7986caab2d1dea902206bd1907f48bde52c8761bea4b7cbb848b2331ea58e6fbe683ecf2d60990001400147304402203287582617de76c70e8f73fba20100471cd40b4d6cff4b883a9ed88922c96dde02206e36f90628e7822206d93fb668e759ed62d6b73d3ecde935187d239c84d296a401483045022100957d7302576e215c6e97eeab33854a139f88839377eaf10edd1f80d7567ed5e102204452ec2dd7f273d586d7ca83f80c554c73531ec689bd961b524c2d0f2b16049e014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000fa10030000000000fd4501483045022100abeb8758b4ccf148e91c24c43b46c34330210bfa56eda2afa91c64f496215b21022046c5ac2cdb04ff964369cc6137b8c6b1133422640769d9f7bcd66cc45bea71b501483045022100901da0b92045f0c0195447fd2ef83b9cd6944e75e685e38a6ebafb16a03087a0022031f2261fa0f6486d000daa590875596ddd40fe99e943ee9d6bb8bd9129b0f90801473044022021e942e7c2e562631492f4c7bdab659af69efec054e5cf8432b9cca6e2b35579022051ce1c6da198abca7414783ef73e9119d6a345a0f0f989c53d74fb506c5c8fc8014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000850a030000000000fd44014730440220132a4fcc7f1a8f6f3fe4cd9ccb32fe3433a4e450f8594424e2389368f6a7203b0220075d01f8b9ed12b416d1d04cb9e95ceccfeeb420fb49720b4a3f0d1404be2f390147304402203707b8551104cac7c862aab1a2f730208f8ecee7180ac474b409be4c6af73fe0022023e293d0368a43397a93928d61586bc41c6c7bb1793b2bd2639ba8520014783a01483045022100d4504304bfa64c675045ffedf26e9b85a3ab839df273d93e2b1b9ff12338c7c50220080f395e7663fb9539181eee186a6960d69319333cbeb4fd5d596226c7cafa34014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000066f7020000000000fd44014730440220048efe6d5dd87a48a1deba890723e0e568ba8fe0112d29537237e0a1ea1c38070220197fda66031d9df627b79538eb4de824b9b49d94fab8aed185674ea4beac7bb901473044022006bc3ef529905db1a6729c0c8755267f63b3de05a0e1df68f9a2a983596e780e0220017582ffba0935ae9c8739bd6be3d21f9aec531ebe36e12073a5ee985df0110a01483045022100ef338afebdcddc9f46ac98ae9d9f936e44241cc46584096980690174b223da3b022062e0cbe00bc6ee9588ddf92e3c9c74f55632743d3d43dba4e43747fb380a4727014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000003901030000000000fd4601483045022100b21b940e774245ff2cbd5e797973a36ae61bd59c5a24081e73894f5823150d4202207c90190110b9607b151db47b81e7008b3fbf18ab952f83cae3189e4324a21709014830450221008949ea570a61d78294fbe8c2453a211e152b0b2190078b3cb085ef58fa2d47de02206dcede7043213254f01ed0e4b73d1f5d4550ac5fdcb815972b788edd1dc626b901483045022100f8b59f01836c28cbde52114bc8bebf8ece08f45ffe1660266e0dcdc187687bed02200b59ef8ca9b9a4d8d9c937014ac9bf66b7638101c89f10549cb28ee2bd7ce63f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000004313030000000000fd440147304402205cfc98a5c55837d45207a22a7e20b646d0805a4d35e4bd10b2bbf3fff6ec0f1502207df92aa9d79c5eca866ddc95c446c774947a824e0901361dd42073f277212b66014830450221008845063e4b5c6387f1333d76010493b23d79d47f19b227b659daf8c12369e87a02203b7002cdd2ebf3974be41a5c0dd6ed267cad19b2fdd0526260e52a738bba2de4014730440220575a271b955e464d335bb32cece0813fc730be1c98f3b41d70739e9457c8b6d602206dba0e5fb0f0b3465736cfed2bab04e8f7defbb9f11c35cf1601b95fdaaa8829014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000a8f6020000000000fd45014830450221009cb6793416713945a3b6b08e10139d5c58f3ad21ba52f45913bbeb33d8ce1f5d02202e550c9d430adfaa81b4c9f6f27c2de234dfdf3936c5ad8a3beead34a8a62fde01483045022100807dfe6e8df9e514b6850f94c04efae0e927466c88bae4985d1f5a8014a5504302205265e75bb3d7b2ecbed322b35e998d904a2e4f2a44d5906807ed06566dbf14320147304402204a629c423c8ddb65ebfd05dccc9510aa3e8119b02d73e5997d559b7f9ad6a87d022029190b7200278ad005bf2f1a7aed9c864f9733ac3ec5bd7102ab18de6f44cd17014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000a6f5020000000000fd450148304502210094ef0e131bead508301ecf03a7ffa18ec9263bc3666450d2bddcfa752107310002207b8cac555f7a132aa98e41d2feff833fed68752601d0f84031eb870307630a480147304402203dffac6f1e5b22325cf2ff59a98665a827852a36225bb7db58c013022ce037cf0220502c495cfae8edbd53ca9e8b6b9bb4efbd1278966fd9156297959696d445c06f01483045022100f9d9f9b2058abc9aeb02bcebf6f5b22faaa6356ca640550b3c20744cbdee77fb022051c28736be4150081d5aef3e2253a5ce9d3ab9c4578beb398561029be530ebf3014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000003307030000000000fd44014730440220521bdce46b83ae123bcc4f0a008d2bd5cf76e76e0f98f21e029cdb2d0a4f868d02201d3abecb1216d4b41e6c6b23ad87feb8f7ba7735508a4f33d701289f736f366d0147304402203d15fd7c4c578a8acc93a1ec867199efec7f3cd532adf75e9a689af0a2b9399d0220598e77fbdb195843a2699c3464bbb5ccc55e608ec06fb2723c449469766d212c01483045022100e82cc5d9dde9a9086518ec2c18fa867ebb46112e37d65d9f34d88ac741996c95022053e900ac59bb0a391677ea209611b858a89540e59d66056852f8bf23fe5670d6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000007eff020000000000fd4401483045022100d71d8a50ea69c55f7fd08defa76bf1b4da053e3575544b0471c461bf5aef137902207fd9f81b4a551bb7afa8dd1b69a0f6b1f2c4e24aa93c992fa82f82471aa8f72701473044022047ab50ee3683939bfef7410135d6b8de00f9405ca5f2faf22979df74bd4ce974022077f23743ab8ae449862ffd48caf40cbac62fdad49e005b7212852d085e82ee020147304402202e98296f1568f3b1fae805d2d6bc6fccd59bf4c5d6f1565b644d142297d7c40902207abe8a1988115e0ab88180cf90821005e645d97ce360d372f2f329fe2a284f76014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000008604030000000000fd4601483045022100d0befa3dba35057e2ef9b8b6d873dbe983166816ceb84eb875b346ce720a6b33022018d3acee74afd13496e6f1c06e7802d7813ad42a890be8a83280dc06ea23941c01483045022100822d27a60f0e4a8c37acfaadbb0be6d49c0981613610fa63c1f162d24e79e4500220316448804078b2df0d126fb9ec97dc1584ca84567332aa3dc2acab6f573856b0014830450221008fd2b5a6421611baaa3deb3739720dfec37f5cf95f93aff572dd92dca8925fa202205d2b99181fc69d7a46c7c58367a3927b1f6fdcf136142cf85f250837fe643454014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000180c030000000000fd44014830450221009c3ccf4b91b6e425a70216bafbcd277682da8bdbdff336b6f58cb97dfc3204cb022058f650ea3ad9d26b2c66f17cacdd10bee5446caa1ee34145061c227a56620225014730440220092afde83e1995e9964b85224dfc4a3782df00a0f982eb4ad3b38d083428149b02207669684a16f7af5563fe061874c80d9e35e745abbaf7396c7f71267f50fe52010147304402202858c626b1245cdfceefa6440e0c0ca838c10d6114098fca6df76559577de29302203fac70696457e9bfec335fa3a892ec3a2161a34c5bdec4a375d63f76a8d51fbe014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000066f4020000000000fd440147304402202397ebef3e1c8008050009f306560d15c5395fa07fae571fb55910749c3fb321022044acc8eab9dc7e1a9b4ab2cb167d0f944398a0b5e2c4d6e007f6f64779ab011301483045022100f4da2295f9558216c77cd9a0c56e0afc84e3ff1e6ec6b286ea5d7ab5a9f0b4b9022047d7353598ee12ea23234fa4fcdc05d7f9930f276cf4ecee76d128fe148596700147304402205216b5502fa0f62c6d5c9844f7b29ada8cda0fdce7d4dbacf8466adffb0eb6680220735d293adb02fb781f1cc02f9d1ef5a64c9436a95b4fc111dc0d69525ebadb03014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000004e09030000000000fd4501483045022100972f0d3af3ad98263fb8f500d6dc9bc75a589148b712ac0c7f95c78feb5a516102207316e12601bfb099b54075e67563a09df9e023094411ad19cbb5850a3778f067014830450221008ef3b3fc80b147b0ec47663d8756ee4d59e6ebbfd53a6d8629d1f30e9d17b70c02206583b2dd5b4f25d219e05da7fc34203ef667e0d49530e6211827f9f3041d3092014730440220088d12eb6a4424bb67b1aa85b8854cec0a959a62ee26e825a64bdc69c5e1219602206912f9adc20c5fe9f46ec852a6f433f276d1480f6a495a7984cf676a925a4f02014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000d80b030000000000fd4401473044022061236f509bf2232223af7219d64a2064dc4c12de828d46a1313b8f97b8a1b73b022043e93a6c2884668dc499ef67e370a6d736318ad39708183d2a702945a53e7cb2014830450221008e6deec7ff876824ee0f5a61f874eb5c303edd2717f5ca866afac208d591cb1502202fef21def83459e46dcb60387fa6ecac65adaf2ebec8d1c4bad92d1b0a928dda014730440220298c9412d02c1c39acfcb9dffa66cb5745904dae9d5f619b29d909cb9d6538ea02201dd6ca43c5fbe2038b6c347ce4e6a35e6d3e6f9703647661f0aa941cfd6136bc014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000b70c030000000000fd4501483045022100ed44d291e5e7c67d7817a0c1efead142048af4b2925df521f5ee011a6bbb797c0220268bc28e0b7f3cefd25b765801d25bc6de760361d5efc4ff4cc37721f191770c0147304402203425355cf89de0872aac696e9a54e1eb47d71b67a878b4291e505f5358b4c8f102205b7bf0aecb2c022fb93d72512fe820b1f9c0f396a80a75dbc72517d41006e12001483045022100b73867e6de73cf880d7eaa7a70f74685284ea52f3fae71eca4e8905d88367248022033f60a882ec544e5607201602229ddc7508c39ec25de2ee9e18e0bffc8f1130f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000dcfe020000000000fd4501483045022100e565de2989fb12d59dceb8717fa7efe1d430031701a178e93a860b6e7c593b5302207a2c8ee53cc8deceb79e959fdbe72f7fc30e97e51652ee6043687a9f68e24eee01473044022035da650da8f643511b343b3314aab45635f5c7a70d09a34eccf208ee8c0285a602206d3125eeb0ba309c14dbac2a67fc807f8e805d210e8b4d36966ca67e80e8c5a001483045022100d2336814da44438d4e6792dec2ed9017ffe295dff7877a326eda47e76bfa587302200e5ddfdf57537fb32b0ff333744c4a426488b8199923de93691e138e7a00928a014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000ca0e030000000000fd440148304502210085f57e21fb1cd388db4e5c62353dc7f520eab422f3d7ef8624552d1385199ce502206565aa1221fc512ae6236bafc08cb8157d774e1d499ebbbe712c10032f5aaf1601473044022047a029d05cfc8da77b76625abb93ee65fa4ffd23672a7d0348e45c145cba13050220740e4bb703957e56da185bfcaece5e4d3cc602271201dadb2d5afb5475c96283014730440220573c5fd3b203915a057765b361f08082e2d891e57bcd010ecaf6e8d307358b54022018848d5a770f33d667e792853f454359d1bf1c1c846dd00ee3cb3296602dd5b8014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000000bf8020000000000fd450147304402203b89df3d311981d4918681f0ee17a629ea632592342085cf1c1794f75626b7d00220141f2bb0d18b5f07d5549d279437c82319ba23b5e23d8b37ee217150331fe05f01483045022100a5b0d516a0457646836b850c195c8389b2747abbf747a557e96059190ad1e38302202ab7e8d5001290350544299dc3556e9abb9da2e8f91dd2ce3b00fa0c718cdec601483045022100f7f5b03dd0f3d6a7edf18847427ac60fb49cb626b074cae1ea95f233960a0729022000aff8e788a856b194effca3a08594ce28d97138143f0b205556886b4a098fec014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000008705030000000000fd4501483045022100c9728ad82c64ab5d548752adf590654a58eb4bfaba85f1f504b57708abc3eb5902204c36886103e1aa4da4c96bb52182710806b25b9b18310d4b9eb574027eddb3100147304402205017577d2e107371b7c8bd17bc15e128e4e1186cef93ed260d6f54947e94382602200ef247802da72844a33163e6d12136027538c6855ff5761aa5ffc65fda7c810a01483045022100b56e938da3ea2ae0248afa7f6be5e8f7ddb81cd3c82e16a41919864482c28ca102202eeb3e20e95448e46c340736d980fc1b75d860264edb814f01e0e430521f51d4014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000004203030000000000fd4501473044022032a1358398cad98c16a8829ffc75fc7b44f77b93d5627dc717b66a44b59dff7102207b0472f44654abdfe1a24eda879f28838bd5184dfba238fb1b3d4ed0adba15a7014830450221008cbaf2f1616afd756d773443a52e55acafdf5202c7cecc5d0775d681de0e903902201218f989b0300a0d75672676a20c3136ef671f5a4c52ea34213eed22b3ee382401483045022100bb7ccc2f7822a511aac2104ef57e34a04c37f3e09bcff1bc779df446a0840d020220789dece4f3172564a56b6001dfddfc1b79e41ab6d156a40f020bb5dde18877a6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000054fc020000000000fd4401473044022021c6612e0d9d3a57628d54fdfb7ee9756d41ad3247c8c460c499164b6ced3fb302206cb072bf1b753b8ff407b767160acf074f6f34286f4caf3ab5061fb4c980fd270147304402203b4f06ae4d5314e5dd95341c9668b16bc4a71efa1ea4bda2403d2be25e9baf8e02200f09352867d755d614bdb6af4cf22211c93c420fec4fa6fcdacae32b11d1036a01483045022100efd849b2c87782427ce6241c9cb87c60eb0202c12d1ce5f2306b25e857aa8f8d02202eac2b493b0be06093bd4c35d111fb5bdcf24d5795449ebdcbbf234237ecb837014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000c2f3020000000000fd450147304402202649f1955b9a482cab0eef5bde264adf912f5c9351c5d9c10ebd74a7b41dda4602205675c9cfb36ad8ed29e7d431bb7b362e001e999b52d10939636147d19d8de00a01483045022100cbe00b8a033296b9b9e269388a63fb96c4a8f75085c941fa32b037a5991932cb0220020788969972594ccac489afad39bcad1534628f6a649ad5b34f14e5e9421d8401483045022100b7160b1edb5919751ecf6d18c98cceeac9f5941c1854af8560432b34b77dd74b02207105457d94cc4839df8af02f9abc34302eca1b061666e6516d859ec73d89a748014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000009209030000000000fd4401483045022100a54e526956343cfc84ce3e428c138d40381003386375d4ebf9d246101ff678e402201c80e61034511ae79e486380e3a652af58ad5b489aa15f29ec56fb84864e768f0147304402203bdeb20123223d56f13e68817d4a29c87e690540019813b2cdcb4fecbab7044b0220396a1d6971b69b4ef3e63e8727f093b3d7bface1d677a798b4a2d5ece218e8fb0147304402203ff11e576e45e7254fa5959c93956a97c09bb123e95da708001f2ede5f9ba8c602200f9f36ba15933a54a4758d97b7842776bd9706c6a8fab6a58649b9040824634f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000670a030000000000fd4301473044022029bb920d11e2bf9201d18e7730f3bc5f6553e62bc8314336ae9c8a5859914c1502203bdacff928d4d666507dd2583b9442959c88726a817c67348817cd65e6c3606601473044022077a8ad215d7005f651f3b73a4f5a2e33e98dd2168268e04eb41af2ed6435ce2d02200af0d91cd2880f4158d175e28bce4ddc3fe50ad78b87f969c3662ae242930d980147304402205479fac1941e63c1de3cb25c4760b13f6b62ca59cf7942fb3170fd2d195678f9022040e827f224ea5551a4dad03daaf0ad63ea470b4fceffa8e4bd495e7560f32289014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000fc11030000000000fd440147304402205c09825c601853704b1b0231fbee7591c79b6cbaf30e2e955a0b6a72793b370502203fa13d433613f7e6e63419d5db0ade84cb18d699da64a2138fc086afb6066e8301483045022100eafd46546faf8c4e1152145d0a5c30ef070d5e455b6b3b685e1cb8f47cc2a0030220452568d3b52d7a6f7b1f30f321cb4481aaf8af3d7223d5e3de2d6612fa2c41bc01473044022012fc1168c457070445b883dfbbad6996a9dca5eb006b3755daeee5908918a6bc022063b589fae666c446199742cd78eb1843385660f2a962492476c6cacf3997c9eb014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000a60f030000000000fd4501483045022100872b40bd06e8bcf66cbc8ce478d9ccb62972670682146d19b06e63b919a86da0022071cf9163b60e61078f4a5be7a46cee4978585f7eb27387c0b27ae696c3d79f4701483045022100848eb32ab0284db06df29338a34ec5d63660d8ff8838501acc00694b203a346b02203f67e1f2a8d05894f14e965748ef9391675c263afc356519f3516df5adbc87ff0147304402201a20d9f8b3e236b0807d84a7d7e041d77ee26f002d2b77c695fecca316c01b5e022035edbd8bbd6917b892166fcf4b8202b93609e04440ef7b6d850c12409cb3c1e5014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000008409030000000000fd4401473044022009153c7b1bfdfe8ac504213c3ba3321ede43e2dc89261d803601ed6e87cace55022051969259b11cacb80d06ca68563ebdbf8a6e85fa88e9c14afc5797dc82f0fdca01483045022100951209e2d941dd5ba148ef2a0d4a0eaf09c9e0c22051719cb5f3a762517964ab02204acdcfddb8b8aa6a1f61b5126dfb607a472b22d5f731e1318f2405732fc54e750147304402200cd5be575d4b681975316726c211db5fbbc3037d29acdeb06bb7c72119fce5db0220514ea54faba32014d3422ca09c2ebcd332888370249af76809a9f5e4c380dfe6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000e600030000000000fd45014830450221008d99ed1beda44a35e04ed4b6a20a9335c29d6fa974011c06f7a4467420b7ea39022041faf1da827bf32bc43e56a3de62512491209b1175c8779afe3e07731db7620001483045022100f38d3d3adec74d05204c0c9f0b79521abdc57f23d9599a0423d0227294a0ae3e02204ffe4c18ccf208ce95ade49bb78cfdd86aded1071e1fcede37e19252ee0b7882014730440220477a3fa0d716f8ca73d0f5cd55508231dc05d90d14ee670527f30c7f68406e4302201ee6504b744a53375afb2e84fab902ff8d299d6d897bed9db8dcbd85fd890bad014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000ed13030000000000fd4301473044022075d9d2d1d73ff65f1c3cb5fc705aa3f117b866901a527607c81807408fc924180220062031fca37eed36da2f119ad7f5018f8fdd6ca01f42c4bfebbe8550c17e8d690147304402202897a5b6ecb4426de79bc5be348c4b359c7a9adfec0c152345538bfd5279a3e8022053992fd5f382089e1f41e0c47a1ecc11cdd604dfc46210e6053b7f690e7ec0bb01473044022031a31eeaac96cce93cd3a5fe3d75e7faf99f17a5bba04a6a8387057815663ced0220266867c47ad462ab2e5a794b5db1325e0dd75588aa45e10dfb9c219918eb7af3014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae \ No newline at end of file -- 2.45.2 From 47806df63d2eba938fd1c27ff55b69ed7651daf4 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 23:45:31 -0800 Subject: [PATCH 002/459] txscript: Add benchmark for CalcWitnessSigHash --- txscript/bench_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index b129b803..037ce531 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -50,3 +50,23 @@ func BenchmarkCalcSigHash(b *testing.B) { } } } + +// BenchmarkCalcWitnessSigHash benchmarks how long it takes to calculate the +// witness signature hashes for all inputs of a transaction with many inputs. +func BenchmarkCalcWitnessSigHash(b *testing.B) { + sigHashes := NewTxSigHashes(&manyInputsBenchTx) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + for j := 0; j < len(manyInputsBenchTx.TxIn); j++ { + _, err := CalcWitnessSigHash( + prevOutScript, sigHashes, SigHashAll, + &manyInputsBenchTx, j, 5, + ) + if err != nil { + b.Fatalf("failed to calc signature hash: %v", err) + } + } + } +} -- 2.45.2 From bcb9643d39d86d21ce7bf0ac11464663b22df931 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:02 -0500 Subject: [PATCH 003/459] txscript: Add benchmark for script parsing. --- txscript/bench_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 037ce531..51f9aeab 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -70,3 +70,43 @@ func BenchmarkCalcWitnessSigHash(b *testing.B) { } } } + +// genComplexScript returns a script comprised of half as many opcodes as the +// maximum allowed followed by as many max size data pushes fit without +// exceeding the max allowed script size. +func genComplexScript() ([]byte, error) { + var scriptLen int + builder := NewScriptBuilder() + for i := 0; i < MaxOpsPerScript/2; i++ { + builder.AddOp(OP_TRUE) + scriptLen++ + } + maxData := bytes.Repeat([]byte{0x02}, MaxScriptElementSize) + for i := 0; i < (MaxScriptSize-scriptLen)/(MaxScriptElementSize+3); i++ { + builder.AddData(maxData) + } + return builder.Script() +} + +// BenchmarkScriptParsing benchmarks how long it takes to parse a very large +// script. +func BenchmarkScriptParsing(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + pops, err := parseScript(script) + if err != nil { + b.Fatalf("failed to parse script: %v", err) + } + + for _, pop := range pops { + _ = pop.opcode + _ = pop.data + } + } +} -- 2.45.2 From c997417978f04881cb0cce570fd9c2cb6d74ed27 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:03 -0500 Subject: [PATCH 004/459] txscript: Introduce zero-alloc script tokenizer. This implements an efficient and zero-allocation script tokenizer that is exported to both provide a new capability to tokenize scripts to external consumers of the API as well as to serve as a base for refactoring the existing highly inefficient internal code. It is important to note that this tokenizer is intended to be used in consensus critical code in the future, so it must exactly follow the existing semantics. The current script parsing mechanism used throughout the txscript module is to fully tokenize the scripts into an array of internal parsed opcodes which are then examined and passed around in order to implement virtually everything related to scripts. While that approach does simplify the analysis of certain scripts and thus provide some nice properties in that regard, it is both extremely inefficient in many cases, and makes it impossible for external consumers of the API to implement any form of custom script analysis without manually implementing a bunch of error prone tokenizing code or, alternatively, the script engine exposing internal structures. For example, as shown by profiling the total memory allocations of an initial sync, the existing script parsing code allocates a total of around 295.12GB, which equates to around 50% of all allocations performed. The zero-alloc tokenizer this introduces will allow that to be reduced to virtually zero. The following is a before and after comparison of tokenizing a large script with a high opcode count using the existing code versus the tokenizer this introduces for both speed and memory allocations: benchmark old ns/op new ns/op delta BenchmarkScriptParsing-8 63464 677 -98.93% benchmark old allocs new allocs delta BenchmarkScriptParsing-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkScriptParsing-8 311299 0 -100.00% The following is an overview of the changes: - Introduce new error code ErrUnsupportedScriptVersion - Implement zero-allocation script tokenizer - Add a full suite of tests to ensure the tokenizer works as intended and follows the required consensus semantics - Add an example of using the new tokenizer to count the number of opcodes in a script - Update README.md to include the new example - Update script parsing benchmark to use the new tokenizer --- txscript/README.md | 4 + txscript/bench_test.go | 15 ++- txscript/error.go | 6 + txscript/error_test.go | 2 + txscript/example_test.go | 32 +++++ txscript/tokenizer.go | 186 ++++++++++++++++++++++++++ txscript/tokenizer_test.go | 259 +++++++++++++++++++++++++++++++++++++ 7 files changed, 497 insertions(+), 7 deletions(-) create mode 100644 txscript/tokenizer.go create mode 100644 txscript/tokenizer_test.go diff --git a/txscript/README.md b/txscript/README.md index 004c586d..f0abb518 100644 --- a/txscript/README.md +++ b/txscript/README.md @@ -37,6 +37,10 @@ $ go get -u github.com/btcsuite/btcd/txscript * [Manually Signing a Transaction Output](https://pkg.go.dev/github.com/btcsuite/btcd/txscript#example-SignTxOutput) Demonstrates manually creating and signing a redeem transaction. +* [Counting Opcodes in Scripts](http://godoc.org/github.com/decred/dcrd/txscript#example-ScriptTokenizer) + Demonstrates creating a script tokenizer instance and using it to count the + number of opcodes a script contains. + ## GPG Verification Key All official release tags are signed by Conformal so users can ensure the code diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 51f9aeab..673d1cc3 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -96,17 +96,18 @@ func BenchmarkScriptParsing(b *testing.B) { b.Fatalf("failed to create benchmark script: %v", err) } + const scriptVersion = 0 b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { - pops, err := parseScript(script) - if err != nil { - b.Fatalf("failed to parse script: %v", err) + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + _ = tokenizer.Opcode() + _ = tokenizer.Data() + _ = tokenizer.ByteIndex() } - - for _, pop := range pops { - _ = pop.opcode - _ = pop.data + if err := tokenizer.Err(); err != nil { + b.Fatalf("failed to parse script: %v", err) } } } diff --git a/txscript/error.go b/txscript/error.go index a61d0272..f42b893e 100644 --- a/txscript/error.go +++ b/txscript/error.go @@ -1,4 +1,5 @@ // Copyright (c) 2013-2017 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -47,6 +48,10 @@ const ( // the provided data exceeds MaxDataCarrierSize. ErrTooMuchNullData + // ErrUnsupportedScriptVersion is returned when an unsupported script + // version is passed to a function which deals with script analysis. + ErrUnsupportedScriptVersion + // ------------------------------------------ // Failures related to final execution state. // ------------------------------------------ @@ -352,6 +357,7 @@ var errorCodeStrings = map[ErrorCode]string{ ErrNotMultisigScript: "ErrNotMultisigScript", ErrTooManyRequiredSigs: "ErrTooManyRequiredSigs", ErrTooMuchNullData: "ErrTooMuchNullData", + ErrUnsupportedScriptVersion: "ErrUnsupportedScriptVersion", ErrEarlyReturn: "ErrEarlyReturn", ErrEmptyStack: "ErrEmptyStack", ErrEvalFalse: "ErrEvalFalse", diff --git a/txscript/error_test.go b/txscript/error_test.go index ebac85fd..abfa1565 100644 --- a/txscript/error_test.go +++ b/txscript/error_test.go @@ -1,4 +1,5 @@ // Copyright (c) 2017 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -22,6 +23,7 @@ func TestErrorCodeStringer(t *testing.T) { {ErrUnsupportedAddress, "ErrUnsupportedAddress"}, {ErrTooManyRequiredSigs, "ErrTooManyRequiredSigs"}, {ErrTooMuchNullData, "ErrTooMuchNullData"}, + {ErrUnsupportedScriptVersion, "ErrUnsupportedScriptVersion"}, {ErrNotMultisigScript, "ErrNotMultisigScript"}, {ErrEarlyReturn, "ErrEarlyReturn"}, {ErrEmptyStack, "ErrEmptyStack"}, diff --git a/txscript/example_test.go b/txscript/example_test.go index 7bf2b3f0..6e17341c 100644 --- a/txscript/example_test.go +++ b/txscript/example_test.go @@ -1,4 +1,5 @@ // Copyright (c) 2014-2016 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -180,3 +181,34 @@ func ExampleSignTxOutput() { // Output: // Transaction successfully signed } + +// This example demonstrates creating a script tokenizer instance and using it +// to count the number of opcodes a script contains. +func ExampleScriptTokenizer() { + // Create a script to use in the example. Ordinarily this would come from + // some other source. + hash160 := btcutil.Hash160([]byte("example")) + script, err := txscript.NewScriptBuilder().AddOp(txscript.OP_DUP). + AddOp(txscript.OP_HASH160).AddData(hash160). + AddOp(txscript.OP_EQUALVERIFY).AddOp(txscript.OP_CHECKSIG).Script() + if err != nil { + fmt.Printf("failed to build script: %v\n", err) + return + } + + // Create a tokenizer to iterate the script and count the number of opcodes. + const scriptVersion = 0 + var numOpcodes int + tokenizer := txscript.MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + numOpcodes++ + } + if tokenizer.Err() != nil { + fmt.Printf("script failed to parse: %v\n", err) + } else { + fmt.Printf("script contains %d opcode(s)\n", numOpcodes) + } + + // Output: + // script contains 5 opcode(s) +} diff --git a/txscript/tokenizer.go b/txscript/tokenizer.go new file mode 100644 index 00000000..72e00f07 --- /dev/null +++ b/txscript/tokenizer.go @@ -0,0 +1,186 @@ +// Copyright (c) 2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package txscript + +import ( + "encoding/binary" + "fmt" +) + +// opcodeArrayRef is used to break initialization cycles. +var opcodeArrayRef *[256]opcode + +func init() { + opcodeArrayRef = &opcodeArray +} + +// ScriptTokenizer provides a facility for easily and efficiently tokenizing +// transaction scripts without creating allocations. Each successive opcode is +// parsed with the Next function, which returns false when iteration is +// complete, either due to successfully tokenizing the entire script or +// encountering a parse error. In the case of failure, the Err function may be +// used to obtain the specific parse error. +// +// Upon successfully parsing an opcode, the opcode and data associated with it +// may be obtained via the Opcode and Data functions, respectively. +// +// The ByteIndex function may be used to obtain the tokenizer's current offset +// into the raw script. +type ScriptTokenizer struct { + script []byte + version uint16 + offset int32 + op *opcode + data []byte + err error +} + +// Done returns true when either all opcodes have been exhausted or a parse +// failure was encountered and therefore the state has an associated error. +func (t *ScriptTokenizer) Done() bool { + return t.err != nil || t.offset >= int32(len(t.script)) +} + +// Next attempts to parse the next opcode and returns whether or not it was +// successful. It will not be successful if invoked when already at the end of +// the script, a parse failure is encountered, or an associated error already +// exists due to a previous parse failure. +// +// In the case of a true return, the parsed opcode and data can be obtained with +// the associated functions and the offset into the script will either point to +// the next opcode or the end of the script if the final opcode was parsed. +// +// In the case of a false return, the parsed opcode and data will be the last +// successfully parsed values (if any) and the offset into the script will +// either point to the failing opcode or the end of the script if the function +// was invoked when already at the end of the script. +// +// Invoking this function when already at the end of the script is not +// considered an error and will simply return false. +func (t *ScriptTokenizer) Next() bool { + if t.Done() { + return false + } + + op := &opcodeArrayRef[t.script[t.offset]] + switch { + // No additional data. Note that some of the opcodes, notably OP_1NEGATE, + // OP_0, and OP_[1-16] represent the data themselves. + case op.length == 1: + t.offset++ + t.op = op + t.data = nil + return true + + // Data pushes of specific lengths -- OP_DATA_[1-75]. + case op.length > 1: + script := t.script[t.offset:] + if len(script) < op.length { + str := fmt.Sprintf("opcode %s requires %d bytes, but script only "+ + "has %d remaining", op.name, op.length, len(script)) + t.err = scriptError(ErrMalformedPush, str) + return false + } + + // Move the offset forward and set the opcode and data accordingly. + t.offset += int32(op.length) + t.op = op + t.data = script[1:op.length] + return true + + // Data pushes with parsed lengths -- OP_PUSHDATA{1,2,4}. + case op.length < 0: + script := t.script[t.offset+1:] + if len(script) < -op.length { + str := fmt.Sprintf("opcode %s requires %d bytes, but script only "+ + "has %d remaining", op.name, -op.length, len(script)) + t.err = scriptError(ErrMalformedPush, str) + return false + } + + // Next -length bytes are little endian length of data. + var dataLen int32 + switch op.length { + case -1: + dataLen = int32(script[0]) + case -2: + dataLen = int32(binary.LittleEndian.Uint16(script[:2])) + case -4: + dataLen = int32(binary.LittleEndian.Uint32(script[:4])) + default: + // In practice it should be impossible to hit this + // check as each op code is predefined, and only uses + // the specified lengths. + str := fmt.Sprintf("invalid opcode length %d", op.length) + t.err = scriptError(ErrMalformedPush, str) + return false + } + + // Move to the beginning of the data. + script = script[-op.length:] + + // Disallow entries that do not fit script or were sign extended. + if dataLen > int32(len(script)) || dataLen < 0 { + str := fmt.Sprintf("opcode %s pushes %d bytes, but script only "+ + "has %d remaining", op.name, dataLen, len(script)) + t.err = scriptError(ErrMalformedPush, str) + return false + } + + // Move the offset forward and set the opcode and data accordingly. + t.offset += 1 + int32(-op.length) + dataLen + t.op = op + t.data = script[:dataLen] + return true + } + + // The only remaining case is an opcode with length zero which is + // impossible. + panic("unreachable") +} + +// Script returns the full script associated with the tokenizer. +func (t *ScriptTokenizer) Script() []byte { + return t.script +} + +// ByteIndex returns the current offset into the full script that will be parsed +// next and therefore also implies everything before it has already been parsed. +func (t *ScriptTokenizer) ByteIndex() int32 { + return t.offset +} + +// Opcode returns the current opcode associated with the tokenizer. +func (t *ScriptTokenizer) Opcode() byte { + return t.op.value +} + +// Data returns the data associated with the most recently successfully parsed +// opcode. +func (t *ScriptTokenizer) Data() []byte { + return t.data +} + +// Err returns any errors currently associated with the tokenizer. This will +// only be non-nil in the case a parsing error was encountered. +func (t *ScriptTokenizer) Err() error { + return t.err +} + +// MakeScriptTokenizer returns a new instance of a script tokenizer. Passing +// an unsupported script version will result in the returned tokenizer +// immediately having an err set accordingly. +// +// See the docs for ScriptTokenizer for more details. +func MakeScriptTokenizer(scriptVersion uint16, script []byte) ScriptTokenizer { + // Only version 0 scripts are currently supported. + var err error + if scriptVersion != 0 { + str := fmt.Sprintf("script version %d is not supported", scriptVersion) + err = scriptError(ErrUnsupportedScriptVersion, str) + + } + return ScriptTokenizer{version: scriptVersion, script: script, err: err} +} diff --git a/txscript/tokenizer_test.go b/txscript/tokenizer_test.go new file mode 100644 index 00000000..fd008bfc --- /dev/null +++ b/txscript/tokenizer_test.go @@ -0,0 +1,259 @@ +// Copyright (c) 2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package txscript + +import ( + "bytes" + "fmt" + "testing" +) + +// TestScriptTokenizer ensures a wide variety of behavior provided by the script +// tokenizer performs as expected. +func TestScriptTokenizer(t *testing.T) { + t.Skip() + + type expectedResult struct { + op byte // expected parsed opcode + data []byte // expected parsed data + index int32 // expected index into raw script after parsing token + } + + type tokenizerTest struct { + name string // test description + script []byte // the script to tokenize + expected []expectedResult // the expected info after parsing each token + finalIdx int32 // the expected final byte index + err error // expected error + } + + // Add both positive and negative tests for OP_DATA_1 through OP_DATA_75. + const numTestsHint = 100 // Make prealloc linter happy. + tests := make([]tokenizerTest, 0, numTestsHint) + for op := byte(OP_DATA_1); op < OP_DATA_75; op++ { + data := bytes.Repeat([]byte{0x01}, int(op)) + tests = append(tests, tokenizerTest{ + name: fmt.Sprintf("OP_DATA_%d", op), + script: append([]byte{op}, data...), + expected: []expectedResult{{op, data, 1 + int32(op)}}, + finalIdx: 1 + int32(op), + err: nil, + }) + + // Create test that provides one less byte than the data push requires. + tests = append(tests, tokenizerTest{ + name: fmt.Sprintf("short OP_DATA_%d", op), + script: append([]byte{op}, data[1:]...), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }) + } + + // Add both positive and negative tests for OP_PUSHDATA{1,2,4}. + data := mustParseShortForm("0x01{76}") + tests = append(tests, []tokenizerTest{{ + name: "OP_PUSHDATA1", + script: mustParseShortForm("OP_PUSHDATA1 0x4c 0x01{76}"), + expected: []expectedResult{{OP_PUSHDATA1, data, 2 + int32(len(data))}}, + finalIdx: 2 + int32(len(data)), + err: nil, + }, { + name: "OP_PUSHDATA1 no data length", + script: mustParseShortForm("OP_PUSHDATA1"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA1 short data by 1 byte", + script: mustParseShortForm("OP_PUSHDATA1 0x4c 0x01{75}"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA2", + script: mustParseShortForm("OP_PUSHDATA2 0x4c00 0x01{76}"), + expected: []expectedResult{{OP_PUSHDATA2, data, 3 + int32(len(data))}}, + finalIdx: 3 + int32(len(data)), + err: nil, + }, { + name: "OP_PUSHDATA2 no data length", + script: mustParseShortForm("OP_PUSHDATA2"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA2 short data by 1 byte", + script: mustParseShortForm("OP_PUSHDATA2 0x4c00 0x01{75}"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA4", + script: mustParseShortForm("OP_PUSHDATA4 0x4c000000 0x01{76}"), + expected: []expectedResult{{OP_PUSHDATA4, data, 5 + int32(len(data))}}, + finalIdx: 5 + int32(len(data)), + err: nil, + }, { + name: "OP_PUSHDATA4 no data length", + script: mustParseShortForm("OP_PUSHDATA4"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA4 short data by 1 byte", + script: mustParseShortForm("OP_PUSHDATA4 0x4c000000 0x01{75}"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }}...) + + // Add tests for OP_0, and OP_1 through OP_16 (small integers/true/false). + opcodes := []byte{OP_0} + for op := byte(OP_1); op < OP_16; op++ { + opcodes = append(opcodes, op) + } + for _, op := range opcodes { + tests = append(tests, tokenizerTest{ + name: fmt.Sprintf("OP_%d", op), + script: []byte{op}, + expected: []expectedResult{{op, nil, 1}}, + finalIdx: 1, + err: nil, + }) + } + + // Add various positive and negative tests for multi-opcode scripts. + tests = append(tests, []tokenizerTest{{ + name: "pay-to-pubkey-hash", + script: mustParseShortForm("DUP HASH160 DATA_20 0x01{20} EQUAL CHECKSIG"), + expected: []expectedResult{ + {OP_DUP, nil, 1}, {OP_HASH160, nil, 2}, + {OP_DATA_20, mustParseShortForm("0x01{20}"), 23}, + {OP_EQUAL, nil, 24}, {OP_CHECKSIG, nil, 25}, + }, + finalIdx: 25, + err: nil, + }, { + name: "almost pay-to-pubkey-hash (short data)", + script: mustParseShortForm("DUP HASH160 DATA_20 0x01{17} EQUAL CHECKSIG"), + expected: []expectedResult{ + {OP_DUP, nil, 1}, {OP_HASH160, nil, 2}, + }, + finalIdx: 2, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "almost pay-to-pubkey-hash (overlapped data)", + script: mustParseShortForm("DUP HASH160 DATA_20 0x01{19} EQUAL CHECKSIG"), + expected: []expectedResult{ + {OP_DUP, nil, 1}, {OP_HASH160, nil, 2}, + {OP_DATA_20, mustParseShortForm("0x01{19} EQUAL"), 23}, + {OP_CHECKSIG, nil, 24}, + }, + finalIdx: 24, + err: nil, + }, { + name: "pay-to-script-hash", + script: mustParseShortForm("HASH160 DATA_20 0x01{20} EQUAL"), + expected: []expectedResult{ + {OP_HASH160, nil, 1}, + {OP_DATA_20, mustParseShortForm("0x01{20}"), 22}, + {OP_EQUAL, nil, 23}, + }, + finalIdx: 23, + err: nil, + }, { + name: "almost pay-to-script-hash (short data)", + script: mustParseShortForm("HASH160 DATA_20 0x01{18} EQUAL"), + expected: []expectedResult{ + {OP_HASH160, nil, 1}, + }, + finalIdx: 1, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "almost pay-to-script-hash (overlapped data)", + script: mustParseShortForm("HASH160 DATA_20 0x01{19} EQUAL"), + expected: []expectedResult{ + {OP_HASH160, nil, 1}, + {OP_DATA_20, mustParseShortForm("0x01{19} EQUAL"), 22}, + }, + finalIdx: 22, + err: nil, + }}...) + + const scriptVersion = 0 + for _, test := range tests { + tokenizer := MakeScriptTokenizer(scriptVersion, test.script) + var opcodeNum int + for tokenizer.Next() { + // Ensure Next never returns true when there is an error set. + if err := tokenizer.Err(); err != nil { + t.Fatalf("%q: Next returned true when tokenizer has err: %v", + test.name, err) + } + + // Ensure the test data expects a token to be parsed. + op := tokenizer.Opcode() + data := tokenizer.Data() + if opcodeNum >= len(test.expected) { + t.Fatalf("%q: unexpected token '%d' (data: '%x')", test.name, + op, data) + } + expected := &test.expected[opcodeNum] + + // Ensure the opcode and data are the expected values. + if op != expected.op { + t.Fatalf("%q: unexpected opcode -- got %v, want %v", test.name, + op, expected.op) + } + if !bytes.Equal(data, expected.data) { + t.Fatalf("%q: unexpected data -- got %x, want %x", test.name, + data, expected.data) + } + + tokenizerIdx := tokenizer.ByteIndex() + if tokenizerIdx != expected.index { + t.Fatalf("%q: unexpected byte index -- got %d, want %d", + test.name, tokenizerIdx, expected.index) + } + + opcodeNum++ + } + + // Ensure the tokenizer claims it is done. This should be the case + // regardless of whether or not there was a parse error. + if !tokenizer.Done() { + t.Fatalf("%q: tokenizer claims it is not done", test.name) + } + + // Ensure the error is as expected. + if test.err == nil && tokenizer.Err() != nil { + t.Fatalf("%q: unexpected tokenizer err -- got %v, want nil", + test.name, tokenizer.Err()) + } else if test.err != nil { + if !IsErrorCode(tokenizer.Err(), test.err.(Error).ErrorCode) { + t.Fatalf("%q: unexpected tokenizer err -- got %v, want %v", + test.name, tokenizer.Err(), test.err.(Error).ErrorCode) + } + } + + // Ensure the final index is the expected value. + tokenizerIdx := tokenizer.ByteIndex() + if tokenizerIdx != test.finalIdx { + t.Fatalf("%q: unexpected final byte index -- got %d, want %d", + test.name, tokenizerIdx, test.finalIdx) + } + } +} + +// TestScriptTokenizerUnsupportedVersion ensures the tokenizer fails immediately +// with an unsupported script version. +func TestScriptTokenizerUnsupportedVersion(t *testing.T) { + const scriptVersion = 65535 + tokenizer := MakeScriptTokenizer(scriptVersion, nil) + if !IsErrorCode(tokenizer.Err(), ErrUnsupportedScriptVersion) { + t.Fatalf("script tokenizer did not error with unsupported version") + } +} -- 2.45.2 From 099784267e52bc6ea11a0012aab56a78e083cb9c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:04 -0500 Subject: [PATCH 005/459] txscript: Add benchmark for DisasmString. --- txscript/bench_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 673d1cc3..3b1ed40d 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -111,3 +111,21 @@ func BenchmarkScriptParsing(b *testing.B) { } } } + +// BenchmarkDisasmString benchmarks how long it takes to disassemble a very +// large script. +func BenchmarkDisasmString(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, err := DisasmString(script) + if err != nil { + b.Fatalf("failed to disasm script: %v", err) + } + } +} -- 2.45.2 From f980c9a28d943e926e2a4241b4e89de3e0a6fca6 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:05 -0500 Subject: [PATCH 006/459] txscript: Optimize script disasm. This converts the DisasmString function to make use of the new zero-allocation script tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. In order to facilitate this, the opcode disassembly functionality is split into a separate function called disasmOpcode that accepts the opcode struct and data independently as opposed to requiring a parsed opcode. The new function also accepts a pointer to a string builder so the disassembly can be more efficiently be built. While here, the comment is modified to explicitly call out the script version semantics. The following is a before and after comparison of a large script: benchmark old ns/op new ns/op delta BenchmarkDisasmString-8 102902 40124 -61.01% benchmark old allocs new allocs delta BenchmarkDisasmString-8 46 51 +10.87% benchmark old bytes new bytes delta BenchmarkDisasmString-8 389324 130552 -66.47% --- txscript/opcode.go | 65 +++++++++++++++++++++++++++++----------------- txscript/script.go | 30 ++++++++++++++------- 2 files changed, 61 insertions(+), 34 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index a878a966..7383f881 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -9,8 +9,10 @@ import ( "crypto/sha1" "crypto/sha256" "encoding/binary" + "encoding/hex" "fmt" "hash" + "strings" "golang.org/x/crypto/ripemd160" @@ -815,45 +817,60 @@ func (pop *parsedOpcode) checkMinimalDataPush() error { return nil } -// print returns a human-readable string representation of the opcode for use -// in script disassembly. -func (pop *parsedOpcode) print(oneline bool) string { - // The reference implementation one-line disassembly replaces opcodes - // which represent values (e.g. OP_0 through OP_16 and OP_1NEGATE) - // with the raw value. However, when not doing a one-line dissassembly, - // we prefer to show the actual opcode names. Thus, only replace the - // opcodes in question when the oneline flag is set. - opcodeName := pop.opcode.name - if oneline { +// disasmOpcode writes a human-readable disassembly of the provided opcode and +// data into the provided buffer. The compact flag indicates the disassembly +// should print a more compact representation of data-carrying and small integer +// opcodes. For example, OP_0 through OP_16 are replaced with the numeric value +// and data pushes are printed as only the hex representation of the data as +// opposed to including the opcode that specifies the amount of data to push as +// well. +func disasmOpcode(buf *strings.Builder, op *opcode, data []byte, compact bool) { + // Replace opcode which represent values (e.g. OP_0 through OP_16 and + // OP_1NEGATE) with the raw value when performing a compact disassembly. + opcodeName := op.name + if compact { if replName, ok := opcodeOnelineRepls[opcodeName]; ok { opcodeName = replName } - // Nothing more to do for non-data push opcodes. - if pop.opcode.length == 1 { - return opcodeName + // Either write the human-readable opcode or the parsed data in hex for + // data-carrying opcodes. + switch { + case op.length == 1: + buf.WriteString(opcodeName) + + default: + buf.WriteString(hex.EncodeToString(data)) } - return fmt.Sprintf("%x", pop.data) + return } - // Nothing more to do for non-data push opcodes. - if pop.opcode.length == 1 { - return opcodeName - } + buf.WriteString(opcodeName) + + switch op.length { + // Only write the opcode name for non-data push opcodes. + case 1: + return // Add length for the OP_PUSHDATA# opcodes. - retString := opcodeName - switch pop.opcode.length { case -1: - retString += fmt.Sprintf(" 0x%02x", len(pop.data)) + buf.WriteString(fmt.Sprintf(" 0x%02x", len(data))) case -2: - retString += fmt.Sprintf(" 0x%04x", len(pop.data)) + buf.WriteString(fmt.Sprintf(" 0x%04x", len(data))) case -4: - retString += fmt.Sprintf(" 0x%08x", len(pop.data)) + buf.WriteString(fmt.Sprintf(" 0x%08x", len(data))) } - return fmt.Sprintf("%s 0x%02x", retString, pop.data) + buf.WriteString(fmt.Sprintf(" 0x%02x", data)) +} + +// print returns a human-readable string representation of the opcode for use +// in script disassembly. +func (pop *parsedOpcode) print(compact bool) string { + var buf strings.Builder + disasmOpcode(&buf, pop.opcode, pop.data, compact) + return buf.String() } // bytes returns any data associated with the opcode encoded as it would be in diff --git a/txscript/script.go b/txscript/script.go index 92a50e37..b7c2ef96 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/binary" "fmt" + "strings" "time" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -275,20 +276,29 @@ func unparseScript(pops []parsedOpcode) ([]byte, error) { // script up to the point the failure occurred along with the string '[error]' // appended. In addition, the reason the script failed to parse is returned // if the caller wants more information about the failure. -func DisasmString(buf []byte) (string, error) { - var disbuf bytes.Buffer - opcodes, err := parseScript(buf) - for _, pop := range opcodes { - disbuf.WriteString(pop.print(true)) +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func DisasmString(script []byte) (string, error) { + const scriptVersion = 0 + + var disbuf strings.Builder + tokenizer := MakeScriptTokenizer(scriptVersion, script) + if tokenizer.Next() { + disasmOpcode(&disbuf, tokenizer.op, tokenizer.Data(), true) + } + for tokenizer.Next() { disbuf.WriteByte(' ') + disasmOpcode(&disbuf, tokenizer.op, tokenizer.Data(), true) } - if disbuf.Len() > 0 { - disbuf.Truncate(disbuf.Len() - 1) - } - if err != nil { + if tokenizer.Err() != nil { + if tokenizer.ByteIndex() != 0 { + disbuf.WriteByte(' ') + } disbuf.WriteString("[error]") } - return disbuf.String(), err + return disbuf.String(), tokenizer.Err() } // removeOpcode will remove any opcode matching ``opcode'' from the opcode -- 2.45.2 From af757d3d0d21468c994401da82816837a9314f62 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 18 Apr 2019 20:11:36 -0700 Subject: [PATCH 007/459] txscript: Introduce raw script sighash calc func. This introduces a new function named calcSignatureHashRaw which accepts the raw script bytes to calculate the script hash versus requiring the parsed opcode only to unparse them later in order to make it more flexible for working with raw scripts. Since there are several places in the rest of the code that currently only have access to the parsed opcodes, this modifies the existing calcSignatureHash to first unparse the script before calling the new function. Backport of decred/dcrd:f306a72a16eaabfb7054a26f9d9f850b87b00279 --- txscript/opcode.go | 10 ++++++++-- txscript/reference_test.go | 7 ++++++- txscript/script.go | 41 ++++++++++++++++++++++++++++---------- txscript/sign.go | 5 ++++- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 7383f881..893bebdf 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -2198,7 +2198,10 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { // to sign itself. subScript = removeOpcodeByData(subScript, fullSigBytes) - hash = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx) + hash, err = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx) + if err != nil { + return err + } } pubKey, err := btcec.ParsePubKey(pkBytes, btcec.S256()) @@ -2467,7 +2470,10 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { return err } } else { - hash = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx) + hash, err = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx) + if err != nil { + return err + } } var valid bool diff --git a/txscript/reference_test.go b/txscript/reference_test.go index 5015960b..6ac9b68f 100644 --- a/txscript/reference_test.go +++ b/txscript/reference_test.go @@ -863,8 +863,13 @@ func TestCalcSignatureHash(t *testing.T) { } hashType := SigHashType(testVecF64ToUint32(test[3].(float64))) - hash := calcSignatureHash(parsedScript, hashType, &tx, + hash, err := calcSignatureHash(parsedScript, hashType, &tx, int(test[2].(float64))) + if err != nil { + t.Errorf("TestCalcSignatureHash failed test #%d: "+ + "Failed to compute sighash: %v", i, err) + continue + } expectedHash, _ := chainhash.NewHashFromStr(test[4].(string)) if !bytes.Equal(hash, expectedHash[:]) { diff --git a/txscript/script.go b/txscript/script.go index b7c2ef96..52bb5b6b 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -572,13 +572,12 @@ func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx if err != nil { return nil, fmt.Errorf("cannot parse output script: %v", err) } - return calcSignatureHash(parsedScript, hashType, tx, idx), nil + return calcSignatureHash(parsedScript, hashType, tx, idx) } -// calcSignatureHash will, given a script and hash type for the current script -// engine instance, calculate the signature hash to be used for signing and -// verification. -func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.MsgTx, idx int) []byte { +// calcSignatureHashRaw computes the signature hash for the specified input of +// the target transaction observing the desired signature hash type. +func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx, idx int) []byte { // The SigHashSingle signature type signs only the corresponding input // and output (the output with the same index number as the input). // @@ -606,17 +605,24 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg } // Remove all instances of OP_CODESEPARATOR from the script. - script = removeOpcode(script, OP_CODESEPARATOR) + filteredScript := make([]byte, 0, len(sigScript)) + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, sigScript) + var prevOffset int32 + for tokenizer.Next() { + if tokenizer.Opcode() != OP_CODESEPARATOR { + filteredScript = append(filteredScript, + sigScript[prevOffset:tokenizer.ByteIndex()]...) + } + prevOffset = tokenizer.ByteIndex() + } // Make a shallow copy of the transaction, zeroing out the script for // all inputs that are not currently being processed. txCopy := shallowCopyTx(tx) for i := range txCopy.TxIn { if i == idx { - // UnparseScript cannot fail here because removeOpcode - // above only returns a valid script. - sigScript, _ := unparseScript(script) - txCopy.TxIn[idx].SignatureScript = sigScript + txCopy.TxIn[idx].SignatureScript = filteredScript } else { txCopy.TxIn[i].SignatureScript = nil } @@ -670,6 +676,21 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg return chainhash.DoubleHashB(wbuf.Bytes()) } +// calcSignatureHash computes the signature hash for the specified input of the +// target transaction observing the desired signature hash type. +// +// DEPRECATED: Use calcSignatureHashRaw instead +func calcSignatureHash(prevOutScript []parsedOpcode, hashType SigHashType, + tx *wire.MsgTx, idx int) ([]byte, error) { + + sigScript, err := unparseScript(prevOutScript) + if err != nil { + return nil, err + } + + return calcSignatureHashRaw(sigScript, hashType, tx, idx), nil +} + // asSmallInt returns the passed opcode, which must be true according to // isSmallInt(), as an integer. func asSmallInt(op *opcode) int { diff --git a/txscript/sign.go b/txscript/sign.go index 42af9686..b9f8b2db 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -345,7 +345,10 @@ sigLoop: // however, assume no sigs etc are in the script since that // would make the transaction nonstandard and thus not // MultiSigTy, so we just need to hash the full thing. - hash := calcSignatureHash(pkPops, hashType, tx, idx) + hash, err := calcSignatureHash(pkPops, hashType, tx, idx) + if err != nil { + panic(fmt.Sprintf("cannot compute sighash: %v", err)) + } for _, addr := range addresses { // All multisig addresses should be pubkey addresses -- 2.45.2 From c19535b1454325ac363070fe1cdbfe2fbd12bdb0 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:07 -0500 Subject: [PATCH 008/459] txscript: Optimize CalcSignatureHash. This modifies the CalcSignatureHash function to make use of the new signature hash calculation function that accepts raw scripts without needing to first parse them. Consequently, it also doubles as a slight optimization to the execution time and a significant reduction in the number of allocations. In order to convert the CalcScriptHash function and keep the same semantics, a new function named checkScriptParses is introduced which will quickly determine if a script can be fully parsed without failure and return the parse failure in the case it can't. The following is a before and after comparison of analyzing a large multiple input transaction: benchmark old ns/op new ns/op delta BenchmarkCalcSigHash-8 3627895 3619477 -0.23% benchmark old allocs new allocs delta BenchmarkCalcSigHash-8 1335 801 -40.00% benchmark old bytes new bytes delta BenchmarkCalcSigHash-8 1373812 1293354 -5.86% --- txscript/script.go | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 52bb5b6b..112c24ac 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -567,12 +567,17 @@ func shallowCopyTx(tx *wire.MsgTx) wire.MsgTx { // CalcSignatureHash will, given a script and hash type for the current script // engine instance, calculate the signature hash to be used for signing and // verification. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx int) ([]byte, error) { - parsedScript, err := parseScript(script) - if err != nil { - return nil, fmt.Errorf("cannot parse output script: %v", err) + const scriptVersion = 0 + if err := checkScriptParses(scriptVersion, script); err != nil { + return nil, err } - return calcSignatureHash(parsedScript, hashType, tx, idx) + + return calcSignatureHashRaw(script, hashType, tx, idx), nil } // calcSignatureHashRaw computes the signature hash for the specified input of @@ -850,6 +855,15 @@ func getWitnessSigOps(pkScript []byte, witness wire.TxWitness) int { return 0 } +// checkScriptParses returns an error if the provided script fails to parse. +func checkScriptParses(scriptVersion uint16, script []byte) error { + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + // Nothing to do. + } + return tokenizer.Err() +} + // IsUnspendable returns whether the passed public key script is unspendable, or // guaranteed to fail at execution. This allows inputs to be pruned instantly // when entering the UTXO set. -- 2.45.2 From c6f4cafe57cac8fb527be53b6418fe96c655265e Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 18 Apr 2019 21:12:34 -0700 Subject: [PATCH 009/459] txscript/reference_test: Convert sighash calc test This converts the tests for calculating signature hashes to use the exported function which handles the raw script versus the now deprecated variant requiring parsed opcodes. Backport of 06f769ef72e6042e7f2b5ff1c512ef1371d615e5 --- txscript/reference_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/txscript/reference_test.go b/txscript/reference_test.go index 6ac9b68f..9d9c8f39 100644 --- a/txscript/reference_test.go +++ b/txscript/reference_test.go @@ -836,6 +836,7 @@ func TestCalcSignatureHash(t *testing.T) { err) } + const scriptVersion = 0 for i, test := range tests { if i == 0 { // Skip first line -- contains comments only. @@ -855,15 +856,14 @@ func TestCalcSignatureHash(t *testing.T) { } subScript, _ := hex.DecodeString(test[1].(string)) - parsedScript, err := parseScript(subScript) - if err != nil { + if err := checkScriptParses(scriptVersion, subScript); err != nil { t.Errorf("TestCalcSignatureHash failed test #%d: "+ "Failed to parse sub-script: %v", i, err) continue } hashType := SigHashType(testVecF64ToUint32(test[3].(float64))) - hash, err := calcSignatureHash(parsedScript, hashType, &tx, + hash, err := CalcSignatureHash(subScript, hashType, &tx, int(test[2].(float64))) if err != nil { t.Errorf("TestCalcSignatureHash failed test #%d: "+ -- 2.45.2 From 583b74040dc92978e9c258b7ea64e3da01f361f2 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:09 -0500 Subject: [PATCH 010/459] txscript: Make isSmallInt accept raw opcode. This converts the isSmallInt function to accept an opcode as a byte instead of the internal opcode data struct in order to make it more flexible for raw script analysis. The comment is modified to explicitly call out the script version semantics. Finally, it updates all callers accordingly. --- txscript/script.go | 14 ++++++++------ txscript/standard.go | 10 +++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 112c24ac..58b8e69f 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -1,4 +1,5 @@ // Copyright (c) 2013-2017 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -45,11 +46,12 @@ const ( // isSmallInt returns whether or not the opcode is considered a small integer, // which is an OP_0, or OP_1 through OP_16. -func isSmallInt(op *opcode) bool { - if op.value == OP_0 || (op.value >= OP_1 && op.value <= OP_16) { - return true - } - return false +// +// NOTE: This function is only valid for version 0 opcodes. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func isSmallInt(op byte) bool { + return op == OP_0 || (op >= OP_1 && op <= OP_16) } // isScriptHash returns true if the script passed is a pay-to-script-hash @@ -136,7 +138,7 @@ func IsWitnessProgram(script []byte) bool { // bytes. func isWitnessProgram(pops []parsedOpcode) bool { return len(pops) == 2 && - isSmallInt(pops[0].opcode) && + isSmallInt(pops[0].opcode.value) && canonicalPush(pops[1]) && (len(pops[1].data) >= 2 && len(pops[1].data) <= 40) } diff --git a/txscript/standard.go b/txscript/standard.go index 2cad218e..a447303d 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -115,10 +115,10 @@ func isMultiSig(pops []parsedOpcode) bool { if l < 4 { return false } - if !isSmallInt(pops[0].opcode) { + if !isSmallInt(pops[0].opcode.value) { return false } - if !isSmallInt(pops[l-2].opcode) { + if !isSmallInt(pops[l-2].opcode.value) { return false } if pops[l-1].opcode.value != OP_CHECKMULTISIG { @@ -153,7 +153,7 @@ func isNullData(pops []parsedOpcode) bool { return l == 2 && pops[0].opcode.value == OP_RETURN && - (isSmallInt(pops[1].opcode) || pops[1].opcode.value <= + (isSmallInt(pops[1].opcode.value) || pops[1].opcode.value <= OP_PUSHDATA4) && len(pops[1].data) <= MaxDataCarrierSize } @@ -705,7 +705,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa return nil, nil } pushes.SecretSize = int64(locktime) - } else if op := pops[2].opcode; isSmallInt(op) { + } else if op := pops[2].opcode; isSmallInt(op.value) { pushes.SecretSize = int64(asSmallInt(op)) } else { return nil, nil @@ -716,7 +716,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa return nil, nil } pushes.LockTime = int64(locktime) - } else if op := pops[11].opcode; isSmallInt(op) { + } else if op := pops[11].opcode; isSmallInt(op.value) { pushes.LockTime = int64(asSmallInt(op)) } else { return nil, nil -- 2.45.2 From dfb1a6797b724873f8d3f785b76f86b9c58a6200 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:11 -0500 Subject: [PATCH 011/459] txscript: Make asSmallInt accept raw opcode. This converts the asSmallInt function to accept an opcode as a byte instead of the internal opcode data struct in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/script.go | 10 +++++----- txscript/standard.go | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 58b8e69f..3dfd82e1 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -159,7 +159,7 @@ func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { "unable to extract version or witness program") } - witnessVersion := asSmallInt(pops[0].opcode) + witnessVersion := asSmallInt(pops[0].opcode.value) witnessProgram := pops[1].data return witnessVersion, witnessProgram, nil @@ -700,12 +700,12 @@ func calcSignatureHash(prevOutScript []parsedOpcode, hashType SigHashType, // asSmallInt returns the passed opcode, which must be true according to // isSmallInt(), as an integer. -func asSmallInt(op *opcode) int { - if op.value == OP_0 { +func asSmallInt(op byte) int { + if op == OP_0 { return 0 } - return int(op.value - (OP_1 - 1)) + return int(op - (OP_1 - 1)) } // getSigOpCount is the implementation function for counting the number of @@ -730,7 +730,7 @@ func getSigOpCount(pops []parsedOpcode, precise bool) int { if precise && i > 0 && pops[i-1].opcode.value >= OP_1 && pops[i-1].opcode.value <= OP_16 { - nSigs += asSmallInt(pops[i-1].opcode) + nSigs += asSmallInt(pops[i-1].opcode.value) } else { nSigs += MaxPubKeysPerMultiSig } diff --git a/txscript/standard.go b/txscript/standard.go index a447303d..94b3cce5 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -127,7 +127,7 @@ func isMultiSig(pops []parsedOpcode) bool { // Verify the number of pubkeys specified matches the actual number // of pubkeys provided. - if l-2-1 != asSmallInt(pops[l-2].opcode) { + if l-2-1 != asSmallInt(pops[l-2].opcode.value) { return false } @@ -238,7 +238,7 @@ func expectedInputs(pops []parsedOpcode, class ScriptClass) int { // the original bitcoind bug where OP_CHECKMULTISIG pops an // additional item from the stack, add an extra expected input // for the extra push that is required to compensate. - return asSmallInt(pops[0].opcode) + 1 + return asSmallInt(pops[0].opcode.value) + 1 case NullDataTy: fallthrough @@ -395,8 +395,8 @@ func CalcMultiSigStats(script []byte) (int, int, error) { return 0, 0, scriptError(ErrNotMultisigScript, str) } - numSigs := asSmallInt(pops[0].opcode) - numPubKeys := asSmallInt(pops[len(pops)-2].opcode) + numSigs := asSmallInt(pops[0].opcode.value) + numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value) return numPubKeys, numSigs, nil } @@ -617,8 +617,8 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script // Therefore the number of required signatures is the 1st item // on the stack and the number of public keys is the 2nd to last // item on the stack. - requiredSigs = asSmallInt(pops[0].opcode) - numPubKeys := asSmallInt(pops[len(pops)-2].opcode) + requiredSigs = asSmallInt(pops[0].opcode.value) + numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value) // Extract the public keys while skipping any that are invalid. addrs = make([]btcutil.Address, 0, numPubKeys) @@ -706,7 +706,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa } pushes.SecretSize = int64(locktime) } else if op := pops[2].opcode; isSmallInt(op.value) { - pushes.SecretSize = int64(asSmallInt(op)) + pushes.SecretSize = int64(asSmallInt(op.value)) } else { return nil, nil } @@ -717,7 +717,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa } pushes.LockTime = int64(locktime) } else if op := pops[11].opcode; isSmallInt(op.value) { - pushes.LockTime = int64(asSmallInt(op)) + pushes.LockTime = int64(asSmallInt(op.value)) } else { return nil, nil } -- 2.45.2 From 05aa488a877faa2fabdac38e024f9f72aa3abe4a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:38 -0500 Subject: [PATCH 012/459] txscript: Add benchmark for IsPayToPubKey --- txscript/bench_test.go | 15 +++++++++++++++ txscript/script.go | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 3b1ed40d..6415c595 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -129,3 +129,18 @@ func BenchmarkDisasmString(b *testing.B) { } } } + +// BenchmarkIsPubKeyScript benchmarks how long it takes to analyze a very large +// script to determine if it is a standard pay-to-pubkey script. +func BenchmarkIsPubKeyScript(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToPubKey(script) + } +} diff --git a/txscript/script.go b/txscript/script.go index 3dfd82e1..c642069c 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -63,6 +63,16 @@ func isScriptHash(pops []parsedOpcode) bool { pops[2].opcode.value == OP_EQUAL } +// IsPayToPubKey returns true if the script is in the standard pay-to-pubkey +// (P2PK) format, false otherwise. +func IsPayToPubKey(script []byte) bool { + pops, err := parseScript(script) + if err != nil { + return false + } + return isPubkey(pops) +} + // IsPayToScriptHash returns true if the script is in the standard // pay-to-script-hash (P2SH) format, false otherwise. func IsPayToScriptHash(script []byte) bool { -- 2.45.2 From 99cb679b6f170003834de4ca326bfcf960bc1629 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:06:56 -0800 Subject: [PATCH 013/459] txscript: Optimize IsPayToPubKey This converts the IsPayToScriptHash function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimizing the function. In order to accomplish this, it introduces four new functions: extractCompressedPubKey, extractUncompressedPubKey, extractPubKey, and isPubKeyScript. The extractPubKey function makes use of extractCompressedPubKey and extractUncompressedPubKey to combine their functionality as a convenience and isPubKeyScript is defined in terms of extractPubKey. The extractCompressedPubKey works with the raw script bytes to simultaneously determine if the script is a pay-to-compressed-pubkey script, and in the case it is, extract and return the raw compressed pubkey bytes. Similarly, the extractUncompressedPubKey works in the same way except it determines if the script is a pay-to-uncompressed-pubkey script and returns the raw uncompressed pubkey bytes in the case it is. The extract function approach was chosen because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result so long as the extraction does not require allocations. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsPubKeyScript-8 62323 2.97 -100.00% benchmark old allocs new allocs delta BenchmarkIsPubKeyScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPubKeyScript-8 311299 0 -100.00% --- txscript/script.go | 6 +---- txscript/standard.go | 58 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index c642069c..00df5216 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -66,11 +66,7 @@ func isScriptHash(pops []parsedOpcode) bool { // IsPayToPubKey returns true if the script is in the standard pay-to-pubkey // (P2PK) format, false otherwise. func IsPayToPubKey(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isPubkey(pops) + return isPubKeyScript(script) } // IsPayToScriptHash returns true if the script is in the standard diff --git a/txscript/standard.go b/txscript/standard.go index 94b3cce5..0a835dbb 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -85,6 +85,64 @@ func (t ScriptClass) String() string { return scriptClassToName[t] } +// extractCompressedPubKey extracts a compressed public key from the passed +// script if it is a standard pay-to-compressed-secp256k1-pubkey script. It +// will return nil otherwise. +func extractCompressedPubKey(script []byte) []byte { + // A pay-to-compressed-pubkey script is of the form: + // OP_DATA_33 <33-byte compressed pubkey> OP_CHECKSIG + + // All compressed secp256k1 public keys must start with 0x02 or 0x03. + if len(script) == 35 && + script[34] == OP_CHECKSIG && + script[0] == OP_DATA_33 && + (script[1] == 0x02 || script[1] == 0x03) { + + return script[1:34] + } + + return nil +} + +// extractUncompressedPubKey extracts an uncompressed public key from the +// passed script if it is a standard pay-to-uncompressed-secp256k1-pubkey +// script. It will return nil otherwise. +func extractUncompressedPubKey(script []byte) []byte { + // A pay-to-uncompressed-pubkey script is of the form: + // OP_DATA_65 <65-byte uncompressed pubkey> OP_CHECKSIG + // + // All non-hybrid uncompressed secp256k1 public keys must start with 0x04. + // Hybrid uncompressed secp256k1 public keys start with 0x06 or 0x07: + // - 0x06 => hybrid format for even Y coords + // - 0x07 => hybrid format for odd Y coords + if len(script) == 67 && + script[66] == OP_CHECKSIG && + script[0] == OP_DATA_65 && + (script[1] == 0x04 || script[1] == 0x06 || script[1] == 0x07) { + + return script[1:66] + } + return nil +} + +// extractPubKey extracts either compressed or uncompressed public key from the +// passed script if it is a either a standard pay-to-compressed-secp256k1-pubkey +// or pay-to-uncompressed-secp256k1-pubkey script, respectively. It will return +// nil otherwise. +func extractPubKey(script []byte) []byte { + if pubKey := extractCompressedPubKey(script); pubKey != nil { + return pubKey + } + return extractUncompressedPubKey(script) +} + +// isPubKeyScript returns whether or not the passed script is either a standard +// pay-to-compressed-secp256k1-pubkey or pay-to-uncompressed-secp256k1-pubkey +// script. +func isPubKeyScript(script []byte) bool { + return extractPubKey(script) != nil +} + // isPubkey returns true if the script passed is a pay-to-pubkey transaction, // false otherwise. func isPubkey(pops []parsedOpcode) bool { -- 2.45.2 From 2d2608c34e293f5d95b132aba67bf1b58de8926f Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:52:11 -0800 Subject: [PATCH 014/459] txscript: Add benchmark for IsPayToPubKeyHash --- txscript/bench_test.go | 15 +++++++++++++++ txscript/script.go | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 6415c595..401b9683 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -144,3 +144,18 @@ func BenchmarkIsPubKeyScript(b *testing.B) { _ = IsPayToPubKey(script) } } + +// BenchmarkIsPubKeyHashScript benchmarks how long it takes to analyze a very +// large script to determine if it is a standard pay-to-pubkey-hash script. +func BenchmarkIsPubKeyHashScript(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToPubKeyHash(script) + } +} diff --git a/txscript/script.go b/txscript/script.go index 00df5216..fb4fc8bc 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -69,6 +69,16 @@ func IsPayToPubKey(script []byte) bool { return isPubKeyScript(script) } +// IsPayToPubKeyHash returns true if the script is in the standard +// pay-to-pubkey-hash (P2PKH) format, false otherwise. +func IsPayToPubKeyHash(script []byte) bool { + pops, err := parseScript(script) + if err != nil { + return false + } + return isPubkeyHash(pops) +} + // IsPayToScriptHash returns true if the script is in the standard // pay-to-script-hash (P2SH) format, false otherwise. func IsPayToScriptHash(script []byte) bool { -- 2.45.2 From c771f4fb386e42a9363b614c58b536504feea0c2 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:09:28 -0800 Subject: [PATCH 015/459] txscript: Optimize IsPayToPubKeyHash This converts the IsPayToPubKeyHash function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimization the function. In order to accomplish this, it introduces two new functions. The first one is named extractPubKeyHash and works with the raw script bytes to simultaneously determine if the script is a pay-to-pubkey-hash script, and in the case it is, extract and return the hash. The second new function is named isPubKeyHashScript and is defined in terms of the former. The extract function approach was chosen because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result so long as the extraction does not require allocations. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsPubKeyHashScript-8 62228 0.45 -100.00% benchmark old allocs new allocs delta BenchmarkIsPubKeyHashScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPubKeyHashScript-8 311299 0 -100.00% --- txscript/script.go | 6 +----- txscript/standard.go | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index fb4fc8bc..b154c110 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -72,11 +72,7 @@ func IsPayToPubKey(script []byte) bool { // IsPayToPubKeyHash returns true if the script is in the standard // pay-to-pubkey-hash (P2PKH) format, false otherwise. func IsPayToPubKeyHash(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isPubkeyHash(pops) + return isPubKeyHashScript(script) } // IsPayToScriptHash returns true if the script is in the standard diff --git a/txscript/standard.go b/txscript/standard.go index 0a835dbb..f7948f79 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -143,6 +143,30 @@ func isPubKeyScript(script []byte) bool { return extractPubKey(script) != nil } +// extractPubKeyHash extracts the public key hash from the passed script if it +// is a standard pay-to-pubkey-hash script. It will return nil otherwise. +func extractPubKeyHash(script []byte) []byte { + // A pay-to-pubkey-hash script is of the form: + // OP_DUP OP_HASH160 <20-byte hash> OP_EQUALVERIFY OP_CHECKSIG + if len(script) == 25 && + script[0] == OP_DUP && + script[1] == OP_HASH160 && + script[2] == OP_DATA_20 && + script[23] == OP_EQUALVERIFY && + script[24] == OP_CHECKSIG { + + return script[3:23] + } + + return nil +} + +// isPubKeyHashScript returns whether or not the passed script is a standard +// pay-to-pubkey-hash script. +func isPubKeyHashScript(script []byte) bool { + return extractPubKeyHash(script) != nil +} + // isPubkey returns true if the script passed is a pay-to-pubkey transaction, // false otherwise. func isPubkey(pops []parsedOpcode) bool { -- 2.45.2 From 665c29802ed3b6034396e4195b2abad8c77d2ab5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:13 -0500 Subject: [PATCH 016/459] txscript: Add benchmark for IsPayToScriptHash. --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 401b9683..e47cf21f 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -159,3 +159,18 @@ func BenchmarkIsPubKeyHashScript(b *testing.B) { _ = IsPayToPubKeyHash(script) } } + +// BenchmarkIsPayToScriptHash benchmarks how long it takes IsPayToScriptHash to +// analyze a very large script. +func BenchmarkIsPayToScriptHash(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToScriptHash(script) + } +} -- 2.45.2 From 215af7ff5427d405d0443aa9b0c4bdb120f55f80 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:14 -0500 Subject: [PATCH 017/459] txscript: Optimize IsPayToScriptHash. This converts the IsPayToScriptHash function to analyze the raw script instead of using the far less efficient parseScript thereby significantly optimizing the function. In order to accomplish this, it introduces two new functions. The first one is named extractScriptHash and works with the raw script bytes to simultaneously determine if the script is a p2sh script, and in the case it is, extract and return the hash. The second new function is named isScriptHashScript and is defined in terms of the former. The extract function approach was chosen because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result so long as the extraction does not require allocations. Finally, this also deprecates the isScriptHash function that requires opcodes in favor of the new functions and modifies the comment on IsPayToScriptHash to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script that is not a p2sh script: benchmark old ns/op new ns/op delta BenchmarkIsPayToScriptHash-8 62393 0.60 -100.00% benchmark old allocs new allocs delta BenchmarkIsPayToScriptHash-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPayToScriptHash-8 311299 0 -100.00% --- txscript/script.go | 14 +++++++++----- txscript/standard.go | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index b154c110..a8cfd166 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -56,6 +56,8 @@ func isSmallInt(op byte) bool { // isScriptHash returns true if the script passed is a pay-to-script-hash // transaction, false otherwise. +// +// DEPRECATED. Use isScriptHashScript or extractScriptHash instead. func isScriptHash(pops []parsedOpcode) bool { return len(pops) == 3 && pops[0].opcode.value == OP_HASH160 && @@ -77,12 +79,14 @@ func IsPayToPubKeyHash(script []byte) bool { // IsPayToScriptHash returns true if the script is in the standard // pay-to-script-hash (P2SH) format, false otherwise. +// +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before determining if the script is a P2SH which means nodes +// on existing rules will analyze new version scripts as if they were version 0. func IsPayToScriptHash(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isScriptHash(pops) + return isScriptHashScript(script) } // isWitnessScriptHash returns true if the passed script is a diff --git a/txscript/standard.go b/txscript/standard.go index f7948f79..a02f8723 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -167,6 +167,32 @@ func isPubKeyHashScript(script []byte) bool { return extractPubKeyHash(script) != nil } +// extractScriptHash extracts the script hash from the passed script if it is a +// standard pay-to-script-hash script. It will return nil otherwise. +// +// NOTE: This function is only valid for version 0 opcodes. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func extractScriptHash(script []byte) []byte { + // A pay-to-script-hash script is of the form: + // OP_HASH160 <20-byte scripthash> OP_EQUAL + if len(script) == 23 && + script[0] == OP_HASH160 && + script[1] == OP_DATA_20 && + script[22] == OP_EQUAL { + + return script[2:22] + } + + return nil +} + +// isScriptHashScript returns whether or not the passed script is a standard +// pay-to-script-hash script. +func isScriptHashScript(script []byte) bool { + return extractScriptHash(script) != nil +} + // isPubkey returns true if the script passed is a pay-to-pubkey transaction, // false otherwise. func isPubkey(pops []parsedOpcode) bool { -- 2.45.2 From 4d31d1599dc351183246aa4e85c9d77b199105f9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:15 -0500 Subject: [PATCH 018/459] txscript: Add benchmarks for IsMutlsigScript. --- txscript/bench_test.go | 45 ++++++++++++++++++++++++++++++++++++++++++ txscript/standard.go | 21 ++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index e47cf21f..49be4958 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -174,3 +174,48 @@ func BenchmarkIsPayToScriptHash(b *testing.B) { _ = IsPayToScriptHash(script) } } + +// BenchmarkIsMultisigScriptLarge benchmarks how long it takes IsMultisigScript +// to analyze a very large script. +func BenchmarkIsMultisigScriptLarge(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + isMultisig, err := IsMultisigScript(script) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + if isMultisig { + b.Fatalf("script should NOT be reported as mutisig script") + } + } +} + +// BenchmarkIsMultisigScript benchmarks how long it takes IsMultisigScript to +// analyze a 1-of-2 multisig public key script. +func BenchmarkIsMultisigScript(b *testing.B) { + multisigShortForm := "1 " + + "DATA_33 " + + "0x030478aaaa2be30772f1e69e581610f1840b3cf2fe7228ee0281cd599e5746f81e " + + "DATA_33 " + + "0x0284f4d078b236a9ff91661f8ffbe012737cd3507566f30fd97d25f2b23539f3cd " + + "2 CHECKMULTISIG" + pkScript := mustParseShortForm(multisigShortForm) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + isMultisig, err := IsMultisigScript(pkScript) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + if !isMultisig { + b.Fatalf("script should be reported as a mutisig script") + } + } +} diff --git a/txscript/standard.go b/txscript/standard.go index a02f8723..25483aeb 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -248,6 +248,27 @@ func isMultiSig(pops []parsedOpcode) bool { return true } +// IsMultisigScript returns whether or not the passed script is a standard +// multisignature script. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +// +// The error is DEPRECATED and will be removed in the major version bump. +func IsMultisigScript(script []byte) (bool, error) { + if len(script) == 0 || script == nil { + return false, nil + } + + pops, err := parseScript(script) + if err != nil { + return false, err + } + + return isMultiSig(pops), nil +} + // isNullData returns true if the passed script is a null data transaction, // false otherwise. func isNullData(pops []parsedOpcode) bool { -- 2.45.2 From 0eaae2663ba9955de61a2c6bf52b008dd40cc7f6 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:16 -0500 Subject: [PATCH 019/459] txscript: Optimize IsMultisigScript. This converts the IsMultisigScript function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. In order to accomplish this, it introduces two new functions. The first one is named extractMultisigScriptDetails and works with the raw script bytes to simultaneously determine if the script is a multisignature script, and in the case it is, extract and return the relevant details. The second new function is named isMultisigScript and is defined in terms of the former. The extract function accepts the script version, raw script bytes, and a flag to determine whether or not the public keys should also be extracted. The flag is provided because extracting pubkeys results in an allocation that the caller might wish to avoid. The extract function approach was chosen because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result so long as the extraction does not require allocations. It is important to note that this new implementation intentionally has a semantic difference from the existing implementation in that it will now correctly identify a multisig script with zero pubkeys whereas previously it incorrectly required at least one pubkey. This change is acceptable because the function only deals with standardness rather than consensus rules. Finally, this also deprecates the isMultiSig function that requires opcodes in favor of the new functions and deprecates the error return on the export IsMultisigScript function since it really does not make sense given the purpose of the function. The following is a before and after comparison of analyzing both a large script that is not a multisig script and a 1-of-2 multisig public key script: benchmark old ns/op new ns/op delta BenchmarkIsMultisigScriptLarge-8 64166 5.52 -99.99% BenchmarkIsMultisigScript-8 630 59.4 -90.57% benchmark old allocs new allocs delta BenchmarkIsMultisigScriptLarge-8 1 0 -100.00% BenchmarkIsMultisigScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsMultisigScriptLarge-8 311299 0 -100.00% BenchmarkIsMultisigScript-8 2304 0 -100.00% --- txscript/engine.go | 21 ++++++++ txscript/standard.go | 116 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 127 insertions(+), 10 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index f2d7b303..3c76b747 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -580,6 +580,27 @@ func (vm *Engine) checkHashTypeEncoding(hashType SigHashType) error { return nil } +// isStrictPubKeyEncoding returns whether or not the passed public key adheres +// to the strict encoding requirements. +func isStrictPubKeyEncoding(pubKey []byte) bool { + if len(pubKey) == 33 && (pubKey[0] == 0x02 || pubKey[0] == 0x03) { + // Compressed + return true + } + if len(pubKey) == 65 { + switch pubKey[0] { + case 0x04: + // Uncompressed + return true + + case 0x06, 0x07: + // Hybrid + return true + } + } + return false +} + // checkPubKeyEncoding returns whether or not the passed public key adheres to // the strict encoding requirements if enabled. func (vm *Engine) checkPubKeyEncoding(pubKey []byte) error { diff --git a/txscript/standard.go b/txscript/standard.go index 25483aeb..096de4e5 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -216,6 +216,8 @@ func isPubkeyHash(pops []parsedOpcode) bool { // isMultiSig returns true if the passed script is a multisig transaction, false // otherwise. +// +// DEPECATED. Use isMultisigScript or extractMultisigScriptDetails instead. func isMultiSig(pops []parsedOpcode) bool { // The absolute minimum is 1 pubkey: // OP_0/OP_1-16 OP_1 OP_CHECKMULTISIG @@ -248,6 +250,108 @@ func isMultiSig(pops []parsedOpcode) bool { return true } +// multiSigDetails houses details extracted from a standard multisig script. +type multiSigDetails struct { + requiredSigs int + numPubKeys int + pubKeys [][]byte + valid bool +} + +// extractMultisigScriptDetails attempts to extract details from the passed +// script if it is a standard multisig script. The returned details struct will +// have the valid flag set to false otherwise. +// +// The extract pubkeys flag indicates whether or not the pubkeys themselves +// should also be extracted and is provided because extracting them results in +// an allocation that the caller might wish to avoid. The pubKeys member of +// the returned details struct will be nil when the flag is false. +// +// NOTE: This function is only valid for version 0 scripts. The returned +// details struct will always be empty and have the valid flag set to false for +// other script versions. +func extractMultisigScriptDetails(scriptVersion uint16, script []byte, extractPubKeys bool) multiSigDetails { + // The only currently supported script version is 0. + if scriptVersion != 0 { + return multiSigDetails{} + } + + // A multi-signature script is of the form: + // NUM_SIGS PUBKEY PUBKEY PUBKEY ... NUM_PUBKEYS OP_CHECKMULTISIG + + // The script can't possibly be a multisig script if it doesn't end with + // OP_CHECKMULTISIG or have at least two small integer pushes preceding it. + // Fail fast to avoid more work below. + if len(script) < 3 || script[len(script)-1] != OP_CHECKMULTISIG { + return multiSigDetails{} + } + + // The first opcode must be a small integer specifying the number of + // signatures required. + tokenizer := MakeScriptTokenizer(scriptVersion, script) + if !tokenizer.Next() || !isSmallInt(tokenizer.Opcode()) { + return multiSigDetails{} + } + requiredSigs := asSmallInt(tokenizer.Opcode()) + + // The next series of opcodes must either push public keys or be a small + // integer specifying the number of public keys. + var numPubKeys int + var pubKeys [][]byte + if extractPubKeys { + pubKeys = make([][]byte, 0, MaxPubKeysPerMultiSig) + } + for tokenizer.Next() { + if isSmallInt(tokenizer.Opcode()) { + break + } + + data := tokenizer.Data() + numPubKeys++ + if !isStrictPubKeyEncoding(data) { + continue + } + if extractPubKeys { + pubKeys = append(pubKeys, data) + } + } + if tokenizer.Done() { + return multiSigDetails{} + } + + // The next opcode must be a small integer specifying the number of public + // keys required. + op := tokenizer.Opcode() + if !isSmallInt(op) || asSmallInt(op) != numPubKeys { + return multiSigDetails{} + } + + // There must only be a single opcode left unparsed which will be + // OP_CHECKMULTISIG per the check above. + if int32(len(tokenizer.Script()))-tokenizer.ByteIndex() != 1 { + return multiSigDetails{} + } + + return multiSigDetails{ + requiredSigs: requiredSigs, + numPubKeys: numPubKeys, + pubKeys: pubKeys, + valid: true, + } +} + +// isMultisigScript returns whether or not the passed script is a standard +// multisig script. +// +// NOTE: This function is only valid for version 0 scripts. It will always +// return false for other script versions. +func isMultisigScript(scriptVersion uint16, script []byte) bool { + // Since this is only checking the form of the script, don't extract the + // public keys to avoid the allocation. + details := extractMultisigScriptDetails(scriptVersion, script, false) + return details.valid +} + // IsMultisigScript returns whether or not the passed script is a standard // multisignature script. // @@ -257,16 +361,8 @@ func isMultiSig(pops []parsedOpcode) bool { // // The error is DEPRECATED and will be removed in the major version bump. func IsMultisigScript(script []byte) (bool, error) { - if len(script) == 0 || script == nil { - return false, nil - } - - pops, err := parseScript(script) - if err != nil { - return false, err - } - - return isMultiSig(pops), nil + const scriptVersion = 0 + return isMultisigScript(scriptVersion, script), nil } // isNullData returns true if the passed script is a null data transaction, -- 2.45.2 From 02dab1695f3d99299f6448523529197cfca584d3 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:17 -0500 Subject: [PATCH 020/459] txscript: Add benchmarks for IsMutlsigSigScript. --- txscript/bench_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++ txscript/standard.go | 18 ++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 49be4958..41d79ccb 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -219,3 +219,51 @@ func BenchmarkIsMultisigScript(b *testing.B) { } } } + +// BenchmarkIsMultisigSigScript benchmarks how long it takes IsMultisigSigScript +// to analyze a very large script. +func BenchmarkIsMultisigSigScriptLarge(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if IsMultisigSigScript(script) { + b.Fatalf("script should NOT be reported as mutisig sig script") + } + } +} + +// BenchmarkIsMultisigSigScript benchmarks how long it takes IsMultisigSigScript +// to analyze both a 1-of-2 multisig public key script (which should be false) +// and a signature script comprised of a pay-to-script-hash 1-of-2 multisig +// redeem script (which should be true). +func BenchmarkIsMultisigSigScript(b *testing.B) { + multisigShortForm := "1 " + + "DATA_33 " + + "0x030478aaaa2be30772f1e69e581610f1840b3cf2fe7228ee0281cd599e5746f81e " + + "DATA_33 " + + "0x0284f4d078b236a9ff91661f8ffbe012737cd3507566f30fd97d25f2b23539f3cd " + + "2 CHECKMULTISIG" + pkScript := mustParseShortForm(multisigShortForm) + + sigHex := "0x304402205795c3ab6ba11331eeac757bf1fc9c34bef0c7e1a9c8bd5eebb8" + + "82f3b79c5838022001e0ab7b4c7662e4522dc5fa479e4b4133fa88c6a53d895dc1d5" + + "2eddc7bbcf2801 " + sigScript := mustParseShortForm("DATA_71 " + sigHex + "DATA_71 " + + multisigShortForm) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if IsMultisigSigScript(pkScript) { + b.Fatalf("script should NOT be reported as mutisig sig script") + } + if !IsMultisigSigScript(sigScript) { + b.Fatalf("script should be reported as a mutisig sig script") + } + } +} diff --git a/txscript/standard.go b/txscript/standard.go index 096de4e5..51dcbfb9 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -365,6 +365,24 @@ func IsMultisigScript(script []byte) (bool, error) { return isMultisigScript(scriptVersion, script), nil } +// IsMultisigSigScript takes a script, parses it, then returns whether or +// not it is a multisignature script. +func IsMultisigSigScript(script []byte) bool { + if len(script) == 0 || script == nil { + return false + } + pops, err := parseScript(script) + if err != nil { + return false + } + subPops, err := parseScript(pops[len(pops)-1].data) + if err != nil { + return false + } + + return isMultiSig(subPops) +} + // isNullData returns true if the passed script is a null data transaction, // false otherwise. func isNullData(pops []parsedOpcode) bool { -- 2.45.2 From 34ebf0f32f4729eb5f37133cae9f9f2b4fdc7033 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:18 -0500 Subject: [PATCH 021/459] txscript: Optimize IsMultisigSigScript. This converts the IsMultisigSigScript function to analyze the raw script and make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. In order to accomplish this, it first rejects scripts that can't possibly fit the bill due to the final byte of what would be the redeem script not being the appropriate opcode or the overall script not having enough bytes. Then, it uses a new function that is introduced named finalOpcodeData that uses the tokenizer to return any data associated with the final opcode in the signature script (which will be nil for non-push opcodes or if the script fails to parse) and analyzes it as if it were a redeem script when it is non nil. It is also worth noting that this new implementation intentionally has the same semantic difference from the existing implementation as the updated IsMultisigScript function in regards to allowing zero pubkeys whereas previously it incorrectly required at least one pubkey. Finally, the comment is modified to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script that is not a multisig script and both a 1-of-2 multisig public key script (which should be false) and a signature script comprised of a pay-to-script-hash 1-of-2 multisig redeem script (which should be true): benchmark old ns/op new ns/op delta BenchmarkIsMultisigSigScriptLarge-8 69328 2.93 -100.00% BenchmarkIsMultisigSigScript-8 2375 146 -93.85% benchmark old allocs new allocs delta BenchmarkIsMultisigSigScriptLarge-8 5 0 -100.00% BenchmarkIsMultisigSigScript-8 3 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsMultisigSigScriptLarge-8 330035 0 -100.00% BenchmarkIsMultisigSigScript-8 9472 0 -100.00% --- txscript/script.go | 19 +++++++++++++++++++ txscript/standard.go | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index a8cfd166..eb5be8b7 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -769,6 +769,25 @@ func GetSigOpCount(script []byte) int { return getSigOpCount(pops, false) } +// finalOpcodeData returns the data associated with the final opcode in the +// script. It will return nil if the script fails to parse. +func finalOpcodeData(scriptVersion uint16, script []byte) []byte { + // Avoid unnecessary work. + if len(script) == 0 { + return nil + } + + var data []byte + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + data = tokenizer.Data() + } + if tokenizer.Err() != nil { + return nil + } + return data +} + // GetPreciseSigOpCount returns the number of signature operations in // scriptPubKey. If bip16 is true then scriptSig may be searched for the // Pay-To-Script-Hash script in order to find the precise number of signature diff --git a/txscript/standard.go b/txscript/standard.go index 51dcbfb9..272b42b8 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -365,22 +365,39 @@ func IsMultisigScript(script []byte) (bool, error) { return isMultisigScript(scriptVersion, script), nil } -// IsMultisigSigScript takes a script, parses it, then returns whether or -// not it is a multisignature script. +// IsMultisigSigScript returns whether or not the passed script appears to be a +// signature script which consists of a pay-to-script-hash multi-signature +// redeem script. Determining if a signature script is actually a redemption of +// pay-to-script-hash requires the associated public key script which is often +// expensive to obtain. Therefore, this makes a fast best effort guess that has +// a high probability of being correct by checking if the signature script ends +// with a data push and treating that data push as if it were a p2sh redeem +// script +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func IsMultisigSigScript(script []byte) bool { - if len(script) == 0 || script == nil { - return false - } - pops, err := parseScript(script) - if err != nil { - return false - } - subPops, err := parseScript(pops[len(pops)-1].data) - if err != nil { + const scriptVersion = 0 + + // The script can't possibly be a multisig signature script if it doesn't + // end with OP_CHECKMULTISIG in the redeem script or have at least two small + // integers preceding it, and the redeem script itself must be preceded by + // at least a data push opcode. Fail fast to avoid more work below. + if len(script) < 4 || script[len(script)-1] != OP_CHECKMULTISIG { return false } - return isMultiSig(subPops) + // Parse through the script to find the last opcode and any data it might + // push and treat it as a p2sh redeem script even though it might not + // actually be one. + possibleRedeemScript := finalOpcodeData(scriptVersion, script) + if possibleRedeemScript == nil { + return false + } + + // Finally, return if that possible redeem script is a multisig script. + return isMultisigScript(scriptVersion, possibleRedeemScript) } // isNullData returns true if the passed script is a null data transaction, -- 2.45.2 From ce1513df03cfc708b2f6eacd1080e6f078455c84 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:25 -0500 Subject: [PATCH 022/459] txscript: Add benchmark for IsPushOnlyScript. --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 41d79ccb..ca64267a 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -267,3 +267,18 @@ func BenchmarkIsMultisigSigScript(b *testing.B) { } } } + +// BenchmarkIsPushOnlyScript benchmarks how long it takes IsPushOnlyScript to +// analyze a very large script. +func BenchmarkIsPushOnlyScript(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPushOnlyScript(script) + } +} -- 2.45.2 From 2d5f7cf82540247f716d65f91dcbc934e67ccb67 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:26 -0500 Subject: [PATCH 023/459] txscript: Optimize IsPushOnlyScript. This converts the IsPushOnlyScript function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. It also deprecates the isPushOnly function that requires opcodes in favor of the new function and modifies the comment on IsPushOnlyScript to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsPushOnlyScript-8 62412 622 -99.00% benchmark old allocs new allocs delta BenchmarkIsPushOnlyScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPushOnlyScript-8 311299 0 -100.00% --- txscript/script.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index eb5be8b7..43048e95 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -182,6 +182,8 @@ func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { } // isPushOnly returns true if the script only pushes data, false otherwise. +// +// DEPRECATED. Use IsPushOnlyScript instead. func isPushOnly(pops []parsedOpcode) bool { // NOTE: This function does NOT verify opcodes directly since it is // internal and is only called with parsed opcodes for scripts that did @@ -199,15 +201,27 @@ func isPushOnly(pops []parsedOpcode) bool { return true } -// IsPushOnlyScript returns whether or not the passed script only pushes data. +// IsPushOnlyScript returns whether or not the passed script only pushes data +// according to the consensus definition of pushing data. // -// False will be returned when the script does not parse. +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before checking if it is a push only script which means nodes +// on existing rules will treat new version scripts as if they were version 0. func IsPushOnlyScript(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + // All opcodes up to OP_16 are data push instructions. + // NOTE: This does consider OP_RESERVED to be a data push instruction, + // but execution of OP_RESERVED will fail anyway and matches the + // behavior required by consensus. + if tokenizer.Opcode() > OP_16 { + return false + } } - return isPushOnly(pops) + return tokenizer.Err() == nil } // parseScriptTemplate is the same as parseScript but allows the passing of the -- 2.45.2 From e422d42d7fdde45c222810363d24b8eb3340cf2a Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 01:43:18 -0700 Subject: [PATCH 024/459] txscript: Add benchmark IsPayToWitnessPubkeyHash --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index ca64267a..de6636d9 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -282,3 +282,18 @@ func BenchmarkIsPushOnlyScript(b *testing.B) { _ = IsPushOnlyScript(script) } } + +// BenchmarkIsWitnessPubKeyHash benchmarks how long it takes to analyze a very +// large script to determine if it is a standard witness pubkey hash script. +func BenchmarkIsWitnessPubKeyHash(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToWitnessPubKeyHash(script) + } +} -- 2.45.2 From 54d08ebd5fa1706790e2cf73e87804b071368a0c Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 13:22:40 -0800 Subject: [PATCH 025/459] txscript: Optimize IsPayToWitnessPubKeyHash This converts the IsPayToWitnessPubKeyHash function to analyze the raw script instead of the far less efficient parseScript, thereby significantly optimizing the function. In order to accomplish this, it introduces two new functions. The first one is named extractWitnessPubKeyHash and works with the raw script bytes to simultaneously deteremine if the script is a p2wkh, and in case it is, extract and return the hash. The second new function is name isWitnessPubKeyHashScript which is defined in terms of the former. The extract function is approach was chosen because it is common for callers to want to only extract relevant details from the script if the script is of the specific type. Extracting those details requires the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two and define the type determination in terms of the result so long as the extraction does not require allocations. Finally, this deprecates the isWitnessPubKeyHash function that requires opcodes in favor of the new functions and modifies the comment on IsPayToWitnessPubKeyHash to explicitly call out the script version semantics. The following is a before and after comparison of executing IsPayToWitnessPubKeyHash on a large script: benchmark old ns/op new ns/op delta BenchmarkIsWitnessPubKeyHash-8 68927 0.53 -100.00% benchmark old allocs new allocs delta BenchmarkIsWitnessPubKeyHash-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsWitnessPubKeyHash-8 311299 0 -100.00% --- txscript/script.go | 6 +----- txscript/standard.go | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 43048e95..59dc2e27 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -110,11 +110,7 @@ func IsPayToWitnessScriptHash(script []byte) bool { // IsPayToWitnessPubKeyHash returns true if the is in the standard // pay-to-witness-pubkey-hash (P2WKH) format, false otherwise. func IsPayToWitnessPubKeyHash(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isWitnessPubKeyHash(pops) + return isWitnessPubKeyHashScript(script) } // isWitnessPubKeyHash returns true if the passed script is a diff --git a/txscript/standard.go b/txscript/standard.go index 272b42b8..513c9ce1 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -400,6 +400,27 @@ func IsMultisigSigScript(script []byte) bool { return isMultisigScript(scriptVersion, possibleRedeemScript) } +// extractWitnessPubKeyHash extracts the witness public key hash from the passed +// script if it is a standard pay-to-witness-pubkey-hash script. It will return +// nil otherwise. +func extractWitnessPubKeyHash(script []byte) []byte { + // A pay-to-witness-pubkey-hash script is of the form: + // OP_0 OP_DATA_20 <20-byte-hash> + if len(script) == 22 && + script[0] == OP_0 && + script[1] == OP_DATA_20 { + + return script[2:22] + } + return nil +} + +// isWitnessPubKeyHashScript returns whether or not the passed script is a +// standard pay-to-witness-pubkey-hash script. +func isWitnessPubKeyHashScript(script []byte) bool { + return extractWitnessPubKeyHash(script) != nil +} + // isNullData returns true if the passed script is a null data transaction, // false otherwise. func isNullData(pops []parsedOpcode) bool { -- 2.45.2 From 728ce1001d210f291796a0ad1748be2fc3abd505 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 01:57:31 -0700 Subject: [PATCH 026/459] txscript: Add benchmark for IsPayToWitnessScriptHash --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index de6636d9..529d32f7 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -297,3 +297,18 @@ func BenchmarkIsWitnessPubKeyHash(b *testing.B) { _ = IsPayToWitnessPubKeyHash(script) } } + +// BenchmarkIsWitnessScriptHash benchmarks how long it takes to analyze a very +// large script to determine if it is a standard witness script hash script. +func BenchmarkIsWitnessScriptHash(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToWitnessScriptHash(script) + } +} -- 2.45.2 From 55a6bb5e325b8a9511e485160420c0acf236b44a Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 13:39:10 -0800 Subject: [PATCH 027/459] txscript: Optimize IsPayToWitnessScriptHash This converts the IsPayToWitnessScriptHash function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimizing the function. In order to accomplish this, it introduces two new functions. The first one is named extractWitnessScriptHash and works with the raw script byte to simultaneously deteremine if the script is a p2wsh script, and in the case that is is, extract and return the hash. The second new function is named isWitnessScriptHashScript and is defined in terms of the former. The extract function approach was chosed because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result, so long as the extraction does not require allocations. Finally, this also deprecates the isWitnessScriptHash function that requires opcodes in favor of the new functions and modifies the comment on IsPayToWitnessScriptHash to call out the script version semantics. The following is a before and after comparison of executing IsPayToWitnessScriptHash on a large script: benchmark old ns/op new ns/op delta BenchmarkIsWitnessScriptHash-8 62774 0.63 -100.00% benchmark old allocs new allocs delta BenchmarkIsWitnessScriptHash-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsWitnessScriptHash-8 311299 0 -100.00% --- txscript/script.go | 6 +----- txscript/standard.go | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 59dc2e27..5968cec7 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -100,11 +100,7 @@ func isWitnessScriptHash(pops []parsedOpcode) bool { // IsPayToWitnessScriptHash returns true if the is in the standard // pay-to-witness-script-hash (P2WSH) format, false otherwise. func IsPayToWitnessScriptHash(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isWitnessScriptHash(pops) + return isWitnessScriptHashScript(script) } // IsPayToWitnessPubKeyHash returns true if the is in the standard diff --git a/txscript/standard.go b/txscript/standard.go index 513c9ce1..a53180f1 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -421,6 +421,28 @@ func isWitnessPubKeyHashScript(script []byte) bool { return extractWitnessPubKeyHash(script) != nil } +// extractWitnessScriptHash extracts the witness script hash from the passed +// script if it is standard pay-to-witness-script-hash script. It will return +// nil otherwise. +func extractWitnessScriptHash(script []byte) []byte { + // A pay-to-witness-script-hash script is of the form: + // OP_0 OP_DATA_32 <32-byte-hash> + if len(script) == 34 && + script[0] == OP_0 && + script[1] == OP_DATA_32 { + + return script[2:34] + } + + return nil +} + +// isWitnessScriptHashScript returns whether or not the passed script is a +// standard pay-to-witness-script-hash script. +func isWitnessScriptHashScript(script []byte) bool { + return extractWitnessScriptHash(script) != nil +} + // isNullData returns true if the passed script is a null data transaction, // false otherwise. func isNullData(pops []parsedOpcode) bool { -- 2.45.2 From e4118c914fb8cdcced379a41b62f95402796cbed Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:49 -0500 Subject: [PATCH 028/459] txscript: Add benchmark for IsNullData --- txscript/bench_test.go | 15 +++++++++++++++ txscript/script.go | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 529d32f7..fda83771 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -312,3 +312,18 @@ func BenchmarkIsWitnessScriptHash(b *testing.B) { _ = IsPayToWitnessScriptHash(script) } } + +// BenchmarkIsNullDataScript benchmarks how long it takes to analyze a very +// large script to determine if it is a standard nulldata script. +func BenchmarkIsNullDataScript(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsNullData(script) + } +} diff --git a/txscript/script.go b/txscript/script.go index 5968cec7..7f812207 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -151,6 +151,16 @@ func isWitnessProgram(pops []parsedOpcode) bool { (len(pops[1].data) >= 2 && len(pops[1].data) <= 40) } +// IsNullData returns true if the passed script is a null data script, false +// otherwise. +func IsNullData(script []byte) bool { + pops, err := parseScript(script) + if err != nil { + return false + } + return isNullData(pops) +} + // ExtractWitnessProgramInfo attempts to extract the witness program version, // as well as the witness program itself from the passed script. func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { -- 2.45.2 From 5f771c1aaa5db7427011de1478182ed0d95ecf37 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 15:15:34 -0800 Subject: [PATCH 029/459] txscript: Optimize IsNullData This converts the IsNullData function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimizing the function. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsNullDataScript-8 62495 2.65 -100.00% benchmark old allocs new allocs delta BenchmarkIsNullDataScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsNullDataScript-8 311299 0 -100.00% --- txscript/script.go | 7 ++----- txscript/standard.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 7f812207..691e31cc 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -154,11 +154,8 @@ func isWitnessProgram(pops []parsedOpcode) bool { // IsNullData returns true if the passed script is a null data script, false // otherwise. func IsNullData(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isNullData(pops) + const scriptVersion = 0 + return isNullDataScript(scriptVersion, script) } // ExtractWitnessProgramInfo attempts to extract the witness program version, diff --git a/txscript/standard.go b/txscript/standard.go index a53180f1..9825f61b 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -461,6 +461,41 @@ func isNullData(pops []parsedOpcode) bool { len(pops[1].data) <= MaxDataCarrierSize } +// isNullDataScript returns whether or not the passed script is a standard +// null data script. +// +// NOTE: This function is only valid for version 0 scripts. It will always +// return false for other script versions. +func isNullDataScript(scriptVersion uint16, script []byte) bool { + // The only currently supported script version is 0. + if scriptVersion != 0 { + return false + } + + // A null script is of the form: + // OP_RETURN + // + // Thus, it can either be a single OP_RETURN or an OP_RETURN followed by a + // data push up to MaxDataCarrierSize bytes. + + // The script can't possibly be a a null data script if it doesn't start + // with OP_RETURN. Fail fast to avoid more work below. + if len(script) < 1 || script[0] != OP_RETURN { + return false + } + + // Single OP_RETURN. + if len(script) == 1 { + return true + } + + // OP_RETURN followed by data push up to MaxDataCarrierSize bytes. + tokenizer := MakeScriptTokenizer(scriptVersion, script[1:]) + return tokenizer.Next() && tokenizer.Done() && + (isSmallInt(tokenizer.Opcode()) || tokenizer.Opcode() <= OP_PUSHDATA4) && + len(tokenizer.Data()) <= MaxDataCarrierSize +} + // scriptType returns the type of the script being inspected from the known // standard types. func typeOfScript(pops []parsedOpcode) ScriptClass { -- 2.45.2 From 77660b7fb0e2de0fd4d159fd09e29bf4025690df Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:20 -0500 Subject: [PATCH 030/459] txscript: Add benchmark for IsUnspendable. --- txscript/bench_test.go | 14 ++++++++++++++ txscript/script_test.go | 13 ------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index fda83771..c8f7d0f7 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -327,3 +327,17 @@ func BenchmarkIsNullDataScript(b *testing.B) { _ = IsNullData(script) } } + +// BenchmarkIsUnspendable benchmarks how long it takes IsUnspendable to analyze +// a very large script. +func BenchmarkIsUnspendable(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsUnspendable(script) + } +} diff --git a/txscript/script_test.go b/txscript/script_test.go index 34c8ef97..665d9ef6 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -4334,16 +4334,3 @@ func TestIsUnspendable(t *testing.T) { } } } - -// BenchmarkIsUnspendable adds a benchmark to compare the time and allocations -// necessary for the IsUnspendable function. -func BenchmarkIsUnspendable(b *testing.B) { - pkScriptToUse := []byte{0xa9, 0x14, 0x82, 0x1d, 0xba, 0x94, 0xbc, 0xfb, 0xa2, 0x57, 0x36, 0xa3, 0x9e, 0x5d, 0x14, 0x5d, 0x69, 0x75, 0xba, 0x8c, 0x0b, 0x42, 0x87} - var res bool = false - for i := 0; i < b.N; i++ { - res = IsUnspendable(pkScriptToUse) - } - if res { - b.Fatalf("Benchmark should never have res be %t\n", res) - } -} -- 2.45.2 From e98b7c1a9a10ae18e2e724aceeee57c216095517 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:21 -0500 Subject: [PATCH 031/459] txscript: Optimize IsUnspendable. This converts the IsUnspendable function to make use of a combination of raw script analysis and the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. It is important to note that this new implementation intentionally has a semantic difference from the existing implementation in that it will now report scripts that are larger than the max allowed script size are unspendable as well. Finally, the comment is modified to explicitly call out the script version semantics. Note: this function was recently optimized in master, so the gains here are less noticable than other optimizations. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsUnspendable-8 656 584 -10.98% benchmark old allocs new allocs delta BenchmarkIsUnspendable-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsUnspendable-8 1 0 -100.00% --- txscript/script.go | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 691e31cc..e933167d 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -917,15 +917,22 @@ func checkScriptParses(scriptVersion uint16, script []byte) error { // IsUnspendable returns whether the passed public key script is unspendable, or // guaranteed to fail at execution. This allows inputs to be pruned instantly // when entering the UTXO set. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func IsUnspendable(pkScript []byte) bool { - // Not provably unspendable - if len(pkScript) == 0 { - return false - } - firstOpcode, err := checkScriptTemplateParseable(pkScript, &opcodeArray) - if err != nil { + // The script is unspendable if starts with OP_RETURN or is guaranteed + // to fail at execution due to being larger than the max allowed script + // size. + switch { + case len(pkScript) > 0 && pkScript[0] == OP_RETURN: + return true + case len(pkScript) > MaxScriptSize: return true } - return firstOpcode != nil && *firstOpcode == OP_RETURN + // The script is unspendable if it is guaranteed to fail at execution. + const scriptVersion = 0 + return checkScriptParses(scriptVersion, pkScript) != nil } -- 2.45.2 From 549a1f26f2de278362b0b7643954c2e5a5a5dd58 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 00:35:28 -0700 Subject: [PATCH 032/459] txscript/engine: Optimize new engine push only script This modifies the check for whether or not a pay-to-script-hash signature script is a push only script to make use of the new and more efficient raw script function. Also, since the script will have already been checked further above when the ScriptVerifySigPushOnly flags is set, avoid checking it again in that case. Backport of af67951b9a66df3aac1bf3d6376af0730287bbf2 --- txscript/engine.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/txscript/engine.go b/txscript/engine.go index 3c76b747..06f454d3 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -946,7 +946,11 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags if vm.hasFlag(ScriptBip16) && isScriptHash(vm.scripts[1]) { // Only accept input scripts that push data for P2SH. - if !isPushOnly(vm.scripts[0]) { + // Notice that the push only checks have already been done when + // the flag to verify signature scripts are push only is set + // above, so avoid checking again. + alreadyChecked := vm.hasFlag(ScriptVerifySigPushOnly) + if !alreadyChecked && !isPushOnly(vm.scripts[0]) { return nil, scriptError(ErrNotPushOnly, "pay to script hash is not push only") } -- 2.45.2 From a59e01c23c057d904cf4b23df0d85620b42a39cd Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 00:43:38 -0700 Subject: [PATCH 033/459] txscript/engine: Use optimized IsPushOnlyScript --- txscript/engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/txscript/engine.go b/txscript/engine.go index 06f454d3..f0a94851 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -950,7 +950,7 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags // the flag to verify signature scripts are push only is set // above, so avoid checking again. alreadyChecked := vm.hasFlag(ScriptVerifySigPushOnly) - if !alreadyChecked && !isPushOnly(vm.scripts[0]) { + if !alreadyChecked && !IsPushOnlyScript(scriptSig) { return nil, scriptError(ErrNotPushOnly, "pay to script hash is not push only") } -- 2.45.2 From 1be3450efb84a7eda89fe1b2040f570e4809a9ae Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 00:49:23 -0700 Subject: [PATCH 034/459] txscript/engine: Use optimized isScriptHashScript --- txscript/engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/txscript/engine.go b/txscript/engine.go index f0a94851..703baef7 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -944,7 +944,7 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags vm.scriptIdx++ } - if vm.hasFlag(ScriptBip16) && isScriptHash(vm.scripts[1]) { + if vm.hasFlag(ScriptBip16) && isScriptHashScript(scriptPubKey) { // Only accept input scripts that push data for P2SH. // Notice that the push only checks have already been done when // the flag to verify signature scripts are push only is set -- 2.45.2 From 98dd6a900f3a1f997ffab68651e49f2772b25d5e Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 00:50:54 -0700 Subject: [PATCH 035/459] txscript/engine: Check ps2h push before parsing script This moves the check for non push-only pay-to-script-hash signature scripts before the script parsing logic when creating a new engine instance to avoid the extra overhead in the error case. --- txscript/engine.go | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 703baef7..576adc71 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -918,6 +918,21 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags "signature script is not push only") } + // The signature script must only contain data pushes for PS2H which is + // determined based on the form of the public key script. + if vm.hasFlag(ScriptBip16) && isScriptHashScript(scriptPubKey) { + // Only accept input scripts that push data for P2SH. + // Notice that the push only checks have already been done when + // the flag to verify signature scripts are push only is set + // above, so avoid checking again. + alreadyChecked := vm.hasFlag(ScriptVerifySigPushOnly) + if !alreadyChecked && !IsPushOnlyScript(scriptSig) { + return nil, scriptError(ErrNotPushOnly, + "pay to script hash is not push only") + } + vm.bip16 = true + } + // The engine stores the scripts in parsed form using a slice. This // allows multiple scripts to be executed in sequence. For example, // with a pay-to-script-hash transaction, there will be ultimately be @@ -943,19 +958,6 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags if len(scripts[0]) == 0 { vm.scriptIdx++ } - - if vm.hasFlag(ScriptBip16) && isScriptHashScript(scriptPubKey) { - // Only accept input scripts that push data for P2SH. - // Notice that the push only checks have already been done when - // the flag to verify signature scripts are push only is set - // above, so avoid checking again. - alreadyChecked := vm.hasFlag(ScriptVerifySigPushOnly) - if !alreadyChecked && !IsPushOnlyScript(scriptSig) { - return nil, scriptError(ErrNotPushOnly, - "pay to script hash is not push only") - } - vm.bip16 = true - } if vm.hasFlag(ScriptVerifyMinimalData) { vm.dstack.verifyMinimalData = true vm.astack.verifyMinimalData = true -- 2.45.2 From 8316a06a0ee4f90512d232ce4ccd00f072ff4e0c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:19 -0500 Subject: [PATCH 036/459] txscript: Add benchmark for GetSigOpCount. --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index c8f7d0f7..7d0b90c4 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -341,3 +341,18 @@ func BenchmarkIsUnspendable(b *testing.B) { _ = IsUnspendable(script) } } + +// BenchmarkGetSigOpCount benchmarks how long it takes to count the signature +// operations of a very large script. +func BenchmarkGetSigOpCount(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetSigOpCount(script) + } +} -- 2.45.2 From 4d5c0b25295855676463942e487635a5cdc45a15 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:20 -0500 Subject: [PATCH 037/459] txscript: Optimize GetSigOpCount. This converts the GetSigOpCount function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. A new function named countSigOpsV0 which accepts the raw script is introduced to perform the bulk of the work so it can be reused for precise signature operation counting as well in a later commit. It retains the same semantics in terms of counting the number of signature operations either up to the first parse error or the end of the script in the case it parses successfully as required by consensus. Finally, this also deprecates the getSigOpCount function that requires opcodes in favor of the new function and modifies the comment on GetSigOpCount to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkGetSigOpCount-8 61051 677 -98.89% benchmark old allocs new allocs delta BenchmarkGetSigOpCount-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkGetSigOpCount-8 311299 0 -100.00% --- txscript/script.go | 66 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index e933167d..32654f78 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -741,6 +741,8 @@ func asSmallInt(op byte) int { // signature operations in the script provided by pops. If precise mode is // requested then we attempt to count the number of operations for a multisig // op. Otherwise we use the maximum. +// +// DEPRECATED. Use countSigOpsV0 instead. func getSigOpCount(pops []parsedOpcode, precise bool) int { nSigs := 0 for i, pop := range pops { @@ -771,15 +773,71 @@ func getSigOpCount(pops []parsedOpcode, precise bool) int { return nSigs } +// countSigOpsV0 returns the number of signature operations in the provided +// script up to the point of the first parse failure or the entire script when +// there are no parse failures. The precise flag attempts to accurately count +// the number of operations for a multisig operation versus using the maximum +// allowed. +// +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before counting their signature operations which means nodes +// on existing rules will count new version scripts as if they were version 0. +func countSigOpsV0(script []byte, precise bool) int { + const scriptVersion = 0 + + numSigOps := 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + prevOp := byte(OP_INVALIDOPCODE) + for tokenizer.Next() { + switch tokenizer.Opcode() { + case OP_CHECKSIG, OP_CHECKSIGVERIFY: + numSigOps++ + + case OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY: + // Note that OP_0 is treated as the max number of sigops here in + // precise mode despite it being a valid small integer in order to + // highly discourage multisigs with zero pubkeys. + // + // Also, even though this is referred to as "precise" counting, it's + // not really precise at all due to the small int opcodes only + // covering 1 through 16 pubkeys, which means this will count any + // more than that value (e.g. 17, 18 19) as the maximum number of + // allowed pubkeys. This is, unfortunately, now part of + // the Bitcion consensus rules, due to historical + // reasons. This could be made more correct with a new + // script version, however, ideally all multisignaure + // operations in new script versions should move to + // aggregated schemes such as Schnorr instead. + if precise && prevOp >= OP_1 && prevOp <= OP_16 { + numSigOps += asSmallInt(prevOp) + } else { + numSigOps += MaxPubKeysPerMultiSig + } + + default: + // Not a sigop. + } + + prevOp = tokenizer.Opcode() + } + + return numSigOps +} + // GetSigOpCount provides a quick count of the number of signature operations // in a script. a CHECKSIG operations counts for 1, and a CHECK_MULTISIG for 20. // If the script fails to parse, then the count up to the point of failure is // returned. +// +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before counting their signature operations which means nodes +// on existing rules will count new version scripts as if they were version 0. func GetSigOpCount(script []byte) int { - // Don't check error since parseScript returns the parsed-up-to-error - // list of pops. - pops, _ := parseScript(script) - return getSigOpCount(pops, false) + return countSigOpsV0(script, false) } // finalOpcodeData returns the data associated with the final opcode in the -- 2.45.2 From cc802d14079debe347b699bb69c913069e679c6a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:30 -0500 Subject: [PATCH 038/459] txscript: Add benchmark for GetPreciseSigOpCount. --- txscript/bench_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 7d0b90c4..817eb98f 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -356,3 +356,29 @@ func BenchmarkGetSigOpCount(b *testing.B) { _ = GetSigOpCount(script) } } + +// BenchmarkGetPreciseSigOpCount benchmarks how long it takes to count the +// signature operations of a very large script using the more precise counting +// method. +func BenchmarkGetPreciseSigOpCount(b *testing.B) { + redeemScript, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + // Create a fake pay-to-script-hash to pass the necessary checks and create + // the signature script accordingly by pushing the generated "redeem" script + // as the final data push so the benchmark will cover the p2sh path. + scriptHash := "0x0000000000000000000000000000000000000001" + pkScript := mustParseShortForm("HASH160 DATA_20 " + scriptHash + " EQUAL") + sigScript, err := NewScriptBuilder().AddFullData(redeemScript).Script() + if err != nil { + b.Fatalf("failed to create signature script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetPreciseSigOpCount(sigScript, pkScript, true) + } +} -- 2.45.2 From a4a21c0b087b9e73ec33def05d4a8d06671eea16 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:31 -0500 Subject: [PATCH 039/459] txscript: Optimize GetPreciseSigOpCount. This converts the GetPreciseSigOpCount function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. In particular it uses the recently converted isScriptHashScript, IsPushOnlyScript, and countSigOpsV0 functions along with the recently added finalOpcodeData functions. It also modifies the comment to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkGetPreciseSigOpCount-8 130223 742 -99.43% benchmark old allocs new allocs delta BenchmarkGetPreciseSigOpCount-8 3 0 -100.00% benchmark old bytes new bytes delta BenchmarkGetPreciseSigOpCount-8 623367 0 -100.00% --- txscript/script.go | 48 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 32654f78..aee1aaac 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -864,44 +864,44 @@ func finalOpcodeData(scriptVersion uint16, script []byte) []byte { // Pay-To-Script-Hash script in order to find the precise number of signature // operations in the transaction. If the script fails to parse, then the count // up to the point of failure is returned. -func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, bip16 bool) int { - // Don't check error since parseScript returns the parsed-up-to-error - // list of pops. - pops, _ := parseScript(scriptPubKey) +// +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before counting their signature operations which means nodes +// on existing rules will count new version scripts as if they were version 0. +// +// The third parameter is DEPRECATED and is unused. +func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, _ bool) int { + const scriptVersion = 0 - // Treat non P2SH transactions as normal. - if !(bip16 && isScriptHash(pops)) { - return getSigOpCount(pops, true) - } - - // The public key script is a pay-to-script-hash, so parse the signature - // script to get the final item. Scripts that fail to fully parse count - // as 0 signature operations. - sigPops, err := parseScript(scriptSig) - if err != nil { - return 0 + // Treat non P2SH transactions as normal. Note that signature operation + // counting includes all operations up to the first parse failure. + if !isScriptHashScript(scriptPubKey) { + return countSigOpsV0(scriptPubKey, true) } // The signature script must only push data to the stack for P2SH to be // a valid pair, so the signature operation count is 0 when that is not // the case. - if !isPushOnly(sigPops) || len(sigPops) == 0 { + if len(scriptSig) == 0 || !IsPushOnlyScript(scriptSig) { return 0 } // The P2SH script is the last item the signature script pushes to the // stack. When the script is empty, there are no signature operations. - shScript := sigPops[len(sigPops)-1].data - if len(shScript) == 0 { + // + // Notice that signature scripts that fail to fully parse count as 0 + // signature operations unlike public key and redeem scripts. + redeemScript := finalOpcodeData(scriptVersion, scriptSig) + if len(redeemScript) == 0 { return 0 } - // Parse the P2SH script and don't check the error since parseScript - // returns the parsed-up-to-error list of pops and the consensus rules - // dictate signature operations are counted up to the first parse - // failure. - shPops, _ := parseScript(shScript) - return getSigOpCount(shPops, true) + // Return the more precise sigops count for the redeem script. Note that + // signature operation counting includes all operations up to the first + // parse failure. + return countSigOpsV0(redeemScript, true) } // GetWitnessSigOpCount returns the number of signature operations generated by -- 2.45.2 From 26d63c61dce4be4721d27506203cd00a5dbd5e4a Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 12:58:03 -0800 Subject: [PATCH 040/459] txscript: add GetWitnessSigOpCountBenchmarks --- txscript/bench_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 817eb98f..52965dca 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -382,3 +382,44 @@ func BenchmarkGetPreciseSigOpCount(b *testing.B) { _ = GetPreciseSigOpCount(sigScript, pkScript, true) } } + +// BenchmarkGetWitnessSigOpCount benchmarks how long it takes to count the +// witness signature operations of a very large script. +func BenchmarkGetWitnessSigOpCountP2WKH(b *testing.B) { + pkScript := mustParseShortForm("OP_0 DATA_20 0x0000000000000000000000000000000000000000") + redeemScript, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + witness := wire.TxWitness{ + redeemScript, + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetWitnessSigOpCount(nil, pkScript, witness) + } +} + +// BenchmarkGetWitnessSigOpCount benchmarks how long it takes to count the +// witness signature operations of a very large script. +func BenchmarkGetWitnessSigOpCountNested(b *testing.B) { + pkScript := mustParseShortForm("HASH160 DATA_20 0x0000000000000000000000000000000000000000 OP_EQUAL") + sigScript := mustParseShortForm("DATA_22 0x001600000000000000000000000000000000000000000000") + redeemScript, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + witness := wire.TxWitness{ + redeemScript, + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetWitnessSigOpCount(sigScript, pkScript, witness) + } +} -- 2.45.2 From 77863f5649cbd55e58e2c3ebdd8587de9edcaef7 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:14:53 -0800 Subject: [PATCH 041/459] txscript: Optimize GetWitnessSigOpCount This converts the GetWitnessSigOpCount function to use a combination of raw script analysis and the new tokenizer instead of the far less efficeint parseScript, thereby significantly optimizing the funciton. In particular, it use the recently added countSigOpsv0 in precise mode to avoid calling paseScript. --- txscript/script.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index aee1aaac..b69c915a 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -955,8 +955,7 @@ func getWitnessSigOps(pkScript []byte, witness wire.TxWitness) int { len(witness) > 0: witnessScript := witness[len(witness)-1] - pops, _ := parseScript(witnessScript) - return getSigOpCount(pops, true) + return countSigOpsV0(witnessScript, true) } } -- 2.45.2 From 69d560c03cea944cf48114732304e2285b7cbbb5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:32 -0500 Subject: [PATCH 042/459] txscript: Add benchmark for GetScriptClass. --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 52965dca..aba3d123 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -423,3 +423,18 @@ func BenchmarkGetWitnessSigOpCountNested(b *testing.B) { _ = GetWitnessSigOpCount(sigScript, pkScript, witness) } } + +// BenchmarkGetScriptClass benchmarks how long it takes GetScriptClass to +// analyze a very large script. +func BenchmarkGetScriptClass(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetScriptClass(script) + } +} -- 2.45.2 From 9b06388f7696fe6e1a4398c2bac6e7277a916067 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:33 -0500 Subject: [PATCH 043/459] txscript: Make typeOfScript accept raw script. This converts the typeOfScript function to accept a script version and raw script instead of an array of internal parsed opcodes in order to make it more flexible for raw script analysis. Also, this adds a comment to CalcScriptInfo to call out the specific version semantics and deprecates the function since nothing currently uses it, and the relevant information can now be obtained by callers more directly through the use of the new script tokenizer. All other callers are updated accordingly. --- txscript/standard.go | 46 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 9825f61b..54c04318 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -498,7 +498,19 @@ func isNullDataScript(scriptVersion uint16, script []byte) bool { // scriptType returns the type of the script being inspected from the known // standard types. -func typeOfScript(pops []parsedOpcode) ScriptClass { +// +// NOTE: All scripts that are not version 0 are currently considered non +// standard. +func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { + if scriptVersion != 0 { + return NonStandardTy + } + + pops, err := parseScript(script) + if err != nil { + return NonStandardTy + } + if isPubkey(pops) { return PubKeyTy } else if isPubkeyHash(pops) { @@ -521,11 +533,8 @@ func typeOfScript(pops []parsedOpcode) ScriptClass { // // NonStandardTy will be returned when the script does not parse. func GetScriptClass(script []byte) ScriptClass { - pops, err := parseScript(script) - if err != nil { - return NonStandardTy - } - return typeOfScript(pops) + const scriptVersion = 0 + return typeOfScript(scriptVersion, script) } // NewScriptClass returns the ScriptClass corresponding to the string name @@ -608,9 +617,17 @@ type ScriptInfo struct { // pair. It will error if the pair is in someway invalid such that they can not // be analysed, i.e. if they do not parse or the pkScript is not a push-only // script +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +// +// DEPRECATED. This will be removed in the next major version bump. func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, bip16, segwit bool) (*ScriptInfo, error) { + const scriptVersion = 0 + sigPops, err := parseScript(sigScript) if err != nil { return nil, err @@ -621,9 +638,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, return nil, err } - // Push only sigScript makes little sense. si := new(ScriptInfo) - si.PkScriptClass = typeOfScript(pkPops) + si.PkScriptClass = typeOfScript(scriptVersion, pkScript) // Can't have a signature script that doesn't just push data. if !isPushOnly(sigPops) { @@ -644,7 +660,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, return nil, err } - shInputs := expectedInputs(shPops, typeOfScript(shPops)) + redeemClass := typeOfScript(scriptVersion, script) + shInputs := expectedInputs(shPops, redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -671,7 +688,9 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, // Extract the pushed witness program from the sigScript so we // can determine the number of expected inputs. pkPops, _ := parseScript(sigScript[1:]) - shInputs := expectedInputs(pkPops, typeOfScript(pkPops)) + + redeemClass := typeOfScript(scriptVersion, sigScript[1:]) + shInputs := expectedInputs(pkPops, redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -691,7 +710,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, witnessScript := witness[len(witness)-1] pops, _ := parseScript(witnessScript) - shInputs := expectedInputs(pops, typeOfScript(pops)) + redeemClass := typeOfScript(scriptVersion, witnessScript) + shInputs := expectedInputs(pops, redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -888,7 +908,9 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return NonStandardTy, nil, 0, err } - scriptClass := typeOfScript(pops) + const scriptVersion = 0 + scriptClass := typeOfScript(scriptVersion, pkScript) + switch scriptClass { case PubKeyHashTy: // A pay-to-pubkey-hash script is of the form: -- 2.45.2 From 3b86e0a0e2df9f20caa68c1dc6fcd67f0b9aa524 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:34 -0500 Subject: [PATCH 044/459] txscript: Optimize typeOfScript pay-to-script-hash. This begins the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes with the intent of significantly optimizing the function. In order to ease the review process, each script type will be converted in a separate commit and the typeOfScript function will be updated such that the script is only parsed as a fallback for the cases that are not already converted to more efficient raw script variants. In particular, for this commit, since the ability to detect pay-to-script-hash via raw script analysis is now available, the function is simply updated to make use of it. --- txscript/standard.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 54c04318..fb3bb982 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -506,6 +506,11 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return NonStandardTy } + switch { + case isScriptHashScript(script): + return ScriptHashTy + } + pops, err := parseScript(script) if err != nil { return NonStandardTy @@ -517,8 +522,6 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return PubKeyHashTy } else if isWitnessPubKeyHash(pops) { return WitnessV0PubKeyHashTy - } else if isScriptHash(pops) { - return ScriptHashTy } else if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy } else if isMultiSig(pops) { -- 2.45.2 From 671b5fefeff4cf07ae1805106c68b90fba291f79 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:35 -0500 Subject: [PATCH 045/459] txscript: Remove unused isScriptHash function. --- txscript/script.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index b69c915a..ca6520c8 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -54,17 +54,6 @@ func isSmallInt(op byte) bool { return op == OP_0 || (op >= OP_1 && op <= OP_16) } -// isScriptHash returns true if the script passed is a pay-to-script-hash -// transaction, false otherwise. -// -// DEPRECATED. Use isScriptHashScript or extractScriptHash instead. -func isScriptHash(pops []parsedOpcode) bool { - return len(pops) == 3 && - pops[0].opcode.value == OP_HASH160 && - pops[1].opcode.value == OP_DATA_20 && - pops[2].opcode.value == OP_EQUAL -} - // IsPayToPubKey returns true if the script is in the standard pay-to-pubkey // (P2PK) format, false otherwise. func IsPayToPubKey(script []byte) bool { -- 2.45.2 From 71bf51e82c57b0d4a68ed3f6d35d94d3e7928d9d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:36 -0500 Subject: [PATCH 046/459] txscript: Optimize typeOfScript multisig. This continues the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes. In particular, for this commit, since the ability to detect multisig scripts via the new tokenizer is now available, the function is simply updated to make use of it. --- txscript/standard.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index fb3bb982..dcd75214 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -509,6 +509,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { switch { case isScriptHashScript(script): return ScriptHashTy + case isMultisigScript(scriptVersion, script): + return MultiSigTy } pops, err := parseScript(script) @@ -524,8 +526,6 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return WitnessV0PubKeyHashTy } else if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy - } else if isMultiSig(pops) { - return MultiSigTy } else if isNullData(pops) { return NullDataTy } -- 2.45.2 From 6e86f0d09bc57573312a9b63044dea64992ff480 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:37 -0500 Subject: [PATCH 047/459] txscript: Remove unused isMultiSig function. --- txscript/standard.go | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index dcd75214..2722bc41 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -214,42 +214,6 @@ func isPubkeyHash(pops []parsedOpcode) bool { } -// isMultiSig returns true if the passed script is a multisig transaction, false -// otherwise. -// -// DEPECATED. Use isMultisigScript or extractMultisigScriptDetails instead. -func isMultiSig(pops []parsedOpcode) bool { - // The absolute minimum is 1 pubkey: - // OP_0/OP_1-16 OP_1 OP_CHECKMULTISIG - l := len(pops) - if l < 4 { - return false - } - if !isSmallInt(pops[0].opcode.value) { - return false - } - if !isSmallInt(pops[l-2].opcode.value) { - return false - } - if pops[l-1].opcode.value != OP_CHECKMULTISIG { - return false - } - - // Verify the number of pubkeys specified matches the actual number - // of pubkeys provided. - if l-2-1 != asSmallInt(pops[l-2].opcode.value) { - return false - } - - for _, pop := range pops[1 : l-2] { - // Valid pubkeys are either 33 or 65 bytes. - if len(pop.data) != 33 && len(pop.data) != 65 { - return false - } - } - return true -} - // multiSigDetails houses details extracted from a standard multisig script. type multiSigDetails struct { requiredSigs int -- 2.45.2 From 8b64adc234cfbfd68394898f2eeea0199fdefdb6 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:07:19 -0800 Subject: [PATCH 048/459] txscript: Optimze typeOfScript pay-to-pubkey This continues the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the face less efficient parsed opcodes, with the intent of significantly optimizing the function. In particular, it converts the detection of pay-to-pubkey scripts to use raw script analysis. --- txscript/standard.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 2722bc41..52a37478 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -471,6 +471,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { } switch { + case isPubKeyScript(script): + return PubKeyTy case isScriptHashScript(script): return ScriptHashTy case isMultisigScript(scriptVersion, script): @@ -482,9 +484,7 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return NonStandardTy } - if isPubkey(pops) { - return PubKeyTy - } else if isPubkeyHash(pops) { + if isPubkeyHash(pops) { return PubKeyHashTy } else if isWitnessPubKeyHash(pops) { return WitnessV0PubKeyHashTy -- 2.45.2 From 1133ea0bb3c95654e827a8ab31531c6163046f4a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:40 -0500 Subject: [PATCH 049/459] txscript: Remove unused isPubkey function. --- txscript/standard.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 52a37478..d2aa0e99 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -193,15 +193,6 @@ func isScriptHashScript(script []byte) bool { return extractScriptHash(script) != nil } -// isPubkey returns true if the script passed is a pay-to-pubkey transaction, -// false otherwise. -func isPubkey(pops []parsedOpcode) bool { - // Valid pubkeys are either 33 or 65 bytes. - return len(pops) == 2 && - (len(pops[0].data) == 33 || len(pops[0].data) == 65) && - pops[1].opcode.value == OP_CHECKSIG -} - // isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash // transaction, false otherwise. func isPubkeyHash(pops []parsedOpcode) bool { -- 2.45.2 From 13f646243d26d34ec46dfd7f9b40d5c8aaae5d59 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:45 -0500 Subject: [PATCH 050/459] txscript: Optimize typeOfScript pay-to-pubkey-hash. This continues the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes. In particular, it converts the detection of pay-to-pubkey-hash scripts to use raw script analysis. --- txscript/standard.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index d2aa0e99..08c6054e 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -464,6 +464,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { switch { case isPubKeyScript(script): return PubKeyTy + case isPubKeyHashScript(script): + return PubKeyHashTy case isScriptHashScript(script): return ScriptHashTy case isMultisigScript(scriptVersion, script): @@ -475,9 +477,7 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return NonStandardTy } - if isPubkeyHash(pops) { - return PubKeyHashTy - } else if isWitnessPubKeyHash(pops) { + if isWitnessPubKeyHash(pops) { return WitnessV0PubKeyHashTy } else if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy -- 2.45.2 From d02f97e04a5243e0343763b30c798863d63f577b Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:46 -0500 Subject: [PATCH 051/459] txscript: Remove unused isPubkeyHash function. --- txscript/standard.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 08c6054e..ff382537 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -193,18 +193,6 @@ func isScriptHashScript(script []byte) bool { return extractScriptHash(script) != nil } -// isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash -// transaction, false otherwise. -func isPubkeyHash(pops []parsedOpcode) bool { - return len(pops) == 5 && - pops[0].opcode.value == OP_DUP && - pops[1].opcode.value == OP_HASH160 && - pops[2].opcode.value == OP_DATA_20 && - pops[3].opcode.value == OP_EQUALVERIFY && - pops[4].opcode.value == OP_CHECKSIG - -} - // multiSigDetails houses details extracted from a standard multisig script. type multiSigDetails struct { requiredSigs int -- 2.45.2 From d80863da921d21dcea851605ca8d74b621bb339e Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 15:15:45 -0800 Subject: [PATCH 052/459] txscript: Optimize typeOfScript for null data scripts This continues the process of converting the typeOfScript function to use a combination of raw script analysize and the tokenizer instead of parsed opcode, with the intent of significanty optimizing the function. In particular, it converts the detection of null data scripts to use raw script analysis. --- txscript/standard.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index ff382537..bae2b0c5 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -458,6 +458,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return ScriptHashTy case isMultisigScript(scriptVersion, script): return MultiSigTy + case isNullDataScript(scriptVersion, script): + return NullDataTy } pops, err := parseScript(script) @@ -469,9 +471,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return WitnessV0PubKeyHashTy } else if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy - } else if isNullData(pops) { - return NullDataTy } + return NonStandardTy } -- 2.45.2 From 78046b3815ac525e86edde8f302b757369856f9e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:51 -0500 Subject: [PATCH 053/459] txscript: Remove unused isNullData function. --- txscript/standard.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index bae2b0c5..85b28582 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -386,24 +386,6 @@ func isWitnessScriptHashScript(script []byte) bool { return extractWitnessScriptHash(script) != nil } -// isNullData returns true if the passed script is a null data transaction, -// false otherwise. -func isNullData(pops []parsedOpcode) bool { - // A nulldata transaction is either a single OP_RETURN or an - // OP_RETURN SMALLDATA (where SMALLDATA is a data push up to - // MaxDataCarrierSize bytes). - l := len(pops) - if l == 1 && pops[0].opcode.value == OP_RETURN { - return true - } - - return l == 2 && - pops[0].opcode.value == OP_RETURN && - (isSmallInt(pops[1].opcode.value) || pops[1].opcode.value <= - OP_PUSHDATA4) && - len(pops[1].data) <= MaxDataCarrierSize -} - // isNullDataScript returns whether or not the passed script is a standard // null data script. // -- 2.45.2 From 847a262d78933c57e6062151ceef8aba17896264 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 01:46:52 -0700 Subject: [PATCH 054/459] txscript: Optimize typeOfScript witness-pubkey-hash This continues the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes. In particular, it converts the detection of witness pubkey hash scripts to use raw script analysis and the new tokenizer. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsWitnessPubKeyHash-8 61688 62839 +1.87% benchmark old allocs new allocs delta BenchmarkIsWitnessPubKeyHash-8 1 1 +0.00% benchmark old bytes new bytes delta BenchmarkIsWitnessPubKeyHash-8 311299 311299 +0.00% --- txscript/standard.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 85b28582..5d5c6687 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -355,6 +355,7 @@ func extractWitnessPubKeyHash(script []byte) []byte { return script[2:22] } + return nil } @@ -438,6 +439,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return PubKeyHashTy case isScriptHashScript(script): return ScriptHashTy + case isWitnessPubKeyHashScript(script): + return WitnessV0PubKeyHashTy case isMultisigScript(scriptVersion, script): return MultiSigTy case isNullDataScript(scriptVersion, script): @@ -449,9 +452,7 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return NonStandardTy } - if isWitnessPubKeyHash(pops) { - return WitnessV0PubKeyHashTy - } else if isWitnessScriptHash(pops) { + if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy } -- 2.45.2 From 1a60e11da7ab917a6725ce10d37da7b7f8634ed5 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 02:04:01 -0700 Subject: [PATCH 055/459] txscript: Optimize typeOfScript for witness-script-hash This concludes the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes. In particular, it converts the detection of witness script hash scripts to use raw script analysis and the new tokenizer. With all of the limbs now useing optimized variants, the following is a before an after comparison of calling GetScriptClass on a large script: benchmark old ns/op new ns/op delta BenchmarkGetScriptClass-8 61515 15.3 -99.98% benchmark old allocs new allocs delta BenchmarkGetScriptClass-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkGetScriptClass-8 311299 0 -100.00% --- txscript/standard.go | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 5d5c6687..dd751cbe 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -441,22 +441,15 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return ScriptHashTy case isWitnessPubKeyHashScript(script): return WitnessV0PubKeyHashTy + case isWitnessScriptHashScript(script): + return WitnessV0ScriptHashTy case isMultisigScript(scriptVersion, script): return MultiSigTy case isNullDataScript(scriptVersion, script): return NullDataTy - } - - pops, err := parseScript(script) - if err != nil { + default: return NonStandardTy } - - if isWitnessScriptHash(pops) { - return WitnessV0ScriptHashTy - } - - return NonStandardTy } // GetScriptClass returns the class of the script passed. -- 2.45.2 From 43846b1edf9f281a88b02e91b361ebdd30b692db Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 02:05:04 -0700 Subject: [PATCH 056/459] txscript: Remove unused isWitnessScriptHash --- txscript/script.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index ca6520c8..0d041a8b 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -78,14 +78,6 @@ func IsPayToScriptHash(script []byte) bool { return isScriptHashScript(script) } -// isWitnessScriptHash returns true if the passed script is a -// pay-to-witness-script-hash transaction, false otherwise. -func isWitnessScriptHash(pops []parsedOpcode) bool { - return len(pops) == 2 && - pops[0].opcode.value == OP_0 && - pops[1].opcode.value == OP_DATA_32 -} - // IsPayToWitnessScriptHash returns true if the is in the standard // pay-to-witness-script-hash (P2WSH) format, false otherwise. func IsPayToWitnessScriptHash(script []byte) bool { -- 2.45.2 From 705d24cab4bb7f9f0891736c4a983abd8d846146 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:09 -0500 Subject: [PATCH 057/459] txscript: Convert CalcScriptInfo. This converts CalcScriptInfo and dependent expectedInputs to make use of the new script tokenizer as well as several of the other recently added raw script analysis functions in order to remove the reliance on parsed opcodes as a step towards utlimately removing them altogether. It is worth noting that this has the side effect of significantly optimizing the function as well, however, since it is deprecated, no benchmarks are provided. --- txscript/standard.go | 76 +++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index dd751cbe..fea6799f 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -481,7 +481,11 @@ func NewScriptClass(name string) (*ScriptClass, error) { // then -1 is returned. We are an internal function and thus assume that class // is the real class of pops (and we can thus assume things that were determined // while finding out the type). -func expectedInputs(pops []parsedOpcode, class ScriptClass) int { +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func expectedInputs(script []byte, class ScriptClass) int { switch class { case PubKeyTy: return 1 @@ -508,7 +512,7 @@ func expectedInputs(pops []parsedOpcode, class ScriptClass) int { // the original bitcoind bug where OP_CHECKMULTISIG pops an // additional item from the stack, add an extra expected input // for the extra push that is required to compensate. - return asSmallInt(pops[0].opcode.value) + 1 + return asSmallInt(script[0]) + 1 case NullDataTy: fallthrough @@ -549,52 +553,52 @@ type ScriptInfo struct { func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, bip16, segwit bool) (*ScriptInfo, error) { + // Count the number of opcodes in the signature script while also ensuring + // that successfully parses. Since there is a check below to ensure the + // script is push only, this equates to the number of inputs to the public + // key script. const scriptVersion = 0 - - sigPops, err := parseScript(sigScript) - if err != nil { + var numInputs int + tokenizer := MakeScriptTokenizer(scriptVersion, sigScript) + for tokenizer.Next() { + numInputs++ + } + if err := tokenizer.Err(); err != nil { return nil, err } - pkPops, err := parseScript(pkScript) - if err != nil { + if err := checkScriptParses(scriptVersion, pkScript); err != nil { return nil, err } + // Can't have a signature script that doesn't just push data. + if !IsPushOnlyScript(sigScript) { + return nil, scriptError(ErrNotPushOnly, + "signature script is not push only") + } + si := new(ScriptInfo) si.PkScriptClass = typeOfScript(scriptVersion, pkScript) - // Can't have a signature script that doesn't just push data. - if !isPushOnly(sigPops) { - return nil, scriptError(ErrNotPushOnly, - "signature script is not push only") - } - - si.ExpectedInputs = expectedInputs(pkPops, si.PkScriptClass) + si.ExpectedInputs = expectedInputs(pkScript, si.PkScriptClass) switch { // Count sigops taking into account pay-to-script-hash. case si.PkScriptClass == ScriptHashTy && bip16 && !segwit: - // The pay-to-hash-script is the final data push of the - // signature script. - script := sigPops[len(sigPops)-1].data - shPops, err := parseScript(script) - if err != nil { - return nil, err - } - - redeemClass := typeOfScript(scriptVersion, script) - shInputs := expectedInputs(shPops, redeemClass) - if shInputs == -1 { + // The redeem script is the final data push of the signature script. + redeemScript := finalOpcodeData(scriptVersion, sigScript) + reedeemClass := typeOfScript(scriptVersion, redeemScript) + rsInputs := expectedInputs(redeemScript, reedeemClass) + if rsInputs == -1 { si.ExpectedInputs = -1 } else { - si.ExpectedInputs += shInputs + si.ExpectedInputs += rsInputs } - si.SigOps = getSigOpCount(shPops, true) + si.SigOps = countSigOpsV0(redeemScript, true) // All entries pushed to stack (or are OP_RESERVED and exec // will fail). - si.NumInputs = len(sigPops) + si.NumInputs = numInputs // If segwit is active, and this is a regular p2wkh output, then we'll // treat the script as a p2pkh output in essence. @@ -610,10 +614,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, // Extract the pushed witness program from the sigScript so we // can determine the number of expected inputs. - pkPops, _ := parseScript(sigScript[1:]) - redeemClass := typeOfScript(scriptVersion, sigScript[1:]) - shInputs := expectedInputs(pkPops, redeemClass) + shInputs := expectedInputs(sigScript[1:], redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -623,18 +625,14 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, si.SigOps = GetWitnessSigOpCount(sigScript, pkScript, witness) si.NumInputs = len(witness) - si.NumInputs += len(sigPops) + si.NumInputs += numInputs // If segwit is active, and this is a p2wsh output, then we'll need to // examine the witness script to generate accurate script info. case si.PkScriptClass == WitnessV0ScriptHashTy && segwit: - // The witness script is the final element of the witness - // stack. witnessScript := witness[len(witness)-1] - pops, _ := parseScript(witnessScript) - redeemClass := typeOfScript(scriptVersion, witnessScript) - shInputs := expectedInputs(pops, redeemClass) + shInputs := expectedInputs(witnessScript, redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -645,11 +643,11 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, si.NumInputs = len(witness) default: - si.SigOps = getSigOpCount(pkPops, true) + si.SigOps = countSigOpsV0(pkScript, true) // All entries pushed to stack (or are OP_RESERVED and exec // will fail). - si.NumInputs = len(sigPops) + si.NumInputs = numInputs } return si, nil -- 2.45.2 From 6c212fd7ee9e0ab2fcd6287d0c5ed26c0b9cf043 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:10 -0500 Subject: [PATCH 058/459] txscript: Remove unused isPushOnly function. --- txscript/script.go | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 0d041a8b..7e0e3669 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -161,26 +161,6 @@ func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { return witnessVersion, witnessProgram, nil } -// isPushOnly returns true if the script only pushes data, false otherwise. -// -// DEPRECATED. Use IsPushOnlyScript instead. -func isPushOnly(pops []parsedOpcode) bool { - // NOTE: This function does NOT verify opcodes directly since it is - // internal and is only called with parsed opcodes for scripts that did - // not have any parse errors. Thus, consensus is properly maintained. - - for _, pop := range pops { - // All opcodes up to OP_16 are data push instructions. - // NOTE: This does consider OP_RESERVED to be a data push - // instruction, but execution of OP_RESERVED will fail anyways - // and matches the behavior required by consensus. - if pop.opcode.value > OP_16 { - return false - } - } - return true -} - // IsPushOnlyScript returns whether or not the passed script only pushes data // according to the consensus definition of pushing data. // @@ -901,11 +881,7 @@ func GetWitnessSigOpCount(sigScript, pkScript []byte, witness wire.TxWitness) in // Next, we'll check the sigScript to see if this is a nested p2sh // witness program. This is a case wherein the sigScript is actually a // datapush of a p2wsh witness program. - sigPops, err := parseScript(sigScript) - if err != nil { - return 0 - } - if IsPayToScriptHash(pkScript) && isPushOnly(sigPops) && + if IsPayToScriptHash(pkScript) && IsPushOnlyScript(sigScript) && IsWitnessProgram(sigScript[1:]) { return getWitnessSigOps(sigScript[1:], witness) } -- 2.45.2 From 8c54905959569b573f019ffc8e4eeb624505a8d9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:11 -0500 Subject: [PATCH 059/459] txscript: Remove unused getSigOpCount function. --- txscript/script.go | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 7e0e3669..10ff4315 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -698,42 +698,6 @@ func asSmallInt(op byte) int { return int(op - (OP_1 - 1)) } -// getSigOpCount is the implementation function for counting the number of -// signature operations in the script provided by pops. If precise mode is -// requested then we attempt to count the number of operations for a multisig -// op. Otherwise we use the maximum. -// -// DEPRECATED. Use countSigOpsV0 instead. -func getSigOpCount(pops []parsedOpcode, precise bool) int { - nSigs := 0 - for i, pop := range pops { - switch pop.opcode.value { - case OP_CHECKSIG: - fallthrough - case OP_CHECKSIGVERIFY: - nSigs++ - case OP_CHECKMULTISIG: - fallthrough - case OP_CHECKMULTISIGVERIFY: - // If we are being precise then look for familiar - // patterns for multisig, for now all we recognize is - // OP_1 - OP_16 to signify the number of pubkeys. - // Otherwise, we use the max of 20. - if precise && i > 0 && - pops[i-1].opcode.value >= OP_1 && - pops[i-1].opcode.value <= OP_16 { - nSigs += asSmallInt(pops[i-1].opcode.value) - } else { - nSigs += MaxPubKeysPerMultiSig - } - default: - // Not a sigop. - } - } - - return nSigs -} - // countSigOpsV0 returns the number of signature operations in the provided // script up to the point of the first parse failure or the entire script when // there are no parse failures. The precise flag attempts to accurately count -- 2.45.2 From 7791f92f6f09390f310c918966178fe189c1632a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:13 -0500 Subject: [PATCH 060/459] txscript: Optimize CalcMultiSigStats. This converts the CalcMultiSigStats function to make use of the new extractMultisigScriptDetails function instead of the far less efficient parseScript thereby significantly optimizing the function. The tests are also updated accordingly. The following is a before and after comparison of analyzing a standard multisig script: benchmark old ns/op new ns/op delta --------------------------------------------------------------- BenchmarkCalcMultiSigStats 972 79.5 -91.82% benchmark old allocs new allocs delta --------------------------------------------------------------- BenchmarkCalcMultiSigStats 1 0 -100.00% benchmark old bytes new bytes delta --------------------------------------------------------------- BenchmarkCalcMultiSigStats 2304 0 -100.00% --- txscript/standard.go | 26 ++++++++++---------------- txscript/standard_test.go | 8 ++------ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index fea6799f..3bb12b9a 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -656,27 +656,21 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, // CalcMultiSigStats returns the number of public keys and signatures from // a multi-signature transaction script. The passed script MUST already be // known to be a multi-signature script. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func CalcMultiSigStats(script []byte) (int, int, error) { - pops, err := parseScript(script) - if err != nil { - return 0, 0, err - } - - // A multi-signature script is of the pattern: - // NUM_SIGS PUBKEY PUBKEY PUBKEY... NUM_PUBKEYS OP_CHECKMULTISIG - // Therefore the number of signatures is the oldest item on the stack - // and the number of pubkeys is the 2nd to last. Also, the absolute - // minimum for a multi-signature script is 1 pubkey, so at least 4 - // items must be on the stack per: - // OP_1 PUBKEY OP_1 OP_CHECKMULTISIG - if len(pops) < 4 { + // The public keys are not needed here, so pass false to avoid the extra + // allocation. + const scriptVersion = 0 + details := extractMultisigScriptDetails(scriptVersion, script, false) + if !details.valid { str := fmt.Sprintf("script %x is not a multisig script", script) return 0, 0, scriptError(ErrNotMultisigScript, str) } - numSigs := asSmallInt(pops[0].opcode.value) - numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value) - return numPubKeys, numSigs, nil + return details.numPubKeys, details.requiredSigs, nil } // payToPubKeyHashScript creates a new script to pay a transaction diff --git a/txscript/standard_test.go b/txscript/standard_test.go index 37dd8f8a..582d30ee 100644 --- a/txscript/standard_test.go +++ b/txscript/standard_test.go @@ -832,7 +832,7 @@ func TestCalcMultiSigStats(t *testing.T) { name: "short script", script: "0x046708afdb0fe5548271967f1a67130b7105cd6a828" + "e03909a67962e0ea1f61d", - err: scriptError(ErrMalformedPush, ""), + err: scriptError(ErrNotMultisigScript, ""), }, { name: "stack underflow", @@ -843,11 +843,7 @@ func TestCalcMultiSigStats(t *testing.T) { }, { name: "multisig script", - script: "0 DATA_72 0x30450220106a3e4ef0b51b764a2887226" + - "2ffef55846514dacbdcbbdd652c849d395b4384022100" + - "e03ae554c3cbb40600d31dd46fc33f25e47bf8525b1fe" + - "07282e3b6ecb5f3bb2801 CODESEPARATOR 1 DATA_33 " + - "0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" + + script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" + "0357b3a7886211ab414d55a 1 CHECKMULTISIG", err: nil, }, -- 2.45.2 From c4f6302189c7c928a2e89212d3727a308512920d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:18 -0500 Subject: [PATCH 061/459] txscript: Add benchmark for PushedData. --- txscript/bench_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index aba3d123..26b7c9fe 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -438,3 +438,21 @@ func BenchmarkGetScriptClass(b *testing.B) { _ = GetScriptClass(script) } } + +// BenchmarkPushedData benchmarks how long it takes to extract the pushed data +// from a very large script. +func BenchmarkPushedData(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, err := PushedData(script) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} -- 2.45.2 From 0a4f228dd10296da4c06484577112bf0411e7fff Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:19 -0500 Subject: [PATCH 062/459] txscript: Optimize PushedData. This converts the PushedData function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. Also, the comment is modified to explicitly call out the script version semantics. The following is a before and after comparison of extracting the data from a very large script: benchmark old ns/op new ns/op delta BenchmarkPushedData-8 64837 1790 -97.24% benchmark old allocs new allocs delta BenchmarkPushedData-8 7 6 -14.29% benchmark old bytes new bytes delta BenchmarkPushedData-8 312816 1520 -99.51% --- txscript/standard.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 3bb12b9a..0607b305 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -791,20 +791,25 @@ func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, er // PushedData returns an array of byte slices containing any pushed data found // in the passed script. This includes OP_0, but not OP_1 - OP_16. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func PushedData(script []byte) ([][]byte, error) { - pops, err := parseScript(script) - if err != nil { - return nil, err - } + const scriptVersion = 0 var data [][]byte - for _, pop := range pops { - if pop.data != nil { - data = append(data, pop.data) - } else if pop.opcode.value == OP_0 { + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if tokenizer.Data() != nil { + data = append(data, tokenizer.Data()) + } else if tokenizer.Opcode() == OP_0 { data = append(data, nil) } } + if err := tokenizer.Err(); err != nil { + return nil, err + } return data, nil } -- 2.45.2 From da9fdabbd5bae2c07aca03af811bfb33b05dd3d6 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:22 -0500 Subject: [PATCH 063/459] txscript: Make canonicalPush accept raw opcode. This renames the canonicalPush function to isCanonicalPush and converts it to accept an opcode as a byte and the associate data as a byte slice instead of the internal parse opcode data struct in order to make it more flexible for raw script analysis. It also updates all callers and tests accordingly. --- txscript/engine.go | 5 +++- txscript/script.go | 23 ++++++++------ txscript/script_test.go | 66 ++++++++++++++++++----------------------- txscript/standard.go | 4 +-- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 576adc71..ef7ad33e 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -875,6 +875,7 @@ func (vm *Engine) SetAltStack(data [][]byte) { // engine according to the description provided by each flag. func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags, sigCache *SigCache, hashCache *TxSigHashes, inputAmount int64) (*Engine, error) { + const scriptVersion = 0 // The provided transaction input index must refer to a valid input. if txIdx < 0 || txIdx >= len(tx.TxIn) { @@ -994,7 +995,9 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags // data push of the witness program, otherwise we // reintroduce malleability. sigPops := vm.scripts[0] - if len(sigPops) == 1 && canonicalPush(sigPops[0]) && + if len(sigPops) == 1 && + isCanonicalPush(sigPops[0].opcode.value, + sigPops[0].data) && IsWitnessProgram(sigPops[0].data) { witProgram = sigPops[0].data diff --git a/txscript/script.go b/txscript/script.go index 10ff4315..52bedf26 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -128,7 +128,7 @@ func IsWitnessProgram(script []byte) bool { func isWitnessProgram(pops []parsedOpcode) bool { return len(pops) == 2 && isSmallInt(pops[0].opcode.value) && - canonicalPush(pops[1]) && + isCanonicalPush(pops[1].opcode.value, pops[1].data) && (len(pops[1].data) >= 2 && len(pops[1].data) <= 40) } @@ -305,13 +305,16 @@ func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode { return retScript } -// canonicalPush returns true if the object is either not a push instruction -// or the push instruction contained wherein is matches the canonical form -// or using the smallest instruction to do the job. False otherwise. -func canonicalPush(pop parsedOpcode) bool { - opcode := pop.opcode.value - data := pop.data - dataLen := len(pop.data) +// isCanonicalPush returns true if the opcode is either not a push instruction +// or the data associated with the push instruction uses the smallest +// instruction to do the job. False otherwise. +// +// For example, it is possible to push a value of 1 to the stack as "OP_1", +// "OP_DATA_1 0x01", "OP_PUSHDATA1 0x01 0x01", and others, however, the first +// only takes a single byte, while the rest take more. Only the first is +// considered canonical. +func isCanonicalPush(opcode byte, data []byte) bool { + dataLen := len(data) if opcode > OP_16 { return true } @@ -336,7 +339,9 @@ func canonicalPush(pop parsedOpcode) bool { func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode { retScript := make([]parsedOpcode, 0, len(pkscript)) for _, pop := range pkscript { - if !canonicalPush(pop) || !bytes.Contains(pop.data, data) { + if !isCanonicalPush(pop.opcode.value, pop.data) || + !bytes.Contains(pop.data, data) { + retScript = append(retScript, pop) } } diff --git a/txscript/script_test.go b/txscript/script_test.go index 665d9ef6..62c51e41 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -3740,31 +3740,25 @@ func TestPushedData(t *testing.T) { } } -// TestHasCanonicalPush ensures the canonicalPush function works as expected. +// TestHasCanonicalPush ensures the isCanonicalPush function works as expected. func TestHasCanonicalPush(t *testing.T) { t.Parallel() + const scriptVersion = 0 for i := 0; i < 65535; i++ { script, err := NewScriptBuilder().AddInt64(int64(i)).Script() if err != nil { - t.Errorf("Script: test #%d unexpected error: %v\n", i, - err) + t.Errorf("Script: test #%d unexpected error: %v\n", i, err) continue } - if result := IsPushOnlyScript(script); !result { - t.Errorf("IsPushOnlyScript: test #%d failed: %x\n", i, - script) + if !IsPushOnlyScript(script) { + t.Errorf("IsPushOnlyScript: test #%d failed: %x\n", i, script) continue } - pops, err := parseScript(script) - if err != nil { - t.Errorf("parseScript: #%d failed: %v", i, err) - continue - } - for _, pop := range pops { - if result := canonicalPush(pop); !result { - t.Errorf("canonicalPush: test #%d failed: %x\n", - i, script) + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { + t.Errorf("isCanonicalPush: test #%d failed: %x\n", i, script) break } } @@ -3774,21 +3768,17 @@ func TestHasCanonicalPush(t *testing.T) { builder.AddData(bytes.Repeat([]byte{0x49}, i)) script, err := builder.Script() if err != nil { - t.Errorf("StandardPushesTests test #%d unexpected error: %v\n", i, err) + t.Errorf("Script: test #%d unexpected error: %v\n", i, err) continue } - if result := IsPushOnlyScript(script); !result { - t.Errorf("StandardPushesTests IsPushOnlyScript test #%d failed: %x\n", i, script) + if !IsPushOnlyScript(script) { + t.Errorf("IsPushOnlyScript: test #%d failed: %x\n", i, script) continue } - pops, err := parseScript(script) - if err != nil { - t.Errorf("StandardPushesTests #%d failed to TstParseScript: %v", i, err) - continue - } - for _, pop := range pops { - if result := canonicalPush(pop); !result { - t.Errorf("StandardPushesTests TstHasCanonicalPushes test #%d failed: %x\n", i, script) + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { + t.Errorf("isCanonicalPush: test #%d failed: %x\n", i, script) break } } @@ -4213,11 +4203,13 @@ func TestIsPayToWitnessPubKeyHash(t *testing.T) { } } -// TestHasCanonicalPushes ensures the canonicalPush function properly determines -// what is considered a canonical push for the purposes of removeOpcodeByData. +// TestHasCanonicalPushes ensures the isCanonicalPush function properly +// determines what is considered a canonical push for the purposes of +// removeOpcodeByData. func TestHasCanonicalPushes(t *testing.T) { t.Parallel() + const scriptVersion = 0 tests := []struct { name string script string @@ -4236,20 +4228,20 @@ func TestHasCanonicalPushes(t *testing.T) { }, } - for i, test := range tests { + for _, test := range tests { script := mustParseShortForm(test.script) - pops, err := parseScript(script) - if err != nil { + if err := checkScriptParses(scriptVersion, script); err != nil { if test.expected { - t.Errorf("TstParseScript #%d failed: %v", i, err) + t.Errorf("%q: script parse failed: %v", test.name, err) } continue } - for _, pop := range pops { - if canonicalPush(pop) != test.expected { - t.Errorf("canonicalPush: #%d (%s) wrong result"+ - "\ngot: %v\nwant: %v", i, test.name, - true, test.expected) + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + result := isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) + if result != test.expected { + t.Errorf("%q: isCanonicalPush wrong result\ngot: %v\nwant: %v", + test.name, result, test.expected) break } } diff --git a/txscript/standard.go b/txscript/standard.go index 0607b305..d97072f1 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -953,7 +953,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa } isAtomicSwap := pops[0].opcode.value == OP_IF && pops[1].opcode.value == OP_SIZE && - canonicalPush(pops[2]) && + isCanonicalPush(pops[2].opcode.value, pops[2].data) && pops[3].opcode.value == OP_EQUALVERIFY && pops[4].opcode.value == OP_SHA256 && pops[5].opcode.value == OP_DATA_32 && @@ -962,7 +962,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa pops[8].opcode.value == OP_HASH160 && pops[9].opcode.value == OP_DATA_20 && pops[10].opcode.value == OP_ELSE && - canonicalPush(pops[11]) && + isCanonicalPush(pops[11].opcode.value, pops[11].data) && pops[12].opcode.value == OP_CHECKLOCKTIMEVERIFY && pops[13].opcode.value == OP_DROP && pops[14].opcode.value == OP_DUP && -- 2.45.2 From 81b80328bd21ae8845a8ca3cb0760898b7119e43 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:24 -0500 Subject: [PATCH 064/459] txscript: Add ExtractAtomicSwapDataPushes benches. --- txscript/bench_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 26b7c9fe..456db25d 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -456,3 +456,44 @@ func BenchmarkPushedData(b *testing.B) { } } } + +// BenchmarkExtractAtomicSwapDataPushesLarge benchmarks how long it takes +// ExtractAtomicSwapDataPushes to analyze a very large script. +func BenchmarkExtractAtomicSwapDataPushesLarge(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + const scriptVersion = 0 + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, err := ExtractAtomicSwapDataPushes(scriptVersion, script) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} + +// BenchmarkExtractAtomicSwapDataPushesLarge benchmarks how long it takes +// ExtractAtomicSwapDataPushes to analyze a standard atomic swap script. +func BenchmarkExtractAtomicSwapDataPushes(b *testing.B) { + secret := "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" + recipient := "0000000000000000000000000000000000000001" + refund := "0000000000000000000000000000000000000002" + script := mustParseShortForm(fmt.Sprintf("IF SIZE 32 EQUALVERIFY SHA256 "+ + "DATA_32 0x%s EQUALVERIFY DUP HASH160 DATA_20 0x%s ELSE 300000 "+ + "CHECKLOCKTIMEVERIFY DROP DUP HASH160 DATA_20 0x%s ENDIF "+ + "EQUALVERIFY CHECKSIG", secret, recipient, refund)) + + const scriptVersion = 0 + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, err := ExtractAtomicSwapDataPushes(scriptVersion, script) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} -- 2.45.2 From 6ec9b73a53a1f7480a5c251e639b754d95f25c27 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 03:05:55 -0700 Subject: [PATCH 065/459] txscript/scriptnum: add maxscriptnum and maxcltvlength --- txscript/scriptnum.go | 20 ++++-- txscript/scriptnum_test.go | 126 ++++++++++++++++++------------------- txscript/stack.go | 4 +- 3 files changed, 81 insertions(+), 69 deletions(-) diff --git a/txscript/scriptnum.go b/txscript/scriptnum.go index a89d5f39..81f26361 100644 --- a/txscript/scriptnum.go +++ b/txscript/scriptnum.go @@ -12,9 +12,21 @@ const ( maxInt32 = 1<<31 - 1 minInt32 = -1 << 31 - // defaultScriptNumLen is the default number of bytes - // data being interpreted as an integer may be. - defaultScriptNumLen = 4 + // maxScriptNumLen is the maximum number of bytes data being interpreted + // as an integer may be for the majority of op codes. + maxScriptNumLen = 4 + + // cltvMaxScriptNumLen is the maximum number of bytes data being interpreted + // as an integer may be for by-time and by-height locks as interpreted by + // CHECKLOCKTIMEVERIFY. + // + // The value comes from the fact that the current transaction locktime + // is a uint32 resulting in a maximum locktime of 2^32-1 (the year + // 2106). However, scriptNums are signed and therefore a standard + // 4-byte scriptNum would only support up to a maximum of 2^31-1 (the + // year 2038). Thus, a 5-byte scriptNum is needed since it will support + // up to 2^39-1 which allows dates beyond the current locktime limit. + cltvMaxScriptNumLen = 5 ) // scriptNum represents a numeric value used in the scripting engine with @@ -178,7 +190,7 @@ func (n scriptNum) Int32() int32 { // before an ErrStackNumberTooBig is returned. This effectively limits the // range of allowed values. // WARNING: Great care should be taken if passing a value larger than -// defaultScriptNumLen, which could lead to addition and multiplication +// maxScriptNumLen, which could lead to addition and multiplication // overflows. // // See the Bytes function documentation for example encodings. diff --git a/txscript/scriptnum_test.go b/txscript/scriptnum_test.go index e32862b7..668f912f 100644 --- a/txscript/scriptnum_test.go +++ b/txscript/scriptnum_test.go @@ -104,35 +104,35 @@ func TestMakeScriptNum(t *testing.T) { err error }{ // Minimal encoding must reject negative 0. - {hexToBytes("80"), 0, defaultScriptNumLen, true, errMinimalData}, + {hexToBytes("80"), 0, maxScriptNumLen, true, errMinimalData}, // Minimally encoded valid values with minimal encoding flag. // Should not error and return expected integral number. - {nil, 0, defaultScriptNumLen, true, nil}, - {hexToBytes("01"), 1, defaultScriptNumLen, true, nil}, - {hexToBytes("81"), -1, defaultScriptNumLen, true, nil}, - {hexToBytes("7f"), 127, defaultScriptNumLen, true, nil}, - {hexToBytes("ff"), -127, defaultScriptNumLen, true, nil}, - {hexToBytes("8000"), 128, defaultScriptNumLen, true, nil}, - {hexToBytes("8080"), -128, defaultScriptNumLen, true, nil}, - {hexToBytes("8100"), 129, defaultScriptNumLen, true, nil}, - {hexToBytes("8180"), -129, defaultScriptNumLen, true, nil}, - {hexToBytes("0001"), 256, defaultScriptNumLen, true, nil}, - {hexToBytes("0081"), -256, defaultScriptNumLen, true, nil}, - {hexToBytes("ff7f"), 32767, defaultScriptNumLen, true, nil}, - {hexToBytes("ffff"), -32767, defaultScriptNumLen, true, nil}, - {hexToBytes("008000"), 32768, defaultScriptNumLen, true, nil}, - {hexToBytes("008080"), -32768, defaultScriptNumLen, true, nil}, - {hexToBytes("ffff00"), 65535, defaultScriptNumLen, true, nil}, - {hexToBytes("ffff80"), -65535, defaultScriptNumLen, true, nil}, - {hexToBytes("000008"), 524288, defaultScriptNumLen, true, nil}, - {hexToBytes("000088"), -524288, defaultScriptNumLen, true, nil}, - {hexToBytes("000070"), 7340032, defaultScriptNumLen, true, nil}, - {hexToBytes("0000f0"), -7340032, defaultScriptNumLen, true, nil}, - {hexToBytes("00008000"), 8388608, defaultScriptNumLen, true, nil}, - {hexToBytes("00008080"), -8388608, defaultScriptNumLen, true, nil}, - {hexToBytes("ffffff7f"), 2147483647, defaultScriptNumLen, true, nil}, - {hexToBytes("ffffffff"), -2147483647, defaultScriptNumLen, true, nil}, + {nil, 0, maxScriptNumLen, true, nil}, + {hexToBytes("01"), 1, maxScriptNumLen, true, nil}, + {hexToBytes("81"), -1, maxScriptNumLen, true, nil}, + {hexToBytes("7f"), 127, maxScriptNumLen, true, nil}, + {hexToBytes("ff"), -127, maxScriptNumLen, true, nil}, + {hexToBytes("8000"), 128, maxScriptNumLen, true, nil}, + {hexToBytes("8080"), -128, maxScriptNumLen, true, nil}, + {hexToBytes("8100"), 129, maxScriptNumLen, true, nil}, + {hexToBytes("8180"), -129, maxScriptNumLen, true, nil}, + {hexToBytes("0001"), 256, maxScriptNumLen, true, nil}, + {hexToBytes("0081"), -256, maxScriptNumLen, true, nil}, + {hexToBytes("ff7f"), 32767, maxScriptNumLen, true, nil}, + {hexToBytes("ffff"), -32767, maxScriptNumLen, true, nil}, + {hexToBytes("008000"), 32768, maxScriptNumLen, true, nil}, + {hexToBytes("008080"), -32768, maxScriptNumLen, true, nil}, + {hexToBytes("ffff00"), 65535, maxScriptNumLen, true, nil}, + {hexToBytes("ffff80"), -65535, maxScriptNumLen, true, nil}, + {hexToBytes("000008"), 524288, maxScriptNumLen, true, nil}, + {hexToBytes("000088"), -524288, maxScriptNumLen, true, nil}, + {hexToBytes("000070"), 7340032, maxScriptNumLen, true, nil}, + {hexToBytes("0000f0"), -7340032, maxScriptNumLen, true, nil}, + {hexToBytes("00008000"), 8388608, maxScriptNumLen, true, nil}, + {hexToBytes("00008080"), -8388608, maxScriptNumLen, true, nil}, + {hexToBytes("ffffff7f"), 2147483647, maxScriptNumLen, true, nil}, + {hexToBytes("ffffffff"), -2147483647, maxScriptNumLen, true, nil}, {hexToBytes("ffffffff7f"), 549755813887, 5, true, nil}, {hexToBytes("ffffffffff"), -549755813887, 5, true, nil}, {hexToBytes("ffffffffffffff7f"), 9223372036854775807, 8, true, nil}, @@ -145,50 +145,50 @@ func TestMakeScriptNum(t *testing.T) { // Minimally encoded values that are out of range for data that // is interpreted as script numbers with the minimal encoding // flag set. Should error and return 0. - {hexToBytes("0000008000"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000008080"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000009000"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000009080"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffff00"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffff80"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000000001"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000000081"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffff00"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffff80"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffffff00"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffffff80"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffffff7f"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffffffff"), 0, defaultScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000008000"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000008080"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000009000"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000009080"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffff00"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffff80"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000000001"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000000081"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffff00"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffff80"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffffff00"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffffff80"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffffff7f"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffffffff"), 0, maxScriptNumLen, true, errNumTooBig}, // Non-minimally encoded, but otherwise valid values with // minimal encoding flag. Should error and return 0. - {hexToBytes("00"), 0, defaultScriptNumLen, true, errMinimalData}, // 0 - {hexToBytes("0100"), 0, defaultScriptNumLen, true, errMinimalData}, // 1 - {hexToBytes("7f00"), 0, defaultScriptNumLen, true, errMinimalData}, // 127 - {hexToBytes("800000"), 0, defaultScriptNumLen, true, errMinimalData}, // 128 - {hexToBytes("810000"), 0, defaultScriptNumLen, true, errMinimalData}, // 129 - {hexToBytes("000100"), 0, defaultScriptNumLen, true, errMinimalData}, // 256 - {hexToBytes("ff7f00"), 0, defaultScriptNumLen, true, errMinimalData}, // 32767 - {hexToBytes("00800000"), 0, defaultScriptNumLen, true, errMinimalData}, // 32768 - {hexToBytes("ffff0000"), 0, defaultScriptNumLen, true, errMinimalData}, // 65535 - {hexToBytes("00000800"), 0, defaultScriptNumLen, true, errMinimalData}, // 524288 - {hexToBytes("00007000"), 0, defaultScriptNumLen, true, errMinimalData}, // 7340032 - {hexToBytes("0009000100"), 0, 5, true, errMinimalData}, // 16779520 + {hexToBytes("00"), 0, maxScriptNumLen, true, errMinimalData}, // 0 + {hexToBytes("0100"), 0, maxScriptNumLen, true, errMinimalData}, // 1 + {hexToBytes("7f00"), 0, maxScriptNumLen, true, errMinimalData}, // 127 + {hexToBytes("800000"), 0, maxScriptNumLen, true, errMinimalData}, // 128 + {hexToBytes("810000"), 0, maxScriptNumLen, true, errMinimalData}, // 129 + {hexToBytes("000100"), 0, maxScriptNumLen, true, errMinimalData}, // 256 + {hexToBytes("ff7f00"), 0, maxScriptNumLen, true, errMinimalData}, // 32767 + {hexToBytes("00800000"), 0, maxScriptNumLen, true, errMinimalData}, // 32768 + {hexToBytes("ffff0000"), 0, maxScriptNumLen, true, errMinimalData}, // 65535 + {hexToBytes("00000800"), 0, maxScriptNumLen, true, errMinimalData}, // 524288 + {hexToBytes("00007000"), 0, maxScriptNumLen, true, errMinimalData}, // 7340032 + {hexToBytes("0009000100"), 0, 5, true, errMinimalData}, // 16779520 // Non-minimally encoded, but otherwise valid values without // minimal encoding flag. Should not error and return expected // integral number. - {hexToBytes("00"), 0, defaultScriptNumLen, false, nil}, - {hexToBytes("0100"), 1, defaultScriptNumLen, false, nil}, - {hexToBytes("7f00"), 127, defaultScriptNumLen, false, nil}, - {hexToBytes("800000"), 128, defaultScriptNumLen, false, nil}, - {hexToBytes("810000"), 129, defaultScriptNumLen, false, nil}, - {hexToBytes("000100"), 256, defaultScriptNumLen, false, nil}, - {hexToBytes("ff7f00"), 32767, defaultScriptNumLen, false, nil}, - {hexToBytes("00800000"), 32768, defaultScriptNumLen, false, nil}, - {hexToBytes("ffff0000"), 65535, defaultScriptNumLen, false, nil}, - {hexToBytes("00000800"), 524288, defaultScriptNumLen, false, nil}, - {hexToBytes("00007000"), 7340032, defaultScriptNumLen, false, nil}, + {hexToBytes("00"), 0, maxScriptNumLen, false, nil}, + {hexToBytes("0100"), 1, maxScriptNumLen, false, nil}, + {hexToBytes("7f00"), 127, maxScriptNumLen, false, nil}, + {hexToBytes("800000"), 128, maxScriptNumLen, false, nil}, + {hexToBytes("810000"), 129, maxScriptNumLen, false, nil}, + {hexToBytes("000100"), 256, maxScriptNumLen, false, nil}, + {hexToBytes("ff7f00"), 32767, maxScriptNumLen, false, nil}, + {hexToBytes("00800000"), 32768, maxScriptNumLen, false, nil}, + {hexToBytes("ffff0000"), 65535, maxScriptNumLen, false, nil}, + {hexToBytes("00000800"), 524288, maxScriptNumLen, false, nil}, + {hexToBytes("00007000"), 7340032, maxScriptNumLen, false, nil}, {hexToBytes("0009000100"), 16779520, 5, false, nil}, } diff --git a/txscript/stack.go b/txscript/stack.go index eb1d8cfd..923047d9 100644 --- a/txscript/stack.go +++ b/txscript/stack.go @@ -86,7 +86,7 @@ func (s *stack) PopInt() (scriptNum, error) { return 0, err } - return makeScriptNum(so, s.verifyMinimalData, defaultScriptNumLen) + return makeScriptNum(so, s.verifyMinimalData, maxScriptNumLen) } // PopBool pops the value off the top of the stack, converts it into a bool, and @@ -123,7 +123,7 @@ func (s *stack) PeekInt(idx int32) (scriptNum, error) { return 0, err } - return makeScriptNum(so, s.verifyMinimalData, defaultScriptNumLen) + return makeScriptNum(so, s.verifyMinimalData, maxScriptNumLen) } // PeekBool returns the Nth item on the stack as a bool without removing it. -- 2.45.2 From 367a75a3f410da2eda19b19b06e9b2eba24511b8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:25 -0500 Subject: [PATCH 066/459] txscript: Optimize ExtractAtomicSwapDataPushes. This converts the ExtractAtomicSwapDataPushes function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. The new implementation is designed such that it should be fairly easy to move the function into the atomic swap tools where it more naturally belongs now that the tokenizer makes it possible to analyze scripts outside of the txscript module. Consequently, this also deprecates the function. The following is a before and after comparison of attempting to extract from both a typical atomic swap script and a very large non-atomic swap script: benchmark old ns/op new ns/op delta BenchmarkExtractAtomicSwapDataPushesLarge-8 61332 44.4 -99.93% BenchmarkExtractAtomicSwapDataPushes-8 990 260 -73.74% benchmark old allocs new allocs delta BenchmarkExtractAtomicSwapDataPushesLarge-8 1 0 -100.00% BenchmarkExtractAtomicSwapDataPushes-8 2 1 -50.00% benchmark old bytes new bytes delta BenchmarkExtractAtomicSwapDataPushesLarge-8 311299 0 -100.00% BenchmarkExtractAtomicSwapDataPushes-8 3168 96 -96.97% --- txscript/standard.go | 144 +++++++++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 53 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index d97072f1..041516e2 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -942,64 +942,102 @@ type AtomicSwapDataPushes struct { // // This function is only defined in the txscript package due to API limitations // which prevent callers using txscript to parse nonstandard scripts. +// +// DEPRECATED. This will be removed in the next major version bump. The error +// should also likely be removed if the code is reimplemented by any callers +// since any errors result in a nil result anyway. func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDataPushes, error) { - pops, err := parseScript(pkScript) - if err != nil { + // An atomic swap is of the form: + // IF + // SIZE EQUALVERIFY SHA256 <32-byte secret> EQUALVERIFY DUP + // HASH160 <20-byte recipient hash> + // ELSE + // CHECKLOCKTIMEVERIFY DROP DUP HASH160 <20-byte refund hash> + // ENDIF + // EQUALVERIFY CHECKSIG + type templateMatch struct { + expectCanonicalInt bool + maxIntBytes int + opcode byte + extractedInt int64 + extractedData []byte + } + var template = [20]templateMatch{ + {opcode: OP_IF}, + {opcode: OP_SIZE}, + {expectCanonicalInt: true, maxIntBytes: maxScriptNumLen}, + {opcode: OP_EQUALVERIFY}, + {opcode: OP_SHA256}, + {opcode: OP_DATA_32}, + {opcode: OP_EQUALVERIFY}, + {opcode: OP_DUP}, + {opcode: OP_HASH160}, + {opcode: OP_DATA_20}, + {opcode: OP_ELSE}, + {expectCanonicalInt: true, maxIntBytes: cltvMaxScriptNumLen}, + {opcode: OP_CHECKLOCKTIMEVERIFY}, + {opcode: OP_DROP}, + {opcode: OP_DUP}, + {opcode: OP_HASH160}, + {opcode: OP_DATA_20}, + {opcode: OP_ENDIF}, + {opcode: OP_EQUALVERIFY}, + {opcode: OP_CHECKSIG}, + } + + var templateOffset int + tokenizer := MakeScriptTokenizer(version, pkScript) + for tokenizer.Next() { + // Not an atomic swap script if it has more opcodes than expected in the + // template. + if templateOffset >= len(template) { + return nil, nil + } + + op := tokenizer.Opcode() + data := tokenizer.Data() + tplEntry := &template[templateOffset] + if tplEntry.expectCanonicalInt { + switch { + case data != nil: + val, err := makeScriptNum(data, true, tplEntry.maxIntBytes) + if err != nil { + return nil, err + } + tplEntry.extractedInt = int64(val) + + case isSmallInt(op): + tplEntry.extractedInt = int64(asSmallInt(op)) + + // Not an atomic swap script if the opcode does not push an int. + default: + return nil, nil + } + } else { + if op != tplEntry.opcode { + return nil, nil + } + + tplEntry.extractedData = data + } + + templateOffset++ + } + if err := tokenizer.Err(); err != nil { return nil, err } - - if len(pops) != 20 { - return nil, nil - } - isAtomicSwap := pops[0].opcode.value == OP_IF && - pops[1].opcode.value == OP_SIZE && - isCanonicalPush(pops[2].opcode.value, pops[2].data) && - pops[3].opcode.value == OP_EQUALVERIFY && - pops[4].opcode.value == OP_SHA256 && - pops[5].opcode.value == OP_DATA_32 && - pops[6].opcode.value == OP_EQUALVERIFY && - pops[7].opcode.value == OP_DUP && - pops[8].opcode.value == OP_HASH160 && - pops[9].opcode.value == OP_DATA_20 && - pops[10].opcode.value == OP_ELSE && - isCanonicalPush(pops[11].opcode.value, pops[11].data) && - pops[12].opcode.value == OP_CHECKLOCKTIMEVERIFY && - pops[13].opcode.value == OP_DROP && - pops[14].opcode.value == OP_DUP && - pops[15].opcode.value == OP_HASH160 && - pops[16].opcode.value == OP_DATA_20 && - pops[17].opcode.value == OP_ENDIF && - pops[18].opcode.value == OP_EQUALVERIFY && - pops[19].opcode.value == OP_CHECKSIG - if !isAtomicSwap { + if !tokenizer.Done() || templateOffset != len(template) { return nil, nil } - pushes := new(AtomicSwapDataPushes) - copy(pushes.SecretHash[:], pops[5].data) - copy(pushes.RecipientHash160[:], pops[9].data) - copy(pushes.RefundHash160[:], pops[16].data) - if pops[2].data != nil { - locktime, err := makeScriptNum(pops[2].data, true, 5) - if err != nil { - return nil, nil - } - pushes.SecretSize = int64(locktime) - } else if op := pops[2].opcode; isSmallInt(op.value) { - pushes.SecretSize = int64(asSmallInt(op.value)) - } else { - return nil, nil + // At this point, the script appears to be an atomic swap, so populate and + // return the extacted data. + pushes := AtomicSwapDataPushes{ + SecretSize: template[2].extractedInt, + LockTime: template[11].extractedInt, } - if pops[11].data != nil { - locktime, err := makeScriptNum(pops[11].data, true, 5) - if err != nil { - return nil, nil - } - pushes.LockTime = int64(locktime) - } else if op := pops[11].opcode; isSmallInt(op.value) { - pushes.LockTime = int64(asSmallInt(op.value)) - } else { - return nil, nil - } - return pushes, nil + copy(pushes.SecretHash[:], template[5].extractedData) + copy(pushes.RecipientHash160[:], template[9].extractedData) + copy(pushes.RefundHash160[:], template[16].extractedData) + return &pushes, nil } -- 2.45.2 From 33ee3e2f53476fa96b80093aa3cbbaaea7091682 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:26 -0500 Subject: [PATCH 067/459] txscript: Add ExtractPkScriptAddrs benchmarks. --- txscript/bench_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 456db25d..cac29202 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -10,6 +10,7 @@ import ( "io/ioutil" "testing" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" ) @@ -497,3 +498,40 @@ func BenchmarkExtractAtomicSwapDataPushes(b *testing.B) { } } } + +// BenchmarkExtractPkScriptAddrsLarge benchmarks how long it takes to analyze +// and potentially extract addresses from a very large non-standard script. +func BenchmarkExtractPkScriptAddrsLarge(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + params := &chaincfg.MainNetParams + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, _, _, err := ExtractPkScriptAddrs(script, params) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} + +// BenchmarkExtractPkScriptAddrs benchmarks how long it takes to analyze and +// potentially extract addresses from a typical script. +func BenchmarkExtractPkScriptAddrs(b *testing.B) { + script := mustParseShortForm("OP_DUP HASH160 " + + "DATA_20 0x0102030405060708090a0b0c0d0e0f1011121314 " + + "EQUAL") + + params := &chaincfg.MainNetParams + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, _, _, err := ExtractPkScriptAddrs(script, params) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} -- 2.45.2 From 055be988c06449007774923b6ff7a8adf8bab945 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:27 -0500 Subject: [PATCH 068/459] txscript: Optimize ExtractPkScriptAddrs scripthash. This begins the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In order to ease the review process, the detection of each script type will be converted in a separate commit such that the script is only parsed as a fallback for the cases that are not already converted to more efficient variants. In particular, this converts the detection for pay-to-script-hash scripts. --- txscript/standard.go | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 041516e2..f55cbf98 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -813,11 +813,36 @@ func PushedData(script []byte) ([][]byte, error) { return data, nil } +// scriptHashToAddrs is a convenience function to attempt to convert the passed +// hash to a pay-to-script-hash address housed within an address slice. It is +// used to consolidate common code. +func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address { + // Skip the hash if it's invalid for some reason. + var addrs []btcutil.Address + addr, err := btcutil.NewAddressScriptHashFromHash(hash, params) + if err == nil { + addrs = append(addrs, addr) + } + return addrs +} + // ExtractPkScriptAddrs returns the type of script, addresses and required // signatures associated with the passed PkScript. Note that it only works for // 'standard' transaction script types. Any data such as public keys which are // invalid are omitted from the results. func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, error) { + + // Avoid parsing the script for the cases that already have the able to + // work with raw scripts. + + // Check for pay-to-script-hash. + if hash := extractScriptHash(pkScript); hash != nil { + return ScriptHashTy, scriptHashToAddrs(hash, chainParams), 1, nil + } + + // Fall back to slow path. Ultimately these are intended to be replaced by + // faster variants based on the unparsed raw scripts. + var addrs []btcutil.Address var requiredSigs int @@ -867,18 +892,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script addrs = append(addrs, addr) } - case ScriptHashTy: - // A pay-to-script-hash script is of the form: - // OP_HASH160 OP_EQUAL - // Therefore the script hash is the 2nd item on the stack. - // Skip the script hash if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressScriptHashFromHash(pops[1].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case WitnessV0ScriptHashTy: // A pay-to-witness-script-hash script is of the form: // OP_0 <32-byte hash> -- 2.45.2 From 16bd6633b64f2fa8b91c580900136545e4cbf350 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:28 -0500 Subject: [PATCH 069/459] txscript: Optimize ExtractPkScriptAddrs pubkeyhash. This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the detection for pay-to-pubkey-hash scripts. --- txscript/standard.go | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index f55cbf98..af506606 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -813,6 +813,19 @@ func PushedData(script []byte) ([][]byte, error) { return data, nil } +// pubKeyHashToAddrs is a convenience function to attempt to convert the +// passed hash to a pay-to-pubkey-hash address housed within an address +// slice. It is used to consolidate common code. +func pubKeyHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address { + // Skip the pubkey hash if it's invalid for some reason. + var addrs []btcutil.Address + addr, err := btcutil.NewAddressPubKeyHash(hash, params) + if err == nil { + addrs = append(addrs, addr) + } + return addrs +} + // scriptHashToAddrs is a convenience function to attempt to convert the passed // hash to a pay-to-script-hash address housed within an address slice. It is // used to consolidate common code. @@ -835,6 +848,11 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script // Avoid parsing the script for the cases that already have the able to // work with raw scripts. + // Check for pay-to-pubkey-hash script. + if hash := extractPubKeyHash(pkScript); hash != nil { + return PubKeyHashTy, pubKeyHashToAddrs(hash, chainParams), 1, nil + } + // Check for pay-to-script-hash. if hash := extractScriptHash(pkScript); hash != nil { return ScriptHashTy, scriptHashToAddrs(hash, chainParams), 1, nil @@ -857,18 +875,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script scriptClass := typeOfScript(scriptVersion, pkScript) switch scriptClass { - case PubKeyHashTy: - // A pay-to-pubkey-hash script is of the form: - // OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG - // Therefore the pubkey hash is the 3rd item on the stack. - // Skip the pubkey hash if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressPubKeyHash(pops[2].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case WitnessV0PubKeyHashTy: // A pay-to-witness-pubkey-hash script is of thw form: // OP_0 <20-byte hash> -- 2.45.2 From 0e810b4ef4a06de24f804f71bbbe12b96edd71e9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:31 -0500 Subject: [PATCH 070/459] txscript: Optimize ExtractPkScriptAddrs pubkey. This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the detection for pay-to-pubkey scripts. --- txscript/standard.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index af506606..6377598c 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -858,6 +858,16 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return ScriptHashTy, scriptHashToAddrs(hash, chainParams), 1, nil } + // Check for pay-to-pubkey script. + if data := extractPubKey(pkScript); data != nil { + var addrs []btcutil.Address + addr, err := btcutil.NewAddressPubKey(data, chainParams) + if err == nil { + addrs = append(addrs, addr) + } + return PubKeyTy, addrs, 1, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. @@ -887,17 +897,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script addrs = append(addrs, addr) } - case PubKeyTy: - // A pay-to-pubkey script is of the form: - // OP_CHECKSIG - // Therefore the pubkey is the first item on the stack. - // Skip the pubkey if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressPubKey(pops[0].data, chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case WitnessV0ScriptHashTy: // A pay-to-witness-script-hash script is of the form: // OP_0 <32-byte hash> -- 2.45.2 From 0bc18254d403ea3d1a77626fa86dc0091c83be15 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:33 -0500 Subject: [PATCH 071/459] txscript: Optimize ExtractPkScriptAddrs multisig. This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the detection for multisig scripts. Also, since the remaining slow path cases are all recursive calls, the parsed opcodes are no longer used, so parsing is removed. --- txscript/standard.go | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 6377598c..b187ac01 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -868,11 +868,27 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return PubKeyTy, addrs, 1, nil } + // Check for multi-signature script. + const scriptVersion = 0 + details := extractMultisigScriptDetails(scriptVersion, pkScript, true) + if details.valid { + // Convert the public keys while skipping any that are invalid. + addrs := make([]btcutil.Address, 0, len(details.pubKeys)) + for _, pubkey := range details.pubKeys { + addr, err := btcutil.NewAddressPubKey(pubkey, chainParams) + if err == nil { + addrs = append(addrs, addr) + } + } + return MultiSigTy, addrs, details.requiredSigs, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. var addrs []btcutil.Address var requiredSigs int + var err error // No valid addresses or required signatures if the script doesn't // parse. @@ -881,7 +897,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return NonStandardTy, nil, 0, err } - const scriptVersion = 0 scriptClass := typeOfScript(scriptVersion, pkScript) switch scriptClass { @@ -909,25 +924,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script addrs = append(addrs, addr) } - case MultiSigTy: - // A multi-signature script is of the form: - // ... OP_CHECKMULTISIG - // Therefore the number of required signatures is the 1st item - // on the stack and the number of public keys is the 2nd to last - // item on the stack. - requiredSigs = asSmallInt(pops[0].opcode.value) - numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value) - - // Extract the public keys while skipping any that are invalid. - addrs = make([]btcutil.Address, 0, numPubKeys) - for i := 0; i < numPubKeys; i++ { - addr, err := btcutil.NewAddressPubKey(pops[i+1].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - } - case NullDataTy: // Null data transactions have no addresses or required // signatures. -- 2.45.2 From 507a4dcc005dea7bf3c1742498cd68de6977a9de Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:38 -0500 Subject: [PATCH 072/459] txscript: Optimize ExtractPkScriptAddrs nulldata. This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the detection for nulldata scripts, removes the slow path fallback code since it is the final case, and modifies the comment to call out the script version semantics. The following is a before and after comparison of analyzing both a typical standard script and a very large non-standard script: benchmark old ns/op new ns/op delta ----------------------------------------------------------------------- BenchmarkExtractPkScriptAddrsLarge 132400 44.4 -99.97% BenchmarkExtractPkScriptAddrs 1265 231 -81.74% benchmark old allocs new allocs delta ----------------------------------------------------------------------- BenchmarkExtractPkScriptAddrsLarge 1 0 -100.00% BenchmarkExtractPkScriptAddrs 5 2 -60.00% benchmark old bytes new bytes delta ----------------------------------------------------------------------- BenchmarkExtractPkScriptAddrsLarge 466944 0 -100.00% BenchmarkExtractPkScriptAddrs 1600 48 -97.00% --- txscript/standard.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index b187ac01..89c21966 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -843,11 +843,12 @@ func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address { // signatures associated with the passed PkScript. Note that it only works for // 'standard' transaction script types. Any data such as public keys which are // invalid are omitted from the results. +// +// NOTE: This function only attempts to identify version 0 scripts. The return +// value will indicate a nonstandard script type for other script versions along +// with an invalid script version error. func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, error) { - // Avoid parsing the script for the cases that already have the able to - // work with raw scripts. - // Check for pay-to-pubkey-hash script. if hash := extractPubKeyHash(pkScript); hash != nil { return PubKeyHashTy, pubKeyHashToAddrs(hash, chainParams), 1, nil @@ -883,6 +884,12 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return MultiSigTy, addrs, details.requiredSigs, nil } + // Check for null data script. + if isNullDataScript(scriptVersion, pkScript) { + // Null data transactions have no addresses or required signatures. + return NullDataTy, nil, 0, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. @@ -924,15 +931,13 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script addrs = append(addrs, addr) } - case NullDataTy: - // Null data transactions have no addresses or required - // signatures. - case NonStandardTy: // Don't attempt to extract addresses or required signatures for // nonstandard transactions. } + // Don't attempt to extract addresses or required signatures for nonstandard + // transactions. return scriptClass, addrs, requiredSigs, nil } -- 2.45.2 From ae7fffbe52af902984f38c55e558a2334ef1fe69 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:18:51 -0700 Subject: [PATCH 073/459] txscript: Optimize ExtractPkScriptAddrs witness pubkey hash This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the extraction for witness-pubkey-hash scripts. --- txscript/standard.go | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 89c21966..c0178250 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -890,6 +890,15 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return NullDataTy, nil, 0, nil } + if hash := extractWitnessPubKeyHash(pkScript); hash != nil { + var addrs []btcutil.Address + addr, err := btcutil.NewAddressWitnessPubKeyHash(hash, chainParams) + if err == nil { + addrs = append(addrs, addr) + } + return WitnessV0PubKeyHashTy, addrs, 1, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. @@ -907,18 +916,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script scriptClass := typeOfScript(scriptVersion, pkScript) switch scriptClass { - case WitnessV0PubKeyHashTy: - // A pay-to-witness-pubkey-hash script is of thw form: - // OP_0 <20-byte hash> - // Therefore, the pubkey hash is the second item on the stack. - // Skip the pubkey hash if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressWitnessPubKeyHash(pops[1].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case WitnessV0ScriptHashTy: // A pay-to-witness-script-hash script is of the form: // OP_0 <32-byte hash> -- 2.45.2 From a83152214ccf3fd4972a011e065e37a982343778 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:22:52 -0700 Subject: [PATCH 074/459] txscript: Optimize ExtractPkScriptAddrs witness script hash This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the extract of witness-pay-to-script-hash scripts. --- txscript/standard.go | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index c0178250..d9f8a9a3 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -899,35 +899,24 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return WitnessV0PubKeyHashTy, addrs, 1, nil } + if hash := extractWitnessScriptHash(pkScript); hash != nil { + var addrs []btcutil.Address + addr, err := btcutil.NewAddressWitnessScriptHash(hash, chainParams) + if err == nil { + addrs = append(addrs, addr) + } + return WitnessV0ScriptHashTy, addrs, 1, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. var addrs []btcutil.Address var requiredSigs int - var err error - - // No valid addresses or required signatures if the script doesn't - // parse. - pops, err := parseScript(pkScript) - if err != nil { - return NonStandardTy, nil, 0, err - } scriptClass := typeOfScript(scriptVersion, pkScript) switch scriptClass { - case WitnessV0ScriptHashTy: - // A pay-to-witness-script-hash script is of the form: - // OP_0 <32-byte hash> - // Therefore, the script hash is the second item on the stack. - // Skip the script hash if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressWitnessScriptHash(pops[1].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case NonStandardTy: // Don't attempt to extract addresses or required signatures for // nonstandard transactions. -- 2.45.2 From 1034a66b357483b61c368232a4df9fc40ddc45ad Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:32:37 -0700 Subject: [PATCH 075/459] txscript: Optimize ExtractPkScriptAddr assume non-standard if no success This completes the process of converting the ExtractPkScriptAddr function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this cleans up the final remaining case for non-standard transactions. The method now returns NonStandardTy direclty if no other branch was taken. The following is a before and after comparison of attempting to extract pkscript addrs from a very large, non-standard script. benchmark old ns/op new ns/op delta BenchmarkExtractPkScriptAddrsLarge-8 60713 17.0 -99.97% BenchmarkExtractPkScriptAddrs-8 289 17.0 -94.12% benchmark old allocs new allocs delta BenchmarkExtractPkScriptAddrsLarge-8 1 0 -100.00% BenchmarkExtractPkScriptAddrs-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkExtractPkScriptAddrsLarge-8 311299 0 -100.00% BenchmarkExtractPkScriptAddrs-8 768 0 -100.00% --- txscript/standard.go | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index d9f8a9a3..326d14d8 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -908,23 +908,8 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return WitnessV0ScriptHashTy, addrs, 1, nil } - // Fall back to slow path. Ultimately these are intended to be replaced by - // faster variants based on the unparsed raw scripts. - - var addrs []btcutil.Address - var requiredSigs int - - scriptClass := typeOfScript(scriptVersion, pkScript) - - switch scriptClass { - case NonStandardTy: - // Don't attempt to extract addresses or required signatures for - // nonstandard transactions. - } - - // Don't attempt to extract addresses or required signatures for nonstandard - // transactions. - return scriptClass, addrs, requiredSigs, nil + // If none of the above passed, then the address must be non-standard. + return NonStandardTy, nil, 0, nil } // AtomicSwapDataPushes houses the data pushes found in atomic swap contracts. -- 2.45.2 From 6fb1c82fe5d14b4b2d7bba13c2d727051107aa25 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 18:58:28 -0700 Subject: [PATCH 076/459] txscript: Optimize IsWitnessProgram --- txscript/script.go | 17 +++-------------- txscript/standard.go | 45 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 52bedf26..1ca953de 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -103,20 +103,7 @@ func isWitnessPubKeyHash(pops []parsedOpcode) bool { // witness program must be a small integer (from 0-16), followed by 2-40 bytes // of pushed data. func IsWitnessProgram(script []byte) bool { - // The length of the script must be between 4 and 42 bytes. The - // smallest program is the witness version, followed by a data push of - // 2 bytes. The largest allowed witness program has a data push of - // 40-bytes. - if len(script) < 4 || len(script) > 42 { - return false - } - - pops, err := parseScript(script) - if err != nil { - return false - } - - return isWitnessProgram(pops) + return isWitnessProgramScript(script) } // isWitnessProgram returns true if the passed script is a witness program, and @@ -125,6 +112,8 @@ func IsWitnessProgram(script []byte) bool { // first opcode MUST be a small integer (0-16), the push data MUST be // canonical, and finally the size of the push data must be between 2 and 40 // bytes. +// +// DEPRECATED: Use isWitnessProgramScript instead. func isWitnessProgram(pops []parsedOpcode) bool { return len(pops) == 2 && isSmallInt(pops[0].opcode.value) && diff --git a/txscript/standard.go b/txscript/standard.go index 326d14d8..4b7d9be5 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -387,6 +387,51 @@ func isWitnessScriptHashScript(script []byte) bool { return extractWitnessScriptHash(script) != nil } +// isWitnessProgramScript returns true if the passed script is a witness +// program, and false otherwise. A witness program MUST adhere to the following +// constraints: there must be exactly two pops (program version and the program +// itself), the first opcode MUST be a small integer (0-16), the push data MUST +// be canonical, and finally the size of the push data must be between 2 and 40 +// bytes. +// +// The length of the script must be between 4 and 42 bytes. The +// smallest program is the witness version, followed by a data push of +// 2 bytes. The largest allowed witness program has a data push of +// 40-bytes. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func isWitnessProgramScript(script []byte) bool { + // Skip parsing if we know the program is invalid based on size. + if len(script) < 4 || len(script) > 42 { + return false + } + + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + + // The first opcode must be a small int. + if !tokenizer.Next() || + !isSmallInt(tokenizer.Opcode()) { + + return false + } + + // The second opcode must be a canonical data push, the length of the + // data push is bounded to 40 by the initial check on overall script + // length. + if !tokenizer.Next() || + !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { + + return false + } + + // The witness program is valid if there are no more opcodes, and we + // terminated without a parsing error. + return tokenizer.Done() && tokenizer.Err() == nil +} + // isNullDataScript returns whether or not the passed script is a standard // null data script. // -- 2.45.2 From 8b706344a1fbbc5307058d2d9beaa054cb43ab49 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:39:28 -0700 Subject: [PATCH 077/459] txscript: Return witness version and program in one pass --- txscript/standard.go | 66 ++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 4b7d9be5..e3cf7707 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -387,6 +387,43 @@ func isWitnessScriptHashScript(script []byte) bool { return extractWitnessScriptHash(script) != nil } +// extractWitnessProgramInfo returns the version and program if the passed +// script constitutes a valid witness program. The alst return value indicates +// whether or not the script is a valid witness program. +func extractWitnessProgramInfo(script []byte) (int, []byte, bool) { + // Skip parsing if we know the program is invalid based on size. + if len(script) < 4 || len(script) > 42 { + return 0, nil, false + } + + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + + // The first opcode must be a small int. + if !tokenizer.Next() || + !isSmallInt(tokenizer.Opcode()) { + + return 0, nil, false + } + version := asSmallInt(tokenizer.Opcode()) + + // The second opcode must be a canonical data push, the length of the + // data push is bounded to 40 by the initial check on overall script + // length. + if !tokenizer.Next() || + !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { + + return 0, nil, false + } + program := tokenizer.Data() + + // The witness program is valid if there are no more opcodes, and we + // terminated without a parsing error. + valid := tokenizer.Done() && tokenizer.Err() == nil + + return version, program, valid +} + // isWitnessProgramScript returns true if the passed script is a witness // program, and false otherwise. A witness program MUST adhere to the following // constraints: there must be exactly two pops (program version and the program @@ -403,33 +440,8 @@ func isWitnessScriptHashScript(script []byte) bool { // does not accept a script version, the results are undefined for other script // versions. func isWitnessProgramScript(script []byte) bool { - // Skip parsing if we know the program is invalid based on size. - if len(script) < 4 || len(script) > 42 { - return false - } - - const scriptVersion = 0 - tokenizer := MakeScriptTokenizer(scriptVersion, script) - - // The first opcode must be a small int. - if !tokenizer.Next() || - !isSmallInt(tokenizer.Opcode()) { - - return false - } - - // The second opcode must be a canonical data push, the length of the - // data push is bounded to 40 by the initial check on overall script - // length. - if !tokenizer.Next() || - !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { - - return false - } - - // The witness program is valid if there are no more opcodes, and we - // terminated without a parsing error. - return tokenizer.Done() && tokenizer.Err() == nil + _, _, valid := extractWitnessProgramInfo(script) + return valid } // isNullDataScript returns whether or not the passed script is a standard -- 2.45.2 From 4b03b593912e1513937d98d7351bf8a58176063f Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 5 Feb 2021 01:58:59 -0800 Subject: [PATCH 078/459] txscript: Use internal analysis methods for GetWitnessSigOpCount --- txscript/script.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 1ca953de..57c7b9be 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -832,15 +832,15 @@ func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, _ bool) int { func GetWitnessSigOpCount(sigScript, pkScript []byte, witness wire.TxWitness) int { // If this is a regular witness program, then we can proceed directly // to counting its signature operations without any further processing. - if IsWitnessProgram(pkScript) { + if isWitnessProgramScript(pkScript) { return getWitnessSigOps(pkScript, witness) } // Next, we'll check the sigScript to see if this is a nested p2sh // witness program. This is a case wherein the sigScript is actually a // datapush of a p2wsh witness program. - if IsPayToScriptHash(pkScript) && IsPushOnlyScript(sigScript) && - IsWitnessProgram(sigScript[1:]) { + if isScriptHashScript(pkScript) && IsPushOnlyScript(sigScript) && + len(sigScript) > 0 && isWitnessProgramScript(sigScript[1:]) { return getWitnessSigOps(sigScript[1:], witness) } -- 2.45.2 From d410d7d7d4fe116508e7aa9a180bd77dd5b9b8c3 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:43:43 -0700 Subject: [PATCH 079/459] txscript: Optimize ExtractWitnessProgramInfo --- txscript/script.go | 13 +++---------- txscript/standard.go | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 57c7b9be..9d7de56c 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -131,23 +131,16 @@ func IsNullData(script []byte) bool { // ExtractWitnessProgramInfo attempts to extract the witness program version, // as well as the witness program itself from the passed script. func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { - pops, err := parseScript(script) - if err != nil { - return 0, nil, err - } - // If at this point, the scripts doesn't resemble a witness program, // then we'll exit early as there isn't a valid version or program to // extract. - if !isWitnessProgram(pops) { + version, program, valid := extractWitnessProgramInfo(script) + if !valid { return 0, nil, fmt.Errorf("script is not a witness program, " + "unable to extract version or witness program") } - witnessVersion := asSmallInt(pops[0].opcode.value) - witnessProgram := pops[1].data - - return witnessVersion, witnessProgram, nil + return version, program, nil } // IsPushOnlyScript returns whether or not the passed script only pushes data diff --git a/txscript/standard.go b/txscript/standard.go index e3cf7707..44902971 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -388,7 +388,7 @@ func isWitnessScriptHashScript(script []byte) bool { } // extractWitnessProgramInfo returns the version and program if the passed -// script constitutes a valid witness program. The alst return value indicates +// script constitutes a valid witness program. The last return value indicates // whether or not the script is a valid witness program. func extractWitnessProgramInfo(script []byte) (int, []byte, bool) { // Skip parsing if we know the program is invalid based on size. -- 2.45.2 From 7ad3a10442d80b204e8276f524d4859aa4d55887 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:46 -0500 Subject: [PATCH 080/459] txscript: mergeMultiSig function def order cleanup. This moves the function definition for mergeMultiSig so it is more consistent with the preferred order used through the codebase. In particular, the functions are defined before they're first used and generally as close as possible to the first use when they're defined in the same file. --- txscript/sign.go | 135 ++++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 67 deletions(-) diff --git a/txscript/sign.go b/txscript/sign.go index b9f8b2db..58791064 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -212,73 +212,6 @@ func sign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, } } -// mergeScripts merges sigScript and prevScript assuming they are both -// partial solutions for pkScript spending output idx of tx. class, addresses -// and nrequired are the result of extracting the addresses from pkscript. -// The return value is the best effort merging of the two scripts. Calling this -// function with addresses, class and nrequired that do not match pkScript is -// an error and results in undefined behaviour. -func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, - pkScript []byte, class ScriptClass, addresses []btcutil.Address, - nRequired int, sigScript, prevScript []byte) []byte { - - // TODO: the scripthash and multisig paths here are overly - // inefficient in that they will recompute already known data. - // some internal refactoring could probably make this avoid needless - // extra calculations. - switch class { - case ScriptHashTy: - // Remove the last push in the script and then recurse. - // this could be a lot less inefficient. - sigPops, err := parseScript(sigScript) - if err != nil || len(sigPops) == 0 { - return prevScript - } - prevPops, err := parseScript(prevScript) - if err != nil || len(prevPops) == 0 { - return sigScript - } - - // assume that script in sigPops is the correct one, we just - // made it. - script := sigPops[len(sigPops)-1].data - - // We already know this information somewhere up the stack. - class, addresses, nrequired, _ := - ExtractPkScriptAddrs(script, chainParams) - - // regenerate scripts. - sigScript, _ := unparseScript(sigPops) - prevScript, _ := unparseScript(prevPops) - - // Merge - mergedScript := mergeScripts(chainParams, tx, idx, script, - class, addresses, nrequired, sigScript, prevScript) - - // Reappend the script and return the result. - builder := NewScriptBuilder() - builder.AddOps(mergedScript) - builder.AddData(script) - finalScript, _ := builder.Script() - return finalScript - case MultiSigTy: - return mergeMultiSig(tx, idx, addresses, nRequired, pkScript, - sigScript, prevScript) - - // It doesn't actually make sense to merge anything other than multiig - // and scripthash (because it could contain multisig). Everything else - // has either zero signature, can't be spent, or has a single signature - // which is either present or not. The other two cases are handled - // above. In the conflict case here we just assume the longest is - // correct (this matches behaviour of the reference implementation). - default: - if len(sigScript) > len(prevScript) { - return sigScript - } - return prevScript - } -} - // mergeMultiSig combines the two signature scripts sigScript and prevScript // that both provide signatures for pkScript in output idx of tx. addresses // and nRequired should be the results from extracting the addresses from @@ -397,6 +330,74 @@ sigLoop: return script } +// mergeScripts merges sigScript and prevScript assuming they are both +// partial solutions for pkScript spending output idx of tx. class, addresses +// and nrequired are the result of extracting the addresses from pkscript. +// The return value is the best effort merging of the two scripts. Calling this +// function with addresses, class and nrequired that do not match pkScript is +// an error and results in undefined behaviour. +func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, + pkScript []byte, class ScriptClass, addresses []btcutil.Address, + nRequired int, sigScript, prevScript []byte) []byte { + + // TODO(oga) the scripthash and multisig paths here are overly + // inefficient in that they will recompute already known data. + // some internal refactoring could probably make this avoid needless + // extra calculations. + switch class { + case ScriptHashTy: + // Remove the last push in the script and then recurse. + // this could be a lot less inefficient. + sigPops, err := parseScript(sigScript) + if err != nil || len(sigPops) == 0 { + return prevScript + } + prevPops, err := parseScript(prevScript) + if err != nil || len(prevPops) == 0 { + return sigScript + } + + // assume that script in sigPops is the correct one, we just + // made it. + script := sigPops[len(sigPops)-1].data + + // We already know this information somewhere up the stack, + // therefore the error is ignored. + class, addresses, nrequired, _ := + ExtractPkScriptAddrs(script, chainParams) + + // regenerate scripts. + sigScript, _ := unparseScript(sigPops) + prevScript, _ := unparseScript(prevPops) + + // Merge + mergedScript := mergeScripts(chainParams, tx, idx, script, + class, addresses, nrequired, sigScript, prevScript) + + // Reappend the script and return the result. + builder := NewScriptBuilder() + builder.AddOps(mergedScript) + builder.AddData(script) + finalScript, _ := builder.Script() + return finalScript + case MultiSigTy: + return mergeMultiSig(tx, idx, addresses, nRequired, pkScript, + sigScript, prevScript) + + // It doesn't actually make sense to merge anything other than multiig + // and scripthash (because it could contain multisig). Everything else + // has either zero signature, can't be spent, or has a single signature + // which is either present or not. The other two cases are handled + // above. In the conflict case here we just assume the longest is + // correct (this matches behaviour of the reference implementation). + default: + if len(sigScript) > len(prevScript) { + return sigScript + } + return prevScript + } +} + // KeyDB is an interface type provided to SignTxOutput, it encapsulates // any user state required to get the private keys for an address. type KeyDB interface { -- 2.45.2 From dd609d6e36f3e6c7a4a0262cd0004733854d35c1 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 15:25:18 -0700 Subject: [PATCH 081/459] txscript: Introduce calcWitnessSignatureHashRaw --- txscript/script.go | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 9d7de56c..46517985 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -385,7 +385,7 @@ func calcHashOutputs(tx *wire.MsgTx) chainhash.Hash { return chainhash.DoubleHashH(b.Bytes()) } -// calcWitnessSignatureHash computes the sighash digest of a transaction's +// calcWitnessSignatureHashRaw computes the sighash digest of a transaction's // segwit input using the new, optimized digest calculation algorithm defined // in BIP0143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki. // This function makes use of pre-calculated sighash fragments stored within @@ -396,7 +396,7 @@ func calcHashOutputs(tx *wire.MsgTx) chainhash.Hash { // being spent, in addition to the final transaction fee. In the case the // wallet if fed an invalid input amount, the real sighash will differ causing // the produced signature to be invalid. -func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, +func calcWitnessSignatureHashRaw(scriptSig []byte, sigHashes *TxSigHashes, hashType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { // As a sanity check, ensure the passed input index for the transaction @@ -446,7 +446,7 @@ func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, binary.LittleEndian.PutUint32(bIndex[:], txIn.PreviousOutPoint.Index) sigHash.Write(bIndex[:]) - if isWitnessPubKeyHash(subScript) { + if isWitnessPubKeyHashScript(scriptSig) { // The script code for a p2wkh is a length prefix varint for // the next 25 bytes, followed by a re-creation of the original // p2pkh pk script. @@ -454,15 +454,14 @@ func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, sigHash.Write([]byte{OP_DUP}) sigHash.Write([]byte{OP_HASH160}) sigHash.Write([]byte{OP_DATA_20}) - sigHash.Write(subScript[1].data) + sigHash.Write(extractWitnessPubKeyHash(scriptSig)) sigHash.Write([]byte{OP_EQUALVERIFY}) sigHash.Write([]byte{OP_CHECKSIG}) } else { // For p2wsh outputs, and future outputs, the script code is // the original script, with all code separators removed, // serialized with a var int length prefix. - rawScript, _ := unparseScript(subScript) - wire.WriteVarBytes(&sigHash, 0, rawScript) + wire.WriteVarBytes(&sigHash, 0, scriptSig) } // Next, add the input amount, and sequence number of the input being @@ -501,6 +500,30 @@ func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, return chainhash.DoubleHashB(sigHash.Bytes()), nil } +// calcWitnessSignatureHash computes the sighash digest of a transaction's +// segwit input using the new, optimized digest calculation algorithm defined +// in BIP0143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki. +// This function makes use of pre-calculated sighash fragments stored within +// the passed HashCache to eliminate duplicate hashing computations when +// calculating the final digest, reducing the complexity from O(N^2) to O(N). +// Additionally, signatures now cover the input value of the referenced unspent +// output. This allows offline, or hardware wallets to compute the exact amount +// being spent, in addition to the final transaction fee. In the case the +// wallet if fed an invalid input amount, the real sighash will differ causing +// the produced signature to be invalid. +// +// DEPRECATED: Use calcWitnessSignatureHashRaw instead. +func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, + hashType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { + + script, err := unparseScript(subScript) + if err != nil { + return nil, err + } + + return calcWitnessSignatureHashRaw(script, sigHashes, hashType, tx, idx, amt) +} + // CalcWitnessSigHash computes the sighash digest for the specified input of // the target transaction observing the desired sig hash type. func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType SigHashType, -- 2.45.2 From ed9e17a043bdab0427b3f3b8113b9cc27e90cd84 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 20:09:07 -0700 Subject: [PATCH 082/459] txscript: Remove unused isWitnessPubKeyHash --- txscript/script.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 46517985..10e0a1ca 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -90,14 +90,6 @@ func IsPayToWitnessPubKeyHash(script []byte) bool { return isWitnessPubKeyHashScript(script) } -// isWitnessPubKeyHash returns true if the passed script is a -// pay-to-witness-pubkey-hash, and false otherwise. -func isWitnessPubKeyHash(pops []parsedOpcode) bool { - return len(pops) == 2 && - pops[0].opcode.value == OP_0 && - pops[1].opcode.value == OP_DATA_20 -} - // IsWitnessProgram returns true if the passed script is a valid witness // program which is encoded according to the passed witness program version. A // witness program must be a small integer (from 0-16), followed by 2-40 bytes -- 2.45.2 From e00fec15571157f1241c8347893cb030ee28e034 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 15:26:10 -0700 Subject: [PATCH 083/459] txscript: Use optimized calcWitnessSignatureHashRaw w/o parsing --- txscript/script.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 10e0a1ca..6798be1c 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -521,13 +521,12 @@ func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { - parsedScript, err := parseScript(script) - if err != nil { - return nil, fmt.Errorf("cannot parse output script: %v", err) + const scriptVersion = 0 + if err := checkScriptParses(scriptVersion, script); err != nil { + return nil, err } - return calcWitnessSignatureHash(parsedScript, sigHashes, hType, tx, idx, - amt) + return calcWitnessSignatureHashRaw(script, sigHashes, hType, tx, idx, amt) } // shallowCopyTx creates a shallow copy of the transaction for use when -- 2.45.2 From f3354beb12ceaf97b0ab25a2ac3d9817231fa663 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:50 -0500 Subject: [PATCH 084/459] txscript: Use raw scripts in SignTxOutput. This converts SignTxOutput and supporting funcs, namely sign, mergeScripts and mergeMultiSig, to make use of the new tokenizer as well as some recently added funcs that deal with raw scripts in order to remove the reliance on parsed opcodes as a step towards utlimately removing them altogether and updates the comments to explicitly call out the script version semantics. It is worth noting that this has the side effect of optimizing the function as well, however, since this change is not focused on the optimization aspects, no benchmarks are provided. --- txscript/sign.go | 88 ++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/txscript/sign.go b/txscript/sign.go index 58791064..4d63a9b2 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -218,37 +218,44 @@ func sign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, // pkScript. Since this function is internal only we assume that the arguments // have come from other functions internally and thus are all consistent with // each other, behaviour is undefined if this contract is broken. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func mergeMultiSig(tx *wire.MsgTx, idx int, addresses []btcutil.Address, nRequired int, pkScript, sigScript, prevScript []byte) []byte { - // This is an internal only function and we already parsed this script - // as ok for multisig (this is how we got here), so if this fails then - // all assumptions are broken and who knows which way is up? - pkPops, _ := parseScript(pkScript) - - sigPops, err := parseScript(sigScript) - if err != nil || len(sigPops) == 0 { + // Nothing to merge if either the new or previous signature scripts are + // empty. + if len(sigScript) == 0 { return prevScript } - - prevPops, err := parseScript(prevScript) - if err != nil || len(prevPops) == 0 { + if len(prevScript) == 0 { return sigScript } // Convenience function to avoid duplication. - extractSigs := func(pops []parsedOpcode, sigs [][]byte) [][]byte { - for _, pop := range pops { - if len(pop.data) != 0 { - sigs = append(sigs, pop.data) + var possibleSigs [][]byte + extractSigs := func(script []byte) error { + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if data := tokenizer.Data(); len(data) != 0 { + possibleSigs = append(possibleSigs, data) } } - return sigs + return tokenizer.Err() } - possibleSigs := make([][]byte, 0, len(sigPops)+len(prevPops)) - possibleSigs = extractSigs(sigPops, possibleSigs) - possibleSigs = extractSigs(prevPops, possibleSigs) + // Attempt to extract signatures from the two scripts. Return the other + // script that is intended to be merged in the case signature extraction + // fails for some reason. + if err := extractSigs(sigScript); err != nil { + return prevScript + } + if err := extractSigs(prevScript); err != nil { + return sigScript + } // Now we need to match the signatures to pubkeys, the only real way to // do that is to try to verify them all and match it to the pubkey @@ -278,10 +285,7 @@ sigLoop: // however, assume no sigs etc are in the script since that // would make the transaction nonstandard and thus not // MultiSigTy, so we just need to hash the full thing. - hash, err := calcSignatureHash(pkPops, hashType, tx, idx) - if err != nil { - panic(fmt.Sprintf("cannot compute sighash: %v", err)) - } + hash := calcSignatureHashRaw(pkScript, hashType, tx, idx) for _, addr := range addresses { // All multisig addresses should be pubkey addresses @@ -336,6 +340,10 @@ sigLoop: // The return value is the best effort merging of the two scripts. Calling this // function with addresses, class and nrequired that do not match pkScript is // an error and results in undefined behaviour. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, pkScript []byte, class ScriptClass, addresses []btcutil.Address, nRequired int, sigScript, prevScript []byte) []byte { @@ -344,32 +352,34 @@ func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, // inefficient in that they will recompute already known data. // some internal refactoring could probably make this avoid needless // extra calculations. + const scriptVersion = 0 switch class { case ScriptHashTy: - // Remove the last push in the script and then recurse. - // this could be a lot less inefficient. - sigPops, err := parseScript(sigScript) - if err != nil || len(sigPops) == 0 { + // Nothing to merge if either the new or previous signature + // scripts are empty or fail to parse. + if len(sigScript) == 0 || + checkScriptParses(scriptVersion, sigScript) != nil { + return prevScript } - prevPops, err := parseScript(prevScript) - if err != nil || len(prevPops) == 0 { + if len(prevScript) == 0 || + checkScriptParses(scriptVersion, prevScript) != nil { + return sigScript } - // assume that script in sigPops is the correct one, we just - // made it. - script := sigPops[len(sigPops)-1].data + // Remove the last push in the script and then recurse. + // this could be a lot less inefficient. + // + // Assume that final script is the correct one since it was just + // made and it is a pay-to-script-hash. + script := finalOpcodeData(scriptVersion, sigScript) // We already know this information somewhere up the stack, // therefore the error is ignored. class, addresses, nrequired, _ := ExtractPkScriptAddrs(script, chainParams) - // regenerate scripts. - sigScript, _ := unparseScript(sigPops) - prevScript, _ := unparseScript(prevPops) - // Merge mergedScript := mergeScripts(chainParams, tx, idx, script, class, addresses, nrequired, sigScript, prevScript) @@ -380,6 +390,7 @@ func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, builder.AddData(script) finalScript, _ := builder.Script() return finalScript + case MultiSigTy: return mergeMultiSig(tx, idx, addresses, nRequired, pkScript, sigScript, prevScript) @@ -408,8 +419,7 @@ type KeyDB interface { type KeyClosure func(btcutil.Address) (*btcec.PrivateKey, bool, error) // GetKey implements KeyDB by returning the result of calling the closure. -func (kc KeyClosure) GetKey(address btcutil.Address) (*btcec.PrivateKey, - bool, error) { +func (kc KeyClosure) GetKey(address btcutil.Address) (*btcec.PrivateKey, bool, error) { return kc(address) } @@ -434,6 +444,10 @@ func (sc ScriptClosure) GetScript(address btcutil.Address) ([]byte, error) { // getScript. If previousScript is provided then the results in previousScript // will be merged in a type-dependent manner with the newly generated. // signature script. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func SignTxOutput(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, pkScript []byte, hashType SigHashType, kdb KeyDB, sdb ScriptDB, previousScript []byte) ([]byte, error) { -- 2.45.2 From 30874ff76b167796960cbd57178305cfefb2b0da Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:51 -0500 Subject: [PATCH 085/459] txscript: Implement efficient opcode data removal. This introduces a new function named removeOpcodeByDataRaw which accepts the raw scripts and data to remove versus requiring the parsed opcodes to both significantly optimize it as well as make it more flexible for working with raw scripts. There are several places in the rest of the code that currently only have access to the parsed opcodes, so this only introduces the function for use in the future and deprecates the existing one. Note that, in practice, the script will never actually contain the data that is intended to be removed since the function is only used during signature verification to remove the signature itself which would require some incredibly non-standard code to create. Thus, as an optimization, it avoids allocating a new script unless there is actually a match that needs to be removed. Finally, it updates the tests to use the new function. --- txscript/script.go | 55 +++++++++++++++++++++++++++++++++++++++++ txscript/script_test.go | 13 +++++----- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 6798be1c..336a2c8b 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -310,6 +310,8 @@ func isCanonicalPush(opcode byte, data []byte) bool { // removeOpcodeByData will return the script minus any opcodes that would push // the passed data to the stack. +// +// DEPRECATED. Use removeOpcodeByDataRaw instead. func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode { retScript := make([]parsedOpcode, 0, len(pkscript)) for _, pop := range pkscript { @@ -323,6 +325,59 @@ func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode { } +// removeOpcodeByDataRaw will return the script minus any opcodes that perform a +// canonical push of data that contains the passed data to remove. This +// function assumes it is provided a version 0 script as any future version of +// script should avoid this functionality since it is unncessary due to the +// signature scripts not being part of the witness-free transaction hash. +// +// WARNING: This will return the passed script unmodified unless a modification +// is necessary in which case the modified script is returned. This implies +// callers may NOT rely on being able to safely mutate either the passed or +// returned script without potentially modifying the same data. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func removeOpcodeByDataRaw(script []byte, dataToRemove []byte) []byte { + // Avoid work when possible. + if len(script) == 0 || len(dataToRemove) == 0 { + return script + } + + // Parse through the script looking for a canonical data push that contains + // the data to remove. + const scriptVersion = 0 + var result []byte + var prevOffset int32 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + // In practice, the script will basically never actually contain the + // data since this function is only used during signature verification + // to remove the signature itself which would require some incredibly + // non-standard code to create. + // + // Thus, as an optimization, avoid allocating a new script unless there + // is actually a match that needs to be removed. + op, data := tokenizer.Opcode(), tokenizer.Data() + if isCanonicalPush(op, data) && bytes.Contains(data, dataToRemove) { + if result == nil { + fullPushLen := tokenizer.ByteIndex() - prevOffset + result = make([]byte, 0, int32(len(script))-fullPushLen) + result = append(result, script[0:prevOffset]...) + } + } else if result != nil { + result = append(result, script[prevOffset:tokenizer.ByteIndex()]...) + } + + prevOffset = tokenizer.ByteIndex() + } + if result == nil { + result = script + } + return result +} + // calcHashPrevOuts calculates a single hash of all the previous outputs // (txid:index) referenced within the passed transaction. This calculated hash // can be re-used when validating all inputs spending segwit outputs, with a diff --git a/txscript/script_test.go b/txscript/script_test.go index 62c51e41..9a64865e 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -4129,16 +4129,15 @@ func TestRemoveOpcodeByData(t *testing.T) { }, } - // tstRemoveOpcodeByData is a convenience function to parse the provided - // raw script, remove the passed data, then unparse the result back - // into a raw script. + // tstRemoveOpcodeByData is a convenience function to ensure the provided + // script parses before attempting to remove the passed data. + const scriptVersion = 0 tstRemoveOpcodeByData := func(script []byte, data []byte) ([]byte, error) { - pops, err := parseScript(script) - if err != nil { + if err := checkScriptParses(scriptVersion, script); err != nil { return nil, err } - pops = removeOpcodeByData(pops, data) - return unparseScript(pops) + + return removeOpcodeByDataRaw(script, data), nil } for _, test := range tests { -- 2.45.2 From a4720f30e532c6c2815dd8ea626cf371ad2dca0e Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 16:26:22 -0700 Subject: [PATCH 086/459] txscript: Optimize removeOpcodeRaw --- txscript/script.go | 39 +++++++++++++++++++++++++++++++++++++++ txscript/script_test.go | 7 +++---- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 336a2c8b..7bfe44b3 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -269,6 +269,8 @@ func DisasmString(script []byte) (string, error) { // removeOpcode will remove any opcode matching ``opcode'' from the opcode // stream in pkscript +// +// DEPRECATED. Use removeOpcodeRaw instead. func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode { retScript := make([]parsedOpcode, 0, len(pkscript)) for _, pop := range pkscript { @@ -279,6 +281,43 @@ func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode { return retScript } +// removeOpcodeRaw will return the script after removing any opcodes that match +// `opcode`. If the opcode does not appear in script, the original script will +// be returned unmodified. Otherwise, a new script will be allocated to contain +// the filtered script. This metehod assumes that the script parses +// successfully. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func removeOpcodeRaw(script []byte, opcode byte) []byte { + // Avoid work when possible. + if len(script) == 0 { + return script + } + + const scriptVersion = 0 + var result []byte + var prevOffset int32 + + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if tokenizer.Opcode() == opcode { + if result == nil { + result = make([]byte, 0, len(script)) + result = append(result, script[:prevOffset]...) + } + } else if result != nil { + result = append(result, script[prevOffset:tokenizer.ByteIndex()]...) + } + prevOffset = tokenizer.ByteIndex() + } + if result == nil { + return script + } + return result +} + // isCanonicalPush returns true if the opcode is either not a push instruction // or the data associated with the push instruction uses the smallest // instruction to do the job. False otherwise. diff --git a/txscript/script_test.go b/txscript/script_test.go index 9a64865e..02c364ce 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -3981,13 +3981,12 @@ func TestRemoveOpcodes(t *testing.T) { // tstRemoveOpcode is a convenience function to parse the provided // raw script, remove the passed opcode, then unparse the result back // into a raw script. + const scriptVersion = 0 tstRemoveOpcode := func(script []byte, opcode byte) ([]byte, error) { - pops, err := parseScript(script) - if err != nil { + if err := checkScriptParses(scriptVersion, script); err != nil { return nil, err } - pops = removeOpcode(pops, opcode) - return unparseScript(pops) + return removeOpcodeRaw(script, opcode), nil } for _, test := range tests { -- 2.45.2 From 2ddcdb91f5bcb8df7fab43cbf1b92cccaadeb6fc Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 20:11:34 -0700 Subject: [PATCH 087/459] txscript: Remove unused removeOpcode --- txscript/script.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 7bfe44b3..7c8423bb 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -267,20 +267,6 @@ func DisasmString(script []byte) (string, error) { return disbuf.String(), tokenizer.Err() } -// removeOpcode will remove any opcode matching ``opcode'' from the opcode -// stream in pkscript -// -// DEPRECATED. Use removeOpcodeRaw instead. -func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode { - retScript := make([]parsedOpcode, 0, len(pkscript)) - for _, pop := range pkscript { - if pop.opcode.value != opcode { - retScript = append(retScript, pop) - } - } - return retScript -} - // removeOpcodeRaw will return the script after removing any opcodes that match // `opcode`. If the opcode does not appear in script, the original script will // be returned unmodified. Otherwise, a new script will be allocated to contain -- 2.45.2 From a2ab5b66816c8270185d43d20de7f11681be8afa Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 16:28:26 -0700 Subject: [PATCH 088/459] txscript: Use removeOpcodeRaw for CODESEP in calcSigHash --- txscript/script.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 7c8423bb..0be0a7b8 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -683,24 +683,14 @@ func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx } // Remove all instances of OP_CODESEPARATOR from the script. - filteredScript := make([]byte, 0, len(sigScript)) - const scriptVersion = 0 - tokenizer := MakeScriptTokenizer(scriptVersion, sigScript) - var prevOffset int32 - for tokenizer.Next() { - if tokenizer.Opcode() != OP_CODESEPARATOR { - filteredScript = append(filteredScript, - sigScript[prevOffset:tokenizer.ByteIndex()]...) - } - prevOffset = tokenizer.ByteIndex() - } + sigScript = removeOpcodeRaw(sigScript, OP_CODESEPARATOR) // Make a shallow copy of the transaction, zeroing out the script for // all inputs that are not currently being processed. txCopy := shallowCopyTx(tx) for i := range txCopy.TxIn { if i == idx { - txCopy.TxIn[idx].SignatureScript = filteredScript + txCopy.TxIn[idx].SignatureScript = sigScript } else { txCopy.TxIn[i].SignatureScript = nil } -- 2.45.2 From 484f7b1fef6a62eabe31f8c8a9fa44d15e2310b2 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:52 -0500 Subject: [PATCH 089/459] txscript: Make isDisabled accept raw opcode. This converts the isDisabled function defined on a parsed opcode to a standalone function which accepts an opcode as a byte instead in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/engine.go | 42 +++++++++++++++++++++++++++++++++++++++++- txscript/opcode.go | 39 --------------------------------------- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index ef7ad33e..00973a03 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -154,12 +154,52 @@ func (vm *Engine) isBranchExecuting() bool { return vm.condStack[len(vm.condStack)-1] == OpCondTrue } +// isOpcodeDisabled returns whether or not the opcode is disabled and thus is +// always bad to see in the instruction stream (even if turned off by a +// conditional). +func isOpcodeDisabled(opcode byte) bool { + switch opcode { + case OP_CAT: + return true + case OP_SUBSTR: + return true + case OP_LEFT: + return true + case OP_RIGHT: + return true + case OP_INVERT: + return true + case OP_AND: + return true + case OP_OR: + return true + case OP_XOR: + return true + case OP_2MUL: + return true + case OP_2DIV: + return true + case OP_MUL: + return true + case OP_DIV: + return true + case OP_MOD: + return true + case OP_LSHIFT: + return true + case OP_RSHIFT: + return true + default: + return false + } +} + // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. func (vm *Engine) executeOpcode(pop *parsedOpcode) error { // Disabled opcodes are fail on program counter. - if pop.isDisabled() { + if isOpcodeDisabled(pop.opcode.value) { str := fmt.Sprintf("attempt to execute disabled opcode %s", pop.opcode.name) return scriptError(ErrDisabledOpcode, str) diff --git a/txscript/opcode.go b/txscript/opcode.go index 893bebdf..62c6649d 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -619,45 +619,6 @@ type parsedOpcode struct { data []byte } -// isDisabled returns whether or not the opcode is disabled and thus is always -// bad to see in the instruction stream (even if turned off by a conditional). -func (pop *parsedOpcode) isDisabled() bool { - switch pop.opcode.value { - case OP_CAT: - return true - case OP_SUBSTR: - return true - case OP_LEFT: - return true - case OP_RIGHT: - return true - case OP_INVERT: - return true - case OP_AND: - return true - case OP_OR: - return true - case OP_XOR: - return true - case OP_2MUL: - return true - case OP_2DIV: - return true - case OP_MUL: - return true - case OP_DIV: - return true - case OP_MOD: - return true - case OP_LSHIFT: - return true - case OP_RSHIFT: - return true - default: - return false - } -} - // checkParseableInScript checks whether or not the current opcode is able to be // parsed at a certain position in a script. // This returns the position of the next opcode to be parsed in the script. -- 2.45.2 From c6410257eb2894ee086fda5bb5ce88e33a44011a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:53 -0500 Subject: [PATCH 090/459] txscript: Make alwaysIllegal accept raw opcode. This converts the alwaysIllegal function defined on a parsed opcode to a standalone function named isOpcodeAlwaysIllegal which accepts an opcode as a byte instead in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/engine.go | 16 +++++++++++++++- txscript/opcode.go | 14 -------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 00973a03..1c6a124b 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -194,6 +194,20 @@ func isOpcodeDisabled(opcode byte) bool { } } +// isOpcodeAlwaysIllegal returns whether or not the opcode is always illegal +// when passed over by the program counter even if in a non-executed branch (it +// isn't a coincidence that they are conditionals). +func isOpcodeAlwaysIllegal(opcode byte) bool { + switch opcode { + case OP_VERIF: + return true + case OP_VERNOTIF: + return true + default: + return false + } +} + // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. @@ -206,7 +220,7 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { } // Always-illegal opcodes are fail on program counter. - if pop.alwaysIllegal() { + if isOpcodeAlwaysIllegal(pop.opcode.value) { str := fmt.Sprintf("attempt to execute reserved opcode %s", pop.opcode.name) return scriptError(ErrReservedOpcode, str) diff --git a/txscript/opcode.go b/txscript/opcode.go index 62c6649d..dc4ec50e 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -692,20 +692,6 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (i return scriptPos, nil } -// alwaysIllegal returns whether or not the opcode is always illegal when passed -// over by the program counter even if in a non-executed branch (it isn't a -// coincidence that they are conditionals). -func (pop *parsedOpcode) alwaysIllegal() bool { - switch pop.opcode.value { - case OP_VERIF: - return true - case OP_VERNOTIF: - return true - default: - return false - } -} - // isConditional returns whether or not the opcode is a conditional opcode which // changes the conditional execution stack when executed. func (pop *parsedOpcode) isConditional() bool { -- 2.45.2 From 62c608f2654367caedef75e4370155d2cd0c0024 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:54 -0500 Subject: [PATCH 091/459] txscript: Make isConditional accept raw opcode. This converts the isConditional function defined on a parsed opcode to a standalone function named isOpcodeConditional which accepts an opcode as a byte instead in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/engine.go | 19 ++++++++++++++++++- txscript/opcode.go | 17 ----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 1c6a124b..ddb26de5 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -208,6 +208,23 @@ func isOpcodeAlwaysIllegal(opcode byte) bool { } } +// isOpcodeConditional returns whether or not the opcode is a conditional opcode +// which changes the conditional execution stack when executed. +func isOpcodeConditional(opcode byte) bool { + switch opcode { + case OP_IF: + return true + case OP_NOTIF: + return true + case OP_ELSE: + return true + case OP_ENDIF: + return true + default: + return false + } +} + // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. @@ -243,7 +260,7 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { // Nothing left to do when this is not a conditional opcode and it is // not in an executing branch. - if !vm.isBranchExecuting() && !pop.isConditional() { + if !vm.isBranchExecuting() && !isOpcodeConditional(pop.opcode.value) { return nil } diff --git a/txscript/opcode.go b/txscript/opcode.go index dc4ec50e..7705f59b 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -692,23 +692,6 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (i return scriptPos, nil } -// isConditional returns whether or not the opcode is a conditional opcode which -// changes the conditional execution stack when executed. -func (pop *parsedOpcode) isConditional() bool { - switch pop.opcode.value { - case OP_IF: - return true - case OP_NOTIF: - return true - case OP_ELSE: - return true - case OP_ENDIF: - return true - default: - return false - } -} - // checkMinimalDataPush returns whether or not the current data push uses the // smallest possible opcode to represent it. For example, the value 15 could // be pushed with OP_DATA_1 15 (among other variations); however, OP_15 is a -- 2.45.2 From 710bd5646e55a520054c4620e507b8867b864e64 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:55 -0500 Subject: [PATCH 092/459] txscript: Make min push accept raw opcode and data. This converts the checkMinimalDataPush function defined on a parsed opcode to a standalone function which accepts an opcode and data slice instead in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/engine.go | 51 +++++++++++++++++++++++++++++++++++++++++- txscript/opcode.go | 55 ---------------------------------------------- 2 files changed, 50 insertions(+), 56 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index ddb26de5..a2dfad4c 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -225,6 +225,55 @@ func isOpcodeConditional(opcode byte) bool { } } +// checkMinimalDataPush returns whether or not the provided opcode is the +// smallest possible way to represent the given data. For example, the value 15 +// could be pushed with OP_DATA_1 15 (among other variations); however, OP_15 is +// a single opcode that represents the same value and is only a single byte +// versus two bytes. +func checkMinimalDataPush(op *opcode, data []byte) error { + opcodeVal := op.value + dataLen := len(data) + switch { + case dataLen == 0 && opcodeVal != OP_0: + str := fmt.Sprintf("zero length data push is encoded with opcode %s "+ + "instead of OP_0", op.name) + return scriptError(ErrMinimalData, str) + case dataLen == 1 && data[0] >= 1 && data[0] <= 16: + if opcodeVal != OP_1+data[0]-1 { + // Should have used OP_1 .. OP_16 + str := fmt.Sprintf("data push of the value %d encoded with opcode "+ + "%s instead of OP_%d", data[0], op.name, data[0]) + return scriptError(ErrMinimalData, str) + } + case dataLen == 1 && data[0] == 0x81: + if opcodeVal != OP_1NEGATE { + str := fmt.Sprintf("data push of the value -1 encoded with opcode "+ + "%s instead of OP_1NEGATE", op.name) + return scriptError(ErrMinimalData, str) + } + case dataLen <= 75: + if int(opcodeVal) != dataLen { + // Should have used a direct push + str := fmt.Sprintf("data push of %d bytes encoded with opcode %s "+ + "instead of OP_DATA_%d", dataLen, op.name, dataLen) + return scriptError(ErrMinimalData, str) + } + case dataLen <= 255: + if opcodeVal != OP_PUSHDATA1 { + str := fmt.Sprintf("data push of %d bytes encoded with opcode %s "+ + "instead of OP_PUSHDATA1", dataLen, op.name) + return scriptError(ErrMinimalData, str) + } + case dataLen <= 65535: + if opcodeVal != OP_PUSHDATA2 { + str := fmt.Sprintf("data push of %d bytes encoded with opcode %s "+ + "instead of OP_PUSHDATA2", dataLen, op.name) + return scriptError(ErrMinimalData, str) + } + } + return nil +} + // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. @@ -269,7 +318,7 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { if vm.dstack.verifyMinimalData && vm.isBranchExecuting() && pop.opcode.value >= 0 && pop.opcode.value <= OP_PUSHDATA4 { - if err := pop.checkMinimalDataPush(); err != nil { + if err := checkMinimalDataPush(pop.opcode, pop.data); err != nil { return err } } diff --git a/txscript/opcode.go b/txscript/opcode.go index 7705f59b..95b47580 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -692,61 +692,6 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (i return scriptPos, nil } -// checkMinimalDataPush returns whether or not the current data push uses the -// smallest possible opcode to represent it. For example, the value 15 could -// be pushed with OP_DATA_1 15 (among other variations); however, OP_15 is a -// single opcode that represents the same value and is only a single byte versus -// two bytes. -func (pop *parsedOpcode) checkMinimalDataPush() error { - data := pop.data - dataLen := len(data) - opcode := pop.opcode.value - - if dataLen == 0 && opcode != OP_0 { - str := fmt.Sprintf("zero length data push is encoded with "+ - "opcode %s instead of OP_0", pop.opcode.name) - return scriptError(ErrMinimalData, str) - } else if dataLen == 1 && data[0] >= 1 && data[0] <= 16 { - if opcode != OP_1+data[0]-1 { - // Should have used OP_1 .. OP_16 - str := fmt.Sprintf("data push of the value %d encoded "+ - "with opcode %s instead of OP_%d", data[0], - pop.opcode.name, data[0]) - return scriptError(ErrMinimalData, str) - } - } else if dataLen == 1 && data[0] == 0x81 { - if opcode != OP_1NEGATE { - str := fmt.Sprintf("data push of the value -1 encoded "+ - "with opcode %s instead of OP_1NEGATE", - pop.opcode.name) - return scriptError(ErrMinimalData, str) - } - } else if dataLen <= 75 { - if int(opcode) != dataLen { - // Should have used a direct push - str := fmt.Sprintf("data push of %d bytes encoded "+ - "with opcode %s instead of OP_DATA_%d", dataLen, - pop.opcode.name, dataLen) - return scriptError(ErrMinimalData, str) - } - } else if dataLen <= 255 { - if opcode != OP_PUSHDATA1 { - str := fmt.Sprintf("data push of %d bytes encoded "+ - "with opcode %s instead of OP_PUSHDATA1", - dataLen, pop.opcode.name) - return scriptError(ErrMinimalData, str) - } - } else if dataLen <= 65535 { - if opcode != OP_PUSHDATA2 { - str := fmt.Sprintf("data push of %d bytes encoded "+ - "with opcode %s instead of OP_PUSHDATA2", - dataLen, pop.opcode.name) - return scriptError(ErrMinimalData, str) - } - } - return nil -} - // disasmOpcode writes a human-readable disassembly of the provided opcode and // data into the provided buffer. The compact flag indicates the disassembly // should print a more compact representation of data-carrying and small integer -- 2.45.2 From 54036e8bab1d8c8a596b2afbf2b0f4641b69a49f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:56 -0500 Subject: [PATCH 093/459] txscript: Convert to use non-parsed opcode disasm. This converts the engine's current program counter disasembly to make use of the standalone disassembly function to remove the dependency on the parsed opcode struct. It also updates the tests accordingly. --- txscript/engine.go | 7 +++++-- txscript/opcode.go | 8 -------- txscript/opcode_test.go | 10 ++++++---- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index a2dfad4c..191de29f 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -10,6 +10,7 @@ import ( "crypto/sha256" "fmt" "math/big" + "strings" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/wire" @@ -331,8 +332,10 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { // provided position in the script. It does no error checking and leaves that // to the caller to provide a valid offset. func (vm *Engine) disasm(scriptIdx int, scriptOff int) string { - return fmt.Sprintf("%02x:%04x: %s", scriptIdx, scriptOff, - vm.scripts[scriptIdx][scriptOff].print(false)) + var buf strings.Builder + pop := vm.scripts[scriptIdx][scriptOff] + disasmOpcode(&buf, pop.opcode, pop.data, false) + return fmt.Sprintf("%02x:%04x: %s", scriptIdx, scriptOff, buf.String()) } // validPC returns an error if the current script position is valid for diff --git a/txscript/opcode.go b/txscript/opcode.go index 95b47580..a0d05052 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -740,14 +740,6 @@ func disasmOpcode(buf *strings.Builder, op *opcode, data []byte, compact bool) { buf.WriteString(fmt.Sprintf(" 0x%02x", data)) } -// print returns a human-readable string representation of the opcode for use -// in script disassembly. -func (pop *parsedOpcode) print(compact bool) string { - var buf strings.Builder - disasmOpcode(&buf, pop.opcode, pop.data, compact) - return buf.String() -} - // bytes returns any data associated with the opcode encoded as it would be in // a script. This is used for unparsing scripts from parsed opcodes. func (pop *parsedOpcode) bytes() ([]byte, error) { diff --git a/txscript/opcode_test.go b/txscript/opcode_test.go index 1487dde5..3c5abf9d 100644 --- a/txscript/opcode_test.go +++ b/txscript/opcode_test.go @@ -127,8 +127,9 @@ func TestOpcodeDisasm(t *testing.T) { expectedStr = "OP_UNKNOWN" + strconv.Itoa(opcodeVal) } - pop := parsedOpcode{opcode: &opcodeArray[opcodeVal], data: data} - gotStr := pop.print(true) + var buf strings.Builder + disasmOpcode(&buf, &opcodeArray[opcodeVal], data, true) + gotStr := buf.String() if gotStr != expectedStr { t.Errorf("pop.print (opcode %x): Unexpected disasm "+ "string - got %v, want %v", opcodeVal, gotStr, @@ -193,8 +194,9 @@ func TestOpcodeDisasm(t *testing.T) { expectedStr = "OP_UNKNOWN" + strconv.Itoa(opcodeVal) } - pop := parsedOpcode{opcode: &opcodeArray[opcodeVal], data: data} - gotStr := pop.print(false) + var buf strings.Builder + disasmOpcode(&buf, &opcodeArray[opcodeVal], data, false) + gotStr := buf.String() if gotStr != expectedStr { t.Errorf("pop.print (opcode %x): Unexpected disasm "+ "string - got %v, want %v", opcodeVal, gotStr, -- 2.45.2 From d6b968c3ea24a55b51af05f764975e782b9bb677 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:58 -0500 Subject: [PATCH 094/459] txscript: Refactor engine to use raw scripts. This refactors the script engine to store and step through raw scripts by making using of the new zero-allocation script tokenizer as opposed to the less efficient method of storing and stepping through parsed opcodes. It also improves several aspects while refactoring such as optimizing the disassembly trace, showing all scripts in the trace in the case of execution failure, and providing additional comments describing the purpose of each field in the engine. It should be noted that this is a step towards removing the parsed opcode struct and associated supporting code altogether, however, in order to ease the review process, this retains the struct and all function signatures for opcode execution which make use of an individual parsed opcode. Those will be updated in future commits. The following is an overview of the changes: - Modify internal engine scripts slice to use raw scripts instead of parsed opcodes - Introduce a tokenizer to the engine to track the current script - Remove no longer needed script offset parameter from the engine since that is tracked by the tokenizer - Add an opcode index counter for disassembly purposes to the engine - Update check for valid program counter to only consider the script index - Update tests for bad program counter accordingly - Rework the NewEngine function - Store the raw scripts - Setup the initial tokenizer - Explicitly check against version 0 instead of DefaultScriptVersion which would break consensus if changed - Check the scripts parse according to version 0 semantics to retain current consensus rules - Improve comments throughout - Rework the Step function - Use the tokenizer and raw scripts - Create a parsed opcode on the fly for now to retain existing opcode execution function signatures - Improve comments throughout - Update the Execute function - Explicitly check against version 0 instead of DefaultScriptVersion which would break consensus if changed - Improve the disassembly tracing in the case of error - Update the CheckErrorCondition function - Modify clean stack error message to make sense in all cases - Improve the comments - Update the DisasmPC and DisasmScript functions on the engine - Use the tokenizer - Optimize construction via the use of strings.Builder - Modify the subScript function to return the raw script bytes since the parsed opcodes are no longer stored - Update the various signature checking opcodes to use the raw opcode data removal and signature hash calculation functions since the subscript is now a raw script - opcodeCheckSig - opcodeCheckMultiSig - opcodeCheckSigAlt --- txscript/engine.go | 373 +++++++++++++++++++++++++++------------- txscript/engine_test.go | 19 +- txscript/opcode.go | 20 +-- 3 files changed, 266 insertions(+), 146 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 191de29f..1afb8324 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -119,21 +119,84 @@ var halfOrder = new(big.Int).Rsh(btcec.S256().N, 1) // Engine is the virtual machine that executes scripts. type Engine struct { - scripts [][]parsedOpcode + // The following fields are set when the engine is created and must not be + // changed afterwards. The entries of the signature cache are mutated + // during execution, however, the cache pointer itself is not changed. + // + // flags specifies the additional flags which modify the execution behavior + // of the engine. + // + // tx identifies the transaction that contains the input which in turn + // contains the signature script being executed. + // + // txIdx identifies the input index within the transaction that contains + // the signature script being executed. + // + // version specifies the version of the public key script to execute. Since + // signature scripts redeem public keys scripts, this means the same version + // also extends to signature scripts and redeem scripts in the case of + // pay-to-script-hash. + // + // bip16 specifies that the public key script is of a special form that + // indicates it is a BIP16 pay-to-script-hash and therefore the + // execution must be treated as such. + // + // sigCache caches the results of signature verifications. This is useful + // since transaction scripts are often executed more than once from various + // contexts (e.g. new block templates, when transactions are first seen + // prior to being mined, part of full block verification, etc). + flags ScriptFlags + tx wire.MsgTx + txIdx int + version uint16 + bip16 bool + sigCache *SigCache + hashCache *TxSigHashes + + // The following fields handle keeping track of the current execution state + // of the engine. + // + // scripts houses the raw scripts that are executed by the engine. This + // includes the signature script as well as the public key script. It also + // includes the redeem script in the case of pay-to-script-hash. + // + // scriptIdx tracks the index into the scripts array for the current program + // counter. + // + // opcodeIdx tracks the number of the opcode within the current script for + // the current program counter. Note that it differs from the actual byte + // index into the script and is really only used for disassembly purposes. + // + // lastCodeSep specifies the position within the current script of the last + // OP_CODESEPARATOR. + // + // tokenizer provides the token stream of the current script being executed + // and doubles as state tracking for the program counter within the script. + // + // savedFirstStack keeps a copy of the stack from the first script when + // performing pay-to-script-hash execution. + // + // dstack is the primary data stack the various opcodes push and pop data + // to and from during execution. + // + // astack is the alternate data stack the various opcodes push and pop data + // to and from during execution. + // + // condStack tracks the conditional execution state with support for + // multiple nested conditional execution opcodes. + // + // numOps tracks the total number of non-push operations in a script and is + // primarily used to enforce maximum limits. + scripts [][]byte scriptIdx int - scriptOff int + opcodeIdx int lastCodeSep int - dstack stack // data stack - astack stack // alt stack - tx wire.MsgTx - txIdx int + tokenizer ScriptTokenizer + savedFirstStack [][]byte + dstack stack + astack stack condStack []int numOps int - flags ScriptFlags - sigCache *SigCache - hashCache *TxSigHashes - bip16 bool // treat execution as pay-to-script-hash - savedFirstStack [][]byte // stack from first script for bip16 scripts witnessVersion int witnessProgram []byte inputAmount int64 @@ -327,44 +390,17 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { return pop.opcode.opfunc(pop, vm) } -// disasm is a helper function to produce the output for DisasmPC and -// DisasmScript. It produces the opcode prefixed by the program counter at the -// provided position in the script. It does no error checking and leaves that -// to the caller to provide a valid offset. -func (vm *Engine) disasm(scriptIdx int, scriptOff int) string { - var buf strings.Builder - pop := vm.scripts[scriptIdx][scriptOff] - disasmOpcode(&buf, pop.opcode, pop.data, false) - return fmt.Sprintf("%02x:%04x: %s", scriptIdx, scriptOff, buf.String()) -} - -// validPC returns an error if the current script position is valid for -// execution, nil otherwise. -func (vm *Engine) validPC() error { +// checkValidPC returns an error if the current script position is not valid for +// execution. +func (vm *Engine) checkValidPC() error { if vm.scriptIdx >= len(vm.scripts) { - str := fmt.Sprintf("past input scripts %v:%v %v:xxxx", - vm.scriptIdx, vm.scriptOff, len(vm.scripts)) - return scriptError(ErrInvalidProgramCounter, str) - } - if vm.scriptOff >= len(vm.scripts[vm.scriptIdx]) { - str := fmt.Sprintf("past input scripts %v:%v %v:%04d", - vm.scriptIdx, vm.scriptOff, vm.scriptIdx, - len(vm.scripts[vm.scriptIdx])) + str := fmt.Sprintf("script index %d beyond total scripts %d", + vm.scriptIdx, len(vm.scripts)) return scriptError(ErrInvalidProgramCounter, str) } return nil } -// curPC returns either the current script and offset, or an error if the -// position isn't valid. -func (vm *Engine) curPC() (script int, off int, err error) { - err = vm.validPC() - if err != nil { - return 0, 0, err - } - return vm.scriptIdx, vm.scriptOff, nil -} - // isWitnessVersionActive returns true if a witness program was extracted // during the initialization of the Engine, and the program's version matches // the specified version. @@ -392,7 +428,9 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { if err != nil { return err } - pops, err := parseScript(pkScript) + + const scriptVersion = 0 + err = checkScriptParses(vm.version, pkScript) if err != nil { return err } @@ -400,7 +438,7 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { // Set the stack to the provided witness stack, then // append the pkScript generated above as the next // script to execute. - vm.scripts = append(vm.scripts, pops) + vm.scripts = append(vm.scripts, pkScript) vm.SetStack(witness) case payToWitnessScriptHashDataSize: // P2WSH @@ -430,10 +468,10 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { "witness program hash mismatch") } - // With all the validity checks passed, parse the - // script into individual op-codes so w can execute it - // as the next script. - pops, err := parseScript(witnessScript) + // With all the validity checks passed, assert that the + // script parses without failure. + const scriptVersion = 0 + err := checkScriptParses(vm.version, witnessScript) if err != nil { return err } @@ -441,7 +479,7 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { // The hash matched successfully, so use the witness as // the stack, and set the witnessScript to be the next // script executed. - vm.scripts = append(vm.scripts, pops) + vm.scripts = append(vm.scripts, witnessScript) vm.SetStack(witness[:len(witness)-1]) default: @@ -482,18 +520,50 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { } // DisasmPC returns the string for the disassembly of the opcode that will be -// next to execute when Step() is called. +// next to execute when Step is called. func (vm *Engine) DisasmPC() (string, error) { - scriptIdx, scriptOff, err := vm.curPC() - if err != nil { + if err := vm.checkValidPC(); err != nil { return "", err } - return vm.disasm(scriptIdx, scriptOff), nil + + // Create a copy of the current tokenizer and parse the next opcode in the + // copy to avoid mutating the current one. + peekTokenizer := vm.tokenizer + if !peekTokenizer.Next() { + // Note that due to the fact that all scripts are checked for parse + // failures before this code ever runs, there should never be an error + // here, but check again to be safe in case a refactor breaks that + // assumption or new script versions are introduced with different + // semantics. + if err := peekTokenizer.Err(); err != nil { + return "", err + } + + // Note that this should be impossible to hit in practice because the + // only way it could happen would be for the final opcode of a script to + // already be parsed without the script index having been updated, which + // is not the case since stepping the script always increments the + // script index when parsing and executing the final opcode of a script. + // + // However, check again to be safe in case a refactor breaks that + // assumption or new script versions are introduced with different + // semantics. + str := fmt.Sprintf("program counter beyond script index %d (bytes %x)", + vm.scriptIdx, vm.scripts[vm.scriptIdx]) + return "", scriptError(ErrInvalidProgramCounter, str) + } + + var buf strings.Builder + disasmOpcode(&buf, peekTokenizer.op, peekTokenizer.Data(), false) + return fmt.Sprintf("%02x:%04x: %s", vm.scriptIdx, vm.opcodeIdx, + buf.String()), nil } // DisasmScript returns the disassembly string for the script at the requested // offset index. Index 0 is the signature script and 1 is the public key -// script. +// script. In the case of pay-to-script-hash, index 2 is the redeem script once +// the execution has progressed far enough to have successfully verified script +// hash and thus add the script to the scripts to execute. func (vm *Engine) DisasmScript(idx int) (string, error) { if idx >= len(vm.scripts) { str := fmt.Sprintf("script index %d >= total scripts %d", idx, @@ -501,19 +571,25 @@ func (vm *Engine) DisasmScript(idx int) (string, error) { return "", scriptError(ErrInvalidIndex, str) } - var disstr string - for i := range vm.scripts[idx] { - disstr = disstr + vm.disasm(idx, i) + "\n" + var disbuf strings.Builder + script := vm.scripts[idx] + tokenizer := MakeScriptTokenizer(vm.version, script) + var opcodeIdx int + for tokenizer.Next() { + disbuf.WriteString(fmt.Sprintf("%02x:%04x: ", idx, opcodeIdx)) + disasmOpcode(&disbuf, tokenizer.op, tokenizer.Data(), false) + disbuf.WriteByte('\n') + opcodeIdx++ } - return disstr, nil + return disbuf.String(), tokenizer.Err() } // CheckErrorCondition returns nil if the running script has ended and was // successful, leaving a a true boolean on the stack. An error otherwise, // including if the script has not finished. func (vm *Engine) CheckErrorCondition(finalScript bool) error { - // Check execution is actually done. When pc is past the end of script - // array there are no more scripts to run. + // Check execution is actually done by ensuring the script index is after + // the final script in the array script. if vm.scriptIdx < len(vm.scripts) { return scriptError(ErrScriptUnfinished, "error check when script unfinished") @@ -527,11 +603,14 @@ func (vm *Engine) CheckErrorCondition(finalScript bool) error { "have clean stack") } + // The final script must end with exactly one data stack item when the + // verify clean stack flag is set. Otherwise, there must be at least one + // data stack item in order to interpret it as a boolean. if finalScript && vm.hasFlag(ScriptVerifyCleanStack) && vm.dstack.Depth() != 1 { - str := fmt.Sprintf("stack contains %d unexpected items", - vm.dstack.Depth()-1) + str := fmt.Sprintf("stack must contain exactly one item (contains %d)", + vm.dstack.Depth()) return scriptError(ErrCleanStack, str) } else if vm.dstack.Depth() < 1 { return scriptError(ErrEmptyStack, @@ -545,10 +624,14 @@ func (vm *Engine) CheckErrorCondition(finalScript bool) error { if !v { // Log interesting data. log.Tracef("%v", newLogClosure(func() string { - dis0, _ := vm.DisasmScript(0) - dis1, _ := vm.DisasmScript(1) - return fmt.Sprintf("scripts failed: script0: %s\n"+ - "script1: %s", dis0, dis1) + var buf strings.Builder + buf.WriteString("scripts failed:\n") + for i := range vm.scripts { + dis, _ := vm.DisasmScript(i) + buf.WriteString(fmt.Sprintf("script%d:\n", i)) + buf.WriteString(dis) + } + return buf.String() })) return scriptError(ErrEvalFalse, "false stack entry at end of script execution") @@ -556,25 +639,39 @@ func (vm *Engine) CheckErrorCondition(finalScript bool) error { return nil } -// Step will execute the next instruction and move the program counter to the -// next opcode in the script, or the next script if the current has ended. Step -// will return true in the case that the last opcode was successfully executed. +// Step executes the next instruction and moves the program counter to the next +// opcode in the script, or the next script if the current has ended. Step will +// return true in the case that the last opcode was successfully executed. // // The result of calling Step or any other method is undefined if an error is // returned. func (vm *Engine) Step() (done bool, err error) { - // Verify that it is pointing to a valid script address. - err = vm.validPC() - if err != nil { + // Verify the engine is pointing to a valid program counter. + if err := vm.checkValidPC(); err != nil { return true, err } - opcode := &vm.scripts[vm.scriptIdx][vm.scriptOff] - vm.scriptOff++ + + // Attempt to parse the next opcode from the current script. + if !vm.tokenizer.Next() { + // Note that due to the fact that all scripts are checked for parse + // failures before this code ever runs, there should never be an error + // here, but check again to be safe in case a refactor breaks that + // assumption or new script versions are introduced with different + // semantics. + if err := vm.tokenizer.Err(); err != nil { + return false, err + } + + str := fmt.Sprintf("attempt to step beyond script index %d (bytes %x)", + vm.scriptIdx, vm.scripts[vm.scriptIdx]) + return true, scriptError(ErrInvalidProgramCounter, str) + } // Execute the opcode while taking into account several things such as - // disabled opcodes, illegal opcodes, maximum allowed operations per - // script, maximum script element sizes, and conditionals. - err = vm.executeOpcode(opcode) + // disabled opcodes, illegal opcodes, maximum allowed operations per script, + // maximum script element sizes, and conditionals. + pop := parsedOpcode{opcode: vm.tokenizer.op, data: vm.tokenizer.Data()} + err = vm.executeOpcode(&pop) if err != nil { return true, err } @@ -589,43 +686,53 @@ func (vm *Engine) Step() (done bool, err error) { } // Prepare for next instruction. - if vm.scriptOff >= len(vm.scripts[vm.scriptIdx]) { - // Illegal to have an `if' that straddles two scripts. - if err == nil && len(vm.condStack) != 0 { + vm.opcodeIdx++ + if vm.tokenizer.Done() { + // Illegal to have a conditional that straddles two scripts. + if len(vm.condStack) != 0 { return false, scriptError(ErrUnbalancedConditional, "end of script reached in conditional execution") } - // Alt stack doesn't persist. + // Alt stack doesn't persist between scripts. _ = vm.astack.DropN(vm.astack.Depth()) - vm.numOps = 0 // number of ops is per script. - vm.scriptOff = 0 - if vm.scriptIdx == 0 && vm.bip16 { + // The number of operations is per script. + vm.numOps = 0 + + // Reset the opcode index for the next script. + vm.opcodeIdx = 0 + + // Advance to the next script as needed. + switch { + case vm.scriptIdx == 0 && vm.bip16: vm.scriptIdx++ vm.savedFirstStack = vm.GetStack() - } else if vm.scriptIdx == 1 && vm.bip16 { + + case vm.scriptIdx == 1 && vm.bip16: // Put us past the end for CheckErrorCondition() vm.scriptIdx++ - // Check script ran successfully and pull the script - // out of the first stack and execute that. + + // Check script ran successfully. err := vm.CheckErrorCondition(false) if err != nil { return false, err } + // Obtain the redeem script from the first stack and ensure it + // parses. script := vm.savedFirstStack[len(vm.savedFirstStack)-1] - pops, err := parseScript(script) - if err != nil { + if err := checkScriptParses(vm.version, script); err != nil { return false, err } - vm.scripts = append(vm.scripts, pops) + vm.scripts = append(vm.scripts, script) - // Set stack to be the stack from first script minus the + // Set stack to be the stack from first script minus the redeem // script itself vm.SetStack(vm.savedFirstStack[:len(vm.savedFirstStack)-1]) - } else if (vm.scriptIdx == 1 && vm.witnessProgram != nil) || - (vm.scriptIdx == 2 && vm.witnessProgram != nil && vm.bip16) { // Nested P2SH. + + case vm.scriptIdx == 1 && vm.witnessProgram != nil, + vm.scriptIdx == 2 && vm.witnessProgram != nil && vm.bip16: // np2sh vm.scriptIdx++ @@ -633,30 +740,46 @@ func (vm *Engine) Step() (done bool, err error) { if err := vm.verifyWitnessProgram(witness); err != nil { return false, err } - } else { + + default: vm.scriptIdx++ } - // there are zero length scripts in the wild - if vm.scriptIdx < len(vm.scripts) && vm.scriptOff >= len(vm.scripts[vm.scriptIdx]) { + + // Skip empty scripts. + if vm.scriptIdx < len(vm.scripts) && len(vm.scripts[vm.scriptIdx]) == 0 { vm.scriptIdx++ } + vm.lastCodeSep = 0 if vm.scriptIdx >= len(vm.scripts) { return true, nil } + + // Finally, update the current tokenizer used to parse through scripts + // one opcode at a time to start from the beginning of the new script + // associated with the program counter. + vm.tokenizer = MakeScriptTokenizer(vm.version, vm.scripts[vm.scriptIdx]) } + return false, nil } // Execute will execute all scripts in the script engine and return either nil // for successful validation or an error if one occurred. func (vm *Engine) Execute() (err error) { + // All script versions other than 0 currently execute without issue, + // making all outputs to them anyone can pay. In the future this + // will allow for the addition of new scripting languages. + if vm.version != 0 { + return nil + } + done := false for !done { log.Tracef("%v", newLogClosure(func() string { dis, err := vm.DisasmPC() if err != nil { - return fmt.Sprintf("stepping (%v)", err) + return fmt.Sprintf("stepping - failed to disasm pc: %v", err) } return fmt.Sprintf("stepping %v", dis) })) @@ -668,7 +791,7 @@ func (vm *Engine) Execute() (err error) { log.Tracef("%v", newLogClosure(func() string { var dstr, astr string - // if we're tracing, dump the stacks. + // Log the non-empty stacks when tracing. if vm.dstack.Depth() != 0 { dstr = "Stack:\n" + vm.dstack.String() } @@ -684,7 +807,7 @@ func (vm *Engine) Execute() (err error) { } // subScript returns the script since the last OP_CODESEPARATOR. -func (vm *Engine) subScript() []parsedOpcode { +func (vm *Engine) subScript() []byte { return vm.scripts[vm.scriptIdx][vm.lastCodeSep:] } @@ -1008,10 +1131,10 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags } scriptSig := tx.TxIn[txIdx].SignatureScript - // When both the signature script and public key script are empty the - // result is necessarily an error since the stack would end up being - // empty which is equivalent to a false top element. Thus, just return - // the relevant error now as an optimization. + // When both the signature script and public key script are empty the result + // is necessarily an error since the stack would end up being empty which is + // equivalent to a false top element. Thus, just return the relevant error + // now as an optimization. if len(scriptSig) == 0 && len(scriptPubKey) == 0 { return nil, scriptError(ErrEvalFalse, "false stack entry at end of script execution") @@ -1057,29 +1180,28 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags vm.bip16 = true } - // The engine stores the scripts in parsed form using a slice. This - // allows multiple scripts to be executed in sequence. For example, - // with a pay-to-script-hash transaction, there will be ultimately be - // a third script to execute. + // The engine stores the scripts using a slice. This allows multiple + // scripts to be executed in sequence. For example, with a + // pay-to-script-hash transaction, there will be ultimately be a third + // script to execute. scripts := [][]byte{scriptSig, scriptPubKey} - vm.scripts = make([][]parsedOpcode, len(scripts)) - for i, scr := range scripts { + for _, scr := range scripts { if len(scr) > MaxScriptSize { - str := fmt.Sprintf("script size %d is larger than max "+ - "allowed size %d", len(scr), MaxScriptSize) + str := fmt.Sprintf("script size %d is larger than max allowed "+ + "size %d", len(scr), MaxScriptSize) return nil, scriptError(ErrScriptTooBig, str) } - var err error - vm.scripts[i], err = parseScript(scr) - if err != nil { + + const scriptVersion = 0 + if err := checkScriptParses(scriptVersion, scr); err != nil { return nil, err } } + vm.scripts = scripts // Advance the program counter to the public key script if the signature - // script is empty since there is nothing to execute for it in that - // case. - if len(scripts[0]) == 0 { + // script is empty since there is nothing to execute for it in that case. + if len(scriptSig) == 0 { vm.scriptIdx++ } if vm.hasFlag(ScriptVerifyMinimalData) { @@ -1103,7 +1225,7 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags var witProgram []byte switch { - case isWitnessProgram(vm.scripts[1]): + case IsWitnessProgram(vm.scripts[1]): // The scriptSig must be *empty* for all native witness // programs, otherwise we introduce malleability. if len(scriptSig) != 0 { @@ -1118,12 +1240,11 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags // data push of the witness program, otherwise we // reintroduce malleability. sigPops := vm.scripts[0] - if len(sigPops) == 1 && - isCanonicalPush(sigPops[0].opcode.value, - sigPops[0].data) && - IsWitnessProgram(sigPops[0].data) { + if len(sigPops) > 2 && + isCanonicalPush(sigPops[0], sigPops[1:]) && + IsWitnessProgram(sigPops[1:]) { - witProgram = sigPops[0].data + witProgram = sigPops[1:] } else { errStr := "signature script for witness " + "nested p2sh is not canonical" @@ -1150,6 +1271,10 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags } + // Setup the current tokenizer used to parse through the script one opcode + // at a time with the script associated with the program counter. + vm.tokenizer = MakeScriptTokenizer(scriptVersion, scripts[vm.scriptIdx]) + vm.tx = *tx vm.txIdx = txIdx diff --git a/txscript/engine_test.go b/txscript/engine_test.go index 2e8c522c..5818080d 100644 --- a/txscript/engine_test.go +++ b/txscript/engine_test.go @@ -1,4 +1,5 @@ // Copyright (c) 2013-2017 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -11,16 +12,16 @@ import ( "github.com/btcsuite/btcd/wire" ) -// TestBadPC sets the pc to a deliberately bad result then confirms that Step() +// TestBadPC sets the pc to a deliberately bad result then confirms that Step // and Disasm fail correctly. func TestBadPC(t *testing.T) { t.Parallel() tests := []struct { - script, off int + scriptIdx int }{ - {script: 2, off: 0}, - {script: 0, off: 2}, + {scriptIdx: 2}, + {scriptIdx: 3}, } // tx with almost empty scripts. @@ -59,20 +60,20 @@ func TestBadPC(t *testing.T) { t.Errorf("Failed to create script: %v", err) } - // set to after all scripts - vm.scriptIdx = test.script - vm.scriptOff = test.off + // Set to after all scripts. + vm.scriptIdx = test.scriptIdx + // Ensure attempting to step fails. _, err = vm.Step() if err == nil { t.Errorf("Step with invalid pc (%v) succeeds!", test) continue } + // Ensure attempting to disassemble the current program counter fails. _, err = vm.DisasmPC() if err == nil { - t.Errorf("DisasmPC with invalid pc (%v) succeeds!", - test) + t.Errorf("DisasmPC with invalid pc (%v) succeeds!", test) } } } diff --git a/txscript/opcode.go b/txscript/opcode.go index a0d05052..950121c6 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -1981,7 +1981,7 @@ func opcodeHash256(op *parsedOpcode, vm *Engine) error { // // This opcode does not change the contents of the data stack. func opcodeCodeSeparator(op *parsedOpcode, vm *Engine) error { - vm.lastCodeSep = vm.scriptOff + vm.lastCodeSep = int(vm.tokenizer.ByteIndex()) return nil } @@ -2055,7 +2055,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { sigHashes = NewTxSigHashes(&vm.tx) } - hash, err = calcWitnessSignatureHash(subScript, sigHashes, hashType, + hash, err = calcWitnessSignatureHashRaw(subScript, sigHashes, hashType, &vm.tx, vm.txIdx, vm.inputAmount) if err != nil { return err @@ -2063,12 +2063,9 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { } else { // Remove the signature since there is no way for a signature // to sign itself. - subScript = removeOpcodeByData(subScript, fullSigBytes) + subScript = removeOpcodeByDataRaw(subScript, fullSigBytes) - hash, err = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx) - if err != nil { - return err - } + hash = calcSignatureHashRaw(subScript, hashType, &vm.tx, vm.txIdx) } pubKey, err := btcec.ParsePubKey(pkBytes, btcec.S256()) @@ -2239,7 +2236,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { // no way for a signature to sign itself. if !vm.isWitnessVersionActive(0) { for _, sigInfo := range signatures { - script = removeOpcodeByData(script, sigInfo.signature) + script = removeOpcodeByDataRaw(script, sigInfo.signature) } } @@ -2331,16 +2328,13 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { sigHashes = NewTxSigHashes(&vm.tx) } - hash, err = calcWitnessSignatureHash(script, sigHashes, hashType, + hash, err = calcWitnessSignatureHashRaw(script, sigHashes, hashType, &vm.tx, vm.txIdx, vm.inputAmount) if err != nil { return err } } else { - hash, err = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx) - if err != nil { - return err - } + hash = calcSignatureHashRaw(script, hashType, &vm.tx, vm.txIdx) } var valid bool -- 2.45.2 From 06c8bea6c76f73f8afa214a99d45fe9c65a20d2d Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:05:20 -0700 Subject: [PATCH 095/459] txscript: Remove unused calcSignatureHash --- txscript/script.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 0be0a7b8..8ff39e20 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -744,21 +744,6 @@ func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx return chainhash.DoubleHashB(wbuf.Bytes()) } -// calcSignatureHash computes the signature hash for the specified input of the -// target transaction observing the desired signature hash type. -// -// DEPRECATED: Use calcSignatureHashRaw instead -func calcSignatureHash(prevOutScript []parsedOpcode, hashType SigHashType, - tx *wire.MsgTx, idx int) ([]byte, error) { - - sigScript, err := unparseScript(prevOutScript) - if err != nil { - return nil, err - } - - return calcSignatureHashRaw(sigScript, hashType, tx, idx), nil -} - // asSmallInt returns the passed opcode, which must be true according to // isSmallInt(), as an integer. func asSmallInt(op byte) int { -- 2.45.2 From 03d1fb0f86ac8dc65c6e67b31069630fce70fb69 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 20:09:59 -0700 Subject: [PATCH 096/459] txscript: Remove unused isWitnessProgram --- txscript/script.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 8ff39e20..6557c64d 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -98,21 +98,6 @@ func IsWitnessProgram(script []byte) bool { return isWitnessProgramScript(script) } -// isWitnessProgram returns true if the passed script is a witness program, and -// false otherwise. A witness program MUST adhere to the following constraints: -// there must be exactly two pops (program version and the program itself), the -// first opcode MUST be a small integer (0-16), the push data MUST be -// canonical, and finally the size of the push data must be between 2 and 40 -// bytes. -// -// DEPRECATED: Use isWitnessProgramScript instead. -func isWitnessProgram(pops []parsedOpcode) bool { - return len(pops) == 2 && - isSmallInt(pops[0].opcode.value) && - isCanonicalPush(pops[1].opcode.value, pops[1].data) && - (len(pops[1].data) >= 2 && len(pops[1].data) <= 40) -} - // IsNullData returns true if the passed script is a null data script, false // otherwise. func IsNullData(script []byte) bool { -- 2.45.2 From 07ab66b790e0b732868548e0624c62a7b03a2863 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:59 -0500 Subject: [PATCH 097/459] txscript: Remove unused removeOpcodeByData func. --- txscript/script.go | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 6557c64d..242fc2d8 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -318,23 +318,6 @@ func isCanonicalPush(opcode byte, data []byte) bool { return true } -// removeOpcodeByData will return the script minus any opcodes that would push -// the passed data to the stack. -// -// DEPRECATED. Use removeOpcodeByDataRaw instead. -func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode { - retScript := make([]parsedOpcode, 0, len(pkscript)) - for _, pop := range pkscript { - if !isCanonicalPush(pop.opcode.value, pop.data) || - !bytes.Contains(pop.data, data) { - - retScript = append(retScript, pop) - } - } - return retScript - -} - // removeOpcodeByDataRaw will return the script minus any opcodes that perform a // canonical push of data that contains the passed data to remove. This // function assumes it is provided a version 0 script as any future version of -- 2.45.2 From 911db90858acff024c54715b5336c95285e695ae Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:00 -0500 Subject: [PATCH 098/459] txscript: Rename removeOpcodeByDataRaw func. This renames the removeOpcodeByDataRaw to removeOpcodeByData now that the old version has been removed. --- txscript/opcode.go | 4 ++-- txscript/script.go | 4 ++-- txscript/script_test.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 950121c6..1d8ee25e 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -2063,7 +2063,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { } else { // Remove the signature since there is no way for a signature // to sign itself. - subScript = removeOpcodeByDataRaw(subScript, fullSigBytes) + subScript = removeOpcodeByData(subScript, fullSigBytes) hash = calcSignatureHashRaw(subScript, hashType, &vm.tx, vm.txIdx) } @@ -2236,7 +2236,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { // no way for a signature to sign itself. if !vm.isWitnessVersionActive(0) { for _, sigInfo := range signatures { - script = removeOpcodeByDataRaw(script, sigInfo.signature) + script = removeOpcodeByData(script, sigInfo.signature) } } diff --git a/txscript/script.go b/txscript/script.go index 242fc2d8..266c36dd 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -318,7 +318,7 @@ func isCanonicalPush(opcode byte, data []byte) bool { return true } -// removeOpcodeByDataRaw will return the script minus any opcodes that perform a +// removeOpcodeByData will return the script minus any opcodes that perform a // canonical push of data that contains the passed data to remove. This // function assumes it is provided a version 0 script as any future version of // script should avoid this functionality since it is unncessary due to the @@ -332,7 +332,7 @@ func isCanonicalPush(opcode byte, data []byte) bool { // NOTE: This function is only valid for version 0 scripts. Since the function // does not accept a script version, the results are undefined for other script // versions. -func removeOpcodeByDataRaw(script []byte, dataToRemove []byte) []byte { +func removeOpcodeByData(script []byte, dataToRemove []byte) []byte { // Avoid work when possible. if len(script) == 0 || len(dataToRemove) == 0 { return script diff --git a/txscript/script_test.go b/txscript/script_test.go index 02c364ce..7db065de 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -4136,7 +4136,7 @@ func TestRemoveOpcodeByData(t *testing.T) { return nil, err } - return removeOpcodeByDataRaw(script, data), nil + return removeOpcodeByData(script, data), nil } for _, test := range tests { -- 2.45.2 From 94e99cf6b7d572ebe46eebc79d04a4a2cb071001 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:07:18 -0700 Subject: [PATCH 099/459] txscript: Rename calcSignatureHashRaw --- txscript/opcode.go | 4 ++-- txscript/script.go | 8 ++++---- txscript/sign.go | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 1d8ee25e..9e0320ae 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -2065,7 +2065,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { // to sign itself. subScript = removeOpcodeByData(subScript, fullSigBytes) - hash = calcSignatureHashRaw(subScript, hashType, &vm.tx, vm.txIdx) + hash = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx) } pubKey, err := btcec.ParsePubKey(pkBytes, btcec.S256()) @@ -2334,7 +2334,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { return err } } else { - hash = calcSignatureHashRaw(script, hashType, &vm.tx, vm.txIdx) + hash = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx) } var valid bool diff --git a/txscript/script.go b/txscript/script.go index 266c36dd..2e3431d0 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -618,12 +618,12 @@ func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx return nil, err } - return calcSignatureHashRaw(script, hashType, tx, idx), nil + return calcSignatureHash(script, hashType, tx, idx), nil } -// calcSignatureHashRaw computes the signature hash for the specified input of -// the target transaction observing the desired signature hash type. -func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx, idx int) []byte { +// calcSignatureHash computes the signature hash for the specified input of the +// target transaction observing the desired signature hash type. +func calcSignatureHash(sigScript []byte, hashType SigHashType, tx *wire.MsgTx, idx int) []byte { // The SigHashSingle signature type signs only the corresponding input // and output (the output with the same index number as the input). // diff --git a/txscript/sign.go b/txscript/sign.go index 4d63a9b2..51c69103 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -285,7 +285,7 @@ sigLoop: // however, assume no sigs etc are in the script since that // would make the transaction nonstandard and thus not // MultiSigTy, so we just need to hash the full thing. - hash := calcSignatureHashRaw(pkScript, hashType, tx, idx) + hash := calcSignatureHash(pkScript, hashType, tx, idx) for _, addr := range addresses { // All multisig addresses should be pubkey addresses -- 2.45.2 From 69f3a39c1c96ba024ed332dd12f86f8f5cf7ba33 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:10:48 -0700 Subject: [PATCH 100/459] txscript/sign: Use calcWitnessSigHashRaw for witness sigs --- txscript/sign.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/txscript/sign.go b/txscript/sign.go index 51c69103..138e31cd 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -22,12 +22,7 @@ func RawTxInWitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int, amt int64, subScript []byte, hashType SigHashType, key *btcec.PrivateKey) ([]byte, error) { - parsedScript, err := parseScript(subScript) - if err != nil { - return nil, fmt.Errorf("cannot parse output script: %v", err) - } - - hash, err := calcWitnessSignatureHash(parsedScript, sigHashes, hashType, tx, + hash, err := calcWitnessSignatureHashRaw(subScript, sigHashes, hashType, tx, idx, amt) if err != nil { return nil, err -- 2.45.2 From 753367299342906c9323cf94a14b151f282c9e4a Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:31:33 -0700 Subject: [PATCH 101/459] txscript/pkscript: Use finalOpcodeData to extract redeem script --- txscript/pkscript.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/txscript/pkscript.go b/txscript/pkscript.go index 0703ef5d..f5b11e6d 100644 --- a/txscript/pkscript.go +++ b/txscript/pkscript.go @@ -211,11 +211,12 @@ func computeNonWitnessPkScript(sigScript []byte) (PkScript, error) { // The redeem script will always be the last data push of the // signature script, so we'll parse the script into opcodes to // obtain it. - parsedOpcodes, err := parseScript(sigScript) + const scriptVersion = 0 + err := checkScriptParses(scriptVersion, sigScript) if err != nil { return PkScript{}, err } - redeemScript := parsedOpcodes[len(parsedOpcodes)-1].data + redeemScript := finalOpcodeData(scriptVersion, sigScript) scriptHash := hash160(redeemScript) script, err := payToScriptHashScript(scriptHash) -- 2.45.2 From 6e5fbf8ea85ca1689d00421f2966436166c2e072 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:03 -0500 Subject: [PATCH 102/459] txscript: Remove unused parseScript func. --- txscript/script.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 2e3431d0..1a8890b9 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -202,12 +202,6 @@ func checkScriptTemplateParseable(script []byte, opcodes *[256]opcode) (*byte, e return &firstOpcode, nil } -// parseScript preparses the script in bytes into a list of parsedOpcodes while -// applying a number of sanity checks. -func parseScript(script []byte) ([]parsedOpcode, error) { - return parseScriptTemplate(script, &opcodeArray) -} - // unparseScript reversed the action of parseScript and returns the // parsedOpcodes as a list of bytes func unparseScript(pops []parsedOpcode) ([]byte, error) { -- 2.45.2 From e06b11a999da91b6e0179795def1f2ee67e3b159 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:48:25 -0700 Subject: [PATCH 103/459] txscript: Remove unused calcWitnessSignatureHash --- txscript/script.go | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 1a8890b9..97c2f401 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -534,30 +534,6 @@ func calcWitnessSignatureHashRaw(scriptSig []byte, sigHashes *TxSigHashes, return chainhash.DoubleHashB(sigHash.Bytes()), nil } -// calcWitnessSignatureHash computes the sighash digest of a transaction's -// segwit input using the new, optimized digest calculation algorithm defined -// in BIP0143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki. -// This function makes use of pre-calculated sighash fragments stored within -// the passed HashCache to eliminate duplicate hashing computations when -// calculating the final digest, reducing the complexity from O(N^2) to O(N). -// Additionally, signatures now cover the input value of the referenced unspent -// output. This allows offline, or hardware wallets to compute the exact amount -// being spent, in addition to the final transaction fee. In the case the -// wallet if fed an invalid input amount, the real sighash will differ causing -// the produced signature to be invalid. -// -// DEPRECATED: Use calcWitnessSignatureHashRaw instead. -func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, - hashType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { - - script, err := unparseScript(subScript) - if err != nil { - return nil, err - } - - return calcWitnessSignatureHashRaw(script, sigHashes, hashType, tx, idx, amt) -} - // CalcWitnessSigHash computes the sighash digest for the specified input of // the target transaction observing the desired sig hash type. func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType SigHashType, -- 2.45.2 From 491b7b59fc4ad2ed8fb516a0105c2ff44a014397 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:04 -0500 Subject: [PATCH 104/459] txscript: Remove unused unparseScript func. Also remove tests associated with unparsing opcodes accordingly. --- txscript/script.go | 14 - txscript/script_test.go | 3651 --------------------------------------- 2 files changed, 3665 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 97c2f401..0dbe4683 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -202,20 +202,6 @@ func checkScriptTemplateParseable(script []byte, opcodes *[256]opcode) (*byte, e return &firstOpcode, nil } -// unparseScript reversed the action of parseScript and returns the -// parsedOpcodes as a list of bytes -func unparseScript(pops []parsedOpcode) ([]byte, error) { - script := make([]byte, 0, len(pops)) - for _, pop := range pops { - b, err := pop.bytes() - if err != nil { - return nil, err - } - script = append(script, b...) - } - return script, nil -} - // DisasmString formats a disassembled script for one line printing. When the // script fails to parse, the returned string will contain the disassembled // script up to the point the failure occurred along with the string '[error]' diff --git a/txscript/script_test.go b/txscript/script_test.go index 7db065de..b6e7ff42 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -28,3657 +28,6 @@ func TestParseOpcode(t *testing.T) { } } -// TestUnparsingInvalidOpcodes tests for errors when unparsing invalid parsed -// opcodes. -func TestUnparsingInvalidOpcodes(t *testing.T) { - tests := []struct { - name string - pop *parsedOpcode - expectedErr error - }{ - { - name: "OP_FALSE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_FALSE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_FALSE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_FALSE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_1 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_1], - data: nil, - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_1], - data: make([]byte, 1), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_1 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_1], - data: make([]byte, 2), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_2 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_2], - data: make([]byte, 2), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_2], - data: make([]byte, 3), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_3 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_3], - data: make([]byte, 2), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_3", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_3], - data: make([]byte, 3), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_3 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_3], - data: make([]byte, 4), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_4 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_4], - data: make([]byte, 3), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_4", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_4], - data: make([]byte, 4), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_4 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_4], - data: make([]byte, 5), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_5 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_5], - data: make([]byte, 4), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_5", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_5], - data: make([]byte, 5), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_5 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_5], - data: make([]byte, 6), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_6 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_6], - data: make([]byte, 5), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_6", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_6], - data: make([]byte, 6), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_6 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_6], - data: make([]byte, 7), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_7 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_7], - data: make([]byte, 6), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_7", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_7], - data: make([]byte, 7), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_7 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_7], - data: make([]byte, 8), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_8 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_8], - data: make([]byte, 7), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_8", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_8], - data: make([]byte, 8), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_8 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_8], - data: make([]byte, 9), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_9 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_9], - data: make([]byte, 8), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_9", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_9], - data: make([]byte, 9), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_9 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_9], - data: make([]byte, 10), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_10 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_10], - data: make([]byte, 9), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_10", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_10], - data: make([]byte, 10), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_10 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_10], - data: make([]byte, 11), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_11 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_11], - data: make([]byte, 10), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_11", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_11], - data: make([]byte, 11), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_11 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_11], - data: make([]byte, 12), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_12 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_12], - data: make([]byte, 11), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_12", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_12], - data: make([]byte, 12), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_12 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_12], - data: make([]byte, 13), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_13 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_13], - data: make([]byte, 12), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_13", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_13], - data: make([]byte, 13), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_13 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_13], - data: make([]byte, 14), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_14 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_14], - data: make([]byte, 13), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_14", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_14], - data: make([]byte, 14), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_14 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_14], - data: make([]byte, 15), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_15 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_15], - data: make([]byte, 14), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_15", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_15], - data: make([]byte, 15), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_15 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_15], - data: make([]byte, 16), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_16 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_16], - data: make([]byte, 15), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_16", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_16], - data: make([]byte, 16), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_16 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_16], - data: make([]byte, 17), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_17 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_17], - data: make([]byte, 16), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_17", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_17], - data: make([]byte, 17), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_17 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_17], - data: make([]byte, 18), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_18 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_18], - data: make([]byte, 17), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_18", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_18], - data: make([]byte, 18), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_18 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_18], - data: make([]byte, 19), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_19 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_19], - data: make([]byte, 18), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_19", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_19], - data: make([]byte, 19), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_19 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_19], - data: make([]byte, 20), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_20 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_20], - data: make([]byte, 19), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_20", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_20], - data: make([]byte, 20), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_20 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_20], - data: make([]byte, 21), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_21 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_21], - data: make([]byte, 20), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_21", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_21], - data: make([]byte, 21), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_21 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_21], - data: make([]byte, 22), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_22 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_22], - data: make([]byte, 21), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_22", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_22], - data: make([]byte, 22), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_22 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_22], - data: make([]byte, 23), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_23 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_23], - data: make([]byte, 22), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_23", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_23], - data: make([]byte, 23), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_23 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_23], - data: make([]byte, 24), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_24 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_24], - data: make([]byte, 23), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_24", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_24], - data: make([]byte, 24), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_24 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_24], - data: make([]byte, 25), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_25 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_25], - data: make([]byte, 24), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_25", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_25], - data: make([]byte, 25), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_25 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_25], - data: make([]byte, 26), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_26 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_26], - data: make([]byte, 25), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_26", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_26], - data: make([]byte, 26), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_26 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_26], - data: make([]byte, 27), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_27 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_27], - data: make([]byte, 26), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_27", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_27], - data: make([]byte, 27), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_27 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_27], - data: make([]byte, 28), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_28 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_28], - data: make([]byte, 27), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_28", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_28], - data: make([]byte, 28), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_28 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_28], - data: make([]byte, 29), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_29 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_29], - data: make([]byte, 28), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_29", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_29], - data: make([]byte, 29), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_29 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_29], - data: make([]byte, 30), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_30 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_30], - data: make([]byte, 29), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_30", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_30], - data: make([]byte, 30), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_30 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_30], - data: make([]byte, 31), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_31 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_31], - data: make([]byte, 30), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_31", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_31], - data: make([]byte, 31), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_31 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_31], - data: make([]byte, 32), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_32 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_32], - data: make([]byte, 31), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_32", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_32], - data: make([]byte, 32), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_32 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_32], - data: make([]byte, 33), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_33 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_33], - data: make([]byte, 32), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_33", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_33], - data: make([]byte, 33), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_33 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_33], - data: make([]byte, 34), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_34 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_34], - data: make([]byte, 33), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_34", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_34], - data: make([]byte, 34), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_34 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_34], - data: make([]byte, 35), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_35 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_35], - data: make([]byte, 34), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_35", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_35], - data: make([]byte, 35), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_35 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_35], - data: make([]byte, 36), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_36 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_36], - data: make([]byte, 35), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_36", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_36], - data: make([]byte, 36), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_36 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_36], - data: make([]byte, 37), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_37 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_37], - data: make([]byte, 36), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_37", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_37], - data: make([]byte, 37), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_37 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_37], - data: make([]byte, 38), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_38 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_38], - data: make([]byte, 37), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_38", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_38], - data: make([]byte, 38), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_38 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_38], - data: make([]byte, 39), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_39 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_39], - data: make([]byte, 38), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_39", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_39], - data: make([]byte, 39), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_39 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_39], - data: make([]byte, 40), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_40 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_40], - data: make([]byte, 39), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_40", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_40], - data: make([]byte, 40), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_40 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_40], - data: make([]byte, 41), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_41 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_41], - data: make([]byte, 40), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_41", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_41], - data: make([]byte, 41), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_41 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_41], - data: make([]byte, 42), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_42 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_42], - data: make([]byte, 41), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_42", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_42], - data: make([]byte, 42), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_42 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_42], - data: make([]byte, 43), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_43 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_43], - data: make([]byte, 42), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_43", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_43], - data: make([]byte, 43), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_43 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_43], - data: make([]byte, 44), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_44 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_44], - data: make([]byte, 43), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_44", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_44], - data: make([]byte, 44), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_44 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_44], - data: make([]byte, 45), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_45 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_45], - data: make([]byte, 44), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_45", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_45], - data: make([]byte, 45), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_45 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_45], - data: make([]byte, 46), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_46 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_46], - data: make([]byte, 45), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_46", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_46], - data: make([]byte, 46), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_46 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_46], - data: make([]byte, 47), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_47 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_47], - data: make([]byte, 46), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_47", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_47], - data: make([]byte, 47), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_47 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_47], - data: make([]byte, 48), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_48 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_48], - data: make([]byte, 47), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_48", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_48], - data: make([]byte, 48), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_48 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_48], - data: make([]byte, 49), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_49 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_49], - data: make([]byte, 48), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_49", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_49], - data: make([]byte, 49), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_49 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_49], - data: make([]byte, 50), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_50 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_50], - data: make([]byte, 49), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_50", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_50], - data: make([]byte, 50), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_50 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_50], - data: make([]byte, 51), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_51 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_51], - data: make([]byte, 50), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_51", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_51], - data: make([]byte, 51), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_51 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_51], - data: make([]byte, 52), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_52 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_52], - data: make([]byte, 51), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_52", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_52], - data: make([]byte, 52), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_52 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_52], - data: make([]byte, 53), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_53 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_53], - data: make([]byte, 52), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_53", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_53], - data: make([]byte, 53), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_53 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_53], - data: make([]byte, 54), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_54 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_54], - data: make([]byte, 53), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_54", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_54], - data: make([]byte, 54), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_54 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_54], - data: make([]byte, 55), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_55 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_55], - data: make([]byte, 54), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_55", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_55], - data: make([]byte, 55), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_55 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_55], - data: make([]byte, 56), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_56 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_56], - data: make([]byte, 55), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_56", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_56], - data: make([]byte, 56), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_56 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_56], - data: make([]byte, 57), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_57 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_57], - data: make([]byte, 56), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_57", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_57], - data: make([]byte, 57), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_57 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_57], - data: make([]byte, 58), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_58 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_58], - data: make([]byte, 57), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_58", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_58], - data: make([]byte, 58), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_58 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_58], - data: make([]byte, 59), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_59 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_59], - data: make([]byte, 58), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_59", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_59], - data: make([]byte, 59), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_59 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_59], - data: make([]byte, 60), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_60 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_60], - data: make([]byte, 59), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_60", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_60], - data: make([]byte, 60), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_60 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_60], - data: make([]byte, 61), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_61 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_61], - data: make([]byte, 60), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_61", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_61], - data: make([]byte, 61), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_61 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_61], - data: make([]byte, 62), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_62 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_62], - data: make([]byte, 61), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_62", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_62], - data: make([]byte, 62), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_62 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_62], - data: make([]byte, 63), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_63 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_63], - data: make([]byte, 62), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_63", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_63], - data: make([]byte, 63), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_63 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_63], - data: make([]byte, 64), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_64 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_64], - data: make([]byte, 63), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_64", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_64], - data: make([]byte, 64), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_64 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_64], - data: make([]byte, 65), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_65 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_65], - data: make([]byte, 64), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_65", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_65], - data: make([]byte, 65), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_65 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_65], - data: make([]byte, 66), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_66 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_66], - data: make([]byte, 65), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_66", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_66], - data: make([]byte, 66), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_66 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_66], - data: make([]byte, 67), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_67 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_67], - data: make([]byte, 66), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_67", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_67], - data: make([]byte, 67), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_67 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_67], - data: make([]byte, 68), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_68 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_68], - data: make([]byte, 67), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_68", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_68], - data: make([]byte, 68), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_68 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_68], - data: make([]byte, 69), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_69 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_69], - data: make([]byte, 68), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_69", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_69], - data: make([]byte, 69), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_69 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_69], - data: make([]byte, 70), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_70 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_70], - data: make([]byte, 69), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_70", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_70], - data: make([]byte, 70), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_70 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_70], - data: make([]byte, 71), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_71 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_71], - data: make([]byte, 70), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_71", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_71], - data: make([]byte, 71), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_71 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_71], - data: make([]byte, 72), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_72 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_72], - data: make([]byte, 71), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_72", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_72], - data: make([]byte, 72), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_72 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_72], - data: make([]byte, 73), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_73 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_73], - data: make([]byte, 72), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_73", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_73], - data: make([]byte, 73), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_73 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_73], - data: make([]byte, 74), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_74 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_74], - data: make([]byte, 73), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_74", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_74], - data: make([]byte, 74), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_74 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_74], - data: make([]byte, 75), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_75 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_75], - data: make([]byte, 74), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_75", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_75], - data: make([]byte, 75), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_75 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_75], - data: make([]byte, 76), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_PUSHDATA1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUSHDATA1], - data: []byte{0, 1, 2, 3, 4}, - }, - expectedErr: nil, - }, - { - name: "OP_PUSHDATA2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUSHDATA2], - data: []byte{0, 1, 2, 3, 4}, - }, - expectedErr: nil, - }, - { - name: "OP_PUSHDATA4", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUSHDATA1], - data: []byte{0, 1, 2, 3, 4}, - }, - expectedErr: nil, - }, - { - name: "OP_1NEGATE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1NEGATE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_1NEGATE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1NEGATE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RESERVED", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RESERVED long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_TRUE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TRUE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_TRUE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TRUE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_3", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_3], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_3 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_3], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_4", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_4], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_4 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_4], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_5", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_5], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_5 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_5], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_6", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_6], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_6 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_6], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_7", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_7], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_7 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_7], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_8", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_8], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_8 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_8], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_9", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_9], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_9 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_9], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_10", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_10], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_10 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_10], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_11", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_11], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_11 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_11], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_12", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_12], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_12 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_12], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_13", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_13], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_13 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_13], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_14", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_14], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_14 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_14], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_15", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_15], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_15 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_15], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_16", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_16], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_16 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_16], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_VER", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VER], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_VER long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VER], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_IF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_IF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_IF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_IF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOTIF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOTIF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOTIF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOTIF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_VERIF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERIF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_VERIF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERIF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_VERNOTIF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERNOTIF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_VERNOTIF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERNOTIF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ELSE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ELSE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ELSE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ELSE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ENDIF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ENDIF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ENDIF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ENDIF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_VERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_VERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RETURN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RETURN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RETURN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RETURN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_TOALTSTACK", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TOALTSTACK], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_TOALTSTACK long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TOALTSTACK], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_FROMALTSTACK", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_FROMALTSTACK], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_FROMALTSTACK long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_FROMALTSTACK], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2DROP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DROP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2DROP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DROP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2DUP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DUP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2DUP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DUP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_3DUP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_3DUP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_3DUP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_3DUP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2OVER", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2OVER], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2OVER long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2OVER], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2ROT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2ROT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2ROT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2ROT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2SWAP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2SWAP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2SWAP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2SWAP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_IFDUP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_IFDUP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_IFDUP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_IFDUP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DEPTH", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DEPTH], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_DEPTH long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DEPTH], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DROP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DROP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_DROP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DROP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DUP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DUP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_DUP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DUP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NIP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NIP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NIP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NIP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_OVER", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_OVER], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_OVER long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_OVER], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_PICK", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PICK], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_PICK long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PICK], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ROLL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ROLL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ROLL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ROLL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ROT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ROT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ROT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ROT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SWAP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SWAP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SWAP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SWAP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_TUCK", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TUCK], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_TUCK long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TUCK], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CAT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CAT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CAT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CAT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SUBSTR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SUBSTR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SUBSTR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SUBSTR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LEFT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LEFT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LEFT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LEFT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LEFT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LEFT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LEFT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LEFT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RIGHT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RIGHT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RIGHT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RIGHT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SIZE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SIZE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SIZE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SIZE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_INVERT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_INVERT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_INVERT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_INVERT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_AND", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_AND], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_AND long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_AND], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_OR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_OR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_OR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_OR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_XOR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_XOR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_XOR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_XOR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_EQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_EQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_EQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_EQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_EQUALVERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_EQUALVERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_EQUALVERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_EQUALVERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RESERVED1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED1], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RESERVED1 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED1], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RESERVED2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED2], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RESERVED2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_1ADD", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1ADD], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_1ADD long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1ADD], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_1SUB", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1SUB], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_1SUB long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1SUB], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2MUL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2MUL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2MUL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2MUL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2DIV", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DIV], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2DIV long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DIV], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NEGATE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NEGATE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NEGATE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NEGATE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ABS", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ABS], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ABS long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ABS], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_0NOTEQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_0NOTEQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_0NOTEQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_0NOTEQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ADD", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ADD], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ADD long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ADD], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SUB", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SUB], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SUB long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SUB], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_MUL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MUL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_MUL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MUL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DIV", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DIV], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_DIV long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DIV], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_MOD", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MOD], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_MOD long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MOD], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LSHIFT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LSHIFT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LSHIFT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LSHIFT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RSHIFT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RSHIFT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RSHIFT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RSHIFT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_BOOLAND", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_BOOLAND], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_BOOLAND long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_BOOLAND], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_BOOLOR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_BOOLOR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_BOOLOR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_BOOLOR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NUMEQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMEQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NUMEQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMEQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NUMEQUALVERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMEQUALVERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NUMEQUALVERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMEQUALVERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NUMNOTEQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMNOTEQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NUMNOTEQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMNOTEQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LESSTHAN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LESSTHAN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LESSTHAN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LESSTHAN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_GREATERTHAN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_GREATERTHAN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_GREATERTHAN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_GREATERTHAN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LESSTHANOREQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LESSTHANOREQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LESSTHANOREQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LESSTHANOREQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_GREATERTHANOREQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_GREATERTHANOREQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_GREATERTHANOREQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_GREATERTHANOREQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_MIN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MIN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_MIN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MIN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_MAX", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MAX], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_MAX long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MAX], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_WITHIN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_WITHIN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_WITHIN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_WITHIN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RIPEMD160", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RIPEMD160], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RIPEMD160 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RIPEMD160], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SHA1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SHA1], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SHA1 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SHA1], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SHA256", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SHA256], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SHA256 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SHA256], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_HASH160", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_HASH160], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_HASH160 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_HASH160], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_HASH256", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_HASH256], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_HASH256 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_HASH256], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CODESAPERATOR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CODESEPARATOR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CODESEPARATOR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CODESEPARATOR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CHECKSIG", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKSIG], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CHECKSIG long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKSIG], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CHECKSIGVERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKSIGVERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CHECKSIGVERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKSIGVERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CHECKMULTISIG", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKMULTISIG], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CHECKMULTISIG long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKMULTISIG], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CHECKMULTISIGVERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKMULTISIGVERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CHECKMULTISIGVERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKMULTISIGVERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP1], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP1 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP1], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP2], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP3", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP3], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP3 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP3], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP4", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP4], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP4 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP4], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP5", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP5], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP5 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP5], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP6", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP6], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP6 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP6], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP7", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP7], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP7 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP7], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP8", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP8], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP8 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP8], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP9", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP9], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP9 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP9], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP10", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP10], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP10 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP10], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_PUBKEYHASH", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUBKEYHASH], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_PUBKEYHASH long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUBKEYHASH], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_PUBKEY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUBKEY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_PUBKEY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUBKEY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_INVALIDOPCODE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_INVALIDOPCODE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_INVALIDOPCODE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_INVALIDOPCODE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - } - - for _, test := range tests { - _, err := test.pop.bytes() - if e := tstCheckScriptError(err, test.expectedErr); e != nil { - t.Errorf("Parsed opcode test '%s': %v", test.name, e) - continue - } - } -} - // TestPushedData ensured the PushedData function extracts the expected data out // of various scripts. func TestPushedData(t *testing.T) { -- 2.45.2 From ca044fefcb80f4cc0ed966895ea390d4d956cd5d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:05 -0500 Subject: [PATCH 105/459] txscript: Remove unused parsedOpcode.bytes func. --- txscript/opcode.go | 57 ---------------------------------------------- 1 file changed, 57 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 9e0320ae..515e1cf2 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -8,7 +8,6 @@ import ( "bytes" "crypto/sha1" "crypto/sha256" - "encoding/binary" "encoding/hex" "fmt" "hash" @@ -740,62 +739,6 @@ func disasmOpcode(buf *strings.Builder, op *opcode, data []byte, compact bool) { buf.WriteString(fmt.Sprintf(" 0x%02x", data)) } -// bytes returns any data associated with the opcode encoded as it would be in -// a script. This is used for unparsing scripts from parsed opcodes. -func (pop *parsedOpcode) bytes() ([]byte, error) { - var retbytes []byte - if pop.opcode.length > 0 { - retbytes = make([]byte, 1, pop.opcode.length) - } else { - retbytes = make([]byte, 1, 1+len(pop.data)- - pop.opcode.length) - } - - retbytes[0] = pop.opcode.value - if pop.opcode.length == 1 { - if len(pop.data) != 0 { - str := fmt.Sprintf("internal consistency error - "+ - "parsed opcode %s has data length %d when %d "+ - "was expected", pop.opcode.name, len(pop.data), - 0) - return nil, scriptError(ErrInternal, str) - } - return retbytes, nil - } - nbytes := pop.opcode.length - if pop.opcode.length < 0 { - l := len(pop.data) - // tempting just to hardcode to avoid the complexity here. - switch pop.opcode.length { - case -1: - retbytes = append(retbytes, byte(l)) - nbytes = int(retbytes[1]) + len(retbytes) - case -2: - retbytes = append(retbytes, byte(l&0xff), - byte(l>>8&0xff)) - nbytes = int(binary.LittleEndian.Uint16(retbytes[1:])) + - len(retbytes) - case -4: - retbytes = append(retbytes, byte(l&0xff), - byte((l>>8)&0xff), byte((l>>16)&0xff), - byte((l>>24)&0xff)) - nbytes = int(binary.LittleEndian.Uint32(retbytes[1:])) + - len(retbytes) - } - } - - retbytes = append(retbytes, pop.data...) - - if len(retbytes) != nbytes { - str := fmt.Sprintf("internal consistency error - "+ - "parsed opcode %s has data length %d when %d was "+ - "expected", pop.opcode.name, len(retbytes), nbytes) - return nil, scriptError(ErrInternal, str) - } - - return retbytes, nil -} - // ******************************************* // Opcode implementation functions start here. // ******************************************* -- 2.45.2 From 595d379fa6c1a588b9e3f58210132da6c6de3825 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:06 -0500 Subject: [PATCH 106/459] txscript: Remove unused parseScriptTemplate func. Also remove tests associated with the func accordingly. --- txscript/opcode.go | 73 ----------------------------------------- txscript/script.go | 59 --------------------------------- txscript/script_test.go | 16 --------- 3 files changed, 148 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 515e1cf2..d6fc494c 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -618,79 +618,6 @@ type parsedOpcode struct { data []byte } -// checkParseableInScript checks whether or not the current opcode is able to be -// parsed at a certain position in a script. -// This returns the position of the next opcode to be parsed in the script. -func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (int, error) { - // Parse data out of instruction. - switch { - // No additional data. Note that some of the opcodes, notably - // OP_1NEGATE, OP_0, and OP_[1-16] represent the data - // themselves. - case pop.opcode.length == 1: - scriptPos++ - - // Data pushes of specific lengths -- OP_DATA_[1-75]. - case pop.opcode.length > 1: - if len(script[scriptPos:]) < pop.opcode.length { - str := fmt.Sprintf("opcode %s requires %d "+ - "bytes, but script only has %d remaining", - pop.opcode.name, pop.opcode.length, len(script[scriptPos:])) - return 0, scriptError(ErrMalformedPush, str) - } - - // Slice out the data. - pop.data = script[scriptPos+1 : scriptPos+pop.opcode.length] - scriptPos += pop.opcode.length - - // Data pushes with parsed lengths -- OP_PUSHDATAP{1,2,4}. - case pop.opcode.length < 0: - var l uint - off := scriptPos + 1 - - if len(script[off:]) < -pop.opcode.length { - str := fmt.Sprintf("opcode %s requires %d "+ - "bytes, but script only has %d remaining", - pop.opcode.name, -pop.opcode.length, len(script[off:])) - return 0, scriptError(ErrMalformedPush, str) - } - - // Next -length bytes are little endian length of data. - switch pop.opcode.length { - case -1: - l = uint(script[off]) - case -2: - l = ((uint(script[off+1]) << 8) | - uint(script[off])) - case -4: - l = ((uint(script[off+3]) << 24) | - (uint(script[off+2]) << 16) | - (uint(script[off+1]) << 8) | - uint(script[off])) - default: - str := fmt.Sprintf("invalid opcode length %d", - pop.opcode.length) - return 0, scriptError(ErrMalformedPush, str) - } - - // Move offset to beginning of the data. - off += -pop.opcode.length - - // Disallow entries that do not fit script or were - // sign extended. - if int(l) > len(script[off:]) || int(l) < 0 { - str := fmt.Sprintf("opcode %s pushes %d bytes, "+ - "but script only has %d remaining", - pop.opcode.name, int(l), len(script[off:])) - return 0, scriptError(ErrMalformedPush, str) - } - - pop.data = script[off : off+int(l)] - scriptPos += 1 - pop.opcode.length + int(l) - } - return scriptPos, nil -} - // disasmOpcode writes a human-readable disassembly of the provided opcode and // data into the provided buffer. The compact flag indicates the disassembly // should print a more compact representation of data-carrying and small integer diff --git a/txscript/script.go b/txscript/script.go index 0dbe4683..696bfe2d 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -143,65 +143,6 @@ func IsPushOnlyScript(script []byte) bool { return tokenizer.Err() == nil } -// parseScriptTemplate is the same as parseScript but allows the passing of the -// template list for testing purposes. When there are parse errors, it returns -// the list of parsed opcodes up to the point of failure along with the error. -func parseScriptTemplate(script []byte, opcodes *[256]opcode) ([]parsedOpcode, error) { - retScript := make([]parsedOpcode, 0, len(script)) - var err error - for i := 0; i < len(script); { - instr := script[i] - op := &opcodes[instr] - pop := parsedOpcode{opcode: op} - i, err = pop.checkParseableInScript(script, i) - if err != nil { - return retScript, err - } - - retScript = append(retScript, pop) - } - - return retScript, nil -} - -// checkScriptTemplateParseable is the same as parseScriptTemplate but does not -// return the list of opcodes up until the point of failure so that this can be -// used in functions which do not necessarily have a need for the failed list of -// opcodes, such as IsUnspendable. -// -// This function returns a pointer to a byte. This byte is nil if the parsing -// has an error, or if the script length is zero. If the script length is not -// zero and parsing succeeds, then the first opcode parsed will be returned. -// -// Not returning the full opcode list up until failure also has the benefit of -// reducing GC pressure, as the list would get immediately thrown away. -func checkScriptTemplateParseable(script []byte, opcodes *[256]opcode) (*byte, error) { - var err error - - // A script of length zero is an unspendable script but it is parseable. - var firstOpcode byte - var numParsedInstr uint = 0 - - for i := 0; i < len(script); { - instr := script[i] - op := &opcodes[instr] - pop := parsedOpcode{opcode: op} - i, err = pop.checkParseableInScript(script, i) - if err != nil { - return nil, err - } - - // if this is a op_return then it is unspendable so we set the first - // parsed instruction in case it's an op_return - if numParsedInstr == 0 { - firstOpcode = pop.opcode.value - } - numParsedInstr++ - } - - return &firstOpcode, nil -} - // DisasmString formats a disassembled script for one line printing. When the // script fails to parse, the returned string will contain the disassembled // script up to the point the failure occurred along with the string '[error]' diff --git a/txscript/script_test.go b/txscript/script_test.go index b6e7ff42..86f94d84 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -12,22 +12,6 @@ import ( "github.com/btcsuite/btcd/wire" ) -// TestParseOpcode tests for opcode parsing with bad data templates. -func TestParseOpcode(t *testing.T) { - // Deep copy the array and make one of the opcodes invalid by setting it - // to the wrong length. - fakeArray := opcodeArray - fakeArray[OP_PUSHDATA4] = opcode{value: OP_PUSHDATA4, - name: "OP_PUSHDATA4", length: -8, opfunc: opcodePushData} - - // This script would be fine if -8 was a valid length. - _, err := parseScriptTemplate([]byte{OP_PUSHDATA4, 0x1, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}, &fakeArray) - if err == nil { - t.Errorf("no error with dodgy opcode array!") - } -} - // TestPushedData ensured the PushedData function extracts the expected data out // of various scripts. func TestPushedData(t *testing.T) { -- 2.45.2 From ef3d06e62b76818163e8302384afcdb44874cf46 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:07 -0500 Subject: [PATCH 107/459] txscript: Make executeOpcode take opcode and data. This converts the executeOpcode function defined on the engine to accept an opcode and data slice instead of a parsed opcode as a step towards removing the parsed opcode struct and associated supporting code altogether. It also updates all callers accordingly. --- txscript/engine.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 1afb8324..a91dc961 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -341,23 +341,21 @@ func checkMinimalDataPush(op *opcode, data []byte) error { // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. -func (vm *Engine) executeOpcode(pop *parsedOpcode) error { +func (vm *Engine) executeOpcode(op *opcode, data []byte) error { // Disabled opcodes are fail on program counter. - if isOpcodeDisabled(pop.opcode.value) { - str := fmt.Sprintf("attempt to execute disabled opcode %s", - pop.opcode.name) + if isOpcodeDisabled(op.value) { + str := fmt.Sprintf("attempt to execute disabled opcode %s", op.name) return scriptError(ErrDisabledOpcode, str) } // Always-illegal opcodes are fail on program counter. - if isOpcodeAlwaysIllegal(pop.opcode.value) { - str := fmt.Sprintf("attempt to execute reserved opcode %s", - pop.opcode.name) + if isOpcodeAlwaysIllegal(op.value) { + str := fmt.Sprintf("attempt to execute reserved opcode %s", op.name) return scriptError(ErrReservedOpcode, str) } // Note that this includes OP_RESERVED which counts as a push operation. - if pop.opcode.value > OP_16 { + if op.value > OP_16 { vm.numOps++ if vm.numOps > MaxOpsPerScript { str := fmt.Sprintf("exceeded max operation limit of %d", @@ -365,29 +363,30 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { return scriptError(ErrTooManyOperations, str) } - } else if len(pop.data) > MaxScriptElementSize { + } else if len(data) > MaxScriptElementSize { str := fmt.Sprintf("element size %d exceeds max allowed size %d", - len(pop.data), MaxScriptElementSize) + len(data), MaxScriptElementSize) return scriptError(ErrElementTooBig, str) } // Nothing left to do when this is not a conditional opcode and it is // not in an executing branch. - if !vm.isBranchExecuting() && !isOpcodeConditional(pop.opcode.value) { + if !vm.isBranchExecuting() && !isOpcodeConditional(op.value) { return nil } // Ensure all executed data push opcodes use the minimal encoding when // the minimal data verification flag is set. if vm.dstack.verifyMinimalData && vm.isBranchExecuting() && - pop.opcode.value >= 0 && pop.opcode.value <= OP_PUSHDATA4 { + op.value >= 0 && op.value <= OP_PUSHDATA4 { - if err := checkMinimalDataPush(pop.opcode, pop.data); err != nil { + if err := checkMinimalDataPush(op, data); err != nil { return err } } - return pop.opcode.opfunc(pop, vm) + pop := parsedOpcode{opcode: op, data: data} + return op.opfunc(&pop, vm) } // checkValidPC returns an error if the current script position is not valid for @@ -670,8 +669,7 @@ func (vm *Engine) Step() (done bool, err error) { // Execute the opcode while taking into account several things such as // disabled opcodes, illegal opcodes, maximum allowed operations per script, // maximum script element sizes, and conditionals. - pop := parsedOpcode{opcode: vm.tokenizer.op, data: vm.tokenizer.Data()} - err = vm.executeOpcode(&pop) + err = vm.executeOpcode(vm.tokenizer.op, vm.tokenizer.Data()) if err != nil { return true, err } -- 2.45.2 From b95ba0ac95e04336f552b42864af824ba221d345 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:08 -0500 Subject: [PATCH 108/459] txscript: Make op callbacks take opcode and data. This converts the callback function defined on the internal opcode struct to accept the opcode and data slice instead of a parsed opcode as the final step towards removing the parsed opcode struct and associated supporting code altogether. It also updates all of the callbacks and tests accordingly and finally removes the now unused parsedOpcode struct. The final results for the raw script analysis and tokenizer optimizations are as follows: benchmark old ns/op new ns/op delta BenchmarkIsPayToScriptHash-8 62393 0.51 -100.00% BenchmarkIsPubKeyHashScript-8 62228 0.56 -100.00% BenchmarkGetSigOpCount-8 61051 658 -98.92% BenchmarkExtractPkScriptAddrsLarge-8 60713 17.2 -99.97% BenchmarkExtractPkScriptAddrs-8 289 17.9 -93.81% BenchmarkIsWitnessPubKeyHash-8 61688 0.42 -100.00% BenchmarkIsUnspendable-8 656 520 -20.73% BenchmarkExtractAtomicSwapDataPushesLarge-8 61332 44.0 -99.93% BenchmarkExtractAtomicSwapDataPushes-8 990 260 -73.74% BenchmarkDisasmString-8 102902 39754 -61.37% BenchmarkGetPreciseSigOpCount-8 130223 715 -99.45% BenchmarkScriptParsing-8 63464 681 -98.93% BenchmarkIsMultisigScriptLarge-8 64166 5.83 -99.99% BenchmarkIsMultisigScript-8 630 58.5 -90.71% BenchmarkPushedData-8 64837 1779 -97.26% BenchmarkCalcSigHash-8 3627895 3605459 -0.62% BenchmarkIsPubKeyScript-8 62323 2.83 -100.00% BenchmarkIsPushOnlyScript-8 62412 569 -99.09% BenchmarkIsWitnessScriptHash-8 61243 0.56 -100.00% BenchmarkGetScriptClass-8 61515 16.4 -99.97% BenchmarkIsNullDataScript-8 62495 2.53 -100.00% BenchmarkIsMultisigSigScriptLarge-8 69328 2.52 -100.00% BenchmarkIsMultisigSigScript-8 2375 141 -94.06% BenchmarkGetWitnessSigOpCountP2WKH-8 504 72.0 -85.71% BenchmarkGetWitnessSigOpCountNested-8 1158 136 -88.26% BenchmarkIsWitnessPubKeyHash-8 68927 0.53 -100.00% BenchmarkIsWitnessScriptHash-8 62774 0.63 -100.00% benchmark old allocs new allocs delta BenchmarkIsPayToScriptHash-8 1 0 -100.00% BenchmarkIsPubKeyHashScript-8 1 0 -100.00% BenchmarkGetSigOpCount-8 1 0 -100.00% BenchmarkExtractPkScriptAddrsLarge-8 1 0 -100.00% BenchmarkExtractPkScriptAddrs-8 1 0 -100.00% BenchmarkIsWitnessPubKeyHash-8 1 0 -100.00% BenchmarkIsUnspendable-8 1 0 -100.00% BenchmarkExtractAtomicSwapDataPushesLarge-8 1 0 -100.00% BenchmarkExtractAtomicSwapDataPushes-8 2 1 -50.00% BenchmarkDisasmString-8 46 51 +10.87% BenchmarkGetPreciseSigOpCount-8 3 0 -100.00% BenchmarkScriptParsing-8 1 0 -100.00% BenchmarkIsMultisigScriptLarge-8 1 0 -100.00% BenchmarkIsMultisigScript-8 1 0 -100.00% BenchmarkPushedData-8 7 6 -14.29% BenchmarkCalcSigHash-8 1335 712 -46.67% BenchmarkIsPubKeyScript-8 1 0 -100.00% BenchmarkIsPushOnlyScript-8 1 0 -100.00% BenchmarkIsWitnessScriptHash-8 1 0 -100.00% BenchmarkGetScriptClass-8 1 0 -100.00% BenchmarkIsNullDataScript-8 1 0 -100.00% BenchmarkIsMultisigSigScriptLarge-8 5 0 -100.00% BenchmarkIsMultisigSigScript-8 3 0 -100.00% BenchmarkGetWitnessSigOpCountP2WKH-8 2 0 -100.00% BenchmarkGetWitnessSigOpCountNested-8 4 0 -100.00% BenchmarkIsWitnessPubKeyHash-8 1 0 -100.00% BenchmarkIsWitnessScriptHash-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPayToScriptHash-8 311299 0 -100.00% BenchmarkIsPubKeyHashScript-8 311299 0 -100.00% BenchmarkGetSigOpCount-8 311299 0 -100.00% BenchmarkExtractPkScriptAddrsLarge-8 311299 0 -100.00% BenchmarkExtractPkScriptAddrs-8 768 0 -100.00% BenchmarkIsWitnessPubKeyHash-8 311299 0 -100.00% BenchmarkIsUnspendable-8 1 0 -100.00% BenchmarkExtractAtomicSwapDataPushesLarge-8 311299 0 -100.00% BenchmarkExtractAtomicSwapDataPushes-8 3168 96 -96.97% BenchmarkDisasmString-8 389324 130552 -66.47% BenchmarkGetPreciseSigOpCount-8 623367 0 -100.00% BenchmarkScriptParsing-8 311299 0 -100.00% BenchmarkIsMultisigScriptLarge-8 311299 0 -100.00% BenchmarkIsMultisigScript-8 2304 0 -100.00% BenchmarkPushedData-8 312816 1520 -99.51% BenchmarkCalcSigHash-8 1373812 1290507 -6.06% BenchmarkIsPubKeyScript-8 311299 0 -100.00% BenchmarkIsPushOnlyScript-8 311299 0 -100.00% BenchmarkIsWitnessScriptHash-8 311299 0 -100.00% BenchmarkGetScriptClass-8 311299 0 -100.00% BenchmarkIsNullDataScript-8 311299 0 -100.00% BenchmarkIsMultisigSigScriptLarge-8 330035 0 -100.00% BenchmarkIsMultisigSigScript-8 9472 0 -100.00% BenchmarkGetWitnessSigOpCountP2WKH-8 1408 0 -100.00% BenchmarkGetWitnessSigOpCountNested-8 3200 0 -100.00% BenchmarkIsWitnessPubKeyHash-8 311299 0 -100.00% BenchmarkIsWitnessScriptHash-8 311299 0 -100.00% --- txscript/engine.go | 3 +- txscript/opcode.go | 183 +++++++++++++++++++--------------------- txscript/opcode_test.go | 4 +- 3 files changed, 90 insertions(+), 100 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index a91dc961..0814e7eb 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -385,8 +385,7 @@ func (vm *Engine) executeOpcode(op *opcode, data []byte) error { } } - pop := parsedOpcode{opcode: op, data: data} - return op.opfunc(&pop, vm) + return op.opfunc(op, data, vm) } // checkValidPC returns an error if the current script position is not valid for diff --git a/txscript/opcode.go b/txscript/opcode.go index d6fc494c..4c31be3f 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -28,7 +28,7 @@ type opcode struct { value byte name string length int - opfunc func(*parsedOpcode, *Engine) error + opfunc func(*opcode, []byte, *Engine) error } // These constants are the values of the official opcodes used on the btc wiki, @@ -611,13 +611,6 @@ var opcodeOnelineRepls = map[string]string{ "OP_16": "16", } -// parsedOpcode represents an opcode that has been parsed and includes any -// potential data associated with it. -type parsedOpcode struct { - opcode *opcode - data []byte -} - // disasmOpcode writes a human-readable disassembly of the provided opcode and // data into the provided buffer. The compact flag indicates the disassembly // should print a more compact representation of data-carrying and small integer @@ -676,45 +669,42 @@ func disasmOpcode(buf *strings.Builder, op *opcode, data []byte, compact bool) { // opcodes before executing in an initial parse step, the consensus rules // dictate the script doesn't fail until the program counter passes over a // disabled opcode (even when they appear in a branch that is not executed). -func opcodeDisabled(op *parsedOpcode, vm *Engine) error { - str := fmt.Sprintf("attempt to execute disabled opcode %s", - op.opcode.name) +func opcodeDisabled(op *opcode, data []byte, vm *Engine) error { + str := fmt.Sprintf("attempt to execute disabled opcode %s", op.name) return scriptError(ErrDisabledOpcode, str) } // opcodeReserved is a common handler for all reserved opcodes. It returns an // appropriate error indicating the opcode is reserved. -func opcodeReserved(op *parsedOpcode, vm *Engine) error { - str := fmt.Sprintf("attempt to execute reserved opcode %s", - op.opcode.name) +func opcodeReserved(op *opcode, data []byte, vm *Engine) error { + str := fmt.Sprintf("attempt to execute reserved opcode %s", op.name) return scriptError(ErrReservedOpcode, str) } // opcodeInvalid is a common handler for all invalid opcodes. It returns an // appropriate error indicating the opcode is invalid. -func opcodeInvalid(op *parsedOpcode, vm *Engine) error { - str := fmt.Sprintf("attempt to execute invalid opcode %s", - op.opcode.name) +func opcodeInvalid(op *opcode, data []byte, vm *Engine) error { + str := fmt.Sprintf("attempt to execute invalid opcode %s", op.name) return scriptError(ErrReservedOpcode, str) } // opcodeFalse pushes an empty array to the data stack to represent false. Note // that 0, when encoded as a number according to the numeric encoding consensus // rules, is an empty array. -func opcodeFalse(op *parsedOpcode, vm *Engine) error { +func opcodeFalse(op *opcode, data []byte, vm *Engine) error { vm.dstack.PushByteArray(nil) return nil } // opcodePushData is a common handler for the vast majority of opcodes that push // raw data (bytes) to the data stack. -func opcodePushData(op *parsedOpcode, vm *Engine) error { - vm.dstack.PushByteArray(op.data) +func opcodePushData(op *opcode, data []byte, vm *Engine) error { + vm.dstack.PushByteArray(data) return nil } // opcode1Negate pushes -1, encoded as a number, to the data stack. -func opcode1Negate(op *parsedOpcode, vm *Engine) error { +func opcode1Negate(op *opcode, data []byte, vm *Engine) error { vm.dstack.PushInt(scriptNum(-1)) return nil } @@ -722,23 +712,24 @@ func opcode1Negate(op *parsedOpcode, vm *Engine) error { // opcodeN is a common handler for the small integer data push opcodes. It // pushes the numeric value the opcode represents (which will be from 1 to 16) // onto the data stack. -func opcodeN(op *parsedOpcode, vm *Engine) error { +func opcodeN(op *opcode, data []byte, vm *Engine) error { // The opcodes are all defined consecutively, so the numeric value is // the difference. - vm.dstack.PushInt(scriptNum((op.opcode.value - (OP_1 - 1)))) + vm.dstack.PushInt(scriptNum((op.value - (OP_1 - 1)))) return nil } // opcodeNop is a common handler for the NOP family of opcodes. As the name // implies it generally does nothing, however, it will return an error when // the flag to discourage use of NOPs is set for select opcodes. -func opcodeNop(op *parsedOpcode, vm *Engine) error { - switch op.opcode.value { +func opcodeNop(op *opcode, data []byte, vm *Engine) error { + switch op.value { case OP_NOP1, OP_NOP4, OP_NOP5, OP_NOP6, OP_NOP7, OP_NOP8, OP_NOP9, OP_NOP10: + if vm.hasFlag(ScriptDiscourageUpgradableNops) { - str := fmt.Sprintf("OP_NOP%d reserved for soft-fork "+ - "upgrades", op.opcode.value-(OP_NOP1-1)) + str := fmt.Sprintf("%v reserved for soft-fork "+ + "upgrades", op.name) return scriptError(ErrDiscourageUpgradableNOPs, str) } } @@ -801,7 +792,7 @@ func popIfBool(vm *Engine) (bool, error) { // // Data stack transformation: [... bool] -> [...] // Conditional stack transformation: [...] -> [... OpCondValue] -func opcodeIf(op *parsedOpcode, vm *Engine) error { +func opcodeIf(op *opcode, data []byte, vm *Engine) error { condVal := OpCondFalse if vm.isBranchExecuting() { ok, err := popIfBool(vm) @@ -835,7 +826,7 @@ func opcodeIf(op *parsedOpcode, vm *Engine) error { // // Data stack transformation: [... bool] -> [...] // Conditional stack transformation: [...] -> [... OpCondValue] -func opcodeNotIf(op *parsedOpcode, vm *Engine) error { +func opcodeNotIf(op *opcode, data []byte, vm *Engine) error { condVal := OpCondFalse if vm.isBranchExecuting() { ok, err := popIfBool(vm) @@ -858,10 +849,10 @@ func opcodeNotIf(op *parsedOpcode, vm *Engine) error { // An error is returned if there has not already been a matching OP_IF. // // Conditional stack transformation: [... OpCondValue] -> [... !OpCondValue] -func opcodeElse(op *parsedOpcode, vm *Engine) error { +func opcodeElse(op *opcode, data []byte, vm *Engine) error { if len(vm.condStack) == 0 { str := fmt.Sprintf("encountered opcode %s with no matching "+ - "opcode to begin conditional execution", op.opcode.name) + "opcode to begin conditional execution", op.name) return scriptError(ErrUnbalancedConditional, str) } @@ -884,10 +875,10 @@ func opcodeElse(op *parsedOpcode, vm *Engine) error { // An error is returned if there has not already been a matching OP_IF. // // Conditional stack transformation: [... OpCondValue] -> [...] -func opcodeEndif(op *parsedOpcode, vm *Engine) error { +func opcodeEndif(op *opcode, data []byte, vm *Engine) error { if len(vm.condStack) == 0 { str := fmt.Sprintf("encountered opcode %s with no matching "+ - "opcode to begin conditional execution", op.opcode.name) + "opcode to begin conditional execution", op.name) return scriptError(ErrUnbalancedConditional, str) } @@ -900,14 +891,14 @@ func opcodeEndif(op *parsedOpcode, vm *Engine) error { // item on the stack or when that item evaluates to false. In the latter case // where the verification fails specifically due to the top item evaluating // to false, the returned error will use the passed error code. -func abstractVerify(op *parsedOpcode, vm *Engine, c ErrorCode) error { +func abstractVerify(op *opcode, vm *Engine, c ErrorCode) error { verified, err := vm.dstack.PopBool() if err != nil { return err } if !verified { - str := fmt.Sprintf("%s failed", op.opcode.name) + str := fmt.Sprintf("%s failed", op.name) return scriptError(c, str) } return nil @@ -915,13 +906,13 @@ func abstractVerify(op *parsedOpcode, vm *Engine, c ErrorCode) error { // opcodeVerify examines the top item on the data stack as a boolean value and // verifies it evaluates to true. An error is returned if it does not. -func opcodeVerify(op *parsedOpcode, vm *Engine) error { +func opcodeVerify(op *opcode, data []byte, vm *Engine) error { return abstractVerify(op, vm, ErrVerify) } // opcodeReturn returns an appropriate error since it is always an error to // return early from a script. -func opcodeReturn(op *parsedOpcode, vm *Engine) error { +func opcodeReturn(op *opcode, data []byte, vm *Engine) error { return scriptError(ErrEarlyReturn, "script returned early") } @@ -951,7 +942,7 @@ func verifyLockTime(txLockTime, threshold, lockTime int64) error { // validating if the transaction outputs are spendable yet. If flag // ScriptVerifyCheckLockTimeVerify is not set, the code continues as if OP_NOP2 // were executed. -func opcodeCheckLockTimeVerify(op *parsedOpcode, vm *Engine) error { +func opcodeCheckLockTimeVerify(op *opcode, data []byte, vm *Engine) error { // If the ScriptVerifyCheckLockTimeVerify script flag is not set, treat // opcode as OP_NOP2 instead. if !vm.hasFlag(ScriptVerifyCheckLockTimeVerify) { @@ -1025,7 +1016,7 @@ func opcodeCheckLockTimeVerify(op *parsedOpcode, vm *Engine) error { // validating if the transaction outputs are spendable yet. If flag // ScriptVerifyCheckSequenceVerify is not set, the code continues as if OP_NOP3 // were executed. -func opcodeCheckSequenceVerify(op *parsedOpcode, vm *Engine) error { +func opcodeCheckSequenceVerify(op *opcode, data []byte, vm *Engine) error { // If the ScriptVerifyCheckSequenceVerify script flag is not set, treat // opcode as OP_NOP3 instead. if !vm.hasFlag(ScriptVerifyCheckSequenceVerify) { @@ -1102,7 +1093,7 @@ func opcodeCheckSequenceVerify(op *parsedOpcode, vm *Engine) error { // // Main data stack transformation: [... x1 x2 x3] -> [... x1 x2] // Alt data stack transformation: [... y1 y2 y3] -> [... y1 y2 y3 x3] -func opcodeToAltStack(op *parsedOpcode, vm *Engine) error { +func opcodeToAltStack(op *opcode, data []byte, vm *Engine) error { so, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1117,7 +1108,7 @@ func opcodeToAltStack(op *parsedOpcode, vm *Engine) error { // // Main data stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 y3] // Alt data stack transformation: [... y1 y2 y3] -> [... y1 y2] -func opcodeFromAltStack(op *parsedOpcode, vm *Engine) error { +func opcodeFromAltStack(op *opcode, data []byte, vm *Engine) error { so, err := vm.astack.PopByteArray() if err != nil { return err @@ -1130,35 +1121,35 @@ func opcodeFromAltStack(op *parsedOpcode, vm *Engine) error { // opcode2Drop removes the top 2 items from the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1] -func opcode2Drop(op *parsedOpcode, vm *Engine) error { +func opcode2Drop(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DropN(2) } // opcode2Dup duplicates the top 2 items on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 x2 x3] -func opcode2Dup(op *parsedOpcode, vm *Engine) error { +func opcode2Dup(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DupN(2) } // opcode3Dup duplicates the top 3 items on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 x1 x2 x3] -func opcode3Dup(op *parsedOpcode, vm *Engine) error { +func opcode3Dup(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DupN(3) } // opcode2Over duplicates the 2 items before the top 2 items on the data stack. // // Stack transformation: [... x1 x2 x3 x4] -> [... x1 x2 x3 x4 x1 x2] -func opcode2Over(op *parsedOpcode, vm *Engine) error { +func opcode2Over(op *opcode, data []byte, vm *Engine) error { return vm.dstack.OverN(2) } // opcode2Rot rotates the top 6 items on the data stack to the left twice. // // Stack transformation: [... x1 x2 x3 x4 x5 x6] -> [... x3 x4 x5 x6 x1 x2] -func opcode2Rot(op *parsedOpcode, vm *Engine) error { +func opcode2Rot(op *opcode, data []byte, vm *Engine) error { return vm.dstack.RotN(2) } @@ -1166,7 +1157,7 @@ func opcode2Rot(op *parsedOpcode, vm *Engine) error { // before them. // // Stack transformation: [... x1 x2 x3 x4] -> [... x3 x4 x1 x2] -func opcode2Swap(op *parsedOpcode, vm *Engine) error { +func opcode2Swap(op *opcode, data []byte, vm *Engine) error { return vm.dstack.SwapN(2) } @@ -1174,7 +1165,7 @@ func opcode2Swap(op *parsedOpcode, vm *Engine) error { // // Stack transformation (x1==0): [... x1] -> [... x1] // Stack transformation (x1!=0): [... x1] -> [... x1 x1] -func opcodeIfDup(op *parsedOpcode, vm *Engine) error { +func opcodeIfDup(op *opcode, data []byte, vm *Engine) error { so, err := vm.dstack.PeekByteArray(0) if err != nil { return err @@ -1194,7 +1185,7 @@ func opcodeIfDup(op *parsedOpcode, vm *Engine) error { // Stack transformation: [...] -> [... ] // Example with 2 items: [x1 x2] -> [x1 x2 2] // Example with 3 items: [x1 x2 x3] -> [x1 x2 x3 3] -func opcodeDepth(op *parsedOpcode, vm *Engine) error { +func opcodeDepth(op *opcode, data []byte, vm *Engine) error { vm.dstack.PushInt(scriptNum(vm.dstack.Depth())) return nil } @@ -1202,28 +1193,28 @@ func opcodeDepth(op *parsedOpcode, vm *Engine) error { // opcodeDrop removes the top item from the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2] -func opcodeDrop(op *parsedOpcode, vm *Engine) error { +func opcodeDrop(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DropN(1) } // opcodeDup duplicates the top item on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 x3] -func opcodeDup(op *parsedOpcode, vm *Engine) error { +func opcodeDup(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DupN(1) } // opcodeNip removes the item before the top item on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x3] -func opcodeNip(op *parsedOpcode, vm *Engine) error { +func opcodeNip(op *opcode, data []byte, vm *Engine) error { return vm.dstack.NipN(1) } // opcodeOver duplicates the item before the top item on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 x2] -func opcodeOver(op *parsedOpcode, vm *Engine) error { +func opcodeOver(op *opcode, data []byte, vm *Engine) error { return vm.dstack.OverN(1) } @@ -1233,7 +1224,7 @@ func opcodeOver(op *parsedOpcode, vm *Engine) error { // Stack transformation: [xn ... x2 x1 x0 n] -> [xn ... x2 x1 x0 xn] // Example with n=1: [x2 x1 x0 1] -> [x2 x1 x0 x1] // Example with n=2: [x2 x1 x0 2] -> [x2 x1 x0 x2] -func opcodePick(op *parsedOpcode, vm *Engine) error { +func opcodePick(op *opcode, data []byte, vm *Engine) error { val, err := vm.dstack.PopInt() if err != nil { return err @@ -1248,7 +1239,7 @@ func opcodePick(op *parsedOpcode, vm *Engine) error { // Stack transformation: [xn ... x2 x1 x0 n] -> [... x2 x1 x0 xn] // Example with n=1: [x2 x1 x0 1] -> [x2 x0 x1] // Example with n=2: [x2 x1 x0 2] -> [x1 x0 x2] -func opcodeRoll(op *parsedOpcode, vm *Engine) error { +func opcodeRoll(op *opcode, data []byte, vm *Engine) error { val, err := vm.dstack.PopInt() if err != nil { return err @@ -1260,14 +1251,14 @@ func opcodeRoll(op *parsedOpcode, vm *Engine) error { // opcodeRot rotates the top 3 items on the data stack to the left. // // Stack transformation: [... x1 x2 x3] -> [... x2 x3 x1] -func opcodeRot(op *parsedOpcode, vm *Engine) error { +func opcodeRot(op *opcode, data []byte, vm *Engine) error { return vm.dstack.RotN(1) } // opcodeSwap swaps the top two items on the stack. // // Stack transformation: [... x1 x2] -> [... x2 x1] -func opcodeSwap(op *parsedOpcode, vm *Engine) error { +func opcodeSwap(op *opcode, data []byte, vm *Engine) error { return vm.dstack.SwapN(1) } @@ -1275,7 +1266,7 @@ func opcodeSwap(op *parsedOpcode, vm *Engine) error { // second-to-top item. // // Stack transformation: [... x1 x2] -> [... x2 x1 x2] -func opcodeTuck(op *parsedOpcode, vm *Engine) error { +func opcodeTuck(op *opcode, data []byte, vm *Engine) error { return vm.dstack.Tuck() } @@ -1283,7 +1274,7 @@ func opcodeTuck(op *parsedOpcode, vm *Engine) error { // stack. // // Stack transformation: [... x1] -> [... x1 len(x1)] -func opcodeSize(op *parsedOpcode, vm *Engine) error { +func opcodeSize(op *opcode, data []byte, vm *Engine) error { so, err := vm.dstack.PeekByteArray(0) if err != nil { return err @@ -1297,7 +1288,7 @@ func opcodeSize(op *parsedOpcode, vm *Engine) error { // bytes, and pushes the result, encoded as a boolean, back to the stack. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeEqual(op *parsedOpcode, vm *Engine) error { +func opcodeEqual(op *opcode, data []byte, vm *Engine) error { a, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1318,8 +1309,8 @@ func opcodeEqual(op *parsedOpcode, vm *Engine) error { // evaluates to true. An error is returned if it does not. // // Stack transformation: [... x1 x2] -> [... bool] -> [...] -func opcodeEqualVerify(op *parsedOpcode, vm *Engine) error { - err := opcodeEqual(op, vm) +func opcodeEqualVerify(op *opcode, data []byte, vm *Engine) error { + err := opcodeEqual(op, data, vm) if err == nil { err = abstractVerify(op, vm, ErrEqualVerify) } @@ -1330,7 +1321,7 @@ func opcodeEqualVerify(op *parsedOpcode, vm *Engine) error { // it with its incremented value (plus 1). // // Stack transformation: [... x1 x2] -> [... x1 x2+1] -func opcode1Add(op *parsedOpcode, vm *Engine) error { +func opcode1Add(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1344,7 +1335,7 @@ func opcode1Add(op *parsedOpcode, vm *Engine) error { // it with its decremented value (minus 1). // // Stack transformation: [... x1 x2] -> [... x1 x2-1] -func opcode1Sub(op *parsedOpcode, vm *Engine) error { +func opcode1Sub(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1358,7 +1349,7 @@ func opcode1Sub(op *parsedOpcode, vm *Engine) error { // it with its negation. // // Stack transformation: [... x1 x2] -> [... x1 -x2] -func opcodeNegate(op *parsedOpcode, vm *Engine) error { +func opcodeNegate(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1372,7 +1363,7 @@ func opcodeNegate(op *parsedOpcode, vm *Engine) error { // it with its absolute value. // // Stack transformation: [... x1 x2] -> [... x1 abs(x2)] -func opcodeAbs(op *parsedOpcode, vm *Engine) error { +func opcodeAbs(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1397,7 +1388,7 @@ func opcodeAbs(op *parsedOpcode, vm *Engine) error { // Stack transformation (x2==0): [... x1 0] -> [... x1 1] // Stack transformation (x2!=0): [... x1 1] -> [... x1 0] // Stack transformation (x2!=0): [... x1 17] -> [... x1 0] -func opcodeNot(op *parsedOpcode, vm *Engine) error { +func opcodeNot(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1417,7 +1408,7 @@ func opcodeNot(op *parsedOpcode, vm *Engine) error { // Stack transformation (x2==0): [... x1 0] -> [... x1 0] // Stack transformation (x2!=0): [... x1 1] -> [... x1 1] // Stack transformation (x2!=0): [... x1 17] -> [... x1 1] -func opcode0NotEqual(op *parsedOpcode, vm *Engine) error { +func opcode0NotEqual(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1434,7 +1425,7 @@ func opcode0NotEqual(op *parsedOpcode, vm *Engine) error { // them with their sum. // // Stack transformation: [... x1 x2] -> [... x1+x2] -func opcodeAdd(op *parsedOpcode, vm *Engine) error { +func opcodeAdd(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1454,7 +1445,7 @@ func opcodeAdd(op *parsedOpcode, vm *Engine) error { // entry. // // Stack transformation: [... x1 x2] -> [... x1-x2] -func opcodeSub(op *parsedOpcode, vm *Engine) error { +func opcodeSub(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1476,7 +1467,7 @@ func opcodeSub(op *parsedOpcode, vm *Engine) error { // Stack transformation (x1!=0, x2==0): [... 5 0] -> [... 0] // Stack transformation (x1==0, x2!=0): [... 0 7] -> [... 0] // Stack transformation (x1!=0, x2!=0): [... 4 8] -> [... 1] -func opcodeBoolAnd(op *parsedOpcode, vm *Engine) error { +func opcodeBoolAnd(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1503,7 +1494,7 @@ func opcodeBoolAnd(op *parsedOpcode, vm *Engine) error { // Stack transformation (x1!=0, x2==0): [... 5 0] -> [... 1] // Stack transformation (x1==0, x2!=0): [... 0 7] -> [... 1] // Stack transformation (x1!=0, x2!=0): [... 4 8] -> [... 1] -func opcodeBoolOr(op *parsedOpcode, vm *Engine) error { +func opcodeBoolOr(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1528,7 +1519,7 @@ func opcodeBoolOr(op *parsedOpcode, vm *Engine) error { // // Stack transformation (x1==x2): [... 5 5] -> [... 1] // Stack transformation (x1!=x2): [... 5 7] -> [... 0] -func opcodeNumEqual(op *parsedOpcode, vm *Engine) error { +func opcodeNumEqual(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1556,8 +1547,8 @@ func opcodeNumEqual(op *parsedOpcode, vm *Engine) error { // to true. An error is returned if it does not. // // Stack transformation: [... x1 x2] -> [... bool] -> [...] -func opcodeNumEqualVerify(op *parsedOpcode, vm *Engine) error { - err := opcodeNumEqual(op, vm) +func opcodeNumEqualVerify(op *opcode, data []byte, vm *Engine) error { + err := opcodeNumEqual(op, data, vm) if err == nil { err = abstractVerify(op, vm, ErrNumEqualVerify) } @@ -1569,7 +1560,7 @@ func opcodeNumEqualVerify(op *parsedOpcode, vm *Engine) error { // // Stack transformation (x1==x2): [... 5 5] -> [... 0] // Stack transformation (x1!=x2): [... 5 7] -> [... 1] -func opcodeNumNotEqual(op *parsedOpcode, vm *Engine) error { +func opcodeNumNotEqual(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1594,7 +1585,7 @@ func opcodeNumNotEqual(op *parsedOpcode, vm *Engine) error { // otherwise a 0. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeLessThan(op *parsedOpcode, vm *Engine) error { +func opcodeLessThan(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1619,7 +1610,7 @@ func opcodeLessThan(op *parsedOpcode, vm *Engine) error { // with a 1, otherwise a 0. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeGreaterThan(op *parsedOpcode, vm *Engine) error { +func opcodeGreaterThan(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1643,7 +1634,7 @@ func opcodeGreaterThan(op *parsedOpcode, vm *Engine) error { // replaced with a 1, otherwise a 0. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeLessThanOrEqual(op *parsedOpcode, vm *Engine) error { +func opcodeLessThanOrEqual(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1667,7 +1658,7 @@ func opcodeLessThanOrEqual(op *parsedOpcode, vm *Engine) error { // item, they are replaced with a 1, otherwise a 0. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeGreaterThanOrEqual(op *parsedOpcode, vm *Engine) error { +func opcodeGreaterThanOrEqual(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1691,7 +1682,7 @@ func opcodeGreaterThanOrEqual(op *parsedOpcode, vm *Engine) error { // them with the minimum of the two. // // Stack transformation: [... x1 x2] -> [... min(x1, x2)] -func opcodeMin(op *parsedOpcode, vm *Engine) error { +func opcodeMin(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1715,7 +1706,7 @@ func opcodeMin(op *parsedOpcode, vm *Engine) error { // them with the maximum of the two. // // Stack transformation: [... x1 x2] -> [... max(x1, x2)] -func opcodeMax(op *parsedOpcode, vm *Engine) error { +func opcodeMax(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1743,7 +1734,7 @@ func opcodeMax(op *parsedOpcode, vm *Engine) error { // the third-to-top item is the value to test. // // Stack transformation: [... x1 min max] -> [... bool] -func opcodeWithin(op *parsedOpcode, vm *Engine) error { +func opcodeWithin(op *opcode, data []byte, vm *Engine) error { maxVal, err := vm.dstack.PopInt() if err != nil { return err @@ -1777,7 +1768,7 @@ func calcHash(buf []byte, hasher hash.Hash) []byte { // replaces it with ripemd160(data). // // Stack transformation: [... x1] -> [... ripemd160(x1)] -func opcodeRipemd160(op *parsedOpcode, vm *Engine) error { +func opcodeRipemd160(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1791,7 +1782,7 @@ func opcodeRipemd160(op *parsedOpcode, vm *Engine) error { // with sha1(data). // // Stack transformation: [... x1] -> [... sha1(x1)] -func opcodeSha1(op *parsedOpcode, vm *Engine) error { +func opcodeSha1(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1806,7 +1797,7 @@ func opcodeSha1(op *parsedOpcode, vm *Engine) error { // it with sha256(data). // // Stack transformation: [... x1] -> [... sha256(x1)] -func opcodeSha256(op *parsedOpcode, vm *Engine) error { +func opcodeSha256(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1821,7 +1812,7 @@ func opcodeSha256(op *parsedOpcode, vm *Engine) error { // it with ripemd160(sha256(data)). // // Stack transformation: [... x1] -> [... ripemd160(sha256(x1))] -func opcodeHash160(op *parsedOpcode, vm *Engine) error { +func opcodeHash160(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1836,7 +1827,7 @@ func opcodeHash160(op *parsedOpcode, vm *Engine) error { // it with sha256(sha256(data)). // // Stack transformation: [... x1] -> [... sha256(sha256(x1))] -func opcodeHash256(op *parsedOpcode, vm *Engine) error { +func opcodeHash256(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1850,7 +1841,7 @@ func opcodeHash256(op *parsedOpcode, vm *Engine) error { // seen OP_CODESEPARATOR which is used during signature checking. // // This opcode does not change the contents of the data stack. -func opcodeCodeSeparator(op *parsedOpcode, vm *Engine) error { +func opcodeCodeSeparator(op *opcode, data []byte, vm *Engine) error { vm.lastCodeSep = int(vm.tokenizer.ByteIndex()) return nil } @@ -1869,7 +1860,7 @@ func opcodeCodeSeparator(op *parsedOpcode, vm *Engine) error { // cryptographic methods against the provided public key. // // Stack transformation: [... signature pubkey] -> [... bool] -func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { +func opcodeCheckSig(op *opcode, data []byte, vm *Engine) error { pkBytes, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1984,9 +1975,9 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { // The opcodeCheckSig function is invoked followed by opcodeVerify. See the // documentation for each of those opcodes for more details. // -// Stack transformation: signature pubkey] -> [... bool] -> [...] -func opcodeCheckSigVerify(op *parsedOpcode, vm *Engine) error { - err := opcodeCheckSig(op, vm) +// Stack transformation: [... signature pubkey] -> [... bool] -> [...] +func opcodeCheckSigVerify(op *opcode, data []byte, vm *Engine) error { + err := opcodeCheckSig(op, data, vm) if err == nil { err = abstractVerify(op, vm, ErrCheckSigVerify) } @@ -2021,7 +2012,7 @@ type parsedSigInfo struct { // // Stack transformation: // [... dummy [sig ...] numsigs [pubkey ...] numpubkeys] -> [... bool] -func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { +func opcodeCheckMultiSig(op *opcode, data []byte, vm *Engine) error { numKeys, err := vm.dstack.PopInt() if err != nil { return err @@ -2247,8 +2238,8 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { // // Stack transformation: // [... dummy [sig ...] numsigs [pubkey ...] numpubkeys] -> [... bool] -> [...] -func opcodeCheckMultiSigVerify(op *parsedOpcode, vm *Engine) error { - err := opcodeCheckMultiSig(op, vm) +func opcodeCheckMultiSigVerify(op *opcode, data []byte, vm *Engine) error { + err := opcodeCheckMultiSig(op, data, vm) if err == nil { err = abstractVerify(op, vm, ErrCheckMultiSigVerify) } diff --git a/txscript/opcode_test.go b/txscript/opcode_test.go index 3c5abf9d..91263c21 100644 --- a/txscript/opcode_test.go +++ b/txscript/opcode_test.go @@ -23,8 +23,8 @@ func TestOpcodeDisabled(t *testing.T) { OP_LSHIFT, OP_RSHIFT, } for _, opcodeVal := range tests { - pop := parsedOpcode{opcode: &opcodeArray[opcodeVal], data: nil} - err := opcodeDisabled(&pop, nil) + op := &opcodeArray[opcodeVal] + err := opcodeDisabled(op, nil, nil) if !IsErrorCode(err, ErrDisabledOpcode) { t.Errorf("opcodeDisabled: unexpected error - got %v, "+ "want %v", err, ErrDisabledOpcode) -- 2.45.2 From 3be166e3ae1521d0cf3472c204a348bca647995d Mon Sep 17 00:00:00 2001 From: Calvin Kim Date: Wed, 17 Nov 2021 12:46:12 +0900 Subject: [PATCH 109/459] go.mod, go.sum: Update goleveldb Goleveldb recently had a PR in where memory allocation was reduced drastically (github.com/syndtr/goleveldb/pull/367). Update goleveldb to use that PR. --- go.mod | 3 ++- go.sum | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7722564f..767c2740 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,8 @@ require ( github.com/decred/dcrd/lru v1.0.0 github.com/jessevdk/go-flags v1.4.0 github.com/jrick/logrotate v1.0.0 - golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 ) go 1.16 diff --git a/go.sum b/go.sum index 4c5a352a..e9ee276d 100644 --- a/go.sum +++ b/go.sum @@ -25,7 +25,18 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -35,28 +46,56 @@ github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -64,3 +103,5 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -- 2.45.2 From 780cc0889fd2f326e4a2a9b513d8d30ff37e0cd2 Mon Sep 17 00:00:00 2001 From: Tomasz Ziolkowski Date: Fri, 15 Oct 2021 16:56:27 +0200 Subject: [PATCH 110/459] reduce redundant memory allocatio - resolves btcsuite/btcd#1699 Signed-off-by: Tomasz Ziolkowski --- connmgr/tor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connmgr/tor.go b/connmgr/tor.go index 2b22ae51..a2e512db 100644 --- a/connmgr/tor.go +++ b/connmgr/tor.go @@ -76,7 +76,7 @@ func TorLookupIP(host, proxy string) ([]net.IP, error) { return nil, ErrTorUnrecognizedAuthMethod } - buf = make([]byte, 7+len(host)) + buf = make([]byte, 6+len(host)) buf[0] = 5 // protocol version buf[1] = '\xF0' // Tor Resolve buf[2] = 0 // reserved -- 2.45.2 From 264075b31160cd0789a4db5022f39e309421b1b5 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 6 Jul 2021 19:36:21 -0700 Subject: [PATCH 111/459] [lbry] wire: optimize binaryFreeList handling --- wire/common.go | 56 ++++++++------------------------------------------ 1 file changed, 9 insertions(+), 47 deletions(-) diff --git a/wire/common.go b/wire/common.go index 42c1797b..8d61bdb6 100644 --- a/wire/common.go +++ b/wire/common.go @@ -18,10 +18,6 @@ import ( const ( // MaxVarIntPayload is the maximum payload size for a variable length integer. MaxVarIntPayload = 9 - - // binaryFreeListMaxItems is the number of buffers to keep in the free - // list to use for binary serialization and deserialization. - binaryFreeListMaxItems = 1024 ) var ( @@ -47,38 +43,14 @@ var ( // io.Writer, and return the buffer to the free list. type binaryFreeList chan []byte -// Borrow returns a byte slice from the free list with a length of 8. A new -// buffer is allocated if there are not any available on the free list. -func (l binaryFreeList) Borrow() []byte { - var buf []byte - select { - case buf = <-l: - default: - buf = make([]byte, 8) - } - return buf[:8] -} - -// Return puts the provided byte slice back on the free list. The buffer MUST -// have been obtained via the Borrow function and therefore have a cap of 8. -func (l binaryFreeList) Return(buf []byte) { - select { - case l <- buf: - default: - // Let it go to the garbage collector. - } -} - // Uint8 reads a single byte from the provided reader using a buffer from the // free list and returns it as a uint8. func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) { - buf := l.Borrow()[:1] + buf := make([]byte, 1) // should be allocated on the stack if _, err := io.ReadFull(r, buf); err != nil { - l.Return(buf) return 0, err } rv := buf[0] - l.Return(buf) return rv, nil } @@ -86,13 +58,11 @@ func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) { // free list, converts it to a number using the provided byte order, and returns // the resulting uint16. func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16, error) { - buf := l.Borrow()[:2] + buf := make([]byte, 2) // should be allocated on the stack if _, err := io.ReadFull(r, buf); err != nil { - l.Return(buf) return 0, err } rv := byteOrder.Uint16(buf) - l.Return(buf) return rv, nil } @@ -100,13 +70,11 @@ func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16, // free list, converts it to a number using the provided byte order, and returns // the resulting uint32. func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder) (uint32, error) { - buf := l.Borrow()[:4] + buf := make([]byte, 4) // should be allocated on the stack if _, err := io.ReadFull(r, buf); err != nil { - l.Return(buf) return 0, err } rv := byteOrder.Uint32(buf) - l.Return(buf) return rv, nil } @@ -114,23 +82,20 @@ func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder) (uint32, // free list, converts it to a number using the provided byte order, and returns // the resulting uint64. func (l binaryFreeList) Uint64(r io.Reader, byteOrder binary.ByteOrder) (uint64, error) { - buf := l.Borrow()[:8] + buf := make([]byte, 8) // should be allocated on the stack if _, err := io.ReadFull(r, buf); err != nil { - l.Return(buf) return 0, err } rv := byteOrder.Uint64(buf) - l.Return(buf) return rv, nil } // PutUint8 copies the provided uint8 into a buffer from the free list and // writes the resulting byte to the given writer. func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error { - buf := l.Borrow()[:1] + buf := make([]byte, 1) // should be allocated on the stack buf[0] = val _, err := w.Write(buf) - l.Return(buf) return err } @@ -138,10 +103,9 @@ func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error { // buffer from the free list and writes the resulting two bytes to the given // writer. func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOrder, val uint16) error { - buf := l.Borrow()[:2] + buf := make([]byte, 2) // should be allocated on the stack byteOrder.PutUint16(buf, val) _, err := w.Write(buf) - l.Return(buf) return err } @@ -149,10 +113,9 @@ func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOrder, val u // buffer from the free list and writes the resulting four bytes to the given // writer. func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOrder, val uint32) error { - buf := l.Borrow()[:4] + buf := make([]byte, 4) // should be allocated on the stack byteOrder.PutUint32(buf, val) _, err := w.Write(buf) - l.Return(buf) return err } @@ -160,16 +123,15 @@ func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOrder, val u // buffer from the free list and writes the resulting eight bytes to the given // writer. func (l binaryFreeList) PutUint64(w io.Writer, byteOrder binary.ByteOrder, val uint64) error { - buf := l.Borrow()[:8] + buf := make([]byte, 8) // should be allocated on the stack byteOrder.PutUint64(buf, val) _, err := w.Write(buf) - l.Return(buf) return err } // binarySerializer provides a free list of buffers to use for serializing and // deserializing primitive integer values to and from io.Readers and io.Writers. -var binarySerializer binaryFreeList = make(chan []byte, binaryFreeListMaxItems) +var binarySerializer binaryFreeList = make(chan []byte) // errNonCanonicalVarInt is the common format string used for non-canonically // encoded variable length integer errors. -- 2.45.2 From 40606d22fdc7c4a698c2d2966abe98952fb00d3e Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 21:05:31 -0700 Subject: [PATCH 112/459] [lbry] wire: update protocol NetIDs --- wire/protocol.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wire/protocol.go b/wire/protocol.go index 8cc9838a..cade06b7 100644 --- a/wire/protocol.go +++ b/wire/protocol.go @@ -147,13 +147,13 @@ type BitcoinNet uint32 // better idea to simply disconnect clients that are misbehaving over TCP. const ( // MainNet represents the main bitcoin network. - MainNet BitcoinNet = 0xd9b4bef9 + MainNet BitcoinNet = 0xf1aae4fa // TestNet represents the regression test network. - TestNet BitcoinNet = 0xdab5bffa + TestNet BitcoinNet = 0xd1aae4fa // TestNet3 represents the test network (version 3). - TestNet3 BitcoinNet = 0x0709110b + TestNet3 BitcoinNet = 0xe1aae4fa // SimNet represents the simulation test network. SimNet BitcoinNet = 0x12141c16 -- 2.45.2 From a5050cf2dee62f8daf8c9d44c9475400b5a42008 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 6 Jul 2021 19:42:57 -0700 Subject: [PATCH 113/459] [lbry] profile: support fgprof (flame graph) --- btcd.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/btcd.go b/btcd.go index 3ace182c..b93851ba 100644 --- a/btcd.go +++ b/btcd.go @@ -18,6 +18,8 @@ import ( "github.com/btcsuite/btcd/blockchain/indexers" "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcd/limits" + + "github.com/felixge/fgprof" ) const ( @@ -65,6 +67,7 @@ func btcdMain(serverChan chan<- *server) error { // Enable http profiling server if requested. if cfg.Profile != "" { + http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler()) go func() { listenAddr := net.JoinHostPort("", cfg.Profile) btcdLog.Infof("Profile server listening on %s", listenAddr) -- 2.45.2 From d7bfc9c07701852479f83c95b8cc5b034c9d5685 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 19:46:51 -0700 Subject: [PATCH 114/459] [lbry] chaincfg: implement LBRY PoW Hash --- chaincfg/chainhash/hashfuncs.go | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/chaincfg/chainhash/hashfuncs.go b/chaincfg/chainhash/hashfuncs.go index bf74f73c..194c60e3 100644 --- a/chaincfg/chainhash/hashfuncs.go +++ b/chaincfg/chainhash/hashfuncs.go @@ -5,7 +5,12 @@ package chainhash -import "crypto/sha256" +import ( + "crypto/sha256" + "crypto/sha512" + + "golang.org/x/crypto/ripemd160" +) // HashB calculates hash(b) and returns the resulting bytes. func HashB(b []byte) []byte { @@ -31,3 +36,26 @@ func DoubleHashH(b []byte) Hash { first := sha256.Sum256(b) return Hash(sha256.Sum256(first[:])) } + +// LbryPoWHashH calculates returns the PoW Hash. +// +// doubled := SHA256(SHA256(b)) +// expanded := SHA512(doubled) +// left := RIPEMD160(expanded[0:32]) +// right := RIPEMD160(expanded[32:64]) +// result := SHA256(SHA256(left||right)) +func LbryPoWHashH(b []byte) Hash { + doubled := DoubleHashB(b) + expanded := sha512.Sum512(doubled) + + r := ripemd160.New() + r.Reset() + r.Write(expanded[:sha256.Size]) + left := r.Sum(nil) + + r.Reset() + r.Write(expanded[sha256.Size:]) + + combined := r.Sum(left) + return DoubleHashH(combined) +} -- 2.45.2 From a8210577844e6f5af568e88227d38d78f6b1fa74 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 21:03:41 -0700 Subject: [PATCH 115/459] [lbry] chaincfg: setup genisis blocks --- chaincfg/genesis.go | 87 +++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/chaincfg/genesis.go b/chaincfg/genesis.go index 73d28610..2c2a043e 100644 --- a/chaincfg/genesis.go +++ b/chaincfg/genesis.go @@ -22,33 +22,22 @@ var genesisCoinbaseTx = wire.MsgTx{ Index: 0xffffffff, }, SignatureScript: []byte{ - 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */ - 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */ - 0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */ - 0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */ - 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */ - 0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */ - 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/ - 0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */ - 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/ - 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */ + 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x17, + 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, }, Sequence: 0xffffffff, }, }, TxOut: []*wire.TxOut{ { - Value: 0x12a05f200, + Value: 0x8e1bc9bf040000, // 400000000 * COIN PkScript: []byte{ - 0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */ - 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */ - 0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */ - 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */ - 0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */ - 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */ - 0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */ - 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */ - 0x1d, 0x5f, 0xac, /* |._.| */ + 0x76, 0xa9, 0x14, 0x34, 0x59, 0x91, 0xdb, 0xf5, + 0x7b, 0xfb, 0x01, 0x4b, 0x87, 0x00, 0x6a, 0xcd, + 0xfa, 0xfb, 0xfc, 0x5f, 0xe8, 0x29, 0x2f, 0x88, + 0xac, }, }, }, @@ -58,19 +47,28 @@ var genesisCoinbaseTx = wire.MsgTx{ // genesisHash is the hash of the first block in the block chain for the main // network (genesis block). var genesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, - 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, - 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x63, 0xf4, 0x34, 0x6a, 0x4d, 0xb3, 0x4f, 0xdf, + 0xce, 0x29, 0xa7, 0x0f, 0x5e, 0x8d, 0x11, 0xf0, + 0x65, 0xf6, 0xb9, 0x16, 0x02, 0xb7, 0x03, 0x6c, + 0x7f, 0x22, 0xf3, 0xa0, 0x3b, 0x28, 0x89, 0x9c, }) // genesisMerkleRoot is the hash of the first transaction in the genesis block // for the main network. var genesisMerkleRoot = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, - 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, - 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, - 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, + 0xcc, 0x59, 0xe5, 0x9f, 0xf9, 0x7a, 0xc0, 0x92, + 0xb5, 0x5e, 0x42, 0x3a, 0xa5, 0x49, 0x51, 0x51, + 0xed, 0x6f, 0xb8, 0x05, 0x70, 0xa5, 0xbb, 0x78, + 0xcd, 0x5b, 0xd1, 0xc3, 0x82, 0x1c, 0x21, 0xb8, +}) + +// genesisClaimTrie is the hash of the first transaction in the genesis block +// for the main network. +var genesisClaimTrie = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }) // genesisBlock defines the genesis block of the block chain which serves as the @@ -79,10 +77,11 @@ var genesisBlock = wire.MsgBlock{ Header: wire.BlockHeader{ Version: 1, PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000 - MerkleRoot: genesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b - Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 18:15:05 +0000 UTC - Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000] - Nonce: 0x7c2bac1d, // 2083236893 + MerkleRoot: genesisMerkleRoot, // b8211c82c3d15bcd78bba57005b86fed515149a53a425eb592c07af99fe559cc + ClaimTrie: genesisClaimTrie, // 0000000000000000000000000000000000000000000000000000000000000001 + Timestamp: time.Unix(1446058291, 0), // 28 Oct 2015 18:51:31 +0000 UTC + Bits: 0x1f00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000] + Nonce: 0x00000507, // 1287 }, Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } @@ -90,10 +89,10 @@ var genesisBlock = wire.MsgBlock{ // regTestGenesisHash is the hash of the first block in the block chain for the // regression test network (genesis block). var regTestGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, - 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, - 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, - 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, + 0x56, 0x75, 0x68, 0x69, 0x76, 0x67, 0x4f, 0x50, + 0xa0, 0xa1, 0x95, 0x3d, 0x17, 0x2e, 0x9e, 0xcf, + 0x4a, 0x4a, 0x62, 0x1d, 0xc9, 0xa4, 0xc3, 0x79, + 0x5d, 0xec, 0xd4, 0x99, 0x12, 0xcf, 0x3f, 0x6e, }) // regTestGenesisMerkleRoot is the hash of the first transaction in the genesis @@ -107,10 +106,11 @@ var regTestGenesisBlock = wire.MsgBlock{ Header: wire.BlockHeader{ Version: 1, PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000 - MerkleRoot: regTestGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b - Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC + MerkleRoot: regTestGenesisMerkleRoot, // b8211c82c3d15bcd78bba57005b86fed515149a53a425eb592c07af99fe559cc + ClaimTrie: genesisClaimTrie, // 0000000000000000000000000000000000000000000000000000000000000001 + Timestamp: time.Unix(1446058291, 0), // 28 Oct 2015 18:51:31 +0000 UTC Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000] - Nonce: 2, + Nonce: 1, }, Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } @@ -135,10 +135,11 @@ var testNet3GenesisBlock = wire.MsgBlock{ Header: wire.BlockHeader{ Version: 1, PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000 - MerkleRoot: testNet3GenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b - Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC - Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000] - Nonce: 0x18aea41a, // 414098458 + MerkleRoot: testNet3GenesisMerkleRoot, // b8211c82c3d15bcd78bba57005b86fed515149a53a425eb592c07af99fe559cc + ClaimTrie: genesisClaimTrie, // 0000000000000000000000000000000000000000000000000000000000000001 + Timestamp: time.Unix(1446058291, 0), // 28 Oct 2015 18:51:31 +0000 UTC + Bits: 0x1f00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000] + Nonce: 0x00000507, // 1287 }, Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -- 2.45.2 From 261f9be12eac56dc1bc428fec6482ac31775a5c5 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 21:04:41 -0700 Subject: [PATCH 116/459] [lbry] chaincfg: update chainparams for LBRY chain Co-authored-by: Brannon King Co-authored-by: Alex Grintsvayg --- chaincfg/params.go | 263 +++++++++++++++++++++------------------------ 1 file changed, 121 insertions(+), 142 deletions(-) diff --git a/chaincfg/params.go b/chaincfg/params.go index a6d8d3e5..68c362d5 100644 --- a/chaincfg/params.go +++ b/chaincfg/params.go @@ -25,8 +25,8 @@ var ( bigOne = big.NewInt(1) // mainPowLimit is the highest proof of work value a Bitcoin block can - // have for the main network. It is the value 2^224 - 1. - mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) + // have for the main network. It is the value 2^240 - 1. + mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 240), bigOne) // regressionPowLimit is the highest proof of work value a Bitcoin block // can have for the regression test network. It is the value 2^255 - 1. @@ -34,8 +34,8 @@ var ( // testNet3PowLimit is the highest proof of work value a Bitcoin block // can have for the test network (version 3). It is the value - // 2^224 - 1. - testNet3PowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) + // 2^240 - 1. + testNet3PowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 240), bigOne) // simNetPowLimit is the highest proof of work value a Bitcoin block // can have for the simulation test network. It is the value 2^255 - 1. @@ -102,6 +102,9 @@ type ConsensusDeployment struct { // ExpireTime is the median block time after which the attempted // deployment expires. ExpireTime uint64 + + // ForceActiveAt is added by LBRY to bypass consensus. Features are activated via hard-fork instead. + ForceActiveAt int32 } // Constants that define the deployment offset in the deployments field of the @@ -237,11 +240,9 @@ type Params struct { Bech32HRPSegwit string // Address encoding magics - PubKeyHashAddrID byte // First byte of a P2PKH address - ScriptHashAddrID byte // First byte of a P2SH address - PrivateKeyID byte // First byte of a WIF private key - WitnessPubKeyHashAddrID byte // First byte of a P2WPKH address - WitnessScriptHashAddrID byte // First byte of a P2WSH address + PubKeyHashAddrID byte // First byte of a P2PKH address + ScriptHashAddrID byte // First byte of a P2SH address + PrivateKeyID byte // First byte of a WIF private key // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID [4]byte @@ -256,60 +257,58 @@ type Params struct { var MainNetParams = Params{ Name: "mainnet", Net: wire.MainNet, - DefaultPort: "8333", + DefaultPort: "9246", DNSSeeds: []DNSSeed{ - {"seed.bitcoin.sipa.be", true}, - {"dnsseed.bluematt.me", true}, - {"dnsseed.bitcoin.dashjr.org", false}, - {"seed.bitcoinstats.com", true}, - {"seed.bitnodes.io", false}, - {"seed.bitcoin.jonasschnelli.ch", true}, + {"dnsseed1.lbry.com", true}, + {"dnsseed2.lbry.com", true}, + {"dnsseed3.lbry.com", true}, + {"seed.lbry.grin.io", true}, + {"seed.allaboutlbc.com", true}, }, // Chain parameters GenesisBlock: &genesisBlock, GenesisHash: &genesisHash, PowLimit: mainPowLimit, - PowLimitBits: 0x1d00ffff, - BIP0034Height: 227931, // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8 - BIP0065Height: 388381, // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 - BIP0066Height: 363725, // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 + PowLimitBits: 0x1f00ffff, + BIP0034Height: 1, + BIP0065Height: 200000, + BIP0066Height: 200000, CoinbaseMaturity: 100, - SubsidyReductionInterval: 210000, - TargetTimespan: time.Hour * 24 * 14, // 14 days - TargetTimePerBlock: time.Minute * 10, // 10 minutes - RetargetAdjustmentFactor: 4, // 25% less, 400% more + SubsidyReductionInterval: 1 << 5, + TargetTimespan: time.Second * 150, // retarget every block + TargetTimePerBlock: time.Second * 150, // 150 seconds + RetargetAdjustmentFactor: 4, // 25% less, 400% more ReduceMinDifficulty: false, MinDiffReductionTime: 0, GenerateSupported: false, // Checkpoints ordered from oldest to newest. Checkpoints: []Checkpoint{ - {11111, newHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")}, - {33333, newHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")}, - {74000, newHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")}, - {105000, newHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")}, - {134444, newHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")}, - {168000, newHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")}, - {193000, newHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")}, - {210000, newHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")}, - {216116, newHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, - {225430, newHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, - {250000, newHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, - {267300, newHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")}, - {279000, newHashFromStr("0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")}, - {300255, newHashFromStr("0000000000000000162804527c6e9b9f0563a280525f9d08c12041def0a0f3b2")}, - {319400, newHashFromStr("000000000000000021c6052e9becade189495d1c539aa37c58917305fd15f13b")}, - {343185, newHashFromStr("0000000000000000072b8bf361d01a6ba7d445dd024203fafc78768ed4368554")}, - {352940, newHashFromStr("000000000000000010755df42dba556bb72be6a32f3ce0b6941ce4430152c9ff")}, - {382320, newHashFromStr("00000000000000000a8dc6ed5b133d0eb2fd6af56203e4159789b092defd8ab2")}, - {400000, newHashFromStr("000000000000000004ec466ce4732fe6f1ed1cddc2ed4b328fff5224276e3f6f")}, - {430000, newHashFromStr("000000000000000001868b2bb3a285f3cc6b33ea234eb70facf4dcdf22186b87")}, - {460000, newHashFromStr("000000000000000000ef751bbce8e744ad303c47ece06c8d863e4d417efc258c")}, - {490000, newHashFromStr("000000000000000000de069137b17b8d5a3dfbd5b145b2dcfb203f15d0c4de90")}, - {520000, newHashFromStr("0000000000000000000d26984c0229c9f6962dc74db0a6d525f2f1640396f69c")}, - {550000, newHashFromStr("000000000000000000223b7a2298fb1c6c75fb0efc28a4c56853ff4112ec6bc9")}, - {560000, newHashFromStr("0000000000000000002c7b276daf6efb2b6aa68e2ce3be67ef925b3264ae7122")}, + {40000, newHashFromStr("4c55584b068108b15c0066a010d11971aa92f46b0a73d479f1b7fa57df8b05f4")}, + {80000, newHashFromStr("6e9facdfb87ba8394a46c61a7c093f7f00b1397a2dabc6a04f2911e0efdcf50a")}, + {120000, newHashFromStr("6a9dba420ec544b927769765dccec8b29e214e6ca9f82b54a52bf20ca517b75a")}, + {160000, newHashFromStr("87b2913a509d857401f7587903c90214db7847af1a1ad63a3b6f245936e3ae9d")}, + {200000, newHashFromStr("0fe8ed6019a83028006435e47be4e37a0d3ed48019cde1dc7ede6562e5829839")}, + {240000, newHashFromStr("cb3c2342afbe7291012f2288403a9d105f46987f78b279d516db2deb4d35b0b7")}, + {280000, newHashFromStr("9835d03eb527ea4ce45c217350c68042926d497c21fb31413b2f7824ff6fc6c3")}, + {320000, newHashFromStr("ad80c7cb91ca1d9c9b7bf68ca1b6d4ba217fe25ca5ded6a7e8acbaba663b143f")}, + {360000, newHashFromStr("f9fd013252439663c1e729a8afb27187a8b9cc63a253336060f867e3cfbe4dcb")}, + {400000, newHashFromStr("f0e56e70782af63ccb49c76e852540688755869ba59ec68cac9c04a6b4d9f5ca")}, + {440000, newHashFromStr("52760e00c369b40781a2ced32836711fab82a720fafb121118c815bb46afd996")}, + {480000, newHashFromStr("cecacaf4d1a8d1ef60da39343540781115abb91f5f0c976bb08afc4d4e3218ac")}, + {520000, newHashFromStr("fa5e9d6dcf9ad57ba60d8ba26fb05585741098d10f42ed9d5e6b5e90ebc278d6")}, + {560000, newHashFromStr("95c6229bd9b40f03a8426b2fec740026b3f06b1628cfb87527b0cbd0da328c0c")}, + {600000, newHashFromStr("532657a97d480feb2d0423bb736cbfd7400b3ac8311e81ac749a2f29103a6c6b")}, + {640000, newHashFromStr("68b69e3e8765e1ddbac63cbfbbf12e1a920da994d242a26fd07624f067743080")}, + {680000, newHashFromStr("7b9f30c959405b5b96d0b0c2ba8fc7c5586cd0ce40df51427de4b8a217859c45")}, + {720000, newHashFromStr("42084d5f88c71c0ae09b8677070969df9c3ef875c5f434133f552d863204f0cb")}, + {760000, newHashFromStr("1887cd8b50375a9ac0dc9686c98fa8ac69bca618eab6254310647057f6fe4fc9")}, + {800000, newHashFromStr("d34bb871b21e6fda4bd9d9e530ebf12e044814004007f088415035c651ecf322")}, + {840000, newHashFromStr("d0e73c5ce3ad5d6fdb4483aa450f0b1cf7e4570987ee3a3806ace4ad2f7cc9af")}, + {880000, newHashFromStr("806a95f26bab603f1d9132b5d4ea72aab9d1198ad55ae18dac1e149f6cb70ce4")}, + {920000, newHashFromStr("83bc84555105436c51728ab200e8da4d9b3a365fd3d1d47a60048ad0f977c55b")}, + {960000, newHashFromStr("60e37b1c2d1f8771290b7f84865cbadf22b5b89d3ce1201d454b09f0775b42c2")}, }, // Consensus rule change deployments. @@ -325,14 +324,16 @@ var MainNetParams = Params{ ExpireTime: 1230767999, // December 31, 2008 UTC }, DeploymentCSV: { - BitNumber: 0, - StartTime: 1462060800, // May 1st, 2016 - ExpireTime: 1493596800, // May 1st, 2017 + BitNumber: 0, + StartTime: 1462060800, // May 1st, 2016 + ExpireTime: 1493596800, // May 1st, 2017 + ForceActiveAt: 200000, }, DeploymentSegwit: { - BitNumber: 1, - StartTime: 1479168000, // November 15, 2016 UTC - ExpireTime: 1510704000, // November 15, 2017 UTC. + BitNumber: 1, + StartTime: 1547942400, // Jan 20, 2019 + ExpireTime: 1548288000, // Jan 24, 2019 + ForceActiveAt: 680770, }, }, @@ -341,18 +342,16 @@ var MainNetParams = Params{ // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "bc", // always bc for main net + Bech32HRPSegwit: "lbc", // Address encoding magics - PubKeyHashAddrID: 0x00, // starts with 1 - ScriptHashAddrID: 0x05, // starts with 3 - PrivateKeyID: 0x80, // starts with 5 (uncompressed) or K (compressed) - WitnessPubKeyHashAddrID: 0x06, // starts with p2 - WitnessScriptHashAddrID: 0x0A, // starts with 7Xh + PubKeyHashAddrID: 0x55, + ScriptHashAddrID: 0x7a, + PrivateKeyID: 0x1c, // BIP32 hierarchical deterministic extended key magics - HDPrivateKeyID: [4]byte{0x04, 0x88, 0xad, 0xe4}, // starts with xprv - HDPublicKeyID: [4]byte{0x04, 0x88, 0xb2, 0x1e}, // starts with xpub + HDPrivateKeyID: [4]byte{0x04, 0x88, 0xad, 0xe4}, + HDPublicKeyID: [4]byte{0x04, 0x88, 0xb2, 0x1e}, // BIP44 coin type used in the hierarchical deterministic path for // address generation. @@ -365,7 +364,7 @@ var MainNetParams = Params{ var RegressionNetParams = Params{ Name: "regtest", Net: wire.TestNet, - DefaultPort: "18444", + DefaultPort: "29246", DNSSeeds: []DNSSeed{}, // Chain parameters @@ -374,15 +373,15 @@ var RegressionNetParams = Params{ PowLimit: regressionPowLimit, PowLimitBits: 0x207fffff, CoinbaseMaturity: 100, - BIP0034Height: 100000000, // Not active - Permit ver 1 blocks - BIP0065Height: 1351, // Used by regression tests - BIP0066Height: 1251, // Used by regression tests - SubsidyReductionInterval: 150, - TargetTimespan: time.Hour * 24 * 14, // 14 days - TargetTimePerBlock: time.Minute * 10, // 10 minutes - RetargetAdjustmentFactor: 4, // 25% less, 400% more - ReduceMinDifficulty: true, - MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 + BIP0034Height: 1000, + BIP0065Height: 1351, // Used by regression tests + BIP0066Height: 1251, // Used by regression tests + SubsidyReductionInterval: 1 << 5, + TargetTimespan: time.Second, + TargetTimePerBlock: time.Second, + RetargetAdjustmentFactor: 4, // 25% less, 400% more + ReduceMinDifficulty: false, + MinDiffReductionTime: 0, GenerateSupported: true, // Checkpoints ordered from oldest to newest. @@ -401,14 +400,16 @@ var RegressionNetParams = Params{ ExpireTime: math.MaxInt64, // Never expires }, DeploymentCSV: { - BitNumber: 0, - StartTime: 0, // Always available for vote - ExpireTime: math.MaxInt64, // Never expires + BitNumber: 0, + StartTime: 0, // Always available for vote + ExpireTime: math.MaxInt64, // Never expires + ForceActiveAt: 1, }, DeploymentSegwit: { - BitNumber: 1, - StartTime: 0, // Always available for vote - ExpireTime: math.MaxInt64, // Never expires. + BitNumber: 1, + StartTime: 0, + ExpireTime: math.MaxInt64, + ForceActiveAt: 150, }, }, @@ -417,12 +418,12 @@ var RegressionNetParams = Params{ // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "bcrt", // always bcrt for reg test net + Bech32HRPSegwit: "rlbc", // Address encoding magics - PubKeyHashAddrID: 0x6f, // starts with m or n - ScriptHashAddrID: 0xc4, // starts with 2 - PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) + PubKeyHashAddrID: 111, // starts with m or n + ScriptHashAddrID: 196, // starts with 2 + PrivateKeyID: 239, // starts with 9 (uncompressed) or c (compressed) // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv @@ -439,48 +440,31 @@ var RegressionNetParams = Params{ var TestNet3Params = Params{ Name: "testnet3", Net: wire.TestNet3, - DefaultPort: "18333", + DefaultPort: "19246", DNSSeeds: []DNSSeed{ - {"testnet-seed.bitcoin.jonasschnelli.ch", true}, - {"testnet-seed.bitcoin.schildbach.de", false}, - {"seed.tbtc.petertodd.org", true}, - {"testnet-seed.bluematt.me", false}, + {"testdnsseed1.lbry.com", true}, + {"testdnsseed2.lbry.com", true}, }, // Chain parameters GenesisBlock: &testNet3GenesisBlock, GenesisHash: &testNet3GenesisHash, PowLimit: testNet3PowLimit, - PowLimitBits: 0x1d00ffff, - BIP0034Height: 21111, // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8 - BIP0065Height: 581885, // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 - BIP0066Height: 330776, // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 + PowLimitBits: 0x1f00ffff, + BIP0034Height: 21111, // 0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8 + BIP0065Height: 1200000, + BIP0066Height: 1200000, CoinbaseMaturity: 100, - SubsidyReductionInterval: 210000, - TargetTimespan: time.Hour * 24 * 14, // 14 days - TargetTimePerBlock: time.Minute * 10, // 10 minutes - RetargetAdjustmentFactor: 4, // 25% less, 400% more - ReduceMinDifficulty: true, - MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 - GenerateSupported: false, + SubsidyReductionInterval: 1 << 5, + TargetTimespan: time.Second * 150, // retarget every block + TargetTimePerBlock: time.Second * 150, // 150 seconds + RetargetAdjustmentFactor: 4, // 25% less, 400% more + ReduceMinDifficulty: false, + MinDiffReductionTime: 0, + GenerateSupported: true, // Checkpoints ordered from oldest to newest. - Checkpoints: []Checkpoint{ - {546, newHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, - {100000, newHashFromStr("00000000009e2958c15ff9290d571bf9459e93b19765c6801ddeccadbb160a1e")}, - {200000, newHashFromStr("0000000000287bffd321963ef05feab753ebe274e1d78b2fd4e2bfe9ad3aa6f2")}, - {300001, newHashFromStr("0000000000004829474748f3d1bc8fcf893c88be255e6d7f571c548aff57abf4")}, - {400002, newHashFromStr("0000000005e2c73b8ecb82ae2dbc2e8274614ebad7172b53528aba7501f5a089")}, - {500011, newHashFromStr("00000000000929f63977fbac92ff570a9bd9e7715401ee96f2848f7b07750b02")}, - {600002, newHashFromStr("000000000001f471389afd6ee94dcace5ccc44adc18e8bff402443f034b07240")}, - {700000, newHashFromStr("000000000000406178b12a4dea3b27e13b3c4fe4510994fd667d7c1e6a3f4dc1")}, - {800010, newHashFromStr("000000000017ed35296433190b6829db01e657d80631d43f5983fa403bfdb4c1")}, - {900000, newHashFromStr("0000000000356f8d8924556e765b7a94aaebc6b5c8685dcfa2b1ee8b41acd89b")}, - {1000007, newHashFromStr("00000000001ccb893d8a1f25b70ad173ce955e5f50124261bbbc50379a612ddf")}, - {1100007, newHashFromStr("00000000000abc7b2cd18768ab3dee20857326a818d1946ed6796f42d66dd1e8")}, - {1200007, newHashFromStr("00000000000004f2dc41845771909db57e04191714ed8c963f7e56713a7b6cea")}, - {1300007, newHashFromStr("0000000072eab69d54df75107c052b26b0395b44f77578184293bf1bb1dbd9fa")}, - }, + Checkpoints: []Checkpoint{}, // Consensus rule change deployments. // @@ -500,9 +484,10 @@ var TestNet3Params = Params{ ExpireTime: 1493596800, // May 1st, 2017 }, DeploymentSegwit: { - BitNumber: 1, - StartTime: 1462060800, // May 1, 2016 UTC - ExpireTime: 1493596800, // May 1, 2017 UTC. + BitNumber: 1, + StartTime: 1462060800, // May 1st 2016 + ExpireTime: 1493596800, // May 1st 2017 + ForceActiveAt: 1198600, }, }, @@ -511,14 +496,12 @@ var TestNet3Params = Params{ // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "tb", // always tb for test net + Bech32HRPSegwit: "tlbc", // Address encoding magics - PubKeyHashAddrID: 0x6f, // starts with m or n - ScriptHashAddrID: 0xc4, // starts with 2 - WitnessPubKeyHashAddrID: 0x03, // starts with QW - WitnessScriptHashAddrID: 0x28, // starts with T7n - PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) + PubKeyHashAddrID: 111, + ScriptHashAddrID: 196, + PrivateKeyID: 239, // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv @@ -552,11 +535,11 @@ var SimNetParams = Params{ BIP0066Height: 0, // Always active on simnet CoinbaseMaturity: 100, SubsidyReductionInterval: 210000, - TargetTimespan: time.Hour * 24 * 14, // 14 days - TargetTimePerBlock: time.Minute * 10, // 10 minutes - RetargetAdjustmentFactor: 4, // 25% less, 400% more + TargetTimespan: time.Second * 150, + TargetTimePerBlock: time.Second * 150, + RetargetAdjustmentFactor: 4, // 25% less, 400% more ReduceMinDifficulty: true, - MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 + MinDiffReductionTime: 0, GenerateSupported: true, // Checkpoints ordered from oldest to newest. @@ -581,8 +564,8 @@ var SimNetParams = Params{ }, DeploymentSegwit: { BitNumber: 1, - StartTime: 0, // Always available for vote - ExpireTime: math.MaxInt64, // Never expires. + StartTime: 0, + ExpireTime: math.MaxInt64, }, }, @@ -591,14 +574,12 @@ var SimNetParams = Params{ // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "sb", // always sb for sim net + Bech32HRPSegwit: "slbc", // Address encoding magics - PubKeyHashAddrID: 0x3f, // starts with S - ScriptHashAddrID: 0x7b, // starts with s - PrivateKeyID: 0x64, // starts with 4 (uncompressed) or F (compressed) - WitnessPubKeyHashAddrID: 0x19, // starts with Gg - WitnessScriptHashAddrID: 0x28, // starts with ? + PubKeyHashAddrID: 111, + ScriptHashAddrID: 196, + PrivateKeyID: 239, // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID: [4]byte{0x04, 0x20, 0xb9, 0x00}, // starts with sprv @@ -691,14 +672,12 @@ func CustomSignetParams(challenge []byte, dnsSeeds []DNSSeed) Params { // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "tb", // always tb for test net + Bech32HRPSegwit: "slbc", // Address encoding magics - PubKeyHashAddrID: 0x6f, // starts with m or n - ScriptHashAddrID: 0xc4, // starts with 2 - WitnessPubKeyHashAddrID: 0x03, // starts with QW - WitnessScriptHashAddrID: 0x28, // starts with T7n - PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) + PubKeyHashAddrID: 0x6f, // starts with m or n + ScriptHashAddrID: 0xc4, // starts with 2 + PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv -- 2.45.2 From 842085749198da16e3ee71482c164784afb4fc8d Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 24 May 2018 14:44:18 -0700 Subject: [PATCH 117/459] [lbry] blockchain, wire: add ClaimTrie to Block Header --- blockchain/blockindex.go | 3 +++ blockchain/error.go | 5 +++++ btcjson/chainsvrresults.go | 2 ++ wire/blockheader.go | 12 ++++++++---- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/blockchain/blockindex.go b/blockchain/blockindex.go index 2ff2fa27..1531e6b1 100644 --- a/blockchain/blockindex.go +++ b/blockchain/blockindex.go @@ -93,6 +93,7 @@ type blockNode struct { nonce uint32 timestamp int64 merkleRoot chainhash.Hash + claimTrie chainhash.Hash // status is a bitfield representing the validation state of the block. The // status field, unlike the other fields, may be written to and so should @@ -114,6 +115,7 @@ func initBlockNode(node *blockNode, blockHeader *wire.BlockHeader, parent *block nonce: blockHeader.Nonce, timestamp: blockHeader.Timestamp.Unix(), merkleRoot: blockHeader.MerkleRoot, + claimTrie: blockHeader.ClaimTrie, } if parent != nil { node.parent = parent @@ -144,6 +146,7 @@ func (node *blockNode) Header() wire.BlockHeader { Version: node.version, PrevBlock: *prevHash, MerkleRoot: node.merkleRoot, + ClaimTrie: node.claimTrie, Timestamp: time.Unix(node.timestamp, 0), Bits: node.bits, Nonce: node.nonce, diff --git a/blockchain/error.go b/blockchain/error.go index 1e7c879b..f18648f3 100644 --- a/blockchain/error.go +++ b/blockchain/error.go @@ -220,6 +220,10 @@ const ( // current chain tip. This is not a block validation rule, but is required // for block proposals submitted via getblocktemplate RPC. ErrPrevBlockNotBest + + // ErrBadClaimTrie indicates the calculated ClaimTrie root does not match + // the expected value. + ErrBadClaimTrie ) // Map of ErrorCode values back to their constant names for pretty printing. @@ -267,6 +271,7 @@ var errorCodeStrings = map[ErrorCode]string{ ErrPreviousBlockUnknown: "ErrPreviousBlockUnknown", ErrInvalidAncestorBlock: "ErrInvalidAncestorBlock", ErrPrevBlockNotBest: "ErrPrevBlockNotBest", + ErrBadClaimTrie: "ErrBadClaimTrie", } // String returns the ErrorCode as a human-readable name. diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 59f18c74..405fd867 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -25,6 +25,7 @@ type GetBlockHeaderVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` + ClaimTrie string `json:"claimtrie"` Time int64 `json:"time"` Nonce uint64 `json:"nonce"` Bits string `json:"bits"` @@ -81,6 +82,7 @@ type GetBlockVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` + ClaimTrie string `json:"claimTrie"` Tx []string `json:"tx,omitempty"` RawTx []TxRawResult `json:"rawtx,omitempty"` // Note: this field is always empty when verbose != 2. Time int64 `json:"time"` diff --git a/wire/blockheader.go b/wire/blockheader.go index 9c9c2237..b4d0531e 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -15,7 +15,7 @@ import ( // MaxBlockHeaderPayload is the maximum number of bytes a block header can be. // Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes + // PrevBlock and MerkleRoot hashes. -const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 2) +const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 3) // BlockHeader defines information about a block and is used in the bitcoin // block (MsgBlock) and headers (MsgHeaders) messages. @@ -29,6 +29,9 @@ type BlockHeader struct { // Merkle tree reference to hash of all transactions for the block. MerkleRoot chainhash.Hash + // ClaimTrie reference to hash of ClaimTrie. + ClaimTrie chainhash.Hash + // Time the block was created. This is, unfortunately, encoded as a // uint32 on the wire and therefore is limited to 2106. Timestamp time.Time @@ -96,7 +99,7 @@ func (h *BlockHeader) Serialize(w io.Writer) error { // block hash, merkle root hash, difficulty bits, and nonce used to generate the // block with defaults for the remaining fields. func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, - bits uint32, nonce uint32) *BlockHeader { + claimTrieHash *chainhash.Hash, bits uint32, nonce uint32) *BlockHeader { // Limit the timestamp to one second precision since the protocol // doesn't support better. @@ -104,6 +107,7 @@ func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, Version: version, PrevBlock: *prevHash, MerkleRoot: *merkleRootHash, + ClaimTrie: *claimTrieHash, Timestamp: time.Unix(time.Now().Unix(), 0), Bits: bits, Nonce: nonce, @@ -115,7 +119,7 @@ func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, // decoding from the wire. func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { return readElements(r, &bh.Version, &bh.PrevBlock, &bh.MerkleRoot, - (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) + &bh.ClaimTrie, (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) } // writeBlockHeader writes a bitcoin block header to w. See Serialize for @@ -124,5 +128,5 @@ func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error { sec := uint32(bh.Timestamp.Unix()) return writeElements(w, bh.Version, &bh.PrevBlock, &bh.MerkleRoot, - sec, bh.Bits, bh.Nonce) + &bh.ClaimTrie, sec, bh.Bits, bh.Nonce) } -- 2.45.2 From ace9c128605aae465c8dc54468fe31e3fd12b819 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 24 May 2018 00:00:35 -0700 Subject: [PATCH 118/459] [lbry] blockchain: change max block size to 2,000,000 --- blockchain/fullblocktests/generate.go | 2 +- blockchain/weight.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index 82d3a036..aee67810 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -31,7 +31,7 @@ const ( // Intentionally defined here rather than using constants from codebase // to ensure consensus changes are detected. maxBlockSigOps = 20000 - maxBlockSize = 1000000 + maxBlockSize = 2000000 minCoinbaseScriptLen = 2 maxCoinbaseScriptLen = 100 medianTimeBlocks = 11 diff --git a/blockchain/weight.go b/blockchain/weight.go index 6f6292a1..e23dd87d 100644 --- a/blockchain/weight.go +++ b/blockchain/weight.go @@ -24,7 +24,7 @@ const ( // MaxBlockBaseSize is the maximum number of bytes within a block // which can be allocated to non-witness data. - MaxBlockBaseSize = 1000000 + MaxBlockBaseSize = 2000000 // MaxBlockSigOpsCost is the maximum number of signature operations // allowed for a block. It is calculated via a weighted algorithm which -- 2.45.2 From b179b1d52dc32648a8c4f544345bac6e81077a5b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 21:06:46 -0700 Subject: [PATCH 119/459] [lbry] blockchain, wire: verify blockheaders using LBRY PoW --- blockchain/validate.go | 2 +- wire/blockheader.go | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index f41d54e6..f7831469 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -324,7 +324,7 @@ func checkProofOfWork(header *wire.BlockHeader, powLimit *big.Int, flags Behavio // to avoid proof of work checks is set. if flags&BFNoPoWCheck != BFNoPoWCheck { // The block hash must be less than the claimed target. - hash := header.BlockHash() + hash := header.BlockPoWHash() hashNum := HashToBig(&hash) if hashNum.Cmp(target) > 0 { str := fmt.Sprintf("block hash of %064x is higher than "+ diff --git a/wire/blockheader.go b/wire/blockheader.go index b4d0531e..ee45ec3b 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -59,6 +59,18 @@ func (h *BlockHeader) BlockHash() chainhash.Hash { return chainhash.DoubleHashH(buf.Bytes()) } +// BlockPoWHash computes the block identifier hash for the given block header. +func (h *BlockHeader) BlockPoWHash() chainhash.Hash { + // Encode the header and double sha256 everything prior to the number of + // transactions. Ignore the error returns since there is no way the + // encode could fail except being out of memory which would cause a + // run-time panic. + buf := bytes.NewBuffer(make([]byte, 0, MaxBlockHeaderPayload)) + _ = writeBlockHeader(buf, 0, h) + + return chainhash.LbryPoWHashH(buf.Bytes()) +} + // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. // See Deserialize for decoding block headers stored to disk, such as in a -- 2.45.2 From 53553df4a87a2b11964636a9aca9a5f8b074f50c Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 5 Jun 2018 10:31:39 -0700 Subject: [PATCH 120/459] [lbry] blockchain, txscript: change maxScriptElementSize from 520 t0 20,000 bytes --- blockchain/fullblocktests/generate.go | 4 ++-- txscript/script.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index aee67810..592a14de 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -35,7 +35,7 @@ const ( minCoinbaseScriptLen = 2 maxCoinbaseScriptLen = 100 medianTimeBlocks = 11 - maxScriptElementSize = 520 + maxScriptElementSize = 20000 // numLargeReorgBlocks is the number of blocks to use in the large block // reorg test (when enabled). This is the equivalent of 1 week's worth @@ -1875,7 +1875,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { // // Comment assumptions: // maxBlockSigOps = 20000 - // maxScriptElementSize = 520 + // maxScriptElementSize = 20000 // // [0-19999] : OP_CHECKSIG // [20000] : OP_PUSHDATA4 diff --git a/txscript/script.go b/txscript/script.go index 696bfe2d..1b3a60bd 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -39,9 +39,9 @@ const ( // These are the constants specified for maximums in individual scripts. const ( - MaxOpsPerScript = 201 // Max number of non-push operations. - MaxPubKeysPerMultiSig = 20 // Multisig can't have more sigs than this. - MaxScriptElementSize = 520 // Max bytes pushable to the stack. + MaxOpsPerScript = 201 // Max number of non-push operations. + MaxPubKeysPerMultiSig = 20 // Multisig can't have more sigs than this. + MaxScriptElementSize = 20000 // Max bytes pushable to the stack. ) // isSmallInt returns whether or not the opcode is considered a small integer, -- 2.45.2 From c8abd8fe93b840445ed3b501962298b311f542dc Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 6 Jun 2018 13:22:50 -0700 Subject: [PATCH 121/459] [lbry] blockchain: make UTXO in Genesis block spendable --- blockchain/chain.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/blockchain/chain.go b/blockchain/chain.go index eea603ce..1a95a00b 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1764,6 +1764,20 @@ func New(config *Config) (*BlockChain, error) { return nil, err } + // Helper function to insert the output in genesis block in to the + // transaction database. + fn := func(dbTx database.Tx) error { + genesisBlock := btcutil.NewBlock(b.chainParams.GenesisBlock) + view := NewUtxoViewpoint() + if err := view.connectTransactions(genesisBlock, nil); err != nil { + return err + } + return dbPutUtxoView(dbTx, view) + } + if err := b.db.Update(fn); err != nil { + return nil, err + } + // Perform any upgrades to the various chain-specific buckets as needed. if err := b.maybeUpgradeDbBuckets(config.Interrupt); err != nil { return nil, err -- 2.45.2 From 8591f960e2bf04048a6df5700023d6cdd3e6b9e3 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 12 Jun 2018 17:27:22 -0700 Subject: [PATCH 122/459] [lbry] blockchain: change the difficulty adjustment algorithm. adjusted := target + (actual - target) / 8 max := target + (target / 2) min := target - (target / 8) if adjusted > max { adjusted = max } else if adj < min { adjusted = min } diffculty := lastDifficulty * adjusted / target --- blockchain/chain.go | 5 ++-- blockchain/difficulty.go | 56 +++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index 1a95a00b..b4a871b9 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1736,7 +1736,6 @@ func New(config *Config) (*BlockChain, error) { params := config.ChainParams targetTimespan := int64(params.TargetTimespan / time.Second) targetTimePerBlock := int64(params.TargetTimePerBlock / time.Second) - adjustmentFactor := params.RetargetAdjustmentFactor b := BlockChain{ checkpoints: config.Checkpoints, checkpointsByHeight: checkpointsByHeight, @@ -1745,8 +1744,8 @@ func New(config *Config) (*BlockChain, error) { timeSource: config.TimeSource, sigCache: config.SigCache, indexManager: config.IndexManager, - minRetargetTimespan: targetTimespan / adjustmentFactor, - maxRetargetTimespan: targetTimespan * adjustmentFactor, + minRetargetTimespan: targetTimespan - (targetTimespan / 8), + maxRetargetTimespan: targetTimespan + (targetTimespan / 2), blocksPerRetarget: int32(targetTimespan / targetTimePerBlock), index: newBlockIndex(config.DB, params), hashCache: config.HashCache, diff --git a/blockchain/difficulty.go b/blockchain/difficulty.go index 05f78a3e..3eae3844 100644 --- a/blockchain/difficulty.go +++ b/blockchain/difficulty.go @@ -159,7 +159,6 @@ func CalcWork(bits uint32) *big.Int { func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 { // Convert types used in the calculations below. durationVal := int64(duration / time.Second) - adjustmentFactor := big.NewInt(b.chainParams.RetargetAdjustmentFactor) // The test network rules allow minimum difficulty blocks after more // than twice the desired amount of time needed to generate a block has @@ -178,7 +177,8 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) // multiplied by the max adjustment factor. newTarget := CompactToBig(bits) for durationVal > 0 && newTarget.Cmp(b.chainParams.PowLimit) < 0 { - newTarget.Mul(newTarget, adjustmentFactor) + adj := new(big.Int).Div(newTarget, big.NewInt(2)) + newTarget.Add(newTarget, adj) durationVal -= b.maxRetargetTimespan } @@ -224,47 +224,44 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim return b.chainParams.PowLimitBits, nil } - // Return the previous block's difficulty requirements if this block - // is not at a difficulty retarget interval. - if (lastNode.height+1)%b.blocksPerRetarget != 0 { - // For networks that support it, allow special reduction of the - // required difficulty once too much time has elapsed without - // mining a block. - if b.chainParams.ReduceMinDifficulty { - // Return minimum difficulty when more than the desired - // amount of time has elapsed without mining a block. - reductionTime := int64(b.chainParams.MinDiffReductionTime / - time.Second) - allowMinTime := lastNode.timestamp + reductionTime - if newBlockTime.Unix() > allowMinTime { - return b.chainParams.PowLimitBits, nil - } - - // The block was mined within the desired timeframe, so - // return the difficulty for the last block which did - // not have the special minimum difficulty rule applied. - return b.findPrevTestNetDifficulty(lastNode), nil + // For networks that support it, allow special reduction of the + // required difficulty once too much time has elapsed without + // mining a block. + if b.chainParams.ReduceMinDifficulty { + // Return minimum difficulty when more than the desired + // amount of time has elapsed without mining a block. + reductionTime := int64(b.chainParams.MinDiffReductionTime / + time.Second) + allowMinTime := lastNode.timestamp + reductionTime + if newBlockTime.Unix() > allowMinTime { + return b.chainParams.PowLimitBits, nil } - // For the main network (or any unrecognized networks), simply - // return the previous block's difficulty requirements. - return lastNode.bits, nil + // The block was mined within the desired timeframe, so + // return the difficulty for the last block which did + // not have the special minimum difficulty rule applied. + return b.findPrevTestNetDifficulty(lastNode), nil } // Get the block node at the previous retarget (targetTimespan days // worth of blocks). - firstNode := lastNode.RelativeAncestor(b.blocksPerRetarget - 1) + firstNode := lastNode.RelativeAncestor(b.blocksPerRetarget) + if lastNode.height == 0 { + firstNode = lastNode + } if firstNode == nil { return 0, AssertError("unable to obtain previous retarget block") } + targetTimeSpan := int64(b.chainParams.TargetTimespan / time.Second) + // Limit the amount of adjustment that can occur to the previous // difficulty. actualTimespan := lastNode.timestamp - firstNode.timestamp - adjustedTimespan := actualTimespan - if actualTimespan < b.minRetargetTimespan { + adjustedTimespan := targetTimeSpan + (actualTimespan-targetTimeSpan)/8 + if adjustedTimespan < b.minRetargetTimespan { adjustedTimespan = b.minRetargetTimespan - } else if actualTimespan > b.maxRetargetTimespan { + } else if adjustedTimespan > b.maxRetargetTimespan { adjustedTimespan = b.maxRetargetTimespan } @@ -275,7 +272,6 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim // result. oldTarget := CompactToBig(lastNode.bits) newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan)) - targetTimeSpan := int64(b.chainParams.TargetTimespan / time.Second) newTarget.Div(newTarget, big.NewInt(targetTimeSpan)) // Limit new value to the proof of work limit. -- 2.45.2 From 25c026e060b4c80c8311474a26259d83c94bc6dd Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 12 Jun 2018 21:11:42 -0700 Subject: [PATCH 123/459] [lbry] blockchain: change Block Subsidy algorithm --- blockchain/validate.go | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index f7831469..2fd5d7fd 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -40,7 +40,7 @@ const ( // baseSubsidy is the starting subsidy amount for mined blocks. This // value is halved every SubsidyHalvingInterval blocks. - baseSubsidy = 50 * btcutil.SatoshiPerBitcoin + baseSubsidy = 500 * btcutil.SatoshiPerBitcoin ) var ( @@ -192,12 +192,42 @@ func isBIP0030Node(node *blockNode) bool { // At the target block generation rate for the main network, this is // approximately every 4 years. func CalcBlockSubsidy(height int32, chainParams *chaincfg.Params) int64 { - if chainParams.SubsidyReductionInterval == 0 { - return baseSubsidy + h := int64(height) + if h == 0 { + return btcutil.SatoshiPerBitcoin * 4e8 + } + if h <= 5100 { + return btcutil.SatoshiPerBitcoin + } + if h <= 55000 { + return btcutil.SatoshiPerBitcoin * (1 + (h-5001)/100) } - // Equivalent to: baseSubsidy / 2^(height/subsidyHalvingInterval) - return baseSubsidy >> uint(height/chainParams.SubsidyReductionInterval) + lv := (h - 55001) / int64(chainParams.SubsidyReductionInterval) + reduction := (int64(math.Sqrt((float64(8*lv))+1)) - 1) / 2 + for !withinLevelBounds(reduction, lv) { + if ((reduction*reduction + reduction) >> 1) > lv { + reduction-- + } else { + reduction++ + } + } + subsidyReduction := btcutil.SatoshiPerBitcoin * reduction + if subsidyReduction >= baseSubsidy { + return 0 + } + return baseSubsidy - subsidyReduction +} + +func withinLevelBounds(reduction int64, lv int64) bool { + if ((reduction*reduction + reduction) >> 1) > lv { + return false + } + reduction++ + if ((reduction*reduction + reduction) >> 1) <= lv { + return false + } + return true } // CheckTransactionSanity performs some preliminary checks on a transaction to -- 2.45.2 From a7b3ed5c294ab34fb807d1b1f7e9fb41e73aba5a Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 15 Jun 2018 13:06:26 -0700 Subject: [PATCH 124/459] [lbry] blockchain, mempool: validate txscripts Co-authored-by: Brannon King --- blockchain/validate.go | 11 ++++++++--- mempool/mempool.go | 2 +- mempool/policy.go | 7 ++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index 2fd5d7fd..ef2c283b 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -231,8 +231,8 @@ func withinLevelBounds(reduction int64, lv int64) bool { } // CheckTransactionSanity performs some preliminary checks on a transaction to -// ensure it is sane. These checks are context free. -func CheckTransactionSanity(tx *btcutil.Tx) error { +// ensure it is sane. +func CheckTransactionSanity(tx *btcutil.Tx, enforceSoftFork bool) error { // A transaction must have at least one input. msgTx := tx.MsgTx() if len(msgTx.TxIn) == 0 { @@ -291,6 +291,11 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { btcutil.MaxSatoshi) return ruleError(ErrBadTxOutValue, str) } + + err := txscript.AllClaimsAreSane(txOut.PkScript, enforceSoftFork) + if err != nil { + return ruleError(ErrBadTxOutValue, err.Error()) + } } // Check for duplicate transaction inputs. @@ -545,7 +550,7 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource Median // Do some preliminary checks on each transaction to ensure they are // sane before continuing. for _, tx := range transactions { - err := CheckTransactionSanity(tx) + err := CheckTransactionSanity(tx, false) if err != nil { return err } diff --git a/mempool/mempool.go b/mempool/mempool.go index b54856c8..0aecff7e 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -963,7 +963,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec // Perform preliminary sanity checks on the transaction. This makes // use of blockchain which contains the invariant rules for what // transactions are allowed into blocks. - err := blockchain.CheckTransactionSanity(tx) + err := blockchain.CheckTransactionSanity(tx, true) if err != nil { if cerr, ok := err.(blockchain.RuleError); ok { return nil, nil, chainRuleError(cerr) diff --git a/mempool/policy.go b/mempool/policy.go index 1fe85079..c18b0d7d 100644 --- a/mempool/policy.go +++ b/mempool/policy.go @@ -99,7 +99,7 @@ func checkInputsStandard(tx *btcutil.Tx, utxoView *blockchain.UtxoViewpoint) err // they have already been checked prior to calling this // function. entry := utxoView.LookupEntry(txIn.PreviousOutPoint) - originPkScript := entry.PkScript() + originPkScript := txscript.StripClaimScriptPrefix(entry.PkScript()) switch txscript.GetScriptClass(originPkScript) { case txscript.ScriptHashTy: numSigOps := txscript.GetPreciseSigOpCount( @@ -339,8 +339,9 @@ func checkTransactionStandard(tx *btcutil.Tx, height int32, // be "dust" (except when the script is a null data script). numNullDataOutputs := 0 for i, txOut := range msgTx.TxOut { - scriptClass := txscript.GetScriptClass(txOut.PkScript) - err := checkPkScriptStandard(txOut.PkScript, scriptClass) + pkScript := txscript.StripClaimScriptPrefix(txOut.PkScript) + scriptClass := txscript.GetScriptClass(pkScript) + err := checkPkScriptStandard(pkScript, scriptClass) if err != nil { // Attempt to extract a reject code from the error so // it can be retained. When not possible, fall back to -- 2.45.2 From f8a5df1b87b89d9e5a2fca520cff4ec01b58b103 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 29 Jul 2021 17:21:51 -0400 Subject: [PATCH 125/459] [lbry] blockchain: support force active fork deployment --- blockchain/thresholdstate.go | 6 ++++++ blockchain/versionbits.go | 6 ++++++ rpcserver.go | 1 + 3 files changed, 13 insertions(+) diff --git a/blockchain/thresholdstate.go b/blockchain/thresholdstate.go index 5da74a95..8a79f968 100644 --- a/blockchain/thresholdstate.go +++ b/blockchain/thresholdstate.go @@ -302,6 +302,12 @@ func (b *BlockChain) deploymentState(prevNode *blockNode, deploymentID uint32) ( } deployment := &b.chainParams.Deployments[deploymentID] + + // added to mimic LBRYcrd: + if deployment.ForceActiveAt > 0 && prevNode != nil && prevNode.height+1 >= deployment.ForceActiveAt { + return ThresholdActive, nil + } + checker := deploymentChecker{deployment: deployment, chain: b} cache := &b.deploymentCaches[deploymentID] diff --git a/blockchain/versionbits.go b/blockchain/versionbits.go index 28fcde7b..acdbf144 100644 --- a/blockchain/versionbits.go +++ b/blockchain/versionbits.go @@ -195,6 +195,12 @@ func (b *BlockChain) calcNextBlockVersion(prevNode *blockNode) (int32, error) { expectedVersion := uint32(vbTopBits) for id := 0; id < len(b.chainParams.Deployments); id++ { deployment := &b.chainParams.Deployments[id] + + // added to mimic LBRYcrd: + if deployment.ForceActiveAt > 0 && prevNode != nil && prevNode.height+1 >= deployment.ForceActiveAt { + continue + } + cache := &b.deploymentCaches[id] checker := deploymentChecker{deployment: deployment, chain: b} state, err := b.thresholdState(prevNode, checker, cache) diff --git a/rpcserver.go b/rpcserver.go index d1840729..4502a4cd 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1294,6 +1294,7 @@ func handleGetBlockChainInfo(s *rpcServer, cmd interface{}, closeChan <-chan str Bit: deploymentDetails.BitNumber, StartTime2: int64(deploymentDetails.StartTime), Timeout: int64(deploymentDetails.ExpireTime), + Since: deploymentDetails.ForceActiveAt, } } -- 2.45.2 From 4ecd4385f5b288f8840d7d5622894cd0f91802e0 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 15:24:20 -0700 Subject: [PATCH 126/459] [lbry] blockchain: Consider a block with timestamp less 6 hours 'current' --- blockchain/chain.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index b4a871b9..79bb3d74 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1208,7 +1208,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla // factors are used to guess, but the key factors that allow the chain to // believe it is current are: // - Latest block height is after the latest checkpoint (if enabled) -// - Latest block has a timestamp newer than 24 hours ago +// - Latest block has a timestamp newer than ~6 hours ago (as LBRY block time is one fourth of bitcoin) // // This function MUST be called with the chain state lock held (for reads). func (b *BlockChain) isCurrent() bool { @@ -1219,13 +1219,13 @@ func (b *BlockChain) isCurrent() bool { return false } - // Not current if the latest best block has a timestamp before 24 hours + // Not current if the latest best block has a timestamp before 7 hours // ago. // // The chain appears to be current if none of the checks reported // otherwise. - minus24Hours := b.timeSource.AdjustedTime().Add(-24 * time.Hour).Unix() - return b.bestChain.Tip().timestamp >= minus24Hours + hours := b.timeSource.AdjustedTime().Add(-7 * time.Hour).Unix() + return b.bestChain.Tip().timestamp >= hours } // IsCurrent returns whether or not the chain believes it is current. Several -- 2.45.2 From 57bca30a00626a48ee9650601797b33936d30d34 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Jun 2018 20:20:44 -0700 Subject: [PATCH 127/459] [lbry] server: update client version to /btcwire:0.5.0/LBRY.GO:0.12.2/ TODO: double check if lbryd bumps the version. --- server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.go b/server.go index 746c48dd..6506c95d 100644 --- a/server.go +++ b/server.go @@ -62,7 +62,7 @@ const ( var ( // userAgentName is the user agent name and is used to help identify // ourselves to other bitcoin peers. - userAgentName = "btcd" + userAgentName = "LBRY.GO" // userAgentVersion is the user agent version and is used to help // identify ourselves to other bitcoin peers. -- 2.45.2 From dfc7a4423cede3621b45dd7e1197a1ed5e79f89c Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 14 Oct 2021 17:43:23 -0400 Subject: [PATCH 128/459] [lbry] server: don't ban peers on tx-not-in-block behavior --- server.go | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/server.go b/server.go index 6506c95d..c5fc4aff 100644 --- a/server.go +++ b/server.go @@ -387,11 +387,13 @@ func (sp *serverPeer) addBanScore(persistent, transient uint32, reason string) b } score := sp.banScore.Increase(persistent, transient) if score > warnThreshold { - peerLog.Warnf("Misbehaving peer %s: %s -- ban score increased to %d", - sp, reason, score) + peerLog.Warnf("Misbehaving peer %s: %s -- ban score increased to %d", sp, reason, score) if score > cfg.BanThreshold { - peerLog.Warnf("Misbehaving peer %s -- banning and disconnecting", - sp) + if sp.server.ConnectedCount() <= 1 { + peerLog.Warnf("Refusing to ban peer %s as it is the only peer", sp) + return false + } + peerLog.Warnf("Misbehaving peer %s -- banning and disconnecting", sp) sp.server.BanPeer(sp) sp.Disconnect() return true @@ -1328,24 +1330,28 @@ func (sp *serverPeer) OnNotFound(p *peer.Peer, msg *wire.MsgNotFound) { case wire.InvTypeWitnessTx: numTxns++ default: - peerLog.Debugf("Invalid inv type '%d' in notfound message from %s", - inv.Type, sp) + peerLog.Infof("Invalid inv type '%d' in NotFound message from %s. Disconnecting...", inv.Type, sp) sp.Disconnect() return } } if numBlocks > 0 { blockStr := pickNoun(uint64(numBlocks), "block", "blocks") - reason := fmt.Sprintf("%d %v not found", numBlocks, blockStr) - if sp.addBanScore(20*numBlocks, 0, reason) { - return + reason := fmt.Sprintf("%d %v not found on %s", numBlocks, blockStr, sp) + if sp.addBanScore(20, 0, reason) { + return // once they fail to return us five block requests they're gone for good } } if numTxns > 0 { - txStr := pickNoun(uint64(numTxns), "transaction", "transactions") - reason := fmt.Sprintf("%d %v not found", numBlocks, txStr) - if sp.addBanScore(0, 10*numTxns, reason) { - return + // This is an expected situation if transactions in the mempool make it into a block before + // this node knows about said block. We don't want to ban them for that alone + peerLog.Debugf("%d transactions not found on %s", numTxns, sp) + if numBlocks+numTxns < wire.MaxInvPerMsg { // if our message is full then it is likely followed by another one that isn't + txStr := pickNoun(uint64(numTxns), "transaction", "transactions") + reason := fmt.Sprintf("%d %v not found on %s", numTxns, txStr, sp) + if sp.addBanScore(0, 20, reason) { + return // if they fail us five times in one minute, they're gone -- hitting them at new-block should be rare + } } } -- 2.45.2 From 185cb711b53387ddc65f8b4aa3995ba650eb68c9 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 5 Jun 2018 10:32:45 -0700 Subject: [PATCH 129/459] [lbry] txscript: change MaxScriptSize from 10,000 to 20,005 --- txscript/engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/txscript/engine.go b/txscript/engine.go index 0814e7eb..40ba0eef 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -103,7 +103,7 @@ const ( MaxStackSize = 1000 // MaxScriptSize is the maximum allowed length of a raw script. - MaxScriptSize = 10000 + MaxScriptSize = 20005 // payToWitnessPubKeyHashDataSize is the size of the witness program's // data push for a pay-to-witness-pub-key-hash output. -- 2.45.2 From 6d80d906a8e169791494d065e3029777cc168380 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Jun 2018 19:13:08 -0700 Subject: [PATCH 130/459] [lbry] txscript: introduce claim script Co-authored-by: Brannon King --- txscript/claimscript.go | 216 +++++++++++++++++++++++++++++++++++ txscript/claimscript_test.go | 80 +++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 txscript/claimscript.go create mode 100644 txscript/claimscript_test.go diff --git a/txscript/claimscript.go b/txscript/claimscript.go new file mode 100644 index 00000000..1737ff60 --- /dev/null +++ b/txscript/claimscript.go @@ -0,0 +1,216 @@ +package txscript + +import ( + "bytes" + "fmt" + "unicode/utf8" +) + +const ( + // MaxClaimScriptSize is the max claim script size in bytes, not including the script pubkey part of the script. + MaxClaimScriptSize = 8192 + + // MaxClaimNameSize is the max claim name size in bytes, for all claim trie transactions. + MaxClaimNameSize = 255 + + ClaimIDLength = 160 / 8 + + claimScriptVersion = 0 +) + +// These constants are used to identify a specific claim script Error. +// The error code starts from 200, which leaves enough room between the rest +// of script error codes (numErrorCodes) +const ( + // ErrNotClaimScript is returned when the script does not have a ClaimScript Opcode. + ErrNotClaimScript ErrorCode = iota + 200 + + // ErrInvalidClaimNameScript is returned a claim name script does not conform to the format. + ErrInvalidClaimNameScript + + // ErrInvalidClaimSupportScript is returned a claim support script does not conform to the format. + ErrInvalidClaimSupportScript + + // ErrInvalidClaimUpdateScript is returned a claim update script does not conform to the format. + ErrInvalidClaimUpdateScript +) + +func claimScriptError(c ErrorCode, desc string) Error { + return Error{ErrorCode: c, Description: desc} +} + +// ClaimNameScript creates a claim name script. +func ClaimNameScript(name string, value string) ([]byte, error) { + return NewScriptBuilder().AddOp(OP_CLAIMNAME).AddData([]byte(name)).AddData([]byte(value)). + AddOp(OP_2DROP).AddOp(OP_DROP).AddOp(OP_TRUE).Script() +} + +// ClaimSupportScript creates a support claim script. +func ClaimSupportScript(name string, claimID []byte, value []byte) ([]byte, error) { + builder := NewScriptBuilder().AddOp(OP_SUPPORTCLAIM).AddData([]byte(name)).AddData(claimID) + if len(value) > 0 { + return builder.addData(value).AddOp(OP_2DROP).AddOp(OP_2DROP).AddOp(OP_TRUE).Script() + } + return builder.AddOp(OP_2DROP).AddOp(OP_DROP).AddOp(OP_TRUE).Script() +} + +// ClaimUpdateScript creates an update claim script. +func ClaimUpdateScript(name string, claimID []byte, value string) ([]byte, error) { + return NewScriptBuilder().AddOp(OP_UPDATECLAIM).AddData([]byte(name)).AddData(claimID).AddData([]byte(value)). + AddOp(OP_2DROP).AddOp(OP_2DROP).AddOp(OP_TRUE).Script() +} + +// ClaimScript represents of one of the ClaimNameScript, ClaimSupportScript, and ClaimUpdateScript. +type ClaimScript struct { + Opcode byte + Name []byte + ClaimID []byte + Value []byte + Size int +} + +// ExtractClaimScript exctracts the claim script from the script if it has one. +// The returned ClaimScript is invalidated if the given script is modified. +func ExtractClaimScript(script []byte) (*ClaimScript, error) { + + var cs ClaimScript + + tokenizer := MakeScriptTokenizer(claimScriptVersion, script) + if !tokenizer.Next() { + return nil, claimScriptError(ErrNotClaimScript, "not a claim script opcode") + } + + cs.Opcode = tokenizer.Opcode() + + switch tokenizer.Opcode() { + case OP_CLAIMNAME: + // OP_CLAIMNAME OP_2DROP OP_DROP + if !tokenizer.Next() || len(tokenizer.Data()) > MaxClaimNameSize { + str := fmt.Sprintf("name size %d exceeds limit %d", len(tokenizer.data), MaxClaimNameSize) + return nil, claimScriptError(ErrInvalidClaimNameScript, str) + } + cs.Name = tokenizer.data + + if !tokenizer.Next() { + return nil, claimScriptError(ErrInvalidClaimNameScript, "expect value") + } + cs.Value = tokenizer.Data() + + if !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP || + !tokenizer.Next() || tokenizer.Opcode() != OP_DROP { + str := fmt.Sprintf("expect OP_2DROP OP_DROP") + return nil, claimScriptError(ErrInvalidClaimNameScript, str) + } + + cs.Size = int(tokenizer.ByteIndex()) + return &cs, nil + + case OP_SUPPORTCLAIM: + // OP_SUPPORTCLAIM OP_2DROP OP_DROP + // OP_SUPPORTCLAIM OP_2DROP OP_2DROP + if !tokenizer.Next() || len(tokenizer.Data()) > MaxClaimNameSize { + str := fmt.Sprintf("name size %d exceeds limit %d", len(tokenizer.data), MaxClaimNameSize) + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + cs.Name = tokenizer.data + + if !tokenizer.Next() || len(tokenizer.Data()) != ClaimIDLength { + str := fmt.Sprintf("expect claim id length %d, instead of %d", ClaimIDLength, len(tokenizer.data)) + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + cs.ClaimID = tokenizer.Data() + + if !tokenizer.Next() { + return nil, claimScriptError(ErrInvalidClaimSupportScript, "incomplete script") + } + + switch { + case tokenizer.Opcode() == OP_2DROP: + // Case 1: OP_SUPPORTCLAIM OP_2DROP OP_DROP + if !tokenizer.Next() || tokenizer.Opcode() != OP_DROP { + str := fmt.Sprintf("expect OP_2DROP OP_DROP") + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + + case len(tokenizer.Data()) != 0: + // Case 2: OP_SUPPORTCLAIM OP_2DROP OP_2DROP + // (old bug: non-length size dummy value?) + cs.Value = tokenizer.Data() + if !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP || + !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP { + str := fmt.Sprintf("expect OP_2DROP OP_2DROP") + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + default: + str := fmt.Sprintf("expect OP_2DROP OP_DROP") + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + + cs.Size = int(tokenizer.ByteIndex()) + return &cs, nil + + case OP_UPDATECLAIM: + + // OP_UPDATECLAIM OP_2DROP OP_2DROP + if !tokenizer.Next() || len(tokenizer.Data()) > MaxClaimNameSize { + str := fmt.Sprintf("name size %d exceeds limit %d", len(tokenizer.data), MaxClaimNameSize) + return nil, claimScriptError(ErrInvalidClaimUpdateScript, str) + } + cs.Name = tokenizer.data + + if !tokenizer.Next() || len(tokenizer.Data()) != ClaimIDLength { + str := fmt.Sprintf("expect claim id length %d, instead of %d", ClaimIDLength, len(tokenizer.data)) + return nil, claimScriptError(ErrInvalidClaimUpdateScript, str) + } + cs.ClaimID = tokenizer.Data() + + if !tokenizer.Next() { + str := fmt.Sprintf("expect value") + return nil, claimScriptError(ErrInvalidClaimUpdateScript, str) + } + cs.Value = tokenizer.Data() + + if !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP || + !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP { + str := fmt.Sprintf("expect OP_2DROP OP_2DROP") + return nil, claimScriptError(ErrInvalidClaimUpdateScript, str) + } + + cs.Size = int(tokenizer.ByteIndex()) + return &cs, nil + + default: + return nil, claimScriptError(ErrNotClaimScript, "") + } +} + +// StripClaimScriptPrefix strips prefixed claim script, if any. +func StripClaimScriptPrefix(script []byte) []byte { + cs, err := ExtractClaimScript(script) + if err != nil { + return script + } + return script[cs.Size:] +} + +const illegalChars = "=&#:*$%?/;\\\b\n\t\r\x00" + +func AllClaimsAreSane(script []byte, enforceSoftFork bool) error { + cs, err := ExtractClaimScript(script) + if IsErrorCode(err, ErrNotClaimScript) { + return nil + } + if err != nil { + return err + } + if enforceSoftFork { + if !utf8.Valid(cs.Name) { + return fmt.Errorf("claim name is not valid UTF-8") + } + if bytes.ContainsAny(cs.Name, illegalChars) { + return fmt.Errorf("claim name has illegal chars; it should not contain any of these: %s", illegalChars) + } + } + + return nil +} diff --git a/txscript/claimscript_test.go b/txscript/claimscript_test.go new file mode 100644 index 00000000..ef2d2b02 --- /dev/null +++ b/txscript/claimscript_test.go @@ -0,0 +1,80 @@ +package txscript + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCreationParseLoopClaim(t *testing.T) { + + r := require.New(t) + + // OP_CLAIMNAME OP_2DROP OP_DROP + script, err := ClaimNameScript("tester", "value") + r.NoError(err) + cs, err := ExtractClaimScript(script) + r.NoError(err) + r.Equal(byte(OP_CLAIMNAME), cs.Opcode) + r.Equal([]byte("tester"), cs.Name) + r.Equal([]byte("value"), cs.Value) +} + +func TestCreationParseLoopUpdate(t *testing.T) { + + r := require.New(t) + + claimID := []byte("12345123451234512345") + claim, err := ClaimUpdateScript("tester", claimID, "value") + r.NoError(err) + cs, err := ExtractClaimScript(claim) + r.NoError(err) + r.Equal(byte(OP_UPDATECLAIM), cs.Opcode) + r.Equal([]byte("tester"), cs.Name) + r.Equal(claimID, cs.ClaimID) + r.Equal([]byte("value"), cs.Value) +} + +func TestCreationParseLoopSupport(t *testing.T) { + + r := require.New(t) + + claimID := []byte("12345123451234512345") + + // case 1: OP_SUPPORTCLAIM OP_2DROP OP_DROP + script, err := ClaimSupportScript("tester", claimID, nil) + r.NoError(err) + cs, err := ExtractClaimScript(script) + r.NoError(err) + + r.Equal(byte(OP_SUPPORTCLAIM), cs.Opcode) + r.Equal([]byte("tester"), cs.Name) + r.Equal(claimID, cs.ClaimID) + r.Nil(cs.Value) + + // case 2: OP_SUPPORTCLAIM OP_2DROP OP_2DROP + script, err = ClaimSupportScript("tester", claimID, []byte("value")) + r.NoError(err) + cs, err = ExtractClaimScript(script) + r.NoError(err) + + r.Equal(byte(OP_SUPPORTCLAIM), cs.Opcode) + r.Equal([]byte("tester"), cs.Name) + r.Equal(claimID, cs.ClaimID) + r.Equal([]byte("value"), cs.Value) + +} + +func TestInvalidChars(t *testing.T) { + r := require.New(t) + + script, err := ClaimNameScript("tester", "value") + r.NoError(err) + r.NoError(AllClaimsAreSane(script, true)) + + for i := range []byte(illegalChars) { + script, err := ClaimNameScript("a"+illegalChars[i:i+1], "value") + r.NoError(err) + r.Error(AllClaimsAreSane(script, true)) + } +} -- 2.45.2 From 2765ac72151c5b227ded9a72d3a7092b8fea8b0c Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Jun 2018 19:12:43 -0700 Subject: [PATCH 131/459] [lbry] txscript: recognize LBRY claim script OPCODES --- txscript/opcode.go | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 4c31be3f..4c00f353 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -220,9 +220,9 @@ const ( OP_CHECKSEQUENCEVERIFY = 0xb2 // 178 - AKA OP_NOP3 OP_NOP4 = 0xb3 // 179 OP_NOP5 = 0xb4 // 180 - OP_NOP6 = 0xb5 // 181 - OP_NOP7 = 0xb6 // 182 - OP_NOP8 = 0xb7 // 183 + OP_CLAIMNAME = 0xb5 // 181 - AKA OP_NOP6 + OP_SUPPORTCLAIM = 0xb6 // 182 - AKA OP_NOP7 + OP_UPDATECLAIM = 0xb7 // 183 - AKA OP_NOP8 OP_NOP9 = 0xb8 // 184 OP_NOP10 = 0xb9 // 185 OP_UNKNOWN186 = 0xba // 186 @@ -501,14 +501,14 @@ var opcodeArray = [256]opcode{ OP_CHECKMULTISIGVERIFY: {OP_CHECKMULTISIGVERIFY, "OP_CHECKMULTISIGVERIFY", 1, opcodeCheckMultiSigVerify}, // Reserved opcodes. - OP_NOP1: {OP_NOP1, "OP_NOP1", 1, opcodeNop}, - OP_NOP4: {OP_NOP4, "OP_NOP4", 1, opcodeNop}, - OP_NOP5: {OP_NOP5, "OP_NOP5", 1, opcodeNop}, - OP_NOP6: {OP_NOP6, "OP_NOP6", 1, opcodeNop}, - OP_NOP7: {OP_NOP7, "OP_NOP7", 1, opcodeNop}, - OP_NOP8: {OP_NOP8, "OP_NOP8", 1, opcodeNop}, - OP_NOP9: {OP_NOP9, "OP_NOP9", 1, opcodeNop}, - OP_NOP10: {OP_NOP10, "OP_NOP10", 1, opcodeNop}, + OP_NOP1: {OP_NOP1, "OP_NOP1", 1, opcodeNop}, + OP_NOP4: {OP_NOP4, "OP_NOP4", 1, opcodeNop}, + OP_NOP5: {OP_NOP5, "OP_NOP5", 1, opcodeNop}, + OP_CLAIMNAME: {OP_CLAIMNAME, "OP_CLAIMNAME", 1, opcodeClaimScript}, + OP_SUPPORTCLAIM: {OP_SUPPORTCLAIM, "OP_SUPPORTCLAIM", 1, opcodeClaimScript}, + OP_UPDATECLAIM: {OP_UPDATECLAIM, "OP_UPDATECLAIM", 1, opcodeClaimScript}, + OP_NOP9: {OP_NOP9, "OP_NOP9", 1, opcodeNop}, + OP_NOP10: {OP_NOP10, "OP_NOP10", 1, opcodeNop}, // Undefined opcodes. OP_UNKNOWN186: {OP_UNKNOWN186, "OP_UNKNOWN186", 1, opcodeInvalid}, @@ -725,8 +725,7 @@ func opcodeN(op *opcode, data []byte, vm *Engine) error { func opcodeNop(op *opcode, data []byte, vm *Engine) error { switch op.value { case OP_NOP1, OP_NOP4, OP_NOP5, - OP_NOP6, OP_NOP7, OP_NOP8, OP_NOP9, OP_NOP10: - + OP_NOP9, OP_NOP10: if vm.hasFlag(ScriptDiscourageUpgradableNops) { str := fmt.Sprintf("%v reserved for soft-fork "+ "upgrades", op.name) @@ -736,6 +735,11 @@ func opcodeNop(op *opcode, data []byte, vm *Engine) error { return nil } +func opcodeClaimScript(op *opcode, data []byte, vm *Engine) error { + vm.dstack.PushByteArray([]byte{0}) + return nil +} + // popIfBool enforces the "minimal if" policy during script execution if the // particular flag is set. If so, in order to eliminate an additional source // of nuisance malleability, post-segwit for version 0 witness programs, we now -- 2.45.2 From 62f2be328457ec90b13ccf1353186efe50c80f23 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 23 Jul 2021 12:13:31 -0400 Subject: [PATCH 132/459] [lbry] txscript: remove claim prefix for addr calculation --- txscript/standard.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/txscript/standard.go b/txscript/standard.go index 44902971..2437b3cc 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -906,6 +906,8 @@ func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address { // with an invalid script version error. func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, error) { + pkScript = StripClaimScriptPrefix(pkScript) + // Check for pay-to-pubkey-hash script. if hash := extractPubKeyHash(pkScript); hash != nil { return PubKeyHashTy, pubKeyHashToAddrs(hash, chainParams), 1, nil -- 2.45.2 From 3f0ec0f28abd15779b39c53d972c9b04cc03ca61 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 6 Jul 2021 19:38:44 -0700 Subject: [PATCH 133/459] [lbry] log: support claimtrie entries --- log.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/log.go b/log.go index 71accc7c..a69509cd 100644 --- a/log.go +++ b/log.go @@ -13,6 +13,7 @@ import ( "github.com/btcsuite/btcd/addrmgr" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/blockchain/indexers" + "github.com/btcsuite/btcd/claimtrie/node" "github.com/btcsuite/btcd/connmgr" "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcd/mempool" @@ -58,8 +59,9 @@ var ( amgrLog = backendLog.Logger("AMGR") cmgrLog = backendLog.Logger("CMGR") bcdbLog = backendLog.Logger("BCDB") - btcdLog = backendLog.Logger("BTCD") + btcdLog = backendLog.Logger("MAIN") chanLog = backendLog.Logger("CHAN") + lbryLog = backendLog.Logger("LBRY") discLog = backendLog.Logger("DISC") indxLog = backendLog.Logger("INDX") minrLog = backendLog.Logger("MINR") @@ -77,6 +79,7 @@ func init() { connmgr.UseLogger(cmgrLog) database.UseLogger(bcdbLog) blockchain.UseLogger(chanLog) + node.UseLogger(lbryLog) indexers.UseLogger(indxLog) mining.UseLogger(minrLog) cpuminer.UseLogger(minrLog) @@ -92,8 +95,9 @@ var subsystemLoggers = map[string]btclog.Logger{ "AMGR": amgrLog, "CMGR": cmgrLog, "BCDB": bcdbLog, - "BTCD": btcdLog, + "MAIN": btcdLog, "CHAN": chanLog, + "LBRY": lbryLog, "DISC": discLog, "INDX": indxLog, "MINR": minrLog, @@ -115,7 +119,7 @@ func initLogRotator(logFile string) { fmt.Fprintf(os.Stderr, "failed to create log directory: %v\n", err) os.Exit(1) } - r, err := rotator.New(logFile, 10*1024, false, 3) + r, err := rotator.New(logFile, 40*1024, false, 3) if err != nil { fmt.Fprintf(os.Stderr, "failed to create file rotator: %v\n", err) os.Exit(1) -- 2.45.2 From dadad3859a905a0b2e543952280cb2e1465b4eac Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 5 Aug 2018 13:59:25 -0700 Subject: [PATCH 134/459] [lbry] blockchain: connect to ClaimTrie Co-authored-by: Brannon King --- blockchain/chain.go | 96 ++++++++++++++++++++- blockchain/claimtrie.go | 183 ++++++++++++++++++++++++++++++++++++++++ btcd.go | 7 ++ server.go | 15 +++- 4 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 blockchain/claimtrie.go diff --git a/blockchain/chain.go b/blockchain/chain.go index 79bb3d74..8ffc4046 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -17,6 +17,8 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" + + "github.com/btcsuite/btcd/claimtrie" ) const ( @@ -180,6 +182,8 @@ type BlockChain struct { // certain blockchain events. notificationsLock sync.RWMutex notifications []NotificationCallback + + claimTrie *claimtrie.ClaimTrie } // HaveBlock returns whether or not the chain instance has the block represented @@ -571,7 +575,8 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, } // No warnings about unknown rules until the chain is current. - if b.isCurrent() { + current := b.isCurrent() + if current { // Warn if any unknown new rules are either about to activate or // have already been activated. if err := b.warnUnknownRuleActivations(node); err != nil { @@ -579,6 +584,13 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, } } + // Handle LBRY Claim Scripts + if b.claimTrie != nil { + if err := b.ParseClaimScripts(block, node, view, current); err != nil { + return ruleError(ErrBadClaimTrie, err.Error()) + } + } + // Write any block status changes to DB before updating best state. err := b.index.flushToDB() if err != nil { @@ -761,6 +773,12 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view return err } + if b.claimTrie != nil { + if err = b.claimTrie.ResetHeight(node.parent.height); err != nil { + return err + } + } + // Prune fully spent entries and mark all entries in the view unmodified // now that the modifications have been committed to the database. view.commit() @@ -1614,6 +1632,11 @@ func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Has return headers } +// ClaimTrie returns the claimTrie associated wit hthe chain. +func (b *BlockChain) ClaimTrie() *claimtrie.ClaimTrie { + return b.claimTrie +} + // IndexManager provides a generic interface that the is called when blocks are // connected and disconnected to and from the tip of the main chain for the // purpose of supporting optional indexes. @@ -1700,6 +1723,8 @@ type Config struct { // This field can be nil if the caller is not interested in using a // signature cache. HashCache *txscript.HashCache + + ClaimTrie *claimtrie.ClaimTrie } // New returns a BlockChain instance using the provided configuration details. @@ -1754,6 +1779,7 @@ func New(config *Config) (*BlockChain, error) { prevOrphans: make(map[chainhash.Hash][]*orphanBlock), warningCaches: newThresholdCaches(vbNumBits), deploymentCaches: newThresholdCaches(chaincfg.DefinedDeployments), + claimTrie: config.ClaimTrie, } // Initialize the chain state from the passed database. When the db @@ -1796,6 +1822,14 @@ func New(config *Config) (*BlockChain, error) { return nil, err } + if b.claimTrie != nil { + err := rebuildMissingClaimTrieData(&b, config.Interrupt) + if err != nil { + b.claimTrie.Close() + return nil, err + } + } + bestNode := b.bestChain.Tip() log.Infof("Chain state (height %d, hash %v, totaltx %d, work %v)", bestNode.height, bestNode.hash, b.stateSnapshot.TotalTxns, @@ -1803,3 +1837,63 @@ func New(config *Config) (*BlockChain, error) { return &b, nil } + +func rebuildMissingClaimTrieData(b *BlockChain, done <-chan struct{}) error { + target := b.bestChain.Height() + if b.claimTrie.Height() == target { + return nil + } + if b.claimTrie.Height() > target { + return b.claimTrie.ResetHeight(target) + } + + start := time.Now() + lastReport := time.Now() + // TODO: move this view inside the loop (or recreate it every 5 sec.) + // as accumulating all inputs has potential to use a huge amount of RAM + // but we need to get the spent inputs working for that to be possible + view := NewUtxoViewpoint() + for h := int32(0); h < target; h++ { + select { + case <-done: + return fmt.Errorf("rebuild unfinished at height %d", b.claimTrie.Height()) + default: + } + + n := b.bestChain.NodeByHeight(h + 1) + + var block *btcutil.Block + err := b.db.View(func(dbTx database.Tx) error { + var err error + block, err = dbFetchBlockByNode(dbTx, n) + return err + }) + if err != nil { + return err + } + + err = view.fetchInputUtxos(b.db, block) + if err != nil { + return err + } + + err = view.connectTransactions(block, nil) + if err != nil { + return err + } + + if h >= b.claimTrie.Height() { + err = b.ParseClaimScripts(block, n, view, false) + if err != nil { + return err + } + } + if time.Since(lastReport) > time.Second*5 { + lastReport = time.Now() + log.Infof("Rebuilding claim trie data to %d. At: %d", target, h) + } + } + log.Infof("Completed rebuilding claim trie data to %d. Took %s ", + b.claimTrie.Height(), time.Since(start)) + return nil +} diff --git a/blockchain/claimtrie.go b/blockchain/claimtrie.go new file mode 100644 index 00000000..de349b3d --- /dev/null +++ b/blockchain/claimtrie.go @@ -0,0 +1,183 @@ +package blockchain + +import ( + "bytes" + "fmt" + + "github.com/pkg/errors" + + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" + + "github.com/btcsuite/btcd/claimtrie" + "github.com/btcsuite/btcd/claimtrie/change" + "github.com/btcsuite/btcd/claimtrie/node" + "github.com/btcsuite/btcd/claimtrie/normalization" +) + +func (b *BlockChain) SetClaimtrieHeader(block *btcutil.Block, view *UtxoViewpoint) error { + b.chainLock.Lock() + defer b.chainLock.Unlock() + + err := b.ParseClaimScripts(block, nil, view, false) + if err != nil { + return errors.Wrapf(err, "in parse claim scripts") + } + + block.MsgBlock().Header.ClaimTrie = *b.claimTrie.MerkleHash() + err = b.claimTrie.ResetHeight(b.claimTrie.Height() - 1) + + return errors.Wrapf(err, "in reset height") +} + +func (b *BlockChain) ParseClaimScripts(block *btcutil.Block, bn *blockNode, view *UtxoViewpoint, shouldFlush bool) error { + ht := block.Height() + + for _, tx := range block.Transactions() { + h := handler{ht, tx, view, map[string][]byte{}} + if err := h.handleTxIns(b.claimTrie); err != nil { + return err + } + if err := h.handleTxOuts(b.claimTrie); err != nil { + return err + } + } + + err := b.claimTrie.AppendBlock() + if err != nil { + return errors.Wrapf(err, "in append block") + } + + if shouldFlush { + b.claimTrie.FlushToDisk() + } + + hash := b.claimTrie.MerkleHash() + if bn != nil && bn.claimTrie != *hash { + // undo our AppendBlock call as we've decided that our interpretation of the block data is incorrect, + // or that the person who made the block assembled the pieces incorrectly. + _ = b.claimTrie.ResetHeight(b.claimTrie.Height() - 1) + return errors.Errorf("height: %d, computed hash: %s != header's ClaimTrie: %s", ht, *hash, bn.claimTrie) + } + return nil +} + +type handler struct { + ht int32 + tx *btcutil.Tx + view *UtxoViewpoint + spent map[string][]byte +} + +func (h *handler) handleTxIns(ct *claimtrie.ClaimTrie) error { + if IsCoinBase(h.tx) { + return nil + } + for _, txIn := range h.tx.MsgTx().TxIn { + op := txIn.PreviousOutPoint + e := h.view.LookupEntry(op) + if e == nil { + return errors.Errorf("missing input in view for %s", op.String()) + } + cs, err := txscript.ExtractClaimScript(e.pkScript) + if txscript.IsErrorCode(err, txscript.ErrNotClaimScript) { + continue + } + if err != nil { + return err + } + + var id change.ClaimID + name := cs.Name // name of the previous one (that we're now spending) + + switch cs.Opcode { + case txscript.OP_CLAIMNAME: // OP code from previous transaction + id = change.NewClaimID(op) // claimID of the previous item now being spent + h.spent[id.Key()] = normalization.NormalizeIfNecessary(name, ct.Height()) + err = ct.SpendClaim(name, op, id) + case txscript.OP_UPDATECLAIM: + copy(id[:], cs.ClaimID) + h.spent[id.Key()] = normalization.NormalizeIfNecessary(name, ct.Height()) + err = ct.SpendClaim(name, op, id) + case txscript.OP_SUPPORTCLAIM: + copy(id[:], cs.ClaimID) + err = ct.SpendSupport(name, op, id) + } + if err != nil { + return errors.Wrapf(err, "handleTxIns") + } + } + return nil +} + +func (h *handler) handleTxOuts(ct *claimtrie.ClaimTrie) error { + for i, txOut := range h.tx.MsgTx().TxOut { + op := *wire.NewOutPoint(h.tx.Hash(), uint32(i)) + cs, err := txscript.ExtractClaimScript(txOut.PkScript) + if txscript.IsErrorCode(err, txscript.ErrNotClaimScript) { + continue + } + if err != nil { + return err + } + + var id change.ClaimID + name := cs.Name + amt := txOut.Value + + switch cs.Opcode { + case txscript.OP_CLAIMNAME: + id = change.NewClaimID(op) + err = ct.AddClaim(name, op, id, amt) + case txscript.OP_SUPPORTCLAIM: + copy(id[:], cs.ClaimID) + err = ct.AddSupport(name, op, amt, id) + case txscript.OP_UPDATECLAIM: + // old code wouldn't run the update if name or claimID didn't match existing data + // that was a safety feature, but it should have rejected the transaction instead + // TODO: reject transactions with invalid update commands + copy(id[:], cs.ClaimID) + normName := normalization.NormalizeIfNecessary(name, ct.Height()) + if !bytes.Equal(h.spent[id.Key()], normName) { + node.LogOnce(fmt.Sprintf("Invalid update operation: name or ID mismatch at %d for: %s, %s", + ct.Height(), normName, id.String())) + continue + } + + delete(h.spent, id.Key()) + err = ct.UpdateClaim(name, op, amt, id) + } + if err != nil { + return errors.Wrapf(err, "handleTxOuts") + } + } + return nil +} + +func (b *BlockChain) GetNamesChangedInBlock(height int32) ([]string, error) { + b.chainLock.RLock() + defer b.chainLock.RUnlock() + + return b.claimTrie.NamesChangedInBlock(height) +} + +func (b *BlockChain) GetClaimsForName(height int32, name string) (string, *node.Node, error) { + + normalizedName := normalization.NormalizeIfNecessary([]byte(name), height) + + b.chainLock.RLock() + defer b.chainLock.RUnlock() + + n, err := b.claimTrie.NodeAt(height, normalizedName) + if err != nil { + return string(normalizedName), nil, err + } + + if n == nil { + return string(normalizedName), nil, fmt.Errorf("name does not exist at height %d: %s", height, name) + } + + n.SortClaimsByBid() + return string(normalizedName), n, nil +} diff --git a/btcd.go b/btcd.go index b93851ba..4f04657b 100644 --- a/btcd.go +++ b/btcd.go @@ -16,6 +16,7 @@ import ( "runtime/pprof" "github.com/btcsuite/btcd/blockchain/indexers" + "github.com/btcsuite/btcd/claimtrie/param" "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcd/limits" @@ -147,6 +148,8 @@ func btcdMain(serverChan chan<- *server) error { return nil } + param.SetNetwork(activeNetParams.Params.Net) // prep the claimtrie params + // Create server and start it. server, err := newServer(cfg.Listeners, cfg.AgentBlacklist, cfg.AgentWhitelist, db, activeNetParams.Params, interrupt) @@ -161,6 +164,10 @@ func btcdMain(serverChan chan<- *server) error { server.Stop() server.WaitForShutdown() srvrLog.Infof("Server shutdown complete") + // TODO: tie into the sync manager for shutdown instead + if ct := server.chain.ClaimTrie(); ct != nil { + ct.Close() + } }() server.Start() if serverChan != nil { diff --git a/server.go b/server.go index c5fc4aff..f550ec8d 100644 --- a/server.go +++ b/server.go @@ -27,6 +27,8 @@ import ( "github.com/btcsuite/btcd/blockchain/indexers" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/claimtrie" + claimtrieconfig "github.com/btcsuite/btcd/claimtrie/config" "github.com/btcsuite/btcd/connmgr" "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcd/mempool" @@ -2728,8 +2730,18 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, checkpoints = mergeCheckpoints(s.chainParams.Checkpoints, cfg.addCheckpoints) } - // Create a new block chain instance with the appropriate configuration. var err error + + claimTrieCfg := claimtrieconfig.DefaultConfig + claimTrieCfg.DataDir = cfg.DataDir + claimTrieCfg.Interrupt = interrupt + + ct, err := claimtrie.New(claimTrieCfg) + if err != nil { + return nil, err + } + + // Create a new block chain instance with the appropriate configuration. s.chain, err = blockchain.New(&blockchain.Config{ DB: s.db, Interrupt: interrupt, @@ -2739,6 +2751,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, SigCache: s.sigCache, IndexManager: indexManager, HashCache: s.hashCache, + ClaimTrie: ct, }) if err != nil { return nil, err -- 2.45.2 From 28a5e6fc6576993b1126035ccac48f8324072a3b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Oct 2021 22:45:32 -0700 Subject: [PATCH 135/459] [lbry] rename btcd to lbcd Co-authored-by: Brannon King --- addrmgr/addrmanager.go | 4 +- addrmgr/addrmanager_internal_test.go | 2 +- addrmgr/addrmanager_test.go | 4 +- addrmgr/internal_test.go | 2 +- addrmgr/knownaddress.go | 2 +- addrmgr/knownaddress_test.go | 4 +- addrmgr/network.go | 2 +- addrmgr/network_test.go | 4 +- blockchain/accept.go | 4 +- blockchain/blockindex.go | 8 ++-- blockchain/chain.go | 14 +++---- blockchain/chain_test.go | 8 ++-- blockchain/chainio.go | 8 ++-- blockchain/chainio_test.go | 4 +- blockchain/chainview_test.go | 2 +- blockchain/checkpoints.go | 8 ++-- blockchain/claimtrie.go | 14 +++---- blockchain/common_test.go | 14 +++---- blockchain/compress.go | 4 +- blockchain/difficulty.go | 2 +- blockchain/example_test.go | 10 ++--- blockchain/fullblocks_test.go | 18 ++++----- blockchain/fullblocktests/generate.go | 14 +++---- blockchain/fullblocktests/params.go | 6 +-- blockchain/indexers/addrindex.go | 14 +++---- blockchain/indexers/addrindex_test.go | 2 +- blockchain/indexers/blocklogger.go | 2 +- blockchain/indexers/cfindex.go | 16 ++++---- blockchain/indexers/common.go | 6 +-- blockchain/indexers/manager.go | 10 ++--- blockchain/indexers/txindex.go | 10 ++--- blockchain/mediantime.go | 2 +- blockchain/merkle.go | 6 +-- blockchain/process.go | 6 +-- blockchain/scriptval.go | 6 +-- blockchain/scriptval_test.go | 2 +- blockchain/thresholdstate.go | 2 +- blockchain/thresholdstate_test.go | 2 +- blockchain/upgrade.go | 6 +-- blockchain/utxoviewpoint.go | 10 ++--- blockchain/validate.go | 10 ++--- blockchain/validate_test.go | 9 +++-- blockchain/versionbits.go | 2 +- blockchain/weight.go | 6 +-- btcec/example_test.go | 4 +- btcec/genprecomps.go | 2 +- btcjson/btcdextcmds_test.go | 2 +- btcjson/btcdextresults_test.go | 2 +- btcjson/btcwalletextcmds_test.go | 2 +- btcjson/chainsvrcmds.go | 2 +- btcjson/chainsvrcmds_test.go | 4 +- btcjson/chainsvrresults.go | 6 +-- btcjson/chainsvrresults_test.go | 6 +-- btcjson/chainsvrwscmds_test.go | 2 +- btcjson/chainsvrwsntfns_test.go | 2 +- btcjson/chainsvrwsresults_test.go | 2 +- btcjson/cmdinfo_test.go | 2 +- btcjson/cmdparse_test.go | 2 +- btcjson/error_test.go | 2 +- btcjson/example_test.go | 2 +- btcjson/help_test.go | 2 +- btcjson/helpers_test.go | 2 +- btcjson/jsonrpc_test.go | 2 +- btcjson/register_test.go | 2 +- btcjson/walletsvrcmds.go | 2 +- btcjson/walletsvrcmds_test.go | 4 +- btcjson/walletsvrresults.go | 2 +- btcjson/walletsvrresults_test.go | 2 +- btcjson/walletsvrwscmds_test.go | 2 +- btcjson/walletsvrwsntfns_test.go | 2 +- chaincfg/doc.go | 4 +- chaincfg/genesis.go | 4 +- chaincfg/params.go | 4 +- chaincfg/register_test.go | 2 +- cmd/addblock/addblock.go | 8 ++-- cmd/addblock/config.go | 16 ++++---- cmd/addblock/import.go | 12 +++--- cmd/findcheckpoint/config.go | 16 ++++---- cmd/findcheckpoint/findcheckpoint.go | 8 ++-- cmd/gencerts/gencerts.go | 2 +- cmd/{btcctl => lbcctl}/config.go | 20 +++++----- cmd/{btcctl => lbcctl}/httpclient.go | 2 +- cmd/{btcctl/btcctl.go => lbcctl/lbcctl.go} | 2 +- cmd/{btcctl => lbcctl}/version.go | 2 +- config.go | 38 +++++++++---------- config_test.go | 8 ++-- connmgr/seed.go | 4 +- database/cmd/dbtool/fetchblock.go | 4 +- database/cmd/dbtool/fetchblockregion.go | 4 +- database/cmd/dbtool/globalconfig.go | 16 ++++---- database/cmd/dbtool/insecureimport.go | 8 ++-- database/cmd/dbtool/loadheaders.go | 4 +- database/cmd/dbtool/main.go | 2 +- database/driver_test.go | 4 +- database/error_test.go | 2 +- database/example_test.go | 24 ++++++------ database/ffldb/bench_test.go | 6 +-- database/ffldb/blockio.go | 6 +-- database/ffldb/db.go | 10 ++--- database/ffldb/dbcache.go | 2 +- database/ffldb/doc.go | 2 +- database/ffldb/driver.go | 4 +- database/ffldb/driver_test.go | 8 ++-- database/ffldb/export_test.go | 2 +- database/ffldb/interface_test.go | 9 ++--- database/ffldb/ldbtreapiter.go | 2 +- database/ffldb/reconcile.go | 2 +- database/ffldb/whitebox_test.go | 7 ++-- database/interface.go | 4 +- doc.go | 10 ++--- docs/conf.py | 10 +++-- integration/bip0009_test.go | 8 ++-- integration/csv_fork_test.go | 16 ++++---- integration/rpcserver_test.go | 8 ++-- integration/rpctest/blockgen.go | 14 +++---- integration/rpctest/btcd.go | 6 +-- integration/rpctest/memwallet.go | 18 ++++----- integration/rpctest/node.go | 6 +-- integration/rpctest/rpc_harness.go | 12 +++--- integration/rpctest/rpc_harness_test.go | 10 ++--- integration/rpctest/utils.go | 4 +- btcd.go => lbcd.go | 8 ++-- log.go | 24 ++++++------ mempool/error.go | 4 +- mempool/estimatefee.go | 6 +-- mempool/estimatefee_test.go | 8 ++-- mempool/mempool.go | 18 ++++----- mempool/mempool_test.go | 14 +++---- mempool/policy.go | 9 +++-- mempool/policy_test.go | 12 +++--- mining/cpuminer/cpuminer.go | 12 +++--- mining/mining.go | 14 +++---- mining/mining_test.go | 2 +- mining/policy.go | 6 +-- mining/policy_test.go | 8 ++-- netsync/blocklogger.go | 2 +- netsync/interface.go | 14 +++---- netsync/manager.go | 16 ++++---- params.go | 4 +- peer/doc.go | 2 +- peer/example_test.go | 6 +-- peer/log.go | 6 +-- peer/peer.go | 8 ++-- peer/peer_test.go | 8 ++-- rpcadapters.go | 14 +++---- rpcclient/chain.go | 6 +-- rpcclient/doc.go | 2 +- rpcclient/example_test.go | 3 +- rpcclient/examples/bitcoincorehttp/main.go | 2 +- .../examples/bitcoincorehttpbulk/main.go | 2 +- rpcclient/examples/btcdwebsockets/main.go | 8 ++-- .../examples/btcwalletwebsockets/main.go | 8 ++-- rpcclient/extensions.go | 8 ++-- rpcclient/infrastructure.go | 16 ++++---- rpcclient/mining.go | 6 +-- rpcclient/net.go | 2 +- rpcclient/notify.go | 10 ++--- rpcclient/rawrequest.go | 2 +- rpcclient/rawtransactions.go | 8 ++-- rpcclient/wallet.go | 10 ++--- rpcserverhelp.go | 28 +++++++------- rpcwebsocket.go | 16 ++++---- server.go | 38 +++++++++---------- txscript/bench_test.go | 4 +- txscript/engine.go | 4 +- txscript/engine_test.go | 4 +- txscript/example_test.go | 12 +++--- txscript/hashcache.go | 4 +- txscript/hashcache_test.go | 2 +- txscript/opcode.go | 6 +-- txscript/pkscript.go | 8 ++-- txscript/pkscript_test.go | 2 +- txscript/reference_test.go | 6 +-- txscript/script.go | 4 +- txscript/script_test.go | 2 +- txscript/sigcache.go | 4 +- txscript/sigcache_test.go | 4 +- txscript/sign.go | 8 ++-- txscript/sign_test.go | 10 ++--- txscript/standard.go | 6 +-- txscript/standard_test.go | 6 +-- upgrade.go | 10 ++--- wire/bench_test.go | 2 +- wire/blockheader.go | 4 +- wire/common.go | 2 +- wire/common_test.go | 2 +- wire/invvect.go | 2 +- wire/invvect_test.go | 2 +- wire/message.go | 2 +- wire/message_test.go | 2 +- wire/msgblock.go | 2 +- wire/msgblock_test.go | 2 +- wire/msgcfcheckpt.go | 2 +- wire/msgcfheaders.go | 2 +- wire/msgcfilter.go | 2 +- wire/msggetblocks.go | 2 +- wire/msggetblocks_test.go | 2 +- wire/msggetcfcheckpt.go | 2 +- wire/msggetcfheaders.go | 2 +- wire/msggetcfilters.go | 2 +- wire/msggetdata_test.go | 2 +- wire/msggetheaders.go | 2 +- wire/msggetheaders_test.go | 2 +- wire/msginv_test.go | 2 +- wire/msgmerkleblock.go | 2 +- wire/msgmerkleblock_test.go | 2 +- wire/msgnotfound_test.go | 2 +- wire/msgreject.go | 2 +- wire/msgtx.go | 2 +- wire/msgtx_test.go | 2 +- 210 files changed, 666 insertions(+), 661 deletions(-) rename cmd/{btcctl => lbcctl}/config.go (95%) rename cmd/{btcctl => lbcctl}/httpclient.go (98%) rename cmd/{btcctl/btcctl.go => lbcctl/lbcctl.go} (99%) rename cmd/{btcctl => lbcctl}/version.go (99%) rename btcd.go => lbcd.go (98%) diff --git a/addrmgr/addrmanager.go b/addrmgr/addrmanager.go index 4c737b93..b7730671 100644 --- a/addrmgr/addrmanager.go +++ b/addrmgr/addrmanager.go @@ -23,8 +23,8 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // AddrManager provides a concurrency safe address manager for caching potential diff --git a/addrmgr/addrmanager_internal_test.go b/addrmgr/addrmanager_internal_test.go index 1c19dceb..b2f5f3d1 100644 --- a/addrmgr/addrmanager_internal_test.go +++ b/addrmgr/addrmanager_internal_test.go @@ -7,7 +7,7 @@ import ( "os" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // randAddr generates a *wire.NetAddress backed by a random IPv4/IPv6 address. diff --git a/addrmgr/addrmanager_test.go b/addrmgr/addrmanager_test.go index 676913e2..d623479c 100644 --- a/addrmgr/addrmanager_test.go +++ b/addrmgr/addrmanager_test.go @@ -12,8 +12,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/wire" ) // naTest is used to describe a test to be performed against the NetAddressKey diff --git a/addrmgr/internal_test.go b/addrmgr/internal_test.go index e50e923c..b7c650c7 100644 --- a/addrmgr/internal_test.go +++ b/addrmgr/internal_test.go @@ -7,7 +7,7 @@ package addrmgr import ( "time" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) func TstKnownAddressIsBad(ka *KnownAddress) bool { diff --git a/addrmgr/knownaddress.go b/addrmgr/knownaddress.go index 5a7674f4..59db5584 100644 --- a/addrmgr/knownaddress.go +++ b/addrmgr/knownaddress.go @@ -8,7 +8,7 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // KnownAddress tracks information about a known network address that is used diff --git a/addrmgr/knownaddress_test.go b/addrmgr/knownaddress_test.go index a289d5a3..fc882667 100644 --- a/addrmgr/knownaddress_test.go +++ b/addrmgr/knownaddress_test.go @@ -9,8 +9,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/wire" ) func TestChance(t *testing.T) { diff --git a/addrmgr/network.go b/addrmgr/network.go index 51bfa3ed..878bc2b1 100644 --- a/addrmgr/network.go +++ b/addrmgr/network.go @@ -8,7 +8,7 @@ import ( "fmt" "net" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) var ( diff --git a/addrmgr/network_test.go b/addrmgr/network_test.go index 8af3369f..6f2565fe 100644 --- a/addrmgr/network_test.go +++ b/addrmgr/network_test.go @@ -8,8 +8,8 @@ import ( "net" "testing" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/wire" ) // TestIPTypes ensures the various functions which determine the type of an IP diff --git a/blockchain/accept.go b/blockchain/accept.go index f85d6558..6acba30d 100644 --- a/blockchain/accept.go +++ b/blockchain/accept.go @@ -7,8 +7,8 @@ package blockchain import ( "fmt" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/database" + btcutil "github.com/lbryio/lbcutil" ) // maybeAcceptBlock potentially accepts a block into the block chain and, if diff --git a/blockchain/blockindex.go b/blockchain/blockindex.go index 1531e6b1..eb7c01a7 100644 --- a/blockchain/blockindex.go +++ b/blockchain/blockindex.go @@ -10,10 +10,10 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) // blockStatus is a bit field representing the validation state of the block. diff --git a/blockchain/chain.go b/blockchain/chain.go index 8ffc4046..a0bfac6c 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -11,14 +11,14 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" - "github.com/btcsuite/btcd/claimtrie" + "github.com/lbryio/lbcd/claimtrie" ) const ( diff --git a/blockchain/chain_test.go b/blockchain/chain_test.go index 7de323bc..b2a155bc 100644 --- a/blockchain/chain_test.go +++ b/blockchain/chain_test.go @@ -9,10 +9,10 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // TestHaveBlock tests the HaveBlock API to ensure proper functionality. diff --git a/blockchain/chainio.go b/blockchain/chainio.go index f40ba465..ae83dc64 100644 --- a/blockchain/chainio.go +++ b/blockchain/chainio.go @@ -12,10 +12,10 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/chainio_test.go b/blockchain/chainio_test.go index 630af14e..76881a33 100644 --- a/blockchain/chainio_test.go +++ b/blockchain/chainio_test.go @@ -11,8 +11,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) // TestErrNotInMainChain ensures the functions related to errNotInMainChain work diff --git a/blockchain/chainview_test.go b/blockchain/chainview_test.go index c59004fd..746bf1bd 100644 --- a/blockchain/chainview_test.go +++ b/blockchain/chainview_test.go @@ -10,7 +10,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // testNoncePrng provides a deterministic prng for the nonce in generated fake diff --git a/blockchain/checkpoints.go b/blockchain/checkpoints.go index af3b6d92..a82d70dd 100644 --- a/blockchain/checkpoints.go +++ b/blockchain/checkpoints.go @@ -8,10 +8,10 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + btcutil "github.com/lbryio/lbcutil" ) // CheckpointConfirmations is the number of blocks before the end of the current diff --git a/blockchain/claimtrie.go b/blockchain/claimtrie.go index de349b3d..b9913203 100644 --- a/blockchain/claimtrie.go +++ b/blockchain/claimtrie.go @@ -6,14 +6,14 @@ import ( "github.com/pkg/errors" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" - "github.com/btcsuite/btcd/claimtrie" - "github.com/btcsuite/btcd/claimtrie/change" - "github.com/btcsuite/btcd/claimtrie/node" - "github.com/btcsuite/btcd/claimtrie/normalization" + "github.com/lbryio/lbcd/claimtrie" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/claimtrie/normalization" ) func (b *BlockChain) SetClaimtrieHeader(block *btcutil.Block, view *UtxoViewpoint) error { diff --git a/blockchain/common_test.go b/blockchain/common_test.go index dd392a66..16ad6756 100644 --- a/blockchain/common_test.go +++ b/blockchain/common_test.go @@ -14,13 +14,13 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/compress.go b/blockchain/compress.go index 611b9f09..70aab39b 100644 --- a/blockchain/compress.go +++ b/blockchain/compress.go @@ -5,8 +5,8 @@ package blockchain import ( - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/txscript" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/txscript" ) // ----------------------------------------------------------------------------- diff --git a/blockchain/difficulty.go b/blockchain/difficulty.go index 3eae3844..2f16e2e5 100644 --- a/blockchain/difficulty.go +++ b/blockchain/difficulty.go @@ -8,7 +8,7 @@ import ( "math/big" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) var ( diff --git a/blockchain/example_test.go b/blockchain/example_test.go index 691d0927..da0cce79 100644 --- a/blockchain/example_test.go +++ b/blockchain/example_test.go @@ -10,11 +10,11 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + btcutil "github.com/lbryio/lbcutil" ) // This example demonstrates how to create a new chain instance and use diff --git a/blockchain/fullblocks_test.go b/blockchain/fullblocks_test.go index 3ae0d0eb..4c45c099 100644 --- a/blockchain/fullblocks_test.go +++ b/blockchain/fullblocks_test.go @@ -12,15 +12,15 @@ import ( "path/filepath" "testing" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/fullblocktests" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/fullblocktests" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index 592a14de..dc182a90 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -18,13 +18,13 @@ import ( "runtime" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/fullblocktests/params.go b/blockchain/fullblocktests/params.go index 4679036f..fa23e841 100644 --- a/blockchain/fullblocktests/params.go +++ b/blockchain/fullblocktests/params.go @@ -9,9 +9,9 @@ import ( "math/big" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // newHashFromStr converts the passed big-endian hex string into a diff --git a/blockchain/indexers/addrindex.go b/blockchain/indexers/addrindex.go index 4a9bf4ec..3ac3924a 100644 --- a/blockchain/indexers/addrindex.go +++ b/blockchain/indexers/addrindex.go @@ -9,13 +9,13 @@ import ( "fmt" "sync" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/indexers/addrindex_test.go b/blockchain/indexers/addrindex_test.go index e545887f..584ed1cc 100644 --- a/blockchain/indexers/addrindex_test.go +++ b/blockchain/indexers/addrindex_test.go @@ -9,7 +9,7 @@ import ( "fmt" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // addrIndexBucket provides a mock address index database bucket by implementing diff --git a/blockchain/indexers/blocklogger.go b/blockchain/indexers/blocklogger.go index 88d6f269..845618e7 100644 --- a/blockchain/indexers/blocklogger.go +++ b/blockchain/indexers/blocklogger.go @@ -9,7 +9,7 @@ import ( "time" "github.com/btcsuite/btclog" - "github.com/btcsuite/btcutil" + btcutil "github.com/lbryio/lbcutil" ) // blockProgressLogger provides periodic logging for other services in order diff --git a/blockchain/indexers/cfindex.go b/blockchain/indexers/cfindex.go index 8ea14728..881d3a30 100644 --- a/blockchain/indexers/cfindex.go +++ b/blockchain/indexers/cfindex.go @@ -7,14 +7,14 @@ package indexers import ( "errors" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" - "github.com/btcsuite/btcutil/gcs" - "github.com/btcsuite/btcutil/gcs/builder" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" + "github.com/lbryio/lbcutil/gcs" + "github.com/lbryio/lbcutil/gcs/builder" ) const ( diff --git a/blockchain/indexers/common.go b/blockchain/indexers/common.go index a912bb4c..57971d8b 100644 --- a/blockchain/indexers/common.go +++ b/blockchain/indexers/common.go @@ -11,9 +11,9 @@ import ( "encoding/binary" "errors" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/database" + btcutil "github.com/lbryio/lbcutil" ) var ( diff --git a/blockchain/indexers/manager.go b/blockchain/indexers/manager.go index bc0804f8..7c0bb0e1 100644 --- a/blockchain/indexers/manager.go +++ b/blockchain/indexers/manager.go @@ -8,11 +8,11 @@ import ( "bytes" "fmt" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( diff --git a/blockchain/indexers/txindex.go b/blockchain/indexers/txindex.go index 00cfd006..96b3edcb 100644 --- a/blockchain/indexers/txindex.go +++ b/blockchain/indexers/txindex.go @@ -8,11 +8,11 @@ import ( "errors" "fmt" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/mediantime.go b/blockchain/mediantime.go index f9c15a23..bb85b646 100644 --- a/blockchain/mediantime.go +++ b/blockchain/mediantime.go @@ -183,7 +183,7 @@ func (m *medianTime) AddTimeSample(sourceID string, timeVal time.Time) { // Warn if none of the time samples are close. if !remoteHasCloseTime { log.Warnf("Please check your date and time " + - "are correct! btcd will not work " + + "are correct! lbcd will not work " + "properly with an invalid time") } } diff --git a/blockchain/merkle.go b/blockchain/merkle.go index 8f3f6b97..29479c1d 100644 --- a/blockchain/merkle.go +++ b/blockchain/merkle.go @@ -9,9 +9,9 @@ import ( "fmt" "math" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/process.go b/blockchain/process.go index 6d2161bb..a48b6e50 100644 --- a/blockchain/process.go +++ b/blockchain/process.go @@ -8,9 +8,9 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + btcutil "github.com/lbryio/lbcutil" ) // BehaviorFlags is a bitmask defining tweaks to the normal behavior when diff --git a/blockchain/scriptval.go b/blockchain/scriptval.go index 8ba59a42..97bf0ece 100644 --- a/blockchain/scriptval.go +++ b/blockchain/scriptval.go @@ -10,9 +10,9 @@ import ( "runtime" "time" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // txValidateItem holds a transaction along with which input to validate. diff --git a/blockchain/scriptval_test.go b/blockchain/scriptval_test.go index 031f0480..62d97362 100644 --- a/blockchain/scriptval_test.go +++ b/blockchain/scriptval_test.go @@ -8,7 +8,7 @@ import ( "fmt" "testing" - "github.com/btcsuite/btcd/txscript" + "github.com/lbryio/lbcd/txscript" ) // TestCheckBlockScripts ensures that validating the all of the scripts in a diff --git a/blockchain/thresholdstate.go b/blockchain/thresholdstate.go index 8a79f968..ac652eff 100644 --- a/blockchain/thresholdstate.go +++ b/blockchain/thresholdstate.go @@ -7,7 +7,7 @@ package blockchain import ( "fmt" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // ThresholdState define the various threshold states used when voting on diff --git a/blockchain/thresholdstate_test.go b/blockchain/thresholdstate_test.go index c65f5a44..5eecc61e 100644 --- a/blockchain/thresholdstate_test.go +++ b/blockchain/thresholdstate_test.go @@ -7,7 +7,7 @@ package blockchain import ( "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestThresholdStateStringer tests the stringized output for the diff --git a/blockchain/upgrade.go b/blockchain/upgrade.go index 253ca62e..a899cb4e 100644 --- a/blockchain/upgrade.go +++ b/blockchain/upgrade.go @@ -11,9 +11,9 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/blockchain/utxoviewpoint.go b/blockchain/utxoviewpoint.go index b8576581..60d48df0 100644 --- a/blockchain/utxoviewpoint.go +++ b/blockchain/utxoviewpoint.go @@ -7,11 +7,11 @@ package blockchain import ( "fmt" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // txoFlags is a bitmask defining additional information and state for a diff --git a/blockchain/validate.go b/blockchain/validate.go index ef2c283b..19183aa9 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -11,11 +11,11 @@ import ( "math/big" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/validate_test.go b/blockchain/validate_test.go index 9bf2ff42..6298ad06 100644 --- a/blockchain/validate_test.go +++ b/blockchain/validate_test.go @@ -5,15 +5,16 @@ package blockchain import ( + "encoding/hex" "math" "reflect" "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // TestSequenceLocksActive tests the SequenceLockActive function to ensure it diff --git a/blockchain/versionbits.go b/blockchain/versionbits.go index acdbf144..ddf1cace 100644 --- a/blockchain/versionbits.go +++ b/blockchain/versionbits.go @@ -7,7 +7,7 @@ package blockchain import ( "math" - "github.com/btcsuite/btcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg" ) const ( diff --git a/blockchain/weight.go b/blockchain/weight.go index e23dd87d..9a3a10b3 100644 --- a/blockchain/weight.go +++ b/blockchain/weight.go @@ -7,9 +7,9 @@ package blockchain import ( "fmt" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/btcec/example_test.go b/btcec/example_test.go index ca51ee87..cea8d771 100644 --- a/btcec/example_test.go +++ b/btcec/example_test.go @@ -8,8 +8,8 @@ import ( "encoding/hex" "fmt" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // This example demonstrates signing a message with a secp256k1 private key that diff --git a/btcec/genprecomps.go b/btcec/genprecomps.go index d4a9c1b8..f09ab311 100644 --- a/btcec/genprecomps.go +++ b/btcec/genprecomps.go @@ -17,7 +17,7 @@ import ( "log" "os" - "github.com/btcsuite/btcd/btcec" + "github.com/lbryio/lbcd/btcec" ) func main() { diff --git a/btcjson/btcdextcmds_test.go b/btcjson/btcdextcmds_test.go index aaa44144..8aadb0af 100644 --- a/btcjson/btcdextcmds_test.go +++ b/btcjson/btcdextcmds_test.go @@ -12,7 +12,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestBtcdExtCmds tests all of the btcd extended commands marshal and unmarshal diff --git a/btcjson/btcdextresults_test.go b/btcjson/btcdextresults_test.go index 478f088c..55327dce 100644 --- a/btcjson/btcdextresults_test.go +++ b/btcjson/btcdextresults_test.go @@ -9,7 +9,7 @@ import ( "encoding/json" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestBtcdExtCustomResults ensures any results that have custom marshalling diff --git a/btcjson/btcwalletextcmds_test.go b/btcjson/btcwalletextcmds_test.go index dea1c614..fe3b54c0 100644 --- a/btcjson/btcwalletextcmds_test.go +++ b/btcjson/btcwalletextcmds_test.go @@ -11,7 +11,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestBtcWalletExtCmds tests all of the btcwallet extended commands marshal and diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index aa1d4415..0cfb2e17 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -13,7 +13,7 @@ import ( "fmt" "reflect" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // AddNodeSubCmd defines the type used in the addnode JSON-RPC command for the diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index 7d3a68dc..fa8305c2 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -12,8 +12,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/wire" ) // TestChainSvrCmds tests all of the chain server commands marshal and unmarshal diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 405fd867..e658cccf 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -9,10 +9,10 @@ import ( "encoding/hex" "encoding/json" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // GetBlockHeaderVerboseResult models the data from the getblockheader command when diff --git a/btcjson/chainsvrresults_test.go b/btcjson/chainsvrresults_test.go index 72dcd8d7..bb04a003 100644 --- a/btcjson/chainsvrresults_test.go +++ b/btcjson/chainsvrresults_test.go @@ -9,10 +9,10 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcutil" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + btcutil "github.com/lbryio/lbcutil" ) // TestChainSvrCustomResults ensures any results that have custom marshalling diff --git a/btcjson/chainsvrwscmds_test.go b/btcjson/chainsvrwscmds_test.go index 03fb22c8..688c3900 100644 --- a/btcjson/chainsvrwscmds_test.go +++ b/btcjson/chainsvrwscmds_test.go @@ -12,7 +12,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestChainSvrWsCmds tests all of the chain server websocket-specific commands diff --git a/btcjson/chainsvrwsntfns_test.go b/btcjson/chainsvrwsntfns_test.go index e2b234c2..ed6902dc 100644 --- a/btcjson/chainsvrwsntfns_test.go +++ b/btcjson/chainsvrwsntfns_test.go @@ -12,7 +12,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestChainSvrWsNtfns tests all of the chain server websocket-specific diff --git a/btcjson/chainsvrwsresults_test.go b/btcjson/chainsvrwsresults_test.go index b1e17450..21e1f2ff 100644 --- a/btcjson/chainsvrwsresults_test.go +++ b/btcjson/chainsvrwsresults_test.go @@ -9,7 +9,7 @@ import ( "encoding/json" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestChainSvrWsResults ensures any results that have custom marshalling diff --git a/btcjson/cmdinfo_test.go b/btcjson/cmdinfo_test.go index 61a693e4..2d7e7ec4 100644 --- a/btcjson/cmdinfo_test.go +++ b/btcjson/cmdinfo_test.go @@ -8,7 +8,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestCmdMethod tests the CmdMethod function to ensure it retunrs the expected diff --git a/btcjson/cmdparse_test.go b/btcjson/cmdparse_test.go index f2585edf..c1414c64 100644 --- a/btcjson/cmdparse_test.go +++ b/btcjson/cmdparse_test.go @@ -10,7 +10,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestAssignField tests the assignField function handles supported combinations diff --git a/btcjson/error_test.go b/btcjson/error_test.go index 8eb93c75..d1f5cb98 100644 --- a/btcjson/error_test.go +++ b/btcjson/error_test.go @@ -7,7 +7,7 @@ package btcjson_test import ( "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestErrorCodeStringer tests the stringized output for the ErrorCode type. diff --git a/btcjson/example_test.go b/btcjson/example_test.go index 74478e74..7974ba0e 100644 --- a/btcjson/example_test.go +++ b/btcjson/example_test.go @@ -8,7 +8,7 @@ import ( "encoding/json" "fmt" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // This example demonstrates how to create and marshal a command into a JSON-RPC diff --git a/btcjson/help_test.go b/btcjson/help_test.go index 918aa144..87ad7f7e 100644 --- a/btcjson/help_test.go +++ b/btcjson/help_test.go @@ -8,7 +8,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestHelpReflectInternals ensures the various help functions which deal with diff --git a/btcjson/helpers_test.go b/btcjson/helpers_test.go index 7bcaf4bc..9023c2e4 100644 --- a/btcjson/helpers_test.go +++ b/btcjson/helpers_test.go @@ -8,7 +8,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestHelpers tests the various helper functions which create pointers to diff --git a/btcjson/jsonrpc_test.go b/btcjson/jsonrpc_test.go index 13d98e89..b7229d35 100644 --- a/btcjson/jsonrpc_test.go +++ b/btcjson/jsonrpc_test.go @@ -9,7 +9,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestIsValidIDType ensures the IsValidIDType function behaves as expected. diff --git a/btcjson/register_test.go b/btcjson/register_test.go index 2d3ab10f..45e7238c 100644 --- a/btcjson/register_test.go +++ b/btcjson/register_test.go @@ -9,7 +9,7 @@ import ( "sort" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestUsageFlagStringer tests the stringized output for the UsageFlag type. diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index e8ed6237..e4d676ff 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -12,7 +12,7 @@ import ( "encoding/json" "fmt" - "github.com/btcsuite/btcutil" + btcutil "github.com/lbryio/lbcutil" ) // AddMultisigAddressCmd defines the addmutisigaddress JSON-RPC command. diff --git a/btcjson/walletsvrcmds_test.go b/btcjson/walletsvrcmds_test.go index 9c68d260..d33888d4 100644 --- a/btcjson/walletsvrcmds_test.go +++ b/btcjson/walletsvrcmds_test.go @@ -11,8 +11,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + btcutil "github.com/lbryio/lbcutil" ) // TestWalletSvrCmds tests all of the wallet server commands marshal and diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index 78a6e647..16df09bb 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -8,7 +8,7 @@ import ( "encoding/json" "fmt" - "github.com/btcsuite/btcd/txscript" + "github.com/lbryio/lbcd/txscript" ) // CreateWalletResult models the result of the createwallet command. diff --git a/btcjson/walletsvrresults_test.go b/btcjson/walletsvrresults_test.go index fd44b066..510c367c 100644 --- a/btcjson/walletsvrresults_test.go +++ b/btcjson/walletsvrresults_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/txscript" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/txscript" ) // TestGetAddressInfoResult ensures that custom unmarshalling of diff --git a/btcjson/walletsvrwscmds_test.go b/btcjson/walletsvrwscmds_test.go index 110a893b..3c9751fc 100644 --- a/btcjson/walletsvrwscmds_test.go +++ b/btcjson/walletsvrwscmds_test.go @@ -11,7 +11,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestWalletSvrWsCmds tests all of the wallet server websocket-specific diff --git a/btcjson/walletsvrwsntfns_test.go b/btcjson/walletsvrwsntfns_test.go index 11191662..51839c68 100644 --- a/btcjson/walletsvrwsntfns_test.go +++ b/btcjson/walletsvrwsntfns_test.go @@ -11,7 +11,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestWalletSvrWsNtfns tests all of the chain server websocket-specific diff --git a/chaincfg/doc.go b/chaincfg/doc.go index 3659adbf..fb5fa677 100644 --- a/chaincfg/doc.go +++ b/chaincfg/doc.go @@ -25,8 +25,8 @@ // "fmt" // "log" // -// "github.com/btcsuite/btcutil" -// "github.com/btcsuite/btcd/chaincfg" +// btcutil "github.com/lbryio/lbcutil" +// "github.com/lbryio/lbcd/chaincfg" // ) // // var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network") diff --git a/chaincfg/genesis.go b/chaincfg/genesis.go index 2c2a043e..a4df289d 100644 --- a/chaincfg/genesis.go +++ b/chaincfg/genesis.go @@ -7,8 +7,8 @@ package chaincfg import ( "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // genesisCoinbaseTx is the coinbase transaction for the genesis blocks for diff --git a/chaincfg/params.go b/chaincfg/params.go index 68c362d5..b2144963 100644 --- a/chaincfg/params.go +++ b/chaincfg/params.go @@ -13,8 +13,8 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // These variables are the chain proof-of-work limit parameters for each default diff --git a/chaincfg/register_test.go b/chaincfg/register_test.go index bcb5b3c6..700a63ff 100644 --- a/chaincfg/register_test.go +++ b/chaincfg/register_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - . "github.com/btcsuite/btcd/chaincfg" + . "github.com/lbryio/lbcd/chaincfg" ) // Define some of the required parameters for a user-registered diff --git a/cmd/addblock/addblock.go b/cmd/addblock/addblock.go index 8b44f307..b601779b 100644 --- a/cmd/addblock/addblock.go +++ b/cmd/addblock/addblock.go @@ -8,11 +8,11 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/limits" "github.com/btcsuite/btclog" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/limits" ) const ( diff --git a/cmd/addblock/config.go b/cmd/addblock/config.go index 90620c8f..d2c9dc0d 100644 --- a/cmd/addblock/config.go +++ b/cmd/addblock/config.go @@ -9,12 +9,12 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -24,7 +24,7 @@ const ( ) var ( - btcdHomeDir = btcutil.AppDataDir("btcd", false) + btcdHomeDir = btcutil.AppDataDir("lbcd", false) defaultDataDir = filepath.Join(btcdHomeDir, "data") knownDbTypes = database.SupportedDrivers() activeNetParams = &chaincfg.MainNetParams @@ -35,7 +35,7 @@ var ( // See loadConfig for details on the configuration load process. type config struct { AddrIndex bool `long:"addrindex" description:"Build a full address-based transaction index which makes the searchrawtransactions RPC available"` - DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` + DataDir string `short:"b" long:"datadir" description:"Location of the lbcd data directory"` DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` InFile string `short:"i" long:"infile" description:"File containing the block(s)"` Progress int `short:"p" long:"progress" description:"Show a progress message each time this number of seconds have passed -- Use 0 to disable progress announcements"` @@ -67,7 +67,7 @@ func validDbType(dbType string) bool { } // netName returns the name used when referring to a bitcoin network. At the -// time of writing, btcd currently places blocks for testnet version 3 in the +// time of writing, lbcd currently places blocks for testnet version 3 in the // data and log directory "testnet", which does not match the Name field of the // chaincfg parameters. This function can be used to override this directory name // as "testnet" when the passed active network matches wire.TestNet3. diff --git a/cmd/addblock/import.go b/cmd/addblock/import.go index b7a30369..34117ecd 100644 --- a/cmd/addblock/import.go +++ b/cmd/addblock/import.go @@ -11,12 +11,12 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var zeroHash = chainhash.Hash{} diff --git a/cmd/findcheckpoint/config.go b/cmd/findcheckpoint/config.go index 87f04cec..7a16069a 100644 --- a/cmd/findcheckpoint/config.go +++ b/cmd/findcheckpoint/config.go @@ -9,12 +9,12 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -25,7 +25,7 @@ const ( ) var ( - btcdHomeDir = btcutil.AppDataDir("btcd", false) + btcdHomeDir = btcutil.AppDataDir("lbcd", false) defaultDataDir = filepath.Join(btcdHomeDir, "data") knownDbTypes = database.SupportedDrivers() activeNetParams = &chaincfg.MainNetParams @@ -35,7 +35,7 @@ var ( // // See loadConfig for details on the configuration load process. type config struct { - DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` + DataDir string `short:"b" long:"datadir" description:"Location of the lbcd data directory"` DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` UseGoOutput bool `short:"g" long:"gooutput" description:"Display the candidates using Go syntax that is ready to insert into the btcchain checkpoint list"` NumCandidates int `short:"n" long:"numcandidates" description:"Max num of checkpoint candidates to show {1-20}"` @@ -56,7 +56,7 @@ func validDbType(dbType string) bool { } // netName returns the name used when referring to a bitcoin network. At the -// time of writing, btcd currently places blocks for testnet version 3 in the +// time of writing, lbcd currently places blocks for testnet version 3 in the // data and log directory "testnet", which does not match the Name field of the // chaincfg parameters. This function can be used to override this directory name // as "testnet" when the passed active network matches wire.TestNet3. diff --git a/cmd/findcheckpoint/findcheckpoint.go b/cmd/findcheckpoint/findcheckpoint.go index ec4a4b30..ae307148 100644 --- a/cmd/findcheckpoint/findcheckpoint.go +++ b/cmd/findcheckpoint/findcheckpoint.go @@ -9,10 +9,10 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" ) const blockDbNamePrefix = "blocks" diff --git a/cmd/gencerts/gencerts.go b/cmd/gencerts/gencerts.go index 27d1073e..3bce5d17 100644 --- a/cmd/gencerts/gencerts.go +++ b/cmd/gencerts/gencerts.go @@ -12,8 +12,8 @@ import ( "strings" "time" - "github.com/btcsuite/btcutil" flags "github.com/jessevdk/go-flags" + btcutil "github.com/lbryio/lbcutil" ) type config struct { diff --git a/cmd/btcctl/config.go b/cmd/lbcctl/config.go similarity index 95% rename from cmd/btcctl/config.go rename to cmd/lbcctl/config.go index 1cc2a260..e00cac77 100644 --- a/cmd/btcctl/config.go +++ b/cmd/lbcctl/config.go @@ -13,10 +13,10 @@ import ( "regexp" "strings" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcutil" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -27,10 +27,10 @@ const ( ) var ( - btcdHomeDir = btcutil.AppDataDir("btcd", false) - btcctlHomeDir = btcutil.AppDataDir("btcctl", false) - btcwalletHomeDir = btcutil.AppDataDir("btcwallet", false) - defaultConfigFile = filepath.Join(btcctlHomeDir, "btcctl.conf") + btcdHomeDir = btcutil.AppDataDir("lbcd", false) + btcctlHomeDir = btcutil.AppDataDir("lbcctl", false) + btcwalletHomeDir = btcutil.AppDataDir("lbcwallet", false) + defaultConfigFile = filepath.Join(btcctlHomeDir, "lbcctl.conf") defaultRPCServer = "localhost" defaultRPCCertFile = filepath.Join(btcdHomeDir, "rpc.cert") defaultWalletCertFile = filepath.Join(btcwalletHomeDir, "rpc.cert") @@ -137,7 +137,7 @@ func normalizeAddress(addr string, chain *chaincfg.Params, useWallet bool) (stri paramErr := fmt.Errorf("cannot use -wallet with -regtest, btcwallet not yet compatible with regtest") return "", paramErr } else { - defaultPort = "18334" + defaultPort = "29245" } case &chaincfg.SigNetParams: if useWallet { @@ -231,9 +231,9 @@ func loadConfig() (*config, []string, error) { // Use config file for RPC server to create default btcctl config var serverConfigPath string if preCfg.Wallet { - serverConfigPath = filepath.Join(btcwalletHomeDir, "btcwallet.conf") + serverConfigPath = filepath.Join(btcwalletHomeDir, "lbcwallet.conf") } else { - serverConfigPath = filepath.Join(btcdHomeDir, "btcd.conf") + serverConfigPath = filepath.Join(btcdHomeDir, "lbcd.conf") } err := createDefaultConfigFile(preCfg.ConfigFile, serverConfigPath) diff --git a/cmd/btcctl/httpclient.go b/cmd/lbcctl/httpclient.go similarity index 98% rename from cmd/btcctl/httpclient.go rename to cmd/lbcctl/httpclient.go index 2a0f6dff..e7ffd205 100644 --- a/cmd/btcctl/httpclient.go +++ b/cmd/lbcctl/httpclient.go @@ -10,8 +10,8 @@ import ( "net" "net/http" - "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/go-socks/socks" + "github.com/lbryio/lbcd/btcjson" ) // newHTTPClient returns a new HTTP client that is configured according to the diff --git a/cmd/btcctl/btcctl.go b/cmd/lbcctl/lbcctl.go similarity index 99% rename from cmd/btcctl/btcctl.go rename to cmd/lbcctl/lbcctl.go index 771d5f7e..79349186 100644 --- a/cmd/btcctl/btcctl.go +++ b/cmd/lbcctl/lbcctl.go @@ -10,7 +10,7 @@ import ( "path/filepath" "strings" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) const ( diff --git a/cmd/btcctl/version.go b/cmd/lbcctl/version.go similarity index 99% rename from cmd/btcctl/version.go rename to cmd/lbcctl/version.go index edb42dbe..fcd70ce4 100644 --- a/cmd/btcctl/version.go +++ b/cmd/lbcctl/version.go @@ -18,7 +18,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr const ( appMajor uint = 0 appMinor uint = 22 - appPatch uint = 0 + appPatch uint = 100 // appPreRelease MUST only contain characters from semanticAlphabet // per the semantic versioning spec. diff --git a/config.go b/config.go index 156084bc..748a626d 100644 --- a/config.go +++ b/config.go @@ -21,26 +21,26 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/connmgr" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/go-socks/socks" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/connmgr" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( - defaultConfigFilename = "btcd.conf" + defaultConfigFilename = "lbcd.conf" defaultDataDirname = "data" defaultLogLevel = "info" defaultLogDirname = "logs" - defaultLogFilename = "btcd.log" + defaultLogFilename = "lbcd.log" defaultMaxPeers = 125 defaultBanDuration = time.Hour * 24 defaultBanThreshold = 100 @@ -63,13 +63,13 @@ const ( defaultMaxOrphanTransactions = 100 defaultMaxOrphanTxSize = 100000 defaultSigCacheMaxSize = 100000 - sampleConfigFilename = "sample-btcd.conf" + sampleConfigFilename = "sample-lbcd.conf" defaultTxIndex = false defaultAddrIndex = false ) var ( - defaultHomeDir = btcutil.AppDataDir("btcd", false) + defaultHomeDir = btcutil.AppDataDir("lbcd", false) defaultConfigFile = filepath.Join(defaultHomeDir, defaultConfigFilename) defaultDataDir = filepath.Join(defaultHomeDir, defaultDataDirname) knownDbTypes = database.SupportedDrivers() @@ -98,8 +98,8 @@ type config struct { AddCheckpoints []string `long:"addcheckpoint" description:"Add a custom checkpoint. Format: ':'"` AddPeers []string `short:"a" long:"addpeer" description:"Add a peer to connect with at startup"` AddrIndex bool `long:"addrindex" description:"Maintain a full address-based transaction index which makes the searchrawtransactions RPC available"` - AgentBlacklist []string `long:"agentblacklist" description:"A comma separated list of user-agent substrings which will cause btcd to reject any peers whose user-agent contains any of the blacklisted substrings."` - AgentWhitelist []string `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause btcd to require all peers' user-agents to contain one of the whitelisted substrings. The blacklist is applied before the blacklist, and an empty whitelist will allow all agents that do not fail the blacklist."` + AgentBlacklist []string `long:"agentblacklist" description:"A comma separated list of user-agent substrings which will cause lbcd to reject any peers whose user-agent contains any of the blacklisted substrings."` + AgentWhitelist []string `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause lbcd to require all peers' user-agents to contain one of the whitelisted substrings. The blacklist is applied before the blacklist, and an empty whitelist will allow all agents that do not fail the blacklist."` BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"` BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."` BlockMaxSize uint32 `long:"blockmaxsize" description:"Maximum block size in bytes to be used when creating a block"` @@ -125,7 +125,7 @@ type config struct { MaxOrphanTxs int `long:"maxorphantx" description:"Max number of orphan transactions to keep in memory"` MaxPeers int `long:"maxpeers" description:"Max number of inbound and outbound peers"` MiningAddrs []string `long:"miningaddr" description:"Add the specified payment address to the list of addresses to use for generated blocks -- At least one address is required if the generate option is set"` - MinRelayTxFee float64 `long:"minrelaytxfee" description:"The minimum transaction fee in BTC/kB to be considered a non-zero fee."` + MinRelayTxFee float64 `long:"minrelaytxfee" description:"The minimum transaction fee in LBC/kB to be considered a non-zero fee."` DisableBanning bool `long:"nobanning" description:"Disable banning of misbehaving peers"` NoCFilters bool `long:"nocfilters" description:"Disable committed filtering (CF) support"` DisableCheckpoints bool `long:"nocheckpoints" description:"Disable built-in checkpoints. Don't do this unless you know what you're doing."` @@ -407,7 +407,7 @@ func newConfigParser(cfg *config, so *serviceOptions, options flags.Options) *fl // 3) Load configuration file overwriting defaults with any specified options // 4) Parse CLI options and overwrite/add any specified options // -// The above results in btcd functioning properly without any config settings +// The above results in lbcd functioning properly without any config settings // while still allowing the user to override settings with config files and // command line options. Command line options always take precedence. func loadConfig() (*config, []string, error) { @@ -1146,7 +1146,7 @@ func loadConfig() (*config, []string, error) { return &cfg, remainingArgs, nil } -// createDefaultConfig copies the file sample-btcd.conf to the given destination path, +// createDefaultConfig copies the file sample-lbcd.conf to the given destination path, // and populates it with some randomly generated RPC username and password. func createDefaultConfigFile(destinationPath string) error { // Create the destination directory if it does not exists diff --git a/config_test.go b/config_test.go index e54a9f5f..84e7d444 100644 --- a/config_test.go +++ b/config_test.go @@ -20,16 +20,16 @@ func TestCreateDefaultConfigFile(t *testing.T) { if !ok { t.Fatalf("Failed finding config file path") } - sampleConfigFile := filepath.Join(filepath.Dir(path), "sample-btcd.conf") + sampleConfigFile := filepath.Join(filepath.Dir(path), "sample-lbcd.conf") // Setup a temporary directory - tmpDir, err := ioutil.TempDir("", "btcd") + tmpDir, err := ioutil.TempDir("", "lbcd") if err != nil { t.Fatalf("Failed creating a temporary directory: %v", err) } testpath := filepath.Join(tmpDir, "test.conf") - // copy config file to location of btcd binary + // copy config file to location of lbcd binary data, err := ioutil.ReadFile(sampleConfigFile) if err != nil { t.Fatalf("Failed reading sample config file: %v", err) @@ -38,7 +38,7 @@ func TestCreateDefaultConfigFile(t *testing.T) { if err != nil { t.Fatalf("Failed obtaining app path: %v", err) } - tmpConfigFile := filepath.Join(appPath, "sample-btcd.conf") + tmpConfigFile := filepath.Join(appPath, "sample-lbcd.conf") err = ioutil.WriteFile(tmpConfigFile, data, 0644) if err != nil { t.Fatalf("Failed copying sample config file: %v", err) diff --git a/connmgr/seed.go b/connmgr/seed.go index 063b546a..b35d2a1a 100644 --- a/connmgr/seed.go +++ b/connmgr/seed.go @@ -11,8 +11,8 @@ import ( "strconv" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/database/cmd/dbtool/fetchblock.go b/database/cmd/dbtool/fetchblock.go index 75a3e31a..b2ac4893 100644 --- a/database/cmd/dbtool/fetchblock.go +++ b/database/cmd/dbtool/fetchblock.go @@ -9,8 +9,8 @@ import ( "errors" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" ) // fetchBlockCmd defines the configuration options for the fetchblock command. diff --git a/database/cmd/dbtool/fetchblockregion.go b/database/cmd/dbtool/fetchblockregion.go index 9d63ed17..0204c36b 100644 --- a/database/cmd/dbtool/fetchblockregion.go +++ b/database/cmd/dbtool/fetchblockregion.go @@ -10,8 +10,8 @@ import ( "strconv" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" ) // blockRegionCmd defines the configuration options for the fetchblockregion diff --git a/database/cmd/dbtool/globalconfig.go b/database/cmd/dbtool/globalconfig.go index aa1e0e04..8d19c2b1 100644 --- a/database/cmd/dbtool/globalconfig.go +++ b/database/cmd/dbtool/globalconfig.go @@ -10,15 +10,15 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( - btcdHomeDir = btcutil.AppDataDir("btcd", false) + btcdHomeDir = btcutil.AppDataDir("lbcd", false) knownDbTypes = database.SupportedDrivers() activeNetParams = &chaincfg.MainNetParams @@ -31,7 +31,7 @@ var ( // config defines the global configuration options. type config struct { - DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` + DataDir string `short:"b" long:"datadir" description:"Location of the lbcd data directory"` DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` RegressionTest bool `long:"regtest" description:"Use the regression test network"` SimNet bool `long:"simnet" description:"Use the simulation test network"` @@ -60,7 +60,7 @@ func validDbType(dbType string) bool { } // netName returns the name used when referring to a bitcoin network. At the -// time of writing, btcd currently places blocks for testnet version 3 in the +// time of writing, lbcd currently places blocks for testnet version 3 in the // data and log directory "testnet", which does not match the Name field of the // chaincfg parameters. This function can be used to override this directory name // as "testnet" when the passed active network matches wire.TestNet3. diff --git a/database/cmd/dbtool/insecureimport.go b/database/cmd/dbtool/insecureimport.go index 7564eb68..442873c9 100644 --- a/database/cmd/dbtool/insecureimport.go +++ b/database/cmd/dbtool/insecureimport.go @@ -12,10 +12,10 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // importCmd defines the configuration options for the insecureimport command. diff --git a/database/cmd/dbtool/loadheaders.go b/database/cmd/dbtool/loadheaders.go index a3ee8c73..00bb5411 100644 --- a/database/cmd/dbtool/loadheaders.go +++ b/database/cmd/dbtool/loadheaders.go @@ -7,8 +7,8 @@ package main import ( "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" ) // headersCmd defines the configuration options for the loadheaders command. diff --git a/database/cmd/dbtool/main.go b/database/cmd/dbtool/main.go index 73c59a6e..c7fb6a45 100644 --- a/database/cmd/dbtool/main.go +++ b/database/cmd/dbtool/main.go @@ -9,9 +9,9 @@ import ( "path/filepath" "strings" - "github.com/btcsuite/btcd/database" "github.com/btcsuite/btclog" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/database" ) const ( diff --git a/database/driver_test.go b/database/driver_test.go index 3bb48de1..6d0b00a6 100644 --- a/database/driver_test.go +++ b/database/driver_test.go @@ -8,8 +8,8 @@ import ( "fmt" "testing" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" ) var ( diff --git a/database/error_test.go b/database/error_test.go index 759d26e1..4d053d4b 100644 --- a/database/error_test.go +++ b/database/error_test.go @@ -8,7 +8,7 @@ import ( "errors" "testing" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/database" ) // TestErrorCodeStringer tests the stringized output for the ErrorCode type. diff --git a/database/example_test.go b/database/example_test.go index 8b6fe7bc..daf475cd 100644 --- a/database/example_test.go +++ b/database/example_test.go @@ -10,11 +10,11 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // This example demonstrates creating a new database. @@ -22,8 +22,8 @@ func ExampleCreate() { // This example assumes the ffldb driver is imported. // // import ( - // "github.com/btcsuite/btcd/database" - // _ "github.com/btcsuite/btcd/database/ffldb" + // "github.com/lbryio/lbcd/database" + // _ "github.com/lbryio/lbcd/database/ffldb" // ) // Create a database and schedule it to be closed and removed on exit. @@ -48,8 +48,8 @@ func Example_basicUsage() { // This example assumes the ffldb driver is imported. // // import ( - // "github.com/btcsuite/btcd/database" - // _ "github.com/btcsuite/btcd/database/ffldb" + // "github.com/lbryio/lbcd/database" + // _ "github.com/lbryio/lbcd/database/ffldb" // ) // Create a database and schedule it to be closed and removed on exit. @@ -114,8 +114,8 @@ func Example_blockStorageAndRetrieval() { // This example assumes the ffldb driver is imported. // // import ( - // "github.com/btcsuite/btcd/database" - // _ "github.com/btcsuite/btcd/database/ffldb" + // "github.com/lbryio/lbcd/database" + // _ "github.com/lbryio/lbcd/database/ffldb" // ) // Create a database and schedule it to be closed and removed on exit. @@ -173,5 +173,5 @@ func Example_blockStorageAndRetrieval() { fmt.Printf("Serialized block size: %d bytes\n", len(loadedBlockBytes)) // Output: - // Serialized block size: 285 bytes + // Serialized block size: 229 bytes } diff --git a/database/ffldb/bench_test.go b/database/ffldb/bench_test.go index 8d020313..7ea0d126 100644 --- a/database/ffldb/bench_test.go +++ b/database/ffldb/bench_test.go @@ -9,9 +9,9 @@ import ( "path/filepath" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + btcutil "github.com/lbryio/lbcutil" ) // BenchmarkBlockHeader benchmarks how long it takes to load the mainnet genesis diff --git a/database/ffldb/blockio.go b/database/ffldb/blockio.go index 8fb27ab2..ae71a891 100644 --- a/database/ffldb/blockio.go +++ b/database/ffldb/blockio.go @@ -17,9 +17,9 @@ import ( "path/filepath" "sync" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/database/ffldb/db.go b/database/ffldb/db.go index b4994421..0d6acd51 100644 --- a/database/ffldb/db.go +++ b/database/ffldb/db.go @@ -14,11 +14,6 @@ import ( "sort" "sync" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/database/internal/treap" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/goleveldb/leveldb" "github.com/btcsuite/goleveldb/leveldb/comparer" ldberrors "github.com/btcsuite/goleveldb/leveldb/errors" @@ -26,6 +21,11 @@ import ( "github.com/btcsuite/goleveldb/leveldb/iterator" "github.com/btcsuite/goleveldb/leveldb/opt" "github.com/btcsuite/goleveldb/leveldb/util" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/database/internal/treap" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/database/ffldb/dbcache.go b/database/ffldb/dbcache.go index a2346b58..15c554a7 100644 --- a/database/ffldb/dbcache.go +++ b/database/ffldb/dbcache.go @@ -10,10 +10,10 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/database/internal/treap" "github.com/btcsuite/goleveldb/leveldb" "github.com/btcsuite/goleveldb/leveldb/iterator" "github.com/btcsuite/goleveldb/leveldb/util" + "github.com/lbryio/lbcd/database/internal/treap" ) const ( diff --git a/database/ffldb/doc.go b/database/ffldb/doc.go index 96a2992c..cca5ebc5 100644 --- a/database/ffldb/doc.go +++ b/database/ffldb/doc.go @@ -6,7 +6,7 @@ Package ffldb implements a driver for the database package that uses leveldb for the backing metadata and flat files for block storage. -This driver is the recommended driver for use with btcd. It makes use leveldb +This driver is the recommended driver for use with lbcd. It makes use leveldb for the metadata, flat files for block storage, and checksums in key areas to ensure data integrity. diff --git a/database/ffldb/driver.go b/database/ffldb/driver.go index 28ab8277..39a1e02b 100644 --- a/database/ffldb/driver.go +++ b/database/ffldb/driver.go @@ -7,9 +7,9 @@ package ffldb import ( "fmt" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btclog" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) var log = btclog.Disabled diff --git a/database/ffldb/driver_test.go b/database/ffldb/driver_test.go index f3db909d..ff53acd0 100644 --- a/database/ffldb/driver_test.go +++ b/database/ffldb/driver_test.go @@ -11,10 +11,10 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/database/ffldb" + btcutil "github.com/lbryio/lbcutil" ) // dbType is the database type name for this driver. diff --git a/database/ffldb/export_test.go b/database/ffldb/export_test.go index 2d8e4d2a..bcad41af 100644 --- a/database/ffldb/export_test.go +++ b/database/ffldb/export_test.go @@ -11,7 +11,7 @@ The functions are only exported while the tests are being run. package ffldb -import "github.com/btcsuite/btcd/database" +import "github.com/lbryio/lbcd/database" // TstRunWithMaxBlockFileSize runs the passed function with the maximum allowed // file size for the database set to the provided value. The value will be set diff --git a/database/ffldb/interface_test.go b/database/ffldb/interface_test.go index 1ce991cc..b1b4cac7 100644 --- a/database/ffldb/interface_test.go +++ b/database/ffldb/interface_test.go @@ -25,11 +25,10 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( diff --git a/database/ffldb/ldbtreapiter.go b/database/ffldb/ldbtreapiter.go index b3d6b6bd..0a552633 100644 --- a/database/ffldb/ldbtreapiter.go +++ b/database/ffldb/ldbtreapiter.go @@ -5,9 +5,9 @@ package ffldb import ( - "github.com/btcsuite/btcd/database/internal/treap" "github.com/btcsuite/goleveldb/leveldb/iterator" "github.com/btcsuite/goleveldb/leveldb/util" + "github.com/lbryio/lbcd/database/internal/treap" ) // ldbTreapIter wraps a treap iterator to provide the additional functionality diff --git a/database/ffldb/reconcile.go b/database/ffldb/reconcile.go index e2c4d6bb..60456c26 100644 --- a/database/ffldb/reconcile.go +++ b/database/ffldb/reconcile.go @@ -8,7 +8,7 @@ import ( "fmt" "hash/crc32" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/database" ) // The serialized write cursor location format is: diff --git a/database/ffldb/whitebox_test.go b/database/ffldb/whitebox_test.go index 161d866d..4314c69f 100644 --- a/database/ffldb/whitebox_test.go +++ b/database/ffldb/whitebox_test.go @@ -17,12 +17,11 @@ import ( "path/filepath" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/goleveldb/leveldb" ldberrors "github.com/btcsuite/goleveldb/leveldb/errors" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( diff --git a/database/interface.go b/database/interface.go index 435a8ff5..5b566f11 100644 --- a/database/interface.go +++ b/database/interface.go @@ -8,8 +8,8 @@ package database import ( - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + btcutil "github.com/lbryio/lbcutil" ) // Cursor represents a cursor over key/value pairs and nested buckets of a diff --git a/doc.go b/doc.go index 70d0d9e4..ce62a7cc 100644 --- a/doc.go +++ b/doc.go @@ -3,22 +3,22 @@ // license that can be found in the LICENSE file. /* -btcd is a full-node bitcoin implementation written in Go. +lbcd is a full-node bitcoin implementation written in Go. -The default options are sane for most users. This means btcd will work 'out of +The default options are sane for most users. This means lbcd will work 'out of the box' for most users. However, there are also a wide variety of flags that can be used to control it. The following section provides a usage overview which enumerates the flags. An interesting point to note is that the long form of all of these options (except -C) can be specified in a configuration file that is automatically -parsed when btcd starts up. By default, the configuration file is located at -~/.btcd/btcd.conf on POSIX-style operating systems and %LOCALAPPDATA%\btcd\btcd.conf +parsed when lbcd starts up. By default, the configuration file is located at +~/.lbcd/lbcd.conf on POSIX-style operating systems and %LOCALAPPDATA%\lbcd\lbcd.conf on Windows. The -C (--configfile) flag, as shown below, can be used to override this location. Usage: - btcd [OPTIONS] + lbcd [OPTIONS] Application Options: --addcheckpoint= Add a custom checkpoint. Format: diff --git a/docs/conf.py b/docs/conf.py index 3db16305..145c0ac5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,9 +18,9 @@ from recommonmark.transform import AutoStructify # -- Project information ----------------------------------------------------- -project = 'btcd' -copyright = '2020, btcd' -author = 'btcsuite developers' +project = 'lbcd' +copyright = '2021, lbcd' +author = 'LBRY developers' # The full version, including alpha/beta/rc tags release = 'beta' @@ -65,9 +65,11 @@ html_theme = 'sphinx_rtd_theme' html_static_path = ['_static'] # app setup hook + + def setup(app): app.add_config_value('recommonmark_config', { - #'url_resolver': lambda url: github_doc_root + url, + # 'url_resolver': lambda url: github_doc_root + url, 'auto_toc_tree_section': 'Contents', 'enable_math': False, 'enable_inline_math': False, diff --git a/integration/bip0009_test.go b/integration/bip0009_test.go index 9bdec34f..fa94d2d0 100644 --- a/integration/bip0009_test.go +++ b/integration/bip0009_test.go @@ -13,10 +13,10 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/integration/rpctest" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/integration/rpctest" ) const ( diff --git a/integration/csv_fork_test.go b/integration/csv_fork_test.go index 31466349..1b4ae02b 100644 --- a/integration/csv_fork_test.go +++ b/integration/csv_fork_test.go @@ -14,14 +14,14 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/integration/rpctest" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/integration/rpctest" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/integration/rpcserver_test.go b/integration/rpcserver_test.go index 5875b353..9fbddc6b 100644 --- a/integration/rpcserver_test.go +++ b/integration/rpcserver_test.go @@ -14,10 +14,10 @@ import ( "runtime/debug" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/integration/rpctest" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/integration/rpctest" + "github.com/lbryio/lbcd/rpcclient" ) func testGetBestBlock(r *rpctest.Harness, t *testing.T) { diff --git a/integration/rpctest/blockgen.go b/integration/rpctest/blockgen.go index 0d802f5a..dae3b7fd 100644 --- a/integration/rpctest/blockgen.go +++ b/integration/rpctest/blockgen.go @@ -11,13 +11,13 @@ import ( "runtime" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // solveBlock attempts to find a nonce which makes the passed block header hash diff --git a/integration/rpctest/btcd.go b/integration/rpctest/btcd.go index 29642c84..e3bd4178 100644 --- a/integration/rpctest/btcd.go +++ b/integration/rpctest/btcd.go @@ -44,16 +44,16 @@ func btcdExecutablePath() (string, error) { } // Build btcd and output an executable in a static temp path. - outputPath := filepath.Join(testDir, "btcd") + outputPath := filepath.Join(testDir, "lbcd") if runtime.GOOS == "windows" { outputPath += ".exe" } cmd := exec.Command( - "go", "build", "-o", outputPath, "github.com/btcsuite/btcd", + "go", "build", "-o", outputPath, "github.com/lbryio/lbcd", ) err = cmd.Run() if err != nil { - return "", fmt.Errorf("Failed to build btcd: %v", err) + return "", fmt.Errorf("Failed to build lbcd: %v", err) } // Save executable path so future calls do not recompile. diff --git a/integration/rpctest/memwallet.go b/integration/rpctest/memwallet.go index 59b0ef4c..c1374ef3 100644 --- a/integration/rpctest/memwallet.go +++ b/integration/rpctest/memwallet.go @@ -10,15 +10,15 @@ import ( "fmt" "sync" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" - "github.com/btcsuite/btcutil/hdkeychain" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" + "github.com/lbryio/lbcutil/hdkeychain" ) var ( diff --git a/integration/rpctest/node.go b/integration/rpctest/node.go index 73dc15fc..2c7644b8 100644 --- a/integration/rpctest/node.go +++ b/integration/rpctest/node.go @@ -14,8 +14,8 @@ import ( "runtime" "time" - rpc "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" + rpc "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) // nodeConfig contains all the args, and data required to launch a btcd process @@ -51,7 +51,7 @@ func newConfig(prefix, certFile, keyFile string, extra []string, var err error btcdPath, err = btcdExecutablePath() if err != nil { - btcdPath = "btcd" + btcdPath = "lbcd" } } diff --git a/integration/rpctest/rpc_harness.go b/integration/rpctest/rpc_harness.go index 679ae4e4..1d1eaefa 100644 --- a/integration/rpctest/rpc_harness.go +++ b/integration/rpctest/rpc_harness.go @@ -16,11 +16,11 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -531,7 +531,7 @@ func generateListeningAddresses() (string, string) { // baseDir is the directory path of the temp directory for all rpctest files. func baseDir() (string, error) { - dirPath := filepath.Join(os.TempDir(), "btcd", "rpctest") + dirPath := filepath.Join(os.TempDir(), "lbcd", "rpctest") err := os.MkdirAll(dirPath, 0755) return dirPath, err } diff --git a/integration/rpctest/rpc_harness_test.go b/integration/rpctest/rpc_harness_test.go index df753e31..de9db318 100644 --- a/integration/rpctest/rpc_harness_test.go +++ b/integration/rpctest/rpc_harness_test.go @@ -13,11 +13,11 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) func testSendOutputs(r *Harness, t *testing.T) { diff --git a/integration/rpctest/utils.go b/integration/rpctest/utils.go index d4d76f2e..3273ae3c 100644 --- a/integration/rpctest/utils.go +++ b/integration/rpctest/utils.go @@ -8,8 +8,8 @@ import ( "reflect" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" ) // JoinType is an enum representing a particular type of "node join". A node diff --git a/btcd.go b/lbcd.go similarity index 98% rename from btcd.go rename to lbcd.go index 4f04657b..1b2ad72d 100644 --- a/btcd.go +++ b/lbcd.go @@ -15,10 +15,10 @@ import ( "runtime/debug" "runtime/pprof" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/claimtrie/param" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/limits" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/claimtrie/param" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/limits" "github.com/felixge/fgprof" ) diff --git a/log.go b/log.go index a69509cd..cc845475 100644 --- a/log.go +++ b/log.go @@ -10,18 +10,18 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/claimtrie/node" - "github.com/btcsuite/btcd/connmgr" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/mining/cpuminer" - "github.com/btcsuite/btcd/netsync" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/txscript" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/connmgr" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/mining/cpuminer" + "github.com/lbryio/lbcd/netsync" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/txscript" "github.com/btcsuite/btclog" "github.com/jrick/logrotate/rotator" diff --git a/mempool/error.go b/mempool/error.go index b0d42be4..7d107ae3 100644 --- a/mempool/error.go +++ b/mempool/error.go @@ -5,8 +5,8 @@ package mempool import ( - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/wire" ) // RuleError identifies a rule violation. It is used to indicate that diff --git a/mempool/estimatefee.go b/mempool/estimatefee.go index 55fe4810..719c42e2 100644 --- a/mempool/estimatefee.go +++ b/mempool/estimatefee.go @@ -16,9 +16,9 @@ import ( "strings" "sync" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + btcutil "github.com/lbryio/lbcutil" ) // TODO incorporate Alex Morcos' modifications to Gavin's initial model diff --git a/mempool/estimatefee_test.go b/mempool/estimatefee_test.go index 16dcfadc..6f86d035 100644 --- a/mempool/estimatefee_test.go +++ b/mempool/estimatefee_test.go @@ -9,10 +9,10 @@ import ( "math/rand" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // newTestFeeEstimator creates a feeEstimator with some different parameters diff --git a/mempool/mempool.go b/mempool/mempool.go index 0aecff7e..de3b8028 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -12,15 +12,15 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 96d50544..b24045ba 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -12,13 +12,13 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // fakeChain is used by the pool harness to provide generated test utxos and diff --git a/mempool/policy.go b/mempool/policy.go index c18b0d7d..21899b0f 100644 --- a/mempool/policy.go +++ b/mempool/policy.go @@ -6,12 +6,13 @@ package mempool import ( "fmt" + "math" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/mempool/policy_test.go b/mempool/policy_test.go index b9cdbac4..b677ab82 100644 --- a/mempool/policy_test.go +++ b/mempool/policy_test.go @@ -9,12 +9,12 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // TestCalcMinRequiredTxRelayFee tests the calcMinRequiredTxRelayFee API. diff --git a/mining/cpuminer/cpuminer.go b/mining/cpuminer/cpuminer.go index 3d5b3b19..b9d1d222 100644 --- a/mining/cpuminer/cpuminer.go +++ b/mining/cpuminer/cpuminer.go @@ -12,12 +12,12 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/mining/mining.go b/mining/mining.go index e918328d..4daad1a6 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -10,12 +10,12 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -30,7 +30,7 @@ const ( // CoinbaseFlags is added to the coinbase script of a generated block // and is used to monitor BIP16 support as well as blocks that are // generated via btcd. - CoinbaseFlags = "/P2SH/btcd/" + CoinbaseFlags = "/P2SH/lbcd/" ) // TxDesc is a descriptor about a transaction in a transaction source along with diff --git a/mining/mining_test.go b/mining/mining_test.go index 362253e5..f2a65419 100644 --- a/mining/mining_test.go +++ b/mining/mining_test.go @@ -9,7 +9,7 @@ import ( "math/rand" "testing" - "github.com/btcsuite/btcutil" + btcutil "github.com/lbryio/lbcutil" ) // TestTxFeePrioHeap ensures the priority queue for transaction fees and diff --git a/mining/policy.go b/mining/policy.go index c3f059c5..040095f9 100644 --- a/mining/policy.go +++ b/mining/policy.go @@ -5,9 +5,9 @@ package mining import ( - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/mining/policy_test.go b/mining/policy_test.go index f66a9c8d..e7ababfa 100644 --- a/mining/policy_test.go +++ b/mining/policy_test.go @@ -8,10 +8,10 @@ import ( "encoding/hex" "testing" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // newHashFromStr converts the passed big-endian hex string into a diff --git a/netsync/blocklogger.go b/netsync/blocklogger.go index 18480e78..34a549a1 100644 --- a/netsync/blocklogger.go +++ b/netsync/blocklogger.go @@ -9,7 +9,7 @@ import ( "time" "github.com/btcsuite/btclog" - "github.com/btcsuite/btcutil" + btcutil "github.com/lbryio/lbcutil" ) // blockProgressLogger provides periodic logging for other services in order diff --git a/netsync/interface.go b/netsync/interface.go index 3e6ca1c1..9361bfbc 100644 --- a/netsync/interface.go +++ b/netsync/interface.go @@ -5,13 +5,13 @@ package netsync import ( - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // PeerNotifier exposes methods to notify peers of status changes to diff --git a/netsync/manager.go b/netsync/manager.go index 2b6c0411..2e3f05b0 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -12,14 +12,14 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/mempool" - peerpkg "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/mempool" + peerpkg "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/params.go b/params.go index b4d1453d..664a7e6a 100644 --- a/params.go +++ b/params.go @@ -5,8 +5,8 @@ package main import ( - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" ) // activeNetParams is a pointer to the parameters specific to the diff --git a/peer/doc.go b/peer/doc.go index 88fae8e8..1bb8cf32 100644 --- a/peer/doc.go +++ b/peer/doc.go @@ -145,6 +145,6 @@ raw message bytes using a format similar to hexdump -C. Bitcoin Improvement Proposals This package supports all BIPS supported by the wire package. -(https://pkg.go.dev/github.com/btcsuite/btcd/wire#hdr-Bitcoin_Improvement_Proposals) +(https://pkg.go.dev/github.com/lbryio/lbcd/wire#hdr-Bitcoin_Improvement_Proposals) */ package peer diff --git a/peer/example_test.go b/peer/example_test.go index d4662a2b..268ed1ea 100644 --- a/peer/example_test.go +++ b/peer/example_test.go @@ -10,9 +10,9 @@ import ( "net" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" ) // mockRemotePeer creates a basic inbound peer listening on the simnet port for diff --git a/peer/log.go b/peer/log.go index 71bebd0d..a96b8e50 100644 --- a/peer/log.go +++ b/peer/log.go @@ -9,10 +9,10 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btclog" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/peer/peer.go b/peer/peer.go index a7b92580..ab8add08 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -18,13 +18,13 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" "github.com/btcsuite/go-socks/socks" "github.com/davecgh/go-spew/spew" "github.com/decred/dcrd/lru" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/peer/peer_test.go b/peer/peer_test.go index dd7f36aa..0cb9c66c 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -13,11 +13,11 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" "github.com/btcsuite/go-socks/socks" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" ) // conn mocks a network connection by implementing the net.Conn interface. It diff --git a/rpcadapters.go b/rpcadapters.go index ddcdf79b..2a1af72f 100644 --- a/rpcadapters.go +++ b/rpcadapters.go @@ -7,13 +7,13 @@ package main import ( "sync/atomic" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/netsync" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/netsync" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // rpcPeer provides a peer for use with the RPC server and implements the diff --git a/rpcclient/chain.go b/rpcclient/chain.go index a97543fd..b3735cee 100644 --- a/rpcclient/chain.go +++ b/rpcclient/chain.go @@ -10,9 +10,9 @@ import ( "encoding/hex" "encoding/json" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // FutureGetBestBlockHashResult is a future promise to deliver the result of a diff --git a/rpcclient/doc.go b/rpcclient/doc.go index b682ba10..d82a40a1 100644 --- a/rpcclient/doc.go +++ b/rpcclient/doc.go @@ -9,7 +9,7 @@ Overview This client provides a robust and easy to use client for interfacing with a Bitcoin RPC server that uses a btcd/bitcoin core compatible Bitcoin JSON-RPC -API. This client has been tested with btcd (https://github.com/btcsuite/btcd), +API. This client has been tested with btcd (https://github.com/lbryio/lbcd), btcwallet (https://github.com/btcsuite/btcwallet), and bitcoin core (https://github.com/bitcoin). diff --git a/rpcclient/example_test.go b/rpcclient/example_test.go index 9ba9adad..f044e9f1 100644 --- a/rpcclient/example_test.go +++ b/rpcclient/example_test.go @@ -6,7 +6,8 @@ package rpcclient import ( "fmt" - "github.com/btcsuite/btcd/btcjson" + + "github.com/lbryio/lbcd/btcjson" ) var connCfg = &ConnConfig{ diff --git a/rpcclient/examples/bitcoincorehttp/main.go b/rpcclient/examples/bitcoincorehttp/main.go index 489770a2..54e727de 100644 --- a/rpcclient/examples/bitcoincorehttp/main.go +++ b/rpcclient/examples/bitcoincorehttp/main.go @@ -7,7 +7,7 @@ package main import ( "log" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/rpcclient" ) func main() { diff --git a/rpcclient/examples/bitcoincorehttpbulk/main.go b/rpcclient/examples/bitcoincorehttpbulk/main.go index 3dce058d..fd21ede4 100644 --- a/rpcclient/examples/bitcoincorehttpbulk/main.go +++ b/rpcclient/examples/bitcoincorehttpbulk/main.go @@ -8,7 +8,7 @@ import ( "fmt" "log" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/rpcclient" ) func main() { diff --git a/rpcclient/examples/btcdwebsockets/main.go b/rpcclient/examples/btcdwebsockets/main.go index 56d12d82..30bb4188 100644 --- a/rpcclient/examples/btcdwebsockets/main.go +++ b/rpcclient/examples/btcdwebsockets/main.go @@ -10,9 +10,9 @@ import ( "path/filepath" "time" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) func main() { @@ -32,7 +32,7 @@ func main() { } // Connect to local btcd RPC server using websockets. - btcdHomeDir := btcutil.AppDataDir("btcd", false) + btcdHomeDir := btcutil.AppDataDir("lbcd", false) certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) diff --git a/rpcclient/examples/btcwalletwebsockets/main.go b/rpcclient/examples/btcwalletwebsockets/main.go index e803138d..b0bc6f83 100644 --- a/rpcclient/examples/btcwalletwebsockets/main.go +++ b/rpcclient/examples/btcwalletwebsockets/main.go @@ -10,9 +10,9 @@ import ( "path/filepath" "time" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) func main() { @@ -27,8 +27,8 @@ func main() { }, } - // Connect to local btcwallet RPC server using websockets. - certHomeDir := btcutil.AppDataDir("btcwallet", false) + // Connect to local lbcwallet RPC server using websockets. + certHomeDir := btcutil.AppDataDir("lbcwallet", false) certs, err := ioutil.ReadFile(filepath.Join(certHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) diff --git a/rpcclient/extensions.go b/rpcclient/extensions.go index c8615293..da44e91f 100644 --- a/rpcclient/extensions.go +++ b/rpcclient/extensions.go @@ -12,10 +12,10 @@ import ( "encoding/json" "fmt" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // FutureDebugLevelResult is a future promise to deliver the result of a diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index 63874c1b..730f8bcb 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -25,10 +25,10 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/go-socks/socks" "github.com/btcsuite/websocket" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" ) var ( @@ -114,8 +114,8 @@ const ( // 0.19.0. BitcoindPost19 - // Btcd represents a catch-all btcd version. - Btcd + // Lbcd represents a catch-all lbcd version. + Lbcd ) // Client represents a Bitcoin RPC client which allows easy access to the @@ -1587,8 +1587,8 @@ func (c *Client) BackendVersion() (BackendVersion, error) { switch err := err.(type) { // Parse the btcd version and cache it. case nil: - log.Debugf("Detected btcd version: %v", info.Version) - version := Btcd + log.Debugf("Detected lbcd version: %v", info.Version) + version := Lbcd c.backendVersion = &version return *c.backendVersion, nil @@ -1596,12 +1596,12 @@ func (c *Client) BackendVersion() (BackendVersion, error) { // we actually ran into an error. case *btcjson.RPCError: if err.Code != btcjson.ErrRPCMethodNotFound.Code { - return 0, fmt.Errorf("unable to detect btcd version: "+ + return 0, fmt.Errorf("unable to detect lbcd version: "+ "%v", err) } default: - return 0, fmt.Errorf("unable to detect btcd version: %v", err) + return 0, fmt.Errorf("unable to detect lbcd version: %v", err) } // Since the GetInfo method was not found, we assume the client is diff --git a/rpcclient/mining.go b/rpcclient/mining.go index 15473e24..ead35213 100644 --- a/rpcclient/mining.go +++ b/rpcclient/mining.go @@ -9,9 +9,9 @@ import ( "encoding/json" "errors" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + btcutil "github.com/lbryio/lbcutil" ) // FutureGenerateResult is a future promise to deliver the result of a diff --git a/rpcclient/net.go b/rpcclient/net.go index da2006c2..2d268235 100644 --- a/rpcclient/net.go +++ b/rpcclient/net.go @@ -7,7 +7,7 @@ package rpcclient import ( "encoding/json" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // AddNodeCommand enumerates the available commands that the AddNode function diff --git a/rpcclient/notify.go b/rpcclient/notify.go index 6879099a..dff3b416 100644 --- a/rpcclient/notify.go +++ b/rpcclient/notify.go @@ -13,10 +13,10 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( @@ -419,7 +419,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { connected, err := parseBtcdConnectedNtfnParams(ntfn.Params) if err != nil { - log.Warnf("Received invalid btcd connected "+ + log.Warnf("Received invalid lbcd connected "+ "notification: %v", err) return } diff --git a/rpcclient/rawrequest.go b/rpcclient/rawrequest.go index f446b008..7c3bddf9 100644 --- a/rpcclient/rawrequest.go +++ b/rpcclient/rawrequest.go @@ -8,7 +8,7 @@ import ( "encoding/json" "errors" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // FutureRawResult is a future promise to deliver the result of a RawRequest RPC diff --git a/rpcclient/rawtransactions.go b/rpcclient/rawtransactions.go index cfc322c7..d0f28c8a 100644 --- a/rpcclient/rawtransactions.go +++ b/rpcclient/rawtransactions.go @@ -9,10 +9,10 @@ import ( "encoding/hex" "encoding/json" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index 71435d99..df928969 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -8,11 +8,11 @@ import ( "encoding/json" "strconv" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // ***************************** diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 570b5b05..e8f7a640 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // helpDescsEnUS defines the English descriptions used for the help strings. @@ -21,7 +21,7 @@ var helpDescsEnUS = map[string]string{ "The levelspec can either a debug level or of the form:\n" + "=,=,...\n" + "The valid debug levels are trace, debug, info, warn, error, and critical.\n" + - "The valid subsystems are AMGR, ADXR, BCDB, BMGR, BTCD, CHAN, DISC, PEER, RPCS, SCRP, SRVR, and TXMP.\n" + + "The valid subsystems are AMGR, ADXR, BCDB, BMGR, MAIN, LBRY, CHAN, DISC, PEER, RPCS, SCRP, SRVR, and TXMP.\n" + "Finally the keyword 'show' will return a list of the available subsystems.", "debuglevel-levelspec": "The debug level(s) to use or the keyword 'show'", "debuglevel--condition0": "levelspec!=show", @@ -52,7 +52,7 @@ var helpDescsEnUS = map[string]string{ "createrawtransaction-amounts": "JSON object with the destination addresses as keys and amounts as values", "createrawtransaction-amounts--key": "address", "createrawtransaction-amounts--value": "n.nnn", - "createrawtransaction-amounts--desc": "The destination address as the key and the amount in BTC as the value", + "createrawtransaction-amounts--desc": "The destination address as the key and the amount in LBC as the value", "createrawtransaction-locktime": "Locktime value; a non-zero value will also locktime-activate the inputs", "createrawtransaction--result0": "Hex-encoded bytes of the serialized transaction", @@ -87,9 +87,11 @@ var helpDescsEnUS = map[string]string{ "scriptpubkeyresult-reqSigs": "The number of required signatures", "scriptpubkeyresult-type": "The type of the script (e.g. 'pubkeyhash')", "scriptpubkeyresult-addresses": "The bitcoin addresses associated with this script", + "scriptpubkeyresult-issupport": "Creates a support", + "scriptpubkeyresult-isclaim": "Creates or updates a claim", // Vout help. - "vout-value": "The amount in BTC", + "vout-value": "The amount in LBC", "vout-n": "The index of this transaction output", "vout-scriptPubKey": "The public key script used to pay coins as a JSON object", @@ -388,7 +390,7 @@ var helpDescsEnUS = map[string]string{ "infochainresult-proxy": "The proxy used by the server", "infochainresult-difficulty": "The current target difficulty", "infochainresult-testnet": "Whether or not server is using testnet", - "infochainresult-relayfee": "The minimum relay fee for non-free transactions in BTC/KB", + "infochainresult-relayfee": "The minimum relay fee for non-free transactions in LBC/KB", "infochainresult-errors": "Any current errors", // InfoWalletResult help. @@ -405,8 +407,8 @@ var helpDescsEnUS = map[string]string{ "infowalletresult-keypoololdest": "Seconds since 1 Jan 1970 GMT of the oldest pre-generated key in the key pool", "infowalletresult-keypoolsize": "The number of new keys that are pre-generated", "infowalletresult-unlocked_until": "The timestamp in seconds since 1 Jan 1970 GMT that the wallet is unlocked for transfers, or 0 if the wallet is locked", - "infowalletresult-paytxfee": "The transaction fee set in BTC/KB", - "infowalletresult-relayfee": "The minimum relay fee for non-free transactions in BTC/KB", + "infowalletresult-paytxfee": "The transaction fee set in LBC/KB", + "infowalletresult-relayfee": "The minimum relay fee for non-free transactions in LBC/KB", "infowalletresult-errors": "Any current errors", // GetHeadersCmd help. @@ -522,7 +524,7 @@ var helpDescsEnUS = map[string]string{ // GetTxOutResult help. "gettxoutresult-bestblock": "The block hash that contains the transaction output", "gettxoutresult-confirmations": "The number of confirmations", - "gettxoutresult-value": "The transaction amount in BTC", + "gettxoutresult-value": "The transaction amount in LBC", "gettxoutresult-scriptPubKey": "The public key script used to pay coins as a JSON object", "gettxoutresult-version": "The transaction version", "gettxoutresult-coinbase": "Whether or not the transaction is a coinbase", @@ -565,7 +567,7 @@ var helpDescsEnUS = map[string]string{ // SendRawTransactionCmd help. "sendrawtransaction--synopsis": "Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.", "sendrawtransaction-hextx": "Serialized, hex-encoded signed transaction", - "sendrawtransaction-feesetting": "Whether or not to allow insanely high fees in bitcoind < v0.19.0 or the max fee rate for bitcoind v0.19.0 and later (btcd does not yet implement this parameter, so it has no effect)", + "sendrawtransaction-feesetting": "Whether or not to allow insanely high fees in bitcoind < v0.19.0 or the max fee rate for bitcoind v0.19.0 and later (lbcd does not yet implement this parameter, so it has no effect)", "sendrawtransaction--result0": "The hash of the transaction", "allowhighfeesormaxfeerate-value": "Either the boolean value for the allowhighfees parameter in bitcoind < v0.19.0 or the numerical value for the maxfeerate field in bitcoind v0.19.0 and later", @@ -581,8 +583,8 @@ var helpDescsEnUS = map[string]string{ "signmessagewithprivkey--result0": "The signature of the message encoded in base 64", // StopCmd help. - "stop--synopsis": "Shutdown btcd.", - "stop--result0": "The string 'btcd stopping.'", + "stop--synopsis": "Shutdown lbcd.", + "stop--result0": "The string 'lbcd stopping.'", // SubmitBlockOptions help. "submitblockoptions-workid": "This parameter is currently ignored", @@ -610,7 +612,7 @@ var helpDescsEnUS = map[string]string{ // VerifyChainCmd help. "verifychain--synopsis": "Verifies the block chain database.\n" + "The actual checks performed by the checklevel parameter are implementation specific.\n" + - "For btcd this is:\n" + + "For lbcd this is:\n" + "checklevel=0 - Look up each block and ensure it can be loaded from the database.\n" + "checklevel=1 - Perform basic context-free sanity checks on each block.", "verifychain-checklevel": "How thorough the block verification is", @@ -657,7 +659,7 @@ var helpDescsEnUS = map[string]string{ "outpoint-index": "The index of the outpoint", // NotifySpentCmd help. - "notifyspent--synopsis": "Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this btcd instance) and when such a transaction first appears in a newly-attached block.", + "notifyspent--synopsis": "Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this lbcd instance) and when such a transaction first appears in a newly-attached block.", "notifyspent-outpoints": "List of transaction outpoints to monitor.", // StopNotifySpentCmd help. diff --git a/rpcwebsocket.go b/rpcwebsocket.go index 356a8974..dd18686a 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -20,15 +20,15 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/websocket" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" "golang.org/x/crypto/ripemd160" ) diff --git a/server.go b/server.go index f550ec8d..690f6ceb 100644 --- a/server.go +++ b/server.go @@ -22,24 +22,24 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/claimtrie" - claimtrieconfig "github.com/btcsuite/btcd/claimtrie/config" - "github.com/btcsuite/btcd/connmgr" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/mining/cpuminer" - "github.com/btcsuite/btcd/netsync" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" - "github.com/btcsuite/btcutil/bloom" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie" + claimtrieconfig "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/connmgr" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/mining/cpuminer" + "github.com/lbryio/lbcd/netsync" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" + "github.com/lbryio/lbcutil/bloom" ) const ( @@ -2539,7 +2539,7 @@ out: // listen port? // XXX this assumes timeout is in seconds. listenPort, err := s.nat.AddPortMapping("tcp", int(lport), int(lport), - "btcd listen port", 20*60) + "lbcd listen port", 20*60) if err != nil { srvrLog.Warnf("can't add UPnP port mapping: %v", err) } diff --git a/txscript/bench_test.go b/txscript/bench_test.go index cac29202..e568b7fc 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -10,8 +10,8 @@ import ( "io/ioutil" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" ) var ( diff --git a/txscript/engine.go b/txscript/engine.go index 40ba0eef..66ead036 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -12,8 +12,8 @@ import ( "math/big" "strings" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/wire" ) // ScriptFlags is a bitmask defining additional operations or tests that will be diff --git a/txscript/engine_test.go b/txscript/engine_test.go index 5818080d..09f945c9 100644 --- a/txscript/engine_test.go +++ b/txscript/engine_test.go @@ -8,8 +8,8 @@ package txscript import ( "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // TestBadPC sets the pc to a deliberately bad result then confirms that Step diff --git a/txscript/example_test.go b/txscript/example_test.go index 6e17341c..82a11799 100644 --- a/txscript/example_test.go +++ b/txscript/example_test.go @@ -9,12 +9,12 @@ import ( "encoding/hex" "fmt" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // This example demonstrates creating a script which pays to a bitcoin address. diff --git a/txscript/hashcache.go b/txscript/hashcache.go index f9c2caf7..ab5d9d1b 100644 --- a/txscript/hashcache.go +++ b/txscript/hashcache.go @@ -7,8 +7,8 @@ package txscript import ( "sync" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // TxSigHashes houses the partial set of sighashes introduced within BIP0143. diff --git a/txscript/hashcache_test.go b/txscript/hashcache_test.go index cee59b99..c1373497 100644 --- a/txscript/hashcache_test.go +++ b/txscript/hashcache_test.go @@ -9,8 +9,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/wire" ) func init() { diff --git a/txscript/opcode.go b/txscript/opcode.go index 4c00f353..7df52d7a 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -15,9 +15,9 @@ import ( "golang.org/x/crypto/ripemd160" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // An opcode defines the information related to a txscript opcode. opfunc, if diff --git a/txscript/pkscript.go b/txscript/pkscript.go index f5b11e6d..999ce212 100644 --- a/txscript/pkscript.go +++ b/txscript/pkscript.go @@ -5,10 +5,10 @@ import ( "errors" "fmt" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" "golang.org/x/crypto/ripemd160" ) diff --git a/txscript/pkscript_test.go b/txscript/pkscript_test.go index 49e2db8a..1e95a49f 100644 --- a/txscript/pkscript_test.go +++ b/txscript/pkscript_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // TestParsePkScript ensures that the supported script types can be parsed diff --git a/txscript/reference_test.go b/txscript/reference_test.go index 9d9c8f39..9642e424 100644 --- a/txscript/reference_test.go +++ b/txscript/reference_test.go @@ -15,9 +15,9 @@ import ( "strings" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // scriptTestName returns a descriptive test name for the given reference script diff --git a/txscript/script.go b/txscript/script.go index 1b3a60bd..6354a92b 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -12,8 +12,8 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // Bip16Activation is the timestamp where BIP0016 is valid to use in the diff --git a/txscript/script_test.go b/txscript/script_test.go index 86f94d84..dd61c4a6 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -9,7 +9,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // TestPushedData ensured the PushedData function extracts the expected data out diff --git a/txscript/sigcache.go b/txscript/sigcache.go index d9e4fa6c..56db61b5 100644 --- a/txscript/sigcache.go +++ b/txscript/sigcache.go @@ -7,8 +7,8 @@ package txscript import ( "sync" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // sigCacheEntry represents an entry in the SigCache. Entries within the diff --git a/txscript/sigcache_test.go b/txscript/sigcache_test.go index 5413ea3b..40958cfb 100644 --- a/txscript/sigcache_test.go +++ b/txscript/sigcache_test.go @@ -8,8 +8,8 @@ import ( "crypto/rand" "testing" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // genRandomSig returns a random message, a signature of the message under the diff --git a/txscript/sign.go b/txscript/sign.go index 138e31cd..7562ca34 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -8,10 +8,10 @@ import ( "errors" "fmt" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // RawTxInWitnessSignature returns the serialized ECDA signature for the input diff --git a/txscript/sign_test.go b/txscript/sign_test.go index b97a8a64..abed8c36 100644 --- a/txscript/sign_test.go +++ b/txscript/sign_test.go @@ -9,11 +9,11 @@ import ( "fmt" "testing" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) type addressToKey struct { diff --git a/txscript/standard.go b/txscript/standard.go index 2437b3cc..a45bfc6f 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -7,9 +7,9 @@ package txscript import ( "fmt" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/txscript/standard_test.go b/txscript/standard_test.go index 582d30ee..d58154e7 100644 --- a/txscript/standard_test.go +++ b/txscript/standard_test.go @@ -11,9 +11,9 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // mustParseShortForm parses the passed short form script and returns the diff --git a/upgrade.go b/upgrade.go index 5dec8d4c..9b5461da 100644 --- a/upgrade.go +++ b/upgrade.go @@ -35,13 +35,13 @@ func oldBtcdHomeDir() string { // Search for Windows APPDATA first. This won't exist on POSIX OSes. appData := os.Getenv("APPDATA") if appData != "" { - return filepath.Join(appData, "btcd") + return filepath.Join(appData, "lbcd") } // Fall back to standard HOME directory that works for most POSIX OSes. home := os.Getenv("HOME") if home != "" { - return filepath.Join(home, ".btcd") + return filepath.Join(home, ".lbcd") } // In the worst case, use the current directory. @@ -96,9 +96,9 @@ func upgradeDBPaths() error { // respective networks. Check for the old database and update it to the // new path introduced with version 0.2.0 accordingly. oldDbRoot := filepath.Join(oldBtcdHomeDir(), "db") - upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd.db"), "mainnet") - upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd_testnet.db"), "testnet") - upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd_regtest.db"), "regtest") + upgradeDBPathNet(filepath.Join(oldDbRoot, "lbcd.db"), "mainnet") + upgradeDBPathNet(filepath.Join(oldDbRoot, "lbcd_testnet.db"), "testnet") + upgradeDBPathNet(filepath.Join(oldDbRoot, "lbcd_regtest.db"), "regtest") // Remove the old db directory. return os.RemoveAll(oldDbRoot) diff --git a/wire/bench_test.go b/wire/bench_test.go index f6637d42..1eb6c413 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -13,7 +13,7 @@ import ( "os" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // genesisCoinbaseTx is the coinbase transaction for the genesis blocks for diff --git a/wire/blockheader.go b/wire/blockheader.go index ee45ec3b..372b7b46 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -9,12 +9,12 @@ import ( "io" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MaxBlockHeaderPayload is the maximum number of bytes a block header can be. // Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes + -// PrevBlock and MerkleRoot hashes. +// PrevBlock, ClaimTrie, and MerkleRoot hashes. const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 3) // BlockHeader defines information about a block and is used in the bitcoin diff --git a/wire/common.go b/wire/common.go index 8d61bdb6..134e0547 100644 --- a/wire/common.go +++ b/wire/common.go @@ -12,7 +12,7 @@ import ( "math" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/common_test.go b/wire/common_test.go index 46e3fa66..d71cc9c9 100644 --- a/wire/common_test.go +++ b/wire/common_test.go @@ -12,8 +12,8 @@ import ( "strings" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // mainNetGenesisHash is the hash of the first block in the block chain for the diff --git a/wire/invvect.go b/wire/invvect.go index 1e706642..d84b52bf 100644 --- a/wire/invvect.go +++ b/wire/invvect.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/invvect_test.go b/wire/invvect_test.go index 1d02c098..1be745c3 100644 --- a/wire/invvect_test.go +++ b/wire/invvect_test.go @@ -9,8 +9,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestInvVectStringer tests the stringized output for inventory vector types. diff --git a/wire/message.go b/wire/message.go index 6d3147a8..23cc2e05 100644 --- a/wire/message.go +++ b/wire/message.go @@ -10,7 +10,7 @@ import ( "io" "unicode/utf8" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MessageHeaderSize is the number of bytes in a bitcoin message header. diff --git a/wire/message_test.go b/wire/message_test.go index 3a422e66..b2ae3f63 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -13,8 +13,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // makeHeader is a convenience function to make a message header in the form of diff --git a/wire/msgblock.go b/wire/msgblock.go index 4172949d..c940b971 100644 --- a/wire/msgblock.go +++ b/wire/msgblock.go @@ -9,7 +9,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // defaultTransactionAlloc is the default size used for the backing array diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index 2a861b20..407e3b2d 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -11,8 +11,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestBlock tests the MsgBlock API. diff --git a/wire/msgcfcheckpt.go b/wire/msgcfcheckpt.go index fc3fd532..91e20de5 100644 --- a/wire/msgcfcheckpt.go +++ b/wire/msgcfcheckpt.go @@ -9,7 +9,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/msgcfheaders.go b/wire/msgcfheaders.go index 40d30f9b..0581581f 100644 --- a/wire/msgcfheaders.go +++ b/wire/msgcfheaders.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/msgcfilter.go b/wire/msgcfilter.go index 097590b2..838b0f55 100644 --- a/wire/msgcfilter.go +++ b/wire/msgcfilter.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // FilterType is used to represent a filter type. diff --git a/wire/msggetblocks.go b/wire/msggetblocks.go index caf4400c..1f94245d 100644 --- a/wire/msggetblocks.go +++ b/wire/msggetblocks.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MaxBlockLocatorsPerMsg is the maximum number of block locator hashes allowed diff --git a/wire/msggetblocks_test.go b/wire/msggetblocks_test.go index 376f7338..0893cc17 100644 --- a/wire/msggetblocks_test.go +++ b/wire/msggetblocks_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestGetBlocks tests the MsgGetBlocks API. diff --git a/wire/msggetcfcheckpt.go b/wire/msggetcfcheckpt.go index c30a86ce..4f7fde47 100644 --- a/wire/msggetcfcheckpt.go +++ b/wire/msggetcfcheckpt.go @@ -7,7 +7,7 @@ package wire import ( "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MsgGetCFCheckpt is a request for filter headers at evenly spaced intervals diff --git a/wire/msggetcfheaders.go b/wire/msggetcfheaders.go index 03a1caf7..46f6aa5f 100644 --- a/wire/msggetcfheaders.go +++ b/wire/msggetcfheaders.go @@ -7,7 +7,7 @@ package wire import ( "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MsgGetCFHeaders is a message similar to MsgGetHeaders, but for committed diff --git a/wire/msggetcfilters.go b/wire/msggetcfilters.go index 80024138..759950fd 100644 --- a/wire/msggetcfilters.go +++ b/wire/msggetcfilters.go @@ -7,7 +7,7 @@ package wire import ( "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MaxGetCFiltersReqRange the maximum number of filters that may be requested in diff --git a/wire/msggetdata_test.go b/wire/msggetdata_test.go index a2dd4651..9e34f296 100644 --- a/wire/msggetdata_test.go +++ b/wire/msggetdata_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestGetData tests the MsgGetData API. diff --git a/wire/msggetheaders.go b/wire/msggetheaders.go index 0bbe42cb..aa5cc3f2 100644 --- a/wire/msggetheaders.go +++ b/wire/msggetheaders.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MsgGetHeaders implements the Message interface and represents a bitcoin diff --git a/wire/msggetheaders_test.go b/wire/msggetheaders_test.go index 34a24ae3..a9ee7ad9 100644 --- a/wire/msggetheaders_test.go +++ b/wire/msggetheaders_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestGetHeaders tests the MsgGetHeader API. diff --git a/wire/msginv_test.go b/wire/msginv_test.go index b7c7c6ae..09aa6732 100644 --- a/wire/msginv_test.go +++ b/wire/msginv_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestInv tests the MsgInv API. diff --git a/wire/msgmerkleblock.go b/wire/msgmerkleblock.go index d2ee4721..075f3d56 100644 --- a/wire/msgmerkleblock.go +++ b/wire/msgmerkleblock.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // maxFlagsPerMerkleBlock is the maximum number of flag bytes that could diff --git a/wire/msgmerkleblock_test.go b/wire/msgmerkleblock_test.go index 9837f8a9..31f01a47 100644 --- a/wire/msgmerkleblock_test.go +++ b/wire/msgmerkleblock_test.go @@ -12,8 +12,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestMerkleBlock tests the MsgMerkleBlock API. diff --git a/wire/msgnotfound_test.go b/wire/msgnotfound_test.go index 69b9d07a..7cb6cf7b 100644 --- a/wire/msgnotfound_test.go +++ b/wire/msgnotfound_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestNotFound tests the MsgNotFound API. diff --git a/wire/msgreject.go b/wire/msgreject.go index a00eeff6..ee64c747 100644 --- a/wire/msgreject.go +++ b/wire/msgreject.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // RejectCode represents a numeric value by which a remote peer indicates diff --git a/wire/msgtx.go b/wire/msgtx.go index 1e2f69fa..34bdeaed 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -10,7 +10,7 @@ import ( "io" "strconv" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index 66965043..11f67293 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -11,8 +11,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestTx tests the MsgTx API. -- 2.45.2 From 753f413c13d1533ed39262f3f2cae464e31f02ba Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 6 Jul 2021 18:39:56 -0700 Subject: [PATCH 136/459] [lbry] claimtrie: import current snapshot Sync to tip Co-authored-by: Brannon King --- claimtrie/block/blockrepo/pebble.go | 87 + claimtrie/block/repo.go | 15 + claimtrie/chain/chainrepo/pebble.go | 77 + claimtrie/chain/repo.go | 10 + claimtrie/change/change.go | 112 ++ claimtrie/change/claimid.go | 54 + claimtrie/claimtrie.go | 485 +++++ claimtrie/claimtrie_test.go | 1027 +++++++++++ claimtrie/cmd/cmd/block.go | 98 + claimtrie/cmd/cmd/chain.go | 441 +++++ claimtrie/cmd/cmd/helper.go | 62 + claimtrie/cmd/cmd/merkletrie.go | 105 ++ claimtrie/cmd/cmd/node.go | 194 ++ claimtrie/cmd/cmd/root.go | 61 + claimtrie/cmd/cmd/temporal.go | 60 + claimtrie/cmd/cmd/ui.go | 76 + claimtrie/cmd/main.go | 9 + claimtrie/config/config.go | 49 + claimtrie/merkletrie/collapsedtrie.go | 235 +++ claimtrie/merkletrie/collapsedtrie_test.go | 113 ++ claimtrie/merkletrie/merkletrie.go | 255 +++ claimtrie/merkletrie/merkletrie_test.go | 25 + claimtrie/merkletrie/merkletrierepo/pebble.go | 67 + claimtrie/merkletrie/ramtrie.go | 139 ++ claimtrie/merkletrie/repo.go | 13 + claimtrie/merkletrie/vertex.go | 43 + claimtrie/node/claim.go | 92 + claimtrie/node/claim_list.go | 33 + claimtrie/node/hashfork_manager.go | 39 + claimtrie/node/hashfunc.go | 57 + claimtrie/node/log.go | 47 + claimtrie/node/manager.go | 374 ++++ claimtrie/node/manager_test.go | 250 +++ claimtrie/node/node.go | 320 ++++ claimtrie/node/noderepo/noderepo_test.go | 188 ++ claimtrie/node/noderepo/pebble.go | 171 ++ claimtrie/node/normalizing_manager.go | 114 ++ claimtrie/node/repo.go | 31 + claimtrie/normalization/CaseFolding_v11.txt | 1574 ++++++++++++++++ claimtrie/normalization/CaseFolding_v13.txt | 1584 +++++++++++++++++ claimtrie/normalization/case_folder.go | 61 + claimtrie/normalization/normalizer.go | 23 + claimtrie/normalization/normalizer_icu.go | 67 + .../normalization/normalizer_icu_test.go | 65 + claimtrie/normalization/normalizer_test.go | 54 + claimtrie/param/delays.go | 285 +++ claimtrie/param/general.go | 74 + claimtrie/param/takeovers.go | 451 +++++ claimtrie/temporal/repo.go | 9 + claimtrie/temporal/temporalrepo/memory.go | 45 + claimtrie/temporal/temporalrepo/pebble.go | 87 + .../temporalrepo/temporalrepo_test.go | 80 + 52 files changed, 10087 insertions(+) create mode 100644 claimtrie/block/blockrepo/pebble.go create mode 100644 claimtrie/block/repo.go create mode 100644 claimtrie/chain/chainrepo/pebble.go create mode 100644 claimtrie/chain/repo.go create mode 100644 claimtrie/change/change.go create mode 100644 claimtrie/change/claimid.go create mode 100644 claimtrie/claimtrie.go create mode 100644 claimtrie/claimtrie_test.go create mode 100644 claimtrie/cmd/cmd/block.go create mode 100644 claimtrie/cmd/cmd/chain.go create mode 100644 claimtrie/cmd/cmd/helper.go create mode 100644 claimtrie/cmd/cmd/merkletrie.go create mode 100644 claimtrie/cmd/cmd/node.go create mode 100644 claimtrie/cmd/cmd/root.go create mode 100644 claimtrie/cmd/cmd/temporal.go create mode 100644 claimtrie/cmd/cmd/ui.go create mode 100644 claimtrie/cmd/main.go create mode 100644 claimtrie/config/config.go create mode 100644 claimtrie/merkletrie/collapsedtrie.go create mode 100644 claimtrie/merkletrie/collapsedtrie_test.go create mode 100644 claimtrie/merkletrie/merkletrie.go create mode 100644 claimtrie/merkletrie/merkletrie_test.go create mode 100644 claimtrie/merkletrie/merkletrierepo/pebble.go create mode 100644 claimtrie/merkletrie/ramtrie.go create mode 100644 claimtrie/merkletrie/repo.go create mode 100644 claimtrie/merkletrie/vertex.go create mode 100644 claimtrie/node/claim.go create mode 100644 claimtrie/node/claim_list.go create mode 100644 claimtrie/node/hashfork_manager.go create mode 100644 claimtrie/node/hashfunc.go create mode 100644 claimtrie/node/log.go create mode 100644 claimtrie/node/manager.go create mode 100644 claimtrie/node/manager_test.go create mode 100644 claimtrie/node/node.go create mode 100644 claimtrie/node/noderepo/noderepo_test.go create mode 100644 claimtrie/node/noderepo/pebble.go create mode 100644 claimtrie/node/normalizing_manager.go create mode 100644 claimtrie/node/repo.go create mode 100644 claimtrie/normalization/CaseFolding_v11.txt create mode 100644 claimtrie/normalization/CaseFolding_v13.txt create mode 100644 claimtrie/normalization/case_folder.go create mode 100644 claimtrie/normalization/normalizer.go create mode 100644 claimtrie/normalization/normalizer_icu.go create mode 100644 claimtrie/normalization/normalizer_icu_test.go create mode 100644 claimtrie/normalization/normalizer_test.go create mode 100644 claimtrie/param/delays.go create mode 100644 claimtrie/param/general.go create mode 100644 claimtrie/param/takeovers.go create mode 100644 claimtrie/temporal/repo.go create mode 100644 claimtrie/temporal/temporalrepo/memory.go create mode 100644 claimtrie/temporal/temporalrepo/pebble.go create mode 100644 claimtrie/temporal/temporalrepo/temporalrepo_test.go diff --git a/claimtrie/block/blockrepo/pebble.go b/claimtrie/block/blockrepo/pebble.go new file mode 100644 index 00000000..b2df6afd --- /dev/null +++ b/claimtrie/block/blockrepo/pebble.go @@ -0,0 +1,87 @@ +package blockrepo + +import ( + "encoding/binary" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + + "github.com/cockroachdb/pebble" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + db, err := pebble.Open(path, &pebble.Options{MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "unable to open %s", path) +} + +func (repo *Pebble) Load() (int32, error) { + + iter := repo.db.NewIter(nil) + if !iter.Last() { + err := iter.Close() + return 0, errors.Wrap(err, "closing iterator with no last") + } + + height := int32(binary.BigEndian.Uint32(iter.Key())) + err := iter.Close() + return height, errors.Wrap(err, "closing iterator") +} + +func (repo *Pebble) Get(height int32) (*chainhash.Hash, error) { + + key := make([]byte, 4) + binary.BigEndian.PutUint32(key, uint32(height)) + + b, closer, err := repo.db.Get(key) + if closer != nil { + defer closer.Close() + } + if err != nil { + return nil, errors.Wrap(err, "in get") + } + hash, err := chainhash.NewHash(b) + return hash, errors.Wrap(err, "creating hash") +} + +func (repo *Pebble) Set(height int32, hash *chainhash.Hash) error { + + key := make([]byte, 4) + binary.BigEndian.PutUint32(key, uint32(height)) + + return errors.WithStack(repo.db.Set(key, hash[:], pebble.NoSync)) +} + +func (repo *Pebble) Delete(heightMin, heightMax int32) error { + lower := make([]byte, 4) + binary.BigEndian.PutUint32(lower, uint32(heightMin)) + + upper := make([]byte, 4) + binary.BigEndian.PutUint32(upper, uint32(heightMax)+1) + + return errors.Wrap(repo.db.DeleteRange(lower, upper, pebble.NoSync), "on range delete") +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/block/repo.go b/claimtrie/block/repo.go new file mode 100644 index 00000000..17907ff2 --- /dev/null +++ b/claimtrie/block/repo.go @@ -0,0 +1,15 @@ +package block + +import ( + "github.com/lbryio/lbcd/chaincfg/chainhash" +) + +// Repo defines APIs for Block to access persistence layer. +type Repo interface { + Load() (int32, error) + Set(height int32, hash *chainhash.Hash) error + Get(height int32) (*chainhash.Hash, error) + Close() error + Flush() error + Delete(heightMin, heightMax int32) error +} diff --git a/claimtrie/chain/chainrepo/pebble.go b/claimtrie/chain/chainrepo/pebble.go new file mode 100644 index 00000000..4100d6ac --- /dev/null +++ b/claimtrie/chain/chainrepo/pebble.go @@ -0,0 +1,77 @@ +package chainrepo + +import ( + "encoding/binary" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/vmihailenco/msgpack/v5" + + "github.com/cockroachdb/pebble" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + db, err := pebble.Open(path, &pebble.Options{BytesPerSync: 64 << 20, MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "open %s", path) +} + +func (repo *Pebble) Save(height int32, changes []change.Change) error { + + if len(changes) == 0 { + return nil + } + + var key [4]byte + binary.BigEndian.PutUint32(key[:], uint32(height)) + + value, err := msgpack.Marshal(changes) + if err != nil { + return errors.Wrap(err, "in marshaller") + } + + err = repo.db.Set(key[:], value, pebble.NoSync) + return errors.Wrap(err, "in set") +} + +func (repo *Pebble) Load(height int32) ([]change.Change, error) { + + var key [4]byte + binary.BigEndian.PutUint32(key[:], uint32(height)) + + b, closer, err := repo.db.Get(key[:]) + if closer != nil { + defer closer.Close() + } + if err != nil { + return nil, errors.Wrap(err, "in get") + } + + var changes []change.Change + err = msgpack.Unmarshal(b, &changes) + return changes, errors.Wrap(err, "in unmarshaller") +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/chain/repo.go b/claimtrie/chain/repo.go new file mode 100644 index 00000000..7d3aa978 --- /dev/null +++ b/claimtrie/chain/repo.go @@ -0,0 +1,10 @@ +package chain + +import "github.com/lbryio/lbcd/claimtrie/change" + +type Repo interface { + Save(height int32, changes []change.Change) error + Load(height int32) ([]change.Change, error) + Close() error + Flush() error +} diff --git a/claimtrie/change/change.go b/claimtrie/change/change.go new file mode 100644 index 00000000..aac349c6 --- /dev/null +++ b/claimtrie/change/change.go @@ -0,0 +1,112 @@ +package change + +import ( + "bytes" + "encoding/binary" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" +) + +type ChangeType uint32 + +const ( + AddClaim ChangeType = iota + SpendClaim + UpdateClaim + AddSupport + SpendSupport +) + +type Change struct { + Type ChangeType + Height int32 + + Name []byte + ClaimID ClaimID + OutPoint wire.OutPoint + Amount int64 + + ActiveHeight int32 + VisibleHeight int32 // aka, CreatedAt; used for normalization fork + + SpentChildren map[string]bool +} + +func NewChange(typ ChangeType) Change { + return Change{Type: typ} +} + +func (c Change) SetHeight(height int32) Change { + c.Height = height + return c +} + +func (c Change) SetName(name []byte) Change { + c.Name = name // need to clone it? + return c +} + +func (c Change) SetOutPoint(op *wire.OutPoint) Change { + c.OutPoint = *op + return c +} + +func (c Change) SetAmount(amt int64) Change { + c.Amount = amt + return c +} + +func (c *Change) Marshal(enc *bytes.Buffer) error { + enc.Write(c.ClaimID[:]) + enc.Write(c.OutPoint.Hash[:]) + var temp [8]byte + binary.BigEndian.PutUint32(temp[:4], c.OutPoint.Index) + enc.Write(temp[:4]) + binary.BigEndian.PutUint32(temp[:4], uint32(c.Type)) + enc.Write(temp[:4]) + binary.BigEndian.PutUint32(temp[:4], uint32(c.Height)) + enc.Write(temp[:4]) + binary.BigEndian.PutUint32(temp[:4], uint32(c.ActiveHeight)) + enc.Write(temp[:4]) + binary.BigEndian.PutUint32(temp[:4], uint32(c.VisibleHeight)) + enc.Write(temp[:4]) + binary.BigEndian.PutUint64(temp[:], uint64(c.Amount)) + enc.Write(temp[:]) + + if c.SpentChildren != nil { + binary.BigEndian.PutUint32(temp[:4], uint32(len(c.SpentChildren))) + enc.Write(temp[:4]) + for key := range c.SpentChildren { + binary.BigEndian.PutUint16(temp[:2], uint16(len(key))) // technically limited to 255; not sure we trust it + enc.Write(temp[:2]) + enc.WriteString(key) + } + } else { + binary.BigEndian.PutUint32(temp[:4], 0) + enc.Write(temp[:4]) + } + return nil +} + +func (c *Change) Unmarshal(dec *bytes.Buffer) error { + copy(c.ClaimID[:], dec.Next(ClaimIDSize)) + copy(c.OutPoint.Hash[:], dec.Next(chainhash.HashSize)) + c.OutPoint.Index = binary.BigEndian.Uint32(dec.Next(4)) + c.Type = ChangeType(binary.BigEndian.Uint32(dec.Next(4))) + c.Height = int32(binary.BigEndian.Uint32(dec.Next(4))) + c.ActiveHeight = int32(binary.BigEndian.Uint32(dec.Next(4))) + c.VisibleHeight = int32(binary.BigEndian.Uint32(dec.Next(4))) + c.Amount = int64(binary.BigEndian.Uint64(dec.Next(8))) + keys := binary.BigEndian.Uint32(dec.Next(4)) + if keys > 0 { + c.SpentChildren = map[string]bool{} + } + for keys > 0 { + keys-- + keySize := int(binary.BigEndian.Uint16(dec.Next(2))) + key := string(dec.Next(keySize)) + c.SpentChildren[key] = true + } + return nil +} diff --git a/claimtrie/change/claimid.go b/claimtrie/change/claimid.go new file mode 100644 index 00000000..e7a92565 --- /dev/null +++ b/claimtrie/change/claimid.go @@ -0,0 +1,54 @@ +package change + +import ( + "encoding/binary" + "encoding/hex" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" +) + +// ClaimID represents a Claim's ClaimID. +const ClaimIDSize = 20 + +type ClaimID [ClaimIDSize]byte + +// NewClaimID returns a Claim ID calculated from Ripemd160(Sha256(OUTPOINT). +func NewClaimID(op wire.OutPoint) (id ClaimID) { + + var buffer [chainhash.HashSize + 4]byte // hoping for stack alloc + copy(buffer[:], op.Hash[:]) + binary.BigEndian.PutUint32(buffer[chainhash.HashSize:], op.Index) + copy(id[:], btcutil.Hash160(buffer[:])) + return id +} + +// NewIDFromString returns a Claim ID from a string. +func NewIDFromString(s string) (id ClaimID, err error) { + + if len(s) == 40 { + _, err = hex.Decode(id[:], []byte(s)) + } else { + copy(id[:], s) + } + for i, j := 0, len(id)-1; i < j; i, j = i+1, j-1 { + id[i], id[j] = id[j], id[i] + } + return id, err +} + +// Key is for in-memory maps +func (id ClaimID) Key() string { + return string(id[:]) +} + +// String is for anything written to a DB +func (id ClaimID) String() string { + + for i, j := 0, len(id)-1; i < j; i, j = i+1, j-1 { + id[i], id[j] = id[j], id[i] + } + + return hex.EncodeToString(id[:]) +} diff --git a/claimtrie/claimtrie.go b/claimtrie/claimtrie.go new file mode 100644 index 00000000..05d423be --- /dev/null +++ b/claimtrie/claimtrie.go @@ -0,0 +1,485 @@ +package claimtrie + +import ( + "bytes" + "fmt" + "path/filepath" + "runtime" + "sort" + "sync" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/claimtrie/block" + "github.com/lbryio/lbcd/claimtrie/block/blockrepo" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/claimtrie/merkletrie" + "github.com/lbryio/lbcd/claimtrie/merkletrie/merkletrierepo" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/claimtrie/node/noderepo" + "github.com/lbryio/lbcd/claimtrie/normalization" + "github.com/lbryio/lbcd/claimtrie/param" + "github.com/lbryio/lbcd/claimtrie/temporal" + "github.com/lbryio/lbcd/claimtrie/temporal/temporalrepo" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" +) + +// ClaimTrie implements a Merkle Trie supporting linear history of commits. +type ClaimTrie struct { + + // Repository for calculated block hashes. + blockRepo block.Repo + + // Repository for storing temporal information of nodes at each block height. + // For example, which nodes (by name) should be refreshed at each block height + // due to stake expiration or delayed activation. + temporalRepo temporal.Repo + + // Cache layer of Nodes. + nodeManager node.Manager + + // Prefix tree (trie) that manages merkle hash of each node. + merkleTrie merkletrie.MerkleTrie + + // Current block height, which is increased by one when AppendBlock() is called. + height int32 + + // Registrered cleanup functions which are invoked in the Close() in reverse order. + cleanups []func() error +} + +func New(cfg config.Config) (*ClaimTrie, error) { + + var cleanups []func() error + + // The passed in cfg.DataDir has been prepended with netname. + dataDir := filepath.Join(cfg.DataDir, "claim_dbs") + + dbPath := filepath.Join(dataDir, cfg.BlockRepoPebble.Path) + blockRepo, err := blockrepo.NewPebble(dbPath) + if err != nil { + return nil, errors.Wrap(err, "creating block repo") + } + cleanups = append(cleanups, blockRepo.Close) + err = blockRepo.Set(0, merkletrie.EmptyTrieHash) + if err != nil { + return nil, errors.Wrap(err, "setting block repo genesis") + } + + dbPath = filepath.Join(dataDir, cfg.TemporalRepoPebble.Path) + temporalRepo, err := temporalrepo.NewPebble(dbPath) + if err != nil { + return nil, errors.Wrap(err, "creating temporal repo") + } + cleanups = append(cleanups, temporalRepo.Close) + + // Initialize repository for changes to nodes. + // The cleanup is delegated to the Node Manager. + dbPath = filepath.Join(dataDir, cfg.NodeRepoPebble.Path) + nodeRepo, err := noderepo.NewPebble(dbPath) + if err != nil { + return nil, errors.Wrap(err, "creating node repo") + } + + baseManager, err := node.NewBaseManager(nodeRepo) + if err != nil { + return nil, errors.Wrap(err, "creating node base manager") + } + normalizingManager := node.NewNormalizingManager(baseManager) + nodeManager := &node.HashV2Manager{Manager: normalizingManager} + cleanups = append(cleanups, nodeManager.Close) + + var trie merkletrie.MerkleTrie + if cfg.RamTrie { + trie = merkletrie.NewRamTrie() + } else { + + // Initialize repository for MerkleTrie. The cleanup is delegated to MerkleTrie. + dbPath = filepath.Join(dataDir, cfg.MerkleTrieRepoPebble.Path) + trieRepo, err := merkletrierepo.NewPebble(dbPath) + if err != nil { + return nil, errors.Wrap(err, "creating trie repo") + } + + persistentTrie := merkletrie.NewPersistentTrie(trieRepo) + cleanups = append(cleanups, persistentTrie.Close) + trie = persistentTrie + } + + // Restore the last height. + previousHeight, err := blockRepo.Load() + if err != nil { + return nil, errors.Wrap(err, "load block tip") + } + + ct := &ClaimTrie{ + blockRepo: blockRepo, + temporalRepo: temporalRepo, + + nodeManager: nodeManager, + merkleTrie: trie, + + height: previousHeight, + } + + ct.cleanups = cleanups + + if previousHeight > 0 { + hash, err := blockRepo.Get(previousHeight) + if err != nil { + ct.Close() // TODO: the cleanups aren't run when we exit with an err above here (but should be) + return nil, errors.Wrap(err, "block repo get") + } + _, err = nodeManager.IncrementHeightTo(previousHeight) + if err != nil { + ct.Close() + return nil, errors.Wrap(err, "increment height to") + } + err = trie.SetRoot(hash) // keep this after IncrementHeightTo + if err == merkletrie.ErrFullRebuildRequired { + ct.runFullTrieRebuild(nil, cfg.Interrupt) + } + + if interruptRequested(cfg.Interrupt) || !ct.MerkleHash().IsEqual(hash) { + ct.Close() + return nil, errors.Errorf("unable to restore the claim hash to %s at height %d", hash.String(), previousHeight) + } + } + + return ct, nil +} + +// AddClaim adds a Claim to the ClaimTrie. +func (ct *ClaimTrie) AddClaim(name []byte, op wire.OutPoint, id change.ClaimID, amt int64) error { + + chg := change.Change{ + Type: change.AddClaim, + Name: name, + OutPoint: op, + Amount: amt, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// UpdateClaim updates a Claim in the ClaimTrie. +func (ct *ClaimTrie) UpdateClaim(name []byte, op wire.OutPoint, amt int64, id change.ClaimID) error { + + chg := change.Change{ + Type: change.UpdateClaim, + Name: name, + OutPoint: op, + Amount: amt, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// SpendClaim spends a Claim in the ClaimTrie. +func (ct *ClaimTrie) SpendClaim(name []byte, op wire.OutPoint, id change.ClaimID) error { + + chg := change.Change{ + Type: change.SpendClaim, + Name: name, + OutPoint: op, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// AddSupport adds a Support to the ClaimTrie. +func (ct *ClaimTrie) AddSupport(name []byte, op wire.OutPoint, amt int64, id change.ClaimID) error { + + chg := change.Change{ + Type: change.AddSupport, + Name: name, + OutPoint: op, + Amount: amt, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// SpendSupport spends a Support in the ClaimTrie. +func (ct *ClaimTrie) SpendSupport(name []byte, op wire.OutPoint, id change.ClaimID) error { + + chg := change.Change{ + Type: change.SpendSupport, + Name: name, + OutPoint: op, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// AppendBlock increases block by one. +func (ct *ClaimTrie) AppendBlock() error { + + ct.height++ + + names, err := ct.nodeManager.IncrementHeightTo(ct.height) + if err != nil { + return errors.Wrap(err, "node manager increment") + } + + expirations, err := ct.temporalRepo.NodesAt(ct.height) + if err != nil { + return errors.Wrap(err, "temporal repo get") + } + + names = removeDuplicates(names) // comes out sorted + + updateNames := make([][]byte, 0, len(names)+len(expirations)) + updateHeights := make([]int32, 0, len(names)+len(expirations)) + updateNames = append(updateNames, names...) + for range names { // log to the db that we updated a name at this height for rollback purposes + updateHeights = append(updateHeights, ct.height) + } + names = append(names, expirations...) + names = removeDuplicates(names) + + nhns := ct.makeNameHashNext(names, false, nil) + for nhn := range nhns { + + ct.merkleTrie.Update(nhn.Name, nhn.Hash, true) + if nhn.Next <= 0 { + continue + } + + newName := normalization.NormalizeIfNecessary(nhn.Name, nhn.Next) + updateNames = append(updateNames, newName) + updateHeights = append(updateHeights, nhn.Next) + } + if len(updateNames) != 0 { + err = ct.temporalRepo.SetNodesAt(updateNames, updateHeights) + if err != nil { + return errors.Wrap(err, "temporal repo set") + } + } + + hitFork := ct.updateTrieForHashForkIfNecessary() + + h := ct.MerkleHash() + ct.blockRepo.Set(ct.height, h) + + if hitFork { + err = ct.merkleTrie.SetRoot(h) // for clearing the memory entirely + } + + return errors.Wrap(err, "merkle trie clear memory") +} + +func (ct *ClaimTrie) updateTrieForHashForkIfNecessary() bool { + if ct.height != param.ActiveParams.AllClaimsInMerkleForkHeight { + return false + } + + node.LogOnce(fmt.Sprintf("Rebuilding all trie nodes for the hash fork at %d...", ct.height)) + ct.runFullTrieRebuild(nil, nil) // I don't think it's safe to allow interrupt during fork + return true +} + +func removeDuplicates(names [][]byte) [][]byte { // this might be too expensive; we'll have to profile it + sort.Slice(names, func(i, j int) bool { // put names in order so we can skip duplicates + return bytes.Compare(names[i], names[j]) < 0 + }) + + for i := len(names) - 2; i >= 0; i-- { + if bytes.Equal(names[i], names[i+1]) { + names = append(names[:i], names[i+1:]...) + } + } + return names +} + +// ResetHeight resets the ClaimTrie to a previous known height.. +func (ct *ClaimTrie) ResetHeight(height int32) error { + + names := make([][]byte, 0) + for h := height + 1; h <= ct.height; h++ { + results, err := ct.temporalRepo.NodesAt(h) + if err != nil { + return err + } + names = append(names, results...) + } + err := ct.nodeManager.DecrementHeightTo(names, height) + if err != nil { + return err + } + + passedHashFork := ct.height >= param.ActiveParams.AllClaimsInMerkleForkHeight && height < param.ActiveParams.AllClaimsInMerkleForkHeight + hash, err := ct.blockRepo.Get(height) + if err != nil { + return err + } + + oldHeight := ct.height + ct.height = height // keep this before the rebuild + + if passedHashFork { + names = nil // force them to reconsider all names + } + err = ct.merkleTrie.SetRoot(hash) + if err == merkletrie.ErrFullRebuildRequired { + ct.runFullTrieRebuild(names, nil) + } + + if !ct.MerkleHash().IsEqual(hash) { + return errors.Errorf("unable to restore the hash at height %d", height) + } + + return errors.WithStack(ct.blockRepo.Delete(height+1, oldHeight)) +} + +func (ct *ClaimTrie) runFullTrieRebuild(names [][]byte, interrupt <-chan struct{}) { + var nhns chan NameHashNext + if names == nil { + node.LogOnce("Building the entire claim trie in RAM...") + + nhns = ct.makeNameHashNext(nil, true, interrupt) + } else { + nhns = ct.makeNameHashNext(names, false, interrupt) + } + + for nhn := range nhns { + ct.merkleTrie.Update(nhn.Name, nhn.Hash, false) + } +} + +// MerkleHash returns the Merkle Hash of the claimTrie. +func (ct *ClaimTrie) MerkleHash() *chainhash.Hash { + if ct.height >= param.ActiveParams.AllClaimsInMerkleForkHeight { + return ct.merkleTrie.MerkleHashAllClaims() + } + return ct.merkleTrie.MerkleHash() +} + +// Height returns the current block height. +func (ct *ClaimTrie) Height() int32 { + return ct.height +} + +// Close persists states. +// Any calls to the ClaimTrie after Close() being called results undefined behaviour. +func (ct *ClaimTrie) Close() { + + for i := len(ct.cleanups) - 1; i >= 0; i-- { + cleanup := ct.cleanups[i] + err := cleanup() + if err != nil { // it would be better to cleanup what we can than exit early + node.LogOnce("On cleanup: " + err.Error()) + } + } + ct.cleanups = nil +} + +func (ct *ClaimTrie) forwardNodeChange(chg change.Change) error { + + chg.Height = ct.Height() + 1 + ct.nodeManager.AppendChange(chg) + return nil +} + +func (ct *ClaimTrie) NodeAt(height int32, name []byte) (*node.Node, error) { + return ct.nodeManager.NodeAt(height, name) +} + +func (ct *ClaimTrie) NamesChangedInBlock(height int32) ([]string, error) { + hits, err := ct.temporalRepo.NodesAt(height) + r := make([]string, len(hits)) + for i := range hits { + r[i] = string(hits[i]) + } + return r, err +} + +func (ct *ClaimTrie) FlushToDisk() { + // maybe the user can fix the file lock shown in the warning before they shut down + if err := ct.nodeManager.Flush(); err != nil { + node.Warn("During nodeManager flush: " + err.Error()) + } + if err := ct.temporalRepo.Flush(); err != nil { + node.Warn("During temporalRepo flush: " + err.Error()) + } + if err := ct.merkleTrie.Flush(); err != nil { + node.Warn("During merkleTrie flush: " + err.Error()) + } + if err := ct.blockRepo.Flush(); err != nil { + node.Warn("During blockRepo flush: " + err.Error()) + } +} + +type NameHashNext struct { + Name []byte + Hash *chainhash.Hash + Next int32 +} + +func interruptRequested(interrupted <-chan struct{}) bool { + select { + case <-interrupted: // should never block on nil + return true + default: + } + + return false +} + +func (ct *ClaimTrie) makeNameHashNext(names [][]byte, all bool, interrupt <-chan struct{}) chan NameHashNext { + inputs := make(chan []byte, 512) + outputs := make(chan NameHashNext, 512) + + var wg sync.WaitGroup + hashComputationWorker := func() { + for name := range inputs { + hash, next := ct.nodeManager.Hash(name) + outputs <- NameHashNext{name, hash, next} + } + wg.Done() + } + + threads := int(0.8 * float32(runtime.NumCPU())) + if threads < 1 { + threads = 1 + } + for threads > 0 { + threads-- + wg.Add(1) + go hashComputationWorker() + } + go func() { + if all { + ct.nodeManager.IterateNames(func(name []byte) bool { + if interruptRequested(interrupt) { + return false + } + clone := make([]byte, len(name)) + copy(clone, name) // iteration name buffer is reused on future loops + inputs <- clone + return true + }) + } else { + for _, name := range names { + if interruptRequested(interrupt) { + break + } + inputs <- name + } + } + close(inputs) + }() + go func() { + wg.Wait() + close(outputs) + }() + return outputs +} diff --git a/claimtrie/claimtrie_test.go b/claimtrie/claimtrie_test.go new file mode 100644 index 00000000..7cd1432b --- /dev/null +++ b/claimtrie/claimtrie_test.go @@ -0,0 +1,1027 @@ +package claimtrie + +import ( + "math/rand" + "testing" + "time" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/claimtrie/merkletrie" + "github.com/lbryio/lbcd/claimtrie/param" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + + "github.com/stretchr/testify/require" +) + +var cfg = config.DefaultConfig + +func setup(t *testing.T) { + param.SetNetwork(wire.TestNet) + cfg.DataDir = t.TempDir() +} + +func b(s string) []byte { + return []byte(s) +} + +func buildTx(hash chainhash.Hash) *wire.MsgTx { + tx := wire.NewMsgTx(1) + txIn := wire.NewTxIn(wire.NewOutPoint(&hash, 0), nil, nil) + tx.AddTxIn(txIn) + tx.AddTxOut(wire.NewTxOut(0, nil)) + return tx +} + +func TestFixedHashes(t *testing.T) { + + r := require.New(t) + + setup(t) + ct, err := New(cfg) + r.NoError(err) + defer ct.Close() + + r.Equal(merkletrie.EmptyTrieHash[:], ct.MerkleHash()[:]) + + tx1 := buildTx(*merkletrie.EmptyTrieHash) + tx2 := buildTx(tx1.TxHash()) + tx3 := buildTx(tx2.TxHash()) + tx4 := buildTx(tx3.TxHash()) + + err = ct.AddClaim(b("test"), tx1.TxIn[0].PreviousOutPoint, change.NewClaimID(tx1.TxIn[0].PreviousOutPoint), 50) + r.NoError(err) + + err = ct.AddClaim(b("test2"), tx2.TxIn[0].PreviousOutPoint, change.NewClaimID(tx2.TxIn[0].PreviousOutPoint), 50) + r.NoError(err) + + err = ct.AddClaim(b("test"), tx3.TxIn[0].PreviousOutPoint, change.NewClaimID(tx3.TxIn[0].PreviousOutPoint), 50) + r.NoError(err) + + err = ct.AddClaim(b("tes"), tx4.TxIn[0].PreviousOutPoint, change.NewClaimID(tx4.TxIn[0].PreviousOutPoint), 50) + r.NoError(err) + + incrementBlock(r, ct, 1) + + expected, err := chainhash.NewHashFromStr("938fb93364bf8184e0b649c799ae27274e8db5221f1723c99fb2acd3386cfb00") + r.NoError(err) + r.Equal(expected[:], ct.MerkleHash()[:]) +} + +func TestEmptyHashFork(t *testing.T) { + r := require.New(t) + + setup(t) + param.ActiveParams.AllClaimsInMerkleForkHeight = 2 + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + for i := 0; i < 5; i++ { + err := ct.AppendBlock() + r.NoError(err) + } +} + +func TestNormalizationFork(t *testing.T) { + r := require.New(t) + + setup(t) + param.ActiveParams.NormalizedNameForkHeight = 2 + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("AÑEJO"), o1, change.NewClaimID(o1), 10) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("AÑejo"), o2, change.NewClaimID(o2), 5) + r.NoError(err) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddClaim([]byte("あてはまる"), o3, change.NewClaimID(o3), 5) + r.NoError(err) + + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddClaim([]byte("Aḿlie"), o4, change.NewClaimID(o4), 5) + r.NoError(err) + + o5 := wire.OutPoint{Hash: hash, Index: 5} + err = ct.AddClaim([]byte("TEST"), o5, change.NewClaimID(o5), 5) + r.NoError(err) + + o6 := wire.OutPoint{Hash: hash, Index: 6} + err = ct.AddClaim([]byte("test"), o6, change.NewClaimID(o6), 7) + r.NoError(err) + + o7 := wire.OutPoint{Hash: hash, Index: 7} + err = ct.AddSupport([]byte("test"), o7, 11, change.NewClaimID(o6)) + r.NoError(err) + + incrementBlock(r, ct, 1) + r.NotEqual(merkletrie.EmptyTrieHash[:], ct.MerkleHash()[:]) + + n, err := ct.nodeManager.NodeAt(ct.nodeManager.Height(), []byte("AÑEJO")) + r.NoError(err) + r.NotNil(n.BestClaim) + r.Equal(int32(1), n.TakenOverAt) + + o8 := wire.OutPoint{Hash: hash, Index: 8} + err = ct.AddClaim([]byte("aÑEJO"), o8, change.NewClaimID(o8), 8) + r.NoError(err) + + incrementBlock(r, ct, 1) + r.NotEqual(merkletrie.EmptyTrieHash[:], ct.MerkleHash()[:]) + + n, err = ct.nodeManager.NodeAt(ct.nodeManager.Height(), []byte("añejo")) + r.NoError(err) + r.Equal(3, len(n.Claims)) + r.Equal(uint32(1), n.BestClaim.OutPoint.Index) + r.Equal(int32(2), n.TakenOverAt) + + n, err = ct.nodeManager.NodeAt(ct.nodeManager.Height(), []byte("test")) + r.NoError(err) + r.Equal(int64(18), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) +} + +func TestActivationsOnNormalizationFork(t *testing.T) { + + r := require.New(t) + + setup(t) + param.ActiveParams.NormalizedNameForkHeight = 4 + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + + o7 := wire.OutPoint{Hash: hash, Index: 7} + err = ct.AddClaim([]byte("A"), o7, change.NewClaimID(o7), 1) + r.NoError(err) + incrementBlock(r, ct, 3) + verifyBestIndex(t, ct, "A", 7, 1) + + o8 := wire.OutPoint{Hash: hash, Index: 8} + err = ct.AddClaim([]byte("A"), o8, change.NewClaimID(o8), 2) + r.NoError(err) + incrementBlock(r, ct, 1) + verifyBestIndex(t, ct, "a", 8, 2) + + incrementBlock(r, ct, 2) + verifyBestIndex(t, ct, "a", 8, 2) + + err = ct.ResetHeight(3) + r.NoError(err) + verifyBestIndex(t, ct, "A", 7, 1) +} + +func TestNormalizationSortOrder(t *testing.T) { + + r := require.New(t) + // this was an unfortunate bug; the normalization fork should not have activated anything + // alas, it's now part of our history; we hereby test it to keep it that way + setup(t) + param.ActiveParams.NormalizedNameForkHeight = 2 + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("A"), o1, change.NewClaimID(o1), 1) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("A"), o2, change.NewClaimID(o2), 2) + r.NoError(err) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddClaim([]byte("a"), o3, change.NewClaimID(o3), 3) + r.NoError(err) + + incrementBlock(r, ct, 1) + verifyBestIndex(t, ct, "A", 2, 2) + verifyBestIndex(t, ct, "a", 3, 1) + + incrementBlock(r, ct, 1) + verifyBestIndex(t, ct, "a", 3, 3) +} + +func verifyBestIndex(t *testing.T, ct *ClaimTrie, name string, idx uint32, claims int) { + + r := require.New(t) + + n, err := ct.nodeManager.NodeAt(ct.nodeManager.Height(), []byte(name)) + r.NoError(err) + r.Equal(claims, len(n.Claims)) + if claims > 0 { + r.Equal(idx, n.BestClaim.OutPoint.Index) + } +} + +func TestRebuild(t *testing.T) { + r := require.New(t) + setup(t) + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test1"), o1, change.NewClaimID(o1), 1) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test2"), o2, change.NewClaimID(o2), 2) + r.NoError(err) + + incrementBlock(r, ct, 1) + + m := ct.MerkleHash() + r.NotNil(m) + r.NotEqual(*merkletrie.EmptyTrieHash, *m) + + ct.merkleTrie = merkletrie.NewRamTrie() + ct.runFullTrieRebuild(nil, nil) + + m2 := ct.MerkleHash() + r.NotNil(m2) + r.Equal(*m, *m2) +} + +func BenchmarkClaimTrie_AppendBlock256(b *testing.B) { + + addUpdateRemoveRandoms(b, 256) +} + +func BenchmarkClaimTrie_AppendBlock4(b *testing.B) { + + addUpdateRemoveRandoms(b, 4) +} + +func addUpdateRemoveRandoms(b *testing.B, inBlock int) { + rand.Seed(42) + names := make([][]byte, 0, b.N) + + for i := 0; i < b.N; i++ { + names = append(names, randomName()) + } + + var hashes []*chainhash.Hash + + param.SetNetwork(wire.TestNet) + param.ActiveParams.OriginalClaimExpirationTime = 1000000 + param.ActiveParams.ExtendedClaimExpirationTime = 1000000 + cfg.DataDir = b.TempDir() + + r := require.New(b) + ct, err := New(cfg) + r.NoError(err) + defer ct.Close() + h1 := chainhash.Hash{100, 200} + + start := time.Now() + b.ResetTimer() + + c := 0 + for i := 0; i < b.N; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + err = ct.AddClaim(names[i], op, id, 500) + r.NoError(err) + if c++; c%inBlock == inBlock-1 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + + for i := 0; i < b.N; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + op.Hash[0] = 1 + err = ct.UpdateClaim(names[i], op, 400, id) + r.NoError(err) + if c++; c%inBlock == inBlock-1 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + + for i := 0; i < b.N; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + op.Hash[0] = 2 + err = ct.UpdateClaim(names[i], op, 300, id) + r.NoError(err) + if c++; c%inBlock == inBlock-1 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + + for i := 0; i < b.N; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + op.Hash[0] = 3 + err = ct.SpendClaim(names[i], op, id) + r.NoError(err) + if c++; c%inBlock == inBlock-1 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + + b.StopTimer() + ht := ct.height + h1 = *ct.MerkleHash() + b.Logf("Running AppendBlock bench with %d names in %f sec. Height: %d, Hash: %s", + b.N, time.Since(start).Seconds(), ht, h1.String()) + + // a very important test of the functionality: + for ct.height > 0 { + r.True(hashes[ct.height-1].IsEqual(ct.MerkleHash())) + err = ct.ResetHeight(ct.height - 1) + r.NoError(err) + } +} + +func randomName() []byte { + name := make([]byte, rand.Intn(30)+10) + rand.Read(name) + for i := range name { + name[i] %= 56 + name[i] += 65 + } + return name +} + +func incrementBlock(r *require.Assertions, ct *ClaimTrie, c int32) { + h := ct.height + c + if c < 0 { + err := ct.ResetHeight(ct.height + c) + r.NoError(err) + } else { + for ; c > 0; c-- { + err := ct.AppendBlock() + r.NoError(err) + } + } + r.Equal(h, ct.height) +} + +func TestNormalizationRollback(t *testing.T) { + param.SetNetwork(wire.TestNet) + param.ActiveParams.OriginalClaimExpirationTime = 1000000 + param.ActiveParams.ExtendedClaimExpirationTime = 1000000 + cfg.DataDir = t.TempDir() + + r := require.New(t) + ct, err := New(cfg) + r.NoError(err) + defer ct.Close() + + r.Equal(int32(250), param.ActiveParams.NormalizedNameForkHeight) + incrementBlock(r, ct, 247) + + h1 := chainhash.Hash{100, 200} + op := wire.OutPoint{Hash: h1, Index: 1} + id := change.NewClaimID(op) + err = ct.AddClaim([]byte("TEST"), op, id, 1000) + r.NoError(err) + + incrementBlock(r, ct, 5) + incrementBlock(r, ct, -4) + err = ct.SpendClaim([]byte("TEST"), op, id) + r.NoError(err) + incrementBlock(r, ct, 1) + h := ct.MerkleHash() + r.True(h.IsEqual(merkletrie.EmptyTrieHash)) + incrementBlock(r, ct, 3) + h2 := ct.MerkleHash() + r.True(h.IsEqual(h2)) +} + +func TestNormalizationRollbackFuzz(t *testing.T) { + rand.Seed(42) + var hashes []*chainhash.Hash + + param.SetNetwork(wire.TestNet) + param.ActiveParams.OriginalClaimExpirationTime = 1000000 + param.ActiveParams.ExtendedClaimExpirationTime = 1000000 + cfg.DataDir = t.TempDir() + + r := require.New(t) + ct, err := New(cfg) + r.NoError(err) + defer ct.Close() + h1 := chainhash.Hash{100, 200} + + r.Equal(int32(250), param.ActiveParams.NormalizedNameForkHeight) + incrementBlock(r, ct, 240) + + for j := 0; j < 10; j++ { + c := 0 + for i := 0; i < 200; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + err = ct.AddClaim(randomName(), op, id, 500) + r.NoError(err) + if c++; c%10 == 9 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + if j > 7 { + ct.runFullTrieRebuild(nil, nil) + h := ct.MerkleHash() + r.True(h.IsEqual(hashes[len(hashes)-1])) + } + for ct.height > 240 { + r.True(hashes[ct.height-1-240].IsEqual(ct.MerkleHash())) + err = ct.ResetHeight(ct.height - 1) + r.NoError(err) + } + hashes = hashes[:0] + } +} + +func TestClaimReplace(t *testing.T) { + r := require.New(t) + setup(t) + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("bass"), o1, change.NewClaimID(o1), 8) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("basso"), o2, change.NewClaimID(o2), 10) + r.NoError(err) + + incrementBlock(r, ct, 1) + n, err := ct.NodeAt(ct.height, []byte("bass")) + r.Equal(o1.String(), n.BestClaim.OutPoint.String()) + + err = ct.SpendClaim([]byte("bass"), o1, n.BestClaim.ClaimID) + r.NoError(err) + + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddClaim([]byte("bassfisher"), o4, change.NewClaimID(o4), 12) + r.NoError(err) + + incrementBlock(r, ct, 1) + n, err = ct.NodeAt(ct.height, []byte("bass")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) + n, err = ct.NodeAt(ct.height, []byte("bassfisher")) + r.Equal(o4.String(), n.BestClaim.OutPoint.String()) +} + +func TestGeneralClaim(t *testing.T) { + r := require.New(t) + setup(t) + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8) + r.NoError(err) + + incrementBlock(r, ct, 1) + err = ct.ResetHeight(ct.height - 1) + r.NoError(err) + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8) + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8) + r.NoError(err) + + incrementBlock(r, ct, 1) + incrementBlock(r, ct, -1) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8) + r.NoError(err) + incrementBlock(r, ct, 1) + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8) + r.NoError(err) + incrementBlock(r, ct, 1) + + incrementBlock(r, ct, -2) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) +} + +func TestClaimTakeover(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8) + r.NoError(err) + + incrementBlock(r, ct, 10) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 18) + r.NoError(err) + + incrementBlock(r, ct, 10) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o1.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, -1) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o1.String(), n.BestClaim.OutPoint.String()) +} + +func TestSpendClaim(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8) + r.NoError(err) + + incrementBlock(r, ct, 1) + + err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, -1) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddClaim([]byte("test"), o3, change.NewClaimID(o3), 22) + r.NoError(err) + + incrementBlock(r, ct, 10) + + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddClaim([]byte("test"), o4, change.NewClaimID(o4), 28) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o3.String(), n.BestClaim.OutPoint.String()) + + err = ct.SpendClaim([]byte("test"), o3, n.BestClaim.ClaimID) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o4.String(), n.BestClaim.OutPoint.String()) + + err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1)) + r.NoError(err) + err = ct.SpendClaim([]byte("test"), o2, change.NewClaimID(o2)) + r.NoError(err) + err = ct.SpendClaim([]byte("test"), o3, change.NewClaimID(o3)) + r.NoError(err) + err = ct.SpendClaim([]byte("test"), o4, change.NewClaimID(o4)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) + + h := ct.MerkleHash() + r.Equal(merkletrie.EmptyTrieHash.String(), h.String()) +} + +func TestSupportDelay(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8) + r.NoError(err) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddSupport([]byte("test"), o3, 18, change.NewClaimID(o3)) // using bad ClaimID on purpose + r.NoError(err) + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddSupport([]byte("test"), o4, 18, change.NewClaimID(o2)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, 10) + + o5 := wire.OutPoint{Hash: hash, Index: 5} + err = ct.AddSupport([]byte("test"), o5, 18, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, 11) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o1.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, -1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) +} + +func TestSupportSpending(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + + incrementBlock(r, ct, 1) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddSupport([]byte("test"), o3, 18, change.NewClaimID(o1)) + r.NoError(err) + + err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) +} + +func TestSupportOnUpdate(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + + err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1)) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.UpdateClaim([]byte("test"), o2, 28, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(28), n.BestClaim.Amount) + + incrementBlock(r, ct, 1) + + err = ct.SpendClaim([]byte("test"), o2, change.NewClaimID(o1)) + r.NoError(err) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.UpdateClaim([]byte("test"), o3, 38, change.NewClaimID(o1)) + r.NoError(err) + + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddSupport([]byte("test"), o4, 2, change.NewClaimID(o1)) + r.NoError(err) + + o5 := wire.OutPoint{Hash: hash, Index: 5} + err = ct.AddClaim([]byte("test"), o5, change.NewClaimID(o5), 39) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(40), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) + + err = ct.SpendSupport([]byte("test"), o4, n.BestClaim.ClaimID) + r.NoError(err) + + incrementBlock(r, ct, 1) + + // NOTE: LBRYcrd did not test that supports can trigger a takeover correctly (and it doesn't work here): + // n, err = ct.NodeAt(ct.height, []byte("test")) + // r.NoError(err) + // r.Equal(int64(39), n.BestClaim.Amount + n.SupportSums[n.BestClaim.ClaimID.Key()]) +} + +func TestSupportPreservation(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + o2 := wire.OutPoint{Hash: hash, Index: 2} + o3 := wire.OutPoint{Hash: hash, Index: 3} + o4 := wire.OutPoint{Hash: hash, Index: 4} + o5 := wire.OutPoint{Hash: hash, Index: 5} + + err = ct.AddSupport([]byte("test"), o2, 10, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + + err = ct.AddClaim([]byte("test"), o3, change.NewClaimID(o3), 7) + r.NoError(err) + + incrementBlock(r, ct, 10) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(28), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) + + err = ct.AddSupport([]byte("test"), o4, 10, change.NewClaimID(o1)) + r.NoError(err) + err = ct.AddSupport([]byte("test"), o5, 100, change.NewClaimID(o3)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(38), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) + + incrementBlock(r, ct, 10) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(107), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) +} + +func TestInvalidClaimID(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + o2 := wire.OutPoint{Hash: hash, Index: 2} + o3 := wire.OutPoint{Hash: hash, Index: 3} + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 10) + r.NoError(err) + + incrementBlock(r, ct, 1) + + err = ct.SpendClaim([]byte("test"), o3, change.NewClaimID(o1)) + r.NoError(err) + + err = ct.UpdateClaim([]byte("test"), o2, 18, change.NewClaimID(o3)) + r.NoError(err) + + incrementBlock(r, ct, 12) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Len(n.Claims, 1) + r.Len(n.Supports, 0) + r.Equal(int64(10), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) +} + +func TestStableTrieHash(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + param.ActiveParams.AllClaimsInMerkleForkHeight = 8 // changes on this one + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 1) + r.NoError(err) + + incrementBlock(r, ct, 1) + + h := ct.MerkleHash() + r.NotEqual(merkletrie.EmptyTrieHash.String(), h.String()) + + for i := 0; i < 6; i++ { + incrementBlock(r, ct, 1) + r.Equal(h.String(), ct.MerkleHash().String()) + } + + incrementBlock(r, ct, 1) + + r.NotEqual(h.String(), ct.MerkleHash()) + h = ct.MerkleHash() + + for i := 0; i < 16; i++ { + incrementBlock(r, ct, 1) + r.Equal(h.String(), ct.MerkleHash().String()) + } +} + +func TestBlock884431(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + param.ActiveParams.MaxRemovalWorkaroundHeight = 0 + param.ActiveParams.AllClaimsInMerkleForkHeight = 0 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + // in this block we have a scenario where we update all the child names + // which, in the old code, caused a trie vertex to be removed + // which, in turn, would trigger a premature takeover + + c := byte(10) + + add := func(s string, amt int64) wire.OutPoint { + h := chainhash.HashH([]byte{c}) + c++ + o := wire.OutPoint{Hash: h, Index: 1} + err := ct.AddClaim([]byte(s), o, change.NewClaimID(o), amt) + r.NoError(err) + return o + } + + update := func(s string, o wire.OutPoint, amt int64) wire.OutPoint { + err = ct.SpendClaim([]byte(s), o, change.NewClaimID(o)) + r.NoError(err) + + h := chainhash.HashH([]byte{c}) + c++ + o2 := wire.OutPoint{Hash: h, Index: 2} + + err = ct.UpdateClaim([]byte(s), o2, amt, change.NewClaimID(o)) + r.NoError(err) + return o2 + } + + o1a := add("go", 10) + o1b := add("go", 20) + o2 := add("goop", 10) + o3 := add("gog", 20) + + o4a := add("test", 10) + o4b := add("test", 20) + o5 := add("tester", 10) + o6 := add("testing", 20) + + for i := 0; i < 10; i++ { + err = ct.AppendBlock() + r.NoError(err) + } + n, err := ct.NodeAt(ct.height, []byte("go")) + r.NoError(err) + r.Equal(o1b.String(), n.BestClaim.OutPoint.String()) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o4b.String(), n.BestClaim.OutPoint.String()) + + update("go", o1b, 30) + o10 := update("go", o1a, 40) + update("gog", o3, 30) + update("goop", o2, 30) + + update("testing", o6, 30) + o11 := update("test", o4b, 30) + update("test", o4a, 40) + update("tester", o5, 30) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("go")) + r.NoError(err) + r.Equal(o10.String(), n.BestClaim.OutPoint.String()) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o11.String(), n.BestClaim.OutPoint.String()) +} diff --git a/claimtrie/cmd/cmd/block.go b/claimtrie/cmd/cmd/block.go new file mode 100644 index 00000000..d0ee7719 --- /dev/null +++ b/claimtrie/cmd/cmd/block.go @@ -0,0 +1,98 @@ +package cmd + +import ( + "fmt" + + "github.com/cockroachdb/errors" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewBlocCommands()) +} + +func NewBlocCommands() *cobra.Command { + + cmd := &cobra.Command{ + Use: "block", + Short: "Block related commands", + } + + cmd.AddCommand(NewBlockBestCommand()) + cmd.AddCommand(NewBlockListCommand()) + + return cmd +} + +func NewBlockBestCommand() *cobra.Command { + + cmd := &cobra.Command{ + Use: "best", + Short: "Show the height and hash of the best block", + RunE: func(cmd *cobra.Command, args []string) error { + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load blocks database") + } + defer db.Close() + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load chain") + } + + state := chain.BestSnapshot() + fmt.Printf("Block %7d: %s\n", state.Height, state.Hash.String()) + + return nil + }, + } + + return cmd +} + +func NewBlockListCommand() *cobra.Command { + + var fromHeight int32 + var toHeight int32 + + cmd := &cobra.Command{ + Use: "list", + Short: "List merkle hash of blocks between ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load blocks database") + } + defer db.Close() + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load chain") + } + + if toHeight > chain.BestSnapshot().Height { + toHeight = chain.BestSnapshot().Height + } + + for ht := fromHeight; ht <= toHeight; ht++ { + hash, err := chain.BlockHashByHeight(ht) + if err != nil { + return errors.Wrapf(err, "load hash for %d", ht) + } + fmt.Printf("Block %7d: %s\n", ht, hash.String()) + } + + return nil + }, + } + + cmd.Flags().Int32Var(&fromHeight, "from", 0, "From height (inclusive)") + cmd.Flags().Int32Var(&toHeight, "to", 0, "To height (inclusive)") + cmd.Flags().SortFlags = false + + return cmd +} diff --git a/claimtrie/cmd/cmd/chain.go b/claimtrie/cmd/cmd/chain.go new file mode 100644 index 00000000..92e52816 --- /dev/null +++ b/claimtrie/cmd/cmd/chain.go @@ -0,0 +1,441 @@ +package cmd + +import ( + "os" + "path/filepath" + "sync" + "time" + + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/claimtrie" + "github.com/lbryio/lbcd/claimtrie/chain" + "github.com/lbryio/lbcd/claimtrie/chain/chainrepo" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" + + "github.com/cockroachdb/errors" + "github.com/cockroachdb/pebble" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewChainCommands()) +} + +func NewChainCommands() *cobra.Command { + + cmd := &cobra.Command{ + Use: "chain", + Short: "chain related command", + } + + cmd.AddCommand(NewChainDumpCommand()) + cmd.AddCommand(NewChainReplayCommand()) + cmd.AddCommand(NewChainConvertCommand()) + + return cmd +} + +func NewChainDumpCommand() *cobra.Command { + + var chainRepoPath string + var fromHeight int32 + var toHeight int32 + + cmd := &cobra.Command{ + Use: "dump", + Short: "Dump the chain changes between and ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := chainRepoPath + log.Debugf("Open chain repo: %q", dbPath) + chainRepo, err := chainrepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open chain repo") + } + + for height := fromHeight; height <= toHeight; height++ { + changes, err := chainRepo.Load(height) + if errors.Is(err, pebble.ErrNotFound) { + continue + } + if err != nil { + return errors.Wrapf(err, "load charnges for height: %d") + } + for _, chg := range changes { + showChange(chg) + } + } + + return nil + }, + } + + cmd.Flags().StringVar(&chainRepoPath, "chaindb", "chain_db", "Claim operation database") + cmd.Flags().Int32Var(&fromHeight, "from", 0, "From height (inclusive)") + cmd.Flags().Int32Var(&toHeight, "to", 0, "To height (inclusive)") + cmd.Flags().SortFlags = false + + return cmd +} + +func NewChainReplayCommand() *cobra.Command { + + var chainRepoPath string + var fromHeight int32 + var toHeight int32 + + cmd := &cobra.Command{ + Use: "replay", + Short: "Replay the chain changes between and ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + for _, dbName := range []string{ + cfg.BlockRepoPebble.Path, + cfg.NodeRepoPebble.Path, + cfg.MerkleTrieRepoPebble.Path, + cfg.TemporalRepoPebble.Path, + } { + dbPath := filepath.Join(dataDir, netName, "claim_dbs", dbName) + log.Debugf("Delete repo: %q", dbPath) + err := os.RemoveAll(dbPath) + if err != nil { + return errors.Wrapf(err, "delete repo: %q", dbPath) + } + } + + log.Debugf("Open chain repo: %q", chainRepoPath) + chainRepo, err := chainrepo.NewPebble(chainRepoPath) + if err != nil { + return errors.Wrapf(err, "open chain repo") + } + + cfg := config.DefaultConfig + cfg.RamTrie = true + cfg.DataDir = filepath.Join(dataDir, netName) + + ct, err := claimtrie.New(cfg) + if err != nil { + return errors.Wrapf(err, "create claimtrie") + } + defer ct.Close() + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load blocks database") + } + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load chain") + } + + startTime := time.Now() + for ht := fromHeight; ht < toHeight; ht++ { + + changes, err := chainRepo.Load(ht + 1) + if errors.Is(err, pebble.ErrNotFound) { + // do nothing. + } else if err != nil { + return errors.Wrapf(err, "load changes for block %d", ht) + } + + for _, chg := range changes { + + switch chg.Type { + case change.AddClaim: + err = ct.AddClaim(chg.Name, chg.OutPoint, chg.ClaimID, chg.Amount) + case change.UpdateClaim: + err = ct.UpdateClaim(chg.Name, chg.OutPoint, chg.Amount, chg.ClaimID) + case change.SpendClaim: + err = ct.SpendClaim(chg.Name, chg.OutPoint, chg.ClaimID) + case change.AddSupport: + err = ct.AddSupport(chg.Name, chg.OutPoint, chg.Amount, chg.ClaimID) + case change.SpendSupport: + err = ct.SpendSupport(chg.Name, chg.OutPoint, chg.ClaimID) + default: + err = errors.Errorf("invalid change type: %v", chg) + } + + if err != nil { + return errors.Wrapf(err, "execute change %v", chg) + } + } + err = appendBlock(ct, chain) + if err != nil { + return errors.Wrapf(err, "appendBlock") + } + + if time.Since(startTime) > 5*time.Second { + log.Infof("Block: %d", ct.Height()) + startTime = time.Now() + } + } + + return nil + }, + } + + cmd.Flags().StringVar(&chainRepoPath, "chaindb", "chain_db", "Claim operation database") + cmd.Flags().Int32Var(&fromHeight, "from", 0, "From height") + cmd.Flags().Int32Var(&toHeight, "to", 0, "To height") + cmd.Flags().SortFlags = false + + return cmd +} + +func appendBlock(ct *claimtrie.ClaimTrie, chain *blockchain.BlockChain) error { + + err := ct.AppendBlock() + if err != nil { + return errors.Wrapf(err, "append block: %w") + } + + blockHash, err := chain.BlockHashByHeight(ct.Height()) + if err != nil { + return errors.Wrapf(err, "load from block repo: %w") + } + + header, err := chain.HeaderByHash(blockHash) + + if err != nil { + return errors.Wrapf(err, "load from block repo: %w") + } + + if *ct.MerkleHash() != header.ClaimTrie { + return errors.Errorf("hash mismatched at height %5d: exp: %s, got: %s", + ct.Height(), header.ClaimTrie, ct.MerkleHash()) + } + + return nil +} + +func NewChainConvertCommand() *cobra.Command { + + var chainRepoPath string + var toHeight int32 + + cmd := &cobra.Command{ + Use: "convert", + Short: "convert changes from 0 to ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load block db") + } + defer db.Close() + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load block db") + } + + if toHeight > chain.BestSnapshot().Height { + toHeight = chain.BestSnapshot().Height + } + + chainRepo, err := chainrepo.NewPebble(chainRepoPath) + if err != nil { + return errors.Wrapf(err, "open chain repo: %v") + } + defer chainRepo.Close() + + converter := chainConverter{ + db: db, + chain: chain, + chainRepo: chainRepo, + toHeight: toHeight, + blockChan: make(chan *btcutil.Block, 1000), + changesChan: make(chan []change.Change, 1000), + wg: &sync.WaitGroup{}, + stat: &stat{}, + } + + startTime := time.Now() + err = converter.start() + if err != nil { + return errors.Wrapf(err, "start Converter") + } + + converter.wait() + log.Infof("Convert chain: took %s", time.Since(startTime)) + + return nil + }, + } + + cmd.Flags().StringVar(&chainRepoPath, "chaindb", "chain_db", "Claim operation database") + cmd.Flags().Int32Var(&toHeight, "to", 0, "toHeight") + cmd.Flags().SortFlags = false + return cmd +} + +type stat struct { + blocksFetched int + blocksProcessed int + changesSaved int +} + +type chainConverter struct { + db database.DB + chain *blockchain.BlockChain + chainRepo chain.Repo + toHeight int32 + + blockChan chan *btcutil.Block + changesChan chan []change.Change + + wg *sync.WaitGroup + + stat *stat +} + +func (cc *chainConverter) wait() { + cc.wg.Wait() +} + +func (cb *chainConverter) start() error { + + go cb.reportStats() + + cb.wg.Add(3) + go cb.getBlock() + go cb.processBlock() + go cb.saveChanges() + + return nil +} + +func (cb *chainConverter) getBlock() { + defer cb.wg.Done() + defer close(cb.blockChan) + + for ht := int32(0); ht < cb.toHeight; ht++ { + block, err := cb.chain.BlockByHeight(ht) + if err != nil { + if errors.Cause(err).Error() == "too many open files" { + err = errors.WithHintf(err, "try ulimit -n 2048") + } + log.Errorf("load changes at %d: %s", ht, err) + return + } + cb.stat.blocksFetched++ + cb.blockChan <- block + } +} + +func (cb *chainConverter) processBlock() { + defer cb.wg.Done() + defer close(cb.changesChan) + + utxoPubScripts := map[wire.OutPoint][]byte{} + for block := range cb.blockChan { + var changes []change.Change + for _, tx := range block.Transactions() { + + if blockchain.IsCoinBase(tx) { + continue + } + + for _, txIn := range tx.MsgTx().TxIn { + prevOutpoint := txIn.PreviousOutPoint + pkScript := utxoPubScripts[prevOutpoint] + cs, err := txscript.ExtractClaimScript(pkScript) + if txscript.IsErrorCode(err, txscript.ErrNotClaimScript) { + continue + } + if err != nil { + log.Criticalf("Can't parse claim script: %s", err) + } + + chg := change.Change{ + Height: block.Height(), + Name: cs.Name, + OutPoint: txIn.PreviousOutPoint, + } + delete(utxoPubScripts, prevOutpoint) + + switch cs.Opcode { + case txscript.OP_CLAIMNAME: + chg.Type = change.SpendClaim + chg.ClaimID = change.NewClaimID(chg.OutPoint) + case txscript.OP_UPDATECLAIM: + chg.Type = change.SpendClaim + copy(chg.ClaimID[:], cs.ClaimID) + case txscript.OP_SUPPORTCLAIM: + chg.Type = change.SpendSupport + copy(chg.ClaimID[:], cs.ClaimID) + } + + changes = append(changes, chg) + } + + op := *wire.NewOutPoint(tx.Hash(), 0) + for i, txOut := range tx.MsgTx().TxOut { + cs, err := txscript.ExtractClaimScript(txOut.PkScript) + if txscript.IsErrorCode(err, txscript.ErrNotClaimScript) { + continue + } + + op.Index = uint32(i) + chg := change.Change{ + Height: block.Height(), + Name: cs.Name, + OutPoint: op, + Amount: txOut.Value, + } + utxoPubScripts[op] = txOut.PkScript + + switch cs.Opcode { + case txscript.OP_CLAIMNAME: + chg.Type = change.AddClaim + chg.ClaimID = change.NewClaimID(op) + case txscript.OP_SUPPORTCLAIM: + chg.Type = change.AddSupport + copy(chg.ClaimID[:], cs.ClaimID) + case txscript.OP_UPDATECLAIM: + chg.Type = change.UpdateClaim + copy(chg.ClaimID[:], cs.ClaimID) + } + changes = append(changes, chg) + } + } + cb.stat.blocksProcessed++ + + if len(changes) != 0 { + cb.changesChan <- changes + } + } +} + +func (cb *chainConverter) saveChanges() { + defer cb.wg.Done() + + for changes := range cb.changesChan { + err := cb.chainRepo.Save(changes[0].Height, changes) + if err != nil { + log.Errorf("save to chain repo: %s", err) + return + } + cb.stat.changesSaved++ + } +} + +func (cb *chainConverter) reportStats() { + stat := cb.stat + tick := time.NewTicker(5 * time.Second) + for range tick.C { + log.Infof("block : %7d / %7d, changes saved: %d", + stat.blocksFetched, stat.blocksProcessed, stat.changesSaved) + + } +} diff --git a/claimtrie/cmd/cmd/helper.go b/claimtrie/cmd/cmd/helper.go new file mode 100644 index 00000000..e75da402 --- /dev/null +++ b/claimtrie/cmd/cmd/helper.go @@ -0,0 +1,62 @@ +package cmd + +import ( + "path/filepath" + "time" + + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + + "github.com/cockroachdb/errors" +) + +func loadBlocksDB() (database.DB, error) { + + dbPath := filepath.Join(dataDir, netName, "blocks_ffldb") + log.Infof("Loading blocks database: %s", dbPath) + db, err := database.Open("ffldb", dbPath, chainPramas().Net) + if err != nil { + return nil, errors.Wrapf(err, "open blocks database") + } + + return db, nil +} + +func loadChain(db database.DB) (*blockchain.BlockChain, error) { + paramsCopy := chaincfg.MainNetParams + + log.Infof("Loading chain from database") + + startTime := time.Now() + chain, err := blockchain.New(&blockchain.Config{ + DB: db, + ChainParams: ¶msCopy, + TimeSource: blockchain.NewMedianTime(), + SigCache: txscript.NewSigCache(1000), + }) + if err != nil { + return nil, errors.Wrapf(err, "create blockchain") + } + + log.Infof("Loaded chain from database (%s)", time.Since(startTime)) + + return chain, err + +} + +func chainPramas() chaincfg.Params { + + // Make a copy so the user won't modify the global instance. + params := chaincfg.MainNetParams + switch netName { + case "mainnet": + params = chaincfg.MainNetParams + case "testnet": + params = chaincfg.TestNet3Params + case "regtest": + params = chaincfg.RegressionNetParams + } + return params +} diff --git a/claimtrie/cmd/cmd/merkletrie.go b/claimtrie/cmd/cmd/merkletrie.go new file mode 100644 index 00000000..66694c98 --- /dev/null +++ b/claimtrie/cmd/cmd/merkletrie.go @@ -0,0 +1,105 @@ +package cmd + +import ( + "fmt" + "path/filepath" + + "github.com/lbryio/lbcd/claimtrie/merkletrie" + "github.com/lbryio/lbcd/claimtrie/merkletrie/merkletrierepo" + "github.com/lbryio/lbcd/claimtrie/temporal/temporalrepo" + + "github.com/cockroachdb/errors" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewTrieCommands()) +} + +func NewTrieCommands() *cobra.Command { + + cmd := &cobra.Command{ + Use: "trie", + Short: "MerkleTrie related commands", + } + + cmd.AddCommand(NewTrieNameCommand()) + + return cmd +} + +func NewTrieNameCommand() *cobra.Command { + + var height int32 + var name string + + cmd := &cobra.Command{ + Use: "name", + Short: "List the claim and child hashes at vertex name of block at height", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load blocks database") + } + defer db.Close() + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load chain") + } + + state := chain.BestSnapshot() + fmt.Printf("Block %7d: %s\n", state.Height, state.Hash.String()) + + if height > state.Height { + return errors.New("requested height is unavailable") + } + + hash := state.Hash + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.MerkleTrieRepoPebble.Path) + log.Debugf("Open merkletrie repo: %q", dbPath) + trieRepo, err := merkletrierepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open merkle trie repo") + } + + trie := merkletrie.NewPersistentTrie(trieRepo) + defer trie.Close() + + trie.SetRoot(&hash) + + if len(name) > 1 { + trie.Dump(name) + return nil + } + + dbPath = filepath.Join(dataDir, netName, "claim_dbs", cfg.TemporalRepoPebble.Path) + log.Debugf("Open temporal repo: %q", dbPath) + tmpRepo, err := temporalrepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open temporal repo") + } + + nodes, err := tmpRepo.NodesAt(height) + if err != nil { + return errors.Wrapf(err, "read temporal repo at %d", height) + } + + for _, name := range nodes { + fmt.Printf("Name: %s, ", string(name)) + trie.Dump(string(name)) + } + + return nil + }, + } + + cmd.Flags().Int32Var(&height, "height", 0, "Height") + cmd.Flags().StringVar(&name, "name", "", "Name") + cmd.Flags().SortFlags = false + + return cmd +} diff --git a/claimtrie/cmd/cmd/node.go b/claimtrie/cmd/cmd/node.go new file mode 100644 index 00000000..08112e94 --- /dev/null +++ b/claimtrie/cmd/cmd/node.go @@ -0,0 +1,194 @@ +package cmd + +import ( + "encoding/hex" + "fmt" + "math" + "path/filepath" + + "github.com/cockroachdb/errors" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/claimtrie/node/noderepo" + + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewNodeCommands()) +} + +func NewNodeCommands() *cobra.Command { + + cmd := &cobra.Command{ + Use: "node", + Short: "Replay the application of changes on a node up to certain height", + } + + cmd.AddCommand(NewNodeDumpCommand()) + cmd.AddCommand(NewNodeReplayCommand()) + cmd.AddCommand(NewNodeChildrenCommand()) + cmd.AddCommand(NewNodeStatsCommand()) + + return cmd +} + +func NewNodeDumpCommand() *cobra.Command { + + var name string + var height int32 + + cmd := &cobra.Command{ + Use: "dump", + Short: "Replay the application of changes on a node up to certain height", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.NodeRepoPebble.Path) + log.Debugf("Open node repo: %q", dbPath) + repo, err := noderepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open node repo") + } + defer repo.Close() + + changes, err := repo.LoadChanges([]byte(name)) + if err != nil { + return errors.Wrapf(err, "load commands") + } + + for _, chg := range changes { + if chg.Height > height { + break + } + showChange(chg) + } + + return nil + }, + } + + cmd.Flags().StringVar(&name, "name", "", "Name") + cmd.MarkFlagRequired("name") + cmd.Flags().Int32Var(&height, "height", math.MaxInt32, "Height") + + return cmd +} + +func NewNodeReplayCommand() *cobra.Command { + + var name string + var height int32 + + cmd := &cobra.Command{ + Use: "replay", + Short: "Replay the changes of up to ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.NodeRepoPebble.Path) + log.Debugf("Open node repo: %q", dbPath) + repo, err := noderepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open node repo") + } + + bm, err := node.NewBaseManager(repo) + if err != nil { + return errors.Wrapf(err, "create node manager") + } + defer bm.Close() + + nm := node.NewNormalizingManager(bm) + + n, err := nm.NodeAt(height, []byte(name)) + if err != nil || n == nil { + return errors.Wrapf(err, "get node: %s", name) + } + + showNode(n) + return nil + }, + } + + cmd.Flags().StringVar(&name, "name", "", "Name") + cmd.MarkFlagRequired("name") + cmd.Flags().Int32Var(&height, "height", 0, "Height (inclusive)") + cmd.Flags().SortFlags = false + + return cmd +} + +func NewNodeChildrenCommand() *cobra.Command { + + var name string + + cmd := &cobra.Command{ + Use: "children", + Short: "Show all the children names of a given node name", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.NodeRepoPebble.Path) + log.Debugf("Open node repo: %q", dbPath) + repo, err := noderepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open node repo") + } + defer repo.Close() + + fn := func(changes []change.Change) bool { + fmt.Printf("Name: %s, Height: %d, %d\n", changes[0].Name, changes[0].Height, + changes[len(changes)-1].Height) + return true + } + + err = repo.IterateChildren([]byte(name), fn) + if err != nil { + return errors.Wrapf(err, "iterate children: %s", name) + } + + return nil + }, + } + + cmd.Flags().StringVar(&name, "name", "", "Name") + cmd.MarkFlagRequired("name") + + return cmd +} + +func NewNodeStatsCommand() *cobra.Command { + + cmd := &cobra.Command{ + Use: "stat", + Short: "Determine the number of unique names, average changes per name, etc.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.NodeRepoPebble.Path) + log.Debugf("Open node repo: %q", dbPath) + repo, err := noderepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open node repo") + } + defer repo.Close() + + n := 0 + c := 0 + err = repo.IterateChildren([]byte{}, func(changes []change.Change) bool { + c += len(changes) + n++ + if len(changes) > 5000 { + fmt.Printf("Name: %s, Hex: %s, Changes: %d\n", string(changes[0].Name), + hex.EncodeToString(changes[0].Name), len(changes)) + } + return true + }) + fmt.Printf("\nNames: %d, Average changes: %.2f\n", n, float64(c)/float64(n)) + return errors.Wrapf(err, "iterate node repo") + }, + } + + return cmd +} diff --git a/claimtrie/cmd/cmd/root.go b/claimtrie/cmd/cmd/root.go new file mode 100644 index 00000000..8b2fb75f --- /dev/null +++ b/claimtrie/cmd/cmd/root.go @@ -0,0 +1,61 @@ +package cmd + +import ( + "os" + + "github.com/btcsuite/btclog" + "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/claimtrie/param" + "github.com/lbryio/lbcd/limits" + "github.com/lbryio/lbcd/wire" + + "github.com/spf13/cobra" +) + +var ( + log btclog.Logger + cfg = config.DefaultConfig + netName string + dataDir string +) + +var rootCmd = NewRootCommand() + +func NewRootCommand() *cobra.Command { + + cmd := &cobra.Command{ + Use: "claimtrie", + Short: "ClaimTrie Command Line Interface", + SilenceUsage: true, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + switch netName { + case "mainnet": + param.SetNetwork(wire.MainNet) + case "testnet": + param.SetNetwork(wire.TestNet3) + case "regtest": + param.SetNetwork(wire.TestNet) + } + }, + } + + cmd.PersistentFlags().StringVar(&netName, "netname", "mainnet", "Net name") + cmd.PersistentFlags().StringVarP(&dataDir, "datadir", "b", cfg.DataDir, "Data dir") + + return cmd +} + +func Execute() { + + backendLogger := btclog.NewBackend(os.Stdout) + defer os.Stdout.Sync() + log = backendLogger.Logger("CMDL") + log.SetLevel(btclog.LevelDebug) + + // Up some limits. + if err := limits.SetLimits(); err != nil { + log.Errorf("failed to set limits: %v\n", err) + } + + rootCmd.Execute() // nolint : errchk +} diff --git a/claimtrie/cmd/cmd/temporal.go b/claimtrie/cmd/cmd/temporal.go new file mode 100644 index 00000000..67d3397c --- /dev/null +++ b/claimtrie/cmd/cmd/temporal.go @@ -0,0 +1,60 @@ +package cmd + +import ( + "path/filepath" + + "github.com/lbryio/lbcd/claimtrie/temporal/temporalrepo" + + "github.com/cockroachdb/errors" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewTemporalCommand()) +} + +func NewTemporalCommand() *cobra.Command { + + var fromHeight int32 + var toHeight int32 + + cmd := &cobra.Command{ + Use: "temporal", + Short: "List which nodes are update in a range of heights", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.TemporalRepoPebble.Path) + log.Debugf("Open temporal repo: %s", dbPath) + repo, err := temporalrepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open temporal repo") + } + + if toHeight <= 0 { + toHeight = fromHeight + } + + for ht := fromHeight; ht <= toHeight; ht++ { + names, err := repo.NodesAt(ht) + if err != nil { + return errors.Wrapf(err, "get node names from temporal") + } + + if len(names) == 0 { + continue + } + + showTemporalNames(ht, names) + } + + return nil + }, + } + + cmd.Flags().Int32Var(&fromHeight, "from", 0, "From height (inclusive)") + cmd.Flags().Int32Var(&toHeight, "to", 0, "To height (inclusive)") + cmd.Flags().SortFlags = false + + return cmd +} diff --git a/claimtrie/cmd/cmd/ui.go b/claimtrie/cmd/cmd/ui.go new file mode 100644 index 00000000..9882b474 --- /dev/null +++ b/claimtrie/cmd/cmd/ui.go @@ -0,0 +1,76 @@ +package cmd + +import ( + "fmt" + "strings" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node" +) + +var status = map[node.Status]string{ + node.Accepted: "Accepted", + node.Activated: "Activated", + node.Deactivated: "Deactivated", +} + +func changeType(c change.ChangeType) string { + switch c { + case change.AddClaim: + return "AddClaim" + case change.SpendClaim: + return "SpendClaim" + case change.UpdateClaim: + return "UpdateClaim" + case change.AddSupport: + return "AddSupport" + case change.SpendSupport: + return "SpendSupport" + } + return "Unknown" +} + +func showChange(chg change.Change) { + fmt.Printf(">>> Height: %6d: %s for %04s, %15d, %s - %s\n", + chg.Height, changeType(chg.Type), chg.ClaimID, chg.Amount, chg.OutPoint, chg.Name) +} + +func showClaim(c *node.Claim, n *node.Node) { + mark := " " + if c == n.BestClaim { + mark = "*" + } + + fmt.Printf("%s C ID: %s, TXO: %s\n %5d/%-5d, Status: %9s, Amount: %15d, Support Amount: %15d\n", + mark, c.ClaimID, c.OutPoint, c.AcceptedAt, c.ActiveAt, status[c.Status], c.Amount, n.SupportSums[c.ClaimID.Key()]) +} + +func showSupport(c *node.Claim) { + fmt.Printf(" S id: %s, op: %s, %5d/%-5d, %9s, amt: %15d\n", + c.ClaimID, c.OutPoint, c.AcceptedAt, c.ActiveAt, status[c.Status], c.Amount) +} + +func showNode(n *node.Node) { + + fmt.Printf("%s\n", strings.Repeat("-", 200)) + fmt.Printf("Last Node Takeover: %d\n\n", n.TakenOverAt) + n.SortClaimsByBid() + for _, c := range n.Claims { + showClaim(c, n) + for _, s := range n.Supports { + if s.ClaimID != c.ClaimID { + continue + } + showSupport(s) + } + } + fmt.Printf("\n\n") +} + +func showTemporalNames(height int32, names [][]byte) { + fmt.Printf("%7d: %q", height, names[0]) + for _, name := range names[1:] { + fmt.Printf(", %q ", name) + } + fmt.Printf("\n") +} diff --git a/claimtrie/cmd/main.go b/claimtrie/cmd/main.go new file mode 100644 index 00000000..b87adc7d --- /dev/null +++ b/claimtrie/cmd/main.go @@ -0,0 +1,9 @@ +package main + +import ( + "github.com/lbryio/lbcd/claimtrie/cmd/cmd" +) + +func main() { + cmd.Execute() +} diff --git a/claimtrie/config/config.go b/claimtrie/config/config.go new file mode 100644 index 00000000..4920ca17 --- /dev/null +++ b/claimtrie/config/config.go @@ -0,0 +1,49 @@ +package config + +import ( + "path/filepath" + + "github.com/lbryio/lbcd/claimtrie/param" + btcutil "github.com/lbryio/lbcutil" +) + +var DefaultConfig = Config{ + Params: param.MainNet, + + RamTrie: true, // as it stands the other trie uses more RAM, more time, and 40GB+ of disk space + + DataDir: filepath.Join(btcutil.AppDataDir("chain", false), "data"), + + BlockRepoPebble: pebbleConfig{ + Path: "blocks_pebble_db", + }, + NodeRepoPebble: pebbleConfig{ + Path: "node_change_pebble_db", + }, + TemporalRepoPebble: pebbleConfig{ + Path: "temporal_pebble_db", + }, + MerkleTrieRepoPebble: pebbleConfig{ + Path: "merkletrie_pebble_db", + }, +} + +// Config is the container of all configurations. +type Config struct { + Params param.ClaimTrieParams + + RamTrie bool + + DataDir string + + BlockRepoPebble pebbleConfig + NodeRepoPebble pebbleConfig + TemporalRepoPebble pebbleConfig + MerkleTrieRepoPebble pebbleConfig + + Interrupt <-chan struct{} +} + +type pebbleConfig struct { + Path string +} diff --git a/claimtrie/merkletrie/collapsedtrie.go b/claimtrie/merkletrie/collapsedtrie.go new file mode 100644 index 00000000..18af30a0 --- /dev/null +++ b/claimtrie/merkletrie/collapsedtrie.go @@ -0,0 +1,235 @@ +package merkletrie + +import ( + "github.com/lbryio/lbcd/chaincfg/chainhash" +) + +type KeyType []byte + +type collapsedVertex struct { + children []*collapsedVertex + key KeyType + merkleHash *chainhash.Hash + claimHash *chainhash.Hash +} + +// insertAt inserts v into s at index i and returns the new slice. +// https://stackoverflow.com/questions/42746972/golang-insert-to-a-sorted-slice +func insertAt(data []*collapsedVertex, i int, v *collapsedVertex) []*collapsedVertex { + if i == len(data) { + // Insert at end is the easy case. + return append(data, v) + } + + // Make space for the inserted element by shifting + // values at the insertion index up one index. The call + // to append does not allocate memory when cap(data) is + // greater than len(data). + data = append(data[:i+1], data[i:]...) + data[i] = v + return data +} + +func (ptn *collapsedVertex) Insert(value *collapsedVertex) *collapsedVertex { + // keep it sorted (and sort.Sort is too slow) + index := sortSearch(ptn.children, value.key[0]) + ptn.children = insertAt(ptn.children, index, value) + + return value +} + +// this sort.Search is stolen shamelessly from search.go, +// and modified for performance to not need a closure +func sortSearch(nodes []*collapsedVertex, b byte) int { + i, j := 0, len(nodes) + for i < j { + h := int(uint(i+j) >> 1) // avoid overflow when computing h + // i ≤ h < j + if nodes[h].key[0] < b { + i = h + 1 // preserves f(i-1) == false + } else { + j = h // preserves f(j) == true + } + } + // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. + return i +} + +func (ptn *collapsedVertex) findNearest(key KeyType) (int, *collapsedVertex) { + // none of the children overlap on the first char or we would have a parent node with that char + index := sortSearch(ptn.children, key[0]) + hits := ptn.children[index:] + if len(hits) > 0 { + return index, hits[0] + } + return -1, nil +} + +type collapsedTrie struct { + Root *collapsedVertex + Nodes int +} + +func NewCollapsedTrie() *collapsedTrie { + // we never delete the Root node + return &collapsedTrie{Root: &collapsedVertex{key: make(KeyType, 0)}, Nodes: 1} +} + +func (pt *collapsedTrie) NodeCount() int { + return pt.Nodes +} + +func matchLength(a, b KeyType) int { + minLen := len(a) + if len(b) < minLen { + minLen = len(b) + } + for i := 0; i < minLen; i++ { + if a[i] != b[i] { + return i + } + } + return minLen +} + +func (pt *collapsedTrie) insert(value KeyType, node *collapsedVertex) (bool, *collapsedVertex) { + index, child := node.findNearest(value) + match := 0 + if index >= 0 { // if we found a child + child.merkleHash = nil + match = matchLength(value, child.key) + if len(value) == match && len(child.key) == match { + return false, child + } + } + if match <= 0 { + pt.Nodes++ + return true, node.Insert(&collapsedVertex{key: value}) + } + if match < len(child.key) { + grandChild := collapsedVertex{key: child.key[match:], children: child.children, + claimHash: child.claimHash, merkleHash: child.merkleHash} + newChild := collapsedVertex{key: child.key[0:match], children: []*collapsedVertex{&grandChild}} + child = &newChild + node.children[index] = child + pt.Nodes++ + if len(value) == match { + return true, child + } + } + return pt.insert(value[match:], child) +} + +func (pt *collapsedTrie) InsertOrFind(value KeyType) (bool, *collapsedVertex) { + pt.Root.merkleHash = nil + if len(value) <= 0 { + return false, pt.Root + } + + // we store the name so we need to make our own copy of it + // this avoids errors where this function is called via the DB iterator + v2 := make([]byte, len(value)) + copy(v2, value) + return pt.insert(v2, pt.Root) +} + +func find(value KeyType, node *collapsedVertex, pathIndexes *[]int, path *[]*collapsedVertex) *collapsedVertex { + index, child := node.findNearest(value) + if index < 0 { + return nil + } + match := matchLength(value, child.key) + if len(value) == match && len(child.key) == match { + if pathIndexes != nil { + *pathIndexes = append(*pathIndexes, index) + } + if path != nil { + *path = append(*path, child) + } + return child + } + if match < len(child.key) || match == len(value) { + return nil + } + if pathIndexes != nil { + *pathIndexes = append(*pathIndexes, index) + } + if path != nil { + *path = append(*path, child) + } + return find(value[match:], child, pathIndexes, path) +} + +func (pt *collapsedTrie) Find(value KeyType) *collapsedVertex { + if len(value) <= 0 { + return pt.Root + } + return find(value, pt.Root, nil, nil) +} + +func (pt *collapsedTrie) FindPath(value KeyType) ([]int, []*collapsedVertex) { + pathIndexes := []int{-1} + path := []*collapsedVertex{pt.Root} + if len(value) > 0 { + result := find(value, pt.Root, &pathIndexes, &path) + if result == nil { // not sure I want this line + return nil, nil + } + } + return pathIndexes, path +} + +// IterateFrom can be used to find a value and run a function on that value. +// If the handler returns true it continues to iterate through the children of value. +func (pt *collapsedTrie) IterateFrom(start KeyType, handler func(name KeyType, value *collapsedVertex) bool) { + node := find(start, pt.Root, nil, nil) + if node == nil { + return + } + iterateFrom(start, node, handler) +} + +func iterateFrom(name KeyType, node *collapsedVertex, handler func(name KeyType, value *collapsedVertex) bool) { + for handler(name, node) { + for _, child := range node.children { + iterateFrom(append(name, child.key...), child, handler) + } + } +} + +func (pt *collapsedTrie) Erase(value KeyType) bool { + indexes, path := pt.FindPath(value) + if path == nil || len(path) <= 1 { + if len(path) == 1 { + path[0].merkleHash = nil + path[0].claimHash = nil + } + return false + } + nodes := pt.Nodes + i := len(path) - 1 + path[i].claimHash = nil // this is the thing we are erasing; the rest is book-keeping + for ; i > 0; i-- { + childCount := len(path[i].children) + noClaimData := path[i].claimHash == nil + path[i].merkleHash = nil + if childCount == 1 && noClaimData { + path[i].key = append(path[i].key, path[i].children[0].key...) + path[i].claimHash = path[i].children[0].claimHash + path[i].children = path[i].children[0].children + pt.Nodes-- + continue + } + if childCount == 0 && noClaimData { + index := indexes[i] + path[i-1].children = append(path[i-1].children[:index], path[i-1].children[index+1:]...) + pt.Nodes-- + continue + } + break + } + for ; i >= 0; i-- { + path[i].merkleHash = nil + } + return nodes > pt.Nodes +} diff --git a/claimtrie/merkletrie/collapsedtrie_test.go b/claimtrie/merkletrie/collapsedtrie_test.go new file mode 100644 index 00000000..ce41c35f --- /dev/null +++ b/claimtrie/merkletrie/collapsedtrie_test.go @@ -0,0 +1,113 @@ +package merkletrie + +import ( + "bytes" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func b(value string) []byte { return []byte(value) } +func eq(x []byte, y string) bool { return bytes.Equal(x, b(y)) } + +func TestInsertAndErase(t *testing.T) { + trie := NewCollapsedTrie() + assert.True(t, trie.NodeCount() == 1) + inserted, node := trie.InsertOrFind(b("abc")) + assert.True(t, inserted) + assert.NotNil(t, node) + assert.Equal(t, 2, trie.NodeCount()) + inserted, node = trie.InsertOrFind(b("abd")) + assert.True(t, inserted) + assert.Equal(t, 4, trie.NodeCount()) + assert.NotNil(t, node) + hit := trie.Find(b("ab")) + assert.True(t, eq(hit.key, "ab")) + assert.Equal(t, 2, len(hit.children)) + hit = trie.Find(b("abc")) + assert.True(t, eq(hit.key, "c")) + hit = trie.Find(b("abd")) + assert.True(t, eq(hit.key, "d")) + hit = trie.Find(b("a")) + assert.Nil(t, hit) + indexes, path := trie.FindPath(b("abd")) + assert.Equal(t, 3, len(indexes)) + assert.True(t, eq(path[1].key, "ab")) + erased := trie.Erase(b("ab")) + assert.False(t, erased) + assert.Equal(t, 4, trie.NodeCount()) + erased = trie.Erase(b("abc")) + assert.True(t, erased) + assert.Equal(t, 2, trie.NodeCount()) + erased = trie.Erase(b("abd")) + assert.True(t, erased) + assert.Equal(t, 1, trie.NodeCount()) +} + +func TestNilNameHandling(t *testing.T) { + trie := NewCollapsedTrie() + inserted, n := trie.InsertOrFind([]byte("test")) + assert.True(t, inserted) + n.claimHash = EmptyTrieHash + inserted, n = trie.InsertOrFind(nil) + assert.False(t, inserted) + n.claimHash = EmptyTrieHash + n.merkleHash = EmptyTrieHash + inserted, n = trie.InsertOrFind(nil) + assert.False(t, inserted) + assert.NotNil(t, n.claimHash) + assert.Nil(t, n.merkleHash) + nodeRemoved := trie.Erase(nil) + assert.False(t, nodeRemoved) + inserted, n = trie.InsertOrFind(nil) + assert.False(t, inserted) + assert.Nil(t, n.claimHash) +} + +func TestCollapsedTriePerformance(t *testing.T) { + inserts := 100000 // increase this to 1M for more interesting results + data := make([][]byte, inserts) + rand.Seed(42) + for i := 0; i < inserts; i++ { + size := rand.Intn(70) + 4 + data[i] = make([]byte, size) + rand.Read(data[i]) + for j := 0; j < size; j++ { + data[i][j] %= byte(62) // shrink the range to match the old test + } + } + + trie := NewCollapsedTrie() + // doing my own timing because I couldn't get the B.Run method to work: + start := time.Now() + for i := 0; i < inserts; i++ { + _, node := trie.InsertOrFind(data[i]) + assert.NotNil(t, node, "Failure at %d of %d", i, inserts) + } + t.Logf("Insertion in %f sec.", time.Since(start).Seconds()) + + start = time.Now() + for i := 0; i < inserts; i++ { + node := trie.Find(data[i]) + assert.True(t, bytes.HasSuffix(data[i], node.key), "Failure on %d of %d", i, inserts) + } + t.Logf("Lookup in %f sec. on %d nodes.", time.Since(start).Seconds(), trie.NodeCount()) + + start = time.Now() + for i := 0; i < inserts; i++ { + indexes, path := trie.FindPath(data[i]) + assert.True(t, len(indexes) == len(path)) + assert.True(t, len(path) > 1) + assert.True(t, bytes.HasSuffix(data[i], path[len(path)-1].key)) + } + t.Logf("Parents in %f sec.", time.Since(start).Seconds()) + + start = time.Now() + for i := 0; i < inserts; i++ { + trie.Erase(data[i]) + } + t.Logf("Deletion in %f sec.", time.Since(start).Seconds()) + assert.Equal(t, 1, trie.NodeCount()) +} diff --git a/claimtrie/merkletrie/merkletrie.go b/claimtrie/merkletrie/merkletrie.go new file mode 100644 index 00000000..3bc525fe --- /dev/null +++ b/claimtrie/merkletrie/merkletrie.go @@ -0,0 +1,255 @@ +package merkletrie + +import ( + "bytes" + "fmt" + "runtime" + "sort" + "sync" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/node" +) + +var ( + // EmptyTrieHash represents the Merkle Hash of an empty PersistentTrie. + // "0000000000000000000000000000000000000000000000000000000000000001" + EmptyTrieHash = &chainhash.Hash{1} + NoChildrenHash = &chainhash.Hash{2} + NoClaimsHash = &chainhash.Hash{3} +) + +// PersistentTrie implements a 256-way prefix tree. +type PersistentTrie struct { + repo Repo + + root *vertex + bufs *sync.Pool +} + +// NewPersistentTrie returns a PersistentTrie. +func NewPersistentTrie(repo Repo) *PersistentTrie { + + tr := &PersistentTrie{ + repo: repo, + bufs: &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + }, + root: newVertex(EmptyTrieHash), + } + + return tr +} + +// SetRoot drops all resolved nodes in the PersistentTrie, and set the Root with specified hash. +func (t *PersistentTrie) SetRoot(h *chainhash.Hash) error { + t.root = newVertex(h) + runtime.GC() + return nil +} + +// Update updates the nodes along the path to the key. +// Each node is resolved or created with their Hash cleared. +func (t *PersistentTrie) Update(name []byte, hash *chainhash.Hash, restoreChildren bool) { + + n := t.root + for i, ch := range name { + if restoreChildren && len(n.childLinks) == 0 { + t.resolveChildLinks(n, name[:i]) + } + if n.childLinks[ch] == nil { + n.childLinks[ch] = newVertex(nil) + } + n.merkleHash = nil + n = n.childLinks[ch] + } + + if restoreChildren && len(n.childLinks) == 0 { + t.resolveChildLinks(n, name) + } + n.merkleHash = nil + n.claimsHash = hash +} + +// resolveChildLinks updates the links on n +func (t *PersistentTrie) resolveChildLinks(n *vertex, key []byte) { + + if n.merkleHash == nil { + return + } + + b := t.bufs.Get().(*bytes.Buffer) + defer t.bufs.Put(b) + b.Reset() + b.Write(key) + b.Write(n.merkleHash[:]) + + result, closer, err := t.repo.Get(b.Bytes()) + if result == nil { + return + } else if err != nil { + panic(err) + } + defer closer.Close() + + nb := nbuf(result) + _, n.claimsHash = nb.hasValue() + for i := 0; i < nb.entries(); i++ { + p, h := nb.entry(i) + n.childLinks[p] = newVertex(h) + } +} + +// MerkleHash returns the Merkle Hash of the PersistentTrie. +// All nodes must have been resolved before calling this function. +func (t *PersistentTrie) MerkleHash() *chainhash.Hash { + buf := make([]byte, 0, 256) + if h := t.merkle(buf, t.root); h == nil { + return EmptyTrieHash + } + return t.root.merkleHash +} + +// merkle recursively resolves the hashes of the node. +// All nodes must have been resolved before calling this function. +func (t *PersistentTrie) merkle(prefix []byte, v *vertex) *chainhash.Hash { + if v.merkleHash != nil { + return v.merkleHash + } + + b := t.bufs.Get().(*bytes.Buffer) + defer t.bufs.Put(b) + b.Reset() + + keys := keysInOrder(v) + + for _, ch := range keys { + child := v.childLinks[ch] + if child == nil { + continue + } + p := append(prefix, ch) + h := t.merkle(p, child) + if h != nil { + b.WriteByte(ch) // nolint : errchk + b.Write(h[:]) // nolint : errchk + } + if h == nil || len(prefix) > 4 { // TODO: determine the right number here + delete(v.childLinks, ch) // keep the RAM down (they get recreated on Update) + } + } + + if v.claimsHash != nil { + b.Write(v.claimsHash[:]) + } + + if b.Len() > 0 { + h := chainhash.DoubleHashH(b.Bytes()) + v.merkleHash = &h + t.repo.Set(append(prefix, h[:]...), b.Bytes()) + } + + return v.merkleHash +} + +func keysInOrder(v *vertex) []byte { + keys := make([]byte, 0, len(v.childLinks)) + for key := range v.childLinks { + keys = append(keys, key) + } + sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] }) + return keys +} + +func (t *PersistentTrie) MerkleHashAllClaims() *chainhash.Hash { + buf := make([]byte, 0, 256) + if h := t.merkleAllClaims(buf, t.root); h == nil { + return EmptyTrieHash + } + return t.root.merkleHash +} + +func (t *PersistentTrie) merkleAllClaims(prefix []byte, v *vertex) *chainhash.Hash { + if v.merkleHash != nil { + return v.merkleHash + } + b := t.bufs.Get().(*bytes.Buffer) + defer t.bufs.Put(b) + b.Reset() + + keys := keysInOrder(v) + childHashes := make([]*chainhash.Hash, 0, len(keys)) + for _, ch := range keys { + n := v.childLinks[ch] + if n == nil { + continue + } + p := append(prefix, ch) + h := t.merkleAllClaims(p, n) + if h != nil { + childHashes = append(childHashes, h) + b.WriteByte(ch) // nolint : errchk + b.Write(h[:]) // nolint : errchk + } + if h == nil || len(prefix) > 4 { // TODO: determine the right number here + delete(v.childLinks, ch) // keep the RAM down (they get recreated on Update) + } + } + + if len(childHashes) > 1 || v.claimsHash != nil { // yeah, about that 1 there -- old code used the condensed trie + left := NoChildrenHash + if len(childHashes) > 0 { + left = node.ComputeMerkleRoot(childHashes) + } + right := NoClaimsHash + if v.claimsHash != nil { + b.Write(v.claimsHash[:]) // for Has Value, nolint : errchk + right = v.claimsHash + } + + h := node.HashMerkleBranches(left, right) + v.merkleHash = h + t.repo.Set(append(prefix, h[:]...), b.Bytes()) + } else if len(childHashes) == 1 { + v.merkleHash = childHashes[0] // pass it up the tree + t.repo.Set(append(prefix, v.merkleHash[:]...), b.Bytes()) + } + + return v.merkleHash +} + +func (t *PersistentTrie) Close() error { + return errors.WithStack(t.repo.Close()) +} + +func (t *PersistentTrie) Dump(s string) { + // TODO: this function is in the wrong spot; either it goes with its caller or it needs to be a generic iterator + // we don't want fmt used in here either way + + v := t.root + + for i := 0; i < len(s); i++ { + t.resolveChildLinks(v, []byte(s[:i])) + ch := s[i] + v = v.childLinks[ch] + if v == nil { + fmt.Printf("Missing child at %s\n", s[:i+1]) + return + } + } + t.resolveChildLinks(v, []byte(s)) + + fmt.Printf("Node hash: %s, has value: %t\n", v.merkleHash.String(), v.claimsHash != nil) + + for key, value := range v.childLinks { + fmt.Printf(" Child %s hash: %s\n", string(key), value.merkleHash.String()) + } +} + +func (t *PersistentTrie) Flush() error { + return t.repo.Flush() +} diff --git a/claimtrie/merkletrie/merkletrie_test.go b/claimtrie/merkletrie/merkletrie_test.go new file mode 100644 index 00000000..fc95a7b4 --- /dev/null +++ b/claimtrie/merkletrie/merkletrie_test.go @@ -0,0 +1,25 @@ +package merkletrie + +import ( + "testing" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/node" + + "github.com/stretchr/testify/require" +) + +func TestName(t *testing.T) { + + r := require.New(t) + + target, _ := chainhash.NewHashFromStr("e9ffb584c62449f157c8be88257bd1eebb2d8ef824f5c86b43c4f8fd9e800d6a") + + data := []*chainhash.Hash{EmptyTrieHash} + root := node.ComputeMerkleRoot(data) + r.True(EmptyTrieHash.IsEqual(root)) + + data = append(data, NoChildrenHash, NoClaimsHash) + root = node.ComputeMerkleRoot(data) + r.True(target.IsEqual(root)) +} diff --git a/claimtrie/merkletrie/merkletrierepo/pebble.go b/claimtrie/merkletrie/merkletrierepo/pebble.go new file mode 100644 index 00000000..c903794e --- /dev/null +++ b/claimtrie/merkletrie/merkletrierepo/pebble.go @@ -0,0 +1,67 @@ +package merkletrierepo + +import ( + "io" + + "github.com/cockroachdb/pebble" + "github.com/pkg/errors" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + cache := pebble.NewCache(512 << 20) + //defer cache.Unref() + // + //go func() { + // tick := time.NewTicker(60 * time.Second) + // for range tick.C { + // + // m := cache.Metrics() + // fmt.Printf("cnt: %s, objs: %s, hits: %s, miss: %s, hitrate: %.2f\n", + // humanize.Bytes(uint64(m.Size)), + // humanize.Comma(m.Count), + // humanize.Comma(m.Hits), + // humanize.Comma(m.Misses), + // float64(m.Hits)/float64(m.Hits+m.Misses)) + // + // } + //}() + + db, err := pebble.Open(path, &pebble.Options{Cache: cache, BytesPerSync: 32 << 20, MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "unable to open %s", path) +} + +func (repo *Pebble) Get(key []byte) ([]byte, io.Closer, error) { + d, c, e := repo.db.Get(key) + if e == pebble.ErrNotFound { + return nil, c, nil + } + return d, c, e +} + +func (repo *Pebble) Set(key, value []byte) error { + return repo.db.Set(key, value, pebble.NoSync) +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/merkletrie/ramtrie.go b/claimtrie/merkletrie/ramtrie.go new file mode 100644 index 00000000..7b426655 --- /dev/null +++ b/claimtrie/merkletrie/ramtrie.go @@ -0,0 +1,139 @@ +package merkletrie + +import ( + "bytes" + "errors" + "runtime" + "sync" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/node" +) + +type MerkleTrie interface { + SetRoot(h *chainhash.Hash) error + Update(name []byte, h *chainhash.Hash, restoreChildren bool) + MerkleHash() *chainhash.Hash + MerkleHashAllClaims() *chainhash.Hash + Flush() error +} + +type RamTrie struct { + collapsedTrie + bufs *sync.Pool +} + +func NewRamTrie() *RamTrie { + return &RamTrie{ + bufs: &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + }, + collapsedTrie: collapsedTrie{Root: &collapsedVertex{merkleHash: EmptyTrieHash}}, + } +} + +var ErrFullRebuildRequired = errors.New("a full rebuild is required") + +func (rt *RamTrie) SetRoot(h *chainhash.Hash) error { + if rt.Root.merkleHash.IsEqual(h) { + runtime.GC() + return nil + } + + // should technically clear the old trie first, but this is abused for partial rebuilds so don't + return ErrFullRebuildRequired +} + +func (rt *RamTrie) Update(name []byte, h *chainhash.Hash, _ bool) { + if h == nil { + rt.Erase(name) + } else { + _, n := rt.InsertOrFind(name) + n.claimHash = h + } +} + +func (rt *RamTrie) MerkleHash() *chainhash.Hash { + if h := rt.merkleHash(rt.Root); h == nil { + return EmptyTrieHash + } + return rt.Root.merkleHash +} + +func (rt *RamTrie) merkleHash(v *collapsedVertex) *chainhash.Hash { + if v.merkleHash != nil { + return v.merkleHash + } + + b := rt.bufs.Get().(*bytes.Buffer) + defer rt.bufs.Put(b) + b.Reset() + + for _, ch := range v.children { + h := rt.merkleHash(ch) // h is a pointer; don't destroy its data + b.WriteByte(ch.key[0]) // nolint : errchk + b.Write(rt.completeHash(h, ch.key)) // nolint : errchk + } + + if v.claimHash != nil { + b.Write(v.claimHash[:]) + } + + if b.Len() > 0 { + h := chainhash.DoubleHashH(b.Bytes()) + v.merkleHash = &h + } + + return v.merkleHash +} + +func (rt *RamTrie) completeHash(h *chainhash.Hash, childKey KeyType) []byte { + var data [chainhash.HashSize + 1]byte + copy(data[1:], h[:]) + for i := len(childKey) - 1; i > 0; i-- { + data[0] = childKey[i] + copy(data[1:], chainhash.DoubleHashB(data[:])) + } + return data[1:] +} + +func (rt *RamTrie) MerkleHashAllClaims() *chainhash.Hash { + if h := rt.merkleHashAllClaims(rt.Root); h == nil { + return EmptyTrieHash + } + return rt.Root.merkleHash +} + +func (rt *RamTrie) merkleHashAllClaims(v *collapsedVertex) *chainhash.Hash { + if v.merkleHash != nil { + return v.merkleHash + } + + childHashes := make([]*chainhash.Hash, 0, len(v.children)) + for _, ch := range v.children { + h := rt.merkleHashAllClaims(ch) + childHashes = append(childHashes, h) + } + + claimHash := NoClaimsHash + if v.claimHash != nil { + claimHash = v.claimHash + } else if len(childHashes) == 0 { + return nil + } + + childHash := NoChildrenHash + if len(childHashes) > 0 { + // this shouldn't be referencing node; where else can we put this merkle root func? + childHash = node.ComputeMerkleRoot(childHashes) + } + + v.merkleHash = node.HashMerkleBranches(childHash, claimHash) + return v.merkleHash +} + +func (rt *RamTrie) Flush() error { + return nil +} diff --git a/claimtrie/merkletrie/repo.go b/claimtrie/merkletrie/repo.go new file mode 100644 index 00000000..68b6c8d6 --- /dev/null +++ b/claimtrie/merkletrie/repo.go @@ -0,0 +1,13 @@ +package merkletrie + +import ( + "io" +) + +// Repo defines APIs for PersistentTrie to access persistence layer. +type Repo interface { + Get(key []byte) ([]byte, io.Closer, error) + Set(key, value []byte) error + Close() error + Flush() error +} diff --git a/claimtrie/merkletrie/vertex.go b/claimtrie/merkletrie/vertex.go new file mode 100644 index 00000000..77f1f04a --- /dev/null +++ b/claimtrie/merkletrie/vertex.go @@ -0,0 +1,43 @@ +package merkletrie + +import ( + "github.com/lbryio/lbcd/chaincfg/chainhash" +) + +type vertex struct { + merkleHash *chainhash.Hash + claimsHash *chainhash.Hash + childLinks map[byte]*vertex +} + +func newVertex(hash *chainhash.Hash) *vertex { + return &vertex{childLinks: map[byte]*vertex{}, merkleHash: hash} +} + +// TODO: more professional to use msgpack here? + +// nbuf decodes the on-disk format of a node, which has the following form: +// ch(1B) hash(32B) +// ... +// ch(1B) hash(32B) +// vhash(32B) +type nbuf []byte + +func (nb nbuf) entries() int { + return len(nb) / 33 +} + +func (nb nbuf) entry(i int) (byte, *chainhash.Hash) { + h := chainhash.Hash{} + copy(h[:], nb[33*i+1:]) + return nb[33*i], &h +} + +func (nb nbuf) hasValue() (bool, *chainhash.Hash) { + if len(nb)%33 == 0 { + return false, nil + } + h := chainhash.Hash{} + copy(h[:], nb[len(nb)-32:]) + return true, &h +} diff --git a/claimtrie/node/claim.go b/claimtrie/node/claim.go new file mode 100644 index 00000000..8f385913 --- /dev/null +++ b/claimtrie/node/claim.go @@ -0,0 +1,92 @@ +package node + +import ( + "bytes" + "strconv" + "strings" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/param" + "github.com/lbryio/lbcd/wire" +) + +type Status int + +const ( + Accepted Status = iota + Activated + Deactivated +) + +// Claim defines a structure of stake, which could be a Claim or Support. +type Claim struct { + OutPoint wire.OutPoint + ClaimID change.ClaimID + Amount int64 + // CreatedAt int32 // the very first block, unused at present + AcceptedAt int32 // the latest update height + ActiveAt int32 // AcceptedAt + actual delay + VisibleAt int32 + + Status Status `msgpack:",omitempty"` + Sequence int32 `msgpack:",omitempty"` +} + +func (c *Claim) setOutPoint(op wire.OutPoint) *Claim { + c.OutPoint = op + return c +} + +func (c *Claim) SetAmt(amt int64) *Claim { + c.Amount = amt + return c +} + +func (c *Claim) setAccepted(height int32) *Claim { + c.AcceptedAt = height + return c +} + +func (c *Claim) setActiveAt(height int32) *Claim { + c.ActiveAt = height + return c +} + +func (c *Claim) setStatus(status Status) *Claim { + c.Status = status + return c +} + +func (c *Claim) ExpireAt() int32 { + + if c.AcceptedAt+param.ActiveParams.OriginalClaimExpirationTime > param.ActiveParams.ExtendedClaimExpirationForkHeight { + return c.AcceptedAt + param.ActiveParams.ExtendedClaimExpirationTime + } + + return c.AcceptedAt + param.ActiveParams.OriginalClaimExpirationTime +} + +func OutPointLess(a, b wire.OutPoint) bool { + + switch cmp := bytes.Compare(a.Hash[:], b.Hash[:]); { + case cmp < 0: + return true + case cmp > 0: + return false + default: + return a.Index < b.Index + } +} + +func NewOutPointFromString(str string) *wire.OutPoint { + + f := strings.Split(str, ":") + if len(f) != 2 { + return nil + } + hash, _ := chainhash.NewHashFromStr(f[0]) + idx, _ := strconv.Atoi(f[1]) + + return wire.NewOutPoint(hash, uint32(idx)) +} diff --git a/claimtrie/node/claim_list.go b/claimtrie/node/claim_list.go new file mode 100644 index 00000000..007a1b6b --- /dev/null +++ b/claimtrie/node/claim_list.go @@ -0,0 +1,33 @@ +package node + +import ( + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/wire" +) + +type ClaimList []*Claim + +type comparator func(c *Claim) bool + +func byID(id change.ClaimID) comparator { + return func(c *Claim) bool { + return c.ClaimID == id + } +} + +func byOut(out wire.OutPoint) comparator { + return func(c *Claim) bool { + return c.OutPoint == out // assuming value comparison + } +} + +func (l ClaimList) find(cmp comparator) *Claim { + + for i := range l { + if cmp(l[i]) { + return l[i] + } + } + + return nil +} diff --git a/claimtrie/node/hashfork_manager.go b/claimtrie/node/hashfork_manager.go new file mode 100644 index 00000000..bbd814ee --- /dev/null +++ b/claimtrie/node/hashfork_manager.go @@ -0,0 +1,39 @@ +package node + +import ( + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/param" +) + +type HashV2Manager struct { + Manager +} + +func (nm *HashV2Manager) computeClaimHashes(name []byte) (*chainhash.Hash, int32) { + + n, err := nm.NodeAt(nm.Height(), name) + if err != nil || n == nil { + return nil, 0 + } + + n.SortClaimsByBid() + claimHashes := make([]*chainhash.Hash, 0, len(n.Claims)) + for _, c := range n.Claims { + if c.Status == Activated { // TODO: unit test this line + claimHashes = append(claimHashes, calculateNodeHash(c.OutPoint, n.TakenOverAt)) + } + } + if len(claimHashes) > 0 { + return ComputeMerkleRoot(claimHashes), n.NextUpdate() + } + return nil, n.NextUpdate() +} + +func (nm *HashV2Manager) Hash(name []byte) (*chainhash.Hash, int32) { + + if nm.Height() >= param.ActiveParams.AllClaimsInMerkleForkHeight { + return nm.computeClaimHashes(name) + } + + return nm.Manager.Hash(name) +} diff --git a/claimtrie/node/hashfunc.go b/claimtrie/node/hashfunc.go new file mode 100644 index 00000000..deec78bb --- /dev/null +++ b/claimtrie/node/hashfunc.go @@ -0,0 +1,57 @@ +package node + +import ( + "crypto/sha256" + "encoding/binary" + "strconv" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" +) + +func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash { + // Concatenate the left and right nodes. + var hash [chainhash.HashSize * 2]byte + copy(hash[:chainhash.HashSize], left[:]) + copy(hash[chainhash.HashSize:], right[:]) + + newHash := chainhash.DoubleHashH(hash[:]) + return &newHash +} + +func ComputeMerkleRoot(hashes []*chainhash.Hash) *chainhash.Hash { + if len(hashes) <= 0 { + return nil + } + for len(hashes) > 1 { + if (len(hashes) & 1) > 0 { // odd count + hashes = append(hashes, hashes[len(hashes)-1]) + } + for i := 0; i < len(hashes); i += 2 { // TODO: parallelize this loop (or use a lib that does it) + hashes[i>>1] = HashMerkleBranches(hashes[i], hashes[i+1]) + } + hashes = hashes[:len(hashes)>>1] + } + return hashes[0] +} + +func calculateNodeHash(op wire.OutPoint, takeover int32) *chainhash.Hash { + + txHash := chainhash.DoubleHashH(op.Hash[:]) + + nOut := []byte(strconv.Itoa(int(op.Index))) + nOutHash := chainhash.DoubleHashH(nOut) + + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, uint64(takeover)) + heightHash := chainhash.DoubleHashH(buf) + + h := make([]byte, 0, sha256.Size*3) + h = append(h, txHash[:]...) + h = append(h, nOutHash[:]...) + h = append(h, heightHash[:]...) + + hh := chainhash.DoubleHashH(h) + + return &hh +} diff --git a/claimtrie/node/log.go b/claimtrie/node/log.go new file mode 100644 index 00000000..86293b58 --- /dev/null +++ b/claimtrie/node/log.go @@ -0,0 +1,47 @@ +package node + +import ( + "sync" + + "github.com/btcsuite/btclog" +) + +// log is a logger that is initialized with no output filters. This +// means the package will not perform any logging by default until the caller +// requests it. +var log btclog.Logger + +// The default amount of logging is none. +func init() { + DisableLog() +} + +// DisableLog disables all library log output. Logging output is disabled +// by default until either UseLogger or SetLogWriter are called. +func DisableLog() { + log = btclog.Disabled +} + +// UseLogger uses a specified Logger to output package logging info. +// This should be used in preference to SetLogWriter if the caller is also +// using btclog. +func UseLogger(logger btclog.Logger) { + log = logger +} + +var loggedStrings = map[string]bool{} // is this gonna get too large? +var loggedStringsMutex sync.Mutex + +func LogOnce(s string) { + loggedStringsMutex.Lock() + defer loggedStringsMutex.Unlock() + if loggedStrings[s] { + return + } + loggedStrings[s] = true + log.Info(s) +} + +func Warn(s string) { + log.Warn(s) +} diff --git a/claimtrie/node/manager.go b/claimtrie/node/manager.go new file mode 100644 index 00000000..605b7123 --- /dev/null +++ b/claimtrie/node/manager.go @@ -0,0 +1,374 @@ +package node + +import ( + "fmt" + "sort" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/param" +) + +type Manager interface { + AppendChange(chg change.Change) + IncrementHeightTo(height int32) ([][]byte, error) + DecrementHeightTo(affectedNames [][]byte, height int32) error + Height() int32 + Close() error + NodeAt(height int32, name []byte) (*Node, error) + IterateNames(predicate func(name []byte) bool) + Hash(name []byte) (*chainhash.Hash, int32) + Flush() error +} + +type BaseManager struct { + repo Repo + + height int32 + changes []change.Change +} + +func NewBaseManager(repo Repo) (*BaseManager, error) { + + nm := &BaseManager{ + repo: repo, + } + + return nm, nil +} + +func (nm *BaseManager) NodeAt(height int32, name []byte) (*Node, error) { + + changes, err := nm.repo.LoadChanges(name) + if err != nil { + return nil, errors.Wrap(err, "in load changes") + } + + n, err := nm.newNodeFromChanges(changes, height) + if err != nil { + return nil, errors.Wrap(err, "in new node") + } + + return n, nil +} + +// Node returns a node at the current height. +// The returned node may have pending changes. +func (nm *BaseManager) node(name []byte) (*Node, error) { + return nm.NodeAt(nm.height, name) +} + +// newNodeFromChanges returns a new Node constructed from the changes. +// The changes must preserve their order received. +func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) { + + if len(changes) == 0 { + return nil, nil + } + + n := New() + previous := changes[0].Height + count := len(changes) + + for i, chg := range changes { + if chg.Height < previous { + panic("expected the changes to be in order by height") + } + if chg.Height > height { + count = i + break + } + + if previous < chg.Height { + n.AdjustTo(previous, chg.Height-1, chg.Name) // update bids and activation + previous = chg.Height + } + + delay := nm.getDelayForName(n, chg) + err := n.ApplyChange(chg, delay) + if err != nil { + return nil, errors.Wrap(err, "in apply change") + } + } + + if count <= 0 { + return nil, nil + } + lastChange := changes[count-1] + return n.AdjustTo(lastChange.Height, height, lastChange.Name), nil +} + +func (nm *BaseManager) AppendChange(chg change.Change) { + + nm.changes = append(nm.changes, chg) + + // worth putting in this kind of thing pre-emptively? + // log.Debugf("CHG: %d, %s, %v, %s, %d", chg.Height, chg.Name, chg.Type, chg.ClaimID, chg.Amount) +} + +func collectChildNames(changes []change.Change) { + // we need to determine which children (names that start with the same name) go with which change + // if we have the names in order then we can avoid iterating through all names in the change list + // and we can possibly reuse the previous list. + + // what would happen in the old code: + // spending a claim (which happens before every update) could remove a node from the cached trie + // in which case we would fall back on the data from the previous block (where it obviously wasn't spent). + // It would only delete the node if it had no children, but have even some rare situations + // Where all of the children happen to be deleted first. That's what we must detect here. + + // Algorithm: + // For each non-spend change + // Loop through all the spends before you and add them to your child list if they are your child + + type pair struct { + name string + order int + } + + spends := make([]pair, 0, len(changes)) + for i := range changes { + t := changes[i].Type + if t != change.SpendClaim { + continue + } + spends = append(spends, pair{string(changes[i].Name), i}) + } + sort.Slice(spends, func(i, j int) bool { + return spends[i].name < spends[j].name + }) + + for i := range changes { + t := changes[i].Type + if t == change.SpendClaim || t == change.SpendSupport { + continue + } + a := string(changes[i].Name) + sc := map[string]bool{} + idx := sort.Search(len(spends), func(k int) bool { + return spends[k].name > a + }) + for idx < len(spends) { + b := spends[idx].name + if len(b) <= len(a) || a != b[:len(a)] { + break // since they're ordered alphabetically, we should be able to break out once we're past matches + } + if spends[idx].order < i { + sc[b] = true + } + idx++ + } + changes[i].SpentChildren = sc + } +} + +// to understand the above function, it may be helpful to refer to the slower implementation: +//func collectChildNamesSlow(changes []change.Change) { +// for i := range changes { +// t := changes[i].Type +// if t == change.SpendClaim || t == change.SpendSupport { +// continue +// } +// a := changes[i].Name +// sc := map[string]bool{} +// for j := 0; j < i; j++ { +// t = changes[j].Type +// if t != change.SpendClaim { +// continue +// } +// b := changes[j].Name +// if len(b) >= len(a) && bytes.Equal(a, b[:len(a)]) { +// sc[string(b)] = true +// } +// } +// changes[i].SpentChildren = sc +// } +//} + +func (nm *BaseManager) IncrementHeightTo(height int32) ([][]byte, error) { + + if height <= nm.height { + panic("invalid height") + } + + if height >= param.ActiveParams.MaxRemovalWorkaroundHeight { + // not technically needed until block 884430, but to be true to the arbitrary rollback length... + collectChildNames(nm.changes) + } + + names := make([][]byte, 0, len(nm.changes)) + for i := range nm.changes { + names = append(names, nm.changes[i].Name) + } + + if err := nm.repo.AppendChanges(nm.changes); err != nil { // destroys names + return nil, errors.Wrap(err, "in append changes") + } + + // Truncate the buffer size to zero. + if len(nm.changes) > 1000 { // TODO: determine a good number here + nm.changes = nil // release the RAM + } else { + nm.changes = nm.changes[:0] + } + nm.height = height + + return names, nil +} + +func (nm *BaseManager) DecrementHeightTo(affectedNames [][]byte, height int32) error { + if height >= nm.height { + return errors.Errorf("invalid height of %d for %d", height, nm.height) + } + + for _, name := range affectedNames { + if err := nm.repo.DropChanges(name, height); err != nil { + return errors.Wrap(err, "in drop changes") + } + } + + nm.height = height + + return nil +} + +func (nm *BaseManager) getDelayForName(n *Node, chg change.Change) int32 { + // Note: we don't consider the active status of BestClaim here on purpose. + // That's because we deactivate and reactivate as part of claim updates. + // However, the final status will be accounted for when we compute the takeover heights; + // claims may get activated early at that point. + + hasBest := n.BestClaim != nil + if hasBest && n.BestClaim.ClaimID == chg.ClaimID { + return 0 + } + if chg.ActiveHeight >= chg.Height { // ActiveHeight is usually unset (aka, zero) + return chg.ActiveHeight - chg.Height + } + if !hasBest { + return 0 + } + + delay := calculateDelay(chg.Height, n.TakenOverAt) + if delay > 0 && nm.aWorkaroundIsNeeded(n, chg) { + if chg.Height >= nm.height { + LogOnce(fmt.Sprintf("Delay workaround applies to %s at %d, ClaimID: %s", + chg.Name, chg.Height, chg.ClaimID)) + } + return 0 + } + return delay +} + +func hasZeroActiveClaims(n *Node) bool { + // this isn't quite the same as having an active best (since that is only updated after all changes are processed) + for _, c := range n.Claims { + if c.Status == Activated { + return false + } + } + return true +} + +// aWorkaroundIsNeeded handles bugs that existed in previous versions +func (nm *BaseManager) aWorkaroundIsNeeded(n *Node, chg change.Change) bool { + + if chg.Type == change.SpendClaim || chg.Type == change.SpendSupport { + return false + } + + if chg.Height >= param.ActiveParams.MaxRemovalWorkaroundHeight { + // TODO: hard fork this out; it's a bug from previous versions: + + // old 17.3 C++ code we're trying to mimic (where empty means no active claims): + // auto it = nodesToAddOrUpdate.find(name); // nodesToAddOrUpdate is the working changes, base is previous block + // auto answer = (it || (it = base->find(name))) && !it->empty() ? nNextHeight - it->nHeightOfLastTakeover : 0; + + return hasZeroActiveClaims(n) && nm.hasChildren(chg.Name, chg.Height, chg.SpentChildren, 2) + } else if len(n.Claims) > 0 { + // NOTE: old code had a bug in it where nodes with no claims but with children would get left in the cache after removal. + // This would cause the getNumBlocksOfContinuousOwnership to return zero (causing incorrect takeover height calc). + w, ok := param.DelayWorkarounds[string(chg.Name)] + if ok { + for _, h := range w { + if chg.Height == h { + return true + } + } + } + } + return false +} + +func calculateDelay(curr, tookOver int32) int32 { + + delay := (curr - tookOver) / param.ActiveParams.ActiveDelayFactor + if delay > param.ActiveParams.MaxActiveDelay { + return param.ActiveParams.MaxActiveDelay + } + + return delay +} + +func (nm *BaseManager) Height() int32 { + return nm.height +} + +func (nm *BaseManager) Close() error { + return errors.WithStack(nm.repo.Close()) +} + +func (nm *BaseManager) hasChildren(name []byte, height int32, spentChildren map[string]bool, required int) bool { + c := map[byte]bool{} + if spentChildren == nil { + spentChildren = map[string]bool{} + } + + err := nm.repo.IterateChildren(name, func(changes []change.Change) bool { + // if the key is unseen, generate a node for it to height + // if that node is active then increase the count + if len(changes) == 0 { + return true + } + if c[changes[0].Name[len(name)]] { // assuming all names here are longer than starter name + return true // we already checked a similar name + } + if spentChildren[string(changes[0].Name)] { + return true // children that are spent in the same block cannot count as active children + } + n, _ := nm.newNodeFromChanges(changes, height) + if n != nil && n.HasActiveBestClaim() { + c[changes[0].Name[len(name)]] = true + if len(c) >= required { + return false + } + } + return true + }) + return err == nil && len(c) >= required +} + +func (nm *BaseManager) IterateNames(predicate func(name []byte) bool) { + nm.repo.IterateAll(predicate) +} + +func (nm *BaseManager) Hash(name []byte) (*chainhash.Hash, int32) { + + n, err := nm.node(name) + if err != nil || n == nil { + return nil, 0 + } + if len(n.Claims) > 0 { + if n.BestClaim != nil && n.BestClaim.Status == Activated { + h := calculateNodeHash(n.BestClaim.OutPoint, n.TakenOverAt) + return h, n.NextUpdate() + } + } + return nil, n.NextUpdate() +} + +func (nm *BaseManager) Flush() error { + return nm.repo.Flush() +} diff --git a/claimtrie/node/manager_test.go b/claimtrie/node/manager_test.go new file mode 100644 index 00000000..705080c8 --- /dev/null +++ b/claimtrie/node/manager_test.go @@ -0,0 +1,250 @@ +package node + +import ( + "fmt" + "testing" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node/noderepo" + "github.com/lbryio/lbcd/claimtrie/param" + "github.com/lbryio/lbcd/wire" + + "github.com/stretchr/testify/require" +) + +var ( + out1 = NewOutPointFromString("0000000000000000000000000000000000000000000000000000000000000000:1") + out2 = NewOutPointFromString("0000000000000000000000000000000000000000000000000000000000000000:2") + out3 = NewOutPointFromString("0100000000000000000000000000000000000000000000000000000000000000:1") + out4 = NewOutPointFromString("0100000000000000000000000000000000000000000000000000000000000000:2") + name1 = []byte("name1") + name2 = []byte("name2") +) + +// verify that we can round-trip bytes to strings +func TestStringRoundTrip(t *testing.T) { + + r := require.New(t) + + data := [][]byte{ + {97, 98, 99, 0, 100, 255}, + {0xc3, 0x28}, + {0xa0, 0xa1}, + {0xe2, 0x28, 0xa1}, + {0xf0, 0x28, 0x8c, 0x28}, + } + for _, d := range data { + s := string(d) + r.Equal(s, fmt.Sprintf("%s", d)) // nolint + d2 := []byte(s) + r.Equal(len(d), len(s)) + r.Equal(d, d2) + } +} + +func TestSimpleAddClaim(t *testing.T) { + + r := require.New(t) + + param.SetNetwork(wire.TestNet) + repo, err := noderepo.NewPebble(t.TempDir()) + r.NoError(err) + + m, err := NewBaseManager(repo) + r.NoError(err) + defer m.Close() + + _, err = m.IncrementHeightTo(10) + r.NoError(err) + + chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(11) + r.NoError(err) + + chg = chg.SetName(name2).SetOutPoint(out2).SetHeight(12) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(12) + r.NoError(err) + + n1, err := m.node(name1) + r.NoError(err) + r.Equal(1, len(n1.Claims)) + r.NotNil(n1.Claims.find(byOut(*out1))) + + n2, err := m.node(name2) + r.NoError(err) + r.Equal(1, len(n2.Claims)) + r.NotNil(n2.Claims.find(byOut(*out2))) + + err = m.DecrementHeightTo([][]byte{name2}, 11) + r.NoError(err) + n2, err = m.node(name2) + r.NoError(err) + r.Nil(n2) + + err = m.DecrementHeightTo([][]byte{name1}, 1) + r.NoError(err) + n2, err = m.node(name1) + r.NoError(err) + r.Nil(n2) +} + +func TestSupportAmounts(t *testing.T) { + + r := require.New(t) + + param.SetNetwork(wire.TestNet) + repo, err := noderepo.NewPebble(t.TempDir()) + r.NoError(err) + + m, err := NewBaseManager(repo) + r.NoError(err) + defer m.Close() + + _, err = m.IncrementHeightTo(10) + r.NoError(err) + + chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11).SetAmount(3) + chg.ClaimID = change.NewClaimID(*out1) + m.AppendChange(chg) + + chg = change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out2).SetHeight(11).SetAmount(4) + chg.ClaimID = change.NewClaimID(*out2) + m.AppendChange(chg) + + _, err = m.IncrementHeightTo(11) + r.NoError(err) + + chg = change.NewChange(change.AddSupport).SetName(name1).SetOutPoint(out3).SetHeight(12).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out1) + m.AppendChange(chg) + + chg = change.NewChange(change.AddSupport).SetName(name1).SetOutPoint(out4).SetHeight(12).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out2) + m.AppendChange(chg) + + chg = change.NewChange(change.SpendSupport).SetName(name1).SetOutPoint(out4).SetHeight(12).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out2) + m.AppendChange(chg) + + _, err = m.IncrementHeightTo(20) + r.NoError(err) + + n1, err := m.node(name1) + r.NoError(err) + r.Equal(2, len(n1.Claims)) + r.Equal(int64(5), n1.BestClaim.Amount+n1.SupportSums[n1.BestClaim.ClaimID.Key()]) +} + +func TestNodeSort(t *testing.T) { + + r := require.New(t) + + param.ActiveParams.ExtendedClaimExpirationTime = 1000 + + r.True(OutPointLess(*out1, *out2)) + r.True(OutPointLess(*out1, *out3)) + + n := New() + n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{1}}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out2, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{2}}) + n.handleExpiredAndActivated(3) + n.updateTakeoverHeight(3, []byte{}, true) + + r.Equal(n.Claims.find(byOut(*out1)).OutPoint.String(), n.BestClaim.OutPoint.String()) + + n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{3}}) + n.handleExpiredAndActivated(3) + n.updateTakeoverHeight(3, []byte{}, true) + r.Equal(n.Claims.find(byOut(*out1)).OutPoint.String(), n.BestClaim.OutPoint.String()) +} + +func TestClaimSort(t *testing.T) { + + r := require.New(t) + + param.ActiveParams.ExtendedClaimExpirationTime = 1000 + + n := New() + n.Claims = append(n.Claims, &Claim{OutPoint: *out2, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{2}, Status: Activated}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 3, Amount: 2, ClaimID: change.ClaimID{3}, Status: Activated}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 4, Amount: 2, ClaimID: change.ClaimID{4}, Status: Activated}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 3, Amount: 4, ClaimID: change.ClaimID{1}, Status: Activated}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 1, Amount: 9, ClaimID: change.ClaimID{5}, Status: Accepted}) + n.SortClaimsByBid() + + r.Equal(int64(4), n.Claims[0].Amount) + r.Equal(int64(3), n.Claims[1].Amount) + r.Equal(int64(2), n.Claims[2].Amount) + r.Equal(int32(4), n.Claims[3].AcceptedAt) +} + +func TestHasChildren(t *testing.T) { + r := require.New(t) + + param.SetNetwork(wire.TestNet) + repo, err := noderepo.NewPebble(t.TempDir()) + r.NoError(err) + + m, err := NewBaseManager(repo) + r.NoError(err) + defer m.Close() + + chg := change.NewChange(change.AddClaim).SetName([]byte("a")).SetOutPoint(out1).SetHeight(1).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out1) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(1) + r.NoError(err) + r.False(m.hasChildren([]byte("a"), 1, nil, 1)) + + chg = change.NewChange(change.AddClaim).SetName([]byte("ab")).SetOutPoint(out2).SetHeight(2).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out2) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(2) + r.NoError(err) + r.False(m.hasChildren([]byte("a"), 2, nil, 2)) + r.True(m.hasChildren([]byte("a"), 2, nil, 1)) + + chg = change.NewChange(change.AddClaim).SetName([]byte("abc")).SetOutPoint(out3).SetHeight(3).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out3) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(3) + r.NoError(err) + r.False(m.hasChildren([]byte("a"), 3, nil, 2)) + + chg = change.NewChange(change.AddClaim).SetName([]byte("ac")).SetOutPoint(out1).SetHeight(4).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out4) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(4) + r.NoError(err) + r.True(m.hasChildren([]byte("a"), 4, nil, 2)) +} + +func TestCollectChildren(t *testing.T) { + r := require.New(t) + + c1 := change.Change{Name: []byte("ba"), Type: change.SpendClaim} + c2 := change.Change{Name: []byte("ba"), Type: change.UpdateClaim} + c3 := change.Change{Name: []byte("ac"), Type: change.SpendClaim} + c4 := change.Change{Name: []byte("ac"), Type: change.UpdateClaim} + c5 := change.Change{Name: []byte("a"), Type: change.SpendClaim} + c6 := change.Change{Name: []byte("a"), Type: change.UpdateClaim} + c7 := change.Change{Name: []byte("ab"), Type: change.SpendClaim} + c8 := change.Change{Name: []byte("ab"), Type: change.UpdateClaim} + c := []change.Change{c1, c2, c3, c4, c5, c6, c7, c8} + + collectChildNames(c) + + r.Empty(c[0].SpentChildren) + r.Empty(c[2].SpentChildren) + r.Empty(c[4].SpentChildren) + r.Empty(c[6].SpentChildren) + + r.Len(c[1].SpentChildren, 0) + r.Len(c[3].SpentChildren, 0) + r.Len(c[5].SpentChildren, 1) + r.True(c[5].SpentChildren["ac"]) + + r.Len(c[7].SpentChildren, 0) +} diff --git a/claimtrie/node/node.go b/claimtrie/node/node.go new file mode 100644 index 00000000..f9a466be --- /dev/null +++ b/claimtrie/node/node.go @@ -0,0 +1,320 @@ +package node + +import ( + "fmt" + "math" + "sort" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/param" +) + +type Node struct { + BestClaim *Claim // The claim that has most effective amount at the current height. + TakenOverAt int32 // The height at when the current BestClaim took over. + Claims ClaimList // List of all Claims. + Supports ClaimList // List of all Supports, including orphaned ones. + SupportSums map[string]int64 +} + +// New returns a new node. +func New() *Node { + return &Node{SupportSums: map[string]int64{}} +} + +func (n *Node) HasActiveBestClaim() bool { + return n.BestClaim != nil && n.BestClaim.Status == Activated +} + +func (n *Node) ApplyChange(chg change.Change, delay int32) error { + + visibleAt := chg.VisibleHeight + if visibleAt <= 0 { + visibleAt = chg.Height + } + + switch chg.Type { + case change.AddClaim: + c := &Claim{ + OutPoint: chg.OutPoint, + Amount: chg.Amount, + ClaimID: chg.ClaimID, + // CreatedAt: chg.Height, + AcceptedAt: chg.Height, + ActiveAt: chg.Height + delay, + VisibleAt: visibleAt, + Sequence: int32(len(n.Claims)), + } + // old := n.Claims.find(byOut(chg.OutPoint)) // TODO: remove this after proving ResetHeight works + // if old != nil { + // return errors.Errorf("CONFLICT WITH EXISTING TXO! Name: %s, Height: %d", chg.Name, chg.Height) + // } + n.Claims = append(n.Claims, c) + + case change.SpendClaim: + c := n.Claims.find(byOut(chg.OutPoint)) + if c != nil { + c.setStatus(Deactivated) + } else { + LogOnce(fmt.Sprintf("Spending claim but missing existing claim with TXO %s, "+ + "Name: %s, ID: %s", chg.OutPoint, chg.Name, chg.ClaimID)) + } + // apparently it's legit to be absent in the map: + // 'two' at 481100, 36a719a156a1df178531f3c712b8b37f8e7cc3b36eea532df961229d936272a1:0 + + case change.UpdateClaim: + // Find and remove the claim, which has just been spent. + c := n.Claims.find(byID(chg.ClaimID)) + if c != nil && c.Status == Deactivated { + + // Keep its ID, which was generated from the spent claim. + // And update the rest of properties. + c.setOutPoint(chg.OutPoint).SetAmt(chg.Amount) + c.setStatus(Accepted) // it was Deactivated in the spend (but we only activate at the end of the block) + // that's because the old code would put all insertions into the "queue" that was processed at block's end + + // This forces us to be newer, which may in an unintentional takeover if there's an older one. + // TODO: reconsider these updates in future hard forks. + c.setAccepted(chg.Height) + c.setActiveAt(chg.Height + delay) + + } else { + LogOnce(fmt.Sprintf("Updating claim but missing existing claim with ID %s", chg.ClaimID)) + } + case change.AddSupport: + n.Supports = append(n.Supports, &Claim{ + OutPoint: chg.OutPoint, + Amount: chg.Amount, + ClaimID: chg.ClaimID, + AcceptedAt: chg.Height, + ActiveAt: chg.Height + delay, + VisibleAt: visibleAt, + }) + + case change.SpendSupport: + s := n.Supports.find(byOut(chg.OutPoint)) + if s != nil { + if s.Status == Activated { + n.SupportSums[s.ClaimID.Key()] -= s.Amount + } + // TODO: we could do without this Deactivated flag if we set expiration instead + // That would eliminate the above Sum update. + // We would also need to track the update situation, though, but that could be done locally. + s.setStatus(Deactivated) + } else { + LogOnce(fmt.Sprintf("Spending support but missing existing claim with TXO %s, "+ + "Name: %s, ID: %s", chg.OutPoint, chg.Name, chg.ClaimID)) + } + } + return nil +} + +// AdjustTo activates claims and computes takeovers until it reaches the specified height. +func (n *Node) AdjustTo(height, maxHeight int32, name []byte) *Node { + changed := n.handleExpiredAndActivated(height) > 0 + n.updateTakeoverHeight(height, name, changed) + if maxHeight > height { + for h := n.NextUpdate(); h <= maxHeight; h = n.NextUpdate() { + changed = n.handleExpiredAndActivated(h) > 0 + n.updateTakeoverHeight(h, name, changed) + height = h + } + } + return n +} + +func (n *Node) updateTakeoverHeight(height int32, name []byte, refindBest bool) { + + candidate := n.BestClaim + if refindBest { + candidate = n.findBestClaim() // so expensive... + } + + hasCandidate := candidate != nil + hasCurrentWinner := n.HasActiveBestClaim() + + takeoverHappening := !hasCandidate || !hasCurrentWinner || candidate.ClaimID != n.BestClaim.ClaimID + + if takeoverHappening { + if n.activateAllClaims(height) > 0 { + candidate = n.findBestClaim() + } + } + + if !takeoverHappening && height < param.ActiveParams.MaxRemovalWorkaroundHeight { + // This is a super ugly hack to work around bug in old code. + // The bug: un/support a name then update it. This will cause its takeover height to be reset to current. + // This is because the old code would add to the cache without setting block originals when dealing in supports. + _, takeoverHappening = param.TakeoverWorkarounds[fmt.Sprintf("%d_%s", height, name)] // TODO: ditch the fmt call + } + + if takeoverHappening { + n.TakenOverAt = height + n.BestClaim = candidate + } +} + +func (n *Node) handleExpiredAndActivated(height int32) int { + + changes := 0 + update := func(items ClaimList, sums map[string]int64) ClaimList { + for i := 0; i < len(items); i++ { + c := items[i] + if c.Status == Accepted && c.ActiveAt <= height && c.VisibleAt <= height { + c.setStatus(Activated) + changes++ + if sums != nil { + sums[c.ClaimID.Key()] += c.Amount + } + } + if c.ExpireAt() <= height || c.Status == Deactivated { + if i < len(items)-1 { + items[i] = items[len(items)-1] + i-- + } + items = items[:len(items)-1] + changes++ + if sums != nil && c.Status != Deactivated { + sums[c.ClaimID.Key()] -= c.Amount + } + } + } + return items + } + n.Claims = update(n.Claims, nil) + n.Supports = update(n.Supports, n.SupportSums) + return changes +} + +// NextUpdate returns the nearest height in the future that the node should +// be refreshed due to changes of claims or supports. +func (n Node) NextUpdate() int32 { + + next := int32(math.MaxInt32) + + for _, c := range n.Claims { + if c.ExpireAt() < next { + next = c.ExpireAt() + } + // if we're not active, we need to go to activeAt unless we're still invisible there + if c.Status == Accepted { + min := c.ActiveAt + if c.VisibleAt > min { + min = c.VisibleAt + } + if min < next { + next = min + } + } + } + + for _, s := range n.Supports { + if s.ExpireAt() < next { + next = s.ExpireAt() + } + if s.Status == Accepted { + min := s.ActiveAt + if s.VisibleAt > min { + min = s.VisibleAt + } + if min < next { + next = min + } + } + } + + return next +} + +func (n Node) findBestClaim() *Claim { + + // WARNING: this method is called billions of times. + // if we just had some easy way to know that our best claim was the first one in the list... + // or it may be faster to cache effective amount in the db at some point. + + var best *Claim + var bestAmount int64 + for _, candidate := range n.Claims { + + // not using switch here for performance reasons + if candidate.Status != Activated { + continue + } + + if best == nil { + best = candidate + continue + } + + candidateAmount := candidate.Amount + n.SupportSums[candidate.ClaimID.Key()] + if bestAmount <= 0 { + bestAmount = best.Amount + n.SupportSums[best.ClaimID.Key()] + } + + switch { + case candidateAmount > bestAmount: + best = candidate + bestAmount = candidateAmount + case candidateAmount < bestAmount: + continue + case candidate.AcceptedAt < best.AcceptedAt: + best = candidate + bestAmount = candidateAmount + case candidate.AcceptedAt > best.AcceptedAt: + continue + case OutPointLess(candidate.OutPoint, best.OutPoint): + best = candidate + bestAmount = candidateAmount + } + } + + return best +} + +func (n *Node) activateAllClaims(height int32) int { + count := 0 + for _, c := range n.Claims { + if c.Status == Accepted && c.ActiveAt > height && c.VisibleAt <= height { + c.setActiveAt(height) // don't necessarily need to change this number? + c.setStatus(Activated) + count++ + } + } + + for _, s := range n.Supports { + if s.Status == Accepted && s.ActiveAt > height && s.VisibleAt <= height { + s.setActiveAt(height) // don't necessarily need to change this number? + s.setStatus(Activated) + count++ + n.SupportSums[s.ClaimID.Key()] += s.Amount + } + } + return count +} + +func (n *Node) SortClaimsByBid() { + + // purposefully sorting by descent via func parameter order: + sort.Slice(n.Claims, func(j, i int) bool { + // SupportSums only include active values; do the same for amount. No active claim will have a zero amount + iAmount := n.SupportSums[n.Claims[i].ClaimID.Key()] + if n.Claims[i].Status == Activated { + iAmount += n.Claims[i].Amount + } + jAmount := n.SupportSums[n.Claims[j].ClaimID.Key()] + if n.Claims[j].Status == Activated { + jAmount += n.Claims[j].Amount + } + switch { + case iAmount < jAmount: + return true + case iAmount > jAmount: + return false + case n.Claims[i].AcceptedAt > n.Claims[j].AcceptedAt: + return true + case n.Claims[i].AcceptedAt < n.Claims[j].AcceptedAt: + return false + } + return OutPointLess(n.Claims[j].OutPoint, n.Claims[i].OutPoint) + }) +} diff --git a/claimtrie/node/noderepo/noderepo_test.go b/claimtrie/node/noderepo/noderepo_test.go new file mode 100644 index 00000000..fb0a9764 --- /dev/null +++ b/claimtrie/node/noderepo/noderepo_test.go @@ -0,0 +1,188 @@ +package noderepo + +import ( + "testing" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node" + + "github.com/stretchr/testify/require" +) + +var ( + out1 = node.NewOutPointFromString("0000000000000000000000000000000000000000000000000000000000000000:1") + testNodeName1 = []byte("name1") +) + +func TestPebble(t *testing.T) { + + r := require.New(t) + + repo, err := NewPebble(t.TempDir()) + r.NoError(err) + defer func() { + err := repo.Close() + r.NoError(err) + }() + + cleanup := func() { + lowerBound := testNodeName1 + upperBound := append(testNodeName1, byte(0)) + err := repo.db.DeleteRange(lowerBound, upperBound, nil) + r.NoError(err) + } + + testNodeRepo(t, repo, func() {}, cleanup) +} + +func testNodeRepo(t *testing.T, repo node.Repo, setup, cleanup func()) { + + r := require.New(t) + + chg := change.NewChange(change.AddClaim).SetName(testNodeName1).SetOutPoint(out1) + + testcases := []struct { + name string + height int32 + changes []change.Change + expected []change.Change + }{ + { + "test 1", + 1, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1)}, + }, + { + "test 2", + 2, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1)}, + }, + { + "test 3", + 3, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1), chg.SetHeight(3)}, + }, + { + "test 4", + 4, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1), chg.SetHeight(3)}, + }, + { + "test 5", + 5, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + }, + { + "test 6", + 6, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + }, + } + + for _, tt := range testcases { + + setup() + + err := repo.AppendChanges(tt.changes) + r.NoError(err) + + changes, err := repo.LoadChanges(testNodeName1) + r.NoError(err) + r.Equalf(tt.expected, changes[:len(tt.expected)], tt.name) + + cleanup() + } + + testcases2 := []struct { + name string + height int32 + changes [][]change.Change + expected []change.Change + }{ + { + "Save in 2 batches, and load up to 1", + 1, + [][]change.Change{ + {chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + {chg.SetHeight(6), chg.SetHeight(8), chg.SetHeight(9)}, + }, + []change.Change{chg.SetHeight(1)}, + }, + { + "Save in 2 batches, and load up to 9", + 9, + [][]change.Change{ + {chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + {chg.SetHeight(6), chg.SetHeight(8), chg.SetHeight(9)}, + }, + []change.Change{ + chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5), + chg.SetHeight(6), chg.SetHeight(8), chg.SetHeight(9), + }, + }, + { + "Save in 3 batches, and load up to 8", + 8, + [][]change.Change{ + {chg.SetHeight(1), chg.SetHeight(3)}, + {chg.SetHeight(5)}, + {chg.SetHeight(6), chg.SetHeight(8), chg.SetHeight(9)}, + }, + []change.Change{ + chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5), + chg.SetHeight(6), chg.SetHeight(8), + }, + }, + } + + for _, tt := range testcases2 { + + setup() + + for _, changes := range tt.changes { + err := repo.AppendChanges(changes) + r.NoError(err) + } + + changes, err := repo.LoadChanges(testNodeName1) + r.NoError(err) + r.Equalf(tt.expected, changes[:len(tt.expected)], tt.name) + + cleanup() + } +} + +func TestIterator(t *testing.T) { + + r := require.New(t) + + repo, err := NewPebble(t.TempDir()) + r.NoError(err) + defer func() { + err := repo.Close() + r.NoError(err) + }() + + creation := []change.Change{ + {Name: []byte("test\x00"), Height: 5}, + {Name: []byte("test\x00\x00"), Height: 5}, + {Name: []byte("test\x00b"), Height: 5}, + {Name: []byte("test\x00\xFF"), Height: 5}, + {Name: []byte("testa"), Height: 5}, + } + err = repo.AppendChanges(creation) + r.NoError(err) + + i := 0 + repo.IterateChildren([]byte{}, func(changes []change.Change) bool { + r.Equal(creation[i], changes[0]) + i++ + return true + }) +} diff --git a/claimtrie/node/noderepo/pebble.go b/claimtrie/node/noderepo/pebble.go new file mode 100644 index 00000000..a13dda82 --- /dev/null +++ b/claimtrie/node/noderepo/pebble.go @@ -0,0 +1,171 @@ +package noderepo + +import ( + "bytes" + "sort" + + "github.com/cockroachdb/pebble" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/pkg/errors" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + db, err := pebble.Open(path, &pebble.Options{Cache: pebble.NewCache(64 << 20), BytesPerSync: 8 << 20, MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "unable to open %s", path) +} + +// AppendChanges makes an assumption that anything you pass to it is newer than what was saved before. +func (repo *Pebble) AppendChanges(changes []change.Change) error { + + batch := repo.db.NewBatch() + defer batch.Close() + + buffer := bytes.NewBuffer(nil) + + for _, chg := range changes { + buffer.Reset() + err := chg.Marshal(buffer) + if err != nil { + return errors.Wrap(err, "in marshaller") + } + + err = batch.Merge(chg.Name, buffer.Bytes(), pebble.NoSync) + if err != nil { + return errors.Wrap(err, "in merge") + } + } + return errors.Wrap(batch.Commit(pebble.NoSync), "in commit") +} + +func (repo *Pebble) LoadChanges(name []byte) ([]change.Change, error) { + + data, closer, err := repo.db.Get(name) + if err != nil && err != pebble.ErrNotFound { + return nil, errors.Wrapf(err, "in get %s", name) // does returning a name in an error expose too much? + } + if closer != nil { + defer closer.Close() + } + + return unmarshalChanges(name, data) +} + +func unmarshalChanges(name, data []byte) ([]change.Change, error) { + // data is 84bytes+ per change + changes := make([]change.Change, 0, len(data)/84+1) // average is 5.1 changes + + buffer := bytes.NewBuffer(data) + for buffer.Len() > 0 { + var chg change.Change + err := chg.Unmarshal(buffer) + if err != nil { + return nil, errors.Wrap(err, "in decode") + } + chg.Name = name + changes = append(changes, chg) + } + + // this was required for the normalization stuff: + sort.SliceStable(changes, func(i, j int) bool { + return changes[i].Height < changes[j].Height + }) + + return changes, nil +} + +func (repo *Pebble) DropChanges(name []byte, finalHeight int32) error { + changes, err := repo.LoadChanges(name) + if err != nil { + return errors.Wrapf(err, "in load changes for %s", name) + } + i := 0 + for ; i < len(changes); i++ { // assuming changes are ordered by height + if changes[i].Height > finalHeight { + break + } + if changes[i].VisibleHeight > finalHeight { // created after this height has to be deleted + changes = append(changes[:i], changes[i+1:]...) + i-- + } + } + // making a performance assumption that DropChanges won't happen often: + err = repo.db.Set(name, []byte{}, pebble.NoSync) + if err != nil { + return errors.Wrapf(err, "in set at %s", name) + } + return repo.AppendChanges(changes[:i]) +} + +func (repo *Pebble) IterateChildren(name []byte, f func(changes []change.Change) bool) error { + start := make([]byte, len(name)+1) // zeros that last byte; need a constant len for stack alloc? + copy(start, name) + + end := make([]byte, len(name)) // max name length is 255 + copy(end, name) + validEnd := false + for i := len(name) - 1; i >= 0; i-- { + end[i]++ + if end[i] != 0 { + validEnd = true + break + } + } + if !validEnd { + end = nil // uh, we think this means run to the end of the table + } + + prefixIterOptions := &pebble.IterOptions{ + LowerBound: start, + UpperBound: end, + } + + iter := repo.db.NewIter(prefixIterOptions) + defer iter.Close() + + for iter.First(); iter.Valid(); iter.Next() { + // NOTE! iter.Key() is ephemeral! + changes, err := unmarshalChanges(iter.Key(), iter.Value()) + if err != nil { + return errors.Wrapf(err, "from unmarshaller at %s", iter.Key()) + } + if !f(changes) { + break + } + } + return nil +} + +func (repo *Pebble) IterateAll(predicate func(name []byte) bool) { + iter := repo.db.NewIter(nil) + defer iter.Close() + + for iter.First(); iter.Valid(); iter.Next() { + if !predicate(iter.Key()) { + break + } + } +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/node/normalizing_manager.go b/claimtrie/node/normalizing_manager.go new file mode 100644 index 00000000..d35403cd --- /dev/null +++ b/claimtrie/node/normalizing_manager.go @@ -0,0 +1,114 @@ +package node + +import ( + "bytes" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/normalization" + "github.com/lbryio/lbcd/claimtrie/param" +) + +type NormalizingManager struct { // implements Manager + Manager + normalizedAt int32 +} + +func NewNormalizingManager(baseManager Manager) Manager { + log.Info(normalization.NormalizeTitle) + return &NormalizingManager{ + Manager: baseManager, + normalizedAt: -1, + } +} + +func (nm *NormalizingManager) AppendChange(chg change.Change) { + chg.Name = normalization.NormalizeIfNecessary(chg.Name, chg.Height) + nm.Manager.AppendChange(chg) +} + +func (nm *NormalizingManager) IncrementHeightTo(height int32) ([][]byte, error) { + nm.addNormalizationForkChangesIfNecessary(height) + return nm.Manager.IncrementHeightTo(height) +} + +func (nm *NormalizingManager) DecrementHeightTo(affectedNames [][]byte, height int32) error { + if nm.normalizedAt > height { + nm.normalizedAt = -1 + } + return nm.Manager.DecrementHeightTo(affectedNames, height) +} + +func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int32) { + + if nm.Manager.Height()+1 != height { + // initialization phase + if height >= param.ActiveParams.NormalizedNameForkHeight { + nm.normalizedAt = param.ActiveParams.NormalizedNameForkHeight // eh, we don't really know that it happened there + } + } + + if nm.normalizedAt >= 0 || height != param.ActiveParams.NormalizedNameForkHeight { + return + } + nm.normalizedAt = height + log.Info("Generating necessary changes for the normalization fork...") + + // the original code had an unfortunate bug where many unnecessary takeovers + // were triggered at the normalization fork + predicate := func(name []byte) bool { + norm := normalization.Normalize(name) + eq := bytes.Equal(name, norm) + if eq { + return true + } + + clone := make([]byte, len(name)) + copy(clone, name) // iteration name buffer is reused on future loops + + // by loading changes for norm here, you can determine if there will be a conflict + + n, err := nm.Manager.NodeAt(nm.Manager.Height(), clone) + if err != nil || n == nil { + return true + } + for _, c := range n.Claims { + nm.Manager.AppendChange(change.Change{ + Type: change.AddClaim, + Name: norm, + Height: c.AcceptedAt, + OutPoint: c.OutPoint, + ClaimID: c.ClaimID, + Amount: c.Amount, + ActiveHeight: c.ActiveAt, // necessary to match the old hash + VisibleHeight: height, // necessary to match the old hash; it would have been much better without + }) + nm.Manager.AppendChange(change.Change{ + Type: change.SpendClaim, + Name: clone, + Height: height, + OutPoint: c.OutPoint, + }) + } + for _, c := range n.Supports { + nm.Manager.AppendChange(change.Change{ + Type: change.AddSupport, + Name: norm, + Height: c.AcceptedAt, + OutPoint: c.OutPoint, + ClaimID: c.ClaimID, + Amount: c.Amount, + ActiveHeight: c.ActiveAt, + VisibleHeight: height, + }) + nm.Manager.AppendChange(change.Change{ + Type: change.SpendSupport, + Name: clone, + Height: height, + OutPoint: c.OutPoint, + }) + } + + return true + } + nm.Manager.IterateNames(predicate) +} diff --git a/claimtrie/node/repo.go b/claimtrie/node/repo.go new file mode 100644 index 00000000..4aaa65e8 --- /dev/null +++ b/claimtrie/node/repo.go @@ -0,0 +1,31 @@ +package node + +import ( + "github.com/lbryio/lbcd/claimtrie/change" +) + +// Repo defines APIs for Node to access persistence layer. +type Repo interface { + // AppendChanges saves changes into the repo. + // The changes can belong to different nodes, but the chronological + // order must be preserved for the same node. + AppendChanges(changes []change.Change) error + + // LoadChanges loads changes of a node up to (includes) the specified height. + // If no changes found, both returned slice and error will be nil. + LoadChanges(name []byte) ([]change.Change, error) + + DropChanges(name []byte, finalHeight int32) error + + // Close closes the repo. + Close() error + + // IterateChildren returns change sets for each of name.+ + // Return false on f to stop the iteration. + IterateChildren(name []byte, f func(changes []change.Change) bool) error + + // IterateAll iterates keys until the predicate function returns false + IterateAll(predicate func(name []byte) bool) + + Flush() error +} diff --git a/claimtrie/normalization/CaseFolding_v11.txt b/claimtrie/normalization/CaseFolding_v11.txt new file mode 100644 index 00000000..cce350f4 --- /dev/null +++ b/claimtrie/normalization/CaseFolding_v11.txt @@ -0,0 +1,1574 @@ +# CaseFolding-11.0.0.txt +# Date: 2018-01-31, 08:20:09 GMT +# © 2018 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Case Folding Properties +# +# This file is a supplement to the UnicodeData file. +# It provides a case folding mapping generated from the Unicode Character Database. +# If all characters are mapped according to the full mapping below, then +# case differences (according to UnicodeData.txt and SpecialCasing.txt) +# are eliminated. +# +# The data supports both implementations that require simple case foldings +# (where string lengths don't change), and implementations that allow full case folding +# (where string lengths may grow). Note that where they can be supported, the +# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match. +# +# All code points not listed in this file map to themselves. +# +# NOTE: case folding does not preserve normalization formats! +# +# For information on case folding, including how to have case folding +# preserve normalization formats, see Section 3.13 Default Case Algorithms in +# The Unicode Standard. +# +# ================================================================================ +# Format +# ================================================================================ +# The entries in this file are in the following machine-readable format: +# +# ; ; ; # +# +# The status field is: +# C: common case folding, common mappings shared by both simple and full mappings. +# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces. +# S: simple case folding, mappings to single characters where different from F. +# T: special case for uppercase I and dotted uppercase I +# - For non-Turkic languages, this mapping is normally not used. +# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters. +# Note that the Turkic mappings do not maintain canonical equivalence without additional processing. +# See the discussions of case mapping in the Unicode Standard for more information. +# +# Usage: +# A. To do a simple case folding, use the mappings with status C + S. +# B. To do a full case folding, use the mappings with status C + F. +# +# The mappings with status T can be used or omitted depending on the desired case-folding +# behavior. (The default option is to exclude them.) +# +# ================================================================= + +# Property: Case_Folding + +# All code points not explicitly listed for Case_Folding +# have the value C for the status field, and the code point itself for the mapping field. + +# ================================================================= +0041; C; 0061; # LATIN CAPITAL LETTER A +0042; C; 0062; # LATIN CAPITAL LETTER B +0043; C; 0063; # LATIN CAPITAL LETTER C +0044; C; 0064; # LATIN CAPITAL LETTER D +0045; C; 0065; # LATIN CAPITAL LETTER E +0046; C; 0066; # LATIN CAPITAL LETTER F +0047; C; 0067; # LATIN CAPITAL LETTER G +0048; C; 0068; # LATIN CAPITAL LETTER H +0049; C; 0069; # LATIN CAPITAL LETTER I +0049; T; 0131; # LATIN CAPITAL LETTER I +004A; C; 006A; # LATIN CAPITAL LETTER J +004B; C; 006B; # LATIN CAPITAL LETTER K +004C; C; 006C; # LATIN CAPITAL LETTER L +004D; C; 006D; # LATIN CAPITAL LETTER M +004E; C; 006E; # LATIN CAPITAL LETTER N +004F; C; 006F; # LATIN CAPITAL LETTER O +0050; C; 0070; # LATIN CAPITAL LETTER P +0051; C; 0071; # LATIN CAPITAL LETTER Q +0052; C; 0072; # LATIN CAPITAL LETTER R +0053; C; 0073; # LATIN CAPITAL LETTER S +0054; C; 0074; # LATIN CAPITAL LETTER T +0055; C; 0075; # LATIN CAPITAL LETTER U +0056; C; 0076; # LATIN CAPITAL LETTER V +0057; C; 0077; # LATIN CAPITAL LETTER W +0058; C; 0078; # LATIN CAPITAL LETTER X +0059; C; 0079; # LATIN CAPITAL LETTER Y +005A; C; 007A; # LATIN CAPITAL LETTER Z +00B5; C; 03BC; # MICRO SIGN +00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE +00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE +00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE +00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS +00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE +00C6; C; 00E6; # LATIN CAPITAL LETTER AE +00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA +00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE +00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE +00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS +00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE +00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE +00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS +00D0; C; 00F0; # LATIN CAPITAL LETTER ETH +00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE +00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE +00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE +00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE +00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS +00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE +00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE +00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE +00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS +00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE +00DE; C; 00FE; # LATIN CAPITAL LETTER THORN +00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S +0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON +0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE +0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK +0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE +0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE +010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON +010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON +0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE +0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON +0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE +0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE +0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK +011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON +011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE +0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE +0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA +0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE +0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE +012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON +012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE +012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK +0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0132; C; 0133; # LATIN CAPITAL LIGATURE IJ +0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA +0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE +013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA +013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON +013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT +0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE +0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE +0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA +0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON +0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +014A; C; 014B; # LATIN CAPITAL LETTER ENG +014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON +014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE +0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0152; C; 0153; # LATIN CAPITAL LIGATURE OE +0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE +0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA +0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON +015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE +015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA +0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON +0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA +0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON +0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE +0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE +016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON +016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE +016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE +0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK +0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS +0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE +017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE +017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON +017F; C; 0073; # LATIN SMALL LETTER LONG S +0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK +0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR +0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX +0186; C; 0254; # LATIN CAPITAL LETTER OPEN O +0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK +0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D +018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK +018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR +018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E +018F; C; 0259; # LATIN CAPITAL LETTER SCHWA +0190; C; 025B; # LATIN CAPITAL LETTER OPEN E +0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK +0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK +0194; C; 0263; # LATIN CAPITAL LETTER GAMMA +0196; C; 0269; # LATIN CAPITAL LETTER IOTA +0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE +0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK +019C; C; 026F; # LATIN CAPITAL LETTER TURNED M +019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK +019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE +01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN +01A2; C; 01A3; # LATIN CAPITAL LETTER OI +01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK +01A6; C; 0280; # LATIN LETTER YR +01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO +01A9; C; 0283; # LATIN CAPITAL LETTER ESH +01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK +01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK +01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN +01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON +01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK +01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK +01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE +01B7; C; 0292; # LATIN CAPITAL LETTER EZH +01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED +01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE +01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON +01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON +01C7; C; 01C9; # LATIN CAPITAL LETTER LJ +01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J +01CA; C; 01CC; # LATIN CAPITAL LETTER NJ +01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J +01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON +01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON +01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON +01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON +01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON +01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON +01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON +01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE +01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON +01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON +01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK +01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON +01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON +01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON +01F1; C; 01F3; # LATIN CAPITAL LETTER DZ +01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z +01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE +01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR +01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN +01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE +01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE +01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE +0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE +0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE +0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE +0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE +020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE +020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE +020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE +0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE +0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE +0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE +0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE +0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW +021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW +021C; C; 021D; # LATIN CAPITAL LETTER YOGH +021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON +0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG +0222; C; 0223; # LATIN CAPITAL LETTER OU +0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK +0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE +0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA +022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON +022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON +022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE +0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON +0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON +023A; C; 2C65; # LATIN CAPITAL LETTER A WITH STROKE +023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE +023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR +023E; C; 2C66; # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE +0241; C; 0242; # LATIN CAPITAL LETTER GLOTTAL STOP +0243; C; 0180; # LATIN CAPITAL LETTER B WITH STROKE +0244; C; 0289; # LATIN CAPITAL LETTER U BAR +0245; C; 028C; # LATIN CAPITAL LETTER TURNED V +0246; C; 0247; # LATIN CAPITAL LETTER E WITH STROKE +0248; C; 0249; # LATIN CAPITAL LETTER J WITH STROKE +024A; C; 024B; # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL +024C; C; 024D; # LATIN CAPITAL LETTER R WITH STROKE +024E; C; 024F; # LATIN CAPITAL LETTER Y WITH STROKE +0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI +0370; C; 0371; # GREEK CAPITAL LETTER HETA +0372; C; 0373; # GREEK CAPITAL LETTER ARCHAIC SAMPI +0376; C; 0377; # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA +037F; C; 03F3; # GREEK CAPITAL LETTER YOT +0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS +0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS +0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS +038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS +038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS +038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS +038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS +0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA +0392; C; 03B2; # GREEK CAPITAL LETTER BETA +0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA +0394; C; 03B4; # GREEK CAPITAL LETTER DELTA +0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON +0396; C; 03B6; # GREEK CAPITAL LETTER ZETA +0397; C; 03B7; # GREEK CAPITAL LETTER ETA +0398; C; 03B8; # GREEK CAPITAL LETTER THETA +0399; C; 03B9; # GREEK CAPITAL LETTER IOTA +039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA +039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA +039C; C; 03BC; # GREEK CAPITAL LETTER MU +039D; C; 03BD; # GREEK CAPITAL LETTER NU +039E; C; 03BE; # GREEK CAPITAL LETTER XI +039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON +03A0; C; 03C0; # GREEK CAPITAL LETTER PI +03A1; C; 03C1; # GREEK CAPITAL LETTER RHO +03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA +03A4; C; 03C4; # GREEK CAPITAL LETTER TAU +03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON +03A6; C; 03C6; # GREEK CAPITAL LETTER PHI +03A7; C; 03C7; # GREEK CAPITAL LETTER CHI +03A8; C; 03C8; # GREEK CAPITAL LETTER PSI +03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA +03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA +03CF; C; 03D7; # GREEK CAPITAL KAI SYMBOL +03D0; C; 03B2; # GREEK BETA SYMBOL +03D1; C; 03B8; # GREEK THETA SYMBOL +03D5; C; 03C6; # GREEK PHI SYMBOL +03D6; C; 03C0; # GREEK PI SYMBOL +03D8; C; 03D9; # GREEK LETTER ARCHAIC KOPPA +03DA; C; 03DB; # GREEK LETTER STIGMA +03DC; C; 03DD; # GREEK LETTER DIGAMMA +03DE; C; 03DF; # GREEK LETTER KOPPA +03E0; C; 03E1; # GREEK LETTER SAMPI +03E2; C; 03E3; # COPTIC CAPITAL LETTER SHEI +03E4; C; 03E5; # COPTIC CAPITAL LETTER FEI +03E6; C; 03E7; # COPTIC CAPITAL LETTER KHEI +03E8; C; 03E9; # COPTIC CAPITAL LETTER HORI +03EA; C; 03EB; # COPTIC CAPITAL LETTER GANGIA +03EC; C; 03ED; # COPTIC CAPITAL LETTER SHIMA +03EE; C; 03EF; # COPTIC CAPITAL LETTER DEI +03F0; C; 03BA; # GREEK KAPPA SYMBOL +03F1; C; 03C1; # GREEK RHO SYMBOL +03F4; C; 03B8; # GREEK CAPITAL THETA SYMBOL +03F5; C; 03B5; # GREEK LUNATE EPSILON SYMBOL +03F7; C; 03F8; # GREEK CAPITAL LETTER SHO +03F9; C; 03F2; # GREEK CAPITAL LUNATE SIGMA SYMBOL +03FA; C; 03FB; # GREEK CAPITAL LETTER SAN +03FD; C; 037B; # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL +03FE; C; 037C; # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL +03FF; C; 037D; # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL +0400; C; 0450; # CYRILLIC CAPITAL LETTER IE WITH GRAVE +0401; C; 0451; # CYRILLIC CAPITAL LETTER IO +0402; C; 0452; # CYRILLIC CAPITAL LETTER DJE +0403; C; 0453; # CYRILLIC CAPITAL LETTER GJE +0404; C; 0454; # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0405; C; 0455; # CYRILLIC CAPITAL LETTER DZE +0406; C; 0456; # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0407; C; 0457; # CYRILLIC CAPITAL LETTER YI +0408; C; 0458; # CYRILLIC CAPITAL LETTER JE +0409; C; 0459; # CYRILLIC CAPITAL LETTER LJE +040A; C; 045A; # CYRILLIC CAPITAL LETTER NJE +040B; C; 045B; # CYRILLIC CAPITAL LETTER TSHE +040C; C; 045C; # CYRILLIC CAPITAL LETTER KJE +040D; C; 045D; # CYRILLIC CAPITAL LETTER I WITH GRAVE +040E; C; 045E; # CYRILLIC CAPITAL LETTER SHORT U +040F; C; 045F; # CYRILLIC CAPITAL LETTER DZHE +0410; C; 0430; # CYRILLIC CAPITAL LETTER A +0411; C; 0431; # CYRILLIC CAPITAL LETTER BE +0412; C; 0432; # CYRILLIC CAPITAL LETTER VE +0413; C; 0433; # CYRILLIC CAPITAL LETTER GHE +0414; C; 0434; # CYRILLIC CAPITAL LETTER DE +0415; C; 0435; # CYRILLIC CAPITAL LETTER IE +0416; C; 0436; # CYRILLIC CAPITAL LETTER ZHE +0417; C; 0437; # CYRILLIC CAPITAL LETTER ZE +0418; C; 0438; # CYRILLIC CAPITAL LETTER I +0419; C; 0439; # CYRILLIC CAPITAL LETTER SHORT I +041A; C; 043A; # CYRILLIC CAPITAL LETTER KA +041B; C; 043B; # CYRILLIC CAPITAL LETTER EL +041C; C; 043C; # CYRILLIC CAPITAL LETTER EM +041D; C; 043D; # CYRILLIC CAPITAL LETTER EN +041E; C; 043E; # CYRILLIC CAPITAL LETTER O +041F; C; 043F; # CYRILLIC CAPITAL LETTER PE +0420; C; 0440; # CYRILLIC CAPITAL LETTER ER +0421; C; 0441; # CYRILLIC CAPITAL LETTER ES +0422; C; 0442; # CYRILLIC CAPITAL LETTER TE +0423; C; 0443; # CYRILLIC CAPITAL LETTER U +0424; C; 0444; # CYRILLIC CAPITAL LETTER EF +0425; C; 0445; # CYRILLIC CAPITAL LETTER HA +0426; C; 0446; # CYRILLIC CAPITAL LETTER TSE +0427; C; 0447; # CYRILLIC CAPITAL LETTER CHE +0428; C; 0448; # CYRILLIC CAPITAL LETTER SHA +0429; C; 0449; # CYRILLIC CAPITAL LETTER SHCHA +042A; C; 044A; # CYRILLIC CAPITAL LETTER HARD SIGN +042B; C; 044B; # CYRILLIC CAPITAL LETTER YERU +042C; C; 044C; # CYRILLIC CAPITAL LETTER SOFT SIGN +042D; C; 044D; # CYRILLIC CAPITAL LETTER E +042E; C; 044E; # CYRILLIC CAPITAL LETTER YU +042F; C; 044F; # CYRILLIC CAPITAL LETTER YA +0460; C; 0461; # CYRILLIC CAPITAL LETTER OMEGA +0462; C; 0463; # CYRILLIC CAPITAL LETTER YAT +0464; C; 0465; # CYRILLIC CAPITAL LETTER IOTIFIED E +0466; C; 0467; # CYRILLIC CAPITAL LETTER LITTLE YUS +0468; C; 0469; # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS +046A; C; 046B; # CYRILLIC CAPITAL LETTER BIG YUS +046C; C; 046D; # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS +046E; C; 046F; # CYRILLIC CAPITAL LETTER KSI +0470; C; 0471; # CYRILLIC CAPITAL LETTER PSI +0472; C; 0473; # CYRILLIC CAPITAL LETTER FITA +0474; C; 0475; # CYRILLIC CAPITAL LETTER IZHITSA +0476; C; 0477; # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0478; C; 0479; # CYRILLIC CAPITAL LETTER UK +047A; C; 047B; # CYRILLIC CAPITAL LETTER ROUND OMEGA +047C; C; 047D; # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO +047E; C; 047F; # CYRILLIC CAPITAL LETTER OT +0480; C; 0481; # CYRILLIC CAPITAL LETTER KOPPA +048A; C; 048B; # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL +048C; C; 048D; # CYRILLIC CAPITAL LETTER SEMISOFT SIGN +048E; C; 048F; # CYRILLIC CAPITAL LETTER ER WITH TICK +0490; C; 0491; # CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0492; C; 0493; # CYRILLIC CAPITAL LETTER GHE WITH STROKE +0494; C; 0495; # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK +0496; C; 0497; # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER +0498; C; 0499; # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER +049A; C; 049B; # CYRILLIC CAPITAL LETTER KA WITH DESCENDER +049C; C; 049D; # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE +049E; C; 049F; # CYRILLIC CAPITAL LETTER KA WITH STROKE +04A0; C; 04A1; # CYRILLIC CAPITAL LETTER BASHKIR KA +04A2; C; 04A3; # CYRILLIC CAPITAL LETTER EN WITH DESCENDER +04A4; C; 04A5; # CYRILLIC CAPITAL LIGATURE EN GHE +04A6; C; 04A7; # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK +04A8; C; 04A9; # CYRILLIC CAPITAL LETTER ABKHASIAN HA +04AA; C; 04AB; # CYRILLIC CAPITAL LETTER ES WITH DESCENDER +04AC; C; 04AD; # CYRILLIC CAPITAL LETTER TE WITH DESCENDER +04AE; C; 04AF; # CYRILLIC CAPITAL LETTER STRAIGHT U +04B0; C; 04B1; # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE +04B2; C; 04B3; # CYRILLIC CAPITAL LETTER HA WITH DESCENDER +04B4; C; 04B5; # CYRILLIC CAPITAL LIGATURE TE TSE +04B6; C; 04B7; # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER +04B8; C; 04B9; # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE +04BA; C; 04BB; # CYRILLIC CAPITAL LETTER SHHA +04BC; C; 04BD; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE +04BE; C; 04BF; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER +04C0; C; 04CF; # CYRILLIC LETTER PALOCHKA +04C1; C; 04C2; # CYRILLIC CAPITAL LETTER ZHE WITH BREVE +04C3; C; 04C4; # CYRILLIC CAPITAL LETTER KA WITH HOOK +04C5; C; 04C6; # CYRILLIC CAPITAL LETTER EL WITH TAIL +04C7; C; 04C8; # CYRILLIC CAPITAL LETTER EN WITH HOOK +04C9; C; 04CA; # CYRILLIC CAPITAL LETTER EN WITH TAIL +04CB; C; 04CC; # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE +04CD; C; 04CE; # CYRILLIC CAPITAL LETTER EM WITH TAIL +04D0; C; 04D1; # CYRILLIC CAPITAL LETTER A WITH BREVE +04D2; C; 04D3; # CYRILLIC CAPITAL LETTER A WITH DIAERESIS +04D4; C; 04D5; # CYRILLIC CAPITAL LIGATURE A IE +04D6; C; 04D7; # CYRILLIC CAPITAL LETTER IE WITH BREVE +04D8; C; 04D9; # CYRILLIC CAPITAL LETTER SCHWA +04DA; C; 04DB; # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS +04DC; C; 04DD; # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS +04DE; C; 04DF; # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS +04E0; C; 04E1; # CYRILLIC CAPITAL LETTER ABKHASIAN DZE +04E2; C; 04E3; # CYRILLIC CAPITAL LETTER I WITH MACRON +04E4; C; 04E5; # CYRILLIC CAPITAL LETTER I WITH DIAERESIS +04E6; C; 04E7; # CYRILLIC CAPITAL LETTER O WITH DIAERESIS +04E8; C; 04E9; # CYRILLIC CAPITAL LETTER BARRED O +04EA; C; 04EB; # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS +04EC; C; 04ED; # CYRILLIC CAPITAL LETTER E WITH DIAERESIS +04EE; C; 04EF; # CYRILLIC CAPITAL LETTER U WITH MACRON +04F0; C; 04F1; # CYRILLIC CAPITAL LETTER U WITH DIAERESIS +04F2; C; 04F3; # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE +04F4; C; 04F5; # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS +04F6; C; 04F7; # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER +04F8; C; 04F9; # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS +04FA; C; 04FB; # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK +04FC; C; 04FD; # CYRILLIC CAPITAL LETTER HA WITH HOOK +04FE; C; 04FF; # CYRILLIC CAPITAL LETTER HA WITH STROKE +0500; C; 0501; # CYRILLIC CAPITAL LETTER KOMI DE +0502; C; 0503; # CYRILLIC CAPITAL LETTER KOMI DJE +0504; C; 0505; # CYRILLIC CAPITAL LETTER KOMI ZJE +0506; C; 0507; # CYRILLIC CAPITAL LETTER KOMI DZJE +0508; C; 0509; # CYRILLIC CAPITAL LETTER KOMI LJE +050A; C; 050B; # CYRILLIC CAPITAL LETTER KOMI NJE +050C; C; 050D; # CYRILLIC CAPITAL LETTER KOMI SJE +050E; C; 050F; # CYRILLIC CAPITAL LETTER KOMI TJE +0510; C; 0511; # CYRILLIC CAPITAL LETTER REVERSED ZE +0512; C; 0513; # CYRILLIC CAPITAL LETTER EL WITH HOOK +0514; C; 0515; # CYRILLIC CAPITAL LETTER LHA +0516; C; 0517; # CYRILLIC CAPITAL LETTER RHA +0518; C; 0519; # CYRILLIC CAPITAL LETTER YAE +051A; C; 051B; # CYRILLIC CAPITAL LETTER QA +051C; C; 051D; # CYRILLIC CAPITAL LETTER WE +051E; C; 051F; # CYRILLIC CAPITAL LETTER ALEUT KA +0520; C; 0521; # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK +0522; C; 0523; # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK +0524; C; 0525; # CYRILLIC CAPITAL LETTER PE WITH DESCENDER +0526; C; 0527; # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER +0528; C; 0529; # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK +052A; C; 052B; # CYRILLIC CAPITAL LETTER DZZHE +052C; C; 052D; # CYRILLIC CAPITAL LETTER DCHE +052E; C; 052F; # CYRILLIC CAPITAL LETTER EL WITH DESCENDER +0531; C; 0561; # ARMENIAN CAPITAL LETTER AYB +0532; C; 0562; # ARMENIAN CAPITAL LETTER BEN +0533; C; 0563; # ARMENIAN CAPITAL LETTER GIM +0534; C; 0564; # ARMENIAN CAPITAL LETTER DA +0535; C; 0565; # ARMENIAN CAPITAL LETTER ECH +0536; C; 0566; # ARMENIAN CAPITAL LETTER ZA +0537; C; 0567; # ARMENIAN CAPITAL LETTER EH +0538; C; 0568; # ARMENIAN CAPITAL LETTER ET +0539; C; 0569; # ARMENIAN CAPITAL LETTER TO +053A; C; 056A; # ARMENIAN CAPITAL LETTER ZHE +053B; C; 056B; # ARMENIAN CAPITAL LETTER INI +053C; C; 056C; # ARMENIAN CAPITAL LETTER LIWN +053D; C; 056D; # ARMENIAN CAPITAL LETTER XEH +053E; C; 056E; # ARMENIAN CAPITAL LETTER CA +053F; C; 056F; # ARMENIAN CAPITAL LETTER KEN +0540; C; 0570; # ARMENIAN CAPITAL LETTER HO +0541; C; 0571; # ARMENIAN CAPITAL LETTER JA +0542; C; 0572; # ARMENIAN CAPITAL LETTER GHAD +0543; C; 0573; # ARMENIAN CAPITAL LETTER CHEH +0544; C; 0574; # ARMENIAN CAPITAL LETTER MEN +0545; C; 0575; # ARMENIAN CAPITAL LETTER YI +0546; C; 0576; # ARMENIAN CAPITAL LETTER NOW +0547; C; 0577; # ARMENIAN CAPITAL LETTER SHA +0548; C; 0578; # ARMENIAN CAPITAL LETTER VO +0549; C; 0579; # ARMENIAN CAPITAL LETTER CHA +054A; C; 057A; # ARMENIAN CAPITAL LETTER PEH +054B; C; 057B; # ARMENIAN CAPITAL LETTER JHEH +054C; C; 057C; # ARMENIAN CAPITAL LETTER RA +054D; C; 057D; # ARMENIAN CAPITAL LETTER SEH +054E; C; 057E; # ARMENIAN CAPITAL LETTER VEW +054F; C; 057F; # ARMENIAN CAPITAL LETTER TIWN +0550; C; 0580; # ARMENIAN CAPITAL LETTER REH +0551; C; 0581; # ARMENIAN CAPITAL LETTER CO +0552; C; 0582; # ARMENIAN CAPITAL LETTER YIWN +0553; C; 0583; # ARMENIAN CAPITAL LETTER PIWR +0554; C; 0584; # ARMENIAN CAPITAL LETTER KEH +0555; C; 0585; # ARMENIAN CAPITAL LETTER OH +0556; C; 0586; # ARMENIAN CAPITAL LETTER FEH +0587; F; 0565 0582; # ARMENIAN SMALL LIGATURE ECH YIWN +10A0; C; 2D00; # GEORGIAN CAPITAL LETTER AN +10A1; C; 2D01; # GEORGIAN CAPITAL LETTER BAN +10A2; C; 2D02; # GEORGIAN CAPITAL LETTER GAN +10A3; C; 2D03; # GEORGIAN CAPITAL LETTER DON +10A4; C; 2D04; # GEORGIAN CAPITAL LETTER EN +10A5; C; 2D05; # GEORGIAN CAPITAL LETTER VIN +10A6; C; 2D06; # GEORGIAN CAPITAL LETTER ZEN +10A7; C; 2D07; # GEORGIAN CAPITAL LETTER TAN +10A8; C; 2D08; # GEORGIAN CAPITAL LETTER IN +10A9; C; 2D09; # GEORGIAN CAPITAL LETTER KAN +10AA; C; 2D0A; # GEORGIAN CAPITAL LETTER LAS +10AB; C; 2D0B; # GEORGIAN CAPITAL LETTER MAN +10AC; C; 2D0C; # GEORGIAN CAPITAL LETTER NAR +10AD; C; 2D0D; # GEORGIAN CAPITAL LETTER ON +10AE; C; 2D0E; # GEORGIAN CAPITAL LETTER PAR +10AF; C; 2D0F; # GEORGIAN CAPITAL LETTER ZHAR +10B0; C; 2D10; # GEORGIAN CAPITAL LETTER RAE +10B1; C; 2D11; # GEORGIAN CAPITAL LETTER SAN +10B2; C; 2D12; # GEORGIAN CAPITAL LETTER TAR +10B3; C; 2D13; # GEORGIAN CAPITAL LETTER UN +10B4; C; 2D14; # GEORGIAN CAPITAL LETTER PHAR +10B5; C; 2D15; # GEORGIAN CAPITAL LETTER KHAR +10B6; C; 2D16; # GEORGIAN CAPITAL LETTER GHAN +10B7; C; 2D17; # GEORGIAN CAPITAL LETTER QAR +10B8; C; 2D18; # GEORGIAN CAPITAL LETTER SHIN +10B9; C; 2D19; # GEORGIAN CAPITAL LETTER CHIN +10BA; C; 2D1A; # GEORGIAN CAPITAL LETTER CAN +10BB; C; 2D1B; # GEORGIAN CAPITAL LETTER JIL +10BC; C; 2D1C; # GEORGIAN CAPITAL LETTER CIL +10BD; C; 2D1D; # GEORGIAN CAPITAL LETTER CHAR +10BE; C; 2D1E; # GEORGIAN CAPITAL LETTER XAN +10BF; C; 2D1F; # GEORGIAN CAPITAL LETTER JHAN +10C0; C; 2D20; # GEORGIAN CAPITAL LETTER HAE +10C1; C; 2D21; # GEORGIAN CAPITAL LETTER HE +10C2; C; 2D22; # GEORGIAN CAPITAL LETTER HIE +10C3; C; 2D23; # GEORGIAN CAPITAL LETTER WE +10C4; C; 2D24; # GEORGIAN CAPITAL LETTER HAR +10C5; C; 2D25; # GEORGIAN CAPITAL LETTER HOE +10C7; C; 2D27; # GEORGIAN CAPITAL LETTER YN +10CD; C; 2D2D; # GEORGIAN CAPITAL LETTER AEN +13F8; C; 13F0; # CHEROKEE SMALL LETTER YE +13F9; C; 13F1; # CHEROKEE SMALL LETTER YI +13FA; C; 13F2; # CHEROKEE SMALL LETTER YO +13FB; C; 13F3; # CHEROKEE SMALL LETTER YU +13FC; C; 13F4; # CHEROKEE SMALL LETTER YV +13FD; C; 13F5; # CHEROKEE SMALL LETTER MV +1C80; C; 0432; # CYRILLIC SMALL LETTER ROUNDED VE +1C81; C; 0434; # CYRILLIC SMALL LETTER LONG-LEGGED DE +1C82; C; 043E; # CYRILLIC SMALL LETTER NARROW O +1C83; C; 0441; # CYRILLIC SMALL LETTER WIDE ES +1C84; C; 0442; # CYRILLIC SMALL LETTER TALL TE +1C85; C; 0442; # CYRILLIC SMALL LETTER THREE-LEGGED TE +1C86; C; 044A; # CYRILLIC SMALL LETTER TALL HARD SIGN +1C87; C; 0463; # CYRILLIC SMALL LETTER TALL YAT +1C88; C; A64B; # CYRILLIC SMALL LETTER UNBLENDED UK +1C90; C; 10D0; # GEORGIAN MTAVRULI CAPITAL LETTER AN +1C91; C; 10D1; # GEORGIAN MTAVRULI CAPITAL LETTER BAN +1C92; C; 10D2; # GEORGIAN MTAVRULI CAPITAL LETTER GAN +1C93; C; 10D3; # GEORGIAN MTAVRULI CAPITAL LETTER DON +1C94; C; 10D4; # GEORGIAN MTAVRULI CAPITAL LETTER EN +1C95; C; 10D5; # GEORGIAN MTAVRULI CAPITAL LETTER VIN +1C96; C; 10D6; # GEORGIAN MTAVRULI CAPITAL LETTER ZEN +1C97; C; 10D7; # GEORGIAN MTAVRULI CAPITAL LETTER TAN +1C98; C; 10D8; # GEORGIAN MTAVRULI CAPITAL LETTER IN +1C99; C; 10D9; # GEORGIAN MTAVRULI CAPITAL LETTER KAN +1C9A; C; 10DA; # GEORGIAN MTAVRULI CAPITAL LETTER LAS +1C9B; C; 10DB; # GEORGIAN MTAVRULI CAPITAL LETTER MAN +1C9C; C; 10DC; # GEORGIAN MTAVRULI CAPITAL LETTER NAR +1C9D; C; 10DD; # GEORGIAN MTAVRULI CAPITAL LETTER ON +1C9E; C; 10DE; # GEORGIAN MTAVRULI CAPITAL LETTER PAR +1C9F; C; 10DF; # GEORGIAN MTAVRULI CAPITAL LETTER ZHAR +1CA0; C; 10E0; # GEORGIAN MTAVRULI CAPITAL LETTER RAE +1CA1; C; 10E1; # GEORGIAN MTAVRULI CAPITAL LETTER SAN +1CA2; C; 10E2; # GEORGIAN MTAVRULI CAPITAL LETTER TAR +1CA3; C; 10E3; # GEORGIAN MTAVRULI CAPITAL LETTER UN +1CA4; C; 10E4; # GEORGIAN MTAVRULI CAPITAL LETTER PHAR +1CA5; C; 10E5; # GEORGIAN MTAVRULI CAPITAL LETTER KHAR +1CA6; C; 10E6; # GEORGIAN MTAVRULI CAPITAL LETTER GHAN +1CA7; C; 10E7; # GEORGIAN MTAVRULI CAPITAL LETTER QAR +1CA8; C; 10E8; # GEORGIAN MTAVRULI CAPITAL LETTER SHIN +1CA9; C; 10E9; # GEORGIAN MTAVRULI CAPITAL LETTER CHIN +1CAA; C; 10EA; # GEORGIAN MTAVRULI CAPITAL LETTER CAN +1CAB; C; 10EB; # GEORGIAN MTAVRULI CAPITAL LETTER JIL +1CAC; C; 10EC; # GEORGIAN MTAVRULI CAPITAL LETTER CIL +1CAD; C; 10ED; # GEORGIAN MTAVRULI CAPITAL LETTER CHAR +1CAE; C; 10EE; # GEORGIAN MTAVRULI CAPITAL LETTER XAN +1CAF; C; 10EF; # GEORGIAN MTAVRULI CAPITAL LETTER JHAN +1CB0; C; 10F0; # GEORGIAN MTAVRULI CAPITAL LETTER HAE +1CB1; C; 10F1; # GEORGIAN MTAVRULI CAPITAL LETTER HE +1CB2; C; 10F2; # GEORGIAN MTAVRULI CAPITAL LETTER HIE +1CB3; C; 10F3; # GEORGIAN MTAVRULI CAPITAL LETTER WE +1CB4; C; 10F4; # GEORGIAN MTAVRULI CAPITAL LETTER HAR +1CB5; C; 10F5; # GEORGIAN MTAVRULI CAPITAL LETTER HOE +1CB6; C; 10F6; # GEORGIAN MTAVRULI CAPITAL LETTER FI +1CB7; C; 10F7; # GEORGIAN MTAVRULI CAPITAL LETTER YN +1CB8; C; 10F8; # GEORGIAN MTAVRULI CAPITAL LETTER ELIFI +1CB9; C; 10F9; # GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN +1CBA; C; 10FA; # GEORGIAN MTAVRULI CAPITAL LETTER AIN +1CBD; C; 10FD; # GEORGIAN MTAVRULI CAPITAL LETTER AEN +1CBE; C; 10FE; # GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN +1CBF; C; 10FF; # GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN +1E00; C; 1E01; # LATIN CAPITAL LETTER A WITH RING BELOW +1E02; C; 1E03; # LATIN CAPITAL LETTER B WITH DOT ABOVE +1E04; C; 1E05; # LATIN CAPITAL LETTER B WITH DOT BELOW +1E06; C; 1E07; # LATIN CAPITAL LETTER B WITH LINE BELOW +1E08; C; 1E09; # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE +1E0A; C; 1E0B; # LATIN CAPITAL LETTER D WITH DOT ABOVE +1E0C; C; 1E0D; # LATIN CAPITAL LETTER D WITH DOT BELOW +1E0E; C; 1E0F; # LATIN CAPITAL LETTER D WITH LINE BELOW +1E10; C; 1E11; # LATIN CAPITAL LETTER D WITH CEDILLA +1E12; C; 1E13; # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW +1E14; C; 1E15; # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE +1E16; C; 1E17; # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE +1E18; C; 1E19; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW +1E1A; C; 1E1B; # LATIN CAPITAL LETTER E WITH TILDE BELOW +1E1C; C; 1E1D; # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE +1E1E; C; 1E1F; # LATIN CAPITAL LETTER F WITH DOT ABOVE +1E20; C; 1E21; # LATIN CAPITAL LETTER G WITH MACRON +1E22; C; 1E23; # LATIN CAPITAL LETTER H WITH DOT ABOVE +1E24; C; 1E25; # LATIN CAPITAL LETTER H WITH DOT BELOW +1E26; C; 1E27; # LATIN CAPITAL LETTER H WITH DIAERESIS +1E28; C; 1E29; # LATIN CAPITAL LETTER H WITH CEDILLA +1E2A; C; 1E2B; # LATIN CAPITAL LETTER H WITH BREVE BELOW +1E2C; C; 1E2D; # LATIN CAPITAL LETTER I WITH TILDE BELOW +1E2E; C; 1E2F; # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE +1E30; C; 1E31; # LATIN CAPITAL LETTER K WITH ACUTE +1E32; C; 1E33; # LATIN CAPITAL LETTER K WITH DOT BELOW +1E34; C; 1E35; # LATIN CAPITAL LETTER K WITH LINE BELOW +1E36; C; 1E37; # LATIN CAPITAL LETTER L WITH DOT BELOW +1E38; C; 1E39; # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON +1E3A; C; 1E3B; # LATIN CAPITAL LETTER L WITH LINE BELOW +1E3C; C; 1E3D; # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW +1E3E; C; 1E3F; # LATIN CAPITAL LETTER M WITH ACUTE +1E40; C; 1E41; # LATIN CAPITAL LETTER M WITH DOT ABOVE +1E42; C; 1E43; # LATIN CAPITAL LETTER M WITH DOT BELOW +1E44; C; 1E45; # LATIN CAPITAL LETTER N WITH DOT ABOVE +1E46; C; 1E47; # LATIN CAPITAL LETTER N WITH DOT BELOW +1E48; C; 1E49; # LATIN CAPITAL LETTER N WITH LINE BELOW +1E4A; C; 1E4B; # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW +1E4C; C; 1E4D; # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE +1E4E; C; 1E4F; # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS +1E50; C; 1E51; # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE +1E52; C; 1E53; # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE +1E54; C; 1E55; # LATIN CAPITAL LETTER P WITH ACUTE +1E56; C; 1E57; # LATIN CAPITAL LETTER P WITH DOT ABOVE +1E58; C; 1E59; # LATIN CAPITAL LETTER R WITH DOT ABOVE +1E5A; C; 1E5B; # LATIN CAPITAL LETTER R WITH DOT BELOW +1E5C; C; 1E5D; # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON +1E5E; C; 1E5F; # LATIN CAPITAL LETTER R WITH LINE BELOW +1E60; C; 1E61; # LATIN CAPITAL LETTER S WITH DOT ABOVE +1E62; C; 1E63; # LATIN CAPITAL LETTER S WITH DOT BELOW +1E64; C; 1E65; # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE +1E66; C; 1E67; # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE +1E68; C; 1E69; # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE +1E6A; C; 1E6B; # LATIN CAPITAL LETTER T WITH DOT ABOVE +1E6C; C; 1E6D; # LATIN CAPITAL LETTER T WITH DOT BELOW +1E6E; C; 1E6F; # LATIN CAPITAL LETTER T WITH LINE BELOW +1E70; C; 1E71; # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW +1E72; C; 1E73; # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW +1E74; C; 1E75; # LATIN CAPITAL LETTER U WITH TILDE BELOW +1E76; C; 1E77; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW +1E78; C; 1E79; # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE +1E7A; C; 1E7B; # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS +1E7C; C; 1E7D; # LATIN CAPITAL LETTER V WITH TILDE +1E7E; C; 1E7F; # LATIN CAPITAL LETTER V WITH DOT BELOW +1E80; C; 1E81; # LATIN CAPITAL LETTER W WITH GRAVE +1E82; C; 1E83; # LATIN CAPITAL LETTER W WITH ACUTE +1E84; C; 1E85; # LATIN CAPITAL LETTER W WITH DIAERESIS +1E86; C; 1E87; # LATIN CAPITAL LETTER W WITH DOT ABOVE +1E88; C; 1E89; # LATIN CAPITAL LETTER W WITH DOT BELOW +1E8A; C; 1E8B; # LATIN CAPITAL LETTER X WITH DOT ABOVE +1E8C; C; 1E8D; # LATIN CAPITAL LETTER X WITH DIAERESIS +1E8E; C; 1E8F; # LATIN CAPITAL LETTER Y WITH DOT ABOVE +1E90; C; 1E91; # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX +1E92; C; 1E93; # LATIN CAPITAL LETTER Z WITH DOT BELOW +1E94; C; 1E95; # LATIN CAPITAL LETTER Z WITH LINE BELOW +1E96; F; 0068 0331; # LATIN SMALL LETTER H WITH LINE BELOW +1E97; F; 0074 0308; # LATIN SMALL LETTER T WITH DIAERESIS +1E98; F; 0077 030A; # LATIN SMALL LETTER W WITH RING ABOVE +1E99; F; 0079 030A; # LATIN SMALL LETTER Y WITH RING ABOVE +1E9A; F; 0061 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING +1E9B; C; 1E61; # LATIN SMALL LETTER LONG S WITH DOT ABOVE +1E9E; F; 0073 0073; # LATIN CAPITAL LETTER SHARP S +1E9E; S; 00DF; # LATIN CAPITAL LETTER SHARP S +1EA0; C; 1EA1; # LATIN CAPITAL LETTER A WITH DOT BELOW +1EA2; C; 1EA3; # LATIN CAPITAL LETTER A WITH HOOK ABOVE +1EA4; C; 1EA5; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA6; C; 1EA7; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE +1EA8; C; 1EA9; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +1EAA; C; 1EAB; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE +1EAC; C; 1EAD; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1EAE; C; 1EAF; # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE +1EB0; C; 1EB1; # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE +1EB2; C; 1EB3; # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE +1EB4; C; 1EB5; # LATIN CAPITAL LETTER A WITH BREVE AND TILDE +1EB6; C; 1EB7; # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW +1EB8; C; 1EB9; # LATIN CAPITAL LETTER E WITH DOT BELOW +1EBA; C; 1EBB; # LATIN CAPITAL LETTER E WITH HOOK ABOVE +1EBC; C; 1EBD; # LATIN CAPITAL LETTER E WITH TILDE +1EBE; C; 1EBF; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +1EC0; C; 1EC1; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC2; C; 1EC3; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +1EC4; C; 1EC5; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE +1EC6; C; 1EC7; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1EC8; C; 1EC9; # LATIN CAPITAL LETTER I WITH HOOK ABOVE +1ECA; C; 1ECB; # LATIN CAPITAL LETTER I WITH DOT BELOW +1ECC; C; 1ECD; # LATIN CAPITAL LETTER O WITH DOT BELOW +1ECE; C; 1ECF; # LATIN CAPITAL LETTER O WITH HOOK ABOVE +1ED0; C; 1ED1; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED2; C; 1ED3; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED4; C; 1ED5; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +1ED6; C; 1ED7; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE +1ED8; C; 1ED9; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW +1EDA; C; 1EDB; # LATIN CAPITAL LETTER O WITH HORN AND ACUTE +1EDC; C; 1EDD; # LATIN CAPITAL LETTER O WITH HORN AND GRAVE +1EDE; C; 1EDF; # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE +1EE0; C; 1EE1; # LATIN CAPITAL LETTER O WITH HORN AND TILDE +1EE2; C; 1EE3; # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW +1EE4; C; 1EE5; # LATIN CAPITAL LETTER U WITH DOT BELOW +1EE6; C; 1EE7; # LATIN CAPITAL LETTER U WITH HOOK ABOVE +1EE8; C; 1EE9; # LATIN CAPITAL LETTER U WITH HORN AND ACUTE +1EEA; C; 1EEB; # LATIN CAPITAL LETTER U WITH HORN AND GRAVE +1EEC; C; 1EED; # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE +1EEE; C; 1EEF; # LATIN CAPITAL LETTER U WITH HORN AND TILDE +1EF0; C; 1EF1; # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW +1EF2; C; 1EF3; # LATIN CAPITAL LETTER Y WITH GRAVE +1EF4; C; 1EF5; # LATIN CAPITAL LETTER Y WITH DOT BELOW +1EF6; C; 1EF7; # LATIN CAPITAL LETTER Y WITH HOOK ABOVE +1EF8; C; 1EF9; # LATIN CAPITAL LETTER Y WITH TILDE +1EFA; C; 1EFB; # LATIN CAPITAL LETTER MIDDLE-WELSH LL +1EFC; C; 1EFD; # LATIN CAPITAL LETTER MIDDLE-WELSH V +1EFE; C; 1EFF; # LATIN CAPITAL LETTER Y WITH LOOP +1F08; C; 1F00; # GREEK CAPITAL LETTER ALPHA WITH PSILI +1F09; C; 1F01; # GREEK CAPITAL LETTER ALPHA WITH DASIA +1F0A; C; 1F02; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA +1F0B; C; 1F03; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA +1F0C; C; 1F04; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA +1F0D; C; 1F05; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA +1F0E; C; 1F06; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI +1F0F; C; 1F07; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F18; C; 1F10; # GREEK CAPITAL LETTER EPSILON WITH PSILI +1F19; C; 1F11; # GREEK CAPITAL LETTER EPSILON WITH DASIA +1F1A; C; 1F12; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA +1F1B; C; 1F13; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA +1F1C; C; 1F14; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA +1F1D; C; 1F15; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +1F28; C; 1F20; # GREEK CAPITAL LETTER ETA WITH PSILI +1F29; C; 1F21; # GREEK CAPITAL LETTER ETA WITH DASIA +1F2A; C; 1F22; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA +1F2B; C; 1F23; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA +1F2C; C; 1F24; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA +1F2D; C; 1F25; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA +1F2E; C; 1F26; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI +1F2F; C; 1F27; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI +1F38; C; 1F30; # GREEK CAPITAL LETTER IOTA WITH PSILI +1F39; C; 1F31; # GREEK CAPITAL LETTER IOTA WITH DASIA +1F3A; C; 1F32; # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA +1F3B; C; 1F33; # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA +1F3C; C; 1F34; # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA +1F3D; C; 1F35; # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA +1F3E; C; 1F36; # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI +1F3F; C; 1F37; # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI +1F48; C; 1F40; # GREEK CAPITAL LETTER OMICRON WITH PSILI +1F49; C; 1F41; # GREEK CAPITAL LETTER OMICRON WITH DASIA +1F4A; C; 1F42; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA +1F4B; C; 1F43; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA +1F4C; C; 1F44; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA +1F4D; C; 1F45; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +1F50; F; 03C5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI +1F52; F; 03C5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA +1F54; F; 03C5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA +1F56; F; 03C5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI +1F59; C; 1F51; # GREEK CAPITAL LETTER UPSILON WITH DASIA +1F5B; C; 1F53; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +1F5D; C; 1F55; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +1F5F; C; 1F57; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F68; C; 1F60; # GREEK CAPITAL LETTER OMEGA WITH PSILI +1F69; C; 1F61; # GREEK CAPITAL LETTER OMEGA WITH DASIA +1F6A; C; 1F62; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA +1F6B; C; 1F63; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA +1F6C; C; 1F64; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA +1F6D; C; 1F65; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA +1F6E; C; 1F66; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI +1F6F; C; 1F67; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI +1F80; F; 1F00 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI +1F81; F; 1F01 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI +1F82; F; 1F02 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F83; F; 1F03 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F84; F; 1F04 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F85; F; 1F05 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F86; F; 1F06 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F87; F; 1F07 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F88; F; 1F00 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +1F88; S; 1F80; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +1F89; F; 1F01 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +1F89; S; 1F81; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +1F8A; F; 1F02 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F8A; S; 1F82; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F8B; F; 1F03 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F8B; S; 1F83; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F8C; F; 1F04 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F8C; S; 1F84; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F8D; F; 1F05 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F8D; S; 1F85; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F8E; F; 1F06 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F8E; S; 1F86; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F8F; F; 1F07 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F8F; S; 1F87; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F90; F; 1F20 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI +1F91; F; 1F21 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI +1F92; F; 1F22 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F93; F; 1F23 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F94; F; 1F24 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F95; F; 1F25 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F96; F; 1F26 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F97; F; 1F27 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F98; F; 1F20 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +1F98; S; 1F90; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +1F99; F; 1F21 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +1F99; S; 1F91; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +1F9A; F; 1F22 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F9A; S; 1F92; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F9B; F; 1F23 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F9B; S; 1F93; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F9C; F; 1F24 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F9C; S; 1F94; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F9D; F; 1F25 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F9D; S; 1F95; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F9E; F; 1F26 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F9E; S; 1F96; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F9F; F; 1F27 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F9F; S; 1F97; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FA0; F; 1F60 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI +1FA1; F; 1F61 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI +1FA2; F; 1F62 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1FA3; F; 1F63 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1FA4; F; 1F64 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1FA5; F; 1F65 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1FA6; F; 1F66 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1FA7; F; 1F67 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1FA8; F; 1F60 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +1FA8; S; 1FA0; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +1FA9; F; 1F61 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +1FA9; S; 1FA1; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +1FAA; F; 1F62 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1FAA; S; 1FA2; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1FAB; F; 1F63 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1FAB; S; 1FA3; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1FAC; F; 1F64 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1FAC; S; 1FA4; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1FAD; F; 1F65 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1FAD; S; 1FA5; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1FAE; F; 1F66 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1FAE; S; 1FA6; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1FAF; F; 1F67 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FAF; S; 1FA7; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FB2; F; 1F70 03B9; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI +1FB3; F; 03B1 03B9; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI +1FB4; F; 03AC 03B9; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1FB6; F; 03B1 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI +1FB7; F; 03B1 0342 03B9; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI +1FB8; C; 1FB0; # GREEK CAPITAL LETTER ALPHA WITH VRACHY +1FB9; C; 1FB1; # GREEK CAPITAL LETTER ALPHA WITH MACRON +1FBA; C; 1F70; # GREEK CAPITAL LETTER ALPHA WITH VARIA +1FBB; C; 1F71; # GREEK CAPITAL LETTER ALPHA WITH OXIA +1FBC; F; 03B1 03B9; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBC; S; 1FB3; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBE; C; 03B9; # GREEK PROSGEGRAMMENI +1FC2; F; 1F74 03B9; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI +1FC3; F; 03B7 03B9; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI +1FC4; F; 03AE 03B9; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1FC6; F; 03B7 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI +1FC7; F; 03B7 0342 03B9; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI +1FC8; C; 1F72; # GREEK CAPITAL LETTER EPSILON WITH VARIA +1FC9; C; 1F73; # GREEK CAPITAL LETTER EPSILON WITH OXIA +1FCA; C; 1F74; # GREEK CAPITAL LETTER ETA WITH VARIA +1FCB; C; 1F75; # GREEK CAPITAL LETTER ETA WITH OXIA +1FCC; F; 03B7 03B9; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FCC; S; 1FC3; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FD2; F; 03B9 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA +1FD3; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD6; F; 03B9 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI +1FD7; F; 03B9 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI +1FD8; C; 1FD0; # GREEK CAPITAL LETTER IOTA WITH VRACHY +1FD9; C; 1FD1; # GREEK CAPITAL LETTER IOTA WITH MACRON +1FDA; C; 1F76; # GREEK CAPITAL LETTER IOTA WITH VARIA +1FDB; C; 1F77; # GREEK CAPITAL LETTER IOTA WITH OXIA +1FE2; F; 03C5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA +1FE3; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA +1FE4; F; 03C1 0313; # GREEK SMALL LETTER RHO WITH PSILI +1FE6; F; 03C5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI +1FE7; F; 03C5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI +1FE8; C; 1FE0; # GREEK CAPITAL LETTER UPSILON WITH VRACHY +1FE9; C; 1FE1; # GREEK CAPITAL LETTER UPSILON WITH MACRON +1FEA; C; 1F7A; # GREEK CAPITAL LETTER UPSILON WITH VARIA +1FEB; C; 1F7B; # GREEK CAPITAL LETTER UPSILON WITH OXIA +1FEC; C; 1FE5; # GREEK CAPITAL LETTER RHO WITH DASIA +1FF2; F; 1F7C 03B9; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI +1FF3; F; 03C9 03B9; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI +1FF4; F; 03CE 03B9; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1FF6; F; 03C9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI +1FF7; F; 03C9 0342 03B9; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI +1FF8; C; 1F78; # GREEK CAPITAL LETTER OMICRON WITH VARIA +1FF9; C; 1F79; # GREEK CAPITAL LETTER OMICRON WITH OXIA +1FFA; C; 1F7C; # GREEK CAPITAL LETTER OMEGA WITH VARIA +1FFB; C; 1F7D; # GREEK CAPITAL LETTER OMEGA WITH OXIA +1FFC; F; 03C9 03B9; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +1FFC; S; 1FF3; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +2126; C; 03C9; # OHM SIGN +212A; C; 006B; # KELVIN SIGN +212B; C; 00E5; # ANGSTROM SIGN +2132; C; 214E; # TURNED CAPITAL F +2160; C; 2170; # ROMAN NUMERAL ONE +2161; C; 2171; # ROMAN NUMERAL TWO +2162; C; 2172; # ROMAN NUMERAL THREE +2163; C; 2173; # ROMAN NUMERAL FOUR +2164; C; 2174; # ROMAN NUMERAL FIVE +2165; C; 2175; # ROMAN NUMERAL SIX +2166; C; 2176; # ROMAN NUMERAL SEVEN +2167; C; 2177; # ROMAN NUMERAL EIGHT +2168; C; 2178; # ROMAN NUMERAL NINE +2169; C; 2179; # ROMAN NUMERAL TEN +216A; C; 217A; # ROMAN NUMERAL ELEVEN +216B; C; 217B; # ROMAN NUMERAL TWELVE +216C; C; 217C; # ROMAN NUMERAL FIFTY +216D; C; 217D; # ROMAN NUMERAL ONE HUNDRED +216E; C; 217E; # ROMAN NUMERAL FIVE HUNDRED +216F; C; 217F; # ROMAN NUMERAL ONE THOUSAND +2183; C; 2184; # ROMAN NUMERAL REVERSED ONE HUNDRED +24B6; C; 24D0; # CIRCLED LATIN CAPITAL LETTER A +24B7; C; 24D1; # CIRCLED LATIN CAPITAL LETTER B +24B8; C; 24D2; # CIRCLED LATIN CAPITAL LETTER C +24B9; C; 24D3; # CIRCLED LATIN CAPITAL LETTER D +24BA; C; 24D4; # CIRCLED LATIN CAPITAL LETTER E +24BB; C; 24D5; # CIRCLED LATIN CAPITAL LETTER F +24BC; C; 24D6; # CIRCLED LATIN CAPITAL LETTER G +24BD; C; 24D7; # CIRCLED LATIN CAPITAL LETTER H +24BE; C; 24D8; # CIRCLED LATIN CAPITAL LETTER I +24BF; C; 24D9; # CIRCLED LATIN CAPITAL LETTER J +24C0; C; 24DA; # CIRCLED LATIN CAPITAL LETTER K +24C1; C; 24DB; # CIRCLED LATIN CAPITAL LETTER L +24C2; C; 24DC; # CIRCLED LATIN CAPITAL LETTER M +24C3; C; 24DD; # CIRCLED LATIN CAPITAL LETTER N +24C4; C; 24DE; # CIRCLED LATIN CAPITAL LETTER O +24C5; C; 24DF; # CIRCLED LATIN CAPITAL LETTER P +24C6; C; 24E0; # CIRCLED LATIN CAPITAL LETTER Q +24C7; C; 24E1; # CIRCLED LATIN CAPITAL LETTER R +24C8; C; 24E2; # CIRCLED LATIN CAPITAL LETTER S +24C9; C; 24E3; # CIRCLED LATIN CAPITAL LETTER T +24CA; C; 24E4; # CIRCLED LATIN CAPITAL LETTER U +24CB; C; 24E5; # CIRCLED LATIN CAPITAL LETTER V +24CC; C; 24E6; # CIRCLED LATIN CAPITAL LETTER W +24CD; C; 24E7; # CIRCLED LATIN CAPITAL LETTER X +24CE; C; 24E8; # CIRCLED LATIN CAPITAL LETTER Y +24CF; C; 24E9; # CIRCLED LATIN CAPITAL LETTER Z +2C00; C; 2C30; # GLAGOLITIC CAPITAL LETTER AZU +2C01; C; 2C31; # GLAGOLITIC CAPITAL LETTER BUKY +2C02; C; 2C32; # GLAGOLITIC CAPITAL LETTER VEDE +2C03; C; 2C33; # GLAGOLITIC CAPITAL LETTER GLAGOLI +2C04; C; 2C34; # GLAGOLITIC CAPITAL LETTER DOBRO +2C05; C; 2C35; # GLAGOLITIC CAPITAL LETTER YESTU +2C06; C; 2C36; # GLAGOLITIC CAPITAL LETTER ZHIVETE +2C07; C; 2C37; # GLAGOLITIC CAPITAL LETTER DZELO +2C08; C; 2C38; # GLAGOLITIC CAPITAL LETTER ZEMLJA +2C09; C; 2C39; # GLAGOLITIC CAPITAL LETTER IZHE +2C0A; C; 2C3A; # GLAGOLITIC CAPITAL LETTER INITIAL IZHE +2C0B; C; 2C3B; # GLAGOLITIC CAPITAL LETTER I +2C0C; C; 2C3C; # GLAGOLITIC CAPITAL LETTER DJERVI +2C0D; C; 2C3D; # GLAGOLITIC CAPITAL LETTER KAKO +2C0E; C; 2C3E; # GLAGOLITIC CAPITAL LETTER LJUDIJE +2C0F; C; 2C3F; # GLAGOLITIC CAPITAL LETTER MYSLITE +2C10; C; 2C40; # GLAGOLITIC CAPITAL LETTER NASHI +2C11; C; 2C41; # GLAGOLITIC CAPITAL LETTER ONU +2C12; C; 2C42; # GLAGOLITIC CAPITAL LETTER POKOJI +2C13; C; 2C43; # GLAGOLITIC CAPITAL LETTER RITSI +2C14; C; 2C44; # GLAGOLITIC CAPITAL LETTER SLOVO +2C15; C; 2C45; # GLAGOLITIC CAPITAL LETTER TVRIDO +2C16; C; 2C46; # GLAGOLITIC CAPITAL LETTER UKU +2C17; C; 2C47; # GLAGOLITIC CAPITAL LETTER FRITU +2C18; C; 2C48; # GLAGOLITIC CAPITAL LETTER HERU +2C19; C; 2C49; # GLAGOLITIC CAPITAL LETTER OTU +2C1A; C; 2C4A; # GLAGOLITIC CAPITAL LETTER PE +2C1B; C; 2C4B; # GLAGOLITIC CAPITAL LETTER SHTA +2C1C; C; 2C4C; # GLAGOLITIC CAPITAL LETTER TSI +2C1D; C; 2C4D; # GLAGOLITIC CAPITAL LETTER CHRIVI +2C1E; C; 2C4E; # GLAGOLITIC CAPITAL LETTER SHA +2C1F; C; 2C4F; # GLAGOLITIC CAPITAL LETTER YERU +2C20; C; 2C50; # GLAGOLITIC CAPITAL LETTER YERI +2C21; C; 2C51; # GLAGOLITIC CAPITAL LETTER YATI +2C22; C; 2C52; # GLAGOLITIC CAPITAL LETTER SPIDERY HA +2C23; C; 2C53; # GLAGOLITIC CAPITAL LETTER YU +2C24; C; 2C54; # GLAGOLITIC CAPITAL LETTER SMALL YUS +2C25; C; 2C55; # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL +2C26; C; 2C56; # GLAGOLITIC CAPITAL LETTER YO +2C27; C; 2C57; # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS +2C28; C; 2C58; # GLAGOLITIC CAPITAL LETTER BIG YUS +2C29; C; 2C59; # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS +2C2A; C; 2C5A; # GLAGOLITIC CAPITAL LETTER FITA +2C2B; C; 2C5B; # GLAGOLITIC CAPITAL LETTER IZHITSA +2C2C; C; 2C5C; # GLAGOLITIC CAPITAL LETTER SHTAPIC +2C2D; C; 2C5D; # GLAGOLITIC CAPITAL LETTER TROKUTASTI A +2C2E; C; 2C5E; # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C60; C; 2C61; # LATIN CAPITAL LETTER L WITH DOUBLE BAR +2C62; C; 026B; # LATIN CAPITAL LETTER L WITH MIDDLE TILDE +2C63; C; 1D7D; # LATIN CAPITAL LETTER P WITH STROKE +2C64; C; 027D; # LATIN CAPITAL LETTER R WITH TAIL +2C67; C; 2C68; # LATIN CAPITAL LETTER H WITH DESCENDER +2C69; C; 2C6A; # LATIN CAPITAL LETTER K WITH DESCENDER +2C6B; C; 2C6C; # LATIN CAPITAL LETTER Z WITH DESCENDER +2C6D; C; 0251; # LATIN CAPITAL LETTER ALPHA +2C6E; C; 0271; # LATIN CAPITAL LETTER M WITH HOOK +2C6F; C; 0250; # LATIN CAPITAL LETTER TURNED A +2C70; C; 0252; # LATIN CAPITAL LETTER TURNED ALPHA +2C72; C; 2C73; # LATIN CAPITAL LETTER W WITH HOOK +2C75; C; 2C76; # LATIN CAPITAL LETTER HALF H +2C7E; C; 023F; # LATIN CAPITAL LETTER S WITH SWASH TAIL +2C7F; C; 0240; # LATIN CAPITAL LETTER Z WITH SWASH TAIL +2C80; C; 2C81; # COPTIC CAPITAL LETTER ALFA +2C82; C; 2C83; # COPTIC CAPITAL LETTER VIDA +2C84; C; 2C85; # COPTIC CAPITAL LETTER GAMMA +2C86; C; 2C87; # COPTIC CAPITAL LETTER DALDA +2C88; C; 2C89; # COPTIC CAPITAL LETTER EIE +2C8A; C; 2C8B; # COPTIC CAPITAL LETTER SOU +2C8C; C; 2C8D; # COPTIC CAPITAL LETTER ZATA +2C8E; C; 2C8F; # COPTIC CAPITAL LETTER HATE +2C90; C; 2C91; # COPTIC CAPITAL LETTER THETHE +2C92; C; 2C93; # COPTIC CAPITAL LETTER IAUDA +2C94; C; 2C95; # COPTIC CAPITAL LETTER KAPA +2C96; C; 2C97; # COPTIC CAPITAL LETTER LAULA +2C98; C; 2C99; # COPTIC CAPITAL LETTER MI +2C9A; C; 2C9B; # COPTIC CAPITAL LETTER NI +2C9C; C; 2C9D; # COPTIC CAPITAL LETTER KSI +2C9E; C; 2C9F; # COPTIC CAPITAL LETTER O +2CA0; C; 2CA1; # COPTIC CAPITAL LETTER PI +2CA2; C; 2CA3; # COPTIC CAPITAL LETTER RO +2CA4; C; 2CA5; # COPTIC CAPITAL LETTER SIMA +2CA6; C; 2CA7; # COPTIC CAPITAL LETTER TAU +2CA8; C; 2CA9; # COPTIC CAPITAL LETTER UA +2CAA; C; 2CAB; # COPTIC CAPITAL LETTER FI +2CAC; C; 2CAD; # COPTIC CAPITAL LETTER KHI +2CAE; C; 2CAF; # COPTIC CAPITAL LETTER PSI +2CB0; C; 2CB1; # COPTIC CAPITAL LETTER OOU +2CB2; C; 2CB3; # COPTIC CAPITAL LETTER DIALECT-P ALEF +2CB4; C; 2CB5; # COPTIC CAPITAL LETTER OLD COPTIC AIN +2CB6; C; 2CB7; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE +2CB8; C; 2CB9; # COPTIC CAPITAL LETTER DIALECT-P KAPA +2CBA; C; 2CBB; # COPTIC CAPITAL LETTER DIALECT-P NI +2CBC; C; 2CBD; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI +2CBE; C; 2CBF; # COPTIC CAPITAL LETTER OLD COPTIC OOU +2CC0; C; 2CC1; # COPTIC CAPITAL LETTER SAMPI +2CC2; C; 2CC3; # COPTIC CAPITAL LETTER CROSSED SHEI +2CC4; C; 2CC5; # COPTIC CAPITAL LETTER OLD COPTIC SHEI +2CC6; C; 2CC7; # COPTIC CAPITAL LETTER OLD COPTIC ESH +2CC8; C; 2CC9; # COPTIC CAPITAL LETTER AKHMIMIC KHEI +2CCA; C; 2CCB; # COPTIC CAPITAL LETTER DIALECT-P HORI +2CCC; C; 2CCD; # COPTIC CAPITAL LETTER OLD COPTIC HORI +2CCE; C; 2CCF; # COPTIC CAPITAL LETTER OLD COPTIC HA +2CD0; C; 2CD1; # COPTIC CAPITAL LETTER L-SHAPED HA +2CD2; C; 2CD3; # COPTIC CAPITAL LETTER OLD COPTIC HEI +2CD4; C; 2CD5; # COPTIC CAPITAL LETTER OLD COPTIC HAT +2CD6; C; 2CD7; # COPTIC CAPITAL LETTER OLD COPTIC GANGIA +2CD8; C; 2CD9; # COPTIC CAPITAL LETTER OLD COPTIC DJA +2CDA; C; 2CDB; # COPTIC CAPITAL LETTER OLD COPTIC SHIMA +2CDC; C; 2CDD; # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA +2CDE; C; 2CDF; # COPTIC CAPITAL LETTER OLD NUBIAN NGI +2CE0; C; 2CE1; # COPTIC CAPITAL LETTER OLD NUBIAN NYI +2CE2; C; 2CE3; # COPTIC CAPITAL LETTER OLD NUBIAN WAU +2CEB; C; 2CEC; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI +2CED; C; 2CEE; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA +2CF2; C; 2CF3; # COPTIC CAPITAL LETTER BOHAIRIC KHEI +A640; C; A641; # CYRILLIC CAPITAL LETTER ZEMLYA +A642; C; A643; # CYRILLIC CAPITAL LETTER DZELO +A644; C; A645; # CYRILLIC CAPITAL LETTER REVERSED DZE +A646; C; A647; # CYRILLIC CAPITAL LETTER IOTA +A648; C; A649; # CYRILLIC CAPITAL LETTER DJERV +A64A; C; A64B; # CYRILLIC CAPITAL LETTER MONOGRAPH UK +A64C; C; A64D; # CYRILLIC CAPITAL LETTER BROAD OMEGA +A64E; C; A64F; # CYRILLIC CAPITAL LETTER NEUTRAL YER +A650; C; A651; # CYRILLIC CAPITAL LETTER YERU WITH BACK YER +A652; C; A653; # CYRILLIC CAPITAL LETTER IOTIFIED YAT +A654; C; A655; # CYRILLIC CAPITAL LETTER REVERSED YU +A656; C; A657; # CYRILLIC CAPITAL LETTER IOTIFIED A +A658; C; A659; # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS +A65A; C; A65B; # CYRILLIC CAPITAL LETTER BLENDED YUS +A65C; C; A65D; # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS +A65E; C; A65F; # CYRILLIC CAPITAL LETTER YN +A660; C; A661; # CYRILLIC CAPITAL LETTER REVERSED TSE +A662; C; A663; # CYRILLIC CAPITAL LETTER SOFT DE +A664; C; A665; # CYRILLIC CAPITAL LETTER SOFT EL +A666; C; A667; # CYRILLIC CAPITAL LETTER SOFT EM +A668; C; A669; # CYRILLIC CAPITAL LETTER MONOCULAR O +A66A; C; A66B; # CYRILLIC CAPITAL LETTER BINOCULAR O +A66C; C; A66D; # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O +A680; C; A681; # CYRILLIC CAPITAL LETTER DWE +A682; C; A683; # CYRILLIC CAPITAL LETTER DZWE +A684; C; A685; # CYRILLIC CAPITAL LETTER ZHWE +A686; C; A687; # CYRILLIC CAPITAL LETTER CCHE +A688; C; A689; # CYRILLIC CAPITAL LETTER DZZE +A68A; C; A68B; # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK +A68C; C; A68D; # CYRILLIC CAPITAL LETTER TWE +A68E; C; A68F; # CYRILLIC CAPITAL LETTER TSWE +A690; C; A691; # CYRILLIC CAPITAL LETTER TSSE +A692; C; A693; # CYRILLIC CAPITAL LETTER TCHE +A694; C; A695; # CYRILLIC CAPITAL LETTER HWE +A696; C; A697; # CYRILLIC CAPITAL LETTER SHWE +A698; C; A699; # CYRILLIC CAPITAL LETTER DOUBLE O +A69A; C; A69B; # CYRILLIC CAPITAL LETTER CROSSED O +A722; C; A723; # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF +A724; C; A725; # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN +A726; C; A727; # LATIN CAPITAL LETTER HENG +A728; C; A729; # LATIN CAPITAL LETTER TZ +A72A; C; A72B; # LATIN CAPITAL LETTER TRESILLO +A72C; C; A72D; # LATIN CAPITAL LETTER CUATRILLO +A72E; C; A72F; # LATIN CAPITAL LETTER CUATRILLO WITH COMMA +A732; C; A733; # LATIN CAPITAL LETTER AA +A734; C; A735; # LATIN CAPITAL LETTER AO +A736; C; A737; # LATIN CAPITAL LETTER AU +A738; C; A739; # LATIN CAPITAL LETTER AV +A73A; C; A73B; # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR +A73C; C; A73D; # LATIN CAPITAL LETTER AY +A73E; C; A73F; # LATIN CAPITAL LETTER REVERSED C WITH DOT +A740; C; A741; # LATIN CAPITAL LETTER K WITH STROKE +A742; C; A743; # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE +A744; C; A745; # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE +A746; C; A747; # LATIN CAPITAL LETTER BROKEN L +A748; C; A749; # LATIN CAPITAL LETTER L WITH HIGH STROKE +A74A; C; A74B; # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY +A74C; C; A74D; # LATIN CAPITAL LETTER O WITH LOOP +A74E; C; A74F; # LATIN CAPITAL LETTER OO +A750; C; A751; # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER +A752; C; A753; # LATIN CAPITAL LETTER P WITH FLOURISH +A754; C; A755; # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL +A756; C; A757; # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER +A758; C; A759; # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE +A75A; C; A75B; # LATIN CAPITAL LETTER R ROTUNDA +A75C; C; A75D; # LATIN CAPITAL LETTER RUM ROTUNDA +A75E; C; A75F; # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE +A760; C; A761; # LATIN CAPITAL LETTER VY +A762; C; A763; # LATIN CAPITAL LETTER VISIGOTHIC Z +A764; C; A765; # LATIN CAPITAL LETTER THORN WITH STROKE +A766; C; A767; # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER +A768; C; A769; # LATIN CAPITAL LETTER VEND +A76A; C; A76B; # LATIN CAPITAL LETTER ET +A76C; C; A76D; # LATIN CAPITAL LETTER IS +A76E; C; A76F; # LATIN CAPITAL LETTER CON +A779; C; A77A; # LATIN CAPITAL LETTER INSULAR D +A77B; C; A77C; # LATIN CAPITAL LETTER INSULAR F +A77D; C; 1D79; # LATIN CAPITAL LETTER INSULAR G +A77E; C; A77F; # LATIN CAPITAL LETTER TURNED INSULAR G +A780; C; A781; # LATIN CAPITAL LETTER TURNED L +A782; C; A783; # LATIN CAPITAL LETTER INSULAR R +A784; C; A785; # LATIN CAPITAL LETTER INSULAR S +A786; C; A787; # LATIN CAPITAL LETTER INSULAR T +A78B; C; A78C; # LATIN CAPITAL LETTER SALTILLO +A78D; C; 0265; # LATIN CAPITAL LETTER TURNED H +A790; C; A791; # LATIN CAPITAL LETTER N WITH DESCENDER +A792; C; A793; # LATIN CAPITAL LETTER C WITH BAR +A796; C; A797; # LATIN CAPITAL LETTER B WITH FLOURISH +A798; C; A799; # LATIN CAPITAL LETTER F WITH STROKE +A79A; C; A79B; # LATIN CAPITAL LETTER VOLAPUK AE +A79C; C; A79D; # LATIN CAPITAL LETTER VOLAPUK OE +A79E; C; A79F; # LATIN CAPITAL LETTER VOLAPUK UE +A7A0; C; A7A1; # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE +A7A2; C; A7A3; # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE +A7A4; C; A7A5; # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE +A7A6; C; A7A7; # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE +A7A8; C; A7A9; # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE +A7AA; C; 0266; # LATIN CAPITAL LETTER H WITH HOOK +A7AB; C; 025C; # LATIN CAPITAL LETTER REVERSED OPEN E +A7AC; C; 0261; # LATIN CAPITAL LETTER SCRIPT G +A7AD; C; 026C; # LATIN CAPITAL LETTER L WITH BELT +A7AE; C; 026A; # LATIN CAPITAL LETTER SMALL CAPITAL I +A7B0; C; 029E; # LATIN CAPITAL LETTER TURNED K +A7B1; C; 0287; # LATIN CAPITAL LETTER TURNED T +A7B2; C; 029D; # LATIN CAPITAL LETTER J WITH CROSSED-TAIL +A7B3; C; AB53; # LATIN CAPITAL LETTER CHI +A7B4; C; A7B5; # LATIN CAPITAL LETTER BETA +A7B6; C; A7B7; # LATIN CAPITAL LETTER OMEGA +A7B8; C; A7B9; # LATIN CAPITAL LETTER U WITH STROKE +AB70; C; 13A0; # CHEROKEE SMALL LETTER A +AB71; C; 13A1; # CHEROKEE SMALL LETTER E +AB72; C; 13A2; # CHEROKEE SMALL LETTER I +AB73; C; 13A3; # CHEROKEE SMALL LETTER O +AB74; C; 13A4; # CHEROKEE SMALL LETTER U +AB75; C; 13A5; # CHEROKEE SMALL LETTER V +AB76; C; 13A6; # CHEROKEE SMALL LETTER GA +AB77; C; 13A7; # CHEROKEE SMALL LETTER KA +AB78; C; 13A8; # CHEROKEE SMALL LETTER GE +AB79; C; 13A9; # CHEROKEE SMALL LETTER GI +AB7A; C; 13AA; # CHEROKEE SMALL LETTER GO +AB7B; C; 13AB; # CHEROKEE SMALL LETTER GU +AB7C; C; 13AC; # CHEROKEE SMALL LETTER GV +AB7D; C; 13AD; # CHEROKEE SMALL LETTER HA +AB7E; C; 13AE; # CHEROKEE SMALL LETTER HE +AB7F; C; 13AF; # CHEROKEE SMALL LETTER HI +AB80; C; 13B0; # CHEROKEE SMALL LETTER HO +AB81; C; 13B1; # CHEROKEE SMALL LETTER HU +AB82; C; 13B2; # CHEROKEE SMALL LETTER HV +AB83; C; 13B3; # CHEROKEE SMALL LETTER LA +AB84; C; 13B4; # CHEROKEE SMALL LETTER LE +AB85; C; 13B5; # CHEROKEE SMALL LETTER LI +AB86; C; 13B6; # CHEROKEE SMALL LETTER LO +AB87; C; 13B7; # CHEROKEE SMALL LETTER LU +AB88; C; 13B8; # CHEROKEE SMALL LETTER LV +AB89; C; 13B9; # CHEROKEE SMALL LETTER MA +AB8A; C; 13BA; # CHEROKEE SMALL LETTER ME +AB8B; C; 13BB; # CHEROKEE SMALL LETTER MI +AB8C; C; 13BC; # CHEROKEE SMALL LETTER MO +AB8D; C; 13BD; # CHEROKEE SMALL LETTER MU +AB8E; C; 13BE; # CHEROKEE SMALL LETTER NA +AB8F; C; 13BF; # CHEROKEE SMALL LETTER HNA +AB90; C; 13C0; # CHEROKEE SMALL LETTER NAH +AB91; C; 13C1; # CHEROKEE SMALL LETTER NE +AB92; C; 13C2; # CHEROKEE SMALL LETTER NI +AB93; C; 13C3; # CHEROKEE SMALL LETTER NO +AB94; C; 13C4; # CHEROKEE SMALL LETTER NU +AB95; C; 13C5; # CHEROKEE SMALL LETTER NV +AB96; C; 13C6; # CHEROKEE SMALL LETTER QUA +AB97; C; 13C7; # CHEROKEE SMALL LETTER QUE +AB98; C; 13C8; # CHEROKEE SMALL LETTER QUI +AB99; C; 13C9; # CHEROKEE SMALL LETTER QUO +AB9A; C; 13CA; # CHEROKEE SMALL LETTER QUU +AB9B; C; 13CB; # CHEROKEE SMALL LETTER QUV +AB9C; C; 13CC; # CHEROKEE SMALL LETTER SA +AB9D; C; 13CD; # CHEROKEE SMALL LETTER S +AB9E; C; 13CE; # CHEROKEE SMALL LETTER SE +AB9F; C; 13CF; # CHEROKEE SMALL LETTER SI +ABA0; C; 13D0; # CHEROKEE SMALL LETTER SO +ABA1; C; 13D1; # CHEROKEE SMALL LETTER SU +ABA2; C; 13D2; # CHEROKEE SMALL LETTER SV +ABA3; C; 13D3; # CHEROKEE SMALL LETTER DA +ABA4; C; 13D4; # CHEROKEE SMALL LETTER TA +ABA5; C; 13D5; # CHEROKEE SMALL LETTER DE +ABA6; C; 13D6; # CHEROKEE SMALL LETTER TE +ABA7; C; 13D7; # CHEROKEE SMALL LETTER DI +ABA8; C; 13D8; # CHEROKEE SMALL LETTER TI +ABA9; C; 13D9; # CHEROKEE SMALL LETTER DO +ABAA; C; 13DA; # CHEROKEE SMALL LETTER DU +ABAB; C; 13DB; # CHEROKEE SMALL LETTER DV +ABAC; C; 13DC; # CHEROKEE SMALL LETTER DLA +ABAD; C; 13DD; # CHEROKEE SMALL LETTER TLA +ABAE; C; 13DE; # CHEROKEE SMALL LETTER TLE +ABAF; C; 13DF; # CHEROKEE SMALL LETTER TLI +ABB0; C; 13E0; # CHEROKEE SMALL LETTER TLO +ABB1; C; 13E1; # CHEROKEE SMALL LETTER TLU +ABB2; C; 13E2; # CHEROKEE SMALL LETTER TLV +ABB3; C; 13E3; # CHEROKEE SMALL LETTER TSA +ABB4; C; 13E4; # CHEROKEE SMALL LETTER TSE +ABB5; C; 13E5; # CHEROKEE SMALL LETTER TSI +ABB6; C; 13E6; # CHEROKEE SMALL LETTER TSO +ABB7; C; 13E7; # CHEROKEE SMALL LETTER TSU +ABB8; C; 13E8; # CHEROKEE SMALL LETTER TSV +ABB9; C; 13E9; # CHEROKEE SMALL LETTER WA +ABBA; C; 13EA; # CHEROKEE SMALL LETTER WE +ABBB; C; 13EB; # CHEROKEE SMALL LETTER WI +ABBC; C; 13EC; # CHEROKEE SMALL LETTER WO +ABBD; C; 13ED; # CHEROKEE SMALL LETTER WU +ABBE; C; 13EE; # CHEROKEE SMALL LETTER WV +ABBF; C; 13EF; # CHEROKEE SMALL LETTER YA +FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF +FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI +FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL +FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI +FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL +FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T +FB06; F; 0073 0074; # LATIN SMALL LIGATURE ST +FB13; F; 0574 0576; # ARMENIAN SMALL LIGATURE MEN NOW +FB14; F; 0574 0565; # ARMENIAN SMALL LIGATURE MEN ECH +FB15; F; 0574 056B; # ARMENIAN SMALL LIGATURE MEN INI +FB16; F; 057E 0576; # ARMENIAN SMALL LIGATURE VEW NOW +FB17; F; 0574 056D; # ARMENIAN SMALL LIGATURE MEN XEH +FF21; C; FF41; # FULLWIDTH LATIN CAPITAL LETTER A +FF22; C; FF42; # FULLWIDTH LATIN CAPITAL LETTER B +FF23; C; FF43; # FULLWIDTH LATIN CAPITAL LETTER C +FF24; C; FF44; # FULLWIDTH LATIN CAPITAL LETTER D +FF25; C; FF45; # FULLWIDTH LATIN CAPITAL LETTER E +FF26; C; FF46; # FULLWIDTH LATIN CAPITAL LETTER F +FF27; C; FF47; # FULLWIDTH LATIN CAPITAL LETTER G +FF28; C; FF48; # FULLWIDTH LATIN CAPITAL LETTER H +FF29; C; FF49; # FULLWIDTH LATIN CAPITAL LETTER I +FF2A; C; FF4A; # FULLWIDTH LATIN CAPITAL LETTER J +FF2B; C; FF4B; # FULLWIDTH LATIN CAPITAL LETTER K +FF2C; C; FF4C; # FULLWIDTH LATIN CAPITAL LETTER L +FF2D; C; FF4D; # FULLWIDTH LATIN CAPITAL LETTER M +FF2E; C; FF4E; # FULLWIDTH LATIN CAPITAL LETTER N +FF2F; C; FF4F; # FULLWIDTH LATIN CAPITAL LETTER O +FF30; C; FF50; # FULLWIDTH LATIN CAPITAL LETTER P +FF31; C; FF51; # FULLWIDTH LATIN CAPITAL LETTER Q +FF32; C; FF52; # FULLWIDTH LATIN CAPITAL LETTER R +FF33; C; FF53; # FULLWIDTH LATIN CAPITAL LETTER S +FF34; C; FF54; # FULLWIDTH LATIN CAPITAL LETTER T +FF35; C; FF55; # FULLWIDTH LATIN CAPITAL LETTER U +FF36; C; FF56; # FULLWIDTH LATIN CAPITAL LETTER V +FF37; C; FF57; # FULLWIDTH LATIN CAPITAL LETTER W +FF38; C; FF58; # FULLWIDTH LATIN CAPITAL LETTER X +FF39; C; FF59; # FULLWIDTH LATIN CAPITAL LETTER Y +FF3A; C; FF5A; # FULLWIDTH LATIN CAPITAL LETTER Z +10400; C; 10428; # DESERET CAPITAL LETTER LONG I +10401; C; 10429; # DESERET CAPITAL LETTER LONG E +10402; C; 1042A; # DESERET CAPITAL LETTER LONG A +10403; C; 1042B; # DESERET CAPITAL LETTER LONG AH +10404; C; 1042C; # DESERET CAPITAL LETTER LONG O +10405; C; 1042D; # DESERET CAPITAL LETTER LONG OO +10406; C; 1042E; # DESERET CAPITAL LETTER SHORT I +10407; C; 1042F; # DESERET CAPITAL LETTER SHORT E +10408; C; 10430; # DESERET CAPITAL LETTER SHORT A +10409; C; 10431; # DESERET CAPITAL LETTER SHORT AH +1040A; C; 10432; # DESERET CAPITAL LETTER SHORT O +1040B; C; 10433; # DESERET CAPITAL LETTER SHORT OO +1040C; C; 10434; # DESERET CAPITAL LETTER AY +1040D; C; 10435; # DESERET CAPITAL LETTER OW +1040E; C; 10436; # DESERET CAPITAL LETTER WU +1040F; C; 10437; # DESERET CAPITAL LETTER YEE +10410; C; 10438; # DESERET CAPITAL LETTER H +10411; C; 10439; # DESERET CAPITAL LETTER PEE +10412; C; 1043A; # DESERET CAPITAL LETTER BEE +10413; C; 1043B; # DESERET CAPITAL LETTER TEE +10414; C; 1043C; # DESERET CAPITAL LETTER DEE +10415; C; 1043D; # DESERET CAPITAL LETTER CHEE +10416; C; 1043E; # DESERET CAPITAL LETTER JEE +10417; C; 1043F; # DESERET CAPITAL LETTER KAY +10418; C; 10440; # DESERET CAPITAL LETTER GAY +10419; C; 10441; # DESERET CAPITAL LETTER EF +1041A; C; 10442; # DESERET CAPITAL LETTER VEE +1041B; C; 10443; # DESERET CAPITAL LETTER ETH +1041C; C; 10444; # DESERET CAPITAL LETTER THEE +1041D; C; 10445; # DESERET CAPITAL LETTER ES +1041E; C; 10446; # DESERET CAPITAL LETTER ZEE +1041F; C; 10447; # DESERET CAPITAL LETTER ESH +10420; C; 10448; # DESERET CAPITAL LETTER ZHEE +10421; C; 10449; # DESERET CAPITAL LETTER ER +10422; C; 1044A; # DESERET CAPITAL LETTER EL +10423; C; 1044B; # DESERET CAPITAL LETTER EM +10424; C; 1044C; # DESERET CAPITAL LETTER EN +10425; C; 1044D; # DESERET CAPITAL LETTER ENG +10426; C; 1044E; # DESERET CAPITAL LETTER OI +10427; C; 1044F; # DESERET CAPITAL LETTER EW +104B0; C; 104D8; # OSAGE CAPITAL LETTER A +104B1; C; 104D9; # OSAGE CAPITAL LETTER AI +104B2; C; 104DA; # OSAGE CAPITAL LETTER AIN +104B3; C; 104DB; # OSAGE CAPITAL LETTER AH +104B4; C; 104DC; # OSAGE CAPITAL LETTER BRA +104B5; C; 104DD; # OSAGE CAPITAL LETTER CHA +104B6; C; 104DE; # OSAGE CAPITAL LETTER EHCHA +104B7; C; 104DF; # OSAGE CAPITAL LETTER E +104B8; C; 104E0; # OSAGE CAPITAL LETTER EIN +104B9; C; 104E1; # OSAGE CAPITAL LETTER HA +104BA; C; 104E2; # OSAGE CAPITAL LETTER HYA +104BB; C; 104E3; # OSAGE CAPITAL LETTER I +104BC; C; 104E4; # OSAGE CAPITAL LETTER KA +104BD; C; 104E5; # OSAGE CAPITAL LETTER EHKA +104BE; C; 104E6; # OSAGE CAPITAL LETTER KYA +104BF; C; 104E7; # OSAGE CAPITAL LETTER LA +104C0; C; 104E8; # OSAGE CAPITAL LETTER MA +104C1; C; 104E9; # OSAGE CAPITAL LETTER NA +104C2; C; 104EA; # OSAGE CAPITAL LETTER O +104C3; C; 104EB; # OSAGE CAPITAL LETTER OIN +104C4; C; 104EC; # OSAGE CAPITAL LETTER PA +104C5; C; 104ED; # OSAGE CAPITAL LETTER EHPA +104C6; C; 104EE; # OSAGE CAPITAL LETTER SA +104C7; C; 104EF; # OSAGE CAPITAL LETTER SHA +104C8; C; 104F0; # OSAGE CAPITAL LETTER TA +104C9; C; 104F1; # OSAGE CAPITAL LETTER EHTA +104CA; C; 104F2; # OSAGE CAPITAL LETTER TSA +104CB; C; 104F3; # OSAGE CAPITAL LETTER EHTSA +104CC; C; 104F4; # OSAGE CAPITAL LETTER TSHA +104CD; C; 104F5; # OSAGE CAPITAL LETTER DHA +104CE; C; 104F6; # OSAGE CAPITAL LETTER U +104CF; C; 104F7; # OSAGE CAPITAL LETTER WA +104D0; C; 104F8; # OSAGE CAPITAL LETTER KHA +104D1; C; 104F9; # OSAGE CAPITAL LETTER GHA +104D2; C; 104FA; # OSAGE CAPITAL LETTER ZA +104D3; C; 104FB; # OSAGE CAPITAL LETTER ZHA +10C80; C; 10CC0; # OLD HUNGARIAN CAPITAL LETTER A +10C81; C; 10CC1; # OLD HUNGARIAN CAPITAL LETTER AA +10C82; C; 10CC2; # OLD HUNGARIAN CAPITAL LETTER EB +10C83; C; 10CC3; # OLD HUNGARIAN CAPITAL LETTER AMB +10C84; C; 10CC4; # OLD HUNGARIAN CAPITAL LETTER EC +10C85; C; 10CC5; # OLD HUNGARIAN CAPITAL LETTER ENC +10C86; C; 10CC6; # OLD HUNGARIAN CAPITAL LETTER ECS +10C87; C; 10CC7; # OLD HUNGARIAN CAPITAL LETTER ED +10C88; C; 10CC8; # OLD HUNGARIAN CAPITAL LETTER AND +10C89; C; 10CC9; # OLD HUNGARIAN CAPITAL LETTER E +10C8A; C; 10CCA; # OLD HUNGARIAN CAPITAL LETTER CLOSE E +10C8B; C; 10CCB; # OLD HUNGARIAN CAPITAL LETTER EE +10C8C; C; 10CCC; # OLD HUNGARIAN CAPITAL LETTER EF +10C8D; C; 10CCD; # OLD HUNGARIAN CAPITAL LETTER EG +10C8E; C; 10CCE; # OLD HUNGARIAN CAPITAL LETTER EGY +10C8F; C; 10CCF; # OLD HUNGARIAN CAPITAL LETTER EH +10C90; C; 10CD0; # OLD HUNGARIAN CAPITAL LETTER I +10C91; C; 10CD1; # OLD HUNGARIAN CAPITAL LETTER II +10C92; C; 10CD2; # OLD HUNGARIAN CAPITAL LETTER EJ +10C93; C; 10CD3; # OLD HUNGARIAN CAPITAL LETTER EK +10C94; C; 10CD4; # OLD HUNGARIAN CAPITAL LETTER AK +10C95; C; 10CD5; # OLD HUNGARIAN CAPITAL LETTER UNK +10C96; C; 10CD6; # OLD HUNGARIAN CAPITAL LETTER EL +10C97; C; 10CD7; # OLD HUNGARIAN CAPITAL LETTER ELY +10C98; C; 10CD8; # OLD HUNGARIAN CAPITAL LETTER EM +10C99; C; 10CD9; # OLD HUNGARIAN CAPITAL LETTER EN +10C9A; C; 10CDA; # OLD HUNGARIAN CAPITAL LETTER ENY +10C9B; C; 10CDB; # OLD HUNGARIAN CAPITAL LETTER O +10C9C; C; 10CDC; # OLD HUNGARIAN CAPITAL LETTER OO +10C9D; C; 10CDD; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE +10C9E; C; 10CDE; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE +10C9F; C; 10CDF; # OLD HUNGARIAN CAPITAL LETTER OEE +10CA0; C; 10CE0; # OLD HUNGARIAN CAPITAL LETTER EP +10CA1; C; 10CE1; # OLD HUNGARIAN CAPITAL LETTER EMP +10CA2; C; 10CE2; # OLD HUNGARIAN CAPITAL LETTER ER +10CA3; C; 10CE3; # OLD HUNGARIAN CAPITAL LETTER SHORT ER +10CA4; C; 10CE4; # OLD HUNGARIAN CAPITAL LETTER ES +10CA5; C; 10CE5; # OLD HUNGARIAN CAPITAL LETTER ESZ +10CA6; C; 10CE6; # OLD HUNGARIAN CAPITAL LETTER ET +10CA7; C; 10CE7; # OLD HUNGARIAN CAPITAL LETTER ENT +10CA8; C; 10CE8; # OLD HUNGARIAN CAPITAL LETTER ETY +10CA9; C; 10CE9; # OLD HUNGARIAN CAPITAL LETTER ECH +10CAA; C; 10CEA; # OLD HUNGARIAN CAPITAL LETTER U +10CAB; C; 10CEB; # OLD HUNGARIAN CAPITAL LETTER UU +10CAC; C; 10CEC; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE +10CAD; C; 10CED; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE +10CAE; C; 10CEE; # OLD HUNGARIAN CAPITAL LETTER EV +10CAF; C; 10CEF; # OLD HUNGARIAN CAPITAL LETTER EZ +10CB0; C; 10CF0; # OLD HUNGARIAN CAPITAL LETTER EZS +10CB1; C; 10CF1; # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN +10CB2; C; 10CF2; # OLD HUNGARIAN CAPITAL LETTER US +118A0; C; 118C0; # WARANG CITI CAPITAL LETTER NGAA +118A1; C; 118C1; # WARANG CITI CAPITAL LETTER A +118A2; C; 118C2; # WARANG CITI CAPITAL LETTER WI +118A3; C; 118C3; # WARANG CITI CAPITAL LETTER YU +118A4; C; 118C4; # WARANG CITI CAPITAL LETTER YA +118A5; C; 118C5; # WARANG CITI CAPITAL LETTER YO +118A6; C; 118C6; # WARANG CITI CAPITAL LETTER II +118A7; C; 118C7; # WARANG CITI CAPITAL LETTER UU +118A8; C; 118C8; # WARANG CITI CAPITAL LETTER E +118A9; C; 118C9; # WARANG CITI CAPITAL LETTER O +118AA; C; 118CA; # WARANG CITI CAPITAL LETTER ANG +118AB; C; 118CB; # WARANG CITI CAPITAL LETTER GA +118AC; C; 118CC; # WARANG CITI CAPITAL LETTER KO +118AD; C; 118CD; # WARANG CITI CAPITAL LETTER ENY +118AE; C; 118CE; # WARANG CITI CAPITAL LETTER YUJ +118AF; C; 118CF; # WARANG CITI CAPITAL LETTER UC +118B0; C; 118D0; # WARANG CITI CAPITAL LETTER ENN +118B1; C; 118D1; # WARANG CITI CAPITAL LETTER ODD +118B2; C; 118D2; # WARANG CITI CAPITAL LETTER TTE +118B3; C; 118D3; # WARANG CITI CAPITAL LETTER NUNG +118B4; C; 118D4; # WARANG CITI CAPITAL LETTER DA +118B5; C; 118D5; # WARANG CITI CAPITAL LETTER AT +118B6; C; 118D6; # WARANG CITI CAPITAL LETTER AM +118B7; C; 118D7; # WARANG CITI CAPITAL LETTER BU +118B8; C; 118D8; # WARANG CITI CAPITAL LETTER PU +118B9; C; 118D9; # WARANG CITI CAPITAL LETTER HIYO +118BA; C; 118DA; # WARANG CITI CAPITAL LETTER HOLO +118BB; C; 118DB; # WARANG CITI CAPITAL LETTER HORR +118BC; C; 118DC; # WARANG CITI CAPITAL LETTER HAR +118BD; C; 118DD; # WARANG CITI CAPITAL LETTER SSUU +118BE; C; 118DE; # WARANG CITI CAPITAL LETTER SII +118BF; C; 118DF; # WARANG CITI CAPITAL LETTER VIYO +16E40; C; 16E60; # MEDEFAIDRIN CAPITAL LETTER M +16E41; C; 16E61; # MEDEFAIDRIN CAPITAL LETTER S +16E42; C; 16E62; # MEDEFAIDRIN CAPITAL LETTER V +16E43; C; 16E63; # MEDEFAIDRIN CAPITAL LETTER W +16E44; C; 16E64; # MEDEFAIDRIN CAPITAL LETTER ATIU +16E45; C; 16E65; # MEDEFAIDRIN CAPITAL LETTER Z +16E46; C; 16E66; # MEDEFAIDRIN CAPITAL LETTER KP +16E47; C; 16E67; # MEDEFAIDRIN CAPITAL LETTER P +16E48; C; 16E68; # MEDEFAIDRIN CAPITAL LETTER T +16E49; C; 16E69; # MEDEFAIDRIN CAPITAL LETTER G +16E4A; C; 16E6A; # MEDEFAIDRIN CAPITAL LETTER F +16E4B; C; 16E6B; # MEDEFAIDRIN CAPITAL LETTER I +16E4C; C; 16E6C; # MEDEFAIDRIN CAPITAL LETTER K +16E4D; C; 16E6D; # MEDEFAIDRIN CAPITAL LETTER A +16E4E; C; 16E6E; # MEDEFAIDRIN CAPITAL LETTER J +16E4F; C; 16E6F; # MEDEFAIDRIN CAPITAL LETTER E +16E50; C; 16E70; # MEDEFAIDRIN CAPITAL LETTER B +16E51; C; 16E71; # MEDEFAIDRIN CAPITAL LETTER C +16E52; C; 16E72; # MEDEFAIDRIN CAPITAL LETTER U +16E53; C; 16E73; # MEDEFAIDRIN CAPITAL LETTER YU +16E54; C; 16E74; # MEDEFAIDRIN CAPITAL LETTER L +16E55; C; 16E75; # MEDEFAIDRIN CAPITAL LETTER Q +16E56; C; 16E76; # MEDEFAIDRIN CAPITAL LETTER HP +16E57; C; 16E77; # MEDEFAIDRIN CAPITAL LETTER NY +16E58; C; 16E78; # MEDEFAIDRIN CAPITAL LETTER X +16E59; C; 16E79; # MEDEFAIDRIN CAPITAL LETTER D +16E5A; C; 16E7A; # MEDEFAIDRIN CAPITAL LETTER OE +16E5B; C; 16E7B; # MEDEFAIDRIN CAPITAL LETTER N +16E5C; C; 16E7C; # MEDEFAIDRIN CAPITAL LETTER R +16E5D; C; 16E7D; # MEDEFAIDRIN CAPITAL LETTER O +16E5E; C; 16E7E; # MEDEFAIDRIN CAPITAL LETTER AI +16E5F; C; 16E7F; # MEDEFAIDRIN CAPITAL LETTER Y +1E900; C; 1E922; # ADLAM CAPITAL LETTER ALIF +1E901; C; 1E923; # ADLAM CAPITAL LETTER DAALI +1E902; C; 1E924; # ADLAM CAPITAL LETTER LAAM +1E903; C; 1E925; # ADLAM CAPITAL LETTER MIIM +1E904; C; 1E926; # ADLAM CAPITAL LETTER BA +1E905; C; 1E927; # ADLAM CAPITAL LETTER SINNYIIYHE +1E906; C; 1E928; # ADLAM CAPITAL LETTER PE +1E907; C; 1E929; # ADLAM CAPITAL LETTER BHE +1E908; C; 1E92A; # ADLAM CAPITAL LETTER RA +1E909; C; 1E92B; # ADLAM CAPITAL LETTER E +1E90A; C; 1E92C; # ADLAM CAPITAL LETTER FA +1E90B; C; 1E92D; # ADLAM CAPITAL LETTER I +1E90C; C; 1E92E; # ADLAM CAPITAL LETTER O +1E90D; C; 1E92F; # ADLAM CAPITAL LETTER DHA +1E90E; C; 1E930; # ADLAM CAPITAL LETTER YHE +1E90F; C; 1E931; # ADLAM CAPITAL LETTER WAW +1E910; C; 1E932; # ADLAM CAPITAL LETTER NUN +1E911; C; 1E933; # ADLAM CAPITAL LETTER KAF +1E912; C; 1E934; # ADLAM CAPITAL LETTER YA +1E913; C; 1E935; # ADLAM CAPITAL LETTER U +1E914; C; 1E936; # ADLAM CAPITAL LETTER JIIM +1E915; C; 1E937; # ADLAM CAPITAL LETTER CHI +1E916; C; 1E938; # ADLAM CAPITAL LETTER HA +1E917; C; 1E939; # ADLAM CAPITAL LETTER QAAF +1E918; C; 1E93A; # ADLAM CAPITAL LETTER GA +1E919; C; 1E93B; # ADLAM CAPITAL LETTER NYA +1E91A; C; 1E93C; # ADLAM CAPITAL LETTER TU +1E91B; C; 1E93D; # ADLAM CAPITAL LETTER NHA +1E91C; C; 1E93E; # ADLAM CAPITAL LETTER VA +1E91D; C; 1E93F; # ADLAM CAPITAL LETTER KHA +1E91E; C; 1E940; # ADLAM CAPITAL LETTER GBE +1E91F; C; 1E941; # ADLAM CAPITAL LETTER ZAL +1E920; C; 1E942; # ADLAM CAPITAL LETTER KPO +1E921; C; 1E943; # ADLAM CAPITAL LETTER SHA +# +# EOF diff --git a/claimtrie/normalization/CaseFolding_v13.txt b/claimtrie/normalization/CaseFolding_v13.txt new file mode 100644 index 00000000..033788b2 --- /dev/null +++ b/claimtrie/normalization/CaseFolding_v13.txt @@ -0,0 +1,1584 @@ +# CaseFolding-13.0.0.txt +# Date: 2019-09-08, 23:30:59 GMT +# © 2019 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Case Folding Properties +# +# This file is a supplement to the UnicodeData file. +# It provides a case folding mapping generated from the Unicode Character Database. +# If all characters are mapped according to the full mapping below, then +# case differences (according to UnicodeData.txt and SpecialCasing.txt) +# are eliminated. +# +# The data supports both implementations that require simple case foldings +# (where string lengths don't change), and implementations that allow full case folding +# (where string lengths may grow). Note that where they can be supported, the +# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match. +# +# All code points not listed in this file map to themselves. +# +# NOTE: case folding does not preserve normalization formats! +# +# For information on case folding, including how to have case folding +# preserve normalization formats, see Section 3.13 Default Case Algorithms in +# The Unicode Standard. +# +# ================================================================================ +# Format +# ================================================================================ +# The entries in this file are in the following machine-readable format: +# +# ; ; ; # +# +# The status field is: +# C: common case folding, common mappings shared by both simple and full mappings. +# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces. +# S: simple case folding, mappings to single characters where different from F. +# T: special case for uppercase I and dotted uppercase I +# - For non-Turkic languages, this mapping is normally not used. +# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters. +# Note that the Turkic mappings do not maintain canonical equivalence without additional processing. +# See the discussions of case mapping in the Unicode Standard for more information. +# +# Usage: +# A. To do a simple case folding, use the mappings with status C + S. +# B. To do a full case folding, use the mappings with status C + F. +# +# The mappings with status T can be used or omitted depending on the desired case-folding +# behavior. (The default option is to exclude them.) +# +# ================================================================= + +# Property: Case_Folding + +# All code points not explicitly listed for Case_Folding +# have the value C for the status field, and the code point itself for the mapping field. + +# ================================================================= +0041; C; 0061; # LATIN CAPITAL LETTER A +0042; C; 0062; # LATIN CAPITAL LETTER B +0043; C; 0063; # LATIN CAPITAL LETTER C +0044; C; 0064; # LATIN CAPITAL LETTER D +0045; C; 0065; # LATIN CAPITAL LETTER E +0046; C; 0066; # LATIN CAPITAL LETTER F +0047; C; 0067; # LATIN CAPITAL LETTER G +0048; C; 0068; # LATIN CAPITAL LETTER H +0049; C; 0069; # LATIN CAPITAL LETTER I +0049; T; 0131; # LATIN CAPITAL LETTER I +004A; C; 006A; # LATIN CAPITAL LETTER J +004B; C; 006B; # LATIN CAPITAL LETTER K +004C; C; 006C; # LATIN CAPITAL LETTER L +004D; C; 006D; # LATIN CAPITAL LETTER M +004E; C; 006E; # LATIN CAPITAL LETTER N +004F; C; 006F; # LATIN CAPITAL LETTER O +0050; C; 0070; # LATIN CAPITAL LETTER P +0051; C; 0071; # LATIN CAPITAL LETTER Q +0052; C; 0072; # LATIN CAPITAL LETTER R +0053; C; 0073; # LATIN CAPITAL LETTER S +0054; C; 0074; # LATIN CAPITAL LETTER T +0055; C; 0075; # LATIN CAPITAL LETTER U +0056; C; 0076; # LATIN CAPITAL LETTER V +0057; C; 0077; # LATIN CAPITAL LETTER W +0058; C; 0078; # LATIN CAPITAL LETTER X +0059; C; 0079; # LATIN CAPITAL LETTER Y +005A; C; 007A; # LATIN CAPITAL LETTER Z +00B5; C; 03BC; # MICRO SIGN +00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE +00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE +00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE +00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS +00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE +00C6; C; 00E6; # LATIN CAPITAL LETTER AE +00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA +00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE +00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE +00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS +00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE +00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE +00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS +00D0; C; 00F0; # LATIN CAPITAL LETTER ETH +00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE +00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE +00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE +00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE +00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS +00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE +00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE +00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE +00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS +00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE +00DE; C; 00FE; # LATIN CAPITAL LETTER THORN +00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S +0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON +0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE +0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK +0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE +0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE +010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON +010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON +0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE +0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON +0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE +0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE +0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK +011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON +011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE +0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE +0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA +0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE +0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE +012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON +012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE +012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK +0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0132; C; 0133; # LATIN CAPITAL LIGATURE IJ +0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA +0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE +013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA +013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON +013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT +0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE +0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE +0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA +0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON +0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +014A; C; 014B; # LATIN CAPITAL LETTER ENG +014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON +014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE +0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0152; C; 0153; # LATIN CAPITAL LIGATURE OE +0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE +0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA +0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON +015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE +015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA +0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON +0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA +0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON +0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE +0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE +016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON +016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE +016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE +0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK +0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS +0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE +017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE +017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON +017F; C; 0073; # LATIN SMALL LETTER LONG S +0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK +0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR +0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX +0186; C; 0254; # LATIN CAPITAL LETTER OPEN O +0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK +0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D +018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK +018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR +018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E +018F; C; 0259; # LATIN CAPITAL LETTER SCHWA +0190; C; 025B; # LATIN CAPITAL LETTER OPEN E +0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK +0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK +0194; C; 0263; # LATIN CAPITAL LETTER GAMMA +0196; C; 0269; # LATIN CAPITAL LETTER IOTA +0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE +0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK +019C; C; 026F; # LATIN CAPITAL LETTER TURNED M +019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK +019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE +01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN +01A2; C; 01A3; # LATIN CAPITAL LETTER OI +01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK +01A6; C; 0280; # LATIN LETTER YR +01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO +01A9; C; 0283; # LATIN CAPITAL LETTER ESH +01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK +01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK +01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN +01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON +01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK +01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK +01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE +01B7; C; 0292; # LATIN CAPITAL LETTER EZH +01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED +01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE +01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON +01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON +01C7; C; 01C9; # LATIN CAPITAL LETTER LJ +01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J +01CA; C; 01CC; # LATIN CAPITAL LETTER NJ +01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J +01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON +01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON +01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON +01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON +01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON +01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON +01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON +01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE +01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON +01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON +01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK +01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON +01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON +01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON +01F1; C; 01F3; # LATIN CAPITAL LETTER DZ +01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z +01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE +01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR +01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN +01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE +01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE +01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE +0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE +0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE +0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE +0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE +020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE +020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE +020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE +0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE +0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE +0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE +0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE +0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW +021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW +021C; C; 021D; # LATIN CAPITAL LETTER YOGH +021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON +0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG +0222; C; 0223; # LATIN CAPITAL LETTER OU +0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK +0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE +0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA +022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON +022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON +022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE +0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON +0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON +023A; C; 2C65; # LATIN CAPITAL LETTER A WITH STROKE +023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE +023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR +023E; C; 2C66; # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE +0241; C; 0242; # LATIN CAPITAL LETTER GLOTTAL STOP +0243; C; 0180; # LATIN CAPITAL LETTER B WITH STROKE +0244; C; 0289; # LATIN CAPITAL LETTER U BAR +0245; C; 028C; # LATIN CAPITAL LETTER TURNED V +0246; C; 0247; # LATIN CAPITAL LETTER E WITH STROKE +0248; C; 0249; # LATIN CAPITAL LETTER J WITH STROKE +024A; C; 024B; # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL +024C; C; 024D; # LATIN CAPITAL LETTER R WITH STROKE +024E; C; 024F; # LATIN CAPITAL LETTER Y WITH STROKE +0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI +0370; C; 0371; # GREEK CAPITAL LETTER HETA +0372; C; 0373; # GREEK CAPITAL LETTER ARCHAIC SAMPI +0376; C; 0377; # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA +037F; C; 03F3; # GREEK CAPITAL LETTER YOT +0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS +0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS +0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS +038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS +038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS +038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS +038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS +0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA +0392; C; 03B2; # GREEK CAPITAL LETTER BETA +0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA +0394; C; 03B4; # GREEK CAPITAL LETTER DELTA +0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON +0396; C; 03B6; # GREEK CAPITAL LETTER ZETA +0397; C; 03B7; # GREEK CAPITAL LETTER ETA +0398; C; 03B8; # GREEK CAPITAL LETTER THETA +0399; C; 03B9; # GREEK CAPITAL LETTER IOTA +039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA +039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA +039C; C; 03BC; # GREEK CAPITAL LETTER MU +039D; C; 03BD; # GREEK CAPITAL LETTER NU +039E; C; 03BE; # GREEK CAPITAL LETTER XI +039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON +03A0; C; 03C0; # GREEK CAPITAL LETTER PI +03A1; C; 03C1; # GREEK CAPITAL LETTER RHO +03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA +03A4; C; 03C4; # GREEK CAPITAL LETTER TAU +03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON +03A6; C; 03C6; # GREEK CAPITAL LETTER PHI +03A7; C; 03C7; # GREEK CAPITAL LETTER CHI +03A8; C; 03C8; # GREEK CAPITAL LETTER PSI +03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA +03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA +03CF; C; 03D7; # GREEK CAPITAL KAI SYMBOL +03D0; C; 03B2; # GREEK BETA SYMBOL +03D1; C; 03B8; # GREEK THETA SYMBOL +03D5; C; 03C6; # GREEK PHI SYMBOL +03D6; C; 03C0; # GREEK PI SYMBOL +03D8; C; 03D9; # GREEK LETTER ARCHAIC KOPPA +03DA; C; 03DB; # GREEK LETTER STIGMA +03DC; C; 03DD; # GREEK LETTER DIGAMMA +03DE; C; 03DF; # GREEK LETTER KOPPA +03E0; C; 03E1; # GREEK LETTER SAMPI +03E2; C; 03E3; # COPTIC CAPITAL LETTER SHEI +03E4; C; 03E5; # COPTIC CAPITAL LETTER FEI +03E6; C; 03E7; # COPTIC CAPITAL LETTER KHEI +03E8; C; 03E9; # COPTIC CAPITAL LETTER HORI +03EA; C; 03EB; # COPTIC CAPITAL LETTER GANGIA +03EC; C; 03ED; # COPTIC CAPITAL LETTER SHIMA +03EE; C; 03EF; # COPTIC CAPITAL LETTER DEI +03F0; C; 03BA; # GREEK KAPPA SYMBOL +03F1; C; 03C1; # GREEK RHO SYMBOL +03F4; C; 03B8; # GREEK CAPITAL THETA SYMBOL +03F5; C; 03B5; # GREEK LUNATE EPSILON SYMBOL +03F7; C; 03F8; # GREEK CAPITAL LETTER SHO +03F9; C; 03F2; # GREEK CAPITAL LUNATE SIGMA SYMBOL +03FA; C; 03FB; # GREEK CAPITAL LETTER SAN +03FD; C; 037B; # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL +03FE; C; 037C; # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL +03FF; C; 037D; # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL +0400; C; 0450; # CYRILLIC CAPITAL LETTER IE WITH GRAVE +0401; C; 0451; # CYRILLIC CAPITAL LETTER IO +0402; C; 0452; # CYRILLIC CAPITAL LETTER DJE +0403; C; 0453; # CYRILLIC CAPITAL LETTER GJE +0404; C; 0454; # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0405; C; 0455; # CYRILLIC CAPITAL LETTER DZE +0406; C; 0456; # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0407; C; 0457; # CYRILLIC CAPITAL LETTER YI +0408; C; 0458; # CYRILLIC CAPITAL LETTER JE +0409; C; 0459; # CYRILLIC CAPITAL LETTER LJE +040A; C; 045A; # CYRILLIC CAPITAL LETTER NJE +040B; C; 045B; # CYRILLIC CAPITAL LETTER TSHE +040C; C; 045C; # CYRILLIC CAPITAL LETTER KJE +040D; C; 045D; # CYRILLIC CAPITAL LETTER I WITH GRAVE +040E; C; 045E; # CYRILLIC CAPITAL LETTER SHORT U +040F; C; 045F; # CYRILLIC CAPITAL LETTER DZHE +0410; C; 0430; # CYRILLIC CAPITAL LETTER A +0411; C; 0431; # CYRILLIC CAPITAL LETTER BE +0412; C; 0432; # CYRILLIC CAPITAL LETTER VE +0413; C; 0433; # CYRILLIC CAPITAL LETTER GHE +0414; C; 0434; # CYRILLIC CAPITAL LETTER DE +0415; C; 0435; # CYRILLIC CAPITAL LETTER IE +0416; C; 0436; # CYRILLIC CAPITAL LETTER ZHE +0417; C; 0437; # CYRILLIC CAPITAL LETTER ZE +0418; C; 0438; # CYRILLIC CAPITAL LETTER I +0419; C; 0439; # CYRILLIC CAPITAL LETTER SHORT I +041A; C; 043A; # CYRILLIC CAPITAL LETTER KA +041B; C; 043B; # CYRILLIC CAPITAL LETTER EL +041C; C; 043C; # CYRILLIC CAPITAL LETTER EM +041D; C; 043D; # CYRILLIC CAPITAL LETTER EN +041E; C; 043E; # CYRILLIC CAPITAL LETTER O +041F; C; 043F; # CYRILLIC CAPITAL LETTER PE +0420; C; 0440; # CYRILLIC CAPITAL LETTER ER +0421; C; 0441; # CYRILLIC CAPITAL LETTER ES +0422; C; 0442; # CYRILLIC CAPITAL LETTER TE +0423; C; 0443; # CYRILLIC CAPITAL LETTER U +0424; C; 0444; # CYRILLIC CAPITAL LETTER EF +0425; C; 0445; # CYRILLIC CAPITAL LETTER HA +0426; C; 0446; # CYRILLIC CAPITAL LETTER TSE +0427; C; 0447; # CYRILLIC CAPITAL LETTER CHE +0428; C; 0448; # CYRILLIC CAPITAL LETTER SHA +0429; C; 0449; # CYRILLIC CAPITAL LETTER SHCHA +042A; C; 044A; # CYRILLIC CAPITAL LETTER HARD SIGN +042B; C; 044B; # CYRILLIC CAPITAL LETTER YERU +042C; C; 044C; # CYRILLIC CAPITAL LETTER SOFT SIGN +042D; C; 044D; # CYRILLIC CAPITAL LETTER E +042E; C; 044E; # CYRILLIC CAPITAL LETTER YU +042F; C; 044F; # CYRILLIC CAPITAL LETTER YA +0460; C; 0461; # CYRILLIC CAPITAL LETTER OMEGA +0462; C; 0463; # CYRILLIC CAPITAL LETTER YAT +0464; C; 0465; # CYRILLIC CAPITAL LETTER IOTIFIED E +0466; C; 0467; # CYRILLIC CAPITAL LETTER LITTLE YUS +0468; C; 0469; # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS +046A; C; 046B; # CYRILLIC CAPITAL LETTER BIG YUS +046C; C; 046D; # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS +046E; C; 046F; # CYRILLIC CAPITAL LETTER KSI +0470; C; 0471; # CYRILLIC CAPITAL LETTER PSI +0472; C; 0473; # CYRILLIC CAPITAL LETTER FITA +0474; C; 0475; # CYRILLIC CAPITAL LETTER IZHITSA +0476; C; 0477; # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0478; C; 0479; # CYRILLIC CAPITAL LETTER UK +047A; C; 047B; # CYRILLIC CAPITAL LETTER ROUND OMEGA +047C; C; 047D; # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO +047E; C; 047F; # CYRILLIC CAPITAL LETTER OT +0480; C; 0481; # CYRILLIC CAPITAL LETTER KOPPA +048A; C; 048B; # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL +048C; C; 048D; # CYRILLIC CAPITAL LETTER SEMISOFT SIGN +048E; C; 048F; # CYRILLIC CAPITAL LETTER ER WITH TICK +0490; C; 0491; # CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0492; C; 0493; # CYRILLIC CAPITAL LETTER GHE WITH STROKE +0494; C; 0495; # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK +0496; C; 0497; # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER +0498; C; 0499; # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER +049A; C; 049B; # CYRILLIC CAPITAL LETTER KA WITH DESCENDER +049C; C; 049D; # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE +049E; C; 049F; # CYRILLIC CAPITAL LETTER KA WITH STROKE +04A0; C; 04A1; # CYRILLIC CAPITAL LETTER BASHKIR KA +04A2; C; 04A3; # CYRILLIC CAPITAL LETTER EN WITH DESCENDER +04A4; C; 04A5; # CYRILLIC CAPITAL LIGATURE EN GHE +04A6; C; 04A7; # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK +04A8; C; 04A9; # CYRILLIC CAPITAL LETTER ABKHASIAN HA +04AA; C; 04AB; # CYRILLIC CAPITAL LETTER ES WITH DESCENDER +04AC; C; 04AD; # CYRILLIC CAPITAL LETTER TE WITH DESCENDER +04AE; C; 04AF; # CYRILLIC CAPITAL LETTER STRAIGHT U +04B0; C; 04B1; # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE +04B2; C; 04B3; # CYRILLIC CAPITAL LETTER HA WITH DESCENDER +04B4; C; 04B5; # CYRILLIC CAPITAL LIGATURE TE TSE +04B6; C; 04B7; # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER +04B8; C; 04B9; # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE +04BA; C; 04BB; # CYRILLIC CAPITAL LETTER SHHA +04BC; C; 04BD; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE +04BE; C; 04BF; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER +04C0; C; 04CF; # CYRILLIC LETTER PALOCHKA +04C1; C; 04C2; # CYRILLIC CAPITAL LETTER ZHE WITH BREVE +04C3; C; 04C4; # CYRILLIC CAPITAL LETTER KA WITH HOOK +04C5; C; 04C6; # CYRILLIC CAPITAL LETTER EL WITH TAIL +04C7; C; 04C8; # CYRILLIC CAPITAL LETTER EN WITH HOOK +04C9; C; 04CA; # CYRILLIC CAPITAL LETTER EN WITH TAIL +04CB; C; 04CC; # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE +04CD; C; 04CE; # CYRILLIC CAPITAL LETTER EM WITH TAIL +04D0; C; 04D1; # CYRILLIC CAPITAL LETTER A WITH BREVE +04D2; C; 04D3; # CYRILLIC CAPITAL LETTER A WITH DIAERESIS +04D4; C; 04D5; # CYRILLIC CAPITAL LIGATURE A IE +04D6; C; 04D7; # CYRILLIC CAPITAL LETTER IE WITH BREVE +04D8; C; 04D9; # CYRILLIC CAPITAL LETTER SCHWA +04DA; C; 04DB; # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS +04DC; C; 04DD; # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS +04DE; C; 04DF; # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS +04E0; C; 04E1; # CYRILLIC CAPITAL LETTER ABKHASIAN DZE +04E2; C; 04E3; # CYRILLIC CAPITAL LETTER I WITH MACRON +04E4; C; 04E5; # CYRILLIC CAPITAL LETTER I WITH DIAERESIS +04E6; C; 04E7; # CYRILLIC CAPITAL LETTER O WITH DIAERESIS +04E8; C; 04E9; # CYRILLIC CAPITAL LETTER BARRED O +04EA; C; 04EB; # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS +04EC; C; 04ED; # CYRILLIC CAPITAL LETTER E WITH DIAERESIS +04EE; C; 04EF; # CYRILLIC CAPITAL LETTER U WITH MACRON +04F0; C; 04F1; # CYRILLIC CAPITAL LETTER U WITH DIAERESIS +04F2; C; 04F3; # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE +04F4; C; 04F5; # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS +04F6; C; 04F7; # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER +04F8; C; 04F9; # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS +04FA; C; 04FB; # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK +04FC; C; 04FD; # CYRILLIC CAPITAL LETTER HA WITH HOOK +04FE; C; 04FF; # CYRILLIC CAPITAL LETTER HA WITH STROKE +0500; C; 0501; # CYRILLIC CAPITAL LETTER KOMI DE +0502; C; 0503; # CYRILLIC CAPITAL LETTER KOMI DJE +0504; C; 0505; # CYRILLIC CAPITAL LETTER KOMI ZJE +0506; C; 0507; # CYRILLIC CAPITAL LETTER KOMI DZJE +0508; C; 0509; # CYRILLIC CAPITAL LETTER KOMI LJE +050A; C; 050B; # CYRILLIC CAPITAL LETTER KOMI NJE +050C; C; 050D; # CYRILLIC CAPITAL LETTER KOMI SJE +050E; C; 050F; # CYRILLIC CAPITAL LETTER KOMI TJE +0510; C; 0511; # CYRILLIC CAPITAL LETTER REVERSED ZE +0512; C; 0513; # CYRILLIC CAPITAL LETTER EL WITH HOOK +0514; C; 0515; # CYRILLIC CAPITAL LETTER LHA +0516; C; 0517; # CYRILLIC CAPITAL LETTER RHA +0518; C; 0519; # CYRILLIC CAPITAL LETTER YAE +051A; C; 051B; # CYRILLIC CAPITAL LETTER QA +051C; C; 051D; # CYRILLIC CAPITAL LETTER WE +051E; C; 051F; # CYRILLIC CAPITAL LETTER ALEUT KA +0520; C; 0521; # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK +0522; C; 0523; # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK +0524; C; 0525; # CYRILLIC CAPITAL LETTER PE WITH DESCENDER +0526; C; 0527; # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER +0528; C; 0529; # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK +052A; C; 052B; # CYRILLIC CAPITAL LETTER DZZHE +052C; C; 052D; # CYRILLIC CAPITAL LETTER DCHE +052E; C; 052F; # CYRILLIC CAPITAL LETTER EL WITH DESCENDER +0531; C; 0561; # ARMENIAN CAPITAL LETTER AYB +0532; C; 0562; # ARMENIAN CAPITAL LETTER BEN +0533; C; 0563; # ARMENIAN CAPITAL LETTER GIM +0534; C; 0564; # ARMENIAN CAPITAL LETTER DA +0535; C; 0565; # ARMENIAN CAPITAL LETTER ECH +0536; C; 0566; # ARMENIAN CAPITAL LETTER ZA +0537; C; 0567; # ARMENIAN CAPITAL LETTER EH +0538; C; 0568; # ARMENIAN CAPITAL LETTER ET +0539; C; 0569; # ARMENIAN CAPITAL LETTER TO +053A; C; 056A; # ARMENIAN CAPITAL LETTER ZHE +053B; C; 056B; # ARMENIAN CAPITAL LETTER INI +053C; C; 056C; # ARMENIAN CAPITAL LETTER LIWN +053D; C; 056D; # ARMENIAN CAPITAL LETTER XEH +053E; C; 056E; # ARMENIAN CAPITAL LETTER CA +053F; C; 056F; # ARMENIAN CAPITAL LETTER KEN +0540; C; 0570; # ARMENIAN CAPITAL LETTER HO +0541; C; 0571; # ARMENIAN CAPITAL LETTER JA +0542; C; 0572; # ARMENIAN CAPITAL LETTER GHAD +0543; C; 0573; # ARMENIAN CAPITAL LETTER CHEH +0544; C; 0574; # ARMENIAN CAPITAL LETTER MEN +0545; C; 0575; # ARMENIAN CAPITAL LETTER YI +0546; C; 0576; # ARMENIAN CAPITAL LETTER NOW +0547; C; 0577; # ARMENIAN CAPITAL LETTER SHA +0548; C; 0578; # ARMENIAN CAPITAL LETTER VO +0549; C; 0579; # ARMENIAN CAPITAL LETTER CHA +054A; C; 057A; # ARMENIAN CAPITAL LETTER PEH +054B; C; 057B; # ARMENIAN CAPITAL LETTER JHEH +054C; C; 057C; # ARMENIAN CAPITAL LETTER RA +054D; C; 057D; # ARMENIAN CAPITAL LETTER SEH +054E; C; 057E; # ARMENIAN CAPITAL LETTER VEW +054F; C; 057F; # ARMENIAN CAPITAL LETTER TIWN +0550; C; 0580; # ARMENIAN CAPITAL LETTER REH +0551; C; 0581; # ARMENIAN CAPITAL LETTER CO +0552; C; 0582; # ARMENIAN CAPITAL LETTER YIWN +0553; C; 0583; # ARMENIAN CAPITAL LETTER PIWR +0554; C; 0584; # ARMENIAN CAPITAL LETTER KEH +0555; C; 0585; # ARMENIAN CAPITAL LETTER OH +0556; C; 0586; # ARMENIAN CAPITAL LETTER FEH +0587; F; 0565 0582; # ARMENIAN SMALL LIGATURE ECH YIWN +10A0; C; 2D00; # GEORGIAN CAPITAL LETTER AN +10A1; C; 2D01; # GEORGIAN CAPITAL LETTER BAN +10A2; C; 2D02; # GEORGIAN CAPITAL LETTER GAN +10A3; C; 2D03; # GEORGIAN CAPITAL LETTER DON +10A4; C; 2D04; # GEORGIAN CAPITAL LETTER EN +10A5; C; 2D05; # GEORGIAN CAPITAL LETTER VIN +10A6; C; 2D06; # GEORGIAN CAPITAL LETTER ZEN +10A7; C; 2D07; # GEORGIAN CAPITAL LETTER TAN +10A8; C; 2D08; # GEORGIAN CAPITAL LETTER IN +10A9; C; 2D09; # GEORGIAN CAPITAL LETTER KAN +10AA; C; 2D0A; # GEORGIAN CAPITAL LETTER LAS +10AB; C; 2D0B; # GEORGIAN CAPITAL LETTER MAN +10AC; C; 2D0C; # GEORGIAN CAPITAL LETTER NAR +10AD; C; 2D0D; # GEORGIAN CAPITAL LETTER ON +10AE; C; 2D0E; # GEORGIAN CAPITAL LETTER PAR +10AF; C; 2D0F; # GEORGIAN CAPITAL LETTER ZHAR +10B0; C; 2D10; # GEORGIAN CAPITAL LETTER RAE +10B1; C; 2D11; # GEORGIAN CAPITAL LETTER SAN +10B2; C; 2D12; # GEORGIAN CAPITAL LETTER TAR +10B3; C; 2D13; # GEORGIAN CAPITAL LETTER UN +10B4; C; 2D14; # GEORGIAN CAPITAL LETTER PHAR +10B5; C; 2D15; # GEORGIAN CAPITAL LETTER KHAR +10B6; C; 2D16; # GEORGIAN CAPITAL LETTER GHAN +10B7; C; 2D17; # GEORGIAN CAPITAL LETTER QAR +10B8; C; 2D18; # GEORGIAN CAPITAL LETTER SHIN +10B9; C; 2D19; # GEORGIAN CAPITAL LETTER CHIN +10BA; C; 2D1A; # GEORGIAN CAPITAL LETTER CAN +10BB; C; 2D1B; # GEORGIAN CAPITAL LETTER JIL +10BC; C; 2D1C; # GEORGIAN CAPITAL LETTER CIL +10BD; C; 2D1D; # GEORGIAN CAPITAL LETTER CHAR +10BE; C; 2D1E; # GEORGIAN CAPITAL LETTER XAN +10BF; C; 2D1F; # GEORGIAN CAPITAL LETTER JHAN +10C0; C; 2D20; # GEORGIAN CAPITAL LETTER HAE +10C1; C; 2D21; # GEORGIAN CAPITAL LETTER HE +10C2; C; 2D22; # GEORGIAN CAPITAL LETTER HIE +10C3; C; 2D23; # GEORGIAN CAPITAL LETTER WE +10C4; C; 2D24; # GEORGIAN CAPITAL LETTER HAR +10C5; C; 2D25; # GEORGIAN CAPITAL LETTER HOE +10C7; C; 2D27; # GEORGIAN CAPITAL LETTER YN +10CD; C; 2D2D; # GEORGIAN CAPITAL LETTER AEN +13F8; C; 13F0; # CHEROKEE SMALL LETTER YE +13F9; C; 13F1; # CHEROKEE SMALL LETTER YI +13FA; C; 13F2; # CHEROKEE SMALL LETTER YO +13FB; C; 13F3; # CHEROKEE SMALL LETTER YU +13FC; C; 13F4; # CHEROKEE SMALL LETTER YV +13FD; C; 13F5; # CHEROKEE SMALL LETTER MV +1C80; C; 0432; # CYRILLIC SMALL LETTER ROUNDED VE +1C81; C; 0434; # CYRILLIC SMALL LETTER LONG-LEGGED DE +1C82; C; 043E; # CYRILLIC SMALL LETTER NARROW O +1C83; C; 0441; # CYRILLIC SMALL LETTER WIDE ES +1C84; C; 0442; # CYRILLIC SMALL LETTER TALL TE +1C85; C; 0442; # CYRILLIC SMALL LETTER THREE-LEGGED TE +1C86; C; 044A; # CYRILLIC SMALL LETTER TALL HARD SIGN +1C87; C; 0463; # CYRILLIC SMALL LETTER TALL YAT +1C88; C; A64B; # CYRILLIC SMALL LETTER UNBLENDED UK +1C90; C; 10D0; # GEORGIAN MTAVRULI CAPITAL LETTER AN +1C91; C; 10D1; # GEORGIAN MTAVRULI CAPITAL LETTER BAN +1C92; C; 10D2; # GEORGIAN MTAVRULI CAPITAL LETTER GAN +1C93; C; 10D3; # GEORGIAN MTAVRULI CAPITAL LETTER DON +1C94; C; 10D4; # GEORGIAN MTAVRULI CAPITAL LETTER EN +1C95; C; 10D5; # GEORGIAN MTAVRULI CAPITAL LETTER VIN +1C96; C; 10D6; # GEORGIAN MTAVRULI CAPITAL LETTER ZEN +1C97; C; 10D7; # GEORGIAN MTAVRULI CAPITAL LETTER TAN +1C98; C; 10D8; # GEORGIAN MTAVRULI CAPITAL LETTER IN +1C99; C; 10D9; # GEORGIAN MTAVRULI CAPITAL LETTER KAN +1C9A; C; 10DA; # GEORGIAN MTAVRULI CAPITAL LETTER LAS +1C9B; C; 10DB; # GEORGIAN MTAVRULI CAPITAL LETTER MAN +1C9C; C; 10DC; # GEORGIAN MTAVRULI CAPITAL LETTER NAR +1C9D; C; 10DD; # GEORGIAN MTAVRULI CAPITAL LETTER ON +1C9E; C; 10DE; # GEORGIAN MTAVRULI CAPITAL LETTER PAR +1C9F; C; 10DF; # GEORGIAN MTAVRULI CAPITAL LETTER ZHAR +1CA0; C; 10E0; # GEORGIAN MTAVRULI CAPITAL LETTER RAE +1CA1; C; 10E1; # GEORGIAN MTAVRULI CAPITAL LETTER SAN +1CA2; C; 10E2; # GEORGIAN MTAVRULI CAPITAL LETTER TAR +1CA3; C; 10E3; # GEORGIAN MTAVRULI CAPITAL LETTER UN +1CA4; C; 10E4; # GEORGIAN MTAVRULI CAPITAL LETTER PHAR +1CA5; C; 10E5; # GEORGIAN MTAVRULI CAPITAL LETTER KHAR +1CA6; C; 10E6; # GEORGIAN MTAVRULI CAPITAL LETTER GHAN +1CA7; C; 10E7; # GEORGIAN MTAVRULI CAPITAL LETTER QAR +1CA8; C; 10E8; # GEORGIAN MTAVRULI CAPITAL LETTER SHIN +1CA9; C; 10E9; # GEORGIAN MTAVRULI CAPITAL LETTER CHIN +1CAA; C; 10EA; # GEORGIAN MTAVRULI CAPITAL LETTER CAN +1CAB; C; 10EB; # GEORGIAN MTAVRULI CAPITAL LETTER JIL +1CAC; C; 10EC; # GEORGIAN MTAVRULI CAPITAL LETTER CIL +1CAD; C; 10ED; # GEORGIAN MTAVRULI CAPITAL LETTER CHAR +1CAE; C; 10EE; # GEORGIAN MTAVRULI CAPITAL LETTER XAN +1CAF; C; 10EF; # GEORGIAN MTAVRULI CAPITAL LETTER JHAN +1CB0; C; 10F0; # GEORGIAN MTAVRULI CAPITAL LETTER HAE +1CB1; C; 10F1; # GEORGIAN MTAVRULI CAPITAL LETTER HE +1CB2; C; 10F2; # GEORGIAN MTAVRULI CAPITAL LETTER HIE +1CB3; C; 10F3; # GEORGIAN MTAVRULI CAPITAL LETTER WE +1CB4; C; 10F4; # GEORGIAN MTAVRULI CAPITAL LETTER HAR +1CB5; C; 10F5; # GEORGIAN MTAVRULI CAPITAL LETTER HOE +1CB6; C; 10F6; # GEORGIAN MTAVRULI CAPITAL LETTER FI +1CB7; C; 10F7; # GEORGIAN MTAVRULI CAPITAL LETTER YN +1CB8; C; 10F8; # GEORGIAN MTAVRULI CAPITAL LETTER ELIFI +1CB9; C; 10F9; # GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN +1CBA; C; 10FA; # GEORGIAN MTAVRULI CAPITAL LETTER AIN +1CBD; C; 10FD; # GEORGIAN MTAVRULI CAPITAL LETTER AEN +1CBE; C; 10FE; # GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN +1CBF; C; 10FF; # GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN +1E00; C; 1E01; # LATIN CAPITAL LETTER A WITH RING BELOW +1E02; C; 1E03; # LATIN CAPITAL LETTER B WITH DOT ABOVE +1E04; C; 1E05; # LATIN CAPITAL LETTER B WITH DOT BELOW +1E06; C; 1E07; # LATIN CAPITAL LETTER B WITH LINE BELOW +1E08; C; 1E09; # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE +1E0A; C; 1E0B; # LATIN CAPITAL LETTER D WITH DOT ABOVE +1E0C; C; 1E0D; # LATIN CAPITAL LETTER D WITH DOT BELOW +1E0E; C; 1E0F; # LATIN CAPITAL LETTER D WITH LINE BELOW +1E10; C; 1E11; # LATIN CAPITAL LETTER D WITH CEDILLA +1E12; C; 1E13; # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW +1E14; C; 1E15; # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE +1E16; C; 1E17; # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE +1E18; C; 1E19; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW +1E1A; C; 1E1B; # LATIN CAPITAL LETTER E WITH TILDE BELOW +1E1C; C; 1E1D; # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE +1E1E; C; 1E1F; # LATIN CAPITAL LETTER F WITH DOT ABOVE +1E20; C; 1E21; # LATIN CAPITAL LETTER G WITH MACRON +1E22; C; 1E23; # LATIN CAPITAL LETTER H WITH DOT ABOVE +1E24; C; 1E25; # LATIN CAPITAL LETTER H WITH DOT BELOW +1E26; C; 1E27; # LATIN CAPITAL LETTER H WITH DIAERESIS +1E28; C; 1E29; # LATIN CAPITAL LETTER H WITH CEDILLA +1E2A; C; 1E2B; # LATIN CAPITAL LETTER H WITH BREVE BELOW +1E2C; C; 1E2D; # LATIN CAPITAL LETTER I WITH TILDE BELOW +1E2E; C; 1E2F; # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE +1E30; C; 1E31; # LATIN CAPITAL LETTER K WITH ACUTE +1E32; C; 1E33; # LATIN CAPITAL LETTER K WITH DOT BELOW +1E34; C; 1E35; # LATIN CAPITAL LETTER K WITH LINE BELOW +1E36; C; 1E37; # LATIN CAPITAL LETTER L WITH DOT BELOW +1E38; C; 1E39; # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON +1E3A; C; 1E3B; # LATIN CAPITAL LETTER L WITH LINE BELOW +1E3C; C; 1E3D; # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW +1E3E; C; 1E3F; # LATIN CAPITAL LETTER M WITH ACUTE +1E40; C; 1E41; # LATIN CAPITAL LETTER M WITH DOT ABOVE +1E42; C; 1E43; # LATIN CAPITAL LETTER M WITH DOT BELOW +1E44; C; 1E45; # LATIN CAPITAL LETTER N WITH DOT ABOVE +1E46; C; 1E47; # LATIN CAPITAL LETTER N WITH DOT BELOW +1E48; C; 1E49; # LATIN CAPITAL LETTER N WITH LINE BELOW +1E4A; C; 1E4B; # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW +1E4C; C; 1E4D; # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE +1E4E; C; 1E4F; # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS +1E50; C; 1E51; # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE +1E52; C; 1E53; # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE +1E54; C; 1E55; # LATIN CAPITAL LETTER P WITH ACUTE +1E56; C; 1E57; # LATIN CAPITAL LETTER P WITH DOT ABOVE +1E58; C; 1E59; # LATIN CAPITAL LETTER R WITH DOT ABOVE +1E5A; C; 1E5B; # LATIN CAPITAL LETTER R WITH DOT BELOW +1E5C; C; 1E5D; # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON +1E5E; C; 1E5F; # LATIN CAPITAL LETTER R WITH LINE BELOW +1E60; C; 1E61; # LATIN CAPITAL LETTER S WITH DOT ABOVE +1E62; C; 1E63; # LATIN CAPITAL LETTER S WITH DOT BELOW +1E64; C; 1E65; # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE +1E66; C; 1E67; # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE +1E68; C; 1E69; # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE +1E6A; C; 1E6B; # LATIN CAPITAL LETTER T WITH DOT ABOVE +1E6C; C; 1E6D; # LATIN CAPITAL LETTER T WITH DOT BELOW +1E6E; C; 1E6F; # LATIN CAPITAL LETTER T WITH LINE BELOW +1E70; C; 1E71; # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW +1E72; C; 1E73; # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW +1E74; C; 1E75; # LATIN CAPITAL LETTER U WITH TILDE BELOW +1E76; C; 1E77; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW +1E78; C; 1E79; # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE +1E7A; C; 1E7B; # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS +1E7C; C; 1E7D; # LATIN CAPITAL LETTER V WITH TILDE +1E7E; C; 1E7F; # LATIN CAPITAL LETTER V WITH DOT BELOW +1E80; C; 1E81; # LATIN CAPITAL LETTER W WITH GRAVE +1E82; C; 1E83; # LATIN CAPITAL LETTER W WITH ACUTE +1E84; C; 1E85; # LATIN CAPITAL LETTER W WITH DIAERESIS +1E86; C; 1E87; # LATIN CAPITAL LETTER W WITH DOT ABOVE +1E88; C; 1E89; # LATIN CAPITAL LETTER W WITH DOT BELOW +1E8A; C; 1E8B; # LATIN CAPITAL LETTER X WITH DOT ABOVE +1E8C; C; 1E8D; # LATIN CAPITAL LETTER X WITH DIAERESIS +1E8E; C; 1E8F; # LATIN CAPITAL LETTER Y WITH DOT ABOVE +1E90; C; 1E91; # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX +1E92; C; 1E93; # LATIN CAPITAL LETTER Z WITH DOT BELOW +1E94; C; 1E95; # LATIN CAPITAL LETTER Z WITH LINE BELOW +1E96; F; 0068 0331; # LATIN SMALL LETTER H WITH LINE BELOW +1E97; F; 0074 0308; # LATIN SMALL LETTER T WITH DIAERESIS +1E98; F; 0077 030A; # LATIN SMALL LETTER W WITH RING ABOVE +1E99; F; 0079 030A; # LATIN SMALL LETTER Y WITH RING ABOVE +1E9A; F; 0061 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING +1E9B; C; 1E61; # LATIN SMALL LETTER LONG S WITH DOT ABOVE +1E9E; F; 0073 0073; # LATIN CAPITAL LETTER SHARP S +1E9E; S; 00DF; # LATIN CAPITAL LETTER SHARP S +1EA0; C; 1EA1; # LATIN CAPITAL LETTER A WITH DOT BELOW +1EA2; C; 1EA3; # LATIN CAPITAL LETTER A WITH HOOK ABOVE +1EA4; C; 1EA5; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA6; C; 1EA7; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE +1EA8; C; 1EA9; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +1EAA; C; 1EAB; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE +1EAC; C; 1EAD; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1EAE; C; 1EAF; # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE +1EB0; C; 1EB1; # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE +1EB2; C; 1EB3; # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE +1EB4; C; 1EB5; # LATIN CAPITAL LETTER A WITH BREVE AND TILDE +1EB6; C; 1EB7; # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW +1EB8; C; 1EB9; # LATIN CAPITAL LETTER E WITH DOT BELOW +1EBA; C; 1EBB; # LATIN CAPITAL LETTER E WITH HOOK ABOVE +1EBC; C; 1EBD; # LATIN CAPITAL LETTER E WITH TILDE +1EBE; C; 1EBF; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +1EC0; C; 1EC1; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC2; C; 1EC3; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +1EC4; C; 1EC5; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE +1EC6; C; 1EC7; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1EC8; C; 1EC9; # LATIN CAPITAL LETTER I WITH HOOK ABOVE +1ECA; C; 1ECB; # LATIN CAPITAL LETTER I WITH DOT BELOW +1ECC; C; 1ECD; # LATIN CAPITAL LETTER O WITH DOT BELOW +1ECE; C; 1ECF; # LATIN CAPITAL LETTER O WITH HOOK ABOVE +1ED0; C; 1ED1; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED2; C; 1ED3; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED4; C; 1ED5; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +1ED6; C; 1ED7; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE +1ED8; C; 1ED9; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW +1EDA; C; 1EDB; # LATIN CAPITAL LETTER O WITH HORN AND ACUTE +1EDC; C; 1EDD; # LATIN CAPITAL LETTER O WITH HORN AND GRAVE +1EDE; C; 1EDF; # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE +1EE0; C; 1EE1; # LATIN CAPITAL LETTER O WITH HORN AND TILDE +1EE2; C; 1EE3; # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW +1EE4; C; 1EE5; # LATIN CAPITAL LETTER U WITH DOT BELOW +1EE6; C; 1EE7; # LATIN CAPITAL LETTER U WITH HOOK ABOVE +1EE8; C; 1EE9; # LATIN CAPITAL LETTER U WITH HORN AND ACUTE +1EEA; C; 1EEB; # LATIN CAPITAL LETTER U WITH HORN AND GRAVE +1EEC; C; 1EED; # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE +1EEE; C; 1EEF; # LATIN CAPITAL LETTER U WITH HORN AND TILDE +1EF0; C; 1EF1; # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW +1EF2; C; 1EF3; # LATIN CAPITAL LETTER Y WITH GRAVE +1EF4; C; 1EF5; # LATIN CAPITAL LETTER Y WITH DOT BELOW +1EF6; C; 1EF7; # LATIN CAPITAL LETTER Y WITH HOOK ABOVE +1EF8; C; 1EF9; # LATIN CAPITAL LETTER Y WITH TILDE +1EFA; C; 1EFB; # LATIN CAPITAL LETTER MIDDLE-WELSH LL +1EFC; C; 1EFD; # LATIN CAPITAL LETTER MIDDLE-WELSH V +1EFE; C; 1EFF; # LATIN CAPITAL LETTER Y WITH LOOP +1F08; C; 1F00; # GREEK CAPITAL LETTER ALPHA WITH PSILI +1F09; C; 1F01; # GREEK CAPITAL LETTER ALPHA WITH DASIA +1F0A; C; 1F02; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA +1F0B; C; 1F03; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA +1F0C; C; 1F04; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA +1F0D; C; 1F05; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA +1F0E; C; 1F06; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI +1F0F; C; 1F07; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F18; C; 1F10; # GREEK CAPITAL LETTER EPSILON WITH PSILI +1F19; C; 1F11; # GREEK CAPITAL LETTER EPSILON WITH DASIA +1F1A; C; 1F12; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA +1F1B; C; 1F13; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA +1F1C; C; 1F14; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA +1F1D; C; 1F15; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +1F28; C; 1F20; # GREEK CAPITAL LETTER ETA WITH PSILI +1F29; C; 1F21; # GREEK CAPITAL LETTER ETA WITH DASIA +1F2A; C; 1F22; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA +1F2B; C; 1F23; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA +1F2C; C; 1F24; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA +1F2D; C; 1F25; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA +1F2E; C; 1F26; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI +1F2F; C; 1F27; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI +1F38; C; 1F30; # GREEK CAPITAL LETTER IOTA WITH PSILI +1F39; C; 1F31; # GREEK CAPITAL LETTER IOTA WITH DASIA +1F3A; C; 1F32; # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA +1F3B; C; 1F33; # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA +1F3C; C; 1F34; # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA +1F3D; C; 1F35; # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA +1F3E; C; 1F36; # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI +1F3F; C; 1F37; # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI +1F48; C; 1F40; # GREEK CAPITAL LETTER OMICRON WITH PSILI +1F49; C; 1F41; # GREEK CAPITAL LETTER OMICRON WITH DASIA +1F4A; C; 1F42; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA +1F4B; C; 1F43; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA +1F4C; C; 1F44; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA +1F4D; C; 1F45; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +1F50; F; 03C5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI +1F52; F; 03C5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA +1F54; F; 03C5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA +1F56; F; 03C5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI +1F59; C; 1F51; # GREEK CAPITAL LETTER UPSILON WITH DASIA +1F5B; C; 1F53; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +1F5D; C; 1F55; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +1F5F; C; 1F57; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F68; C; 1F60; # GREEK CAPITAL LETTER OMEGA WITH PSILI +1F69; C; 1F61; # GREEK CAPITAL LETTER OMEGA WITH DASIA +1F6A; C; 1F62; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA +1F6B; C; 1F63; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA +1F6C; C; 1F64; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA +1F6D; C; 1F65; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA +1F6E; C; 1F66; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI +1F6F; C; 1F67; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI +1F80; F; 1F00 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI +1F81; F; 1F01 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI +1F82; F; 1F02 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F83; F; 1F03 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F84; F; 1F04 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F85; F; 1F05 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F86; F; 1F06 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F87; F; 1F07 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F88; F; 1F00 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +1F88; S; 1F80; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +1F89; F; 1F01 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +1F89; S; 1F81; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +1F8A; F; 1F02 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F8A; S; 1F82; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F8B; F; 1F03 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F8B; S; 1F83; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F8C; F; 1F04 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F8C; S; 1F84; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F8D; F; 1F05 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F8D; S; 1F85; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F8E; F; 1F06 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F8E; S; 1F86; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F8F; F; 1F07 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F8F; S; 1F87; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F90; F; 1F20 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI +1F91; F; 1F21 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI +1F92; F; 1F22 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F93; F; 1F23 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F94; F; 1F24 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F95; F; 1F25 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F96; F; 1F26 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F97; F; 1F27 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F98; F; 1F20 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +1F98; S; 1F90; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +1F99; F; 1F21 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +1F99; S; 1F91; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +1F9A; F; 1F22 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F9A; S; 1F92; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F9B; F; 1F23 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F9B; S; 1F93; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F9C; F; 1F24 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F9C; S; 1F94; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F9D; F; 1F25 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F9D; S; 1F95; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F9E; F; 1F26 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F9E; S; 1F96; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F9F; F; 1F27 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F9F; S; 1F97; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FA0; F; 1F60 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI +1FA1; F; 1F61 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI +1FA2; F; 1F62 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1FA3; F; 1F63 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1FA4; F; 1F64 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1FA5; F; 1F65 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1FA6; F; 1F66 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1FA7; F; 1F67 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1FA8; F; 1F60 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +1FA8; S; 1FA0; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +1FA9; F; 1F61 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +1FA9; S; 1FA1; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +1FAA; F; 1F62 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1FAA; S; 1FA2; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1FAB; F; 1F63 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1FAB; S; 1FA3; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1FAC; F; 1F64 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1FAC; S; 1FA4; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1FAD; F; 1F65 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1FAD; S; 1FA5; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1FAE; F; 1F66 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1FAE; S; 1FA6; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1FAF; F; 1F67 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FAF; S; 1FA7; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FB2; F; 1F70 03B9; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI +1FB3; F; 03B1 03B9; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI +1FB4; F; 03AC 03B9; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1FB6; F; 03B1 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI +1FB7; F; 03B1 0342 03B9; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI +1FB8; C; 1FB0; # GREEK CAPITAL LETTER ALPHA WITH VRACHY +1FB9; C; 1FB1; # GREEK CAPITAL LETTER ALPHA WITH MACRON +1FBA; C; 1F70; # GREEK CAPITAL LETTER ALPHA WITH VARIA +1FBB; C; 1F71; # GREEK CAPITAL LETTER ALPHA WITH OXIA +1FBC; F; 03B1 03B9; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBC; S; 1FB3; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBE; C; 03B9; # GREEK PROSGEGRAMMENI +1FC2; F; 1F74 03B9; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI +1FC3; F; 03B7 03B9; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI +1FC4; F; 03AE 03B9; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1FC6; F; 03B7 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI +1FC7; F; 03B7 0342 03B9; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI +1FC8; C; 1F72; # GREEK CAPITAL LETTER EPSILON WITH VARIA +1FC9; C; 1F73; # GREEK CAPITAL LETTER EPSILON WITH OXIA +1FCA; C; 1F74; # GREEK CAPITAL LETTER ETA WITH VARIA +1FCB; C; 1F75; # GREEK CAPITAL LETTER ETA WITH OXIA +1FCC; F; 03B7 03B9; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FCC; S; 1FC3; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FD2; F; 03B9 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA +1FD3; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD6; F; 03B9 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI +1FD7; F; 03B9 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI +1FD8; C; 1FD0; # GREEK CAPITAL LETTER IOTA WITH VRACHY +1FD9; C; 1FD1; # GREEK CAPITAL LETTER IOTA WITH MACRON +1FDA; C; 1F76; # GREEK CAPITAL LETTER IOTA WITH VARIA +1FDB; C; 1F77; # GREEK CAPITAL LETTER IOTA WITH OXIA +1FE2; F; 03C5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA +1FE3; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA +1FE4; F; 03C1 0313; # GREEK SMALL LETTER RHO WITH PSILI +1FE6; F; 03C5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI +1FE7; F; 03C5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI +1FE8; C; 1FE0; # GREEK CAPITAL LETTER UPSILON WITH VRACHY +1FE9; C; 1FE1; # GREEK CAPITAL LETTER UPSILON WITH MACRON +1FEA; C; 1F7A; # GREEK CAPITAL LETTER UPSILON WITH VARIA +1FEB; C; 1F7B; # GREEK CAPITAL LETTER UPSILON WITH OXIA +1FEC; C; 1FE5; # GREEK CAPITAL LETTER RHO WITH DASIA +1FF2; F; 1F7C 03B9; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI +1FF3; F; 03C9 03B9; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI +1FF4; F; 03CE 03B9; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1FF6; F; 03C9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI +1FF7; F; 03C9 0342 03B9; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI +1FF8; C; 1F78; # GREEK CAPITAL LETTER OMICRON WITH VARIA +1FF9; C; 1F79; # GREEK CAPITAL LETTER OMICRON WITH OXIA +1FFA; C; 1F7C; # GREEK CAPITAL LETTER OMEGA WITH VARIA +1FFB; C; 1F7D; # GREEK CAPITAL LETTER OMEGA WITH OXIA +1FFC; F; 03C9 03B9; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +1FFC; S; 1FF3; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +2126; C; 03C9; # OHM SIGN +212A; C; 006B; # KELVIN SIGN +212B; C; 00E5; # ANGSTROM SIGN +2132; C; 214E; # TURNED CAPITAL F +2160; C; 2170; # ROMAN NUMERAL ONE +2161; C; 2171; # ROMAN NUMERAL TWO +2162; C; 2172; # ROMAN NUMERAL THREE +2163; C; 2173; # ROMAN NUMERAL FOUR +2164; C; 2174; # ROMAN NUMERAL FIVE +2165; C; 2175; # ROMAN NUMERAL SIX +2166; C; 2176; # ROMAN NUMERAL SEVEN +2167; C; 2177; # ROMAN NUMERAL EIGHT +2168; C; 2178; # ROMAN NUMERAL NINE +2169; C; 2179; # ROMAN NUMERAL TEN +216A; C; 217A; # ROMAN NUMERAL ELEVEN +216B; C; 217B; # ROMAN NUMERAL TWELVE +216C; C; 217C; # ROMAN NUMERAL FIFTY +216D; C; 217D; # ROMAN NUMERAL ONE HUNDRED +216E; C; 217E; # ROMAN NUMERAL FIVE HUNDRED +216F; C; 217F; # ROMAN NUMERAL ONE THOUSAND +2183; C; 2184; # ROMAN NUMERAL REVERSED ONE HUNDRED +24B6; C; 24D0; # CIRCLED LATIN CAPITAL LETTER A +24B7; C; 24D1; # CIRCLED LATIN CAPITAL LETTER B +24B8; C; 24D2; # CIRCLED LATIN CAPITAL LETTER C +24B9; C; 24D3; # CIRCLED LATIN CAPITAL LETTER D +24BA; C; 24D4; # CIRCLED LATIN CAPITAL LETTER E +24BB; C; 24D5; # CIRCLED LATIN CAPITAL LETTER F +24BC; C; 24D6; # CIRCLED LATIN CAPITAL LETTER G +24BD; C; 24D7; # CIRCLED LATIN CAPITAL LETTER H +24BE; C; 24D8; # CIRCLED LATIN CAPITAL LETTER I +24BF; C; 24D9; # CIRCLED LATIN CAPITAL LETTER J +24C0; C; 24DA; # CIRCLED LATIN CAPITAL LETTER K +24C1; C; 24DB; # CIRCLED LATIN CAPITAL LETTER L +24C2; C; 24DC; # CIRCLED LATIN CAPITAL LETTER M +24C3; C; 24DD; # CIRCLED LATIN CAPITAL LETTER N +24C4; C; 24DE; # CIRCLED LATIN CAPITAL LETTER O +24C5; C; 24DF; # CIRCLED LATIN CAPITAL LETTER P +24C6; C; 24E0; # CIRCLED LATIN CAPITAL LETTER Q +24C7; C; 24E1; # CIRCLED LATIN CAPITAL LETTER R +24C8; C; 24E2; # CIRCLED LATIN CAPITAL LETTER S +24C9; C; 24E3; # CIRCLED LATIN CAPITAL LETTER T +24CA; C; 24E4; # CIRCLED LATIN CAPITAL LETTER U +24CB; C; 24E5; # CIRCLED LATIN CAPITAL LETTER V +24CC; C; 24E6; # CIRCLED LATIN CAPITAL LETTER W +24CD; C; 24E7; # CIRCLED LATIN CAPITAL LETTER X +24CE; C; 24E8; # CIRCLED LATIN CAPITAL LETTER Y +24CF; C; 24E9; # CIRCLED LATIN CAPITAL LETTER Z +2C00; C; 2C30; # GLAGOLITIC CAPITAL LETTER AZU +2C01; C; 2C31; # GLAGOLITIC CAPITAL LETTER BUKY +2C02; C; 2C32; # GLAGOLITIC CAPITAL LETTER VEDE +2C03; C; 2C33; # GLAGOLITIC CAPITAL LETTER GLAGOLI +2C04; C; 2C34; # GLAGOLITIC CAPITAL LETTER DOBRO +2C05; C; 2C35; # GLAGOLITIC CAPITAL LETTER YESTU +2C06; C; 2C36; # GLAGOLITIC CAPITAL LETTER ZHIVETE +2C07; C; 2C37; # GLAGOLITIC CAPITAL LETTER DZELO +2C08; C; 2C38; # GLAGOLITIC CAPITAL LETTER ZEMLJA +2C09; C; 2C39; # GLAGOLITIC CAPITAL LETTER IZHE +2C0A; C; 2C3A; # GLAGOLITIC CAPITAL LETTER INITIAL IZHE +2C0B; C; 2C3B; # GLAGOLITIC CAPITAL LETTER I +2C0C; C; 2C3C; # GLAGOLITIC CAPITAL LETTER DJERVI +2C0D; C; 2C3D; # GLAGOLITIC CAPITAL LETTER KAKO +2C0E; C; 2C3E; # GLAGOLITIC CAPITAL LETTER LJUDIJE +2C0F; C; 2C3F; # GLAGOLITIC CAPITAL LETTER MYSLITE +2C10; C; 2C40; # GLAGOLITIC CAPITAL LETTER NASHI +2C11; C; 2C41; # GLAGOLITIC CAPITAL LETTER ONU +2C12; C; 2C42; # GLAGOLITIC CAPITAL LETTER POKOJI +2C13; C; 2C43; # GLAGOLITIC CAPITAL LETTER RITSI +2C14; C; 2C44; # GLAGOLITIC CAPITAL LETTER SLOVO +2C15; C; 2C45; # GLAGOLITIC CAPITAL LETTER TVRIDO +2C16; C; 2C46; # GLAGOLITIC CAPITAL LETTER UKU +2C17; C; 2C47; # GLAGOLITIC CAPITAL LETTER FRITU +2C18; C; 2C48; # GLAGOLITIC CAPITAL LETTER HERU +2C19; C; 2C49; # GLAGOLITIC CAPITAL LETTER OTU +2C1A; C; 2C4A; # GLAGOLITIC CAPITAL LETTER PE +2C1B; C; 2C4B; # GLAGOLITIC CAPITAL LETTER SHTA +2C1C; C; 2C4C; # GLAGOLITIC CAPITAL LETTER TSI +2C1D; C; 2C4D; # GLAGOLITIC CAPITAL LETTER CHRIVI +2C1E; C; 2C4E; # GLAGOLITIC CAPITAL LETTER SHA +2C1F; C; 2C4F; # GLAGOLITIC CAPITAL LETTER YERU +2C20; C; 2C50; # GLAGOLITIC CAPITAL LETTER YERI +2C21; C; 2C51; # GLAGOLITIC CAPITAL LETTER YATI +2C22; C; 2C52; # GLAGOLITIC CAPITAL LETTER SPIDERY HA +2C23; C; 2C53; # GLAGOLITIC CAPITAL LETTER YU +2C24; C; 2C54; # GLAGOLITIC CAPITAL LETTER SMALL YUS +2C25; C; 2C55; # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL +2C26; C; 2C56; # GLAGOLITIC CAPITAL LETTER YO +2C27; C; 2C57; # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS +2C28; C; 2C58; # GLAGOLITIC CAPITAL LETTER BIG YUS +2C29; C; 2C59; # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS +2C2A; C; 2C5A; # GLAGOLITIC CAPITAL LETTER FITA +2C2B; C; 2C5B; # GLAGOLITIC CAPITAL LETTER IZHITSA +2C2C; C; 2C5C; # GLAGOLITIC CAPITAL LETTER SHTAPIC +2C2D; C; 2C5D; # GLAGOLITIC CAPITAL LETTER TROKUTASTI A +2C2E; C; 2C5E; # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C60; C; 2C61; # LATIN CAPITAL LETTER L WITH DOUBLE BAR +2C62; C; 026B; # LATIN CAPITAL LETTER L WITH MIDDLE TILDE +2C63; C; 1D7D; # LATIN CAPITAL LETTER P WITH STROKE +2C64; C; 027D; # LATIN CAPITAL LETTER R WITH TAIL +2C67; C; 2C68; # LATIN CAPITAL LETTER H WITH DESCENDER +2C69; C; 2C6A; # LATIN CAPITAL LETTER K WITH DESCENDER +2C6B; C; 2C6C; # LATIN CAPITAL LETTER Z WITH DESCENDER +2C6D; C; 0251; # LATIN CAPITAL LETTER ALPHA +2C6E; C; 0271; # LATIN CAPITAL LETTER M WITH HOOK +2C6F; C; 0250; # LATIN CAPITAL LETTER TURNED A +2C70; C; 0252; # LATIN CAPITAL LETTER TURNED ALPHA +2C72; C; 2C73; # LATIN CAPITAL LETTER W WITH HOOK +2C75; C; 2C76; # LATIN CAPITAL LETTER HALF H +2C7E; C; 023F; # LATIN CAPITAL LETTER S WITH SWASH TAIL +2C7F; C; 0240; # LATIN CAPITAL LETTER Z WITH SWASH TAIL +2C80; C; 2C81; # COPTIC CAPITAL LETTER ALFA +2C82; C; 2C83; # COPTIC CAPITAL LETTER VIDA +2C84; C; 2C85; # COPTIC CAPITAL LETTER GAMMA +2C86; C; 2C87; # COPTIC CAPITAL LETTER DALDA +2C88; C; 2C89; # COPTIC CAPITAL LETTER EIE +2C8A; C; 2C8B; # COPTIC CAPITAL LETTER SOU +2C8C; C; 2C8D; # COPTIC CAPITAL LETTER ZATA +2C8E; C; 2C8F; # COPTIC CAPITAL LETTER HATE +2C90; C; 2C91; # COPTIC CAPITAL LETTER THETHE +2C92; C; 2C93; # COPTIC CAPITAL LETTER IAUDA +2C94; C; 2C95; # COPTIC CAPITAL LETTER KAPA +2C96; C; 2C97; # COPTIC CAPITAL LETTER LAULA +2C98; C; 2C99; # COPTIC CAPITAL LETTER MI +2C9A; C; 2C9B; # COPTIC CAPITAL LETTER NI +2C9C; C; 2C9D; # COPTIC CAPITAL LETTER KSI +2C9E; C; 2C9F; # COPTIC CAPITAL LETTER O +2CA0; C; 2CA1; # COPTIC CAPITAL LETTER PI +2CA2; C; 2CA3; # COPTIC CAPITAL LETTER RO +2CA4; C; 2CA5; # COPTIC CAPITAL LETTER SIMA +2CA6; C; 2CA7; # COPTIC CAPITAL LETTER TAU +2CA8; C; 2CA9; # COPTIC CAPITAL LETTER UA +2CAA; C; 2CAB; # COPTIC CAPITAL LETTER FI +2CAC; C; 2CAD; # COPTIC CAPITAL LETTER KHI +2CAE; C; 2CAF; # COPTIC CAPITAL LETTER PSI +2CB0; C; 2CB1; # COPTIC CAPITAL LETTER OOU +2CB2; C; 2CB3; # COPTIC CAPITAL LETTER DIALECT-P ALEF +2CB4; C; 2CB5; # COPTIC CAPITAL LETTER OLD COPTIC AIN +2CB6; C; 2CB7; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE +2CB8; C; 2CB9; # COPTIC CAPITAL LETTER DIALECT-P KAPA +2CBA; C; 2CBB; # COPTIC CAPITAL LETTER DIALECT-P NI +2CBC; C; 2CBD; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI +2CBE; C; 2CBF; # COPTIC CAPITAL LETTER OLD COPTIC OOU +2CC0; C; 2CC1; # COPTIC CAPITAL LETTER SAMPI +2CC2; C; 2CC3; # COPTIC CAPITAL LETTER CROSSED SHEI +2CC4; C; 2CC5; # COPTIC CAPITAL LETTER OLD COPTIC SHEI +2CC6; C; 2CC7; # COPTIC CAPITAL LETTER OLD COPTIC ESH +2CC8; C; 2CC9; # COPTIC CAPITAL LETTER AKHMIMIC KHEI +2CCA; C; 2CCB; # COPTIC CAPITAL LETTER DIALECT-P HORI +2CCC; C; 2CCD; # COPTIC CAPITAL LETTER OLD COPTIC HORI +2CCE; C; 2CCF; # COPTIC CAPITAL LETTER OLD COPTIC HA +2CD0; C; 2CD1; # COPTIC CAPITAL LETTER L-SHAPED HA +2CD2; C; 2CD3; # COPTIC CAPITAL LETTER OLD COPTIC HEI +2CD4; C; 2CD5; # COPTIC CAPITAL LETTER OLD COPTIC HAT +2CD6; C; 2CD7; # COPTIC CAPITAL LETTER OLD COPTIC GANGIA +2CD8; C; 2CD9; # COPTIC CAPITAL LETTER OLD COPTIC DJA +2CDA; C; 2CDB; # COPTIC CAPITAL LETTER OLD COPTIC SHIMA +2CDC; C; 2CDD; # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA +2CDE; C; 2CDF; # COPTIC CAPITAL LETTER OLD NUBIAN NGI +2CE0; C; 2CE1; # COPTIC CAPITAL LETTER OLD NUBIAN NYI +2CE2; C; 2CE3; # COPTIC CAPITAL LETTER OLD NUBIAN WAU +2CEB; C; 2CEC; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI +2CED; C; 2CEE; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA +2CF2; C; 2CF3; # COPTIC CAPITAL LETTER BOHAIRIC KHEI +A640; C; A641; # CYRILLIC CAPITAL LETTER ZEMLYA +A642; C; A643; # CYRILLIC CAPITAL LETTER DZELO +A644; C; A645; # CYRILLIC CAPITAL LETTER REVERSED DZE +A646; C; A647; # CYRILLIC CAPITAL LETTER IOTA +A648; C; A649; # CYRILLIC CAPITAL LETTER DJERV +A64A; C; A64B; # CYRILLIC CAPITAL LETTER MONOGRAPH UK +A64C; C; A64D; # CYRILLIC CAPITAL LETTER BROAD OMEGA +A64E; C; A64F; # CYRILLIC CAPITAL LETTER NEUTRAL YER +A650; C; A651; # CYRILLIC CAPITAL LETTER YERU WITH BACK YER +A652; C; A653; # CYRILLIC CAPITAL LETTER IOTIFIED YAT +A654; C; A655; # CYRILLIC CAPITAL LETTER REVERSED YU +A656; C; A657; # CYRILLIC CAPITAL LETTER IOTIFIED A +A658; C; A659; # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS +A65A; C; A65B; # CYRILLIC CAPITAL LETTER BLENDED YUS +A65C; C; A65D; # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS +A65E; C; A65F; # CYRILLIC CAPITAL LETTER YN +A660; C; A661; # CYRILLIC CAPITAL LETTER REVERSED TSE +A662; C; A663; # CYRILLIC CAPITAL LETTER SOFT DE +A664; C; A665; # CYRILLIC CAPITAL LETTER SOFT EL +A666; C; A667; # CYRILLIC CAPITAL LETTER SOFT EM +A668; C; A669; # CYRILLIC CAPITAL LETTER MONOCULAR O +A66A; C; A66B; # CYRILLIC CAPITAL LETTER BINOCULAR O +A66C; C; A66D; # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O +A680; C; A681; # CYRILLIC CAPITAL LETTER DWE +A682; C; A683; # CYRILLIC CAPITAL LETTER DZWE +A684; C; A685; # CYRILLIC CAPITAL LETTER ZHWE +A686; C; A687; # CYRILLIC CAPITAL LETTER CCHE +A688; C; A689; # CYRILLIC CAPITAL LETTER DZZE +A68A; C; A68B; # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK +A68C; C; A68D; # CYRILLIC CAPITAL LETTER TWE +A68E; C; A68F; # CYRILLIC CAPITAL LETTER TSWE +A690; C; A691; # CYRILLIC CAPITAL LETTER TSSE +A692; C; A693; # CYRILLIC CAPITAL LETTER TCHE +A694; C; A695; # CYRILLIC CAPITAL LETTER HWE +A696; C; A697; # CYRILLIC CAPITAL LETTER SHWE +A698; C; A699; # CYRILLIC CAPITAL LETTER DOUBLE O +A69A; C; A69B; # CYRILLIC CAPITAL LETTER CROSSED O +A722; C; A723; # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF +A724; C; A725; # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN +A726; C; A727; # LATIN CAPITAL LETTER HENG +A728; C; A729; # LATIN CAPITAL LETTER TZ +A72A; C; A72B; # LATIN CAPITAL LETTER TRESILLO +A72C; C; A72D; # LATIN CAPITAL LETTER CUATRILLO +A72E; C; A72F; # LATIN CAPITAL LETTER CUATRILLO WITH COMMA +A732; C; A733; # LATIN CAPITAL LETTER AA +A734; C; A735; # LATIN CAPITAL LETTER AO +A736; C; A737; # LATIN CAPITAL LETTER AU +A738; C; A739; # LATIN CAPITAL LETTER AV +A73A; C; A73B; # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR +A73C; C; A73D; # LATIN CAPITAL LETTER AY +A73E; C; A73F; # LATIN CAPITAL LETTER REVERSED C WITH DOT +A740; C; A741; # LATIN CAPITAL LETTER K WITH STROKE +A742; C; A743; # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE +A744; C; A745; # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE +A746; C; A747; # LATIN CAPITAL LETTER BROKEN L +A748; C; A749; # LATIN CAPITAL LETTER L WITH HIGH STROKE +A74A; C; A74B; # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY +A74C; C; A74D; # LATIN CAPITAL LETTER O WITH LOOP +A74E; C; A74F; # LATIN CAPITAL LETTER OO +A750; C; A751; # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER +A752; C; A753; # LATIN CAPITAL LETTER P WITH FLOURISH +A754; C; A755; # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL +A756; C; A757; # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER +A758; C; A759; # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE +A75A; C; A75B; # LATIN CAPITAL LETTER R ROTUNDA +A75C; C; A75D; # LATIN CAPITAL LETTER RUM ROTUNDA +A75E; C; A75F; # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE +A760; C; A761; # LATIN CAPITAL LETTER VY +A762; C; A763; # LATIN CAPITAL LETTER VISIGOTHIC Z +A764; C; A765; # LATIN CAPITAL LETTER THORN WITH STROKE +A766; C; A767; # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER +A768; C; A769; # LATIN CAPITAL LETTER VEND +A76A; C; A76B; # LATIN CAPITAL LETTER ET +A76C; C; A76D; # LATIN CAPITAL LETTER IS +A76E; C; A76F; # LATIN CAPITAL LETTER CON +A779; C; A77A; # LATIN CAPITAL LETTER INSULAR D +A77B; C; A77C; # LATIN CAPITAL LETTER INSULAR F +A77D; C; 1D79; # LATIN CAPITAL LETTER INSULAR G +A77E; C; A77F; # LATIN CAPITAL LETTER TURNED INSULAR G +A780; C; A781; # LATIN CAPITAL LETTER TURNED L +A782; C; A783; # LATIN CAPITAL LETTER INSULAR R +A784; C; A785; # LATIN CAPITAL LETTER INSULAR S +A786; C; A787; # LATIN CAPITAL LETTER INSULAR T +A78B; C; A78C; # LATIN CAPITAL LETTER SALTILLO +A78D; C; 0265; # LATIN CAPITAL LETTER TURNED H +A790; C; A791; # LATIN CAPITAL LETTER N WITH DESCENDER +A792; C; A793; # LATIN CAPITAL LETTER C WITH BAR +A796; C; A797; # LATIN CAPITAL LETTER B WITH FLOURISH +A798; C; A799; # LATIN CAPITAL LETTER F WITH STROKE +A79A; C; A79B; # LATIN CAPITAL LETTER VOLAPUK AE +A79C; C; A79D; # LATIN CAPITAL LETTER VOLAPUK OE +A79E; C; A79F; # LATIN CAPITAL LETTER VOLAPUK UE +A7A0; C; A7A1; # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE +A7A2; C; A7A3; # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE +A7A4; C; A7A5; # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE +A7A6; C; A7A7; # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE +A7A8; C; A7A9; # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE +A7AA; C; 0266; # LATIN CAPITAL LETTER H WITH HOOK +A7AB; C; 025C; # LATIN CAPITAL LETTER REVERSED OPEN E +A7AC; C; 0261; # LATIN CAPITAL LETTER SCRIPT G +A7AD; C; 026C; # LATIN CAPITAL LETTER L WITH BELT +A7AE; C; 026A; # LATIN CAPITAL LETTER SMALL CAPITAL I +A7B0; C; 029E; # LATIN CAPITAL LETTER TURNED K +A7B1; C; 0287; # LATIN CAPITAL LETTER TURNED T +A7B2; C; 029D; # LATIN CAPITAL LETTER J WITH CROSSED-TAIL +A7B3; C; AB53; # LATIN CAPITAL LETTER CHI +A7B4; C; A7B5; # LATIN CAPITAL LETTER BETA +A7B6; C; A7B7; # LATIN CAPITAL LETTER OMEGA +A7B8; C; A7B9; # LATIN CAPITAL LETTER U WITH STROKE +A7BA; C; A7BB; # LATIN CAPITAL LETTER GLOTTAL A +A7BC; C; A7BD; # LATIN CAPITAL LETTER GLOTTAL I +A7BE; C; A7BF; # LATIN CAPITAL LETTER GLOTTAL U +A7C2; C; A7C3; # LATIN CAPITAL LETTER ANGLICANA W +A7C4; C; A794; # LATIN CAPITAL LETTER C WITH PALATAL HOOK +A7C5; C; 0282; # LATIN CAPITAL LETTER S WITH HOOK +A7C6; C; 1D8E; # LATIN CAPITAL LETTER Z WITH PALATAL HOOK +A7C7; C; A7C8; # LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY +A7C9; C; A7CA; # LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY +A7F5; C; A7F6; # LATIN CAPITAL LETTER REVERSED HALF H +AB70; C; 13A0; # CHEROKEE SMALL LETTER A +AB71; C; 13A1; # CHEROKEE SMALL LETTER E +AB72; C; 13A2; # CHEROKEE SMALL LETTER I +AB73; C; 13A3; # CHEROKEE SMALL LETTER O +AB74; C; 13A4; # CHEROKEE SMALL LETTER U +AB75; C; 13A5; # CHEROKEE SMALL LETTER V +AB76; C; 13A6; # CHEROKEE SMALL LETTER GA +AB77; C; 13A7; # CHEROKEE SMALL LETTER KA +AB78; C; 13A8; # CHEROKEE SMALL LETTER GE +AB79; C; 13A9; # CHEROKEE SMALL LETTER GI +AB7A; C; 13AA; # CHEROKEE SMALL LETTER GO +AB7B; C; 13AB; # CHEROKEE SMALL LETTER GU +AB7C; C; 13AC; # CHEROKEE SMALL LETTER GV +AB7D; C; 13AD; # CHEROKEE SMALL LETTER HA +AB7E; C; 13AE; # CHEROKEE SMALL LETTER HE +AB7F; C; 13AF; # CHEROKEE SMALL LETTER HI +AB80; C; 13B0; # CHEROKEE SMALL LETTER HO +AB81; C; 13B1; # CHEROKEE SMALL LETTER HU +AB82; C; 13B2; # CHEROKEE SMALL LETTER HV +AB83; C; 13B3; # CHEROKEE SMALL LETTER LA +AB84; C; 13B4; # CHEROKEE SMALL LETTER LE +AB85; C; 13B5; # CHEROKEE SMALL LETTER LI +AB86; C; 13B6; # CHEROKEE SMALL LETTER LO +AB87; C; 13B7; # CHEROKEE SMALL LETTER LU +AB88; C; 13B8; # CHEROKEE SMALL LETTER LV +AB89; C; 13B9; # CHEROKEE SMALL LETTER MA +AB8A; C; 13BA; # CHEROKEE SMALL LETTER ME +AB8B; C; 13BB; # CHEROKEE SMALL LETTER MI +AB8C; C; 13BC; # CHEROKEE SMALL LETTER MO +AB8D; C; 13BD; # CHEROKEE SMALL LETTER MU +AB8E; C; 13BE; # CHEROKEE SMALL LETTER NA +AB8F; C; 13BF; # CHEROKEE SMALL LETTER HNA +AB90; C; 13C0; # CHEROKEE SMALL LETTER NAH +AB91; C; 13C1; # CHEROKEE SMALL LETTER NE +AB92; C; 13C2; # CHEROKEE SMALL LETTER NI +AB93; C; 13C3; # CHEROKEE SMALL LETTER NO +AB94; C; 13C4; # CHEROKEE SMALL LETTER NU +AB95; C; 13C5; # CHEROKEE SMALL LETTER NV +AB96; C; 13C6; # CHEROKEE SMALL LETTER QUA +AB97; C; 13C7; # CHEROKEE SMALL LETTER QUE +AB98; C; 13C8; # CHEROKEE SMALL LETTER QUI +AB99; C; 13C9; # CHEROKEE SMALL LETTER QUO +AB9A; C; 13CA; # CHEROKEE SMALL LETTER QUU +AB9B; C; 13CB; # CHEROKEE SMALL LETTER QUV +AB9C; C; 13CC; # CHEROKEE SMALL LETTER SA +AB9D; C; 13CD; # CHEROKEE SMALL LETTER S +AB9E; C; 13CE; # CHEROKEE SMALL LETTER SE +AB9F; C; 13CF; # CHEROKEE SMALL LETTER SI +ABA0; C; 13D0; # CHEROKEE SMALL LETTER SO +ABA1; C; 13D1; # CHEROKEE SMALL LETTER SU +ABA2; C; 13D2; # CHEROKEE SMALL LETTER SV +ABA3; C; 13D3; # CHEROKEE SMALL LETTER DA +ABA4; C; 13D4; # CHEROKEE SMALL LETTER TA +ABA5; C; 13D5; # CHEROKEE SMALL LETTER DE +ABA6; C; 13D6; # CHEROKEE SMALL LETTER TE +ABA7; C; 13D7; # CHEROKEE SMALL LETTER DI +ABA8; C; 13D8; # CHEROKEE SMALL LETTER TI +ABA9; C; 13D9; # CHEROKEE SMALL LETTER DO +ABAA; C; 13DA; # CHEROKEE SMALL LETTER DU +ABAB; C; 13DB; # CHEROKEE SMALL LETTER DV +ABAC; C; 13DC; # CHEROKEE SMALL LETTER DLA +ABAD; C; 13DD; # CHEROKEE SMALL LETTER TLA +ABAE; C; 13DE; # CHEROKEE SMALL LETTER TLE +ABAF; C; 13DF; # CHEROKEE SMALL LETTER TLI +ABB0; C; 13E0; # CHEROKEE SMALL LETTER TLO +ABB1; C; 13E1; # CHEROKEE SMALL LETTER TLU +ABB2; C; 13E2; # CHEROKEE SMALL LETTER TLV +ABB3; C; 13E3; # CHEROKEE SMALL LETTER TSA +ABB4; C; 13E4; # CHEROKEE SMALL LETTER TSE +ABB5; C; 13E5; # CHEROKEE SMALL LETTER TSI +ABB6; C; 13E6; # CHEROKEE SMALL LETTER TSO +ABB7; C; 13E7; # CHEROKEE SMALL LETTER TSU +ABB8; C; 13E8; # CHEROKEE SMALL LETTER TSV +ABB9; C; 13E9; # CHEROKEE SMALL LETTER WA +ABBA; C; 13EA; # CHEROKEE SMALL LETTER WE +ABBB; C; 13EB; # CHEROKEE SMALL LETTER WI +ABBC; C; 13EC; # CHEROKEE SMALL LETTER WO +ABBD; C; 13ED; # CHEROKEE SMALL LETTER WU +ABBE; C; 13EE; # CHEROKEE SMALL LETTER WV +ABBF; C; 13EF; # CHEROKEE SMALL LETTER YA +FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF +FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI +FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL +FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI +FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL +FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T +FB06; F; 0073 0074; # LATIN SMALL LIGATURE ST +FB13; F; 0574 0576; # ARMENIAN SMALL LIGATURE MEN NOW +FB14; F; 0574 0565; # ARMENIAN SMALL LIGATURE MEN ECH +FB15; F; 0574 056B; # ARMENIAN SMALL LIGATURE MEN INI +FB16; F; 057E 0576; # ARMENIAN SMALL LIGATURE VEW NOW +FB17; F; 0574 056D; # ARMENIAN SMALL LIGATURE MEN XEH +FF21; C; FF41; # FULLWIDTH LATIN CAPITAL LETTER A +FF22; C; FF42; # FULLWIDTH LATIN CAPITAL LETTER B +FF23; C; FF43; # FULLWIDTH LATIN CAPITAL LETTER C +FF24; C; FF44; # FULLWIDTH LATIN CAPITAL LETTER D +FF25; C; FF45; # FULLWIDTH LATIN CAPITAL LETTER E +FF26; C; FF46; # FULLWIDTH LATIN CAPITAL LETTER F +FF27; C; FF47; # FULLWIDTH LATIN CAPITAL LETTER G +FF28; C; FF48; # FULLWIDTH LATIN CAPITAL LETTER H +FF29; C; FF49; # FULLWIDTH LATIN CAPITAL LETTER I +FF2A; C; FF4A; # FULLWIDTH LATIN CAPITAL LETTER J +FF2B; C; FF4B; # FULLWIDTH LATIN CAPITAL LETTER K +FF2C; C; FF4C; # FULLWIDTH LATIN CAPITAL LETTER L +FF2D; C; FF4D; # FULLWIDTH LATIN CAPITAL LETTER M +FF2E; C; FF4E; # FULLWIDTH LATIN CAPITAL LETTER N +FF2F; C; FF4F; # FULLWIDTH LATIN CAPITAL LETTER O +FF30; C; FF50; # FULLWIDTH LATIN CAPITAL LETTER P +FF31; C; FF51; # FULLWIDTH LATIN CAPITAL LETTER Q +FF32; C; FF52; # FULLWIDTH LATIN CAPITAL LETTER R +FF33; C; FF53; # FULLWIDTH LATIN CAPITAL LETTER S +FF34; C; FF54; # FULLWIDTH LATIN CAPITAL LETTER T +FF35; C; FF55; # FULLWIDTH LATIN CAPITAL LETTER U +FF36; C; FF56; # FULLWIDTH LATIN CAPITAL LETTER V +FF37; C; FF57; # FULLWIDTH LATIN CAPITAL LETTER W +FF38; C; FF58; # FULLWIDTH LATIN CAPITAL LETTER X +FF39; C; FF59; # FULLWIDTH LATIN CAPITAL LETTER Y +FF3A; C; FF5A; # FULLWIDTH LATIN CAPITAL LETTER Z +10400; C; 10428; # DESERET CAPITAL LETTER LONG I +10401; C; 10429; # DESERET CAPITAL LETTER LONG E +10402; C; 1042A; # DESERET CAPITAL LETTER LONG A +10403; C; 1042B; # DESERET CAPITAL LETTER LONG AH +10404; C; 1042C; # DESERET CAPITAL LETTER LONG O +10405; C; 1042D; # DESERET CAPITAL LETTER LONG OO +10406; C; 1042E; # DESERET CAPITAL LETTER SHORT I +10407; C; 1042F; # DESERET CAPITAL LETTER SHORT E +10408; C; 10430; # DESERET CAPITAL LETTER SHORT A +10409; C; 10431; # DESERET CAPITAL LETTER SHORT AH +1040A; C; 10432; # DESERET CAPITAL LETTER SHORT O +1040B; C; 10433; # DESERET CAPITAL LETTER SHORT OO +1040C; C; 10434; # DESERET CAPITAL LETTER AY +1040D; C; 10435; # DESERET CAPITAL LETTER OW +1040E; C; 10436; # DESERET CAPITAL LETTER WU +1040F; C; 10437; # DESERET CAPITAL LETTER YEE +10410; C; 10438; # DESERET CAPITAL LETTER H +10411; C; 10439; # DESERET CAPITAL LETTER PEE +10412; C; 1043A; # DESERET CAPITAL LETTER BEE +10413; C; 1043B; # DESERET CAPITAL LETTER TEE +10414; C; 1043C; # DESERET CAPITAL LETTER DEE +10415; C; 1043D; # DESERET CAPITAL LETTER CHEE +10416; C; 1043E; # DESERET CAPITAL LETTER JEE +10417; C; 1043F; # DESERET CAPITAL LETTER KAY +10418; C; 10440; # DESERET CAPITAL LETTER GAY +10419; C; 10441; # DESERET CAPITAL LETTER EF +1041A; C; 10442; # DESERET CAPITAL LETTER VEE +1041B; C; 10443; # DESERET CAPITAL LETTER ETH +1041C; C; 10444; # DESERET CAPITAL LETTER THEE +1041D; C; 10445; # DESERET CAPITAL LETTER ES +1041E; C; 10446; # DESERET CAPITAL LETTER ZEE +1041F; C; 10447; # DESERET CAPITAL LETTER ESH +10420; C; 10448; # DESERET CAPITAL LETTER ZHEE +10421; C; 10449; # DESERET CAPITAL LETTER ER +10422; C; 1044A; # DESERET CAPITAL LETTER EL +10423; C; 1044B; # DESERET CAPITAL LETTER EM +10424; C; 1044C; # DESERET CAPITAL LETTER EN +10425; C; 1044D; # DESERET CAPITAL LETTER ENG +10426; C; 1044E; # DESERET CAPITAL LETTER OI +10427; C; 1044F; # DESERET CAPITAL LETTER EW +104B0; C; 104D8; # OSAGE CAPITAL LETTER A +104B1; C; 104D9; # OSAGE CAPITAL LETTER AI +104B2; C; 104DA; # OSAGE CAPITAL LETTER AIN +104B3; C; 104DB; # OSAGE CAPITAL LETTER AH +104B4; C; 104DC; # OSAGE CAPITAL LETTER BRA +104B5; C; 104DD; # OSAGE CAPITAL LETTER CHA +104B6; C; 104DE; # OSAGE CAPITAL LETTER EHCHA +104B7; C; 104DF; # OSAGE CAPITAL LETTER E +104B8; C; 104E0; # OSAGE CAPITAL LETTER EIN +104B9; C; 104E1; # OSAGE CAPITAL LETTER HA +104BA; C; 104E2; # OSAGE CAPITAL LETTER HYA +104BB; C; 104E3; # OSAGE CAPITAL LETTER I +104BC; C; 104E4; # OSAGE CAPITAL LETTER KA +104BD; C; 104E5; # OSAGE CAPITAL LETTER EHKA +104BE; C; 104E6; # OSAGE CAPITAL LETTER KYA +104BF; C; 104E7; # OSAGE CAPITAL LETTER LA +104C0; C; 104E8; # OSAGE CAPITAL LETTER MA +104C1; C; 104E9; # OSAGE CAPITAL LETTER NA +104C2; C; 104EA; # OSAGE CAPITAL LETTER O +104C3; C; 104EB; # OSAGE CAPITAL LETTER OIN +104C4; C; 104EC; # OSAGE CAPITAL LETTER PA +104C5; C; 104ED; # OSAGE CAPITAL LETTER EHPA +104C6; C; 104EE; # OSAGE CAPITAL LETTER SA +104C7; C; 104EF; # OSAGE CAPITAL LETTER SHA +104C8; C; 104F0; # OSAGE CAPITAL LETTER TA +104C9; C; 104F1; # OSAGE CAPITAL LETTER EHTA +104CA; C; 104F2; # OSAGE CAPITAL LETTER TSA +104CB; C; 104F3; # OSAGE CAPITAL LETTER EHTSA +104CC; C; 104F4; # OSAGE CAPITAL LETTER TSHA +104CD; C; 104F5; # OSAGE CAPITAL LETTER DHA +104CE; C; 104F6; # OSAGE CAPITAL LETTER U +104CF; C; 104F7; # OSAGE CAPITAL LETTER WA +104D0; C; 104F8; # OSAGE CAPITAL LETTER KHA +104D1; C; 104F9; # OSAGE CAPITAL LETTER GHA +104D2; C; 104FA; # OSAGE CAPITAL LETTER ZA +104D3; C; 104FB; # OSAGE CAPITAL LETTER ZHA +10C80; C; 10CC0; # OLD HUNGARIAN CAPITAL LETTER A +10C81; C; 10CC1; # OLD HUNGARIAN CAPITAL LETTER AA +10C82; C; 10CC2; # OLD HUNGARIAN CAPITAL LETTER EB +10C83; C; 10CC3; # OLD HUNGARIAN CAPITAL LETTER AMB +10C84; C; 10CC4; # OLD HUNGARIAN CAPITAL LETTER EC +10C85; C; 10CC5; # OLD HUNGARIAN CAPITAL LETTER ENC +10C86; C; 10CC6; # OLD HUNGARIAN CAPITAL LETTER ECS +10C87; C; 10CC7; # OLD HUNGARIAN CAPITAL LETTER ED +10C88; C; 10CC8; # OLD HUNGARIAN CAPITAL LETTER AND +10C89; C; 10CC9; # OLD HUNGARIAN CAPITAL LETTER E +10C8A; C; 10CCA; # OLD HUNGARIAN CAPITAL LETTER CLOSE E +10C8B; C; 10CCB; # OLD HUNGARIAN CAPITAL LETTER EE +10C8C; C; 10CCC; # OLD HUNGARIAN CAPITAL LETTER EF +10C8D; C; 10CCD; # OLD HUNGARIAN CAPITAL LETTER EG +10C8E; C; 10CCE; # OLD HUNGARIAN CAPITAL LETTER EGY +10C8F; C; 10CCF; # OLD HUNGARIAN CAPITAL LETTER EH +10C90; C; 10CD0; # OLD HUNGARIAN CAPITAL LETTER I +10C91; C; 10CD1; # OLD HUNGARIAN CAPITAL LETTER II +10C92; C; 10CD2; # OLD HUNGARIAN CAPITAL LETTER EJ +10C93; C; 10CD3; # OLD HUNGARIAN CAPITAL LETTER EK +10C94; C; 10CD4; # OLD HUNGARIAN CAPITAL LETTER AK +10C95; C; 10CD5; # OLD HUNGARIAN CAPITAL LETTER UNK +10C96; C; 10CD6; # OLD HUNGARIAN CAPITAL LETTER EL +10C97; C; 10CD7; # OLD HUNGARIAN CAPITAL LETTER ELY +10C98; C; 10CD8; # OLD HUNGARIAN CAPITAL LETTER EM +10C99; C; 10CD9; # OLD HUNGARIAN CAPITAL LETTER EN +10C9A; C; 10CDA; # OLD HUNGARIAN CAPITAL LETTER ENY +10C9B; C; 10CDB; # OLD HUNGARIAN CAPITAL LETTER O +10C9C; C; 10CDC; # OLD HUNGARIAN CAPITAL LETTER OO +10C9D; C; 10CDD; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE +10C9E; C; 10CDE; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE +10C9F; C; 10CDF; # OLD HUNGARIAN CAPITAL LETTER OEE +10CA0; C; 10CE0; # OLD HUNGARIAN CAPITAL LETTER EP +10CA1; C; 10CE1; # OLD HUNGARIAN CAPITAL LETTER EMP +10CA2; C; 10CE2; # OLD HUNGARIAN CAPITAL LETTER ER +10CA3; C; 10CE3; # OLD HUNGARIAN CAPITAL LETTER SHORT ER +10CA4; C; 10CE4; # OLD HUNGARIAN CAPITAL LETTER ES +10CA5; C; 10CE5; # OLD HUNGARIAN CAPITAL LETTER ESZ +10CA6; C; 10CE6; # OLD HUNGARIAN CAPITAL LETTER ET +10CA7; C; 10CE7; # OLD HUNGARIAN CAPITAL LETTER ENT +10CA8; C; 10CE8; # OLD HUNGARIAN CAPITAL LETTER ETY +10CA9; C; 10CE9; # OLD HUNGARIAN CAPITAL LETTER ECH +10CAA; C; 10CEA; # OLD HUNGARIAN CAPITAL LETTER U +10CAB; C; 10CEB; # OLD HUNGARIAN CAPITAL LETTER UU +10CAC; C; 10CEC; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE +10CAD; C; 10CED; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE +10CAE; C; 10CEE; # OLD HUNGARIAN CAPITAL LETTER EV +10CAF; C; 10CEF; # OLD HUNGARIAN CAPITAL LETTER EZ +10CB0; C; 10CF0; # OLD HUNGARIAN CAPITAL LETTER EZS +10CB1; C; 10CF1; # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN +10CB2; C; 10CF2; # OLD HUNGARIAN CAPITAL LETTER US +118A0; C; 118C0; # WARANG CITI CAPITAL LETTER NGAA +118A1; C; 118C1; # WARANG CITI CAPITAL LETTER A +118A2; C; 118C2; # WARANG CITI CAPITAL LETTER WI +118A3; C; 118C3; # WARANG CITI CAPITAL LETTER YU +118A4; C; 118C4; # WARANG CITI CAPITAL LETTER YA +118A5; C; 118C5; # WARANG CITI CAPITAL LETTER YO +118A6; C; 118C6; # WARANG CITI CAPITAL LETTER II +118A7; C; 118C7; # WARANG CITI CAPITAL LETTER UU +118A8; C; 118C8; # WARANG CITI CAPITAL LETTER E +118A9; C; 118C9; # WARANG CITI CAPITAL LETTER O +118AA; C; 118CA; # WARANG CITI CAPITAL LETTER ANG +118AB; C; 118CB; # WARANG CITI CAPITAL LETTER GA +118AC; C; 118CC; # WARANG CITI CAPITAL LETTER KO +118AD; C; 118CD; # WARANG CITI CAPITAL LETTER ENY +118AE; C; 118CE; # WARANG CITI CAPITAL LETTER YUJ +118AF; C; 118CF; # WARANG CITI CAPITAL LETTER UC +118B0; C; 118D0; # WARANG CITI CAPITAL LETTER ENN +118B1; C; 118D1; # WARANG CITI CAPITAL LETTER ODD +118B2; C; 118D2; # WARANG CITI CAPITAL LETTER TTE +118B3; C; 118D3; # WARANG CITI CAPITAL LETTER NUNG +118B4; C; 118D4; # WARANG CITI CAPITAL LETTER DA +118B5; C; 118D5; # WARANG CITI CAPITAL LETTER AT +118B6; C; 118D6; # WARANG CITI CAPITAL LETTER AM +118B7; C; 118D7; # WARANG CITI CAPITAL LETTER BU +118B8; C; 118D8; # WARANG CITI CAPITAL LETTER PU +118B9; C; 118D9; # WARANG CITI CAPITAL LETTER HIYO +118BA; C; 118DA; # WARANG CITI CAPITAL LETTER HOLO +118BB; C; 118DB; # WARANG CITI CAPITAL LETTER HORR +118BC; C; 118DC; # WARANG CITI CAPITAL LETTER HAR +118BD; C; 118DD; # WARANG CITI CAPITAL LETTER SSUU +118BE; C; 118DE; # WARANG CITI CAPITAL LETTER SII +118BF; C; 118DF; # WARANG CITI CAPITAL LETTER VIYO +16E40; C; 16E60; # MEDEFAIDRIN CAPITAL LETTER M +16E41; C; 16E61; # MEDEFAIDRIN CAPITAL LETTER S +16E42; C; 16E62; # MEDEFAIDRIN CAPITAL LETTER V +16E43; C; 16E63; # MEDEFAIDRIN CAPITAL LETTER W +16E44; C; 16E64; # MEDEFAIDRIN CAPITAL LETTER ATIU +16E45; C; 16E65; # MEDEFAIDRIN CAPITAL LETTER Z +16E46; C; 16E66; # MEDEFAIDRIN CAPITAL LETTER KP +16E47; C; 16E67; # MEDEFAIDRIN CAPITAL LETTER P +16E48; C; 16E68; # MEDEFAIDRIN CAPITAL LETTER T +16E49; C; 16E69; # MEDEFAIDRIN CAPITAL LETTER G +16E4A; C; 16E6A; # MEDEFAIDRIN CAPITAL LETTER F +16E4B; C; 16E6B; # MEDEFAIDRIN CAPITAL LETTER I +16E4C; C; 16E6C; # MEDEFAIDRIN CAPITAL LETTER K +16E4D; C; 16E6D; # MEDEFAIDRIN CAPITAL LETTER A +16E4E; C; 16E6E; # MEDEFAIDRIN CAPITAL LETTER J +16E4F; C; 16E6F; # MEDEFAIDRIN CAPITAL LETTER E +16E50; C; 16E70; # MEDEFAIDRIN CAPITAL LETTER B +16E51; C; 16E71; # MEDEFAIDRIN CAPITAL LETTER C +16E52; C; 16E72; # MEDEFAIDRIN CAPITAL LETTER U +16E53; C; 16E73; # MEDEFAIDRIN CAPITAL LETTER YU +16E54; C; 16E74; # MEDEFAIDRIN CAPITAL LETTER L +16E55; C; 16E75; # MEDEFAIDRIN CAPITAL LETTER Q +16E56; C; 16E76; # MEDEFAIDRIN CAPITAL LETTER HP +16E57; C; 16E77; # MEDEFAIDRIN CAPITAL LETTER NY +16E58; C; 16E78; # MEDEFAIDRIN CAPITAL LETTER X +16E59; C; 16E79; # MEDEFAIDRIN CAPITAL LETTER D +16E5A; C; 16E7A; # MEDEFAIDRIN CAPITAL LETTER OE +16E5B; C; 16E7B; # MEDEFAIDRIN CAPITAL LETTER N +16E5C; C; 16E7C; # MEDEFAIDRIN CAPITAL LETTER R +16E5D; C; 16E7D; # MEDEFAIDRIN CAPITAL LETTER O +16E5E; C; 16E7E; # MEDEFAIDRIN CAPITAL LETTER AI +16E5F; C; 16E7F; # MEDEFAIDRIN CAPITAL LETTER Y +1E900; C; 1E922; # ADLAM CAPITAL LETTER ALIF +1E901; C; 1E923; # ADLAM CAPITAL LETTER DAALI +1E902; C; 1E924; # ADLAM CAPITAL LETTER LAAM +1E903; C; 1E925; # ADLAM CAPITAL LETTER MIIM +1E904; C; 1E926; # ADLAM CAPITAL LETTER BA +1E905; C; 1E927; # ADLAM CAPITAL LETTER SINNYIIYHE +1E906; C; 1E928; # ADLAM CAPITAL LETTER PE +1E907; C; 1E929; # ADLAM CAPITAL LETTER BHE +1E908; C; 1E92A; # ADLAM CAPITAL LETTER RA +1E909; C; 1E92B; # ADLAM CAPITAL LETTER E +1E90A; C; 1E92C; # ADLAM CAPITAL LETTER FA +1E90B; C; 1E92D; # ADLAM CAPITAL LETTER I +1E90C; C; 1E92E; # ADLAM CAPITAL LETTER O +1E90D; C; 1E92F; # ADLAM CAPITAL LETTER DHA +1E90E; C; 1E930; # ADLAM CAPITAL LETTER YHE +1E90F; C; 1E931; # ADLAM CAPITAL LETTER WAW +1E910; C; 1E932; # ADLAM CAPITAL LETTER NUN +1E911; C; 1E933; # ADLAM CAPITAL LETTER KAF +1E912; C; 1E934; # ADLAM CAPITAL LETTER YA +1E913; C; 1E935; # ADLAM CAPITAL LETTER U +1E914; C; 1E936; # ADLAM CAPITAL LETTER JIIM +1E915; C; 1E937; # ADLAM CAPITAL LETTER CHI +1E916; C; 1E938; # ADLAM CAPITAL LETTER HA +1E917; C; 1E939; # ADLAM CAPITAL LETTER QAAF +1E918; C; 1E93A; # ADLAM CAPITAL LETTER GA +1E919; C; 1E93B; # ADLAM CAPITAL LETTER NYA +1E91A; C; 1E93C; # ADLAM CAPITAL LETTER TU +1E91B; C; 1E93D; # ADLAM CAPITAL LETTER NHA +1E91C; C; 1E93E; # ADLAM CAPITAL LETTER VA +1E91D; C; 1E93F; # ADLAM CAPITAL LETTER KHA +1E91E; C; 1E940; # ADLAM CAPITAL LETTER GBE +1E91F; C; 1E941; # ADLAM CAPITAL LETTER ZAL +1E920; C; 1E942; # ADLAM CAPITAL LETTER KPO +1E921; C; 1E943; # ADLAM CAPITAL LETTER SHA +# +# EOF diff --git a/claimtrie/normalization/case_folder.go b/claimtrie/normalization/case_folder.go new file mode 100644 index 00000000..0d7e5747 --- /dev/null +++ b/claimtrie/normalization/case_folder.go @@ -0,0 +1,61 @@ +package normalization + +import ( + "bytes" + _ "embed" + "regexp" + "strconv" + "strings" + "unicode/utf8" +) + +//go:embed CaseFolding_v11.txt +var v11 string + +var foldMap map[rune][]rune + +func init() { + foldMap = map[rune][]rune{} + r, _ := regexp.Compile(`([[:xdigit:]]+?); (.); ([[:xdigit:] ]+?);`) + matches := r.FindAllStringSubmatch(v11, 1000000000) + for i := range matches { + if matches[i][2] == "C" || matches[i][2] == "F" { + key, err := strconv.ParseUint(matches[i][1], 16, len(matches[i][1])*4) + if err != nil { + panic(err) + } + splits := strings.Split(matches[i][3], " ") + var values []rune + for j := range splits { + value, err := strconv.ParseUint(splits[j], 16, len(splits[j])*4) + if err != nil { + panic(err) + } + values = append(values, rune(value)) + } + foldMap[rune(key)] = values + } + } +} + +func CaseFold(name []byte) []byte { + var b bytes.Buffer + b.Grow(len(name)) + for i := 0; i < len(name); { + r, w := utf8.DecodeRune(name[i:]) + if r == utf8.RuneError && w < 2 { + // HACK: their RuneError is actually a valid character if coming from a width of 2 or more + return name + } + replacements := foldMap[r] + if len(replacements) > 0 { + for j := range replacements { + b.WriteRune(replacements[j]) + } + } else { + b.WriteRune(r) + } + i += w + } + return b.Bytes() +} diff --git a/claimtrie/normalization/normalizer.go b/claimtrie/normalization/normalizer.go new file mode 100644 index 00000000..55275105 --- /dev/null +++ b/claimtrie/normalization/normalizer.go @@ -0,0 +1,23 @@ +package normalization + +import ( + "github.com/lbryio/lbcd/claimtrie/param" + "golang.org/x/text/unicode/norm" +) + +var Normalize = normalizeGo +var NormalizeTitle = "Normalizing strings via Go. Casefold table version = 11.0.0, NFD version = " + norm.Version + +func NormalizeIfNecessary(name []byte, height int32) []byte { + if height < param.ActiveParams.NormalizedNameForkHeight { + return name + } + return Normalize(name) +} + +func normalizeGo(value []byte) []byte { + + normalized := norm.NFD.Bytes(value) // may need to hard-code the version on this + // not using x/text/cases because it does too good of a job; it seems to use v14 tables even when it claims v13 + return CaseFold(normalized) +} diff --git a/claimtrie/normalization/normalizer_icu.go b/claimtrie/normalization/normalizer_icu.go new file mode 100644 index 00000000..d5093ba2 --- /dev/null +++ b/claimtrie/normalization/normalizer_icu.go @@ -0,0 +1,67 @@ +//go:build use_icu_normalization +// +build use_icu_normalization + +package normalization + +// #cgo CFLAGS: -O2 +// #cgo LDFLAGS: -licuio -licui18n -licuuc -licudata +// #include +// #include +// #include +// int icu_version() { +// UVersionInfo info; +// u_getVersion(info); +// return ((int)(info[0]) << 16) + info[1]; +// } +// int normalize(char* name, int length, char* result) { +// UErrorCode ec = U_ZERO_ERROR; +// static const UNormalizer2* normalizer = NULL; +// if (normalizer == NULL) normalizer = unorm2_getNFDInstance(&ec); +// UChar dest[256]; // maximum claim name size is 255; we won't have more UTF16 chars than bytes +// int dest_len; +// u_strFromUTF8(dest, 256, &dest_len, name, length, &ec); +// if (U_FAILURE(ec) || dest_len == 0) return 0; +// UChar normalized[256]; +// dest_len = unorm2_normalize(normalizer, dest, dest_len, normalized, 256, &ec); +// if (U_FAILURE(ec) || dest_len == 0) return 0; +// dest_len = u_strFoldCase(dest, 256, normalized, dest_len, U_FOLD_CASE_DEFAULT, &ec); +// if (U_FAILURE(ec) || dest_len == 0) return 0; +// u_strToUTF8(result, 512, &dest_len, dest, dest_len, &ec); +// return dest_len; +// } +import "C" +import ( + "fmt" + "unsafe" +) + +func init() { + Normalize = normalizeICU + NormalizeTitle = "Normalizing strings via ICU. ICU version = " + IcuVersion() +} + +func IcuVersion() string { + // TODO: we probably need to explode if it's not 63.2 as it affects consensus + result := C.icu_version() + return fmt.Sprintf("%d.%d", result>>16, result&0xffff) +} + +func normalizeICU(value []byte) []byte { + if len(value) <= 0 { + return value + } + name := (*C.char)(unsafe.Pointer(&value[0])) + length := C.int(len(value)) + + // hopefully this is a stack alloc (but it may be a bit large for that): + var resultName [512]byte // inputs are restricted to 255 chars; it shouldn't expand too much past that + result := unsafe.Pointer(&resultName[0]) + + resultLength := C.normalize(name, length, (*C.char)(result)) + if resultLength == 0 { + return value + } + + // return resultName[0:resultLength] -- we want to shrink the result (not use a slice on 1024) + return C.GoBytes(result, resultLength) +} diff --git a/claimtrie/normalization/normalizer_icu_test.go b/claimtrie/normalization/normalizer_icu_test.go new file mode 100644 index 00000000..b02f315a --- /dev/null +++ b/claimtrie/normalization/normalizer_icu_test.go @@ -0,0 +1,65 @@ +//go:build use_icu_normalization +// +build use_icu_normalization + +package normalization + +import ( + "encoding/hex" + "testing" + "unicode/utf8" + + "github.com/stretchr/testify/assert" +) + +func TestNormalizationICU(t *testing.T) { + testNormalization(t, normalizeICU) +} + +func BenchmarkNormalizeICU(b *testing.B) { + benchmarkNormalize(b, normalizeICU) +} + +var testStrings = []string{ + "Les-Masques-Blancs-Die-Dead-place-Sathonay-28-Août", + "Bez-komentu-výbuch-z-vnútra,-radšej-pozri-video...-", + "၂-နစ်အကြာမှာ", + "ငရဲပြည်မှ-6", + "@happyvision", + "ကမ္ဘာပျက်ကိန်း-9", + "ဝိညာဉ်နား၊-3", + "un-amore-nuovo-o-un-ritorno-cosa-mi-dona", + "è-innamorato-di-me-anche-se-non-lo-dice", + "ပြင်ဆင်ပါ-no.1", + "ပြင်ဆင်ပါ-no.4", + "ပြင်ဆင်ပါ-no.2", + "ပြင်ဆင်ပါ-no.3", + "ငရဲပြည်မှ-5", + "ပြင်ဆင်ပါ-no.6", + "ပြင်ဆင်ပါ-no.5", + "ပြင်ဆင်ပါ-no.7", + "ပြင်ဆင်ပါ-no.8", + "အချိန်-2", + "ဝိညာဉ်နား၊-4", + "ပြင်ဆင်ပါ-no.-13", + "ပြင်ဆင်ပါ-no.15", + "ပြင်ဆင်ပါ-9", + "schilddrüsenhormonsubstitution-nach", + "Linxextremismus-JPzuG_UBtEg", + "Ꮖ-Ꮩ-Ꭺ-N--------Ꭺ-N-Ꮹ-Ꭼ-Ꮮ-Ꭺ-on-Instagram_-“Our-next-destination-is-East-and-Southeast-Asia--selfie--asia”", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", +} + +func TestBlock760150_1020105(t *testing.T) { + test, _ := hex.DecodeString("43efbfbd") + assert.True(t, utf8.Valid(test)) + a := normalizeGo(test) + b := normalizeICU(test) + assert.Equal(t, a, b) + + for i, s := range testStrings { + a = normalizeGo([]byte(s)) + b = normalizeICU([]byte(s)) + assert.Equal(t, a, b, "%d: %s != %s", i, string(a), string(b)) + // t.Logf("%s -> %s", s, string(b)) + } +} diff --git a/claimtrie/normalization/normalizer_test.go b/claimtrie/normalization/normalizer_test.go new file mode 100644 index 00000000..ea43b677 --- /dev/null +++ b/claimtrie/normalization/normalizer_test.go @@ -0,0 +1,54 @@ +package normalization + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNormalizationGo(t *testing.T) { + testNormalization(t, normalizeGo) +} + +func testNormalization(t *testing.T, normalize func(value []byte) []byte) { + + r := require.New(t) + + r.Equal("test", string(normalize([]byte("TESt")))) + r.Equal("test 23", string(normalize([]byte("tesT 23")))) + r.Equal("\xFF", string(normalize([]byte("\xFF")))) + r.Equal("\xC3\x28", string(normalize([]byte("\xC3\x28")))) + r.Equal("\xCF\x89", string(normalize([]byte("\xE2\x84\xA6")))) + r.Equal("\xD1\x84", string(normalize([]byte("\xD0\xA4")))) + r.Equal("\xD5\xA2", string(normalize([]byte("\xD4\xB2")))) + r.Equal("\xE3\x81\xB5\xE3\x82\x99", string(normalize([]byte("\xE3\x81\xB6")))) + r.Equal("\xE1\x84\x81\xE1\x85\xAA\xE1\x86\xB0", string(normalize([]byte("\xEA\xBD\x91")))) +} + +func randSeq(n int) []byte { + var alphabet = []rune("abcdefghijklmnopqrstuvwxyz̃ABCDEFGHIJKLMNOPQRSTUVWXYZ̃") + + b := make([]rune, n) + for i := range b { + b[i] = alphabet[rand.Intn(len(alphabet))] + } + return []byte(string(b)) +} + +func BenchmarkNormalize(b *testing.B) { + benchmarkNormalize(b, normalizeGo) +} + +func benchmarkNormalize(b *testing.B, normalize func(value []byte) []byte) { + rand.Seed(42) + strings := make([][]byte, b.N) + for i := 0; i < b.N; i++ { + strings[i] = randSeq(32) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + s := normalize(strings[i]) + require.True(b, len(s) >= 8) + } +} diff --git a/claimtrie/param/delays.go b/claimtrie/param/delays.go new file mode 100644 index 00000000..d310877f --- /dev/null +++ b/claimtrie/param/delays.go @@ -0,0 +1,285 @@ +package param + +var DelayWorkarounds = generateDelayWorkarounds() // called "removal workarounds" in previous versions + +func generateDelayWorkarounds() map[string][]int32 { + return map[string][]int32{ + "travtest01": {426898}, + "gauntlet-invade-the-darkness-lvl-1-of": {583305}, + "fr-let-s-play-software-inc-jay": {588308}, + "fr-motorsport-manager-jay-s-racing": {588308}, + "fr-crusader-kings-2-la-dynastie-6": {588318}, + "fr-jurassic-world-evolution-let-s-play": {588318}, + "calling-tech-support-scammers-live-3": {588683, 646584}, + "let-s-play-jackbox-games": {589013}, + "lets-play-jackbox-games-5": {589013}, + "kabutothesnake-s-live-ps4-broadcast": {589538}, + "no-eas-strong-thunderstorm-advisory": {589554}, + "geometry-dash-level-requests": {589564}, + "geometry-dash-level-requests-2": {589564}, + "star-ocean-integrity-and-faithlessness": {589609}, + "@pop": {589613}, + "ullash": {589630}, + "today-s-professionals-2018-winter-3": {589640}, + "today-s-professionals-2018-winter-4": {589640}, + "today-s-professionals-2018-winter-10": {589641}, + "today-s-professionals-big-brother-6-13": {589641}, + "today-s-professionals-big-brother-6-14": {589641}, + "today-s-professionals-big-brother-6-26": {589641}, + "today-s-professionals-big-brother-6-27": {589641}, + "today-s-professionals-big-brother-6-28": {589641}, + "today-s-professionals-big-brother-6-29": {589641}, + "dark-souls-iii": {589697}, + "bobby-blades": {589760}, + "adrian": {589803}, + "roblox-2": {589803, 597925}, + "roblox-4": {589803}, + "roblox-5": {589803}, + "roblox-6": {589803}, + "roblox-7": {589803}, + "roblox-8": {589803}, + "madden-17": {589809}, + "madden-18-franchise": {589810}, + "fifa-14-android-astrodude44-vs": {589831}, + "gaming-with-silverwolf-live-stream-3": {589849}, + "gaming-with-silverwolf-live-stream-4": {589849}, + "gaming-with-silverwolf-live-stream-5": {589849}, + "gaming-with-silverwolf-videos-live": {589849}, + "gaming-with-silverwolf-live-stream-6": {589851}, + "live-q-a": {589851}, + "classic-sonic-games": {589870}, + "gta": {589926}, + "j-dog7973-s-fortnite-squad": {589926}, + "wow-warlords-of-draenor-horde-side": {589967}, + "minecraft-ps4-hardcore-survival-2-the-5": {589991}, + "happy-new-year-2017": {590013}, + "come-chill-with-rekzzey-2": {590020}, + "counter-strike-global-offensive-funny": {590031}, + "father-vs-son-stickfight-stickfight": {590178}, + "little-t-playing-subnautica-livestream": {590178}, + "today-s-professionals-big-brother-7-26-5": {590200}, + "50585be4e3159a7-1": {590206}, + "dark-souls-iii-soul-level-1-challenge": {590223}, + "dark-souls-iii-soul-level-1-challenge-3": {590223}, + "let-s-play-sniper-elite-4-authentic-2": {590225}, + "skyrim-special-edition-ps4-platinum-4": {590225}, + "let-s-play-final-fantasy-the-zodiac-2": {590226}, + "let-s-play-final-fantasy-the-zodiac-3": {590226}, + "ls-h-ppchen-halloween-stream-vom-31-10": {590401}, + "a-new-stream": {590669}, + "danganronpa-v3-killing-harmony-episode": {590708}, + "danganronpa-v3-killing-harmony-episode-4": {590708}, + "danganronpa-v3-killing-harmony-episode-6": {590708}, + "danganronpa-v3-killing-harmony-episode-8": {590708}, + "danganronpa-v3-killing-harmony-episode-9": {590708}, + "call-of-duty-infinite-warfare-gameplay-2": {591982}, + "destiny-the-taken-king-gameplay": {591982}, + "horizon-zero-dawn-100-complete-4": {591983}, + "ghost-recon-wildlands-100-complete-4": {591984}, + "nier-automata-100-complete-gameplay-25": {591985}, + "frustrert": {592291}, + "call-of-duty-black-ops-3-multiplayer": {593504}, + "rayman-legends-challenges-app-the": {593551}, + "super-mario-sunshine-3-player-race-2": {593552}, + "some-new-stuff-might-play-a-game": {593698}, + "memory-techniques-1-000-people-system": {595537}, + "propresenter-6-tutorials-new-features-4": {595559}, + "rocket-league-live": {595559}, + "fortnite-battle-royale": {595818}, + "fortnite-battle-royale-2": {595818}, + "ohare12345-s-live-ps4-broadcast": {595818}, + "super-smash-bros-u-home-run-contest-13": {595838}, + "super-smash-bros-u-home-run-contest-15": {595838}, + "super-smash-bros-u-home-run-contest-2": {595838, 595844}, + "super-smash-bros-u-home-run-contest-22": {595838, 595845}, + "super-smash-bros-u-multi-man-smash-3": {595838}, + "minecraft-survival-biedronka-i-czarny-2": {596828}, + "gramy-minecraft-jasmc-pl": {596829}, + "farcry-5-gameplay": {595818}, + "my-channel-trailer": {595818}, + "full-song-production-tutorial-aeternum": {596934}, + "blackboxglobalreview-hd": {597091}, + "tom-clancy-s-rainbow-six-siege": {597633}, + "5-new-technology-innovations-in-5": {597635}, + "5-new-technology-innovations-in-5-2": {597635}, + "how-to-play-nothing-else-matters-on": {597637}, + "rb6": {597639}, + "borderlands-2-tiny-tina-s-assault-on": {597658}, + "let-s-play-borderlands-the-pre-sequel": {597658}, + "caveman-world-mountains-of-unga-boonga": {597660}, + "for-honor-ps4-2": {597706}, + "fortnite-episode-1": {597728}, + "300-subscribers": {597750}, + "viscera-cleanup-detail-santa-s-rampage": {597755}, + "infinite-voxel-terrain-in-unity-update": {597777}, + "let-s-play-pok-mon-light-platinum": {597783}, + "video-2": {597785}, + "video-8": {597785}, + "finally": {597793}, + "let-s-play-mario-party-luigi-s-engine": {597796}, + "my-edited-video": {597799}, + "we-need-to-talk": {597800}, + "tf2-stream-2": {597811}, + "royal-thumble-tuesday-night-thumbdown": {597814}, + "beat-it-michael-jackson-cover": {597815}, + "black-ops-3": {597816}, + "call-of-duty-black-ops-3-campaign": {597819}, + "skyrim-special-edition-silent-2": {597822}, + "the-chainsmokers-everybody-hates-me": {597823}, + "experiment-glowing-1000-degree-knife-vs": {597824}, + "l1011widebody-friends-let-s-play-2": {597824}, + "call-of-duty-black-ops-4": {597825}, + "let-s-play-fallout-2-restoration-3": {597825}, + "let-s-play-fallout-2-restoration-19": {597826}, + "let-s-play-fallout-2-restoration-27": {597826}, + "2015": {597828}, + "payeer": {597829}, + "youtube-3": {597829}, + "bitcoin-5": {597830}, + "2016": {597831}, + "bitcoin-2": {597831}, + "dreamtowards": {597831}, + "surfearner": {597831}, + "100-000": {597832}, + "20000": {597833}, + "remme": {597833}, + "hycon": {597834}, + "robocraft": {597834}, + "saturday-night-baseball-with-37": {597834}, + "let-s-play-command-conquer-red-alert-9": {597835}, + "15-curiosidades-que-probablemente-ya": {597837}, + "elder-scrolls-online-road-to-level-20": {597893}, + "playerunknown-s-battlegrounds": {597894}, + "black-ops-3-fun": {597897}, + "mortal-kombat-xl-the-funniest": {597899}, + "try-not-to-laugh-2": {597899}, + "call-of-duty-advanced-warfare-domination": {597898}, + "my-live-stream-with-du-recorder-5": {597900}, + "ls-h-ppchen-halloween-stream-vom-31-10-2": {597904}, + "ls-h-ppchen-halloween-stream-vom-31-10-3": {597904}, + "how-it-feels-to-chew-5-gum-funny-8": {597905}, + "live-stream-mu-club-america-3": {597918}, + "black-death": {597927}, + "lets-play-spore-with-3": {597929}, + "true-mov-2": {597933}, + "fortnite-w-pat-the-rat-pat-the-rat": {597935}, + "jugando-pokemon-esmeralda-gba": {597935}, + "talking-about-my-channel-and-much-more-4": {597936}, + "-14": {597939}, + "-15": {597939}, + "-16": {597939}, + "-17": {597939}, + "-18": {597939}, + "-20": {597939}, + "-21": {597939}, + "-24": {597939}, + "-25": {597939}, + "-26": {597939}, + "-27": {597939}, + "-28": {597939}, + "-29": {597939}, + "-31": {597941}, + "-34": {597941}, + "-6": {597939}, + "-7": {597939}, + "10-4": {612097}, + "10-6": {612097}, + "10-7": {612097}, + "10-diy": {612097}, + "10-twitch": {612097}, + "100-5": {597909}, + "189f2f04a378c02-1": {612097}, + "2011-2": {597917}, + "2011-3": {597917}, + "2c61c818687ed09-1": {612097}, + "5-diy-4": {612097}, + "@andymcdandycdn": {640212}, + "@lividjava": {651654}, + "@mhx": {653957}, + "@tipwhatyoulike": {599792}, + "@wibbels": {612195}, + "@yisraeldov": {647416}, + "beyaz-hap-biseks-el-evlat": {657957}, + "bilgisayar-al-t-rma-s-recinde-ya-ananlar": {657957}, + "brave-como-ganhar-dinheiro-todos-os-dias": {598494}, + "c81e728d9d4c2f6-1": {598178}, + "call-of-duty-world-war-2": {597935}, + "chain-reaction": {597940}, + "commodore-64-an-lar-ve-oyunlar": {657957}, + "counter-strike-global-offensive-gameplay": {597900}, + "dead-island-riptide-co-op-walkthrough-2": {597904, 598105}, + "diy-10": {612097}, + "diy-11": {612097}, + "diy-13": {612097}, + "diy-14": {612097}, + "diy-19": {612097}, + "diy-4": {612097}, + "diy-6": {612097}, + "diy-7": {612097}, + "diy-9": {612097}, + "doktor-ve-patron-sahnesinin-haz-rl-k-ve": {657957}, + "eat-the-street": {597910}, + "fallout-4-modded": {597901}, + "fallout-4-walkthrough": {597900}, + "filmli-efecast-129-film-inde-film-inde": {657957}, + "filmli-efecast-130-ger-ek-hayatta-anime": {657957}, + "filmli-efecast-97-netflix-filmi-form-l": {657957}, + "for-honor-2": {597932}, + "for-honor-4": {597932}, + "gta-5": {597902}, + "gta-5-2": {597902}, + "helldriver-g-n-n-ekstrem-filmi": {657957}, + "hi-4": {597933}, + "hi-5": {597933}, + "hi-7": {597933}, + "kizoa-movie-video-slideshow-maker": {597900, 597932}, + "l1011widebody-friends-let-s-play-3": {598070}, + "lbry": {608276}, + "lets-play-spore-with": {597930}, + "madants": {625032}, + "mechwarrior-2-soundtrack-clan-jade": {598070}, + "milo-forbidden-conversation": {655173}, + "mobile-record": {597910}, + "mouths": {607379}, + "mp-aleyna-tilki-nin-zorla-seyrettirilen": {657957}, + "mp-atat-rk-e-eytan-diyen-yunan-as-ll": {657957}, + "mp-bah-eli-calan-avukatlar-yla-g-r-s-n": {657957}, + "mp-bu-podcast-babalar-in": {657957}, + "mp-bu-podcasti-akp-li-tan-d-klar-n-za": {657957}, + "mp-gaziantep-te-tacizle-su-lan-p-dayak": {650409}, + "mp-hatipo-lu-nun-ermeni-bir-ocu-u-canl": {657957}, + "mp-k-rt-annelerin-hdp-ye-tepkisi": {657957}, + "mp-kenan-sofuo-lu-nun-mamo-lu-na-destek": {657957}, + "mp-mamo-lu-nun-muhafazakar-g-r-nmesi": {657957}, + "mp-mhp-akp-gerginli-i": {657957}, + "mp-otob-ste-t-rkle-meyin-diye-ba-ran-svi": {657957}, + "mp-pace-i-kazand-m-diyip-21-bin-dolar": {657957}, + "mp-rusya-da-kad-nlara-tecav-zc-s-n-ld": {657957}, + "mp-s-n-rs-z-nafakan-n-kalkmas-adil-mi": {657957}, + "mp-susamam-ark-s-ve-serkan-nci-nin-ark": {657957}, + "mp-y-lmaz-zdil-in-kitap-paralar-yla-yard": {657957}, + "mp-yang-n-u-aklar-pahal-diyen-orman": {657957}, + "mp-yeni-zelanda-katliam-ndan-siyasi-rant": {657957}, + "my-edited-video-4": {597932}, + "my-live-stream-with-du-recorder": {597900}, + "my-live-stream-with-du-recorder-3": {597900}, + "new-channel-intro": {598235}, + "paladins-3": {597900}, + "popstar-sahnesi-kamera-arkas-g-r-nt-leri": {657957}, + "retro-bilgisayar-bulu-mas": {657957}, + "scp-t-rk-e-scp-002-canl-oda": {657957}, + "steep": {597900}, + "stephen-hicks-postmodernism-reprise": {655173}, + "super-smash-bros-u-brawl-co-op-event": {595841}, + "super-smash-bros-u-super-mario-u-smash": {595839}, + "super-smash-bros-u-zelda-smash-series": {595841}, + "superonline-fiber-den-efsane-kaz-k-yedim": {657957}, + "talking-about-my-channel-and-much-more-5": {597936}, + "test1337reflector356": {627814}, + "the-last-of-us-remastered-2": {597915}, + "tom-clancy-s-ghost-recon-wildlands-2": {597916}, + "tom-clancy-s-rainbow-six-siege-3": {597935}, + "wwe-2k18-with-that-guy-and-tricky": {597901}, + "yay-nc-bob-afet-kamera-arkas": {657957}, + } +} diff --git a/claimtrie/param/general.go b/claimtrie/param/general.go new file mode 100644 index 00000000..92ff06fe --- /dev/null +++ b/claimtrie/param/general.go @@ -0,0 +1,74 @@ +package param + +import "github.com/lbryio/lbcd/wire" + +type ClaimTrieParams struct { + MaxActiveDelay int32 + ActiveDelayFactor int32 + + MaxNodeManagerCacheSize int + + OriginalClaimExpirationTime int32 + ExtendedClaimExpirationTime int32 + ExtendedClaimExpirationForkHeight int32 + + MaxRemovalWorkaroundHeight int32 + + NormalizedNameForkHeight int32 + AllClaimsInMerkleForkHeight int32 +} + +var ( + ActiveParams = MainNet + + MainNet = ClaimTrieParams{ + MaxActiveDelay: 4032, + ActiveDelayFactor: 32, + MaxNodeManagerCacheSize: 32000, + + OriginalClaimExpirationTime: 262974, + ExtendedClaimExpirationTime: 2102400, + ExtendedClaimExpirationForkHeight: 400155, // https://lbry.io/news/hf1807 + MaxRemovalWorkaroundHeight: 658300, + NormalizedNameForkHeight: 539940, // targeting 21 March 2019}, https://lbry.com/news/hf1903 + AllClaimsInMerkleForkHeight: 658309, // targeting 30 Oct 2019}, https://lbry.com/news/hf1910 + } + + TestNet = ClaimTrieParams{ + MaxActiveDelay: 4032, + ActiveDelayFactor: 32, + MaxNodeManagerCacheSize: 32000, + + OriginalClaimExpirationTime: 262974, + ExtendedClaimExpirationTime: 2102400, + ExtendedClaimExpirationForkHeight: 278160, + MaxRemovalWorkaroundHeight: 1, // if you get a hash mismatch, come back to this + NormalizedNameForkHeight: 993380, + AllClaimsInMerkleForkHeight: 1198559, + } + + Regtest = ClaimTrieParams{ + MaxActiveDelay: 4032, + ActiveDelayFactor: 32, + MaxNodeManagerCacheSize: 32000, + + OriginalClaimExpirationTime: 500, + ExtendedClaimExpirationTime: 600, + ExtendedClaimExpirationForkHeight: 800, + MaxRemovalWorkaroundHeight: -1, + NormalizedNameForkHeight: 250, + AllClaimsInMerkleForkHeight: 349, + } +) + +func SetNetwork(net wire.BitcoinNet) { + + switch net { + case wire.MainNet: + ActiveParams = MainNet + case wire.TestNet3: + ActiveParams = TestNet + case wire.TestNet, wire.SimNet: // "regtest" + ActiveParams = Regtest + } +} diff --git a/claimtrie/param/takeovers.go b/claimtrie/param/takeovers.go new file mode 100644 index 00000000..7ba125ac --- /dev/null +++ b/claimtrie/param/takeovers.go @@ -0,0 +1,451 @@ +package param + +var TakeoverWorkarounds = generateTakeoverWorkarounds() + +func generateTakeoverWorkarounds() map[string]int { // TODO: the values here are unused; bools would probably be better + return map[string]int{ + "496856_HunterxHunterAMV": 496835, + "542978_namethattune1": 542429, + "543508_namethattune-5": 543306, + "546780_forecasts": 546624, + "548730_forecasts": 546780, + "551540_forecasts": 548730, + "552380_chicthinkingofyou": 550804, + "560363_takephotowithlbryteam": 559962, + "563710_test-img": 563700, + "566750_itila": 543261, + "567082_malabarismo-com-bolas-de-futebol-vs-chap": 563592, + "596860_180mphpullsthrougheurope": 596757, + "617743_vaccines": 572756, + "619609_copface-slamshandcuffedteengirlintoconcrete": 539940, + "620392_banker-exposes-satanic-elite": 597788, + "624997_direttiva-sulle-armi-ue-in-svizzera-di": 567908, + "624997_best-of-apex": 585580, + "629970_cannot-ignore-my-veins": 629914, + "633058_bio-waste-we-programmed-your-brain": 617185, + "633601_macrolauncher-overview-first-look": 633058, + "640186_its-up-to-you-and-i-2019": 639116, + "640241_tor-eas-3-20": 592645, + "640522_seadoxdark": 619531, + "640617_lbry-przewodnik-1-instalacja": 451186, + "640623_avxchange-2019-the-next-netflix-spotify": 606790, + "640684_algebra-introduction": 624152, + "640684_a-high-school-math-teacher-does-a": 600885, + "640684_another-random-life-update": 600884, + "640684_who-is-the-taylor-series-for": 600882, + "640684_tedx-talk-released": 612303, + "640730_e-mental": 615375, + "641143_amiga-1200-bespoke-virgin-cinema": 623542, + "641161_dreamscape-432-omega": 618894, + "641162_2019-topstone-carbon-force-etap-axs-bike": 639107, + "641186_arin-sings-big-floppy-penis-live-jazz-2": 638904, + "641421_edward-snowden-on-bitcoin-and-privacy": 522729, + "641421_what-is-libra-facebook-s-new": 598236, + "641421_what-are-stablecoins-counter-party-risk": 583508, + "641421_anthony-pomp-pompliano-discusses-crypto": 564416, + "641421_tim-draper-crypto-invest-summit-2019": 550329, + "641421_mass-adoption-and-what-will-it-take-to": 549781, + "641421_dragonwolftech-youtube-channel-trailer": 567128, + "641421_naomi-brockwell-s-weekly-crypto-recap": 540006, + "641421_blockchain-based-youtube-twitter": 580809, + "641421_andreas-antonopoulos-on-privacy-privacy": 533522, + "641817_mexico-submits-and-big-tech-worsens": 582977, + "641817_why-we-need-travel-bans": 581354, + "641880_censored-by-patreon-bitchute-shares": 482460, + "641880_crypto-wonderland": 485218, + "642168_1-diabolo-julio-cezar-16-cbmcp-freestyle": 374999, + "642314_tough-students": 615780, + "642697_gamercauldronep2": 642153, + "643406_the-most-fun-i-ve-had-in-a-long-time": 616506, + "643893_spitshine69-and-uk-freedom-audits": 616876, + "644480_my-mum-getting-attacked-a-duck": 567624, + "644486_the-cryptocurrency-experiment": 569189, + "644486_tag-you-re-it": 558316, + "644486_orange-county-mineral-society-rock-and": 397138, + "644486_sampling-with-the-gold-rush-nugget": 527960, + "644562_september-15-21-a-new-way-of-doing": 634792, + "644562_july-week-3-collective-frequency-general": 607942, + "644562_september-8-14-growing-up-general": 630977, + "644562_august-4-10-collective-frequency-general": 612307, + "644562_august-11-17-collective-frequency": 617279, + "644562_september-1-7-gentle-wake-up-call": 627104, + "644607_no-more-lol": 643497, + "644607_minion-masters-who-knew": 641313, + "645236_danganronpa-3-the-end-of-hope-s-peak": 644153, + "645348_captchabot-a-discord-bot-to-protect-your": 592810, + "645701_the-xero-hour-saint-greta-of-thunberg": 644081, + "645701_batman-v-superman-theological-notions": 590189, + "645918_emacs-is-great-ep-0-init-el-from-org": 575666, + "645918_emacs-is-great-ep-1-packages": 575666, + "645918_emacs-is-great-ep-40-pt-2-hebrew": 575668, + "645923_nasal-snuff-review-osp-batch-2": 575658, + "645923_why-bit-coin": 575658, + "645929_begin-quest": 598822, + "645929_filthy-foe": 588386, + "645929_unsanitary-snow": 588386, + "645929_famispam-1-music-box": 588386, + "645929_running-away": 598822, + "645931_my-beloved-chris-madsen": 589114, + "645931_space-is-consciousness-chris-madsen": 589116, + "645947_gasifier-rocket-stove-secondary-burn": 590595, + "645949_mouse-razer-abyssus-v2-e-mousepad": 591139, + "645949_pr-temporada-2018-league-of-legends": 591138, + "645949_windows-10-build-9901-pt-br": 591137, + "645949_abrindo-pacotes-do-festival-lunar-2018": 591139, + "645949_unboxing-camisetas-personalizadas-play-e": 591138, + "645949_abrindo-envelopes-do-festival-lunar-2017": 591138, + "645951_grub-my-grub-played-guruku-tersayang": 618033, + "645951_ismeeltimepiece": 618038, + "645951_thoughts-on-doom": 596485, + "645951_thoughts-on-god-of-war-about-as-deep-as": 596485, + "645956_linux-lite-3-6-see-what-s-new": 645195, + "646191_kahlil-gibran-the-prophet-part-1": 597637, + "646551_crypto-market-crash-should-you-sell-your": 442613, + "646551_live-crypto-trading-and-market-analysis": 442615, + "646551_5-reasons-trading-is-always-better-than": 500850, + "646551_digitex-futures-dump-panic-selling-or": 568065, + "646552_how-to-install-polarr-on-kali-linux-bynp": 466235, + "646586_electoral-college-kids-civics-lesson": 430818, + "646602_grapes-full-90-minute-watercolour": 537108, + "646602_meizu-mx4-the-second-ubuntu-phone": 537109, + "646609_how-to-set-up-the-ledger-nano-x": 569992, + "646609_how-to-buy-ethereum": 482354, + "646609_how-to-install-setup-the-exodus-multi": 482356, + "646609_how-to-manage-your-passwords-using": 531987, + "646609_cryptodad-s-live-q-a-friday-may-3rd-2019": 562303, + "646638_resident-evil-ada-chapter-5-final": 605612, + "646639_taurus-june-2019-career-love-tarot": 586910, + "646652_digital-bullpen-ep-5-building-a-digital": 589274, + "646661_sunlight": 591076, + "646661_grasp-lab-nasa-open-mct-series": 589414, + "646663_bunnula-s-creepers-tim-pool-s-beanie-a": 599669, + "646663_bunnula-music-hey-ya-by-outkast": 605685, + "646663_bunnula-tv-s-music-television-eunoia": 644437, + "646663_the-pussy-centipede-40-sneakers-and": 587265, + "646663_bunnula-reacts-ashton-titty-whitty": 596988, + "646677_filip-reviews-jeromes-dream-cataracts-so": 589751, + "646691_fascism-and-its-mobilizing-passions": 464342, + "646692_hsb-color-layers-action-for-adobe": 586533, + "646692_master-colorist-action-pack-extracting": 631830, + "646693_how-to-protect-your-garden-from-animals": 588476, + "646693_gardening-for-the-apocalypse-epic": 588472, + "646693_my-first-bee-hive-foundationless-natural": 588469, + "646693_dragon-fruit-and-passion-fruit-planting": 588470, + "646693_installing-my-first-foundationless": 588469, + "646705_first-naza-fpv": 590411, + "646717_first-burning-man-2019-detour-034": 630247, + "646717_why-bob-marley-was-an-idiot-test-driving": 477558, + "646717_we-are-addicted-to-gambling-ufc-207-w": 481398, + "646717_ghetto-swap-meet-selling-storage-lockers": 498291, + "646738_1-kings-chapter-7-summary-and-what-god": 586599, + "646814_brand-spanking-new-junior-high-school": 592378, + "646814_lupe-fiasco-freestyle-at-end-of-the-weak": 639535, + "646824_how-to-one-stroke-painting-doodles-mixed": 592404, + "646824_acrylic-pouring-landscape-with-a-tree": 592404, + "646824_how-to-make-a-diy-concrete-paste-planter": 595976, + "646824_how-to-make-a-rustic-sand-planter-sand": 592404, + "646833_3-day-festival-at-the-galilee-lake-and": 592842, + "646833_rainbow-circle-around-the-noon-sun-above": 592842, + "646833_energetic-self-control-demonstration": 623811, + "646833_bees-congregating": 592842, + "646856_formula-offroad-honefoss-sunday-track2": 592872, + "646862_h3video1-dc-vs-mb-1": 593237, + "646862_h3video1-iwasgoingto-load-up-gmod-but": 593237, + "646883_watch-this-game-developer-make-a-video": 592593, + "646883_how-to-write-secure-javascript": 592593, + "646883_blockchain-technology-explained-2-hour": 592593, + "646888_fl-studio-bits": 608155, + "646914_andy-s-shed-live-s03e02-the-longest": 592200, + "646914_gpo-telephone-776-phone-restoration": 592201, + "646916_toxic-studios-co-stream-pubg": 597126, + "646916_hyperlapse-of-prague-praha-from-inside": 597109, + "646933_videobits-1": 597378, + "646933_clouds-developing-daytime-8": 597378, + "646933_slechtvalk-in-watertoren-bodegraven": 597378, + "646933_timelapse-maansverduistering-16-juli": 605880, + "646933_startrails-27": 597378, + "646933_passing-clouds-daytime-3": 597378, + "646940_nerdgasm-unboxing-massive-playing-cards": 597421, + "646946_debunking-cops-volume-3-the-murder-of": 630570, + "646961_kingsong-ks16x-electric-unicycle-250km": 636725, + "646968_wild-mountain-goats-amazing-rock": 621940, + "646968_no-shelter-backcountry-camping-in": 621940, + "646968_can-i-live-in-this-through-winter-lets": 645750, + "646968_why-i-wear-a-chest-rig-backcountry-or": 621940, + "646989_marc-ivan-o-gorman-promo-producer-editor": 645656, + "647045_@moraltis": 646367, + "647045_moraltis-twitch-highlights-first-edit": 646368, + "647075_the-3-massive-tinder-convo-mistakes": 629464, + "647075_how-to-get-friend-zoned-via-text": 592298, + "647075_don-t-do-this-on-tinder": 624591, + "647322_world-of-tanks-7-kills": 609905, + "647322_the-tier-6-auto-loading-swedish-meatball": 591338, + "647416_hypnotic-soundscapes-garden-of-the": 596923, + "647416_hypnotic-soundscapes-the-cauldron-sacred": 596928, + "647416_schumann-resonance-to-theta-sweep": 596920, + "647416_conversational-indirect-hypnosis-why": 596913, + "647493_mimirs-brunnr": 590498, + "648143_live-ita-completiamo-the-evil-within-2": 646568, + "648203_why-we-love-people-that-hurt-us": 591128, + "648203_i-didn-t-like-my-baby-and-considered": 591128, + "648220_trade-talk-001-i-m-a-vlogger-now-fielder": 597303, + "648220_vise-restoration-record-no-6-vise": 597303, + "648540_amv-reign": 571863, + "648540_amv-virus": 571863, + "648588_audial-drift-(a-journey-into-sound)": 630217, + "648616_quick-zbrush-tip-transpose-master-scale": 463205, + "648616_how-to-create-3d-horns-maya-to-zbrush-2": 463205, + "648815_arduino-based-cartridge-game-handheld": 593252, + "648815_a-maze-update-3-new-game-modes-amazing": 593252, + "649209_denmark-trip": 591428, + "649209_stunning-4k-drone-footage": 591428, + "649215_how-to-create-a-channel-and-publish-a": 414908, + "649215_lbryclass-11-how-to-get-your-deposit": 632420, + "649543_spring-break-madness-at-universal": 599698, + "649921_navegador-brave-navegador-da-web-seguro": 649261, + "650191_stream-intro": 591301, + "650946_platelet-chan-fan-art": 584601, + "650946_aqua-fanart": 584601, + "650946_virginmedia-stores-password-in-plain": 619537, + "650946_running-linux-on-android-teaser": 604441, + "650946_hatsune-miku-ievan-polka": 600126, + "650946_digital-security-and-privacy-2-and-a-new": 600135, + "650993_my-editorial-comment-on-recent-youtube": 590305, + "650993_drive-7-18-2018": 590305, + "651011_old-world-put-on-realm-realms-gg": 591899, + "651011_make-your-own-soundboard-with-autohotkey": 591899, + "651011_ark-survival-https-discord-gg-ad26xa": 637680, + "651011_minecraft-featuring-seus-8-just-came-4": 596488, + "651057_found-footage-bikinis-at-the-beach-with": 593586, + "651057_found-footage-sexy-mom-a-mink-stole": 593586, + "651067_who-are-the-gentiles-gomer": 597094, + "651067_take-back-the-kingdom-ep-2-450-million": 597094, + "651067_mmxtac-implemented-footstep-sounds-and": 597094, + "651067_dynasoul-s-blender-to-unreal-animated": 597094, + "651103_calling-a-scammer-syntax-error": 612532, + "651103_quick-highlight-of-my-day": 647651, + "651103_calling-scammers-and-singing-christmas": 612531, + "651109_@livingtzm": 637322, + "651109_living-tzm-juuso-from-finland-september": 643412, + "651373_se-voc-rir-ou-sorrir-reinicie-o-v-deo": 649302, + "651476_what-is-pagan-online-polished-new-arpg": 592157, + "651476_must-have-elder-scrolls-online-addons": 592156, + "651476_who-should-play-albion-online": 592156, + "651730_person-detection-with-keras-tensorflow": 621276, + "651730_youtube-censorship-take-two": 587249, + "651730_new-red-tail-shark-and-two-silver-sharks": 587251, + "651730_around-auckland": 587250, + "651730_humanism-in-islam": 587250, + "651730_tigers-at-auckland-zoo": 587250, + "651730_gravity-demonstration": 587250, + "651730_copyright-question": 587249, + "651730_uberg33k-the-ultimate-software-developer": 599522, + "651730_chl-e-swarbrick-auckland-mayoral": 587250, + "651730_code-reviews": 587249, + "651730_raising-robots": 587251, + "651730_teaching-python": 587250, + "651730_kelly-tarlton-2016": 587250, + "652172_where-is-everything": 589491, + "652172_some-guy-and-his-camera": 617062, + "652172_practical-information-pt-1": 589491, + "652172_latent-vibrations": 589491, + "652172_maldek-compilation": 589491, + "652444_thank-you-etika-thank-you-desmond": 652121, + "652611_plants-vs-zombies-gw2-20190827183609": 624339, + "652611_wolfenstein-the-new-order-playthrough-6": 650299, + "652887_a-codeigniter-cms-open-source-download": 652737, + "652966_@pokesadventures": 632391, + "653009_flat-earth-uk-convention-is-a-bust": 585786, + "653009_flat-earth-reset-flat-earth-money-tree": 585786, + "653011_veil-of-thorns-dispirit-brutal-leech-3": 652475, + "653069_being-born-after-9-11": 632218, + "653069_8-years-on-youtube-what-it-has-done-for": 637130, + "653069_answering-questions-how-original": 521447, + "653069_talking-about-my-first-comedy-stand-up": 583450, + "653069_doing-push-ups-in-public": 650920, + "653069_vlog-extra": 465997, + "653069_crying-myself": 465997, + "653069_xbox-rejection": 465992, + "653354_msps-how-to-find-a-linux-job-where-no": 642537, + "653354_windows-is-better-than-linux-vlog-it-and": 646306, + "653354_luke-smith-is-wrong-about-everything": 507717, + "653354_advice-for-those-starting-out-in-tech": 612452, + "653354_treating-yourself-to-make-studying-more": 623561, + "653354_lpi-linux-essential-dns-tools-vlog-what": 559464, + "653354_is-learning-linux-worth-it-in-2019-vlog": 570886, + "653354_huawei-linux-and-cellphones-in-2019-vlog": 578501, + "653354_how-to-use-webmin-to-manage-linux": 511507, + "653354_latency-concurrency-and-the-best-value": 596857, + "653354_how-to-use-the-pomodoro-method-in-it": 506632, + "653354_negotiating-compensation-vlog-it-and": 542317, + "653354_procedural-goals-vs-outcome-goals-vlog": 626785, + "653354_intro-to-raid-understanding-how-raid": 529341, + "653354_smokeping": 574693, + "653354_richard-stallman-should-not-be-fired": 634928, + "653354_unusual-or-specialty-certifications-vlog": 620146, + "653354_gratitude-and-small-projects-vlog-it": 564900, + "653354_why-linux-on-the-smartphone-is-important": 649543, + "653354_opportunity-costs-vlog-it-devops-career": 549708, + "653354_double-giveaway-lpi-class-dates-and": 608129, + "653354_linux-on-the-smartphone-in-2019-librem": 530426, + "653524_celtic-folk-music-full-live-concert-mps": 589762, + "653745_aftermath-of-the-mac": 592768, + "653745_b-c-a-glock-17-threaded-barrel": 592770, + "653800_middle-earth-shadow-of-mordor-by": 590229, + "654079_tomand-jeremy-chirs45": 614296, + "654096_achamos-carteira-com-grana-olha-o-que": 466262, + "654096_viagem-bizarra-e-cansativa-ao-nordeste": 466263, + "654096_tedio-na-tailandia-limpeza-de-area": 466265, + "654425_schau-bung-2014-in-windischgarsten": 654410, + "654425_mitternachtseinlage-ball-rk": 654410, + "654425_zugabe-ball-rk-windischgarsten": 654412, + "654722_skytrain-in-korea": 463145, + "654722_luwak-coffee-the-shit-coffee": 463155, + "654722_puppet-show-in-bangkok-thailand": 462812, + "654722_kyaito-market-myanmar": 462813, + "654724_wipeout-zombies-bo3-custom-zombies-1st": 589569, + "654724_the-street-bo3-custom-zombies": 589544, + "654880_wwii-airsoft-pow": 586968, + "654880_dueling-geese-fight-to-the-death": 586968, + "654880_wwii-airsoft-torgau-raw-footage-part4": 586968, + "655173_april-2019-q-and-a": 554032, + "655173_the-meaning-and-reality-of-individual": 607892, + "655173_steven-pinker-progress-despite": 616984, + "655173_we-make-stories-out-of-totem-poles": 549090, + "655173_jamil-jivani-author-of-why-young-men": 542035, + "655173_commentaries-on-jb-peterson-rebel-wisdom": 528898, + "655173_auckland-clip-4-on-cain-and-abel": 629242, + "655173_peterson-vs-zizek-livestream-tickets": 545285, + "655173_auckland-clip-3-the-dawning-of-the-moral": 621154, + "655173_religious-belief-and-the-enlightenment": 606269, + "655173_auckland-lc-highlight-1-the-presumption": 565783, + "655173_q-a-sir-roger-scruton-dr-jordan-b": 544184, + "655173_cancellation-polish-national-foundation": 562529, + "655173_the-coddling-of-the-american-mind-haidt": 440185, + "655173_02-harris-weinstein-peterson-discussion": 430896, + "655173_jordan-peterson-threatens-everything-of": 519737, + "655173_on-claiming-belief-in-god-commentary": 581738, + "655173_how-to-make-the-world-better-really-with": 482317, + "655173_quillette-discussion-with-founder-editor": 413749, + "655173_jb-peterson-on-free-thought-and-speech": 462849, + "655173_marxism-zizek-peterson-official-video": 578453, + "655173_patreon-problem-solution-dave-rubin-dr": 490394, + "655173_next-week-st-louis-salt-lake-city": 445933, + "655173_conversations-with-john-anderson-jordan": 529981, + "655173_nz-australia-12-rules-tour-next-2-weeks": 518649, + "655173_a-call-to-rebellion-for-ontario-legal": 285451, + "655173_2016-personality-lecture-12": 578465, + "655173_on-the-vital-necessity-of-free-speech": 427404, + "655173_2017-01-23-social-justice-freedom-of": 578465, + "655173_discussion-sam-harris-the-idw-and-the": 423332, + "655173_march-2018-patreon-q-a": 413749, + "655173_take-aim-even-badly": 490395, + "655173_jp-f-wwbgo6a2w": 539940, + "655173_patreon-account-deletion": 503477, + "655173_canada-us-europe-tour-august-dec-2018": 413749, + "655173_leaders-myth-reality-general-stanley": 514333, + "655173_jp-ifi5kkxig3s": 539940, + "655173_documentary-a-glitch-in-the-matrix-david": 413749, + "655173_2017-08-14-patreon-q-and-a": 285451, + "655173_postmodernism-history-and-diagnosis": 285451, + "655173_23-minutes-from-maps-of-meaning-the": 413749, + "655173_milo-forbidden-conversation": 578493, + "655173_jp-wnjbasba-qw": 539940, + "655173_uk-12-rules-tour-october-and-november": 462849, + "655173_2015-maps-of-meaning-10-culture-anomaly": 578465, + "655173_ayaan-hirsi-ali-islam-mecca-vs-medina": 285452, + "655173_jp-f9393el2z1i": 539940, + "655173_campus-indoctrination-the-parasitization": 285453, + "655173_jp-owgc63khcl8": 539940, + "655173_the-death-and-resurrection-of-christ-a": 413749, + "655173_01-harris-weinstein-peterson-discussion": 430896, + "655173_enlightenment-now-steven-pinker-jb": 413749, + "655173_the-lindsay-shepherd-affair-update": 413749, + "655173_jp-g3fwumq5k8i": 539940, + "655173_jp-evvs3l-abv4": 539940, + "655173_former-australian-deputy-pm-john": 413750, + "655173_message-to-my-korean-readers-90-seconds": 477424, + "655173_jp--0xbomwjkgm": 539940, + "655173_ben-shapiro-jordan-peterson-and-a-12": 413749, + "655173_jp-91jwsb7zyhw": 539940, + "655173_deconstruction-the-lindsay-shepherd": 299272, + "655173_september-patreon-q-a": 285451, + "655173_jp-2c3m0tt5kce": 539940, + "655173_australia-s-john-anderson-dr-jordan-b": 413749, + "655173_jp-hdrlq7dpiws": 539940, + "655173_stephen-hicks-postmodernism-reprise": 578480, + "655173_october-patreon-q-a": 285451, + "655173_an-animated-intro-to-truth-order-and": 413749, + "655173_jp-bsh37-x5rny": 539940, + "655173_january-2019-q-a": 503477, + "655173_comedians-canaries-and-coalmines": 498586, + "655173_the-democrats-apology-and-promise": 465433, + "655173_jp-s4c-jodptn8": 539940, + "655173_2014-personality-lecture-16-extraversion": 578465, + "655173_dr-jordan-b-peterson-on-femsplainers": 490395, + "655173_higher-ed-our-cultural-inflection-point": 527291, + "655173_archetype-reality-friendship-and": 519736, + "655173_sir-roger-scruton-dr-jordan-b-peterson": 490395, + "655173_jp-cf2nqmqifxc": 539940, + "655173_penguin-uk-12-rules-for-life": 413749, + "655173_march-2019-q-and-a": 537138, + "655173_jp-ne5vbomsqjc": 539940, + "655173_dublin-london-harris-murray-new-usa-12": 413749, + "655173_12-rules-12-cities-tickets-now-available": 413749, + "655173_jp-j9j-bvdrgdi": 539940, + "655173_responsibility-conscience-and-meaning": 499123, + "655173_04-harris-murray-peterson-discussion": 436678, + "655173_jp-ayhaz9k008q": 539940, + "655173_with-jocko-willink-the-catastrophe-of": 490395, + "655173_interview-with-the-grievance-studies": 501296, + "655173_russell-brand-jordan-b-peterson-under": 413750, + "655173_goodbye-to-patreon": 496771, + "655173_revamped-podcast-announcement-with": 540943, + "655173_swedes-want-to-know": 285453, + "655173_auckland-clip-2-the-four-fundamental": 607892, + "655173_jp-dtirzqmgbdm": 539940, + "655173_political-correctness-a-force-for-good-a": 413750, + "655173_sean-plunket-full-interview-new-zealand": 597638, + "655173_q-a-the-meaning-and-reality-of": 616984, + "655173_lecture-and-q-a-with-jordan-peterson-the": 413749, + "655173_2017-personality-07-carl-jung-and-the": 578465, + "655173_nina-paley-animator-extraordinaire": 413750, + "655173_truth-as-the-antidote-to-suffering-with": 455127, + "655173_bishop-barron-word-on-fire": 599814, + "655173_zizek-vs-peterson-april-19": 527291, + "655173_revamped-podcast-with-westwood-one": 540943, + "655173_2016-11-19-university-of-toronto-free": 578465, + "655173_jp-1emrmtrj5jc": 539940, + "655173_who-is-joe-rogan-with-jordan-peterson": 585578, + "655173_who-dares-say-he-believes-in-god": 581738, + "655252_games-with-live2d": 589978, + "655252_kaenbyou-rin-live2d": 589978, + "655374_steam-groups-are-crazy": 607590, + "655379_asmr-captain-falcon-happily-beats-you-up": 644574, + "655379_pixel-art-series-5-link-holding-the": 442952, + "655379_who-can-cross-the-planck-length-the-hero": 610830, + "655379_ssbb-the-yoshi-grab-release-crash": 609747, + "655379_tas-captain-falcon-s-bizarre-adventure": 442958, + "655379_super-smash-bros-in-360-test": 442963, + "655379_what-if-luigi-was-b-u-f-f": 442971, + "655803_sun-time-lapse-test-7": 610634, + "655952_upper-build-complete": 591728, + "656758_cryptocurrency-awareness-adoption-the": 541770, + "656829_3d-printing-technologies-comparison": 462685, + "656829_3d-printing-for-everyone": 462685, + "657052_tni-punya-ilmu-kanuragan-gaya-baru": 657045, + "657052_papa-sunimah-nelpon-sri-utami-emon": 657045, + "657274_rapforlife-4-win": 656856, + "657274_bizzilion-proof-of-withdrawal": 656856, + "657420_quick-drawing-prince-tribute-colored": 605630, + "657453_white-boy-tom-mcdonald-facts": 597169, + "657453_is-it-ok-to-look-when-you-with-your-girl": 610508, + "657584_need-for-speed-ryzen-5-1600-gtx-1050-ti": 657161, + "657584_quantum-break-ryzen-5-1600-gtx-1050-ti-4": 657161, + "657584_nightcore-legends-never-die": 657161, + "657706_mtb-enduro-ferragosto-2019-sestri": 638904, + "657706_warface-free-for-all": 638908, + "657782_nick-warren-at-loveland-but-not-really": 444299, + "658098_le-temps-nous-glisse-entre-les-doigts": 600099, + } +} diff --git a/claimtrie/temporal/repo.go b/claimtrie/temporal/repo.go new file mode 100644 index 00000000..6b2df037 --- /dev/null +++ b/claimtrie/temporal/repo.go @@ -0,0 +1,9 @@ +package temporal + +// Repo defines APIs for Temporal to access persistence layer. +type Repo interface { + SetNodesAt(names [][]byte, heights []int32) error + NodesAt(height int32) ([][]byte, error) + Close() error + Flush() error +} diff --git a/claimtrie/temporal/temporalrepo/memory.go b/claimtrie/temporal/temporalrepo/memory.go new file mode 100644 index 00000000..0c1c8591 --- /dev/null +++ b/claimtrie/temporal/temporalrepo/memory.go @@ -0,0 +1,45 @@ +package temporalrepo + +type Memory struct { + cache map[int32]map[string]bool +} + +func NewMemory() *Memory { + return &Memory{ + cache: map[int32]map[string]bool{}, + } +} + +func (repo *Memory) SetNodesAt(names [][]byte, heights []int32) error { + + for i, height := range heights { + c, ok := repo.cache[height] + if !ok { + c = map[string]bool{} + repo.cache[height] = c + } + name := string(names[i]) + c[name] = true + } + + return nil +} + +func (repo *Memory) NodesAt(height int32) ([][]byte, error) { + + var names [][]byte + + for name := range repo.cache[height] { + names = append(names, []byte(name)) + } + + return names, nil +} + +func (repo *Memory) Close() error { + return nil +} + +func (repo *Memory) Flush() error { + return nil +} diff --git a/claimtrie/temporal/temporalrepo/pebble.go b/claimtrie/temporal/temporalrepo/pebble.go new file mode 100644 index 00000000..f7b083dc --- /dev/null +++ b/claimtrie/temporal/temporalrepo/pebble.go @@ -0,0 +1,87 @@ +package temporalrepo + +import ( + "bytes" + "encoding/binary" + + "github.com/pkg/errors" + + "github.com/cockroachdb/pebble" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + db, err := pebble.Open(path, &pebble.Options{Cache: pebble.NewCache(16 << 20), MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "unable to open %s", path) +} + +func (repo *Pebble) SetNodesAt(name [][]byte, heights []int32) error { + + // key format: height(4B) + 0(1B) + name(varable length) + key := bytes.NewBuffer(nil) + batch := repo.db.NewBatch() + defer batch.Close() + for i, name := range name { + key.Reset() + binary.Write(key, binary.BigEndian, heights[i]) + binary.Write(key, binary.BigEndian, byte(0)) + key.Write(name) + + err := batch.Set(key.Bytes(), nil, pebble.NoSync) + if err != nil { + return errors.Wrap(err, "in set") + } + } + return errors.Wrap(batch.Commit(pebble.NoSync), "in commit") +} + +func (repo *Pebble) NodesAt(height int32) ([][]byte, error) { + + prefix := bytes.NewBuffer(nil) + binary.Write(prefix, binary.BigEndian, height) + binary.Write(prefix, binary.BigEndian, byte(0)) + + end := bytes.NewBuffer(nil) + binary.Write(end, binary.BigEndian, height) + binary.Write(end, binary.BigEndian, byte(1)) + + prefixIterOptions := &pebble.IterOptions{ + LowerBound: prefix.Bytes(), + UpperBound: end.Bytes(), + } + + var names [][]byte + + iter := repo.db.NewIter(prefixIterOptions) + for iter.First(); iter.Valid(); iter.Next() { + // Skipping the first 5 bytes (height and a null byte), we get the name. + name := make([]byte, len(iter.Key())-5) + copy(name, iter.Key()[5:]) // iter.Key() reuses its buffer + names = append(names, name) + } + + return names, errors.Wrap(iter.Close(), "in close") +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/temporal/temporalrepo/temporalrepo_test.go b/claimtrie/temporal/temporalrepo/temporalrepo_test.go new file mode 100644 index 00000000..090dc187 --- /dev/null +++ b/claimtrie/temporal/temporalrepo/temporalrepo_test.go @@ -0,0 +1,80 @@ +package temporalrepo + +import ( + "testing" + + "github.com/lbryio/lbcd/claimtrie/temporal" + + "github.com/stretchr/testify/require" +) + +func TestMemory(t *testing.T) { + + repo := NewMemory() + testTemporalRepo(t, repo) +} + +func TestPebble(t *testing.T) { + + repo, err := NewPebble(t.TempDir()) + require.NoError(t, err) + + testTemporalRepo(t, repo) +} + +func testTemporalRepo(t *testing.T, repo temporal.Repo) { + + r := require.New(t) + + nameA := []byte("a") + nameB := []byte("b") + nameC := []byte("c") + + testcases := []struct { + name []byte + heights []int32 + }{ + {nameA, []int32{1, 3, 2}}, + {nameA, []int32{2, 3}}, + {nameB, []int32{5, 4}}, + {nameB, []int32{5, 1}}, + {nameC, []int32{4, 3, 8}}, + } + + for _, i := range testcases { + names := make([][]byte, 0, len(i.heights)) + for range i.heights { + names = append(names, i.name) + } + err := repo.SetNodesAt(names, i.heights) + r.NoError(err) + } + + // a: 1, 2, 3 + // b: 1, 5, 4 + // c: 4, 3, 8 + + names, err := repo.NodesAt(2) + r.NoError(err) + r.ElementsMatch([][]byte{nameA}, names) + + names, err = repo.NodesAt(5) + r.NoError(err) + r.ElementsMatch([][]byte{nameB}, names) + + names, err = repo.NodesAt(8) + r.NoError(err) + r.ElementsMatch([][]byte{nameC}, names) + + names, err = repo.NodesAt(1) + r.NoError(err) + r.ElementsMatch([][]byte{nameA, nameB}, names) + + names, err = repo.NodesAt(4) + r.NoError(err) + r.ElementsMatch([][]byte{nameB, nameC}, names) + + names, err = repo.NodesAt(3) + r.NoError(err) + r.ElementsMatch([][]byte{nameA, nameC}, names) +} -- 2.45.2 From 470a71fbe12a9bef45c4a7b4c7e900ce921b7d81 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 27 Jul 2021 09:33:10 -0400 Subject: [PATCH 137/459] [lbry] print out memory usage periodically --- lbcd.go | 2 ++ resourceLogging.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 resourceLogging.go diff --git a/lbcd.go b/lbcd.go index 1b2ad72d..ec6ef086 100644 --- a/lbcd.go +++ b/lbcd.go @@ -150,6 +150,8 @@ func btcdMain(serverChan chan<- *server) error { param.SetNetwork(activeNetParams.Params.Net) // prep the claimtrie params + go logMemoryUsage() + // Create server and start it. server, err := newServer(cfg.Listeners, cfg.AgentBlacklist, cfg.AgentWhitelist, db, activeNetParams.Params, interrupt) diff --git a/resourceLogging.go b/resourceLogging.go new file mode 100644 index 00000000..d6e92051 --- /dev/null +++ b/resourceLogging.go @@ -0,0 +1,74 @@ +package main + +import ( + "fmt" + + "github.com/shirou/gopsutil/v3/disk" + "github.com/shirou/gopsutil/v3/mem" + "github.com/shirou/gopsutil/v3/process" + + "os" + "path/filepath" + "time" +) + +func toGB(n uint64) float64 { + return float64(n) / 1024.0 / 1024.0 / 1024.0 +} + +func dirSize(path string) (int64, error) { + var size int64 + err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + size += info.Size() + } + return err + }) + return size, err +} + +func logMemoryUsage() { + last := "" + tick := time.NewTicker(40 * time.Second) + for range tick.C { + m, err := mem.VirtualMemory() + if err != nil { + btcdLog.Warnf("When reading memory size: %s", err.Error()) + continue + } + + d, err := disk.Usage(cfg.DataDir) + if err != nil { + btcdLog.Warnf("When reading disk usage: %s", err.Error()) + continue + } + + p, err := process.NewProcess(int32(os.Getpid())) + if err != nil { + btcdLog.Warnf("When reading process: %s", err.Error()) + continue + } + + m2, err := p.MemoryInfo() + if err != nil { + btcdLog.Warnf("When reading memory info: %s", err.Error()) + continue + } + + ds, err := dirSize(cfg.DataDir) + if err != nil { + btcdLog.Debugf("When reading directory: %s", err.Error()) + continue + } + + cur := fmt.Sprintf("RAM: using %.1f GB with %.1f available, DISK: using %.1f GB with %.1f available", + toGB(m2.RSS), toGB(m.Available), toGB(uint64(ds)), toGB(d.Free)) + if cur != last { + btcdLog.Infof(cur) + last = cur + } + } +} -- 2.45.2 From 7f3d51f8c3765e55c9176c5c939cdaac158782a8 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 30 Jul 2021 16:24:14 -0400 Subject: [PATCH 138/459] [lbry] rpc: support claim related methods --- btcjson/chainsvrresults.go | 7 + btcjson/chainsvrresults_test.go | 2 +- btcjson/claimcmds.go | 97 +++++++++ btcjson/help.go | 6 + btcjson/jsonrpc.go | 8 +- rpcclaimtrie.go | 352 ++++++++++++++++++++++++++++++++ rpcserverhelp.go | 84 ++++++++ 7 files changed, 553 insertions(+), 3 deletions(-) create mode 100644 btcjson/claimcmds.go create mode 100644 rpcclaimtrie.go diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index e658cccf..e82a14bc 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -298,6 +298,8 @@ type GetBlockTemplateResult struct { // Block proposal from BIP 0023. Capabilities []string `json:"capabilities,omitempty"` RejectReasion string `json:"reject-reason,omitempty"` + + ClaimTrieHash string `json:"claimtrie"` } // GetMempoolEntryResult models the data returned from the getmempoolentry's @@ -430,6 +432,9 @@ type ScriptPubKeyResult struct { Hex string `json:"hex,omitempty"` ReqSigs int32 `json:"reqSigs,omitempty"` Type string `json:"type"` + SubType string `json:"subtype"` + IsClaim bool `json:"isclaim"` + IsSupport bool `json:"issupport"` Addresses []string `json:"addresses,omitempty"` } @@ -588,6 +593,8 @@ func (v *Vin) MarshalJSON() ([]byte, error) { type PrevOut struct { Addresses []string `json:"addresses,omitempty"` Value float64 `json:"value"` + IsClaim bool `json:"isclaim"` + IsSupport bool `json:"issupport"` } // VinPrevOut is like Vin except it includes PrevOut. It is used by searchrawtransaction diff --git a/btcjson/chainsvrresults_test.go b/btcjson/chainsvrresults_test.go index bb04a003..cbdca095 100644 --- a/btcjson/chainsvrresults_test.go +++ b/btcjson/chainsvrresults_test.go @@ -70,7 +70,7 @@ func TestChainSvrCustomResults(t *testing.T) { }, Sequence: 4294967295, }, - expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"prevOut":{"addresses":["addr1"],"value":0},"sequence":4294967295}`, + expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"prevOut":{"addresses":["addr1"],"value":0,"isclaim":false,"issupport":false},"sequence":4294967295}`, }, } diff --git a/btcjson/claimcmds.go b/btcjson/claimcmds.go new file mode 100644 index 00000000..8f50fc0c --- /dev/null +++ b/btcjson/claimcmds.go @@ -0,0 +1,97 @@ +package btcjson + +func init() { + // No special flags for commands in this file. + flags := UsageFlag(0) + + MustRegisterCmd("getchangesinblock", (*GetChangesInBlockCmd)(nil), flags) + MustRegisterCmd("getclaimsforname", (*GetClaimsForNameCmd)(nil), flags) + MustRegisterCmd("getclaimsfornamebyid", (*GetClaimsForNameByIDCmd)(nil), flags) + MustRegisterCmd("getclaimsfornamebybid", (*GetClaimsForNameByBidCmd)(nil), flags) + MustRegisterCmd("getclaimsfornamebyseq", (*GetClaimsForNameBySeqCmd)(nil), flags) + MustRegisterCmd("normalize", (*GetNormalizedCmd)(nil), flags) +} + +// optional inputs are required to be pointers, but they support things like `jsonrpcdefault:"false"` +// optional inputs have to be at the bottom of the struct +// optional outputs require ",omitempty" +// traditional bitcoin fields are all lowercase + +type GetChangesInBlockCmd struct { + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` +} + +type GetChangesInBlockResult struct { + Hash string `json:"hash"` + Height int32 `json:"height"` + Names []string `json:"names"` +} + +type GetClaimsForNameCmd struct { + Name string `json:"name"` + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` + IncludeValues *bool `json:"includevalues" jsonrpcdefault:"false"` +} + +type GetClaimsForNameByIDCmd struct { + Name string `json:"name"` + PartialClaimIDs []string `json:"partialclaimids"` + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` + IncludeValues *bool `json:"includevalues" jsonrpcdefault:"false"` +} + +type GetClaimsForNameByBidCmd struct { + Name string `json:"name"` + Bids []int32 `json:"bids"` + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` + IncludeValues *bool `json:"includevalues" jsonrpcdefault:"false"` +} + +type GetClaimsForNameBySeqCmd struct { + Name string `json:"name"` + Sequences []int32 `json:"sequences" jsonrpcusage:"[sequence,...]"` + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` + IncludeValues *bool `json:"includevalues" jsonrpcdefault:"false"` +} + +type GetClaimsForNameResult struct { + Hash string `json:"hash"` + Height int32 `json:"height"` + LastTakeoverHeight int32 `json:"lasttakeoverheight"` + NormalizedName string `json:"normalizedname"` + Claims []ClaimResult `json:"claims"` + // UnclaimedSupports []SupportResult `json:"supportswithoutclaim"` how would this work with other constraints? +} + +type SupportResult struct { + TXID string `json:"txid"` + N uint32 `json:"n"` + Height int32 `json:"height"` + ValidAtHeight int32 `json:"validatheight"` + Amount int64 `json:"amount"` + Address string `json:"address,omitempty"` + Value string `json:"value,omitempty"` +} + +type ClaimResult struct { + ClaimID string `json:"claimid"` + TXID string `json:"txid"` + N uint32 `json:"n"` + Bid int32 `json:"bid"` + Sequence int32 `json:"sequence"` + Height int32 `json:"height"` + ValidAtHeight int32 `json:"validatheight"` + Amount int64 `json:"amount"` + EffectiveAmount int64 `json:"effectiveamount"` + Supports []SupportResult `json:"supports,omitempty"` + Address string `json:"address,omitempty"` + Value string `json:"value,omitempty"` +} + +type GetNormalizedCmd struct { + Name string `json:"name"` +} + +type GetNormalizedResult struct { + NormalizedName string `json:"normalizedname"` +} diff --git a/btcjson/help.go b/btcjson/help.go index f502d09f..04d85635 100644 --- a/btcjson/help.go +++ b/btcjson/help.go @@ -547,6 +547,12 @@ func GenerateHelp(method string, descs map[string]string, resultTypes ...interfa return desc } + if strings.Contains(key, "base-") { + if desc, ok := descs[strings.ReplaceAll(key, "base-", "-")]; ok { + return desc + } + } + missingKey = key return key } diff --git a/btcjson/jsonrpc.go b/btcjson/jsonrpc.go index 553a7bc3..e94653da 100644 --- a/btcjson/jsonrpc.go +++ b/btcjson/jsonrpc.go @@ -226,8 +226,12 @@ func NewResponse(rpcVersion RPCVersion, id interface{}, marshalledResult []byte, // JSON-RPC client. func MarshalResponse(rpcVersion RPCVersion, id interface{}, result interface{}, rpcErr *RPCError) ([]byte, error) { if !rpcVersion.IsValid() { - str := fmt.Sprintf("rpcversion '%s' is invalid", rpcVersion) - return nil, makeError(ErrInvalidType, str) + if rpcVersion == "" { + rpcVersion = RpcVersion1 + } else { + str := fmt.Sprintf("rpcversion '%s' is unsupported", rpcVersion) + return nil, makeError(ErrInvalidType, str) + } } marshalledResult, err := json.Marshal(result) diff --git a/rpcclaimtrie.go b/rpcclaimtrie.go new file mode 100644 index 00000000..11706920 --- /dev/null +++ b/rpcclaimtrie.go @@ -0,0 +1,352 @@ +package main + +import ( + "bytes" + "encoding/hex" + "strconv" + "strings" + + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/claimtrie/normalization" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" +) + +var claimtrieHandlers = map[string]commandHandler{ + "getchangesinblock": handleGetChangesInBlock, + "getclaimsforname": handleGetClaimsForName, + "getclaimsfornamebyid": handleGetClaimsForNameByID, + "getclaimsfornamebybid": handleGetClaimsForNameByBid, + "getclaimsfornamebyseq": handleGetClaimsForNameBySeq, + "normalize": handleGetNormalized, +} + +func handleGetChangesInBlock(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetChangesInBlockCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + names, err := s.cfg.Chain.GetNamesChangedInBlock(height) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + return btcjson.GetChangesInBlockResult{ + Hash: hash, + Height: height, + Names: names, + }, nil +} + +func parseHashOrHeight(s *rpcServer, hashOrHeight *string) (string, int32, error) { + if hashOrHeight == nil || len(*hashOrHeight) == 0 { + + if !s.cfg.Chain.IsCurrent() { + return "", 0, &btcjson.RPCError{ + Code: btcjson.ErrRPCClientInInitialDownload, + Message: "Unable to query the chain tip during initial download", + } + } + + // just give them the latest block if a specific one wasn't requested + best := s.cfg.Chain.BestSnapshot() + return best.Hash.String(), best.Height, nil + } + + ht, err := strconv.ParseInt(*hashOrHeight, 10, 32) + if err == nil && len(*hashOrHeight) < 32 { + hs, err := s.cfg.Chain.BlockHashByHeight(int32(ht)) + if err != nil { + return "", 0, &btcjson.RPCError{ + Code: btcjson.ErrRPCBlockNotFound, + Message: "Unable to locate a block at height " + *hashOrHeight + ": " + err.Error(), + } + } + return hs.String(), int32(ht), nil + } + + hs, err := chainhash.NewHashFromStr(*hashOrHeight) + if err != nil { + return "", 0, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Unable to parse a height or hash from " + *hashOrHeight + ": " + err.Error(), + } + } + h, err := s.cfg.Chain.BlockHeightByHash(hs) + if err != nil { + return hs.String(), h, &btcjson.RPCError{ + Code: btcjson.ErrRPCBlockNotFound, + Message: "Unable to find a block with hash " + hs.String() + ": " + err.Error(), + } + } + return hs.String(), h, nil +} + +func handleGetClaimsForName(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetClaimsForNameCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + name, n, err := s.cfg.Chain.GetClaimsForName(height, c.Name) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + var results []btcjson.ClaimResult + for i := range n.Claims { + cr, err := toClaimResult(s, int32(i), n, c.IncludeValues) + if err != nil { + return nil, err + } + results = append(results, cr) + } + + return btcjson.GetClaimsForNameResult{ + Hash: hash, + Height: height, + LastTakeoverHeight: n.TakenOverAt, + NormalizedName: name, + Claims: results, + }, nil +} + +func handleGetClaimsForNameByID(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetClaimsForNameByIDCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + name, n, err := s.cfg.Chain.GetClaimsForName(height, c.Name) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + var results []btcjson.ClaimResult + for i := 0; i < len(n.Claims); i++ { + for _, id := range c.PartialClaimIDs { + if strings.HasPrefix(n.Claims[i].ClaimID.String(), id) { + cr, err := toClaimResult(s, int32(i), n, c.IncludeValues) + if err != nil { + return nil, err + } + results = append(results, cr) + break + } + } + } + + return btcjson.GetClaimsForNameResult{ + Hash: hash, + Height: height, + LastTakeoverHeight: n.TakenOverAt, + NormalizedName: name, + Claims: results, + }, nil +} + +func handleGetClaimsForNameByBid(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetClaimsForNameByBidCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + name, n, err := s.cfg.Chain.GetClaimsForName(height, c.Name) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + var results []btcjson.ClaimResult + for _, b := range c.Bids { // claims are already sorted in bid order + if b >= 0 && int(b) < len(n.Claims) { + cr, err := toClaimResult(s, b, n, c.IncludeValues) + if err != nil { + return nil, err + } + results = append(results, cr) + } + } + + return btcjson.GetClaimsForNameResult{ + Hash: hash, + Height: height, + LastTakeoverHeight: n.TakenOverAt, + NormalizedName: name, + Claims: results, + }, nil +} + +func handleGetClaimsForNameBySeq(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetClaimsForNameBySeqCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + name, n, err := s.cfg.Chain.GetClaimsForName(height, c.Name) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + sm := map[int32]bool{} + for _, seq := range c.Sequences { + sm[seq] = true + } + + var results []btcjson.ClaimResult + for i := 0; i < len(n.Claims); i++ { + if sm[n.Claims[i].Sequence] { + cr, err := toClaimResult(s, int32(i), n, c.IncludeValues) + if err != nil { + return nil, err + } + results = append(results, cr) + } + } + + return btcjson.GetClaimsForNameResult{ + Hash: hash, + Height: height, + LastTakeoverHeight: n.TakenOverAt, + NormalizedName: name, + Claims: results, + }, nil +} + +func toClaimResult(s *rpcServer, i int32, n *node.Node, includeValues *bool) (btcjson.ClaimResult, error) { + claim := n.Claims[i] + address, value, err := lookupValue(s, claim.OutPoint, includeValues) + supports, err := toSupportResults(s, i, n, includeValues) + effectiveAmount := n.SupportSums[claim.ClaimID.Key()] // should only be active supports + if claim.Status == node.Activated { + effectiveAmount += claim.Amount + } + return btcjson.ClaimResult{ + ClaimID: claim.ClaimID.String(), + Height: claim.AcceptedAt, + ValidAtHeight: claim.ActiveAt, + TXID: claim.OutPoint.Hash.String(), + N: claim.OutPoint.Index, + Bid: i, // assuming sorted by bid + Amount: claim.Amount, + EffectiveAmount: effectiveAmount, + Sequence: claim.Sequence, + Supports: supports, + Address: address, + Value: value, + }, err +} + +func toSupportResults(s *rpcServer, i int32, n *node.Node, includeValues *bool) ([]btcjson.SupportResult, error) { + var results []btcjson.SupportResult + c := n.Claims[i] + for _, sup := range n.Supports { + if sup.Status == node.Activated && c.ClaimID == sup.ClaimID { + address, value, err := lookupValue(s, sup.OutPoint, includeValues) + if err != nil { + return results, err + } + results = append(results, btcjson.SupportResult{ + TXID: sup.OutPoint.Hash.String(), + N: sup.OutPoint.Index, + Height: sup.AcceptedAt, + ValidAtHeight: sup.ActiveAt, + Amount: sup.Amount, + Value: value, + Address: address, + }) + } + } + return results, nil +} + +func lookupValue(s *rpcServer, outpoint wire.OutPoint, includeValues *bool) (string, string, error) { + if includeValues == nil || !*includeValues { + return "", "", nil + } + // TODO: maybe use addrIndex if the txIndex is not available + + if s.cfg.TxIndex == nil { + return "", "", &btcjson.RPCError{ + Code: btcjson.ErrRPCNoTxInfo, + Message: "The transaction index must be " + + "enabled to query the blockchain " + + "(specify --txindex)", + } + } + + txHash := &outpoint.Hash + blockRegion, err := s.cfg.TxIndex.TxBlockRegion(txHash) + if err != nil { + context := "Failed to retrieve transaction location" + return "", "", internalRPCError(err.Error(), context) + } + if blockRegion == nil { + return "", "", rpcNoTxInfoError(txHash) + } + + // Load the raw transaction bytes from the database. + var txBytes []byte + err = s.cfg.DB.View(func(dbTx database.Tx) error { + var err error + txBytes, err = dbTx.FetchBlockRegion(blockRegion) + return err + }) + if err != nil { + return "", "", rpcNoTxInfoError(txHash) + } + + // Deserialize the transaction + var msgTx wire.MsgTx + err = msgTx.Deserialize(bytes.NewReader(txBytes)) + if err != nil { + context := "Failed to deserialize transaction" + return "", "", internalRPCError(err.Error(), context) + } + + txo := msgTx.TxOut[outpoint.Index] + cs, err := txscript.ExtractClaimScript(txo.PkScript) + if err != nil { + context := "Failed to decode the claim script" + return "", "", internalRPCError(err.Error(), context) + } + + _, addresses, _, _ := txscript.ExtractPkScriptAddrs(txo.PkScript[cs.Size:], s.cfg.ChainParams) + return addresses[0].EncodeAddress(), hex.EncodeToString(cs.Value), nil +} + +func handleGetNormalized(_ *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.GetNormalizedCmd) + r := btcjson.GetNormalizedResult{ + NormalizedName: string(normalization.Normalize([]byte(c.Name))), + } + return r, nil +} diff --git a/rpcserverhelp.go b/rpcserverhelp.go index e8f7a640..1ab92644 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -247,6 +247,7 @@ var helpDescsEnUS = map[string]string{ "getblockverboseresult-version": "The block version", "getblockverboseresult-versionHex": "The block version in hexadecimal", "getblockverboseresult-merkleroot": "Root hash of the merkle tree", + "getblockverboseresult-nameclaimroot": "Root hash of the claim trie", "getblockverboseresult-tx": "The transaction hashes (only when verbosity=1)", "getblockverboseresult-rawtx": "The transactions as JSON objects (only when verbosity=2)", "getblockverboseresult-time": "The block time in seconds since 1 Jan 1970 GMT", @@ -288,6 +289,7 @@ var helpDescsEnUS = map[string]string{ "getblockheaderverboseresult-difficulty": "The proof-of-work difficulty as a multiple of the minimum difficulty", "getblockheaderverboseresult-previousblockhash": "The hash of the previous block", "getblockheaderverboseresult-nextblockhash": "The hash of the next block (only if there is one)", + "getblockheaderverboseresult-nameclaimroot": "The hash of the root of the claim trie", // TemplateRequest help. "templaterequest-mode": "This is 'template', 'proposal', or omitted", @@ -339,6 +341,8 @@ var helpDescsEnUS = map[string]string{ "getblocktemplateresult-reject-reason": "Reason the proposal was invalid as-is (only applies to proposal responses)", "getblocktemplateresult-default_witness_commitment": "The witness commitment itself. Will be populated if the block has witness data", "getblocktemplateresult-weightlimit": "The current limit on the max allowed weight of a block", + "getblocktemplateresult-rules": "Rules that are required to process the output", + "getblocktemplateresult-claimtrie": "The hash of the root of the claim trie - a necessary block header", // GetBlockTemplateCmd help. "getblocktemplate--synopsis": "Returns a JSON object with information necessary to construct a block to mine or accepts a proposal to validate.\n" + @@ -708,6 +712,78 @@ var helpDescsEnUS = map[string]string{ "versionresult-patch": "The patch component of the JSON-RPC API version", "versionresult-prerelease": "Prerelease info about the current build", "versionresult-buildmetadata": "Metadata about the current build", + + "getclaimsforname--synopsis": "Look up claims for the given name as they stand at a give block", + "getclaimsfornamebyid--synopsis": "Look up claims for the given name as they stand at a give block", + "getclaimsfornamebybid--synopsis": "Look up claims for the given name as they stand at a give block", + "getclaimsfornamebyseq--synopsis": "Look up claims for the given name as they stand at a give block", + + "getclaimsforname-hashorheight": "Requested block hash or height; default to tip", + "getclaimsfornamebyid-hashorheight": "Requested block hash or height; default to tip", + "getclaimsfornamebybid-hashorheight": "Requested block hash or height; default to tip", + "getclaimsfornamebyseq-hashorheight": "Requested block hash or height; default to tip", + + "getclaimsforname-name": "Requested name for lookup", + "getclaimsfornamebyid-name": "Requested name for lookup", + "getclaimsfornamebybid-name": "Requested name for lookup", + "getclaimsfornamebyseq-name": "Requested name for lookup", + + "getclaimsfornamebyid-partialclaimids": "Limit the returned claims to those with matching (partial) claimIDs in this list", + "getclaimsfornamebybid-bids": "Limit the returned claims to those with bids to this list", + "getclaimsfornamebyseq-sequences": "Limit the returned claims to those with bids to this list", + + "getclaimsforname-includevalues": "Return the metadata and address", + "getclaimsfornamebyseq-includevalues": "Return the metadata and address", + "getclaimsfornamebybid-includevalues": "Return the metadata and address", + "getclaimsfornamebyid-includevalues": "Return the metadata and address", + + "getclaimsfornameresult-claims": "All the active claims on the given name", + "getclaimsfornameresult-normalizedname": "Lower-case version of the passed-in name", + "getclaimsfornameresult-height": "Height of the requested block", + "getclaimsfornameresult-lasttakeoverheight": "Height of the most recent name takeover", + "getclaimsfornameresult-hash": "Hash of the requested block", + + "getchangesinblock--synopsis": "Returns a list of names affected by a given block", + "getchangesinblockresult-names": "Names that changed (or were at least checked for change) on the given height", + "getchangesinblockresult-height": "Height that was requested", + "getchangesinblockresult-hash": "Hash of the block at the height requested", + + "scriptpubkeyresult-subtype": "Claims return Non-standard address types, but they use standard address types internally exposed here", + + "supportresult-value": "This is the metadata given as part of the support", + "supportresult-txid": "The hash of the transaction", + "supportresult-n": "The output (TXO) index", + "supportresult-address": "The destination address for the support", + "supportresult-amount": "LBC staked", + "supportresult-height": "The height when the stake was created or updated", + "supportresult-validatheight": "The height when the stake becomes valid", + "claimresult-value": "This is the metadata given as part of the claim", + "claimresult-txid": "The hash of the transaction", + "claimresult-n": "The output (TXO) index", + "claimresult-address": "The destination address for the claim", + "claimresult-supports": "The list of supports active on the claim", + "claimresult-validatheight": "The height when the stake becomes valid", + "claimresult-height": "The height when the stake was created or updated", + "claimresult-amount": "The stake amount in sats", + "claimresult-effectiveamount": "The stake amount plus the active supports' amounts", + "claimresult-sequence": "The order this claim was created compared to other claims on this name", + "claimresult-bid": "Bid of 0 means that this claim currently owns the name", + "claimresult-claimid": "20-byte hash of TXID:N, often used in indexes for the claims", + + "generatetoaddress--synopsis": "Mine blocks and send their reward to a given address", + "generatetoaddress--result0": "The list of generated blocks' hashes", + "generatetoaddress-maxtries": "The maximum number of hashes to attempt", + "generatetoaddress-address": "The destination -- the place where the LBC will be sent", + "generatetoaddress-numblocks": "The number of blocks to mine", + "getchangesinblock-hashorheight": "The requested height or block hash whose changes are of interest", + + "normalize--synopsis": "Used to show how lbcd will normalize a string", + "normalize--result0": "The normalized name", + "normalize-name": "The string to be normalized", + + "getblockverboseresult-getblockverboseresultbase": "", + "prevout-issupport": "Previous output created a support", + "prevout-isclaim": "Previous output created or updated a claim", } // rpcResultTypes specifies the result types that each RPC command can return. @@ -776,6 +852,14 @@ var rpcResultTypes = map[string][]interface{}{ "stopnotifyspent": nil, "rescan": nil, "rescanblocks": {(*[]btcjson.RescannedBlock)(nil)}, + + // ClaimTrie + "getclaimsforname": {(*btcjson.GetClaimsForNameResult)(nil)}, + "getclaimsfornamebyid": {(*btcjson.GetClaimsForNameResult)(nil)}, + "getclaimsfornamebybid": {(*btcjson.GetClaimsForNameResult)(nil)}, + "getclaimsfornamebyseq": {(*btcjson.GetClaimsForNameResult)(nil)}, + "normalize": {(*string)(nil)}, + "getchangesinblock": {(*btcjson.GetChangesInBlockResult)(nil)}, } // helpCacher provides a concurrent safe type that provides help and usage for -- 2.45.2 From 8205e467afe90d76ea5e57c568e6deb8d638656c Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 19:48:59 -0700 Subject: [PATCH 139/459] [lbry] rpc: add ClaimTrie root hash to GetBlockTemplate() --- rpcserver.go | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 4502a4cd..607733e1 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1748,23 +1748,24 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld targetDifficulty := fmt.Sprintf("%064x", blockchain.CompactToBig(header.Bits)) templateID := encodeTemplateID(state.prevHash, state.lastGenerated) reply := btcjson.GetBlockTemplateResult{ - Bits: strconv.FormatInt(int64(header.Bits), 16), - CurTime: header.Timestamp.Unix(), - Height: int64(template.Height), - PreviousHash: header.PrevBlock.String(), - WeightLimit: blockchain.MaxBlockWeight, - SigOpLimit: blockchain.MaxBlockSigOpsCost, - SizeLimit: wire.MaxBlockPayload, - Transactions: transactions, - Version: header.Version, - LongPollID: templateID, - SubmitOld: submitOld, - Target: targetDifficulty, - MinTime: state.minTimestamp.Unix(), - MaxTime: maxTime.Unix(), - Mutable: gbtMutableFields, - NonceRange: gbtNonceRange, - Capabilities: gbtCapabilities, + Bits: strconv.FormatInt(int64(header.Bits), 16), + CurTime: header.Timestamp.Unix(), + Height: int64(template.Height), + PreviousHash: header.PrevBlock.String(), + WeightLimit: blockchain.MaxBlockWeight, + SigOpLimit: blockchain.MaxBlockSigOpsCost, + SizeLimit: wire.MaxBlockPayload, + Transactions: transactions, + Version: header.Version, + LongPollID: templateID, + SubmitOld: submitOld, + Target: targetDifficulty, + MinTime: state.minTimestamp.Unix(), + MaxTime: maxTime.Unix(), + Mutable: gbtMutableFields, + NonceRange: gbtNonceRange, + Capabilities: gbtCapabilities, + ClaimTrieHash: header.ClaimTrie.String(), } // If the generated block template includes transactions with witness // data, then include the witness commitment in the GBT result. @@ -4663,5 +4664,8 @@ func (s *rpcServer) handleBlockchainNotification(notification *blockchain.Notifi func init() { rpcHandlers = rpcHandlersBeforeInit + for key := range claimtrieHandlers { + rpcHandlers[key] = claimtrieHandlers[key] + } rand.Seed(time.Now().UnixNano()) } -- 2.45.2 From 207fadab42ed9bd5eeb3660d892eec11f760df80 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 30 Jul 2021 14:12:28 -0400 Subject: [PATCH 140/459] [lbry] rpc: output segwit rule --- btcjson/chainsvrresults.go | 2 ++ rpcserver.go | 1 + 2 files changed, 3 insertions(+) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index e82a14bc..ecc26827 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -300,6 +300,8 @@ type GetBlockTemplateResult struct { RejectReasion string `json:"reject-reason,omitempty"` ClaimTrieHash string `json:"claimtrie"` + + Rules []string `json:"rules,omitempty"` } // GetMempoolEntryResult models the data returned from the getmempoolentry's diff --git a/rpcserver.go b/rpcserver.go index 607733e1..7014c7b6 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1771,6 +1771,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld // data, then include the witness commitment in the GBT result. if template.WitnessCommitment != nil { reply.DefaultWitnessCommitment = hex.EncodeToString(template.WitnessCommitment) + reply.Rules = append(reply.Rules, "!segwit") } if useCoinbaseValue { -- 2.45.2 From 9f88501d07db50dbc00b47d969bcb7aff2529f2f Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 22:10:26 -0700 Subject: [PATCH 141/459] [lbry] rpc: update defaultMaxFeeRate from 0.1 LBC to 0.5 LBC --- rpcclient/rawtransactions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcclient/rawtransactions.go b/rpcclient/rawtransactions.go index d0f28c8a..3512ccb7 100644 --- a/rpcclient/rawtransactions.go +++ b/rpcclient/rawtransactions.go @@ -18,7 +18,7 @@ import ( const ( // defaultMaxFeeRate is the default maximum fee rate in sat/KB enforced // by bitcoind v0.19.0 or after for transaction broadcast. - defaultMaxFeeRate = btcutil.SatoshiPerBitcoin / 10 + defaultMaxFeeRate = btcutil.SatoshiPerBitcoin / 2 ) // SigHashType enumerates the available signature hashing types that the -- 2.45.2 From 8f3de76e1970dccaa2ff61f8368dee2d93593fcf Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 22:10:26 -0700 Subject: [PATCH 142/459] [lbry] rpc: fix getblock reponse --- btcjson/chainsvrresults.go | 62 ++++++++++++++++---------------------- rpcserver.go | 45 ++++++++++++++++++--------- rpcserverhelp.go | 2 +- 3 files changed, 57 insertions(+), 52 deletions(-) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index ecc26827..46d454c5 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -25,7 +25,7 @@ type GetBlockHeaderVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` - ClaimTrie string `json:"claimtrie"` + ClaimTrie string `json:"nameclaimroot,omitempty"` Time int64 `json:"time"` Nonce uint64 `json:"nonce"` Bits string `json:"bits"` @@ -66,6 +66,27 @@ type GetBlockStatsResult struct { UTXOSizeIncrease int64 `json:"utxo_size_inc"` } +type GetBlockVerboseResultBase struct { + Hash string `json:"hash"` + Confirmations int64 `json:"confirmations"` + StrippedSize int32 `json:"strippedsize"` + Size int32 `json:"size"` + Weight int32 `json:"weight"` + Height int64 `json:"height"` + Version int32 `json:"version"` + VersionHex string `json:"versionHex"` + MerkleRoot string `json:"merkleroot"` + Time int64 `json:"time"` + Nonce uint32 `json:"nonce"` + Bits string `json:"bits"` + Difficulty float64 `json:"difficulty"` + PreviousHash string `json:"previousblockhash,omitempty"` + NextHash string `json:"nextblockhash,omitempty"` + + ClaimTrie string `json:"nameclaimroot,omitempty"` + TxCount int `json:"nTx"` // For backwards compatibility only +} + // GetBlockVerboseResult models the data from the getblock command when the // verbose flag is set to 1. When the verbose flag is set to 0, getblock returns a // hex-encoded string. When the verbose flag is set to 1, getblock returns an object @@ -73,24 +94,8 @@ type GetBlockStatsResult struct { // getblock returns an object whose tx field is an array of raw transactions. // Use GetBlockVerboseTxResult to unmarshal data received from passing verbose=2 to getblock. type GetBlockVerboseResult struct { - Hash string `json:"hash"` - Confirmations int64 `json:"confirmations"` - StrippedSize int32 `json:"strippedsize"` - Size int32 `json:"size"` - Weight int32 `json:"weight"` - Height int64 `json:"height"` - Version int32 `json:"version"` - VersionHex string `json:"versionHex"` - MerkleRoot string `json:"merkleroot"` - ClaimTrie string `json:"claimTrie"` - Tx []string `json:"tx,omitempty"` - RawTx []TxRawResult `json:"rawtx,omitempty"` // Note: this field is always empty when verbose != 2. - Time int64 `json:"time"` - Nonce uint32 `json:"nonce"` - Bits string `json:"bits"` - Difficulty float64 `json:"difficulty"` - PreviousHash string `json:"previousblockhash"` - NextHash string `json:"nextblockhash,omitempty"` + GetBlockVerboseResultBase + Tx []string `json:"tx"` } // GetBlockVerboseTxResult models the data from the getblock command when the @@ -100,23 +105,8 @@ type GetBlockVerboseResult struct { // getblock returns an object whose tx field is an array of raw transactions. // Use GetBlockVerboseResult to unmarshal data received from passing verbose=1 to getblock. type GetBlockVerboseTxResult struct { - Hash string `json:"hash"` - Confirmations int64 `json:"confirmations"` - StrippedSize int32 `json:"strippedsize"` - Size int32 `json:"size"` - Weight int32 `json:"weight"` - Height int64 `json:"height"` - Version int32 `json:"version"` - VersionHex string `json:"versionHex"` - MerkleRoot string `json:"merkleroot"` - Tx []TxRawResult `json:"tx,omitempty"` - RawTx []TxRawResult `json:"rawtx,omitempty"` // Deprecated: removed in Bitcoin Core - Time int64 `json:"time"` - Nonce uint32 `json:"nonce"` - Bits string `json:"bits"` - Difficulty float64 `json:"difficulty"` - PreviousHash string `json:"previousblockhash"` - NextHash string `json:"nextblockhash,omitempty"` + GetBlockVerboseResultBase + Tx []TxRawResult `json:"tx"` } // GetChainTxStatsResult models the data from the getchaintxstats command. diff --git a/rpcserver.go b/rpcserver.go index 7014c7b6..04ff9e08 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1122,12 +1122,17 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i params := s.cfg.ChainParams blockHeader := &blk.MsgBlock().Header - blockReply := btcjson.GetBlockVerboseResult{ + var prevHashString string + if blockHeight > 0 { + prevHashString = blockHeader.PrevBlock.String() + } + + base := btcjson.GetBlockVerboseResultBase{ Hash: c.Hash, Version: blockHeader.Version, VersionHex: fmt.Sprintf("%08x", blockHeader.Version), MerkleRoot: blockHeader.MerkleRoot.String(), - PreviousHash: blockHeader.PrevBlock.String(), + PreviousHash: prevHashString, Nonce: blockHeader.Nonce, Time: blockHeader.Timestamp.Unix(), Confirmations: int64(1 + best.Height - blockHeight), @@ -1138,6 +1143,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i Bits: strconv.FormatInt(int64(blockHeader.Bits), 16), Difficulty: getDifficultyRatio(blockHeader.Bits, params), NextHash: nextHashString, + ClaimTrie: blockHeader.ClaimTrie.String(), } if *c.Verbosity == 1 { @@ -1147,20 +1153,29 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i txNames[i] = tx.Hash().String() } - blockReply.Tx = txNames - } else { - txns := blk.Transactions() - rawTxns := make([]btcjson.TxRawResult, len(txns)) - for i, tx := range txns { - rawTxn, err := createTxRawResult(params, tx.MsgTx(), - tx.Hash().String(), blockHeader, hash.String(), - blockHeight, best.Height) - if err != nil { - return nil, err - } - rawTxns[i] = *rawTxn + base.TxCount = len(txNames) + blockReply := btcjson.GetBlockVerboseResult{ + GetBlockVerboseResultBase: base, + Tx: txNames, } - blockReply.RawTx = rawTxns + return blockReply, nil + } + + txns := blk.Transactions() + rawTxns := make([]btcjson.TxRawResult, len(txns)) + for i, tx := range txns { + rawTxn, err := createTxRawResult(params, tx.MsgTx(), + tx.Hash().String(), blockHeader, hash.String(), + blockHeight, best.Height) + if err != nil { + return nil, err + } + rawTxns[i] = *rawTxn + } + base.TxCount = len(rawTxns) + blockReply := btcjson.GetBlockVerboseTxResult{ + GetBlockVerboseResultBase: base, + Tx: rawTxns, } return blockReply, nil diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 1ab92644..ac0bf42d 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -249,7 +249,7 @@ var helpDescsEnUS = map[string]string{ "getblockverboseresult-merkleroot": "Root hash of the merkle tree", "getblockverboseresult-nameclaimroot": "Root hash of the claim trie", "getblockverboseresult-tx": "The transaction hashes (only when verbosity=1)", - "getblockverboseresult-rawtx": "The transactions as JSON objects (only when verbosity=2)", + "getblockverboseresult-nTx": "The number of transactions (aka, count of TX)", "getblockverboseresult-time": "The block time in seconds since 1 Jan 1970 GMT", "getblockverboseresult-nonce": "The block nonce", "getblockverboseresult-bits": "The bits which represent the block difficulty", -- 2.45.2 From 4b477221361571b1493119f3817eaf58c1f3f70e Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 28 Oct 2021 14:02:44 -0400 Subject: [PATCH 143/459] [lbry] rpc: import getnetworkinfo from bchd --- addrmgr/addrmanager.go | 47 +++++---- blockchain/chain.go | 9 ++ rpcserver.go | 218 ++++++++++++++++++++++++++++++++++++----- rpcserverhelp.go | 22 +++++ server.go | 2 + version.go | 5 + 6 files changed, 257 insertions(+), 46 deletions(-) diff --git a/addrmgr/addrmanager.go b/addrmgr/addrmanager.go index b7730671..37236c1d 100644 --- a/addrmgr/addrmanager.go +++ b/addrmgr/addrmanager.go @@ -45,7 +45,7 @@ type AddrManager struct { nTried int nNew int lamtx sync.Mutex - localAddresses map[string]*localAddress + localAddresses map[string]*LocalAddress version int } @@ -69,9 +69,9 @@ type serializedAddrManager struct { TriedBuckets [triedBucketCount][]string } -type localAddress struct { - na *wire.NetAddress - score AddressPriority +type LocalAddress struct { + NA *wire.NetAddress + Score AddressPriority } // AddressPriority type is used to describe the hierarchy of local address @@ -178,7 +178,7 @@ func (a *AddrManager) updateAddress(netAddr, srcAddr *wire.NetAddress) { // note that to prevent causing excess garbage on getaddr // messages the netaddresses in addrmanager are *immutable*, // if we need to change them then we replace the pointer with a - // new copy so that we don't have to copy every na for getaddr. + // new copy so that we don't have to copy every NA for getaddr. if netAddr.Timestamp.After(ka.na.Timestamp) || (ka.na.Services&netAddr.Services) != netAddr.Services { @@ -755,7 +755,7 @@ func (a *AddrManager) HostToNetAddress(host string, port uint16, services wire.S // the relevant .onion address. func ipString(na *wire.NetAddress) string { if IsOnionCatTor(na) { - // We know now that na.IP is long enough. + // We know now that NA.IP is long enough. base32 := base32.StdEncoding.EncodeToString(na.IP[6:]) return strings.ToLower(base32) + ".onion" } @@ -882,7 +882,7 @@ func (a *AddrManager) Connected(addr *wire.NetAddress) { // so. now := time.Now() if now.After(ka.na.Timestamp.Add(time.Minute * 20)) { - // ka.na is immutable, so replace it. + // ka.NA is immutable, so replace it. naCopy := *ka.na naCopy.Timestamp = time.Now() ka.mtx.Lock() @@ -994,7 +994,7 @@ func (a *AddrManager) SetServices(addr *wire.NetAddress, services wire.ServiceFl // Update the services if needed. if ka.na.Services != services { - // ka.na is immutable, so replace it. + // ka.NA is immutable, so replace it. naCopy := *ka.na naCopy.Services = services ka.mtx.Lock() @@ -1003,7 +1003,7 @@ func (a *AddrManager) SetServices(addr *wire.NetAddress, services wire.ServiceFl } } -// AddLocalAddress adds na to the list of known local addresses to advertise +// AddLocalAddress adds NA to the list of known local addresses to advertise // with the given priority. func (a *AddrManager) AddLocalAddress(na *wire.NetAddress, priority AddressPriority) error { if !IsRoutable(na) { @@ -1015,13 +1015,13 @@ func (a *AddrManager) AddLocalAddress(na *wire.NetAddress, priority AddressPrior key := NetAddressKey(na) la, ok := a.localAddresses[key] - if !ok || la.score < priority { + if !ok || la.Score < priority { if ok { - la.score = priority + 1 + la.Score = priority + 1 } else { - a.localAddresses[key] = &localAddress{ - na: na, - score: priority, + a.localAddresses[key] = &LocalAddress{ + NA: na, + Score: priority, } } } @@ -1117,12 +1117,12 @@ func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.Net var bestscore AddressPriority var bestAddress *wire.NetAddress for _, la := range a.localAddresses { - reach := getReachabilityFrom(la.na, remoteAddr) + reach := getReachabilityFrom(la.NA, remoteAddr) if reach > bestreach || - (reach == bestreach && la.score > bestscore) { + (reach == bestreach && la.Score > bestscore) { bestreach = reach - bestscore = la.score - bestAddress = la.na + bestscore = la.Score + bestAddress = la.NA } } if bestAddress != nil { @@ -1146,6 +1146,15 @@ func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.Net return bestAddress } +// LocalAddresses returns the list of local addresses for our node. +func (a *AddrManager) LocalAddresses() []*LocalAddress { + var addrs []*LocalAddress + for _, addr := range a.localAddresses { + addrs = append(addrs, addr) + } + return addrs +} + // New returns a new bitcoin address manager. // Use Start to begin processing asynchronous address updates. func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager { @@ -1154,7 +1163,7 @@ func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager lookupFunc: lookupFunc, rand: rand.New(rand.NewSource(time.Now().UnixNano())), quit: make(chan struct{}), - localAddresses: make(map[string]*localAddress), + localAddresses: make(map[string]*LocalAddress), version: serialisationVersion, } am.reset() diff --git a/blockchain/chain.go b/blockchain/chain.go index a0bfac6c..66c435d8 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -199,6 +199,15 @@ func (b *BlockChain) HaveBlock(hash *chainhash.Hash) (bool, error) { return exists || b.IsKnownOrphan(hash), nil } +// GetWarnings returns a bool for whether unknownRules +// has been warned. +func (b *BlockChain) GetWarnings() bool { + b.chainLock.RLock() + defer b.chainLock.RUnlock() + + return b.unknownRulesWarned +} + // IsKnownOrphan returns whether the passed hash is currently a known orphan. // Keep in mind that only a limited number of orphans are held onto for a // limited amount of time, so this function must not be used as an absolute diff --git a/rpcserver.go b/rpcserver.go index 04ff9e08..5c20436d 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -27,21 +27,22 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/mining/cpuminer" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/websocket" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/mining/cpuminer" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // API version constants @@ -137,6 +138,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "decodescript": handleDecodeScript, "estimatefee": handleEstimateFee, "generate": handleGenerate, + "generatetoaddress": handleGenerateToAddress, "getaddednodeinfo": handleGetAddedNodeInfo, "getbestblock": handleGetBestBlock, "getbestblockhash": handleGetBestBlockHash, @@ -159,6 +161,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getmininginfo": handleGetMiningInfo, "getnettotals": handleGetNetTotals, "getnetworkhashps": handleGetNetworkHashPS, + "getnetworkinfo": handleGetNetworkInfo, "getnodeaddresses": handleGetNodeAddresses, "getpeerinfo": handleGetPeerInfo, "getrawmempool": handleGetRawMempool, @@ -233,7 +236,6 @@ var rpcUnimplemented = map[string]struct{}{ "estimatepriority": {}, "getchaintips": {}, "getmempoolentry": {}, - "getnetworkinfo": {}, "getwork": {}, "invalidateblock": {}, "preciousblock": {}, @@ -573,7 +575,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan default: return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidAddressOrKey, - Message: "Invalid address or key", + Message: "Invalid address or key: " + addr.String(), } } if !addr.IsForNet(params) { @@ -701,11 +703,12 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap // script doesn't fully parse, so ignore the error here. disbuf, _ := txscript.DisasmString(v.PkScript) + script := txscript.StripClaimScriptPrefix(v.PkScript) + // Ignore the error here since an error means the script // couldn't parse and there is no additional information about // it anyways. - scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs( - v.PkScript, chainParams) + scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script, chainParams) // Encode the addresses while checking if the address passes the // filter when needed. @@ -735,9 +738,19 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap vout.ScriptPubKey.Addresses = encodedAddrs vout.ScriptPubKey.Asm = disbuf vout.ScriptPubKey.Hex = hex.EncodeToString(v.PkScript) - vout.ScriptPubKey.Type = scriptClass.String() vout.ScriptPubKey.ReqSigs = int32(reqSigs) + if len(script) < len(v.PkScript) { + vout.ScriptPubKey.IsClaim = v.PkScript[0] == txscript.OP_CLAIMNAME || v.PkScript[0] == txscript.OP_UPDATECLAIM + vout.ScriptPubKey.IsSupport = v.PkScript[0] == txscript.OP_SUPPORTCLAIM + vout.ScriptPubKey.SubType = scriptClass.String() + vout.ScriptPubKey.Type = txscript.ScriptClass.String(0) + } else { + vout.ScriptPubKey.Type = scriptClass.String() + } + + // TODO here: isclaim, issupport, subtype, + voutList = append(voutList, vout) } @@ -882,7 +895,6 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) return float64(feeRate), nil } -// handleGenerate handles generate commands. func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { // Respond with an error if there are no addresses to pay the // created blocks to. @@ -919,7 +931,62 @@ func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i // Create a reply reply := make([]string, c.NumBlocks) - blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(c.NumBlocks) + blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(c.NumBlocks, nil) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: err.Error(), + } + } + + // Mine the correct number of blocks, assigning the hex representation of the + // hash of each one to its place in the reply. + for i, hash := range blockHashes { + reply[i] = hash.String() + } + + return reply, nil +} + +// handleGenerateToAddress handles generate commands. +func handleGenerateToAddress(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.GenerateToAddressCmd) + payToAddr, err := btcutil.DecodeAddress(c.Address, s.cfg.ChainParams) + + // Respond with an error if there are no addresses to pay the + // created blocks to. + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "No payment addresses specified ", + } + } + // cfg.miningAddrs = append(cfg.miningAddrs, maddr) + + // Respond with an error if there's virtually 0 chance of mining a block + // with the CPU. + if !s.cfg.ChainParams.GenerateSupported { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCDifficulty, + Message: fmt.Sprintf("No support for `generatetoaddress` on "+ + "the current network, %s, as it's unlikely to "+ + "be possible to mine a block with the CPU.", + s.cfg.ChainParams.Net), + } + } + + // Respond with an error if the client is requesting 0 blocks to be generated. + if c.NumBlocks == 0 { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: "Please request a nonzero number of blocks to generate.", + } + } + + // Create a reply + reply := make([]string, c.NumBlocks) + + blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(uint32(c.NumBlocks), payToAddr) if err != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInternal.Code, @@ -2537,6 +2604,84 @@ func handleGetNodeAddresses(s *rpcServer, cmd interface{}, closeChan <-chan stru return addresses, nil } +// handleGetNetworkInfo implements the getnetworkinfo command. +func handleGetNetworkInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + ver := wire.MsgVersion{} + _ = ver.AddUserAgent(userAgentName, userAgentVersion, cfg.UserAgentComments...) + + var localAddrs []btcjson.LocalAddressesResult + var ipv4Reachable, ipv6Reachable bool + for _, addr := range s.cfg.AddrMgr.LocalAddresses() { + localAddrs = append(localAddrs, btcjson.LocalAddressesResult{ + Address: addr.NA.IP.String(), + Port: addr.NA.Port, + Score: int32(addr.Score), + }) + if addr.NA.IP.To4() != nil { + ipv4Reachable = true + } else { + ipv6Reachable = true + } + } + + onionProxy := cfg.Proxy + if cfg.OnionProxy != "" { + onionProxy = cfg.OnionProxy + } + + var warnings string + unknownRulesWarned := s.cfg.Chain.GetWarnings() + if unknownRulesWarned { + warnings = "Warning: Unknown new rules activated! " + } + + var timeOffset int64 + if !s.cfg.SyncMgr.IsCurrent() { + ss := s.cfg.Chain.BestSnapshot() + bestHeader, err := s.cfg.Chain.HeaderByHash(&ss.Hash) + if err != nil { + return nil, err + } + timeOffset = int64(time.Since(bestHeader.Timestamp).Seconds()) + } + + reply := &btcjson.GetNetworkInfoResult{ + ProtocolVersion: int32(wire.ProtocolVersion), + Version: versionNumeric(), + Connections: s.cfg.ConnMgr.ConnectedCount(), + IncrementalFee: cfg.MinRelayTxFee, + LocalAddresses: localAddrs, + LocalRelay: !cfg.BlocksOnly, + LocalServices: s.cfg.Services.String(), + NetworkActive: true, + Networks: []btcjson.NetworksResult{ + { + Name: "ipv4", + Reachable: ipv4Reachable, + Proxy: cfg.Proxy, + }, + { + Name: "ipv6", + Reachable: ipv6Reachable, + Proxy: cfg.Proxy, + }, + { + Name: "onion", + + ProxyRandomizeCredentials: cfg.TorIsolation, + + Proxy: onionProxy, + Reachable: cfg.Proxy != "" || cfg.OnionProxy != "", + }, + }, + RelayFee: cfg.MinRelayTxFee, + SubVersion: ver.UserAgent, + TimeOffset: timeOffset, + Warnings: warnings, + } + return reply, nil +} + // handleGetPeerInfo implements the getpeerinfo command. func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { peers := s.cfg.ConnMgr.ConnectedPeers() @@ -2795,10 +2940,12 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i // doesn't fully parse, so ignore the error here. disbuf, _ := txscript.DisasmString(pkScript) + script := txscript.StripClaimScriptPrefix(pkScript) + // Get further info about the script. // Ignore the error here since an error means the script couldn't parse // and there is no additional information about it anyways. - scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(pkScript, + scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script, s.cfg.ChainParams) addresses := make([]string, len(addrs)) for i, addr := range addrs { @@ -2813,11 +2960,20 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i Asm: disbuf, Hex: hex.EncodeToString(pkScript), ReqSigs: int32(reqSigs), - Type: scriptClass.String(), Addresses: addresses, }, Coinbase: isCoinbase, } + + if len(script) < len(pkScript) { + txOutReply.ScriptPubKey.IsClaim = pkScript[0] == txscript.OP_CLAIMNAME || pkScript[0] == txscript.OP_UPDATECLAIM + txOutReply.ScriptPubKey.IsSupport = pkScript[0] == txscript.OP_SUPPORTCLAIM + txOutReply.ScriptPubKey.SubType = scriptClass.String() + txOutReply.ScriptPubKey.Type = txscript.ScriptClass.String(0) + } else { + txOutReply.ScriptPubKey.Type = scriptClass.String() + } + return txOutReply, nil } @@ -3066,6 +3222,8 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P vinListEntry.PrevOut = &btcjson.PrevOut{ Addresses: encodedAddrs, Value: btcutil.Amount(originTxOut.Value).ToBTC(), + IsClaim: originTxOut.PkScript[0] == txscript.OP_CLAIMNAME || originTxOut.PkScript[0] == txscript.OP_UPDATECLAIM, + IsSupport: originTxOut.PkScript[0] == txscript.OP_SUPPORTCLAIM, } } } @@ -3548,7 +3706,7 @@ func handleStop(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter case s.requestProcessShutdown <- struct{}{}: default: } - return "btcd stopping.", nil + return "lbcd stopping.", nil } // handleSubmitBlock implements the submitblock command. @@ -3756,7 +3914,7 @@ func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{ // NOTE: This is a btcsuite extension ported from github.com/decred/dcrd. func handleVersion(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { result := map[string]btcjson.VersionResult{ - "btcdjsonrpcapi": { + "lbcdjsonrpcapi": { VersionString: jsonrpcSemverString, Major: jsonrpcSemverMajor, Minor: jsonrpcSemverMinor, @@ -4350,7 +4508,7 @@ func (s *rpcServer) jsonRPCRead(w http.ResponseWriter, r *http.Request, isAdmin // jsonAuthFail sends a message back to the client if the http auth is rejected. func jsonAuthFail(w http.ResponseWriter) { - w.Header().Add("WWW-Authenticate", `Basic realm="btcd RPC"`) + w.Header().Add("WWW-Authenticate", `Basic realm="lbcd RPC"`) http.Error(w, "401 Unauthorized.", http.StatusUnauthorized) } @@ -4431,7 +4589,7 @@ func (s *rpcServer) Start() { func genCertPair(certFile, keyFile string) error { rpcsLog.Infof("Generating TLS certificates...") - org := "btcd autogenerated cert" + org := "lbcd autogenerated cert" validUntil := time.Now().Add(10 * 365 * 24 * time.Hour) cert, key, err := btcutil.NewTLSCertPair(org, validUntil, nil) if err != nil { @@ -4582,6 +4740,9 @@ type rpcserverConfig struct { // connection-related data and tasks. ConnMgr rpcserverConnManager + // AddrMgr is the server's instance of the AddressManager. + AddrMgr *addrmgr.AddrManager + // SyncMgr defines the sync manager for the RPC server to use. SyncMgr rpcserverSyncManager @@ -4612,6 +4773,9 @@ type rpcserverConfig struct { // The fee estimator keeps track of how long transactions are left in // the mempool before they are mined into blocks. FeeEstimator *mempool.FeeEstimator + + // Services represents the services supported by this node. + Services wire.ServiceFlag } // newRPCServer returns a new instance of the rpcServer struct. diff --git a/rpcserverhelp.go b/rpcserverhelp.go index ac0bf42d..a124e492 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -454,6 +454,27 @@ var helpDescsEnUS = map[string]string{ "getnetworkhashps-height": "Perform estimate ending with this height or -1 for current best chain block height", "getnetworkhashps--result0": "Estimated hashes per second", + // GetNetworkInfo help. + "getnetworkinfo--synopsis": "Returns an object containing various state info regarding P2P networking.", + "getnetworkinfo--result0--desc": "GetNetworkInfo object", + "getnetworkinfo--result0--key": "Field name", + "getnetworkinfo--result0--value": "Object containing the network info", + + // GetNetworkInfoResult help. + "getnetworkinforesult-version": "The server version", + "getnetworkinforesult-subversion": "The server subversion string", + "getnetworkinforesult-protocolversion": "The protocol version", + "getnetworkinforesult-localservices": "The services we offer to the network", + "getnetworkinforesult-localrelay": "True if transaction relay is requested from peers", + "getnetworkinforesult-timeoffset": "The time offset", + "getnetworkinforesult-connections": "The number of connections", + "getnetworkinforesult-networkactive": "Whether p2p networking is enabled", + "getnetworkinforesult-networks": "Information per network", + "getnetworkinforesult-relayfee": "Minimum relay fee for transactions in BTC/kB", + "getnetworkinforesult-incrementalfee": "Minimum fee increment for mempool limiting or BIP 125 replacement in BTC/kB", + "getnetworkinforesult-localaddresses": "List of local addresses", + "getnetworkinforesult-warnings": "Any network and blockchain warnings", + // GetNetTotalsCmd help. "getnettotals--synopsis": "Returns a JSON object containing network traffic statistics.", @@ -819,6 +840,7 @@ var rpcResultTypes = map[string][]interface{}{ "getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)}, "getnettotals": {(*btcjson.GetNetTotalsResult)(nil)}, "getnetworkhashps": {(*int64)(nil)}, + "getnetworkinfo": {(*map[string]btcjson.GetNetworkInfoResult)(nil)}, "getnodeaddresses": {(*[]btcjson.GetNodeAddressesResult)(nil)}, "getpeerinfo": {(*[]btcjson.GetPeerInfoResult)(nil)}, "getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)}, diff --git a/server.go b/server.go index 690f6ceb..02e47e7f 100644 --- a/server.go +++ b/server.go @@ -2952,6 +2952,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, Listeners: rpcListeners, StartupTime: s.startupTime, ConnMgr: &rpcConnManager{&s}, + AddrMgr: amgr, SyncMgr: &rpcSyncMgr{&s, s.syncManager}, TimeSource: s.timeSource, Chain: s.chain, @@ -2964,6 +2965,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, AddrIndex: s.addrIndex, CfIndex: s.cfIndex, FeeEstimator: s.feeEstimator, + Services: s.services, }) if err != nil { return nil, err diff --git a/version.go b/version.go index d6ff9171..23f1f3de 100644 --- a/version.go +++ b/version.go @@ -57,6 +57,11 @@ func version() string { return version } +// Numeric returns the application version as an integer. +func versionNumeric() int32 { + return int32(2 ^ appMajor*3 ^ appMinor*5 ^ appPatch) +} + // normalizeVerString returns the passed string stripped of all characters which // are not valid according to the semantic versioning guidelines for pre-release // version and build metadata strings. In particular they MUST only contain -- 2.45.2 From a76bc2b828ed6dbc702ed9a831c0549404a266a5 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 28 Oct 2021 16:29:03 -0400 Subject: [PATCH 144/459] [lbry] rpc: import invalidate/reconsiderblock from bchd --- blockchain/chain.go | 109 ++++++++++++++++++++++++++++++++++++++++++ blockchain/process.go | 34 +++++++------ rpcserver.go | 28 ++++++++++- rpcserverhelp.go | 10 ++++ 4 files changed, 165 insertions(+), 16 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index 66c435d8..c829b61c 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1641,6 +1641,115 @@ func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Has return headers } +// InvalidateBlock takes a block hash and invalidates it. +// +// This function is safe for concurrent access. +func (b *BlockChain) InvalidateBlock(hash *chainhash.Hash) error { + return b.invalidateBlock(hash) +} + +// invalidateBlock takes a block hash and invalidates it. +func (b *BlockChain) invalidateBlock(hash *chainhash.Hash) error { + node := b.index.LookupNode(hash) + if node == nil { + err := fmt.Errorf("block %s is not known", hash) + return err + } + + // No need to invalidate if its already invalid. + if node.status.KnownInvalid() { + err := fmt.Errorf("block %s is already invalid", hash) + return err + } + + if node.parent == nil { + err := fmt.Errorf("block %s has no parent", hash) + return err + } + + b.index.SetStatusFlags(node, statusValidateFailed) + b.index.UnsetStatusFlags(node, statusValid) + + b.chainLock.Lock() + defer b.chainLock.Unlock() + detachNodes, attachNodes := b.getReorganizeNodes(node.parent) + + err := b.reorganizeChain(detachNodes, attachNodes) + if err != nil { + return err + } + + for i, e := 0, detachNodes.Front(); e != nil; i, e = i+1, e.Next() { + n := e.Value.(*blockNode) + + b.index.SetStatusFlags(n, statusInvalidAncestor) + b.index.UnsetStatusFlags(n, statusValid) + } + + if writeErr := b.index.flushToDB(); writeErr != nil { + log.Warnf("Error flushing block index changes to disk: %v", writeErr) + } + + return nil +} + +// ReconsiderBlock takes a block hash and allows it to be revalidated. +// +// This function is safe for concurrent access. +func (b *BlockChain) ReconsiderBlock(hash *chainhash.Hash) error { + return b.reconsiderBlock(hash) +} + +// reconsiderBlock takes a block hash and allows it to be revalidated. +func (b *BlockChain) reconsiderBlock(hash *chainhash.Hash) error { + node := b.index.LookupNode(hash) + if node == nil { + err := fmt.Errorf("block %s is not known", hash) + return err + } + + // No need to reconsider, it is already valid. + if node.status.KnownValid() { + err := fmt.Errorf("block %s is already valid", hash) + return err + } + + // Keep a reference to the first node in the chain of invalid + // blocks so we can reprocess after status flags are updated. + firstNode := node + + // Find previous node to the point where the blocks are valid again. + for n := node; n.status.KnownInvalid(); n = n.parent { + b.index.UnsetStatusFlags(n, statusInvalidAncestor) + b.index.UnsetStatusFlags(n, statusValidateFailed) + + firstNode = n + } + + var blk *btcutil.Block + err := b.db.View(func(dbTx database.Tx) error { + var err error + blk, err = dbFetchBlockByNode(dbTx, firstNode) + return err + }) + if err != nil { + return err + } + + // Process it all again. This will take care of the + // orphans as well. + _, _, err = b.ProcessBlock(blk, BFNoDupBlockCheck) + if err != nil { + return err + } + + if writeErr := b.index.flushToDB(); writeErr != nil { + log.Warnf("Error flushing block index changes to disk: %v", writeErr) + } + + return nil +} + // ClaimTrie returns the claimTrie associated wit hthe chain. func (b *BlockChain) ClaimTrie() *claimtrie.ClaimTrie { return b.claimTrie diff --git a/blockchain/process.go b/blockchain/process.go index a48b6e50..8aaa91bc 100644 --- a/blockchain/process.go +++ b/blockchain/process.go @@ -29,6 +29,10 @@ const ( // not be performed. BFNoPoWCheck + // BFNoDupBlockCheck signals if the block should skip existence + // checks. + BFNoDupBlockCheck + // BFNone is a convenience value to specifically indicate no flags. BFNone BehaviorFlags = 0 ) @@ -148,24 +152,26 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo blockHash := block.Hash() log.Tracef("Processing block %v", blockHash) - // The block must not already exist in the main chain or side chains. - exists, err := b.blockExists(blockHash) - if err != nil { - return false, false, err - } - if exists { - str := fmt.Sprintf("already have block %v", blockHash) - return false, false, ruleError(ErrDuplicateBlock, str) - } + if flags&BFNoDupBlockCheck != BFNoDupBlockCheck { + // The block must not already exist in the main chain or side chains. + exists, err := b.blockExists(blockHash) + if err != nil { + return false, false, err + } + if exists { + str := fmt.Sprintf("already have block %v", blockHash) + return false, false, ruleError(ErrDuplicateBlock, str) + } - // The block must not already exist as an orphan. - if _, exists := b.orphans[*blockHash]; exists { - str := fmt.Sprintf("already have block (orphan) %v", blockHash) - return false, false, ruleError(ErrDuplicateBlock, str) + // The block must not already exist as an orphan. + if _, exists := b.orphans[*blockHash]; exists { + str := fmt.Sprintf("already have block (orphan) %v", blockHash) + return false, false, ruleError(ErrDuplicateBlock, str) + } } // Perform preliminary sanity checks on the block and its transactions. - err = checkBlockSanity(block, b.chainParams.PowLimit, b.timeSource, flags) + err := checkBlockSanity(block, b.chainParams.PowLimit, b.timeSource, flags) if err != nil { return false, false, err } diff --git a/rpcserver.go b/rpcserver.go index 5c20436d..4797d64f 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -168,8 +168,10 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getrawtransaction": handleGetRawTransaction, "gettxout": handleGetTxOut, "help": handleHelp, + "invalidateblock": handleInvalidateBlock, "node": handleNode, "ping": handlePing, + "reconsiderblock": handleReconsiderBlock, "searchrawtransactions": handleSearchRawTransactions, "sendrawtransaction": handleSendRawTransaction, "setgenerate": handleSetGenerate, @@ -237,9 +239,7 @@ var rpcUnimplemented = map[string]struct{}{ "getchaintips": {}, "getmempoolentry": {}, "getwork": {}, - "invalidateblock": {}, "preciousblock": {}, - "reconsiderblock": {}, } // Commands that are available to a limited user @@ -2977,6 +2977,30 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i return txOutReply, nil } +// handleInvalidateBlock implements the invalidateblock command +func handleInvalidateBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.InvalidateBlockCmd) + + hash, err := chainhash.NewHashFromStr(c.BlockHash) + if err != nil { + return nil, err + } + + return nil, s.cfg.Chain.InvalidateBlock(hash) +} + +// handleReconsiderBlock implements the reconsiderblock command +func handleReconsiderBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.ReconsiderBlockCmd) + + hash, err := chainhash.NewHashFromStr(c.BlockHash) + if err != nil { + return nil, err + } + + return nil, s.cfg.Chain.ReconsiderBlock(hash) +} + // handleHelp implements the help command. func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*btcjson.HelpCmd) diff --git a/rpcserverhelp.go b/rpcserverhelp.go index a124e492..038b3495 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -568,10 +568,18 @@ var helpDescsEnUS = map[string]string{ "help--result0": "List of commands", "help--result1": "Help for specified command", + // InvalidateBlockCmd + "invalidateblock--synopsis": "Invalidate a block.", + "invalidateblock-blockhash": "Hash of the block you want to invalidate", + // PingCmd help. "ping--synopsis": "Queues a ping to be sent to each connected peer.\n" + "Ping times are provided by getpeerinfo via the pingtime and pingwait fields.", + // ReconsiderBlockCmd + "reconsiderblock--synopsis": "Reconsider a block for validation.", + "reconsiderblock-blockhash": "Hash of the block you want to reconsider", + // SearchRawTransactionsCmd help. "searchrawtransactions--synopsis": "Returns raw data for transactions involving the passed address.\n" + "Returned transactions are pulled from both the database, and transactions currently in the mempool.\n" + @@ -848,7 +856,9 @@ var rpcResultTypes = map[string][]interface{}{ "gettxout": {(*btcjson.GetTxOutResult)(nil)}, "node": nil, "help": {(*string)(nil), (*string)(nil)}, + "invalidateblock": nil, "ping": nil, + "reconsiderblock": nil, "searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)}, "sendrawtransaction": {(*string)(nil)}, "setgenerate": nil, -- 2.45.2 From 3fde64cd63f59dd545237d70e2e466c011bd73f6 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 28 Oct 2021 21:58:57 -0400 Subject: [PATCH 145/459] [lbry] rpc: added getchaintips RPC remove btcjson dep in chainquery --- blockchain/chainquery.go | 123 +++++++++++++++++++++++++++++++++++++ btcjson/chainsvrresults.go | 8 +++ rpcserver.go | 11 ++++ rpcserverhelp.go | 17 +++++ 4 files changed, 159 insertions(+) create mode 100644 blockchain/chainquery.go diff --git a/blockchain/chainquery.go b/blockchain/chainquery.go new file mode 100644 index 00000000..162a1d47 --- /dev/null +++ b/blockchain/chainquery.go @@ -0,0 +1,123 @@ +package blockchain + +import ( + "sort" + "strings" + + btcutil "github.com/lbryio/lbcutil" +) + +type ChainTip struct { // duplicate of btcjson.GetChainTipsResult to avoid circular reference + Height int64 + Hash string + BranchLen int64 + Status string +} + +// nodeHeightSorter implements sort.Interface to allow a slice of nodes to +// be sorted by height in ascending order. +type nodeHeightSorter []ChainTip + +// Len returns the number of nodes in the slice. It is part of the +// sort.Interface implementation. +func (s nodeHeightSorter) Len() int { + return len(s) +} + +// Swap swaps the nodes at the passed indices. It is part of the +// sort.Interface implementation. +func (s nodeHeightSorter) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Less returns whether the node with index i should sort before the node with +// index j. It is part of the sort.Interface implementation. +func (s nodeHeightSorter) Less(i, j int) bool { + // To ensure stable order when the heights are the same, fall back to + // sorting based on hash. + if s[i].Height == s[j].Height { + return strings.Compare(s[i].Hash, s[j].Hash) < 0 + } + return s[i].Height < s[j].Height +} + +// ChainTips returns information, in JSON-RPC format, about all the currently +// known chain tips in the block index. +func (b *BlockChain) ChainTips() []ChainTip { + // we need our current tip + // we also need all of our orphans that aren't in the prevOrphans + var results []ChainTip + + tip := b.bestChain.Tip() + results = append(results, ChainTip{ + Height: int64(tip.height), + Hash: tip.hash.String(), + BranchLen: 0, + Status: "active", + }) + + b.orphanLock.RLock() + defer b.orphanLock.RUnlock() + + notInBestChain := func(block *btcutil.Block) bool { + node := b.bestChain.NodeByHeight(block.Height()) + if node == nil { + return false + } + return node.hash.IsEqual(block.Hash()) + } + + for hash, orphan := range b.orphans { + if len(b.prevOrphans[hash]) > 0 { + continue + } + fork := orphan.block + for fork != nil && notInBestChain(fork) { + fork = b.orphans[*fork.Hash()].block + } + + result := ChainTip{ + Height: int64(orphan.block.Height()), + Hash: hash.String(), + BranchLen: int64(orphan.block.Height() - fork.Height()), + } + + // Determine the status of the chain tip. + // + // active: + // The current best chain tip. + // + // invalid: + // The block or one of its ancestors is invalid. + // + // headers-only: + // The block or one of its ancestors does not have the full block data + // available which also means the block can't be validated or + // connected. + // + // valid-fork: + // The block is fully validated which implies it was probably part of + // main chain at one point and was reorganized. + // + // valid-headers: + // The full block data is available and the header is valid, but the + // block was never validated which implies it was probably never part + // of the main chain. + tipStatus := b.index.LookupNode(&hash).status + if tipStatus.KnownInvalid() { + result.Status = "invalid" + } else if !tipStatus.HaveData() { + result.Status = "headers-only" + } else if tipStatus.KnownValid() { + result.Status = "valid-fork" + } else { + result.Status = "valid-headers" + } + + results = append(results, result) + } + + // Generate the results sorted by descending height. + sort.Sort(sort.Reverse(nodeHeightSorter(results))) + return results +} diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 46d454c5..811883c7 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -325,6 +325,14 @@ type GetMempoolEntryResult struct { Depends []string `json:"depends"` } +// GetChainTipsResult models the data returns from the getchaintips command. +type GetChainTipsResult struct { + Height int64 `json:"height"` + Hash string `json:"hash"` + BranchLen int64 `json:"branchlen"` + Status string `json:"status"` +} + // GetMempoolInfoResult models the data returned from the getmempoolinfo // command. type GetMempoolInfoResult struct { diff --git a/rpcserver.go b/rpcserver.go index 4797d64f..6cfb962a 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -147,6 +147,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getblockcount": handleGetBlockCount, "getblockhash": handleGetBlockHash, "getblockheader": handleGetBlockHeader, + "getchaintips": handleGetChainTips, "getblocktemplate": handleGetBlockTemplate, "getcfilter": handleGetCFilter, "getcfilterheader": handleGetCFilterHeader, @@ -1471,6 +1472,16 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct return blockHeaderReply, nil } +// handleGetChainTips implements the getchaintips command. +func handleGetChainTips(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + tips := s.cfg.Chain.ChainTips() + results := make([]btcjson.GetChainTipsResult, 0, len(tips)) + for _, tip := range tips { + results = append(results, btcjson.GetChainTipsResult(tip)) + } + return results, nil +} + // encodeTemplateID encodes the passed details into an ID that can be used to // uniquely identify a block template. func encodeTemplateID(prevHash *chainhash.Hash, lastGenerated time.Time) string { diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 038b3495..acc71212 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -353,6 +353,22 @@ var helpDescsEnUS = map[string]string{ "getblocktemplate--condition2": "mode=proposal, accepted", "getblocktemplate--result1": "An error string which represents why the proposal was rejected or nothing if accepted", + // GetChainTips help. + "getchaintips--synopsis": "Returns information about all known chain tips the in the block tree.\n\n" + + "The statuses in the result have the following meanings:\n" + + "active: The current best chain tip.\n" + + "invalid: The block or one of its ancestors is invalid.\n" + + "headers-only: The block or one of its ancestors does not have the full block data available which also means the block can't be validated or connected.\n" + + "valid-fork: The block is fully validated which implies it was probably part of the main chain at one point and was reorganized.\n" + + "valid-headers: The full block data is available and the header is valid, but the block was never validated which implies it was probably never part of the main chain.", + + // GetChainTipsResult help. + "getchaintipsresult-height": "The height of the chain tip", + "getchaintipsresult-hash": "The block hash of the chain tip", + "getchaintipsresult-branchlen": "The length of the branch that connects the tip to the main chain (0 for the main chain tip)", + "getchaintipsresult-status": "The status of the chain (active, invalid, headers-only, valid-fork, valid-headers)", + "getchaintipsresults--result0": "test", + // GetCFilterCmd help. "getcfilter--synopsis": "Returns a block's committed filter given its hash.", "getcfilter-filtertype": "The type of filter to return (0=regular)", @@ -837,6 +853,7 @@ var rpcResultTypes = map[string][]interface{}{ "getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)}, "getcfilter": {(*string)(nil)}, "getcfilterheader": {(*string)(nil)}, + "getchaintips": {(*[]btcjson.GetChainTipsResult)(nil)}, "getconnectioncount": {(*int32)(nil)}, "getcurrentnet": {(*uint32)(nil)}, "getdifficulty": {(*float64)(nil)}, -- 2.45.2 From 9ae7b95c85a0f61e27a547d1bf7ca7b90e9b2380 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 19 Aug 2021 14:41:48 -0400 Subject: [PATCH 146/459] [lbry] rpc, mining: calculate claimtrie root hash for generate RPC --- mining/mining.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mining/mining.go b/mining/mining.go index 4daad1a6..6eb00316 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -843,6 +843,11 @@ mempoolLoop: // chain with no issues. block := btcutil.NewBlock(&msgBlock) block.SetHeight(nextBlockHeight) + + if err := g.chain.SetClaimtrieHeader(block, blockUtxos); err != nil { + return nil, err + } + if err := g.chain.CheckConnectBlockTemplate(block); err != nil { return nil, err } -- 2.45.2 From 96846fef20d40981553f20d7ed2122e33a9852eb Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 19 Aug 2021 16:39:53 -0400 Subject: [PATCH 147/459] [lbry] rpc, mining: fix generatetoaddress --- mining/cpuminer/cpuminer.go | 9 +++++---- rpcserverhelp.go | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mining/cpuminer/cpuminer.go b/mining/cpuminer/cpuminer.go index b9d1d222..64cfaf50 100644 --- a/mining/cpuminer/cpuminer.go +++ b/mining/cpuminer/cpuminer.go @@ -274,7 +274,7 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, blockHeight int32, // increment the number of hashes completed for each // attempt accordingly. header.Nonce = i - hash := header.BlockHash() + hash := header.BlockPoWHash() hashesCompleted += 2 // The block is solved when the new block hash is less @@ -544,7 +544,7 @@ func (m *CPUMiner) NumWorkers() int32 { // detecting when it is performing stale work and reacting accordingly by // generating a new block template. When a block is solved, it is submitted. // The function returns a list of the hashes of generated blocks. -func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) { +func (m *CPUMiner) GenerateNBlocks(n uint32, payToAddr btcutil.Address) ([]*chainhash.Hash, error) { m.Lock() // Respond with an error if server is already mining. @@ -590,8 +590,9 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) { // Choose a payment address at random. rand.Seed(time.Now().UnixNano()) - payToAddr := m.cfg.MiningAddrs[rand.Intn(len(m.cfg.MiningAddrs))] - + if payToAddr == nil { + payToAddr = m.cfg.MiningAddrs[rand.Intn(len(m.cfg.MiningAddrs))] + } // Create a new block template using the available transactions // in the memory pool as a source of transactions to potentially // include in the block. diff --git a/rpcserverhelp.go b/rpcserverhelp.go index acc71212..2d191649 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -842,6 +842,7 @@ var rpcResultTypes = map[string][]interface{}{ "decodescript": {(*btcjson.DecodeScriptResult)(nil)}, "estimatefee": {(*float64)(nil)}, "generate": {(*[]string)(nil)}, + "generatetoaddress": {(*[]string)(nil)}, "getaddednodeinfo": {(*[]string)(nil), (*[]btcjson.GetAddedNodeInfoResult)(nil)}, "getbestblock": {(*btcjson.GetBestBlockResult)(nil)}, "getbestblockhash": {(*string)(nil)}, -- 2.45.2 From 276a6141c785cfdccb0cde9fadd3e18cfbf8fbdd Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 9 Nov 2021 15:50:02 -0500 Subject: [PATCH 148/459] [lbry] rpc: made estimatesmartfee call estimatefee (for now) --- rpcserver.go | 24 +++++++++++++++++++++--- rpcserverhelp.go | 12 +++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 6cfb962a..195d1c6c 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -137,6 +137,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "decoderawtransaction": handleDecodeRawTransaction, "decodescript": handleDecodeScript, "estimatefee": handleEstimateFee, + "estimatesmartfee": handleEstimateSmartFee, "generate": handleGenerate, "generatetoaddress": handleGenerateToAddress, "getaddednodeinfo": handleGetAddedNodeInfo, @@ -879,23 +880,40 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) c := cmd.(*btcjson.EstimateFeeCmd) if s.cfg.FeeEstimator == nil { - return nil, errors.New("Fee estimation disabled") + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: "Fee estimation disabled", + } } if c.NumBlocks <= 0 { - return -1.0, errors.New("Parameter NumBlocks must be positive") + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Parameter NumBlocks must be positive", + } } feeRate, err := s.cfg.FeeEstimator.EstimateFee(uint32(c.NumBlocks)) if err != nil { - return -1.0, err + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: err.Error(), + } } // Convert to satoshis per kb. return float64(feeRate), nil } +func handleEstimateSmartFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.EstimateSmartFeeCmd) + + rpcsLog.Debugf("EstimateSmartFee is not implemented; falling back to EstimateFee. Requested mode: %s", c.EstimateMode) + + return handleEstimateFee(s, &btcjson.EstimateFeeCmd{NumBlocks: c.ConfTarget}, closeChan) +} + func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { // Respond with an error if there are no addresses to pay the // created blocks to. diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 2d191649..881cfeb5 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -123,9 +123,18 @@ var helpDescsEnUS = map[string]string{ "blocks have been generated.", "estimatefee-numblocks": "The maximum number of blocks which can be " + "generated before the transaction is mined.", - "estimatefee--result0": "Estimated fee per kilobyte in satoshis for a block to " + + "estimatefee--result0": "Estimated fee per kilobyte in satoshis necessary for a block to " + "be mined in the next NumBlocks blocks.", + "estimatesmartfee--synopsis": "Estimate the fee per kilobyte in satoshis " + + "required for a transaction to be mined before a certain number of " + + "blocks have been generated. Same as estimatefee presently.", + "estimatesmartfee-conftarget": "The maximum number of blocks which can be " + + "generated before the transaction is mined.", + "estimatesmartfee-estimatemode": "Unused at present.", + "estimatesmartfee--result0": "Estimated fee per kilobyte in satoshis necessary for a block to " + + "be mined in the next ConfTarget blocks.", + // GenerateCmd help "generate--synopsis": "Generates a set number of blocks (simnet or regtest only) and returns a JSON\n" + " array of their hashes.", @@ -841,6 +850,7 @@ var rpcResultTypes = map[string][]interface{}{ "decoderawtransaction": {(*btcjson.TxRawDecodeResult)(nil)}, "decodescript": {(*btcjson.DecodeScriptResult)(nil)}, "estimatefee": {(*float64)(nil)}, + "estimatesmartfee": {(*float64)(nil)}, "generate": {(*[]string)(nil)}, "generatetoaddress": {(*[]string)(nil)}, "getaddednodeinfo": {(*[]string)(nil), (*[]btcjson.GetAddedNodeInfoResult)(nil)}, -- 2.45.2 From c87ce562418fc674bf0c5b367800588f34c2cb5a Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Fri, 29 Oct 2021 16:21:54 -0400 Subject: [PATCH 149/459] [lbry] rpc: make uptime rpc return a real uptime --- server.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/server.go b/server.go index 02e47e7f..84cb0be2 100644 --- a/server.go +++ b/server.go @@ -205,7 +205,6 @@ type server struct { started int32 shutdown int32 shutdownSched int32 - startupTime int64 chainParams *chaincfg.Params addrManager *addrmgr.AddrManager @@ -2373,9 +2372,6 @@ func (s *server) Start() { srvrLog.Trace("Starting server") - // Server startup time. Used for the uptime command for uptime calculation. - s.startupTime = time.Now().Unix() - // Start the peer handler which in turn starts the address and block // managers. s.wg.Add(1) @@ -2633,6 +2629,8 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, db database.DB, chainParams *chaincfg.Params, interrupt <-chan struct{}) (*server, error) { + startupTime := time.Now() + services := defaultServices if cfg.NoPeerBloomFilters { services &^= wire.SFNodeBloom @@ -2950,7 +2948,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, s.rpcServer, err = newRPCServer(&rpcserverConfig{ Listeners: rpcListeners, - StartupTime: s.startupTime, + StartupTime: startupTime.Unix(), ConnMgr: &rpcConnManager{&s}, AddrMgr: amgr, SyncMgr: &rpcSyncMgr{&s, s.syncManager}, -- 2.45.2 From c035acb6b21884c9238f9152272b94ecd2f92011 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 14 Dec 2021 15:28:28 -0500 Subject: [PATCH 150/459] [lbry] rpc: ladded claim related fields for wallet --- btcjson/walletsvrresults.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index 16df09bb..2b7354e7 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -25,7 +25,6 @@ type CreateWalletResult struct { type embeddedAddressInfo struct { Address string `json:"address"` ScriptPubKey string `json:"scriptPubKey"` - Solvable bool `json:"solvable"` Descriptor *string `json:"desc,omitempty"` IsScript bool `json:"isscript"` IsChange bool `json:"ischange"` @@ -229,6 +228,7 @@ type InfoWalletResult struct { PaytxFee float64 `json:"paytxfee"` RelayFee float64 `json:"relayfee"` Errors string `json:"errors"` + Staked float64 `json:"staked"` } // ListTransactionsResult models the data from the listtransactions command. @@ -293,7 +293,9 @@ type ListUnspentResult struct { RedeemScript string `json:"redeemScript,omitempty"` Amount float64 `json:"amount"` Confirmations int64 `json:"confirmations"` + Solvable bool `json:"solvable"` Spendable bool `json:"spendable"` + IsStake bool `json:"isstake"` } // SignRawTransactionError models the data that contains script verification -- 2.45.2 From 30f4bd6582653934c1b3ec9d371a793693470a86 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 12 Nov 2021 16:49:24 -0500 Subject: [PATCH 151/459] [lbry] rpc: added optional address type for getnewaddress --- btcjson/walletsvrcmds.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index e4d676ff..8569c1d5 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -242,7 +242,8 @@ func NewGetBalancesCmd() *GetBalancesCmd { // GetNewAddressCmd defines the getnewaddress JSON-RPC command. type GetNewAddressCmd struct { - Account *string + Account *string + AddressType *string // must be one of legacy / p2pkh or p2sh-p2wkh / p2sh-segwit, or p2wkh / bech32 } // NewGetNewAddressCmd returns a new instance which can be used to issue a -- 2.45.2 From 41472404c68946d05cd4448e1b021c18416f38ad Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 22:10:55 -0700 Subject: [PATCH 152/459] [lbry] enable segwit --- blockchain/merkle.go | 4 ++-- blockchain/weight.go | 4 ++-- netsync/manager.go | 9 ++++++++- peer/peer.go | 8 +++++++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/blockchain/merkle.go b/blockchain/merkle.go index 29479c1d..92b59c5e 100644 --- a/blockchain/merkle.go +++ b/blockchain/merkle.go @@ -230,8 +230,8 @@ func ValidateWitnessCommitment(blk *btcutil.Block) error { coinbaseWitness := coinbaseTx.MsgTx().TxIn[0].Witness if len(coinbaseWitness) != 1 { str := fmt.Sprintf("the coinbase transaction has %d items in "+ - "its witness stack when only one is allowed", - len(coinbaseWitness)) + "its witness stack when only one is allowed. Height: %d", + len(coinbaseWitness), blk.Height()) return ruleError(ErrInvalidWitnessCommitment, str) } witnessNonce := coinbaseWitness[0] diff --git a/blockchain/weight.go b/blockchain/weight.go index 9a3a10b3..7dc51b3f 100644 --- a/blockchain/weight.go +++ b/blockchain/weight.go @@ -20,11 +20,11 @@ const ( // weight of a "base" byte is 4, while the weight of a witness byte is // 1. As a result, for a block to be valid, the BlockWeight MUST be // less than, or equal to MaxBlockWeight. - MaxBlockWeight = 4000000 + MaxBlockWeight = 8000000 // MaxBlockBaseSize is the maximum number of bytes within a block // which can be allocated to non-witness data. - MaxBlockBaseSize = 2000000 + MaxBlockBaseSize = 8000000 // MaxBlockSigOpsCost is the maximum number of signature operations // allowed for a block. It is calculated via a weighted algorithm which diff --git a/netsync/manager.go b/netsync/manager.go index 2e3f05b0..69093610 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -1293,9 +1293,16 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) { break } } + + e := wire.BaseEncoding + // we think that the iv.Type set above is sufficient. If not: + // if peer.IsWitnessEnabled() { + // e = wire.WitnessEncoding + //} + state.requestQueue = requestQueue if len(gdmsg.InvList) > 0 { - peer.QueueMessage(gdmsg, nil) + peer.QueueMessageWithEncoding(gdmsg, nil, e) } } diff --git a/peer/peer.go b/peer/peer.go index ab8add08..ffedc6dc 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -2241,9 +2241,15 @@ func newPeerBase(origCfg *Config, inbound bool) *Peer { cfg.TrickleInterval = DefaultTrickleInterval } + encoding := wire.BaseEncoding + // we think this gets overwritten downstream. If not: + // if cfg.Services&wire.SFNodeWitness > 0 { + // encoding = wire.WitnessEncoding + //} + p := Peer{ inbound: inbound, - wireEncoding: wire.BaseEncoding, + wireEncoding: encoding, knownInventory: lru.NewCache(maxKnownInventory), stallControl: make(chan stallControlMsg, 1), // nonblocking sync outputQueue: make(chan outMsg, outputBufferSize), -- 2.45.2 From 0c8cf5dea0270868c198f56b8f8825e5a90edae1 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 30 Jul 2021 14:11:10 -0400 Subject: [PATCH 153/459] [lbry] upnp: switched upnp param to its opposite --- config.go | 2 +- server.go | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/config.go b/config.go index 748a626d..7b6b69f1 100644 --- a/config.go +++ b/config.go @@ -170,7 +170,7 @@ type config struct { TrickleInterval time.Duration `long:"trickleinterval" description:"Minimum time between attempts to send new inventory to a connected peer"` TxIndex bool `long:"txindex" description:"Maintain a full hash-based transaction index which makes all transactions available via the getrawtransaction RPC"` UserAgentComments []string `long:"uacomment" description:"Comment to add to the user agent -- See BIP 14 for more information."` - Upnp bool `long:"upnp" description:"Use UPnP to map our listening port outside of NAT"` + NoUpnp bool `long:"noupnp" description:"Don't use UPnP to map our listening port outside of NAT"` ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` Whitelists []string `long:"whitelist" description:"Add an IP network or IP that will not be banned. (eg. 192.168.1.0/24 or ::1)"` lookup func(string) ([]net.IP, error) diff --git a/server.go b/server.go index 84cb0be2..d0a7ad1c 100644 --- a/server.go +++ b/server.go @@ -3035,11 +3035,16 @@ func initListeners(amgr *addrmgr.AddrManager, listenAddrs []string, services wir } } } else { - if cfg.Upnp { + if !cfg.NoUpnp && !cfg.RegressionTest && !cfg.SimNet { var err error nat, err = Discover() if err != nil { - srvrLog.Warnf("Can't discover upnp: %v", err) + srvrLog.Infof("Can't discover UPnP-enabled device: %v", err) + } else { + address, err := nat.GetExternalAddress() + if err == nil && address != nil { + srvrLog.Infof("UPnP successfully registered on %s", address.String()) + } } // nil nat here is fine, just means no upnp on network. } -- 2.45.2 From ed5dd41a2a835e84f8f6d3c858d6b3e8454ad46f Mon Sep 17 00:00:00 2001 From: Brannon King Date: Mon, 9 Aug 2021 16:19:47 -0400 Subject: [PATCH 154/459] [lbry] upnp: brought in upnp fix from dcrd --- upnp.go | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/upnp.go b/upnp.go index c74e4ed7..402924f5 100644 --- a/upnp.go +++ b/upnp.go @@ -39,7 +39,7 @@ import ( "fmt" "net" "net/http" - "os" + "net/url" "strconv" "strings" "time" @@ -126,8 +126,9 @@ func Discover() (nat NAT, err error) { if err != nil { return } + var serviceIP string = getServiceIP(serviceURL) var ourIP string - ourIP, err = getOurIP() + ourIP, err = getOurIP(serviceIP) if err != nil { return } @@ -212,13 +213,22 @@ func getChildService(d *device, serviceType string) *service { return nil } -// getOurIP returns a best guess at what the local IP is. -func getOurIP() (ip string, err error) { - hostname, err := os.Hostname() - if err != nil { - return +func getServiceIP(serviceURL string) (routerIP string) { + url, _ := url.Parse(serviceURL) + return url.Hostname() +} + +// getOurIP returns the local IP that is on the same subnet as the serviceIP. +func getOurIP(serviceIP string) (ip string, err error) { + _, serviceNet, _ := net.ParseCIDR(serviceIP + "/24") + addrs, err := net.InterfaceAddrs() + for _, addr := range addrs { + ip, _, _ := net.ParseCIDR(addr.String()) + if serviceNet.Contains(ip) { + return ip.String(), nil + } } - return net.LookupCNAME(hostname) + return } // getServiceURL parses the xml description at the given root url to find the -- 2.45.2 From f73b79ae04c80eba844b6db3310d3833f3a0c450 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 19 Aug 2021 14:41:48 -0400 Subject: [PATCH 155/459] [lbry] test: fixed all current tests and delete three. Co-authored-by: Roy Lee --- blockchain/bench_test.go | 8 +- blockchain/chain_test.go | 96 ------- blockchain/common_test.go | 17 +- blockchain/difficulty.go | 7 +- blockchain/example_test.go | 2 +- blockchain/fullblocks_test.go | 2 +- blockchain/fullblocktests/generate.go | 12 +- blockchain/fullblocktests/params.go | 10 +- blockchain/merkle_test.go | 6 +- blockchain/notifications_test.go | 51 ---- blockchain/testdata/blk_0_to_4.dat.bz2 | Bin 1684 -> 0 bytes blockchain/testdata/blk_3A.dat.bz2 | Bin 801 -> 0 bytes blockchain/testdata/blk_4A.dat.bz2 | Bin 271 -> 0 bytes blockchain/testdata/blk_5A.dat.bz2 | Bin 480 -> 0 bytes blockchain/testdata/reorgtest.hex | 180 ------------- blockchain/validate_test.go | 343 +----------------------- btcjson/chainsvrcmds_test.go | 4 +- chaincfg/genesis.go | 46 +--- chaincfg/genesis_test.go | 244 ----------------- database/ffldb/interface_test.go | 23 +- database/ffldb/whitebox_test.go | 23 +- database/testdata/blocks1-256.bz2 | Bin 37555 -> 42273 bytes integration/bip0009_test.go | 5 +- integration/csv_fork_test.go | 11 +- integration/rpcserver_test.go | 1 + integration/rpctest/blockgen.go | 3 +- integration/rpctest/rpc_harness.go | 7 +- integration/rpctest/rpc_harness_test.go | 29 +- mempool/mempool_test.go | 2 +- mempool/policy.go | 5 + mempool/policy_test.go | 6 +- peer/peer_test.go | 4 +- txscript/data/script_tests.json | 37 +-- txscript/data/tx_invalid.json | 4 - txscript/example_test.go | 8 +- txscript/opcode_test.go | 12 + txscript/scriptbuilder_test.go | 11 +- wire/bench_test.go | 4 +- wire/blockheader.go | 2 +- wire/blockheader_test.go | 14 +- wire/common_test.go | 2 +- wire/message_test.go | 6 +- wire/msgblock_test.go | 42 ++- wire/msgheaders_test.go | 22 +- wire/msgmerkleblock_test.go | 36 ++- 45 files changed, 237 insertions(+), 1110 deletions(-) delete mode 100644 blockchain/notifications_test.go delete mode 100644 blockchain/testdata/blk_0_to_4.dat.bz2 delete mode 100644 blockchain/testdata/blk_3A.dat.bz2 delete mode 100644 blockchain/testdata/blk_4A.dat.bz2 delete mode 100644 blockchain/testdata/blk_5A.dat.bz2 delete mode 100644 blockchain/testdata/reorgtest.hex diff --git a/blockchain/bench_test.go b/blockchain/bench_test.go index 43d3152b..3246e653 100644 --- a/blockchain/bench_test.go +++ b/blockchain/bench_test.go @@ -6,14 +6,12 @@ package blockchain import ( "testing" - - "github.com/btcsuite/btcutil" ) // BenchmarkIsCoinBase performs a simple benchmark against the IsCoinBase // function. func BenchmarkIsCoinBase(b *testing.B) { - tx, _ := btcutil.NewBlock(&Block100000).Tx(1) + tx, _ := GetBlock100000().Tx(1) b.ResetTimer() for i := 0; i < b.N; i++ { IsCoinBase(tx) @@ -23,9 +21,9 @@ func BenchmarkIsCoinBase(b *testing.B) { // BenchmarkIsCoinBaseTx performs a simple benchmark against the IsCoinBaseTx // function. func BenchmarkIsCoinBaseTx(b *testing.B) { - tx := Block100000.Transactions[1] + tx, _ := GetBlock100000().Tx(1) b.ResetTimer() for i := 0; i < b.N; i++ { - IsCoinBaseTx(tx) + IsCoinBaseTx(tx.MsgTx()) } } diff --git a/blockchain/chain_test.go b/blockchain/chain_test.go index b2a155bc..2e77e578 100644 --- a/blockchain/chain_test.go +++ b/blockchain/chain_test.go @@ -15,102 +15,6 @@ import ( btcutil "github.com/lbryio/lbcutil" ) -// TestHaveBlock tests the HaveBlock API to ensure proper functionality. -func TestHaveBlock(t *testing.T) { - // Load up blocks such that there is a side chain. - // (genesis block) -> 1 -> 2 -> 3 -> 4 - // \-> 3a - testFiles := []string{ - "blk_0_to_4.dat.bz2", - "blk_3A.dat.bz2", - } - - var blocks []*btcutil.Block - for _, file := range testFiles { - blockTmp, err := loadBlocks(file) - if err != nil { - t.Errorf("Error loading file: %v\n", err) - return - } - blocks = append(blocks, blockTmp...) - } - - // Create a new database and chain instance to run tests against. - chain, teardownFunc, err := chainSetup("haveblock", - &chaincfg.MainNetParams) - if err != nil { - t.Errorf("Failed to setup chain instance: %v", err) - return - } - defer teardownFunc() - - // Since we're not dealing with the real block chain, set the coinbase - // maturity to 1. - chain.TstSetCoinbaseMaturity(1) - - for i := 1; i < len(blocks); i++ { - _, isOrphan, err := chain.ProcessBlock(blocks[i], BFNone) - if err != nil { - t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) - return - } - if isOrphan { - t.Errorf("ProcessBlock incorrectly returned block %v "+ - "is an orphan\n", i) - return - } - } - - // Insert an orphan block. - _, isOrphan, err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), - BFNone) - if err != nil { - t.Errorf("Unable to process block: %v", err) - return - } - if !isOrphan { - t.Errorf("ProcessBlock indicated block is an not orphan when " + - "it should be\n") - return - } - - tests := []struct { - hash string - want bool - }{ - // Genesis block should be present (in the main chain). - {hash: chaincfg.MainNetParams.GenesisHash.String(), want: true}, - - // Block 3a should be present (on a side chain). - {hash: "00000000474284d20067a4d33f6a02284e6ef70764a3a26d6a5b9df52ef663dd", want: true}, - - // Block 100000 should be present (as an orphan). - {hash: "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506", want: true}, - - // Random hashes should not be available. - {hash: "123", want: false}, - } - - for i, test := range tests { - hash, err := chainhash.NewHashFromStr(test.hash) - if err != nil { - t.Errorf("NewHashFromStr: %v", err) - continue - } - - result, err := chain.HaveBlock(hash) - if err != nil { - t.Errorf("HaveBlock #%d unexpected error: %v", i, err) - return - } - if result != test.want { - t.Errorf("HaveBlock #%d got %v want %v", i, result, - test.want) - continue - } - } -} - // TestCalcSequenceLock tests the LockTimeToSequence function, and the // CalcSequenceLock method of a Chain instance. The tests exercise several // combinations of inputs to the CalcSequenceLock function in order to ensure diff --git a/blockchain/common_test.go b/blockchain/common_test.go index 16ad6756..ae25889d 100644 --- a/blockchain/common_test.go +++ b/blockchain/common_test.go @@ -5,6 +5,7 @@ package blockchain import ( + "bytes" "compress/bzip2" "encoding/binary" "fmt" @@ -63,13 +64,13 @@ func isSupportedDbType(dbType string) bool { func loadBlocks(filename string) (blocks []*btcutil.Block, err error) { filename = filepath.Join("testdata/", filename) - var network = wire.MainNet + var network = 0xd9b4bef9 // bitcoin's network ID var dr io.Reader var fi io.ReadCloser fi, err = os.Open(filename) if err != nil { - return + return blocks, err } if strings.HasSuffix(filename, ".bz2") { @@ -95,7 +96,7 @@ func loadBlocks(filename string) (blocks []*btcutil.Block, err error) { break } if rintbuf != uint32(network) { - break + continue } err = binary.Read(dr, binary.LittleEndian, &rintbuf) blocklen := rintbuf @@ -105,14 +106,20 @@ func loadBlocks(filename string) (blocks []*btcutil.Block, err error) { // read block dr.Read(rbytes) + // inject claimtrie: + tail := make([]byte, len(rbytes)-68) + copy(tail, rbytes[68:]) + rbytes = append(rbytes[:68], bytes.Repeat([]byte{23}, chainhash.HashSize)...) + rbytes = append(rbytes, tail...) + block, err = btcutil.NewBlockFromBytes(rbytes) if err != nil { - return + return blocks, err } blocks = append(blocks, block) } - return + return blocks, err } // chainSetup is used to create a new db and chain instance with the genesis diff --git a/blockchain/difficulty.go b/blockchain/difficulty.go index 2f16e2e5..051998ba 100644 --- a/blockchain/difficulty.go +++ b/blockchain/difficulty.go @@ -245,10 +245,11 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim // Get the block node at the previous retarget (targetTimespan days // worth of blocks). - firstNode := lastNode.RelativeAncestor(b.blocksPerRetarget) - if lastNode.height == 0 { - firstNode = lastNode + blocksBack := b.blocksPerRetarget + if blocksBack > lastNode.height { + blocksBack = lastNode.height } + firstNode := lastNode.RelativeAncestor(blocksBack) if firstNode == nil { return 0, AssertError("unable to obtain previous retarget block") } diff --git a/blockchain/example_test.go b/blockchain/example_test.go index da0cce79..432602df 100644 --- a/blockchain/example_test.go +++ b/blockchain/example_test.go @@ -69,7 +69,7 @@ func ExampleBlockChain_ProcessBlock() { fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan) // Output: - // Failed to process block: already have block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f + // Failed to process block: already have block 9c89283ba0f3227f6c03b70216b9f665f0118d5e0fa729cedf4fb34d6a34f463 } // This example demonstrates how to convert the compact "bits" in a block header diff --git a/blockchain/fullblocks_test.go b/blockchain/fullblocks_test.go index 4c45c099..d7a7d7c2 100644 --- a/blockchain/fullblocks_test.go +++ b/blockchain/fullblocks_test.go @@ -139,7 +139,7 @@ func TestFullBlocks(t *testing.T) { // Create a new database and chain instance to run tests against. chain, teardownFunc, err := chainSetup("fullblocktest", - &chaincfg.RegressionNetParams) + fullblocktests.FbRegressionNetParams) if err != nil { t.Errorf("Failed to setup chain instance: %v", err) return diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index dc182a90..56f4601a 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -31,7 +31,7 @@ const ( // Intentionally defined here rather than using constants from codebase // to ensure consensus changes are detected. maxBlockSigOps = 20000 - maxBlockSize = 2000000 + maxBlockSize = 8000000 minCoinbaseScriptLen = 2 maxCoinbaseScriptLen = 100 medianTimeBlocks = 11 @@ -342,10 +342,8 @@ func solveBlock(header *wire.BlockHeader) bool { return default: hdr.Nonce = i - hash := hdr.BlockHash() - if blockchain.HashToBig(&hash).Cmp( - targetDifficulty) <= 0 { - + hash := hdr.BlockPoWHash() + if blockchain.HashToBig(&hash).Cmp(targetDifficulty) <= 0 { results <- sbResult{true, i} return } @@ -811,7 +809,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { // Create a test generator instance initialized with the genesis block // as the tip. - g, err := makeTestGenerator(regressionNetParams) + g, err := makeTestGenerator(FbRegressionNetParams) if err != nil { return nil, err } @@ -1444,7 +1442,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { // Keep incrementing the nonce until the hash treated as // a uint256 is higher than the limit. b46.Header.Nonce++ - blockHash := b46.BlockHash() + blockHash := b46.Header.BlockPoWHash() hashNum := blockchain.HashToBig(&blockHash) if hashNum.Cmp(g.params.PowLimit) >= 0 { break diff --git a/blockchain/fullblocktests/params.go b/blockchain/fullblocktests/params.go index fa23e841..d0463806 100644 --- a/blockchain/fullblocktests/params.go +++ b/blockchain/fullblocktests/params.go @@ -54,6 +54,7 @@ var ( Version: 1, PrevBlock: *newHashFromStr("0000000000000000000000000000000000000000000000000000000000000000"), MerkleRoot: *newHashFromStr("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"), + ClaimTrie: chainhash.Hash{1}, // EmptyTrieHash Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000] Nonce: 2, @@ -83,23 +84,25 @@ var ( LockTime: 0, }}, } + + regTestGenesisBlockHash = regTestGenesisBlock.BlockHash() ) -// regressionNetParams defines the network parameters for the regression test +// FbRegressionNetParams defines the network parameters for the regression test // network. // // NOTE: The test generator intentionally does not use the existing definitions // in the chaincfg package since the intent is to be able to generate known // good tests which exercise that code. Using the chaincfg parameters would // allow them to change out from under the tests potentially invalidating them. -var regressionNetParams = &chaincfg.Params{ +var FbRegressionNetParams = &chaincfg.Params{ Name: "regtest", Net: wire.TestNet, DefaultPort: "18444", // Chain parameters GenesisBlock: ®TestGenesisBlock, - GenesisHash: newHashFromStr("5bec7567af40504e0994db3b573c186fffcc4edefe096ff2e58d00523bd7e8a6"), + GenesisHash: ®TestGenesisBlockHash, PowLimit: regressionPowLimit, PowLimitBits: 0x207fffff, CoinbaseMaturity: 100, @@ -113,6 +116,7 @@ var regressionNetParams = &chaincfg.Params{ ReduceMinDifficulty: true, MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 GenerateSupported: true, + MinerConfirmationWindow: 1, // Checkpoints ordered from oldest to newest. Checkpoints: nil, diff --git a/blockchain/merkle_test.go b/blockchain/merkle_test.go index 275ffef3..c43ed281 100644 --- a/blockchain/merkle_test.go +++ b/blockchain/merkle_test.go @@ -6,16 +6,14 @@ package blockchain import ( "testing" - - "github.com/btcsuite/btcutil" ) // TestMerkle tests the BuildMerkleTreeStore API. func TestMerkle(t *testing.T) { - block := btcutil.NewBlock(&Block100000) + block := GetBlock100000() merkles := BuildMerkleTreeStore(block.Transactions(), false) calculatedMerkleRoot := merkles[len(merkles)-1] - wantMerkle := &Block100000.Header.MerkleRoot + wantMerkle := block.MsgBlock().Header.MerkleRoot if !wantMerkle.IsEqual(calculatedMerkleRoot) { t.Errorf("BuildMerkleTreeStore: merkle root mismatch - "+ "got %v, want %v", calculatedMerkleRoot, wantMerkle) diff --git a/blockchain/notifications_test.go b/blockchain/notifications_test.go deleted file mode 100644 index fde58735..00000000 --- a/blockchain/notifications_test.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2017 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package blockchain - -import ( - "testing" - - "github.com/btcsuite/btcd/chaincfg" -) - -// TestNotifications ensures that notification callbacks are fired on events. -func TestNotifications(t *testing.T) { - blocks, err := loadBlocks("blk_0_to_4.dat.bz2") - if err != nil { - t.Fatalf("Error loading file: %v\n", err) - } - - // Create a new database and chain instance to run tests against. - chain, teardownFunc, err := chainSetup("notifications", - &chaincfg.MainNetParams) - if err != nil { - t.Fatalf("Failed to setup chain instance: %v", err) - } - defer teardownFunc() - - notificationCount := 0 - callback := func(notification *Notification) { - if notification.Type == NTBlockAccepted { - notificationCount++ - } - } - - // Register callback multiple times then assert it is called that many - // times. - const numSubscribers = 3 - for i := 0; i < numSubscribers; i++ { - chain.Subscribe(callback) - } - - _, _, err = chain.ProcessBlock(blocks[1], BFNone) - if err != nil { - t.Fatalf("ProcessBlock fail on block 1: %v\n", err) - } - - if notificationCount != numSubscribers { - t.Fatalf("Expected notification callback to be executed %d "+ - "times, found %d", numSubscribers, notificationCount) - } -} diff --git a/blockchain/testdata/blk_0_to_4.dat.bz2 b/blockchain/testdata/blk_0_to_4.dat.bz2 deleted file mode 100644 index 274c710d275f032791bcbd4b463be9c1901b85ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1684 zcmV;F25b33T4*^jL0KkKS>X=}n*alCfB*mg|NsB~|NsC0|NsC0|Ns2||NsC0|NsC0 z|NsC0|M$=Y9t(Fm>CWv=ZMtEpNSUHxp$!c(Z3M^-0D77zBWYbXck0U6}AU2aVH2qV`dLgwvPe^%9G-UM$sLAC$Pg80Q9*m>ZdY(kc z(@#dHpifBk4^vN5z?wA;JtwA7hND2p(1o z=yg{qttlfz;)yXscsGR(5C)TK6Hpv_Pk>L|Z$1FW7sl#J#f5^EFk?RGk}2}OQHWmt zCkrKivn*Y95NXEdtS9#2ha(9rE7%A7=&0QG&d&pIMBeyzspkuNJ(?qSQ*WlrMpak8 z*#&ikj*8fm%)b*GMLucZmne_XVc-mAw}&pfrK$R9bk-2m>Pl|WZ6ypg0U`aLL?yLB zaglMf!D^hc6$a?m!JU$?PbMk6A+rg{oNcusEjSN_3N#`iplPsy*!(=L!Ig^nmLMgg zr!s^Vyw#5Tx<+i~CyKFzqBszwrEO;|Ty+a(TrGL#4C`@%f0QMQqcPHXNFpQ3;`w2A zw3ryzNfMdP7{fMQHwb{!)D_XvWvP`m(xa?NW0zD~ym1E)UUA%x*lSR76U4I?b7@RE z+hXztqDF1tCtThrVK$+c+%}C0sSaZI7XFbr_u8<8J-VqX9hn>H58bpWzK_K7IM4b7 z2|niAf9pH6Mb?Z=(h;bWKLE5W6R=Dq^33r~jta*kM+b~nJ~RY=*B8}?+XsY^p+wU$D*u+(fl02==XNV5 zazgd?ICllOR_iyij-Vav$@XDvA;60lopJ5pB~QnGFM_tk4EV7(wud8sxU&{_{T2kJ zs>Mq{NE8LxZ8JyGPh9fm{pN-~B+W$F@|W17K413j9EX`=oFW^>@3Dksc>`tQ@S_kCRq9#_IJ-KV=AoS`veBIfAfB;Zn=C8aiK zKF(x>$`mYn_m6Z*d_m+vjD#?mJzkjrp#KV;U2*>WFu2Z+5~v_6A-<1*TvK&L2f2bq>1VIw2fElyv7wSUV2wi| eLqeg%m7b@}t+ANUN4}&X{}*yaI8cz`4+)z-{1!U^ diff --git a/blockchain/testdata/blk_3A.dat.bz2 b/blockchain/testdata/blk_3A.dat.bz2 deleted file mode 100644 index 01266565d573ca0f7e7601d011fb4f98e243445a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 801 zcmV++1K#{XT4*^jL0KkKSvvUkH~;}T|NsBz_5c0;|L_05_I~^R?|c2;-~aRc|NsC0 z|NsB{fBe7!yv*vg#8pi;rf2{F00hXxK`;O&1i>&(F`xh=00009hJX>80$>0DWGA3Z zdWM0tjUJ#8R2l#P000dD000008UO$Q00E!?XaEL)Gyu>5GyniJGyoa}R5qXnhJer- z00001paVbvG&Ilv0000000E!|hJXM70004@rkVs()dWqFU;rje005W(695T-009p| z3Jk%wT+;0O$0FY!ne@1J8)9k90GOeZGInoM1&UY41q8TUM5S9l{fm}~XuF$g0*D{bOg6L;u&U>AFG>g9|;M&U> z1w|OguMnW1sS^dz91cXDHw_xR;eW~XC=|3qoP{edVW5%|YD6QM5zK{VS=8ad7%;1d zU~4^Rhb-VQrZcE9Ps0!X7C(3F9(fyu+l&#w%G;BTbA{&QHx6`P!%=P%#gtH^OVA-I zU0=IB4bB*n=X-fliQ7?Y1%y@<0Nvt5A3~51XAKg~+yUbLM1Vp-)MEMbrqxHDyC1NH z7!W1`ED$8}380;NL$K-BvBN}`5tR59j9nL^$p5T@?qBpcyuwz>6O2K)mibZ!0&YD7 z_s4+p_+ab}Gy#5e(@dU@Z%D-ChuU~&14RA!fF!Dd`cgP=NT~SjahqqpIK}{;HC~TT z2(ILkeuBLc?gM2zZY*x^7$rC=;p80^7A^UV-7;G;LGs%_hy~6qb f_`c&%W+X@o@c@qy4iiSpcZ<0qoG3^ge0v-K)fQGt diff --git a/blockchain/testdata/blk_4A.dat.bz2 b/blockchain/testdata/blk_4A.dat.bz2 deleted file mode 100644 index 19b409e752f37840b271e4e9f0b90dcd06e1cad3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271 zcmV+q0r37pT4*^jL0KkKS)#5T-T(kw|Nr)=P(OnG%3!|lLXNzfU?7AN6cRr~MVBQ2 zA0t9myXT+)lo>RJ)HG?4qfADgrVz=aL&yZgWZ0T&8X6v^L)7&eZ8XCv>8MpdQ2+rL z00A_>00000BLX&n000cEjyQmUh5!K)7oh+EqJZEaPB5`2`g%`}NewXJA%&J^c!3*M z$>&bK9{A*x-#>_1L8fteTKC-0?Cz6_@US3)f1n@oih|ATh}}(4Jy`UR58d*`H|r@9 zn^e@jIT!g%N-p)E1~|{dn8BDHZ~gm547v*zyOjpf)Jn$MfHXv+%N;`K))-t6TsWFQ05 zP|5&g8fefoGyr4_o>LZzc~ zp`#N(0j7qTG-v>6p`g*AX^7K602wj>FouSJ0i#BNrj1;cQ3j$xfC2yjL;;2u@c;+{ zmmo%n6kwkqz!};kMF*mNWE62tG=RVH)POU#z~VBHgOiEVpItH$l30xDGRXF!C4(!F zm2p{67q;92;Dsoa7tNZKHpsy7arVhE-@{}&c0R9zbN=av#Q`5aLQlstV5M*uJm_9Y z86x2&VkO?P4`X!KirXud5$d4O57oTkVI{TPp^6!Lon|}lzctd=a|8u7D^ip4@NQJ~ z_nL9s#MxZGz5`XDg8QmCNR3Wap_q`;|3sOV5M=z}Mz6txyzLMvx&+SI{NZ!vu^oW_ zKcRFYm;`k@0xyy)8C6JtU?Ql;?N1QXCWw(aH32%xW1Ud@xYp{1wLJJx?+;2#Ip0x+ W5)=|hP-7M^@pmLsg$WN38`vQD7Tcl# diff --git a/blockchain/testdata/reorgtest.hex b/blockchain/testdata/reorgtest.hex deleted file mode 100644 index 5b9e75e7..00000000 --- a/blockchain/testdata/reorgtest.hex +++ /dev/null @@ -1,180 +0,0 @@ -File path: reorgTest/blk_0_to_4.dat - -Block 0: - f9beb4d9 - 1d010000 - - 01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 3ba3edfd 7a7b12b2 7ac72c3e 67768f61 7fc81bc3 888a5132 3a9fb8aa - 4b1e5e4a 29ab5f49 ffff001d 1dac2b7c - 01 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff4d04ff ff001d01 04455468 65205469 6d657320 30332f4a - 616e2f32 30303920 4368616e 63656c6c 6f72206f 6e206272 696e6b20 6f662073 - 65636f6e 64206261 696c6f75 7420666f 72206261 6e6b73ff ffffff01 00f2052a - 01000000 43410467 8afdb0fe 55482719 67f1a671 30b7105c d6a828e0 3909a679 - 62e0ea1f 61deb649 f6bc3f4c ef38c4f3 5504e51e c112de5c 384df7ba 0b8d578a - 4c702b6b f11d5fac 00000000 -Block 1: - f9beb4d9 - d4000000 - - 01000000 6fe28c0a b6f1b372 c1a6a246 ae63f74f 931e8365 e15a089c 68d61900 - 00000000 3bbd67ad e98fbbb7 0718cd80 f9e9acf9 3b5fae91 7bb2b41d 4c3bb82c - 77725ca5 81ad5f49 ffff001d 44e69904 - 01 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff04722f 2e2bffff ffff0100 f2052a01 00000043 41046868 - 0737c76d abb801cb 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 - b5ac9e8b 4c9f49be 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ac00 - 000000 -Block 2: - f9beb4d9 - 95010000 - - 01000000 13ca7940 4c11c63e ca906bbd f190b751 2872b857 1b5143ae e8cb5737 - 00000000 fc07c983 d7391736 0aeda657 29d0d4d3 2533eb84 76ee9d64 aa27538f - 9b4fc00a d9af5f49 ffff001d 630bea22 - 02 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff04eb96 14e5ffff ffff0100 f2052a01 00000043 41046868 - 0737c76d abb801cb 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 - b5ac9e8b 4c9f49be 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ac00 - 000000 - - 01000000 0163451d 1002611c 1388d5ba 4ddfdf99 196a86b5 990fb5b0 dc786207 - 4fdcb8ee d2000000 004a4930 46022100 3dde52c6 5e339f45 7fe1015e 70eed208 - 872eb71e dd484c07 206b190e cb2ec3f8 02210011 c78dcfd0 3d43fa63 61242a33 - 6291ba2a 8c1ef5bc d5472126 2468f2bf 8dee4d01 ffffffff 0200ca9a 3b000000 - 001976a9 14cb2abd e8bccacc 32e893df 3a054b9e f7f227a4 ce88ac00 286bee00 - 00000019 76a914ee 26c56fc1 d942be8d 7a24b2a1 001dd894 69398088 ac000000 - 00 -Block 3: - f9beb4d9 - 96020000 - - 01000000 7d338254 0506faab 0d4cf179 45dda023 49db51f9 6233f24c 28002258 - 00000000 4806fe80 bf85931b 882ea645 77ca5a03 22bb8af2 3f277b20 55f160cd - 972c8e8b 31b25f49 ffff001d e8f0c653 - 03 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff044abd 8159ffff ffff0100 f2052a01 00000043 4104b95c - 249d84f4 17e3e395 a1274254 28b54067 1cc15881 eb828c17 b722a53f c599e21c - a5e56c90 f340988d 3933acc7 6beb832f d64cab07 8ddf3ce7 32923031 d1a8ac00 - 000000 - - 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb - bad253d3 77010000 008c4930 46022100 96ee0d02 b35fd61e 4960b44f f396f67e - 01fe17f9 de4e0c17 b6a963bd ab2b50a6 02210034 920d4daa 7e9f8abe 5675c931 - 495809f9 0b9c1189 d05fbaf1 dd6696a5 b0d8f301 41046868 0737c76d abb801cb - 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 b5ac9e8b 4c9f49be - 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ffff ffff0100 286bee00 - 00000019 76a914c5 22664fb0 e55cdc5c 0cea73b4 aad97ec8 34323288 ac000000 - 00 - - 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb - bad253d3 77000000 008c4930 46022100 b08b922a c4bde411 1c229f92 9fe6eb6a - 50161f98 1f4cf47e a9214d35 bf74d380 022100d2 f6640327 e677a1e1 cc474991 - b9a48ba5 bd1e0c94 d1c8df49 f7b0193b 7ea4fa01 4104b95c 249d84f4 17e3e395 - a1274254 28b54067 1cc15881 eb828c17 b722a53f c599e21c a5e56c90 f340988d - 3933acc7 6beb832f d64cab07 8ddf3ce7 32923031 d1a8ffff ffff0100 ca9a3b00 - 00000019 76a914c5 22664fb0 e55cdc5c 0cea73b4 aad97ec8 34323288 ac000000 - 00 - -Block 4: - f9beb4d9 - 73010000 - - 01000000 5da36499 06f35e09 9be42a1d 87b6dd42 11bc1400 6c220694 0807eaae - 00000000 48eeeaed 2d9d8522 e6201173 743823fd 4b87cd8a ca8e6408 ec75ca38 - 302c2ff0 89b45f49 ffff001d 00530839 - 02 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff04d41d 2213ffff ffff0100 f2052a01 00000043 4104678a - fdb0fe55 48271967 f1a67130 b7105cd6 a828e039 09a67962 e0ea1f61 deb649f6 - bc3f4cef 38c4f355 04e51ec1 12de5c38 4df7ba0b 8d578a4c 702b6bf1 1d5fac00 - 000000 - - 01000000 0163451d 1002611c 1388d5ba 4ddfdf99 196a86b5 990fb5b0 dc786207 - 4fdcb8ee d2000000 004a4930 46022100 8c8fd57b 48762135 8d8f3e69 19f33e08 - 804736ff 83db47aa 248512e2 6df9b8ba 022100b0 c59e5ee7 bfcbfcd1 a4d83da9 - 55fb260e fda7f42a 25522625 a3d6f2d9 1174a701 ffffffff 0100f205 2a010000 - 001976a9 14c52266 4fb0e55c dc5c0cea 73b4aad9 7ec83432 3288ac00 000000 - -File path: reorgTest/blk_3A.dat -Block 3A: - f9beb4d9 - 96020000 - - 01000000 7d338254 0506faab 0d4cf179 45dda023 49db51f9 6233f24c 28002258 - 00000000 5a15f573 1177a353 bdca7aab 20e16624 dfe90adc 70accadc 68016732 - 302c20a7 31b25f49 ffff001d 6a901440 - 03 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff04ad1b e7d5ffff ffff0100 f2052a01 00000043 4104ed83 - 704c95d8 29046f1a c2780621 1132102c 34e9ac7f fa1b7111 0658e5b9 d1bdedc4 - 16f5cefc 1db0625c d0c75de8 192d2b59 2d7e3b00 bcfb4a0e 860d880f d1fcac00 - 000000 - - 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb - bad253d3 77010000 008c4930 46022100 96ee0d02 b35fd61e 4960b44f f396f67e - 01fe17f9 de4e0c17 b6a963bd ab2b50a6 02210034 920d4daa 7e9f8abe 5675c931 - 495809f9 0b9c1189 d05fbaf1 dd6696a5 b0d8f301 41046868 0737c76d abb801cb - 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 b5ac9e8b 4c9f49be - 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ffff ffff0100 286bee00 - 00000019 76a914c5 22664fb0 e55cdc5c 0cea73b4 aad97ec8 34323288 ac000000 - 00 - - 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb - bad253d3 77000000 008c4930 46022100 9cc67ddd aa6f592a 6b2babd4 d6ff954f - 25a784cf 4fe4bb13 afb9f49b 08955119 022100a2 d99545b7 94080757 fcf2b563 - f2e91287 86332f46 0ec6b90f f085fb28 41a69701 4104b95c 249d84f4 17e3e395 - a1274254 28b54067 1cc15881 eb828c17 b722a53f c599e21c a5e56c90 f340988d - 3933acc7 6beb832f d64cab07 8ddf3ce7 32923031 d1a8ffff ffff0100 ca9a3b00 - 00000019 76a914ee 26c56fc1 d942be8d 7a24b2a1 001dd894 69398088 ac000000 - 00 - -File path: reorgTest/blk_4A.dat -Block 4A: - f9beb4d9 - d4000000 - - 01000000 aae77468 2205667d 4f413a58 47cc8fe8 9795f1d5 645d5b24 1daf3c92 - 00000000 361c9cde a09637a0 d0c05c3b 4e7a5d91 9edb184a 0a4c7633 d92e2ddd - f04cb854 89b45f49 ffff001d 9e9aa1e8 - 01 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff0401b8 f3eaffff ffff0100 f2052a01 00000043 4104678a - fdb0fe55 48271967 f1a67130 b7105cd6 a828e039 09a67962 e0ea1f61 deb649f6 - bc3f4cef 38c4f355 04e51ec1 12de5c38 4df7ba0b 8d578a4c 702b6bf1 1d5fac00 - 000000 - -File path: reorgTest/blk_5A.dat -Block 5A: - f9beb4d9 - 73010000 - - 01000000 ebc7d0de 9c31a71b 7f41d275 2c080ba4 11e1854b d45cb2cf 8c1e4624 - 00000000 a607774b 79b8eb50 b52a5a32 c1754281 ec67f626 9561df28 57d1fe6a - ea82c696 e1b65f49 ffff001d 4a263577 - 02 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff049971 0c7dffff ffff0100 f2052a01 00000043 4104678a - fdb0fe55 48271967 f1a67130 b7105cd6 a828e039 09a67962 e0ea1f61 deb649f6 - bc3f4cef 38c4f355 04e51ec1 12de5c38 4df7ba0b 8d578a4c 702b6bf1 1d5fac00 - 000000 - - 01000000 0163451d 1002611c 1388d5ba 4ddfdf99 196a86b5 990fb5b0 dc786207 - 4fdcb8ee d2000000 004a4930 46022100 8c8fd57b 48762135 8d8f3e69 19f33e08 - 804736ff 83db47aa 248512e2 6df9b8ba 022100b0 c59e5ee7 bfcbfcd1 a4d83da9 - 55fb260e fda7f42a 25522625 a3d6f2d9 1174a701 ffffffff 0100f205 2a010000 - 001976a9 14c52266 4fb0e55c dc5c0cea 73b4aad9 7ec83432 3288ac00 000000 - diff --git a/blockchain/validate_test.go b/blockchain/validate_test.go index 6298ad06..db6ea663 100644 --- a/blockchain/validate_test.go +++ b/blockchain/validate_test.go @@ -64,96 +64,11 @@ func TestSequenceLocksActive(t *testing.T) { } } -// TestCheckConnectBlockTemplate tests the CheckConnectBlockTemplate function to -// ensure it fails. -func TestCheckConnectBlockTemplate(t *testing.T) { - // Create a new database and chain instance to run tests against. - chain, teardownFunc, err := chainSetup("checkconnectblocktemplate", - &chaincfg.MainNetParams) - if err != nil { - t.Errorf("Failed to setup chain instance: %v", err) - return - } - defer teardownFunc() - - // Since we're not dealing with the real block chain, set the coinbase - // maturity to 1. - chain.TstSetCoinbaseMaturity(1) - - // Load up blocks such that there is a side chain. - // (genesis block) -> 1 -> 2 -> 3 -> 4 - // \-> 3a - testFiles := []string{ - "blk_0_to_4.dat.bz2", - "blk_3A.dat.bz2", - } - - var blocks []*btcutil.Block - for _, file := range testFiles { - blockTmp, err := loadBlocks(file) - if err != nil { - t.Fatalf("Error loading file: %v\n", err) - } - blocks = append(blocks, blockTmp...) - } - - for i := 1; i <= 3; i++ { - isMainChain, _, err := chain.ProcessBlock(blocks[i], BFNone) - if err != nil { - t.Fatalf("CheckConnectBlockTemplate: Received unexpected error "+ - "processing block %d: %v", i, err) - } - if !isMainChain { - t.Fatalf("CheckConnectBlockTemplate: Expected block %d to connect "+ - "to main chain", i) - } - } - - // Block 3 should fail to connect since it's already inserted. - err = chain.CheckConnectBlockTemplate(blocks[3]) - if err == nil { - t.Fatal("CheckConnectBlockTemplate: Did not received expected error " + - "on block 3") - } - - // Block 4 should connect successfully to tip of chain. - err = chain.CheckConnectBlockTemplate(blocks[4]) - if err != nil { - t.Fatalf("CheckConnectBlockTemplate: Received unexpected error on "+ - "block 4: %v", err) - } - - // Block 3a should fail to connect since does not build on chain tip. - err = chain.CheckConnectBlockTemplate(blocks[5]) - if err == nil { - t.Fatal("CheckConnectBlockTemplate: Did not received expected error " + - "on block 3a") - } - - // Block 4 should connect even if proof of work is invalid. - invalidPowBlock := *blocks[4].MsgBlock() - invalidPowBlock.Header.Nonce++ - err = chain.CheckConnectBlockTemplate(btcutil.NewBlock(&invalidPowBlock)) - if err != nil { - t.Fatalf("CheckConnectBlockTemplate: Received unexpected error on "+ - "block 4 with bad nonce: %v", err) - } - - // Invalid block building on chain tip should fail to connect. - invalidBlock := *blocks[4].MsgBlock() - invalidBlock.Header.Bits-- - err = chain.CheckConnectBlockTemplate(btcutil.NewBlock(&invalidBlock)) - if err == nil { - t.Fatal("CheckConnectBlockTemplate: Did not received expected error " + - "on block 4 with invalid difficulty bits") - } -} - // TestCheckBlockSanity tests the CheckBlockSanity function to ensure it works // as expected. func TestCheckBlockSanity(t *testing.T) { powLimit := chaincfg.MainNetParams.PowLimit - block := btcutil.NewBlock(&Block100000) + block := GetBlock100000() timeSource := NewMedianTime() err := CheckBlockSanity(block, powLimit, timeSource) if err != nil { @@ -235,254 +150,12 @@ func TestCheckSerializedHeight(t *testing.T) { } } -// Block100000 defines block 100,000 of the block chain. It is used to +var block100000Hex = "0000002024cbdc8644ee3983e66b003a0733891c069ca74c114c034c7b3e2e7ad7a12cd67e95e0555c0e056f6f2af538268ff9d21b420e529750d08eacb25c40f1322936637109b8a051157604c1c163cd39237687f6244b4e6d2b3a94e9d816babaecbb10c56058c811041b2b9c43000701000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2003a086010410c56058081011314abf0100000d2f6e6f64655374726174756d2f000000000180354a6e0a0000001976a914b5e74e7cc9e1f480a6599895c92aab1401f870f188ac000000000100000002f1b75decc2c1c59c2178852822de412f574ad9796b65ac9092a79630d8109aaf000000006a47304402202f78ed3bf8dcadb6c17e289cd06e9c96b02c6f23aa1f446a4a7896a31cfd1e4702202862261e2eb59475ac91092c620b3cac5a831372bafc446d5ee450866040b532012103db4f3785354d84311fab7624c52784a61e3046d8f364463d327bdd96281b5b90feffffff987ee6b4bf95548d01e443683261dd0ffdcb2eb335b2f7119df0d41b60756b92010000006a47304402200c422c7560b6418d45443138bb957ec44eb293a639f4b2235a622205ca6cac370220759f15d5dc2543fd1aef80104c93427fcb025847bf895669025d1d82c62fbf6801210201864b998db5436990a0029fc3fb153c09e8c2689214b91c8ed68784995c8da0feffffff022bccfedd000000001976a914738f16132942a01d00cb9699bd058c4925aada3288ac1f4d030c000000001976a914c4292e757f5ff6a27c2f0a87d3a4aea5e46c275a88ac9f86010001000000015fbb26ad6d818186032baeef4d3f475dfe165c6da2d93411b8ec5f9f523cf1a4000000006a4730440220356999ad5a9f6f09b676f17dd4a2617a0af234722d68a50edc3768c983c0623d022056b4e5531608aeb0205fde9c44f741158da3bba1f4c3788c9fe79d36d43ea355012103509893a2a7c765d49ac9ff70126cb1af54871d70baba2c7e39ec9b4096289a9bfeffffff02389332fa080000001976a914f85e054405fbcedc2341cf8bf41ea989090587a288acf9321a41000000001976a914e85e90c048fdfbe1c2117a7132856ff4b39b470188ac9f86010001000000013508189b9bb61ac2aa536b905447b58f6c58c17cdef305240f566caa689d760a010000006a4730440220669a2b86e5abe58bae54829d3c271669540a9ad965c2fb79e8cc1fb609c0b60002202f958403d979138075cb53d8cb5ff6bb14e18d66dfdb6701c7d43a8ceeed0fa80121029935a602205a3fb72446064f3bc3a55ab9cd2e3459bf2ffdf80a48ab029d4b42feffffff02523c2f13000000001976a914c5b2ae398496f0f9ceaf81b83c28a27ddc890e3588ac211958f2000000001976a914ac65f1d16e5a2af37408b5d65406000a7ea143ca88ac9f8601000100000001bdd724322c555a21d5eb62d4aadbdc051663bcd4ec03f8d9005992f299783c21000000006a47304402205448141a2a788f73310025123bd24f5bee01dd8f48f18d7abc62d7c26465008902207ab46e6ddf6ba416decf3fbb97b6946a1428ea0a7c25a55cab47c47110d8e9ce0121029d6ff3b1235f2a08560b23dd4a08b14cc415b544801b885365736ea8ab1d3470feffffff029d104ccf000000001976a914999d5b0e3d5efcf601c711127b91841afbf5c37a88ace5c5a07f070000001976a9144aade372298eb387da9b6ac69d215a213e822f3f88ac9f86010001000000011658304d4ce796cd450228a10fdf647c6ea42295c9f5e1663df11481af1c884d010000006b483045022100a35d5d3ccde85b41559047d976ae6210b8e6ba5653c53aae1adc90048de0761002200d6bd6ebc6d73f97855f435c6fd595009ee71d23bb34870ab83ad53f67eeb22b012102d2f681ebfd1a570416d602986a47ca4254d8dedf2935b3f8c2ba55dcee8e98f4feffffff025ee913e6020000001976a91468076c9380d3c6b468ad1d6109c36770fb181e8f88acb165394f000000001976a9147ae970e81b3657cbb59df26517e372165807be0088ac9f86010001000000018f285109f78524a88ff328a4f94de2ac03224c50984b11c68adda192e8f78efa010000006b483045022100d77f2ac32dd6a3015f02f7115a13f617c57952fc5d53a33a87dc3fc00ffe1864022006455f74cff864b10424e445c530a59243f86d309dc92c5010ec5709e38471ab012102fdac7335b41edcd2846fc7e2166bb48312ee583ed6ff70fb5c27bcb2addaad86feffffff028b7a6d5c000000001976a914c65106d2e7ea4ec6aa8aa30ba4d11cfd1143123388ac5934c228000000001976a914d1c4d190b07edb972b91f33c36c6568b80358dd488ac9f860100" + +// GetBlock100000 defines block 100,000 of the block chain. It is used to // test Block operations. -var Block100000 = wire.MsgBlock{ - Header: wire.BlockHeader{ - Version: 1, - PrevBlock: chainhash.Hash([32]byte{ // Make go vet happy. - 0x50, 0x12, 0x01, 0x19, 0x17, 0x2a, 0x61, 0x04, - 0x21, 0xa6, 0xc3, 0x01, 0x1d, 0xd3, 0x30, 0xd9, - 0xdf, 0x07, 0xb6, 0x36, 0x16, 0xc2, 0xcc, 0x1f, - 0x1c, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - }), // 000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250 - MerkleRoot: chainhash.Hash([32]byte{ // Make go vet happy. - 0x66, 0x57, 0xa9, 0x25, 0x2a, 0xac, 0xd5, 0xc0, - 0xb2, 0x94, 0x09, 0x96, 0xec, 0xff, 0x95, 0x22, - 0x28, 0xc3, 0x06, 0x7c, 0xc3, 0x8d, 0x48, 0x85, - 0xef, 0xb5, 0xa4, 0xac, 0x42, 0x47, 0xe9, 0xf3, - }), // f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766 - Timestamp: time.Unix(1293623863, 0), // 2010-12-29 11:57:43 +0000 UTC - Bits: 0x1b04864c, // 453281356 - Nonce: 0x10572b0f, // 274148111 - }, - Transactions: []*wire.MsgTx{ - { - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - Hash: chainhash.Hash{}, - Index: 0xffffffff, - }, - SignatureScript: []byte{ - 0x04, 0x4c, 0x86, 0x04, 0x1b, 0x02, 0x06, 0x02, - }, - Sequence: 0xffffffff, - }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0x12a05f200, // 5000000000 - PkScript: []byte{ - 0x41, // OP_DATA_65 - 0x04, 0x1b, 0x0e, 0x8c, 0x25, 0x67, 0xc1, 0x25, - 0x36, 0xaa, 0x13, 0x35, 0x7b, 0x79, 0xa0, 0x73, - 0xdc, 0x44, 0x44, 0xac, 0xb8, 0x3c, 0x4e, 0xc7, - 0xa0, 0xe2, 0xf9, 0x9d, 0xd7, 0x45, 0x75, 0x16, - 0xc5, 0x81, 0x72, 0x42, 0xda, 0x79, 0x69, 0x24, - 0xca, 0x4e, 0x99, 0x94, 0x7d, 0x08, 0x7f, 0xed, - 0xf9, 0xce, 0x46, 0x7c, 0xb9, 0xf7, 0xc6, 0x28, - 0x70, 0x78, 0xf8, 0x01, 0xdf, 0x27, 0x6f, 0xdf, - 0x84, // 65-byte signature - 0xac, // OP_CHECKSIG - }, - }, - }, - LockTime: 0, - }, - { - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - Hash: chainhash.Hash([32]byte{ // Make go vet happy. - 0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60, - 0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac, - 0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07, - 0x79, 0xac, 0x88, 0xfd, 0xf3, 0x57, 0xa1, 0x87, - }), // 87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03 - Index: 0, - }, - SignatureScript: []byte{ - 0x49, // OP_DATA_73 - 0x30, 0x46, 0x02, 0x21, 0x00, 0xc3, 0x52, 0xd3, - 0xdd, 0x99, 0x3a, 0x98, 0x1b, 0xeb, 0xa4, 0xa6, - 0x3a, 0xd1, 0x5c, 0x20, 0x92, 0x75, 0xca, 0x94, - 0x70, 0xab, 0xfc, 0xd5, 0x7d, 0xa9, 0x3b, 0x58, - 0xe4, 0xeb, 0x5d, 0xce, 0x82, 0x02, 0x21, 0x00, - 0x84, 0x07, 0x92, 0xbc, 0x1f, 0x45, 0x60, 0x62, - 0x81, 0x9f, 0x15, 0xd3, 0x3e, 0xe7, 0x05, 0x5c, - 0xf7, 0xb5, 0xee, 0x1a, 0xf1, 0xeb, 0xcc, 0x60, - 0x28, 0xd9, 0xcd, 0xb1, 0xc3, 0xaf, 0x77, 0x48, - 0x01, // 73-byte signature - 0x41, // OP_DATA_65 - 0x04, 0xf4, 0x6d, 0xb5, 0xe9, 0xd6, 0x1a, 0x9d, - 0xc2, 0x7b, 0x8d, 0x64, 0xad, 0x23, 0xe7, 0x38, - 0x3a, 0x4e, 0x6c, 0xa1, 0x64, 0x59, 0x3c, 0x25, - 0x27, 0xc0, 0x38, 0xc0, 0x85, 0x7e, 0xb6, 0x7e, - 0xe8, 0xe8, 0x25, 0xdc, 0xa6, 0x50, 0x46, 0xb8, - 0x2c, 0x93, 0x31, 0x58, 0x6c, 0x82, 0xe0, 0xfd, - 0x1f, 0x63, 0x3f, 0x25, 0xf8, 0x7c, 0x16, 0x1b, - 0xc6, 0xf8, 0xa6, 0x30, 0x12, 0x1d, 0xf2, 0xb3, - 0xd3, // 65-byte pubkey - }, - Sequence: 0xffffffff, - }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0x2123e300, // 556000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0xc3, 0x98, 0xef, 0xa9, 0xc3, 0x92, 0xba, 0x60, - 0x13, 0xc5, 0xe0, 0x4e, 0xe7, 0x29, 0x75, 0x5e, - 0xf7, 0xf5, 0x8b, 0x32, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - { - Value: 0x108e20f00, // 4444000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0x94, 0x8c, 0x76, 0x5a, 0x69, 0x14, 0xd4, 0x3f, - 0x2a, 0x7a, 0xc1, 0x77, 0xda, 0x2c, 0x2f, 0x6b, - 0x52, 0xde, 0x3d, 0x7c, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - }, - LockTime: 0, - }, - { - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - Hash: chainhash.Hash([32]byte{ // Make go vet happy. - 0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d, - 0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27, - 0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65, - 0xe4, 0x1c, 0x61, 0xd0, 0x78, 0x29, 0x4e, 0xcf, - }), // cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3 - Index: 1, - }, - SignatureScript: []byte{ - 0x47, // OP_DATA_71 - 0x30, 0x44, 0x02, 0x20, 0x03, 0x2d, 0x30, 0xdf, - 0x5e, 0xe6, 0xf5, 0x7f, 0xa4, 0x6c, 0xdd, 0xb5, - 0xeb, 0x8d, 0x0d, 0x9f, 0xe8, 0xde, 0x6b, 0x34, - 0x2d, 0x27, 0x94, 0x2a, 0xe9, 0x0a, 0x32, 0x31, - 0xe0, 0xba, 0x33, 0x3e, 0x02, 0x20, 0x3d, 0xee, - 0xe8, 0x06, 0x0f, 0xdc, 0x70, 0x23, 0x0a, 0x7f, - 0x5b, 0x4a, 0xd7, 0xd7, 0xbc, 0x3e, 0x62, 0x8c, - 0xbe, 0x21, 0x9a, 0x88, 0x6b, 0x84, 0x26, 0x9e, - 0xae, 0xb8, 0x1e, 0x26, 0xb4, 0xfe, 0x01, - 0x41, // OP_DATA_65 - 0x04, 0xae, 0x31, 0xc3, 0x1b, 0xf9, 0x12, 0x78, - 0xd9, 0x9b, 0x83, 0x77, 0xa3, 0x5b, 0xbc, 0xe5, - 0xb2, 0x7d, 0x9f, 0xff, 0x15, 0x45, 0x68, 0x39, - 0xe9, 0x19, 0x45, 0x3f, 0xc7, 0xb3, 0xf7, 0x21, - 0xf0, 0xba, 0x40, 0x3f, 0xf9, 0x6c, 0x9d, 0xee, - 0xb6, 0x80, 0xe5, 0xfd, 0x34, 0x1c, 0x0f, 0xc3, - 0xa7, 0xb9, 0x0d, 0xa4, 0x63, 0x1e, 0xe3, 0x95, - 0x60, 0x63, 0x9d, 0xb4, 0x62, 0xe9, 0xcb, 0x85, - 0x0f, // 65-byte pubkey - }, - Sequence: 0xffffffff, - }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0xf4240, // 1000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0xb0, 0xdc, 0xbf, 0x97, 0xea, 0xbf, 0x44, 0x04, - 0xe3, 0x1d, 0x95, 0x24, 0x77, 0xce, 0x82, 0x2d, - 0xad, 0xbe, 0x7e, 0x10, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - { - Value: 0x11d260c0, // 299000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0x6b, 0x12, 0x81, 0xee, 0xc2, 0x5a, 0xb4, 0xe1, - 0xe0, 0x79, 0x3f, 0xf4, 0xe0, 0x8a, 0xb1, 0xab, - 0xb3, 0x40, 0x9c, 0xd9, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - }, - LockTime: 0, - }, - { - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - Hash: chainhash.Hash([32]byte{ // Make go vet happy. - 0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73, - 0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac, - 0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90, - 0x9b, 0xa1, 0xc4, 0x3d, 0xed, 0x5f, 0x51, 0xf4, - }), // f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b - Index: 0, - }, - SignatureScript: []byte{ - 0x49, // OP_DATA_73 - 0x30, 0x46, 0x02, 0x21, 0x00, 0xbb, 0x1a, 0xd2, - 0x6d, 0xf9, 0x30, 0xa5, 0x1c, 0xce, 0x11, 0x0c, - 0xf4, 0x4f, 0x7a, 0x48, 0xc3, 0xc5, 0x61, 0xfd, - 0x97, 0x75, 0x00, 0xb1, 0xae, 0x5d, 0x6b, 0x6f, - 0xd1, 0x3d, 0x0b, 0x3f, 0x4a, 0x02, 0x21, 0x00, - 0xc5, 0xb4, 0x29, 0x51, 0xac, 0xed, 0xff, 0x14, - 0xab, 0xba, 0x27, 0x36, 0xfd, 0x57, 0x4b, 0xdb, - 0x46, 0x5f, 0x3e, 0x6f, 0x8d, 0xa1, 0x2e, 0x2c, - 0x53, 0x03, 0x95, 0x4a, 0xca, 0x7f, 0x78, 0xf3, - 0x01, // 73-byte signature - 0x41, // OP_DATA_65 - 0x04, 0xa7, 0x13, 0x5b, 0xfe, 0x82, 0x4c, 0x97, - 0xec, 0xc0, 0x1e, 0xc7, 0xd7, 0xe3, 0x36, 0x18, - 0x5c, 0x81, 0xe2, 0xaa, 0x2c, 0x41, 0xab, 0x17, - 0x54, 0x07, 0xc0, 0x94, 0x84, 0xce, 0x96, 0x94, - 0xb4, 0x49, 0x53, 0xfc, 0xb7, 0x51, 0x20, 0x65, - 0x64, 0xa9, 0xc2, 0x4d, 0xd0, 0x94, 0xd4, 0x2f, - 0xdb, 0xfd, 0xd5, 0xaa, 0xd3, 0xe0, 0x63, 0xce, - 0x6a, 0xf4, 0xcf, 0xaa, 0xea, 0x4e, 0xa1, 0x4f, - 0xbb, // 65-byte pubkey - }, - Sequence: 0xffffffff, - }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0xf4240, // 1000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0x39, 0xaa, 0x3d, 0x56, 0x9e, 0x06, 0xa1, 0xd7, - 0x92, 0x6d, 0xc4, 0xbe, 0x11, 0x93, 0xc9, 0x9b, - 0xf2, 0xeb, 0x9e, 0xe0, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - }, - LockTime: 0, - }, - }, +func GetBlock100000() *btcutil.Block { + var block100000Bytes, _ = hex.DecodeString(block100000Hex) + var results, _ = btcutil.NewBlockFromBytes(block100000Bytes) + return results } diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index fa8305c2..95320dbd 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -388,7 +388,7 @@ func TestChainSvrCmds(t *testing.T) { return btcjson.NewGetBlockFilterCmd("0000afaf", nil) }, marshalled: `{"jsonrpc":"1.0","method":"getblockfilter","params":["0000afaf"],"id":1}`, - unmarshalled: &btcjson.GetBlockFilterCmd{"0000afaf", nil}, + unmarshalled: &btcjson.GetBlockFilterCmd{BlockHash: "0000afaf", FilterType: nil}, }, { name: "getblockfilter optional filtertype", @@ -399,7 +399,7 @@ func TestChainSvrCmds(t *testing.T) { return btcjson.NewGetBlockFilterCmd("0000afaf", btcjson.NewFilterTypeName(btcjson.FilterTypeBasic)) }, marshalled: `{"jsonrpc":"1.0","method":"getblockfilter","params":["0000afaf","basic"],"id":1}`, - unmarshalled: &btcjson.GetBlockFilterCmd{"0000afaf", btcjson.NewFilterTypeName(btcjson.FilterTypeBasic)}, + unmarshalled: &btcjson.GetBlockFilterCmd{BlockHash: "0000afaf", FilterType: btcjson.NewFilterTypeName(btcjson.FilterTypeBasic)}, }, { name: "getblockhash", diff --git a/chaincfg/genesis.go b/chaincfg/genesis.go index a4df289d..bfa2a845 100644 --- a/chaincfg/genesis.go +++ b/chaincfg/genesis.go @@ -86,15 +86,6 @@ var genesisBlock = wire.MsgBlock{ Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -// regTestGenesisHash is the hash of the first block in the block chain for the -// regression test network (genesis block). -var regTestGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x56, 0x75, 0x68, 0x69, 0x76, 0x67, 0x4f, 0x50, - 0xa0, 0xa1, 0x95, 0x3d, 0x17, 0x2e, 0x9e, 0xcf, - 0x4a, 0x4a, 0x62, 0x1d, 0xc9, 0xa4, 0xc3, 0x79, - 0x5d, 0xec, 0xd4, 0x99, 0x12, 0xcf, 0x3f, 0x6e, -}) - // regTestGenesisMerkleRoot is the hash of the first transaction in the genesis // block for the regression test network. It is the same as the merkle root for // the main network. @@ -115,14 +106,9 @@ var regTestGenesisBlock = wire.MsgBlock{ Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -// testNet3GenesisHash is the hash of the first block in the block chain for the -// test network (version 3). -var testNet3GenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, - 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae, - 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, - 0x01, 0xea, 0x33, 0x09, 0x00, 0x00, 0x00, 0x00, -}) +// regTestGenesisHash is the hash of the first block in the block chain for the +// regression test network (genesis block). +var regTestGenesisHash = regTestGenesisBlock.BlockHash() // testNet3GenesisMerkleRoot is the hash of the first transaction in the genesis // block for the test network (version 3). It is the same as the merkle root @@ -144,14 +130,9 @@ var testNet3GenesisBlock = wire.MsgBlock{ Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -// simNetGenesisHash is the hash of the first block in the block chain for the -// simulation test network. -var simNetGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, - 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, - 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, - 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, -}) +// testNet3GenesisHash is the hash of the first block in the block chain for the +// test network (version 3). +var testNet3GenesisHash = testNet3GenesisBlock.BlockHash() // simNetGenesisMerkleRoot is the hash of the first transaction in the genesis // block for the simulation test network. It is the same as the merkle root for @@ -172,14 +153,9 @@ var simNetGenesisBlock = wire.MsgBlock{ Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -// sigNetGenesisHash is the hash of the first block in the block chain for the -// signet test network. -var sigNetGenesisHash = chainhash.Hash{ - 0xf6, 0x1e, 0xee, 0x3b, 0x63, 0xa3, 0x80, 0xa4, - 0x77, 0xa0, 0x63, 0xaf, 0x32, 0xb2, 0xbb, 0xc9, - 0x7c, 0x9f, 0xf9, 0xf0, 0x1f, 0x2c, 0x42, 0x25, - 0xe9, 0x73, 0x98, 0x81, 0x08, 0x00, 0x00, 0x00, -} +// simNetGenesisHash is the hash of the first block in the block chain for the +// simulation test network. +var simNetGenesisHash = simNetGenesisBlock.BlockHash() // sigNetGenesisMerkleRoot is the hash of the first transaction in the genesis // block for the signet test network. It is the same as the merkle root for @@ -199,3 +175,7 @@ var sigNetGenesisBlock = wire.MsgBlock{ }, Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } + +// sigNetGenesisHash is the hash of the first block in the block chain for the +// signet test network. +var sigNetGenesisHash = sigNetGenesisBlock.BlockHash() diff --git a/chaincfg/genesis_test.go b/chaincfg/genesis_test.go index 1daf8479..b3b54e5d 100644 --- a/chaincfg/genesis_test.go +++ b/chaincfg/genesis_test.go @@ -21,13 +21,6 @@ func TestGenesisBlock(t *testing.T) { t.Fatalf("TestGenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), genesisBlockBytes) { - t.Fatalf("TestGenesisBlock: Genesis block does not appear valid - "+ - "got %v, want %v", spew.Sdump(buf.Bytes()), - spew.Sdump(genesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := MainNetParams.GenesisBlock.BlockHash() if !MainNetParams.GenesisHash.IsEqual(&hash) { @@ -47,14 +40,6 @@ func TestRegTestGenesisBlock(t *testing.T) { t.Fatalf("TestRegTestGenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), regTestGenesisBlockBytes) { - t.Fatalf("TestRegTestGenesisBlock: Genesis block does not "+ - "appear valid - got %v, want %v", - spew.Sdump(buf.Bytes()), - spew.Sdump(regTestGenesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := RegressionNetParams.GenesisBlock.BlockHash() if !RegressionNetParams.GenesisHash.IsEqual(&hash) { @@ -74,14 +59,6 @@ func TestTestNet3GenesisBlock(t *testing.T) { t.Fatalf("TestTestNet3GenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), testNet3GenesisBlockBytes) { - t.Fatalf("TestTestNet3GenesisBlock: Genesis block does not "+ - "appear valid - got %v, want %v", - spew.Sdump(buf.Bytes()), - spew.Sdump(testNet3GenesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := TestNet3Params.GenesisBlock.BlockHash() if !TestNet3Params.GenesisHash.IsEqual(&hash) { @@ -101,14 +78,6 @@ func TestSimNetGenesisBlock(t *testing.T) { t.Fatalf("TestSimNetGenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), simNetGenesisBlockBytes) { - t.Fatalf("TestSimNetGenesisBlock: Genesis block does not "+ - "appear valid - got %v, want %v", - spew.Sdump(buf.Bytes()), - spew.Sdump(simNetGenesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := SimNetParams.GenesisBlock.BlockHash() if !SimNetParams.GenesisHash.IsEqual(&hash) { @@ -128,14 +97,6 @@ func TestSigNetGenesisBlock(t *testing.T) { t.Fatalf("TestSigNetGenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), sigNetGenesisBlockBytes) { - t.Fatalf("TestSigNetGenesisBlock: Genesis block does not "+ - "appear valid - got %v, want %v", - spew.Sdump(buf.Bytes()), - spew.Sdump(sigNetGenesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := SigNetParams.GenesisBlock.BlockHash() if !SigNetParams.GenesisHash.IsEqual(&hash) { @@ -144,208 +105,3 @@ func TestSigNetGenesisBlock(t *testing.T) { spew.Sdump(SigNetParams.GenesisHash)) } } - -// genesisBlockBytes are the wire encoded bytes for the genesis block of the -// main network as of protocol version 60002. -var genesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |....;...| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |z{..z.,>| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |gv.a....| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |..Q2:...| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0x29, 0xab, 0x5f, 0x49, /* |K.^J)._I| */ - 0xff, 0xff, 0x00, 0x1d, 0x1d, 0xac, 0x2b, 0x7c, /* |......+|| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..M.....| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..EThe T| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |imes 03/| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |Jan/2009| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* | Chancel| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* |lor on b| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |rink of | */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |second b| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |ailout f| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |or banks| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |*....CA.| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |g....UH'| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |.g..q0..| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |\..(.9..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |yb...a..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |I..?L.8.| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |.U......| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |\8M....W| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} - -// regTestGenesisBlockBytes are the wire encoded bytes for the genesis block of -// the regression test network as of protocol version 60002. -var regTestGenesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |....;...| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |z{..z.,>| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |gv.a....| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |..Q2:...| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0xda, 0xe5, 0x49, 0x4d, /* |K.^J)._I| */ - 0xff, 0xff, 0x7f, 0x20, 0x02, 0x00, 0x00, 0x00, /* |......+|| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..M.....| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..EThe T| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |imes 03/| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |Jan/2009| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* | Chancel| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* |lor on b| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |rink of | */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |second b| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |ailout f| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |or banks| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |*....CA.| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |g....UH'| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |.g..q0..| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |\..(.9..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |yb...a..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |I..?L.8.| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |.U......| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |\8M....W| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} - -// testNet3GenesisBlockBytes are the wire encoded bytes for the genesis block of -// the test network (version 3) as of protocol version 60002. -var testNet3GenesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |....;...| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |z{..z.,>| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |gv.a....| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |..Q2:...| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0xda, 0xe5, 0x49, 0x4d, /* |K.^J)._I| */ - 0xff, 0xff, 0x00, 0x1d, 0x1a, 0xa4, 0xae, 0x18, /* |......+|| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..M.....| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..EThe T| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |imes 03/| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |Jan/2009| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* | Chancel| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* |lor on b| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |rink of | */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |second b| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |ailout f| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |or banks| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |*....CA.| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |g....UH'| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |.g..q0..| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |\..(.9..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |yb...a..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |I..?L.8.| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |.U......| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |\8M....W| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} - -// simNetGenesisBlockBytes are the wire encoded bytes for the genesis block of -// the simulation test network as of protocol version 70002. -var simNetGenesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |....;...| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |z{..z.,>| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |gv.a....| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |..Q2:...| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0x45, 0x06, 0x86, 0x53, /* |K.^J)._I| */ - 0xff, 0xff, 0x7f, 0x20, 0x02, 0x00, 0x00, 0x00, /* |......+|| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..M.....| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..EThe T| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |imes 03/| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |Jan/2009| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* | Chancel| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* |lor on b| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |rink of | */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |second b| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |ailout f| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |or banks| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |*....CA.| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |g....UH'| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |.g..q0..| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |\..(.9..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |yb...a..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |I..?L.8.| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |.U......| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |\8M....W| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} - -// sigNetGenesisBlockBytes are the wire encoded bytes for the genesis block of -// the signet test network as of protocol version 70002. -var sigNetGenesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |...@....| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |........| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |....;...| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |z{..z.,>| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |gv.a....| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0x00, 0x8f, 0x4d, 0x5f, /* |..Q2:...| */ - 0xae, 0x77, 0x03, 0x1e, 0x8a, 0xd2, 0x22, 0x03, /* |K.^J..M_| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |.w....".| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |........| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..M.....| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |..EThe T| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |imes 03/| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* |Jan/2009| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* | Chancel| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |lor on b| */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |rink of| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |second b| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |ailout f| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |or banks| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |........| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |*....CA.| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |g....UH'| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |.g..q0..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |\..(.9..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |yb...a..| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |I..?L.8.| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |.U......| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |\8M....W| */ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} diff --git a/database/ffldb/interface_test.go b/database/ffldb/interface_test.go index b1b4cac7..f7330f4f 100644 --- a/database/ffldb/interface_test.go +++ b/database/ffldb/interface_test.go @@ -61,12 +61,10 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu dr := bzip2.NewReader(fi) // Set the first block as the genesis block. - blocks := make([]*btcutil.Block, 0, 256) - genesis := btcutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) - blocks = append(blocks, genesis) + blocks := make([]*btcutil.Block, 0, 257) // Load the remaining blocks. - for height := 1; ; height++ { + for { var net uint32 err := binary.Read(dr, binary.LittleEndian, &net) if err == io.EOF { @@ -75,20 +73,18 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu } if err != nil { t.Errorf("Failed to load network type for block %d: %v", - height, err) + len(blocks), err) return nil, err } if net != uint32(network) { - t.Errorf("Block doesn't match network: %v expects %v", - net, network) - return nil, err + continue } var blockLen uint32 err = binary.Read(dr, binary.LittleEndian, &blockLen) if err != nil { t.Errorf("Failed to load block size for block %d: %v", - height, err) + len(blocks), err) return nil, err } @@ -96,17 +92,22 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu blockBytes := make([]byte, blockLen) _, err = io.ReadFull(dr, blockBytes) if err != nil { - t.Errorf("Failed to load block %d: %v", height, err) + t.Errorf("Failed to load block %d: %v", len(blocks), err) return nil, err } // Deserialize and store the block. block, err := btcutil.NewBlockFromBytes(blockBytes) if err != nil { - t.Errorf("Failed to parse block %v: %v", height, err) + t.Errorf("Failed to parse block %v: %v", len(blocks), err) return nil, err } + // NOTE: there's a bug here in that it doesn't read the checksum; + // we account for that by checking the network above; it probably skips every other block blocks = append(blocks, block) + if len(blocks) == 257 { + break + } } return blocks, nil diff --git a/database/ffldb/whitebox_test.go b/database/ffldb/whitebox_test.go index 4314c69f..15c83cec 100644 --- a/database/ffldb/whitebox_test.go +++ b/database/ffldb/whitebox_test.go @@ -54,12 +54,10 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu dr := bzip2.NewReader(fi) // Set the first block as the genesis block. - blocks := make([]*btcutil.Block, 0, 256) - genesis := btcutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) - blocks = append(blocks, genesis) + blocks := make([]*btcutil.Block, 0, 257) // Load the remaining blocks. - for height := 1; ; height++ { + for { var net uint32 err := binary.Read(dr, binary.LittleEndian, &net) if err == io.EOF { @@ -68,20 +66,18 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu } if err != nil { t.Errorf("Failed to load network type for block %d: %v", - height, err) + len(blocks), err) return nil, err } if net != uint32(network) { - t.Errorf("Block doesn't match network: %v expects %v", - net, network) - return nil, err + continue } var blockLen uint32 err = binary.Read(dr, binary.LittleEndian, &blockLen) if err != nil { t.Errorf("Failed to load block size for block %d: %v", - height, err) + len(blocks), err) return nil, err } @@ -89,17 +85,22 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu blockBytes := make([]byte, blockLen) _, err = io.ReadFull(dr, blockBytes) if err != nil { - t.Errorf("Failed to load block %d: %v", height, err) + t.Errorf("Failed to load block %d: %v", len(blocks), err) return nil, err } // Deserialize and store the block. block, err := btcutil.NewBlockFromBytes(blockBytes) if err != nil { - t.Errorf("Failed to parse block %v: %v", height, err) + t.Errorf("Failed to parse block %v: %v", len(blocks), err) return nil, err } + // there's a bug here in that it doesn't read the checksum + // and then it maybe ends up skipping a block blocks = append(blocks, block) + if len(blocks) == 257 { + break + } } return blocks, nil diff --git a/database/testdata/blocks1-256.bz2 b/database/testdata/blocks1-256.bz2 index 6b8bda4429200c0566bb13c28c35d6397272e475..8e9b44c004d757b18c93bd96f5acb5d74d3b119a 100644 GIT binary patch literal 42273 zcmV);K!(3UT4*^jL0KkKSs%#<+yI}=fB*mg|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0 z|NsC0|Nr1_zW@)ObATIQ3F`ZRA7%hOZ#i$dyRFsru4*^CyEMydY}=|ghrRDRJH2ji zd^z6%(BAvI?|?n`y}Px-wC>rPu9eq!eA(#OYU{h#Uc*z~Gu?MR?zP)*UiSCEKJ&c# z+r0O4cYEFM9BZw!TX&lF?XKB-;0w8Yvwe4`Z#8!BcW-m0S3A!2r@8H(tvhqKw^7u0 zw_e`&Ztpqv?>xTUJA1b_^=`|jZ1=s_de+?{_R6~T?{_slPjT+-_qVY3cY)sPy>71B z+}E1i>g&BdJbQb3_q)CT?_T$JON9FzoprlTu000Su#J~xr0%be^005Ynm0MKZt zM5xf4Kuk;k36lT`fJ`Gs0GcqE6A6lXU;qdVj3$^y05k$&FaR0}fCSS`4KPhG6+c5J zCMHZHR4RyRFa*s21jNM1$&E}JA?jf?)6p=RWMMN2so@%)fMjUVFle4kf@ISs6wOo2 zh9(tH^wFg9VlgzyiHOL`W(dQXvva#P^vTxfC6cz5MnZ$ z6HQDLO+7;sOcO??PfZ#yCK0qv88Hn2(lqj68f3&WCetc@j3o5b^kp>iVGNVgO*F($ zA(4dAdSYZWGBlu(A_S2%%6^o2PYQacgxXI{O`{V{Ddh4rnHXfrP!)zO4 zY)y@*Xo!UkCNYe01UAq^gwWd>K-(H=gBZq}8yiqGK+|B@HliRH(rvV%gf!TjV@;rJ zZ8no&Hj`p)HrU%6h)Nq`Z4k&DI2br^#x~n%8*GLUG}zl>ZKlT#7&e;*#x}&p4T+65 zIiwv%8e({8Bw)+CZbxG+g1gO_MX5O0K#gvl@qN_b$v3ly77F*pzaASMY?c3|3B z+sqJD-Y}Vmof!>~$P$sfEKXO(^w&%MmOZG_laS2T3915J8UhMuunEta|6EJ zVcwD|t;}AVOudWqJ4FJWQ(IhS@iH@VyNp64dd6fPoO>!1kAI{LNjb>hT=O;R?6>(- z1&+3Ux@3G>42ljJB*rt`d2V7whl}6T{uH@(-s&{&iY<~CZF{FJYMV@57)wZfh$@aE z@ih*{SpAIR4LJXwMXsB2-qKI;x6tgB)^v@S>wVvzAAyoBb+HvEN328;jxIdmIZ%B0 zNSnLud%6>!@{-qgj=Glj(v^3+cf2=WN0gJN4^Nv10o*&e zXZZR$Iyt`m5fptFa^0T~$Jp<8+s@DXe{aRT`8T`m7JXzIFl~*u%yhC4BrMCCNhHRQ zBpXNxu;$wAS`74{=vjMyYuPk)?*7BdkXQ(n6ba}Gb@=_Iy~>OZxRyU0977v^hvoGLtjOU z;A-g3b6E@A$-s9_Z}<0`&~k&mokS*B@T}QBydV0_E3i<_f6{zM$}Vo4cN}Al>tV1j zGnI9t*;v9?EwU(8e#tmmvkQ4$9ThG)?X?W`UAI-=NgW+GVfc5YqhS2xSVXJ4Mm`On z3KQ4VPt%=G`qv(UXIm+fLJ}4<5G(6I+hQ9MKsEvq2+w7r=at*<`96dA@O7af3fSl2 zB#2{R*fz#;ZXXiW$;gO5l^ALwaYO_?G(&Vw0mMoo6C6th)Tdn%l~u%>rh-(;DV#S% zoit6k*AYdh5~C*KmYtAT2OLNPE|Ofh?eG1q&p%~ z2UE5gQ>3n`I-yYtfvHX_rcDJzAPRXPe>R~F1CO*K_IX(WG-_sI2B;sk9anK~(bhB?Du?W_Cj#FutqPYfZ>mIKXP0K7B=a^ppo$%7h*=YxUXIK< zj;s|yx<2yEDDy5zhdeF?B>!568k(7GL0j|*wmZuABYGt_3qKrR7bFVwW;53PTkLB7 z*ZIjo)ma|Pl{LjG_F2}dHs!@OjZO#qSo`CeWulVS;hp_&4t$^GX|V9Y%3XHsJr~cV;;Z@Urvh4D-ZM3m2FS%}j#fp3RP*3YM zu92ib{u#QC6!a}rjBC@e=~QxEYQ&bly*f7Pskh8{cP9oTkl7*4Hlo4VEd~SDV@TO? zHt+E7p;~Cz+->pLN@*G&wV1}p=HACC2*EU~VZ^a_>|D+2J%$@6-ZXCB*`IT&g-1A$ zD95nBGf>g~nCSbTdJWqPtI;#I=X6pr&0{`~Z7okb3;4Xd1FZ1lqh`}h2K@gC7n5_e zuu(Dged)mFXhzRLSVT60xJVCZSS@_9hiw+kOj`6g#2?oZ55_Waci(z&`UPc!^KO-h z!n`q#)(t7+AMo=QqWye3D5+?|-Mtj?2m}HFWB_#=PyqI4F5^V$G!BEtebtDqAwNJ- z{R4)B&?W8a!P6&TVLhJ}O7)`CP|JIhH84-Ssqc3>Zx9_7+rGVQ`YvnX^56Vq{?-Fw z#bB_R(+y_O?x z&3i&rFb>gzhPyU}4K6XLVjJa|mS_ny1|6G*0ukad31Wif_gUZ$+1y$B7{1H;jQ^jC zGK^MjAjasSa5#9%FfD7N@wNS0wgC^nV0Z7W-bZfuR$kt{?pcUv)H9UhV}3~_^W8LL zUvkV(2_Mr1^<ju#W7#nUK{>w7W@MYADsq`lSmga0$(kg zt9UeQ@7bhhXXn7L4AHS0#u`5}hU4aESQxIB3&RY1GVC#L4}ODY%?sl`)Gp6A9vkwp z5Nw!go)PjaG*}v>yDs80%+ufC%CPkrZvAGs$I&rpbCJ4!D?~E{!zIN)b-0)`&!_xR zzPF9P71#RQ#*&ktb%+x_e*uN!(X0C&&GX>wuROoxJ-$lj1ge4^73HiqGwtbzC#d&GZ^C5fgH>r2Kg6*8lSX2WR`Z-5+bP z!f-#io=f(gaqix&oS(4<-JSMIIM!ivTU=K+`C$Lg4s|X3=L6qM>sfpm`>oOMg$k*< z)Rrj)U=V-?VD;GLU(V86^Ugp(AOZN2Nh?0&C5Yjo01Z*MB>EVyKjb=@s{b{kUjva~ zgdhhqninI#Y-v8YQ#pIFC;sx-%gt=A#uys6D7cmwZT3S%mj{vdPHP?$qqhol62S_FSp=-)E<{N@DxJqj23eA zYev>ZKtunj&TZQ08r~ZD002NCBoF|AKmy2`xEr^7m$bNB%*&JX#hZ3)jSF4U1Rwzj z1Cq0@ugmG9##Ff@X>#LuucjxQ??M0FyRN5Z`$3!_027-j8ExA|_w?(z9RqR1@h}aw zv}Z#wq{(pXNTsa{co>uYGCfR~1&7|d&&0lx#D%bjRyiBM6FG<6`2A77EpwEx;lLlKfJ^`7?V6J|55t4QvJCY4U7nx^^j^7m)E6 zJiH8dA}aF`N9jxsesq- z;jAaI(e!KA`nL;GL?8hVzc@{rO__jSd1v2oKgrrYG5P(7e>Xe+RV%-t1 zbO$srNd3^ajxt8#O_7$;E{FgGq`hM*b?YpLI&2{b6ft?_`@OoGBB>4!mohNcSaS+d ztBU30RbgKrkADQcpBY+ec-HCk3yAzVXas^Jhp2T5b^Zl7`tCpgAOPBA>`674wJ|p4 zM@(}t#Ckl|u={$^|9=kWA`pN=0GFOlz0~WEK}*SY8HKjL;xveebD(6F#bJ_b{4U9K zJGd^~PFSH9v$+33J`3Ib%R99aQ*US==vha11RH+IDndWQd$+Ehx1D=}k_KTs{O657m2y?kwH9;%zJaud@eQazckB3ZBG#}v zvT8JoAOIk%gc$ws?6LCF30R)!{=1hfXi~OtzD@SuVST{3ZuXuMwq}rQH|dBjmx*1E z-f1G3fZ3RYbs+MnKh;U|=#a=S;$XLwbb~xy^S-*G(MXGKj++g-UFtd4y3Erb^6T^F zJR{Em1;lguCQ~%(xv$9z$ z-04KEMD`m9r9Bcife5Wl@-57sA^8<a9w06P?v6yGz1_H zXC-}qkl~fr_Yf#F@29#y-^jInI+1vgkwW!Q(rUnr!ffyHDoLkUArt9n(bRX$Te#j= zrnkJ2*=(OlOoH{1&N5egYHFmjBaAwGH@~7XZ2-|Tv3LDd#H?PGlD!@Ef9*v!o$*Ls zvLW;2#<~6XQ*i^A>iE*S78^?Q$+;l_1N{U=J65n@3L4clo42I$B6$m@>@sf?A{QYK z@A9PCkL%_7dX`tP2WO(Ium7KL03AEWBOgJb+?LjG*Fw3a=}uQ^*SeXvjoc$_GxT|t z?Hd$Z@#gV3(;VKqMLjBqfxNr2OauY|PK@iSn$vj@*HfZkWn2m@6>V&2W8~-a`0IF3 ztsnU%NP^M6C57B%g`I0&1aG2xX-N{UWnaNz0Ds`7anfg;kMG)`7DQfq`5-l~rrk>G z$8Xxh+s!Mq_YKaI5EH7tN)J}s^q=(2O;lEf`86}~=4pCL={GA^XM2GEN&IqS!d#e% z^6QlrRERKg>0+F4Y9Rul_K0k#j8en4O>qxh>10v7AEshs!~}^agG4x0Uh`%2WI?D$|pwnxE?w`efTv z1~K;>Ge3Jiwv+6n%Fiv)DaQPXJT30r6tg=Mndi!njZ@M#hWCE;v~&Hjjd){RXq;ew zoxtJU%=E$$9!16WM6*MShNTVKg@0>pdPXJVZvs8gY!CnlC-^($7%7|zHpMAw9&DSH zg|Q-c+jq0Ebeag`UcPy(wJH4Cwa&LEC&PYR1|!RuX3CgSUwHC1@miP@ zW-g@zs(F2KgH5gULD!}mLBiNlqlKpOvb zbBL8HKktgDKQFLEm&YY~J^v{o_*?Khl;OZ5DNx@TYPyI3Eix^6!AE6+?PG0I$M|#v zAqZ2Kh&uj^zcn-PO-rlF8&cp)V@yP(v6vgiKmY_b<^g>2Z{A^Jkyc~pAra%aZ2;CV z3em7gA2O+Y6DS2+%xkh!XbM>f7$Y^FsOv8tDm?Q92?jyYv8+5|glvwtxaTT%N=)6@ z&)|KVVOCV-$a(zVO}n5f6bZ>5{k(WLvbs9 ze?j%p%w&IEb4}Aw%c%|Hbnh}|Fl?=)XX>chY^SS9jZwrm8|MWK#ZT^a3qHJU7GD<00K`D_Zk#y4o1?9{rc~!=bd@H8NVrq>DFwyq}oRT+>&aWn@BLT zkFqvwCDqxGIa>D>{IOsrll*UBXS{t=mBL8S;g_pGs4wr;Xip#oIbm+n^cGEZwA zMwOrV<^j^218VcM_ufo6FCiS}+d{1{3p2IK?Ll44rHQW6J-hp{8B-_v{l_OGj4Bdr zi4Z?~iaEivU1}+&!z}K@FEBNGg%DqJv|@ANI57dKH&$nud;S;A_E!cety^e&sKu#O zo`>5oJ{LT2IHB}!l7C{h$X%UY#_t1cQAj@VS#r`8+EMM`eT(mv(@tyt2V%r+S+jL0 zqn-{i_bu5&|HY4;#2Qkr%MiEsMnjC;I{g)6Wx7r=?|u! zOou?it*c+QB#AZ+$edwd(?Eqpv@feARF0X1UzsYoUptCL?tTt0AahY{GjP#iMoL#d zscO1(ykuRnLAoM^wXLLfJCt00nVX<)DfUzI9-SSi_O9W7h-kon1T~yl9ekygS?f8u zN(HnPewx)~-yx37Qn~J40le)bVFNN1E;Py6Rm;|qZET0|Hxw=Q!rH=@?oaiZ3agfh zuP&PLQ6g-e^Yb|}IZJT~TJ>;UVhgow3oD0Y<>CzVHhC|_y~3v?~pj>x#-CIMyP;dfbaTYRbEw@yzhl4;)X zx9*{MJd8TOC#bZ&5@5YxTam;H`gO(P2+4^EptTpJC|Op8Hc+p}^%xXT{(@#bUx%U8N^-9XVo=L<7? z;gRs=*ZH8&pT>MSTpmC-{zDe9G%zsArkWaJyK&m2bP(Jg&c<2fQ#}#fAFK$P;e7@K zdMxBB4B+u8ZaIi=yU<8D0Y~6}62o{0S|x-8I3LIMdGad(pO5GN4jgbKB+f>%$X^K# z&gbl&OH{A2l2OZOB9LSyt+MiEzVZlsa+Q{bgo{ZF}tZ7^0*=uDw+^ zx*d?!#|<0#04POgWN&^QK3lp?cL*a4f5H%e6pi~d(rtf{t1B}kpmt_W5=DyLP5kiw zyG^f6A>QIq<=?b29w2M4x)J|Qn%|2P`uRBBtjp@|VrMMp6{jxF)*o2)w8U!UCvJ2@1jA zg?N_`gC51cPLD=Y#`G;>dFF6ewdH(+rMer-hmMDBUh%aBdg-|bgK=t#C9^+3C#9(jzdse zn#hVA=CLe*LI5XdUV0|2NW|Lb7eT=1xtcf_*+RWJLKhH(0uTXo_FVznzxFc)O>l$& zDl9BsEBpS@YJZH!=z*F_I^+j-JLosZndB>;yAAF1mn;7*Qsw&XMv{N2+daEUU07xr z={$p0nd4}>i66a&{Lc}E>Co@{LJlX|`+A9+$JswCwE4FhaJ2di{kff9ius@)7{|A$TV<>KYD6>j*-eLaW!-)E98t%3|_ zHb|CTf+s>~W!f}-m&GDK`zHIF2w~`<+#%rH!S!}|dcC=8uHEVwKQG6hL23X$y89~2 zwjK&ms4A}>I`M7Zc~<9N#=6~&FsF@Hx-Dg0@_x#L(3gkb^%P-ucjE~zysY^$g*x2N z=!78)fNq;b&O~Z!DcS5aUn4_Q0RRAiLIE^x9)}Qe3wf(O52tgnbUL6%9MQuNju2TM zGf0F-13x_->4L-C`~-DFRQ(MBU+@AJrpg(dENF|(U^)Ty5D&y?@$pFx9!xF+0MVm# zWJ!z;jL<+JENx)L_|e0Kk_w>+L!gI@COA>@KBtHscyP?^KQnj&%YTRb-sG$2K+0@j zj6rhDyzYj{<{@~JQxOmuvdfG z3xaa1>~Kf}gn&5kh(jJ!u|_6jL?H-=?lfV%m4D^OGJzK4vC`9}29ruGc+$kR0_Dd< zk_!fWApjvTkZOaWHeCiTQ7L>vg=1HOEvFAOb_(JHB9bp|1SkDSeV9uQNRbaH*byKK zVDLwgc=O9Uc&5-GBYIdQ3lNOb<(ObHdvM7JV-HLQ^JyL_F}EiOw&CaER&Gp`<|h=_o_ygxc|vB@7cI7?WZF zIEKcHZ6FYZUDt;Y7Mz(T1HCgp5}`AT3h>owXiM^*q$Wt0JP^+!oa@t@nTEzU{Mnrg zh3T$tmLVGm00BVVJN!Gwiv4u8;0}ZntT`Yqzx%szK+Gx%Db7`X#Xt_IR8(JhmT>s@Phw`UZnS?hWl7G z#asAaX52<|fP1b+JoGVpYcNXsA`pN=0DTigON`|Ww}=(Jv# zAL{q4E(|md7;&sH?Roh=$1^*AIu03#=-b0M=vXY<0}tgw4}qgb?wi;blFeug;dQW! zqgYp|csF-<28;K-33d%+Hqd-s>>o{sVD^o1t#l0M-YNDi7bb(RXf+KN)-7vZLq@Uq zEeGl5qZ#{Q91BSIm}MA$R=DTEUu@jyyX{zT z;}7r2KqJV+!Qr*>v~`VXUzFF@WyPZ1iv;oH!!Oy-R31kTqkgT6cLs;B9PFaL&2Yw$e4` zZ$+(6=B92~i$X2A_cs8b!bWMzmsD%A zd}GjWaS9IE{tFg_PaI2y$0OuxrF(-!{&Tg4OTOrQe}yc(e&zEp88R{m05Gt9cJ??y z|0~HN-guj2Zc?r|qO^;4A3aZMd;$=JCPSZS2m}D#*I_e9o(hY=(S@Xw#P}HTZ@-_K-$yj#B7M&y&pYOb{Rd5ip}`U(eKGbDq<@r(X>zJE+ZYO<6B+Yi@69 zX?d9`_D_B>yx(9gFXMNK_nd2V68r!VAOJ?Mr*?)?HZau_^;TgLxuXB1T;t}JF#Zy# zGbCn6UT-6DC97jieI~mR)uR$kx7OX@I=8pI4m%o{7$hFbH?@o646p8QD2a-AA%F4_ z;kByainI|3k80`@v7Z=?3$vkmUJW(F?wy?XTQu9JP=vg10+Qe%2m^j+m3VQUfBON> z^n`H$rxkl{(=U zl2Sb}H_Q3>O?k+VANud2?IG;ai4xhl=kTYDBP)N+90cBWi1qkbUnT}(i(8cP6@IsC z7g23yH+5%nPIqvLzt7SkpC#t)&24()Pp}`7GUJ|ixu#L|d^7*v0-pVuHRFB8qx4Qd zgdh-rKKrIBd=_bauD>(-M)sYgo&#NL0uMU>MycJjAVS_S4sovh()`M zL@HSRhMBwizXggOU#TYOF3atV^quFg98Z>TYXo_dgCTBQLo1R@%4nK&5|Y^F)!P1i zYb$LSrV1<_k&`1CftT6u)x5L`hL0oW$H=hdgJp6m1xyx8a#GxDTt9~n!VrKu++P8? z4OtWbN2cmlxHfJWw?$DQ`oT8&;p6~77jOrcU#4dl5K?AR;bR5SsZ2PDR0A-H!p@WR zbe4a+nDJAS1po;R;rgqGTQPxaPB$k9VW#w{2~KSTecct5}v1?Uw>;3~q!gJwi-GiS1^1T_NboG|F5k1Bm_x zVbj0MZ$=DgZhZkvXVg1e2C?X_8Jn~V_72MIvb5u8I=#ASu>1v_YbTEE zgxI@lB)BgJtT{VFIvP}<|B3LH-R1|3Xtfw&__UTlM$HApX~iYMqxhA|Kz^l}H-qq}#>qp?=vl3krU*g+iSZn;IXdLvChv$s z2k+__-!0NzkH_n$16PrbLJ%N8fda>#e@BYII4I_}Fp_q@wd8XU&5zkr4Sb zkx)LjmXWLu*j4)>+((M&>HRxIMNL>Z6-O+5Q$_bFy77ox-V~iO?=NRFPy&O z!x&2EdC0yXx@vX*AfJWxU->UzI{WuN582&i_6PW^@zWZaNsCj3h7bS*w25nVf#8iS zIW#I8&qfo$ zBW@dBW5}QY2$Ahl2DCfMt9{#p?D1W{?5|(GIKv349_Dr$eh8GmHQS9@oR2aNHnZ2! zXKDY|@_fMJ1qu`bbp7H`pvRloAE(~6>(yrAjVQNjoxx&z*i|)VWxQO3S10OO=Kv4^ z01aegZp`X?3abY238cNk_CP=1U{j>D;k!0bMz}tT3U_E)2VD@iQO{$Z@-O`yN>zK)OhhvY!M5APhqlC@|)XRr6=iYHOfr^RxCXEz1LA zH>|1E_9y~3s`mySU&23Tqpy2HzQs{s?eCZLo%?QAGt4CHDMsyLdi6_Sz*LuXdm;Ht z^jqJQV{9*|=xn~xL7WIb{qfd+vs8%R$DNwtcmhKv)= z=%t!|rT15q*JUX1kiw=F$# z{lTPJUFhqDaR>lS%zywOJ*E479@1w#REJp1Xy4cGCpi8IqDph?ulgDtL0DR13Vc!a zxH?z#{o?F@>%KK;ZcNuatMyj-ij9iRZU@i#-{L5p*4VsLR^32^gc&Nni*ls-G7Q=5 z#xr%AzxBCsTk&J9_t`!|7M+gsG~wxPvkwXZx9~evGD!w{hn%uglFaJayz#XSCkA+A zTz{wBE$7#VXB?q5siTUzwQ{r!5FkJRnkUh_g|Zn3x8whN^IgR4oSm-GW4Ox`x79L2 z3UnAVy9&>FBL7K8h`p0VkLt*o#An}b^EOhoSlC{tl}Ttbs3)lDNh;>Dkv`FYfdBxR z59xNPg>p2#E&GLc)>B&B=dFDkz23Zgk$}Yuj#{?!bPi$IN;j08C1R5TKQXHQ*(ulL zQRBmZlqF6aJ7L2dr(s!c&5YDCssxjD9$!}%I*Vsx33%s5ibv&VrT-1qU!{os(TGHn z;)NXpb8}EZ016i%)0m;4!d=y>#=_=KzN28iPwMdBYeM#)CcQ$XYVnW~5z+(X#h;z6 z(8Z*ITtf|SlZ|uHf#WID(xs+YYQ+2>KgOdC@7v{&tBK`qkkZyk{azQlOyo&5+S?`D z+pn$ib3Nou#Etdb-(I?-^k*TqpI+kOYo_11`}?{a zXWXDsSu+xg=S^4@1^3I#0P*xwf9lV$c$~1(#~1BElh}x`D~$Py8hOQ6sS*BV*FW_t z!s_31Q&~n~>DjtY^8$Ef0`Hm{3%S5%qI6Uc0128T9?mLqdd-X#7`Ecjn6rRiu#Qt6 znk|mhx?tRh-%Z-4E3Up-D9BU+yF4Nw*-sl3pP^E50^m=xq&QzAPZ-5JL!4YjHSzi7r3Z~YW-5LGpfZsA>)7YI--*IT)^g$8Y=YQ?AOfAu4?Q9dEM|qmiv2!;9+7-yuEN)%a+$Ik z20=M>1VRu2U7IYlCq7NqS-re!_N*(ZRs3nqEi18sH(ED(tis99$}t8!%@jfqGKfMD zkvUbQdzUfohffK`u0@E~%2|R>rg=*R*8WcqU;sb>Uuv~0VzJzrQ<$N&(+HSH{i*^J z{#)3B1k-oC%6I8@ZIK8-ApkDCHxKoh4VJ$_zYi zhqTmbYdubTSFx~!SA%U-TEYJeGQrqcUuN=b{YDUn8z2u!jO4@YTPk*!_m0+S z?*RYCN($V|j2_Mk9863#iAC~jEsB@UT7TboiMi>qmA4^&Q?I}$p9N1?>2E&m112`M zNu?nPvvP6{z`C;Z(qHq`g?_zJQ5xOaE+Gg$S?+!D`9Ujn>Bq^==h2xBQ0%R<4j6_( zMLnqVODzU!$zOPcMUPMEpPvM(m~-}1p=!q3xcVdH<3+SV*x47(B%)c>VS%Aa_-R{k zm;eF-9?cDb5mK2Zjo}%lF8g>uYj201nXE$?iARwD0IR%R@Xq~Ud7GS_0ssKA@XxZf z&urP0%%u2q$jQJTSpHN108{mIHVa@&I{P`ftWEc)2$-T{>2Xuv{(R5&Y}Os-LJOao z=gs`Cba78Rr_0otOhtovi$ITJQ=r zRa=tq&-h=Fd?9l4Dz^tSvZ%DH-sS_%1DcwFNAPk!Ljg4tj8DMLP~lsVA3JGOfM#U+*$-Zw#Fb5v;H z5P%L%&%7yYx1?5NNMB{G`JbPL_BJ)(N278+wo`st=dE*ky3=M`CI3zZDfJ)Bstif@ zAQW*MytY*9<%E(FDLck{6jk{!zUx`PZSuV0o3wQNh~N9n_=1ukYYzjyCk5xgQ8(!3 zJP;s2R79YDFT!X{4rh){UmD8<00A2N+~EHgf0>i}Pqei=s#X`6YB|L(b|YzAciw8} zrL!=)RO^>%9{~vD^KVhshwPT$B85*AF zT&$TN_Cf>*0#fDgj(ASfeb=e-KDH6NB{68Pr&e#tb&#K3zyLtB8nIh(ZAf0rDRLEgqQ%4p`i)`f^(2B7u$CjtT{R(yyoY-bjkT zLI+OB-MOrocHj|6bz;Hg*B)!&I8ECKykRlsZXfq(G zJg$`YnpvmX@wlQ$%}i`)-8afG`}>Cp3Q)g)0?hpT5dC)fAPBk7)Ihhw8|u|kF!@yw zOEooZpACE)_yWl@4G%uF#5!9L5GkXLd>oC~xw{uk)vrle5w#Rk*`2+E24J(Hyo}dn zO}^jRq}j(x*=OBG-y;Gm`H2r=j>Ukw4Hri#E&_>bD+R)Xi_1=dhE$1B*^&^Vn%A^> zqw>A;zWcN2$X_FM^08GbkNJk2LuN}ngPYCyyo?z{Ju|(UrGNksW9P`5k2^&;jGB2x z|HOZ}?zOFFrt&@$!xfTNn(OfL7_Cq@OQ%##4t+fF6BeUMX}lG6Aeq+;?8g7j9|BWw~% zI0_PnSo@UxXkp=OGi;HV?LyCokoOG}WpwncL)pPnNUG_=h@#?HlNQyp9bqj20Ht#= zCK^sd<7kMLPw99gf#Q5opybNq>Ny^hh0EhQeb-&{>+PRI!a_^Ve-lBB%k3m~_gFWN z%JFwn!#)dJAHl2RUE}jw{LIbq8Hr~Z&i|Yod$FW;>|Yx>_O%a|y+&&J1{0)FpL%94 zRoK$nGb6Qxdk?FATRo5ZkM7I}*8tI-(?#Di3iqzN^Qk1Jy#~5$1=|hfP~gxeOAf>G z4^QvH?lG`v8K!5h#Aul&EDtMq%;s)hW=^g{uGVUQI!H2;;qSX^rq{#GX@Evk!q{I_ zk+DEx=kJnj9&GMNjRgoWaJ7rPWXxj@a(Emw*(;w zT!gudaV9T*6@q@+f6{)5P9U~y^NCKHjY!65j#Y|u`CXAGZX|AZyu+48yBmhl2dgUo zj;w3eX=&6Dt+mnN3vhliHn~~4v`ILs>6~Z~7~c2|B2~-b2tpHNKVB;~{ZssD8C`M| ziPota$BYR9zm+M4&m(~ZDAA&h&E=Nmwix)Cglq3=Z)RyWWOY0v%gN%?XuVazwV5yM z>TI9|=RaymMlX&5`I-TQ?zgaS+ zRJby~l54}kk}JRfgSH*!dzW+96x>VjWc2bo$zsv8D>b9X9`6jmaCTj*wohH4OvH$E zpLC(yWoO~3=K67F8{g2de^$|V`tytp3g;uD&CgtOPL!>##-Xw1t!{eNE!J5ee2%L^d0dX!Y5U6p>p!d>)=k&yVW~n-q)T3 zhV7oq$;zk~5FH@Mp<0v@hKAJZRbrMbTNk9V$eyv|rEv`rdwrkt92o0UouxN1??2J@u2qKqfBuDmb1W?} z5wZuU<_>-@?ouIpA<{$R<>zrVJ{xeoJl!XtLJ$Z*6SAskYPn8#9uj@6!@U|143P)` zM5lxx0b)Q$`+`NJS0W4WBclv&ex!+0dWrnWCk&NDLQaPtP zrZ8?fvy8sv?&fJ7CKOlkk0iHvo~S?p;PBDJ-}@Ad^GgRdDq}b&SP8uS_oh23?Ni^-WXUlO|O+6<2eS66O1Ib!Mzgm~&D0W=;|j%Vc}603x+-yg)ZBnoj6p3>qh&6#jjVD*w&fE zFnt#YZ#49;YPR>qrSx=^FP#Q!tW#XOS1MbG04j%OmW_aqken$e_g_cAFG5n+URDxO zMwZ6Qvj6vWW`HG4=J!1_1Zk)CtK&^?AG3*;(NTK(e!wQ<$Lj z&WfRsZRipg*3&Y#*82U=eJ&X&wFR2)YRY2nbH!Nx7Cv8IJbuDJGoB}HKLd)$tFJso zyJg?!QFE8pd)kQ;sngk(b3YxiMFvi!KC-^rNnuoo`k_Ixy^xySR!x)v9Nyn(#YDnY z58iUwxJedHoQGq2ipQz*qRQ0uG>ax18jX1{lcHhA5`O*?s?W?CS_3M<~`{N zic{(5m58@{SK7H~SFOz7OZiw{12+5061P9jp;7dV3)e}a*erUn@BFp46zPnA`&(aW zOIY(>UX4{b9HJdVD`le2yL>f#A8W^#_U8t$@qo2&&wU+%DSOcNrXa47uGSpGMrhx*^r)<^Y@HNj z(b%F{S3TqR&!C^ne^s41%g3_DI!nte0!?}B!o_-5hNN|WUpM6pApi=)ee|KKhEH-0 zEEN73OShQ+bpmHy>LJj|s0_i?hqp55{T2#Ye-oAiT*LG$sOCrcJD#fmfdBxP$T+o6 z8QI~Pn78X+?=0ogMjqzKVUhOYAG$w%(0yLp2ep55n1Pe1@5 z2k&xpu?43xrErBA$9>}f*0_#I-hQ&@7p}kBY#1}>Q^>gOD(Gb&hR_AcgvS3!&Aj#u zg_O2rWlv?*#OpHchl%;4E8K|`R`6=YvrN8U0d0DiOGZ;2Tc1m>ePTbw%(IS918vD- z>^8-hr0owB00VqqS?e}a(BiQqWUg`J>{HsOR^*uZV3Lc-00Ge@3)*9J>g$fAbLzO` zt(&7QwukmOl@hYXh(ZUM&5zx8(~!IG?;8NXJouYL(a8J^5pNmizt`!a5P(7evpt65i89w^QrLQVNo#n7VA3drkHQT9$v$6S2gu6Ska#RPu+8Lns)x_X6YJO zGD@B)TDht)-HZ8AdnODPc72(Ds(@ z{2YD+M+=C@6tcMGVR~dAReR%-H(S9?Xc6pR|INvUt-{+eAtTW)`>V?J;&lOMFr^CF zn1lc%LTN_IyLcuyV7bY02pR{qHFYhlSK<6Z&i|?Z`PSij6oS*wz{;wQ-DY}+Bm)xG zQ?YQVNY@(AWIYGupKw$6YC~zySwv72tVNYvtMuRESfbGsTK{yR4-vZ+BB^M?3DF%N z!bop|*HnDMmy3wFZkI>2|Ln(aQJGrFGck-d^-3`+IJf8ro#xCw!WwkZPRgjyi-{52 zWYx9i*0k_w88#P&Kb;P^;mnQ&${vGU-BP^^w)p_MqwNfa_n-Yx@ybcnuZb#ssT4eN z|3~I<6$JONNqx}>08iEZCJr-QNHNYP{{)O)tp;T`&V0=LKmiEl%TZ$V#~bh`F!5kR zbOWsulEt>c_^iI!XA7s}fsS|8Um^%&j@%5+`9Fvq~nV{k`~Yve&o9~t$1X)Cbm_+Ng!+syzNc0RH#-O1nJ zwIZ%yY&8NaB@{vsgs0gMgdt`Uv)cc<$Y;EzfB+KG(+aGieon8rp|T+iLF8JAUXq4x zwDJENxsoIc@gT*Q@EPs-zN)=FK}=*x!gv=Y@@VmByTs}Um0FmP^iGhIX&Q>FiIykN zf7DP<8-kQ${SuzaAX12!tIi^31sa~1&w5Pj8 zL;PN~zR_cF`?*3Z1UAa2$&5DE6?B;?=SQd);E=BAprPdq8FX!vrYwFUI0!W@0-Tt9pEh zH|f2x^ih*GzfFn<(i!-a2Pe+Gmx(RgFLAi@0I)z$zwL)D6L)$Mu0ScpdQX3Pf*pfU zcz~b}Ko9~JC|%e}xSyB(^T{?J#F6_2r}Pp=|!#E(8q^fg;lzHy(^! z8s+o8yp~O>+h8^~!=!F^#p|FK85eeam$hNFXxTH2_+eVQK@2!H9?otB zHopT{7Q5z8Gasd*Ou9q|3d}>rxxWeY%smEsv_f2qSlL5k8Rkb5FRS1|{2Ej+*tlbO zE2I)jUFt{%oqS?*;~weeNZ z=tJ$0;(Z2Too={n=xU|>$p04^^zUQ48`&Gy8(@9X^r=qx$pxi!(G4@pR#Jqw(TETL zdw-DHj)}&`FU|$cQe1vNN$w&be1stgUOPROBjMjP4+n`1+CB0<4E9jSr?=Z9|9d)K zik)}HWAYypqr{n5jYpaWvTfLZ41eR;a>W<9{Qv3JaN+TnMS-^< znD9hXMw`~ga~gwr-qJ8ltqKzt<$*zQ0IvZqr>1O*@xAA3MZbnU-OX;hXF-67NLKeX z?{nfFwOk)S<7EGs`JQE*wior-d!`hZ*qb{s+~|2IjV0|Bq-#rsI-iZy%5q-scJpx1 zn+8kWYP6>>F=Kt9;)N{1h%fMbX`Ro#*r_CBD%I@W`fq*KH6K4h2g&NO#{W8@f3sOt{ zbH-k&zXw$!KSIQ4aTH4w87s-}N>`n6+#B{-|Af-42ryF&o4gH$%8b5 ze#g+>T(dEL(B|BRII|G~ObSMqS`D3k5=uj~#0!;pQPAhby~bO4YJM-;D1;!PI-JX{ z^ZbTnYIEWU3T!HJ5~w#j-c#xzG(f=Y%q{PG+&#IT35C9uZrJzu$-3+DfEm8Hh^|SjQ73wOBEW{tPB6m$=WQA|g zJA#;wt3Md4C*7er{MtWhv*7&UxQKH=v0fR&#RfX0&F$rU#|1!;EYGzV8!~q3N#5$> zYZ`4Y6+oQRw)0yA3+?-I%&*mveAjs6b&yzl3&xXhR=TII19q>%-1JC+48LL@iNbW$MpZgczNQt5~K zi4#SYv}P@wfm4?zafO5G7?%NzVgjZH48oAUT$i%JNIJmyPQL4Pe~e<=rCGWvFI zbcA>B1@AQPwdnbjrSMi#c2BHv5GRsu4qn}2&3kh%vV5DVH3TQ_)M0}OvTc?nCYzG_ z_#(Xy0+9z8#7D()d3E{anPrYD{(%H*&*nn*zeqpmQ$R>@$J?t!Vvt+lh7%^OU$}RDM z3F&o%=O*f;CcI(Wq}N!mhyVoP_IuoUdR5^tSf@rdn&8+{8|{w(3gNiPalsu z$3Qu4Rfc-3ErxOHH&ML{ACBX`ymPE<{(v<6`Ph)hNH0MrW-nal)Z8p|GJtx9t*4S; zhBbgil>NS!p(dnoX4r6Eo80)vAt_>!xd!N;a+weSfCvC1Dte_;Cy!6ca_W)K#+OgW zo490$4l)pE*B9)KBg^Odb_!JnS~*3kE&aB0MiYlqfKs=4P~n`dN@pYp4CB%zY^`>& z2mnJ7JQI=AZakzgR(r4B$Ibc2olqFxo^yhb=Gn-3>pi7~oa(cNCVN*gWRAjcLJ%HG zUrQ2uuhFD})EeeH(j<}5@)(|)hgB@mttY}V7uofj3jl+(Xq?XP;>nULt{s717N)eL3Y`H9_og_tKk}h0*TIy8islb#+wy3=EDXBUy!dqE}8#E~4k!L`H7N;QSs@45bAs=r|IM49p`<{A-(K1!jny_92;b_=L@$`_*%n;*LJ$Z*2zeDo zV98##^CVAmN^!_ss)qR%&VR)+-+##RzJ33!x?QmdKnAR<7t%k&C zg7u87V-EFBG_dmRQv!n6+>2nE&_r|dhUSFZ=uI*Ii?LLU&rP(S8T}Uw5S3l406#Zf zEnynhVMB7E%+IqM0%$d^<5{S}P8wl4E-SWTy6C68yJW4(xyWQM#v7F0@E~1L&bbg$iXZ zBZk4Ll$KYAuIt3qo%VQ)KaR#JMb@#rG1gOJcu#Z{QF8vmMrclS72uuscY)P7vm#Cl zxj<=_dxf_DG&LhFJS|m7Qy#9=Mz?*OF@co3ChVn&8~K>>X5ad(FZVxTIW*iSmCnK5 zqEHYcA{{+e(cpX&J>GHqdGsZw?lP(g6q~^aw%_ ziGJE1_IZzr7nK?AoCrR4Rs*)Eq0J)Ov|;hzUWX{$L=h_emCLs6Pf59@RlT(;RTs8- zb+n-OI`(g9&;bB9alFUVs9e576aSo2m3^3gKGQ+ZNktF*>2vew-0UD5Km8Z@1Rw!u zsu2CQScCuuE*&TYd7Dz_XHwpVV)RnYIauj0I|+|bqZDJhr0%korXzfDHV!G~!B4^` zGVA1|(G>Z{Vi}yk%AneM6xD+pjUrCB@rfjlz*4gigdto__?ihtYHBBVxsj#Z^W>qL zM#z5o&{<%uTrWkZ$CJCOC(Cd;rC7hq3hTns?$x7Vi1NDEsG!Pq@@(kOsh2n_h7S)i z)xLG7vj6*?rljoVV{=WUt!x(v*%AI2-~8*KX8PsiuDe@b%-tmL=wcU)bcX-|00bEc zo!rw9fE)OBxQF#d6`t?8XG23HZK}^?1pz#wu^eAFil#>lj13Kxx7g4$n*79 z9Y!%kg&WQan26 zrwI_ha#HgWL#&uW6sU#$M+|humZ%OHDu99`XZ<&xems+_W!e~QQRVoT}j_#@O583Uhpi8H-Sz&bsuQ!;dSY-v&x*tb2vkd5ed5F-t!HL zv0finssh1Zef&{ae4rr}EJP#pE15>G4hQZBN85H3;6U#$EZqTUQ>rGQWiY*EfPUAX zbVBX3;TVB@=s1owqU#ZaEF1*lZp*mOTW0^nfOJ_e7#sbAYSOk`?;?}1mlGtrF86?w zlwuv$Lukavv2s=2Be>QaV7HqRt_FIDni2v`;JWd<@M7U1?jDw;lP;dPMjJ&Y_djh_ zywaSpc)w13;RQMW&FzK#d6}vU`jqet+5rH7AdmbU5*GzK>yDM85P(7ek8I%`5p}6` zZtt)4>#>+MbY0iiIyj^+Y0rw?ULkwF9W1j~{z+)?EpriUTO?mzi z#RZueft?NHJYbvY^`JraBD^6n#)g_4gmHqTj%!PUm)VE6`q#|&wd9buPC*}n@Q|#E zu)m&JO2Llp_Z8LIocNCAmWid?+7hF*ggfVmc}4j?ssG`b8w)H3#HlxcgaO_UY?mfe z#e=tJtJNrhh8n_O0T4ri_q7|WY({}sU6{iW@G7Kb9Mgl2C{Um_s`EEf#^e{iLpkE%K--IKJNyNrBZ1Un;ttAXn}c*Gdtly?8`Lep@4gvkKe~4(JK@N4 z6ws~rH52=0zMtXm0f;nhqlzY7$Uo(au#nCfh{V}!%lb$sn07TdxzvulaE{V$tBAv)E#nFhW7R#6dE&b<_Hi9*z5=SYgB7-e%=zNAQPN zRJD~W{+W!r5CAyiEl;#7w)WpL_mJf4`uEv=qLIV(3$|*hn={}b^J}vW@1+oDi0x6# zo@c}@4)`7u*Q8pSjb-Y^NL3&kg~lX9p24}d=@MxS(HbJ1g(<*50MKg~U5YRNJBKgV zEtQ$*;_yNcI>odwMll_Z&6sm}^PwYS?|t2Cp{oY8`M)Hh5QHY*X{x{>j+cLg1 zXaq(07L||y?yLMSgK?c}=Pi)~bKxx*9jW06LKA5(T?cNx@uS0*yx&XuWJWGp2Q$d( z@goIc9dv2O0LH6J%90pqC65EBXNIGX-pteB<7wsw`5qF&&wIAd8DM~<2vCtnDn4t+ zXeBoH{}b>(4-kYAD18R?Fyu^)JT?YCWG>j1s@YLDxOONzvyGGlE@&o^X!M%uNmKoX zx{>chXra6RdylVe^*;LGE&F75lNt!Mot_-8OXi9{M4;gfsM95{y{f(S?ddxyL*W@U zR|Rwoxoh#946g?VVmGyJyUVB`01IbuJh}+9a8p!nCaR!VtUwA%rno&yrm(2yBa}06 z&)~ztc)ztMbN})1{#dhAY~cU^Wj^7jfm;nHx5PM`;x_b2CF6;F-)8?{k4=w9RbrpK z`&qc(_Ga7PojoxV!*bh-00E^Q8#Vk%zUZ`5n!-_B6W1B6_?DFyt$%DOLkTp8+P(%o z6xS2=(a+DNzY8@#(wW@<@H#nlNkyL-sr|UUKMR6oJ~(jBk++E z9MQXE)wxcZ1^el|8A1!4#yeM}bzlFj7S_CKVn^+z$FeaREV4z#^@Y7|){Sne`=)0u z_8m$cOw z<49P1zjq|fCwfRPuV;~#Iv4~X1Yaln@t}TUQ1T!EI@7mO@<(+! zDlf7uKN5c&yrN;e0uTU?`Z#gU#>{3jvVBymiOn~@jYP}~fgwm6@$-sAHxtGs+u=C*jN37GjJO9sSprSSbM znoP2JW(&p6cl@4Q@DPA2A)&9Hea-w42teUjoEn-g|0dZ?;)(v>s>$Dkx&PbLFd@A4 zwj_ALL-<+MBjLs=8lz=TGQ1TeTSU13;h|;wh9Mr59YrR|9KMnzRsL@`m}8MW@#@@P zh|GTYUHKvCRv!mujdcuCfNr>;W(+k&-1@W?j1hb>8Jgt%X=rT{lq+~IFFbWRZhgga z39^yiob;q&k0|4Fc9k9t3atboL<((|gm>;}zI{In5XvR`qcrzNny`e3ghOYcm~a3B z1k>1LjKnOZ$+zWM3aq$~UUTwv!@`Xti|Ptc;+nSeiYb1%KHNr*TbnaeYF^j?V@Xar zD18l&^X4_R?^?k{0M;RcR_6C&HYx|+n!n@bz+1ztC6?>z!H^PMX)<8HmeNIedf}l# z7Gd}k+HDvOg?TZ3wf?$ix6KB4IT{WP%^3V^sc`?cog#aceIcK};Y=0krx#jHe$_zV zk|-05G{)A#F;gd>o`m7LvC#8Q2tp98C_7nL@MugCRMx5vlsMg%HUDgJP8*?L8?@HX zQTmBpmvvEr?Nc`$F^l02_CZa@k!EQ^-sJU~!^kFV3ZrhD`Nw+OggNJ8gz0@bs1kbH zon5i|#J-2FBb`mMMwzDbxxREXyS#$;x4Dqa`v+3>ADpR2UIq4Wb# z>)X(P01?R!g!}YQm7dxTSDsBi&M;a#7ns3~Ed^G7YLG0Z^G>C;s;peOI{o*QSf*-( zApnE`!%;4WgAS{P;;MX9eI15Bkg59jDtmyiYcM?H70JBArE=~e2m~MpRPtj+xU$$4 zMAaq&1o=L8>bHT`SsQZD_lN&<_kdbTxaE#2Xw}a;swG#rkmA@t?SF48ey_qw`58k+VLh z#6X>wthD0TIoNhwqisKWg${=gKAj5(C32UvzBjHxBZyn!x@c znUm8Ru(vD85Ssdh+2orEdEH<)0MU4DOJmlG000|ABJPp5p*8P%!<`5Te#J86d;8Xv zKKk_n$B#{W1>x1l-$PnyQO1K1tZz`}gyX+-VLJwI5j_j3?2BEzVm2gh z=~W>N5{TD4$k9^ZAX#s9tyIV3T-;a0YCmL&pYF_m)jZ|}+MawUz3U;Bqs})rYS)zu z1TFxKaxLD#QQ18Z<%$3RlBzSdL(r-FhuO4}^pk-_4b?7~2WKoW`Ar%wo~UI$a4C-Z z4M2VKbTN7pPDO2$g2P@w7jgaI+dR#=OA5H z3PTS9z|D^lNPQ}yN7zMyIABH95-TymvHMN;dcAYVYS|zF0s~CrAe*exJIcXq1~#XL z7nv8w4LT$`2Z5j@u^mj~emGdcP!iwYEQ^VCf)~6EXGvP0P6<8u!s2<6;tGTTc)dJk zr)~@q&ce#YG3uF!Rg>=$K66;a9vz!6jlTBH~KZz@wMl$aUV-RZCqk$|13 z%%%Jsid1`*j453lY~QEyF}lSJ02^NoKi?b>RDXmDfqI+qemGbNeMBk_4Tmu#47j72 z=d%keR~=8aUQ_BgwNXR#L3EKOh^%3c}_ z(SJWl4biPtszI`!8VwV-S-G2gDErqRpTKUx?Op03Nscyp(~xFGfwZJ+jHE)b>(czn zak85s(PX+Ub2$a{OZdnAKNMV;uRlu!nCZ-^`qnY`1<-4dgdqiul~LndcMn!MUvyz# zTw%KWa5E29Ka_-xQBCLm^kS%8!pg>+aAAb@dbh*%ks!)25~@5*RH3p`ohsIcj}iKf zGs?M-ga!jat=}CTAjRxAP8>-%{x5qsn3J#}2tsOZbMT^*_$HFskyMb3VQMA4eEH$N z!Sn&cV32sxp#otgc;eBQVVLijbLvS||+eJe0F(~YD{E|%nyNR0C)2PN{a z72eJ;uc9$FyUPIpfDY?(#-TsX`D+bYx*#AB1rlGmQAv)xkKHv{6TR*}elS_{h@ae{ zyKBj2{nfsc9@kBE(m|0x5tXc9&IkYy08;e9BbFwoL#HsdM?-7O=hgXIjHEkPD9mNW z=Af8*Z|A;zr;ia2hXX*aL(H}x=j>3CVmU$9R3MFjLm+|*U zaK6dp>E&2-6I1OxYa_Y?|5*Y63pbdl9z>Zk>TfO)aw{n9D7)p5Nz(3BsY)*EN~`4S=`>mzfkgz3dRqi(Tc!*=SrB;)d=2nLI=%YKI0`T((zTdB}1(AfXRCKMZ4I;r6A)mPZj(`Z8@{0@d?Skc@@8HMU2}gj#ytAJgi-jUzX7caD=~PfrB<;hQ zvR}(-r>h^Fo+>e_J2iR8CALVP)uxZ7KvS?Vwu@|)TBy&K zb7;3NTPk)!b4qu6&D0vx=_ixFUNvW>7Dl(G^u{i4?dF%5cYc_*bTg^&HbtxEFO$AC znA{Q-%tQB{lSAXP#$rB3Y^@H#biJ7Mc!%Uw&Yrzntv%$g3a@_&cd3AJB~#Z>`?Ol% z+eRi=gmp~(fFPyWOO#UO!CFA&eA)H5qMVVP^G%yhBc9kv+(1ZJ^gJt2uWL?3AI8-f&G^kj5#*k)ty?WuhYi2m{N(XU47?|J#JrF7L^gE?=8b0BFEdFXkOF@5xPQ*2^bv+|Qct{0I>_M^1p z8)W+EQ~R8^rQ0hE=Pm`Qc!z$ELbBih1q%AQq10h*@~K(A1KQ{1+2S|m`hFGp@X_UV z3>gKpg;CbGitG%MFu`l%t)wPmNsRf)Fjo=ohmp)vx_Ud~>qBEq65__JHUnfOTmLsp zIx!TaGh*oX>uyNs6Y7fS)mk+OIA~yxGgUvYa}b0A5C+rs2JaReAIZ`awk;R@zc?)g z?pRXzW$~xb8Ty3S**vRE=FMnU{d?fNC{Hxj54|ig*Rdv9=>tcIMWoaFo9%I7sdS(K z7L&crysm-ui~Tsk^2h447Ha?UIwO6|miWdO-Fj~{AAQ8~jJ|sJ-fE4`Rg&n_e@E6H z72CxC1mlj_JWpU`O!!%xx;*+d9BD!m=gJzjC&7$olE6zLkOTq%MHo8SLi4bh8kGp$ z0-`jNk&ZHpVmaHqX?JAWNUwc=!~dS>>`h~7D>_n`G@yenmnne zEilX0#N6Gk%7_AYOINNrSsQQw5goTSbb3Ac&nR|VY1_=@(Ap4+*4@hJGTTrD0y%!$ z%_GAVg^R0Bgda;@G94QBQj$sp<)?C|!cquBHPv7G`7!3StKR=>D~FM2T;|J|*>79? z_?>Xjn!uv1X|pF~qgK50GmSqF#fz_5r0o9_t19TMghVXjCKDfa)@z$y4!Sd&7N7cC zo5tehggLzK0xeUO_?Q3$95#;Qb1mCc93fMBOztPw2CRk72VHKTNYW3(Tv+c>WamYB zFhQ4!`bVtsxtr_(2mzN@e)ePMJxpsKib8`I>g3`1NQam66T9u(y4bFQC^alWppT|* zApJFSI(8xP7#8=TW6Sqb005CGp6y*T-iaTYV2H395voomk|5Q>gf=KN?iHe8S=GAivDq_pO9aJ_ zWnhMTGXMAWv_Z$pRqrxvqUa+RyJKXl5*YEdc3vr#^@)0w_%NS2Y8qW8HViy6W^{be zfpT6}jL{v%IfDr5g)g?=K_o#q4#MYb_@WR10t<>bK!E@Q);6Jw6YOb){0_%(_r4`T zi$%*rifP^Yj|D;8w*hVQc@jj*7wJsh1L{9oFu4ok##}CG#H!y(AOhZjQv9U=DDS_3 zAOZjszFKy3p zea5k5QDwc;u7}9CG|B&2OW~hfaD;tDm*h5fPfw_KFIw232BVRqdVt!{&UeucC1;#$IR z&w;(o;L-EffQ~e@4bPlH5QLb=Oi?ghaG^+A=57y^>a4gqo|9W^AMdQty&u+LF>mP= zo27)W(lH{=qLcM=c(Ug}`(ELK;OKG@y029IMMIDO*tMPjF{?Fsdz@eY7uoGig^2#j|E9UYy!TkB{RE z%6OZiXk2mq3DbN~Gp0B7I{106HH(YWUk?%(M#+DCiY9Zi^47zljklSc44wKwZTXhv ztKF<-1e|Y^sMAsUwJh=wGEXVxnl3((S|RV5IQEl0)~CN{?;fufGv1KZGU$}jGHgN+ zh0bJVYl~Si*Ng5yPPTt>&3G1}u$0%Neu>%c&zLY)a%j0HC;N;wmFbMu=wZvDcKfR{ zd)iGs$gCNlLTKA6Iq}{cBNZa+VRC;LVqLO+%+?8r8fh-nFL!@*a@ua^uVUAJE10oQ zy`Z9U#!8%f9h8g4AqYa%D5v5bXy)-ld+=huiaDw6#l7$Lssh~m+c$kJJJK^mrKiYt zNM}>lMUr_R$YcNl3<^h;NAi-Q4>P9nuE6mdj8Z;|Bg?s`i!T1w+me(2MR$Xk=9%84 zq&=C;DRL@YK3vEgb$~Z%^1xtp-N<>!wNx2?RlZ;!%8k&4P7Jf8LAM=?l|m`t5C{Xd z;?NWk3AGYj!J!gBEkp}bT6{`4kNhDB1MYpbyisS+Tr8L%xd0FWcQs}bu!%T=8Ij}r z*fIWj<@7MWnd$@DtqMDIsuyD=p-fIb4Zfy{NrGT-PJJd)i#tbbX@Qk%SXr5=*?pN+ z`tq50HGxA4=kDTCd*|n39`l=Cq&Obj%GXMqAwZHrO*$PfZylxC~g|rzW2Fpsq7hvu(-wgB@t-Me@@=l?}wBe#D%-Nk;% zzt={4Xmoq2`G);?&{?7JBjZU`v9~X|a;_9J<%}S}X~V0Cp((?z4A$xI?DEoknfj%r zOUxPA$~Y^pm0ZW9mX}!kxDe{8DGb9q9B`~R`8)b6?0u9Sh#<}%X-242caHPg)r-kX zUN4X;jr6~Cl}fsk-?0b)T4&1KZG{GZvImv&2;)}b2Q#4oF%_69Mc1Z)?KWC6#$!4*pVmYYJg7ox68tBP z`9Ugeml+u( zxN*G2*qm5r*h29bA-{WH^co+U*~9E(Q50~10NmXLF)*Zm_o;A9j6YxBM@82``k^@{ zSWo<7F#Lc508WuqLd`}+DFKuXE3W5w*akU% zJikY=L4JP_taIF&fH18&C6y-K%hIbtHLB--YrVSzPSKD)hb(r@3|D-bCiW@H^vZtC zAKrGZ60)Xg$~5t{aQa(TsT_%#YLEKm#T(7w(+jEVhmmX=i;Rq}$1D|ot>M?44g1bZ z*Vo7?&)acV!!m8v&loiwAzFc1OQ)wV4B&NVK}=Sm%oQP7!I>*`fbH-HfYCIP^&_ z&Dd{|Yr|XOws$C@KmZ~ixx}Fvy_yzm8uolBM()FkuRzmu%i+A{`kBebYmY5glHuD^Ry)mU?BG(Z%dIAOv0_NA z_7lPw@Be)sK6)?H`1J?A0uTdfc}OT^^2!b8qnuuVgaI+AyYYKZ!J3m&)m%3agdtis z@OB>wzoL#U4H20 zjOxuKF%ZwsBwL&s`7bIKsT^c7HLH#KoOq`R zr1%Dz>+ydnH^&?&#i7WAPTazpB#`#}@{>Qb>~R19zX}?dk=#d$C;kmNoWo>p*1|Mf zlm1SC zxCjIRMAA+9nTdPd9)9Yx><87D<-6Z3L@DHZlq-m>4haRl4GnAAsJH!8i|9b1Lxatm zz*eO_FZa@GCJ!~uo?WGjR1Xjv6|(#8!q0slV{qp!$95QXkU@NhitZxI|%)&PJ& zALeALe(2?G!>2=D)m5NE(Iv1Mr=Wm-Y+{!qyRt=O4dG)fCxYsjn}8$s>&_WYsI8Adr2cD^d?ge5)TOvb5r(d`&F0oGwyPZ zV>8FbaR6aaQJYg{`p{1QhdVN}TRN1x#JZ)(BF6Fx)Wvq?zo&DrNSyKqeg z{T|YA^A2Wty_Hg&!z^!bzg-gqX~$Ew=MVHeUa7>{hA7&Y?V3y$!yNlh>NSs^c~q{fdC6I0W}y6pxYnt z@teEXX~#^suC_`Ra-MthlCS!__Diafic=6@V{kaZ001Oy@pp-BV8ULq$*-<+$r==P z9fF0sGwni5PqRp=aY_Gwa%mM76yZtc+4g#x?}F+x%a!KrI*9p*FvSR5N&?o{M@Z`zsXLEAx3X8 z*{a)kga9H{{`UN!0099@TYXlf!j7v26c1MWN}&rFZTANT6>Rp7NC}^TX_KfCjvh;m z+OFM>nUH+D?`jNIoAfhQn&dWa8*!-N4Y|pEe%`oLlUaQ`n(cJ^Lm7Q2FSv9v5w$F^ z5pgBiiNFE@2nBnYyOM=lY3FKe^*BZlN30>{mQ8u`quJz|UZ2)wG1;`{jgc7tahbm2 z(J&Q#YUs-wB4Nam&;bB|H=cJ+nJDG9&+s|EJC6jN6s=kEqa<{yV}v!EDxtZC?V>&% zAa434NgFOpWa`DP7=(tq_Qwjr&8H>4LSTUc03bjBeo(h#BYtbp@wFVTM+aYn*yMMZ zuV)kbEpxzv|ApOS-kiLwl;ysO`M$Lp`m%LOsW~~$${bfJDWHNJq*UoDq041n;;Sl% zvZrlSs*6?HqS@7IB8Z%wqIEgb7NurYn&_%UkvW#FS6t|> zw^cDWWmZKoT%xKb9%C!EiwkF5n{i||P{hgI;1(Y^EVWMCH^U2k$3!;;5j zDItuaRMnq#FhJzJ#j?9#v43$dchCxk{w$sqKArrf%8&=R`t8>Y}psDE6TZd z;SFw(S=8XCJ`KrAf#!qyUv2x>lxvl?5ZN(?@dYMQ|6a$O9b%i+zH!vuM*>tNvykeN zJw_+MFH4Bo9Mr#X8SL7_q&nNw)^WS}<~6Kms@JYQ_U_z*h`c}Rbsz1ffa+Xir!mgx>W@>JqEI!d9neh|^Z9k?Dz1f_PKsbfr#5qYbu^^aV_hW`1Nj(;|~3=twod4YFRy8Zq5NZO*NBQd8Q<+U-@Xn z*(C(NjpuqjJ|rOX3ydTdB9i&4>+0F@u+Cn8YIR|x$N+#l88g`U@fpqtda2)WnF3HRATiMl$9;{gAOdO z7mJ#~v;qMDGoEqfw^1x_2JBDEAgDs>7frN6ghE7ep)ahIda9*xI~Gp%cuzM-WrcTn znN~}PbdrF7AiRgmH?RH;HzOy<#_SuKUG#7Eq4~a!t4d5S&mWxPg6l^=Il;EIC2V!q z>sR??zuKy}#8JA|)%yyNj6nJw@hJ?wsx#NG0JpWNX|7Z+1tf?+I{nf!{_kqG^=ff) z!n_m_vLrwo(+njuKNYCcUkxb&puerq&w|zW(B4%p_J+(T+Z#|^Gqa{z39Y$3S zwwn5Pjt5WU0evEKoc2in1{YwLe%N|iG^y?9mYP{U1fHkayu}1^f&B$C{Y6~o>h&<= zFs{|x^@HY0T5pQ=v+F^wct#IWI2*eev)zyLsi2F1tZHDHUY1hLehPHUbU%zPeBQmqv*M%;pI$u&ir+IoxW-u5eFX& zBt7DihVpD&s zN1p%%3}sCfLkImgQ#t*mxvi-=`?(nm_R?e6yI8vP#VEDD4tEbf0tX9h*aG%+sR$aQ zU!%ls1BR$zw6*nw#u(N}>P|uL>u48so)|PLg1&bHa)*_DcVs@VfA%rXlSwHm>%(A{ zS36EW;ACN*K<;x>Rm63GQtd+gI0PRZWrkNRH0G^(FlC=SuaBo_#c*a&6O-Z};G3i9 z3RoQ8QDcSgjuM*ds#cE*D(>8Pbm{APny=R$V=rnypUGz6@y4k7YZ)G&Sdo>Flwxb+ zW(tuvSf~fu$)t0!Y95kq3w!zk3eCZERwMd@g>)>vEAl?pd#5c~oagM74Mm%5m9+UJ zbKvp;Nz~LV@Zi|5QeN8V;NT4?NzX{dwWCE?uE1rjr7vyTq!SDQ0DwCyqcbn)O-3xDR?jJJ>(PBL zrfA$r5Ty0d)pk!Z&g${}HpvB2zXIk({|?b!FwR5zER4sFIJlhr6`2p5eA?-ZR*5V_ zK4o^Wax?~x85~YP0sy4A z$}roI_IBcF^9mAQv1uIQcal1y5P&p~bNQ2xp6M^=_75CGzFgZHlh;hw+FD&e^`SwM zq4BUrCXD6fwF_g2spjjiGZ!9_1EtziAzh|9)DF0---Sc@bgQel?{J< z!4f|`5=)|_i0E!X7O^)`P{gfA&1v*9V0(s^)?t< zY5e2UX(a@$boH89P~ctVLPb5fxbNYeoaiC_)T}pIF0HS+tw^o*2U_Q{|Mb4`b>soQ z>rM`-SNXPi!r$X|>DpiV6?<5St>4O`#$Ea6{r8Y4f3y00-F+MuN~@vPOGv*3c?v3{ zB(Ll!U-f!vq(RCHgXsR!F-H1z_UN!U^laTqjO0ypu@djG(z`AD7}!4g3r-ya+M?DY zLl-&r=2w~HFNG$n^TMdRs>k(jk}7X`c482KLIB-p-|(=dVSii;cqMVuSfVX&OM5^gB_uII%X!Exn_=LfS1z9gu?u->%`)^m%k8% z0h;Qc6m&_}R;^Hfm!asKxjHIljOg6$$C9V6j+CF7+9}&^ocSY>YNPw1kTP1==H_O- z%W6ZO-1f5_T;{D`3ru9l9n|Ej@T1}CoSAW@xbifDUD2R&dDWHoFm^?PD2?JRaRWfZ zF&Y3M4X0D)gBopS(DTDT2tokfPY-OlI$F8D|ED=o0lEcRN{O?b+iWxA9rIit{wHXn z^a{hF?_Kd!r%+S2889njsrc>OEcYE(9D)pSzOG#puX&}=u?(|cH3f4&GM~n)j`zA( z_~#M#7^f@FTS{hq3R-GttNjRzU*~E#=Edh4fi;rAglw`m8E?dFQCDW-g|)9nlHI`X zam0tqXNH2uLB)FsambPI_^wms;g{?PH=ekU&@Z_4@Hhwu8*zr0?V<=m0KkH*h%;IM z5CwuZG$!Ecwk2D1MuD)WR2JFsJSd`|M|`#HFE_J`5^v6DH;$ZDU_K!5-Z>~Tp=QOy*e>2IXsd;Apkg;004nJ z+>SYTsC5%a0DvGPIZenEYo+<=*nS0m9gnhpB5^dkm?qL^$WutEatJ~J2mp7M<&N=3 z##3_BV@`9;_cb_5yB;x}A!jeI<=^dJL6LmYjx`@r3EFKs zM@2+unYoyIp69txuu!0yld;qoBO?^Sa=VPQHLcg`4sF^9nUCi+63M7H_2WnOpW~f^7m;Od2}_pAQc`vBe`KI#s(qREd1!f44BvjmH~#L{>CU3< zv^%>)eQvJ2iWvVYUp$g&NCu@W8cIglZB-XD`2YYmN9e^Q7L=mZpF`$&%V~fC`+GH5 z6BB@>I!&tnL0yPK0SE))XRWX5wuNakKVJB=o2D4%Mf7fU6WA$S0t5&E3!<3J%_2219mDk! zyCSfidmX1o(SkI|a?#4TB=a2WqN{kajv~wHy(~2^MhblSp>JsYbiTqCpg;g4ABQD( z&A^UtNA(v7AOPN$tchCcOfHTel*0EKAOJvYFGFu!Ywfq;7RvCtaYD2|K_?baU*4BR z-!LeU;{o_12i#@mTZ1;pb2rK`8Iza`+c8pazZG~6YOL0Z((`f}e-sTa{mdK@E{2(X zF21njKKR?PC7ml^+K+`Iw{m!ca|S_(rVs!Fx`L0P=85Am>|f;zZC9%X-gNe^n&O?| zt@Ci{BoTDuiyvlEjrrj;I<92njB?3!K!~K<$nAJ4++p;#&c<2Q(KPdTdsn7#26X>L zx-p+$JYU@BeNaLW0r}$oO&5qj0OR?lD@};E?0y^CG*+Oakn~j?S1|4r+>A&tQZ;HM zYu`tpKCS9<)x1UVyy#Aadd)#laur^m8I@UbBvsj=OTq79ng3JY+SM(TAkk25$o`*3 zZTHT%Jo$w+3n1|u@0WV>-1erq8L|-EgROoKHDtH2e@DUKKT#i;?_O5L=jU|8bcEE6 zOXB+FN$aMd^$Hmkzq|&eY7gxSi`Sxo{x=ixC!Jsa-z%xoH`YQBf(D~VLI4vUygerk zFzb8Sd8Sq4%m;ev+GEVcf{9yD8iCU1EA|)F4lsGu zI?YyIiU-^lL?#Ed`Zs=Z3@=cU&9}kCkWE9)Ar;eb7=O{0rUb;{M zEv+?|Vh~#+QSq<%J*?2Rkv2s(+DUZF>E{aui#q*Nif5 zT7=`P` zoUu{n8fz3(BN7*19;1LW*&?#N4b*H2z4i-=B7Y1z=VQ@fPl=74}e1e&Jn=zQ5S zqKA4NJnF#Y_YQzP@~{14wZ^d3BU6RZZYwN$`v?b{yP z`cj3%G%@I*;2bavH2ZJ0fB=Dqwr37gi024%pElqz%j5Wpzog=jtE+UTL*YTDn&yW3J`!cf=>wm)rA}jMo3x=#Udk0cz;L&TYAn=PxKx z*7Bw#iZK^sclOF}GJU)c-TA;k00@BQ(YM@@Ek%dg4)lEWmTy%e5ao6yqVwE@N@INP zblKu-pfb4VPBbt=O|pQ1KpH>-08UUXSTVhc0SExnOn_=L0y2%crq5&Fq(K`Pd74Sa zZA0cfV~X~7;|i!OCLiC$W=K54*(EXE24BmChunQ{?R!S)csscje%&UYfy4rL@iL!D|Uuc-}T$#0Ab$P{@w^jkH?k6^$dV%u4CePCL z_BW>DJ&y zDKIwuE1x&lwWRTdl8JU6J#`PH$wjI{6mt{Rq=BP1&O zTh&&VhaOEV>ik7Tej(%M`uH2Vjkn)3SYMJM+$}{Z3=O;f4Ac*L1_58d$4SL8xU-)l zQ-8i82m~MmWG%#sOo}gow;ExQrZl;xB^S`UHk|nP5-;KGNHv^f3E>C;P=4%_lBP1t zw(YBDZf^l**3N&^0f8Yp;!2yOjd&lE&n2Up1W8L^00x^sKMG$z9hwTBylS_Jk}^;F zbBUUl_^O`lAvTbb>t`_f$nSd<3E5PJdX#um?G`Uuya_M>AP@qLwTkRVsN=%G3}dfk ztd@_cQ_+dy=A2Y(FS9mpEt)N5!p4@@TkB4?~CYB z#vyduL?93gb0M8C`RcWSPat$Z89oyC#rpgxs}ynCy6L8(Yf2;>c~fy#C_j(x%H5st z`k^4z7t0KWPBUjTZH|sq7VRt0skL0 z5ntqp8z#KyEoByx$E){XY(+gFwP(O1N$orh$oqXnWWJSDbJEAR|F2RVsO@c)0OREz zW;O#n;*`6_t$J1-oUC(vT(nw0&lSlnP-C-du^-s*kawllD+S`>i#-WQZem;(vW%AG z-n@2c0`)`uYDms-p>BUVrS^~O7nsvDmFeiG>h6+$C5!)Wh1z?8Vv^z; zT$Y9Gah>KZ!>jB0tB{8+sCeOm1ONg%j*WPQ!L;YDtw#zX@ih|UM+b3C<>~8j)&&8h z#~C;G*n&GKMNv_z&qcg{t6{v+^mQ?>)#SO%xY5$NkrL|2!VrKeJRBadrrOrn0>b!s zFg}MU--GSa(yw+u_O7|gd@DEGkyXw5%hB8-KBN%uS=d@+ch6irCoR1D6l$H-T^A|? z8;YL-15X7;aQyhO{Z1*uvsj4dLj&15(_2YWKD%zrbrzKcN8EFAUERh5brJJTZ3IR) zkmWMUzkF~;#IVu$JMt{2T2Tt!HfD3KI)$h`mz~6Cl@9S zgmj&F+Mq6*=AX3Cko(I}StrnjW4OF)M>b*q-A0mc?MYBlv@&duR7_sc-0dyN_l)VN zH%!L$m-~O>)PI%PEs#I}1!g9BxxHKEO&I>T5WuL??cu-T%E*12n43Kvw7WgE{OeQy zNo`BDI*roA-~s^hYrtO9t@yEE_qsO)j!uZuv2y|t0FrmCYuhTN?=6N@s@i!t4T-lx z+bV7ERfvd-WYSVg#`7XH>c1>F&%AaCT~WBW>Pfp6p*nb9>Erju@tjk@AIY_~;6^s; zQOrM~DBw!g7l;5ne#~jRCikFa$)4?~*p$O9xy5CcFDp=0%=Uw-vH!l@3DxU;6ZM80 zrzWYpCxdhX_H;TM4sY?u-C287>$_j5S-3eB*nO633c5A95YB?M8jbj%_VLicg_>81 zjgXP3P3u}fGk?!r)p*h6()Xlke@{=wQyr1k)}vxMW)u(>ya%MWNHM>zZksk^puZFF zGz+l~GbU7-J>`t6EK-Q~9RO&gm$tW>Cn$#fzp$U?eP7WYYgCOd&2USuK;1 zTc$t}t*Q*b$(LIemhts~MGxc&=^)5JCJdr3CHP9u_(@qf!?^QB}`|*$ER0Vr>U5Vv7!o@F?F{JNt zxhwgvj+=e9C8>ON@7yJ3Y2!JXE4rg!XndJXWH!J61Omc(m%g39gz`lcr9l-vAX4!R z+L8~Xl?I!)B{M)E05NW)X+s)BuvuSsBjT~^e_64pZoCs|FLeA6*QYY_?sQ)OdhMAu zAm!sOQs(r-nyLM;ayghh8Rg)8Q~}fp8(avX7ZKH zqr$n{o2IpXQi=-XQM&zZXQje#B*bT|jM|QuE>}f8L5XR~?7(s5yH4z60A0g)Mdg)$Wf}4t!XZZP`?~P{ONZa%!m1L= z6|U?axW&IoWR&8cB-ui5zGdz`^h=SQlr#rsOeb)y`bAR? z_LUr}tamOz7U*()Ft9G4{)KlvSUwfSL;xA*IV<#<=l{%F z6x(W)U+HF_guZs9=+I%4Rn{BlglB+l0Rz=(00I;MApj5btZZwUKts&?&ie!%-3)KT zyK_WO*QYNs)KJ;SRLZ~SVz{)Jhi4)kyLr6z(I7=p>hnw19NaTH8HLF59c41^5|>g7 z4l;4I|8G)tr6Ee@e*gf0LIFb>6&JEUdlU3@9Y=Y|$N2VptCr4glhm{nTT2hbiFz0F-BJ zcOl7OyVfZG&c5c9U1x3JpeX)p9xv?R!qHR2`R`to_^i8ENaMYB5trm%`PneV2crJb z`bA1{*4MnJyK=?ro_7vX*%fQ$x7AgjUiX>jFZh@CCh{o}GH&L6ae+Z2`t?IH*zRe6 zNB3xB*Xy^)a5I)vPzU@g)w`2IV{O_!p^K8Riug3?7VXJfMEaV@%1n!o9K~MZ?vV`Vg})H3{fK{C*rB1000UHPhY}O{YLL{Dk+Ik zlb-N;a-4(yh~|b#JHv{8VP3TJdMVKo;DsXS9c9kp{T%a*M+PWm!9t5!hO38_4!rd- z7!WH7bn%wbrfKci8y%}N_>yGQoq9&CxcF$xJr!Rpr+Ztt>`^$uw-0$VZ(gh?4RRVB zDar@uSRg=w0xRKdgPvcUvYa}GHD9|Jko<#h>-u7fHzp65MWgJ@F$e$vCwihe>=7ne zACFLLxxn0l@1WsDsV z_1Du20uTjjrd9kB zY~?wBZP)EDzs{pRNXB{gtx{R(%`i>AsQ655jYqzAk5`J|NOE74kG20 zQDqMWFy@9&Rev9vi5uS+Kq=c#h2l+ln8~zk%bxtmy!_tW^$QJ6808*ILtC^*BUV_E zFEK}^03ZTC(;l?viX)#N3YI$0Z0b31fcIUCdK^VTm;T|+9ZAuq+ALq~!dekB zqUOc~X`%!VBWZ1b&?qUqY>Ufkz#e99L1xFi+4elITBxkC^*jmJD%KceKZ7+GJ-IPGy@Ls6QqKw8ii%$Mz?${jWNdh<4IEwkxN<%`PD;iGN$SqCvDJN>LNh z`feZDZwJCAQnVe9F0^C}V1JFZeo%w}CM#W)Om?Iv3n**MxPlYjD*D%FcKWA2tX5is zY?9u;Ulj9RjP&6=-;*fL$!4F9vm^dK(}4KXLY*du2a z?Uh|XKgK}ftp{JIeHm<>ar%ALF1Qn$+2WI-^+fVD0eXa9BZNcat%8?87m#Z{7+&DS! zH0E6}(Glc>AEp7FPljyqpg;gAsoz{O zmm(?6;l9>6N`Iw5MyR8SSk?@McfN6GpIPJPKaTXBa&}wxZOrJonT;1bnP|k_|2*)Z z!^W#`dVHcDDe zCmy}OSAgrK%>8PP+y4v9+4LpP_R@cFvF|dyX1`ad^boan5O?K7h}SnqcpobLv&s8H zn|)CNWZj{0Ze+p)5CtJE`i17Cfw!3)?o5K!D(;etlJ}Jd4cwZRwZw_dXQpw_WBqn; zqU2+&c+cMR)9Ja(X#B>*#ymCS2e5%`GwCuMOvzyIcY6p3&Tz}4HR5Z5C;$W&wYr~~ zo34|z9j{IG3-z1ZQ|?{Jp>R?k-F~X>5TZEAiSsx{a>=Sqw%6#r>`BYg%XAC%8Wipp zyaUrKR}$@3SSl^-C5ZDJbv&_^_h%lBzIE)a=b23=7b5)28J5rD#g?xRr}E9PK9&%K z0uTX{D;IN^XzRpyFR^rRkR1Q)mXw*~3ziwdD3moKb5FkNXX(Dd^X(y=J7af62hk{C zs|)=*J%vcRL>BA1aei6ZKZiC@gP?r)?@UUHvQpn zUF=?I&rWvHGm2WU+L!i#b0l2H649%6HS)jXkM7&7Am<$P!B{y5b5aZ1sWP)r3B9+L zevYik;OhQbjAmcXp+l8v0>-JGZQO^1sdNy400Mx>1OP0MG7y9yjWPiMfCWA1rAqzt zjm?ge`|bXzr(_PgLEQpe`7KDk1AUvi2gie)?Q%pmb?ugyqa5Gri5C`7Cg+ODllg|u zSvzkLf%|d2lZqkrc_Zz0nW|qBB#wNnurllvP{bes8lVCKg4-Ec9$FR`8=p$1_Z&AF znseHxL9Neywzc#XO*7{+Qi<*cba8JJU;)$KD4_gqPgQ@!Ly6r$sxoAE1jW+ zQt(zF1OPw+k>7o~gYhGii;)15+vI8l=I`ONPdUOSDka?Lms!n}xvs@xhQ;E)3$<)n zP3fN6JOxDsu+A-0+oQ=nLDdKC7EN?|A#hup@J&Q)&rgjyJ^Zqg(b+~pqsvm%pekv? z_TT;S$+cF@Cl(V@X)C6aY%)K}oQ~%qTEt!FAIzP&{g(zeYAr!XFsc+fM=amFJ}W50 z{%`;YEL^)P_$wU)Ba%o&5iT*H@l9l!mzn)|#E#*in=)#dNxN^f6wQ77P)?EK#a z>Y>ht{}j58>;f_0&GW|{n|PNtE^y~RzdaZpTp|)_?&)g{$0If=WOv84E9;~I=92Ui z)?Q8x4jTxDMy5?P=DuZ{Fz9YGp1wVm5fVcFx-}2^6oK&Y$=Wiv{FKO)AlzcO#8xFL zic0-Ss}rq9$tL9;SpJOXfuUaJZ$+MS`}NZ77{`AncWec|-j4Yzk$BOy z)L?NdG`l?5sVQ4uay@-+V&<(pUwX?eo4VOul~hBsGL}~P?wF{>fIUX9|s`>5k>&USsV?p{9nsJ##I3HZ=@4{=pd zsEHhTIzH?&ZP~IUt*CRG=#TtG@zSl_XBrN)8xh{cd<(7qWL60QsejdLK;A6*YSguL zXnzlU`}k_DJDagRkb7%(EsXh02OJ%j_=GVNZU?mj2eh|v)D>AyoZl}Q5h2xYZ$>i= zEfv@)R@Af`~%tgXT`oESevqjxH*K5_|A~=#n!IxbvI#JSmv-=bY1_Z|= zHnSV4a2xx}bj-@7PeO~QH^g!5^- z#oBC_=)dQ5Ot;#fXMbp8cfw6aVLPuf>}%+|)sBeh{P4~lkp2j`v)2*713OY;Qk`Sp zG@AVq3RYc*Cdtsn+1~uxsmZn<&6B{SG(r$G4>*BZ_xQeOze2*N9FF&XAC0nqx_Kp~ z+E=V-bnQUuQ^nHI=${y+F5`9QmnN{>YhQpsAPQqE?A_#G+1SI)iF&&L0R`tvm}D7V zGdRhp2mKiZd4$v~l7ImKK>Fu8w!Ou3E@YRXmam$w;G!t7qx0%^alR9G+o1Qc5Q z*@>7ax;nFVPm@&asGV;z{2bn}sF=jXk%OGO@r3~`?9z~O6|(%O-J)DY38Sw(h)zwuER;0_59YI%2#pN6 zkRN(zzS9Jz(gKix00J5w-RhY&&d@N`edv&Nj!Cj44Hn4`fSwx-qmnCUv1>~4w>3#R zuij7lasUVd%w;(8NYvsa;*-#&YJ6TS`@vn_0wJ2NZ}FGYl?Mk@gLCRrS@aQ9g=o)1 zkH3>vBA7NH6Vef$18d#K(_b+c zc?zC28VP@0x7R#V^y_L5U>uEV1rW-7@*G>lcUcWai#Blc1UKYHT=|+r7kwIb$4YtTm5c_rYg6b0uTbGZy3I+XXc|{)#yifaYe&KUN;-XqrvdE zTs|9x;5ZM}&*8kgkHPbHJ3DM=sZtOmEgQ$>;Ul$RAt7}s9zQaWE)k$e|F)7y3z9$h R5Rkw8UC9*TLO_2cA8=B~x`qG% literal 37555 zcmV)8K*qm9T4*^jL0KkKSr@A=?*Lyo|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0 z|NsC0|Nr1%0`GtT00*bHz1|n5T)=M=pBnqU;dPxJy+dC1_BM0g?t47Wcf|GKdY#;B zx%Jb_&i2~vj_uc8@w++d_r2Xc+bQeWwB7AnH@m&s?|Z7VcLwh6_&)Ua-C7%VGQQc~ z>${h|?$>*(yBXJ;E3Q`cd%f+uRJ}XA?=#ch z^LF0cm$dfxz3JWU#m@D$*Rj3c>USOO?{`dUw52*PZ4) zZsq3L?C!nYb#Ajg-1geucDp>i-Q{VQx3xUI&gD6`Uawu6^=;dCb=vn_^?SRn>aKNl zE$pv*o-NzE&uh^0y|K@GzIV4+$bmfo002w?nqp#L0%cFrLlY(dm;eaCCJBH5N#bAt zO*GR4VqgTqU=ssCXc_@FgCjbAaCIAVQ4yFcx0gyDQ{z0Gs4FX^(;0dOf69QlWOd2#a z4FC-Q0fYo#1w0VRlT9>W35k^S(-Q<>m=TeQsvT87z%&|Zsek|g&_ zj3y%jGfhmMr>UAIk3kuxqef2@z$c;x$u^Pc4@lCq5G;R}q9*?O-;!gJMnwV1tNmyb zJ@fx!pSG8@UQWKV&A3<1{kZJNqQ08k z6D?(C9~^K8No6azD{saS5up0CIL)USziD_I?C)=&!gQRRl1VS{+J?XC_#bbw?xgcw zjlnWQhmuJmK$1=Nq>@QeY{iyDRa8VqDzR1~h>SsCD;S`vMFkaz#a1j>F^Y@@ixB}8 zR7F^*f~;V~WLU;U0gMLL5g4e*#6~J23L=XU6%+sgVk!!%C^905f(&B?Rz?W0j2J=! zkz&A5Bv=9>DkzG^F;zul6^s@Nf+(vMV51aRs)#D6ixx2yRYe3*Q4s|eF+^2@v4W~9 z3lL()AgmOMip7Gf76_n>7{x?j!Bi0#Dx^^qh$zHCR8?TA005$jqA-Mjq=2G;p(GR_ zERkRYhGl^yhX}|(fNQV-4dYK>n#ItplMB?#{#=cV!a#-X6#_w-Hww)~IQDocyC!q_ zP;QC6GWpfg{SRTvVKK%&;D83JAV?@cB9MTfNoG=P`RhZcW`%~VouXmT%%>Q`%gFiG znI{I2!l$s1vkuvTf^(_QFeC#yn%e`wLK@aVJW{_@>IkMu*Tz znP6aPZ9IqEsuH!41X8oO@$DzHuf2m$q6GXXz?)H=) z8Oo<|u~gic8#@ls4^23kc~Cpor9%wuOfhH~@7+O`A-6w1U~OG zKw{EgNhFbmD_5u(-)^8l4f&a^9R_dO&uKNTUsBR*+$IlA*>~OFPl4v}nJizqrf9w) zqe22=T4Ir+f2Wo>`sLWI3k8mhw?H3J4@8NVOJTC0;$We@CRKTKF-3MYHiCQ2x3BU( z)}O1pcK`t1iH=|ZvOy7K09X-1NkIVYB$7zO4T7V2@@RyR?lKpdotDOu@DKn100025 z8j|2a5i)c~hdx1-v5bPtJMzV|CO3sRfYNWYLAI?F)Ks#b?V*}=K)U~Rs~`0}`9jfr zq@K;^8mYzZ93voGNFdj?bzU>-R^QcyxFYAQ$zjzXUTxHHURb0-{WBrwQ(ZhX(djB$ z`|{b~h9T^fOv9~7I81ym3u$cwRR4{rh|WgWszLs;K?0NUxzv@B&3M~d!H89)Ki8|p zAx&K5^LeTg6__5a@+Dnc!orx%+h*yBU8H0mz)})hyp3;X`sbgdLE`m z?DM(0Suen3X-SJQGFHiJ0yCcr?|5*sFDL6h7#NVcZP%#TI4$qq*)#tOc#{r?EQZ$3 z@2aWLp$#GztTlv&s>7+oXsj0TsvJKrUA^1=xCTk?v&P>l6P;n&yXO^LN(W_@q8;<+ zrl^L0MY!5`jO_o#dV1AP-7?iu{WwR>bh*tHu{|g2=;Y@7OV2^dGW>g#(m%7hqc51| zzcxELdBOX6%VscLc4GgiyT#Xi{j2Y7xDyeuA-Ni0gT+xi?gf7B=ljdA!DA@CvcVa z0|L+;v>c%L7r?;)(hZ#!uzUkvOYL5>NO9@tvhh0$`rHzF$Y-2yK|#}W7;QdVP@gZ+ zsaaj}*SXBqyKiTPvBhP!4o2f%PFbD9m|>CUYfa|p_$#mW%GO>rXDT<-Io!O+ur6g+)r2!T9)G#e18LaZ{9x-(kfMX?ERZ|fqNIO zME-!VUTi4TBS-t#Yyc}w_xB<;JV`o%DIac@7nw_d$iX@5|TOOcDXyH_y!EDC<-4 zp|dc+urTQkwTFY@)y(Qp%58N!TtBnjTp9Kr7BaYo8#iI4v7ogav*%~Y0v&t_4WK;m zs=m@rZ7B+osQl1Akfx1co1S^%Ikray<`Wy)L8)zO^LY$qI#2!G2Dw%`Dr z5h{+fe|-9E$fmiB08zRveD1Yhcfwjt`wk1Iq2R`X1Q91A_9FYJ^&CP00aaVyE^zPKKH@`iDe(E?g>zB zM}%7D;S$eKl={FXK@rn&5>;QeQly&S%rH!KMK``jv;;EAMXa9wnFszdSnAk@(`fr1 z-F= zHj`aS%|-LLjNoBDsEib}NSwq5JLd6T7693-79 zDa>6lA#reFs2?X-X75sY!}Ai3TB3CwkYdOYjVslXg2Yd1enXi;DDq zzWn4VT)GEKJ7~9}y%gc+VRK3Rba`|;zJX#GA9Sf|N_4kmm@4D}qpUcsJR#}R86^G< zK3?Ss!&$nw>89d_t1|k&(zzOxU|5m0sk1dZMgpjHbS26>7RoL1{!7IW2-RKL0>wZ8 z&XXqs4L;1xknu*uwWRl0<1N;nGu^qkNAlVzq+3u3ApfQF#4g+wm$A|d!l1-_#J;yG zm3x<}PZ#pXr1xG8Mz6(W3cqYjn`{FN9tt7SJ^^!VBXJqHN)y}$W&%S+7+*{gN8(YL z5ohchr<3tZ=0#=0qo6$Obbi|LG=kcor0YLPK%_&LwJHl&e<-7n0%_7Ta;(=}?ZcGW z7T+s3xx;mUgx3d_b@*|}#dzL(mHFl|$h7?z$9%yOaT#1n%`PLi)RS9__>lx%bOy-Akf0XxoAo4bGs7|!&K zVdF4s+eNgQ3=(XFg^_SFGpAPBZD=(#bR(ZH3bbYqvRA4Zo{_Q@@-*w8gy+Zad|ABU zng4o-FaT?4s=bRnwy7h7^VJ49_PuGt6%Aw3^Ipp5ilKx@+Z*_<&m%won)`+4@VZhV zHg!;XUaY*>_#7oW>`w9d$demj4)B-L*Vf+Fq$4Eu;;nfzU&F4!7U$Y;%AhWCArS@4 zB!BjEb@@nDgj}0dN(C~)NpQOJmA$-mN*V2{*!6eX*_INd= z=fDLXe|P-UT#c#q@ZPo1k2PUb7tiD4X_n7hlBX;1ska~8f}x~aVURQY=<+tUzpc8Q zt}=$!+y>*`gZNj!5}6~H{CYxa&DUZ!e6P7Q>tOFrPa3)|*u*W5>(T_uBFMBznE3Ltoe!nHloq_n88!ROprYEC+-9f037NNO1u(LBUw5W@{UzH{ zvCt>#Fg;Vo6hJ%Fop`;K%e8Y>BbS@MN%9|0Q1jv&Cs+^WQ3dArTb$@NUIfB^_Etm{#jDAgQ26YLod%U4$7rV$nkip#Q; zvi&FM<=Wu3y>RFweN0i2m&BIh_6I)3sl3>%#?p>Oi$q6=fLPteH>3$a5%w<^?vPMx92tvP>l`P47rW>_nRV zfTuj5mXN3^1KHqn*R7R%+`@egteS@{*&XrjM}$b7JMs=%nfx8OU+@sd&h}0>q$MBB>Xtm9SQ3y(jn(R)=rk;Q9OyH<*O6iS5u|W4h`{~KFJ0>Vg z-T)so!4so}@3v1B6kS5-Vz>J_5MmX%qd4QCPk{?u2foQxU_6MN!AHoM(wxhl*b;TM z1Vc4s3M`q+D(3}9B?WVa2OXyh?MVLn(58ibwBV0>n8?IKhxzI6M3eipVcjT~Gg@sj zr3x+?rRe|yL6CuI#nExc0uEL0z;~%k$8}GWF4o}+u)v>uH8KGVcw;$W=TtOdp<1JY z>&0-7e74P}{5i5mO07Yj)vr2GA`vMe_~&8aJdLJv*Zvq)>xYGcx>e%fBr_I(A0_M8 z-2LHMP!X^vW`ssRiVCJe8%@HcwnK0tLj!mXR8aCCWjmL9=>r&1a;T&p5CGt3I6#)n zhJ$eIk5qwZ7)WCkTnYj$7IOL0cD_r5wZRr z+F$0YH)+(-acsHH3%sf~mV>de!rMD)&xx*pi?5t-?`=cTH&3+WJ_0#<$&N1s;tVj1 z$dZbT!Ut-R-|uHiCcl-y7L}JrexMik7fubi8A`5AQwV^<3O zvMAAehg72IDOeXh@D!UxlQsEJl=%P>u7uKX`3!JcHnGka85W3nE#PSINg{E0{wD=S zhbu{ICpZI4(!`e|;c+h^v9W_rsI((Fd5G*^&@x1f@g~_SaIHAVGpyN+_`OUdWwfb%tOm<=fAr+k#^ol)(mY~0;e6ub=ZYCNZ#N- zSNQxcn83j??A=7`CZ0T&ugeN+;a%HG&NJe)xG5?EB8&P(r;-b`nFqjTo4=QjzwCje zHv%x^VocPEEI8_gyF}U z9pvK~V+b=B5R9h2qxin_J4Xdc(z@@#F}NTA05l9fPEw?hhAjzx_ADd}+D-w64KyhY zD-2Tu&1aX5;B7dB|7ae%NN8CnroskUKKeuTG8&qB??RczamaLa)$>;Xcns?hoc{q* z9+M4;1OOmB{j6i;?=bEeCj>{!Ndv>{hTuK?$PU_V`q;=oS?|dw)c;^gbCJ@}{&ol( zG}`__Ye=$*XQ*$OKh8J%p~-)M$$^{R1wVz|BB4`wOXN{NrnbI*51{T&F}p(eEGcsd*hV!#dDi#q_s*aTQp>WFk}=m;i!mO@#$~$1$9Q z)DGq=0clhG9_ZIYpO1%oOOXCn9@L{E;4r4!r6aiu+H?x)UIj?Swau?7%vC_yz7;uw zrt09C8M>e143Sp^{62F%Y7cKvioYprA2YA`bO&hOf^B|EM;d3yQ%a&@eJ!T_R8agz zHhPGZCFS`JR!m?Xu<>>N0p^zY0%^=&eE6sE2t;-_DF`HSb^{%BhQ$r;{|s3<%TMHJ=< z2|zw&$9M{Q@6bFxgY)Pr{WDSmS9tx6(qg>iC`@J*O^=qiWa6wb>`x=paOV7;29 zV-v2R9sV)9Z$OA=;{Vh%5`ROu$rsj-RJs|{-y{i0!c%SF3;fZ?K;p6@pI>rjuC#f!b=sjjvC}>NP?9n+E)e&15F=|TC@q-uXa7u-Bg5j0PQo)`j zZ>sI6uXDvqO08=l=3gWk4;h$nL2?eU*{%W%^aTRLTQ5o{K@?D|^S*KJ0afG3xl;<< z`AWFU4nje8|G`DTW0H%|5#FYonpW5RaHNV}l>`v=l>xAdqQ8a;@-ZLES1y)nap^|N zIod@?T5cf9@Xl5fFaWqwn6+$OsG1-tMX10B6x1(glQ5#>XBtB$*!pSG>0O!ob;qZaXL6Ha7B;80j?8 z{}q;zbcgif=%+p44x-ZaH9&k3`(9`qpP1PT9|b4bsqA|LO!Nt_em#gvlaEL4(It8d z{!m={WQ44r9K>E;Th~1_A+S4*pXAl@ald22vvnJl-!F=%~@s9ixdn@!ZJ2y)eN8w!b_^*|_SCkF)X@Lc_ zuw z%2r~joj8{{}al_64lG#3>B!L0}UvOp^dlC?}*6T9gg>t3e3y-T;K&pW}WcNL3cv+tRdd}&IGy{^+PfR0r+x@iY*)P$?01PsOC(oy1 z#nV-XH;RVIrmexLdt5^@oZl~M2Pq|3lTiCp+~(TAv`vbqFsoFHAuLO>0_62)5V};3 zOoU&*!AT*Ssn8y)OE*&%QZ|;1KgR^NDcJ048K=(eRlPU%O$hf`=^u$tJ|lmjoAU@A z22e`ua92W66s3+L0MV-b1)c zp==w?W|Ijsh{zsEg;)*9q1CY2OX;-hEtF)9qaXXP(lKfS@vT8WbO@;Ctn`>awixJ5 zkV?)8pif(N0QQe{=&aezjmMHNo?ETY^11IR!EdZ_!IP58gB@qp<-~N+t*?b>RLn%g zBYyR+@6h4Mn-UrR_R;?*34M45Io7xf_*(Zp^<^_lSHz~6k_BPtIy9ZiK!4^Bs1SEO zL$hL`wZf=(T*2y~oWMIxy6PqMz(N{8P}4W|pB179@)(-XAjQRkU!41R;6Y}dy1iZH zl6bmLiQw?c>}CK2(KdPV8fM1N;+H;Sk9K)H<=O1uWB5zYcRRt=XKd?r9f0mUADj;B z1kD2Xk&Au~#!EdkP#pWw$}6b@&a38XB~2m?1X}Qyg-crDKjGbHl-QA*j?XLP02O3% zDqvOZPs?=4Ii!(#j%Q`3+QV`#&)scQXNmK`XHg!swI9*|7TH>Be-H?P+t3PoGl?WE zNcJP|@|^46ceBYkMF~TM^25yD__nO291fj)$oXZA9*cUzECm{cyBXYR*XKgpffH<&>{;tfFZqBo_tinP;NIski2aIz4{*5|TACBfs!izV=|dyCoG9 zz~!gb{RZ}x*h1SSvXSt_*rdAQ05^tmZPcKq-8^b8<}>mZn^a(S$=>fT_0@k(le0xB zK?dbLJY%G$iM7h{J9;n{$k1uCEb_d0Py8G(rOp>cf|7CMeG@dK{!;U2!)zL+_y}bA z{vZIA0^M#9j!2K%_}_HXFCUCjUg&#;sn(m=v-z5dK1I$IIt6L%GF+~z;sj%>iGs-d ztwx5ygjCKHN1|PuTfJ-I_%#Z|fvfH1>!bv8)_lRy@E429$}Gis61OSMxbSDz90@-Cpc5pAmFzC% zYat}Wlhp$p$6TauFQ=x^D4)icV=O~eLCeNu;Fb$?r*7OHQnkQS^TBhzu)J|9JlHor z?PK}DGx#cRf26S-3hMvZl^6^)kqvEki=jR_iW!vp(FbX$%oxxTSxvk6$5_(ADL%Ez z!Ueg?O*nIv)V)v;ai!VF!R*GG*C)mAP4+8xmZbJMta#t;W_i+fm4b~f*dUjha6a-Y zX2JI?JN?gjWF@k#tSrEV6khcjk}3V3Tp;b)Du|yCd_WE^D{IHURBOmvapg&qb>t+c z@@-?b-+xDKrnuU7Y4peX;Bg%xn0&YA4i$<>dUQ;t1V8EA6A(Fp zwrw(9N>E;KX!cv;Qwg@;0pX!)ETZj*harI_6CDaPvSq9GXW)OGvhu|)!;XB0(TJry zEA$e5YR3r`w()t@f{N}U7$8ZfOgOhgw}fEuKE0U7n@DSRoF=b?(t?0zr{N#2H;AhD zlhh|tg05^rc{EgFH-g3J>NVz27WM8Ok7qs;zO~8!3eqC22PPS(% z$I9%xedtE-HQmt@k77Q@Kf^Bj0K8LJt(EDkiPF#_agy4YO%tOr(y4JEzR4NF6i3%I zJ}zq8*%t9Psk`Bl&Umodgy>{zxN;@qfWNL%(_)wLP8N&oU=lgq9Dqt| z45sReb`|n^m5`3}J#aMnY&tKzZlfj69wy|%qeVR9L9=9aS6VJcn$fsqqGrGZ0c^t! zz!HaD_Brrds;Is!h4AnDj;w$`T$pz~3eJwFW^OlCp|v&VUr_`JrY_fv*wiB*{1HQ> zR9)Qq@r7O+)U>nyKGEI*OcRiEO-mEd2KKBpH?vYs7uhTuHSqby@?Ho|&=lDH8%gut z3izkU4iz>ozAqE>=S(RPr|;P8A|P6gr=^v%d8#W>c|X)r!}J#dn9~_T)~P6(6P%<` zE{)0DChf+U2F04m&PV&3%*-3+4`4C;;48GBRV=7DnNTimgz3Kx^pTbA%!zv9b5y;b z;d{+zn0p^~5_mVrU6ScAev{rYKQeCpCghkx5R^kwq#uCSlazx1u}>%7v5hENn$qC| zI+}DOBOI3rSn1uR!~SbHAwBm@Iu}+8arJHf0(R`XtN?2dIb-?9Peb2X9SQ#iHuF*W zU19p5XpS20Aupl(RS-xBO_Jw`rpj&CDRbz?c-bQHge57#@|=7^lGT3jF(C>YU&mCT;k>TZ&&`H!$wxFytAfws_qJ?=$8 z>`UJbOaBfBicz+->C*3^M)}d`Yzwnv00~p~NLFygppXX-Q4;XQV2szX6Xouw$#!pM zJMeu91+nXl3+=g^nVSKEu~g&8h*%dXFDPm5jk@=NEWGR&R>8ea)8I@e{=%+a^WVy5 zWT<32ar3O+*9548(8C~dP@wwfMrF{=qio`JGZ{2I63&2e`rj#S>+7)g+RvfFPN>~j zf6i*P#-AoVlyJM@VsZHvChWhU**l+~ykDY%Z z2Ncg4P0;z6=~g6?y1;>y`0RsZM)4#MYRjZ)Rc~F+Zqd) zpsIJ-n0KL%roT^=ziQw8%ZoKe=F2G=Vv{j748R*U~naE^xh~17J(XDZ;esTXq6@GOwywuuo3t@JQ zCA2c!7{lIA_5 z!5H9~7v%4w!st_~Uy(*9mTV6d;{XfU3W?XhM_{0EpLx+~S9FoPdCnpZ7j{_5e3d1% zKJIfK4LU5ZpUbtozoFsH4;`Up0Xo?u7K_-;;^L+`ZtNS2`<3pztx~bEQlFcyE|pzD zyMWzLIFR8v~Tg??*(FfRCxe=H^UvFViAfjX&96|Oup1Sc102c5Y8d|HhWhucJAAy9 zU%SlT$}N_Xw!888G70-zPy4(QBWI!AVdvw%HyPVt>IrzJXVRA!E3|N4Vi$$y!8;4U zY>*ka?;IBem#wf3hQtMZn>3UnJWar}D-?+o$msXO*k|%y@QYZMK8!y1a5hUqLmBC> zAdKG1;O7u0XA8z9X>izL{~5&vMf=|&!hTIp@%5TxFUyUGaZ95fM9EA)72K2>hDZdR zd*|7`S6C4|Q zN@h(Z`%r@zs(r0MlA1OnT9@BhQX{^W_#gE*7fEe`mSrC9dnbnxq}}i*?`PN)KebIA zu7;u6s)>U|Ao`4z3Oc@16lTJ z(f=$05I}$g0003fxZ=ctLVW>5=-9ogS{uLLHS~39zSq7vauxJOg=w{x8n@`@TJ1NA zNtwqK8fDEFTGX^QYqr{P+ck-*tIJhOD(Y48Q2t*R z_0B7+2_s?lYXSRf_|;=?dj1)Yv8TJT12Qk8q9%r;eFr`x0)CSGgxRk&cE1=L||Z}$GTNm<(>%Xz0QWjq=VrC``!OcoOPuj(6DP9E~cTQl(aFR=eMWZjrc z5yAkJgf-3G>EO77ky?(J%@Wh=5q{RNw)|^ApsmS2I$gSP_uH9@=?J6v-TRWTF^8g0 zY_q=d6nkitvXy$lKHTUSn2_tyF4BrZ*`TH6*+ZthdifoXP;vFOlCo<6H{mA)2mn9; z02j9j!|0f3icy5q?EPNRnqj|bkZTLfu8pz!Df&O9A#SnU{q=RLR7}_TUB=~2yPi3K zvqzi0n-JQUWKLx#3EOEozTg|QF>lV8eJ zCyanlg)xM9%++q6#WDrg(>b1AZ#Cf3$?Coh8DsQFqekXFX3WbDw0Eepi=Ix=T+!S%qE>XLnQ zJZ&Sl3e+7PQc1Oa44GCUz8I;2Htja%C=E8`$4`E(f4#Rg&1i_6T_@5S!Rr}s*+Ss2 zQ-oA?q4L^jv`d%EM_MPsF(J3_{TsR7Ym=g+bf~K)JR2^xQ;>fv3nKe4WrqbBKi>s2 zP%^agjI8kT0O=N_Kn3FhO9pLr_a#(jyn9Q)APeqwTkQDMY<#g{C}DD#sYfHsdsIGb zRAzou_V4l!=O8abKb7bEAn$m&9ELQzzpj7_%i&gR6|{7cawMrl1`9fTgtg=Dg^}vp zxJNY!t_BSD>>CCD&R+=a{E9c3-iXv;hYZP;joK47d=&1afrfOJoB11AkXjJts0xu@ zY0~2@ejy!Uje{J$nJ~Nqcvi4A8F~>ukDis6vXfewm5&pyDZmi=Kq%@O?-UO>Xh-!fmpQ!1v9L&ud^N+*mN@V{yu3K z5NBWm1`HY4Fkrx`<^wtfYL`_OM(eIEaaOWbt#emUw-01EAUTaHXb324v75*e9p-2o;v+=yY{nw`w!4G8 zpO%*!0tlNpnZygqt+;q|V_9q4Vk+eaGx+3g9CbRLgkxkH&`tGYp*&I!mLQo4=1JEE zq{szdU#@PKK24!vgzwp7EQbRP>0hbpx`)efOyy*(a3N;AkhrZDyoYqq&R|cFJSLP^ zXxDw_0&a+D8H5eJ-3saL+S4m6i2lawPW&srwf<}8%vBqoX4*6(*njt488~K|9<08R z`s^3eC&e=Tb_oVK+^L6wl}iQd>hB7OCCE`b+A3j#hZa0(2_l-C^vD*C{<2WceP!~+Q$2GN#BEnQPW zhFl~rJwC?r}F^8S^GiK z;ZBi1%eqBRD2c?n9>Qt7UW0Tr9&Debt`0>bK|!@?<~I`|wts7nAhI0Z1^Is7QwD7U zz#9}=ZYqS*x-9Ha;ovp8!xIUe{Z1s@B|ojO84og2OuJqtqwaF}of9I`J{xwICP!0H zRS9>k1R>hXcskaT;Oi@!W_Yb1X=tV7{17$u+uw5`tIAn=*n5;HZn@slpo@8+<)ndqG10G}rjN7*|V|Tc){W|sY zO_+E!RxrevJYB4P$I&~8u>NhS8^@0D?9i?;&4F3D7CVthKUqmI{fA$OX7eu`X~G&D zguCRcJC9;*swzJAp%4j4(B^uPzDI;sMRqc$E3z*SvCLJ#JM>@m!}Nk;j>TQQH)Ycg z;#%P`j%m^=M)PU|*BiQ;uPdHSl<0UZY#^_#Qp9}^!4m~fzUJ6pg>LGt?zo7O-A{^2 z*U)@#(N6mqPe)d6J$LTM^$z=kkb!&c#ecT>2S#W}qMO=;sQPEVuBo^iC*5-z}~vm7}YJWDEXDwan{MP?{aNBjMHZ;Malui4^RKu~#s2#LV=cSv5OPBExF zeuuF8WbU4r;pu~zlGIsB_^a4_Nt|Cf2|D-6t$I7QOm2<7bvwRpXvVhiw}s3LLY$1y z$rf*q05397&3(bmRSw8q_GRhSyQuf5Y<%u4J5dpD=h_bA4D;-Ej~25JP8v5dC|WcJ z;+vN=1=Qq1fLgxt@{*fKbf4KQ(5*WfrbnqN^w=6SRpI&%=^g#kmY}9yd2e}`1;UKh z37$4WI*Rsf_$LV}g~!h;du9PEAw#~oZ1!5Bf3`IFeXF)ZtnKdeatr1jUC2eFSogHn1z`8ZEF5EgtGM1pqN+{}U&g^u#WxbC2b>`(`OFvC3Im9u{A{@sHD&28a(LvAqW;0WXC6WK2Yn0l zQ2%Sa%r!P38F{?O6yx=p*tF-*RJX*w;NF<{pvBKP z7j$P3qEgs}5|rUsw7x64Y)v=p4lf^l^V}U=JUG6kj20TpW=Kd3BYJ(;Ykf=X1!OKs z7mi|0fG6#xelqZ!tWl5Mm*9JAi=1Y6?9)hb+nS`AVOA(SJ##`=(ZVKAoy*7D2{=k{hiNLd?)Xo=a1t#UOfkcGMH?mSG z|32j`0Wz-{2jC7rblzQEG@N>eoJmotLj|)FMpY;KrcGXe_Q32Xwq{s2&-!mB@{>wm z$mGA;u_A1(R5Ocz3a*v*L7_%jw`%d48>Ll!b;Z>eR#qV7vv8;wIcG(a!DT+0S#o1{o5J^ja_we^7ruY*;Lw1%4+G z0hT9?cyG70ZkYGJcx|#fTzCRcc6B`V?mV$Gcvq7Ic_Ht??Z`MnM|>2oIO@Sdf*uMf zdaOi-**5u4+#byzQSc}cRR8ooo=AQ_b$qj?Sg90fS=kF@)s>{78uHZjOP-x5oRFqj z&AB-49>CXD=x1q}6zAV&1X{x7%Y+k&a*AR2w}04P&F}^oBU%vF@8#lb5;Q|(;r5s< z2ZMIw7_WlTwl=W{Cn-C_0u!kyuyT}JPXmrVD)wEkg16xI(Nh!b*GA$eApNo$)%f~L z9}twgk{DB<9lXeS&tj%bSR#hyk2I06bL?@!!nU+xr~4JE=`ljs+oO;nxJSYsquI!| z4@|(ixO9nRgUf)APO zHC-1-Mu`F%?(-j}0=-sw0muI02t zHA8RuNt{wi9{ZW5dkLa6<(N z)}x;N`Q1=d|8?1|@?NLpN!Uo8!{kOuazfnSLaI?2H|AgGx5Z~db{Ofs$80l1emiyd zSX~ybB4ojmll(sa)E!B+rHIc~Wk$xSc?EUn_&k59v&Lok>V2yQgZpsF-FD%Wk zRmdEBoOiVbxE0iU{_4owaly5X0X6pEQ6;B!si1D^z>MI=`e12)>Spf(S<@mW_isCW z>6O9WA+`EZKPmEVy0XA~UdSdAscc&R`jr7>$y(uH6W_bvHwAZSiI(%XM2G@u(@Bfd zrIgIB=&;?LG#3mf`Nwv1+tRIYNAX(S=u?TebBvQyLVpRJFwLmD@-kBNQy--6B~JgE zqfb+Wj^SIw)y)`udeb~ywB52=L^LW$+X}@^sC%v4tn-Q zHBuA;60W?;bvcpCK& ztK$bw=YE|&Xw7J{879u;p%4HWI+HxTRK!^sJ?^z>Qgv~;EXw-H#9oW8Bc;a*K@>6iI_Lqu?wI8BItku z47lg)q6g5WOc8hg% z<0i&l_J2+33db%_TzgiRr_7buwYm&zSBo_P5zqvthL_SdePGke6cM6ZeG$PRGa2<$oOn9H5w8zj z0=lL)_~xL?mK_K3rM)Y))>6rXhSBA$K}8`ZL_l7@!K`t8cjH51H#8SrqN_p6%y46W z2LUf>z#Zd?D0U8hc7($3@_d9wBpX)PZAc{@x8Ns!sC~KgPyVE9g-*hrf9kpIv zyh;UF%DegG(*CtJTMHzO082o$zc+>ybHSVn8%+g9|8OzzRzTLTw)Me9d2Pg8TXa+< z22w{r!wa(HSxGei8fZT(f`-0S*<={VyX!9Ve7~I&=uSFR``F$_v+14h8RM76#cJRA zCEdoNM?lV_2Nb^bT=gM(iSB-ov)dmiK`V0t*5(Upy^OJBv?u9%%}nfvIiykRA8SXjhRGg7vd!qzZ>n+A&{<_s>G1{d)GB7Q2d7SIt z&&2~lSe5yM*)ANmM9^@fSo*kEsE({m_-IPBXV>IrbU!z^+8v-I(>I(TOIKwx|MDZN zlGutuHPLkAI*9d`dauC>t~tF8Z7>YX8XV1jX@6n->)=)cy%+oMl-<3@v{C%$dfoX! zjV!WU#8PO5Uhwxp1|DsAknnIBcGI&x(J^$Cn&P{6Z2a$40arZo;xPRJKMKs!6BIN3 zHb*-+0vy;9F%dGm&LM1%KD03$)*AhvoOlf%HBU6SW-*hhN=J8*%iI!&14gn?Gp^a`JjGMDEO;O8C^r!{2H0W3tVh z{eHX8vDlqR6sM+4X^n`(Ii$iIi$={kG4VYk-v-6dmzisw*rgWyBN<#B(8+Z^myEo0 zYV}v1)G@8c8qpRY0yO(6$kan?{JI&hDKK-z`+i?>rT5yp%Qc4q+qZ4Aqdtj5rqRL4$tUTSi70@QlO3JoRGjO zF~(1n%7$uR$y``c-)+&x1V%zcS!cqrm-zSUkn4h553EXxwh5w!jRu&CoH8=@GZ;j% z+=mMPpLJ3uYIQ@@ko@OglllIx?dbN;;S<>69a5XZi{fCktb+ptBToT?w6Op}GWRof z?3)S%{xcyz;r_0qYvwQZ%`MQUCD*EoyTkXW|3U>g`g)_SHMAEGh2P&D;ki#R2s^ZI zU|5p%%kE8$YhNP@>|UDz|2~QA!YPzK3PcA_d>nYa7N2@^_+4tRzp^_K3g!*`8GI*U zwvXF;97?Oah8_Y8CEKyN8=0b?a^jk-t4bT%f(lfx-IOY_F0Hq^!3Ft}R>B+z>=K3c>TA_Z2IsZ&)-2!0TLqHyyOMM)-?&k6 zPu?B|qAHr!NK0s~y;ukU9EO-VpMu<2h<|08-39tUz|!YWs-BQfcux%j-S+M)Xf{C( zy`k&PN#(C6w;D+@m#cOCLg%n&T?iC^60EBStoG0~s(l(Hsid2YYc!Y^yMVa38tK55 z#mm{MXm&VU%dsUBPUxBtE`{6`C<&|yTR9$$7IC8G%=s^%Zb<0ZZs;kG@`ry_=wIHUo5E;0Z^{?IaH zqt9Ql636QouvSA<>7YM?;&d*lW{Q*Fo*k8F z`x@E%EKYj~&Yvz;`vfH&Z9TgRC7TtzJGez~z}U|JCs2Pl+*D_LJ@oR0+!oVaCyvpH zzI_Uom{dSmGc18{{K7Njbp3)*;K=@!g*zgcIjw~nV#tmyM*6M)q2@!A-e-a zPa0i&LAeu8jp1&we@p84U}MCnIlslLHpxu3+dq^oWi7)q3{%6l5(j|jS~DYTskE2` z7?lrp2`5IhO}|-^wUx#!j8n#meoNdFi~Gd4Z=jmAF(y#abkCX{4)Pr zb!`0}{DpKq2EspI`F(BcV}3|H4aJ4OlM7uO;@WyG>@=zw?e#4J>Mo(zQm=TO?Cs53 zl>Gtw>>+aVW&dAt%Tq>(k%f(k2?4b)QH-gWfA4b2KZUP3SE%5|k!2lQ0;S_ibu)vN zp4I8@n%T+&VPq5=OmOCkSwVo4C%IGrc{0!QQhQ&Ni_jtrvZ0ig5U|sTzcq1cG{XQ! z_0Q$n$@K&?Y2P{6Lhw8;a#OuCpb-iZT<>n?>dkZw-mhTy8fyxZ(QC^dPHm&U69!=! zIqQ|RAz0OC`#UB2;KQ>hL%yF;qW{8nHY7atx@mG@y{3+U@d z(jeYFAuryR^57#adKhF_>=%HU=vZLhCMcCCA}$T+1r;}~(v_03(}Wg>OT7H4Rb5(^ z=X=TbH4Cw@WdBB6Y}A$2C6-9P#7AqfwT-K9@~KuVHe26uMM#fk2vA};Kc9z5==@Hz zF*t*&f9tUO8*{a&f>!q4CLMLjOO6IzICVY5FE6Y*0tcVCGhIUE!wVY~>oEhLe-WwM z-2Kf`eIOzK5H$blws1Gm#@RshqSsjH6A`-f<{Di1z7&kd^^2L?DkV19+haCUQ_b#? zoJ7)^1zdH1?L?iYgkcKIVc#EY6%E?*W~1akYwzC$`cj<~1e1{%inTz;@V!15ajP~5 zBZ^lvy$c-wELgSFG>q!K;p+51dwwl8O4ZwjeqBXXHKmkh%a(~x!U3L@B zp=SEB%uO*p0U0XyVA+d~I!-U*>*Eda+p7bhFr5EEo_oZ31#z(4aRQ@-%X2zhuSY#7 zK4GY)^QRrjgfVq1K?csCugofW1*X0rHA&5vJBPC`JMnqMZ*Y;!H2X);qko8Cb$JKE z1I*Vln5%AcWrakVMu*U+Jmb6w>2kLwx0HdcF*KudB<_l#<)(KomMGpS`(AO=nrQ9! zxf3~&k*W+zjBNzsuORV_Uw)@OB`Nh3dO^_j zncN`A^KknQZRzd0V7QNBK+bvKXnf9qukyUvK=SKfld7wz92r4NWDMa%;P13ysk z|B$xJG(!tTnyqUp$os%lp9Vqv1NnS~J}Q7k&1sFCOE*Mvu!7#xZn&v)LOJE9WiJM!Jl> z2$Hk}GUyhQEO73Uf`jK~V0Q1*d~0q0v>*3mi|wMjVTevS9Bqm)pzm^Z|1BB{1{gRy z=L`^u_MkO90a`iIGn)!)W;|q9#C5xl2$4u!b<%fTxJ3R^NET&~ z({=qmZU*^G=1^S-v2nyHuV)gBe9QmnuQ%aWoCjSQzIDp_Ip#{-%R#E1Sc5kLv3^LY zGx^x40@oCdZ*p^ytO#e=sX2u(ERg;5~sC<(C{*N++EEZ*9abR@i;L{of~m;U=oy@Mm99B(#7IMO(e zreEnwo0rq=b2)TgN}om{#z6=3f6!n9eKPI?@tRClMe?#v%{E}zh}ZTL4y z6{la2?*NHm(aBS)Tc?K|N{UOPcRRG%MiTU&k!yn1yeUmM(gOsMjAd;2ze9za#yaEN zp)=l3MNhHH9-T2&7@{j45-lNySFYz%hFSVzMSnzi3qiBj2|S_O6)o(SC!cb}W+`)}^130+~;@NJs9lO6LOe}Fr%%9lg19HLB44ap7YfuqCYJ1D2(& zlq-1Si;HMS?fNp>jYNar_2Y=yHRI^@;qZX(CyY82`gR+tOx5;%LaQi=B~_%jQpnPv zGY!KSO}rHolUd-e>4lcqXy4V(elD=W8HNgR9xJ8MA!{kX*FJ@p9e~_;zui(HxHSNT z>%R{2`lCA(sWiq9|77G8M?ITf6uA8W( zeLRsdj~@6tH~M}i%jV@sCIeYgNyFK*N7fLr$x`Wy^pkB*(4% zVBk@l$zA6Z&zF5X)s2t+Jy1m#pmy5#tXr_*1I(Ihzp6+TzNs~ukA4J)&qI?0KmAr4 z?nBJdwNpensuYJ$V%DzoJ^|_a{t*HHLB2*}U>h4j=CCrbz`x|8?el;O)cqx6%z!ef z#V$Pkzd$7)O>TKZ`;;(w6yAx)9G#{(J$(2N zhjuKs_o-B^{m2-5XKUVL|Lz#~1IHBdkTRq#1pa_uJ}RG7HIBz&Xl~YBCsp{+U%l1Z zoBKss)x|nWcGTxNlILtJ$xXl3_r{iXr6{dnm$*h~@iF2&AQEE`v2dMlDkIJj0Fxe0our_l0u?5(y7OmZ}QybYIG)(wUF!Be% znn}f1oS9g6Z$myLn#cK_KSe76+do+N|T|ue;q^nL+(cQK314@ApOmF~Io*W0q*IObCOU1>Nc%#7fb}vE0=rV@eclw)IVHmmcn&P`~S4<#iO;$;$@jXdQ-YKk!Sb3uKA$&HOYux)Q(s?Vk z$e(A*&pp|kQ3F56xS?r3Zl)^3OZ6LR9`PD({~#6htEl(ie%X&hNdM}L0LBlxkGtDH zKpA6wmG}Bu4w*NWzxK#oR8 z6BKx0iUdG?%s>SBz@z$M4zpFb$mU2tvY^}NXqDf%QF?XVM{jmyF&H|5Mn&Mv#ya>*O?~BpA z2o0jMsn=w#IpQb+EN-X%bVRFulM%wN`M+9BHnj$ET8YNt2m?qwc_{r4C5DiM?B;Yg z5Y{cYcF=;Fok(p*0G@3KgpQPb5-j<0Hk;T1=AZ2Ya}dD#S~8}Jsbw8T@>UwDm^c&_ zIihpB(tkyMrrUHBTMemXWHK+QaEFfhu9$QgHzD3eP5)Ja&x>o~Ntu=IFO}I9Zyhq^ z@NJ4e>%cMOK4G7mf#cvtQO*1cED@MsvBkP(adfCNirS%a25qg>wDZ-`@`K36bzW=i`@^Qpx@l^dek zmC;~c&qAE_Q-_RI*<|vChv_f*uqzUMhMi3Qs`Wf|E@K#QId)q&DMbQu5i)auGHV!5 z@ou%oZnHI)uj(dZ(bo+}`dngA04kQ&@*4KMkvix?qZLue)2g&p;EZ<1X?RzndQu@r z`Iw5E9Xh(YT@?N?%fcMRv_{UUqmofVn*4M@)2hc}oxvYx*inrahpH7Fw>7>L94&f0 z-l(lD~pSvR*4pC1uB>)kP33GjC_lLVk4gl(Kk!!S(KuI38i^UO%L@ z!Kq}KTXK!p72q}NdDpyNoh-cFOlucm}3c>8GVCN^`{2Xe4hs7q({ zlLzYFY?tRxApJy47o07h)O;@^n-);%x}uo!&|yOw&OqOuc=$u;>i)OMqi~SbBq<{; zA=Qc6oj%Usi0hdTD7PmULITA{?-Z>I@UzFGyJN#y=~!lk-o0m&lpF*9c+bPjCBZ4` zRxbb>ruTJV)9Iq?X)QYZGtu3_ty1N~*GEouKU`opuNcd-AQuv$e zR`2VsI)X3`M)%{KF^l9t=Ouaz0C|P}_t0c!r&8M-$-8xIAjvyrmLJ@1*oOFyGfeKt z8!5X=$H0}Hml!@lAx89hSxALh3q>WU^zKsZMr;?GzGfJ&+@zk1R!p40@``T}RH@WI z#P4Ev2I{!i)-l0PI@AT+au?GK1)Di7vaw=GkGi@g&@2vcBZ!JVylYq+w|T=-Sy(b4 zTrF#Gy9(02{r|#8pW5@TLOStCg@Z`v2VTcHH3p7l&Zk3MN! z8_!2PZ>&1E6NZVcLbiMwEr${R;u~Y7LZvS{GGA3s$$Lj$1h={7q`6L+`W z3B1b#*Tv9QhhvdPBuO3cu=#7g{=odNLX+4pTXJl|3V(txm1PSbk)4L;Agc>ojh%!I zA_1g6NhXD#YNB1fY(Iod!c7TSp<))t1#f>uYb_)GKMI~xSk|NG*)kd1JhXfrOR)M7 zW%k7c?aOang&+lFLK+{2BPe!8wnhP2tx6)`B(%RVyigoD3xs(~;}&m=`L*Lm3nrYL zK+vpY>01zZa%BABY2ehy>^G$Js*U@GnKLaqm#OB^2VUPy^_aD{f&;xG1GU5wwKB_V)hcBV#gp_0|nsh~Gs`8Kg38UkrXXTmku?Mo0 znb-S#$KFSVXSmwHDKk&~whhzJ6i(iFB0`jcVVlwmYq&ehP?${EBKdI`$JH2iAOecF z$g`2{TA|DE#aCT2yK?98LP814ftMbIA~{R9W%Z48!Ybba9dlRpC!4b{>>H$+Y!xr^ z+V-geM|Smk513B9e&5MrygSf3rj??q*HZ9MT}mA=hq%aHMn%U7muZn(rr@cD{k!9#d zM@K783Yjm9;ETRzgE^4*if;54FCWLDfA#Sfh@v+Ptz(HqSO!W0h^tCr4wh_(0Dq1v zgG~gj+D$A{7H{~p2m?*#11drO!5KY{$4!u0FoWou4)(j}AQTJ_^-7x;=;1wav!S~e zCcNph0}beNU`x0(*YMwI4^pZso*r#8c&Ah$bSQ|2_54TjyBJbRvA4@TEPFo2{8W09 zT1T9e(4v{~*Z)i;UsKc?I!qg#I6T$mg60$j>k4l(wq&@aH-}$tyDVI09X5`9FExC_ z-stj^{7unI)r36DlnV@3Pp%e#V)?`#bFWR&pXB{9t8>kUr3W{DmNSOMJ#VFD{`{FX zf}DuJZGK_)yrO4+fbvg85!Yjt?lzoma{UTz!Nr!u6}I_jY5uH}EwrzLeBjN1am5}v zW{L~3@>qN+o4Iiw(bfRSUrFtm!m$$mdZ=r5TN_Qpg>`Jh*Io?=PF=^&LO>^5DZ`f;X zA68@2k>3{kij=Ri3X}#&RJGuqd7~pl9Furt+b`?<{G}Jh2*MzoA7x3*=$J)Sb_WI~k-Y zk@m!Vf)nnFeLt@~0OunK`|wl)Qpg7+4p2rKQ4@RJx9yH}*0qxAyx@$ot98(J4x=6! z^5iUte;{!iZ7$@|n;}ehC;r!pwWECugI9+_D-6@SJu6buN2%^kbG94;dFmp!X7648 z5?C8>(GO20R{$oHv8PeVb6skEshgAnI+MM>vd(Ewr>N5k)WwaQL(Ge?-2b^GSiTos zaV)K}OKVd#x9VGFz7S?P^`mAwD)O9u4Ovx~TytbaHh!#TcW_dvE%qP1ba-jS!EL_k z{(W8v6T5&bE-atcW9p{9T~y~&5v*&md>#EF78O-OYq2mHQ-Fk}3~kk^c^0t4kD#$m zvwe@mJ>^6SQSJom&0yn?(kjeW%gen$#&|erp))8`Tq2^lY@^EkIAmN0C)l9+7^W(= zdDu{Il8|Flb8*V!bW=@NLEF+x)uc^Z3ZK^Dxl^qc+V|?;B}5*&S+{y-ym6ZRwoM?M zwVjdxF->KlgQ5aF zoT(%NF@${SRK}#yh53o@IC8I<#M?Dtr$@wvItW3eSbzZ!I4+wtOk+D$Htsl@p(PoO zh)mo{%zd<0i>(jXa``AL6UQz)S$=$_C!`J=!ZpUf+*?}t*fe~yO8XTu(|nw1wt|EFN?4dVvP)Ea?i!-`(T4+I@C z1ROJ!56fyCKrd!aqBXe6bM1+$=^VNTW&~na;HPkT*vN++;gxm z=Xh4s1P=oKy_yhaoC`TROa!CR9-(MXP7?^;6|y!Q1Z)^VpnIeApX#i63FA%uxq zUCnF3^$&mwYjW4?3gW%sXenZoxrA#i{3HI;GFRp=oG=0g!EgUaN1u-~9ujr3p_;{i z@0jC}dY*)cB3mxti~a*;Kh8??fD$2>pa#vYU>=-n=RY0fKF%oM4qrfbPY%*)_4I;||*9TNZdAz8qO30$O9>*-(N>ZlAuSP{pPv4rk0)uv7jGQcla z%C?@!5JR>bbZ4tB5Zx!4&Eq-FrJYw|lY5F;T8ogOfmA{$5j4M@9Kk=u1BJe9dfLjo z87|Pec8}|i9gQ#NIzRX3xJ;w<9oQ07NhrFb#POY@dwi=aH2gfnkPm#1wrB$j?X!Dg zY;tO!t=%ooBV}j+s?aKukPXBUEZy_39zCQ!G;n+bD~*N(-C1Pc6U~@-;H#S^5>yq+ zfnXRN*EA+{^-}kCvjS+Szu3!2jd)+oQ>b4I)7Sy9)m?ikawgZbbzmsuws?L|z&XvL zQ}C1MwP@;2 z9wp2KE^XtD6=`rzb4=`y>V-4Q#({+RG-I~T@{^mO6<1>KnoJ;>l?%!=QAqdqM5Wo) z2IyN~MX9y&an`Fo$b8(#11~v2eS=y*8wA9^M77rNhfH77N}}EUK3|bX4{f=OqKhuG&V2;p)@Nv?#Nhw_Ajm?7M@SB z;GV|Uk0Z!Du?Ho!3o9K8HxEB+pi7Pyb8jou4Ia77SMW9)fI?-b@Mo>+J!BJ%8{7l?*APU;%g|euGg}k4W8RGjiC1a#Pm^O14 zWyVQ9Xy4-_PM>8s$vvjIzHHt47U6v!75TrLU@L=-UGaqGq6H9OFt#{0bPVhSZcx2j zW3J+u(B8gyUb1d7!+7!og2vxs^1;S89c^ERkeUYDv)Eci^++`omB9xdUiJ?+<#LPZ zHJHX45PP+R7VQq7fU02^FhWMI?RooSzMHwfz(<+~I7!`frD`cu;o_0O7$gJu@05U3| z%gi?_O8j1r5Lo9%3I!?b&vA&+J%nHE$AIZOvK_7HR!mXIacl32w66J*964@Yr;X`u zR2e3v5PH10d8hrA7?w=sG0Vp!RIJu-W)N%)R&&fs3h({8s95e@6V+*-`uzR?S2M+C z6p7(is?dDO0KJ0$e*Gs)mRc1=05S~ZgSUAVf7}e`q>8L-)1+x8_OT5j+|XKjEH9FA z;>A2c*zMO%S=r0r%}X96-SmX2jhYt4swrkMLgg%7kk+5omjz3@mHXLfxDjtNxTaEt z18~qWb-)C?F8tpbwt%^HzQ&s9XI271$tPE)2PH(=nn2yQc(?NDUk)E3+wy>D%LzIa z`Hk;Vpiw#+Riz$BN77oYkt1coE_YBX?KwFG!?saP_~j4wgVVjyQYG_H=R2g5{L=g4v*-_R|CLpZV}JqJEz731h{rXufsb*6{+)7b(CJoj)^h zJ0=wO+>OBm4T63uBfsT`@>MtRKc_m2BLrSUGWn;ZJZkYVHbHH>}9BoarOfVgz|y zkM+!M1bLJZ&%nuoTl~K+D&Um<$NF2`02PYKD8*N%jWiir>t?}QNT$BxfoR!OL2J{c zT{^?(ZOLb;Q^6Ayyudk)THe-Hv!kqzQZq9RLT{JIjH-#$5IZYMP;#~g+9~n)%j&@# z{HZ%dFacNuWCrXFT3=1CF~0nbw11QvVm{;0r#gU24oTAZ`B|E(cWnF-Rc@$k2IaV7;uRk3mm8-OfS7eAF=2#(i8b zJHrtfZ~6yf|3P)E(zyD}5e7@b!lwJ$K99(o5KD4|S`sTyjeg47th!NA`tHS$fym>` z8>2Kb0oqNy_4H)2>hgzZ4)-}_^P{d+mOohk=wq->x?K;~IK!;%8!VERIPtqoNQhfs zuWXdEUhos>>CkXr&&Q~JvCjCH7dh`)3D-3-fofRKbh&66qZ$0ZS25ez37Ly_P&S&F z=t*6)0}andO}WJU`F@o51*8wpOMdITW$-=#!2k#lAV7w$pJjHh1$uw7VnV=YqC5z_S5*X*%nQ%AY=p*^=l-<4K_@WWwyzw4~f6n};az?yxk? zxuS14yu>F-*9(F88s^^;hKMRyzbtKiVH8@LH`Lr6QRyX3>O$t}x&meZz_9{Lh#<=S zbSEln8I#BzQu)K&KNz0hwZhs3$oYM4jQqJF5m>a=hibdWD-$EgIep7M8U4rojqlS> zG-=xqGS#7!MV54-o_&6i{b>@zBT5lhXAp-;>~PJdQq8DdU)WBAK2X}5-!y=`mmMjF zp0{8DPyg63%^OCR}?IH8C69`sZv3AXE>a)v8YBO46yl4McUq2q7qBS zA$1iI3#BmX>IqS|+Q8J8D1o(vTVe^0vpmbJAuf6fC29M5k? zq)3R!d(CpLD&0y06z4P7wDuU?cjceVYXEVMOXbM!c=VsdD}^flDyt?WMfl!z7%m#} zrPRx$!Q8noT&AC~xYD+D^?xkC!$zxIiKxk8Paa2AGcTW^T4yk(xvrwGTgj4u$JK$Q zrqdVF^!h>!`(Ae*az76^+f~M_{Jharpyr?P$d}^=(&%Jg-kX1>RQ087rT@cQ-AA#> zU)=if*Gz5Sjl>*X_@bQZn38rPmCCj1{8Uy~hi9+1ivVIMu{&X;qvTX^xJ&f#(Gtn0 z;$<3-Hz)9Um`ow|X()i+GHTYR*JI1E6eZYbMTAeBc%W+cs|p>1*Bv&I-=;b3s(k$e#>v> z16rC8Wa`H(|19JkNWa$V6^v(8a z^PI@M-E;MmBA-QLqtl4eT{J(&5;?xLAa{VlsGc!&7?B(vmtXZm&NkM_^1w-_JcCqO zZn8Xlq}Wb<t%rF+7}Yb~>sgz9hbVx)@bL_vRtNoK z3T#4@NUL=K<@j`GV{>tixFMU6IcmUnqt0`5=IfUW2ysPzvJ{kBaPY52AV$h~%t zZ>H#h@#G|j=hDAP)Fxe=8KA+d@mA}V(q^)ZCtjyum#HFq^a#WI^;-LmkYo<`6&~TD zmPI^698bu^1zRl`XE`!mCE(+)aytT(B`m@jsRGI}w{!^Xpo<%8d^UQ~*?$oCgVh1WT&k=*|pd9d<9H}Ip*H!vs0 z6gu1apbrQnHq4zF_quM)Y|>a1VO&?tMSboKEs>+h>5PH~7i zp?9%EZ%Gcb2Fl%HrPh*Mp3_yCm=^%(&0Q6+%(L#34Yl0KOFW=3vlM#Zo(h;O>!g!% zGa31?jP#y!LRZdjpQ7fvsV2%JZ$yc$b^X=&!hdlKHfSn;#l$x9d9I6hKbF$}kJ@4C zH7FUbs^K4hRns zP@$T_fxxL?BGJ{Yr8q7%v1s-!T+9!9x*UD6q;y-d6Hg=SNOzZI!!!-F`ldA~WS$|D z@LMuFm)m!Z4#JO-eCnocmB{TJ#;Ha>+NvWJ+!n=y#_iVAy&E}IYnc&O`679-DBK+L z922J7^iAz{Scf``_mo1l>meOecho~<$b?EHO~yQChr9by3cwwFFtP8|ExxvLqv4{N z{Gy{vGQdKdpkOWj6xa7Gn!D=E#bU&=QzHQSiNOob|H8{NiTB;Nq%BonVxM75grez& z_*_DEcU~L7p@x&`v@k$z_L$5CcX(*=-3V1}6$;{K1sO6=mj+LyF%ZHsfs1Q+IkAAT zQX;F~1Ps{MTZ4ZlbLw&_(15jHhEzmr6N z#bvCa6E&B@lu2ynaIKoi(bM(>Ba$xtVl*8yxF87gwA|`B$=g-l94a3?Qt7ub-UZgk zqM|z8@-=<;2!uEIcZCVi$C2n6tIAZl)`{R>PSOPbMHjRhYz2r385wrKheo zw8b$AvsPjfFLPhr>lZFC&$T{6Y&;>ihG#4tvmCG(k^_pT7OK*5J(_xW+=(;xV?@|G zyisP8S7z3V-ZcJyv-=et8(Dn1EXUmmv)+Dg`CWp&&t-`Oz@uWRc~sdU@g+C2Q=kb6 zaXLal7Jm|5${FfaKtQFwH zM+uqJq*WR8I>G-@f$n9XCRjVv#@}58@&l!8DP`jC%K(<`v1bp&SI@lm+VX9YR63@- zW_ll1bs(JSf!Ki6VT;LO@O2D}>7=ICPJR6NIlScj75yAO8Dn|YIUnM|-m7ca6xztK zBwlt>D&}7=>LBM`Deg%Fz(L6Ns8ERa>=?)=Z6ycsQ(Ci#^^sfs|60XX@Dw=~6@=-!#hvE~`O{XN~1kX2mqL1*NMMN_ybA3%J(Buh3JX5A~LC z{BEvRA`8tGC@&PeS~*+MMLHwvp^Y7d{4?E@T&_1E1k^U9AiJZ*`|%LeEsS``hV3|9 z*jIljz766qCHO*nHAB&7`kk?iay`6jBK`-$IzNlIJmk=GKp^tTTQm_6qN@9aVwlUW z&G68IB^tsmbFw(`valR5&IX&C{&LCxegD*DR}@XrJG>rchQuZ&OrXw(>PHNQHY4Z; zi9?N^)QxM*RU6l4$^SQSv62oPAH)^}b0&Mn+IPz%J!ELfB%lM@CP6RsJJ|@EQ+U7l z%08VU=#-jh{^Y9)Rtp8E;8FKGw=d8fY756g{_V;SonZLfa%Cr{3{YNr;do|R&YTb4 z1`TqtuU>>Zz0VWP{W>C4ux@vzn_pbMT-l-2?P*VTafrWa?ImH1JLp6(MSreqD0mM+ z0T&#G!XSXN|6~tun{C#w)3$cK(lnBvu(gM&Vw!#Aod6V5Si0-K(fW{FlJgDNz5;(J zfQv+^W`3VbK#tD6v@(0k6+>6PRSm)N7fL;+Cg+KTEvTEhS40r-(>yBTv1yg~O5EWg z2sioupNkO&s0OS>=7|2WroW1pwvyM$1emyELcsB{Iv@QukgjSmp>R-UH&!{rH+bs-chDY&8iDP*V~ zk1s?2s<`BQNsz^b_G&5HT8Qv%Uq5kO!l{KRs{aYX0Y;PlD{r@F>B&>58`LI(r{_`_ z6WZC9lH<#4-KoBQ5SGUrzDvAkZ{N0Rht=u6sO z`5eK2yA{pOj9*qY0v7UwOiqw%`9;Uj0eRO^*<*@WYxF+ebwZNL3fd&&<7Cv2I?C(72~0J)Q&l^mSIhpN}%>T8^> z6)e?`_wgA>cJ`#&zi#I5D+3UTS2S`gc&^-@%Db#kbInXSS4#3gF_R%l%* zS)%;p3RJx=bfu9B5$t$%I_yS=sT$t~F?MeHLt=^4O;eQ{dMovNU9axwC3f$BQEq?Vz zb1AKHgM$jvRuRa3Je;?EJJ+<&0NZcgGU67libhCcExzWv4W7vZwkt{hiqBd1#!X2; z%x^n_S?x0{vTWjN?_9DIADTu^owN4>Qi_}j)J&Fo zS)*;_MpBDWdE-OpP_^b7va1pR&>AZD%AqH68n-XAIVbEge3CE3IB^;mi9A~yHqcjG zw|>YL!FuIS?QQZ-kHj;2C_u=)@!~E>PjD=aGtsQ_eyl5#*WK4vw;F7Y&i2e9ygq5C zJrP_YuqO(VwdTAvf5TYe5T05CS0cB!?PAW<(%1G4295yK=u!nc_;&6KShJ8sU~Z6l z3M&$)$N;ZQ8H?e+M}}7vtS+2K6Q3Ed?|c-hcw_Ou>#uv#NBvc4{f;`}@O$MCcy5P{4IP$o zc|QEw|6ldXB6pCzNrBsdw?k+tUm;;cohB*gcQ0gDIV4Gmj%S0~=+0rN!2FUja`aY+ zAh)iF{wjvzu2usLfaurL*8gTcyXq%a(1amvZO|lB&?(B3rCc*@@DV*B)gP}dkCO$^ zCIKm1@6vx)QYr(*@#NkZ8IbYDzO=&sr7FfGq)ZnRc?`BXLPlOUx*!}{uS5WpZX?ZG zP446~FwAWZE5xZ}@BwiHAf~M9a%d__!8P{2p~jlT3}KWkX5O-?MwTaqAtNgDdM?pm zS4&N%Ajl<0|AhUysJ528<*8e617QCiTN&dCVZv9Yu-hb?mM zV|j%|U`Dr#4ih5r36F0yrV0FibHub`O|Ut^1#H~h3ahkp2d%b61G_wLagMl_Y1zzY z%Nx&hc+)NaF3+y>2|b+ujyeq&hzC3$EFm^6yB1i>Wlc;cpeN5-3`Gxodu$Pg;Ae7o z-6uGxE49kOmwhOz1L93c`hm={5tN8+Y}}pUfY4Gq>H<)T{GY%l6HN%2YoF!Atv4fn zs@9S`vIXvyLTC`U_DiHH%Pv(+hSuGq_pHJ+BMk! z66ccFpq_<=CC^#v=RbBbvlJ;Ouhz1uO{DT4_n%!|#Wz%ELrEiULDY|(1DMnQ*ZlVl zv{kRN9lYv*`|zF?-(*=}_p-zIN&pM4(KyE#*;9Q1N#XV)pA-!Ddw|&!i7Gl}ABj$a z@=45Aie*y))n-jUHKPSf;jUzS1334&WH^6E1UMi-fbRfTEb*5DgnwCVWt*#6yTyY1 z;N9S{w3!qfH@tRN0ztoTyiiiQ@CKZ?6@x6-pR;0c2l!`f* zCpO~1?K^_0MTaQ6fHv7KGM-vR$bI}CYW+_DcCS+KTKtYSbw|xjW&6uhZ#ugFFY?kG zUsy(JJqytZ9_o~_z-LekZ((&?4I?5L13PiKRA>^^wN(RPyYT1!`5umHevYHX`Y{kK z`5@APqY{yn{49!;WQVpZaq+XqZY|XAYo8fNw~?us0001i0tGMGJk>dcvUkfqNC*R$ zIG{DrsXgbBz$n*!eTMUfe+kq(uc-zESBDDu{){Mf5e}d>oB1tq@vV6dxdPLRU7aE% zT9s^M?U(C2uQ0*Nna}gW^|=}K2QsXCvQu>1TSd31oc|H=xnSbGHTlxLmTD7{;|~@5 zk5GXwxVJD+X(pIGhf)bvS}vq%CS#P(B5`!P6D8)BYdIfG>LKFdmftjg zw!P+dCxKITjfW49YT_Sh3;4p8U(Ye46phzYYj za=O$r2Tsw^#GA8?o>v--onQc{cr*r1e!vAs8a>XoxX-Q%Q#U(sY@kAz@ZsX4X>v-yF1!i7d1^5>~m7IU2XZ z{T4)qEA1p&Qkcx(yx&%cIS)f|pkeEtP&#kj7orFCkuw=XhBu@DC7h0d zRIBT4ezzk=^+yP2ONqj}wx&bQr^ls#FE_t)x=@KT>)lmbip;XQb?b4wQokIgt}w)` zn_L$p*j~vPYyhWXTpq)|TjqqO46MVj_&zwX<}Ctp=?kIWvoWUg)~Us4$K`fELv2(ddm#|pN;is z<(eYBgsRnXQ-qJqTwuiH(uMM6QCSMY>GcPDKOP*QMjvS!a^0K0+(LJgWQ_Ww74GV+ zuJ@NdP{G$O&(=UZyKuY982=pBKV@~4ySauD?!;=~%d|A=ZwCrl53yI%QWbh~`Sy;N zu;A$E67k|XLldB2`DL0b`ZD)gM<}D9Bc<3ZY6Ypa&W&0s>+?H5XAddO!=st5Vg-UI za87)OtrP98Nh5kT$TYDaJI@?J*zPdZYU3$7&6PAtuMD#Aso>Ie)tP54m76gge%DIR zh6c2l&{+C4Lm_&+v)6Ke)+q@9Fx32q&A=qXW8-d=Df82AZQW6zpMM~q7qJ4?ok*hA zh2B9kR!$iQ;fbzAb_)CjZ#TyDf;frDHwT@y&@F=NI#xhuu;KjJ6!Y5%L0TEt2!IQH zbumB6J4A=aRSft54tD%t^Iu+4-W^fSIy2D&%}m}h=Stb^h{c&`7e~Qyjm_tCFyL1a zf&F`{_+X|@bl8H6y3q@i=x94m9mLWuJ)0VdsM%)U!V63eB6T8cptp}sV=ax6@N`&7 z+TU=lQt;WKh>>Z%=BLh@+qB;fAoRmcn#x|}4oG{Wu1^0G!jYn(Z}Kox}m8(mO! zYV-Tt4jRXI?0{}^j-#dTJUX1*6Y=Db7#+iWJx1+4OqlJ>ECpfmEM|2|zvS-z z!QBtw!+eo@NOdOqX^4Hsj~z7e)xD*qe&ciIAqf}O%=KTT)4+*+??C?(-Pjqy9zi1KG=FQ7l5mvL+g-7pqbuPtvPXWCj3i0U_O?)#Uia1UAy#TXq>XYhNIJ zRht0?E2q?CX`!WtIdD?zADQ+g)Hk9+)BOP2G3wg?vE)`MslM6xDBwOzSG~&C-I_@8 zwE$7eqGn$Q9W8kEO`K4x=*!e(y0+*4-Q z=o=4Oi>47X3VAr1+I?ngFn`sx1CwTHQ>Uh~i7C+`wv`XV>5+h4h}Hs4qg-Fp2z7c# zFML>f=YK_4P0lN`5k_v=nLpFcOsDmC64Y{{-_u4d61O0*%BiY}31XWa;D(!DODJh? zwe$+Meg!_itom8!%t+8E$PrCbin!a}2O~kLBv`2-_k2oNSi61R*jUW~{Eaau55ap; zMw+byrw{ZqdkK~JqcEFk)*bKfP(%nMB%j!iQ0bXFx z-G0&^xtjEs-zMOVL9zz($UgpV@h$b!((-~Os7hng{ve%|VyhP%*Z}3%v`wy)NE5hs z&-&eEbqc-FGHR(De4x7vX}sEQcFzmVO=qoN7n{q(xOUMyK7aa*3W7ac)axZ9%L2u; zmyS-B7v?m~mlq9yoq&1jI*_wTfttl=xitk3p1x-5chIkOQ;^x>_*^?DidL5OyOWt6P&bJd2Y`QAN*{5I{bGqla08NTnR#Zvm=&1xx5A|k&R+L;zO z2jKpxUvM(F=v*0s8YkUu3@TcSL+p3zel7Lh(rqZhYsgG(PjRo4+Lwc(-Ae#lE0EzK zNf8mCZIceE7h1_}67=e*T=Kq8ojHqQZ|k@1UW9V>{XDc#&M+*}o{f6Yg+=!DqsX3?$g3apEB9Um(A zpjHH@HjG+3&Je(zGj?gjls1YunBhkjp!*zS9rALJ11`a7Uk%k%%ht2*Vcs33d!fwr z#F$srH^-7O%$kO)^PbZh#OAOEDl4{*%;hYFNNfv=D#}~i&3&FmC&?AvR|yf4dM>n5 z7oxjDHb1|5{Ok=o&XZBB#U>U93&J^eEitpyoHa)k4*j=5UPnJL)K4o#E0df{8$8#i z=-395O{xcysV3?wRJEL=*&rY{zMwAvIojiE`(A&;9@^J!b)nl8nu#GccFR_U|E`7k znSGicyf4};$zJ+CoM>iG!d-pO7R+|J1Jew9j@Ft5M1>wbU-!_+cd^nKYFbs8!Ufx_ ze6`KO0h}b(Dklk%TpvY3>HvWP1PBl#XIX>h$;lwV)^+>W0!dSU@4{rZj{BL`9$4GB z#n-P{2M!yBC`<>LVTT!cj6iV+`hCM*lhVtOEy6Ufk~6%PXQ*k%PfCs*#U@xhsKB;# zcHr6h$@A(bw2+=-vvZRfcNlFV3%fJpm?X{rdrjW%3}ZL}$Wl$D?%G)qW$=`A17Ly5 z#@CY}VaQ9A)>sxz;8+L|i8z06q8{Ctjq-n10c)_%d8E2-*sX3PeyJfEdV-jMaf)L| z=TY{j1&vwo`{)VyjfV)ir5&JZ^A$br7cJf#P?@vQc)NUv3E|J&_xS1bWLb^1dZQoF zGT?b)d&yL{PQAU1J!OfYeiW7uhv4vZPFJZSFc+~p3@BY#e+7o>A*SkD_ zHkw};T)O!G{Z}Fn{o}NJVt|umP_dtHEpZKF0o?b%+WB!R-QJB(I?N+Hn%E!qhB$~_ zu%qf}bo%1Xl8;1Xc5gwZy8B8l&(+IQtXBuXFpB|w16W#xsJtL@YN04}ndEZas`+kA zJX{zP*F?<3i~o;S00q{UbKYB-9m4xon{@9S%x!Q0Tp6j0r zKIw&zXEMUrXjP{%?uUs~_gj1EtJLzG#`RMFUR9W@mC6-JD%0K+R7kvNS{ z^FM*Ae7@7)D&9>uVM|3^dhcx`q?;GfI+1dv1UMc%Vij|9JB}q6b~u6U(cn zJH!o>Svo#SvV+Q{^uM;lUWZ`>2oNAZfmVK($@I1g01AQHixeeO*Q*t>!+N31Ph|Bx zGLu^twPg{Fy;*^cc@aY<@+%2+Ce_#)xgssQDo>BV1w*V- z(wleC=<-KC!5VanMvQ@OR<>*2EM8Ujq{5hxyKGwD1FFW0H&Jl=g$CH%z}mD7Yu(dv z?2E@s;|H(6(5tntnd#Vt4l&E-@91V4nYx=HX@fUWa_B8dBb<_h0YqKp8%M|n@%@39 zyo?$p`VvvxGRO||*!bi>pP6F<(jF~Um4}s~!)&&N$SS|I2TGiB*d|s;XxX|?GC`tM zuQb=MHv!)zuy1@-=uOje%Y8SQj+Vef1>*iy4`I@eqg&t@t9^lwQcCOk@{u z{|9a`=Z^5=1e2s2Z=h$d7CtpH6@G&+VZ9-md8{prEH*vI;M^y%)=gE4TPdt?&rcw4 zhX`ahwlX6J?J?&(xr{{0pmiA5mZPm?f&y8#5PE$*-PMGTvGoM@cQe|9a;L%MNxDGH zPItG>Np-(#^vbvO zYlkPNa&>c(=5}Q?L()|JtMBPnFnoSyD=J*2_@S`Qiju9l=kE+ZTVV+N^Z3Xx(^v)c z5WVqznmd(W+;tmQ62VK!J3k2qIZFsbAhIi~%bFMz5!+U`hjw<1C-76K!Acftr~L@= z_D5Y@Yn)aqA07kx#-{v8f~d&2n&!CuD)^OPgGu^YTVDori{ceo-4X2Yba!~bt<{<8 z>TMp5fJh4&P39#~7<(f<_lx%{Eh<;OYQM1@(<~|uA)4yU3Zl7ja{|%X%TtoMyYRpe z$(L@>daFcLhvldIS>r#cI06I!000000aUy?5J>D?Wl5R~m`n%HTUvVZJ{N*w8(Lh{ z^_#Ko~Xplcg?!2@UUQ z=1B;g&Dm9zy3=xYiF>)`U_;pefc-`yAIuk`d63N fn*wjQQLZMzvf=dzVx*Eu|Ha&qP81{s>dU*pKfkT7 diff --git a/integration/bip0009_test.go b/integration/bip0009_test.go index fa94d2d0..e22fdaba 100644 --- a/integration/bip0009_test.go +++ b/integration/bip0009_test.go @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. // This file is ignored during the regular tests due to the following build tag. +//go:build rpctest // +build rpctest package integration @@ -129,7 +130,7 @@ func assertSoftForkStatus(r *rpctest.Harness, t *testing.T, forkKey string, stat // specific soft fork deployment to test. func testBIP0009(t *testing.T, forkKey string, deploymentID uint32) { // Initialize the primary mining node with only the genesis block. - r, err := rpctest.New(&chaincfg.RegressionNetParams, nil, nil, "") + r, err := rpctest.New(&chaincfg.SimNetParams, nil, nil, "") if err != nil { t.Fatalf("unable to create primary harness: %v", err) } @@ -320,7 +321,7 @@ func TestBIP0009Mining(t *testing.T) { t.Parallel() // Initialize the primary mining node with only the genesis block. - r, err := rpctest.New(&chaincfg.SimNetParams, nil, nil, "") + r, err := rpctest.New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatalf("unable to create primary harness: %v", err) } diff --git a/integration/csv_fork_test.go b/integration/csv_fork_test.go index 1b4ae02b..ac8512e0 100644 --- a/integration/csv_fork_test.go +++ b/integration/csv_fork_test.go @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. // This file is ignored during the regular tests due to the following build tag. +//go:build rpctest // +build rpctest package integration @@ -113,13 +114,13 @@ func TestBIP0113Activation(t *testing.T) { if err != nil { t.Fatal("unable to create primary harness: ", err) } - if err := r.SetUp(true, 1); err != nil { + if err := r.SetUp(true, 10); err != nil { t.Fatalf("unable to setup test chain: %v", err) } defer r.TearDown() // Create a fresh output for usage within the test below. - const outputValue = btcutil.SatoshiPerBitcoin + const outputValue = btcutil.SatoshiPerBitcoin / 50 outputKey, testOutput, testPkScript, err := makeTestOutput(r, t, outputValue) if err != nil { @@ -189,7 +190,7 @@ func TestBIP0113Activation(t *testing.T) { // to create a single mature output, then an additional block to create // a new output, and then mined a single block above to include our // transaction. - assertChainHeight(r, t, 103) + assertChainHeight(r, t, 112) // Next, mine enough blocks to ensure that the soft-fork becomes // activated. Assert that the block version of the second-to-last block @@ -205,7 +206,7 @@ func TestBIP0113Activation(t *testing.T) { t.Fatalf("unable to generate blocks: %v", err) } - assertChainHeight(r, t, 299) + assertChainHeight(r, t, 308) assertSoftForkStatus(r, t, csvKey, blockchain.ThresholdActive) // The timeLockDeltas slice represents a series of deviations from the @@ -426,7 +427,7 @@ func TestBIP0068AndBIP0112Activation(t *testing.T) { } const ( - outputAmt = btcutil.SatoshiPerBitcoin + outputAmt = btcutil.SatoshiPerBitcoin / 50 relativeBlockLock = 10 ) diff --git a/integration/rpcserver_test.go b/integration/rpcserver_test.go index 9fbddc6b..2ed6b408 100644 --- a/integration/rpcserver_test.go +++ b/integration/rpcserver_test.go @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. // This file is ignored during the regular tests due to the following build tag. +//go:build rpctest // +build rpctest package integration diff --git a/integration/rpctest/blockgen.go b/integration/rpctest/blockgen.go index dae3b7fd..afa35896 100644 --- a/integration/rpctest/blockgen.go +++ b/integration/rpctest/blockgen.go @@ -44,7 +44,7 @@ func solveBlock(header *wire.BlockHeader, targetDifficulty *big.Int) bool { return default: hdr.Nonce = i - hash := hdr.BlockHash() + hash := hdr.BlockPoWHash() if blockchain.HashToBig(&hash).Cmp(targetDifficulty) <= 0 { select { case results <- sbResult{true, i}: @@ -205,6 +205,7 @@ func CreateBlock(prevBlock *btcutil.Block, inclusionTxs []*btcutil.Tx, MerkleRoot: *merkles[len(merkles)-1], Timestamp: ts, Bits: net.PowLimitBits, + ClaimTrie: chainhash.Hash{1}, // EmptyTrieHash } for _, tx := range blockTxns { if err := block.AddTransaction(tx.MsgTx()); err != nil { diff --git a/integration/rpctest/rpc_harness.go b/integration/rpctest/rpc_harness.go index 1d1eaefa..17603aa7 100644 --- a/integration/rpctest/rpc_harness.go +++ b/integration/rpctest/rpc_harness.go @@ -256,11 +256,11 @@ func (h *Harness) SetUp(createTestChain bool, numMatureOutputs uint32) error { return err } + numToGenerate := uint32(0) // Create a test chain with the desired number of mature coinbase // outputs. if createTestChain && numMatureOutputs != 0 { - numToGenerate := (uint32(h.ActiveNet.CoinbaseMaturity) + - numMatureOutputs) + numToGenerate = uint32(h.ActiveNet.CoinbaseMaturity) + numMatureOutputs _, err := h.Client.Generate(numToGenerate) if err != nil { return err @@ -273,6 +273,9 @@ func (h *Harness) SetUp(createTestChain bool, numMatureOutputs uint32) error { if err != nil { return err } + if numToGenerate > 0 && uint32(height) < numToGenerate { + return fmt.Errorf("failed to generate this many blocks: %d", numToGenerate) + } ticker := time.NewTicker(time.Millisecond * 100) for range ticker.C { walletHeight := h.wallet.SyncedHeight() diff --git a/integration/rpctest/rpc_harness_test.go b/integration/rpctest/rpc_harness_test.go index de9db318..bfb3ceb1 100644 --- a/integration/rpctest/rpc_harness_test.go +++ b/integration/rpctest/rpc_harness_test.go @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. // This file is ignored during the regular tests due to the following build tag. +//go:build rpctest // +build rpctest package rpctest @@ -63,7 +64,7 @@ func testSendOutputs(r *Harness, t *testing.T) { // First, generate a small spend which will require only a single // input. - txid := genSpend(btcutil.Amount(5 * btcutil.SatoshiPerBitcoin)) + txid := genSpend(btcutil.Amount(btcutil.SatoshiPerBitcoin)) // Generate a single block, the transaction the wallet created should // be found in this block. @@ -75,7 +76,7 @@ func testSendOutputs(r *Harness, t *testing.T) { // Next, generate a spend much greater than the block reward. This // transaction should also have been mined properly. - txid = genSpend(btcutil.Amount(500 * btcutil.SatoshiPerBitcoin)) + txid = genSpend(btcutil.Amount(10 * btcutil.SatoshiPerBitcoin)) blockHashes, err = r.Client.Generate(1) if err != nil { t.Fatalf("unable to generate single block: %v", err) @@ -105,7 +106,7 @@ func assertConnectedTo(t *testing.T, nodeA *Harness, nodeB *Harness) { func testConnectNode(r *Harness, t *testing.T) { // Create a fresh test harness. - harness, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -153,7 +154,7 @@ func testActiveHarnesses(r *Harness, t *testing.T) { numInitialHarnesses := len(ActiveHarnesses()) // Create a single test harness. - harness1, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness1, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -181,7 +182,7 @@ func testJoinMempools(r *Harness, t *testing.T) { // Create a local test harness with only the genesis block. The nodes // will be synced below so the same transaction can be sent to both // nodes without it being an orphan. - harness, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -281,7 +282,7 @@ func testJoinMempools(r *Harness, t *testing.T) { func testJoinBlocks(r *Harness, t *testing.T) { // Create a second harness with only the genesis block so it is behind // the main harness. - harness, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -335,7 +336,7 @@ func testGenerateAndSubmitBlock(r *Harness, t *testing.T) { if err != nil { t.Fatalf("unable to create script: %v", err) } - output := wire.NewTxOut(btcutil.SatoshiPerBitcoin, pkScript) + output := wire.NewTxOut(btcutil.SatoshiPerBitcoin/50, pkScript) const numTxns = 5 txns := make([]*btcutil.Tx, 0, numTxns) @@ -469,7 +470,7 @@ func testGenerateAndSubmitBlockWithCustomCoinbaseOutputs(r *Harness, func testMemWalletReorg(r *Harness, t *testing.T) { // Create a fresh harness, we'll be using the main harness to force a // re-org on this local harness. - harness, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -478,8 +479,8 @@ func testMemWalletReorg(r *Harness, t *testing.T) { } defer harness.TearDown() - // The internal wallet of this harness should now have 250 BTC. - expectedBalance := btcutil.Amount(250 * btcutil.SatoshiPerBitcoin) + // The internal wallet of this harness should now have 250 BTC, but BTC is 50x LBC per generated coin. + expectedBalance := btcutil.Amount(5 * btcutil.SatoshiPerBitcoin) walletBalance := harness.ConfirmedBalance() if expectedBalance != walletBalance { t.Fatalf("wallet balance incorrect: expected %v, got %v", @@ -520,7 +521,7 @@ func testMemWalletLockedOutputs(r *Harness, t *testing.T) { if err != nil { t.Fatalf("unable to create script: %v", err) } - outputAmt := btcutil.Amount(50 * btcutil.SatoshiPerBitcoin) + outputAmt := btcutil.Amount(btcutil.SatoshiPerBitcoin) output := wire.NewTxOut(int64(outputAmt), pkScript) tx, err := r.CreateTransaction([]*wire.TxOut{output}, 10, true) if err != nil { @@ -566,7 +567,7 @@ const ( func TestMain(m *testing.M) { var err error - mainHarness, err = New(&chaincfg.SimNetParams, nil, nil, "") + mainHarness, err = New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { fmt.Println("unable to create main harness: ", err) os.Exit(1) @@ -601,9 +602,7 @@ func TestMain(m *testing.M) { } func TestHarness(t *testing.T) { - // We should have (numMatureOutputs * 50 BTC) of mature unspendable - // outputs. - expectedBalance := btcutil.Amount(numMatureOutputs * 50 * btcutil.SatoshiPerBitcoin) + expectedBalance := btcutil.Amount(numMatureOutputs * btcutil.SatoshiPerBitcoin) harnessBalance := mainHarness.ConfirmedBalance() if harnessBalance != expectedBalance { t.Fatalf("expected wallet balance of %v instead have %v", diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index b24045ba..b4070dd7 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -1457,7 +1457,7 @@ func TestAncestorsDescendants(t *testing.T) { func TestRBF(t *testing.T) { t.Parallel() - const defaultFee = btcutil.SatoshiPerBitcoin + const defaultFee = btcutil.SatoshiPerBitcoin / 50 testCases := []struct { name string diff --git a/mempool/policy.go b/mempool/policy.go index 21899b0f..e91ce260 100644 --- a/mempool/policy.go +++ b/mempool/policy.go @@ -176,6 +176,8 @@ func checkPkScriptStandard(pkScript []byte, scriptClass txscript.ScriptClass) er // GetDustThreshold calculates the dust limit for a *wire.TxOut by taking the // size of a typical spending transaction and multiplying it by 3 to account // for the minimum dust relay fee of 3000sat/kvb. +const dustCap = math.MaxInt64 / 1001 + func GetDustThreshold(txOut *wire.TxOut) int64 { // The total serialized size consists of the output and the associated // input script to redeem it. Since there is no input script @@ -273,6 +275,9 @@ func IsDust(txOut *wire.TxOut, minRelayTxFee btcutil.Amount) bool { // // The following is equivalent to (value/totalSize) * (1/3) * 1000 // without needing to do floating point math. + if txOut.Value > dustCap { + return false + } return txOut.Value*1000/GetDustThreshold(txOut) < int64(minRelayTxFee) } diff --git a/mempool/policy_test.go b/mempool/policy_test.go index b677ab82..5e4d4ff0 100644 --- a/mempool/policy_test.go +++ b/mempool/policy_test.go @@ -48,7 +48,7 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) { { "max standard tx size with max satoshi relay fee", maxStandardTxWeight / 4, - btcutil.MaxSatoshi, + btcutil.MaxSatoshi / 100, // overflow on purpose btcutil.MaxSatoshi, }, { @@ -252,11 +252,11 @@ func TestDust(t *testing.T) { false, }, { - // Maximum int64 value causes overflow. + // Maximum int64 value causes overflow if we're not careful "maximum int64 value", wire.TxOut{Value: 1<<63 - 1, PkScript: pkScript}, 1<<63 - 1, - true, + false, }, { // Unspendable pkScript due to an invalid public key diff --git a/peer/peer_test.go b/peer/peer_test.go index 0cb9c66c..4a2a0048 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -519,7 +519,7 @@ func TestPeerListeners(t *testing.T) { { "OnBlock", wire.NewMsgBlock(wire.NewBlockHeader(1, - &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), + &chainhash.Hash{}, &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), }, { "OnInv", @@ -585,7 +585,7 @@ func TestPeerListeners(t *testing.T) { { "OnMerkleBlock", wire.NewMsgMerkleBlock(wire.NewBlockHeader(1, - &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), + &chainhash.Hash{}, &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), }, // only one version message is allowed // only one verack message is allowed diff --git a/txscript/data/script_tests.json b/txscript/data/script_tests.json index 5c054ed3..4a0717dc 100644 --- a/txscript/data/script_tests.json +++ b/txscript/data/script_tests.json @@ -232,8 +232,8 @@ ["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC", "OK"], -["1","NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], +["1","NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], ["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "OK", "Discourage NOPx flag allows OP_NOP"], @@ -446,9 +446,6 @@ ["NOP", "CHECKSEQUENCEVERIFY 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP4 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP5 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP6 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP7 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP8 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP9 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP10 1", "P2SH,STRICTENC", "OK"], @@ -857,8 +854,8 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["1", "NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["1", "NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], ["Ensure 100% coverage of discouraged NOPS"], ["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], @@ -866,9 +863,6 @@ ["1", "CHECKSEQUENCEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], @@ -957,16 +951,6 @@ ["NOP", "HASH160", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], ["NOP", "HASH256", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", -"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", -"P2SH,STRICTENC", -"PUSH_SIZE", -">520 byte push"], -["0", -"IF 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ENDIF 1", -"P2SH,STRICTENC", -"PUSH_SIZE", -">520 byte push in non-executed IF branch"], ["1", "0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", "P2SH,STRICTENC", @@ -987,11 +971,6 @@ "P2SH,STRICTENC", "STACK_SIZE", ">1,000 stack+altstack size"], -["NOP", -"0 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", -"P2SH,STRICTENC", -"SCRIPT_SIZE", -"10,001-byte scriptPubKey"], ["NOP1","NOP10", "P2SH,STRICTENC", "EVAL_FALSE"], @@ -1786,28 +1765,28 @@ "2-of-2 with two identical keys and sigs pushed using OP_DUP" ], [ - "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP4 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "", "OK", "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY" ], [ - "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 NOP8", + "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 NOP4", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "", "OK", "P2PK with non-push scriptSig but with P2SH validation" ], [ - "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP4 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "P2SH", "SIG_PUSHONLY", "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY" ], [ - "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP4 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "SIGPUSHONLY", "SIG_PUSHONLY", diff --git a/txscript/data/tx_invalid.json b/txscript/data/tx_invalid.json index db465109..393d447b 100644 --- a/txscript/data/tx_invalid.json +++ b/txscript/data/tx_invalid.json @@ -275,10 +275,6 @@ ["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], "0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151540b00000000000001510002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], -["Witness with a push of 521 bytes"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349", 1000]], -"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015102fd0902000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002755100000000", "P2SH,WITNESS"], - ["Witness with unknown version which push false on the stack should be invalid (even without DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x02 0x0000", 2000]], "0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015101010100000000", "P2SH,WITNESS"], diff --git a/txscript/example_test.go b/txscript/example_test.go index 82a11799..6f9dc16b 100644 --- a/txscript/example_test.go +++ b/txscript/example_test.go @@ -25,7 +25,7 @@ func ExamplePayToAddrScript() { // which is useful to ensure the accuracy of the address and determine // the address type. It is also required for the upcoming call to // PayToAddrScript. - addressStr := "12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV" + addressStr := "bHW58d37s1hBjj3wPBkn5zpCX3F8ZW3uWf" address, err := btcutil.DecodeAddress(addressStr, &chaincfg.MainNetParams) if err != nil { fmt.Println(err) @@ -48,8 +48,8 @@ func ExamplePayToAddrScript() { fmt.Println("Script Disassembly:", disasm) // Output: - // Script Hex: 76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac - // Script Disassembly: OP_DUP OP_HASH160 128004ff2fcaf13b2b91eb654b1dc2b674f7ec61 OP_EQUALVERIFY OP_CHECKSIG + // Script Hex: 76a914345991dbf57bfb014b87006acdfafbfc5fe8292f88ac + // Script Disassembly: OP_DUP OP_HASH160 345991dbf57bfb014b87006acdfafbfc5fe8292f OP_EQUALVERIFY OP_CHECKSIG } // This example demonstrates extracting information from a standard public key @@ -76,7 +76,7 @@ func ExampleExtractPkScriptAddrs() { // Output: // Script Class: pubkeyhash - // Addresses: [12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV] + // Addresses: [bER6Ddq6YfRKDJDmmdeaqrP8XHmDJcYSJQ] // Required Signatures: 1 } diff --git a/txscript/opcode_test.go b/txscript/opcode_test.go index 91263c21..86d08838 100644 --- a/txscript/opcode_test.go +++ b/txscript/opcode_test.go @@ -117,6 +117,12 @@ func TestOpcodeDisasm(t *testing.T) { case 0xb2: // OP_NOP3 is an alias of OP_CHECKSEQUENCEVERIFY expectedStr = "OP_CHECKSEQUENCEVERIFY" + case OP_CLAIMNAME: + expectedStr = "OP_CLAIMNAME" + case OP_SUPPORTCLAIM: + expectedStr = "OP_SUPPORTCLAIM" + case OP_UPDATECLAIM: + expectedStr = "OP_UPDATECLAIM" default: val := byte(opcodeVal - (0xb0 - 1)) expectedStr = "OP_NOP" + strconv.Itoa(int(val)) @@ -184,6 +190,12 @@ func TestOpcodeDisasm(t *testing.T) { case 0xb2: // OP_NOP3 is an alias of OP_CHECKSEQUENCEVERIFY expectedStr = "OP_CHECKSEQUENCEVERIFY" + case OP_CLAIMNAME: + expectedStr = "OP_CLAIMNAME" + case OP_SUPPORTCLAIM: + expectedStr = "OP_SUPPORTCLAIM" + case OP_UPDATECLAIM: + expectedStr = "OP_UPDATECLAIM" default: val := byte(opcodeVal - (0xb0 - 1)) expectedStr = "OP_NOP" + strconv.Itoa(int(val)) diff --git a/txscript/scriptbuilder_test.go b/txscript/scriptbuilder_test.go index 89f2b861..0bb67aa1 100644 --- a/txscript/scriptbuilder_test.go +++ b/txscript/scriptbuilder_test.go @@ -220,19 +220,10 @@ func TestScriptBuilderAddData(t *testing.T) { expected: append([]byte{OP_PUSHDATA2, 0, 1}, bytes.Repeat([]byte{0x49}, 256)...), }, { - name: "push data len 520", + name: "push data len 520", // bitcoin has a 520 byte cap, but lbry is 20k data: bytes.Repeat([]byte{0x49}, 520), expected: append([]byte{OP_PUSHDATA2, 0x08, 0x02}, bytes.Repeat([]byte{0x49}, 520)...), }, - - // BIP0062: OP_PUSHDATA4 can never be used, as pushes over 520 - // bytes are not allowed, and those below can be done using - // other operators. - { - name: "push data len 521", - data: bytes.Repeat([]byte{0x49}, 521), - expected: nil, - }, { name: "push data len 32767 (canonical)", data: bytes.Repeat([]byte{0x49}, 32767), diff --git a/wire/bench_test.go b/wire/bench_test.go index 1eb6c413..42caac86 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -419,7 +419,7 @@ func BenchmarkDecodeHeaders(b *testing.B) { if err != nil { b.Fatalf("NewHashFromStr: unexpected error: %v", err) } - m.AddBlockHeader(NewBlockHeader(1, hash, hash, 0, uint32(i))) + m.AddBlockHeader(NewBlockHeader(1, hash, hash, hash, 0, uint32(i))) } // Serialize it so the bytes are available to test the decode below. @@ -565,7 +565,7 @@ func BenchmarkDecodeMerkleBlock(b *testing.B) { if err != nil { b.Fatalf("NewHashFromStr: unexpected error: %v", err) } - m.Header = *NewBlockHeader(1, hash, hash, 0, uint32(10000)) + m.Header = *NewBlockHeader(1, hash, hash, hash, 0, uint32(10000)) for i := 0; i < 105; i++ { hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i)) if err != nil { diff --git a/wire/blockheader.go b/wire/blockheader.go index 372b7b46..4019c179 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -45,7 +45,7 @@ type BlockHeader struct { // blockHeaderLen is a constant that represents the number of bytes for a block // header. -const blockHeaderLen = 80 +const blockHeaderLen = 112 // BlockHash computes the block identifier hash for the given block header. func (h *BlockHeader) BlockHash() chainhash.Hash { diff --git a/wire/blockheader_test.go b/wire/blockheader_test.go index fef06967..66e37d6c 100644 --- a/wire/blockheader_test.go +++ b/wire/blockheader_test.go @@ -24,7 +24,7 @@ func TestBlockHeader(t *testing.T) { hash := mainNetGenesisHash merkleHash := mainNetGenesisMerkleRoot bits := uint32(0x1d00ffff) - bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bh := NewBlockHeader(1, &hash, &merkleHash, &merkleHash, bits, nonce) // Ensure we get the same data back out. if !bh.PrevBlock.IsEqual(&hash) { @@ -57,10 +57,12 @@ func TestBlockHeaderWire(t *testing.T) { Version: 1, PrevBlock: mainNetGenesisHash, MerkleRoot: mainNetGenesisMerkleRoot, + ClaimTrie: mainNetGenesisMerkleRoot, Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Bits: bits, Nonce: nonce, } + baseBlockHdr.ClaimTrie[0] = 0x33 // baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr. baseBlockHdrEncoded := []byte{ @@ -73,6 +75,10 @@ func TestBlockHeaderWire(t *testing.T) { 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot + 0x33, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, + 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, + 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // ClaimTrie 0x29, 0xab, 0x5f, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0xf3, 0xe0, 0x01, 0x00, // Nonce @@ -196,10 +202,12 @@ func TestBlockHeaderSerialize(t *testing.T) { Version: 1, PrevBlock: mainNetGenesisHash, MerkleRoot: mainNetGenesisMerkleRoot, + ClaimTrie: mainNetGenesisMerkleRoot, Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Bits: bits, Nonce: nonce, } + baseBlockHdr.ClaimTrie[0] = 0x33 // baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr. baseBlockHdrEncoded := []byte{ @@ -212,6 +220,10 @@ func TestBlockHeaderSerialize(t *testing.T) { 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot + 0x33, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, + 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, + 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // ClaimTrie 0x29, 0xab, 0x5f, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0xf3, 0xe0, 0x01, 0x00, // Nonce diff --git a/wire/common_test.go b/wire/common_test.go index d71cc9c9..f76cc4db 100644 --- a/wire/common_test.go +++ b/wire/common_test.go @@ -127,7 +127,7 @@ func TestElementWire(t *testing.T) { }, { MainNet, - []byte{0xf9, 0xbe, 0xb4, 0xd9}, + []byte{0xfa, 0xe4, 0xaa, 0xf1}, }, // Type not supported by the "fast" path and requires reflection. { diff --git a/wire/message_test.go b/wire/message_test.go index b2ae3f63..65754b41 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -66,7 +66,7 @@ func TestMessage(t *testing.T) { msgFilterAdd := NewMsgFilterAdd([]byte{0x01}) msgFilterClear := NewMsgFilterClear() msgFilterLoad := NewMsgFilterLoad([]byte{0x01}, 10, 0, BloomUpdateNone) - bh := NewBlockHeader(1, &chainhash.Hash{}, &chainhash.Hash{}, 0, 0) + bh := NewBlockHeader(1, &chainhash.Hash{}, &chainhash.Hash{}, &chainhash.Hash{}, 0, 0) msgMerkleBlock := NewMsgMerkleBlock(bh) msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block") msgGetCFilters := NewMsgGetCFilters(GCSFilterRegular, 0, &chainhash.Hash{}) @@ -89,7 +89,7 @@ func TestMessage(t *testing.T) { {msgGetAddr, msgGetAddr, pver, MainNet, 24}, {msgAddr, msgAddr, pver, MainNet, 25}, {msgGetBlocks, msgGetBlocks, pver, MainNet, 61}, - {msgBlock, msgBlock, pver, MainNet, 239}, + {msgBlock, msgBlock, pver, MainNet, 271}, {msgInv, msgInv, pver, MainNet, 25}, {msgGetData, msgGetData, pver, MainNet, 25}, {msgNotFound, msgNotFound, pver, MainNet, 25}, @@ -103,7 +103,7 @@ func TestMessage(t *testing.T) { {msgFilterAdd, msgFilterAdd, pver, MainNet, 26}, {msgFilterClear, msgFilterClear, pver, MainNet, 24}, {msgFilterLoad, msgFilterLoad, pver, MainNet, 35}, - {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 110}, + {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 142}, {msgReject, msgReject, pver, MainNet, 79}, {msgGetCFilters, msgGetCFilters, pver, MainNet, 61}, {msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61}, diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index 407e3b2d..f906892a 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -24,7 +24,7 @@ func TestBlock(t *testing.T) { merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce - bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) + bh := NewBlockHeader(1, prevHash, merkleHash, merkleHash, bits, nonce) // Ensure the command is expected value. wantCmd := "block" @@ -92,7 +92,7 @@ func TestBlockTxHashes(t *testing.T) { // TestBlockHash tests the ability to generate the hash of a block accurately. func TestBlockHash(t *testing.T) { // Block 1 hash. - hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048" + hashStr := "a6b9bbfdd71af02426d2fc8131cfb843a27946e1f660a9dbca7556a0bb4a8ce2" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewHashFromStr: %v", err) @@ -224,15 +224,15 @@ func TestBlockWireErrors(t *testing.T) { // Force error in merkle root. {&blockOne, blockOneBytes, pver, BaseEncoding, 36, io.ErrShortWrite, io.EOF}, // Force error in timestamp. - {&blockOne, blockOneBytes, pver, BaseEncoding, 68, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 68 + 32, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - {&blockOne, blockOneBytes, pver, BaseEncoding, 72, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 72 + 32, io.ErrShortWrite, io.EOF}, // Force error in header nonce. - {&blockOne, blockOneBytes, pver, BaseEncoding, 76, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 76 + 32, io.ErrShortWrite, io.EOF}, // Force error in transaction count. - {&blockOne, blockOneBytes, pver, BaseEncoding, 80, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 80 + 32, io.ErrShortWrite, io.EOF}, // Force error in transactions. - {&blockOne, blockOneBytes, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 81 + 32, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -342,15 +342,15 @@ func TestBlockSerializeErrors(t *testing.T) { // Force error in merkle root. {&blockOne, blockOneBytes, 36, io.ErrShortWrite, io.EOF}, // Force error in timestamp. - {&blockOne, blockOneBytes, 68, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 68 + 32, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - {&blockOne, blockOneBytes, 72, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 72 + 32, io.ErrShortWrite, io.EOF}, // Force error in header nonce. - {&blockOne, blockOneBytes, 76, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 76 + 32, io.ErrShortWrite, io.EOF}, // Force error in transaction count. - {&blockOne, blockOneBytes, 80, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 80 + 32, io.ErrShortWrite, io.EOF}, // Force error in transactions. - {&blockOne, blockOneBytes, 81, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 81 + 32, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -413,6 +413,10 @@ func TestBlockOverflowErrors(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -465,7 +469,7 @@ func TestBlockSerializeSize(t *testing.T) { size int // Expected serialized size }{ // Block with no transactions. - {noTxBlock, 81}, + {noTxBlock, 81 + 32}, // First block in the mainnet block chain. {&blockOne, len(blockOneBytes)}, @@ -498,6 +502,12 @@ var blockOne = MsgBlock{ 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, }), + ClaimTrie: chainhash.Hash([chainhash.HashSize]byte{ + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, + }), Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST Bits: 0x1d00ffff, // 486604799 @@ -552,6 +562,10 @@ var blockOneBytes = []byte{ 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -585,5 +599,5 @@ var blockOneBytes = []byte{ // Transaction location information for block one transactions. var blockOneTxLocs = []TxLoc{ - {TxStart: 81, TxLen: 134}, + {TxStart: 81 + 32, TxLen: 134}, } diff --git a/wire/msgheaders_test.go b/wire/msgheaders_test.go index 9b94545b..0501bc7e 100644 --- a/wire/msgheaders_test.go +++ b/wire/msgheaders_test.go @@ -28,7 +28,7 @@ func TestHeaders(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num headers (varInt) + max allowed headers (header length + 1 byte // for the number of transactions which is always 0). - wantPayload := uint32(162009) + wantPayload := uint32(226009) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ @@ -64,7 +64,7 @@ func TestHeadersWire(t *testing.T) { merkleHash := blockOne.Header.MerkleRoot bits := uint32(0x1d00ffff) nonce := uint32(0x9962e301) - bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bh := NewBlockHeader(1, &hash, &merkleHash, &merkleHash, bits, nonce) bh.Version = blockOne.Header.Version bh.Timestamp = blockOne.Header.Timestamp @@ -88,6 +88,10 @@ func TestHeadersWire(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -232,7 +236,7 @@ func TestHeadersWireErrors(t *testing.T) { merkleHash := blockOne.Header.MerkleRoot bits := uint32(0x1d00ffff) nonce := uint32(0x9962e301) - bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bh := NewBlockHeader(1, &hash, &merkleHash, &merkleHash, bits, nonce) bh.Version = blockOne.Header.Version bh.Timestamp = blockOne.Header.Timestamp @@ -250,6 +254,10 @@ func TestHeadersWireErrors(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -269,7 +277,7 @@ func TestHeadersWireErrors(t *testing.T) { // Intentionally invalid block header that has a transaction count used // to force errors. - bhTrans := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bhTrans := NewBlockHeader(1, &hash, &merkleHash, &merkleHash, bits, nonce) bhTrans.Version = blockOne.Header.Version bhTrans.Timestamp = blockOne.Header.Timestamp @@ -286,6 +294,10 @@ func TestHeadersWireErrors(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -309,7 +321,7 @@ func TestHeadersWireErrors(t *testing.T) { // Force error with greater than max headers. {maxHeaders, maxHeadersEncoded, pver, BaseEncoding, 3, wireErr, wireErr}, // Force error with number of transactions. - {transHeader, transHeaderEncoded, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF}, + {transHeader, transHeaderEncoded, pver, BaseEncoding, 81 + 32, io.ErrShortWrite, io.EOF}, // Force error with included transactions. {transHeader, transHeaderEncoded, pver, BaseEncoding, len(transHeaderEncoded), nil, wireErr}, } diff --git a/wire/msgmerkleblock_test.go b/wire/msgmerkleblock_test.go index 31f01a47..9f7a8403 100644 --- a/wire/msgmerkleblock_test.go +++ b/wire/msgmerkleblock_test.go @@ -26,7 +26,7 @@ func TestMerkleBlock(t *testing.T) { merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce - bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) + bh := NewBlockHeader(1, prevHash, merkleHash, merkleHash, bits, nonce) // Ensure the command is expected value. wantCmd := "merkleblock" @@ -118,7 +118,7 @@ func TestMerkleBlockCrossProtocol(t *testing.T) { merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce - bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) + bh := NewBlockHeader(1, prevHash, merkleHash, merkleHash, bits, nonce) msg := NewMsgMerkleBlock(bh) @@ -229,48 +229,48 @@ func TestMerkleBlockWireErrors(t *testing.T) { }, // Force error in timestamp. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 68, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 68 + 32, io.ErrShortWrite, io.EOF, }, // Force error in difficulty bits. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 72, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 72 + 32, io.ErrShortWrite, io.EOF, }, // Force error in header nonce. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 76, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 76 + 32, io.ErrShortWrite, io.EOF, }, // Force error in transaction count. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 80, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 80 + 32, io.ErrShortWrite, io.EOF, }, // Force error in num hashes. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 84, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 84 + 32, io.ErrShortWrite, io.EOF, }, // Force error in hashes. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 85, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 85 + 32, io.ErrShortWrite, io.EOF, }, // Force error in num flag bytes. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 117, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 117 + 32, io.ErrShortWrite, io.EOF, }, // Force error in flag bytes. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 118, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 118 + 32, io.ErrShortWrite, io.EOF, }, // Force error due to unsupported protocol version. { &merkleBlockOne, merkleBlockOneBytes, pverNoMerkleBlock, - BaseEncoding, 119, wireErr, wireErr, + BaseEncoding, 119 + 32, wireErr, wireErr, }, } @@ -331,7 +331,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) { // allowed tx hashes. var buf bytes.Buffer WriteVarInt(&buf, pver, maxTxPerBlock+1) - numHashesOffset := 84 + numHashesOffset := 84 + 32 exceedMaxHashes := make([]byte, numHashesOffset) copy(exceedMaxHashes, merkleBlockOneBytes[:numHashesOffset]) exceedMaxHashes = append(exceedMaxHashes, buf.Bytes()...) @@ -340,7 +340,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) { // allowed flag bytes. buf.Reset() WriteVarInt(&buf, pver, maxFlagsPerMerkleBlock+1) - numFlagBytesOffset := 117 + numFlagBytesOffset := 117 + 32 exceedMaxFlagBytes := make([]byte, numFlagBytesOffset) copy(exceedMaxFlagBytes, merkleBlockOneBytes[:numFlagBytesOffset]) exceedMaxFlagBytes = append(exceedMaxFlagBytes, buf.Bytes()...) @@ -388,6 +388,12 @@ var merkleBlockOne = MsgMerkleBlock{ 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, }), + ClaimTrie: chainhash.Hash([chainhash.HashSize]byte{ + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, + }), Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST Bits: 0x1d00ffff, // 486604799 Nonce: 0x9962e301, // 2573394689 @@ -416,6 +422,10 @@ var merkleBlockOneBytes = []byte{ 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce -- 2.45.2 From a09c895f494b2f82bae9cf59d435eeb3f81503e8 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 26 Nov 2021 11:36:53 -0500 Subject: [PATCH 156/459] [lbry] test: don't remove old regression DB --- lbcd.go | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/lbcd.go b/lbcd.go index ec6ef086..e47efdb8 100644 --- a/lbcd.go +++ b/lbcd.go @@ -183,34 +183,6 @@ func btcdMain(serverChan chan<- *server) error { return nil } -// removeRegressionDB removes the existing regression test database if running -// in regression test mode and it already exists. -func removeRegressionDB(dbPath string) error { - // Don't do anything if not in regression test mode. - if !cfg.RegressionTest { - return nil - } - - // Remove the old regression test database if it already exists. - fi, err := os.Stat(dbPath) - if err == nil { - btcdLog.Infof("Removing regression test database from '%s'", dbPath) - if fi.IsDir() { - err := os.RemoveAll(dbPath) - if err != nil { - return err - } - } else { - err := os.Remove(dbPath) - if err != nil { - return err - } - } - } - - return nil -} - // dbPath returns the path to the block database given a database type. func blockDbPath(dbType string) string { // The database name is based on the database type. @@ -277,11 +249,6 @@ func loadBlockDB() (database.DB, error) { // The database name is based on the database type. dbPath := blockDbPath(cfg.DbType) - - // The regression test is special in that it needs a clean database for - // each run, so remove it now if it already exists. - removeRegressionDB(dbPath) - btcdLog.Infof("Loading block database from '%s'", dbPath) db, err := database.Open(cfg.DbType, dbPath, activeNetParams.Net) if err != nil { -- 2.45.2 From 4e63bef33b31279ddb96f3e618daa21378fc2eb8 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 19 Aug 2021 14:41:48 -0400 Subject: [PATCH 157/459] [lbry] docs: update docs for LBRY Co-authored-by: Roy Lee --- CHANGES | 1230 ----------------- LICENSE | 1 + README.md | 168 +-- blockchain/README.md | 68 +- blockchain/fullblocktests/README.md | 6 +- blockchain/indexers/README.md | 6 +- btcec/README.md | 61 +- btcjson/README.md | 64 +- chaincfg/README.md | 81 +- chaincfg/chainhash/README.md | 6 +- connmgr/README.md | 20 +- database/README.md | 30 +- database/ffldb/README.md | 4 +- database/internal/treap/README.md | 4 +- doc.go | 6 +- docs/code_contribution_guidelines.md | 319 ----- docs/configuration.md | 110 +- docs/configuring_tor.md | 34 +- docs/contact.md | 15 - docs/controlling.md | 12 +- docs/developer_resources.md | 37 - docs/index.md | 48 +- docs/installation.md | 76 - docs/json_rpc_api.md | 1160 ++++++++-------- docs/mining.md | 16 +- docs/table_of_content.md | 13 - docs/update.md | 8 - docs/using_docker.md | 160 --- docs/wallet.md | 5 - integration/README.md | 7 +- integration/rpctest/README.md | 14 - mempool/README.md | 18 - mining/README.md | 15 +- mining/cpuminer/README.md | 6 +- netsync/README.md | 12 - peer/README.md | 23 +- release/README.md | 181 --- rpcclient/README.md | 37 +- rpcclient/examples/bitcoincorehttp/README.md | 4 +- .../examples/bitcoincorehttpbulk/README.md | 4 +- rpcclient/examples/btcdwebsockets/README.md | 4 +- .../examples/btcwalletwebsockets/README.md | 4 +- rpcclient/examples/customcommand/README.md | 4 +- rpcclient/examples/customcommand/main.go | 4 +- sample-btcd.conf => sample-lbcd.conf | 44 +- txscript/README.md | 58 +- wire/README.md | 43 +- 47 files changed, 836 insertions(+), 3414 deletions(-) delete mode 100644 CHANGES delete mode 100644 docs/code_contribution_guidelines.md delete mode 100644 docs/contact.md delete mode 100644 docs/developer_resources.md delete mode 100644 docs/installation.md delete mode 100644 docs/table_of_content.md delete mode 100644 docs/update.md delete mode 100644 docs/using_docker.md delete mode 100644 docs/wallet.md delete mode 100644 release/README.md rename sample-btcd.conf => sample-lbcd.conf (94%) diff --git a/CHANGES b/CHANGES deleted file mode 100644 index fd59a886..00000000 --- a/CHANGES +++ /dev/null @@ -1,1230 +0,0 @@ -============================================================================ -User visible changes for btcd - A full-node bitcoin implementation written in Go -============================================================================ - -Changes in 0.22.0 (Tue Jun 01 2021) - - Protocol and network-related changes: - - Add support for witness tx and block in notfound msg (#1625) - - Add support for receiving sendaddrv2 messages from a peer (#1670) - - Fix bug in peer package causing last block height to go backwards - (#1606) - - Add chain parameters for connecting to the public Signet network - (#1692, #1718) - - Crypto changes: - - Fix bug causing panic due to bad R and S signature components in - btcec.RecoverCompact (#1691) - - Set the name (secp256k1) in the CurveParams of the S256 curve - (#1565) - - Notable developer-related package changes: - - Remove unknown block version warning in the blockchain package, - due to false positives triggered by AsicBoost (#1463) - - Add chaincfg.RegisterHDKeyID function to populate HD key ID pairs - (#1617) - - Add new method mining.AddWitnessCommitment to add the witness - commitment as an OP_RETURN output within the coinbase transaction. - (#1716) - - RPC changes: - - Support Batch JSON-RPC in rpcclient and server (#1583) - - Add rpcclient method to invoke getdescriptorinfo JSON-RPC command - (#1578) - - Update the rpcserver handler for validateaddress JSON-RPC command to - have parity with the bitcoind 0.20.0 interface (#1613) - - Add rpcclient method to invoke getblockfilter JSON-RPC command - (#1579) - - Add signmessagewithprivkey JSON-RPC command in rpcserver (#1585) - - Add rpcclient method to invoke importmulti JSON-RPC command (#1579) - - Add watchOnly argument in rpcclient method to invoke - listtransactions JSON-RPC command (#1628) - - Update btcjson.ListTransactionsResult for compatibility with Bitcoin - Core 0.20.0 (#1626) - - Support nullable optional JSON-RPC parameters (#1594) - - Add rpcclient and server method to invoke getnodeaddresses JSON-RPC - command (#1590) - - Add rpcclient methods to invoke PSBT JSON-RPC commands (#1596) - - Add rpcclient method to invoke listsinceblock with the - include_watchonly parameter enabled (#1451) - - Add rpcclient method to invoke deriveaddresses JSON-RPC command - (#1631) - - Add rpcclient method to invoke getblocktemplate JSON-RPC command - (#1629) - - Add rpcclient method to invoke getaddressinfo JSON-RPC command - (#1633) - - Add rpcclient method to invoke getwalletinfo JSON-RPC command - (#1638) - - Fix error message in rpcserver when an unknown RPC command is - encountered (#1695) - - Fix error message returned by estimatefee when the number of blocks - exceeds the max depth (#1678) - - Update btcjson.GetBlockChainInfoResult to include new fields in - Bitcoin Core (#1676) - - Add ExtraHeaders in rpcclient.ConnConfig struct (#1669) - - Fix bitcoind compatibility issue with the sendrawtransaction - JSON-RPC command (#1659) - - Add new JSON-RPC errors to btcjson package, and documented them - (#1648) - - Add rpcclient method to invoke createwallet JSON-RPC command - (#1650) - - Add rpcclient methods to invoke backupwallet, dumpwallet, loadwallet - and unloadwallet JSON-RPC commands (#1645) - - Fix unmarshalling error in getmininginfo JSON-RPC command, for valid - integers in scientific notation (#1644) - - Add rpcclient method to invoke gettxoutsetinfo JSON-RPC command - (#1641) - - Add rpcclient method to invoke signrawtransactionwithwallet JSON-RPC - command (#1642) - - Add txid to getblocktemplate response of rpcserver (#1639) - - Fix monetary unit used in createrawtransaction JSON-RPC command in - rpcserver (#1614) - - Add rawtx field to btcjson.GetBlockVerboseTxResult to provide - backwards compatibility with older versions of Bitcoin Core (#1677) - - Misc changes: - - Update btcutil dependency (#1704) - - Add Dockerfile to build and run btcd on Docker (#1465) - - Rework documentation and publish on https://btcd.readthedocs.io (#1468) - - Add support for Go 1.15 (#1619) - - Add Go 1.14 as the minimum supported version of Golang (#1621) - - Contributors (alphabetical order): - - 10gic - - Andrew Tugarinov - - Anirudha Bose - - Appelberg-s - - Armando Ochoa - - Aurèle Oulès - - Calvin Kim - - Christian Lehmann - - Conner Fromknecht - - Dan Cline - - David Mazary - - Elliott Minns - - Federico Bond - - Friedger Müffke - - Gustavo Chain - - Hanjun Kim - - Henry Fisher - - Iskander Sharipov - - Jake Sylvestre - - Johan T. Halseth - - John C. Vernaleo - - Liran Sharir - - Mikael Lindlof - - Olaoluwa Osuntokun - - Oliver Gugger - - Rjected - - Steven Kreuzer - - Torkel Rogstad - - Tristyn - - Victor Lavaud - - Vinayak Borkar - - Wilmer Paulino - - Yaacov Akiba Slama - - ebiiim - - ipriver - - wakiyamap - - yyforyongyu - -Changes in 0.21.0 (Thu Aug 27 2020) - - Network-related changes: - - Handle notfound messages from peers in netsync package (#1603) - - RPC changes: - - Add compatibility for getblock RPC changes in bitcoind 0.15.0 (#1529) - - Add new optional Params field to rpcclient.ConnConfig (#1467) - - Add new error code ErrRPCInWarmup in btcjson (#1541) - - Add compatibility for changes to getmempoolentry response in bitcoind - 0.19.0 (#1524) - - Add rpcclient methods for estimatesmartfee and generatetoaddress - commands (#1500) - - Add rpcclient method for getblockstats command (#1500) - - Parse serialized transaction from createrawtransaction command using - both segwit, and legacy format (#1502) - - Support cookie-based authentication in rpcclient (#1460) - - Add rpcclient method for getchaintxstats command (#1571) - - Add rpcclient method for fundrawtransaction command (#1553) - - Add rpcclient method for getbalances command (#1595) - - Add new method rpcclient.GetTransactionWatchOnly (#1592) - - Crypto changes: - - Fix panic in fieldVal.SetByteSlice when called with large values, and - improve the method to be 35% faster (#1602) - - btcctl changes: - - Add -regtest mode to btcctl (#1556) - - Misc changes: - - Fix a bug due to a deadlock in connmgr's dynamic ban scoring (#1509) - - Add blockchain.NewUtxoEntry() to directly create entries for - UtxoViewpoint (#1588) - - Replace LRU cache implementation in peer package with a generic one - from decred/dcrd (#1599) - - Contributors (alphabetical order): - - Anirudha Bose - - Antonin Hildebrand - - Dan Cline - - Daniel McNally - - David Hill - - Federico Bond - - George Tankersley - - Henry - - Henry Harder - - Iskander Sharipov - - Ivan Kuznetsov - - Jake Sylvestre - - Javed Khan - - JeremyRand - - Jin - - John C. Vernaleo - - Kulpreet Singh - - Mikael Lindlof - - Murray Nesbitt - - Nisen - - Olaoluwa Osuntokun - - Oliver Gugger - - Steven Roose - - Torkel Rogstad - - Tyler Chambers - - Wilmer Paulino - - Yash Bhutwala - - adiabat - - jalavosus - - mohanson - - qqjettkgjzhxmwj - - qshuai - - shuai.qi - - tpkeeper - -Changes in v0.20.1 (Wed Nov 13 2019) - - RPC changes: - - Add compatibility for bitcoind v0.19.0 in rpcclient and btcjson - packages (#1484) - - Contributors (alphabetical order): - - Eugene Zeigel - - Olaoluwa Osuntokun - - Wilmer Paulino - -Changes in v0.20.0 (Tue Oct 15 2019) - - Significant changes made since 0.12.0. See git log or refer to release - notes on GitHub for full details. - - Contributors (alphabetical order): - - Albert Puigsech Galicia - - Alex Akselrod - - Alex Bosworth - - Alex Manuskin - - Alok Menghrajani - - Anatoli Babenia - - Andy Weidenbaum - - Calvin McAnarney - - Chris Martin - - Chris Pacia - - Chris Shepherd - - Conner Fromknecht - - Craig Sturdy - - Cédric Félizard - - Daniel Krawisz - - Daniel Martí - - Daniel McNally - - Dario Nieuwenhuis - - Dave Collins - - David Hill - - David de Kloet - - GeertJohan - - Grace Noah - - Gregory Trubetskoy - - Hector Jusforgues - - Iskander (Alex) Sharipov - - Janus Troelsen - - Jasper - - Javed Khan - - Jeremiah Goyette - - Jim Posen - - Jimmy Song - - Johan T. Halseth - - John C. Vernaleo - - Jonathan Gillham - - Josh Rickmar - - Jon Underwood - - Jonathan Zeppettini - - Jouke Hofman - - Julian Meyer - - Kai - - Kamil Slowikowski - - Kefkius - - Leonardo Lazzaro - - Marco Peereboom - - Marko Bencun - - Mawueli Kofi Adzoe - - Michail Kargakis - - Mitchell Paull - - Nathan Bass - - Nicola 'tekNico' Larosa - - Olaoluwa Osuntokun - - Pedro Martelletto - - Ricardo Velhote - - Roei Erez - - Ruben de Vries - - Rune T. Aune - - Sad Pencil - - Shuai Qi - - Steven Roose - - Tadge Dryja - - Tibor Bősze - - Tomás Senart - - Tzu-Jung Lee - - Vadym Popov - - Waldir Pimenta - - Wilmer Paulino - - benma - - danda - - dskloet - - esemplastic - - jadeblaquiere - - nakagawa - - preminem - - qshuai - -Changes in 0.12.0 (Fri Nov 20 2015) - - Protocol and network related changes: - - Add a new checkpoint at block height 382320 (#555) - - Implement BIP0065 which includes support for version 4 blocks, a new - consensus opcode (OP_CHECKLOCKTIMEVERIFY) that enforces transaction - lock times, and a double-threshold switchover mechanism (#535, #459, - #455) - - Implement BIP0111 which provides a new bloom filter service flag and - hence provides support for protocol version 70011 (#499) - - Add a new parameter --nopeerbloomfilters to allow disabling bloom - filter support (#499) - - Reject non-canonically encoded variable length integers (#507) - - Add mainnet peer discovery DNS seed (seed.bitcoin.jonasschnelli.ch) - (#496) - - Correct reconnect handling for persistent peers (#463, #464) - - Ignore requests for block headers if not fully synced (#444) - - Add CLI support for specifying the zone id on IPv6 addresses (#538) - - Fix a couple of issues where the initial block sync could stall (#518, - #229, #486) - - Fix an issue which prevented the --onion option from working as - intended (#446) - - Transaction relay (memory pool) changes: - - Require transactions to only include signatures encoded with the - canonical 'low-s' encoding (#512) - - Add a new parameter --minrelaytxfee to allow the minimum transaction - fee in BTC/kB to be overridden (#520) - - Retain memory pool transactions when they redeem another one that is - removed when a block is accepted (#539) - - Do not send reject messages for a transaction if it is valid but - causes an orphan transaction which depends on it to be determined - as invalid (#546) - - Refrain from attempting to add orphans to the memory pool multiple - times when the transaction they redeem is added (#551) - - Modify minimum transaction fee calculations to scale based on bytes - instead of full kilobyte boundaries (#521, #537) - - Implement signature cache: - - Provides a limited memory cache of validated signatures which is a - huge optimization when verifying blocks for transactions that are - already in the memory pool (#506) - - Add a new parameter '--sigcachemaxsize' which allows the size of the - new cache to be manually changed if desired (#506) - - Mining support changes: - - Notify getblocktemplate long polling clients when a block is pushed - via submitblock (#488) - - Speed up getblocktemplate by making use of the new signature cache - (#506) - - RPC changes: - - Implement getmempoolinfo command (#453) - - Implement getblockheader command (#461) - - Modify createrawtransaction command to accept a new optional parameter - 'locktime' (#529) - - Modify listunspent result to include the 'spendable' field (#440) - - Modify getinfo command to include 'errors' field (#511) - - Add timestamps to blockconnected and blockdisconnected notifications - (#450) - - Several modifications to searchrawtranscations command: - - Accept a new optional parameter 'vinextra' which causes the results - to include information about the outputs referenced by a transaction's - inputs (#485, #487) - - Skip entries in the mempool too (#495) - - Accept a new optional parameter 'reverse' to return the results in - reverse order (most recent to oldest) (#497) - - Accept a new optional parameter 'filteraddrs' which causes the - results to only include inputs and outputs which involve the - provided addresses (#516) - - Change the notification order to notify clients about mined - transactions (recvtx, redeemingtx) before the blockconnected - notification (#449) - - Update verifymessage RPC to use the standard algorithm so it is - compatible with other implementations (#515) - - Improve ping statistics by pinging on an interval (#517) - - Websocket changes: - - Implement session command which returns a per-session unique id (#500, - #503) - - btcctl utility changes: - - Add getmempoolinfo command (#453) - - Add getblockheader command (#461) - - Add getwalletinfo command (#471) - - Notable developer-related package changes: - - Introduce a new peer package which acts a common base for creating and - concurrently managing bitcoin network peers (#445) - - Various cleanup of the new peer package (#528, #531, #524, #534, - #549) - - Blocks heights now consistently use int32 everywhere (#481) - - The BlockHeader type in the wire package now provides the BtcDecode - and BtcEncode methods (#467) - - Update wire package to recognize BIP0064 (getutxo) service bit (#489) - - Export LockTimeThreshold constant from txscript package (#454) - - Export MaxDataCarrierSize constant from txscript package (#466) - - Provide new IsUnspendable function from the txscript package (#478) - - Export variable length string functions from the wire package (#514) - - Export DNS Seeds for each network from the chaincfg package (#544) - - Preliminary work towards separating the memory pool into a separate - package (#525, #548) - - Misc changes: - - Various documentation updates (#442, #462, #465, #460, #470, #473, - #505, #530, #545) - - Add installation instructions for gentoo (#542) - - Ensure an error is shown if OS limits can't be set at startup (#498) - - Tighten the standardness checks for multisig scripts (#526) - - Test coverage improvement (#468, #494, #527, #543, #550) - - Several optimizations (#457, #474, #475, #476, #508, #509) - - Minor code cleanup and refactoring (#472, #479, #482, #519, #540) - - Contributors (alphabetical order): - - Ben Echols - - Bruno Clermont - - danda - - Daniel Krawisz - - Dario Nieuwenhuis - - Dave Collins - - David Hill - - Javed Khan - - Jonathan Gillham - - Joseph Becher - - Josh Rickmar - - Justus Ranvier - - Mawuli Adzoe - - Olaoluwa Osuntokun - - Rune T. Aune - -Changes in 0.11.1 (Wed May 27 2015) - - Protocol and network related changes: - - Use correct sub-command in reject message for rejected transactions - (#436, #437) - - Add a new parameter --torisolation which forces new circuits for each - connection when using tor (#430) - - Transaction relay (memory pool) changes: - - Reduce the default number max number of allowed orphan transactions - to 1000 (#419) - - Add a new parameter --maxorphantx which allows the maximum number of - orphan transactions stored in the mempool to be specified (#419) - - RPC changes: - - Modify listtransactions result to include the 'involveswatchonly' and - 'vout' fields (#427) - - Update getrawtransaction result to omit the 'confirmations' field - when it is 0 (#420, #422) - - Update signrawtransaction result to include errors (#423) - - btcctl utility changes: - - Add gettxoutproof command (#428) - - Add verifytxoutproof command (#428) - - Notable developer-related package changes: - - The btcec package now provides the ability to perform ECDH - encryption and decryption (#375) - - The block and header validation in the blockchain package has been - split to help pave the way toward concurrent downloads (#386) - - Misc changes: - - Minor peer optimization (#433) - - Contributors (alphabetical order): - - Dave Collins - - David Hill - - Federico Bond - - Ishbir Singh - - Josh Rickmar - -Changes in 0.11.0 (Wed May 06 2015) - - Protocol and network related changes: - - **IMPORTANT: Update is required due to the following point** - - Correct a few corner cases in script handling which could result in - forking from the network on non-standard transactions (#425) - - Add a new checkpoint at block height 352940 (#418) - - Optimized script execution (#395, #400, #404, #409) - - Fix a case that could lead stalled syncs (#138, #296) - - Network address manager changes: - - Implement eclipse attack countermeasures as proposed in - http://cs-people.bu.edu/heilman/eclipse (#370, #373) - - Optional address indexing changes: - - Fix an issue where a reorg could cause an orderly shutdown when the - address index is active (#340, #357) - - Transaction relay (memory pool) changes: - - Increase maximum allowed space for nulldata transactions to 80 bytes - (#331) - - Implement support for the following rules specified by BIP0062: - - The S value in ECDSA signature must be at most half the curve order - (rule 5) (#349) - - Script execution must result in a single non-zero value on the stack - (rule 6) (#347) - - NOTE: All 7 rules of BIP0062 are now implemented - - Use network adjusted time in finalized transaction checks to improve - consistency across nodes (#332) - - Process orphan transactions on acceptance of new transactions (#345) - - RPC changes: - - Add support for a limited RPC user which is not allowed admin level - operations on the server (#363) - - Implement node command for more unified control over connected peers - (#79, #341) - - Implement generate command for regtest/simnet to support - deterministically mining a specified number of blocks (#362, #407) - - Update searchrawtransactions to return the matching transactions in - order (#354) - - Correct an issue with searchrawtransactions where it could return - duplicates (#346, #354) - - Increase precision of 'difficulty' field in getblock result to 8 - (#414, #415) - - Omit 'nextblockhash' field from getblock result when it is empty - (#416, #417) - - Add 'id' and 'timeoffset' fields to getpeerinfo result (#335) - - Websocket changes: - - Implement new commands stopnotifyspent, stopnotifyreceived, - stopnotifyblocks, and stopnotifynewtransactions to allow clients to - cancel notification registrations (#122, #342) - - btcctl utility changes: - - A single dash can now be used as an argument to cause that argument to - be read from stdin (#348) - - Add generate command - - Notable developer-related package changes: - - The new version 2 btcjson package has now replaced the deprecated - version 1 package (#368) - - The btcec package now performs all signing using RFC6979 deterministic - signatures (#358, #360) - - The txscript package has been significantly cleaned up and had a few - API changes (#387, #388, #389, #390, #391, #392, #393, #395, #396, - #400, #403, #404, #405, #406, #408, #409, #410, #412) - - A new PkScriptLocs function has been added to the wire package MsgTx - type which provides callers that deal with scripts optimization - opportunities (#343) - - Misc changes: - - Minor wire hashing optimizations (#366, #367) - - Other minor internal optimizations - - Contributors (alphabetical order): - - Alex Akselrod - - Arne Brutschy - - Chris Jepson - - Daniel Krawisz - - Dave Collins - - David Hill - - Jimmy Song - - Jonas Nick - - Josh Rickmar - - Olaoluwa Osuntokun - - Oleg Andreev - -Changes in 0.10.0 (Sun Mar 01 2015) - - Protocol and network related changes: - - Add a new checkpoint at block height 343185 - - Implement BIP066 which includes support for version 3 blocks, a new - consensus rule which prevents non-DER encoded signatures, and a - double-threshold switchover mechanism - - Rather than announcing all known addresses on getaddr requests which - can possibly result in multiple messages, randomize the results and - limit them to the max allowed by a single message (1000 addresses) - - Add more reserved IP spaces to the address manager - - Transaction relay (memory pool) changes: - - Make transactions which contain reserved opcodes nonstandard - - No longer accept or relay free and low-fee transactions that have - insufficient priority to be mined in the next block - - Implement support for the following rules specified by BIP0062: - - ECDSA signature must use strict DER encoding (rule 1) - - The signature script must only contain push operations (rule 2) - - All push operations must use the smallest possible encoding (rule 3) - - All stack values interpreted as a number must be encoding using the - shortest possible form (rule 4) - - NOTE: Rule 1 was already enforced, however the entire script now - evaluates to false rather than only the signature verification as - required by BIP0062 - - Allow transactions with nulldata transaction outputs to be treated as - standard - - Mining support changes: - - Modify the getblocktemplate RPC to generate and return block templates - for version 3 blocks which are compatible with BIP0066 - - Allow getblocktemplate to serve blocks when the current time is - less than the minimum allowed time for a generated block template - (https://github.com/btcsuite/btcd/issues/209) - - Crypto changes: - - Optimize scalar multiplication by the base point by using a - pre-computed table which results in approximately a 35% speedup - (https://github.com/btcsuite/btcec/issues/2) - - Optimize general scalar multiplication by using the secp256k1 - endomorphism which results in approximately a 17-20% speedup - (https://github.com/btcsuite/btcec/issues/1) - - Optimize general scalar multiplication by using non-adjacent form - which results in approximately an additional 8% speedup - (https://github.com/btcsuite/btcec/issues/3) - - Implement optional address indexing: - - Add a new parameter --addrindex which will enable the creation of an - address index which can be queried to determine all transactions which - involve a given address - (https://github.com/btcsuite/btcd/issues/190) - - Add a new logging subsystem for address index related operations - - Support new searchrawtransactions RPC - (https://github.com/btcsuite/btcd/issues/185) - - RPC changes: - - Require TLS version 1.2 as the minimum version for all TLS connections - - Provide support for disabling TLS when only listening on localhost - (https://github.com/btcsuite/btcd/pull/192) - - Modify help output for all commands to provide much more consistent - and detailed information - - Correct case in getrawtransaction which would refuse to serve certain - transactions with invalid scripts - (https://github.com/btcsuite/btcd/issues/210) - - Correct error handling in the getrawtransaction RPC which could lead - to a crash in rare cases - (https://github.com/btcsuite/btcd/issues/196) - - Update getinfo RPC to include the appropriate 'timeoffset' calculated - from the median network time - - Modify listreceivedbyaddress result type to include txids field so it - is compatible - - Add 'iswatchonly' field to validateaddress result - - Add 'startingpriority' and 'currentpriority' fields to getrawmempool - (https://github.com/btcsuite/btcd/issues/178) - - Don't omit the 'confirmations' field from getrawtransaction when it is - zero - - Websocket changes: - - Modify the behavior of the rescan command to automatically register - for notifications about transactions paying to rescanned addresses - or spending outputs from the final rescan utxo set when the rescan - is through the best block in the chain - - btcctl utility changes: - - Make the list of commands available via the -l option rather than - dumping the entire list on usage errors - - Alphabetize and categorize the list of commands by chain and wallet - - Make the help option only show the help options instead of also - dumping all of the commands - - Make the usage syntax much more consistent and correct a few cases of - misnamed fields - (https://github.com/btcsuite/btcd/issues/305) - - Improve usage errors to show the specific parameter number, reason, - and error code - - Only show the usage for specific command is shown when a valid command - is provided with invalid parameters - - Add support for a SOCK5 proxy - - Modify output for integer fields (such as timestamps) to display - normally instead in scientific notation - - Add invalidateblock command - - Add reconsiderblock command - - Add createnewaccount command - - Add renameaccount command - - Add searchrawtransactions command - - Add importaddress command - - Add importpubkey command - - showblock utility changes: - - Remove utility in favor of the RPC getblock method - - Notable developer-related package changes: - - Many of the core packages have been relocated into the btcd repository - (https://github.com/btcsuite/btcd/issues/214) - - A new version of the btcjson package that has been completely - redesigned from the ground up based based upon how the project has - evolved and lessons learned while using it since it was first written - is now available in the btcjson/v2/btcjson directory - - This will ultimately replace the current version so anyone making - use of this package will need to update their code accordingly - - The btcec package now provides better facilities for working directly - with its public and private keys without having to mix elements from - the ecdsa package - - Update the script builder to ensure all rules specified by BIP0062 are - adhered to when creating scripts - - The blockchain package now provides a MedianTimeSource interface and - concrete implementation for providing time samples from remote peers - and using that data to calculate an offset against the local time - - Misc changes: - - Fix a slow memory leak due to tickers not being stopped - (https://github.com/btcsuite/btcd/issues/189) - - Fix an issue where a mix of orphans and SPV clients could trigger a - condition where peers would no longer be served - (https://github.com/btcsuite/btcd/issues/231) - - The RPC username and password can now contain symbols which previously - conflicted with special symbols used in URLs - - Improve handling of obtaining random nonces to prevent cases where it - could error when not enough entropy was available - - Improve handling of home directory creation errors such as in the case - of unmounted symlinks (https://github.com/btcsuite/btcd/issues/193) - - Improve the error reporting for rejected transactions to include the - inputs which are missing and/or being double spent - - Update sample config file with new options and correct a comment - regarding the fact the RPC server only listens on localhost by default - (https://github.com/btcsuite/btcd/issues/218) - - Update the continuous integration builds to run several tools which - help keep code quality high - - Significant amount of internal code cleanup and improvements - - Other minor internal optimizations - - Code Contributors (alphabetical order): - - Beldur - - Ben Holden-Crowther - - Dave Collins - - David Evans - - David Hill - - Guilherme Salgado - - Javed Khan - - Jimmy Song - - John C. Vernaleo - - Jonathan Gillham - - Josh Rickmar - - Michael Ford - - Michail Kargakis - - kac - - Olaoluwa Osuntokun - -Changes in 0.9.0 (Sat Sep 20 2014) - - Protocol and network related changes: - - Add a new checkpoint at block height 319400 - - Add support for BIP0037 bloom filters - (https://github.com/conformal/btcd/issues/132) - - Implement BIP0061 reject handling and hence support for protocol - version 70002 (https://github.com/conformal/btcd/issues/133) - - Add testnet DNS seeds for peer discovery (testnet-seed.alexykot.me - and testnet-seed.bitcoin.schildbach.de) - - Add mainnet DNS seed for peer discovery (seeds.bitcoin.open-nodes.org) - - Make multisig transactions with non-null dummy data nonstandard - (https://github.com/conformal/btcd/issues/131) - - Make transactions with an excessive number of signature operations - nonstandard - - Perform initial DNS lookups concurrently which allows connections - more quickly - - Improve the address manager to significantly reduce memory usage and - add tests - - Remove orphan transactions when they appear in a mined block - (https://github.com/conformal/btcd/issues/166) - - Apply incremental back off on connection retries for persistent peers - that give invalid replies to mirror the logic used for failed - connections (https://github.com/conformal/btcd/issues/103) - - Correct rate-limiting of free and low-fee transactions - - Mining support changes: - - Implement getblocktemplate RPC with the following support: - (https://github.com/conformal/btcd/issues/124) - - BIP0022 Non-Optional Sections - - BIP0022 Long Polling - - BIP0023 Basic Pool Extensions - - BIP0023 Mutation coinbase/append - - BIP0023 Mutations time, time/increment, and time/decrement - - BIP0023 Mutation transactions/add - - BIP0023 Mutations prevblock, coinbase, and generation - - BIP0023 Block Proposals - - Implement built-in concurrent CPU miner - (https://github.com/conformal/btcd/issues/137) - NOTE: CPU mining on mainnet is pointless. This has been provided - for testing purposes such as for the new simulation test network - - Add --generate flag to enable CPU mining - - Deprecate the --getworkkey flag in favor of --miningaddr which - specifies which addresses generated blocks will choose from to pay - the subsidy to - - RPC changes: - - Implement gettxout command - (https://github.com/conformal/btcd/issues/141) - - Implement validateaddress command - - Implement verifymessage command - - Mark getunconfirmedbalance RPC as wallet-only - - Mark getwalletinfo RPC as wallet-only - - Update getgenerate, setgenerate, gethashespersec, and getmininginfo - to return the appropriate information about new CPU mining status - - Modify getpeerinfo pingtime and pingwait field types to float64 so - they are compatible - - Improve disconnect handling for normal HTTP clients - - Make error code returns for invalid hex more consistent - - Websocket changes: - - Switch to a new more efficient websocket package - (https://github.com/conformal/btcd/issues/134) - - Add rescanfinished notification - - Modify the rescanprogress notification to include block hash as well - as height (https://github.com/conformal/btcd/issues/151) - - btcctl utility changes: - - Accept --simnet flag which automatically selects the appropriate port - and TLS certificates needed to communicate with btcd and btcwallet on - the simulation test network - - Fix createrawtransaction command to send amounts denominated in BTC - - Add estimatefee command - - Add estimatepriority command - - Add getmininginfo command - - Add getnetworkinfo command - - Add gettxout command - - Add lockunspent command - - Add signrawtransaction command - - addblock utility changes: - - Accept --simnet flag which automatically selects the appropriate port - and TLS certificates needed to communicate with btcd and btcwallet on - the simulation test network - - Notable developer-related package changes: - - Provide a new bloom package in btcutil which allows creating and - working with BIP0037 bloom filters - - Provide a new hdkeychain package in btcutil which allows working with - BIP0032 hierarchical deterministic key chains - - Introduce a new btcnet package which houses network parameters - - Provide new simnet network (--simnet) which is useful for private - simulation testing - - Enforce low S values in serialized signatures as detailed in BIP0062 - - Return errors from all methods on the btcdb.Db interface - (https://github.com/conformal/btcdb/issues/5) - - Allow behavior flags to alter btcchain.ProcessBlock - (https://github.com/conformal/btcchain/issues/5) - - Provide a new SerializeSize API for blocks - (https://github.com/conformal/btcwire/issues/19) - - Several of the core packages now work with Google App Engine - - Misc changes: - - Correct an issue where the database could corrupt under certain - circumstances which would require a new chain download - - Slightly optimize deserialization - - Use the correct IP block for he.net - - Fix an issue where it was possible the block manager could hang on - shutdown - - Update sample config file so the comments are on a separate line - rather than the end of a line so they are not interpreted as settings - (https://github.com/conformal/btcd/issues/135) - - Correct an issue where getdata requests were not being properly - throttled which could lead to larger than necessary memory usage - - Always show help when given the help flag even when the config file - contains invalid entries - - General code cleanup and minor optimizations - -Changes in 0.8.0-beta (Sun May 25 2014) - - Btcd is now Beta (https://github.com/conformal/btcd/issues/130) - - Add a new checkpoint at block height 300255 - - Protocol and network related changes: - - Lower the minimum transaction relay fee to 1000 satoshi to match - recent reference client changes - (https://github.com/conformal/btcd/issues/100) - - Raise the maximum signature script size to support standard 15-of-15 - multi-signature pay-to-sript-hash transactions with compressed pubkeys - to remain compatible with the reference client - (https://github.com/conformal/btcd/issues/128) - - Reduce max bytes allowed for a standard nulldata transaction to 40 for - compatibility with the reference client - - Introduce a new btcnet package which houses all of the network params - for each network (mainnet, testnet3, regtest) to ultimately enable - easier addition and tweaking of networks without needing to change - several packages - - Fix several script discrepancies found by reference client test data - - Add new DNS seed for peer discovery (seed.bitnodes.io) - - Reduce the max known inventory cache from 20000 items to 1000 items - - Fix an issue where unknown inventory types could lead to a hung peer - - Implement inventory rebroadcast handler for sendrawtransaction - (https://github.com/conformal/btcd/issues/99) - - Update user agent to fully support BIP0014 - (https://github.com/conformal/btcwire/issues/10) - - Implement initial mining support: - - Add a new logging subsystem for mining related operations - - Implement infrastructure for creating block templates - - Provide options to control block template creation settings - - Support the getwork RPC - - Allow address identifiers to apply to more than one network since both - testnet3 and the regression test network unfortunately use the same - identifier - - RPC changes: - - Set the content type for HTTP POST RPC connections to application/json - (https://github.com/conformal/btcd/issues/121) - - Modified the RPC server startup so it only requires at least one valid - listen interface - - Correct an error path where it was possible certain errors would not - be returned - - Implement getwork command - (https://github.com/conformal/btcd/issues/125) - - Update sendrawtransaction command to reject orphans - - Update sendrawtransaction command to include the reason a transaction - was rejected - - Update getinfo command to populate connection count field - - Update getinfo command to include relay fee field - (https://github.com/conformal/btcd/issues/107) - - Allow transactions submitted with sendrawtransaction to bypass the - rate limiter - - Allow the getcurrentnet and getbestblock extensions to be accessed via - HTTP POST in addition to Websockets - (https://github.com/conformal/btcd/issues/127) - - Websocket changes: - - Rework notifications to ensure they are delivered in the order they - occur - - Rename notifynewtxs command to notifyreceived (funds received) - - Rename notifyallnewtxs command to notifynewtransactions - - Rename alltx notification to txaccepted - - Rename allverbosetx notification to txacceptedverbose - (https://github.com/conformal/btcd/issues/98) - - Add rescan progress notification - - Add recvtx notification - - Add redeemingtx notification - - Modify notifyspent command to accept an array of outpoints - (https://github.com/conformal/btcd/issues/123) - - Significantly optimize the rescan command to yield up to a 60x speed - increase - - btcctl utility changes: - - Add createencryptedwallet command - - Add getblockchaininfo command - - Add importwallet command - - Add addmultisigaddress command - - Add setgenerate command - - Accept --testnet and --wallet flags which automatically select - the appropriate port and TLS certificates needed to communicate - with btcd and btcwallet (https://github.com/conformal/btcd/issues/112) - - Allow path expansion from config file entries - (https://github.com/conformal/btcd/issues/113) - - Minor refactor simplify handling of options - - addblock utility changes: - - Improve logging by making it consistent with the logging provided by - btcd (https://github.com/conformal/btcd/issues/90) - - Improve several package APIs for developers: - - Add new amount type for consistently handling monetary values - - Add new coin selector API - - Add new WIF (Wallet Import Format) API - - Add new crypto types for private keys and signatures - - Add new API to sign transactions including script merging and hash - types - - Expose function to extract all pushed data from a script - (https://github.com/conformal/btcscript/issues/8) - - Misc changes: - - Optimize address manager shuffling to do 67% less work on average - - Resolve a couple of benign data races found by the race detector - (https://github.com/conformal/btcd/issues/101) - - Add IP address to all peer related errors to clarify which peer is the - cause (https://github.com/conformal/btcd/issues/102) - - Fix a UPNP case issue that prevented the --upnp option from working - with some UPNP servers - - Update documentation in the sample config file regarding debug levels - - Adjust some logging levels to improve debug messages - - Improve the throughput of query messages to the block manager - - Several minor optimizations to reduce GC churn and enhance speed - - Other minor refactoring - - General code cleanup - -Changes in 0.7.0 (Thu Feb 20 2014) - - Fix an issue when parsing scripts which contain a multi-signature script - which require zero signatures such as testnet block - 000000001881dccfeda317393c261f76d09e399e15e27d280e5368420f442632 - (https://github.com/conformal/btcscript/issues/7) - - Add check to ensure all transactions accepted to mempool only contain - canonical data pushes (https://github.com/conformal/btcscript/issues/6) - - Fix an issue causing excessive memory consumption - - Significantly rework and improve the websocket notification system: - - Each client is now independent so slow clients no longer limit the - speed of other connected clients - - Potentially long-running operations such as rescans are now run in - their own handler and rate-limited to one operation at a time without - preventing simultaneous requests from the same client for the faster - requests or notifications - - A couple of scenarios which could cause shutdown to hang have been - resolved - - Update notifynewtx notifications to support all address types instead - of only pay-to-pubkey-hash - - Provide a --rpcmaxwebsockets option to allow limiting the number of - concurrent websocket clients - - Add a new websocket command notifyallnewtxs to request notifications - (https://github.com/conformal/btcd/issues/86) (thanks @flammit) - - Improve btcctl utility in the following ways: - - Add getnetworkhashps command - - Add gettransaction command (wallet-specific) - - Add signmessage command (wallet-specific) - - Update getwork command to accept - - Continue cleanup and work on implementing the RPC API: - - Implement getnettotals command - (https://github.com/conformal/btcd/issues/84) - - Implement networkhashps command - (https://github.com/conformal/btcd/issues/87) - - Update getpeerinfo to always include syncnode field even when false - - Remove help addenda for getpeerinfo now that it supports all fields - - Close standard RPC connections on auth failure - - Provide a --rpcmaxclients option to allow limiting the number of - concurrent RPC clients (https://github.com/conformal/btcd/issues/68) - - Include IP address in RPC auth failure log messages - - Resolve a rather harmless data races found by the race detector - (https://github.com/conformal/btcd/issues/94) - - Increase block priority size and max standard transaction size to 50k - and 100k, respectively (https://github.com/conformal/btcd/issues/71) - - Add rate limiting of free transactions to the memory pool to prevent - penny flooding (https://github.com/conformal/btcd/issues/40) - - Provide a --logdir option (https://github.com/conformal/btcd/issues/95) - - Change the default log file path to include the network - - Add a new ScriptBuilder interface to btcscript to support creation of - custom scripts (https://github.com/conformal/btcscript/issues/5) - - General code cleanup - -Changes in 0.6.0 (Tue Feb 04 2014) - - Fix an issue when parsing scripts which contain invalid signatures that - caused a chain fork on block - 0000000000000001e4241fd0b3469a713f41c5682605451c05d3033288fb2244 - - Correct an issue which could lead to an error in removeBlockNode - (https://github.com/conformal/btcchain/issues/4) - - Improve addblock utility as follows: - - Check imported blocks against all chain rules and checkpoints - - Skip blocks which are already known so you can stop and restart the - import or start the import after you have already downloaded a portion - of the chain - - Correct an issue where the utility did not shutdown cleanly after - processing all blocks - - Add error on attempt to import orphan blocks - - Improve error handling and reporting - - Display statistics after input file has been fully processed - - Rework, optimize, and improve headers-first mode: - - Resuming the chain sync from any point before the final checkpoint - will now use headers-first mode - (https://github.com/conformal/btcd/issues/69) - - Verify all checkpoints as opposed to only the final one - - Reduce and bound memory usage - - Rollback to the last known good point when a header does not match a - checkpoint - - Log information about what is happening with headers - - Improve btcctl utility in the following ways: - - Add getaddednodeinfo command - - Add getnettotals command - - Add getblocktemplate command (wallet-specific) - - Add getwork command (wallet-specific) - - Add getnewaddress command (wallet-specific) - - Add walletpassphrasechange command (wallet-specific) - - Add walletlock command (wallet-specific) - - Add sendfrom command (wallet-specific) - - Add sendmany command (wallet-specific) - - Add settxfee command (wallet-specific) - - Add listsinceblock command (wallet-specific) - - Add listaccounts command (wallet-specific) - - Add keypoolrefill command (wallet-specific) - - Add getreceivedbyaccount command (wallet-specific) - - Add getrawchangeaddress command (wallet-specific) - - Add gettxoutsetinfo command (wallet-specific) - - Add listaddressgroupings command (wallet-specific) - - Add listlockunspent command (wallet-specific) - - Add listlock command (wallet-specific) - - Add listreceivedbyaccount command (wallet-specific) - - Add validateaddress command (wallet-specific) - - Add verifymessage command (wallet-specific) - - Add sendtoaddress command (wallet-specific) - - Continue cleanup and work on implementing the RPC API: - - Implement submitblock command - (https://github.com/conformal/btcd/issues/61) - - Implement help command - - Implement ping command - - Implement getaddednodeinfo command - (https://github.com/conformal/btcd/issues/78) - - Implement getinfo command - - Update getpeerinfo to support bytesrecv and bytessent - (https://github.com/conformal/btcd/issues/83) - - Improve and correct several RPC server and websocket areas: - - Change the connection endpoint for websockets from /wallet to /ws - (https://github.com/conformal/btcd/issues/80) - - Implement an alternative authentication for websockets so clients - such as javascript from browsers that don't support setting HTTP - headers can authenticate (https://github.com/conformal/btcd/issues/77) - - Add an authentication deadline for RPC connections - (https://github.com/conformal/btcd/issues/68) - - Use standard authentication failure responses for RPC connections - - Make automatically generated certificate more standard so it works - from client such as node.js and Firefox - - Correct some minor issues which could prevent the RPC server from - shutting down in an orderly fashion - - Make all websocket notifications require registration - - Change the data sent over websockets to text since it is JSON-RPC - - Allow connections that do not have an Origin header set - - Expose and track the number of bytes read and written per peer - (https://github.com/conformal/btcwire/issues/6) - - Correct an issue with sendrawtransaction when invoked via websockets - which prevented a minedtx notification from being added - - Rescan operations issued from remote wallets are no stopped when - the wallet disconnects mid-operation - (https://github.com/conformal/btcd/issues/66) - - Several optimizations related to fetching block information from the - database - - General code cleanup - -Changes in 0.5.0 (Mon Jan 13 2014) - - Optimize initial block download by introducing a new mode which - downloads the block headers first (up to the final checkpoint) - - Improve peer handling to remove the potential for slow peers to cause - sluggishness amongst all peers - (https://github.com/conformal/btcd/issues/63) - - Fix an issue where the initial block sync could stall when the sync peer - disconnects (https://github.com/conformal/btcd/issues/62) - - Correct an issue where --externalip was doing a DNS lookup on the full - host:port instead of just the host portion - (https://github.com/conformal/btcd/issues/38) - - Fix an issue which could lead to a panic on chain switches - (https://github.com/conformal/btcd/issues/70) - - Improve btcctl utility in the following ways: - - Show getdifficulty output as floating point to 6 digits of precision - - Show all JSON object replies formatted as standard JSON - - Allow btcctl getblock to accept optional params - - Add getaccount command (wallet-specific) - - Add getaccountaddress command (wallet-specific) - - Add sendrawtransaction command - - Continue cleanup and work on implementing RPC API calls - - Update getrawmempool to support new optional verbose flag - - Update getrawtransaction to match the reference client - - Update getblock to support new optional verbose flag - - Update raw transactions to fully match the reference client including - support for all transaction types and address types - - Correct getrawmempool fee field to return BTC instead of Satoshi - - Correct getpeerinfo service flag to return 8 digit string so it - matches the reference client - - Correct verifychain to return a boolean - - Implement decoderawtransaction command - - Implement createrawtransaction command - - Implement decodescript command - - Implement gethashespersec command - - Allow RPC handler overrides when invoked via a websocket versus - legacy connection - - Add new DNS seed for peer discovery - - Display user agent on new valid peer log message - (https://github.com/conformal/btcd/issues/64) - - Notify wallet when new transactions that pay to registered addresses - show up in the mempool before being mined into a block - - Support a tor-specific proxy in addition to a normal proxy - (https://github.com/conformal/btcd/issues/47) - - Remove deprecated sqlite3 imports from utilities - - Remove leftover profile write from addblock utility - - Quite a bit of code cleanup and refactoring to improve maintainability - -Changes in 0.4.0 (Thu Dec 12 2013) - - Allow listen interfaces to be specified via --listen instead of only the - port (https://github.com/conformal/btcd/issues/33) - - Allow listen interfaces for the RPC server to be specified via - --rpclisten instead of only the port - (https://github.com/conformal/btcd/issues/34) - - Only disable listening when --connect or --proxy are used when no - --listen interface are specified - (https://github.com/conformal/btcd/issues/10) - - Add several new standard transaction checks to transaction memory pool: - - Support nulldata scripts as standard - - Only allow a max of one nulldata output per transaction - - Enforce a maximum of 3 public keys in multi-signature transactions - - The number of signatures in multi-signature transactions must not - exceed the number of public keys - - The number of inputs to a signature script must match the expected - number of inputs for the script type - - The number of inputs pushed onto the stack by a redeeming signature - script must match the number of inputs consumed by the referenced - public key script - - When a block is connected, remove any transactions from the memory pool - which are now double spends as a result of the newly connected - transactions - - Don't relay transactions resurrected during a chain switch since - other peers will also be switching chains and therefore already know - about them - - Cleanup a few cases where rejected transactions showed as an error - rather than as a rejected transaction - - Ignore the default configuration file when --regtest (regression test - mode) is specified - - Implement TLS support for RPC including automatic certificate generation - - Support HTTP authentication headers for web sockets - - Update address manager to recognize and properly work with Tor - addresses (https://github.com/conformal/btcd/issues/36) and - (https://github.com/conformal/btcd/issues/37) - - Improve btcctl utility in the following ways: - - Add the ability to specify a configuration file - - Add a default entry for the RPC cert to point to the location - it will likely be in the btcd home directory - - Implement --version flag - - Provide a --notls option to support non-TLS configurations - - Fix a couple of minor races found by the Go race detector - - Improve logging - - Allow logging level to be specified on a per subsystem basis - (https://github.com/conformal/btcd/issues/48) - - Allow logging levels to be dynamically changed via RPC - (https://github.com/conformal/btcd/issues/15) - - Implement a rolling log file with a max of 10MB per file and a - rotation size of 3 which results in a max logging size of 30 MB - - Correct a minor issue with the rescanning websocket call - (https://github.com/conformal/btcd/issues/54) - - Fix a race with pushing address messages that could lead to a panic - (https://github.com/conformal/btcd/issues/58) - - Improve which external IP address is reported to peers based on which - interface they are connected through - (https://github.com/conformal/btcd/issues/35) - - Add --externalip option to allow an external IP address to be specified - for cases such as tor hidden services or advanced network configurations - (https://github.com/conformal/btcd/issues/38) - - Add --upnp option to support automatic port mapping via UPnP - (https://github.com/conformal/btcd/issues/51) - - Update Ctrl+C interrupt handler to properly sync address manager and - remove the UPnP port mapping (if needed) - - Continue cleanup and work on implementing RPC API calls - - Add importprivkey (import private key) command to btcctl - - Update getrawtransaction to provide addresses properly, support - new verbose param, and match the reference implementation with the - exception of MULTISIG (thanks @flammit) - - Update getblock with new verbose flag (thanks @flammit) - - Add listtransactions command to btcctl - - Add getbalance command to btcctl - - Add basic support for btcd to run as a native Windows service - (https://github.com/conformal/btcd/issues/42) - - Package addblock utility with Windows MSIs - - Add support for TravisCI (continuous build integration) - - Cleanup some documentation and usage - - Several other minor bug fixes and general code cleanup - -Changes in 0.3.3 (Wed Nov 13 2013) - - Significantly improve initial block chain download speed - (https://github.com/conformal/btcd/issues/20) - - Add a new checkpoint at block height 267300 - - Optimize most recently used inventory handling - (https://github.com/conformal/btcd/issues/21) - - Optimize duplicate transaction input check - (https://github.com/conformal/btcchain/issues/2) - - Optimize transaction hashing - (https://github.com/conformal/btcd/issues/25) - - Rework and optimize wallet listener notifications - (https://github.com/conformal/btcd/issues/22) - - Optimize serialization and deserialization - (https://github.com/conformal/btcd/issues/27) - - Add support for minimum transaction fee to memory pool acceptance - (https://github.com/conformal/btcd/issues/29) - - Improve leveldb database performance by removing explicit GC call - - Fix an issue where Ctrl+C was not always finishing orderly database - shutdown - - Fix an issue in the script handling for OP_CHECKSIG - - Impose max limits on all variable length protocol entries to prevent - abuse from malicious peers - - Enforce DER signatures for transactions allowed into the memory pool - - Separate the debug profile http server from the RPC server - - Rework of the RPC code to improve performance and make the code cleaner - - The getrawtransaction RPC call now properly checks the memory pool - before consulting the db (https://github.com/conformal/btcd/issues/26) - - Add support for the following RPC calls: getpeerinfo, getconnectedcount, - addnode, verifychain - (https://github.com/conformal/btcd/issues/13) - (https://github.com/conformal/btcd/issues/17) - - Implement rescan websocket extension to allow wallet rescans - - Use correct paths for application data storage for all supported - operating systems (https://github.com/conformal/btcd/issues/30) - - Add a default redirect to the http profiling page when accessing the - http profile server - - Add a new --cpuprofile option which can be used to generate CPU - profiling data on platforms that support it - - Several other minor performance optimizations - - Other minor bug fixes and general code cleanup - -Changes in 0.3.2 (Tue Oct 22 2013) - - Fix an issue that could cause the download of the block chain to stall - (https://github.com/conformal/btcd/issues/12) - - Remove deprecated sqlite as an available database backend - - Close sqlite compile issue as sqlite has now been removed - (https://github.com/conformal/btcd/issues/11) - - Change default RPC ports to 8334 (mainnet) and 18334 (testnet) - - Continue cleanup and work on implementing RPC API calls - - Add support for the following RPC calls: getrawmempool, - getbestblockhash, decoderawtransaction, getdifficulty, - getconnectioncount, getpeerinfo, and addnode - - Improve the btcctl utility that is used to issue JSON-RPC commands - - Fix an issue preventing btcd from cleanly shutting down with the RPC - stop command - - Add a number of database interface tests to ensure backends implement - the expected interface - - Expose some additional information from btcscript to be used for - identifying "standard"" transactions - - Add support for plan9 - thanks @mischief - (https://github.com/conformal/btcd/pull/19) - - Other minor bug fixes and general code cleanup - -Changes in 0.3.1-alpha (Tue Oct 15 2013) - - Change default database to leveldb - NOTE: This does mean you will have to redownload the block chain. Since we - are still in alpha, we didn't feel writing a converter was worth the time as - it would take away from more important issues at this stage - - Add a warning if there are multiple block chain databases of different types - - Fix issue with unexpected EOF in leveldb -- https://github.com/conformal/btcd/issues/18 - - Fix issue preventing block 21066 on testnet -- https://github.com/conformal/btcchain/issues/1 - - Fix issue preventing block 96464 on testnet -- https://github.com/conformal/btcscript/issues/1 - - Optimize transaction lookups - - Correct a few cases of list removal that could result in improper cleanup - of no longer needed orphans - - Add functionality to increase ulimits on non-Windows platforms - - Add support for mempool command which allows remote peers to query the - transaction memory pool via the bitcoin protocol - - Clean up logging a bit - - Add a flag to disable checkpoints for developers - - Add a lot of useful debug logging such as message summaries - - Other minor bug fixes and general code cleanup - -Initial Release 0.3.0-alpha (Sat Oct 05 2013): - - Initial release diff --git a/LICENSE b/LICENSE index 53ba0c56..fa218625 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,6 @@ ISC License +Copyright (c) 2021 The LBRY developers Copyright (c) 2013-2017 The btcsuite developers Copyright (c) 2015-2016 The Decred developers diff --git a/README.md b/README.md index 5ec1454f..16800c6f 100644 --- a/README.md +++ b/README.md @@ -1,121 +1,133 @@ -btcd -==== +# lbcd -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) -[![Coverage Status](https://coveralls.io/repos/github/btcsuite/btcd/badge.svg?branch=master)](https://coveralls.io/github/btcsuite/btcd?branch=master) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) +[![Coverage Status](https://coveralls.io/repos/github/lbryio/lbcd/badge.svg?branch=master)](https://coveralls.io/github/lbryio/lbcd?branch=master) [![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd) + -btcd is an alternative full node bitcoin implementation written in Go (golang). +`lbcd` is a full node implementation of LBRY's blockchain written in Go (golang). -This project is currently under active development and is in a Beta state. It -is extremely stable and has been in production use since October 2013. +This project is currently under active development and is in a Beta state while +we ensure it matches LBRYcrd's functionality. The intention is that it properly +downloads, validates, and serves the block chain using the exact rules +(including consensus bugs) for block acceptance as LBRYcrd. +We have taken great care to avoid lbcd causing a fork to the blockchain. -It properly downloads, validates, and serves the block chain using the exact -rules (including consensus bugs) for block acceptance as Bitcoin Core. We have -taken great care to avoid btcd causing a fork to the block chain. It includes a -full block validation testing framework which contains all of the 'official' -block acceptance tests (and some additional ones) that is run on every pull -request to help ensure it properly follows consensus. Also, it passes all of -the JSON test data in the Bitcoin Core code. +Note: `lbcd` does *NOT* include wallet functionality. That functionality is provided by the +[lbcwallet](https://github.com/lbryio/lbcwallet) and the [LBRY SDK](https://github.com/lbryio/lbry-sdk). -It also properly relays newly mined blocks, maintains a transaction pool, and -relays individual transactions that have not yet made it into a block. It -ensures all individual transactions admitted to the pool follow the rules -required by the block chain and also includes more strict checks which filter -transactions based on miner requirements ("standard" transactions). +## Security -One key difference between btcd and Bitcoin Core is that btcd does *NOT* include -wallet functionality and this was a very intentional design decision. See the -blog entry [here](https://web.archive.org/web/20171125143919/https://blog.conformal.com/btcd-not-your-moms-bitcoin-daemon) -for more details. This means you can't actually make or receive payments -directly with btcd. That functionality is provided by the -[btcwallet](https://github.com/btcsuite/btcwallet) and -[Paymetheus](https://github.com/btcsuite/Paymetheus) (Windows-only) projects -which are both under active development. +We take security seriously. Please contact [security](mailto:security@lbry.com) regarding any security issues. +Our PGP key is [here](https://lbry.com/faq/pgp-key) if you need it. + +We maintain a mailing list for notifications of upgrades, security issues, +and soft/hard forks. To join, visit [fork list](https://lbry.com/forklist) ## Requirements -[Go](http://golang.org) 1.16 or newer. +All common operating systems are supported. lbcd requires at least 8GB of RAM +and at least 100GB of disk storage. Both RAM and disk requirements increase slowly over time. +Using a fast NVMe disk is recommended. + +`lbcd` is not immune to data loss. It expects a clean shutdown via SIGINT or +SIGTERM. SIGKILL, immediate VM kills, and sudden power loss can cause data +corruption, thus requiring chain resynchronization for recovery. + +For compilation, [Go](http://golang.org) 1.16 or newer is required. ## Installation -https://github.com/btcsuite/btcd/releases +Acquire binary files from [releases](https://github.com/lbryio/lbcd/releases) -#### Linux/BSD/MacOSX/POSIX - Build from Source +### To build from Source on Linux/BSD/MacOSX/POSIX -- Install Go according to the installation instructions here: - http://golang.org/doc/install +Install Go according to its [installation instructions](http://golang.org/doc/install). -- Ensure Go was installed properly and is a supported version: +``` sh +git clone https://github.com/lbryio/lbcd +cd lbcd -```bash -$ go version -$ go env GOROOT GOPATH +# Build lbcd +go build . + +# Build lbcctl +go build ./cmd/lbcctl ``` -NOTE: The `GOROOT` and `GOPATH` above must not be the same path. It is -recommended that `GOPATH` is set to a directory in your home directory such as -`~/goprojects` to avoid write permission issues. It is also recommended to add -`$GOPATH/bin` to your `PATH` at this point. +Both [GoLand](https://www.jetbrains.com/go/) +and [VS Code](https://code.visualstudio.com/docs/languages/go) IDEs are supported. -- Run the following commands to obtain btcd, all dependencies, and install it: +## Usage -```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd -$ GO111MODULE=on go install -v . ./cmd/... +By default, data and logs are stored in ``: + +- Linux: `~/.lbcd/` +- MacOS: `/Users//Library/Application Support/Lbcd/` + +To enable RPC access a username and password is required. Example: + +``` sh +./lbcd --txindex --rpcuser=rpcuser --rpcpass=rpcpass ``` -- btcd (and utilities) will now be installed in ```$GOPATH/bin```. If you did - not already add the bin directory to your system path during Go installation, - we recommend you do so now. +Interact with lbcd via RPC using `lbcctl` -## Updating - -#### Linux/BSD/MacOSX/POSIX - Build from Source - -- Run the following commands to update btcd, all dependencies, and install it: - -```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd -$ git pull -$ GO111MODULE=on go install -v . ./cmd/... +``` sh +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass getblockcount +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass getblocktemplate ``` -## Getting Started +By default, the RPCs are served over TLS. `lbcd` generates (if not exists) `rpc.cert` and +`rpc.key` under `` where `lbcctl` would search and use them. -btcd has several configuration options available to tweak how it runs, but all -of the basic operations described in the intro section work with zero -configuration. +The RPCs can also be served without TLS *(on localhost only)* using (`--notls`) -#### Linux/BSD/POSIX/Source - -```bash -$ ./btcd +``` sh +./lbcd --txindex --rpcuser=rpcuser --rpcpass=rpcpass --notls +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass --notls getblockcount ``` -## IRC +## Working with Different Networks -- irc.libera.chat -- channel #btcd -- [webchat](https://web.libera.chat/gamja/?channels=btcd) +By default, `lbcd` and `lbcctl` use the following ports for different networks respectively: -## Issue Tracker +| Network | RPC Port | Network Port | +| ------- | -------- | ------------ | +| mainnet | 9245 | 9246 | +| testnet | 19245 | 19246 | +| regtest | 29245 | 29246 | -The [integrated github issue tracker](https://github.com/btcsuite/btcd/issues) -is used for this project. +Running `lbcd` and `lbcctl` with `--testnet` or `--regtest` would use different chain params as well as default RPC and Network ports. -## Documentation +``` sh +./lbcd --txindex --rpcuser=rpcuser --rpcpass=rpcpass --regtest +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass --regtest getblockcount +``` -The documentation is a work-in-progress. It is located in the [docs](https://github.com/btcsuite/btcd/tree/master/docs) folder. +The default Network and RPC ports of `lbcd` can be overriden using `--listen` and `--rpclisten` +`lbcctl` can also connect to RPC server specified by `--rpcserver` -## Release Verification +``` sh +./lbcd --txindex --rpcuser=rpcuser --rpcpass=rpcpass --regtest --listen=127.0.0.1:29248 --rpclisten=127.0.0.1:29247 +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass --regtest --rpcserver=127.0.0.1:29247 getblockcount +``` +Note: Wallet related RPCs are provided by [lbcwallet](https://github.com/lbryio/lbcwallet). + +## Contributing + +Contributions to this project are welcome, encouraged, and compensated. +The [integrated github issue tracker](https://github.com/lbryio/lbcd/issues) +is used for this project. All pull requests will be considered. + + ## License -btcd is licensed under the [copyfree](http://copyfree.org) ISC License. +lbcd is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/blockchain/README.md b/blockchain/README.md index 2237780c..cb9ddb45 100644 --- a/blockchain/README.md +++ b/blockchain/README.md @@ -1,30 +1,9 @@ blockchain ========== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain) -Package blockchain implements bitcoin block handling and chain selection rules. -The test coverage is currently only around 60%, but will be increasing over -time. See `test_coverage.txt` for the gocov coverage report. Alternatively, if -you are running a POSIX OS, you can run the `cov_report.sh` script for a -real-time report. Package blockchain is licensed under the liberal ISC license. - -There is an associated blog post about the release of this package -[here](https://blog.conformal.com/btcchain-the-bitcoin-chain-package-from-bctd/). - -This package has intentionally been designed so it can be used as a standalone -package for any projects needing to handle processing of blocks into the bitcoin -block chain. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/blockchain -``` - -## Bitcoin Chain Processing Overview +### Bitcoin Chain Processing Overview Before a block is allowed into the block chain, it must go through an intensive series of validation rules. The following list serves as a general outline of @@ -57,47 +36,4 @@ is by no means exhaustive: transaction values - Run the transaction scripts to verify the spender is allowed to spend the coins - - Insert the block into the block database - -## Examples - -* [ProcessBlock Example](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain#example-BlockChain-ProcessBlock) - Demonstrates how to create a new chain instance and use ProcessBlock to - attempt to add a block to the chain. This example intentionally - attempts to insert a duplicate genesis block to illustrate how an invalid - block is handled. - -* [CompactToBig Example](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain#example-CompactToBig) - Demonstrates how to convert the compact "bits" in a block header which - represent the target difficulty to a big integer and display it using the - typical hex notation. - -* [BigToCompact Example](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain#example-BigToCompact) - Demonstrates how to convert a target difficulty into the - compact "bits" in a block header which represent that target difficulty. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - - -Package blockchain is licensed under the [copyfree](http://copyfree.org) ISC -License. + - Insert the block into the block database \ No newline at end of file diff --git a/blockchain/fullblocktests/README.md b/blockchain/fullblocktests/README.md index 943989be..de7781dc 100644 --- a/blockchain/fullblocktests/README.md +++ b/blockchain/fullblocktests/README.md @@ -1,9 +1,9 @@ fullblocktests ============== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain/fullblocktests) +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/lbryio/lbcd/blockchain/fullblocktests) Package fullblocktests provides a set of full block tests to be used for testing the consensus validation rules. The tests are intended to be flexible enough to @@ -20,7 +20,7 @@ of blocks that exercise the consensus validation rules. ## Installation and Updating ```bash -$ go get -u github.com/btcsuite/btcd/blockchain/fullblocktests +$ go get -u github.com/lbryio/lbcd/blockchain/fullblocktests ``` ## License diff --git a/blockchain/indexers/README.md b/blockchain/indexers/README.md index f4849152..989cb555 100644 --- a/blockchain/indexers/README.md +++ b/blockchain/indexers/README.md @@ -1,9 +1,9 @@ indexers ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain/indexers?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain/indexers) +[![GoDoc](https://pkg.go.dev/github.com/lbryio/lbcd/blockchain/indexers?status.png)](https://pkg.go.dev/github.com/lbryio/lbcd/blockchain/indexers) Package indexers implements optional block chain indexes. @@ -23,7 +23,7 @@ via an RPC interface. ## Installation ```bash -$ go get -u github.com/btcsuite/btcd/blockchain/indexers +$ go get -u github.com/lbryio/lbcd/blockchain/indexers ``` ## License diff --git a/btcec/README.md b/btcec/README.md index a6dd2cf2..0cf57a80 100644 --- a/btcec/README.md +++ b/btcec/README.md @@ -1,68 +1,11 @@ btcec ===== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/btcec?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/btcec) -Package btcec implements elliptic curve cryptography needed for working with +btcec implements elliptic curve cryptography needed for working with Bitcoin (secp256k1 only for now). It is designed so that it may be used with the standard crypto/ecdsa packages provided with go. A comprehensive suite of test is provided to ensure proper functionality. Package btcec was originally based on work from ThePiachu which is licensed under the same terms as Go, but it has -signficantly diverged since then. The btcsuite developers original is licensed -under the liberal ISC license. - -Although this package was primarily written for btcd, it has intentionally been -designed so it can be used as a standalone package for any projects needing to -use secp256k1 elliptic curve cryptography. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/btcec -``` - -## Examples - -* [Sign Message](https://pkg.go.dev/github.com/btcsuite/btcd/btcec#example-package--SignMessage) - Demonstrates signing a message with a secp256k1 private key that is first - parsed form raw bytes and serializing the generated signature. - -* [Verify Signature](https://pkg.go.dev/github.com/btcsuite/btcd/btcec#example-package--VerifySignature) - Demonstrates verifying a secp256k1 signature against a public key that is - first parsed from raw bytes. The signature is also parsed from raw bytes. - -* [Encryption](https://pkg.go.dev/github.com/btcsuite/btcd/btcec#example-package--EncryptMessage) - Demonstrates encrypting a message for a public key that is first parsed from - raw bytes, then decrypting it using the corresponding private key. - -* [Decryption](https://pkg.go.dev/github.com/btcsuite/btcd/btcec#example-package--DecryptMessage) - Demonstrates decrypting a message using a private key that is first parsed - from raw bytes. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package btcec is licensed under the [copyfree](http://copyfree.org) ISC License -except for btcec.go and btcec_test.go which is under the same license as Go. - +signficantly diverged since then. \ No newline at end of file diff --git a/btcjson/README.md b/btcjson/README.md index 48f32263..9d981333 100644 --- a/btcjson/README.md +++ b/btcjson/README.md @@ -1,70 +1,8 @@ btcjson ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson) Package btcjson implements concrete types for marshalling to and from the bitcoin JSON-RPC API. A comprehensive suite of tests is provided to ensure -proper functionality. - -Although this package was primarily written for the btcsuite, it has -intentionally been designed so it can be used as a standalone package for any -projects needing to marshal to and from bitcoin JSON-RPC requests and responses. - -Note that although it's possible to use this package directly to implement an -RPC client, it is not recommended since it is only intended as an infrastructure -package. Instead, RPC clients should use the -[btcrpcclient](https://github.com/btcsuite/btcrpcclient) package which provides -a full blown RPC client with many features such as automatic connection -management, websocket support, automatic notification re-registration on -reconnect, and conversion from the raw underlying RPC types (strings, floats, -ints, etc) to higher-level types with many nice and useful properties. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/btcjson -``` - -## Examples - -* [Marshal Command](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson#example-MarshalCmd) - Demonstrates how to create and marshal a command into a JSON-RPC request. - -* [Unmarshal Command](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson#example-UnmarshalCmd) - Demonstrates how to unmarshal a JSON-RPC request and then unmarshal the - concrete request into a concrete command. - -* [Marshal Response](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson#example-MarshalResponse) - Demonstrates how to marshal a JSON-RPC response. - -* [Unmarshal Response](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson#example-package--UnmarshalResponse) - Demonstrates how to unmarshal a JSON-RPC response and then unmarshal the - result field in the response to a concrete type. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package btcjson is licensed under the [copyfree](http://copyfree.org) ISC -License. +proper functionality. \ No newline at end of file diff --git a/chaincfg/README.md b/chaincfg/README.md index 72fac2e7..da3254c7 100644 --- a/chaincfg/README.md +++ b/chaincfg/README.md @@ -1,85 +1,8 @@ chaincfg ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/chaincfg) Package chaincfg defines chain configuration parameters for the three standard -Bitcoin networks and provides the ability for callers to define their own custom -Bitcoin networks. - -Although this package was primarily written for btcd, it has intentionally been -designed so it can be used as a standalone package for any projects needing to -use parameters for the standard Bitcoin networks or for projects needing to -define their own network. - -## Sample Use - -```Go -package main - -import ( - "flag" - "fmt" - "log" - - "github.com/btcsuite/btcutil" - "github.com/btcsuite/btcd/chaincfg" -) - -var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network") - -// By default (without -testnet), use mainnet. -var chainParams = &chaincfg.MainNetParams - -func main() { - flag.Parse() - - // Modify active network parameters if operating on testnet. - if *testnet { - chainParams = &chaincfg.TestNet3Params - } - - // later... - - // Create and print new payment address, specific to the active network. - pubKeyHash := make([]byte, 20) - addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, chainParams) - if err != nil { - log.Fatal(err) - } - fmt.Println(addr) -} -``` - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/chaincfg -``` - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package chaincfg is licensed under the [copyfree](http://copyfree.org) ISC -License. +LBRY networks and provides the ability for callers to define their own custom +LBRY networks. \ No newline at end of file diff --git a/chaincfg/chainhash/README.md b/chaincfg/chainhash/README.md index b7ddf19e..da54f734 100644 --- a/chaincfg/chainhash/README.md +++ b/chaincfg/chainhash/README.md @@ -1,9 +1,9 @@ chainhash ========= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/chaincfg/chainhash) +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/lbryio/lbcd/chaincfg/chainhash) ======= chainhash provides a generic hash type and associated functions that allows the @@ -12,7 +12,7 @@ specific hash algorithm to be abstracted. ## Installation and Updating ```bash -$ go get -u github.com/btcsuite/btcd/chaincfg/chainhash +$ go get -u github.com/lbryio/lbcd/chaincfg/chainhash ``` ## GPG Verification Key diff --git a/connmgr/README.md b/connmgr/README.md index b1aa3cc7..5237bf46 100644 --- a/connmgr/README.md +++ b/connmgr/README.md @@ -1,13 +1,11 @@ connmgr ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/connmgr) -Package connmgr implements a generic Bitcoin network connection manager. +Package connmgr implements a generic network connection manager. -## Overview +### Overview Connection Manager handles all the general connection concerns such as maintaining a set number of outbound connections, sourcing peers, banning, @@ -18,20 +16,10 @@ connection requests from a source or a set of given addresses, dial them and notify the caller on connections. The main intended use is to initialize a pool of active connections and maintain them to remain connected to the P2P network. -In addition the connection manager provides the following utilities: +In addition, the connection manager provides the following utilities: - Notifications on connections or disconnections - Handle failures and retry new addresses from the source - Connect only to specified addresses - Permanent connections with increasing backoff retry timers -- Disconnect or Remove an established connection - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/connmgr -``` - -## License - -Package connmgr is licensed under the [copyfree](http://copyfree.org) ISC License. +- Disconnect or Remove an established connection \ No newline at end of file diff --git a/database/README.md b/database/README.md index 21563d1a..6e937304 100644 --- a/database/README.md +++ b/database/README.md @@ -1,9 +1,7 @@ database ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/database) Package database provides a block and metadata storage database. @@ -13,8 +11,8 @@ one entity can have the database open at a time (for most database backends), and that entity will be btcd. When a client wants programmatic access to the data provided by btcd, they'll -likely want to use the [rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) -package which makes use of the [JSON-RPC API](https://github.com/btcsuite/btcd/tree/master/docs/json_rpc_api.md). +likely want to use the [rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) +package which makes use of the [JSON-RPC API](https://github.com/lbryio/lbcd/tree/master/docs/json_rpc_api.md). However, this package could be extremely useful for any applications requiring Bitcoin block storage capabilities. @@ -32,26 +30,4 @@ storage, and strict checksums in key areas to ensure data integrity. - Nested buckets - Iteration support including cursors with seek capability - Supports registration of backend databases -- Comprehensive test coverage - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/database -``` - -## Examples - -* [Basic Usage Example](https://pkg.go.dev/github.com/btcsuite/btcd/database#example-package--BasicUsage) - Demonstrates creating a new database and using a managed read-write - transaction to store and retrieve metadata. - -* [Block Storage and Retrieval Example](https://pkg.go.dev/github.com/btcsuite/btcd/database#example-package--BlockStorageAndRetrieval) - Demonstrates creating a new database, using a managed read-write transaction - to store a block, and then using a managed read-only transaction to fetch the - block. - -## License - -Package database is licensed under the [copyfree](http://copyfree.org) ISC -License. +- Comprehensive test coverage \ No newline at end of file diff --git a/database/ffldb/README.md b/database/ffldb/README.md index 5b855faa..4a43fb73 100644 --- a/database/ffldb/README.md +++ b/database/ffldb/README.md @@ -1,9 +1,9 @@ ffldb ===== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/database/ffldb?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/database/ffldb) +[![GoDoc](https://pkg.go.dev/github.com/lbryio/lbcd/database/ffldb?status.png)](https://pkg.go.dev/github.com/lbryio/lbcd/database/ffldb) ======= Package ffldb implements a driver for the database package that uses leveldb for diff --git a/database/internal/treap/README.md b/database/internal/treap/README.md index 14c3159a..28f0c810 100644 --- a/database/internal/treap/README.md +++ b/database/internal/treap/README.md @@ -1,9 +1,9 @@ treap ===== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/database/internal/treap?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/database/internal/treap) +[![GoDoc](https://pkg.go.dev/github.com/lbryio/lbcd/database/internal/treap?status.png)](https://pkg.go.dev/github.com/lbryio/lbcd/database/internal/treap) Package treap implements a treap data structure that is used to hold ordered key/value pairs using a combination of binary search tree and heap semantics. diff --git a/doc.go b/doc.go index ce62a7cc..ee4a9405 100644 --- a/doc.go +++ b/doc.go @@ -71,8 +71,8 @@ Application Options: fee to the given amount in thousands of bytes per minute (default: 15) --listen= Add an interface/port to listen for connections - (default all interfaces port: 8333, testnet: - 18333, signet: 38333) + (default all interfaces port: 9246, testnet: + 19246, regtest: 29246, signet: 39246) --logdir= Directory to log output --maxorphantx= Max number of orphan transactions to keep in memory (default: 100) @@ -123,7 +123,7 @@ Application Options: --rpclimitpass= Password for limited RPC connections --rpclimituser= Username for limited RPC connections --rpclisten= Add an interface/port to listen for RPC - connections (default port: 8334, testnet: 18334) + connections (default port: 9245, testnet: 19245, regtest: 29245) --rpcmaxclients= Max number of RPC clients for standard connections (default: 10) --rpcmaxconcurrentreqs= Max number of concurrent RPC requests that may be diff --git a/docs/code_contribution_guidelines.md b/docs/code_contribution_guidelines.md deleted file mode 100644 index c0a7eecc..00000000 --- a/docs/code_contribution_guidelines.md +++ /dev/null @@ -1,319 +0,0 @@ -# Code contribution guidelines - -Developing cryptocurrencies is an exciting endeavor that touches a wide variety -of areas such as wire protocols, peer-to-peer networking, databases, -cryptography, language interpretation (transaction scripts), RPC, and -websockets. They also represent a radical shift to the current fiscal system -and as a result provide an opportunity to help reshape the entire financial -system. There are few projects that offer this level of diversity and impact -all in one code base. - -However, as exciting as it is, one must keep in mind that cryptocurrencies -represent real money and introducing bugs and security vulnerabilities can have -far more dire consequences than in typical projects where having a small bug is -minimal by comparison. In the world of cryptocurrencies, even the smallest bug -in the wrong area can cost people a significant amount of money. For this -reason, the btcd suite has a formalized and rigorous development process which -is outlined on this page. - -We highly encourage code contributions, however it is imperative that you adhere -to the guidelines established on this page. - -## Minimum Recommended Skillset - -The following list is a set of core competencies that we recommend you possess -before you really start attempting to contribute code to the project. These are -not hard requirements as we will gladly accept code contributions as long as -they follow the guidelines set forth on this page. That said, if you don't have -the following basic qualifications you will likely find it quite difficult to -contribute. - -- A reasonable understanding of bitcoin at a high level (see the - [Required Reading](#ReqReading) section for the original white paper) -- Experience in some type of C-like language -- An understanding of data structures and their performance implications -- Familiarity with unit testing -- Debugging experience -- Ability to understand not only the area you are making a change in, but also - the code your change relies on, and the code which relies on your changed code - -Building on top of those core competencies, the recommended skill set largely -depends on the specific areas you are looking to contribute to. For example, -if you wish to contribute to the cryptography code, you should have a good -understanding of the various aspects involved with cryptography such as the -security and performance implications. - -## Required Reading - -- [Effective Go](http://golang.org/doc/effective_go.html) - The entire btcd - suite follows the guidelines in this document. For your code to be accepted, - it must follow the guidelines therein. -- [Original Satoshi Whitepaper](http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCkQFjAA&url=http%3A%2F%2Fbitcoin.org%2Fbitcoin.pdf&ei=os3VUuH8G4SlsASV74GoAg&usg=AFQjCNEipPLigou_1MfB7DQjXCNdlylrBg&sig2=FaHDuT5z36GMWDEnybDJLg&bvm=bv.59378465,d.b2I) - This is the white paper that started it all. Having a solid - foundation to build on will make the code much more comprehensible. - -## Development Practices - -Developers are expected to work in their own trees and submit pull requests when -they feel their feature or bug fix is ready for integration into the master -branch. - -## Share Early, Share Often - -We firmly believe in the share early, share often approach. The basic premise -of the approach is to announce your plans **before** you start work, and once -you have started working, craft your changes into a stream of small and easily -reviewable commits. - -This approach has several benefits: - -- Announcing your plans to work on a feature **before** you begin work avoids - duplicate work -- It permits discussions which can help you achieve your goals in a way that is - consistent with the existing architecture -- It minimizes the chances of you spending time and energy on a change that - might not fit with the consensus of the community or existing architecture and - potentially be rejected as a result -- Incremental development helps ensure you are on the right track with regards - to the rest of the community -- The quicker your changes are merged to master, the less time you will need to - spend rebasing and otherwise trying to keep up with the main code base - -## Testing - -One of the major design goals of all core btcd packages is to aim for complete -test coverage. This is financial software so bugs and regressions can cost -people real money. For this reason every effort must be taken to ensure the -code is as accurate and bug-free as possible. Thorough testing is a good way to -help achieve that goal. - -Unless a new feature you submit is completely trivial, it will probably be -rejected unless it is also accompanied by adequate test coverage for both -positive and negative conditions. That is to say, the tests must ensure your -code works correctly when it is fed correct data as well as incorrect data -(error paths). - -Go provides an excellent test framework that makes writing test code and -checking coverage statistics straight forward. For more information about the -test coverage tools, see the [golang cover blog post](http://blog.golang.org/cover). - -A quick summary of test practices follows: - -- All new code should be accompanied by tests that ensure the code behaves - correctly when given expected values, and, perhaps even more importantly, that - it handles errors gracefully -- When you fix a bug, it should be accompanied by tests which exercise the bug - to both prove it has been resolved and to prevent future regressions - -## Code Documentation and Commenting - -- At a minimum every function must be commented with its intended purpose and - any assumptions that it makes - - Function comments must always begin with the name of the function per - [Effective Go](http://golang.org/doc/effective_go.html) - - Function comments should be complete sentences since they allow a wide - variety of automated presentations such as [go.dev](https://go.dev) - - The general rule of thumb is to look at it as if you were completely - unfamiliar with the code and ask yourself, would this give me enough - information to understand what this function does and how I'd probably want - to use it? -- Exported functions should also include detailed information the caller of the - function will likely need to know and/or understand: - -**WRONG** - -```Go -// convert a compact uint32 to big.Int -func CompactToBig(compact uint32) *big.Int { -``` - -**RIGHT** - -```Go -// CompactToBig converts a compact representation of a whole number N to a -// big integer. The representation is similar to IEEE754 floating point -// numbers. -// -// Like IEEE754 floating point, there are three basic components: the sign, -// the exponent, and the mantissa. They are broken out as follows: -// -// * the most significant 8 bits represent the unsigned base 256 exponent -// * bit 23 (the 24th bit) represents the sign bit -// * the least significant 23 bits represent the mantissa -// -// ------------------------------------------------- -// | Exponent | Sign | Mantissa | -// ------------------------------------------------- -// | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] | -// ------------------------------------------------- -// -// The formula to calculate N is: -// N = (-1^sign) * mantissa * 256^(exponent-3) -// -// This compact form is only used in bitcoin to encode unsigned 256-bit numbers -// which represent difficulty targets, thus there really is not a need for a -// sign bit, but it is implemented here to stay consistent with bitcoind. -func CompactToBig(compact uint32) *big.Int { -``` - -- Comments in the body of the code are highly encouraged, but they should - explain the intention of the code as opposed to just calling out the - obvious - -**WRONG** - -```Go -// return err if amt is less than 5460 -if amt < 5460 { - return err -} -``` - -**RIGHT** - -```Go -// Treat transactions with amounts less than the amount which is considered dust -// as non-standard. -if amt < 5460 { - return err -} -``` - -**NOTE:** The above should really use a constant as opposed to a magic number, -but it was left as a magic number to show how much of a difference a good -comment can make. - -## Model Git Commit Messages - -This project prefers to keep a clean commit history with well-formed commit -messages. This section illustrates a model commit message and provides a bit -of background for it. This content was originally created by Tim Pope and made -available on his website, however that website is no longer active, so it is -being provided here. - -Here’s a model Git commit message: - -```text -Short (50 chars or less) summary of changes - -More detailed explanatory text, if necessary. Wrap it to about 72 -characters or so. In some contexts, the first line is treated as the -subject of an email and the rest of the text as the body. The blank -line separating the summary from the body is critical (unless you omit -the body entirely); tools like rebase can get confused if you run the -two together. - -Write your commit message in the present tense: "Fix bug" and not "Fixed -bug." This convention matches up with commit messages generated by -commands like git merge and git revert. - -Further paragraphs come after blank lines. - -- Bullet points are okay, too -- Typically a hyphen or asterisk is used for the bullet, preceded by a - single space, with blank lines in between, but conventions vary here -- Use a hanging indent -``` - -Prefix the summary with the subsystem/package when possible. Many other -projects make use of the code and this makes it easier for them to tell when -something they're using has changed. Have a look at [past -commits](https://github.com/btcsuite/btcd/commits/master) for examples of -commit messages. - -Here are some of the reasons why wrapping your commit messages to 72 columns is -a good thing. - -- git log doesn’t do any special special wrapping of the commit messages. With - the default pager of less -S, this means your paragraphs flow far off the edge - of the screen, making them difficult to read. On an 80 column terminal, if we - subtract 4 columns for the indent on the left and 4 more for symmetry on the - right, we’re left with 72 columns. -- git format-patch --stdout converts a series of commits to a series of emails, - using the messages for the message body. Good email netiquette dictates we - wrap our plain text emails such that there’s room for a few levels of nested - reply indicators without overflow in an 80 column terminal. - -## Code Approval Process - -This section describes the code approval process that is used for code -contributions. This is how to get your changes into btcd. - -## Code Review - -All code which is submitted will need to be reviewed before inclusion into the -master branch. This process is performed by the project maintainers and usually -other committers who are interested in the area you are working in as well. - -## Code Review Timeframe - -The timeframe for a code review will vary greatly depending on factors such as -the number of other pull requests which need to be reviewed, the size and -complexity of the contribution, how well you followed the guidelines presented -on this page, and how easy it is for the reviewers to digest your commits. For -example, if you make one monolithic commit that makes sweeping changes to things -in multiple subsystems, it will obviously take much longer to review. You will -also likely be asked to split the commit into several smaller, and hence more -manageable, commits. - -Keeping the above in mind, most small changes will be reviewed within a few -days, while large or far reaching changes may take weeks. This is a good reason -to stick with the [Share Early, Share Often](#ShareOften) development practice -outlined above. - -## What is the review looking for? - -The review is mainly ensuring the code follows the [Development Practices](#DevelopmentPractices) -and [Code Contribution Standards](#Standards). However, there are a few other -checks which are generally performed as follows: - -- The code is stable and has no stability or security concerns -- The code is properly using existing APIs and generally fits well into the - overall architecture -- The change is not something which is deemed inappropriate by community - consensus - -## Rework Code (if needed) - -After the code review, the change will be accepted immediately if no issues are -found. If there are any concerns or questions, you will be provided with -feedback along with the next steps needed to get your contribution merged with -master. In certain cases the code reviewer(s) or interested committers may help -you rework the code, but generally you will simply be given feedback for you to -make the necessary changes. - -This process will continue until the code is finally accepted. - -## Acceptance - -Once your code is accepted, it will be integrated with the master branch. -Typically it will be rebased and fast-forward merged to master as we prefer to -keep a clean commit history over a tangled weave of merge commits. However, -regardless of the specific merge method used, the code will be integrated with -the master branch and the pull request will be closed. - -Rejoice as you will now be listed as a [contributor](https://github.com/btcsuite/btcd/graphs/contributors)! - -## Contribution Standards - -## Contribution Checklist - -- [  ] All changes are Go version 1.3 compliant -- [  ] The code being submitted is commented according to the - [Code Documentation and Commenting](#CodeDocumentation) section -- [  ] For new code: Code is accompanied by tests which exercise both - the positive and negative (error paths) conditions (if applicable) -- [  ] For bug fixes: Code is accompanied by new tests which trigger - the bug being fixed to prevent regressions -- [  ] Any new logging statements use an appropriate subsystem and - logging level -- [  ] Code has been formatted with `go fmt` -- [  ] Running `go test` does not fail any tests -- [  ] Running `go vet` does not report any issues -- [  ] Running [golint](https://github.com/golang/lint) does not - report any **new** issues that did not already exist - -## Licensing of Contributions - -All contributions must be licensed with the -[ISC license](https://github.com/btcsuite/btcd/blob/master/LICENSE). This is -the same license as all of the code in the btcd suite. diff --git a/docs/configuration.md b/docs/configuration.md index c6f95b27..1a02007b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,11 +1,11 @@ # Configuration -btcd has a number of [configuration](https://pkg.go.dev/github.com/btcsuite/btcd) -options, which can be viewed by running: `$ btcd --help`. +lbcd has a number of configuration +options, which can be viewed by running: `$ lbcd --help`. ## Peer server listen interface -btcd allows you to bind to specific interfaces which enables you to setup +lbcd allows you to bind to specific interfaces which enables you to setup configurations with varying levels of complexity. The listen parameter can be specified on the command line as shown below with the -- prefix or in the configuration file without the -- prefix (as can all long command line options). @@ -16,42 +16,42 @@ interfaces as a couple of the examples below illustrate. Command Line Examples: -|Flags|Comment| -|----------|------------| -|--listen=|all interfaces on default port which is changed by `--testnet` and `--regtest` (**default**)| -|--listen=0.0.0.0|all IPv4 interfaces on default port which is changed by `--testnet` and `--regtest`| -|--listen=::|all IPv6 interfaces on default port which is changed by `--testnet` and `--regtest`| -|--listen=:8333|all interfaces on port 8333| -|--listen=0.0.0.0:8333|all IPv4 interfaces on port 8333| -|--listen=[::]:8333|all IPv6 interfaces on port 8333| -|--listen=127.0.0.1:8333|only IPv4 localhost on port 8333| -|--listen=[::1]:8333|only IPv6 localhost on port 8333| -|--listen=:8336|all interfaces on non-standard port 8336| -|--listen=0.0.0.0:8336|all IPv4 interfaces on non-standard port 8336| -|--listen=[::]:8336|all IPv6 interfaces on non-standard port 8336| -|--listen=127.0.0.1:8337 --listen=[::1]:8333|IPv4 localhost on port 8337 and IPv6 localhost on port 8333| -|--listen=:8333 --listen=:8337|all interfaces on ports 8333 and 8337| +| Flags | Comment | +| ------------------------------------------- | -------------------------------------------------------------------------------------------- | +| --listen= | all interfaces on default port which is changed by `--testnet` and `--regtest` (**default**) | +| --listen=0.0.0.0 | all IPv4 interfaces on default port which is changed by `--testnet` and `--regtest` | +| --listen=:: | all IPv6 interfaces on default port which is changed by `--testnet` and `--regtest` | +| --listen=:9246 | all interfaces on port 9246 | +| --listen=0.0.0.0:9246 | all IPv4 interfaces on port 9246 | +| --listen=[::]:9246 | all IPv6 interfaces on port 9246 | +| --listen=127.0.0.1:9246 | only IPv4 localhost on port 9246 | +| --listen=[::1]:9246 | only IPv6 localhost on port 9246 | +| --listen=:9247 | all interfaces on non-standard port 9247 | +| --listen=0.0.0.0:9247 | all IPv4 interfaces on non-standard port 9247 | +| --listen=[::]:9247 | all IPv6 interfaces on non-standard port 9247 | +| --listen=127.0.0.1:9248 --listen=[::1]:9246 | IPv4 localhost on port 9248 and IPv6 localhost on port 9246 | +| --listen=:9246 --listen=:9248 | all interfaces on ports 9246 and 9248 | -The following config file would configure btcd to only listen on localhost for both IPv4 and IPv6: +The following config file would configure lbcd to only listen on localhost for both IPv4 and IPv6: ```text [Application Options] -listen=127.0.0.1:8333 -listen=[::1]:8333 +listen=127.0.0.1:9246 +listen=[::1]:9246 ``` -In addition, if you are starting btcd with TLS and want to make it +In addition, if you are starting lbcd with TLS and want to make it available via a hostname, then you will need to generate the TLS certificates for that host. For example, ``` -gencerts --host=myhostname.example.com --directory=/home/me/.btcd/ +gencerts --host=myhostname.example.com --directory=/home/me/.lbcd/ ``` ## RPC server listen interface -btcd allows you to bind the RPC server to specific interfaces which enables you +lbcd allows you to bind the RPC server to specific interfaces which enables you to setup configurations with varying levels of complexity. The `rpclisten` parameter can be specified on the command line as shown below with the -- prefix or in the configuration file without the -- prefix (as can all long command line @@ -76,23 +76,23 @@ A few things to note regarding the RPC server: Command Line Examples: -|Flags|Comment| -|----------|------------| -|--rpclisten=|all interfaces on default port which is changed by `--testnet`| -|--rpclisten=0.0.0.0|all IPv4 interfaces on default port which is changed by `--testnet`| -|--rpclisten=::|all IPv6 interfaces on default port which is changed by `--testnet`| -|--rpclisten=:8334|all interfaces on port 8334| -|--rpclisten=0.0.0.0:8334|all IPv4 interfaces on port 8334| -|--rpclisten=[::]:8334|all IPv6 interfaces on port 8334| -|--rpclisten=127.0.0.1:8334|only IPv4 localhost on port 8334| -|--rpclisten=[::1]:8334|only IPv6 localhost on port 8334| -|--rpclisten=:8336|all interfaces on non-standard port 8336| -|--rpclisten=0.0.0.0:8336|all IPv4 interfaces on non-standard port 8336| -|--rpclisten=[::]:8336|all IPv6 interfaces on non-standard port 8336| -|--rpclisten=127.0.0.1:8337 --listen=[::1]:8334|IPv4 localhost on port 8337 and IPv6 localhost on port 8334| -|--rpclisten=:8334 --listen=:8337|all interfaces on ports 8334 and 8337| +| Flags | Comment | +| ---------------------------------------------- | ------------------------------------------------------------------- | +| --rpclisten= | all interfaces on default port which is changed by `--testnet` | +| --rpclisten=0.0.0.0 | all IPv4 interfaces on default port which is changed by `--testnet` | +| --rpclisten=:: | all IPv6 interfaces on default port which is changed by `--testnet` | +| --rpclisten=:9245 | all interfaces on port 9245 | +| --rpclisten=0.0.0.0:9245 | all IPv4 interfaces on port 9245 | +| --rpclisten=[::]:9245 | all IPv6 interfaces on port 9245 | +| --rpclisten=127.0.0.1:9245 | only IPv4 localhost on port 9245 | +| --rpclisten=[::1]:9245 | only IPv6 localhost on port 9245 | +| --rpclisten=:9247 | all interfaces on non-standard port 9247 | +| --rpclisten=0.0.0.0:9247 | all IPv4 interfaces on non-standard port 9247 | +| --rpclisten=[::]:9247 | all IPv6 interfaces on non-standard port 9247 | +| --rpclisten=127.0.0.1:9248 --listen=[::1]:9245 | IPv4 localhost on port 9248 and IPv6 localhost on port 9245 | +| --rpclisten=:9245 --listen=:9248 | all interfaces on ports 9245 and 9248 | -The following config file would configure the btcd RPC server to listen to all interfaces on the default port, including external interfaces, for both IPv4 and IPv6: +The following config file would configure the lbcd RPC server to listen to all interfaces on the default port, including external interfaces, for both IPv4 and IPv6: ```text [Application Options] @@ -102,21 +102,21 @@ rpclisten= ## Default ports -While btcd is highly configurable when it comes to the network configuration, +While lbcd is highly configurable when it comes to the network configuration, the following is intended to be a quick reference for the default ports used so port forwarding can be configured as required. -btcd provides a `--upnp` flag which can be used to automatically map the bitcoin +lbcd by default will automatically map the peer-to-peer listening port if your router supports UPnP. If your router does -not support UPnP, or you don't wish to use it, please note that only the bitcoin +not support UPnP, or you don't wish to use it, please note that only the peer-to-peer port should be forwarded unless you specifically want to allow RPC -access to your btcd from external sources such as in more advanced network -configurations. +access to your lbcd from external sources such as in more advanced network +configurations. You can disable UPnP with the `--noupnp` daemon option. -|Name|Port| -|----|----| -|Default Bitcoin peer-to-peer port|TCP 8333| -|Default RPC port|TCP 8334| +| Name | Port | +| ------------------------- | -------- | +| Default peer-to-peer port | TCP 9246 | +| Default RPC port | TCP 9245 | ## Using bootstrap.dat @@ -129,7 +129,7 @@ on the last time it was updated. See [this](https://bitcointalk.org/index.php?topic=145386.0) thread on bitcointalk for more details. -**NOTE:** Using bootstrap.dat is entirely optional. Btcd will download the +**NOTE:** Using bootstrap.dat is entirely optional. lbcd will download the block chain from other peers through the Bitcoin protocol with no extra configuration needed. @@ -165,14 +165,14 @@ checkpoints for the known-good block chain at periodic intervals. This ensures that not only is it a valid chain, but it is the same chain that everyone else is using. -### How do I use bootstrap.dat with btcd? +### How do I use bootstrap.dat with lbcd? -btcd comes with a separate utility named `addblock` which can be used to import +lbcd comes with a separate utility named `addblock` which can be used to import `bootstrap.dat`. This approach is used since the import is a one-time operation and we prefer to keep the daemon itself as lightweight as possible. -1. Stop btcd if it is already running. This is required since addblock needs to - access the database used by btcd and it will be locked if btcd is using it. +1. Stop lbcd if it is already running. This is required since addblock needs to + access the database used by lbcd and it will be locked if lbcd is using it. 2. Note the path to the downloaded bootstrap.dat file. 3. Run the addblock utility with the `-i` argument pointing to the location of boostrap.dat: @@ -180,7 +180,7 @@ and we prefer to keep the daemon itself as lightweight as possible. **Windows:** ```bat -"%PROGRAMFILES%\Btcd Suite\Btcd\addblock" -i C:\Path\To\bootstrap.dat +"%PROGRAMFILES%\lbcd Suite\lbcd\addblock" -i C:\Path\To\bootstrap.dat ``` **Linux/Unix/BSD/POSIX:** diff --git a/docs/configuring_tor.md b/docs/configuring_tor.md index ecb03bfc..84bc0efd 100644 --- a/docs/configuring_tor.md +++ b/docs/configuring_tor.md @@ -1,9 +1,9 @@ # Configuring TOR -btcd provides full support for anonymous networking via the +lbcd provides full support for anonymous networking via the [Tor Project](https://www.torproject.org/), including [client-only](#Client) and [hidden service](#HiddenService) configurations along with -[stream isolation](#TorStreamIsolation). In addition, btcd supports a hybrid, +[stream isolation](#TorStreamIsolation). In addition, lbcd supports a hybrid, [bridge mode](#Bridge) which is not anonymous, but allows it to operate as a bridge between regular nodes and hidden service nodes without routing the regular connections through Tor. @@ -15,15 +15,15 @@ hidden service for this reason. ## Client-only -Configuring btcd as a Tor client is straightforward. The first step is +Configuring lbcd as a Tor client is straightforward. The first step is obviously to install Tor and ensure it is working. Once that is done, all that -typically needs to be done is to specify the `--proxy` flag via the btcd command -line or in the btcd configuration file. Typically the Tor proxy address will be +typically needs to be done is to specify the `--proxy` flag via the lbcd command +line or in the lbcd configuration file. Typically the Tor proxy address will be 127.0.0.1:9050 (if using standalone Tor) or 127.0.0.1:9150 (if using the Tor Browser Bundle). If you have Tor configured to require a username and password, you may specify them with the `--proxyuser` and `--proxypass` flags. -By default, btcd assumes the proxy specified with `--proxy` is a Tor proxy and +By default, lbcd assumes the proxy specified with `--proxy` is a Tor proxy and hence will send all traffic, including DNS resolution requests, via the specified proxy. @@ -34,7 +34,7 @@ not be reachable for inbound connections unless you also configure a Tor ### Command line example ```bash -./btcd --proxy=127.0.0.1:9050 +./lbcd --proxy=127.0.0.1:9050 ``` ### Config file example @@ -51,7 +51,7 @@ The first step is to configure Tor to provide a hidden service. Documentation for this can be found on the Tor project website [here](https://www.torproject.org/docs/tor-hidden-service.html.en). However, there is no need to install a web server locally as the linked instructions -discuss since btcd will act as the server. +discuss since lbcd will act as the server. In short, the instructions linked above entail modifying your `torrc` file to add something similar to the following, restarting Tor, and opening the @@ -59,12 +59,12 @@ add something similar to the following, restarting Tor, and opening the address. ```text -HiddenServiceDir /var/tor/btcd -HiddenServicePort 8333 127.0.0.1:8333 +HiddenServiceDir /var/tor/lbcd +HiddenServicePort 9246 127.0.0.1:9246 ``` Once Tor is configured to provide the hidden service and you have obtained your -generated .onion address, configuring btcd as a Tor hidden service requires +generated .onion address, configuring lbcd as a Tor hidden service requires three flags: * `--proxy` to identify the Tor (SOCKS 5) proxy to use for outgoing traffic. @@ -76,7 +76,7 @@ three flags: ### Command line example ```bash -./btcd --proxy=127.0.0.1:9050 --listen=127.0.0.1 --externalip=fooanon.onion +./lbcd --proxy=127.0.0.1:9050 --listen=127.0.0.1 --externalip=fooanon.onion ``` ### Config file example @@ -91,13 +91,13 @@ externalip=fooanon.onion ## Bridge mode (not anonymous) -btcd provides support for operating as a bridge between regular nodes and hidden +lbcd provides support for operating as a bridge between regular nodes and hidden service nodes. In particular this means only traffic which is directed to or from a .onion address is sent through Tor while other traffic is sent normally. _As a result, this mode is **NOT** anonymous._ This mode works by specifying an onion-specific proxy, which is pointed at Tor, -by using the `--onion` flag via the btcd command line or in the btcd +by using the `--onion` flag via the lbcd command line or in the lbcd configuration file. If you have Tor configured to require a username and password, you may specify them with the `--onionuser` and `--onionpass` flags. @@ -111,7 +111,7 @@ routed via Tor due to the `--onion` flag. ### Command line example ```bash -./btcd --onion=127.0.0.1:9050 --externalip=fooanon.onion +./lbcd --onion=127.0.0.1:9050 --externalip=fooanon.onion ``` ### Config file example @@ -128,13 +128,13 @@ externalip=fooanon.onion Tor stream isolation forces Tor to build a new circuit for each connection making it harder to correlate connections. -btcd provides support for Tor stream isolation by using the `--torisolation` +lbcd provides support for Tor stream isolation by using the `--torisolation` flag. This option requires --proxy or --onionproxy to be set. ### Command line example ```bash -./btcd --proxy=127.0.0.1:9050 --torisolation +./lbcd --proxy=127.0.0.1:9050 --torisolation ``` ### Config file example diff --git a/docs/contact.md b/docs/contact.md deleted file mode 100644 index 1ed9fc0b..00000000 --- a/docs/contact.md +++ /dev/null @@ -1,15 +0,0 @@ -# Contact - -## IRC - -* [irc.libera.chat](irc://irc.libera.chat), channel `#btcd` - -## Mailing Lists - -* [btcd](mailto:btcd+subscribe@opensource.conformal.com): discussion of btcd and its packages. -* [btcd-commits](mailto:btcd-commits+subscribe@opensource.conformal.com): readonly mail-out of source code changes. - -## Issue Tracker - -The [integrated github issue tracker](https://github.com/btcsuite/btcd/issues) -is used for this project. diff --git a/docs/controlling.md b/docs/controlling.md index 93ab403b..a187e412 100644 --- a/docs/controlling.md +++ b/docs/controlling.md @@ -1,11 +1,11 @@ -# Controlling and querying btcd via btcctl +# Controlling and querying lbcd via lbcctl -btcctl is a command line utility that can be used to both control and query btcd -via [RPC](http://www.wikipedia.org/wiki/Remote_procedure_call). btcd does +lbcctl is a command line utility that can be used to both control and query lbcd +via [RPC](http://www.wikipedia.org/wiki/Remote_procedure_call). lbcd does **not** enable its RPC server by default; You must configure at minimum both an RPC username and password or both an RPC limited username and password: -* btcd.conf configuration file +* lbcd.conf configuration file ```bash [Application Options] @@ -15,7 +15,7 @@ rpclimituser=mylimituser rpclimitpass=Limitedp4ssw0rd ``` -* btcctl.conf configuration file +* lbcctl.conf configuration file ```bash [Application Options] @@ -31,4 +31,4 @@ rpclimituser=mylimituser rpclimitpass=Limitedp4ssw0rd ``` -For a list of available options, run: `$ btcctl --help` +For a list of available options, run: `$ lbcctl --help` diff --git a/docs/developer_resources.md b/docs/developer_resources.md deleted file mode 100644 index cec8ce99..00000000 --- a/docs/developer_resources.md +++ /dev/null @@ -1,37 +0,0 @@ -# Developer Resources - -* [Code Contribution Guidelines](https://github.com/btcsuite/btcd/tree/master/docs/code_contribution_guidelines.md) - -* [JSON-RPC Reference](https://github.com/btcsuite/btcd/tree/master/docs/json_rpc_api.md) - * [RPC Examples](https://github.com/btcsuite/btcd/tree/master/docs/json_rpc_api.md#ExampleCode) - -* The btcsuite Bitcoin-related Go Packages: - * [btcrpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) - Implements a - robust and easy to use Websocket-enabled Bitcoin JSON-RPC client - * [btcjson](https://github.com/btcsuite/btcd/tree/master/btcjson) - Provides an extensive API - for the underlying JSON-RPC command and return values - * [wire](https://github.com/btcsuite/btcd/tree/master/wire) - Implements the - Bitcoin wire protocol - * [peer](https://github.com/btcsuite/btcd/tree/master/peer) - - Provides a common base for creating and managing Bitcoin network peers. - * [blockchain](https://github.com/btcsuite/btcd/tree/master/blockchain) - - Implements Bitcoin block handling and chain selection rules - * [blockchain/fullblocktests](https://github.com/btcsuite/btcd/tree/master/blockchain/fullblocktests) - - Provides a set of block tests for testing the consensus validation rules - * [txscript](https://github.com/btcsuite/btcd/tree/master/txscript) - - Implements the Bitcoin transaction scripting language - * [btcec](https://github.com/btcsuite/btcd/tree/master/btcec) - Implements - support for the elliptic curve cryptographic functions needed for the - Bitcoin scripts - * [database](https://github.com/btcsuite/btcd/tree/master/database) - - Provides a database interface for the Bitcoin block chain - * [mempool](https://github.com/btcsuite/btcd/tree/master/mempool) - - Package mempool provides a policy-enforced pool of unmined bitcoin - transactions. - * [btcutil](https://github.com/btcsuite/btcutil) - Provides Bitcoin-specific - convenience functions and types - * [chainhash](https://github.com/btcsuite/btcd/tree/master/chaincfg/chainhash) - - Provides a generic hash type and associated functions that allows the - specific hash algorithm to be abstracted. - * [connmgr](https://github.com/btcsuite/btcd/tree/master/connmgr) - - Package connmgr implements a generic Bitcoin network connection manager. diff --git a/docs/index.md b/docs/index.md index 9d980626..a3792a6f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,57 +1,11 @@ -# btcd +# lbcd -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd) - -btcd is an alternative full node bitcoin implementation written in Go (golang). - -This project is currently under active development and is in a Beta state. It -is extremely stable and has been in production use since October 2013. - -It properly downloads, validates, and serves the block chain using the exact -rules (including consensus bugs) for block acceptance as Bitcoin Core. We have -taken great care to avoid btcd causing a fork to the block chain. It includes a -full block validation testing framework which contains all of the 'official' -block acceptance tests (and some additional ones) that is run on every pull -request to help ensure it properly follows consensus. Also, it passes all of -the JSON test data in the Bitcoin Core code. - -It also properly relays newly mined blocks, maintains a transaction pool, and -relays individual transactions that have not yet made it into a block. It -ensures all individual transactions admitted to the pool follow the rules -required by the block chain and also includes more strict checks which filter -transactions based on miner requirements ("standard" transactions). - -One key difference between btcd and Bitcoin Core is that btcd does *NOT* include -wallet functionality and this was a very intentional design decision. See the -blog entry [here](https://web.archive.org/web/20171125143919/https://blog.conformal.com/btcd-not-your-moms-bitcoin-daemon) -for more details. This means you can't actually make or receive payments -directly with btcd. That functionality is provided by the -[btcwallet](https://github.com/btcsuite/btcwallet) and -[Paymetheus](https://github.com/btcsuite/Paymetheus) (Windows-only) projects -which are both under active development. - -## Documentation - -Documentation is a work-in-progress. It is available at [btcd.readthedocs.io](https://btcd.readthedocs.io). ## Contents -* [Installation](installation.md) -* [Update](update.md) * [Configuration](configuration.md) * [Configuring TOR](configuring_tor.md) -* [Docker](using_docker.md) * [Controlling](controlling.md) * [Mining](mining.md) -* [Wallet](wallet.md) -* [Developer resources](developer_resources.md) * [JSON RPC API](json_rpc_api.md) -* [Code contribution guidelines](code_contribution_guidelines.md) -* [Contact](contact.md) - -## License - -btcd is licensed under the [copyfree](http://copyfree.org) ISC License. - diff --git a/docs/installation.md b/docs/installation.md deleted file mode 100644 index a74db560..00000000 --- a/docs/installation.md +++ /dev/null @@ -1,76 +0,0 @@ -# Installation - -The first step is to install btcd. See one of the following sections for -details on how to install on the supported operating systems. - -## Requirements - -[Go](http://golang.org) 1.16 or newer. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -* Download the Conformal public key: - https://raw.githubusercontent.com/btcsuite/btcd/master/release/GIT-GPG-KEY-conformal.txt - -* Import the public key into your GPG keyring: - - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -* Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - - ```bash - git tag -v TAG_NAME - ``` - -## Windows Installation - -* Install the MSI available at: [btcd windows installer](https://github.com/btcsuite/btcd/releases) -* Launch btcd from the Start Menu - -## Linux/BSD/MacOSX/POSIX Installation - -* Install Go according to the [installation instructions](http://golang.org/doc/install) -* Ensure Go was installed properly and is a supported version: - -```bash -go version -go env GOROOT GOPATH -``` - -NOTE: The `GOROOT` and `GOPATH` above must not be the same path. It is -recommended that `GOPATH` is set to a directory in your home directory such as -`~/goprojects` to avoid write permission issues. It is also recommended to add -`$GOPATH/bin` to your `PATH` at this point. - -* Run the following commands to obtain btcd, all dependencies, and install it: - -```bash -git clone https://github.com/btcsuite/btcd $GOPATH/src/github.com/btcsuite/btcd -cd $GOPATH/src/github.com/btcsuite/btcd -GO111MODULE=on go install -v . ./cmd/... -``` - -* btcd (and utilities) will now be installed in ```$GOPATH/bin```. If you did - not already add the bin directory to your system path during Go installation, - we recommend you do so now. - -## Gentoo Linux Installation - -* [Install Layman](https://gitlab.com/bitcoin/gentoo) and enable the Bitcoin overlay. -* Copy or symlink `/var/lib/layman/bitcoin/Documentation/package.keywords/btcd-live` to `/etc/portage/package.keywords/` -* Install btcd: `$ emerge net-p2p/btcd` - -## Startup - -Typically btcd will run and start downloading the block chain with no extra -configuration necessary, however, there is an optional method to use a -`bootstrap.dat` file that may speed up the initial block chain download process. - -* [Using bootstrap.dat](https://github.com/btcsuite/btcd/blob/master/docs/configuration.md#using-bootstrapdat) diff --git a/docs/json_rpc_api.md b/docs/json_rpc_api.md index db292d2b..17ccba64 100644 --- a/docs/json_rpc_api.md +++ b/docs/json_rpc_api.md @@ -27,27 +27,19 @@ ### 1. Overview -btcd provides a [JSON-RPC](http://json-rpc.org/wiki/specification) API that is +lbcd provides a [JSON-RPC](http://json-rpc.org/wiki/specification) API that is fully compatible with the original bitcoind/bitcoin-qt. There are a few key -differences between btcd and bitcoind as far as how RPCs are serviced: -* Unlike bitcoind that has the wallet and chain intermingled in the same process - which leads to several issues, btcd intentionally splits the wallet and chain - services into independent processes. See the blog post - [here](https://blog.conformal.com/btcd-not-your-moms-bitcoin-daemon/) for - further details on why they were separated. This means that if you are - talking directly to btcd, only chain-related RPCs are available. However both - chain-related and wallet-related RPCs are available via - [btcwallet](https://github.com/btcsuite/btcwallet). -* btcd is secure by default which means that the RPC connection is TLS-enabled +differences between lbcd and bitcoind as far as how RPCs are serviced: +* lbcd is secure by default which means that the RPC connection is TLS-enabled by default -* btcd provides access to the API through both +* lbcd provides access to the API through both [HTTP POST](http://en.wikipedia.org/wiki/POST_%28HTTP%29) requests and [Websockets](http://en.wikipedia.org/wiki/WebSocket) -Websockets are the preferred transport for btcd RPC and are used by applications +Websockets are the preferred transport for lbcd RPC and are used by applications such as [btcwallet](https://github.com/btcsuite/btcwallet) for inter-process -communication with btcd. The websocket connection endpoint for btcd is -`wss://your_ip_or_domain:8334/ws`. +communication with lbcd. The websocket connection endpoint for lbcd is +`wss://your_ip_or_domain:9245/ws`. In addition to the [standard API](#Methods), an [extension API](#WSExtMethods) has been developed that is exclusive to clients using Websockets. In its current @@ -64,7 +56,7 @@ The original bitcoind/bitcoin-qt JSON-RPC API documentation is available at [htt ### 2. HTTP POST Versus Websockets -The btcd RPC server supports both [HTTP POST](http://en.wikipedia.org/wiki/POST_%28HTTP%29) +The lbcd RPC server supports both [HTTP POST](http://en.wikipedia.org/wiki/POST_%28HTTP%29) requests and the preferred [Websockets](http://en.wikipedia.org/wiki/WebSocket). All of the [standard](#Methods) and [extension](#ExtensionMethods) methods described in this documentation can be accessed through both. As the name @@ -72,16 +64,16 @@ indicates, the [Websocket-specific extension](#WSExtMethods) methods can only be accessed when connected via Websockets. As mentioned in the [overview](#Overview), the websocket connection endpoint for -btcd is `wss://your_ip_or_domain:8334/ws`. +lbcd is `wss://your_ip_or_domain:9245/ws`. The most important differences between the two transports as it pertains to the JSON-RPC API are: -| |HTTP POST Requests|Websockets| -|---|------------------|----------| -|Allows multiple requests across a single connection|No|Yes| -|Supports asynchronous notifications|No|Yes| -|Scales well with large numbers of requests|No|Yes| +| | HTTP POST Requests | Websockets | +| --------------------------------------------------- | ------------------ | ---------- | +| Allows multiple requests across a single connection | No | Yes | +| Supports asynchronous notifications | No | Yes | +| Scales well with large numbers of requests | No | Yes | @@ -92,18 +84,18 @@ JSON-RPC API are: **3.1 Authentication Overview**
The following authentication details are needed before establishing a connection -to a btcd RPC server: +to a lbcd RPC server: -* **rpcuser** is the full-access username configured for the btcd RPC server -* **rpcpass** is the full-access password configured for the btcd RPC server -* **rpclimituser** is the limited username configured for the btcd RPC server -* **rpclimitpass** is the limited password configured for the btcd RPC server -* **rpccert** is the PEM-encoded X.509 certificate (public key) that the btcd - server is configured with. It is automatically generated by btcd and placed - in the btcd home directory (which is typically `%LOCALAPPDATA%\Btcd` on - Windows and `~/.btcd` on POSIX-like OSes) +* **rpcuser** is the full-access username configured for the lbcd RPC server +* **rpcpass** is the full-access password configured for the lbcd RPC server +* **rpclimituser** is the limited username configured for the lbcd RPC server +* **rpclimitpass** is the limited password configured for the lbcd RPC server +* **rpccert** is the PEM-encoded X.509 certificate (public key) that the lbcd + server is configured with. It is automatically generated by lbcd and placed + in the lbcd home directory (which is typically `%LOCALAPPDATA%\lbcd` on + Windows and `~/.lbcd` on POSIX-like OSes) -**NOTE:** As mentioned above, btcd is secure by default which means the RPC +**NOTE:** As mentioned above, lbcd is secure by default which means the RPC server is not running unless configured with a **rpcuser** and **rpcpass** and/or a **rpclimituser** and **rpclimitpass**, and uses TLS authentication for all connections. @@ -117,7 +109,7 @@ two, mutually exclusive, methods. **3.2 HTTP Basic Access Authentication**
-The btcd RPC server uses HTTP [basic access authentication](http://en.wikipedia.org/wiki/Basic_access_authentication) with the **rpcuser** +The lbcd RPC server uses HTTP [basic access authentication](http://en.wikipedia.org/wiki/Basic_access_authentication) with the **rpcuser** and **rpcpass** detailed above. If the supplied credentials are invalid, you will be disconnected immediately upon making the connection. @@ -139,8 +131,8 @@ authenticated will cause the websocket to be closed immediately. ### 4. Command-line Utility -btcd comes with a separate utility named `btcctl` which can be used to issue -these RPC commands via HTTP POST requests to btcd after configuring it with the +lbcd comes with a separate utility named `lbcctl` which can be used to issue +these RPC commands via HTTP POST requests to lbcd after configuring it with the information in the [Authentication](#Authentication) section above. It can also be used to communicate with any server/daemon/service which provides a JSON-RPC API compatible with the original bitcoind/bitcoin-qt client. @@ -156,38 +148,38 @@ API compatible with the original bitcoind/bitcoin-qt client. The following is an overview of the RPC methods and their current status. Click the method name for further details such as parameter and return information. -|#|Method|Safe for limited user?|Description| -|---|------|----------|-----------| -|1|[addnode](#addnode)|N|Attempts to add or remove a persistent peer.| -|2|[createrawtransaction](#createrawtransaction)|Y|Returns a new transaction spending the provided inputs and sending to the provided addresses.| -|3|[decoderawtransaction](#decoderawtransaction)|Y|Returns a JSON object representing the provided serialized, hex-encoded transaction.| -|4|[decodescript](#decodescript)|Y|Returns a JSON object with information about the provided hex-encoded script.| -|5|[getaddednodeinfo](#getaddednodeinfo)|N|Returns information about manually added (persistent) peers.| -|6|[getbestblockhash](#getbestblockhash)|Y|Returns the hash of the of the best (most recent) block in the longest block chain.| -|7|[getblock](#getblock)|Y|Returns information about a block given its hash.| -|8|[getblockcount](#getblockcount)|Y|Returns the number of blocks in the longest block chain.| -|9|[getblockhash](#getblockhash)|Y|Returns hash of the block in best block chain at the given height.| -|10|[getblockheader](#getblockheader)|Y|Returns the block header of the block.| -|11|[getconnectioncount](#getconnectioncount)|N|Returns the number of active connections to other peers.| -|12|[getdifficulty](#getdifficulty)|Y|Returns the proof-of-work difficulty as a multiple of the minimum difficulty.| -|13|[getgenerate](#getgenerate)|N|Return if the server is set to generate coins (mine) or not.| -|14|[gethashespersec](#gethashespersec)|N|Returns a recent hashes per second performance measurement while generating coins (mining).| -|15|[getinfo](#getinfo)|Y|Returns a JSON object containing various state info.| -|16|[getmempoolinfo](#getmempoolinfo)|N|Returns a JSON object containing mempool-related information.| -|17|[getmininginfo](#getmininginfo)|N|Returns a JSON object containing mining-related information.| -|18|[getnettotals](#getnettotals)|Y|Returns a JSON object containing network traffic statistics.| -|19|[getnetworkhashps](#getnetworkhashps)|Y|Returns the estimated network hashes per second for the block heights provided by the parameters.| -|20|[getpeerinfo](#getpeerinfo)|N|Returns information about each connected network peer as an array of json objects.| -|21|[getrawmempool](#getrawmempool)|Y|Returns an array of hashes for all of the transactions currently in the memory pool.| -|22|[getrawtransaction](#getrawtransaction)|Y|Returns information about a transaction given its hash.| -|23|[help](#help)|Y|Returns a list of all commands or help for a specified command.| -|24|[ping](#ping)|N|Queues a ping to be sent to each connected peer.| -|25|[sendrawtransaction](#sendrawtransaction)|Y|Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.
btcd does not yet implement the `allowhighfees` parameter, so it has no effect| -|26|[setgenerate](#setgenerate) |N|Set the server to generate coins (mine) or not.
NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.| -|27|[stop](#stop)|N|Shutdown btcd.| -|28|[submitblock](#submitblock)|Y|Attempts to submit a new serialized, hex-encoded block to the network.| -|29|[validateaddress](#validateaddress)|Y|Verifies the given address is valid. NOTE: Since btcd does not have a wallet integrated, btcd will only return whether the address is valid or not.| -|30|[verifychain](#verifychain)|N|Verifies the block chain database.| +| # | Method | Safe for limited user? | Description | +| --- | --------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | [addnode](#addnode) | N | Attempts to add or remove a persistent peer. | +| 2 | [createrawtransaction](#createrawtransaction) | Y | Returns a new transaction spending the provided inputs and sending to the provided addresses. | +| 3 | [decoderawtransaction](#decoderawtransaction) | Y | Returns a JSON object representing the provided serialized, hex-encoded transaction. | +| 4 | [decodescript](#decodescript) | Y | Returns a JSON object with information about the provided hex-encoded script. | +| 5 | [getaddednodeinfo](#getaddednodeinfo) | N | Returns information about manually added (persistent) peers. | +| 6 | [getbestblockhash](#getbestblockhash) | Y | Returns the hash of the of the best (most recent) block in the longest block chain. | +| 7 | [getblock](#getblock) | Y | Returns information about a block given its hash. | +| 8 | [getblockcount](#getblockcount) | Y | Returns the number of blocks in the longest block chain. | +| 9 | [getblockhash](#getblockhash) | Y | Returns hash of the block in best block chain at the given height. | +| 10 | [getblockheader](#getblockheader) | Y | Returns the block header of the block. | +| 11 | [getconnectioncount](#getconnectioncount) | N | Returns the number of active connections to other peers. | +| 12 | [getdifficulty](#getdifficulty) | Y | Returns the proof-of-work difficulty as a multiple of the minimum difficulty. | +| 13 | [getgenerate](#getgenerate) | N | Return if the server is set to generate coins (mine) or not. | +| 14 | [gethashespersec](#gethashespersec) | N | Returns a recent hashes per second performance measurement while generating coins (mining). | +| 15 | [getinfo](#getinfo) | Y | Returns a JSON object containing various state info. | +| 16 | [getmempoolinfo](#getmempoolinfo) | N | Returns a JSON object containing mempool-related information. | +| 17 | [getmininginfo](#getmininginfo) | N | Returns a JSON object containing mining-related information. | +| 18 | [getnettotals](#getnettotals) | Y | Returns a JSON object containing network traffic statistics. | +| 19 | [getnetworkhashps](#getnetworkhashps) | Y | Returns the estimated network hashes per second for the block heights provided by the parameters. | +| 20 | [getpeerinfo](#getpeerinfo) | N | Returns information about each connected network peer as an array of json objects. | +| 21 | [getrawmempool](#getrawmempool) | Y | Returns an array of hashes for all of the transactions currently in the memory pool. | +| 22 | [getrawtransaction](#getrawtransaction) | Y | Returns information about a transaction given its hash. | +| 23 | [help](#help) | Y | Returns a list of all commands or help for a specified command. | +| 24 | [ping](#ping) | N | Queues a ping to be sent to each connected peer. | +| 25 | [sendrawtransaction](#sendrawtransaction) | Y | Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.
lbcd does not yet implement the `allowhighfees` parameter, so it has no effect | +| 26 | [setgenerate](#setgenerate) | N | Set the server to generate coins (mine) or not.
NOTE: Since lbcd does not have the wallet integrated to provide payment addresses, lbcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function. | +| 27 | [stop](#stop) | N | Shutdown lbcd. | +| 28 | [submitblock](#submitblock) | Y | Attempts to submit a new serialized, hex-encoded block to the network. | +| 29 | [validateaddress](#validateaddress) | Y | Verifies the given address is valid. NOTE: Since lbcd does not have a wallet integrated, lbcd will only return whether the address is valid or not. | +| 30 | [verifychain](#verifychain) | N | Verifies the block chain database. |
@@ -195,370 +187,370 @@ the method name for further details such as parameter and return information. -| | | -|---|---| -|Method|addnode| -|Parameters|1. peer (string, required) - ip address and port of the peer to operate on
2. command (string, required) - `add` to add a persistent peer, `remove` to remove a persistent peer, or `onetry` to try a single connection to a peer| -|Description|Attempts to add or remove a persistent peer.| -|Returns|Nothing| +| | | +| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | addnode | +| Parameters | 1. peer (string, required) - ip address and port of the peer to operate on
2. command (string, required) - `add` to add a persistent peer, `remove` to remove a persistent peer, or `onetry` to try a single connection to a peer | +| Description | Attempts to add or remove a persistent peer. | +| Returns | Nothing | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|createrawtransaction| -|Parameters|1. transaction inputs (JSON array, required) - json array of json objects
`[`
  `{`
    `"txid": "hash", (string, required) the hash of the input transaction`
    `"vout": n (numeric, required) the specific output of the input transaction to redeem`
  `}, ...`
`]`
2. addresses and amounts (JSON object, required) - json object with addresses as keys and amounts as values
`{`
  `"address": n.nnn (numeric, required) the address to send to as the key and the amount in BTC as the value`
  `, ...`
`}`
3. locktime (int64, optional, default=0) - specifies the transaction locktime. If non-zero, the inputs will also have their locktimes activated. | -|Description|Returns a new transaction spending the provided inputs and sending to the provided addresses.
The transaction inputs are not signed in the created transaction.
The `signrawtransaction` RPC command provided by wallet must be used to sign the resulting transaction.| -|Returns|`"transaction" (string) hex-encoded bytes of the serialized transaction`| -|Example Parameters|1. transaction inputs `[{"txid":"e6da89de7a6b8508ce8f371a3d0535b04b5e108cb1a6e9284602d3bfd357c018","vout":1}]`
2. addresses and amounts `{"13cgrTP7wgbZYWrY9BZ22BV6p82QXQT3nY": 0.49213337}`
3. locktime `0`| -|Example Return|`010000000118c057d3bfd3024628e9a6b18c105e4bb035053d1a378fce08856b7ade89dae6010000`
`0000ffffffff0199efee02000000001976a9141cb013db35ecccc156fdfd81d03a11c51998f99388`
`ac00000000`
**Newlines added for display purposes. The actual return does not contain newlines.**| +| | | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | createrawtransaction | +| Parameters | 1. transaction inputs (JSON array, required) - json array of json objects
`[`
  `{`
    `"txid": "hash", (string, required) the hash of the input transaction`
    `"vout": n (numeric, required) the specific output of the input transaction to redeem`
  `}, ...`
`]`
2. addresses and amounts (JSON object, required) - json object with addresses as keys and amounts as values
`{`
  `"address": n.nnn (numeric, required) the address to send to as the key and the amount in BTC as the value`
  `, ...`
`}`
3. locktime (int64, optional, default=0) - specifies the transaction locktime. If non-zero, the inputs will also have their locktimes activated. | +| Description | Returns a new transaction spending the provided inputs and sending to the provided addresses.
The transaction inputs are not signed in the created transaction.
The `signrawtransaction` RPC command provided by wallet must be used to sign the resulting transaction. | +| Returns | `"transaction" (string) hex-encoded bytes of the serialized transaction` | +| Example Parameters | 1. transaction inputs `[{"txid":"e6da89de7a6b8508ce8f371a3d0535b04b5e108cb1a6e9284602d3bfd357c018","vout":1}]`
2. addresses and amounts `{"13cgrTP7wgbZYWrY9BZ22BV6p82QXQT3nY": 0.49213337}`
3. locktime `0` | +| Example Return | `010000000118c057d3bfd3024628e9a6b18c105e4bb035053d1a378fce08856b7ade89dae6010000`
`0000ffffffff0199efee02000000001976a9141cb013db35ecccc156fdfd81d03a11c51998f99388`
`ac00000000`
**Newlines added for display purposes. The actual return does not contain newlines.** | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|decoderawtransaction| -|Parameters|1. data (string, required) - serialized, hex-encoded transaction| -|Description|Returns a JSON object representing the provided serialized, hex-encoded transaction.| -|Returns|`{ (json object)`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}`| -|Example Return|`{`
  `"txid": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"version": 1,`
  `"locktime": 0,`
  `"vin": [`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6...",`
      `"sequence": 4294967295,`
    `}`
  For non-coinbase transactions:
    `{`
      `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
      `"vout": 0,`
      `"scriptSig": {`
        `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
        `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
      `}`
      `"sequence": 4294967295,`
    `}`
  `]`
  `"vout": [`
    `{`
      `"value": 50,`
      `"n": 0,`
      `"scriptPubKey": {`
        `"asm": "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4ce...",`
        `"hex": "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4...",`
        `"reqSigs": 1,`
        `"type": "pubkey"`
        `"addresses": [`
          `"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",`
        `]`
      `}`
    `}`
  `]`
`}`| +| | | +| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | decoderawtransaction | +| Parameters | 1. data (string, required) - serialized, hex-encoded transaction | +| Description | Returns a JSON object representing the provided serialized, hex-encoded transaction. | +| Returns | `{ (json object)`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}` | +| Example Return | `{`
  `"txid": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"version": 1,`
  `"locktime": 0,`
  `"vin": [`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6...",`
      `"sequence": 4294967295,`
    `}`
  For non-coinbase transactions:
    `{`
      `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
      `"vout": 0,`
      `"scriptSig": {`
        `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
        `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
      `}`
      `"sequence": 4294967295,`
    `}`
  `]`
  `"vout": [`
    `{`
      `"value": 50,`
      `"n": 0,`
      `"scriptPubKey": {`
        `"asm": "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4ce...",`
        `"hex": "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4...",`
        `"reqSigs": 1,`
        `"type": "pubkey"`
        `"addresses": [`
          `"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",`
        `]`
      `}`
    `}`
  `]`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|decodescript| -|Parameters|1. script (string, required) - hex-encoded script| -|Description|Returns a JSON object with information about the provided hex-encoded script.| -|Returns|`{ (json object)`
  `"asm": "asm", (string) disassembly of the script`
  `"reqSigs": n, (numeric) the number of required signatures`
  `"type": "scripttype", (string) the type of the script (e.g. 'pubkeyhash')`
  `"addresses": [ (json array of string) the bitcoin addresses associated with this script`
    `"bitcoinaddress", (string) the bitcoin address`
    `...`
  `]`
  `"p2sh": "scripthash", (string) the script hash for use in pay-to-script-hash transactions`
`}`| -|Example Return|`{`
  `"asm": "OP_DUP OP_HASH160 b0a4d8a91981106e4ed85165a66748b19f7b7ad4 OP_EQUALVERIFY OP_CHECKSIG",`
  `"reqSigs": 1,`
  `"type": "pubkeyhash",`
  `"addresses": [`
    `"1H71QVBpzuLTNUh5pewaH3UTLTo2vWgcRJ"`
  `]`
  `"p2sh": "359b84ff799f48231990ff0298206f54117b08b6"`
`}`| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | decodescript | +| Parameters | 1. script (string, required) - hex-encoded script | +| Description | Returns a JSON object with information about the provided hex-encoded script. | +| Returns | `{ (json object)`
  `"asm": "asm", (string) disassembly of the script`
  `"reqSigs": n, (numeric) the number of required signatures`
  `"type": "scripttype", (string) the type of the script (e.g. 'pubkeyhash')`
  `"addresses": [ (json array of string) the bitcoin addresses associated with this script`
    `"bitcoinaddress", (string) the bitcoin address`
    `...`
  `]`
  `"p2sh": "scripthash", (string) the script hash for use in pay-to-script-hash transactions`
`}` | +| Example Return | `{`
  `"asm": "OP_DUP OP_HASH160 b0a4d8a91981106e4ed85165a66748b19f7b7ad4 OP_EQUALVERIFY OP_CHECKSIG",`
  `"reqSigs": 1,`
  `"type": "pubkeyhash",`
  `"addresses": [`
    `"1H71QVBpzuLTNUh5pewaH3UTLTo2vWgcRJ"`
  `]`
  `"p2sh": "359b84ff799f48231990ff0298206f54117b08b6"`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getaddednodeinfo| -|Parameters|1. dns (boolean, required) - specifies whether the returned data is a JSON object including DNS and connection information, or just a list of added peers
2. node (string, optional) - only return information about this specific peer instead of all added peers.| -|Description|Returns information about manually added (persistent) peers.| -|Returns (dns=false)|`["ip:port", ...]`| -|Returns (dns=true)|`[ (json array of objects)`
  `{ (json object)`
    `"addednode": "ip_or_domain", (string) the ip address or domain of the added peer`
    `"connected": true or false, (boolean) whether or not the peer is currently connected`
    `"addresses": [ (json array or objects) DNS lookup and connection information about the peer`
      `{ (json object)`
        `"address": "ip", (string) the ip address for this DNS entry`
        `"connected": "inbound/outbound/false" (string) the connection 'direction' (if connected)`
      `}, ...`
    `]`
  `}, ...`
`]`| -|Example Return (dns=false)|`["192.168.0.10:8333", "mydomain.org:8333"]`| -|Example Return (dns=true)|`[`
  `{`
    `"addednode": "mydomain.org:8333",`
    `"connected": true,`
    `"addresses": [`
      `{`
        `"address": "1.2.3.4",`
        `"connected": "outbound"`
      `},`
      `{`
        `"address": "5.6.7.8",`
        `"connected": "false"`
      `}`
    `]`
  `}`
`]`| +| | | +| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getaddednodeinfo | +| Parameters | 1. dns (boolean, required) - specifies whether the returned data is a JSON object including DNS and connection information, or just a list of added peers
2. node (string, optional) - only return information about this specific peer instead of all added peers. | +| Description | Returns information about manually added (persistent) peers. | +| Returns (dns=false) | `["ip:port", ...]` | +| Returns (dns=true) | `[ (json array of objects)`
  `{ (json object)`
    `"addednode": "ip_or_domain", (string) the ip address or domain of the added peer`
    `"connected": true or false, (boolean) whether or not the peer is currently connected`
    `"addresses": [ (json array or objects) DNS lookup and connection information about the peer`
      `{ (json object)`
        `"address": "ip", (string) the ip address for this DNS entry`
        `"connected": "inbound/outbound/false" (string) the connection 'direction' (if connected)`
      `}, ...`
    `]`
  `}, ...`
`]` | +| Example Return (dns=false) | `["192.168.0.10:9246", "mydomain.org:9246"]` | +| Example Return (dns=true) | `[`
  `{`
    `"addednode": "mydomain.org:9246",`
    `"connected": true,`
    `"addresses": [`
      `{`
        `"address": "1.2.3.4",`
        `"connected": "outbound"`
      `},`
      `{`
        `"address": "5.6.7.8",`
        `"connected": "false"`
      `}`
    `]`
  `}`
`]` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getbestblockhash| -|Parameters|None| -|Description|Returns the hash of the of the best (most recent) block in the longest block chain.| -|Returns|string| -|Example Return|`0000000000000001f356adc6b29ab42b59f913a396e170f80190dba615bd1e60`| +| | | +| -------------- | ----------------------------------------------------------------------------------- | +| Method | getbestblockhash | +| Parameters | None | +| Description | Returns the hash of the of the best (most recent) block in the longest block chain. | +| Returns | string | +| Example Return | `0000000000000001f356adc6b29ab42b59f913a396e170f80190dba615bd1e60` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getblock| -|Parameters|1. block hash (string, required) - the hash of the block
2. verbosity (int, optional, default=1) - Specifies whether the block data should be returned as a hex-encoded string (0), as parsed data with a slice of TXIDs (1), or as parsed data with parsed transaction data (2). -|Description|Returns information about a block given its hash.| -|Returns (verbosity=0)|`"data" (string) hex-encoded bytes of the serialized block`| -|Returns (verbosity=1)|`{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"strippedsize", n (numeric) the size of the block without witness data`
  `"size": n, (numeric) the size of the block`
  `"weight": n, (numeric) value of the weight metric`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"tx": [ (json array of string) the transaction hashes`
    `"transactionhash", (string) hash of the parent transaction`
    `...`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`
`}`| -|Returns (verbosity=2)|`{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"strippedsize", n (numeric) the size of the block without witness data`
  `"size": n, (numeric) the size of the block`
  `"weight": n, (numeric) value of the weight metric`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"rawtx": [ (array of json objects) the transactions as json objects`
    `(see getrawtransaction json object details)`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block`
`}`| -|Example Return (verbosity=0)|`"010000000000000000000000000000000000000000000000000000000000000000000000`
`3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49`
`ffff001d1dac2b7c01010000000100000000000000000000000000000000000000000000`
`00000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f`
`4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f`
`6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104`
`678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f`
`4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"`
**Newlines added for display purposes. The actual return does not contain newlines.**| -|Example Return (verbosity=1)|`{`
  `"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",`
  `"confirmations": 277113,`
  `"size": 285,`
  `"height": 0,`
  `"version": 1,`
  `"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"tx": [`
    `"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"`
  `],`
  `"time": 1231006505,`
  `"nonce": 2083236893,`
  `"bits": "1d00ffff",`
  `"difficulty": 1,`
  `"previousblockhash": "0000000000000000000000000000000000000000000000000000000000000000",`
  `"nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"`
`}`| +| | | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getblock | +| Parameters | 1. block hash (string, required) - the hash of the block
2. verbosity (int, optional, default=1) - Specifies whether the block data should be returned as a hex-encoded string (0), as parsed data with a slice of TXIDs (1), or as parsed data with parsed transaction data (2). | +| Description | Returns information about a block given its hash. | +| Returns (verbosity=0) | `"data" (string) hex-encoded bytes of the serialized block` | +| Returns (verbosity=1) | `{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"strippedsize", n (numeric) the size of the block without witness data`
  `"size": n, (numeric) the size of the block`
  `"weight": n, (numeric) value of the weight metric`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"tx": [ (json array of string) the transaction hashes`
    `"transactionhash", (string) hash of the parent transaction`
    `...`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`
`}` | +| Returns (verbosity=2) | `{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"strippedsize", n (numeric) the size of the block without witness data`
  `"size": n, (numeric) the size of the block`
  `"weight": n, (numeric) value of the weight metric`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"rawtx": [ (array of json objects) the transactions as json objects`
    `(see getrawtransaction json object details)`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block`
`}` | +| Example Return (verbosity=0) | `"010000000000000000000000000000000000000000000000000000000000000000000000`
`3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49`
`ffff001d1dac2b7c01010000000100000000000000000000000000000000000000000000`
`00000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f`
`4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f`
`6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104`
`678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f`
`4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"`
**Newlines added for display purposes. The actual return does not contain newlines.** | +| Example Return (verbosity=1) | `{`
  `"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",`
  `"confirmations": 277113,`
  `"size": 285,`
  `"height": 0,`
  `"version": 1,`
  `"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"tx": [`
    `"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"`
  `],`
  `"time": 1231006505,`
  `"nonce": 2083236893,`
  `"bits": "1d00ffff",`
  `"difficulty": 1,`
  `"previousblockhash": "0000000000000000000000000000000000000000000000000000000000000000",`
  `"nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getblockcount| -|Parameters|None| -|Description|Returns the number of blocks in the longest block chain.| -|Returns|numeric| -|Example Return|`276820`| +| | | +| -------------- | -------------------------------------------------------- | +| Method | getblockcount | +| Parameters | None | +| Description | Returns the number of blocks in the longest block chain. | +| Returns | numeric | +| Example Return | `276820` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getblockhash| -|Parameters|1. block height (numeric, required)| -|Description|Returns hash of the block in best block chain at the given height.| -|Returns|string| -|Example Return|`000000000000000096579458d1c0f1531fcfc58d57b4fce51eb177d8d10e784d`| +| | | +| -------------- | ------------------------------------------------------------------ | +| Method | getblockhash | +| Parameters | 1. block height (numeric, required) | +| Description | Returns hash of the block in best block chain at the given height. | +| Returns | string | +| Example Return | `000000000000000096579458d1c0f1531fcfc58d57b4fce51eb177d8d10e784d` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getblockheader| -|Parameters|1. block hash (string, required) - the hash of the block
2. verbose (boolean, optional, default=true) - specifies the block header is returned as a JSON object instead of a hex-encoded string| -|Description|Returns hex-encoded bytes of the serialized block header.| -|Returns (verbose=false)|`"data" (string) hex-encoded bytes of the serialized block`| -|Returns (verbose=true)|`{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits": n, (numeric) the bits which represent the block difficulty`
  `"difficulty": n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`
`}`| -|Example Return (verbose=false)|`"0200000035ab154183570282ce9afc0b494c9fc6a3cfea05aa8c1add2ecc564900000000`
`38ba3d78e4500a5a7570dbe61960398add4410d278b21cd9708e6d9743f374d544fc0552`
`27f1001c29c1ea3b"`
**Newlines added for display purposes. The actual return does not contain newlines.**| -|Example Return (verbose=true)|`{`
  `"hash": "00000000009e2958c15ff9290d571bf9459e93b19765c6801ddeccadbb160a1e",`
  `"confirmations": 392076,`
  `"height": 100000,`
  `"version": 2,`
  `"merkleroot": "d574f343976d8e70d91cb278d21044dd8a396019e6db70755a0a50e4783dba38",`
  `"time": 1376123972,`
  `"nonce": 1005240617,`
  `"bits": "1c00f127",`
  `"difficulty": 271.75767393,`
  `"previousblockhash": "000000004956cc2edd1a8caa05eacfa3c69f4c490bfc9ace820257834115ab35",`
  `"nextblockhash": "0000000000629d100db387f37d0f37c51118f250fb0946310a8c37316cbc4028"`
`}`| +| | | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | getblockheader | +| Parameters | 1. block hash (string, required) - the hash of the block
2. verbose (boolean, optional, default=true) - specifies the block header is returned as a JSON object instead of a hex-encoded string | +| Description | Returns hex-encoded bytes of the serialized block header. | +| Returns (verbose=false) | `"data" (string) hex-encoded bytes of the serialized block` | +| Returns (verbose=true) | `{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits": n, (numeric) the bits which represent the block difficulty`
  `"difficulty": n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`
`}` | +| Example Return (verbose=false) | `"0200000035ab154183570282ce9afc0b494c9fc6a3cfea05aa8c1add2ecc564900000000`
`38ba3d78e4500a5a7570dbe61960398add4410d278b21cd9708e6d9743f374d544fc0552`
`27f1001c29c1ea3b"`
**Newlines added for display purposes. The actual return does not contain newlines.** | +| Example Return (verbose=true) | `{`
  `"hash": "00000000009e2958c15ff9290d571bf9459e93b19765c6801ddeccadbb160a1e",`
  `"confirmations": 392076,`
  `"height": 100000,`
  `"version": 2,`
  `"merkleroot": "d574f343976d8e70d91cb278d21044dd8a396019e6db70755a0a50e4783dba38",`
  `"time": 1376123972,`
  `"nonce": 1005240617,`
  `"bits": "1c00f127",`
  `"difficulty": 271.75767393,`
  `"previousblockhash": "000000004956cc2edd1a8caa05eacfa3c69f4c490bfc9ace820257834115ab35",`
  `"nextblockhash": "0000000000629d100db387f37d0f37c51118f250fb0946310a8c37316cbc4028"`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getconnectioncount| -|Parameters|None| -|Description|Returns the number of active connections to other peers| -|Returns|numeric| -|Example Return|`8`| +| | | +| -------------- | ------------------------------------------------------- | +| Method | getconnectioncount | +| Parameters | None | +| Description | Returns the number of active connections to other peers | +| Returns | numeric | +| Example Return | `8` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getdifficulty| -|Parameters|None| -|Description|Returns the proof-of-work difficulty as a multiple of the minimum difficulty.| -|Returns|numeric| -|Example Return|`1180923195.260000`| +| | | +| -------------- | ----------------------------------------------------------------------------- | +| Method | getdifficulty | +| Parameters | None | +| Description | Returns the proof-of-work difficulty as a multiple of the minimum difficulty. | +| Returns | numeric | +| Example Return | `1180923195.260000` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getgenerate| -|Parameters|None| -|Description|Return if the server is set to generate coins (mine) or not.| -|Returns|`false` (boolean)| +| | | +| ----------- | ------------------------------------------------------------ | +| Method | getgenerate | +| Parameters | None | +| Description | Return if the server is set to generate coins (mine) or not. | +| Returns | `false` (boolean) | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|gethashespersec| -|Parameters|None| -|Description|Returns a recent hashes per second performance measurement while generating coins (mining).| -|Returns|`0` (numeric)| +| | | +| ----------- | ------------------------------------------------------------------------------------------- | +| Method | gethashespersec | +| Parameters | None | +| Description | Returns a recent hashes per second performance measurement while generating coins (mining). | +| Returns | `0` (numeric) | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getinfo| -|Parameters|None| -|Description|Returns a JSON object containing various state info.| -|Notes|NOTE: Since btcd does NOT contain wallet functionality, wallet-related fields are not returned. See getinfo in btcwallet for a version which includes that information.| -|Returns|`{ (json object)`
  `"version": n, (numeric) the version of the server`
  `"protocolversion": n, (numeric) the latest supported protocol version`
  `"blocks": n, (numeric) the number of blocks processed`
  `"timeoffset": n, (numeric) the time offset`
  `"connections": n, (numeric) the number of connected peers`
  `"proxy": "host:port", (string) the proxy used by the server`
  `"difficulty": n.nn, (numeric) the current target difficulty`
  `"testnet": true or false, (boolean) whether or not server is using testnet`
  `"relayfee": n.nn, (numeric) the minimum relay fee for non-free transactions in BTC/KB`
`}`| -|Example Return|`{`
  `"version": 70000`
  `"protocolversion": 70001, `
  `"blocks": 298963,`
  `"timeoffset": 0,`
  `"connections": 17,`
  `"proxy": "",`
  `"difficulty": 8000872135.97,`
  `"testnet": false,`
  `"relayfee": 0.00001,`
`}`| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | getinfo | +| Parameters | None | +| Description | Returns a JSON object containing various state info. | +| Notes | NOTE: Since lbcd does NOT contain wallet functionality, wallet-related fields are not returned. See getinfo in btcwallet for a version which includes that information. | +| Returns | `{ (json object)`
  `"version": n, (numeric) the version of the server`
  `"protocolversion": n, (numeric) the latest supported protocol version`
  `"blocks": n, (numeric) the number of blocks processed`
  `"timeoffset": n, (numeric) the time offset`
  `"connections": n, (numeric) the number of connected peers`
  `"proxy": "host:port", (string) the proxy used by the server`
  `"difficulty": n.nn, (numeric) the current target difficulty`
  `"testnet": true or false, (boolean) whether or not server is using testnet`
  `"relayfee": n.nn, (numeric) the minimum relay fee for non-free transactions in BTC/KB`
`}` | +| Example Return | `{`
  `"version": 70000`
  `"protocolversion": 70001, `
  `"blocks": 298963,`
  `"timeoffset": 0,`
  `"connections": 17,`
  `"proxy": "",`
  `"difficulty": 8000872135.97,`
  `"testnet": false,`
  `"relayfee": 0.00001,`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getmempoolinfo| -|Parameters|None| -|Description|Returns a JSON object containing mempool-related information.| -|Returns|`{ (json object)`
  `"bytes": n, (numeric) size in bytes of the mempool`
  `"size": n, (numeric) number of transactions in the mempool`
`}`| -Example Return|`{`
  `"bytes": 310768,`
  `"size": 157,`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getmempoolinfo | +| Parameters | None | +| Description | Returns a JSON object containing mempool-related information. | +| Returns | `{ (json object)`
  `"bytes": n, (numeric) size in bytes of the mempool`
  `"size": n, (numeric) number of transactions in the mempool`
`}` | +| Example Return | `{`
  `"bytes": 310768,`
  `"size": 157,`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getmininginfo| -|Parameters|None| -|Description|Returns a JSON object containing mining-related information.| -|Returns|`{ (json object)`
  `"blocks": n, (numeric) latest best block`
  `"currentblocksize": n, (numeric) size of the latest best block`
  `"currentblockweight": n, (numeric) weight of the latest best block`
  `"currentblocktx": n, (numeric) number of transactions in the latest best block`
  `"difficulty": n.nn, (numeric) current target difficulty`
  `"errors": "errors", (string) any current errors`
  `"generate": true or false, (boolean) whether or not server is set to generate coins`
  `"genproclimit": n, (numeric) number of processors to use for coin generation (-1 when disabled)`
  `"hashespersec": n, (numeric) recent hashes per second performance measurement while generating coins`
  `"networkhashps": n, (numeric) estimated network hashes per second for the most recent blocks`
  `"pooledtx": n, (numeric) number of transactions in the memory pool`
  `"testnet": true or false, (boolean) whether or not server is using testnet`
`}`| -|Example Return|`{`
  `"blocks": 236526,`
  `"currentblocksize": 185,`
  `"currentblockweight": 740,`
  `"currentblocktx": 1,`
  `"difficulty": 256,`
  `"errors": "",`
  `"generate": false,`
  `"genproclimit": -1,`
  `"hashespersec": 0,`
  `"networkhashps": 33081554756,`
  `"pooledtx": 8,`
  `"testnet": true,`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getmininginfo | +| Parameters | None | +| Description | Returns a JSON object containing mining-related information. | +| Returns | `{ (json object)`
  `"blocks": n, (numeric) latest best block`
  `"currentblocksize": n, (numeric) size of the latest best block`
  `"currentblockweight": n, (numeric) weight of the latest best block`
  `"currentblocktx": n, (numeric) number of transactions in the latest best block`
  `"difficulty": n.nn, (numeric) current target difficulty`
  `"errors": "errors", (string) any current errors`
  `"generate": true or false, (boolean) whether or not server is set to generate coins`
  `"genproclimit": n, (numeric) number of processors to use for coin generation (-1 when disabled)`
  `"hashespersec": n, (numeric) recent hashes per second performance measurement while generating coins`
  `"networkhashps": n, (numeric) estimated network hashes per second for the most recent blocks`
  `"pooledtx": n, (numeric) number of transactions in the memory pool`
  `"testnet": true or false, (boolean) whether or not server is using testnet`
`}` | +| Example Return | `{`
  `"blocks": 236526,`
  `"currentblocksize": 185,`
  `"currentblockweight": 740,`
  `"currentblocktx": 1,`
  `"difficulty": 256,`
  `"errors": "",`
  `"generate": false,`
  `"genproclimit": -1,`
  `"hashespersec": 0,`
  `"networkhashps": 33081554756,`
  `"pooledtx": 8,`
  `"testnet": true,`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getnettotals| -|Parameters|None| -|Description|Returns a JSON object containing network traffic statistics.| -|Returns|`{`
  `"totalbytesrecv": n, (numeric) total bytes received`
  `"totalbytessent": n, (numeric) total bytes sent`
  `"timemillis": n (numeric) number of milliseconds since 1 Jan 1970 GMT`
`}`| -|Example Return|`{`
  `"totalbytesrecv": 1150990,`
  `"totalbytessent": 206739,`
  `"timemillis": 1391626433845`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getnettotals | +| Parameters | None | +| Description | Returns a JSON object containing network traffic statistics. | +| Returns | `{`
  `"totalbytesrecv": n, (numeric) total bytes received`
  `"totalbytessent": n, (numeric) total bytes sent`
  `"timemillis": n (numeric) number of milliseconds since 1 Jan 1970 GMT`
`}` | +| Example Return | `{`
  `"totalbytesrecv": 1150990,`
  `"totalbytessent": 206739,`
  `"timemillis": 1391626433845`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getnetworkhashps| -|Parameters|1. blocks (numeric, optional, default=120) - The number of blocks, or -1 for blocks since last difficulty change
2. height (numeric, optional, default=-1) - Perform estimate ending with this height or -1 for current best chain block height| -|Description|Returns the estimated network hashes per second for the block heights provided by the parameters.| -|Returns|numeric| -|Example Return|`6573971939`| +| | | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getnetworkhashps | +| Parameters | 1. blocks (numeric, optional, default=120) - The number of blocks, or -1 for blocks since last difficulty change
2. height (numeric, optional, default=-1) - Perform estimate ending with this height or -1 for current best chain block height | +| Description | Returns the estimated network hashes per second for the block heights provided by the parameters. | +| Returns | numeric | +| Example Return | `6573971939` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getpeerinfo| -|Parameters|None| -|Description|Returns data about each connected network peer as an array of json objects.| -|Returns|`[`
  `{`
    `"addr": "host:port", (string) the ip address and port of the peer`
    `"services": "00000001", (string) the services supported by the peer`
    `"lastrecv": n, (numeric) time the last message was received in seconds since 1 Jan 1970 GMT`
    `"lastsend": n, (numeric) time the last message was sent in seconds since 1 Jan 1970 GMT`
    `"bytessent": n, (numeric) total bytes sent`
    `"bytesrecv": n, (numeric) total bytes received`
    `"conntime": n, (numeric) time the connection was made in seconds since 1 Jan 1970 GMT`
    `"pingtime": n, (numeric) number of microseconds the last ping took`
    `"pingwait": n, (numeric) number of microseconds a queued ping has been waiting for a response`
    `"version": n, (numeric) the protocol version of the peer`
    `"subver": "useragent", (string) the user agent of the peer`
    `"inbound": true_or_false, (boolean) whether or not the peer is an inbound connection`
    `"startingheight": n, (numeric) the latest block height the peer knew about when the connection was established`
    `"currentheight": n, (numeric) the latest block height the peer is known to have relayed since connected`
    `"syncnode": true_or_false, (boolean) whether or not the peer is the sync peer`
  `}, ...`
`]`| -|Example Return|`[`
  `{`
    `"addr": "178.172.xxx.xxx:8333",`
    `"services": "00000001",`
    `"lastrecv": 1388183523,`
    `"lastsend": 1388185470,`
    `"bytessent": 287592965,`
    `"bytesrecv": 780340,`
    `"conntime": 1388182973,`
    `"pingtime": 405551,`
    `"pingwait": 183023,`
    `"version": 70001,`
    `"subver": "/btcd:0.4.0/",`
    `"inbound": false,`
    `"startingheight": 276921,`
    `"currentheight": 276955,`
    `"syncnode": true,`
  `}`
`]`| +| | | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getpeerinfo | +| Parameters | None | +| Description | Returns data about each connected network peer as an array of json objects. | +| Returns | `[`
  `{`
    `"addr": "host:port", (string) the ip address and port of the peer`
    `"services": "00000001", (string) the services supported by the peer`
    `"lastrecv": n, (numeric) time the last message was received in seconds since 1 Jan 1970 GMT`
    `"lastsend": n, (numeric) time the last message was sent in seconds since 1 Jan 1970 GMT`
    `"bytessent": n, (numeric) total bytes sent`
    `"bytesrecv": n, (numeric) total bytes received`
    `"conntime": n, (numeric) time the connection was made in seconds since 1 Jan 1970 GMT`
    `"pingtime": n, (numeric) number of microseconds the last ping took`
    `"pingwait": n, (numeric) number of microseconds a queued ping has been waiting for a response`
    `"version": n, (numeric) the protocol version of the peer`
    `"subver": "useragent", (string) the user agent of the peer`
    `"inbound": true_or_false, (boolean) whether or not the peer is an inbound connection`
    `"startingheight": n, (numeric) the latest block height the peer knew about when the connection was established`
    `"currentheight": n, (numeric) the latest block height the peer is known to have relayed since connected`
    `"syncnode": true_or_false, (boolean) whether or not the peer is the sync peer`
  `}, ...`
`]` | +| Example Return | `[`
  `{`
    `"addr": "178.172.xxx.xxx:9246",`
    `"services": "00000001",`
    `"lastrecv": 1388183523,`
    `"lastsend": 1388185470,`
    `"bytessent": 287592965,`
    `"bytesrecv": 780340,`
    `"conntime": 1388182973,`
    `"pingtime": 405551,`
    `"pingwait": 183023,`
    `"version": 70001,`
    `"subver": "/lbcd:0.4.0/",`
    `"inbound": false,`
    `"startingheight": 276921,`
    `"currentheight": 276955,`
    `"syncnode": true,`
  `}`
`]` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getrawtransaction| -|Parameters|1. transaction hash (string, required) - the hash of the transaction
2. verbose (int, optional, default=0) - specifies the transaction is returned as a JSON object instead of hex-encoded string| -|Description|Returns information about a transaction given its hash.| -|Returns (verbose=0)|`"data" (string) hex-encoded bytes of the serialized transaction`| -|Returns (verbose=1)|`{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}`| -|Example Return (verbose=0)|`"010000000104be666c7053ef26c6110597dad1c1e81b5e6be53d17a8b9d0b34772054bac60000000`
`008c493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f`
`022100fbce8d84fcf2839127605818ac6c3e7a1531ebc69277c504599289fb1e9058df0141045a33`
`76eeb85e494330b03c1791619d53327441002832f4bd618fd9efa9e644d242d5e1145cb9c2f71965`
`656e276633d4ff1a6db5e7153a0a9042745178ebe0f5ffffffff0280841e00000000001976a91406`
`f1b6703d3f56427bfcfd372f952d50d04b64bd88ac4dd52700000000001976a9146b63f291c295ee`
`abd9aee6be193ab2d019e7ea7088ac00000000`
**Newlines added for display purposes. The actual return does not contain newlines.**| -|Example Return (verbose=1)|`{`
  `"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...",`
  `"txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9",`
  `"version": 1,`
  `"locktime": 0,`
  `"vin": [`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f",`
      `"sequence": 0,`
    `}`
  For non-coinbase transactions:
    `{`
      `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
      `"vout": 0,`
      `"scriptSig": {`
        `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
        `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
      `}`
      `"sequence": 4294967295,`
    `}`
  `]`
  `"vout": [`
    `{`
      `"value": 25.1394,`
      `"n": 0,`
      `"scriptPubKey": {`
        `"asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG",`
        `"hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac",`
        `"reqSigs": 1,`
        `"type": "pubkeyhash"`
        `"addresses": [`
          `"1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh",`
        `]`
      `}`
    `}`
  `]`
`}`| +| | | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getrawtransaction | +| Parameters | 1. transaction hash (string, required) - the hash of the transaction
2. verbose (int, optional, default=0) - specifies the transaction is returned as a JSON object instead of hex-encoded string | +| Description | Returns information about a transaction given its hash. | +| Returns (verbose=0) | `"data" (string) hex-encoded bytes of the serialized transaction` | +| Returns (verbose=1) | `{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}` | +| Example Return (verbose=0) | `"010000000104be666c7053ef26c6110597dad1c1e81b5e6be53d17a8b9d0b34772054bac60000000`
`008c493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f`
`022100fbce8d84fcf2839127605818ac6c3e7a1531ebc69277c504599289fb1e9058df0141045a33`
`76eeb85e494330b03c1791619d53327441002832f4bd618fd9efa9e644d242d5e1145cb9c2f71965`
`656e276633d4ff1a6db5e7153a0a9042745178ebe0f5ffffffff0280841e00000000001976a91406`
`f1b6703d3f56427bfcfd372f952d50d04b64bd88ac4dd52700000000001976a9146b63f291c295ee`
`abd9aee6be193ab2d019e7ea7088ac00000000`
**Newlines added for display purposes. The actual return does not contain newlines.** | +| Example Return (verbose=1) | `{`
  `"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...",`
  `"txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9",`
  `"version": 1,`
  `"locktime": 0,`
  `"vin": [`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f",`
      `"sequence": 0,`
    `}`
  For non-coinbase transactions:
    `{`
      `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
      `"vout": 0,`
      `"scriptSig": {`
        `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
        `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
      `}`
      `"sequence": 4294967295,`
    `}`
  `]`
  `"vout": [`
    `{`
      `"value": 25.1394,`
      `"n": 0,`
      `"scriptPubKey": {`
        `"asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG",`
        `"hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac",`
        `"reqSigs": 1,`
        `"type": "pubkeyhash"`
        `"addresses": [`
          `"1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh",`
        `]`
      `}`
    `}`
  `]`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|help| -|Parameters|1. command (string, optional) - the command to get help for| -|Description|Returns a list of all commands or help for a specified command.
When no `command` parameter is specified, a list of avaialable commands is returned
When `command` is a valid method, the help text for that method is returned.| -|Returns|string| -|Example Return|getblockcount
Returns a numeric for the number of blocks in the longest block chain.| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | help | +| Parameters | 1. command (string, optional) - the command to get help for | +| Description | Returns a list of all commands or help for a specified command.
When no `command` parameter is specified, a list of avaialable commands is returned
When `command` is a valid method, the help text for that method is returned. | +| Returns | string | +| Example Return | getblockcount
Returns a numeric for the number of blocks in the longest block chain. | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|ping| -|Parameters|None| -|Description|Queues a ping to be sent to each connected peer.
Ping times are provided by [getpeerinfo](#getpeerinfo) via the `pingtime` and `pingwait` fields.| -|Returns|Nothing| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | ping | +| Parameters | None | +| Description | Queues a ping to be sent to each connected peer.
Ping times are provided by [getpeerinfo](#getpeerinfo) via the `pingtime` and `pingwait` fields. | +| Returns | Nothing | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getrawmempool| -|Parameters|1. verbose (boolean, optional, default=false)| -|Description|Returns an array of hashes for all of the transactions currently in the memory pool.
The `verbose` flag specifies that each transaction is returned as a JSON object.| -|Notes|Since btcd does not perform any mining, the priority related fields `startingpriority` and `currentpriority` that are available when the `verbose` flag is set are always 0.| -|Returns (verbose=false)|`[ (json array of string)`
  `"transactionhash", (string) hash of the transaction`
  `...`
`]`| -|Returns (verbose=true)|`{ (json object)`
  `"transactionhash": { (json object)`
    `"size": n, (numeric) transaction size in bytes`
    `"vsize": n, (numeric) transaction virtual size`
    `"weight": n, (numeric) The transaction's weight (between vsize*4-3 and vsize*4)`
    `"fee" : n, (numeric) transaction fee in bitcoins`
    `"time": n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT`
    `"height": n, (numeric) block height when transaction entered the pool`
    `"startingpriority": n, (numeric) priority when transaction entered the pool`
    `"currentpriority": n, (numeric) current priority`
    `"depends": [ (json array) unconfirmed transactions used as inputs for this transaction`
      `"transactionhash", (string) hash of the parent transaction`
      `...`
    `]`
  `}, ...`
`}`| -|Example Return (verbose=false)|`[`
  `"3480058a397b6ffcc60f7e3345a61370fded1ca6bef4b58156ed17987f20d4e7",`
  `"cbfe7c056a358c3a1dbced5a22b06d74b8650055d5195c1c2469e6b63a41514a"`
`]`| -|Example Return (verbose=true)|`{`
  `"1697a19cede08694278f19584e8dcc87945f40c6b59a942dd8906f133ad3f9cc": {`
    `"size": 226,`
    `"fee" : 0.0001,`
    `"time": 1387992789,`
    `"height": 276836,`
    `"startingpriority": 0,`
    `"currentpriority": 0,`
    `"depends": [`
      `"aa96f672fcc5a1ec6a08a94aa46d6b789799c87bd6542967da25a96b2dee0afb",`
    `]`
`}`| +| | | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getrawmempool | +| Parameters | 1. verbose (boolean, optional, default=false) | +| Description | Returns an array of hashes for all of the transactions currently in the memory pool.
The `verbose` flag specifies that each transaction is returned as a JSON object. | +| Notes | Since lbcd does not perform any mining, the priority related fields `startingpriority` and `currentpriority` that are available when the `verbose` flag is set are always 0. | +| Returns (verbose=false) | `[ (json array of string)`
  `"transactionhash", (string) hash of the transaction`
  `...`
`]` | +| Returns (verbose=true) | `{ (json object)`
  `"transactionhash": { (json object)`
    `"size": n, (numeric) transaction size in bytes`
    `"vsize": n, (numeric) transaction virtual size`
    `"weight": n, (numeric) The transaction's weight (between vsize*4-3 and vsize*4)`
    `"fee" : n, (numeric) transaction fee in bitcoins`
    `"time": n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT`
    `"height": n, (numeric) block height when transaction entered the pool`
    `"startingpriority": n, (numeric) priority when transaction entered the pool`
    `"currentpriority": n, (numeric) current priority`
    `"depends": [ (json array) unconfirmed transactions used as inputs for this transaction`
      `"transactionhash", (string) hash of the parent transaction`
      `...`
    `]`
  `}, ...`
`}` | +| Example Return (verbose=false) | `[`
  `"3480058a397b6ffcc60f7e3345a61370fded1ca6bef4b58156ed17987f20d4e7",`
  `"cbfe7c056a358c3a1dbced5a22b06d74b8650055d5195c1c2469e6b63a41514a"`
`]` | +| Example Return (verbose=true) | `{`
  `"1697a19cede08694278f19584e8dcc87945f40c6b59a942dd8906f133ad3f9cc": {`
    `"size": 226,`
    `"fee" : 0.0001,`
    `"time": 1387992789,`
    `"height": 276836,`
    `"startingpriority": 0,`
    `"currentpriority": 0,`
    `"depends": [`
      `"aa96f672fcc5a1ec6a08a94aa46d6b789799c87bd6542967da25a96b2dee0afb",`
    `]`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|setgenerate| -|Parameters|1. generate (boolean, required) - `true` to enable generation, `false` to disable it
2. genproclimit (numeric, optional) - the number of processors (cores) to limit generation to or `-1` for default| -|Description|Set the server to generate coins (mine) or not.| -|Notes|NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.| -|Returns|Nothing| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | setgenerate | +| Parameters | 1. generate (boolean, required) - `true` to enable generation, `false` to disable it
2. genproclimit (numeric, optional) - the number of processors (cores) to limit generation to or `-1` for default | +| Description | Set the server to generate coins (mine) or not. | +| Notes | NOTE: Since lbcd does not have the wallet integrated to provide payment addresses, lbcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function. | +| Returns | Nothing | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|sendrawtransaction| -|Parameters|1. signedhex (string, required) serialized, hex-encoded signed transaction
2. allowhighfees (boolean, optional, default=false) whether or not to allow insanely high fees| -|Description|Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.| -|Notes|btcd does not yet implement the `allowhighfees` parameter, so it has no effect| -|Returns|`"hash" (string) the hash of the transaction`| -|Example Return|`"1697a19cede08694278f19584e8dcc87945f40c6b59a942dd8906f133ad3f9cc"`| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | sendrawtransaction | +| Parameters | 1. signedhex (string, required) serialized, hex-encoded signed transaction
2. allowhighfees (boolean, optional, default=false) whether or not to allow insanely high fees | +| Description | Submits the serialized, hex-encoded transaction to the local peer and relays it to the network. | +| Notes | lbcd does not yet implement the `allowhighfees` parameter, so it has no effect | +| Returns | `"hash" (string) the hash of the transaction` | +| Example Return | `"1697a19cede08694278f19584e8dcc87945f40c6b59a942dd8906f133ad3f9cc"` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|submitblock| -|Parameters|1. data (string, required) serialized, hex-encoded block
2. params (json object, optional, default=nil) this parameter is currently ignored| -|Description|Attempts to submit a new serialized, hex-encoded block to the network.| -|Returns (success)|Success: Nothing
Failure: `"rejected: reason"` (string)| +| | | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | submitblock | +| Parameters | 1. data (string, required) serialized, hex-encoded block
2. params (json object, optional, default=nil) this parameter is currently ignored | +| Description | Attempts to submit a new serialized, hex-encoded block to the network. | +| Returns (success) | Success: Nothing
Failure: `"rejected: reason"` (string) | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|stop| -|Parameters|None| -|Description|Shutdown btcd.| -|Returns|`"btcd stopping."` (string)| +| | | +| ----------- | --------------------------- | +| Method | stop | +| Parameters | None | +| Description | Shutdown lbcd. | +| Returns | `"lbcd stopping."` (string) | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|validateaddress| -|Parameters|1. address (string, required) - bitcoin address| -|Description|Verify an address is valid.| -|Returns|`{ (json object)`
  `"isvalid": true or false, (bool) whether or not the address is valid.`
  `"address": "bitcoinaddress", (string) the bitcoin address validated.`
}| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | validateaddress | +| Parameters | 1. address (string, required) - bitcoin address | +| Description | Verify an address is valid. | +| Returns | `{ (json object)`
  `"isvalid": true or false, (bool) whether or not the address is valid.`
  `"address": "bitcoinaddress", (string) the bitcoin address validated.`
} | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|verifychain| -|Parameters|1. checklevel (numeric, optional, default=3) - how in-depth the verification is (0=least amount of checks, higher levels are clamped to the highest supported level)
2. numblocks (numeric, optional, default=288) - the number of blocks starting from the end of the chain to verify| -|Description|Verifies the block chain database.
The actual checks performed by the `checklevel` parameter is implementation specific. For btcd this is:
`checklevel=0` - Look up each block and ensure it can be loaded from the database.
`checklevel=1` - Perform basic context-free sanity checks on each block.| -|Notes|Btcd currently only supports `checklevel` 0 and 1, but the default is still 3 for compatibility. Per the information in the Parameters section above, higher levels are automatically clamped to the highest supported level, so this means the default is effectively 1 for btcd.| -|Returns|`true` or `false` (boolean)| -|Example Return|`true`| +| | | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | verifychain | +| Parameters | 1. checklevel (numeric, optional, default=3) - how in-depth the verification is (0=least amount of checks, higher levels are clamped to the highest supported level)
2. numblocks (numeric, optional, default=288) - the number of blocks starting from the end of the chain to verify | +| Description | Verifies the block chain database.
The actual checks performed by the `checklevel` parameter is implementation specific. For lbcd this is:
`checklevel=0` - Look up each block and ensure it can be loaded from the database.
`checklevel=1` - Perform basic context-free sanity checks on each block. | +| Notes | lbcd currently only supports `checklevel` 0 and 1, but the default is still 3 for compatibility. Per the information in the Parameters section above, higher levels are automatically clamped to the highest supported level, so this means the default is effectively 1 for lbcd. | +| Returns | `true` or `false` (boolean) | +| Example Return | `true` | [Return to Overview](#MethodOverview)
@@ -570,18 +562,18 @@ Example Return|`{`
  `"bytes": 310768,`
  `"size": **6.1 Method Overview**
-The following is an overview of the RPC methods which are implemented by btcd, but not the original bitcoind client. Click the method name for further details such as parameter and return information. +The following is an overview of the RPC methods which are implemented by lbcd, but not the original bitcoind client. Click the method name for further details such as parameter and return information. -|#|Method|Safe for limited user?|Description| -|---|------|----------|-----------| -|1|[debuglevel](#debuglevel)|N|Dynamically changes the debug logging level.| -|2|[getbestblock](#getbestblock)|Y|Get block height and hash of best block in the main chain.|None| -|3|[getcurrentnet](#getcurrentnet)|Y|Get bitcoin network btcd is running on.|None| -|4|[searchrawtransactions](#searchrawtransactions)|Y|Query for transactions related to a particular address.|None| -|5|[node](#node)|N|Attempts to add or remove a peer. |None| -|6|[generate](#generate)|N|When in simnet or regtest mode, generate a set number of blocks. |None| -|7|[version](#version)|Y|Returns the JSON-RPC API version.| -|8|[getheaders](#getheaders)|Y|Returns block headers starting with the first known block hash from the request.| +| # | Method | Safe for limited user? | Description | +| --- | ----------------------------------------------- | ---------------------- | -------------------------------------------------------------------------------- | +| 1 | [debuglevel](#debuglevel) | N | Dynamically changes the debug logging level. | +| 2 | [getbestblock](#getbestblock) | Y | Get block height and hash of best block in the main chain. | None | +| 3 | [getcurrentnet](#getcurrentnet) | Y | Get bitcoin network lbcd is running on. | None | +| 4 | [searchrawtransactions](#searchrawtransactions) | Y | Query for transactions related to a particular address. | None | +| 5 | [node](#node) | N | Attempts to add or remove a peer. | None | +| 6 | [generate](#generate) | N | When in simnet or regtest mode, generate a set number of blocks. | None | +| 7 | [version](#version) | Y | Returns the JSON-RPC API version. | +| 8 | [getheaders](#getheaders) | Y | Returns block headers starting with the first known block hash from the request. |
@@ -590,102 +582,102 @@ The following is an overview of the RPC methods which are implemented by btcd, b -| | | -|---|---| -|Method|debuglevel| -|Parameters|1. _levelspec_ (string)| -|Description|Dynamically changes the debug logging level.
The levelspec can either a debug level or of the form `=,=,...`
The valid debug levels are `trace`, `debug`, `info`, `warn`, `error`, and `critical`.
The valid subsystems are `AMGR`, `ADXR`, `BCDB`, `BMGR`, `BTCD`, `CHAN`, `DISC`, `PEER`, `RPCS`, `SCRP`, `SRVR`, and `TXMP`.
Additionally, the special keyword `show` can be used to get a list of the available subsystems.| -|Returns|string| -|Example Return|`Done.`| -|Example `show` Return|`Supported subsystems [AMGR ADXR BCDB BMGR BTCD CHAN DISC PEER RPCS SCRP SRVR TXMP]`| +| | | +| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | debuglevel | +| Parameters | 1. _levelspec_ (string) | +| Description | Dynamically changes the debug logging level.
The levelspec can either a debug level or of the form `=,=,...`
The valid debug levels are `trace`, `debug`, `info`, `warn`, `error`, and `critical`.
The valid subsystems are `AMGR`, `ADXR`, `BCDB`, `BMGR`, `lbcd`, `CHAN`, `DISC`, `PEER`, `RPCS`, `SCRP`, `SRVR`, and `TXMP`.
Additionally, the special keyword `show` can be used to get a list of the available subsystems. | +| Returns | string | +| Example Return | `Done.` | +| Example `show` Return | `Supported subsystems [AMGR ADXR BCDB BMGR lbcd CHAN DISC PEER RPCS SCRP SRVR TXMP]` | [Return to Overview](#ExtMethodOverview)
***
-| | | -|---|---| -|Method|getbestblock| -|Parameters|None| -|Description|Get block height and hash of best block in the main chain.| -|Returns|`{ (json object)`
 `"hash": "data", (string) the hex-encoded bytes of the best block hash`
 `"height": n (numeric) the block height of the best block`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | getbestblock | +| Parameters | None | +| Description | Get block height and hash of best block in the main chain. | +| Returns | `{ (json object)`
 `"hash": "data", (string) the hex-encoded bytes of the best block hash`
 `"height": n (numeric) the block height of the best block`
`}` | [Return to Overview](#ExtMethodOverview)
***
-| | | -|---|---| -|Method|getcurrentnet| -|Parameters|None| -|Description|Get bitcoin network btcd is running on.| -|Returns|numeric| -|Example Return|`3652501241` (mainnet)
`118034699` (testnet3)| +| | | +| -------------- | -------------------------------------------------- | +| Method | getcurrentnet | +| Parameters | None | +| Description | Get bitcoin network lbcd is running on. | +| Returns | numeric | +| Example Return | `3652501241` (mainnet)
`118034699` (testnet3) | [Return to Overview](#ExtMethodOverview)
***
-| | | -|---|---| -|Method|searchrawtransactions| -|Parameters|1. address (string, required) - bitcoin address
2. verbose (int, optional, default=true) - specifies the transaction is returned as a JSON object instead of hex-encoded string
3. skip (int, optional, default=0) - the number of leading transactions to leave out of the final response
4. count (int, optional, default=100) - the maximum number of transactions to return
5. vinextra (int, optional, default=0) - Specify that extra data from previous output will be returned in vin
6. reverse (boolean, optional, default=false) - Specifies that the transactions should be returned in reverse chronological order| -|Description|Returns raw data for transactions involving the passed address. Returned transactions are pulled from both the database, and transactions currently in the mempool. Transactions pulled from the mempool will have the `"confirmations"` field set to 0. Usage of this RPC requires the optional `--addrindex` flag to be activated, otherwise all responses will simply return with an error stating the address index has not yet been built up. Similarly, until the address index has caught up with the current best height, all requests will return an error response in order to avoid serving stale data.| -|Returns (verbose=0)|`[ (json array of strings)`
   `"serializedtx", ... hex-encoded bytes of the serialized transaction`
`]` | -|Returns (verbose=1)|`[ (array of json objects)`
   `{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"txinwitness": “data", (string) the witness stack for the input`
    `"sequence": n, (numeric) the script sequence number`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"prevOut": { (json object) Data from the origin transaction output with index vout.`
        `"addresses": ["value",...], (array of string) previous output addresses`
        `"value": n.nnn, (numeric) previous output value`
      `}`
      `"txinwitness": “data", (string) the witness stack for the input`
    `"sequence": n, (numeric) the script sequence number`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"address", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
   `]`
   `"blockhash":"hash" Hash of the block the transaction is part of.`
   `"confirmations":n, Number of numeric confirmations of block.`
   `"time":t, Transaction time in seconds since the epoch.`
   `"blocktime":t, Block time in seconds since the epoch.`
`},...`
`]`| +| | | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | searchrawtransactions | +| Parameters | 1. address (string, required) - bitcoin address
2. verbose (int, optional, default=true) - specifies the transaction is returned as a JSON object instead of hex-encoded string
3. skip (int, optional, default=0) - the number of leading transactions to leave out of the final response
4. count (int, optional, default=100) - the maximum number of transactions to return
5. vinextra (int, optional, default=0) - Specify that extra data from previous output will be returned in vin
6. reverse (boolean, optional, default=false) - Specifies that the transactions should be returned in reverse chronological order | +| Description | Returns raw data for transactions involving the passed address. Returned transactions are pulled from both the database, and transactions currently in the mempool. Transactions pulled from the mempool will have the `"confirmations"` field set to 0. Usage of this RPC requires the optional `--addrindex` flag to be activated, otherwise all responses will simply return with an error stating the address index has not yet been built up. Similarly, until the address index has caught up with the current best height, all requests will return an error response in order to avoid serving stale data. | +| Returns (verbose=0) | `[ (json array of strings)`
   `"serializedtx", ... hex-encoded bytes of the serialized transaction`
`]` | +| Returns (verbose=1) | `[ (array of json objects)`
   `{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"txinwitness": “data", (string) the witness stack for the input`
    `"sequence": n, (numeric) the script sequence number`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"prevOut": { (json object) Data from the origin transaction output with index vout.`
        `"addresses": ["value",...], (array of string) previous output addresses`
        `"value": n.nnn, (numeric) previous output value`
      `}`
      `"txinwitness": “data", (string) the witness stack for the input`
    `"sequence": n, (numeric) the script sequence number`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"address", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
   `]`
   `"blockhash":"hash" Hash of the block the transaction is part of.`
   `"confirmations":n, Number of numeric confirmations of block.`
   `"time":t, Transaction time in seconds since the epoch.`
   `"blocktime":t, Block time in seconds since the epoch.`
`},...`
`]` | [Return to Overview](#ExtMethodOverview)
***
-| | | -|---|---| -|Method|node| -|Parameters|1. command (string, required) - `connect` to add a peer (defaults to temporary), `remove` to remove a persistent peer, or `disconnect` to remove all matching non-persistent peers
2. peer (string, required) - ip address and port, or ID of the peer to operate on
3. connection type (string, optional) - `perm` indicates the peer should be added as a permanent peer, `temp` indicates a connection should only be attempted once. | -|Description|Attempts to add or remove a peer.| -|Returns|Nothing| +| | | +| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | node | +| Parameters | 1. command (string, required) - `connect` to add a peer (defaults to temporary), `remove` to remove a persistent peer, or `disconnect` to remove all matching non-persistent peers
2. peer (string, required) - ip address and port, or ID of the peer to operate on
3. connection type (string, optional) - `perm` indicates the peer should be added as a permanent peer, `temp` indicates a connection should only be attempted once. | +| Description | Attempts to add or remove a peer. | +| Returns | Nothing | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|generate| -|Parameters|1. numblocks (int, required) - The number of blocks to generate | -|Description|When in simnet or regtest mode, generates `numblocks` blocks. If blocks arrive from elsewhere, they are built upon but don't count toward the number of blocks to generate. Only generated blocks are returned. This RPC call will exit with an error if the server is already CPU mining, and will prevent the server from CPU mining for another command while it runs. | -|Returns|`[ (json array of strings)`
   `"blockhash", ... hash of the generated block`
`]` | +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | generate | +| Parameters | 1. numblocks (int, required) - The number of blocks to generate | +| Description | When in simnet or regtest mode, generates `numblocks` blocks. If blocks arrive from elsewhere, they are built upon but don't count toward the number of blocks to generate. Only generated blocks are returned. This RPC call will exit with an error if the server is already CPU mining, and will prevent the server from CPU mining for another command while it runs. | +| Returns | `[ (json array of strings)`
   `"blockhash", ... hash of the generated block`
`]` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|version| -|Parameters|None| -|Description|Returns the version of the JSON-RPC API built into this release of btcd.| -|Returns|`{ (json object)`
  `"btcdjsonrpcapi": {`
    `"versionstring": "x.y.z", (string) the version of the JSON-RPC API`
    `"major": x, (numeric) the major version of the JSON-RPC API`
    `"minor": y, (numeric) the minor version of the JSON-RPC API`
    `"patch": z, (numeric) the patch version of the JSON-RPC API`
    `"prerelease": "", (string) prerelease info for the JSON-RPC API`
    `"buildmetadata": "" (string) metadata about the server build`
  `}`
`}`| -|Example Return|`{`
  `"btcdjsonrpcapi": {`
    `"versionstring": "1.0.0",`
    `"major": 1, `
    `"minor": 0,`
    `"patch": 0,`
    `"prerelease": "",`
    `"buildmetadata": ""`
  `}`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | version | +| Parameters | None | +| Description | Returns the version of the JSON-RPC API built into this release of lbcd. | +| Returns | `{ (json object)`
  `"lbcdjsonrpcapi": {`
    `"versionstring": "x.y.z", (string) the version of the JSON-RPC API`
    `"major": x, (numeric) the major version of the JSON-RPC API`
    `"minor": y, (numeric) the minor version of the JSON-RPC API`
    `"patch": z, (numeric) the patch version of the JSON-RPC API`
    `"prerelease": "", (string) prerelease info for the JSON-RPC API`
    `"buildmetadata": "" (string) metadata about the server build`
  `}`
`}` | +| Example Return | `{`
  `"lbcdjsonrpcapi": {`
    `"versionstring": "1.0.0",`
    `"major": 1, `
    `"minor": 0,`
    `"patch": 0,`
    `"prerelease": "",`
    `"buildmetadata": ""`
  `}`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getheaders| -|Parameters|1. Block Locators (JSON array, required)
 `[ (json array of strings)`
  `"blocklocator", (string) the known block hash`
  `...`
 `]`
2. hashstop (string) - last desired block's hash| -|Description|Returns block headers starting with the first known block hash from the request.| -|Returns|`[ (json array of strings)`
  `"blockheader",`
  `...`
`]`| -|Example Return|`[`
  `"0000002099417930b2ae09feda10e38b58c0f6bb44b4d60fa33f0e000000000000000000d53...",`
  `"000000203ba25a173bfd24d09e0c76002a910b685ca297bd09a17b020000000000000000702..."`
`]`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getheaders | +| Parameters | 1. Block Locators (JSON array, required)
 `[ (json array of strings)`
  `"blocklocator", (string) the known block hash`
  `...`
 `]`
2. hashstop (string) - last desired block's hash | +| Description | Returns block headers starting with the first known block hash from the request. | +| Returns | `[ (json array of strings)`
  `"blockheader",`
  `...`
`]` | +| Example Return | `[`
  `"0000002099417930b2ae09feda10e38b58c0f6bb44b4d60fa33f0e000000000000000000d53...",`
  `"000000203ba25a173bfd24d09e0c76002a910b685ca297bd09a17b020000000000000000702..."`
`]` | [Return to Overview](#MethodOverview)
*** @@ -701,21 +693,21 @@ The following is an overview of the RPC methods which are implemented by btcd, b The following is an overview of the RPC method requests available exclusively to Websocket clients. All of these RPC methods are available to the limited user. Click the method name for further details such as parameter and return information. -|#|Method|Description|Notifications| -|---|------|-----------|-------------| -|1|[authenticate](#authenticate)|Authenticate the connection against the username and passphrase configured for the RPC server.
NOTE: This is only required if an HTTP Authorization header is not being used.|None| -|2|[notifyblocks](#notifyblocks)|Send notifications when a block is connected or disconnected from the best chain.|[blockconnected](#blockconnected), [blockdisconnected](#blockdisconnected), [filteredblockconnected](#filteredblockconnected), and [filteredblockdisconnected](#filteredblockdisconnected)| -|3|[stopnotifyblocks](#stopnotifyblocks)|Cancel registered notifications for whenever a block is connected or disconnected from the main (best) chain. |None| -|4|[notifyreceived](#notifyreceived)|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send notifications when a txout spends to an address.|[recvtx](#recvtx) and [redeemingtx](#redeemingtx)| -|5|[stopnotifyreceived](#stopnotifyreceived)|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered notifications for when a txout spends to any of the passed addresses.|None| -|6|[notifyspent](#notifyspent)|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send notification when a txout is spent.|[redeemingtx](#redeemingtx)| -|7|[stopnotifyspent](#stopnotifyspent)|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered spending notifications for each passed outpoint.|None| -|8|[rescan](#rescan)|*DEPRECATED, for similar functionality see [rescanblocks](#rescanblocks)*
Rescan block chain for transactions to addresses and spent transaction outpoints.|[recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished) | -|9|[notifynewtransactions](#notifynewtransactions)|Send notifications for all new transactions as they are accepted into the mempool.|[txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose)| -|10|[stopnotifynewtransactions](#stopnotifynewtransactions)|Stop sending either a txaccepted or a txacceptedverbose notification when a new transaction is accepted into the mempool.|None| -|11|[session](#session)|Return details regarding a websocket client's current connection.|None| -|12|[loadtxfilter](#loadtxfilter)|Load, add to, or reload a websocket client's transaction filter for mempool transactions, new blocks and rescanblocks.|[relevanttxaccepted](#relevanttxaccepted)| -|13|[rescanblocks](#rescanblocks)|Rescan blocks for transactions matching the loaded transaction filter.|None| +| # | Method | Description | Notifications | +| --- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 1 | [authenticate](#authenticate) | Authenticate the connection against the username and passphrase configured for the RPC server.
NOTE: This is only required if an HTTP Authorization header is not being used. | None | +| 2 | [notifyblocks](#notifyblocks) | Send notifications when a block is connected or disconnected from the best chain. | [blockconnected](#blockconnected), [blockdisconnected](#blockdisconnected), [filteredblockconnected](#filteredblockconnected), and [filteredblockdisconnected](#filteredblockdisconnected) | +| 3 | [stopnotifyblocks](#stopnotifyblocks) | Cancel registered notifications for whenever a block is connected or disconnected from the main (best) chain. | None | +| 4 | [notifyreceived](#notifyreceived) | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send notifications when a txout spends to an address. | [recvtx](#recvtx) and [redeemingtx](#redeemingtx) | +| 5 | [stopnotifyreceived](#stopnotifyreceived) | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered notifications for when a txout spends to any of the passed addresses. | None | +| 6 | [notifyspent](#notifyspent) | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send notification when a txout is spent. | [redeemingtx](#redeemingtx) | +| 7 | [stopnotifyspent](#stopnotifyspent) | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered spending notifications for each passed outpoint. | None | +| 8 | [rescan](#rescan) | *DEPRECATED, for similar functionality see [rescanblocks](#rescanblocks)*
Rescan block chain for transactions to addresses and spent transaction outpoints. | [recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished) | +| 9 | [notifynewtransactions](#notifynewtransactions) | Send notifications for all new transactions as they are accepted into the mempool. | [txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose) | +| 10 | [stopnotifynewtransactions](#stopnotifynewtransactions) | Stop sending either a txaccepted or a txacceptedverbose notification when a new transaction is accepted into the mempool. | None | +| 11 | [session](#session) | Return details regarding a websocket client's current connection. | None | +| 12 | [loadtxfilter](#loadtxfilter) | Load, add to, or reload a websocket client's transaction filter for mempool transactions, new blocks and rescanblocks. | [relevanttxaccepted](#relevanttxaccepted) | +| 13 | [rescanblocks](#rescanblocks) | Rescan blocks for transactions matching the loaded transaction filter. | None |
@@ -723,177 +715,177 @@ user. Click the method name for further details such as parameter and return in -| | | -|---|---| -|Method|authenticate| -|Parameters|1. username (string, required)
2. passphrase (string, required)| -|Description|Authenticate the connection against the username and password configured for the RPC server.
Invoking any other method before authenticating with this command will close the connection.
NOTE: This is only required if an HTTP Authorization header is not being used.| -|Returns|Success: Nothing
Failure: Nothing (websocket disconnected)| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | authenticate | +| Parameters | 1. username (string, required)
2. passphrase (string, required) | +| Description | Authenticate the connection against the username and password configured for the RPC server.
Invoking any other method before authenticating with this command will close the connection.
NOTE: This is only required if an HTTP Authorization header is not being used. | +| Returns | Success: Nothing
Failure: Nothing (websocket disconnected) | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|notifyblocks| -|Notifications|[blockconnected](#blockconnected), [blockdisconnected](#blockdisconnected), [filteredblockconnected](#filteredblockconnected), and [filteredblockdisconnected](#filteredblockdisconnected)| -|Parameters|None| -|Description|Request notifications for whenever a block is connected or disconnected from the main (best) chain.
NOTE: If a client subscribes to both block and transaction (recvtx and redeemingtx) notifications, the blockconnected notification will be sent after all transaction notifications have been sent. This allows clients to know when all relevant transactions for a block have been received.| -|Returns|Nothing| +| | | +| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | notifyblocks | +| Notifications | [blockconnected](#blockconnected), [blockdisconnected](#blockdisconnected), [filteredblockconnected](#filteredblockconnected), and [filteredblockdisconnected](#filteredblockdisconnected) | +| Parameters | None | +| Description | Request notifications for whenever a block is connected or disconnected from the main (best) chain.
NOTE: If a client subscribes to both block and transaction (recvtx and redeemingtx) notifications, the blockconnected notification will be sent after all transaction notifications have been sent. This allows clients to know when all relevant transactions for a block have been received. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|stopnotifyblocks| -|Notifications|None| -|Parameters|None| -|Description|Cancel sending notifications for whenever a block is connected or disconnected from the main (best) chain.| -|Returns|Nothing| +| | | +| ------------- | ---------------------------------------------------------------------------------------------------------- | +| Method | stopnotifyblocks | +| Notifications | None | +| Parameters | None | +| Description | Cancel sending notifications for whenever a block is connected or disconnected from the main (best) chain. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|notifyreceived| -|Notifications|[recvtx](#recvtx) and [redeemingtx](#redeemingtx)| -|Parameters|1. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]`| -|Description|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send a recvtx notification when a transaction added to mempool or appears in a newly-attached block contains a txout pkScript sending to any of the passed addresses. Matching outpoints are automatically registered for redeemingtx notifications.| -|Returns|Nothing| +| | | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | notifyreceived | +| Notifications | [recvtx](#recvtx) and [redeemingtx](#redeemingtx) | +| Parameters | 1. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]` | +| Description | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send a recvtx notification when a transaction added to mempool or appears in a newly-attached block contains a txout pkScript sending to any of the passed addresses. Matching outpoints are automatically registered for redeemingtx notifications. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|stopnotifyreceived| -|Notifications|None| -|Parameters|1. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]`| -|Description|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered receive notifications for each passed address.| -|Returns|Nothing| +| | | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | stopnotifyreceived | +| Notifications | None | +| Parameters | 1. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]` | +| Description | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered receive notifications for each passed address. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|notifyspent| -|Notifications|[redeemingtx](#redeemingtx)| -|Parameters|1. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]`| -|Description|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this btcd instance) and when such a transaction first appears in a newly-attached block.| -|Returns|Nothing| +| | | +| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | notifyspent | +| Notifications | [redeemingtx](#redeemingtx) | +| Parameters | 1. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]` | +| Description | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this lbcd instance) and when such a transaction first appears in a newly-attached block. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|stopnotifyspent| -|Notifications|None| -|Parameters|1. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]`| -|Description|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered spending notifications for each passed outpoint.| -|Returns|Nothing| +| | | +| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | stopnotifyspent | +| Notifications | None | +| Parameters | 1. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]` | +| Description | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered spending notifications for each passed outpoint. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|rescan| -|Notifications|[recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished)| -|Parameters|1. BeginBlock (string, required) block hash to begin rescanning from
2. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]`
3. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]`
4. EndBlock (string, optional) hash of final block to rescan| -|Description|*DEPRECATED, for similar functionality see [rescanblocks](#rescanblocks)*
Rescan block chain for transactions to addresses, starting at block BeginBlock and ending at EndBlock. The current known UTXO set for all passed addresses at height BeginBlock should included in the Outpoints argument. If EndBlock is omitted, the rescan continues through the best block in the main chain. Additionally, if no EndBlock is provided, the client is automatically registered for transaction notifications for all rescanned addresses and the final UTXO set. Rescan results are sent as recvtx and redeemingtx notifications. This call returns once the rescan completes.| -|Returns|Nothing| +| | | +| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | rescan | +| Notifications | [recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished) | +| Parameters | 1. BeginBlock (string, required) block hash to begin rescanning from
2. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]`
3. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]`
4. EndBlock (string, optional) hash of final block to rescan | +| Description | *DEPRECATED, for similar functionality see [rescanblocks](#rescanblocks)*
Rescan block chain for transactions to addresses, starting at block BeginBlock and ending at EndBlock. The current known UTXO set for all passed addresses at height BeginBlock should included in the Outpoints argument. If EndBlock is omitted, the rescan continues through the best block in the main chain. Additionally, if no EndBlock is provided, the client is automatically registered for transaction notifications for all rescanned addresses and the final UTXO set. Rescan results are sent as recvtx and redeemingtx notifications. This call returns once the rescan completes. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|notifynewtransactions| -|Notifications|[txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose)| -|Parameters|1. verbose (boolean, optional, default=false) - specifies which type of notification to receive. If verbose is true, then the caller receives [txacceptedverbose](#txacceptedverbose), otherwise the caller receives [txaccepted](#txaccepted)| -|Description|Send either a [txaccepted](#txaccepted) or a [txacceptedverbose](#txacceptedverbose) notification when a new transaction is accepted into the mempool.| -|Returns|Nothing| +| | | +| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | notifynewtransactions | +| Notifications | [txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose) | +| Parameters | 1. verbose (boolean, optional, default=false) - specifies which type of notification to receive. If verbose is true, then the caller receives [txacceptedverbose](#txacceptedverbose), otherwise the caller receives [txaccepted](#txaccepted) | +| Description | Send either a [txaccepted](#txaccepted) or a [txacceptedverbose](#txacceptedverbose) notification when a new transaction is accepted into the mempool. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|stopnotifynewtransactions| -|Notifications|None| -|Parameters|None| -|Description|Stop sending either a [txaccepted](#txaccepted) or a [txacceptedverbose](#txacceptedverbose) notification when a new transaction is accepted into the mempool.| -|Returns|Nothing| +| | | +| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | stopnotifynewtransactions | +| Notifications | None | +| Parameters | None | +| Description | Stop sending either a [txaccepted](#txaccepted) or a [txacceptedverbose](#txacceptedverbose) notification when a new transaction is accepted into the mempool. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|session| -|Notifications|None| -|Parameters|None| -|Description|Return a JSON object with details regarding a websocket client's current connection to the RPC server. This currently only includes the session ID, a random unsigned 64-bit integer that is created for each newly connected client. Session IDs may be used to verify that the current connection was not lost and subsequently reestablished.| -|Returns|`{ (json object)`
  `"sessionid": n (numeric) the session ID`
`}`| -|Example Return|`{`
  `"sessionid": 67089679842`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | session | +| Notifications | None | +| Parameters | None | +| Description | Return a JSON object with details regarding a websocket client's current connection to the RPC server. This currently only includes the session ID, a random unsigned 64-bit integer that is created for each newly connected client. Session IDs may be used to verify that the current connection was not lost and subsequently reestablished. | +| Returns | `{ (json object)`
  `"sessionid": n (numeric) the session ID`
`}` | +| Example Return | `{`
  `"sessionid": 67089679842`
`}` | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|loadtxfilter| -|Notifications|[relevanttxaccepted](#relevanttxaccepted)| -|Parameters|1. Reload (boolean, required) - Load a new filter instead of adding data to an existing one
2. Addresses (JSON array, required) - Array of addresses to add to the transaction filter
3. Outpoints (JSON array, required) - Array of outpoints to add to the transaction filter| -|Description|Load, add to, or reload a websocket client's transaction filter for mempool transactions, new blocks and [rescanblocks](#rescanblocks).| -|Returns|Nothing| +| | | +| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | loadtxfilter | +| Notifications | [relevanttxaccepted](#relevanttxaccepted) | +| Parameters | 1. Reload (boolean, required) - Load a new filter instead of adding data to an existing one
2. Addresses (JSON array, required) - Array of addresses to add to the transaction filter
3. Outpoints (JSON array, required) - Array of outpoints to add to the transaction filter | +| Description | Load, add to, or reload a websocket client's transaction filter for mempool transactions, new blocks and [rescanblocks](#rescanblocks). | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|rescanblocks| -|Notifications|None| -|Parameters|1. Blockhashes (JSON array, required) - List of hashes to rescan. Each next block must be a child of the previous.| -|Description|Rescan blocks for transactions matching the loaded transaction filter.| -|Returns|`[ (JSON array)`
  `{ (JSON object)`
    `"hash": "data", (string) Hash of the matching block.`
    `"transactions": [ (JSON array) List of matching transactions, serialized and hex-encoded.`
      `"serializedtx" (string) Serialized and hex-encoded transaction.`
    `]`
  `}`
`]`| -|Example Return|`[`
  `{`
    `"hash": "0000002099417930b2ae09feda10e38b58c0f6bb44b4d60fa33f0e000000000000000000d53...",`
    `"transactions": [`
      `"493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8..."`
    `]`
  `}`
`]`| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | rescanblocks | +| Notifications | None | +| Parameters | 1. Blockhashes (JSON array, required) - List of hashes to rescan. Each next block must be a child of the previous. | +| Description | Rescan blocks for transactions matching the loaded transaction filter. | +| Returns | `[ (JSON array)`
  `{ (JSON object)`
    `"hash": "data", (string) Hash of the matching block.`
    `"transactions": [ (JSON array) List of matching transactions, serialized and hex-encoded.`
      `"serializedtx" (string) Serialized and hex-encoded transaction.`
    `]`
  `}`
`]` | +| Example Return | `[`
  `{`
    `"hash": "0000002099417930b2ae09feda10e38b58c0f6bb44b4d60fa33f0e000000000000000000d53...",`
    `"transactions": [`
      `"493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8..."`
    `]`
  `}`
`]` |
### 8. Notifications (Websocket-specific) -btcd uses standard JSON-RPC notifications to notify clients of changes, rather than requiring clients to poll btcd for updates. JSON-RPC notifications are a subset of requests, but do not contain an ID. The notification type is categorized by the `method` field and additional details are sent as a JSON array in the `params` field. +lbcd uses standard JSON-RPC notifications to notify clients of changes, rather than requiring clients to poll lbcd for updates. JSON-RPC notifications are a subset of requests, but do not contain an ID. The notification type is categorized by the `method` field and additional details are sent as a JSON array in the `params` field. @@ -901,19 +893,19 @@ btcd uses standard JSON-RPC notifications to notify clients of changes, rather t The following is an overview of the JSON-RPC notifications used for Websocket connections. Click the method name for further details of the context(s) in which they are sent and their parameters. -|#|Method|Description|Request| -|---|------|-----------|-------| -|1|[blockconnected](#blockconnected)|*DEPRECATED, for similar functionality see [filteredblockconnected](#filteredblockconnected)*
Block connected to the main chain.|[notifyblocks](#notifyblocks)| -|2|[blockdisconnected](#blockdisconnected)|*DEPRECATED, for similar functionality see [filteredblockdisconnected](#filteredblockdisconnected)*
Block disconnected from the main chain.|[notifyblocks](#notifyblocks)| -|3|[recvtx](#recvtx)|*DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Processed a transaction output spending to a wallet address.|[notifyreceived](#notifyreceived) and [rescan](#rescan)| -|4|[redeemingtx](#redeemingtx)|*DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Processed a transaction that spends a registered outpoint.|[notifyspent](#notifyspent) and [rescan](#rescan)| -|5|[txaccepted](#txaccepted)|Received a new transaction after requesting simple notifications of all new transactions accepted into the mempool.|[notifynewtransactions](#notifynewtransactions)| -|6|[txacceptedverbose](#txacceptedverbose)|Received a new transaction after requesting verbose notifications of all new transactions accepted into the mempool.|[notifynewtransactions](#notifynewtransactions)| -|7|[rescanprogress](#rescanprogress)|*DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
A rescan operation that is underway has made progress.|[rescan](#rescan)| -|8|[rescanfinished](#rescanfinished)|*DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
A rescan operation has completed.|[rescan](#rescan)| -|9|[relevanttxaccepted](#relevanttxaccepted)|A transaction matching the tx filter has been accepted into the mempool.|[loadtxfilter](#loadtxfilter)| -|10|[filteredblockconnected](#filteredblockconnected)|Block connected to the main chain; contains any transactions that match the client's tx filter.|[notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter)| -|11|[filteredblockdisconnected](#filteredblockdisconnected)|Block disconnected from the main chain.|[notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter)| +| # | Method | Description | Request | +| --- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| 1 | [blockconnected](#blockconnected) | *DEPRECATED, for similar functionality see [filteredblockconnected](#filteredblockconnected)*
Block connected to the main chain. | [notifyblocks](#notifyblocks) | +| 2 | [blockdisconnected](#blockdisconnected) | *DEPRECATED, for similar functionality see [filteredblockdisconnected](#filteredblockdisconnected)*
Block disconnected from the main chain. | [notifyblocks](#notifyblocks) | +| 3 | [recvtx](#recvtx) | *DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Processed a transaction output spending to a wallet address. | [notifyreceived](#notifyreceived) and [rescan](#rescan) | +| 4 | [redeemingtx](#redeemingtx) | *DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Processed a transaction that spends a registered outpoint. | [notifyspent](#notifyspent) and [rescan](#rescan) | +| 5 | [txaccepted](#txaccepted) | Received a new transaction after requesting simple notifications of all new transactions accepted into the mempool. | [notifynewtransactions](#notifynewtransactions) | +| 6 | [txacceptedverbose](#txacceptedverbose) | Received a new transaction after requesting verbose notifications of all new transactions accepted into the mempool. | [notifynewtransactions](#notifynewtransactions) | +| 7 | [rescanprogress](#rescanprogress) | *DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
A rescan operation that is underway has made progress. | [rescan](#rescan) | +| 8 | [rescanfinished](#rescanfinished) | *DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
A rescan operation has completed. | [rescan](#rescan) | +| 9 | [relevanttxaccepted](#relevanttxaccepted) | A transaction matching the tx filter has been accepted into the mempool. | [loadtxfilter](#loadtxfilter) | +| 10 | [filteredblockconnected](#filteredblockconnected) | Block connected to the main chain; contains any transactions that match the client's tx filter. | [notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter) | +| 11 | [filteredblockdisconnected](#filteredblockdisconnected) | Block disconnected from the main chain. | [notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter) |
@@ -921,142 +913,142 @@ The following is an overview of the JSON-RPC notifications used for Websocket co -| | | -|---|---| -|Method|blockconnected| -|Request|[notifyblocks](#notifyblocks)| -|Parameters|1. BlockHash (string) hex-encoded bytes of the attached block hash
2. BlockHeight (numeric) height of the attached block
3. BlockTime (numeric) unix time of the attached block| -|Description|*DEPRECATED, for similar functionality see [filteredblockconnected](#filteredblockconnected)*
Notifies when a block has been added to the main chain. Notification is sent to all connected clients.| -|Example|Example blockconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockconnected",`
 `"params":`
  `[`
   `"000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd",`
   `280330,`
   `1389636265`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | blockconnected | +| Request | [notifyblocks](#notifyblocks) | +| Parameters | 1. BlockHash (string) hex-encoded bytes of the attached block hash
2. BlockHeight (numeric) height of the attached block
3. BlockTime (numeric) unix time of the attached block | +| Description | *DEPRECATED, for similar functionality see [filteredblockconnected](#filteredblockconnected)*
Notifies when a block has been added to the main chain. Notification is sent to all connected clients. | +| Example | Example blockconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockconnected",`
 `"params":`
  `[`
   `"000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd",`
   `280330,`
   `1389636265`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|blockdisconnected| -|Request|[notifyblocks](#notifyblocks)| -|Parameters|1. BlockHash (string) hex-encoded bytes of the disconnected block hash
2. BlockHeight (numeric) height of the disconnected block
3. BlockTime (numeric) unix time of the disconnected block| -|Description|*DEPRECATED, for similar functionality see [filteredblockdisconnected](#filteredblockdisconnected)*
Notifies when a block has been removed from the main chain. Notification is sent to all connected clients.| -|Example|Example blockdisconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockdisconnected",`
 `"params":`
  `[`
   `"000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd",`
   `280330,`
   `1389636265`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | blockdisconnected | +| Request | [notifyblocks](#notifyblocks) | +| Parameters | 1. BlockHash (string) hex-encoded bytes of the disconnected block hash
2. BlockHeight (numeric) height of the disconnected block
3. BlockTime (numeric) unix time of the disconnected block | +| Description | *DEPRECATED, for similar functionality see [filteredblockdisconnected](#filteredblockdisconnected)*
Notifies when a block has been removed from the main chain. Notification is sent to all connected clients. | +| Example | Example blockdisconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockdisconnected",`
 `"params":`
  `[`
   `"000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd",`
   `280330,`
   `1389636265`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|recvtx| -|Request|[rescan](#rescan) or [notifyreceived](#notifyreceived)| -|Parameters|1. Transaction (string) full transaction encoded as a hex string
2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined| -|Description|*DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Notifies a client when a transaction is processed that contains at least a single output with a pkScript sending to a requested address. If multiple outputs send to requested addresses, a single notification is sent. If a mempool (unmined) transaction is processed, the block details object (second parameter) is excluded.| -|Example|Example recvtx notification for mainnet transaction 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad when processed by mempool (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000..."`
  `],`
 `"id": null`
`}`
The recvtx notification for the same txout, after the transaction was mined into block 276425:
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000...",`
   `{`
    `"height": 276425,`
    `"hash": "000000000000000325474bb799b9e591f965ca4461b72cb7012b808db92bb2fc",`
    `"index": 684,`
    `"time": 1387737310`
   `}`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | recvtx | +| Request | [rescan](#rescan) or [notifyreceived](#notifyreceived) | +| Parameters | 1. Transaction (string) full transaction encoded as a hex string
2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined | +| Description | *DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Notifies a client when a transaction is processed that contains at least a single output with a pkScript sending to a requested address. If multiple outputs send to requested addresses, a single notification is sent. If a mempool (unmined) transaction is processed, the block details object (second parameter) is excluded. | +| Example | Example recvtx notification for mainnet transaction 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad when processed by mempool (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000..."`
  `],`
 `"id": null`
`}`
The recvtx notification for the same txout, after the transaction was mined into block 276425:
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000...",`
   `{`
    `"height": 276425,`
    `"hash": "000000000000000325474bb799b9e591f965ca4461b72cb7012b808db92bb2fc",`
    `"index": 684,`
    `"time": 1387737310`
   `}`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|redeemingtx| -|Requests|[notifyspent](#notifyspent) and [rescan](#rescan)| -|Parameters|1. Transaction (string) full transaction encoded as a hex string
2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined| -|Description|*DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Notifies a client when an registered outpoint is spent by a transaction accepted to mempool and/or mined into a block.| -|Example|Example redeemingtx notification for mainnet outpoint 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad:0 after being spent by transaction 4ad0c16ac973ff675dec1f3e5f1273f1c45be2a63554343f21b70240a1e43ece (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "redeemingtx",`
 `"params":`
  `[`
   `"0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000..."`
  `],`
 `"id": null`
`}`
The redeemingtx notification for the same txout, after the spending transaction was mined into block 279143:
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000...",`
   `{`
    `"height": 279143,`
    `"hash": "00000000000000017188b968a371bab95aa43522665353b646e41865abae02a4",`
    `"index": 6,`
    `"time": 1389115004`
   `}`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | redeemingtx | +| Requests | [notifyspent](#notifyspent) and [rescan](#rescan) | +| Parameters | 1. Transaction (string) full transaction encoded as a hex string
2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined | +| Description | *DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Notifies a client when an registered outpoint is spent by a transaction accepted to mempool and/or mined into a block. | +| Example | Example redeemingtx notification for mainnet outpoint 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad:0 after being spent by transaction 4ad0c16ac973ff675dec1f3e5f1273f1c45be2a63554343f21b70240a1e43ece (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "redeemingtx",`
 `"params":`
  `[`
   `"0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000..."`
  `],`
 `"id": null`
`}`
The redeemingtx notification for the same txout, after the spending transaction was mined into block 279143:
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000...",`
   `{`
    `"height": 279143,`
    `"hash": "00000000000000017188b968a371bab95aa43522665353b646e41865abae02a4",`
    `"index": 6,`
    `"time": 1389115004`
   `}`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|txaccepted| -|Request|[notifynewtransactions](#notifynewtransactions)| -|Parameters|1. TxHash (string) hex-encoded bytes of the transaction hash
2. Amount (numeric) sum of the value of all the transaction outpoints| -|Description|Notifies when a new transaction has been accepted and the client has requested standard transaction details.| -|Example|Example txaccepted notification for mainnet transaction id "16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261" (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "txaccepted",`
 `"params":`
  `[`
   `"16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261",`
   `55838384`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | txaccepted | +| Request | [notifynewtransactions](#notifynewtransactions) | +| Parameters | 1. TxHash (string) hex-encoded bytes of the transaction hash
2. Amount (numeric) sum of the value of all the transaction outpoints | +| Description | Notifies when a new transaction has been accepted and the client has requested standard transaction details. | +| Example | Example txaccepted notification for mainnet transaction id "16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261" (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "txaccepted",`
 `"params":`
  `[`
   `"16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261",`
   `55838384`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|txacceptedverbose| -|Request|[notifynewtransactions](#notifynewtransactions)| -|Parameters|1. RawTx (json object) the transaction as a json object (see getrawtransaction json object details)| -|Description|Notifies when a new transaction has been accepted and the client has requested verbose transaction details.| -|Example|Example txacceptedverbose notification (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "txacceptedverbose",`
 `"params":`
  `[`
   `{`
    `"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...",`
    `"txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9",`
    `"version": 1,`
    `"locktime": 0,`
    `"vin": [`
    For coinbase transactions:
      `{ (json object)`
        `"coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f",`
        `"sequence": 0,`
      `}`
    For non-coinbase transactions:
      `{`
        `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
        `"vout": 0,`
        `"scriptSig": {`
          `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
          `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
        `}`
        `"sequence": 4294967295,`
      `}`
    `],`
    `"vout": [`
     `{`
      `"value": 25.1394,`
      `"n": 0,`
      `"scriptPubKey": {`
       `"asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG",`
       `"hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac",`
       `"reqSigs": 1,`
       `"type": "pubkeyhash"`
       `"addresses": [`
        `"1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh",`
       `]`
     `}`
    `]`
   `}`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | txacceptedverbose | +| Request | [notifynewtransactions](#notifynewtransactions) | +| Parameters | 1. RawTx (json object) the transaction as a json object (see getrawtransaction json object details) | +| Description | Notifies when a new transaction has been accepted and the client has requested verbose transaction details. | +| Example | Example txacceptedverbose notification (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "txacceptedverbose",`
 `"params":`
  `[`
   `{`
    `"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...",`
    `"txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9",`
    `"version": 1,`
    `"locktime": 0,`
    `"vin": [`
    For coinbase transactions:
      `{ (json object)`
        `"coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f",`
        `"sequence": 0,`
      `}`
    For non-coinbase transactions:
      `{`
        `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
        `"vout": 0,`
        `"scriptSig": {`
          `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
          `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
        `}`
        `"sequence": 4294967295,`
      `}`
    `],`
    `"vout": [`
     `{`
      `"value": 25.1394,`
      `"n": 0,`
      `"scriptPubKey": {`
       `"asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG",`
       `"hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac",`
       `"reqSigs": 1,`
       `"type": "pubkeyhash"`
       `"addresses": [`
        `"1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh",`
       `]`
     `}`
    `]`
   `}`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|rescanprogress| -|Request|[rescan](#rescan)| -|Parameters|1. Hash (string) hash of the last processed block
2. Height (numeric) height of the last processed block
3. Time (numeric) UNIX time of the last processed block| -|Description|*DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
Notifies a client with the current progress at periodic intervals when a long-running [rescan](#rescan) is underway.| -|Example|`{`
 `"jsonrpc": "1.0",`
 `"method": "rescanprogress",`
 `"params":`
  `[`
   `"0000000000000ea86b49e11843b2ad937ac89ae74a963c7edd36e0147079b89d",`
   `127213,`
   `1306533807`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | rescanprogress | +| Request | [rescan](#rescan) | +| Parameters | 1. Hash (string) hash of the last processed block
2. Height (numeric) height of the last processed block
3. Time (numeric) UNIX time of the last processed block | +| Description | *DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
Notifies a client with the current progress at periodic intervals when a long-running [rescan](#rescan) is underway. | +| Example | `{`
 `"jsonrpc": "1.0",`
 `"method": "rescanprogress",`
 `"params":`
  `[`
   `"0000000000000ea86b49e11843b2ad937ac89ae74a963c7edd36e0147079b89d",`
   `127213,`
   `1306533807`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|rescanfinished| -|Request|[rescan](#rescan)| -|Parameters|1. Hash (string) hash of the last rescanned block
2. Height (numeric) height of the last rescanned block
3. Time (numeric) UNIX time of the last rescanned block | -|Description|*DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
Notifies a client that the [rescan](#rescan) has completed and no further notifications will be sent.| -|Example|`{`
 `"jsonrpc": "1.0",`
 `"method": "rescanfinished",`
 `"params":`
  `[`
   `"0000000000000ea86b49e11843b2ad937ac89ae74a963c7edd36e0147079b89d",`
   `127213,`
   `1306533807`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | rescanfinished | +| Request | [rescan](#rescan) | +| Parameters | 1. Hash (string) hash of the last rescanned block
2. Height (numeric) height of the last rescanned block
3. Time (numeric) UNIX time of the last rescanned block | +| Description | *DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
Notifies a client that the [rescan](#rescan) has completed and no further notifications will be sent. | +| Example | `{`
 `"jsonrpc": "1.0",`
 `"method": "rescanfinished",`
 `"params":`
  `[`
   `"0000000000000ea86b49e11843b2ad937ac89ae74a963c7edd36e0147079b89d",`
   `127213,`
   `1306533807`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|relevanttxaccepted| -|Request|[loadtxfilter](#loadtxfilter)| -|Parameters|1. Transaction (string) hex-encoded serialized transaction matching the client's filter loaded ith [loadtxfilter](#loadtxfilter)| -|Description|Notifies a client that a transaction matching the client's tx filter has been accepted into he mempool.| -|Example|Example `relevanttxaccepted` notification (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "relevanttxaccepted",`
 `"params": [`
  `"01000000014221abdcca25c8a3b0c044034875dece048c77d567a806f0c2e7e0f5e25a8f100..."`
 `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | relevanttxaccepted | +| Request | [loadtxfilter](#loadtxfilter) | +| Parameters | 1. Transaction (string) hex-encoded serialized transaction matching the client's filter loaded ith [loadtxfilter](#loadtxfilter) | +| Description | Notifies a client that a transaction matching the client's tx filter has been accepted into he mempool. | +| Example | Example `relevanttxaccepted` notification (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "relevanttxaccepted",`
 `"params": [`
  `"01000000014221abdcca25c8a3b0c044034875dece048c77d567a806f0c2e7e0f5e25a8f100..."`
 `],`
 `"id": null`
`}` | ***
-| | | -|---|---| -|Method|filteredblockconnected| -|Request|[notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter)| -|Parameters|1. BlockHeight (numeric) height of the attached block
2. Header (string) hex-encoded serialized header of the attached block
3. Transactions (JSON array) hex-encoded serialized transactions matching the filter for the client connection loaded with [loadtxfilter](#loadtxfilter)| -|Description|Notifies when a block has been added to the main chain. Notification is sent to all connected clients.| -|Example|Example filteredblockconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "filteredblockconnected",`
 `"params":`
  `[`
   `280330,`
   `"0200000052d1e8813f697293e41942aa230e7e4fcc44832d78a1372202000000000000006aa...",`
   `[`
    `"01000000014221abdcca25c8a3b0c044034875dece048c77d567a806f0c2e7e0f5e25a8f100..."`
   `]`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | filteredblockconnected | +| Request | [notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter) | +| Parameters | 1. BlockHeight (numeric) height of the attached block
2. Header (string) hex-encoded serialized header of the attached block
3. Transactions (JSON array) hex-encoded serialized transactions matching the filter for the client connection loaded with [loadtxfilter](#loadtxfilter) | +| Description | Notifies when a block has been added to the main chain. Notification is sent to all connected clients. | +| Example | Example filteredblockconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "filteredblockconnected",`
 `"params":`
  `[`
   `280330,`
   `"0200000052d1e8813f697293e41942aa230e7e4fcc44832d78a1372202000000000000006aa...",`
   `[`
    `"01000000014221abdcca25c8a3b0c044034875dece048c77d567a806f0c2e7e0f5e25a8f100..."`
   `]`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|filteredblockdisconnected| -|Request|[notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter)| -|Parameters|1. BlockHeight (numeric) height of the disconnected block
2. Header (string) hex-encoded serialized header of the disconnected block| -|Description|Notifies when a block has been removed from the main chain. Notification is sent to all connected clients.| -|Example|Example blockdisconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockdisconnected",`
 `"params":`
  `[`
   `280330,`
   `"0200000052d1e8813f697293e41942aa230e7e4fcc44832d78a1372202000000000000006aa..."`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | filteredblockdisconnected | +| Request | [notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter) | +| Parameters | 1. BlockHeight (numeric) height of the disconnected block
2. Header (string) hex-encoded serialized header of the disconnected block | +| Description | Notifies when a block has been removed from the main chain. Notification is sent to all connected clients. | +| Example | Example blockdisconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockdisconnected",`
 `"params":`
  `[`
   `280330,`
   `"0200000052d1e8813f697293e41942aa230e7e4fcc44832d78a1372202000000000000006aa..."`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
@@ -1075,7 +1067,7 @@ various languages. **9.1 Go** This section provides examples of using the RPC interface using Go and the -[rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) package. +[rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) package. * [Using getblockcount to Retrieve the Current Block Height](#ExampleGetBlockCount) * [Using getblock to Retrieve the Genesis Block](#ExampleGetBlock) @@ -1087,8 +1079,8 @@ This section provides examples of using the RPC interface using Go and the **9.1.1 Using getblockcount to Retrieve the Current Block Height**
The following is an example Go application which uses the -[rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) package to connect with -a btcd instance via Websockets, issues [getblockcount](#getblockcount) to +[rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) package to connect with +a lbcd instance via Websockets, issues [getblockcount](#getblockcount) to retrieve the current block height, and displays it. ```Go @@ -1099,16 +1091,16 @@ import ( "log" "path/filepath" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) func main() { // Load the certificate for the TLS connection which is automatically - // generated by btcd when it starts the RPC server and doesn't already + // generated by lbcd when it starts the RPC server and doesn't already // have one. - btcdHomeDir := btcutil.AppDataDir("btcd", false) - certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert")) + lbcdHomeDir := btcutil.AppDataDir("lbcd", false) + certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) } @@ -1116,8 +1108,8 @@ func main() { // Create a new RPC client using websockets. Since this example is // not long-lived, the connection will be closed as soon as the program // exits. - connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8334", + connCfg := &btcrpcclient.ConnConfig{ + Host: "localhost:9245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", @@ -1149,8 +1141,8 @@ Which results in: **9.1.2 Using getblock to Retrieve the Genesis Block**
The following is an example Go application which uses the -[rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) package to connect with -a btcd instance via Websockets, issues [getblock](#getblock) to retrieve +[rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) package to connect with +a lbcd instance via Websockets, issues [getblock](#getblock) to retrieve information about the Genesis block, and display a few details about it. ```Go @@ -1162,17 +1154,17 @@ import ( "path/filepath" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) func main() { // Load the certificate for the TLS connection which is automatically - // generated by btcd when it starts the RPC server and doesn't already + // generated by lbcd when it starts the RPC server and doesn't already // have one. - btcdHomeDir := btcutil.AppDataDir("btcd", false) - certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert")) + lbcdHomeDir := btcutil.AppDataDir("lbcd", false) + certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) } @@ -1180,8 +1172,8 @@ func main() { // Create a new RPC client using websockets. Since this example is // not long-lived, the connection will be closed as soon as the program // exits. - connCfg := &rpcclient.ConnConfig{ - Host: "localhost:18334", + connCfg := &btcrpcclient.ConnConfig{ + Host: "localhost:19245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", @@ -1239,8 +1231,8 @@ Num transactions: 1 Notifications (Websocket-specific)**
The following is an example Go application which uses the -[rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) package to connect with -a btcd instance via Websockets and registers for +[rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) package to connect with +a lbcd instance via Websockets and registers for [blockconnected](#blockconnected) and [blockdisconnected](#blockdisconnected) notifications with [notifyblocks](#notifyblocks). It also sets up handlers for the notifications. @@ -1254,9 +1246,9 @@ import ( "path/filepath" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) func main() { @@ -1272,17 +1264,17 @@ func main() { } // Load the certificate for the TLS connection which is automatically - // generated by btcd when it starts the RPC server and doesn't already + // generated by lbcd when it starts the RPC server and doesn't already // have one. - btcdHomeDir := btcutil.AppDataDir("btcd", false) - certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert")) + lbcdHomeDir := btcutil.AppDataDir("lbcd", false) + certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) } // Create a new RPC client using websockets. - connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8334", + connCfg := &btcrpcclient.ConnConfig{ + Host: "localhost:9245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", @@ -1337,7 +1329,7 @@ Example output: **9.2.1 Using notifyblocks to be Notified of Block Connects and Disconnects**
The following is example node.js code which uses [ws](https://github.com/einaros/ws) -(can be installed with `npm install ws`) to connect with a btcd instance, +(can be installed with `npm install ws`) to connect with a lbcd instance, issues [notifyblocks](#notifyblocks) to register for [blockconnected](#blockconnected) and [blockdisconnected](#blockdisconnected) notifications, and displays all incoming messages. @@ -1347,17 +1339,17 @@ var fs = require('fs'); var WebSocket = require('ws'); // Load the certificate for the TLS connection which is automatically -// generated by btcd when it starts the RPC server and doesn't already +// generated by lbcd when it starts the RPC server and doesn't already // have one. -var cert = fs.readFileSync('/path/to/btcd/appdata/rpc.cert'); +var cert = fs.readFileSync('/path/to/lbcd/appdata/rpc.cert'); var user = "yourusername"; var password = "yourpassword"; -// Initiate the websocket connection. The btcd generated certificate acts as +// Initiate the websocket connection. The lbcd generated certificate acts as // its own certificate authority, so it needs to be specified in the 'ca' array // for the certificate to properly validate. -var ws = new WebSocket('wss://127.0.0.1:8334/ws', { +var ws = new WebSocket('wss://127.0.0.1:9245/ws', { headers: { 'Authorization': 'Basic '+new Buffer(user+':'+password).toString('base64') }, diff --git a/docs/mining.md b/docs/mining.md index 29a3e898..226d560b 100644 --- a/docs/mining.md +++ b/docs/mining.md @@ -1,6 +1,6 @@ # Mining -btcd supports the `getblocktemplate` RPC. +lbcd supports the `getblocktemplate` RPC. The limited user cannot access this RPC. ## Add the payment addresses with the `miningaddr` option @@ -13,18 +13,20 @@ miningaddr=12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX miningaddr=1M83ju3EChKYyysmM2FXtLNftbacagd8FR ``` -## Add btcd's RPC TLS certificate to system Certificate Authority list +## Add lbcd's RPC TLS certificate to system Certificate Authority list -`cgminer` uses [curl](http://curl.haxx.se/) to fetch data from the RPC server. -Since curl validates the certificate by default, we must install the `btcd` RPC +Various miners use [curl](http://curl.haxx.se/) to fetch data from the RPC server. +Since curl validates the certificate by default, we must install the `lbcd` RPC certificate into the default system Certificate Authority list. ## Ubuntu -1. Copy rpc.cert to /usr/share/ca-certificates: `# cp /home/user/.btcd/rpc.cert /usr/share/ca-certificates/btcd.crt` -2. Add btcd.crt to /etc/ca-certificates.conf: `# echo btcd.crt >> /etc/ca-certificates.conf` +1. Copy rpc.cert to /usr/share/ca-certificates: `# cp /home/user/.lbcd/rpc.cert /usr/share/ca-certificates/lbcd.crt` +2. Add lbcd.crt to /etc/ca-certificates.conf: `# echo lbcd.crt >> /etc/ca-certificates.conf` 3. Update the CA certificate list: `# update-ca-certificates` ## Set your mining software url to use https -`cgminer -o https://127.0.0.1:8334 -u rpcuser -p rpcpassword` +`cgminer -o https://127.0.0.1:9245 -u rpcuser -p rpcpassword` + +Alternatively, you can disable TLS with the `--notls` option for the server. diff --git a/docs/table_of_content.md b/docs/table_of_content.md deleted file mode 100644 index 85f08a97..00000000 --- a/docs/table_of_content.md +++ /dev/null @@ -1,13 +0,0 @@ -# Contents - -* [Installation](installation.md) -* [Update](update.md) -* [Configuration](configuration.md) -* [Configuring TOR](configuring_tor.md) -* [Controlling](controlling.md) -* [Mining](mining.md) -* [Wallet](wallet.md) -* [Developer resources](developer_resources.md) -* [JSON RPC API](json_rpc_api.md) -* [Code contribution guidelines](code_contribution_guidelines.md) -* [Contact](contact.md) diff --git a/docs/update.md b/docs/update.md deleted file mode 100644 index 1fb847cf..00000000 --- a/docs/update.md +++ /dev/null @@ -1,8 +0,0 @@ -# Update - -* Run the following commands to update btcd, all dependencies, and install it: - -```bash -cd $GOPATH/src/github.com/btcsuite/btcd -git pull && GO111MODULE=on go install -v . ./cmd/... -``` diff --git a/docs/using_docker.md b/docs/using_docker.md deleted file mode 100644 index 0809abc1..00000000 --- a/docs/using_docker.md +++ /dev/null @@ -1,160 +0,0 @@ -# Using Docker - -- [Using Docker](#using-docker) - - [Introduction](#introduction) - - [Docker volumes](#docker-volumes) - - [Known error messages when starting the btcd container](#known-error-messages-when-starting-the-btcd-container) - - [Examples](#examples) - - [Preamble](#preamble) - - [Full node without RPC port](#full-node-without-rpc-port) - - [Full node with RPC port](#full-node-with-rpc-port) - - [Full node with RPC port running on TESTNET](#full-node-with-rpc-port-running-on-testnet) - -## Introduction - -With Docker you can easily set up *btcd* to run your Bitcoin full node. You can find the official *btcd* Docker images on Docker Hub [btcsuite/btcd](https://hub.docker.com/r/btcsuite/btcd). The Docker source file of this image is located at [Dockerfile](https://github.com/btcsuite/btcd/blob/master/Dockerfile). - -This documentation focuses on running Docker container with *docker-compose.yml* files. These files are better to read and you can use them as a template for your own use. For more information about Docker and Docker compose visit the official [Docker documentation](https://docs.docker.com/). - -## Docker volumes - -**Special diskspace hint**: The following examples are using a Docker managed volume. The volume is named *btcd-data* This will use a lot of disk space, because it contains the full Bitcoin blockchain. Please make yourself familiar with [Docker volumes](https://docs.docker.com/storage/volumes/). - -The *btcd-data* volume will be reused, if you upgrade your *docker-compose.yml* file. Keep in mind, that it is not automatically removed by Docker, if you delete the btcd container. If you don't need the volume anymore, please delete it manually with the command: - -```bash -docker volume ls -docker volume rm btcd-data -``` - -For binding a local folder to your *btcd* container please read the [Docker documentation](https://docs.docker.com/). The preferred way is to use a Docker managed volume. - -## Known error messages when starting the btcd container - -We pass all needed arguments to *btcd* as command line parameters in our *docker-compose.yml* file. It doesn't make sense to create a *btcd.conf* file. This would make things too complicated. Anyhow *btcd* will complain with following log messages when starting. These messages can be ignored: - -```bash -Error creating a default config file: open /sample-btcd.conf: no such file or directory -... -[WRN] BTCD: open /root/.btcd/btcd.conf: no such file or directory -``` - -## Examples - -### Preamble - -All following examples uses some defaults: - -- container_name: btcd - Name of the docker container that is be shown by e.g. ```docker ps -a``` - -- hostname: btcd **(very important to set a fixed name before first start)** - The internal hostname in the docker container. By default, docker is recreating the hostname every time you change the *docker-compose.yml* file. The default hostnames look like *ef00548d4fa5*. This is a problem when using the *btcd* RPC port. The RPC port is using a certificate to validate the hostname. If the hostname changes you need to recreate the certificate. To avoid this, you should set a fixed hostname before the first start. This ensures, that the docker volume is created with a certificate with this hostname. - -- restart: unless-stopped - Starts the *btcd* container when Docker starts, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker restarts. - -To use the following examples create an empty directory. In this directory create a file named *docker-compose.yml*, copy and paste the example into the *docker-compose.yml* file and run it. - -```bash -mkdir ~/btcd-docker -cd ~/btcd-docker -touch docker-compose.yaml -nano docker-compose.yaml (use your favourite editor to edit the compose file) -docker-compose up (creates and starts a new btcd container) -``` - -With the following commands you can control *docker-compose*: - -```docker-compose up -d``` (creates and starts the container in background) - -```docker-compose down``` (stops and delete the container. **The docker volume btcd-data will not be deleted**) - -```docker-compose stop``` (stops the container) - -```docker-compose start``` (starts the container) - -```docker ps -a``` (list all running and stopped container) - -```docker volume ls``` (lists all docker volumes) - -```docker logs btcd``` (shows the log ) - -```docker-compose help``` (brings up some helpful information) - -### Full node without RPC port - -Let's start with an easy example. If you just want to create a full node without the need of using the RPC port, you can use the following example. This example will launch *btcd* and exposes only the default p2p port 8333 to the outside world: - -```yaml -version: "2" - -services: - btcd: - container_name: btcd - hostname: btcd - image: btcsuite/btcd:latest - restart: unless-stopped - volumes: - - btcd-data:/root/.btcd - ports: - - 8333:8333 - -volumes: - btcd-data: -``` - -### Full node with RPC port - -To use the RPC port of *btcd* you need to specify a *username* and a very strong *password*. If you want to connect to the RPC port from the internet, you need to expose port 8334(RPC) as well. - -```yaml -version: "2" - -services: - btcd: - container_name: btcd - hostname: btcd - image: btcsuite/btcd:latest - restart: unless-stopped - volumes: - - btcd-data:/root/.btcd - ports: - - 8333:8333 - - 8334:8334 - command: [ - "--rpcuser=[CHOOSE_A_USERNAME]", - "--rpcpass=[CREATE_A_VERY_HARD_PASSWORD]" - ] - -volumes: - btcd-data: -``` - -### Full node with RPC port running on TESTNET - -To run a node on testnet, you need to provide the *--testnet* argument. The ports for testnet are 18333 (p2p) and 18334 (RPC): - -```yaml -version: "2" - -services: - btcd: - container_name: btcd - hostname: btcd - image: btcsuite/btcd:latest - restart: unless-stopped - volumes: - - btcd-data:/root/.btcd - ports: - - 18333:18333 - - 18334:18334 - command: [ - "--testnet", - "--rpcuser=[CHOOSE_A_USERNAME]", - "--rpcpass=[CREATE_A_VERY_HARD_PASSWORD]" - ] - -volumes: - btcd-data: -``` diff --git a/docs/wallet.md b/docs/wallet.md deleted file mode 100644 index cc123aa7..00000000 --- a/docs/wallet.md +++ /dev/null @@ -1,5 +0,0 @@ -# Wallet - -btcd was intentionally developed without an integrated wallet for security -reasons. Please see [btcwallet](https://github.com/btcsuite/btcwallet) for more -information. diff --git a/integration/README.md b/integration/README.md index 5f6f14ea..db58a898 100644 --- a/integration/README.md +++ b/integration/README.md @@ -1,13 +1,8 @@ integration =========== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) This contains integration tests which make use of the -[rpctest](https://github.com/btcsuite/btcd/tree/master/integration/rpctest) +[rpctest](https://github.com/lbryio/lbcd/tree/master/integration/rpctest) package to programmatically drive nodes via RPC. - -## License - -This code is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/integration/rpctest/README.md b/integration/rpctest/README.md index 79f45bc8..8ccfc879 100644 --- a/integration/rpctest/README.md +++ b/integration/rpctest/README.md @@ -1,9 +1,7 @@ rpctest ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/integration/rpctest) Package rpctest provides a btcd-specific RPC testing harness crafting and executing integration tests by driving a `btcd` instance via the `RPC` @@ -16,15 +14,3 @@ This package was designed specifically to act as an RPC testing harness for `btcd`. However, the constructs presented are general enough to be adapted to any project wishing to programmatically drive a `btcd` instance of its systems/integration tests. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/integration/rpctest -``` - -## License - -Package rpctest is licensed under the [copyfree](http://copyfree.org) ISC -License. - diff --git a/mempool/README.md b/mempool/README.md index 5f1e4a4c..1e19f843 100644 --- a/mempool/README.md +++ b/mempool/README.md @@ -1,9 +1,7 @@ mempool ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/mempool) Package mempool provides a policy-enforced pool of unmined bitcoin transactions. @@ -33,11 +31,6 @@ proceed. Typically, this will involve things such as relaying the transactions to other peers on the network and notifying the mining process that new transactions are available. -This package has intentionally been designed so it can be used as a standalone -package for any projects needing the ability create an in-memory pool of bitcoin -transactions that are not only valid by consensus rules, but also adhere to a -configurable policy. - ## Feature Overview The following is a quick overview of the major features. It is not intended to @@ -70,14 +63,3 @@ be an exhaustive list. - The starting priority for the transaction - Manual control of transaction removal - Recursive removal of all dependent transactions - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/mempool -``` - -## License - -Package mempool is licensed under the [copyfree](http://copyfree.org) ISC -License. diff --git a/mining/README.md b/mining/README.md index 3abd1953..40a30a20 100644 --- a/mining/README.md +++ b/mining/README.md @@ -1,21 +1,8 @@ mining ====== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/mining) ## Overview -This package is currently a work in progress. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/mining -``` - -## License - -Package mining is licensed under the [copyfree](http://copyfree.org) ISC -License. +This package is currently a work in progress. \ No newline at end of file diff --git a/mining/cpuminer/README.md b/mining/cpuminer/README.md index 47247be9..270e435d 100644 --- a/mining/cpuminer/README.md +++ b/mining/cpuminer/README.md @@ -1,9 +1,9 @@ cpuminer ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/mining/cpuminer) +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/lbryio/lbcd/mining/cpuminer) ======= ## Overview @@ -16,7 +16,7 @@ now. ## Installation and Updating ```bash -$ go get -u github.com/btcsuite/btcd/mining/cpuminer +$ go get -u github.com/lbryio/lbcd/mining/cpuminer ``` ## License diff --git a/netsync/README.md b/netsync/README.md index a4966815..22f51701 100644 --- a/netsync/README.md +++ b/netsync/README.md @@ -1,9 +1,7 @@ netsync ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/netsync) ## Overview @@ -13,13 +11,3 @@ download, keep the chain and unconfirmed transaction pool in sync, and announce new blocks connected to the chain. Currently the sync manager selects a single sync peer that it downloads all blocks from until it is up to date with the longest chain the sync peer is aware of. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/netsync -``` - -## License - -Package netsync is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/peer/README.md b/peer/README.md index 217f5dc3..51761319 100644 --- a/peer/README.md +++ b/peer/README.md @@ -1,16 +1,11 @@ peer ==== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/peer) Package peer provides a common base for creating and managing bitcoin network peers. -This package has intentionally been designed so it can be used as a standalone -package for any projects needing a full featured bitcoin peer base to build on. - ## Overview This package builds upon the wire package, which provides the fundamental @@ -54,20 +49,4 @@ A quick overview of the major features peer provides are as follows: filtering and address randomization - Ability to wait for shutdown/disconnect - Comprehensive test coverage - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/peer -``` - -## Examples - -* [New Outbound Peer Example](https://pkg.go.dev/github.com/btcsuite/btcd/peer#example-package--NewOutboundPeer) - Demonstrates the basic process for initializing and creating an outbound peer. - Peers negotiate by exchanging version and verack messages. For demonstration, - a simple handler for the version message is attached to the peer. - -## License - -Package peer is licensed under the [copyfree](http://copyfree.org) ISC License. + \ No newline at end of file diff --git a/release/README.md b/release/README.md deleted file mode 100644 index 7128ef1f..00000000 --- a/release/README.md +++ /dev/null @@ -1,181 +0,0 @@ -# `btcd`'s Reproducible Build System - -This package contains the build script that the `btcd` project uses in order to -build binaries for each new release. As of `go1.13`, with some new build flags, -binaries are now reproducible, allowing developers to build the binary on -distinct machines, and end up with a byte-for-byte identical binary. -Every release should note which Go version was used to build the release, so -that version should be used for verifying the release. - -## Building a New Release - -### Tagging and pushing a new tag (for maintainers) - -Before running release scripts, a few things need to happen in order to finally -create a release and make sure there are no mistakes in the release process. - -First, make sure that before the tagged commit there are modifications to the -[CHANGES](../CHANGES) file committed. -The CHANGES file should be a changelog that roughly mirrors the release notes. -Generally, the PRs that have been merged since the last release have been -listed in the CHANGES file and categorized. -For example, these changes have had the following format in the past: -``` -Changes in X.YY.Z (Month Day Year): - - Protocol and Network-related changes: - - PR Title One (#PRNUM) - - PR Title Two (#PRNUMTWO) - ... - - RPC changes: - - Crypto changes: - ... - - - Contributors (alphabetical order): - - Contributor A - - Contributor B - - Contributor C - ... -``` - -If the previous tag is, for example, `vA.B.C`, then you can get the list of -contributors (from `vA.B.C` until the current `HEAD`) using the following command: -```bash -git log vA.B.C..HEAD --pretty="%an" | sort | uniq -``` -After committing changes to the CHANGES file, the tagged release commit -should be created. - -The tagged commit should be a commit that bumps version numbers in `version.go` -and `cmd/btcctl/version.go`. -For example (taken from [f3ec130](https://github.com/btcsuite/btcd/commit/f3ec13030e4e828869954472cbc51ac36bee5c1d)): -```diff -diff --git a/cmd/btcctl/version.go b/cmd/btcctl/version.go -index 2195175c71..f65cacef7e 100644 ---- a/cmd/btcctl/version.go -+++ b/cmd/btcctl/version.go -@@ -18,7 +18,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr - const ( - appMajor uint = 0 - appMinor uint = 20 -- appPatch uint = 0 -+ appPatch uint = 1 - - // appPreRelease MUST only contain characters from semanticAlphabet - // per the semantic versioning spec. -diff --git a/version.go b/version.go -index 92fd60fdd4..fba55b5a37 100644 ---- a/version.go -+++ b/version.go -@@ -18,7 +18,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr - const ( - appMajor uint = 0 - appMinor uint = 20 -- appPatch uint = 0 -+ appPatch uint = 1 - - // appPreRelease MUST only contain characters from semanticAlphabet - // per the semantic versioning spec. -``` - -Next, this commit should be signed by the maintainer using `git commit -S`. -The commit should be tagged and signed with `git tag -s`, and should be -pushed using `git push origin TAG`. - -### Building a release on macOS/Linux/Windows (WSL) - -No prior set up is needed on Linux or macOS is required in order to build the -release binaries. However, on Windows, the only way to build the release -binaries at the moment is by using the Windows Subsystem Linux. One can build -the release binaries following these steps: - -1. `git clone https://github.com/btcsuite/btcd.git` -2. `cd btcd` -3. `./release/release.sh # is the name of the next release/tag` - -This will then create a directory of the form `btcd-` containing archives -of the release binaries for each supported operating system and architecture, -and a manifest file containing the hash of each archive. - -### Pushing a release (for maintainers) - -Now that the directory `btcd-` is created, the manifest file needs to be -signed by a maintainer and the release files need to be published to GitHub. - -Sign the `manifest-.txt` file like so: -```sh -gpg --sign --detach-sig manifest-.txt -``` -This will create a file named `manifest-.txt.sig`, which will must -be included in the release files later. - -#### Note before publishing -Before publishing, go through the reproducible build process that is outlined -in this document with the files created from `release/release.sh`. This includes -verifying commit and tag signatures using `git verify-commit` and git `verify-tag` -respectively. - -Now that we've double-checked everything and have all of the necessary files, -it's time to publish release files on GitHub. -Follow [this documentation](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository) -to create a release using the GitHub UI, and make sure to write release notes -which roughly follow the format of [previous release notes](https://github.com/btcsuite/btcd/releases/tag/v0.20.1-beta). -This is different from the [CHANGES](../CHANGES) file, which should be before the -tagged commit in the git history. -Much of the information in the release notes will be the same as the CHANGES -file. -It's important to include the Go version used to produce the release files in -the release notes, so users know the correct version of Go to use to reproduce -and verify the build. -When following the GitHub documentation, include every file in the `btcd-` -directory. - -At this point, a signed commit and tag on that commit should be pushed to the main -branch. The directory created from running `release/release.sh` should be included -as release files in the GitHub release UI, and the `manifest-.txt` file -signature, called `manifest-.txt.sig`, should also be included. -A release notes document should be created and written in the GitHub release UI. -Once all of this is done, feel free to click `Publish Release`! - -## Verifying a Release - -With `go1.13`, it's now possible for third parties to verify release binaries. -Before this version of `go`, one had to trust the release manager(s) to build the -proper binary. With this new system, third parties can now _independently_ run -the release process, and verify that all the hashes of the release binaries -match exactly that of the release binaries produced by said third parties. - -To verify a release, one must obtain the following tools (many of these come -installed by default in most Unix systems): `gpg`/`gpg2`, `shashum`, and -`tar`/`unzip`. - -Once done, verifiers can proceed with the following steps: - -1. Acquire the archive containing the release binaries for one's specific - operating system and architecture, and the manifest file along with its - signature. -2. Verify the signature of the manifest file with `gpg --verify - manifest-.txt.sig`. This will require obtaining the PGP keys which - signed the manifest file, which are included in the release notes. -3. Recompute the `SHA256` hash of the archive with `shasum -a 256 `, - locate the corresponding one in the manifest file, and ensure they match - __exactly__. - -At this point, verifiers can use the release binaries acquired if they trust -the integrity of the release manager(s). Otherwise, one can proceed with the -guide to verify the release binaries were built properly by obtaining `shasum` -and `go` (matching the same version used in the release): - -4. Extract the release binaries contained within the archive, compute their - hashes as done above, and note them down. -5. Ensure `go` is installed, matching the same version as noted in the release - notes. -6. Obtain a copy of `btcd`'s source code with `git clone - https://github.com/btcsuite/btcd` and checkout the source code of the - release with `git checkout `. -7. Proceed to verify the tag with `git verify-tag ` and compile the - binaries from source for the intended operating system and architecture with - `BTCDBUILDSYS=OS-ARCH ./release/release.sh `. -8. Extract the archive found in the `btcd-` directory created by the - release script and recompute the `SHA256` hash of the release binaries (btcd - and btcctl) with `shasum -a 256 `. These should match __exactly__ - as the ones noted above. \ No newline at end of file diff --git a/rpcclient/README.md b/rpcclient/README.md index 08b16f75..c5a42063 100644 --- a/rpcclient/README.md +++ b/rpcclient/README.md @@ -1,13 +1,11 @@ rpcclient ========= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/rpcclient) rpcclient implements a Websocket-enabled Bitcoin JSON-RPC client package written in [Go](http://golang.org/). It provides a robust and easy to use client for -interfacing with a Bitcoin RPC server that uses a btcd/bitcoin core compatible +interfacing with a Bitcoin RPC server that uses a lbcd/bitcoin core compatible Bitcoin JSON-RPC API. ## Status @@ -16,26 +14,11 @@ This package is currently under active development. It is already stable and the infrastructure is complete. However, there are still several RPCs left to implement and the API is not stable yet. -## Documentation - -* [API Reference](https://pkg.go.dev/github.com/btcsuite/btcd/rpcclient) -* [btcd Websockets Example](https://github.com/btcsuite/btcd/tree/master/rpcclient/examples/btcdwebsockets) - Connects to a btcd RPC server using TLS-secured websockets, registers for - block connected and block disconnected notifications, and gets the current - block count -* [btcwallet Websockets Example](https://github.com/btcsuite/btcd/tree/master/rpcclient/examples/btcwalletwebsockets) - Connects to a btcwallet RPC server using TLS-secured websockets, registers for - notifications about changes to account balances, and gets a list of unspent - transaction outputs (utxos) the wallet can sign -* [Bitcoin Core HTTP POST Example](https://github.com/btcsuite/btcd/tree/master/rpcclient/examples/bitcoincorehttp) - Connects to a bitcoin core RPC server using HTTP POST mode with TLS disabled - and gets the current block count - ## Major Features -* Supports Websockets (btcd/btcwallet) and HTTP POST mode (bitcoin core) -* Provides callback and registration functions for btcd/btcwallet notifications -* Supports btcd extensions +* Supports Websockets (lbcd/lbcwallet) and HTTP POST mode (bitcoin core) +* Provides callback and registration functions for lbcd/lbcwallet notifications +* Supports lbcd extensions * Translates to and from higher-level and easier to use Go types * Offers a synchronous (blocking) and asynchronous API * When running in Websockets mode (the default): @@ -43,14 +26,4 @@ implement and the API is not stable yet. * Outstanding commands are automatically reissued * Registered notifications are automatically reregistered * Back-off support on reconnect attempts - -## Installation - -```bash -$ go get -u github.com/btcsuite/btcd/rpcclient -``` - -## License - -Package rpcclient is licensed under the [copyfree](http://copyfree.org) ISC -License. + \ No newline at end of file diff --git a/rpcclient/examples/bitcoincorehttp/README.md b/rpcclient/examples/bitcoincorehttp/README.md index 4d1f0adf..e26e68ce 100644 --- a/rpcclient/examples/bitcoincorehttp/README.md +++ b/rpcclient/examples/bitcoincorehttp/README.md @@ -10,7 +10,7 @@ block count. The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -24,7 +24,7 @@ password for the RPC server: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/bitcoincorehttp +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/bitcoincorehttp $ go run *.go ``` diff --git a/rpcclient/examples/bitcoincorehttpbulk/README.md b/rpcclient/examples/bitcoincorehttpbulk/README.md index ca900b6e..6d1a02c0 100644 --- a/rpcclient/examples/bitcoincorehttpbulk/README.md +++ b/rpcclient/examples/bitcoincorehttpbulk/README.md @@ -8,7 +8,7 @@ This example shows how to use the rpclient package to connect to a Bitcoin Core The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -22,7 +22,7 @@ password for the RPC server: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/bitcoincorehttp +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/bitcoincorehttp $ go run *.go ``` diff --git a/rpcclient/examples/btcdwebsockets/README.md b/rpcclient/examples/btcdwebsockets/README.md index a1686484..4168a0fa 100644 --- a/rpcclient/examples/btcdwebsockets/README.md +++ b/rpcclient/examples/btcdwebsockets/README.md @@ -13,7 +13,7 @@ demonstrate clean shutdown. The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -27,7 +27,7 @@ password for the RPC server: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/btcdwebsockets +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/btcdwebsockets $ go run *.go ``` diff --git a/rpcclient/examples/btcwalletwebsockets/README.md b/rpcclient/examples/btcwalletwebsockets/README.md index e495dff8..1e95a6c1 100644 --- a/rpcclient/examples/btcwalletwebsockets/README.md +++ b/rpcclient/examples/btcwalletwebsockets/README.md @@ -14,7 +14,7 @@ demonstrate clean shutdown. The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -28,7 +28,7 @@ password for the RPC server: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/btcwalletwebsockets +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/btcwalletwebsockets $ go run *.go ``` diff --git a/rpcclient/examples/customcommand/README.md b/rpcclient/examples/customcommand/README.md index 0e36d649..21670cc8 100644 --- a/rpcclient/examples/customcommand/README.md +++ b/rpcclient/examples/customcommand/README.md @@ -9,7 +9,7 @@ implementing the `name_show` command from Namecoin Core. The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -23,7 +23,7 @@ password for the RPC server of your Namecoin Core node: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/customcommand +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/customcommand $ go run *.go ``` diff --git a/rpcclient/examples/customcommand/main.go b/rpcclient/examples/customcommand/main.go index 1e14c06f..e89719d5 100644 --- a/rpcclient/examples/customcommand/main.go +++ b/rpcclient/examples/customcommand/main.go @@ -9,8 +9,8 @@ import ( "encoding/json" "log" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/rpcclient" ) // NameShowCmd defines the name_show JSON-RPC command. diff --git a/sample-btcd.conf b/sample-lbcd.conf similarity index 94% rename from sample-btcd.conf rename to sample-lbcd.conf index 0a765fca..ae9d232e 100644 --- a/sample-btcd.conf +++ b/sample-lbcd.conf @@ -6,12 +6,12 @@ ; The directory to store data such as the block chain and peer addresses. The ; block chain takes several GB, so this location must have a lot of free space. -; The default is ~/.btcd/data on POSIX OSes, $LOCALAPPDATA/Btcd/data on Windows, -; ~/Library/Application Support/Btcd/data on Mac OS, and $home/btcd/data on +; The default is ~/.lbcd/data on POSIX OSes, $LOCALAPPDATA/Lbcd/data on Windows, +; ~/Library/Application Support/Lbcd/data on Mac OS, and $home/lbcd/data on ; Plan9. Environment variables are expanded so they may be used. NOTE: Windows ; environment variables are typically %VARIABLE%, but they must be accessed with ; $VARIABLE here. Also, ~ is expanded to $LOCALAPPDATA on Windows. -; datadir=~/.btcd/data +; datadir=~/.lbcd/data ; ------------------------------------------------------------------------------ @@ -52,7 +52,7 @@ ; upnp=1 ; Specify the external IP addresses your node is listening on. One address per -; line. btcd will not contact 3rd-party sites to obtain external ip addresses. +; line. lbcd will not contact 3rd-party sites to obtain external ip addresses. ; This means if you are behind NAT, your node will not be able to advertise a ; reachable address unless you specify it here or enable the 'upnp' option (and ; have a supported device). @@ -64,7 +64,7 @@ ; ; Only one of the following two options, 'addpeer' and 'connect', may be ; specified. Both allow you to specify peers that you want to stay connected -; with, but the behavior is slightly different. By default, btcd will query DNS +; with, but the behavior is slightly different. By default, lbcd will query DNS ; to find peers to connect to, so unless you have a specific reason such as ; those described below, you probably won't need to modify anything here. ; @@ -86,9 +86,9 @@ ; You may specify each IP address with or without a port. The default port will ; be added automatically if one is not specified here. ; addpeer=192.168.1.1 -; addpeer=10.0.0.2:8333 +; addpeer=10.0.0.2:9246 ; addpeer=fe80::1 -; addpeer=[fe80::2]:8333 +; addpeer=[fe80::2]:9246 ; Add persistent peers that you ONLY want to connect to as desired. One peer ; per line. You may specify each IP address with or without a port. The @@ -96,9 +96,9 @@ ; NOTE: Specifying this option has other side effects as described above in ; the 'addpeer' versus 'connect' summary section. ; connect=192.168.1.1 -; connect=10.0.0.2:8333 +; connect=10.0.0.2:9246 ; connect=fe80::1 -; connect=[fe80::2]:8333 +; connect=[fe80::2]:9246 ; Maximum number of inbound and outbound peers. ; maxpeers=125 @@ -121,7 +121,7 @@ ; whitelist=192.168.0.0/24 ; whitelist=fd00::/16 -; Disable DNS seeding for peers. By default, when btcd starts, it will use +; Disable DNS seeding for peers. By default, when lbcd starts, it will use ; DNS to query for available peers to connect with. ; nodnsseed=1 @@ -135,16 +135,16 @@ ; listen=0.0.0.0 ; All ipv6 interfaces on default port: ; listen=:: -; All interfaces on port 8333: -; listen=:8333 -; All ipv4 interfaces on port 8333: -; listen=0.0.0.0:8333 -; All ipv6 interfaces on port 8333: -; listen=[::]:8333 -; Only ipv4 localhost on port 8333: -; listen=127.0.0.1:8333 -; Only ipv6 localhost on port 8333: -; listen=[::1]:8333 +; All interfaces on port 9246: +; listen=:9246 +; All ipv4 interfaces on port 9246: +; listen=0.0.0.0:9246 +; All ipv6 interfaces on port 9246: +; listen=[::]:9246 +; Only ipv4 localhost on port 9246: +; listen=127.0.0.1:9246 +; Only ipv6 localhost on port 9246: +; listen=[::1]:9246 ; Only ipv4 localhost on non-standard port 8336: ; listen=127.0.0.1:8336 ; All interfaces on non-standard port 8336: @@ -172,7 +172,7 @@ ; ------------------------------------------------------------------------------ ; RPC server options - The following options control the built-in RPC server -; which is used to control and query information from a running btcd process. +; which is used to control and query information from a running lbcd process. ; ; NOTE: The RPC server is disabled by default if rpcuser AND rpcpass, or ; rpclimituser AND rpclimitpass, are not specified. @@ -335,7 +335,7 @@ ; Debug logging level. ; Valid levels are {trace, debug, info, warn, error, critical} ; You may also specify =,=,... to set -; log level for individual subsystems. Use btcd --debuglevel=show to list +; log level for individual subsystems. Use lbcd --debuglevel=show to list ; available subsystems. ; debuglevel=info diff --git a/txscript/README.md b/txscript/README.md index f0abb518..e0b8fdd6 100644 --- a/txscript/README.md +++ b/txscript/README.md @@ -1,67 +1,15 @@ txscript ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) -[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/txscript?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/txscript) - Package txscript implements the bitcoin transaction script language. There is a comprehensive test suite. -This package has intentionally been designed so it can be used as a standalone -package for any projects needing to use or validate bitcoin transaction scripts. +This package has been augmented to include support for LBRY's custom claim operations. +See https://lbry.tech/spec ## Bitcoin Scripts Bitcoin provides a stack-based, FORTH-like language for the scripts in the bitcoin transactions. This language is not turing complete although it is still fairly powerful. A description of the language -can be found at https://en.bitcoin.it/wiki/Script - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/txscript -``` - -## Examples - -* [Standard Pay-to-pubkey-hash Script](https://pkg.go.dev/github.com/btcsuite/btcd/txscript#example-PayToAddrScript) - Demonstrates creating a script which pays to a bitcoin address. It also - prints the created script hex and uses the DisasmString function to display - the disassembled script. - -* [Extracting Details from Standard Scripts](https://pkg.go.dev/github.com/btcsuite/btcd/txscript#example-ExtractPkScriptAddrs) - Demonstrates extracting information from a standard public key script. - -* [Manually Signing a Transaction Output](https://pkg.go.dev/github.com/btcsuite/btcd/txscript#example-SignTxOutput) - Demonstrates manually creating and signing a redeem transaction. - -* [Counting Opcodes in Scripts](http://godoc.org/github.com/decred/dcrd/txscript#example-ScriptTokenizer) - Demonstrates creating a script tokenizer instance and using it to count the - number of opcodes a script contains. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package txscript is licensed under the [copyfree](http://copyfree.org) ISC -License. +can be found at https://en.bitcoin.it/wiki/Script \ No newline at end of file diff --git a/wire/README.md b/wire/README.md index 8660bbfd..c14a3640 100644 --- a/wire/README.md +++ b/wire/README.md @@ -1,26 +1,14 @@ wire ==== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) -[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/wire) -======= - Package wire implements the bitcoin wire protocol. A comprehensive suite of tests with 100% test coverage is provided to ensure proper functionality. There is an associated blog post about the release of this package [here](https://blog.conformal.com/btcwire-the-bitcoin-wire-protocol-package-from-btcd/). -This package has intentionally been designed so it can be used as a standalone -package for any projects needing to interface with bitcoin peers at the wire -protocol level. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/wire -``` +This package has been augmented from the original btcd implementation. +The block header was modified to contain the claimtrie hash. ## Bitcoin Message Overview @@ -85,29 +73,4 @@ from a remote peer is: if err != nil { // Log and handle the error } -``` - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package wire is licensed under the [copyfree](http://copyfree.org) ISC -License. +``` \ No newline at end of file -- 2.45.2 From b9d6044694ffb93114cad108d614d02ef18b91cc Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 24 Sep 2021 13:25:27 -0400 Subject: [PATCH 158/459] [lbry] increase open file limit to 2048 --- limits/limits_unix.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/limits/limits_unix.go b/limits/limits_unix.go index 7ebf8667..e55a1c28 100644 --- a/limits/limits_unix.go +++ b/limits/limits_unix.go @@ -12,8 +12,8 @@ import ( ) const ( - fileLimitWant = 2048 - fileLimitMin = 1024 + fileLimitWant = 2048 * 12 + fileLimitMin = 2048 * 8 ) // SetLimits raises some process limits to values which allow btcd and -- 2.45.2 From 68369ba9370cca9f053fdb5f8d2bd48b49083b88 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 24 Sep 2021 13:25:27 -0400 Subject: [PATCH 159/459] [lbry] ffldb: increase open file limit and flush more often --- database/ffldb/blockio.go | 2 +- database/ffldb/db.go | 9 +++++---- database/ffldb/dbcache.go | 14 +++++--------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/database/ffldb/blockio.go b/database/ffldb/blockio.go index ae71a891..2ed4eccf 100644 --- a/database/ffldb/blockio.go +++ b/database/ffldb/blockio.go @@ -37,7 +37,7 @@ const ( // maxOpenFiles is the max number of open files to maintain in the // open blocks cache. Note that this does not include the current // write file, so there will typically be one more than this value open. - maxOpenFiles = 25 + maxOpenFiles = 40 // maxBlockFileSize is the maximum size for each file used to store // blocks. diff --git a/database/ffldb/db.go b/database/ffldb/db.go index 0d6acd51..ee6d55f0 100644 --- a/database/ffldb/db.go +++ b/database/ffldb/db.go @@ -2001,10 +2001,11 @@ func openDB(dbPath string, network wire.BitcoinNet, create bool) (database.DB, e // Open the metadata database (will create it if needed). opts := opt.Options{ - ErrorIfExist: create, - Strict: opt.DefaultStrict, - Compression: opt.NoCompression, - Filter: filter.NewBloomFilter(10), + ErrorIfExist: create, + Strict: opt.DefaultStrict, + Compression: opt.NoCompression, + Filter: filter.NewBloomFilter(10), + OpenFilesCacheCapacity: 2000, } ldb, err := leveldb.OpenFile(metadataDbPath, &opts) if err != nil { diff --git a/database/ffldb/dbcache.go b/database/ffldb/dbcache.go index 15c554a7..1bc21a35 100644 --- a/database/ffldb/dbcache.go +++ b/database/ffldb/dbcache.go @@ -23,7 +23,7 @@ const ( // defaultFlushSecs is the default number of seconds to use as a // threshold in between database cache flushes when the cache size has // not been exceeded. - defaultFlushSecs = 300 // 5 minutes + defaultFlushSecs = 120 // 2 minutes // ldbBatchHeaderSize is the size of a leveldb batch header which // includes the sequence header and record counter. @@ -499,10 +499,12 @@ func (c *dbCache) flush() error { // Since the cached keys to be added and removed use an immutable treap, // a snapshot is simply obtaining the root of the tree under the lock // which is used to atomically swap the root. - c.cacheLock.RLock() + c.cacheLock.Lock() cachedKeys := c.cachedKeys cachedRemove := c.cachedRemove - c.cacheLock.RUnlock() + c.cachedKeys = treap.NewImmutable() + c.cachedRemove = treap.NewImmutable() + c.cacheLock.Unlock() // Nothing to do if there is no data to flush. if cachedKeys.Len() == 0 && cachedRemove.Len() == 0 { @@ -514,12 +516,6 @@ func (c *dbCache) flush() error { return err } - // Clear the cache since it has been flushed. - c.cacheLock.Lock() - c.cachedKeys = treap.NewImmutable() - c.cachedRemove = treap.NewImmutable() - c.cacheLock.Unlock() - return nil } -- 2.45.2 From ca6243fbd0017c853732ad09b7f991c1646031b8 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 14 Aug 2018 17:59:48 -0700 Subject: [PATCH 160/459] [lbry] align port settings between lbcd, lbcctl, and lbcwallet --- Dockerfile | 4 +- addrmgr/addrmanager_test.go | 90 +++++++++---------- addrmgr/network_test.go | 4 +- chaincfg/params.go | 6 +- cmd/lbcctl/config.go | 40 ++++----- config.go | 4 +- connmgr/connmanager_test.go | 2 +- docs/README.md | 1 - params.go | 24 ++--- peer/peer_test.go | 40 ++++----- rpcclient/example_test.go | 2 +- rpcclient/examples/bitcoincorehttp/main.go | 2 +- .../examples/bitcoincorehttpbulk/main.go | 2 +- rpcclient/examples/btcdwebsockets/main.go | 2 +- .../examples/btcwalletwebsockets/main.go | 2 +- rpcclient/wallet.go | 2 +- sample-lbcd.conf | 20 ++--- wire/message_test.go | 4 +- wire/msgaddr_test.go | 10 +-- wire/msgversion_test.go | 24 ++--- wire/netaddress_test.go | 10 +-- 21 files changed, 146 insertions(+), 149 deletions(-) delete mode 120000 docs/README.md diff --git a/Dockerfile b/Dockerfile index ec45ee64..ddd4f647 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,8 +11,8 @@ # For more information how to use this docker image visit: # https://github.com/btcsuite/btcd/tree/master/docs # -# 8333 Mainnet Bitcoin peer-to-peer port -# 8334 Mainet RPC port +# 9246 Mainnet Bitcoin peer-to-peer port +# 9245 Mainet RPC port ARG ARCH=amd64 # using the SHA256 instead of tags diff --git a/addrmgr/addrmanager_test.go b/addrmgr/addrmanager_test.go index d623479c..182f65da 100644 --- a/addrmgr/addrmanager_test.go +++ b/addrmgr/addrmanager_test.go @@ -34,61 +34,61 @@ var someIP = "173.194.115.66" func addNaTests() { // IPv4 // Localhost - addNaTest("127.0.0.1", 8333, "127.0.0.1:8333") - addNaTest("127.0.0.1", 8334, "127.0.0.1:8334") + addNaTest("127.0.0.1", 9244, "127.0.0.1:9244") + addNaTest("127.0.0.1", 9245, "127.0.0.1:9245") // Class A - addNaTest("1.0.0.1", 8333, "1.0.0.1:8333") - addNaTest("2.2.2.2", 8334, "2.2.2.2:8334") - addNaTest("27.253.252.251", 8335, "27.253.252.251:8335") - addNaTest("123.3.2.1", 8336, "123.3.2.1:8336") + addNaTest("1.0.0.1", 9244, "1.0.0.1:9244") + addNaTest("2.2.2.2", 9245, "2.2.2.2:9245") + addNaTest("27.253.252.251", 9246, "27.253.252.251:9246") + addNaTest("123.3.2.1", 9247, "123.3.2.1:9247") // Private Class A - addNaTest("10.0.0.1", 8333, "10.0.0.1:8333") - addNaTest("10.1.1.1", 8334, "10.1.1.1:8334") - addNaTest("10.2.2.2", 8335, "10.2.2.2:8335") - addNaTest("10.10.10.10", 8336, "10.10.10.10:8336") + addNaTest("10.0.0.1", 9244, "10.0.0.1:9244") + addNaTest("10.1.1.1", 9245, "10.1.1.1:9245") + addNaTest("10.2.2.2", 9246, "10.2.2.2:9246") + addNaTest("10.10.10.10", 9247, "10.10.10.10:9247") // Class B - addNaTest("128.0.0.1", 8333, "128.0.0.1:8333") - addNaTest("129.1.1.1", 8334, "129.1.1.1:8334") - addNaTest("180.2.2.2", 8335, "180.2.2.2:8335") - addNaTest("191.10.10.10", 8336, "191.10.10.10:8336") + addNaTest("128.0.0.1", 9244, "128.0.0.1:9244") + addNaTest("129.1.1.1", 9245, "129.1.1.1:9245") + addNaTest("180.2.2.2", 9246, "180.2.2.2:9246") + addNaTest("191.10.10.10", 9247, "191.10.10.10:9247") // Private Class B - addNaTest("172.16.0.1", 8333, "172.16.0.1:8333") - addNaTest("172.16.1.1", 8334, "172.16.1.1:8334") - addNaTest("172.16.2.2", 8335, "172.16.2.2:8335") - addNaTest("172.16.172.172", 8336, "172.16.172.172:8336") + addNaTest("172.16.0.1", 9244, "172.16.0.1:9244") + addNaTest("172.16.1.1", 9245, "172.16.1.1:9245") + addNaTest("172.16.2.2", 9246, "172.16.2.2:9246") + addNaTest("172.16.172.172", 9247, "172.16.172.172:9247") // Class C - addNaTest("193.0.0.1", 8333, "193.0.0.1:8333") - addNaTest("200.1.1.1", 8334, "200.1.1.1:8334") - addNaTest("205.2.2.2", 8335, "205.2.2.2:8335") - addNaTest("223.10.10.10", 8336, "223.10.10.10:8336") + addNaTest("193.0.0.1", 9244, "193.0.0.1:9244") + addNaTest("200.1.1.1", 9245, "200.1.1.1:9245") + addNaTest("205.2.2.2", 9246, "205.2.2.2:9246") + addNaTest("223.10.10.10", 9247, "223.10.10.10:9247") // Private Class C - addNaTest("192.168.0.1", 8333, "192.168.0.1:8333") - addNaTest("192.168.1.1", 8334, "192.168.1.1:8334") - addNaTest("192.168.2.2", 8335, "192.168.2.2:8335") - addNaTest("192.168.192.192", 8336, "192.168.192.192:8336") + addNaTest("192.168.0.1", 9244, "192.168.0.1:9244") + addNaTest("192.168.1.1", 9245, "192.168.1.1:9245") + addNaTest("192.168.2.2", 9246, "192.168.2.2:9246") + addNaTest("192.168.192.192", 9247, "192.168.192.192:9247") // IPv6 // Localhost - addNaTest("::1", 8333, "[::1]:8333") - addNaTest("fe80::1", 8334, "[fe80::1]:8334") + addNaTest("::1", 9244, "[::1]:9244") + addNaTest("fe80::1", 9245, "[fe80::1]:9245") // Link-local - addNaTest("fe80::1:1", 8333, "[fe80::1:1]:8333") - addNaTest("fe91::2:2", 8334, "[fe91::2:2]:8334") - addNaTest("fea2::3:3", 8335, "[fea2::3:3]:8335") - addNaTest("feb3::4:4", 8336, "[feb3::4:4]:8336") + addNaTest("fe80::1:1", 9244, "[fe80::1:1]:9244") + addNaTest("fe91::2:2", 9245, "[fe91::2:2]:9245") + addNaTest("fea2::3:3", 9246, "[fea2::3:3]:9246") + addNaTest("feb3::4:4", 9247, "[feb3::4:4]:9247") // Site-local - addNaTest("fec0::1:1", 8333, "[fec0::1:1]:8333") - addNaTest("fed1::2:2", 8334, "[fed1::2:2]:8334") - addNaTest("fee2::3:3", 8335, "[fee2::3:3]:8335") - addNaTest("fef3::4:4", 8336, "[fef3::4:4]:8336") + addNaTest("fec0::1:1", 9244, "[fec0::1:1]:9244") + addNaTest("fed1::2:2", 9245, "[fed1::2:2]:9245") + addNaTest("fee2::3:3", 9246, "[fee2::3:3]:9246") + addNaTest("fef3::4:4", 9247, "[fef3::4:4]:9247") } func addNaTest(ip string, port uint16, want string) { @@ -119,7 +119,7 @@ func TestAddAddressByIP(t *testing.T) { err error }{ { - someIP + ":8333", + someIP + ":9244", nil, }, { @@ -127,7 +127,7 @@ func TestAddAddressByIP(t *testing.T) { addrErr, }, { - someIP[:12] + ":8333", + someIP[:12] + ":9244", fmtErr, }, { @@ -212,7 +212,7 @@ func TestAttempt(t *testing.T) { n := addrmgr.New("testattempt", lookupFunc) // Add a new address and get it - err := n.AddAddressByIP(someIP + ":8333") + err := n.AddAddressByIP(someIP + ":9244") if err != nil { t.Fatalf("Adding address failed: %v", err) } @@ -234,7 +234,7 @@ func TestConnected(t *testing.T) { n := addrmgr.New("testconnected", lookupFunc) // Add a new address and get it - err := n.AddAddressByIP(someIP + ":8333") + err := n.AddAddressByIP(someIP + ":9244") if err != nil { t.Fatalf("Adding address failed: %v", err) } @@ -261,14 +261,14 @@ func TestNeedMoreAddresses(t *testing.T) { var err error for i := 0; i < addrsToAdd; i++ { - s := fmt.Sprintf("%d.%d.173.147:8333", i/128+60, i%128+60) + s := fmt.Sprintf("%d.%d.173.147:9244", i/128+60, i%128+60) addrs[i], err = n.DeserializeNetAddress(s, wire.SFNodeNetwork) if err != nil { t.Errorf("Failed to turn %s into an address: %v", s, err) } } - srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0) + srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 9244, 0) n.AddAddresses(addrs, srcAddr) numAddrs := n.NumAddresses() @@ -289,14 +289,14 @@ func TestGood(t *testing.T) { var err error for i := 0; i < addrsToAdd; i++ { - s := fmt.Sprintf("%d.173.147.%d:8333", i/64+60, i%64+60) + s := fmt.Sprintf("%d.173.147.%d:9244", i/64+60, i%64+60) addrs[i], err = n.DeserializeNetAddress(s, wire.SFNodeNetwork) if err != nil { t.Errorf("Failed to turn %s into an address: %v", s, err) } } - srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0) + srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 9244, 0) n.AddAddresses(addrs, srcAddr) for _, addr := range addrs { @@ -323,7 +323,7 @@ func TestGetAddress(t *testing.T) { } // Add a new address and get it - err := n.AddAddressByIP(someIP + ":8333") + err := n.AddAddressByIP(someIP + ":9244") if err != nil { t.Fatalf("Adding address failed: %v", err) } diff --git a/addrmgr/network_test.go b/addrmgr/network_test.go index 6f2565fe..cb86a193 100644 --- a/addrmgr/network_test.go +++ b/addrmgr/network_test.go @@ -39,7 +39,7 @@ func TestIPTypes(t *testing.T) { rfc4193, rfc4380, rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598, local, valid, routable bool) ipTest { nip := net.ParseIP(ip) - na := *wire.NewNetAddressIPPort(nip, 8333, wire.SFNodeNetwork) + na := *wire.NewNetAddressIPPort(nip, 9246, wire.SFNodeNetwork) test := ipTest{na, rfc1918, rfc2544, rfc3849, rfc3927, rfc3964, rfc4193, rfc4380, rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598, local, valid, routable} return test @@ -192,7 +192,7 @@ func TestGroupKey(t *testing.T) { for i, test := range tests { nip := net.ParseIP(test.ip) - na := *wire.NewNetAddressIPPort(nip, 8333, wire.SFNodeNetwork) + na := *wire.NewNetAddressIPPort(nip, 9246, wire.SFNodeNetwork) if key := addrmgr.GroupKey(&na); key != test.expected { t.Errorf("TestGroupKey #%d (%s): unexpected group key "+ "- got '%s', want '%s'", i, test.name, diff --git a/chaincfg/params.go b/chaincfg/params.go index b2144963..1efb9b3d 100644 --- a/chaincfg/params.go +++ b/chaincfg/params.go @@ -62,7 +62,7 @@ var ( DefaultSignetDNSSeeds = []DNSSeed{ {"178.128.221.177", false}, {"2a01:7c8:d005:390::5", false}, - {"v7ajjeirttkbnt32wpy3c6w3emwnfr3fkla7hpxcfokr3ysd3kqtzmqd.onion:38333", false}, + {"v7ajjeirttkbnt32wpy3c6w3emwnfr3fkla7hpxcfokr3ysd3kqtzmqd.onion:39246", false}, } ) @@ -522,7 +522,7 @@ var TestNet3Params = Params{ var SimNetParams = Params{ Name: "simnet", Net: wire.SimNet, - DefaultPort: "18555", + DefaultPort: "39246", DNSSeeds: []DNSSeed{}, // NOTE: There must NOT be any seeds. // Chain parameters @@ -615,7 +615,7 @@ func CustomSignetParams(challenge []byte, dnsSeeds []DNSSeed) Params { return Params{ Name: "signet", Net: wire.BitcoinNet(net), - DefaultPort: "38333", + DefaultPort: "39246", DNSSeeds: dnsSeeds, // Chain parameters diff --git a/cmd/lbcctl/config.go b/cmd/lbcctl/config.go index e00cac77..ef961df9 100644 --- a/cmd/lbcctl/config.go +++ b/cmd/lbcctl/config.go @@ -96,20 +96,20 @@ type config struct { ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"` ListCommands bool `short:"l" long:"listcommands" description:"List all of the supported commands and exit"` NoTLS bool `long:"notls" description:"Disable TLS"` + TLSSkipVerify bool `long:"skipverify" description:"Do not verify tls certificates (not recommended!)"` Proxy string `long:"proxy" description:"Connect via SOCKS5 proxy (eg. 127.0.0.1:9050)"` ProxyPass string `long:"proxypass" default-mask:"-" description:"Password for proxy server"` ProxyUser string `long:"proxyuser" description:"Username for proxy server"` - RegressionTest bool `long:"regtest" description:"Connect to the regression test network"` RPCCert string `short:"c" long:"rpccert" description:"RPC server certificate chain for validation"` RPCPassword string `short:"P" long:"rpcpass" default-mask:"-" description:"RPC password"` RPCServer string `short:"s" long:"rpcserver" description:"RPC server to connect to"` RPCUser string `short:"u" long:"rpcuser" description:"RPC username"` - SimNet bool `long:"simnet" description:"Connect to the simulation test network"` - TLSSkipVerify bool `long:"skipverify" description:"Do not verify tls certificates (not recommended!)"` - TestNet3 bool `long:"testnet" description:"Connect to testnet"` - SigNet bool `long:"signet" description:"Connect to signet"` + TestNet3 bool `long:"testnet" description:"Connect to testnet (default RPC server: localhost:19245)"` + RegressionTest bool `long:"regtest" description:"Connect to the regression test network (default RPC server: localhost:29245)"` + SimNet bool `long:"simnet" description:"Connect to the simulation test network (default RPC server: localhost:39245)"` + SigNet bool `long:"signet" description:"Connect to signet (default RPC server: localhost:49245)"` + Wallet bool `long:"wallet" description:"Connect to wallet RPC server instead (default: localhost:9244, testnet: localhost:19244, regtest: localhost:29244)"` ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` - Wallet bool `long:"wallet" description:"Connect to wallet"` } // normalizeAddress returns addr with the passed default port appended if @@ -121,35 +121,33 @@ func normalizeAddress(addr string, chain *chaincfg.Params, useWallet bool) (stri switch chain { case &chaincfg.TestNet3Params: if useWallet { - defaultPort = "18332" + defaultPort = "19244" } else { - defaultPort = "18334" - } - case &chaincfg.SimNetParams: - if useWallet { - defaultPort = "18554" - } else { - defaultPort = "18556" + defaultPort = "19245" } case &chaincfg.RegressionNetParams: if useWallet { - // TODO: add port once regtest is supported in btcwallet - paramErr := fmt.Errorf("cannot use -wallet with -regtest, btcwallet not yet compatible with regtest") - return "", paramErr + defaultPort = "29244" } else { defaultPort = "29245" } + case &chaincfg.SimNetParams: + if useWallet { + defaultPort = "39244" + } else { + defaultPort = "39245" + } case &chaincfg.SigNetParams: if useWallet { - defaultPort = "38332" + defaultPort = "49244" } else { - defaultPort = "38332" + defaultPort = "49245" } default: if useWallet { - defaultPort = "8332" + defaultPort = "9244" } else { - defaultPort = "8334" + defaultPort = "9245" } } diff --git a/config.go b/config.go index 7b6b69f1..15b80921 100644 --- a/config.go +++ b/config.go @@ -120,7 +120,7 @@ type config struct { ExternalIPs []string `long:"externalip" description:"Add an ip to the list of local addresses we claim to listen on to peers"` Generate bool `long:"generate" description:"Generate (mine) bitcoins using the CPU"` FreeTxRelayLimit float64 `long:"limitfreerelay" description:"Limit relay of transactions with no transaction fee to the given amount in thousands of bytes per minute"` - Listeners []string `long:"listen" description:"Add an interface/port to listen for connections (default all interfaces port: 8333, testnet: 18333)"` + Listeners []string `long:"listen" description:"Add an interface/port to listen for connections (default all interfaces port: 9246, testnet: 19246, regtest: 29246)"` LogDir string `long:"logdir" description:"Directory to log output."` MaxOrphanTxs int `long:"maxorphantx" description:"Max number of orphan transactions to keep in memory"` MaxPeers int `long:"maxpeers" description:"Max number of inbound and outbound peers"` @@ -153,7 +153,7 @@ type config struct { RPCKey string `long:"rpckey" description:"File containing the certificate key"` RPCLimitPass string `long:"rpclimitpass" default-mask:"-" description:"Password for limited RPC connections"` RPCLimitUser string `long:"rpclimituser" description:"Username for limited RPC connections"` - RPCListeners []string `long:"rpclisten" description:"Add an interface/port to listen for RPC connections (default port: 8334, testnet: 18334)"` + RPCListeners []string `long:"rpclisten" description:"Add an interface/port to listen for RPC connections (default port: 9245, testnet: 19245, regtest: 29245)"` RPCMaxClients int `long:"rpcmaxclients" description:"Max number of RPC clients for standard connections"` RPCMaxConcurrentReqs int `long:"rpcmaxconcurrentreqs" description:"Max number of concurrent RPC requests that may be processed concurrently"` RPCMaxWebsockets int `long:"rpcmaxwebsockets" description:"Max number of RPC websocket connections"` diff --git a/connmgr/connmanager_test.go b/connmgr/connmanager_test.go index 94cb65ff..900dbc19 100644 --- a/connmgr/connmanager_test.go +++ b/connmgr/connmanager_test.go @@ -617,7 +617,7 @@ func TestListeners(t *testing.T) { // Setup a connection manager with a couple of mock listeners that // notify a channel when they receive mock connections. receivedConns := make(chan net.Conn) - listener1 := newMockListener("127.0.0.1:8333") + listener1 := newMockListener("127.0.0.1:9246") listener2 := newMockListener("127.0.0.1:9333") listeners := []net.Listener{listener1, listener2} cmgr, err := New(&Config{ diff --git a/docs/README.md b/docs/README.md deleted file mode 120000 index dd0ea36c..00000000 --- a/docs/README.md +++ /dev/null @@ -1 +0,0 @@ -index.md \ No newline at end of file diff --git a/params.go b/params.go index 664a7e6a..81fd18dd 100644 --- a/params.go +++ b/params.go @@ -28,7 +28,15 @@ type params struct { // to emulate the full reference implementation RPC API. var mainNetParams = params{ Params: &chaincfg.MainNetParams, - rpcPort: "8334", + rpcPort: "9245", +} + +// testNet3Params contains parameters specific to the test network (version 3) +// (wire.TestNet3). NOTE: The RPC port is intentionally different than the +// reference implementation - see the mainNetParams comment for details. +var testNet3Params = params{ + Params: &chaincfg.TestNet3Params, + rpcPort: "19245", } // regressionNetParams contains parameters specific to the regression test @@ -37,29 +45,21 @@ var mainNetParams = params{ // details. var regressionNetParams = params{ Params: &chaincfg.RegressionNetParams, - rpcPort: "18334", -} - -// testNet3Params contains parameters specific to the test network (version 3) -// (wire.TestNet3). NOTE: The RPC port is intentionally different than the -// reference implementation - see the mainNetParams comment for details. -var testNet3Params = params{ - Params: &chaincfg.TestNet3Params, - rpcPort: "18334", + rpcPort: "29245", } // simNetParams contains parameters specific to the simulation test network // (wire.SimNet). var simNetParams = params{ Params: &chaincfg.SimNetParams, - rpcPort: "18556", + rpcPort: "39245", } // sigNetParams contains parameters specific to the Signet network // (wire.SigNet). var sigNetParams = params{ Params: &chaincfg.SigNetParams, - rpcPort: "38332", + rpcPort: "49245", } // netName returns the name used when referring to a bitcoin network. At the diff --git a/peer/peer_test.go b/peer/peer_test.go index 4a2a0048..dcc0f257 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -290,13 +290,13 @@ func TestPeerConnection(t *testing.T) { "basic handshake", func() (*peer.Peer, *peer.Peer, error) { inConn, outConn := pipe( - &conn{raddr: "10.0.0.1:8333"}, - &conn{raddr: "10.0.0.2:8333"}, + &conn{raddr: "10.0.0.1:9246"}, + &conn{raddr: "10.0.0.2:9246"}, ) inPeer := peer.NewInboundPeer(peer1Cfg) inPeer.AssociateConnection(inConn) - outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:8333") + outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:9246") if err != nil { return nil, nil, err } @@ -316,13 +316,13 @@ func TestPeerConnection(t *testing.T) { "socks proxy", func() (*peer.Peer, *peer.Peer, error) { inConn, outConn := pipe( - &conn{raddr: "10.0.0.1:8333", proxy: true}, - &conn{raddr: "10.0.0.2:8333"}, + &conn{raddr: "10.0.0.1:9246", proxy: true}, + &conn{raddr: "10.0.0.2:9246"}, ) inPeer := peer.NewInboundPeer(peer1Cfg) inPeer.AssociateConnection(inConn) - outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:8333") + outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:9246") if err != nil { return nil, nil, err } @@ -457,8 +457,8 @@ func TestPeerListeners(t *testing.T) { AllowSelfConns: true, } inConn, outConn := pipe( - &conn{raddr: "10.0.0.1:8333"}, - &conn{raddr: "10.0.0.2:8333"}, + &conn{raddr: "10.0.0.1:9246"}, + &conn{raddr: "10.0.0.2:9246"}, ) inPeer := peer.NewInboundPeer(peerCfg) inPeer.AssociateConnection(inConn) @@ -468,7 +468,7 @@ func TestPeerListeners(t *testing.T) { verack <- struct{}{} }, } - outPeer, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + outPeer, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Errorf("NewOutboundPeer: unexpected err %v\n", err) return @@ -630,9 +630,9 @@ func TestOutboundPeer(t *testing.T) { } r, w := io.Pipe() - c := &conn{raddr: "10.0.0.1:8333", Writer: w, Reader: r} + c := &conn{raddr: "10.0.0.1:9246", Writer: w, Reader: r} - p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return @@ -687,8 +687,8 @@ func TestOutboundPeer(t *testing.T) { peerCfg.NewestBlock = newestBlock r1, w1 := io.Pipe() - c1 := &conn{raddr: "10.0.0.1:8333", Writer: w1, Reader: r1} - p1, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + c1 := &conn{raddr: "10.0.0.1:9246", Writer: w1, Reader: r1} + p1, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return @@ -717,8 +717,8 @@ func TestOutboundPeer(t *testing.T) { peerCfg.ChainParams = &chaincfg.RegressionNetParams peerCfg.Services = wire.SFNodeBloom r2, w2 := io.Pipe() - c2 := &conn{raddr: "10.0.0.1:8333", Writer: w2, Reader: r2} - p2, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + c2 := &conn{raddr: "10.0.0.1:9246", Writer: w2, Reader: r2} + p2, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return @@ -773,20 +773,20 @@ func TestUnsupportedVersionPeer(t *testing.T) { localNA := wire.NewNetAddressIPPort( net.ParseIP("10.0.0.1"), - uint16(8333), + uint16(9246), wire.SFNodeNetwork, ) remoteNA := wire.NewNetAddressIPPort( net.ParseIP("10.0.0.2"), - uint16(8333), + uint16(9246), wire.SFNodeNetwork, ) localConn, remoteConn := pipe( - &conn{laddr: "10.0.0.1:8333", raddr: "10.0.0.2:8333"}, - &conn{laddr: "10.0.0.2:8333", raddr: "10.0.0.1:8333"}, + &conn{laddr: "10.0.0.1:9246", raddr: "10.0.0.2:9246"}, + &conn{laddr: "10.0.0.2:9246", raddr: "10.0.0.1:9246"}, ) - p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Fatalf("NewOutboundPeer: unexpected err - %v\n", err) } diff --git a/rpcclient/example_test.go b/rpcclient/example_test.go index f044e9f1..f617e6ce 100644 --- a/rpcclient/example_test.go +++ b/rpcclient/example_test.go @@ -11,7 +11,7 @@ import ( ) var connCfg = &ConnConfig{ - Host: "localhost:8332", + Host: "localhost:9244", User: "user", Pass: "pass", HTTPPostMode: true, diff --git a/rpcclient/examples/bitcoincorehttp/main.go b/rpcclient/examples/bitcoincorehttp/main.go index 54e727de..eba2fcb4 100644 --- a/rpcclient/examples/bitcoincorehttp/main.go +++ b/rpcclient/examples/bitcoincorehttp/main.go @@ -13,7 +13,7 @@ import ( func main() { // Connect to local bitcoin core RPC server using HTTP POST mode. connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8332", + Host: "localhost:9245", User: "yourrpcuser", Pass: "yourrpcpass", HTTPPostMode: true, // Bitcoin core only supports HTTP POST mode diff --git a/rpcclient/examples/bitcoincorehttpbulk/main.go b/rpcclient/examples/bitcoincorehttpbulk/main.go index fd21ede4..36b12e5d 100644 --- a/rpcclient/examples/bitcoincorehttpbulk/main.go +++ b/rpcclient/examples/bitcoincorehttpbulk/main.go @@ -14,7 +14,7 @@ import ( func main() { // Connect to local bitcoin core RPC server using HTTP POST mode. connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8332", + Host: "localhost:9245", User: "yourrpcuser", Pass: "yourrpcpass", DisableConnectOnNew: true, diff --git a/rpcclient/examples/btcdwebsockets/main.go b/rpcclient/examples/btcdwebsockets/main.go index 30bb4188..1a12da9e 100644 --- a/rpcclient/examples/btcdwebsockets/main.go +++ b/rpcclient/examples/btcdwebsockets/main.go @@ -38,7 +38,7 @@ func main() { log.Fatal(err) } connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8334", + Host: "localhost:9245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", diff --git a/rpcclient/examples/btcwalletwebsockets/main.go b/rpcclient/examples/btcwalletwebsockets/main.go index b0bc6f83..f506f3d3 100644 --- a/rpcclient/examples/btcwalletwebsockets/main.go +++ b/rpcclient/examples/btcwalletwebsockets/main.go @@ -34,7 +34,7 @@ func main() { log.Fatal(err) } connCfg := &rpcclient.ConnConfig{ - Host: "localhost:18332", + Host: "localhost:19245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index df928969..784f0688 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -2792,7 +2792,7 @@ func (c *Client) UnloadWalletAsync(walletName *string) FutureUnloadWalletResult } // UnloadWallet unloads the referenced wallet. If the RPC server URL already -// contains the name of the wallet, like http://127.0.0.1:8332/wallet/, +// contains the name of the wallet, like http://127.0.0.1:9245/wallet/, // the parameter must be nil, or it'll return an error. func (c *Client) UnloadWallet(walletName *string) error { return c.UnloadWalletAsync(walletName).Receive() diff --git a/sample-lbcd.conf b/sample-lbcd.conf index ae9d232e..dbff2949 100644 --- a/sample-lbcd.conf +++ b/sample-lbcd.conf @@ -198,16 +198,16 @@ ; rpclisten=0.0.0.0 ; All ipv6 interfaces on default port: ; rpclisten=:: -; All interfaces on port 8334: -; rpclisten=:8334 -; All ipv4 interfaces on port 8334: -; rpclisten=0.0.0.0:8334 -; All ipv6 interfaces on port 8334: -; rpclisten=[::]:8334 -; Only ipv4 localhost on port 8334: -; rpclisten=127.0.0.1:8334 -; Only ipv6 localhost on port 8334: -; rpclisten=[::1]:8334 +; All interfaces on port 9245: +; rpclisten=:9245 +; All ipv4 interfaces on port 9245: +; rpclisten=0.0.0.0:9245 +; All ipv6 interfaces on port 9245: +; rpclisten=[::]:9245 +; Only ipv4 localhost on port 9245: +; rpclisten=127.0.0.1:9245 +; Only ipv6 localhost on port 9245: +; rpclisten=[::1]:9245 ; Only ipv4 localhost on non-standard port 8337: ; rpclisten=127.0.0.1:8337 ; All interfaces on non-standard port 8337: diff --git a/wire/message_test.go b/wire/message_test.go index 65754b41..2ec5d8d1 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -40,10 +40,10 @@ func TestMessage(t *testing.T) { // Create the various types of messages to test. // MsgVersion. - addrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 8333} + addrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 9246} you := NewNetAddress(addrYou, SFNodeNetwork) you.Timestamp = time.Time{} // Version message has zero value timestamp. - addrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333} + addrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 9246} me := NewNetAddress(addrMe, SFNodeNetwork) me.Timestamp = time.Time{} // Version message has zero value timestamp. msgVersion := NewMsgVersion(me, you, 123123, 0) diff --git a/wire/msgaddr_test.go b/wire/msgaddr_test.go index 7516d324..a823b812 100644 --- a/wire/msgaddr_test.go +++ b/wire/msgaddr_test.go @@ -38,7 +38,7 @@ func TestAddr(t *testing.T) { } // Ensure NetAddresses are added properly. - tcpAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333} + tcpAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 9246} na := NewNetAddress(tcpAddr, SFNodeNetwork) err := msg.AddAddress(na) if err != nil { @@ -105,7 +105,7 @@ func TestAddrWire(t *testing.T) { Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } na2 := &NetAddress{ Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST @@ -129,7 +129,7 @@ func TestAddrWire(t *testing.T) { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian 0x29, 0xab, 0x5f, 0x49, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -216,7 +216,7 @@ func TestAddrWireErrors(t *testing.T) { Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } na2 := &NetAddress{ Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST @@ -234,7 +234,7 @@ func TestAddrWireErrors(t *testing.T) { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian 0x29, 0xab, 0x5f, 0x49, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/wire/msgversion_test.go b/wire/msgversion_test.go index dc2b6e09..f5166e23 100644 --- a/wire/msgversion_test.go +++ b/wire/msgversion_test.go @@ -22,9 +22,9 @@ func TestVersion(t *testing.T) { // Create version message data. lastBlock := int32(234234) - tcpAddrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333} + tcpAddrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 9246} me := NewNetAddress(tcpAddrMe, SFNodeNetwork) - tcpAddrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 8333} + tcpAddrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 9246} you := NewNetAddress(tcpAddrYou, SFNodeNetwork) nonce, err := RandomUint64() if err != nil { @@ -377,7 +377,7 @@ func TestVersionOptionalFields(t *testing.T) { Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("192.168.0.1"), - Port: 8333, + Port: 9246, }, } onlyRequiredVersionEncoded := make([]byte, len(baseVersionEncoded)-55) @@ -390,7 +390,7 @@ func TestVersionOptionalFields(t *testing.T) { Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } addrMeVersionEncoded := make([]byte, len(baseVersionEncoded)-29) copy(addrMeVersionEncoded, baseVersionEncoded) @@ -480,13 +480,13 @@ var baseVersion = &MsgVersion{ Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("192.168.0.1"), - Port: 8333, + Port: 9246, }, AddrMe: NetAddress{ Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, }, Nonce: 123123, // 0x1e0f3 UserAgent: "/btcdtest:0.0.1/", @@ -503,12 +503,12 @@ var baseVersionEncoded = []byte{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian // AddrMe -- No timestamp for NetAddress in version message 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian 0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce 0x10, // Varint for user agent length 0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73, @@ -526,13 +526,13 @@ var baseVersionBIP0037 = &MsgVersion{ Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("192.168.0.1"), - Port: 8333, + Port: 9246, }, AddrMe: NetAddress{ Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, }, Nonce: 123123, // 0x1e0f3 UserAgent: "/btcdtest:0.0.1/", @@ -549,12 +549,12 @@ var baseVersionBIP0037Encoded = []byte{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian // AddrMe -- No timestamp for NetAddress in version message 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian 0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce 0x10, // Varint for user agent length 0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73, diff --git a/wire/netaddress_test.go b/wire/netaddress_test.go index 128a7fbc..3d1bf809 100644 --- a/wire/netaddress_test.go +++ b/wire/netaddress_test.go @@ -18,7 +18,7 @@ import ( // TestNetAddress tests the NetAddress API. func TestNetAddress(t *testing.T) { ip := net.ParseIP("127.0.0.1") - port := 8333 + port := 9246 // Test NewNetAddress. na := NewNetAddress(&net.TCPAddr{IP: ip, Port: port}, 0) @@ -79,7 +79,7 @@ func TestNetAddressWire(t *testing.T) { Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } // baseNetAddrNoTS is baseNetAddr with a zero value for the timestamp. @@ -92,7 +92,7 @@ func TestNetAddressWire(t *testing.T) { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian } // baseNetAddrNoTSEncoded is the wire encoded bytes of baseNetAddrNoTS. @@ -101,7 +101,7 @@ func TestNetAddressWire(t *testing.T) { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian } tests := []struct { @@ -211,7 +211,7 @@ func TestNetAddressWireErrors(t *testing.T) { Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } tests := []struct { -- 2.45.2 From 974c71284bed50ec3735cc51e26a23fc659b96a4 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 2 Jun 2021 10:10:01 -0700 Subject: [PATCH 161/459] [lbry] ci: gitignore IDE stuff --- .gitignore | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index c3effe5f..11125e86 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Databases btcd.db +lbcd.db *-shm *-wal @@ -33,6 +34,21 @@ _testmain.go *.exe +.DS_Store + # Code coverage files profile.tmp profile.cov + +# IDE +.idea +.vscode + +# Binaries +btcd +btcctl +lbcd +lbcctl + +# CI artifacts +dist -- 2.45.2 From 00d1ac1162e7c69360e49ea78f016f6ed9793738 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 6 Jul 2021 18:39:27 -0700 Subject: [PATCH 162/459] [lbry] ci: Update Go toolchain to 1.17.3 --- .github/workflows/{go.yml => basic-check.yml} | 9 +- .github/workflows/full-sync-part-1.yml | 35 ++++ .github/workflows/full-sync-part-2.yml | 37 +++++ .github/workflows/golangci-lint.yml | 57 +++++++ .golangci.yml | 152 ++++++++++++++++++ Dockerfile | 16 +- goclean.sh | 8 +- release/release.sh | 108 ------------- 8 files changed, 293 insertions(+), 129 deletions(-) rename .github/workflows/{go.yml => basic-check.yml} (74%) create mode 100644 .github/workflows/full-sync-part-1.yml create mode 100644 .github/workflows/full-sync-part-2.yml create mode 100644 .github/workflows/golangci-lint.yml create mode 100644 .golangci.yml delete mode 100755 release/release.sh diff --git a/.github/workflows/go.yml b/.github/workflows/basic-check.yml similarity index 74% rename from .github/workflows/go.yml rename to .github/workflows/basic-check.yml index 5da1bebc..ab6e5d87 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/basic-check.yml @@ -15,17 +15,14 @@ jobs: uses: actions/setup-go@v2 with: go-version: ${{ matrix.go }} + - name: Check out source uses: actions/checkout@v2 - - name: Install Linters - run: "curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.26.0" + - name: Build - env: - GO111MODULE: "on" run: go build ./... + - name: Test - env: - GO111MODULE: "on" run: | sh ./goclean.sh diff --git a/.github/workflows/full-sync-part-1.yml b/.github/workflows/full-sync-part-1.yml new file mode 100644 index 00000000..27b88567 --- /dev/null +++ b/.github/workflows/full-sync-part-1.yml @@ -0,0 +1,35 @@ +name: Full Sync From 0 + +on: + workflow_dispatch: + inputs: + note: + description: 'Note' + required: false + default: '' + +jobs: + build: + name: Go CI + runs-on: self-hosted + strategy: + matrix: + go: [1.17.3] + steps: + - run: | + echo "Note ${{ github.event.inputs.note }}!" + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + - name: Checkout source + uses: actions/checkout@v2 + - name: Build lbcd + run: go build . + - name: Create datadir + run: echo "TEMP_DATA_DIR=$(mktemp -d)" >> $GITHUB_ENV + - name: Run lbcd + run: ./lbcd --datadir=${{env.TEMP_DATA_DIR}}/data --logdir=${{env.TEMP_DATA_DIR}}/logs --connect=127.0.0.1 --norpc + - name: Remove datadir + if: always() + run: rm -rf ${{env.TEMP_DATA_DIR}} diff --git a/.github/workflows/full-sync-part-2.yml b/.github/workflows/full-sync-part-2.yml new file mode 100644 index 00000000..ab0309fb --- /dev/null +++ b/.github/workflows/full-sync-part-2.yml @@ -0,0 +1,37 @@ +name: Full Sync From 814k + +on: + workflow_dispatch: + inputs: + note: + description: 'Note' + required: false + default: '' + +jobs: + build: + name: Go CI + runs-on: self-hosted + strategy: + matrix: + go: [1.17.3] + steps: + - run: | + echo "Note ${{ github.event.inputs.note }}!" + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + - name: Checkout source + uses: actions/checkout@v2 + - name: Build lbcd + run: go build . + - name: Create datadir + run: echo "TEMP_DATA_DIR=$(mktemp -d)" >> $GITHUB_ENV + - name: Copy initial data + run: cp -r /home/lbry/lbcd_814k/* ${{env.TEMP_DATA_DIR}} + - name: Run lbcd + run: ./lbcd --datadir=${{env.TEMP_DATA_DIR}}/data --logdir=${{env.TEMP_DATA_DIR}}/logs --connect=127.0.0.1 --norpc + - name: Remove datadir + if: always() + run: rm -rf ${{env.TEMP_DATA_DIR}} diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 00000000..b0a478d4 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,57 @@ +name: golangci-lint + +env: + # go needs absolute directories, using the $HOME variable doesn't work here. + GOCACHE: /home/runner/work/go/pkg/build + GOPATH: /home/runner/work/go + GO_VERSION: '^1.17.0' + +on: + push: + tags: + - v* + branches: + - "*" + pull_request: + branches: + - "*" + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - name: setup go ${{ env.GO_VERSION }} + uses: actions/setup-go@v2 + with: + go-version: '${{ env.GO_VERSION }}' + + - name: checkout source + uses: actions/checkout@v2 + + - name: compile code + run: go install -v ./... + + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: latest + + # Optional: working directory, useful for monorepos + # working-directory: somedir + + # Optional: golangci-lint command line arguments. + # args: --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true then the action will use pre-installed Go. + skip-go-installation: true + + # Optional: if set to true then the action don't cache or restore ~/go/pkg. + # skip-pkg-cache: true + + # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. + # skip-build-cache: true diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..a32e6267 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,152 @@ +linters-settings: + depguard: + list-type: blacklist + packages: + # logging is allowed only by logutils.Log, logrus + # is allowed to use only in logutils package + - github.com/sirupsen/logrus + packages-with-error-message: + - github.com/sirupsen/logrus: "logging is allowed only by logutils.Log" + dupl: + threshold: 100 + funlen: + lines: 100 + statements: 50 + gci: + local-prefixes: github.com/golangci/golangci-lint + goconst: + min-len: 2 + min-occurrences: 2 + gocritic: + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + disabled-checks: + - dupImport # https://github.com/go-critic/go-critic/issues/845 + - ifElseChain + - octalLiteral + - whyNoLint + - wrapperFunc + gocyclo: + min-complexity: 15 + goimports: + local-prefixes: github.com/golangci/golangci-lint + gomnd: + settings: + mnd: + # don't include the "operation" and "assign" + checks: + - argument + - case + - condition + - return + govet: + check-shadowing: true + settings: + printf: + funcs: + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + lll: + line-length: 140 + maligned: + suggest-new: true + misspell: + locale: US + nolintlint: + allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space) + allow-unused: false # report any unused nolint directives + require-explanation: false # don't require an explanation for nolint directives + require-specific: false # don't require nolint directives to be specific about which linter is being skipped + +linters: + disable-all: true + enable: + - asciicheck + - bodyclose + # - deadcode + - depguard + # - dogsled + # - dupl + # - errcheck + # - exhaustive + - exportloopref + # - funlen + # - gochecknoglobals + # - gochecknoinits + # - gocognit + # - goconst + # - gocritic + # - gocyclo + # - godot + # - godox + # - goerr113 + - gofmt + - goimports + # - gomnd + - goprintffuncname + # - gosec + # - gosimple + # - govet + # - ineffassign + # - interfacer + # - lll + # - maligned + # - misspell + - nakedret + # - nestif + # - noctx + # - nolintlint + # - prealloc + - rowserrcheck + # - revive + # - scopelint + # - staticcheck + # - structcheck + # - stylecheck + # - testpackage + # - typecheck + - unconvert + # - unparam + # - unused + # - varcheck + # - whitespace + # - wsl + +issues: + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + - path: _test\.go + linters: + - gomnd + + - path: pkg/golinters/errcheck.go + text: "SA1019: errCfg.Exclude is deprecated: use ExcludeFunctions instead" + - path: pkg/commands/run.go + text: "SA1019: lsc.Errcheck.Exclude is deprecated: use ExcludeFunctions instead" + + # TODO must be removed after the release of the next version (v1.41.0) + - path: pkg/commands/run.go + linters: + - gomnd + # TODO must be removed after the release of the next version (v1.41.0) + - path: pkg/golinters/nolintlint/nolintlint.go + linters: + - gomnd + # TODO must be removed after the release of the next version (v1.41.0) + - path: pkg/printers/tab.go + linters: + - gomnd + + +run: + skip-dirs: + - test/testdata_etc + - internal/cache + - internal/renameio + - internal/robustio diff --git a/Dockerfile b/Dockerfile index ddd4f647..17009ce2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,15 @@ -# This Dockerfile builds btcd from source and creates a small (55 MB) docker container based on alpine linux. +# This Dockerfile builds lbcd from source and creates a small (55 MB) docker container based on alpine linux. # -# Clone this repository and run the following command to build and tag a fresh btcd amd64 container: +# Clone this repository and run the following command to build and tag a fresh lbcd amd64 container: # -# docker build . -t yourregistry/btcd +# docker build . -t yourregistry/lbcd # # You can use the following command to buid an arm64v8 container: # -# docker build . -t yourregistry/btcd --build-arg ARCH=arm64v8 +# docker build . -t yourregistry/lbcd --build-arg ARCH=arm64v8 # # For more information how to use this docker image visit: -# https://github.com/btcsuite/btcd/tree/master/docs +# https://github.com/lbryio/lbcd/tree/master/docs # # 9246 Mainnet Bitcoin peer-to-peer port # 9245 Mainet RPC port @@ -39,8 +39,8 @@ FROM $ARCH/alpine:3.12 COPY --from=build-container /go/bin /bin -VOLUME ["/root/.btcd"] +VOLUME ["/root/.lbcd"] -EXPOSE 8333 8334 +EXPOSE 9245 9246 -ENTRYPOINT ["btcd"] +ENTRYPOINT ["lbcd"] diff --git a/goclean.sh b/goclean.sh index dad9f8f1..7540af6f 100755 --- a/goclean.sh +++ b/goclean.sh @@ -10,10 +10,4 @@ set -ex env GORACE="halt_on_error=1" go test -race -tags="rpctest" -covermode atomic -coverprofile=profile.cov ./... - -# Automatic checks -golangci-lint run --deadline=10m --disable-all \ ---enable=gofmt \ ---enable=vet \ ---enable=gosimple \ ---enable=unconvert +go test -bench=. -benchtime=4000x ./claimtrie/ diff --git a/release/release.sh b/release/release.sh deleted file mode 100755 index de49f641..00000000 --- a/release/release.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Company 0, LLC. -# Copyright (c) 2016-2020 The btcsuite developers -# Use of this source code is governed by an ISC -# license that can be found in the LICENSE file. - -# Simple bash script to build basic btcd tools for all the platforms we support -# with the golang cross-compiler. - -set -e - -# If no tag specified, use date + version otherwise use tag. -if [[ $1x = x ]]; then - DATE=`date +%Y%m%d` - VERSION="01" - TAG=$DATE-$VERSION -else - TAG=$1 -fi - -go mod vendor -tar -cvzf vendor.tar.gz vendor - -PACKAGE=btcd -MAINDIR=$PACKAGE-$TAG -mkdir -p $MAINDIR - -cp vendor.tar.gz $MAINDIR/ -rm vendor.tar.gz -rm -r vendor - -PACKAGESRC="$MAINDIR/$PACKAGE-source-$TAG.tar" -git archive -o $PACKAGESRC HEAD -gzip -f $PACKAGESRC > "$PACKAGESRC.gz" - -cd $MAINDIR - -# If BTCDBUILDSYS is set the default list is ignored. Useful to release -# for a subset of systems/architectures. -SYS=${BTCDBUILDSYS:-" - darwin-amd64 - dragonfly-amd64 - freebsd-386 - freebsd-amd64 - freebsd-arm - illumos-amd64 - linux-386 - linux-amd64 - linux-armv6 - linux-armv7 - linux-arm64 - linux-ppc64 - linux-ppc64le - linux-mips - linux-mipsle - linux-mips64 - linux-mips64le - linux-s390x - netbsd-386 - netbsd-amd64 - netbsd-arm - netbsd-arm64 - openbsd-386 - openbsd-amd64 - openbsd-arm - openbsd-arm64 - solaris-amd64 - windows-386 - windows-amd64 -"} - -# Use the first element of $GOPATH in the case where GOPATH is a list -# (something that is totally allowed). -PKG="github.com/btcsuite/btcd" -COMMIT=$(git describe --abbrev=40 --dirty) - -for i in $SYS; do - OS=$(echo $i | cut -f1 -d-) - ARCH=$(echo $i | cut -f2 -d-) - ARM= - - if [[ $ARCH = "armv6" ]]; then - ARCH=arm - ARM=6 - elif [[ $ARCH = "armv7" ]]; then - ARCH=arm - ARM=7 - fi - - mkdir $PACKAGE-$i-$TAG - cd $PACKAGE-$i-$TAG - - echo "Building:" $OS $ARCH $ARM - env CGO_ENABLED=0 GOOS=$OS GOARCH=$ARCH GOARM=$ARM go build -v -trimpath -ldflags="-s -w -buildid=" github.com/btcsuite/btcd - env CGO_ENABLED=0 GOOS=$OS GOARCH=$ARCH GOARM=$ARM go build -v -trimpath -ldflags="-s -w -buildid=" github.com/btcsuite/btcd/cmd/btcctl - cd .. - - if [[ $OS = "windows" ]]; then - zip -r $PACKAGE-$i-$TAG.zip $PACKAGE-$i-$TAG - else - tar -cvzf $PACKAGE-$i-$TAG.tar.gz $PACKAGE-$i-$TAG - fi - - rm -r $PACKAGE-$i-$TAG -done - -shasum -a 256 * > manifest-$TAG.txt -- 2.45.2 From 73af86f9ae5dfe21780b478ef696af1b8ab142a6 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 15 Oct 2021 15:16:58 -0700 Subject: [PATCH 163/459] [lbry] ci: fixups lint warnings --- blockchain/validate.go | 5 +---- btcec/genprecomps.go | 1 + btcec/gensecp256k1.go | 1 + btcec/precompute.go | 2 +- limits/limits_unix.go | 1 + rpcclient/infrastructure.go | 5 +++-- signalsigterm.go | 1 + upnp.go | 4 ++-- 8 files changed, 11 insertions(+), 9 deletions(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index 19183aa9..85946611 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -224,10 +224,7 @@ func withinLevelBounds(reduction int64, lv int64) bool { return false } reduction++ - if ((reduction*reduction + reduction) >> 1) <= lv { - return false - } - return true + return ((reduction*reduction + reduction) >> 1) > lv } // CheckTransactionSanity performs some preliminary checks on a transaction to diff --git a/btcec/genprecomps.go b/btcec/genprecomps.go index f09ab311..ea40ceac 100644 --- a/btcec/genprecomps.go +++ b/btcec/genprecomps.go @@ -5,6 +5,7 @@ // This file is ignored during the regular build due to the following build tag. // It is called by go generate and used to automatically generate pre-computed // tables used to accelerate operations. +//go:build ignore // +build ignore package main diff --git a/btcec/gensecp256k1.go b/btcec/gensecp256k1.go index 1928702d..e079f553 100644 --- a/btcec/gensecp256k1.go +++ b/btcec/gensecp256k1.go @@ -4,6 +4,7 @@ // This file is ignored during the regular build due to the following build tag. // This build tag is set during go generate. +//go:build gensecp256k1 // +build gensecp256k1 package btcec diff --git a/btcec/precompute.go b/btcec/precompute.go index 034cd553..3d2eedbb 100644 --- a/btcec/precompute.go +++ b/btcec/precompute.go @@ -12,7 +12,7 @@ import ( "strings" ) -//go:generate go run -tags gensecp256k1 genprecomps.go +//go:rm -f gensecp256k1.go; generate go run -tags gensecp256k1 genprecomps.go // loadS256BytePoints decompresses and deserializes the pre-computed byte points // used to accelerate scalar base multiplication for the secp256k1 curve. This diff --git a/limits/limits_unix.go b/limits/limits_unix.go index e55a1c28..f8511458 100644 --- a/limits/limits_unix.go +++ b/limits/limits_unix.go @@ -2,6 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. +//go:build !windows && !plan9 // +build !windows,!plan9 package limits diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index 730f8bcb..9923cbd1 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -803,6 +803,7 @@ func (c *Client) handleSendPostMessage(jReq *jsonRequest) { time.Sleep(backoff) continue } + defer httpResponse.Body.Close() break } if err != nil { @@ -810,9 +811,8 @@ func (c *Client) handleSendPostMessage(jReq *jsonRequest) { return } - // Read the raw bytes and close the response. + // Read the raw bytes from the response. respBytes, err := ioutil.ReadAll(httpResponse.Body) - httpResponse.Body.Close() if err != nil { err = fmt.Errorf("error reading json reply: %v", err) jReq.responseChan <- &Response{err: err} @@ -1381,6 +1381,7 @@ func dial(config *ConnConfig) (*websocket.Conn, error) { // cases above apply. return nil, errors.New(resp.Status) } + resp.Body.Close() return wsConn, nil } diff --git a/signalsigterm.go b/signalsigterm.go index 83165501..63bdb9c0 100644 --- a/signalsigterm.go +++ b/signalsigterm.go @@ -2,6 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris // +build darwin dragonfly freebsd linux netbsd openbsd solaris package main diff --git a/upnp.go b/upnp.go index 402924f5..d07d5ce9 100644 --- a/upnp.go +++ b/upnp.go @@ -136,7 +136,7 @@ func Discover() (nat NAT, err error) { return } err = errors.New("UPnP port discovery failed") - return + return nat, err } // service represents the Service type in an UPnP xml description. @@ -269,7 +269,7 @@ func getServiceURL(rootURL string) (url string, err error) { return } url = combineURL(rootURL, d.ControlURL) - return + return url, err } // combineURL appends subURL onto rootURL. -- 2.45.2 From 0783e61fd8adb58a22889c825d44ae6adb637c69 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 24 Sep 2021 13:25:27 -0400 Subject: [PATCH 164/459] [lbry] ci: bump version to 0.22.100 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 23f1f3de..89c3ff19 100644 --- a/version.go +++ b/version.go @@ -18,7 +18,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr const ( appMajor uint = 0 appMinor uint = 22 - appPatch uint = 0 + appPatch uint = 100 // appPreRelease MUST only contain characters from semanticAlphabet // per the semantic versioning spec. -- 2.45.2 From d9147a4b9c89b5cd450823c6fff948731d3764c0 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 9 Nov 2021 18:07:05 -0800 Subject: [PATCH 165/459] [lbry] ci: setup goreleaser --- .github/workflows/release.yml | 48 +++++++++++++++++++++++++++++ .goreleaser.yml | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 .goreleaser.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..92cffcc4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +name: goreleaser + +on: + workflow_dispatch: + inputs: + note: + description: 'Note' + required: false + default: '' + pull_request: + push: + tags: + - '*' + +permissions: + contents: write + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - + name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.17.3 + - + name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + distribution: goreleaser + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - + name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: lbcd-${{ github.sha }} + path: | + dist/checksums.txt + dist/*.tar.gz diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 00000000..db30c7fe --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,57 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy + # you may remove this if you don't need go generate + - go generate ./... +builds: + - + main: . + id: "lbcd" + binary: "lbcd" + env: + - CGO_ENABLED=0 + flags: + - -trimpath + ldflags: + - -s -w + - -X main.appBuild={{.Commit}} + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + - windows_amd64 + - + main: ./cmd/lbcctl + id: "lbcctl" + binary: "lbcctl" + flags: + - -trimpath + ldflags: + - -s -w + - -X main.appBuild={{.Commit}} + env: + - CGO_ENABLED=0 + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + - windows_amd64 +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ incpatch .Version }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + +release: + draft: true + prerelease: auto -- 2.45.2 From eb686cfa9e51ccd4198bee90c866466a19f5d3d4 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Wed, 10 Nov 2021 12:24:33 -0500 Subject: [PATCH 166/459] [lbry] blockchain, mining: don't flush on each new block in regtest --- blockchain/chain.go | 3 ++- mining/cpuminer/cpuminer.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index c829b61c..0e48b694 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -595,7 +595,8 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, // Handle LBRY Claim Scripts if b.claimTrie != nil { - if err := b.ParseClaimScripts(block, node, view, current); err != nil { + shouldFlush := current && b.chainParams.Net != wire.TestNet + if err := b.ParseClaimScripts(block, node, view, shouldFlush); err != nil { return ruleError(ErrBadClaimTrie, err.Error()) } } diff --git a/mining/cpuminer/cpuminer.go b/mining/cpuminer/cpuminer.go index 64cfaf50..7659d1a2 100644 --- a/mining/cpuminer/cpuminer.go +++ b/mining/cpuminer/cpuminer.go @@ -638,6 +638,6 @@ func New(cfg *Config) *CPUMiner { numWorkers: defaultNumWorkers, updateNumWorkers: make(chan struct{}), queryHashesPerSec: make(chan float64), - updateHashes: make(chan uint64), + updateHashes: make(chan uint64, 512), } } -- 2.45.2 From 2df74a828fa1d28ef08ecea3ab1a1e4fc1547252 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 26 Nov 2021 11:36:30 -0500 Subject: [PATCH 167/459] fix crash on unlock generate/invalidate loop --- blockchain/accept.go | 4 +++- blockchain/chain.go | 19 +++++++++++++++---- mempool/estimatefee.go | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/blockchain/accept.go b/blockchain/accept.go index 6acba30d..67657e4f 100644 --- a/blockchain/accept.go +++ b/blockchain/accept.go @@ -84,9 +84,11 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) // Notify the caller that the new block was accepted into the block // chain. The caller would typically want to react by relaying the // inventory to other peers. + b.notificationSendLock.Lock() + defer b.notificationSendLock.Unlock() b.chainLock.Unlock() + defer b.chainLock.Lock() b.sendNotification(NTBlockAccepted, block) - b.chainLock.Lock() return isMainChain, nil } diff --git a/blockchain/chain.go b/blockchain/chain.go index 0e48b694..4da5fbc1 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -116,6 +116,12 @@ type BlockChain struct { // fields in this struct below this point. chainLock sync.RWMutex + // notificationSendLock helps us only process one block at a time. + // It's definitely a hack. DCRD has much better structure in this regard. + // Without this you will get an error if you invalidate a block and then generate more right after. + // Taken from https://github.com/gcash/bchd/pull/308 + notificationSendLock sync.Mutex + // These fields are related to the memory block index. They both have // their own locks, however they are often also protected by the chain // lock to help prevent logic races when blocks are being processed. @@ -683,9 +689,11 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, // Notify the caller that the block was connected to the main chain. // The caller would typically want to react with actions such as // updating wallets. + b.notificationSendLock.Lock() + defer b.notificationSendLock.Unlock() b.chainLock.Unlock() + defer b.chainLock.Lock() b.sendNotification(NTBlockConnected, block) - b.chainLock.Lock() return nil } @@ -808,9 +816,11 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view // Notify the caller that the block was disconnected from the main // chain. The caller would typically want to react with actions such as // updating wallets. + b.notificationSendLock.Lock() + defer b.notificationSendLock.Unlock() b.chainLock.Unlock() + defer b.chainLock.Lock() b.sendNotification(NTBlockDisconnected, block) - b.chainLock.Lock() return nil } @@ -1646,6 +1656,8 @@ func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Has // // This function is safe for concurrent access. func (b *BlockChain) InvalidateBlock(hash *chainhash.Hash) error { + b.chainLock.Lock() + defer b.chainLock.Unlock() return b.invalidateBlock(hash) } @@ -1671,8 +1683,6 @@ func (b *BlockChain) invalidateBlock(hash *chainhash.Hash) error { b.index.SetStatusFlags(node, statusValidateFailed) b.index.UnsetStatusFlags(node, statusValid) - b.chainLock.Lock() - defer b.chainLock.Unlock() detachNodes, attachNodes := b.getReorganizeNodes(node.parent) err := b.reorganizeChain(detachNodes, attachNodes) @@ -1727,6 +1737,7 @@ func (b *BlockChain) reconsiderBlock(hash *chainhash.Hash) error { firstNode = n } + // do we need an rlock on chainstate for this section? var blk *btcutil.Block err := b.db.View(func(dbTx database.Tx) error { var err error diff --git a/mempool/estimatefee.go b/mempool/estimatefee.go index 719c42e2..bb1d5770 100644 --- a/mempool/estimatefee.go +++ b/mempool/estimatefee.go @@ -275,7 +275,7 @@ func (ef *FeeEstimator) RegisterBlock(block *btcutil.Block) error { // This shouldn't happen but check just in case to avoid // an out-of-bounds array index later. - if blocksToConfirm >= estimateFeeDepth { + if blocksToConfirm >= estimateFeeDepth || blocksToConfirm < 0 { continue } -- 2.45.2 From cb7b2b28bf6ac63ee0ce5fb08c72edd6267025fc Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Fri, 10 Dec 2021 11:06:55 -0500 Subject: [PATCH 168/459] [lbry] contrib: add linode deployment using docker --- contrib/linode/Dockerfile.deploy | 38 ++++++++++++++ contrib/linode/docker-compose.yml | 19 +++++++ contrib/linode/lbcd_stack_script.sh | 79 +++++++++++++++++++++++++++++ contrib/linode/run.sh | 2 + 4 files changed, 138 insertions(+) create mode 100644 contrib/linode/Dockerfile.deploy create mode 100644 contrib/linode/docker-compose.yml create mode 100644 contrib/linode/lbcd_stack_script.sh create mode 100755 contrib/linode/run.sh diff --git a/contrib/linode/Dockerfile.deploy b/contrib/linode/Dockerfile.deploy new file mode 100644 index 00000000..b9440234 --- /dev/null +++ b/contrib/linode/Dockerfile.deploy @@ -0,0 +1,38 @@ +# This Dockerfile builds btcd from source and creates a small (55 MB) docker container based on alpine linux. +# +# Clone this repository and run the following command to build and tag a fresh btcd amd64 container: +# +# docker build . -t yourregistry/btcd +# +# You can use the following command to buid an arm64v8 container: +# +# docker build . -t yourregistry/btcd --build-arg ARCH=arm64v8 +# +# For more information how to use this docker image visit: +# https://github.com/lbryio/lbcd/tree/master/docs +# +# 9246 Mainnet Bitcoin peer-to-peer port +# 9245 Mainet RPC port + +FROM golang AS build-container + +# ENV GO111MODULE=on + +ADD . /app +WORKDIR /app +RUN set -ex \ + && if [ "${ARCH}" = "amd64" ]; then export GOARCH=amd64; fi \ + && if [ "${ARCH}" = "arm64v8" ]; then export GOARCH=arm64; fi \ + && echo "Compiling for $GOARCH" \ + && CGO_ENABLED=0 go build . + +FROM debian:11-slim + +COPY --from=build-container /app/lbcd / +COPY --from=build-container /app/contrib/linode/run.sh / + +VOLUME ["/root/.lbcd"] + +EXPOSE 9245 9246 + +ENTRYPOINT ["/run.sh"] diff --git a/contrib/linode/docker-compose.yml b/contrib/linode/docker-compose.yml new file mode 100644 index 00000000..23b396d3 --- /dev/null +++ b/contrib/linode/docker-compose.yml @@ -0,0 +1,19 @@ +version: "3" + +volumes: + lbcd: + external: true + +services: + lbcd: + image: lbry/lbcd:linode_deployment + container_name: lbcd + ulimits: + memlock: + soft: -1 + hard: -1 + volumes: + - lbcd:/root/.lbcd:rw + ports: + - "REPLACE_ME:9245:9245" + - "9246:9246" diff --git a/contrib/linode/lbcd_stack_script.sh b/contrib/linode/lbcd_stack_script.sh new file mode 100644 index 00000000..8348d144 --- /dev/null +++ b/contrib/linode/lbcd_stack_script.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# +# +# +# +# +# +# +# + +source + +# For debugging +exec > >(tee -i /var/log/stackscript.log) 2>&1 +set -xeo pipefail + +function user_add_sudo { + USERNAME="$1" + USERPASS="$2" + if [ ! -n "$USERNAME" ] || [ ! -n "$USERPASS" ]; then + echo "No new username and/or password entered" + return 1; + fi + adduser "$USERNAME" --disabled-password --gecos "" + echo "$USERNAME:$USERPASS" | chpasswd + apt-get install -y sudo + usermod -aG sudo "$USERNAME" +} + +function download_snapshot { + if [ -z "${AWS_ACCESS_KEY_ID}" ]; then + wget "${SNAPSHOT_URL}" + else + echo "[default] + access_key = ${AWS_ACCESS_KEY_ID} + secret_key = ${AWS_SECRET_ACCESS_KEY}" > ~/.s3cfg + if [ -z "${ENDPOINT_URL}" ]; then + s4cmd --verbose get "${SNAPSHOT_URL}" + else + s4cmd --verbose get "${SNAPSHOT_URL}" --endpoint-url "${ENDPOINT_URL}" + fi + fi +} + +function download_and_start { + download_snapshot + # get the snapshot data into place + SNAPSHOT_FILE_NAME=$(echo "${SNAPSHOT_URL}" | rev | cut -d/ -f1 | rev) + unzip "${SNAPSHOT_FILE_NAME}" -d ~/.lbcd/ + mv ~/.lbcd/"${SNAPSHOT_FILE_NAME}" ~/.lbcd/data + rm "${SNAPSHOT_FILE_NAME}" + # get our private ip + PRIVATE_IP=$(ip addr | grep "${PRIVATE_IP_PREFIX}" | cut -d'/' -f1 | rev | cut -d" " -f 1 | rev) + # download the compose-compose and put our private ip in the for RPC endpoint + wget "${DOCKER_COMPOSE_FILE_URL}" -O - | sed 's/REPLACE_ME/'"${PRIVATE_IP}"'/g' > docker-compose.yml + # Create our volume and start lbcd + docker volume create --driver local \ + --opt type=none \ + --opt device=~/.lbcd\ + --opt o=bind lbcd + docker-compose up -d +} +# add a non-root sudo user +user_add_sudo "${USERNAME}" "${PASSWORD}" +# Update and install dependencies +sudo apt-get update && sudo apt-get upgrade -y +sudo apt-get install -y unzip wget s4cmd +apt install -y apt-transport-https ca-certificates curl software-properties-common && \ + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \ + add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \ + apt install -y docker-ce docker-ce-cli containerd.io && \ + systemctl enable docker && sudo systemctl start docker && \ + curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \ + chmod +x /usr/local/bin/docker-compose +# make sure we can use docker +usermod -aG docker $USERNAME +export -f download_and_start +export -f download_snapshot +su "${USERNAME}" -c 'bash -c "cd ~ && download_and_start"' \ No newline at end of file diff --git a/contrib/linode/run.sh b/contrib/linode/run.sh new file mode 100755 index 00000000..2966339c --- /dev/null +++ b/contrib/linode/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +/lbcd --txindex --notls --rpcuser=lbry --rpcpass=lbry --rpclisten= -- 2.45.2 From 3f2a2b1f760871ed511aa63dcef1b0f735e3f410 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 8 Apr 2021 22:42:13 -0700 Subject: [PATCH 169/459] [lbry] ci: update go modules --- go.mod | 48 +++- go.sum | 758 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 785 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 767c2740..02cf78c6 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,56 @@ -module github.com/btcsuite/btcd +module github.com/lbryio/lbcd + +go 1.17 require ( github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f - github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd github.com/btcsuite/goleveldb v1.0.0 github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 github.com/btcsuite/winsvc v1.0.0 + github.com/cockroachdb/errors v1.8.6 + github.com/cockroachdb/pebble v0.0.0-20211124004043-0dc90bc41e62 github.com/davecgh/go-spew v1.1.1 github.com/decred/dcrd/lru v1.0.0 + github.com/felixge/fgprof v0.9.1 github.com/jessevdk/go-flags v1.4.0 github.com/jrick/logrotate v1.0.0 - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect - golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 + github.com/lbryio/lbcutil v1.0.202-rc3 + github.com/pkg/errors v0.9.1 + github.com/shirou/gopsutil/v3 v3.21.7 + github.com/spf13/cobra v1.1.3 + github.com/stretchr/testify v1.7.0 + github.com/vmihailenco/msgpack/v5 v5.3.2 + golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b + golang.org/x/text v0.3.7 ) -go 1.16 +require ( + github.com/DataDog/zstd v1.5.0 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect + github.com/aead/siphash v1.0.1 // indirect + github.com/btcsuite/snappy-go v1.0.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect + github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 // indirect + github.com/go-ole/go-ole v1.2.5 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/pprof v0.0.0-20200615235658-03e1cf38a040 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/kkdai/bstream v1.0.0 // indirect + github.com/klauspost/compress v1.13.6 // indirect + github.com/kr/pretty v0.3.0 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/onsi/ginkgo v1.14.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/tklauser/go-sysconf v0.3.7 // indirect + github.com/tklauser/numcpus v0.2.3 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + golang.org/x/exp v0.0.0-20211123021643-48cbe7f80d7c // indirect + golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) diff --git a/go.sum b/go.sum index e9ee276d..ca8a9a18 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,64 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= +github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= @@ -18,90 +72,762 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3 github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= +github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= +github.com/cockroachdb/errors v1.8.6 h1:Am9evxl/po3RzpokemQvq7S7Cd0mxv24xy0B/trlQF4= +github.com/cockroachdb/errors v1.8.6/go.mod h1:hOm5fabihW+xEyY1kuypGwqT+Vt7rafg04ytBtIpeIQ= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f h1:6jduT9Hfc0njg5jJ1DdKCFPdMBrp/mdZfCpa5h+WM74= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v0.0.0-20210525181856-e45797baeb78/go.mod h1:1XpB4cLQcF189RAcWi4gUc110zJgtOfT7SVNGY8sOe0= +github.com/cockroachdb/pebble v0.0.0-20211124004043-0dc90bc41e62 h1:MPucjIPsIzjSY4RLiyhjX00sHQVNXbzzTpfYHfj0cQw= +github.com/cockroachdb/pebble v0.0.0-20211124004043-0dc90bc41e62/go.mod h1:buxOO9GBtOcq1DiXDpIPYrmxY020K2A8lOrwno5FetU= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.1/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/felixge/fgprof v0.9.1 h1:E6FUJ2Mlv043ipLOCFqo8+cHo9MhQ203E2cdEK/isEs= +github.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphsnGvqxE= +github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20200615235658-03e1cf38a040 h1:i7RUpu0EybzQyQvPT7J3MmODs4+gPcHsD/pqW0uIYVo= +github.com/google/pprof v0.0.0-20200615235658-03e1cf38a040/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= +github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= +github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kkdai/bstream v1.0.0 h1:Se5gHwgp2VT2uHfDrkbbgbgEvV9cimLELwrPJctSjg8= +github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/lbryio/lbcd v0.22.100-beta/go.mod h1:u8SaFX4xdGMMR5xasBGfgApC8pvD4rnK2OujZnrq5gs= +github.com/lbryio/lbcd v0.22.100-beta-rc5/go.mod h1:9PbFSlHYX7WlnDQwcTxHVf1W35VAnRsattCSyKOO55g= +github.com/lbryio/lbcutil v1.0.201/go.mod h1:gDHc/b+Rdz3J7+VB8e5/Bl9roVf8Q5/8FQCyuK9dXD0= +github.com/lbryio/lbcutil v1.0.202-rc3 h1:J7zYnIj3iN/ndPYKqMKBukLaLM1GhCEaiaMOYIMdUCU= +github.com/lbryio/lbcutil v1.0.202-rc3/go.mod h1:LGPtVBBzh4cFXfLFb8ginlFcbA2QwumLNFd0yk/as2o= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= +github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil/v3 v3.21.7 h1:PnTqQamUjwEDSgn+nBGu0qSDV/CfvyiR/gwTH3i7HTU= +github.com/shirou/gopsutil/v3 v3.21.7/go.mod h1:RGl11Y7XMTQPmHh8F0ayC6haKNBgH4PXMJuTAcMOlz4= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tklauser/go-sysconf v0.3.7 h1:HT7h4+536gjqeq1ZIJPgOl1rg1XFatQGVZWp7Py53eg= +github.com/tklauser/go-sysconf v0.3.7/go.mod h1:JZIdXh4RmBvZDBZ41ld2bGxRV3n4daiiqA3skYhAoQ4= +github.com/tklauser/numcpus v0.2.3 h1:nQ0QYpiritP6ViFhrKYsiv6VVxOpum2Gks5GhnJbS/8= +github.com/tklauser/numcpus v0.2.3/go.mod h1:vpEPS/JC+oZGGQ/My/vJnNsvMDQL6PwOqt8dsCw5j+E= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vmihailenco/msgpack/v5 v5.3.2 h1:MsXyN2rqdM8NM0lLiIpTn610e8Zcoj8ZuHxsMOi9qhI= +github.com/vmihailenco/msgpack/v5 v5.3.2/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= +go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= +go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= +go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4= +golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20211123021643-48cbe7f80d7c h1:hp+QRBz/P/780ndA1Rv/UpvsR6AsVmOMGYitxgZ1PPA= +golang.org/x/exp v0.0.0-20211123021643-48cbe7f80d7c/go.mod h1:b9TAUYHmRtqA6klRHApnXMnj+OyLce4yF5cZCUbk2ps= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab h1:rfJ1bsoJQQIAoAxTxB7bme+vHrNkRw8CqfsYh9w54cw= +golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -- 2.45.2 From b87ee2b51e5f63c204aa52fc5f04942d30e5647a Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 24 Dec 2021 15:15:13 -0500 Subject: [PATCH 170/459] switch to syndtr, golang 1.17.5 forgot to run tidy --- .github/workflows/basic-check.yml | 2 +- .github/workflows/full-sync-part-1.yml | 2 +- .github/workflows/full-sync-part-2.yml | 2 +- .github/workflows/release.yml | 2 +- blockchain/checkpoints.go | 3 ++- database/ffldb/db.go | 14 +++++++------- database/ffldb/dbcache.go | 6 +++--- database/ffldb/ldbtreapiter.go | 4 ++-- database/ffldb/whitebox_test.go | 4 ++-- go.mod | 4 +--- go.sum | 6 ++++-- 11 files changed, 25 insertions(+), 24 deletions(-) diff --git a/.github/workflows/basic-check.yml b/.github/workflows/basic-check.yml index ab6e5d87..4a644e87 100644 --- a/.github/workflows/basic-check.yml +++ b/.github/workflows/basic-check.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: [1.16.8, 1.17.1] + go: [1.16.8, 1.17.5] steps: - name: Set up Go uses: actions/setup-go@v2 diff --git a/.github/workflows/full-sync-part-1.yml b/.github/workflows/full-sync-part-1.yml index 27b88567..280fb2b2 100644 --- a/.github/workflows/full-sync-part-1.yml +++ b/.github/workflows/full-sync-part-1.yml @@ -14,7 +14,7 @@ jobs: runs-on: self-hosted strategy: matrix: - go: [1.17.3] + go: [1.17.5] steps: - run: | echo "Note ${{ github.event.inputs.note }}!" diff --git a/.github/workflows/full-sync-part-2.yml b/.github/workflows/full-sync-part-2.yml index ab0309fb..bc72cf62 100644 --- a/.github/workflows/full-sync-part-2.yml +++ b/.github/workflows/full-sync-part-2.yml @@ -14,7 +14,7 @@ jobs: runs-on: self-hosted strategy: matrix: - go: [1.17.3] + go: [1.17.5] steps: - run: | echo "Note ${{ github.event.inputs.note }}!" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 92cffcc4..5ab6d24b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.17.3 + go-version: 1.17.5 - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 diff --git a/blockchain/checkpoints.go b/blockchain/checkpoints.go index a82d70dd..e9b2d5a2 100644 --- a/blockchain/checkpoints.go +++ b/blockchain/checkpoints.go @@ -172,7 +172,8 @@ func (b *BlockChain) findPreviousCheckpoint() (*blockNode, error) { func isNonstandardTransaction(tx *btcutil.Tx) bool { // Check all of the output public key scripts for non-standard scripts. for _, txOut := range tx.MsgTx().TxOut { - scriptClass := txscript.GetScriptClass(txOut.PkScript) + stripped := txscript.StripClaimScriptPrefix(txOut.PkScript) + scriptClass := txscript.GetScriptClass(stripped) if scriptClass == txscript.NonStandardTy { return true } diff --git a/database/ffldb/db.go b/database/ffldb/db.go index ee6d55f0..843ef6bb 100644 --- a/database/ffldb/db.go +++ b/database/ffldb/db.go @@ -14,18 +14,18 @@ import ( "sort" "sync" - "github.com/btcsuite/goleveldb/leveldb" - "github.com/btcsuite/goleveldb/leveldb/comparer" - ldberrors "github.com/btcsuite/goleveldb/leveldb/errors" - "github.com/btcsuite/goleveldb/leveldb/filter" - "github.com/btcsuite/goleveldb/leveldb/iterator" - "github.com/btcsuite/goleveldb/leveldb/opt" - "github.com/btcsuite/goleveldb/leveldb/util" "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/database" "github.com/lbryio/lbcd/database/internal/treap" "github.com/lbryio/lbcd/wire" btcutil "github.com/lbryio/lbcutil" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/comparer" + ldberrors "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/filter" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/util" ) const ( diff --git a/database/ffldb/dbcache.go b/database/ffldb/dbcache.go index 1bc21a35..eff239c6 100644 --- a/database/ffldb/dbcache.go +++ b/database/ffldb/dbcache.go @@ -10,10 +10,10 @@ import ( "sync" "time" - "github.com/btcsuite/goleveldb/leveldb" - "github.com/btcsuite/goleveldb/leveldb/iterator" - "github.com/btcsuite/goleveldb/leveldb/util" "github.com/lbryio/lbcd/database/internal/treap" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/util" ) const ( diff --git a/database/ffldb/ldbtreapiter.go b/database/ffldb/ldbtreapiter.go index 0a552633..2073abbe 100644 --- a/database/ffldb/ldbtreapiter.go +++ b/database/ffldb/ldbtreapiter.go @@ -5,9 +5,9 @@ package ffldb import ( - "github.com/btcsuite/goleveldb/leveldb/iterator" - "github.com/btcsuite/goleveldb/leveldb/util" "github.com/lbryio/lbcd/database/internal/treap" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/util" ) // ldbTreapIter wraps a treap iterator to provide the additional functionality diff --git a/database/ffldb/whitebox_test.go b/database/ffldb/whitebox_test.go index 15c83cec..31a8ab34 100644 --- a/database/ffldb/whitebox_test.go +++ b/database/ffldb/whitebox_test.go @@ -17,11 +17,11 @@ import ( "path/filepath" "testing" - "github.com/btcsuite/goleveldb/leveldb" - ldberrors "github.com/btcsuite/goleveldb/leveldb/errors" "github.com/lbryio/lbcd/database" "github.com/lbryio/lbcd/wire" btcutil "github.com/lbryio/lbcutil" + "github.com/syndtr/goleveldb/leveldb" + ldberrors "github.com/syndtr/goleveldb/leveldb/errors" ) var ( diff --git a/go.mod b/go.mod index 02cf78c6..9ac89078 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.17 require ( github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd - github.com/btcsuite/goleveldb v1.0.0 github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 github.com/btcsuite/winsvc v1.0.0 github.com/cockroachdb/errors v1.8.6 @@ -20,6 +19,7 @@ require ( github.com/shirou/gopsutil/v3 v3.21.7 github.com/spf13/cobra v1.1.3 github.com/stretchr/testify v1.7.0 + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/vmihailenco/msgpack/v5 v5.3.2 golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b golang.org/x/text v0.3.7 @@ -29,7 +29,6 @@ require ( github.com/DataDog/zstd v1.5.0 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/aead/siphash v1.0.1 // indirect - github.com/btcsuite/snappy-go v1.0.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect github.com/cockroachdb/redact v1.1.3 // indirect @@ -43,7 +42,6 @@ require ( github.com/klauspost/compress v1.13.6 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/kr/text v0.2.0 // indirect - github.com/onsi/ginkgo v1.14.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect diff --git a/go.sum b/go.sum index ca8a9a18..987e44d5 100644 --- a/go.sum +++ b/go.sum @@ -63,10 +63,8 @@ github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlH github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0 h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE= github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= @@ -498,6 +496,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.7 h1:HT7h4+536gjqeq1ZIJPgOl1rg1XFatQGVZWp7Py53eg= github.com/tklauser/go-sysconf v0.3.7/go.mod h1:JZIdXh4RmBvZDBZ41ld2bGxRV3n4daiiqA3skYhAoQ4= github.com/tklauser/numcpus v0.2.3 h1:nQ0QYpiritP6ViFhrKYsiv6VVxOpum2Gks5GhnJbS/8= @@ -628,6 +628,7 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= @@ -679,6 +680,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -- 2.45.2 From 50d678b007e484ef6b972ebdcba9c2b33afdbeef Mon Sep 17 00:00:00 2001 From: Brannon King Date: Mon, 27 Dec 2021 17:17:44 -0500 Subject: [PATCH 171/459] [lbry] claimtrie: try to make ExpiresAt inlinable --- claimtrie/node/claim.go | 10 ---------- claimtrie/node/node.go | 32 +++++++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/claimtrie/node/claim.go b/claimtrie/node/claim.go index 8f385913..09a7ed08 100644 --- a/claimtrie/node/claim.go +++ b/claimtrie/node/claim.go @@ -7,7 +7,6 @@ import ( "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/claimtrie/change" - "github.com/lbryio/lbcd/claimtrie/param" "github.com/lbryio/lbcd/wire" ) @@ -58,15 +57,6 @@ func (c *Claim) setStatus(status Status) *Claim { return c } -func (c *Claim) ExpireAt() int32 { - - if c.AcceptedAt+param.ActiveParams.OriginalClaimExpirationTime > param.ActiveParams.ExtendedClaimExpirationForkHeight { - return c.AcceptedAt + param.ActiveParams.ExtendedClaimExpirationTime - } - - return c.AcceptedAt + param.ActiveParams.OriginalClaimExpirationTime -} - func OutPointLess(a, b wire.OutPoint) bool { switch cmp := bytes.Compare(a.Hash[:], b.Hash[:]); { diff --git a/claimtrie/node/node.go b/claimtrie/node/node.go index f9a466be..fe6db947 100644 --- a/claimtrie/node/node.go +++ b/claimtrie/node/node.go @@ -156,6 +156,16 @@ func (n *Node) updateTakeoverHeight(height int32, name []byte, refindBest bool) func (n *Node) handleExpiredAndActivated(height int32) int { + ot := param.ActiveParams.OriginalClaimExpirationTime + et := param.ActiveParams.ExtendedClaimExpirationTime + fk := param.ActiveParams.ExtendedClaimExpirationForkHeight + expiresAt := func(c *Claim) int32 { + if c.AcceptedAt+ot > fk { + return c.AcceptedAt + et + } + return c.AcceptedAt + ot + } + changes := 0 update := func(items ClaimList, sums map[string]int64) ClaimList { for i := 0; i < len(items); i++ { @@ -167,7 +177,7 @@ func (n *Node) handleExpiredAndActivated(height int32) int { sums[c.ClaimID.Key()] += c.Amount } } - if c.ExpireAt() <= height || c.Status == Deactivated { + if c.Status == Deactivated || expiresAt(c) <= height { if i < len(items)-1 { items[i] = items[len(items)-1] i-- @@ -190,11 +200,22 @@ func (n *Node) handleExpiredAndActivated(height int32) int { // be refreshed due to changes of claims or supports. func (n Node) NextUpdate() int32 { + ot := param.ActiveParams.OriginalClaimExpirationTime + et := param.ActiveParams.ExtendedClaimExpirationTime + fk := param.ActiveParams.ExtendedClaimExpirationForkHeight + expiresAt := func(c *Claim) int32 { + if c.AcceptedAt+ot > fk { + return c.AcceptedAt + et + } + return c.AcceptedAt + ot + } + next := int32(math.MaxInt32) for _, c := range n.Claims { - if c.ExpireAt() < next { - next = c.ExpireAt() + ea := expiresAt(c) + if ea < next { + next = ea } // if we're not active, we need to go to activeAt unless we're still invisible there if c.Status == Accepted { @@ -209,8 +230,9 @@ func (n Node) NextUpdate() int32 { } for _, s := range n.Supports { - if s.ExpireAt() < next { - next = s.ExpireAt() + es := expiresAt(s) + if es < next { + next = es } if s.Status == Accepted { min := s.ActiveAt -- 2.45.2 From 1f8ed174c0f573897c2b98438bd467b4c311e737 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Wed, 29 Dec 2021 14:24:19 -0500 Subject: [PATCH 172/459] [lbry] removed dependency on text/norm, fixed NFD normalization --- claimtrie/normalization/CaseFolding_v13.txt | 1584 -- claimtrie/normalization/NFC_v11.txt | 2431 ++ .../normalization/NormalizationTest_v11.txt | 18847 ++++++++++++++++ claimtrie/normalization/case_folder.go | 2 +- claimtrie/normalization/char_decomposer.go | 177 + claimtrie/normalization/normalizer.go | 7 +- claimtrie/normalization/normalizer_icu.go | 22 +- .../normalization/normalizer_icu_test.go | 9 + claimtrie/normalization/normalizer_test.go | 35 + go.mod | 1 - 10 files changed, 21519 insertions(+), 1596 deletions(-) delete mode 100644 claimtrie/normalization/CaseFolding_v13.txt create mode 100644 claimtrie/normalization/NFC_v11.txt create mode 100644 claimtrie/normalization/NormalizationTest_v11.txt create mode 100644 claimtrie/normalization/char_decomposer.go diff --git a/claimtrie/normalization/CaseFolding_v13.txt b/claimtrie/normalization/CaseFolding_v13.txt deleted file mode 100644 index 033788b2..00000000 --- a/claimtrie/normalization/CaseFolding_v13.txt +++ /dev/null @@ -1,1584 +0,0 @@ -# CaseFolding-13.0.0.txt -# Date: 2019-09-08, 23:30:59 GMT -# © 2019 Unicode®, Inc. -# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see http://www.unicode.org/terms_of_use.html -# -# Unicode Character Database -# For documentation, see http://www.unicode.org/reports/tr44/ -# -# Case Folding Properties -# -# This file is a supplement to the UnicodeData file. -# It provides a case folding mapping generated from the Unicode Character Database. -# If all characters are mapped according to the full mapping below, then -# case differences (according to UnicodeData.txt and SpecialCasing.txt) -# are eliminated. -# -# The data supports both implementations that require simple case foldings -# (where string lengths don't change), and implementations that allow full case folding -# (where string lengths may grow). Note that where they can be supported, the -# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match. -# -# All code points not listed in this file map to themselves. -# -# NOTE: case folding does not preserve normalization formats! -# -# For information on case folding, including how to have case folding -# preserve normalization formats, see Section 3.13 Default Case Algorithms in -# The Unicode Standard. -# -# ================================================================================ -# Format -# ================================================================================ -# The entries in this file are in the following machine-readable format: -# -# ; ; ; # -# -# The status field is: -# C: common case folding, common mappings shared by both simple and full mappings. -# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces. -# S: simple case folding, mappings to single characters where different from F. -# T: special case for uppercase I and dotted uppercase I -# - For non-Turkic languages, this mapping is normally not used. -# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters. -# Note that the Turkic mappings do not maintain canonical equivalence without additional processing. -# See the discussions of case mapping in the Unicode Standard for more information. -# -# Usage: -# A. To do a simple case folding, use the mappings with status C + S. -# B. To do a full case folding, use the mappings with status C + F. -# -# The mappings with status T can be used or omitted depending on the desired case-folding -# behavior. (The default option is to exclude them.) -# -# ================================================================= - -# Property: Case_Folding - -# All code points not explicitly listed for Case_Folding -# have the value C for the status field, and the code point itself for the mapping field. - -# ================================================================= -0041; C; 0061; # LATIN CAPITAL LETTER A -0042; C; 0062; # LATIN CAPITAL LETTER B -0043; C; 0063; # LATIN CAPITAL LETTER C -0044; C; 0064; # LATIN CAPITAL LETTER D -0045; C; 0065; # LATIN CAPITAL LETTER E -0046; C; 0066; # LATIN CAPITAL LETTER F -0047; C; 0067; # LATIN CAPITAL LETTER G -0048; C; 0068; # LATIN CAPITAL LETTER H -0049; C; 0069; # LATIN CAPITAL LETTER I -0049; T; 0131; # LATIN CAPITAL LETTER I -004A; C; 006A; # LATIN CAPITAL LETTER J -004B; C; 006B; # LATIN CAPITAL LETTER K -004C; C; 006C; # LATIN CAPITAL LETTER L -004D; C; 006D; # LATIN CAPITAL LETTER M -004E; C; 006E; # LATIN CAPITAL LETTER N -004F; C; 006F; # LATIN CAPITAL LETTER O -0050; C; 0070; # LATIN CAPITAL LETTER P -0051; C; 0071; # LATIN CAPITAL LETTER Q -0052; C; 0072; # LATIN CAPITAL LETTER R -0053; C; 0073; # LATIN CAPITAL LETTER S -0054; C; 0074; # LATIN CAPITAL LETTER T -0055; C; 0075; # LATIN CAPITAL LETTER U -0056; C; 0076; # LATIN CAPITAL LETTER V -0057; C; 0077; # LATIN CAPITAL LETTER W -0058; C; 0078; # LATIN CAPITAL LETTER X -0059; C; 0079; # LATIN CAPITAL LETTER Y -005A; C; 007A; # LATIN CAPITAL LETTER Z -00B5; C; 03BC; # MICRO SIGN -00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE -00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE -00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX -00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE -00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS -00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE -00C6; C; 00E6; # LATIN CAPITAL LETTER AE -00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA -00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE -00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE -00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX -00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS -00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE -00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE -00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX -00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS -00D0; C; 00F0; # LATIN CAPITAL LETTER ETH -00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE -00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE -00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE -00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX -00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE -00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS -00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE -00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE -00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE -00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX -00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS -00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE -00DE; C; 00FE; # LATIN CAPITAL LETTER THORN -00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S -0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON -0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE -0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK -0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE -0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX -010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE -010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON -010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON -0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE -0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON -0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE -0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE -0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK -011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON -011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX -011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE -0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE -0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA -0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX -0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE -0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE -012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON -012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE -012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK -0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE -0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE -0132; C; 0133; # LATIN CAPITAL LIGATURE IJ -0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX -0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA -0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE -013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA -013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON -013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT -0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE -0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE -0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA -0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON -0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE -014A; C; 014B; # LATIN CAPITAL LETTER ENG -014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON -014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE -0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -0152; C; 0153; # LATIN CAPITAL LIGATURE OE -0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE -0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA -0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON -015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE -015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX -015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA -0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON -0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA -0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON -0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE -0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE -016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON -016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE -016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE -0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK -0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX -0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX -0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS -0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE -017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE -017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON -017F; C; 0073; # LATIN SMALL LETTER LONG S -0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK -0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR -0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX -0186; C; 0254; # LATIN CAPITAL LETTER OPEN O -0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK -0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D -018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK -018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR -018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E -018F; C; 0259; # LATIN CAPITAL LETTER SCHWA -0190; C; 025B; # LATIN CAPITAL LETTER OPEN E -0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK -0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK -0194; C; 0263; # LATIN CAPITAL LETTER GAMMA -0196; C; 0269; # LATIN CAPITAL LETTER IOTA -0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE -0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK -019C; C; 026F; # LATIN CAPITAL LETTER TURNED M -019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK -019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE -01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN -01A2; C; 01A3; # LATIN CAPITAL LETTER OI -01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK -01A6; C; 0280; # LATIN LETTER YR -01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO -01A9; C; 0283; # LATIN CAPITAL LETTER ESH -01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK -01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK -01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN -01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON -01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK -01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK -01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE -01B7; C; 0292; # LATIN CAPITAL LETTER EZH -01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED -01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE -01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON -01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON -01C7; C; 01C9; # LATIN CAPITAL LETTER LJ -01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J -01CA; C; 01CC; # LATIN CAPITAL LETTER NJ -01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J -01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON -01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON -01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON -01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON -01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON -01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE -01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON -01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE -01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON -01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON -01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON -01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE -01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON -01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON -01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK -01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON -01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON -01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON -01F1; C; 01F3; # LATIN CAPITAL LETTER DZ -01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z -01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE -01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR -01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN -01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE -01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE -01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE -01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE -0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE -0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE -0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE -0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE -0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE -020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE -020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE -020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE -0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE -0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE -0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE -0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE -0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW -021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW -021C; C; 021D; # LATIN CAPITAL LETTER YOGH -021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON -0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG -0222; C; 0223; # LATIN CAPITAL LETTER OU -0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK -0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE -0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA -022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON -022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON -022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE -0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON -0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON -023A; C; 2C65; # LATIN CAPITAL LETTER A WITH STROKE -023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE -023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR -023E; C; 2C66; # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE -0241; C; 0242; # LATIN CAPITAL LETTER GLOTTAL STOP -0243; C; 0180; # LATIN CAPITAL LETTER B WITH STROKE -0244; C; 0289; # LATIN CAPITAL LETTER U BAR -0245; C; 028C; # LATIN CAPITAL LETTER TURNED V -0246; C; 0247; # LATIN CAPITAL LETTER E WITH STROKE -0248; C; 0249; # LATIN CAPITAL LETTER J WITH STROKE -024A; C; 024B; # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL -024C; C; 024D; # LATIN CAPITAL LETTER R WITH STROKE -024E; C; 024F; # LATIN CAPITAL LETTER Y WITH STROKE -0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI -0370; C; 0371; # GREEK CAPITAL LETTER HETA -0372; C; 0373; # GREEK CAPITAL LETTER ARCHAIC SAMPI -0376; C; 0377; # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA -037F; C; 03F3; # GREEK CAPITAL LETTER YOT -0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS -0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS -0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS -038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS -038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS -038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS -038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS -0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA -0392; C; 03B2; # GREEK CAPITAL LETTER BETA -0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA -0394; C; 03B4; # GREEK CAPITAL LETTER DELTA -0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON -0396; C; 03B6; # GREEK CAPITAL LETTER ZETA -0397; C; 03B7; # GREEK CAPITAL LETTER ETA -0398; C; 03B8; # GREEK CAPITAL LETTER THETA -0399; C; 03B9; # GREEK CAPITAL LETTER IOTA -039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA -039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA -039C; C; 03BC; # GREEK CAPITAL LETTER MU -039D; C; 03BD; # GREEK CAPITAL LETTER NU -039E; C; 03BE; # GREEK CAPITAL LETTER XI -039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON -03A0; C; 03C0; # GREEK CAPITAL LETTER PI -03A1; C; 03C1; # GREEK CAPITAL LETTER RHO -03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA -03A4; C; 03C4; # GREEK CAPITAL LETTER TAU -03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON -03A6; C; 03C6; # GREEK CAPITAL LETTER PHI -03A7; C; 03C7; # GREEK CAPITAL LETTER CHI -03A8; C; 03C8; # GREEK CAPITAL LETTER PSI -03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA -03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA -03CF; C; 03D7; # GREEK CAPITAL KAI SYMBOL -03D0; C; 03B2; # GREEK BETA SYMBOL -03D1; C; 03B8; # GREEK THETA SYMBOL -03D5; C; 03C6; # GREEK PHI SYMBOL -03D6; C; 03C0; # GREEK PI SYMBOL -03D8; C; 03D9; # GREEK LETTER ARCHAIC KOPPA -03DA; C; 03DB; # GREEK LETTER STIGMA -03DC; C; 03DD; # GREEK LETTER DIGAMMA -03DE; C; 03DF; # GREEK LETTER KOPPA -03E0; C; 03E1; # GREEK LETTER SAMPI -03E2; C; 03E3; # COPTIC CAPITAL LETTER SHEI -03E4; C; 03E5; # COPTIC CAPITAL LETTER FEI -03E6; C; 03E7; # COPTIC CAPITAL LETTER KHEI -03E8; C; 03E9; # COPTIC CAPITAL LETTER HORI -03EA; C; 03EB; # COPTIC CAPITAL LETTER GANGIA -03EC; C; 03ED; # COPTIC CAPITAL LETTER SHIMA -03EE; C; 03EF; # COPTIC CAPITAL LETTER DEI -03F0; C; 03BA; # GREEK KAPPA SYMBOL -03F1; C; 03C1; # GREEK RHO SYMBOL -03F4; C; 03B8; # GREEK CAPITAL THETA SYMBOL -03F5; C; 03B5; # GREEK LUNATE EPSILON SYMBOL -03F7; C; 03F8; # GREEK CAPITAL LETTER SHO -03F9; C; 03F2; # GREEK CAPITAL LUNATE SIGMA SYMBOL -03FA; C; 03FB; # GREEK CAPITAL LETTER SAN -03FD; C; 037B; # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL -03FE; C; 037C; # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL -03FF; C; 037D; # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL -0400; C; 0450; # CYRILLIC CAPITAL LETTER IE WITH GRAVE -0401; C; 0451; # CYRILLIC CAPITAL LETTER IO -0402; C; 0452; # CYRILLIC CAPITAL LETTER DJE -0403; C; 0453; # CYRILLIC CAPITAL LETTER GJE -0404; C; 0454; # CYRILLIC CAPITAL LETTER UKRAINIAN IE -0405; C; 0455; # CYRILLIC CAPITAL LETTER DZE -0406; C; 0456; # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -0407; C; 0457; # CYRILLIC CAPITAL LETTER YI -0408; C; 0458; # CYRILLIC CAPITAL LETTER JE -0409; C; 0459; # CYRILLIC CAPITAL LETTER LJE -040A; C; 045A; # CYRILLIC CAPITAL LETTER NJE -040B; C; 045B; # CYRILLIC CAPITAL LETTER TSHE -040C; C; 045C; # CYRILLIC CAPITAL LETTER KJE -040D; C; 045D; # CYRILLIC CAPITAL LETTER I WITH GRAVE -040E; C; 045E; # CYRILLIC CAPITAL LETTER SHORT U -040F; C; 045F; # CYRILLIC CAPITAL LETTER DZHE -0410; C; 0430; # CYRILLIC CAPITAL LETTER A -0411; C; 0431; # CYRILLIC CAPITAL LETTER BE -0412; C; 0432; # CYRILLIC CAPITAL LETTER VE -0413; C; 0433; # CYRILLIC CAPITAL LETTER GHE -0414; C; 0434; # CYRILLIC CAPITAL LETTER DE -0415; C; 0435; # CYRILLIC CAPITAL LETTER IE -0416; C; 0436; # CYRILLIC CAPITAL LETTER ZHE -0417; C; 0437; # CYRILLIC CAPITAL LETTER ZE -0418; C; 0438; # CYRILLIC CAPITAL LETTER I -0419; C; 0439; # CYRILLIC CAPITAL LETTER SHORT I -041A; C; 043A; # CYRILLIC CAPITAL LETTER KA -041B; C; 043B; # CYRILLIC CAPITAL LETTER EL -041C; C; 043C; # CYRILLIC CAPITAL LETTER EM -041D; C; 043D; # CYRILLIC CAPITAL LETTER EN -041E; C; 043E; # CYRILLIC CAPITAL LETTER O -041F; C; 043F; # CYRILLIC CAPITAL LETTER PE -0420; C; 0440; # CYRILLIC CAPITAL LETTER ER -0421; C; 0441; # CYRILLIC CAPITAL LETTER ES -0422; C; 0442; # CYRILLIC CAPITAL LETTER TE -0423; C; 0443; # CYRILLIC CAPITAL LETTER U -0424; C; 0444; # CYRILLIC CAPITAL LETTER EF -0425; C; 0445; # CYRILLIC CAPITAL LETTER HA -0426; C; 0446; # CYRILLIC CAPITAL LETTER TSE -0427; C; 0447; # CYRILLIC CAPITAL LETTER CHE -0428; C; 0448; # CYRILLIC CAPITAL LETTER SHA -0429; C; 0449; # CYRILLIC CAPITAL LETTER SHCHA -042A; C; 044A; # CYRILLIC CAPITAL LETTER HARD SIGN -042B; C; 044B; # CYRILLIC CAPITAL LETTER YERU -042C; C; 044C; # CYRILLIC CAPITAL LETTER SOFT SIGN -042D; C; 044D; # CYRILLIC CAPITAL LETTER E -042E; C; 044E; # CYRILLIC CAPITAL LETTER YU -042F; C; 044F; # CYRILLIC CAPITAL LETTER YA -0460; C; 0461; # CYRILLIC CAPITAL LETTER OMEGA -0462; C; 0463; # CYRILLIC CAPITAL LETTER YAT -0464; C; 0465; # CYRILLIC CAPITAL LETTER IOTIFIED E -0466; C; 0467; # CYRILLIC CAPITAL LETTER LITTLE YUS -0468; C; 0469; # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS -046A; C; 046B; # CYRILLIC CAPITAL LETTER BIG YUS -046C; C; 046D; # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS -046E; C; 046F; # CYRILLIC CAPITAL LETTER KSI -0470; C; 0471; # CYRILLIC CAPITAL LETTER PSI -0472; C; 0473; # CYRILLIC CAPITAL LETTER FITA -0474; C; 0475; # CYRILLIC CAPITAL LETTER IZHITSA -0476; C; 0477; # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT -0478; C; 0479; # CYRILLIC CAPITAL LETTER UK -047A; C; 047B; # CYRILLIC CAPITAL LETTER ROUND OMEGA -047C; C; 047D; # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO -047E; C; 047F; # CYRILLIC CAPITAL LETTER OT -0480; C; 0481; # CYRILLIC CAPITAL LETTER KOPPA -048A; C; 048B; # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL -048C; C; 048D; # CYRILLIC CAPITAL LETTER SEMISOFT SIGN -048E; C; 048F; # CYRILLIC CAPITAL LETTER ER WITH TICK -0490; C; 0491; # CYRILLIC CAPITAL LETTER GHE WITH UPTURN -0492; C; 0493; # CYRILLIC CAPITAL LETTER GHE WITH STROKE -0494; C; 0495; # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK -0496; C; 0497; # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER -0498; C; 0499; # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER -049A; C; 049B; # CYRILLIC CAPITAL LETTER KA WITH DESCENDER -049C; C; 049D; # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE -049E; C; 049F; # CYRILLIC CAPITAL LETTER KA WITH STROKE -04A0; C; 04A1; # CYRILLIC CAPITAL LETTER BASHKIR KA -04A2; C; 04A3; # CYRILLIC CAPITAL LETTER EN WITH DESCENDER -04A4; C; 04A5; # CYRILLIC CAPITAL LIGATURE EN GHE -04A6; C; 04A7; # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK -04A8; C; 04A9; # CYRILLIC CAPITAL LETTER ABKHASIAN HA -04AA; C; 04AB; # CYRILLIC CAPITAL LETTER ES WITH DESCENDER -04AC; C; 04AD; # CYRILLIC CAPITAL LETTER TE WITH DESCENDER -04AE; C; 04AF; # CYRILLIC CAPITAL LETTER STRAIGHT U -04B0; C; 04B1; # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE -04B2; C; 04B3; # CYRILLIC CAPITAL LETTER HA WITH DESCENDER -04B4; C; 04B5; # CYRILLIC CAPITAL LIGATURE TE TSE -04B6; C; 04B7; # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER -04B8; C; 04B9; # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE -04BA; C; 04BB; # CYRILLIC CAPITAL LETTER SHHA -04BC; C; 04BD; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE -04BE; C; 04BF; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER -04C0; C; 04CF; # CYRILLIC LETTER PALOCHKA -04C1; C; 04C2; # CYRILLIC CAPITAL LETTER ZHE WITH BREVE -04C3; C; 04C4; # CYRILLIC CAPITAL LETTER KA WITH HOOK -04C5; C; 04C6; # CYRILLIC CAPITAL LETTER EL WITH TAIL -04C7; C; 04C8; # CYRILLIC CAPITAL LETTER EN WITH HOOK -04C9; C; 04CA; # CYRILLIC CAPITAL LETTER EN WITH TAIL -04CB; C; 04CC; # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE -04CD; C; 04CE; # CYRILLIC CAPITAL LETTER EM WITH TAIL -04D0; C; 04D1; # CYRILLIC CAPITAL LETTER A WITH BREVE -04D2; C; 04D3; # CYRILLIC CAPITAL LETTER A WITH DIAERESIS -04D4; C; 04D5; # CYRILLIC CAPITAL LIGATURE A IE -04D6; C; 04D7; # CYRILLIC CAPITAL LETTER IE WITH BREVE -04D8; C; 04D9; # CYRILLIC CAPITAL LETTER SCHWA -04DA; C; 04DB; # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS -04DC; C; 04DD; # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS -04DE; C; 04DF; # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS -04E0; C; 04E1; # CYRILLIC CAPITAL LETTER ABKHASIAN DZE -04E2; C; 04E3; # CYRILLIC CAPITAL LETTER I WITH MACRON -04E4; C; 04E5; # CYRILLIC CAPITAL LETTER I WITH DIAERESIS -04E6; C; 04E7; # CYRILLIC CAPITAL LETTER O WITH DIAERESIS -04E8; C; 04E9; # CYRILLIC CAPITAL LETTER BARRED O -04EA; C; 04EB; # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS -04EC; C; 04ED; # CYRILLIC CAPITAL LETTER E WITH DIAERESIS -04EE; C; 04EF; # CYRILLIC CAPITAL LETTER U WITH MACRON -04F0; C; 04F1; # CYRILLIC CAPITAL LETTER U WITH DIAERESIS -04F2; C; 04F3; # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE -04F4; C; 04F5; # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS -04F6; C; 04F7; # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER -04F8; C; 04F9; # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS -04FA; C; 04FB; # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK -04FC; C; 04FD; # CYRILLIC CAPITAL LETTER HA WITH HOOK -04FE; C; 04FF; # CYRILLIC CAPITAL LETTER HA WITH STROKE -0500; C; 0501; # CYRILLIC CAPITAL LETTER KOMI DE -0502; C; 0503; # CYRILLIC CAPITAL LETTER KOMI DJE -0504; C; 0505; # CYRILLIC CAPITAL LETTER KOMI ZJE -0506; C; 0507; # CYRILLIC CAPITAL LETTER KOMI DZJE -0508; C; 0509; # CYRILLIC CAPITAL LETTER KOMI LJE -050A; C; 050B; # CYRILLIC CAPITAL LETTER KOMI NJE -050C; C; 050D; # CYRILLIC CAPITAL LETTER KOMI SJE -050E; C; 050F; # CYRILLIC CAPITAL LETTER KOMI TJE -0510; C; 0511; # CYRILLIC CAPITAL LETTER REVERSED ZE -0512; C; 0513; # CYRILLIC CAPITAL LETTER EL WITH HOOK -0514; C; 0515; # CYRILLIC CAPITAL LETTER LHA -0516; C; 0517; # CYRILLIC CAPITAL LETTER RHA -0518; C; 0519; # CYRILLIC CAPITAL LETTER YAE -051A; C; 051B; # CYRILLIC CAPITAL LETTER QA -051C; C; 051D; # CYRILLIC CAPITAL LETTER WE -051E; C; 051F; # CYRILLIC CAPITAL LETTER ALEUT KA -0520; C; 0521; # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK -0522; C; 0523; # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK -0524; C; 0525; # CYRILLIC CAPITAL LETTER PE WITH DESCENDER -0526; C; 0527; # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER -0528; C; 0529; # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK -052A; C; 052B; # CYRILLIC CAPITAL LETTER DZZHE -052C; C; 052D; # CYRILLIC CAPITAL LETTER DCHE -052E; C; 052F; # CYRILLIC CAPITAL LETTER EL WITH DESCENDER -0531; C; 0561; # ARMENIAN CAPITAL LETTER AYB -0532; C; 0562; # ARMENIAN CAPITAL LETTER BEN -0533; C; 0563; # ARMENIAN CAPITAL LETTER GIM -0534; C; 0564; # ARMENIAN CAPITAL LETTER DA -0535; C; 0565; # ARMENIAN CAPITAL LETTER ECH -0536; C; 0566; # ARMENIAN CAPITAL LETTER ZA -0537; C; 0567; # ARMENIAN CAPITAL LETTER EH -0538; C; 0568; # ARMENIAN CAPITAL LETTER ET -0539; C; 0569; # ARMENIAN CAPITAL LETTER TO -053A; C; 056A; # ARMENIAN CAPITAL LETTER ZHE -053B; C; 056B; # ARMENIAN CAPITAL LETTER INI -053C; C; 056C; # ARMENIAN CAPITAL LETTER LIWN -053D; C; 056D; # ARMENIAN CAPITAL LETTER XEH -053E; C; 056E; # ARMENIAN CAPITAL LETTER CA -053F; C; 056F; # ARMENIAN CAPITAL LETTER KEN -0540; C; 0570; # ARMENIAN CAPITAL LETTER HO -0541; C; 0571; # ARMENIAN CAPITAL LETTER JA -0542; C; 0572; # ARMENIAN CAPITAL LETTER GHAD -0543; C; 0573; # ARMENIAN CAPITAL LETTER CHEH -0544; C; 0574; # ARMENIAN CAPITAL LETTER MEN -0545; C; 0575; # ARMENIAN CAPITAL LETTER YI -0546; C; 0576; # ARMENIAN CAPITAL LETTER NOW -0547; C; 0577; # ARMENIAN CAPITAL LETTER SHA -0548; C; 0578; # ARMENIAN CAPITAL LETTER VO -0549; C; 0579; # ARMENIAN CAPITAL LETTER CHA -054A; C; 057A; # ARMENIAN CAPITAL LETTER PEH -054B; C; 057B; # ARMENIAN CAPITAL LETTER JHEH -054C; C; 057C; # ARMENIAN CAPITAL LETTER RA -054D; C; 057D; # ARMENIAN CAPITAL LETTER SEH -054E; C; 057E; # ARMENIAN CAPITAL LETTER VEW -054F; C; 057F; # ARMENIAN CAPITAL LETTER TIWN -0550; C; 0580; # ARMENIAN CAPITAL LETTER REH -0551; C; 0581; # ARMENIAN CAPITAL LETTER CO -0552; C; 0582; # ARMENIAN CAPITAL LETTER YIWN -0553; C; 0583; # ARMENIAN CAPITAL LETTER PIWR -0554; C; 0584; # ARMENIAN CAPITAL LETTER KEH -0555; C; 0585; # ARMENIAN CAPITAL LETTER OH -0556; C; 0586; # ARMENIAN CAPITAL LETTER FEH -0587; F; 0565 0582; # ARMENIAN SMALL LIGATURE ECH YIWN -10A0; C; 2D00; # GEORGIAN CAPITAL LETTER AN -10A1; C; 2D01; # GEORGIAN CAPITAL LETTER BAN -10A2; C; 2D02; # GEORGIAN CAPITAL LETTER GAN -10A3; C; 2D03; # GEORGIAN CAPITAL LETTER DON -10A4; C; 2D04; # GEORGIAN CAPITAL LETTER EN -10A5; C; 2D05; # GEORGIAN CAPITAL LETTER VIN -10A6; C; 2D06; # GEORGIAN CAPITAL LETTER ZEN -10A7; C; 2D07; # GEORGIAN CAPITAL LETTER TAN -10A8; C; 2D08; # GEORGIAN CAPITAL LETTER IN -10A9; C; 2D09; # GEORGIAN CAPITAL LETTER KAN -10AA; C; 2D0A; # GEORGIAN CAPITAL LETTER LAS -10AB; C; 2D0B; # GEORGIAN CAPITAL LETTER MAN -10AC; C; 2D0C; # GEORGIAN CAPITAL LETTER NAR -10AD; C; 2D0D; # GEORGIAN CAPITAL LETTER ON -10AE; C; 2D0E; # GEORGIAN CAPITAL LETTER PAR -10AF; C; 2D0F; # GEORGIAN CAPITAL LETTER ZHAR -10B0; C; 2D10; # GEORGIAN CAPITAL LETTER RAE -10B1; C; 2D11; # GEORGIAN CAPITAL LETTER SAN -10B2; C; 2D12; # GEORGIAN CAPITAL LETTER TAR -10B3; C; 2D13; # GEORGIAN CAPITAL LETTER UN -10B4; C; 2D14; # GEORGIAN CAPITAL LETTER PHAR -10B5; C; 2D15; # GEORGIAN CAPITAL LETTER KHAR -10B6; C; 2D16; # GEORGIAN CAPITAL LETTER GHAN -10B7; C; 2D17; # GEORGIAN CAPITAL LETTER QAR -10B8; C; 2D18; # GEORGIAN CAPITAL LETTER SHIN -10B9; C; 2D19; # GEORGIAN CAPITAL LETTER CHIN -10BA; C; 2D1A; # GEORGIAN CAPITAL LETTER CAN -10BB; C; 2D1B; # GEORGIAN CAPITAL LETTER JIL -10BC; C; 2D1C; # GEORGIAN CAPITAL LETTER CIL -10BD; C; 2D1D; # GEORGIAN CAPITAL LETTER CHAR -10BE; C; 2D1E; # GEORGIAN CAPITAL LETTER XAN -10BF; C; 2D1F; # GEORGIAN CAPITAL LETTER JHAN -10C0; C; 2D20; # GEORGIAN CAPITAL LETTER HAE -10C1; C; 2D21; # GEORGIAN CAPITAL LETTER HE -10C2; C; 2D22; # GEORGIAN CAPITAL LETTER HIE -10C3; C; 2D23; # GEORGIAN CAPITAL LETTER WE -10C4; C; 2D24; # GEORGIAN CAPITAL LETTER HAR -10C5; C; 2D25; # GEORGIAN CAPITAL LETTER HOE -10C7; C; 2D27; # GEORGIAN CAPITAL LETTER YN -10CD; C; 2D2D; # GEORGIAN CAPITAL LETTER AEN -13F8; C; 13F0; # CHEROKEE SMALL LETTER YE -13F9; C; 13F1; # CHEROKEE SMALL LETTER YI -13FA; C; 13F2; # CHEROKEE SMALL LETTER YO -13FB; C; 13F3; # CHEROKEE SMALL LETTER YU -13FC; C; 13F4; # CHEROKEE SMALL LETTER YV -13FD; C; 13F5; # CHEROKEE SMALL LETTER MV -1C80; C; 0432; # CYRILLIC SMALL LETTER ROUNDED VE -1C81; C; 0434; # CYRILLIC SMALL LETTER LONG-LEGGED DE -1C82; C; 043E; # CYRILLIC SMALL LETTER NARROW O -1C83; C; 0441; # CYRILLIC SMALL LETTER WIDE ES -1C84; C; 0442; # CYRILLIC SMALL LETTER TALL TE -1C85; C; 0442; # CYRILLIC SMALL LETTER THREE-LEGGED TE -1C86; C; 044A; # CYRILLIC SMALL LETTER TALL HARD SIGN -1C87; C; 0463; # CYRILLIC SMALL LETTER TALL YAT -1C88; C; A64B; # CYRILLIC SMALL LETTER UNBLENDED UK -1C90; C; 10D0; # GEORGIAN MTAVRULI CAPITAL LETTER AN -1C91; C; 10D1; # GEORGIAN MTAVRULI CAPITAL LETTER BAN -1C92; C; 10D2; # GEORGIAN MTAVRULI CAPITAL LETTER GAN -1C93; C; 10D3; # GEORGIAN MTAVRULI CAPITAL LETTER DON -1C94; C; 10D4; # GEORGIAN MTAVRULI CAPITAL LETTER EN -1C95; C; 10D5; # GEORGIAN MTAVRULI CAPITAL LETTER VIN -1C96; C; 10D6; # GEORGIAN MTAVRULI CAPITAL LETTER ZEN -1C97; C; 10D7; # GEORGIAN MTAVRULI CAPITAL LETTER TAN -1C98; C; 10D8; # GEORGIAN MTAVRULI CAPITAL LETTER IN -1C99; C; 10D9; # GEORGIAN MTAVRULI CAPITAL LETTER KAN -1C9A; C; 10DA; # GEORGIAN MTAVRULI CAPITAL LETTER LAS -1C9B; C; 10DB; # GEORGIAN MTAVRULI CAPITAL LETTER MAN -1C9C; C; 10DC; # GEORGIAN MTAVRULI CAPITAL LETTER NAR -1C9D; C; 10DD; # GEORGIAN MTAVRULI CAPITAL LETTER ON -1C9E; C; 10DE; # GEORGIAN MTAVRULI CAPITAL LETTER PAR -1C9F; C; 10DF; # GEORGIAN MTAVRULI CAPITAL LETTER ZHAR -1CA0; C; 10E0; # GEORGIAN MTAVRULI CAPITAL LETTER RAE -1CA1; C; 10E1; # GEORGIAN MTAVRULI CAPITAL LETTER SAN -1CA2; C; 10E2; # GEORGIAN MTAVRULI CAPITAL LETTER TAR -1CA3; C; 10E3; # GEORGIAN MTAVRULI CAPITAL LETTER UN -1CA4; C; 10E4; # GEORGIAN MTAVRULI CAPITAL LETTER PHAR -1CA5; C; 10E5; # GEORGIAN MTAVRULI CAPITAL LETTER KHAR -1CA6; C; 10E6; # GEORGIAN MTAVRULI CAPITAL LETTER GHAN -1CA7; C; 10E7; # GEORGIAN MTAVRULI CAPITAL LETTER QAR -1CA8; C; 10E8; # GEORGIAN MTAVRULI CAPITAL LETTER SHIN -1CA9; C; 10E9; # GEORGIAN MTAVRULI CAPITAL LETTER CHIN -1CAA; C; 10EA; # GEORGIAN MTAVRULI CAPITAL LETTER CAN -1CAB; C; 10EB; # GEORGIAN MTAVRULI CAPITAL LETTER JIL -1CAC; C; 10EC; # GEORGIAN MTAVRULI CAPITAL LETTER CIL -1CAD; C; 10ED; # GEORGIAN MTAVRULI CAPITAL LETTER CHAR -1CAE; C; 10EE; # GEORGIAN MTAVRULI CAPITAL LETTER XAN -1CAF; C; 10EF; # GEORGIAN MTAVRULI CAPITAL LETTER JHAN -1CB0; C; 10F0; # GEORGIAN MTAVRULI CAPITAL LETTER HAE -1CB1; C; 10F1; # GEORGIAN MTAVRULI CAPITAL LETTER HE -1CB2; C; 10F2; # GEORGIAN MTAVRULI CAPITAL LETTER HIE -1CB3; C; 10F3; # GEORGIAN MTAVRULI CAPITAL LETTER WE -1CB4; C; 10F4; # GEORGIAN MTAVRULI CAPITAL LETTER HAR -1CB5; C; 10F5; # GEORGIAN MTAVRULI CAPITAL LETTER HOE -1CB6; C; 10F6; # GEORGIAN MTAVRULI CAPITAL LETTER FI -1CB7; C; 10F7; # GEORGIAN MTAVRULI CAPITAL LETTER YN -1CB8; C; 10F8; # GEORGIAN MTAVRULI CAPITAL LETTER ELIFI -1CB9; C; 10F9; # GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN -1CBA; C; 10FA; # GEORGIAN MTAVRULI CAPITAL LETTER AIN -1CBD; C; 10FD; # GEORGIAN MTAVRULI CAPITAL LETTER AEN -1CBE; C; 10FE; # GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN -1CBF; C; 10FF; # GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN -1E00; C; 1E01; # LATIN CAPITAL LETTER A WITH RING BELOW -1E02; C; 1E03; # LATIN CAPITAL LETTER B WITH DOT ABOVE -1E04; C; 1E05; # LATIN CAPITAL LETTER B WITH DOT BELOW -1E06; C; 1E07; # LATIN CAPITAL LETTER B WITH LINE BELOW -1E08; C; 1E09; # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE -1E0A; C; 1E0B; # LATIN CAPITAL LETTER D WITH DOT ABOVE -1E0C; C; 1E0D; # LATIN CAPITAL LETTER D WITH DOT BELOW -1E0E; C; 1E0F; # LATIN CAPITAL LETTER D WITH LINE BELOW -1E10; C; 1E11; # LATIN CAPITAL LETTER D WITH CEDILLA -1E12; C; 1E13; # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW -1E14; C; 1E15; # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE -1E16; C; 1E17; # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE -1E18; C; 1E19; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW -1E1A; C; 1E1B; # LATIN CAPITAL LETTER E WITH TILDE BELOW -1E1C; C; 1E1D; # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE -1E1E; C; 1E1F; # LATIN CAPITAL LETTER F WITH DOT ABOVE -1E20; C; 1E21; # LATIN CAPITAL LETTER G WITH MACRON -1E22; C; 1E23; # LATIN CAPITAL LETTER H WITH DOT ABOVE -1E24; C; 1E25; # LATIN CAPITAL LETTER H WITH DOT BELOW -1E26; C; 1E27; # LATIN CAPITAL LETTER H WITH DIAERESIS -1E28; C; 1E29; # LATIN CAPITAL LETTER H WITH CEDILLA -1E2A; C; 1E2B; # LATIN CAPITAL LETTER H WITH BREVE BELOW -1E2C; C; 1E2D; # LATIN CAPITAL LETTER I WITH TILDE BELOW -1E2E; C; 1E2F; # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE -1E30; C; 1E31; # LATIN CAPITAL LETTER K WITH ACUTE -1E32; C; 1E33; # LATIN CAPITAL LETTER K WITH DOT BELOW -1E34; C; 1E35; # LATIN CAPITAL LETTER K WITH LINE BELOW -1E36; C; 1E37; # LATIN CAPITAL LETTER L WITH DOT BELOW -1E38; C; 1E39; # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON -1E3A; C; 1E3B; # LATIN CAPITAL LETTER L WITH LINE BELOW -1E3C; C; 1E3D; # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW -1E3E; C; 1E3F; # LATIN CAPITAL LETTER M WITH ACUTE -1E40; C; 1E41; # LATIN CAPITAL LETTER M WITH DOT ABOVE -1E42; C; 1E43; # LATIN CAPITAL LETTER M WITH DOT BELOW -1E44; C; 1E45; # LATIN CAPITAL LETTER N WITH DOT ABOVE -1E46; C; 1E47; # LATIN CAPITAL LETTER N WITH DOT BELOW -1E48; C; 1E49; # LATIN CAPITAL LETTER N WITH LINE BELOW -1E4A; C; 1E4B; # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW -1E4C; C; 1E4D; # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE -1E4E; C; 1E4F; # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS -1E50; C; 1E51; # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE -1E52; C; 1E53; # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE -1E54; C; 1E55; # LATIN CAPITAL LETTER P WITH ACUTE -1E56; C; 1E57; # LATIN CAPITAL LETTER P WITH DOT ABOVE -1E58; C; 1E59; # LATIN CAPITAL LETTER R WITH DOT ABOVE -1E5A; C; 1E5B; # LATIN CAPITAL LETTER R WITH DOT BELOW -1E5C; C; 1E5D; # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON -1E5E; C; 1E5F; # LATIN CAPITAL LETTER R WITH LINE BELOW -1E60; C; 1E61; # LATIN CAPITAL LETTER S WITH DOT ABOVE -1E62; C; 1E63; # LATIN CAPITAL LETTER S WITH DOT BELOW -1E64; C; 1E65; # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE -1E66; C; 1E67; # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE -1E68; C; 1E69; # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE -1E6A; C; 1E6B; # LATIN CAPITAL LETTER T WITH DOT ABOVE -1E6C; C; 1E6D; # LATIN CAPITAL LETTER T WITH DOT BELOW -1E6E; C; 1E6F; # LATIN CAPITAL LETTER T WITH LINE BELOW -1E70; C; 1E71; # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW -1E72; C; 1E73; # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW -1E74; C; 1E75; # LATIN CAPITAL LETTER U WITH TILDE BELOW -1E76; C; 1E77; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW -1E78; C; 1E79; # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE -1E7A; C; 1E7B; # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS -1E7C; C; 1E7D; # LATIN CAPITAL LETTER V WITH TILDE -1E7E; C; 1E7F; # LATIN CAPITAL LETTER V WITH DOT BELOW -1E80; C; 1E81; # LATIN CAPITAL LETTER W WITH GRAVE -1E82; C; 1E83; # LATIN CAPITAL LETTER W WITH ACUTE -1E84; C; 1E85; # LATIN CAPITAL LETTER W WITH DIAERESIS -1E86; C; 1E87; # LATIN CAPITAL LETTER W WITH DOT ABOVE -1E88; C; 1E89; # LATIN CAPITAL LETTER W WITH DOT BELOW -1E8A; C; 1E8B; # LATIN CAPITAL LETTER X WITH DOT ABOVE -1E8C; C; 1E8D; # LATIN CAPITAL LETTER X WITH DIAERESIS -1E8E; C; 1E8F; # LATIN CAPITAL LETTER Y WITH DOT ABOVE -1E90; C; 1E91; # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX -1E92; C; 1E93; # LATIN CAPITAL LETTER Z WITH DOT BELOW -1E94; C; 1E95; # LATIN CAPITAL LETTER Z WITH LINE BELOW -1E96; F; 0068 0331; # LATIN SMALL LETTER H WITH LINE BELOW -1E97; F; 0074 0308; # LATIN SMALL LETTER T WITH DIAERESIS -1E98; F; 0077 030A; # LATIN SMALL LETTER W WITH RING ABOVE -1E99; F; 0079 030A; # LATIN SMALL LETTER Y WITH RING ABOVE -1E9A; F; 0061 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING -1E9B; C; 1E61; # LATIN SMALL LETTER LONG S WITH DOT ABOVE -1E9E; F; 0073 0073; # LATIN CAPITAL LETTER SHARP S -1E9E; S; 00DF; # LATIN CAPITAL LETTER SHARP S -1EA0; C; 1EA1; # LATIN CAPITAL LETTER A WITH DOT BELOW -1EA2; C; 1EA3; # LATIN CAPITAL LETTER A WITH HOOK ABOVE -1EA4; C; 1EA5; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE -1EA6; C; 1EA7; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE -1EA8; C; 1EA9; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE -1EAA; C; 1EAB; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE -1EAC; C; 1EAD; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW -1EAE; C; 1EAF; # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE -1EB0; C; 1EB1; # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE -1EB2; C; 1EB3; # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE -1EB4; C; 1EB5; # LATIN CAPITAL LETTER A WITH BREVE AND TILDE -1EB6; C; 1EB7; # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW -1EB8; C; 1EB9; # LATIN CAPITAL LETTER E WITH DOT BELOW -1EBA; C; 1EBB; # LATIN CAPITAL LETTER E WITH HOOK ABOVE -1EBC; C; 1EBD; # LATIN CAPITAL LETTER E WITH TILDE -1EBE; C; 1EBF; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE -1EC0; C; 1EC1; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE -1EC2; C; 1EC3; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE -1EC4; C; 1EC5; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE -1EC6; C; 1EC7; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW -1EC8; C; 1EC9; # LATIN CAPITAL LETTER I WITH HOOK ABOVE -1ECA; C; 1ECB; # LATIN CAPITAL LETTER I WITH DOT BELOW -1ECC; C; 1ECD; # LATIN CAPITAL LETTER O WITH DOT BELOW -1ECE; C; 1ECF; # LATIN CAPITAL LETTER O WITH HOOK ABOVE -1ED0; C; 1ED1; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE -1ED2; C; 1ED3; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE -1ED4; C; 1ED5; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE -1ED6; C; 1ED7; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE -1ED8; C; 1ED9; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW -1EDA; C; 1EDB; # LATIN CAPITAL LETTER O WITH HORN AND ACUTE -1EDC; C; 1EDD; # LATIN CAPITAL LETTER O WITH HORN AND GRAVE -1EDE; C; 1EDF; # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE -1EE0; C; 1EE1; # LATIN CAPITAL LETTER O WITH HORN AND TILDE -1EE2; C; 1EE3; # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW -1EE4; C; 1EE5; # LATIN CAPITAL LETTER U WITH DOT BELOW -1EE6; C; 1EE7; # LATIN CAPITAL LETTER U WITH HOOK ABOVE -1EE8; C; 1EE9; # LATIN CAPITAL LETTER U WITH HORN AND ACUTE -1EEA; C; 1EEB; # LATIN CAPITAL LETTER U WITH HORN AND GRAVE -1EEC; C; 1EED; # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE -1EEE; C; 1EEF; # LATIN CAPITAL LETTER U WITH HORN AND TILDE -1EF0; C; 1EF1; # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW -1EF2; C; 1EF3; # LATIN CAPITAL LETTER Y WITH GRAVE -1EF4; C; 1EF5; # LATIN CAPITAL LETTER Y WITH DOT BELOW -1EF6; C; 1EF7; # LATIN CAPITAL LETTER Y WITH HOOK ABOVE -1EF8; C; 1EF9; # LATIN CAPITAL LETTER Y WITH TILDE -1EFA; C; 1EFB; # LATIN CAPITAL LETTER MIDDLE-WELSH LL -1EFC; C; 1EFD; # LATIN CAPITAL LETTER MIDDLE-WELSH V -1EFE; C; 1EFF; # LATIN CAPITAL LETTER Y WITH LOOP -1F08; C; 1F00; # GREEK CAPITAL LETTER ALPHA WITH PSILI -1F09; C; 1F01; # GREEK CAPITAL LETTER ALPHA WITH DASIA -1F0A; C; 1F02; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA -1F0B; C; 1F03; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA -1F0C; C; 1F04; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA -1F0D; C; 1F05; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA -1F0E; C; 1F06; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI -1F0F; C; 1F07; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI -1F18; C; 1F10; # GREEK CAPITAL LETTER EPSILON WITH PSILI -1F19; C; 1F11; # GREEK CAPITAL LETTER EPSILON WITH DASIA -1F1A; C; 1F12; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA -1F1B; C; 1F13; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA -1F1C; C; 1F14; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA -1F1D; C; 1F15; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA -1F28; C; 1F20; # GREEK CAPITAL LETTER ETA WITH PSILI -1F29; C; 1F21; # GREEK CAPITAL LETTER ETA WITH DASIA -1F2A; C; 1F22; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA -1F2B; C; 1F23; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA -1F2C; C; 1F24; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA -1F2D; C; 1F25; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA -1F2E; C; 1F26; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI -1F2F; C; 1F27; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI -1F38; C; 1F30; # GREEK CAPITAL LETTER IOTA WITH PSILI -1F39; C; 1F31; # GREEK CAPITAL LETTER IOTA WITH DASIA -1F3A; C; 1F32; # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA -1F3B; C; 1F33; # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA -1F3C; C; 1F34; # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA -1F3D; C; 1F35; # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA -1F3E; C; 1F36; # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI -1F3F; C; 1F37; # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI -1F48; C; 1F40; # GREEK CAPITAL LETTER OMICRON WITH PSILI -1F49; C; 1F41; # GREEK CAPITAL LETTER OMICRON WITH DASIA -1F4A; C; 1F42; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA -1F4B; C; 1F43; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA -1F4C; C; 1F44; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA -1F4D; C; 1F45; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA -1F50; F; 03C5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI -1F52; F; 03C5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA -1F54; F; 03C5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA -1F56; F; 03C5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI -1F59; C; 1F51; # GREEK CAPITAL LETTER UPSILON WITH DASIA -1F5B; C; 1F53; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA -1F5D; C; 1F55; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA -1F5F; C; 1F57; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI -1F68; C; 1F60; # GREEK CAPITAL LETTER OMEGA WITH PSILI -1F69; C; 1F61; # GREEK CAPITAL LETTER OMEGA WITH DASIA -1F6A; C; 1F62; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA -1F6B; C; 1F63; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA -1F6C; C; 1F64; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA -1F6D; C; 1F65; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA -1F6E; C; 1F66; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI -1F6F; C; 1F67; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI -1F80; F; 1F00 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI -1F81; F; 1F01 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI -1F82; F; 1F02 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI -1F83; F; 1F03 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI -1F84; F; 1F04 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI -1F85; F; 1F05 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI -1F86; F; 1F06 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI -1F87; F; 1F07 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI -1F88; F; 1F00 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI -1F88; S; 1F80; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI -1F89; F; 1F01 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI -1F89; S; 1F81; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI -1F8A; F; 1F02 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1F8A; S; 1F82; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1F8B; F; 1F03 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1F8B; S; 1F83; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1F8C; F; 1F04 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1F8C; S; 1F84; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1F8D; F; 1F05 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1F8D; S; 1F85; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1F8E; F; 1F06 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1F8E; S; 1F86; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1F8F; F; 1F07 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1F8F; S; 1F87; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1F90; F; 1F20 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI -1F91; F; 1F21 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI -1F92; F; 1F22 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI -1F93; F; 1F23 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI -1F94; F; 1F24 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI -1F95; F; 1F25 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI -1F96; F; 1F26 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI -1F97; F; 1F27 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI -1F98; F; 1F20 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI -1F98; S; 1F90; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI -1F99; F; 1F21 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI -1F99; S; 1F91; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI -1F9A; F; 1F22 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1F9A; S; 1F92; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1F9B; F; 1F23 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1F9B; S; 1F93; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1F9C; F; 1F24 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1F9C; S; 1F94; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1F9D; F; 1F25 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1F9D; S; 1F95; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1F9E; F; 1F26 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1F9E; S; 1F96; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1F9F; F; 1F27 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1F9F; S; 1F97; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1FA0; F; 1F60 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI -1FA1; F; 1F61 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI -1FA2; F; 1F62 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI -1FA3; F; 1F63 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI -1FA4; F; 1F64 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI -1FA5; F; 1F65 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI -1FA6; F; 1F66 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI -1FA7; F; 1F67 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI -1FA8; F; 1F60 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI -1FA8; S; 1FA0; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI -1FA9; F; 1F61 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI -1FA9; S; 1FA1; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI -1FAA; F; 1F62 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1FAA; S; 1FA2; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1FAB; F; 1F63 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1FAB; S; 1FA3; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1FAC; F; 1F64 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1FAC; S; 1FA4; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1FAD; F; 1F65 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1FAD; S; 1FA5; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1FAE; F; 1F66 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1FAE; S; 1FA6; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1FAF; F; 1F67 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1FAF; S; 1FA7; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1FB2; F; 1F70 03B9; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI -1FB3; F; 03B1 03B9; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI -1FB4; F; 03AC 03B9; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI -1FB6; F; 03B1 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI -1FB7; F; 03B1 0342 03B9; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI -1FB8; C; 1FB0; # GREEK CAPITAL LETTER ALPHA WITH VRACHY -1FB9; C; 1FB1; # GREEK CAPITAL LETTER ALPHA WITH MACRON -1FBA; C; 1F70; # GREEK CAPITAL LETTER ALPHA WITH VARIA -1FBB; C; 1F71; # GREEK CAPITAL LETTER ALPHA WITH OXIA -1FBC; F; 03B1 03B9; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI -1FBC; S; 1FB3; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI -1FBE; C; 03B9; # GREEK PROSGEGRAMMENI -1FC2; F; 1F74 03B9; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI -1FC3; F; 03B7 03B9; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI -1FC4; F; 03AE 03B9; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI -1FC6; F; 03B7 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI -1FC7; F; 03B7 0342 03B9; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI -1FC8; C; 1F72; # GREEK CAPITAL LETTER EPSILON WITH VARIA -1FC9; C; 1F73; # GREEK CAPITAL LETTER EPSILON WITH OXIA -1FCA; C; 1F74; # GREEK CAPITAL LETTER ETA WITH VARIA -1FCB; C; 1F75; # GREEK CAPITAL LETTER ETA WITH OXIA -1FCC; F; 03B7 03B9; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI -1FCC; S; 1FC3; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI -1FD2; F; 03B9 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA -1FD3; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA -1FD6; F; 03B9 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI -1FD7; F; 03B9 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI -1FD8; C; 1FD0; # GREEK CAPITAL LETTER IOTA WITH VRACHY -1FD9; C; 1FD1; # GREEK CAPITAL LETTER IOTA WITH MACRON -1FDA; C; 1F76; # GREEK CAPITAL LETTER IOTA WITH VARIA -1FDB; C; 1F77; # GREEK CAPITAL LETTER IOTA WITH OXIA -1FE2; F; 03C5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA -1FE3; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA -1FE4; F; 03C1 0313; # GREEK SMALL LETTER RHO WITH PSILI -1FE6; F; 03C5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI -1FE7; F; 03C5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI -1FE8; C; 1FE0; # GREEK CAPITAL LETTER UPSILON WITH VRACHY -1FE9; C; 1FE1; # GREEK CAPITAL LETTER UPSILON WITH MACRON -1FEA; C; 1F7A; # GREEK CAPITAL LETTER UPSILON WITH VARIA -1FEB; C; 1F7B; # GREEK CAPITAL LETTER UPSILON WITH OXIA -1FEC; C; 1FE5; # GREEK CAPITAL LETTER RHO WITH DASIA -1FF2; F; 1F7C 03B9; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI -1FF3; F; 03C9 03B9; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI -1FF4; F; 03CE 03B9; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI -1FF6; F; 03C9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI -1FF7; F; 03C9 0342 03B9; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI -1FF8; C; 1F78; # GREEK CAPITAL LETTER OMICRON WITH VARIA -1FF9; C; 1F79; # GREEK CAPITAL LETTER OMICRON WITH OXIA -1FFA; C; 1F7C; # GREEK CAPITAL LETTER OMEGA WITH VARIA -1FFB; C; 1F7D; # GREEK CAPITAL LETTER OMEGA WITH OXIA -1FFC; F; 03C9 03B9; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI -1FFC; S; 1FF3; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI -2126; C; 03C9; # OHM SIGN -212A; C; 006B; # KELVIN SIGN -212B; C; 00E5; # ANGSTROM SIGN -2132; C; 214E; # TURNED CAPITAL F -2160; C; 2170; # ROMAN NUMERAL ONE -2161; C; 2171; # ROMAN NUMERAL TWO -2162; C; 2172; # ROMAN NUMERAL THREE -2163; C; 2173; # ROMAN NUMERAL FOUR -2164; C; 2174; # ROMAN NUMERAL FIVE -2165; C; 2175; # ROMAN NUMERAL SIX -2166; C; 2176; # ROMAN NUMERAL SEVEN -2167; C; 2177; # ROMAN NUMERAL EIGHT -2168; C; 2178; # ROMAN NUMERAL NINE -2169; C; 2179; # ROMAN NUMERAL TEN -216A; C; 217A; # ROMAN NUMERAL ELEVEN -216B; C; 217B; # ROMAN NUMERAL TWELVE -216C; C; 217C; # ROMAN NUMERAL FIFTY -216D; C; 217D; # ROMAN NUMERAL ONE HUNDRED -216E; C; 217E; # ROMAN NUMERAL FIVE HUNDRED -216F; C; 217F; # ROMAN NUMERAL ONE THOUSAND -2183; C; 2184; # ROMAN NUMERAL REVERSED ONE HUNDRED -24B6; C; 24D0; # CIRCLED LATIN CAPITAL LETTER A -24B7; C; 24D1; # CIRCLED LATIN CAPITAL LETTER B -24B8; C; 24D2; # CIRCLED LATIN CAPITAL LETTER C -24B9; C; 24D3; # CIRCLED LATIN CAPITAL LETTER D -24BA; C; 24D4; # CIRCLED LATIN CAPITAL LETTER E -24BB; C; 24D5; # CIRCLED LATIN CAPITAL LETTER F -24BC; C; 24D6; # CIRCLED LATIN CAPITAL LETTER G -24BD; C; 24D7; # CIRCLED LATIN CAPITAL LETTER H -24BE; C; 24D8; # CIRCLED LATIN CAPITAL LETTER I -24BF; C; 24D9; # CIRCLED LATIN CAPITAL LETTER J -24C0; C; 24DA; # CIRCLED LATIN CAPITAL LETTER K -24C1; C; 24DB; # CIRCLED LATIN CAPITAL LETTER L -24C2; C; 24DC; # CIRCLED LATIN CAPITAL LETTER M -24C3; C; 24DD; # CIRCLED LATIN CAPITAL LETTER N -24C4; C; 24DE; # CIRCLED LATIN CAPITAL LETTER O -24C5; C; 24DF; # CIRCLED LATIN CAPITAL LETTER P -24C6; C; 24E0; # CIRCLED LATIN CAPITAL LETTER Q -24C7; C; 24E1; # CIRCLED LATIN CAPITAL LETTER R -24C8; C; 24E2; # CIRCLED LATIN CAPITAL LETTER S -24C9; C; 24E3; # CIRCLED LATIN CAPITAL LETTER T -24CA; C; 24E4; # CIRCLED LATIN CAPITAL LETTER U -24CB; C; 24E5; # CIRCLED LATIN CAPITAL LETTER V -24CC; C; 24E6; # CIRCLED LATIN CAPITAL LETTER W -24CD; C; 24E7; # CIRCLED LATIN CAPITAL LETTER X -24CE; C; 24E8; # CIRCLED LATIN CAPITAL LETTER Y -24CF; C; 24E9; # CIRCLED LATIN CAPITAL LETTER Z -2C00; C; 2C30; # GLAGOLITIC CAPITAL LETTER AZU -2C01; C; 2C31; # GLAGOLITIC CAPITAL LETTER BUKY -2C02; C; 2C32; # GLAGOLITIC CAPITAL LETTER VEDE -2C03; C; 2C33; # GLAGOLITIC CAPITAL LETTER GLAGOLI -2C04; C; 2C34; # GLAGOLITIC CAPITAL LETTER DOBRO -2C05; C; 2C35; # GLAGOLITIC CAPITAL LETTER YESTU -2C06; C; 2C36; # GLAGOLITIC CAPITAL LETTER ZHIVETE -2C07; C; 2C37; # GLAGOLITIC CAPITAL LETTER DZELO -2C08; C; 2C38; # GLAGOLITIC CAPITAL LETTER ZEMLJA -2C09; C; 2C39; # GLAGOLITIC CAPITAL LETTER IZHE -2C0A; C; 2C3A; # GLAGOLITIC CAPITAL LETTER INITIAL IZHE -2C0B; C; 2C3B; # GLAGOLITIC CAPITAL LETTER I -2C0C; C; 2C3C; # GLAGOLITIC CAPITAL LETTER DJERVI -2C0D; C; 2C3D; # GLAGOLITIC CAPITAL LETTER KAKO -2C0E; C; 2C3E; # GLAGOLITIC CAPITAL LETTER LJUDIJE -2C0F; C; 2C3F; # GLAGOLITIC CAPITAL LETTER MYSLITE -2C10; C; 2C40; # GLAGOLITIC CAPITAL LETTER NASHI -2C11; C; 2C41; # GLAGOLITIC CAPITAL LETTER ONU -2C12; C; 2C42; # GLAGOLITIC CAPITAL LETTER POKOJI -2C13; C; 2C43; # GLAGOLITIC CAPITAL LETTER RITSI -2C14; C; 2C44; # GLAGOLITIC CAPITAL LETTER SLOVO -2C15; C; 2C45; # GLAGOLITIC CAPITAL LETTER TVRIDO -2C16; C; 2C46; # GLAGOLITIC CAPITAL LETTER UKU -2C17; C; 2C47; # GLAGOLITIC CAPITAL LETTER FRITU -2C18; C; 2C48; # GLAGOLITIC CAPITAL LETTER HERU -2C19; C; 2C49; # GLAGOLITIC CAPITAL LETTER OTU -2C1A; C; 2C4A; # GLAGOLITIC CAPITAL LETTER PE -2C1B; C; 2C4B; # GLAGOLITIC CAPITAL LETTER SHTA -2C1C; C; 2C4C; # GLAGOLITIC CAPITAL LETTER TSI -2C1D; C; 2C4D; # GLAGOLITIC CAPITAL LETTER CHRIVI -2C1E; C; 2C4E; # GLAGOLITIC CAPITAL LETTER SHA -2C1F; C; 2C4F; # GLAGOLITIC CAPITAL LETTER YERU -2C20; C; 2C50; # GLAGOLITIC CAPITAL LETTER YERI -2C21; C; 2C51; # GLAGOLITIC CAPITAL LETTER YATI -2C22; C; 2C52; # GLAGOLITIC CAPITAL LETTER SPIDERY HA -2C23; C; 2C53; # GLAGOLITIC CAPITAL LETTER YU -2C24; C; 2C54; # GLAGOLITIC CAPITAL LETTER SMALL YUS -2C25; C; 2C55; # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL -2C26; C; 2C56; # GLAGOLITIC CAPITAL LETTER YO -2C27; C; 2C57; # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS -2C28; C; 2C58; # GLAGOLITIC CAPITAL LETTER BIG YUS -2C29; C; 2C59; # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS -2C2A; C; 2C5A; # GLAGOLITIC CAPITAL LETTER FITA -2C2B; C; 2C5B; # GLAGOLITIC CAPITAL LETTER IZHITSA -2C2C; C; 2C5C; # GLAGOLITIC CAPITAL LETTER SHTAPIC -2C2D; C; 2C5D; # GLAGOLITIC CAPITAL LETTER TROKUTASTI A -2C2E; C; 2C5E; # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C60; C; 2C61; # LATIN CAPITAL LETTER L WITH DOUBLE BAR -2C62; C; 026B; # LATIN CAPITAL LETTER L WITH MIDDLE TILDE -2C63; C; 1D7D; # LATIN CAPITAL LETTER P WITH STROKE -2C64; C; 027D; # LATIN CAPITAL LETTER R WITH TAIL -2C67; C; 2C68; # LATIN CAPITAL LETTER H WITH DESCENDER -2C69; C; 2C6A; # LATIN CAPITAL LETTER K WITH DESCENDER -2C6B; C; 2C6C; # LATIN CAPITAL LETTER Z WITH DESCENDER -2C6D; C; 0251; # LATIN CAPITAL LETTER ALPHA -2C6E; C; 0271; # LATIN CAPITAL LETTER M WITH HOOK -2C6F; C; 0250; # LATIN CAPITAL LETTER TURNED A -2C70; C; 0252; # LATIN CAPITAL LETTER TURNED ALPHA -2C72; C; 2C73; # LATIN CAPITAL LETTER W WITH HOOK -2C75; C; 2C76; # LATIN CAPITAL LETTER HALF H -2C7E; C; 023F; # LATIN CAPITAL LETTER S WITH SWASH TAIL -2C7F; C; 0240; # LATIN CAPITAL LETTER Z WITH SWASH TAIL -2C80; C; 2C81; # COPTIC CAPITAL LETTER ALFA -2C82; C; 2C83; # COPTIC CAPITAL LETTER VIDA -2C84; C; 2C85; # COPTIC CAPITAL LETTER GAMMA -2C86; C; 2C87; # COPTIC CAPITAL LETTER DALDA -2C88; C; 2C89; # COPTIC CAPITAL LETTER EIE -2C8A; C; 2C8B; # COPTIC CAPITAL LETTER SOU -2C8C; C; 2C8D; # COPTIC CAPITAL LETTER ZATA -2C8E; C; 2C8F; # COPTIC CAPITAL LETTER HATE -2C90; C; 2C91; # COPTIC CAPITAL LETTER THETHE -2C92; C; 2C93; # COPTIC CAPITAL LETTER IAUDA -2C94; C; 2C95; # COPTIC CAPITAL LETTER KAPA -2C96; C; 2C97; # COPTIC CAPITAL LETTER LAULA -2C98; C; 2C99; # COPTIC CAPITAL LETTER MI -2C9A; C; 2C9B; # COPTIC CAPITAL LETTER NI -2C9C; C; 2C9D; # COPTIC CAPITAL LETTER KSI -2C9E; C; 2C9F; # COPTIC CAPITAL LETTER O -2CA0; C; 2CA1; # COPTIC CAPITAL LETTER PI -2CA2; C; 2CA3; # COPTIC CAPITAL LETTER RO -2CA4; C; 2CA5; # COPTIC CAPITAL LETTER SIMA -2CA6; C; 2CA7; # COPTIC CAPITAL LETTER TAU -2CA8; C; 2CA9; # COPTIC CAPITAL LETTER UA -2CAA; C; 2CAB; # COPTIC CAPITAL LETTER FI -2CAC; C; 2CAD; # COPTIC CAPITAL LETTER KHI -2CAE; C; 2CAF; # COPTIC CAPITAL LETTER PSI -2CB0; C; 2CB1; # COPTIC CAPITAL LETTER OOU -2CB2; C; 2CB3; # COPTIC CAPITAL LETTER DIALECT-P ALEF -2CB4; C; 2CB5; # COPTIC CAPITAL LETTER OLD COPTIC AIN -2CB6; C; 2CB7; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE -2CB8; C; 2CB9; # COPTIC CAPITAL LETTER DIALECT-P KAPA -2CBA; C; 2CBB; # COPTIC CAPITAL LETTER DIALECT-P NI -2CBC; C; 2CBD; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI -2CBE; C; 2CBF; # COPTIC CAPITAL LETTER OLD COPTIC OOU -2CC0; C; 2CC1; # COPTIC CAPITAL LETTER SAMPI -2CC2; C; 2CC3; # COPTIC CAPITAL LETTER CROSSED SHEI -2CC4; C; 2CC5; # COPTIC CAPITAL LETTER OLD COPTIC SHEI -2CC6; C; 2CC7; # COPTIC CAPITAL LETTER OLD COPTIC ESH -2CC8; C; 2CC9; # COPTIC CAPITAL LETTER AKHMIMIC KHEI -2CCA; C; 2CCB; # COPTIC CAPITAL LETTER DIALECT-P HORI -2CCC; C; 2CCD; # COPTIC CAPITAL LETTER OLD COPTIC HORI -2CCE; C; 2CCF; # COPTIC CAPITAL LETTER OLD COPTIC HA -2CD0; C; 2CD1; # COPTIC CAPITAL LETTER L-SHAPED HA -2CD2; C; 2CD3; # COPTIC CAPITAL LETTER OLD COPTIC HEI -2CD4; C; 2CD5; # COPTIC CAPITAL LETTER OLD COPTIC HAT -2CD6; C; 2CD7; # COPTIC CAPITAL LETTER OLD COPTIC GANGIA -2CD8; C; 2CD9; # COPTIC CAPITAL LETTER OLD COPTIC DJA -2CDA; C; 2CDB; # COPTIC CAPITAL LETTER OLD COPTIC SHIMA -2CDC; C; 2CDD; # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA -2CDE; C; 2CDF; # COPTIC CAPITAL LETTER OLD NUBIAN NGI -2CE0; C; 2CE1; # COPTIC CAPITAL LETTER OLD NUBIAN NYI -2CE2; C; 2CE3; # COPTIC CAPITAL LETTER OLD NUBIAN WAU -2CEB; C; 2CEC; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI -2CED; C; 2CEE; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA -2CF2; C; 2CF3; # COPTIC CAPITAL LETTER BOHAIRIC KHEI -A640; C; A641; # CYRILLIC CAPITAL LETTER ZEMLYA -A642; C; A643; # CYRILLIC CAPITAL LETTER DZELO -A644; C; A645; # CYRILLIC CAPITAL LETTER REVERSED DZE -A646; C; A647; # CYRILLIC CAPITAL LETTER IOTA -A648; C; A649; # CYRILLIC CAPITAL LETTER DJERV -A64A; C; A64B; # CYRILLIC CAPITAL LETTER MONOGRAPH UK -A64C; C; A64D; # CYRILLIC CAPITAL LETTER BROAD OMEGA -A64E; C; A64F; # CYRILLIC CAPITAL LETTER NEUTRAL YER -A650; C; A651; # CYRILLIC CAPITAL LETTER YERU WITH BACK YER -A652; C; A653; # CYRILLIC CAPITAL LETTER IOTIFIED YAT -A654; C; A655; # CYRILLIC CAPITAL LETTER REVERSED YU -A656; C; A657; # CYRILLIC CAPITAL LETTER IOTIFIED A -A658; C; A659; # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS -A65A; C; A65B; # CYRILLIC CAPITAL LETTER BLENDED YUS -A65C; C; A65D; # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS -A65E; C; A65F; # CYRILLIC CAPITAL LETTER YN -A660; C; A661; # CYRILLIC CAPITAL LETTER REVERSED TSE -A662; C; A663; # CYRILLIC CAPITAL LETTER SOFT DE -A664; C; A665; # CYRILLIC CAPITAL LETTER SOFT EL -A666; C; A667; # CYRILLIC CAPITAL LETTER SOFT EM -A668; C; A669; # CYRILLIC CAPITAL LETTER MONOCULAR O -A66A; C; A66B; # CYRILLIC CAPITAL LETTER BINOCULAR O -A66C; C; A66D; # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O -A680; C; A681; # CYRILLIC CAPITAL LETTER DWE -A682; C; A683; # CYRILLIC CAPITAL LETTER DZWE -A684; C; A685; # CYRILLIC CAPITAL LETTER ZHWE -A686; C; A687; # CYRILLIC CAPITAL LETTER CCHE -A688; C; A689; # CYRILLIC CAPITAL LETTER DZZE -A68A; C; A68B; # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK -A68C; C; A68D; # CYRILLIC CAPITAL LETTER TWE -A68E; C; A68F; # CYRILLIC CAPITAL LETTER TSWE -A690; C; A691; # CYRILLIC CAPITAL LETTER TSSE -A692; C; A693; # CYRILLIC CAPITAL LETTER TCHE -A694; C; A695; # CYRILLIC CAPITAL LETTER HWE -A696; C; A697; # CYRILLIC CAPITAL LETTER SHWE -A698; C; A699; # CYRILLIC CAPITAL LETTER DOUBLE O -A69A; C; A69B; # CYRILLIC CAPITAL LETTER CROSSED O -A722; C; A723; # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF -A724; C; A725; # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN -A726; C; A727; # LATIN CAPITAL LETTER HENG -A728; C; A729; # LATIN CAPITAL LETTER TZ -A72A; C; A72B; # LATIN CAPITAL LETTER TRESILLO -A72C; C; A72D; # LATIN CAPITAL LETTER CUATRILLO -A72E; C; A72F; # LATIN CAPITAL LETTER CUATRILLO WITH COMMA -A732; C; A733; # LATIN CAPITAL LETTER AA -A734; C; A735; # LATIN CAPITAL LETTER AO -A736; C; A737; # LATIN CAPITAL LETTER AU -A738; C; A739; # LATIN CAPITAL LETTER AV -A73A; C; A73B; # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR -A73C; C; A73D; # LATIN CAPITAL LETTER AY -A73E; C; A73F; # LATIN CAPITAL LETTER REVERSED C WITH DOT -A740; C; A741; # LATIN CAPITAL LETTER K WITH STROKE -A742; C; A743; # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE -A744; C; A745; # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE -A746; C; A747; # LATIN CAPITAL LETTER BROKEN L -A748; C; A749; # LATIN CAPITAL LETTER L WITH HIGH STROKE -A74A; C; A74B; # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY -A74C; C; A74D; # LATIN CAPITAL LETTER O WITH LOOP -A74E; C; A74F; # LATIN CAPITAL LETTER OO -A750; C; A751; # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER -A752; C; A753; # LATIN CAPITAL LETTER P WITH FLOURISH -A754; C; A755; # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL -A756; C; A757; # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER -A758; C; A759; # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE -A75A; C; A75B; # LATIN CAPITAL LETTER R ROTUNDA -A75C; C; A75D; # LATIN CAPITAL LETTER RUM ROTUNDA -A75E; C; A75F; # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE -A760; C; A761; # LATIN CAPITAL LETTER VY -A762; C; A763; # LATIN CAPITAL LETTER VISIGOTHIC Z -A764; C; A765; # LATIN CAPITAL LETTER THORN WITH STROKE -A766; C; A767; # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER -A768; C; A769; # LATIN CAPITAL LETTER VEND -A76A; C; A76B; # LATIN CAPITAL LETTER ET -A76C; C; A76D; # LATIN CAPITAL LETTER IS -A76E; C; A76F; # LATIN CAPITAL LETTER CON -A779; C; A77A; # LATIN CAPITAL LETTER INSULAR D -A77B; C; A77C; # LATIN CAPITAL LETTER INSULAR F -A77D; C; 1D79; # LATIN CAPITAL LETTER INSULAR G -A77E; C; A77F; # LATIN CAPITAL LETTER TURNED INSULAR G -A780; C; A781; # LATIN CAPITAL LETTER TURNED L -A782; C; A783; # LATIN CAPITAL LETTER INSULAR R -A784; C; A785; # LATIN CAPITAL LETTER INSULAR S -A786; C; A787; # LATIN CAPITAL LETTER INSULAR T -A78B; C; A78C; # LATIN CAPITAL LETTER SALTILLO -A78D; C; 0265; # LATIN CAPITAL LETTER TURNED H -A790; C; A791; # LATIN CAPITAL LETTER N WITH DESCENDER -A792; C; A793; # LATIN CAPITAL LETTER C WITH BAR -A796; C; A797; # LATIN CAPITAL LETTER B WITH FLOURISH -A798; C; A799; # LATIN CAPITAL LETTER F WITH STROKE -A79A; C; A79B; # LATIN CAPITAL LETTER VOLAPUK AE -A79C; C; A79D; # LATIN CAPITAL LETTER VOLAPUK OE -A79E; C; A79F; # LATIN CAPITAL LETTER VOLAPUK UE -A7A0; C; A7A1; # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE -A7A2; C; A7A3; # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE -A7A4; C; A7A5; # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE -A7A6; C; A7A7; # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE -A7A8; C; A7A9; # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE -A7AA; C; 0266; # LATIN CAPITAL LETTER H WITH HOOK -A7AB; C; 025C; # LATIN CAPITAL LETTER REVERSED OPEN E -A7AC; C; 0261; # LATIN CAPITAL LETTER SCRIPT G -A7AD; C; 026C; # LATIN CAPITAL LETTER L WITH BELT -A7AE; C; 026A; # LATIN CAPITAL LETTER SMALL CAPITAL I -A7B0; C; 029E; # LATIN CAPITAL LETTER TURNED K -A7B1; C; 0287; # LATIN CAPITAL LETTER TURNED T -A7B2; C; 029D; # LATIN CAPITAL LETTER J WITH CROSSED-TAIL -A7B3; C; AB53; # LATIN CAPITAL LETTER CHI -A7B4; C; A7B5; # LATIN CAPITAL LETTER BETA -A7B6; C; A7B7; # LATIN CAPITAL LETTER OMEGA -A7B8; C; A7B9; # LATIN CAPITAL LETTER U WITH STROKE -A7BA; C; A7BB; # LATIN CAPITAL LETTER GLOTTAL A -A7BC; C; A7BD; # LATIN CAPITAL LETTER GLOTTAL I -A7BE; C; A7BF; # LATIN CAPITAL LETTER GLOTTAL U -A7C2; C; A7C3; # LATIN CAPITAL LETTER ANGLICANA W -A7C4; C; A794; # LATIN CAPITAL LETTER C WITH PALATAL HOOK -A7C5; C; 0282; # LATIN CAPITAL LETTER S WITH HOOK -A7C6; C; 1D8E; # LATIN CAPITAL LETTER Z WITH PALATAL HOOK -A7C7; C; A7C8; # LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY -A7C9; C; A7CA; # LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY -A7F5; C; A7F6; # LATIN CAPITAL LETTER REVERSED HALF H -AB70; C; 13A0; # CHEROKEE SMALL LETTER A -AB71; C; 13A1; # CHEROKEE SMALL LETTER E -AB72; C; 13A2; # CHEROKEE SMALL LETTER I -AB73; C; 13A3; # CHEROKEE SMALL LETTER O -AB74; C; 13A4; # CHEROKEE SMALL LETTER U -AB75; C; 13A5; # CHEROKEE SMALL LETTER V -AB76; C; 13A6; # CHEROKEE SMALL LETTER GA -AB77; C; 13A7; # CHEROKEE SMALL LETTER KA -AB78; C; 13A8; # CHEROKEE SMALL LETTER GE -AB79; C; 13A9; # CHEROKEE SMALL LETTER GI -AB7A; C; 13AA; # CHEROKEE SMALL LETTER GO -AB7B; C; 13AB; # CHEROKEE SMALL LETTER GU -AB7C; C; 13AC; # CHEROKEE SMALL LETTER GV -AB7D; C; 13AD; # CHEROKEE SMALL LETTER HA -AB7E; C; 13AE; # CHEROKEE SMALL LETTER HE -AB7F; C; 13AF; # CHEROKEE SMALL LETTER HI -AB80; C; 13B0; # CHEROKEE SMALL LETTER HO -AB81; C; 13B1; # CHEROKEE SMALL LETTER HU -AB82; C; 13B2; # CHEROKEE SMALL LETTER HV -AB83; C; 13B3; # CHEROKEE SMALL LETTER LA -AB84; C; 13B4; # CHEROKEE SMALL LETTER LE -AB85; C; 13B5; # CHEROKEE SMALL LETTER LI -AB86; C; 13B6; # CHEROKEE SMALL LETTER LO -AB87; C; 13B7; # CHEROKEE SMALL LETTER LU -AB88; C; 13B8; # CHEROKEE SMALL LETTER LV -AB89; C; 13B9; # CHEROKEE SMALL LETTER MA -AB8A; C; 13BA; # CHEROKEE SMALL LETTER ME -AB8B; C; 13BB; # CHEROKEE SMALL LETTER MI -AB8C; C; 13BC; # CHEROKEE SMALL LETTER MO -AB8D; C; 13BD; # CHEROKEE SMALL LETTER MU -AB8E; C; 13BE; # CHEROKEE SMALL LETTER NA -AB8F; C; 13BF; # CHEROKEE SMALL LETTER HNA -AB90; C; 13C0; # CHEROKEE SMALL LETTER NAH -AB91; C; 13C1; # CHEROKEE SMALL LETTER NE -AB92; C; 13C2; # CHEROKEE SMALL LETTER NI -AB93; C; 13C3; # CHEROKEE SMALL LETTER NO -AB94; C; 13C4; # CHEROKEE SMALL LETTER NU -AB95; C; 13C5; # CHEROKEE SMALL LETTER NV -AB96; C; 13C6; # CHEROKEE SMALL LETTER QUA -AB97; C; 13C7; # CHEROKEE SMALL LETTER QUE -AB98; C; 13C8; # CHEROKEE SMALL LETTER QUI -AB99; C; 13C9; # CHEROKEE SMALL LETTER QUO -AB9A; C; 13CA; # CHEROKEE SMALL LETTER QUU -AB9B; C; 13CB; # CHEROKEE SMALL LETTER QUV -AB9C; C; 13CC; # CHEROKEE SMALL LETTER SA -AB9D; C; 13CD; # CHEROKEE SMALL LETTER S -AB9E; C; 13CE; # CHEROKEE SMALL LETTER SE -AB9F; C; 13CF; # CHEROKEE SMALL LETTER SI -ABA0; C; 13D0; # CHEROKEE SMALL LETTER SO -ABA1; C; 13D1; # CHEROKEE SMALL LETTER SU -ABA2; C; 13D2; # CHEROKEE SMALL LETTER SV -ABA3; C; 13D3; # CHEROKEE SMALL LETTER DA -ABA4; C; 13D4; # CHEROKEE SMALL LETTER TA -ABA5; C; 13D5; # CHEROKEE SMALL LETTER DE -ABA6; C; 13D6; # CHEROKEE SMALL LETTER TE -ABA7; C; 13D7; # CHEROKEE SMALL LETTER DI -ABA8; C; 13D8; # CHEROKEE SMALL LETTER TI -ABA9; C; 13D9; # CHEROKEE SMALL LETTER DO -ABAA; C; 13DA; # CHEROKEE SMALL LETTER DU -ABAB; C; 13DB; # CHEROKEE SMALL LETTER DV -ABAC; C; 13DC; # CHEROKEE SMALL LETTER DLA -ABAD; C; 13DD; # CHEROKEE SMALL LETTER TLA -ABAE; C; 13DE; # CHEROKEE SMALL LETTER TLE -ABAF; C; 13DF; # CHEROKEE SMALL LETTER TLI -ABB0; C; 13E0; # CHEROKEE SMALL LETTER TLO -ABB1; C; 13E1; # CHEROKEE SMALL LETTER TLU -ABB2; C; 13E2; # CHEROKEE SMALL LETTER TLV -ABB3; C; 13E3; # CHEROKEE SMALL LETTER TSA -ABB4; C; 13E4; # CHEROKEE SMALL LETTER TSE -ABB5; C; 13E5; # CHEROKEE SMALL LETTER TSI -ABB6; C; 13E6; # CHEROKEE SMALL LETTER TSO -ABB7; C; 13E7; # CHEROKEE SMALL LETTER TSU -ABB8; C; 13E8; # CHEROKEE SMALL LETTER TSV -ABB9; C; 13E9; # CHEROKEE SMALL LETTER WA -ABBA; C; 13EA; # CHEROKEE SMALL LETTER WE -ABBB; C; 13EB; # CHEROKEE SMALL LETTER WI -ABBC; C; 13EC; # CHEROKEE SMALL LETTER WO -ABBD; C; 13ED; # CHEROKEE SMALL LETTER WU -ABBE; C; 13EE; # CHEROKEE SMALL LETTER WV -ABBF; C; 13EF; # CHEROKEE SMALL LETTER YA -FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF -FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI -FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL -FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI -FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL -FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T -FB06; F; 0073 0074; # LATIN SMALL LIGATURE ST -FB13; F; 0574 0576; # ARMENIAN SMALL LIGATURE MEN NOW -FB14; F; 0574 0565; # ARMENIAN SMALL LIGATURE MEN ECH -FB15; F; 0574 056B; # ARMENIAN SMALL LIGATURE MEN INI -FB16; F; 057E 0576; # ARMENIAN SMALL LIGATURE VEW NOW -FB17; F; 0574 056D; # ARMENIAN SMALL LIGATURE MEN XEH -FF21; C; FF41; # FULLWIDTH LATIN CAPITAL LETTER A -FF22; C; FF42; # FULLWIDTH LATIN CAPITAL LETTER B -FF23; C; FF43; # FULLWIDTH LATIN CAPITAL LETTER C -FF24; C; FF44; # FULLWIDTH LATIN CAPITAL LETTER D -FF25; C; FF45; # FULLWIDTH LATIN CAPITAL LETTER E -FF26; C; FF46; # FULLWIDTH LATIN CAPITAL LETTER F -FF27; C; FF47; # FULLWIDTH LATIN CAPITAL LETTER G -FF28; C; FF48; # FULLWIDTH LATIN CAPITAL LETTER H -FF29; C; FF49; # FULLWIDTH LATIN CAPITAL LETTER I -FF2A; C; FF4A; # FULLWIDTH LATIN CAPITAL LETTER J -FF2B; C; FF4B; # FULLWIDTH LATIN CAPITAL LETTER K -FF2C; C; FF4C; # FULLWIDTH LATIN CAPITAL LETTER L -FF2D; C; FF4D; # FULLWIDTH LATIN CAPITAL LETTER M -FF2E; C; FF4E; # FULLWIDTH LATIN CAPITAL LETTER N -FF2F; C; FF4F; # FULLWIDTH LATIN CAPITAL LETTER O -FF30; C; FF50; # FULLWIDTH LATIN CAPITAL LETTER P -FF31; C; FF51; # FULLWIDTH LATIN CAPITAL LETTER Q -FF32; C; FF52; # FULLWIDTH LATIN CAPITAL LETTER R -FF33; C; FF53; # FULLWIDTH LATIN CAPITAL LETTER S -FF34; C; FF54; # FULLWIDTH LATIN CAPITAL LETTER T -FF35; C; FF55; # FULLWIDTH LATIN CAPITAL LETTER U -FF36; C; FF56; # FULLWIDTH LATIN CAPITAL LETTER V -FF37; C; FF57; # FULLWIDTH LATIN CAPITAL LETTER W -FF38; C; FF58; # FULLWIDTH LATIN CAPITAL LETTER X -FF39; C; FF59; # FULLWIDTH LATIN CAPITAL LETTER Y -FF3A; C; FF5A; # FULLWIDTH LATIN CAPITAL LETTER Z -10400; C; 10428; # DESERET CAPITAL LETTER LONG I -10401; C; 10429; # DESERET CAPITAL LETTER LONG E -10402; C; 1042A; # DESERET CAPITAL LETTER LONG A -10403; C; 1042B; # DESERET CAPITAL LETTER LONG AH -10404; C; 1042C; # DESERET CAPITAL LETTER LONG O -10405; C; 1042D; # DESERET CAPITAL LETTER LONG OO -10406; C; 1042E; # DESERET CAPITAL LETTER SHORT I -10407; C; 1042F; # DESERET CAPITAL LETTER SHORT E -10408; C; 10430; # DESERET CAPITAL LETTER SHORT A -10409; C; 10431; # DESERET CAPITAL LETTER SHORT AH -1040A; C; 10432; # DESERET CAPITAL LETTER SHORT O -1040B; C; 10433; # DESERET CAPITAL LETTER SHORT OO -1040C; C; 10434; # DESERET CAPITAL LETTER AY -1040D; C; 10435; # DESERET CAPITAL LETTER OW -1040E; C; 10436; # DESERET CAPITAL LETTER WU -1040F; C; 10437; # DESERET CAPITAL LETTER YEE -10410; C; 10438; # DESERET CAPITAL LETTER H -10411; C; 10439; # DESERET CAPITAL LETTER PEE -10412; C; 1043A; # DESERET CAPITAL LETTER BEE -10413; C; 1043B; # DESERET CAPITAL LETTER TEE -10414; C; 1043C; # DESERET CAPITAL LETTER DEE -10415; C; 1043D; # DESERET CAPITAL LETTER CHEE -10416; C; 1043E; # DESERET CAPITAL LETTER JEE -10417; C; 1043F; # DESERET CAPITAL LETTER KAY -10418; C; 10440; # DESERET CAPITAL LETTER GAY -10419; C; 10441; # DESERET CAPITAL LETTER EF -1041A; C; 10442; # DESERET CAPITAL LETTER VEE -1041B; C; 10443; # DESERET CAPITAL LETTER ETH -1041C; C; 10444; # DESERET CAPITAL LETTER THEE -1041D; C; 10445; # DESERET CAPITAL LETTER ES -1041E; C; 10446; # DESERET CAPITAL LETTER ZEE -1041F; C; 10447; # DESERET CAPITAL LETTER ESH -10420; C; 10448; # DESERET CAPITAL LETTER ZHEE -10421; C; 10449; # DESERET CAPITAL LETTER ER -10422; C; 1044A; # DESERET CAPITAL LETTER EL -10423; C; 1044B; # DESERET CAPITAL LETTER EM -10424; C; 1044C; # DESERET CAPITAL LETTER EN -10425; C; 1044D; # DESERET CAPITAL LETTER ENG -10426; C; 1044E; # DESERET CAPITAL LETTER OI -10427; C; 1044F; # DESERET CAPITAL LETTER EW -104B0; C; 104D8; # OSAGE CAPITAL LETTER A -104B1; C; 104D9; # OSAGE CAPITAL LETTER AI -104B2; C; 104DA; # OSAGE CAPITAL LETTER AIN -104B3; C; 104DB; # OSAGE CAPITAL LETTER AH -104B4; C; 104DC; # OSAGE CAPITAL LETTER BRA -104B5; C; 104DD; # OSAGE CAPITAL LETTER CHA -104B6; C; 104DE; # OSAGE CAPITAL LETTER EHCHA -104B7; C; 104DF; # OSAGE CAPITAL LETTER E -104B8; C; 104E0; # OSAGE CAPITAL LETTER EIN -104B9; C; 104E1; # OSAGE CAPITAL LETTER HA -104BA; C; 104E2; # OSAGE CAPITAL LETTER HYA -104BB; C; 104E3; # OSAGE CAPITAL LETTER I -104BC; C; 104E4; # OSAGE CAPITAL LETTER KA -104BD; C; 104E5; # OSAGE CAPITAL LETTER EHKA -104BE; C; 104E6; # OSAGE CAPITAL LETTER KYA -104BF; C; 104E7; # OSAGE CAPITAL LETTER LA -104C0; C; 104E8; # OSAGE CAPITAL LETTER MA -104C1; C; 104E9; # OSAGE CAPITAL LETTER NA -104C2; C; 104EA; # OSAGE CAPITAL LETTER O -104C3; C; 104EB; # OSAGE CAPITAL LETTER OIN -104C4; C; 104EC; # OSAGE CAPITAL LETTER PA -104C5; C; 104ED; # OSAGE CAPITAL LETTER EHPA -104C6; C; 104EE; # OSAGE CAPITAL LETTER SA -104C7; C; 104EF; # OSAGE CAPITAL LETTER SHA -104C8; C; 104F0; # OSAGE CAPITAL LETTER TA -104C9; C; 104F1; # OSAGE CAPITAL LETTER EHTA -104CA; C; 104F2; # OSAGE CAPITAL LETTER TSA -104CB; C; 104F3; # OSAGE CAPITAL LETTER EHTSA -104CC; C; 104F4; # OSAGE CAPITAL LETTER TSHA -104CD; C; 104F5; # OSAGE CAPITAL LETTER DHA -104CE; C; 104F6; # OSAGE CAPITAL LETTER U -104CF; C; 104F7; # OSAGE CAPITAL LETTER WA -104D0; C; 104F8; # OSAGE CAPITAL LETTER KHA -104D1; C; 104F9; # OSAGE CAPITAL LETTER GHA -104D2; C; 104FA; # OSAGE CAPITAL LETTER ZA -104D3; C; 104FB; # OSAGE CAPITAL LETTER ZHA -10C80; C; 10CC0; # OLD HUNGARIAN CAPITAL LETTER A -10C81; C; 10CC1; # OLD HUNGARIAN CAPITAL LETTER AA -10C82; C; 10CC2; # OLD HUNGARIAN CAPITAL LETTER EB -10C83; C; 10CC3; # OLD HUNGARIAN CAPITAL LETTER AMB -10C84; C; 10CC4; # OLD HUNGARIAN CAPITAL LETTER EC -10C85; C; 10CC5; # OLD HUNGARIAN CAPITAL LETTER ENC -10C86; C; 10CC6; # OLD HUNGARIAN CAPITAL LETTER ECS -10C87; C; 10CC7; # OLD HUNGARIAN CAPITAL LETTER ED -10C88; C; 10CC8; # OLD HUNGARIAN CAPITAL LETTER AND -10C89; C; 10CC9; # OLD HUNGARIAN CAPITAL LETTER E -10C8A; C; 10CCA; # OLD HUNGARIAN CAPITAL LETTER CLOSE E -10C8B; C; 10CCB; # OLD HUNGARIAN CAPITAL LETTER EE -10C8C; C; 10CCC; # OLD HUNGARIAN CAPITAL LETTER EF -10C8D; C; 10CCD; # OLD HUNGARIAN CAPITAL LETTER EG -10C8E; C; 10CCE; # OLD HUNGARIAN CAPITAL LETTER EGY -10C8F; C; 10CCF; # OLD HUNGARIAN CAPITAL LETTER EH -10C90; C; 10CD0; # OLD HUNGARIAN CAPITAL LETTER I -10C91; C; 10CD1; # OLD HUNGARIAN CAPITAL LETTER II -10C92; C; 10CD2; # OLD HUNGARIAN CAPITAL LETTER EJ -10C93; C; 10CD3; # OLD HUNGARIAN CAPITAL LETTER EK -10C94; C; 10CD4; # OLD HUNGARIAN CAPITAL LETTER AK -10C95; C; 10CD5; # OLD HUNGARIAN CAPITAL LETTER UNK -10C96; C; 10CD6; # OLD HUNGARIAN CAPITAL LETTER EL -10C97; C; 10CD7; # OLD HUNGARIAN CAPITAL LETTER ELY -10C98; C; 10CD8; # OLD HUNGARIAN CAPITAL LETTER EM -10C99; C; 10CD9; # OLD HUNGARIAN CAPITAL LETTER EN -10C9A; C; 10CDA; # OLD HUNGARIAN CAPITAL LETTER ENY -10C9B; C; 10CDB; # OLD HUNGARIAN CAPITAL LETTER O -10C9C; C; 10CDC; # OLD HUNGARIAN CAPITAL LETTER OO -10C9D; C; 10CDD; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE -10C9E; C; 10CDE; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE -10C9F; C; 10CDF; # OLD HUNGARIAN CAPITAL LETTER OEE -10CA0; C; 10CE0; # OLD HUNGARIAN CAPITAL LETTER EP -10CA1; C; 10CE1; # OLD HUNGARIAN CAPITAL LETTER EMP -10CA2; C; 10CE2; # OLD HUNGARIAN CAPITAL LETTER ER -10CA3; C; 10CE3; # OLD HUNGARIAN CAPITAL LETTER SHORT ER -10CA4; C; 10CE4; # OLD HUNGARIAN CAPITAL LETTER ES -10CA5; C; 10CE5; # OLD HUNGARIAN CAPITAL LETTER ESZ -10CA6; C; 10CE6; # OLD HUNGARIAN CAPITAL LETTER ET -10CA7; C; 10CE7; # OLD HUNGARIAN CAPITAL LETTER ENT -10CA8; C; 10CE8; # OLD HUNGARIAN CAPITAL LETTER ETY -10CA9; C; 10CE9; # OLD HUNGARIAN CAPITAL LETTER ECH -10CAA; C; 10CEA; # OLD HUNGARIAN CAPITAL LETTER U -10CAB; C; 10CEB; # OLD HUNGARIAN CAPITAL LETTER UU -10CAC; C; 10CEC; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE -10CAD; C; 10CED; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE -10CAE; C; 10CEE; # OLD HUNGARIAN CAPITAL LETTER EV -10CAF; C; 10CEF; # OLD HUNGARIAN CAPITAL LETTER EZ -10CB0; C; 10CF0; # OLD HUNGARIAN CAPITAL LETTER EZS -10CB1; C; 10CF1; # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN -10CB2; C; 10CF2; # OLD HUNGARIAN CAPITAL LETTER US -118A0; C; 118C0; # WARANG CITI CAPITAL LETTER NGAA -118A1; C; 118C1; # WARANG CITI CAPITAL LETTER A -118A2; C; 118C2; # WARANG CITI CAPITAL LETTER WI -118A3; C; 118C3; # WARANG CITI CAPITAL LETTER YU -118A4; C; 118C4; # WARANG CITI CAPITAL LETTER YA -118A5; C; 118C5; # WARANG CITI CAPITAL LETTER YO -118A6; C; 118C6; # WARANG CITI CAPITAL LETTER II -118A7; C; 118C7; # WARANG CITI CAPITAL LETTER UU -118A8; C; 118C8; # WARANG CITI CAPITAL LETTER E -118A9; C; 118C9; # WARANG CITI CAPITAL LETTER O -118AA; C; 118CA; # WARANG CITI CAPITAL LETTER ANG -118AB; C; 118CB; # WARANG CITI CAPITAL LETTER GA -118AC; C; 118CC; # WARANG CITI CAPITAL LETTER KO -118AD; C; 118CD; # WARANG CITI CAPITAL LETTER ENY -118AE; C; 118CE; # WARANG CITI CAPITAL LETTER YUJ -118AF; C; 118CF; # WARANG CITI CAPITAL LETTER UC -118B0; C; 118D0; # WARANG CITI CAPITAL LETTER ENN -118B1; C; 118D1; # WARANG CITI CAPITAL LETTER ODD -118B2; C; 118D2; # WARANG CITI CAPITAL LETTER TTE -118B3; C; 118D3; # WARANG CITI CAPITAL LETTER NUNG -118B4; C; 118D4; # WARANG CITI CAPITAL LETTER DA -118B5; C; 118D5; # WARANG CITI CAPITAL LETTER AT -118B6; C; 118D6; # WARANG CITI CAPITAL LETTER AM -118B7; C; 118D7; # WARANG CITI CAPITAL LETTER BU -118B8; C; 118D8; # WARANG CITI CAPITAL LETTER PU -118B9; C; 118D9; # WARANG CITI CAPITAL LETTER HIYO -118BA; C; 118DA; # WARANG CITI CAPITAL LETTER HOLO -118BB; C; 118DB; # WARANG CITI CAPITAL LETTER HORR -118BC; C; 118DC; # WARANG CITI CAPITAL LETTER HAR -118BD; C; 118DD; # WARANG CITI CAPITAL LETTER SSUU -118BE; C; 118DE; # WARANG CITI CAPITAL LETTER SII -118BF; C; 118DF; # WARANG CITI CAPITAL LETTER VIYO -16E40; C; 16E60; # MEDEFAIDRIN CAPITAL LETTER M -16E41; C; 16E61; # MEDEFAIDRIN CAPITAL LETTER S -16E42; C; 16E62; # MEDEFAIDRIN CAPITAL LETTER V -16E43; C; 16E63; # MEDEFAIDRIN CAPITAL LETTER W -16E44; C; 16E64; # MEDEFAIDRIN CAPITAL LETTER ATIU -16E45; C; 16E65; # MEDEFAIDRIN CAPITAL LETTER Z -16E46; C; 16E66; # MEDEFAIDRIN CAPITAL LETTER KP -16E47; C; 16E67; # MEDEFAIDRIN CAPITAL LETTER P -16E48; C; 16E68; # MEDEFAIDRIN CAPITAL LETTER T -16E49; C; 16E69; # MEDEFAIDRIN CAPITAL LETTER G -16E4A; C; 16E6A; # MEDEFAIDRIN CAPITAL LETTER F -16E4B; C; 16E6B; # MEDEFAIDRIN CAPITAL LETTER I -16E4C; C; 16E6C; # MEDEFAIDRIN CAPITAL LETTER K -16E4D; C; 16E6D; # MEDEFAIDRIN CAPITAL LETTER A -16E4E; C; 16E6E; # MEDEFAIDRIN CAPITAL LETTER J -16E4F; C; 16E6F; # MEDEFAIDRIN CAPITAL LETTER E -16E50; C; 16E70; # MEDEFAIDRIN CAPITAL LETTER B -16E51; C; 16E71; # MEDEFAIDRIN CAPITAL LETTER C -16E52; C; 16E72; # MEDEFAIDRIN CAPITAL LETTER U -16E53; C; 16E73; # MEDEFAIDRIN CAPITAL LETTER YU -16E54; C; 16E74; # MEDEFAIDRIN CAPITAL LETTER L -16E55; C; 16E75; # MEDEFAIDRIN CAPITAL LETTER Q -16E56; C; 16E76; # MEDEFAIDRIN CAPITAL LETTER HP -16E57; C; 16E77; # MEDEFAIDRIN CAPITAL LETTER NY -16E58; C; 16E78; # MEDEFAIDRIN CAPITAL LETTER X -16E59; C; 16E79; # MEDEFAIDRIN CAPITAL LETTER D -16E5A; C; 16E7A; # MEDEFAIDRIN CAPITAL LETTER OE -16E5B; C; 16E7B; # MEDEFAIDRIN CAPITAL LETTER N -16E5C; C; 16E7C; # MEDEFAIDRIN CAPITAL LETTER R -16E5D; C; 16E7D; # MEDEFAIDRIN CAPITAL LETTER O -16E5E; C; 16E7E; # MEDEFAIDRIN CAPITAL LETTER AI -16E5F; C; 16E7F; # MEDEFAIDRIN CAPITAL LETTER Y -1E900; C; 1E922; # ADLAM CAPITAL LETTER ALIF -1E901; C; 1E923; # ADLAM CAPITAL LETTER DAALI -1E902; C; 1E924; # ADLAM CAPITAL LETTER LAAM -1E903; C; 1E925; # ADLAM CAPITAL LETTER MIIM -1E904; C; 1E926; # ADLAM CAPITAL LETTER BA -1E905; C; 1E927; # ADLAM CAPITAL LETTER SINNYIIYHE -1E906; C; 1E928; # ADLAM CAPITAL LETTER PE -1E907; C; 1E929; # ADLAM CAPITAL LETTER BHE -1E908; C; 1E92A; # ADLAM CAPITAL LETTER RA -1E909; C; 1E92B; # ADLAM CAPITAL LETTER E -1E90A; C; 1E92C; # ADLAM CAPITAL LETTER FA -1E90B; C; 1E92D; # ADLAM CAPITAL LETTER I -1E90C; C; 1E92E; # ADLAM CAPITAL LETTER O -1E90D; C; 1E92F; # ADLAM CAPITAL LETTER DHA -1E90E; C; 1E930; # ADLAM CAPITAL LETTER YHE -1E90F; C; 1E931; # ADLAM CAPITAL LETTER WAW -1E910; C; 1E932; # ADLAM CAPITAL LETTER NUN -1E911; C; 1E933; # ADLAM CAPITAL LETTER KAF -1E912; C; 1E934; # ADLAM CAPITAL LETTER YA -1E913; C; 1E935; # ADLAM CAPITAL LETTER U -1E914; C; 1E936; # ADLAM CAPITAL LETTER JIIM -1E915; C; 1E937; # ADLAM CAPITAL LETTER CHI -1E916; C; 1E938; # ADLAM CAPITAL LETTER HA -1E917; C; 1E939; # ADLAM CAPITAL LETTER QAAF -1E918; C; 1E93A; # ADLAM CAPITAL LETTER GA -1E919; C; 1E93B; # ADLAM CAPITAL LETTER NYA -1E91A; C; 1E93C; # ADLAM CAPITAL LETTER TU -1E91B; C; 1E93D; # ADLAM CAPITAL LETTER NHA -1E91C; C; 1E93E; # ADLAM CAPITAL LETTER VA -1E91D; C; 1E93F; # ADLAM CAPITAL LETTER KHA -1E91E; C; 1E940; # ADLAM CAPITAL LETTER GBE -1E91F; C; 1E941; # ADLAM CAPITAL LETTER ZAL -1E920; C; 1E942; # ADLAM CAPITAL LETTER KPO -1E921; C; 1E943; # ADLAM CAPITAL LETTER SHA -# -# EOF diff --git a/claimtrie/normalization/NFC_v11.txt b/claimtrie/normalization/NFC_v11.txt new file mode 100644 index 00000000..de6bdd91 --- /dev/null +++ b/claimtrie/normalization/NFC_v11.txt @@ -0,0 +1,2431 @@ +# Copyright (C) 2016 and later: Unicode, Inc. and others. +# License & terms of use: http://www.unicode.org/copyright.html +# Copyright (C) 1999-2016, International Business Machines +# Corporation and others. All Rights Reserved. +# +# file name: nfc.txt +# +# machine-generated by ICU preparseucd.py +# +# Complete data for Unicode NFC normalization. + +* Unicode 11.0.0 + +# Canonical_Combining_Class (ccc) values +0300..0314:230 +0315:232 +0316..0319:220 +031A:232 +031B:216 +031C..0320:220 +0321..0322:202 +0323..0326:220 +0327..0328:202 +0329..0333:220 +0334..0338:1 +0339..033C:220 +033D..0344:230 +0345:240 +0346:230 +0347..0349:220 +034A..034C:230 +034D..034E:220 +0350..0352:230 +0353..0356:220 +0357:230 +0358:232 +0359..035A:220 +035B:230 +035C:233 +035D..035E:234 +035F:233 +0360..0361:234 +0362:233 +0363..036F:230 +0483..0487:230 +0591:220 +0592..0595:230 +0596:220 +0597..0599:230 +059A:222 +059B:220 +059C..05A1:230 +05A2..05A7:220 +05A8..05A9:230 +05AA:220 +05AB..05AC:230 +05AD:222 +05AE:228 +05AF:230 +05B0:10 +05B1:11 +05B2:12 +05B3:13 +05B4:14 +05B5:15 +05B6:16 +05B7:17 +05B8:18 +05B9..05BA:19 +05BB:20 +05BC:21 +05BD:22 +05BF:23 +05C1:24 +05C2:25 +05C4:230 +05C5:220 +05C7:18 +0610..0617:230 +0618:30 +0619:31 +061A:32 +064B:27 +064C:28 +064D:29 +064E:30 +064F:31 +0650:32 +0651:33 +0652:34 +0653..0654:230 +0655..0656:220 +0657..065B:230 +065C:220 +065D..065E:230 +065F:220 +0670:35 +06D6..06DC:230 +06DF..06E2:230 +06E3:220 +06E4:230 +06E7..06E8:230 +06EA:220 +06EB..06EC:230 +06ED:220 +0711:36 +0730:230 +0731:220 +0732..0733:230 +0734:220 +0735..0736:230 +0737..0739:220 +073A:230 +073B..073C:220 +073D:230 +073E:220 +073F..0741:230 +0742:220 +0743:230 +0744:220 +0745:230 +0746:220 +0747:230 +0748:220 +0749..074A:230 +07EB..07F1:230 +07F2:220 +07F3:230 +07FD:220 +0816..0819:230 +081B..0823:230 +0825..0827:230 +0829..082D:230 +0859..085B:220 +08D3:220 +08D4..08E1:230 +08E3:220 +08E4..08E5:230 +08E6:220 +08E7..08E8:230 +08E9:220 +08EA..08EC:230 +08ED..08EF:220 +08F0:27 +08F1:28 +08F2:29 +08F3..08F5:230 +08F6:220 +08F7..08F8:230 +08F9..08FA:220 +08FB..08FF:230 +093C:7 +094D:9 +0951:230 +0952:220 +0953..0954:230 +09BC:7 +09CD:9 +09FE:230 +0A3C:7 +0A4D:9 +0ABC:7 +0ACD:9 +0B3C:7 +0B4D:9 +0BCD:9 +0C4D:9 +0C55:84 +0C56:91 +0CBC:7 +0CCD:9 +0D3B..0D3C:9 +0D4D:9 +0DCA:9 +0E38..0E39:103 +0E3A:9 +0E48..0E4B:107 +0EB8..0EB9:118 +0EC8..0ECB:122 +0F18..0F19:220 +0F35:220 +0F37:220 +0F39:216 +0F71:129 +0F72:130 +0F74:132 +0F7A..0F7D:130 +0F80:130 +0F82..0F83:230 +0F84:9 +0F86..0F87:230 +0FC6:220 +1037:7 +1039..103A:9 +108D:220 +135D..135F:230 +1714:9 +1734:9 +17D2:9 +17DD:230 +18A9:228 +1939:222 +193A:230 +193B:220 +1A17:230 +1A18:220 +1A60:9 +1A75..1A7C:230 +1A7F:220 +1AB0..1AB4:230 +1AB5..1ABA:220 +1ABB..1ABC:230 +1ABD:220 +1B34:7 +1B44:9 +1B6B:230 +1B6C:220 +1B6D..1B73:230 +1BAA..1BAB:9 +1BE6:7 +1BF2..1BF3:9 +1C37:7 +1CD0..1CD2:230 +1CD4:1 +1CD5..1CD9:220 +1CDA..1CDB:230 +1CDC..1CDF:220 +1CE0:230 +1CE2..1CE8:1 +1CED:220 +1CF4:230 +1CF8..1CF9:230 +1DC0..1DC1:230 +1DC2:220 +1DC3..1DC9:230 +1DCA:220 +1DCB..1DCC:230 +1DCD:234 +1DCE:214 +1DCF:220 +1DD0:202 +1DD1..1DF5:230 +1DF6:232 +1DF7..1DF8:228 +1DF9:220 +1DFB:230 +1DFC:233 +1DFD:220 +1DFE:230 +1DFF:220 +20D0..20D1:230 +20D2..20D3:1 +20D4..20D7:230 +20D8..20DA:1 +20DB..20DC:230 +20E1:230 +20E5..20E6:1 +20E7:230 +20E8:220 +20E9:230 +20EA..20EB:1 +20EC..20EF:220 +20F0:230 +2CEF..2CF1:230 +2D7F:9 +2DE0..2DFF:230 +302A:218 +302B:228 +302C:232 +302D:222 +302E..302F:224 +3099..309A:8 +A66F:230 +A674..A67D:230 +A69E..A69F:230 +A6F0..A6F1:230 +A806:9 +A8C4:9 +A8E0..A8F1:230 +A92B..A92D:220 +A953:9 +A9B3:7 +A9C0:9 +AAB0:230 +AAB2..AAB3:230 +AAB4:220 +AAB7..AAB8:230 +AABE..AABF:230 +AAC1:230 +AAF6:9 +ABED:9 +FB1E:26 +FE20..FE26:230 +FE27..FE2D:220 +FE2E..FE2F:230 +101FD:220 +102E0:220 +10376..1037A:230 +10A0D:220 +10A0F:230 +10A38:230 +10A39:1 +10A3A:220 +10A3F:9 +10AE5:230 +10AE6:220 +10D24..10D27:230 +10F46..10F47:220 +10F48..10F4A:230 +10F4B:220 +10F4C:230 +10F4D..10F50:220 +11046:9 +1107F:9 +110B9:9 +110BA:7 +11100..11102:230 +11133..11134:9 +11173:7 +111C0:9 +111CA:7 +11235:9 +11236:7 +112E9:7 +112EA:9 +1133B..1133C:7 +1134D:9 +11366..1136C:230 +11370..11374:230 +11442:9 +11446:7 +1145E:230 +114C2:9 +114C3:7 +115BF:9 +115C0:7 +1163F:9 +116B6:9 +116B7:7 +1172B:9 +11839:9 +1183A:7 +11A34:9 +11A47:9 +11A99:9 +11C3F:9 +11D42:7 +11D44..11D45:9 +11D97:9 +16AF0..16AF4:1 +16B30..16B36:230 +1BC9E:1 +1D165..1D166:216 +1D167..1D169:1 +1D16D:226 +1D16E..1D172:216 +1D17B..1D182:220 +1D185..1D189:230 +1D18A..1D18B:220 +1D1AA..1D1AD:230 +1D242..1D244:230 +1E000..1E006:230 +1E008..1E018:230 +1E01B..1E021:230 +1E023..1E024:230 +1E026..1E02A:230 +1E8D0..1E8D6:220 +1E944..1E949:230 +1E94A:7 + +# Canonical decomposition mappings +00C0=0041 0300 +00C1=0041 0301 +00C2=0041 0302 +00C3=0041 0303 +00C4=0041 0308 +00C5=0041 030A +00C7=0043 0327 +00C8=0045 0300 +00C9=0045 0301 +00CA=0045 0302 +00CB=0045 0308 +00CC=0049 0300 +00CD=0049 0301 +00CE=0049 0302 +00CF=0049 0308 +00D1=004E 0303 +00D2=004F 0300 +00D3=004F 0301 +00D4=004F 0302 +00D5=004F 0303 +00D6=004F 0308 +00D9=0055 0300 +00DA=0055 0301 +00DB=0055 0302 +00DC=0055 0308 +00DD=0059 0301 +00E0=0061 0300 +00E1=0061 0301 +00E2=0061 0302 +00E3=0061 0303 +00E4=0061 0308 +00E5=0061 030A +00E7=0063 0327 +00E8=0065 0300 +00E9=0065 0301 +00EA=0065 0302 +00EB=0065 0308 +00EC=0069 0300 +00ED=0069 0301 +00EE=0069 0302 +00EF=0069 0308 +00F1=006E 0303 +00F2=006F 0300 +00F3=006F 0301 +00F4=006F 0302 +00F5=006F 0303 +00F6=006F 0308 +00F9=0075 0300 +00FA=0075 0301 +00FB=0075 0302 +00FC=0075 0308 +00FD=0079 0301 +00FF=0079 0308 +0100=0041 0304 +0101=0061 0304 +0102=0041 0306 +0103=0061 0306 +0104=0041 0328 +0105=0061 0328 +0106=0043 0301 +0107=0063 0301 +0108=0043 0302 +0109=0063 0302 +010A=0043 0307 +010B=0063 0307 +010C=0043 030C +010D=0063 030C +010E=0044 030C +010F=0064 030C +0112=0045 0304 +0113=0065 0304 +0114=0045 0306 +0115=0065 0306 +0116=0045 0307 +0117=0065 0307 +0118=0045 0328 +0119=0065 0328 +011A=0045 030C +011B=0065 030C +011C=0047 0302 +011D=0067 0302 +011E=0047 0306 +011F=0067 0306 +0120=0047 0307 +0121=0067 0307 +0122=0047 0327 +0123=0067 0327 +0124=0048 0302 +0125=0068 0302 +0128=0049 0303 +0129=0069 0303 +012A=0049 0304 +012B=0069 0304 +012C=0049 0306 +012D=0069 0306 +012E=0049 0328 +012F=0069 0328 +0130=0049 0307 +0134=004A 0302 +0135=006A 0302 +0136=004B 0327 +0137=006B 0327 +0139=004C 0301 +013A=006C 0301 +013B=004C 0327 +013C=006C 0327 +013D=004C 030C +013E=006C 030C +0143=004E 0301 +0144=006E 0301 +0145=004E 0327 +0146=006E 0327 +0147=004E 030C +0148=006E 030C +014C=004F 0304 +014D=006F 0304 +014E=004F 0306 +014F=006F 0306 +0150=004F 030B +0151=006F 030B +0154=0052 0301 +0155=0072 0301 +0156=0052 0327 +0157=0072 0327 +0158=0052 030C +0159=0072 030C +015A=0053 0301 +015B=0073 0301 +015C=0053 0302 +015D=0073 0302 +015E=0053 0327 +015F=0073 0327 +0160=0053 030C +0161=0073 030C +0162=0054 0327 +0163=0074 0327 +0164=0054 030C +0165=0074 030C +0168=0055 0303 +0169=0075 0303 +016A=0055 0304 +016B=0075 0304 +016C=0055 0306 +016D=0075 0306 +016E=0055 030A +016F=0075 030A +0170=0055 030B +0171=0075 030B +0172=0055 0328 +0173=0075 0328 +0174=0057 0302 +0175=0077 0302 +0176=0059 0302 +0177=0079 0302 +0178=0059 0308 +0179=005A 0301 +017A=007A 0301 +017B=005A 0307 +017C=007A 0307 +017D=005A 030C +017E=007A 030C +01A0=004F 031B +01A1=006F 031B +01AF=0055 031B +01B0=0075 031B +01CD=0041 030C +01CE=0061 030C +01CF=0049 030C +01D0=0069 030C +01D1=004F 030C +01D2=006F 030C +01D3=0055 030C +01D4=0075 030C +01D5=00DC 0304 +01D6=00FC 0304 +01D7=00DC 0301 +01D8=00FC 0301 +01D9=00DC 030C +01DA=00FC 030C +01DB=00DC 0300 +01DC=00FC 0300 +01DE=00C4 0304 +01DF=00E4 0304 +01E0=0226 0304 +01E1=0227 0304 +01E2=00C6 0304 +01E3=00E6 0304 +01E6=0047 030C +01E7=0067 030C +01E8=004B 030C +01E9=006B 030C +01EA=004F 0328 +01EB=006F 0328 +01EC=01EA 0304 +01ED=01EB 0304 +01EE=01B7 030C +01EF=0292 030C +01F0=006A 030C +01F4=0047 0301 +01F5=0067 0301 +01F8=004E 0300 +01F9=006E 0300 +01FA=00C5 0301 +01FB=00E5 0301 +01FC=00C6 0301 +01FD=00E6 0301 +01FE=00D8 0301 +01FF=00F8 0301 +0200=0041 030F +0201=0061 030F +0202=0041 0311 +0203=0061 0311 +0204=0045 030F +0205=0065 030F +0206=0045 0311 +0207=0065 0311 +0208=0049 030F +0209=0069 030F +020A=0049 0311 +020B=0069 0311 +020C=004F 030F +020D=006F 030F +020E=004F 0311 +020F=006F 0311 +0210=0052 030F +0211=0072 030F +0212=0052 0311 +0213=0072 0311 +0214=0055 030F +0215=0075 030F +0216=0055 0311 +0217=0075 0311 +0218=0053 0326 +0219=0073 0326 +021A=0054 0326 +021B=0074 0326 +021E=0048 030C +021F=0068 030C +0226=0041 0307 +0227=0061 0307 +0228=0045 0327 +0229=0065 0327 +022A=00D6 0304 +022B=00F6 0304 +022C=00D5 0304 +022D=00F5 0304 +022E=004F 0307 +022F=006F 0307 +0230=022E 0304 +0231=022F 0304 +0232=0059 0304 +0233=0079 0304 +0340>0300 +0341>0301 +0343>0313 +0344>0308 0301 +0374>02B9 +037E>003B +0385=00A8 0301 +0386=0391 0301 +0387>00B7 +0388=0395 0301 +0389=0397 0301 +038A=0399 0301 +038C=039F 0301 +038E=03A5 0301 +038F=03A9 0301 +0390=03CA 0301 +03AA=0399 0308 +03AB=03A5 0308 +03AC=03B1 0301 +03AD=03B5 0301 +03AE=03B7 0301 +03AF=03B9 0301 +03B0=03CB 0301 +03CA=03B9 0308 +03CB=03C5 0308 +03CC=03BF 0301 +03CD=03C5 0301 +03CE=03C9 0301 +03D3=03D2 0301 +03D4=03D2 0308 +0400=0415 0300 +0401=0415 0308 +0403=0413 0301 +0407=0406 0308 +040C=041A 0301 +040D=0418 0300 +040E=0423 0306 +0419=0418 0306 +0439=0438 0306 +0450=0435 0300 +0451=0435 0308 +0453=0433 0301 +0457=0456 0308 +045C=043A 0301 +045D=0438 0300 +045E=0443 0306 +0476=0474 030F +0477=0475 030F +04C1=0416 0306 +04C2=0436 0306 +04D0=0410 0306 +04D1=0430 0306 +04D2=0410 0308 +04D3=0430 0308 +04D6=0415 0306 +04D7=0435 0306 +04DA=04D8 0308 +04DB=04D9 0308 +04DC=0416 0308 +04DD=0436 0308 +04DE=0417 0308 +04DF=0437 0308 +04E2=0418 0304 +04E3=0438 0304 +04E4=0418 0308 +04E5=0438 0308 +04E6=041E 0308 +04E7=043E 0308 +04EA=04E8 0308 +04EB=04E9 0308 +04EC=042D 0308 +04ED=044D 0308 +04EE=0423 0304 +04EF=0443 0304 +04F0=0423 0308 +04F1=0443 0308 +04F2=0423 030B +04F3=0443 030B +04F4=0427 0308 +04F5=0447 0308 +04F8=042B 0308 +04F9=044B 0308 +0622=0627 0653 +0623=0627 0654 +0624=0648 0654 +0625=0627 0655 +0626=064A 0654 +06C0=06D5 0654 +06C2=06C1 0654 +06D3=06D2 0654 +0929=0928 093C +0931=0930 093C +0934=0933 093C +0958>0915 093C +0959>0916 093C +095A>0917 093C +095B>091C 093C +095C>0921 093C +095D>0922 093C +095E>092B 093C +095F>092F 093C +09CB=09C7 09BE +09CC=09C7 09D7 +09DC>09A1 09BC +09DD>09A2 09BC +09DF>09AF 09BC +0A33>0A32 0A3C +0A36>0A38 0A3C +0A59>0A16 0A3C +0A5A>0A17 0A3C +0A5B>0A1C 0A3C +0A5E>0A2B 0A3C +0B48=0B47 0B56 +0B4B=0B47 0B3E +0B4C=0B47 0B57 +0B5C>0B21 0B3C +0B5D>0B22 0B3C +0B94=0B92 0BD7 +0BCA=0BC6 0BBE +0BCB=0BC7 0BBE +0BCC=0BC6 0BD7 +0C48=0C46 0C56 +0CC0=0CBF 0CD5 +0CC7=0CC6 0CD5 +0CC8=0CC6 0CD6 +0CCA=0CC6 0CC2 +0CCB=0CCA 0CD5 +0D4A=0D46 0D3E +0D4B=0D47 0D3E +0D4C=0D46 0D57 +0DDA=0DD9 0DCA +0DDC=0DD9 0DCF +0DDD=0DDC 0DCA +0DDE=0DD9 0DDF +0F43>0F42 0FB7 +0F4D>0F4C 0FB7 +0F52>0F51 0FB7 +0F57>0F56 0FB7 +0F5C>0F5B 0FB7 +0F69>0F40 0FB5 +0F73>0F71 0F72 +0F75>0F71 0F74 +0F76>0FB2 0F80 +0F78>0FB3 0F80 +0F81>0F71 0F80 +0F93>0F92 0FB7 +0F9D>0F9C 0FB7 +0FA2>0FA1 0FB7 +0FA7>0FA6 0FB7 +0FAC>0FAB 0FB7 +0FB9>0F90 0FB5 +1026=1025 102E +1B06=1B05 1B35 +1B08=1B07 1B35 +1B0A=1B09 1B35 +1B0C=1B0B 1B35 +1B0E=1B0D 1B35 +1B12=1B11 1B35 +1B3B=1B3A 1B35 +1B3D=1B3C 1B35 +1B40=1B3E 1B35 +1B41=1B3F 1B35 +1B43=1B42 1B35 +1E00=0041 0325 +1E01=0061 0325 +1E02=0042 0307 +1E03=0062 0307 +1E04=0042 0323 +1E05=0062 0323 +1E06=0042 0331 +1E07=0062 0331 +1E08=00C7 0301 +1E09=00E7 0301 +1E0A=0044 0307 +1E0B=0064 0307 +1E0C=0044 0323 +1E0D=0064 0323 +1E0E=0044 0331 +1E0F=0064 0331 +1E10=0044 0327 +1E11=0064 0327 +1E12=0044 032D +1E13=0064 032D +1E14=0112 0300 +1E15=0113 0300 +1E16=0112 0301 +1E17=0113 0301 +1E18=0045 032D +1E19=0065 032D +1E1A=0045 0330 +1E1B=0065 0330 +1E1C=0228 0306 +1E1D=0229 0306 +1E1E=0046 0307 +1E1F=0066 0307 +1E20=0047 0304 +1E21=0067 0304 +1E22=0048 0307 +1E23=0068 0307 +1E24=0048 0323 +1E25=0068 0323 +1E26=0048 0308 +1E27=0068 0308 +1E28=0048 0327 +1E29=0068 0327 +1E2A=0048 032E +1E2B=0068 032E +1E2C=0049 0330 +1E2D=0069 0330 +1E2E=00CF 0301 +1E2F=00EF 0301 +1E30=004B 0301 +1E31=006B 0301 +1E32=004B 0323 +1E33=006B 0323 +1E34=004B 0331 +1E35=006B 0331 +1E36=004C 0323 +1E37=006C 0323 +1E38=1E36 0304 +1E39=1E37 0304 +1E3A=004C 0331 +1E3B=006C 0331 +1E3C=004C 032D +1E3D=006C 032D +1E3E=004D 0301 +1E3F=006D 0301 +1E40=004D 0307 +1E41=006D 0307 +1E42=004D 0323 +1E43=006D 0323 +1E44=004E 0307 +1E45=006E 0307 +1E46=004E 0323 +1E47=006E 0323 +1E48=004E 0331 +1E49=006E 0331 +1E4A=004E 032D +1E4B=006E 032D +1E4C=00D5 0301 +1E4D=00F5 0301 +1E4E=00D5 0308 +1E4F=00F5 0308 +1E50=014C 0300 +1E51=014D 0300 +1E52=014C 0301 +1E53=014D 0301 +1E54=0050 0301 +1E55=0070 0301 +1E56=0050 0307 +1E57=0070 0307 +1E58=0052 0307 +1E59=0072 0307 +1E5A=0052 0323 +1E5B=0072 0323 +1E5C=1E5A 0304 +1E5D=1E5B 0304 +1E5E=0052 0331 +1E5F=0072 0331 +1E60=0053 0307 +1E61=0073 0307 +1E62=0053 0323 +1E63=0073 0323 +1E64=015A 0307 +1E65=015B 0307 +1E66=0160 0307 +1E67=0161 0307 +1E68=1E62 0307 +1E69=1E63 0307 +1E6A=0054 0307 +1E6B=0074 0307 +1E6C=0054 0323 +1E6D=0074 0323 +1E6E=0054 0331 +1E6F=0074 0331 +1E70=0054 032D +1E71=0074 032D +1E72=0055 0324 +1E73=0075 0324 +1E74=0055 0330 +1E75=0075 0330 +1E76=0055 032D +1E77=0075 032D +1E78=0168 0301 +1E79=0169 0301 +1E7A=016A 0308 +1E7B=016B 0308 +1E7C=0056 0303 +1E7D=0076 0303 +1E7E=0056 0323 +1E7F=0076 0323 +1E80=0057 0300 +1E81=0077 0300 +1E82=0057 0301 +1E83=0077 0301 +1E84=0057 0308 +1E85=0077 0308 +1E86=0057 0307 +1E87=0077 0307 +1E88=0057 0323 +1E89=0077 0323 +1E8A=0058 0307 +1E8B=0078 0307 +1E8C=0058 0308 +1E8D=0078 0308 +1E8E=0059 0307 +1E8F=0079 0307 +1E90=005A 0302 +1E91=007A 0302 +1E92=005A 0323 +1E93=007A 0323 +1E94=005A 0331 +1E95=007A 0331 +1E96=0068 0331 +1E97=0074 0308 +1E98=0077 030A +1E99=0079 030A +1E9B=017F 0307 +1EA0=0041 0323 +1EA1=0061 0323 +1EA2=0041 0309 +1EA3=0061 0309 +1EA4=00C2 0301 +1EA5=00E2 0301 +1EA6=00C2 0300 +1EA7=00E2 0300 +1EA8=00C2 0309 +1EA9=00E2 0309 +1EAA=00C2 0303 +1EAB=00E2 0303 +1EAC=1EA0 0302 +1EAD=1EA1 0302 +1EAE=0102 0301 +1EAF=0103 0301 +1EB0=0102 0300 +1EB1=0103 0300 +1EB2=0102 0309 +1EB3=0103 0309 +1EB4=0102 0303 +1EB5=0103 0303 +1EB6=1EA0 0306 +1EB7=1EA1 0306 +1EB8=0045 0323 +1EB9=0065 0323 +1EBA=0045 0309 +1EBB=0065 0309 +1EBC=0045 0303 +1EBD=0065 0303 +1EBE=00CA 0301 +1EBF=00EA 0301 +1EC0=00CA 0300 +1EC1=00EA 0300 +1EC2=00CA 0309 +1EC3=00EA 0309 +1EC4=00CA 0303 +1EC5=00EA 0303 +1EC6=1EB8 0302 +1EC7=1EB9 0302 +1EC8=0049 0309 +1EC9=0069 0309 +1ECA=0049 0323 +1ECB=0069 0323 +1ECC=004F 0323 +1ECD=006F 0323 +1ECE=004F 0309 +1ECF=006F 0309 +1ED0=00D4 0301 +1ED1=00F4 0301 +1ED2=00D4 0300 +1ED3=00F4 0300 +1ED4=00D4 0309 +1ED5=00F4 0309 +1ED6=00D4 0303 +1ED7=00F4 0303 +1ED8=1ECC 0302 +1ED9=1ECD 0302 +1EDA=01A0 0301 +1EDB=01A1 0301 +1EDC=01A0 0300 +1EDD=01A1 0300 +1EDE=01A0 0309 +1EDF=01A1 0309 +1EE0=01A0 0303 +1EE1=01A1 0303 +1EE2=01A0 0323 +1EE3=01A1 0323 +1EE4=0055 0323 +1EE5=0075 0323 +1EE6=0055 0309 +1EE7=0075 0309 +1EE8=01AF 0301 +1EE9=01B0 0301 +1EEA=01AF 0300 +1EEB=01B0 0300 +1EEC=01AF 0309 +1EED=01B0 0309 +1EEE=01AF 0303 +1EEF=01B0 0303 +1EF0=01AF 0323 +1EF1=01B0 0323 +1EF2=0059 0300 +1EF3=0079 0300 +1EF4=0059 0323 +1EF5=0079 0323 +1EF6=0059 0309 +1EF7=0079 0309 +1EF8=0059 0303 +1EF9=0079 0303 +1F00=03B1 0313 +1F01=03B1 0314 +1F02=1F00 0300 +1F03=1F01 0300 +1F04=1F00 0301 +1F05=1F01 0301 +1F06=1F00 0342 +1F07=1F01 0342 +1F08=0391 0313 +1F09=0391 0314 +1F0A=1F08 0300 +1F0B=1F09 0300 +1F0C=1F08 0301 +1F0D=1F09 0301 +1F0E=1F08 0342 +1F0F=1F09 0342 +1F10=03B5 0313 +1F11=03B5 0314 +1F12=1F10 0300 +1F13=1F11 0300 +1F14=1F10 0301 +1F15=1F11 0301 +1F18=0395 0313 +1F19=0395 0314 +1F1A=1F18 0300 +1F1B=1F19 0300 +1F1C=1F18 0301 +1F1D=1F19 0301 +1F20=03B7 0313 +1F21=03B7 0314 +1F22=1F20 0300 +1F23=1F21 0300 +1F24=1F20 0301 +1F25=1F21 0301 +1F26=1F20 0342 +1F27=1F21 0342 +1F28=0397 0313 +1F29=0397 0314 +1F2A=1F28 0300 +1F2B=1F29 0300 +1F2C=1F28 0301 +1F2D=1F29 0301 +1F2E=1F28 0342 +1F2F=1F29 0342 +1F30=03B9 0313 +1F31=03B9 0314 +1F32=1F30 0300 +1F33=1F31 0300 +1F34=1F30 0301 +1F35=1F31 0301 +1F36=1F30 0342 +1F37=1F31 0342 +1F38=0399 0313 +1F39=0399 0314 +1F3A=1F38 0300 +1F3B=1F39 0300 +1F3C=1F38 0301 +1F3D=1F39 0301 +1F3E=1F38 0342 +1F3F=1F39 0342 +1F40=03BF 0313 +1F41=03BF 0314 +1F42=1F40 0300 +1F43=1F41 0300 +1F44=1F40 0301 +1F45=1F41 0301 +1F48=039F 0313 +1F49=039F 0314 +1F4A=1F48 0300 +1F4B=1F49 0300 +1F4C=1F48 0301 +1F4D=1F49 0301 +1F50=03C5 0313 +1F51=03C5 0314 +1F52=1F50 0300 +1F53=1F51 0300 +1F54=1F50 0301 +1F55=1F51 0301 +1F56=1F50 0342 +1F57=1F51 0342 +1F59=03A5 0314 +1F5B=1F59 0300 +1F5D=1F59 0301 +1F5F=1F59 0342 +1F60=03C9 0313 +1F61=03C9 0314 +1F62=1F60 0300 +1F63=1F61 0300 +1F64=1F60 0301 +1F65=1F61 0301 +1F66=1F60 0342 +1F67=1F61 0342 +1F68=03A9 0313 +1F69=03A9 0314 +1F6A=1F68 0300 +1F6B=1F69 0300 +1F6C=1F68 0301 +1F6D=1F69 0301 +1F6E=1F68 0342 +1F6F=1F69 0342 +1F70=03B1 0300 +1F71>03AC +1F72=03B5 0300 +1F73>03AD +1F74=03B7 0300 +1F75>03AE +1F76=03B9 0300 +1F77>03AF +1F78=03BF 0300 +1F79>03CC +1F7A=03C5 0300 +1F7B>03CD +1F7C=03C9 0300 +1F7D>03CE +1F80=1F00 0345 +1F81=1F01 0345 +1F82=1F02 0345 +1F83=1F03 0345 +1F84=1F04 0345 +1F85=1F05 0345 +1F86=1F06 0345 +1F87=1F07 0345 +1F88=1F08 0345 +1F89=1F09 0345 +1F8A=1F0A 0345 +1F8B=1F0B 0345 +1F8C=1F0C 0345 +1F8D=1F0D 0345 +1F8E=1F0E 0345 +1F8F=1F0F 0345 +1F90=1F20 0345 +1F91=1F21 0345 +1F92=1F22 0345 +1F93=1F23 0345 +1F94=1F24 0345 +1F95=1F25 0345 +1F96=1F26 0345 +1F97=1F27 0345 +1F98=1F28 0345 +1F99=1F29 0345 +1F9A=1F2A 0345 +1F9B=1F2B 0345 +1F9C=1F2C 0345 +1F9D=1F2D 0345 +1F9E=1F2E 0345 +1F9F=1F2F 0345 +1FA0=1F60 0345 +1FA1=1F61 0345 +1FA2=1F62 0345 +1FA3=1F63 0345 +1FA4=1F64 0345 +1FA5=1F65 0345 +1FA6=1F66 0345 +1FA7=1F67 0345 +1FA8=1F68 0345 +1FA9=1F69 0345 +1FAA=1F6A 0345 +1FAB=1F6B 0345 +1FAC=1F6C 0345 +1FAD=1F6D 0345 +1FAE=1F6E 0345 +1FAF=1F6F 0345 +1FB0=03B1 0306 +1FB1=03B1 0304 +1FB2=1F70 0345 +1FB3=03B1 0345 +1FB4=03AC 0345 +1FB6=03B1 0342 +1FB7=1FB6 0345 +1FB8=0391 0306 +1FB9=0391 0304 +1FBA=0391 0300 +1FBB>0386 +1FBC=0391 0345 +1FBE>03B9 +1FC1=00A8 0342 +1FC2=1F74 0345 +1FC3=03B7 0345 +1FC4=03AE 0345 +1FC6=03B7 0342 +1FC7=1FC6 0345 +1FC8=0395 0300 +1FC9>0388 +1FCA=0397 0300 +1FCB>0389 +1FCC=0397 0345 +1FCD=1FBF 0300 +1FCE=1FBF 0301 +1FCF=1FBF 0342 +1FD0=03B9 0306 +1FD1=03B9 0304 +1FD2=03CA 0300 +1FD3>0390 +1FD6=03B9 0342 +1FD7=03CA 0342 +1FD8=0399 0306 +1FD9=0399 0304 +1FDA=0399 0300 +1FDB>038A +1FDD=1FFE 0300 +1FDE=1FFE 0301 +1FDF=1FFE 0342 +1FE0=03C5 0306 +1FE1=03C5 0304 +1FE2=03CB 0300 +1FE3>03B0 +1FE4=03C1 0313 +1FE5=03C1 0314 +1FE6=03C5 0342 +1FE7=03CB 0342 +1FE8=03A5 0306 +1FE9=03A5 0304 +1FEA=03A5 0300 +1FEB>038E +1FEC=03A1 0314 +1FED=00A8 0300 +1FEE>0385 +1FEF>0060 +1FF2=1F7C 0345 +1FF3=03C9 0345 +1FF4=03CE 0345 +1FF6=03C9 0342 +1FF7=1FF6 0345 +1FF8=039F 0300 +1FF9>038C +1FFA=03A9 0300 +1FFB>038F +1FFC=03A9 0345 +1FFD>00B4 +2000>2002 +2001>2003 +2126>03A9 +212A>004B +212B>00C5 +219A=2190 0338 +219B=2192 0338 +21AE=2194 0338 +21CD=21D0 0338 +21CE=21D4 0338 +21CF=21D2 0338 +2204=2203 0338 +2209=2208 0338 +220C=220B 0338 +2224=2223 0338 +2226=2225 0338 +2241=223C 0338 +2244=2243 0338 +2247=2245 0338 +2249=2248 0338 +2260=003D 0338 +2262=2261 0338 +226D=224D 0338 +226E=003C 0338 +226F=003E 0338 +2270=2264 0338 +2271=2265 0338 +2274=2272 0338 +2275=2273 0338 +2278=2276 0338 +2279=2277 0338 +2280=227A 0338 +2281=227B 0338 +2284=2282 0338 +2285=2283 0338 +2288=2286 0338 +2289=2287 0338 +22AC=22A2 0338 +22AD=22A8 0338 +22AE=22A9 0338 +22AF=22AB 0338 +22E0=227C 0338 +22E1=227D 0338 +22E2=2291 0338 +22E3=2292 0338 +22EA=22B2 0338 +22EB=22B3 0338 +22EC=22B4 0338 +22ED=22B5 0338 +2329>3008 +232A>3009 +2ADC>2ADD 0338 +304C=304B 3099 +304E=304D 3099 +3050=304F 3099 +3052=3051 3099 +3054=3053 3099 +3056=3055 3099 +3058=3057 3099 +305A=3059 3099 +305C=305B 3099 +305E=305D 3099 +3060=305F 3099 +3062=3061 3099 +3065=3064 3099 +3067=3066 3099 +3069=3068 3099 +3070=306F 3099 +3071=306F 309A +3073=3072 3099 +3074=3072 309A +3076=3075 3099 +3077=3075 309A +3079=3078 3099 +307A=3078 309A +307C=307B 3099 +307D=307B 309A +3094=3046 3099 +309E=309D 3099 +30AC=30AB 3099 +30AE=30AD 3099 +30B0=30AF 3099 +30B2=30B1 3099 +30B4=30B3 3099 +30B6=30B5 3099 +30B8=30B7 3099 +30BA=30B9 3099 +30BC=30BB 3099 +30BE=30BD 3099 +30C0=30BF 3099 +30C2=30C1 3099 +30C5=30C4 3099 +30C7=30C6 3099 +30C9=30C8 3099 +30D0=30CF 3099 +30D1=30CF 309A +30D3=30D2 3099 +30D4=30D2 309A +30D6=30D5 3099 +30D7=30D5 309A +30D9=30D8 3099 +30DA=30D8 309A +30DC=30DB 3099 +30DD=30DB 309A +30F4=30A6 3099 +30F7=30EF 3099 +30F8=30F0 3099 +30F9=30F1 3099 +30FA=30F2 3099 +30FE=30FD 3099 +F900>8C48 +F901>66F4 +F902>8ECA +F903>8CC8 +F904>6ED1 +F905>4E32 +F906>53E5 +F907>9F9C +F908>9F9C +F909>5951 +F90A>91D1 +F90B>5587 +F90C>5948 +F90D>61F6 +F90E>7669 +F90F>7F85 +F910>863F +F911>87BA +F912>88F8 +F913>908F +F914>6A02 +F915>6D1B +F916>70D9 +F917>73DE +F918>843D +F919>916A +F91A>99F1 +F91B>4E82 +F91C>5375 +F91D>6B04 +F91E>721B +F91F>862D +F920>9E1E +F921>5D50 +F922>6FEB +F923>85CD +F924>8964 +F925>62C9 +F926>81D8 +F927>881F +F928>5ECA +F929>6717 +F92A>6D6A +F92B>72FC +F92C>90CE +F92D>4F86 +F92E>51B7 +F92F>52DE +F930>64C4 +F931>6AD3 +F932>7210 +F933>76E7 +F934>8001 +F935>8606 +F936>865C +F937>8DEF +F938>9732 +F939>9B6F +F93A>9DFA +F93B>788C +F93C>797F +F93D>7DA0 +F93E>83C9 +F93F>9304 +F940>9E7F +F941>8AD6 +F942>58DF +F943>5F04 +F944>7C60 +F945>807E +F946>7262 +F947>78CA +F948>8CC2 +F949>96F7 +F94A>58D8 +F94B>5C62 +F94C>6A13 +F94D>6DDA +F94E>6F0F +F94F>7D2F +F950>7E37 +F951>964B +F952>52D2 +F953>808B +F954>51DC +F955>51CC +F956>7A1C +F957>7DBE +F958>83F1 +F959>9675 +F95A>8B80 +F95B>62CF +F95C>6A02 +F95D>8AFE +F95E>4E39 +F95F>5BE7 +F960>6012 +F961>7387 +F962>7570 +F963>5317 +F964>78FB +F965>4FBF +F966>5FA9 +F967>4E0D +F968>6CCC +F969>6578 +F96A>7D22 +F96B>53C3 +F96C>585E +F96D>7701 +F96E>8449 +F96F>8AAA +F970>6BBA +F971>8FB0 +F972>6C88 +F973>62FE +F974>82E5 +F975>63A0 +F976>7565 +F977>4EAE +F978>5169 +F979>51C9 +F97A>6881 +F97B>7CE7 +F97C>826F +F97D>8AD2 +F97E>91CF +F97F>52F5 +F980>5442 +F981>5973 +F982>5EEC +F983>65C5 +F984>6FFE +F985>792A +F986>95AD +F987>9A6A +F988>9E97 +F989>9ECE +F98A>529B +F98B>66C6 +F98C>6B77 +F98D>8F62 +F98E>5E74 +F98F>6190 +F990>6200 +F991>649A +F992>6F23 +F993>7149 +F994>7489 +F995>79CA +F996>7DF4 +F997>806F +F998>8F26 +F999>84EE +F99A>9023 +F99B>934A +F99C>5217 +F99D>52A3 +F99E>54BD +F99F>70C8 +F9A0>88C2 +F9A1>8AAA +F9A2>5EC9 +F9A3>5FF5 +F9A4>637B +F9A5>6BAE +F9A6>7C3E +F9A7>7375 +F9A8>4EE4 +F9A9>56F9 +F9AA>5BE7 +F9AB>5DBA +F9AC>601C +F9AD>73B2 +F9AE>7469 +F9AF>7F9A +F9B0>8046 +F9B1>9234 +F9B2>96F6 +F9B3>9748 +F9B4>9818 +F9B5>4F8B +F9B6>79AE +F9B7>91B4 +F9B8>96B8 +F9B9>60E1 +F9BA>4E86 +F9BB>50DA +F9BC>5BEE +F9BD>5C3F +F9BE>6599 +F9BF>6A02 +F9C0>71CE +F9C1>7642 +F9C2>84FC +F9C3>907C +F9C4>9F8D +F9C5>6688 +F9C6>962E +F9C7>5289 +F9C8>677B +F9C9>67F3 +F9CA>6D41 +F9CB>6E9C +F9CC>7409 +F9CD>7559 +F9CE>786B +F9CF>7D10 +F9D0>985E +F9D1>516D +F9D2>622E +F9D3>9678 +F9D4>502B +F9D5>5D19 +F9D6>6DEA +F9D7>8F2A +F9D8>5F8B +F9D9>6144 +F9DA>6817 +F9DB>7387 +F9DC>9686 +F9DD>5229 +F9DE>540F +F9DF>5C65 +F9E0>6613 +F9E1>674E +F9E2>68A8 +F9E3>6CE5 +F9E4>7406 +F9E5>75E2 +F9E6>7F79 +F9E7>88CF +F9E8>88E1 +F9E9>91CC +F9EA>96E2 +F9EB>533F +F9EC>6EBA +F9ED>541D +F9EE>71D0 +F9EF>7498 +F9F0>85FA +F9F1>96A3 +F9F2>9C57 +F9F3>9E9F +F9F4>6797 +F9F5>6DCB +F9F6>81E8 +F9F7>7ACB +F9F8>7B20 +F9F9>7C92 +F9FA>72C0 +F9FB>7099 +F9FC>8B58 +F9FD>4EC0 +F9FE>8336 +F9FF>523A +FA00>5207 +FA01>5EA6 +FA02>62D3 +FA03>7CD6 +FA04>5B85 +FA05>6D1E +FA06>66B4 +FA07>8F3B +FA08>884C +FA09>964D +FA0A>898B +FA0B>5ED3 +FA0C>5140 +FA0D>55C0 +FA10>585A +FA12>6674 +FA15>51DE +FA16>732A +FA17>76CA +FA18>793C +FA19>795E +FA1A>7965 +FA1B>798F +FA1C>9756 +FA1D>7CBE +FA1E>7FBD +FA20>8612 +FA22>8AF8 +FA25>9038 +FA26>90FD +FA2A>98EF +FA2B>98FC +FA2C>9928 +FA2D>9DB4 +FA2E>90DE +FA2F>96B7 +FA30>4FAE +FA31>50E7 +FA32>514D +FA33>52C9 +FA34>52E4 +FA35>5351 +FA36>559D +FA37>5606 +FA38>5668 +FA39>5840 +FA3A>58A8 +FA3B>5C64 +FA3C>5C6E +FA3D>6094 +FA3E>6168 +FA3F>618E +FA40>61F2 +FA41>654F +FA42>65E2 +FA43>6691 +FA44>6885 +FA45>6D77 +FA46>6E1A +FA47>6F22 +FA48>716E +FA49>722B +FA4A>7422 +FA4B>7891 +FA4C>793E +FA4D>7949 +FA4E>7948 +FA4F>7950 +FA50>7956 +FA51>795D +FA52>798D +FA53>798E +FA54>7A40 +FA55>7A81 +FA56>7BC0 +FA57>7DF4 +FA58>7E09 +FA59>7E41 +FA5A>7F72 +FA5B>8005 +FA5C>81ED +FA5D>8279 +FA5E>8279 +FA5F>8457 +FA60>8910 +FA61>8996 +FA62>8B01 +FA63>8B39 +FA64>8CD3 +FA65>8D08 +FA66>8FB6 +FA67>9038 +FA68>96E3 +FA69>97FF +FA6A>983B +FA6B>6075 +FA6C>242EE +FA6D>8218 +FA70>4E26 +FA71>51B5 +FA72>5168 +FA73>4F80 +FA74>5145 +FA75>5180 +FA76>52C7 +FA77>52FA +FA78>559D +FA79>5555 +FA7A>5599 +FA7B>55E2 +FA7C>585A +FA7D>58B3 +FA7E>5944 +FA7F>5954 +FA80>5A62 +FA81>5B28 +FA82>5ED2 +FA83>5ED9 +FA84>5F69 +FA85>5FAD +FA86>60D8 +FA87>614E +FA88>6108 +FA89>618E +FA8A>6160 +FA8B>61F2 +FA8C>6234 +FA8D>63C4 +FA8E>641C +FA8F>6452 +FA90>6556 +FA91>6674 +FA92>6717 +FA93>671B +FA94>6756 +FA95>6B79 +FA96>6BBA +FA97>6D41 +FA98>6EDB +FA99>6ECB +FA9A>6F22 +FA9B>701E +FA9C>716E +FA9D>77A7 +FA9E>7235 +FA9F>72AF +FAA0>732A +FAA1>7471 +FAA2>7506 +FAA3>753B +FAA4>761D +FAA5>761F +FAA6>76CA +FAA7>76DB +FAA8>76F4 +FAA9>774A +FAAA>7740 +FAAB>78CC +FAAC>7AB1 +FAAD>7BC0 +FAAE>7C7B +FAAF>7D5B +FAB0>7DF4 +FAB1>7F3E +FAB2>8005 +FAB3>8352 +FAB4>83EF +FAB5>8779 +FAB6>8941 +FAB7>8986 +FAB8>8996 +FAB9>8ABF +FABA>8AF8 +FABB>8ACB +FABC>8B01 +FABD>8AFE +FABE>8AED +FABF>8B39 +FAC0>8B8A +FAC1>8D08 +FAC2>8F38 +FAC3>9072 +FAC4>9199 +FAC5>9276 +FAC6>967C +FAC7>96E3 +FAC8>9756 +FAC9>97DB +FACA>97FF +FACB>980B +FACC>983B +FACD>9B12 +FACE>9F9C +FACF>2284A +FAD0>22844 +FAD1>233D5 +FAD2>3B9D +FAD3>4018 +FAD4>4039 +FAD5>25249 +FAD6>25CD0 +FAD7>27ED3 +FAD8>9F43 +FAD9>9F8E +FB1D>05D9 05B4 +FB1F>05F2 05B7 +FB2A>05E9 05C1 +FB2B>05E9 05C2 +FB2C>FB49 05C1 +FB2D>FB49 05C2 +FB2E>05D0 05B7 +FB2F>05D0 05B8 +FB30>05D0 05BC +FB31>05D1 05BC +FB32>05D2 05BC +FB33>05D3 05BC +FB34>05D4 05BC +FB35>05D5 05BC +FB36>05D6 05BC +FB38>05D8 05BC +FB39>05D9 05BC +FB3A>05DA 05BC +FB3B>05DB 05BC +FB3C>05DC 05BC +FB3E>05DE 05BC +FB40>05E0 05BC +FB41>05E1 05BC +FB43>05E3 05BC +FB44>05E4 05BC +FB46>05E6 05BC +FB47>05E7 05BC +FB48>05E8 05BC +FB49>05E9 05BC +FB4A>05EA 05BC +FB4B>05D5 05B9 +FB4C>05D1 05BF +FB4D>05DB 05BF +FB4E>05E4 05BF +1109A=11099 110BA +1109C=1109B 110BA +110AB=110A5 110BA +1112E=11131 11127 +1112F=11132 11127 +1134B=11347 1133E +1134C=11347 11357 +114BB=114B9 114BA +114BC=114B9 114B0 +114BE=114B9 114BD +115BA=115B8 115AF +115BB=115B9 115AF +1D15E>1D157 1D165 +1D15F>1D158 1D165 +1D160>1D15F 1D16E +1D161>1D15F 1D16F +1D162>1D15F 1D170 +1D163>1D15F 1D171 +1D164>1D15F 1D172 +1D1BB>1D1B9 1D165 +1D1BC>1D1BA 1D165 +1D1BD>1D1BB 1D16E +1D1BE>1D1BC 1D16E +1D1BF>1D1BB 1D16F +1D1C0>1D1BC 1D16F +2F800>4E3D +2F801>4E38 +2F802>4E41 +2F803>20122 +2F804>4F60 +2F805>4FAE +2F806>4FBB +2F807>5002 +2F808>507A +2F809>5099 +2F80A>50E7 +2F80B>50CF +2F80C>349E +2F80D>2063A +2F80E>514D +2F80F>5154 +2F810>5164 +2F811>5177 +2F812>2051C +2F813>34B9 +2F814>5167 +2F815>518D +2F816>2054B +2F817>5197 +2F818>51A4 +2F819>4ECC +2F81A>51AC +2F81B>51B5 +2F81C>291DF +2F81D>51F5 +2F81E>5203 +2F81F>34DF +2F820>523B +2F821>5246 +2F822>5272 +2F823>5277 +2F824>3515 +2F825>52C7 +2F826>52C9 +2F827>52E4 +2F828>52FA +2F829>5305 +2F82A>5306 +2F82B>5317 +2F82C>5349 +2F82D>5351 +2F82E>535A +2F82F>5373 +2F830>537D +2F831>537F +2F832>537F +2F833>537F +2F834>20A2C +2F835>7070 +2F836>53CA +2F837>53DF +2F838>20B63 +2F839>53EB +2F83A>53F1 +2F83B>5406 +2F83C>549E +2F83D>5438 +2F83E>5448 +2F83F>5468 +2F840>54A2 +2F841>54F6 +2F842>5510 +2F843>5553 +2F844>5563 +2F845>5584 +2F846>5584 +2F847>5599 +2F848>55AB +2F849>55B3 +2F84A>55C2 +2F84B>5716 +2F84C>5606 +2F84D>5717 +2F84E>5651 +2F84F>5674 +2F850>5207 +2F851>58EE +2F852>57CE +2F853>57F4 +2F854>580D +2F855>578B +2F856>5832 +2F857>5831 +2F858>58AC +2F859>214E4 +2F85A>58F2 +2F85B>58F7 +2F85C>5906 +2F85D>591A +2F85E>5922 +2F85F>5962 +2F860>216A8 +2F861>216EA +2F862>59EC +2F863>5A1B +2F864>5A27 +2F865>59D8 +2F866>5A66 +2F867>36EE +2F868>36FC +2F869>5B08 +2F86A>5B3E +2F86B>5B3E +2F86C>219C8 +2F86D>5BC3 +2F86E>5BD8 +2F86F>5BE7 +2F870>5BF3 +2F871>21B18 +2F872>5BFF +2F873>5C06 +2F874>5F53 +2F875>5C22 +2F876>3781 +2F877>5C60 +2F878>5C6E +2F879>5CC0 +2F87A>5C8D +2F87B>21DE4 +2F87C>5D43 +2F87D>21DE6 +2F87E>5D6E +2F87F>5D6B +2F880>5D7C +2F881>5DE1 +2F882>5DE2 +2F883>382F +2F884>5DFD +2F885>5E28 +2F886>5E3D +2F887>5E69 +2F888>3862 +2F889>22183 +2F88A>387C +2F88B>5EB0 +2F88C>5EB3 +2F88D>5EB6 +2F88E>5ECA +2F88F>2A392 +2F890>5EFE +2F891>22331 +2F892>22331 +2F893>8201 +2F894>5F22 +2F895>5F22 +2F896>38C7 +2F897>232B8 +2F898>261DA +2F899>5F62 +2F89A>5F6B +2F89B>38E3 +2F89C>5F9A +2F89D>5FCD +2F89E>5FD7 +2F89F>5FF9 +2F8A0>6081 +2F8A1>393A +2F8A2>391C +2F8A3>6094 +2F8A4>226D4 +2F8A5>60C7 +2F8A6>6148 +2F8A7>614C +2F8A8>614E +2F8A9>614C +2F8AA>617A +2F8AB>618E +2F8AC>61B2 +2F8AD>61A4 +2F8AE>61AF +2F8AF>61DE +2F8B0>61F2 +2F8B1>61F6 +2F8B2>6210 +2F8B3>621B +2F8B4>625D +2F8B5>62B1 +2F8B6>62D4 +2F8B7>6350 +2F8B8>22B0C +2F8B9>633D +2F8BA>62FC +2F8BB>6368 +2F8BC>6383 +2F8BD>63E4 +2F8BE>22BF1 +2F8BF>6422 +2F8C0>63C5 +2F8C1>63A9 +2F8C2>3A2E +2F8C3>6469 +2F8C4>647E +2F8C5>649D +2F8C6>6477 +2F8C7>3A6C +2F8C8>654F +2F8C9>656C +2F8CA>2300A +2F8CB>65E3 +2F8CC>66F8 +2F8CD>6649 +2F8CE>3B19 +2F8CF>6691 +2F8D0>3B08 +2F8D1>3AE4 +2F8D2>5192 +2F8D3>5195 +2F8D4>6700 +2F8D5>669C +2F8D6>80AD +2F8D7>43D9 +2F8D8>6717 +2F8D9>671B +2F8DA>6721 +2F8DB>675E +2F8DC>6753 +2F8DD>233C3 +2F8DE>3B49 +2F8DF>67FA +2F8E0>6785 +2F8E1>6852 +2F8E2>6885 +2F8E3>2346D +2F8E4>688E +2F8E5>681F +2F8E6>6914 +2F8E7>3B9D +2F8E8>6942 +2F8E9>69A3 +2F8EA>69EA +2F8EB>6AA8 +2F8EC>236A3 +2F8ED>6ADB +2F8EE>3C18 +2F8EF>6B21 +2F8F0>238A7 +2F8F1>6B54 +2F8F2>3C4E +2F8F3>6B72 +2F8F4>6B9F +2F8F5>6BBA +2F8F6>6BBB +2F8F7>23A8D +2F8F8>21D0B +2F8F9>23AFA +2F8FA>6C4E +2F8FB>23CBC +2F8FC>6CBF +2F8FD>6CCD +2F8FE>6C67 +2F8FF>6D16 +2F900>6D3E +2F901>6D77 +2F902>6D41 +2F903>6D69 +2F904>6D78 +2F905>6D85 +2F906>23D1E +2F907>6D34 +2F908>6E2F +2F909>6E6E +2F90A>3D33 +2F90B>6ECB +2F90C>6EC7 +2F90D>23ED1 +2F90E>6DF9 +2F90F>6F6E +2F910>23F5E +2F911>23F8E +2F912>6FC6 +2F913>7039 +2F914>701E +2F915>701B +2F916>3D96 +2F917>704A +2F918>707D +2F919>7077 +2F91A>70AD +2F91B>20525 +2F91C>7145 +2F91D>24263 +2F91E>719C +2F91F>243AB +2F920>7228 +2F921>7235 +2F922>7250 +2F923>24608 +2F924>7280 +2F925>7295 +2F926>24735 +2F927>24814 +2F928>737A +2F929>738B +2F92A>3EAC +2F92B>73A5 +2F92C>3EB8 +2F92D>3EB8 +2F92E>7447 +2F92F>745C +2F930>7471 +2F931>7485 +2F932>74CA +2F933>3F1B +2F934>7524 +2F935>24C36 +2F936>753E +2F937>24C92 +2F938>7570 +2F939>2219F +2F93A>7610 +2F93B>24FA1 +2F93C>24FB8 +2F93D>25044 +2F93E>3FFC +2F93F>4008 +2F940>76F4 +2F941>250F3 +2F942>250F2 +2F943>25119 +2F944>25133 +2F945>771E +2F946>771F +2F947>771F +2F948>774A +2F949>4039 +2F94A>778B +2F94B>4046 +2F94C>4096 +2F94D>2541D +2F94E>784E +2F94F>788C +2F950>78CC +2F951>40E3 +2F952>25626 +2F953>7956 +2F954>2569A +2F955>256C5 +2F956>798F +2F957>79EB +2F958>412F +2F959>7A40 +2F95A>7A4A +2F95B>7A4F +2F95C>2597C +2F95D>25AA7 +2F95E>25AA7 +2F95F>7AEE +2F960>4202 +2F961>25BAB +2F962>7BC6 +2F963>7BC9 +2F964>4227 +2F965>25C80 +2F966>7CD2 +2F967>42A0 +2F968>7CE8 +2F969>7CE3 +2F96A>7D00 +2F96B>25F86 +2F96C>7D63 +2F96D>4301 +2F96E>7DC7 +2F96F>7E02 +2F970>7E45 +2F971>4334 +2F972>26228 +2F973>26247 +2F974>4359 +2F975>262D9 +2F976>7F7A +2F977>2633E +2F978>7F95 +2F979>7FFA +2F97A>8005 +2F97B>264DA +2F97C>26523 +2F97D>8060 +2F97E>265A8 +2F97F>8070 +2F980>2335F +2F981>43D5 +2F982>80B2 +2F983>8103 +2F984>440B +2F985>813E +2F986>5AB5 +2F987>267A7 +2F988>267B5 +2F989>23393 +2F98A>2339C +2F98B>8201 +2F98C>8204 +2F98D>8F9E +2F98E>446B +2F98F>8291 +2F990>828B +2F991>829D +2F992>52B3 +2F993>82B1 +2F994>82B3 +2F995>82BD +2F996>82E6 +2F997>26B3C +2F998>82E5 +2F999>831D +2F99A>8363 +2F99B>83AD +2F99C>8323 +2F99D>83BD +2F99E>83E7 +2F99F>8457 +2F9A0>8353 +2F9A1>83CA +2F9A2>83CC +2F9A3>83DC +2F9A4>26C36 +2F9A5>26D6B +2F9A6>26CD5 +2F9A7>452B +2F9A8>84F1 +2F9A9>84F3 +2F9AA>8516 +2F9AB>273CA +2F9AC>8564 +2F9AD>26F2C +2F9AE>455D +2F9AF>4561 +2F9B0>26FB1 +2F9B1>270D2 +2F9B2>456B +2F9B3>8650 +2F9B4>865C +2F9B5>8667 +2F9B6>8669 +2F9B7>86A9 +2F9B8>8688 +2F9B9>870E +2F9BA>86E2 +2F9BB>8779 +2F9BC>8728 +2F9BD>876B +2F9BE>8786 +2F9BF>45D7 +2F9C0>87E1 +2F9C1>8801 +2F9C2>45F9 +2F9C3>8860 +2F9C4>8863 +2F9C5>27667 +2F9C6>88D7 +2F9C7>88DE +2F9C8>4635 +2F9C9>88FA +2F9CA>34BB +2F9CB>278AE +2F9CC>27966 +2F9CD>46BE +2F9CE>46C7 +2F9CF>8AA0 +2F9D0>8AED +2F9D1>8B8A +2F9D2>8C55 +2F9D3>27CA8 +2F9D4>8CAB +2F9D5>8CC1 +2F9D6>8D1B +2F9D7>8D77 +2F9D8>27F2F +2F9D9>20804 +2F9DA>8DCB +2F9DB>8DBC +2F9DC>8DF0 +2F9DD>208DE +2F9DE>8ED4 +2F9DF>8F38 +2F9E0>285D2 +2F9E1>285ED +2F9E2>9094 +2F9E3>90F1 +2F9E4>9111 +2F9E5>2872E +2F9E6>911B +2F9E7>9238 +2F9E8>92D7 +2F9E9>92D8 +2F9EA>927C +2F9EB>93F9 +2F9EC>9415 +2F9ED>28BFA +2F9EE>958B +2F9EF>4995 +2F9F0>95B7 +2F9F1>28D77 +2F9F2>49E6 +2F9F3>96C3 +2F9F4>5DB2 +2F9F5>9723 +2F9F6>29145 +2F9F7>2921A +2F9F8>4A6E +2F9F9>4A76 +2F9FA>97E0 +2F9FB>2940A +2F9FC>4AB2 +2F9FD>29496 +2F9FE>980B +2F9FF>980B +2FA00>9829 +2FA01>295B6 +2FA02>98E2 +2FA03>4B33 +2FA04>9929 +2FA05>99A7 +2FA06>99C2 +2FA07>99FE +2FA08>4BCE +2FA09>29B30 +2FA0A>9B12 +2FA0B>9C40 +2FA0C>9CFD +2FA0D>4CCE +2FA0E>4CED +2FA0F>9D67 +2FA10>2A0CE +2FA11>4CF8 +2FA12>2A105 +2FA13>2A20E +2FA14>2A291 +2FA15>9EBB +2FA16>4D56 +2FA17>9EF9 +2FA18>9EFE +2FA19>9F05 +2FA1A>9F0F +2FA1B>9F16 +2FA1C>9F3B +2FA1D>2A600 \ No newline at end of file diff --git a/claimtrie/normalization/NormalizationTest_v11.txt b/claimtrie/normalization/NormalizationTest_v11.txt new file mode 100644 index 00000000..cb72a0cb --- /dev/null +++ b/claimtrie/normalization/NormalizationTest_v11.txt @@ -0,0 +1,18847 @@ +# NormalizationTest-11.0.0.txt +# Date: 2018-02-19, 18:33:08 GMT +# © 2018 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Normalization Test Suite +# Format: +# +# Columns (c1, c2,...) are separated by semicolons +# They have the following meaning: +# source; NFC; NFD; NFKC; NFKD +# Comments are indicated with hash marks +# Each of the columns may have one or more code points. +# +# CONFORMANCE: +# 1. The following invariants must be true for all conformant implementations +# +# NFC +# c2 == toNFC(c1) == toNFC(c2) == toNFC(c3) +# c4 == toNFC(c4) == toNFC(c5) +# +# NFD +# c3 == toNFD(c1) == toNFD(c2) == toNFD(c3) +# c5 == toNFD(c4) == toNFD(c5) +# +# NFKC +# c4 == toNFKC(c1) == toNFKC(c2) == toNFKC(c3) == toNFKC(c4) == toNFKC(c5) +# +# NFKD +# c5 == toNFKD(c1) == toNFKD(c2) == toNFKD(c3) == toNFKD(c4) == toNFKD(c5) +# +# 2. For every code point X assigned in this version of Unicode that is not specifically +# listed in Part 1, the following invariants must be true for all conformant +# implementations: +# +# X == toNFC(X) == toNFD(X) == toNFKC(X) == toNFKD(X) +# +@Part0 # Specific cases +# +1E0A;1E0A;0044 0307;1E0A;0044 0307; +1E0C;1E0C;0044 0323;1E0C;0044 0323; +1E0A 0323;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; +1E0C 0307;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; +0044 0307 0323;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; +0044 0323 0307;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; +1E0A 031B;1E0A 031B;0044 031B 0307;1E0A 031B;0044 031B 0307; +1E0C 031B;1E0C 031B;0044 031B 0323;1E0C 031B;0044 031B 0323; +1E0A 031B 0323;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; +1E0C 031B 0307;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; +0044 031B 0307 0323;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; +0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; +00C8;00C8;0045 0300;00C8;0045 0300; +0112;0112;0045 0304;0112;0045 0304; +0045 0300;00C8;0045 0300;00C8;0045 0300; +0045 0304;0112;0045 0304;0112;0045 0304; +1E14;1E14;0045 0304 0300;1E14;0045 0304 0300; +0112 0300;1E14;0045 0304 0300;1E14;0045 0304 0300; +1E14 0304;1E14 0304;0045 0304 0300 0304;1E14 0304;0045 0304 0300 0304; +0045 0304 0300;1E14;0045 0304 0300;1E14;0045 0304 0300; +0045 0300 0304;00C8 0304;0045 0300 0304;00C8 0304;0045 0300 0304; +05B8 05B9 05B1 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F; +0592 05B7 05BC 05A5 05B0 05C0 05C4 05AD;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4; +1100 AC00 11A8;1100 AC01;1100 1100 1161 11A8;1100 AC01;1100 1100 1161 11A8; +1100 AC00 11A8 11A8;1100 AC01 11A8;1100 1100 1161 11A8 11A8;1100 AC01 11A8;1100 1100 1161 11A8 11A8; +# +@Part1 # Character by character test +# All characters not explicitly occurring in c1 of Part 1 have identical NFC, D, KC, KD forms. +# +00A0;00A0;00A0;0020;0020; +00A8;00A8;00A8;0020 0308;0020 0308; +00AA;00AA;00AA;0061;0061; +00AF;00AF;00AF;0020 0304;0020 0304; +00B2;00B2;00B2;0032;0032; +00B3;00B3;00B3;0033;0033; +00B4;00B4;00B4;0020 0301;0020 0301; +00B5;00B5;00B5;03BC;03BC; +00B8;00B8;00B8;0020 0327;0020 0327; +00B9;00B9;00B9;0031;0031; +00BA;00BA;00BA;006F;006F; +00BC;00BC;00BC;0031 2044 0034;0031 2044 0034; +00BD;00BD;00BD;0031 2044 0032;0031 2044 0032; +00BE;00BE;00BE;0033 2044 0034;0033 2044 0034; +00C0;00C0;0041 0300;00C0;0041 0300; +00C1;00C1;0041 0301;00C1;0041 0301; +00C2;00C2;0041 0302;00C2;0041 0302; +00C3;00C3;0041 0303;00C3;0041 0303; +00C4;00C4;0041 0308;00C4;0041 0308; +00C5;00C5;0041 030A;00C5;0041 030A; +00C7;00C7;0043 0327;00C7;0043 0327; +00C8;00C8;0045 0300;00C8;0045 0300; +00C9;00C9;0045 0301;00C9;0045 0301; +00CA;00CA;0045 0302;00CA;0045 0302; +00CB;00CB;0045 0308;00CB;0045 0308; +00CC;00CC;0049 0300;00CC;0049 0300; +00CD;00CD;0049 0301;00CD;0049 0301; +00CE;00CE;0049 0302;00CE;0049 0302; +00CF;00CF;0049 0308;00CF;0049 0308; +00D1;00D1;004E 0303;00D1;004E 0303; +00D2;00D2;004F 0300;00D2;004F 0300; +00D3;00D3;004F 0301;00D3;004F 0301; +00D4;00D4;004F 0302;00D4;004F 0302; +00D5;00D5;004F 0303;00D5;004F 0303; +00D6;00D6;004F 0308;00D6;004F 0308; +00D9;00D9;0055 0300;00D9;0055 0300; +00DA;00DA;0055 0301;00DA;0055 0301; +00DB;00DB;0055 0302;00DB;0055 0302; +00DC;00DC;0055 0308;00DC;0055 0308; +00DD;00DD;0059 0301;00DD;0059 0301; +00E0;00E0;0061 0300;00E0;0061 0300; +00E1;00E1;0061 0301;00E1;0061 0301; +00E2;00E2;0061 0302;00E2;0061 0302; +00E3;00E3;0061 0303;00E3;0061 0303; +00E4;00E4;0061 0308;00E4;0061 0308; +00E5;00E5;0061 030A;00E5;0061 030A; +00E7;00E7;0063 0327;00E7;0063 0327; +00E8;00E8;0065 0300;00E8;0065 0300; +00E9;00E9;0065 0301;00E9;0065 0301; +00EA;00EA;0065 0302;00EA;0065 0302; +00EB;00EB;0065 0308;00EB;0065 0308; +00EC;00EC;0069 0300;00EC;0069 0300; +00ED;00ED;0069 0301;00ED;0069 0301; +00EE;00EE;0069 0302;00EE;0069 0302; +00EF;00EF;0069 0308;00EF;0069 0308; +00F1;00F1;006E 0303;00F1;006E 0303; +00F2;00F2;006F 0300;00F2;006F 0300; +00F3;00F3;006F 0301;00F3;006F 0301; +00F4;00F4;006F 0302;00F4;006F 0302; +00F5;00F5;006F 0303;00F5;006F 0303; +00F6;00F6;006F 0308;00F6;006F 0308; +00F9;00F9;0075 0300;00F9;0075 0300; +00FA;00FA;0075 0301;00FA;0075 0301; +00FB;00FB;0075 0302;00FB;0075 0302; +00FC;00FC;0075 0308;00FC;0075 0308; +00FD;00FD;0079 0301;00FD;0079 0301; +00FF;00FF;0079 0308;00FF;0079 0308; +0100;0100;0041 0304;0100;0041 0304; +0101;0101;0061 0304;0101;0061 0304; +0102;0102;0041 0306;0102;0041 0306; +0103;0103;0061 0306;0103;0061 0306; +0104;0104;0041 0328;0104;0041 0328; +0105;0105;0061 0328;0105;0061 0328; +0106;0106;0043 0301;0106;0043 0301; +0107;0107;0063 0301;0107;0063 0301; +0108;0108;0043 0302;0108;0043 0302; +0109;0109;0063 0302;0109;0063 0302; +010A;010A;0043 0307;010A;0043 0307; +010B;010B;0063 0307;010B;0063 0307; +010C;010C;0043 030C;010C;0043 030C; +010D;010D;0063 030C;010D;0063 030C; +010E;010E;0044 030C;010E;0044 030C; +010F;010F;0064 030C;010F;0064 030C; +0112;0112;0045 0304;0112;0045 0304; +0113;0113;0065 0304;0113;0065 0304; +0114;0114;0045 0306;0114;0045 0306; +0115;0115;0065 0306;0115;0065 0306; +0116;0116;0045 0307;0116;0045 0307; +0117;0117;0065 0307;0117;0065 0307; +0118;0118;0045 0328;0118;0045 0328; +0119;0119;0065 0328;0119;0065 0328; +011A;011A;0045 030C;011A;0045 030C; +011B;011B;0065 030C;011B;0065 030C; +011C;011C;0047 0302;011C;0047 0302; +011D;011D;0067 0302;011D;0067 0302; +011E;011E;0047 0306;011E;0047 0306; +011F;011F;0067 0306;011F;0067 0306; +0120;0120;0047 0307;0120;0047 0307; +0121;0121;0067 0307;0121;0067 0307; +0122;0122;0047 0327;0122;0047 0327; +0123;0123;0067 0327;0123;0067 0327; +0124;0124;0048 0302;0124;0048 0302; +0125;0125;0068 0302;0125;0068 0302; +0128;0128;0049 0303;0128;0049 0303; +0129;0129;0069 0303;0129;0069 0303; +012A;012A;0049 0304;012A;0049 0304; +012B;012B;0069 0304;012B;0069 0304; +012C;012C;0049 0306;012C;0049 0306; +012D;012D;0069 0306;012D;0069 0306; +012E;012E;0049 0328;012E;0049 0328; +012F;012F;0069 0328;012F;0069 0328; +0130;0130;0049 0307;0130;0049 0307; +0132;0132;0132;0049 004A;0049 004A; +0133;0133;0133;0069 006A;0069 006A; +0134;0134;004A 0302;0134;004A 0302; +0135;0135;006A 0302;0135;006A 0302; +0136;0136;004B 0327;0136;004B 0327; +0137;0137;006B 0327;0137;006B 0327; +0139;0139;004C 0301;0139;004C 0301; +013A;013A;006C 0301;013A;006C 0301; +013B;013B;004C 0327;013B;004C 0327; +013C;013C;006C 0327;013C;006C 0327; +013D;013D;004C 030C;013D;004C 030C; +013E;013E;006C 030C;013E;006C 030C; +013F;013F;013F;004C 00B7;004C 00B7; +0140;0140;0140;006C 00B7;006C 00B7; +0143;0143;004E 0301;0143;004E 0301; +0144;0144;006E 0301;0144;006E 0301; +0145;0145;004E 0327;0145;004E 0327; +0146;0146;006E 0327;0146;006E 0327; +0147;0147;004E 030C;0147;004E 030C; +0148;0148;006E 030C;0148;006E 030C; +0149;0149;0149;02BC 006E;02BC 006E; +014C;014C;004F 0304;014C;004F 0304; +014D;014D;006F 0304;014D;006F 0304; +014E;014E;004F 0306;014E;004F 0306; +014F;014F;006F 0306;014F;006F 0306; +0150;0150;004F 030B;0150;004F 030B; +0151;0151;006F 030B;0151;006F 030B; +0154;0154;0052 0301;0154;0052 0301; +0155;0155;0072 0301;0155;0072 0301; +0156;0156;0052 0327;0156;0052 0327; +0157;0157;0072 0327;0157;0072 0327; +0158;0158;0052 030C;0158;0052 030C; +0159;0159;0072 030C;0159;0072 030C; +015A;015A;0053 0301;015A;0053 0301; +015B;015B;0073 0301;015B;0073 0301; +015C;015C;0053 0302;015C;0053 0302; +015D;015D;0073 0302;015D;0073 0302; +015E;015E;0053 0327;015E;0053 0327; +015F;015F;0073 0327;015F;0073 0327; +0160;0160;0053 030C;0160;0053 030C; +0161;0161;0073 030C;0161;0073 030C; +0162;0162;0054 0327;0162;0054 0327; +0163;0163;0074 0327;0163;0074 0327; +0164;0164;0054 030C;0164;0054 030C; +0165;0165;0074 030C;0165;0074 030C; +0168;0168;0055 0303;0168;0055 0303; +0169;0169;0075 0303;0169;0075 0303; +016A;016A;0055 0304;016A;0055 0304; +016B;016B;0075 0304;016B;0075 0304; +016C;016C;0055 0306;016C;0055 0306; +016D;016D;0075 0306;016D;0075 0306; +016E;016E;0055 030A;016E;0055 030A; +016F;016F;0075 030A;016F;0075 030A; +0170;0170;0055 030B;0170;0055 030B; +0171;0171;0075 030B;0171;0075 030B; +0172;0172;0055 0328;0172;0055 0328; +0173;0173;0075 0328;0173;0075 0328; +0174;0174;0057 0302;0174;0057 0302; +0175;0175;0077 0302;0175;0077 0302; +0176;0176;0059 0302;0176;0059 0302; +0177;0177;0079 0302;0177;0079 0302; +0178;0178;0059 0308;0178;0059 0308; +0179;0179;005A 0301;0179;005A 0301; +017A;017A;007A 0301;017A;007A 0301; +017B;017B;005A 0307;017B;005A 0307; +017C;017C;007A 0307;017C;007A 0307; +017D;017D;005A 030C;017D;005A 030C; +017E;017E;007A 030C;017E;007A 030C; +017F;017F;017F;0073;0073; +01A0;01A0;004F 031B;01A0;004F 031B; +01A1;01A1;006F 031B;01A1;006F 031B; +01AF;01AF;0055 031B;01AF;0055 031B; +01B0;01B0;0075 031B;01B0;0075 031B; +01C4;01C4;01C4;0044 017D;0044 005A 030C; +01C5;01C5;01C5;0044 017E;0044 007A 030C; +01C6;01C6;01C6;0064 017E;0064 007A 030C; +01C7;01C7;01C7;004C 004A;004C 004A; +01C8;01C8;01C8;004C 006A;004C 006A; +01C9;01C9;01C9;006C 006A;006C 006A; +01CA;01CA;01CA;004E 004A;004E 004A; +01CB;01CB;01CB;004E 006A;004E 006A; +01CC;01CC;01CC;006E 006A;006E 006A; +01CD;01CD;0041 030C;01CD;0041 030C; +01CE;01CE;0061 030C;01CE;0061 030C; +01CF;01CF;0049 030C;01CF;0049 030C; +01D0;01D0;0069 030C;01D0;0069 030C; +01D1;01D1;004F 030C;01D1;004F 030C; +01D2;01D2;006F 030C;01D2;006F 030C; +01D3;01D3;0055 030C;01D3;0055 030C; +01D4;01D4;0075 030C;01D4;0075 030C; +01D5;01D5;0055 0308 0304;01D5;0055 0308 0304; +01D6;01D6;0075 0308 0304;01D6;0075 0308 0304; +01D7;01D7;0055 0308 0301;01D7;0055 0308 0301; +01D8;01D8;0075 0308 0301;01D8;0075 0308 0301; +01D9;01D9;0055 0308 030C;01D9;0055 0308 030C; +01DA;01DA;0075 0308 030C;01DA;0075 0308 030C; +01DB;01DB;0055 0308 0300;01DB;0055 0308 0300; +01DC;01DC;0075 0308 0300;01DC;0075 0308 0300; +01DE;01DE;0041 0308 0304;01DE;0041 0308 0304; +01DF;01DF;0061 0308 0304;01DF;0061 0308 0304; +01E0;01E0;0041 0307 0304;01E0;0041 0307 0304; +01E1;01E1;0061 0307 0304;01E1;0061 0307 0304; +01E2;01E2;00C6 0304;01E2;00C6 0304; +01E3;01E3;00E6 0304;01E3;00E6 0304; +01E6;01E6;0047 030C;01E6;0047 030C; +01E7;01E7;0067 030C;01E7;0067 030C; +01E8;01E8;004B 030C;01E8;004B 030C; +01E9;01E9;006B 030C;01E9;006B 030C; +01EA;01EA;004F 0328;01EA;004F 0328; +01EB;01EB;006F 0328;01EB;006F 0328; +01EC;01EC;004F 0328 0304;01EC;004F 0328 0304; +01ED;01ED;006F 0328 0304;01ED;006F 0328 0304; +01EE;01EE;01B7 030C;01EE;01B7 030C; +01EF;01EF;0292 030C;01EF;0292 030C; +01F0;01F0;006A 030C;01F0;006A 030C; +01F1;01F1;01F1;0044 005A;0044 005A; +01F2;01F2;01F2;0044 007A;0044 007A; +01F3;01F3;01F3;0064 007A;0064 007A; +01F4;01F4;0047 0301;01F4;0047 0301; +01F5;01F5;0067 0301;01F5;0067 0301; +01F8;01F8;004E 0300;01F8;004E 0300; +01F9;01F9;006E 0300;01F9;006E 0300; +01FA;01FA;0041 030A 0301;01FA;0041 030A 0301; +01FB;01FB;0061 030A 0301;01FB;0061 030A 0301; +01FC;01FC;00C6 0301;01FC;00C6 0301; +01FD;01FD;00E6 0301;01FD;00E6 0301; +01FE;01FE;00D8 0301;01FE;00D8 0301; +01FF;01FF;00F8 0301;01FF;00F8 0301; +0200;0200;0041 030F;0200;0041 030F; +0201;0201;0061 030F;0201;0061 030F; +0202;0202;0041 0311;0202;0041 0311; +0203;0203;0061 0311;0203;0061 0311; +0204;0204;0045 030F;0204;0045 030F; +0205;0205;0065 030F;0205;0065 030F; +0206;0206;0045 0311;0206;0045 0311; +0207;0207;0065 0311;0207;0065 0311; +0208;0208;0049 030F;0208;0049 030F; +0209;0209;0069 030F;0209;0069 030F; +020A;020A;0049 0311;020A;0049 0311; +020B;020B;0069 0311;020B;0069 0311; +020C;020C;004F 030F;020C;004F 030F; +020D;020D;006F 030F;020D;006F 030F; +020E;020E;004F 0311;020E;004F 0311; +020F;020F;006F 0311;020F;006F 0311; +0210;0210;0052 030F;0210;0052 030F; +0211;0211;0072 030F;0211;0072 030F; +0212;0212;0052 0311;0212;0052 0311; +0213;0213;0072 0311;0213;0072 0311; +0214;0214;0055 030F;0214;0055 030F; +0215;0215;0075 030F;0215;0075 030F; +0216;0216;0055 0311;0216;0055 0311; +0217;0217;0075 0311;0217;0075 0311; +0218;0218;0053 0326;0218;0053 0326; +0219;0219;0073 0326;0219;0073 0326; +021A;021A;0054 0326;021A;0054 0326; +021B;021B;0074 0326;021B;0074 0326; +021E;021E;0048 030C;021E;0048 030C; +021F;021F;0068 030C;021F;0068 030C; +0226;0226;0041 0307;0226;0041 0307; +0227;0227;0061 0307;0227;0061 0307; +0228;0228;0045 0327;0228;0045 0327; +0229;0229;0065 0327;0229;0065 0327; +022A;022A;004F 0308 0304;022A;004F 0308 0304; +022B;022B;006F 0308 0304;022B;006F 0308 0304; +022C;022C;004F 0303 0304;022C;004F 0303 0304; +022D;022D;006F 0303 0304;022D;006F 0303 0304; +022E;022E;004F 0307;022E;004F 0307; +022F;022F;006F 0307;022F;006F 0307; +0230;0230;004F 0307 0304;0230;004F 0307 0304; +0231;0231;006F 0307 0304;0231;006F 0307 0304; +0232;0232;0059 0304;0232;0059 0304; +0233;0233;0079 0304;0233;0079 0304; +02B0;02B0;02B0;0068;0068; +02B1;02B1;02B1;0266;0266; +02B2;02B2;02B2;006A;006A; +02B3;02B3;02B3;0072;0072; +02B4;02B4;02B4;0279;0279; +02B5;02B5;02B5;027B;027B; +02B6;02B6;02B6;0281;0281; +02B7;02B7;02B7;0077;0077; +02B8;02B8;02B8;0079;0079; +02D8;02D8;02D8;0020 0306;0020 0306; +02D9;02D9;02D9;0020 0307;0020 0307; +02DA;02DA;02DA;0020 030A;0020 030A; +02DB;02DB;02DB;0020 0328;0020 0328; +02DC;02DC;02DC;0020 0303;0020 0303; +02DD;02DD;02DD;0020 030B;0020 030B; +02E0;02E0;02E0;0263;0263; +02E1;02E1;02E1;006C;006C; +02E2;02E2;02E2;0073;0073; +02E3;02E3;02E3;0078;0078; +02E4;02E4;02E4;0295;0295; +0340;0300;0300;0300;0300; +0341;0301;0301;0301;0301; +0343;0313;0313;0313;0313; +0344;0308 0301;0308 0301;0308 0301;0308 0301; +0374;02B9;02B9;02B9;02B9; +037A;037A;037A;0020 0345;0020 0345; +037E;003B;003B;003B;003B; +0384;0384;0384;0020 0301;0020 0301; +0385;0385;00A8 0301;0020 0308 0301;0020 0308 0301; +0386;0386;0391 0301;0386;0391 0301; +0387;00B7;00B7;00B7;00B7; +0388;0388;0395 0301;0388;0395 0301; +0389;0389;0397 0301;0389;0397 0301; +038A;038A;0399 0301;038A;0399 0301; +038C;038C;039F 0301;038C;039F 0301; +038E;038E;03A5 0301;038E;03A5 0301; +038F;038F;03A9 0301;038F;03A9 0301; +0390;0390;03B9 0308 0301;0390;03B9 0308 0301; +03AA;03AA;0399 0308;03AA;0399 0308; +03AB;03AB;03A5 0308;03AB;03A5 0308; +03AC;03AC;03B1 0301;03AC;03B1 0301; +03AD;03AD;03B5 0301;03AD;03B5 0301; +03AE;03AE;03B7 0301;03AE;03B7 0301; +03AF;03AF;03B9 0301;03AF;03B9 0301; +03B0;03B0;03C5 0308 0301;03B0;03C5 0308 0301; +03CA;03CA;03B9 0308;03CA;03B9 0308; +03CB;03CB;03C5 0308;03CB;03C5 0308; +03CC;03CC;03BF 0301;03CC;03BF 0301; +03CD;03CD;03C5 0301;03CD;03C5 0301; +03CE;03CE;03C9 0301;03CE;03C9 0301; +03D0;03D0;03D0;03B2;03B2; +03D1;03D1;03D1;03B8;03B8; +03D2;03D2;03D2;03A5;03A5; +03D3;03D3;03D2 0301;038E;03A5 0301; +03D4;03D4;03D2 0308;03AB;03A5 0308; +03D5;03D5;03D5;03C6;03C6; +03D6;03D6;03D6;03C0;03C0; +03F0;03F0;03F0;03BA;03BA; +03F1;03F1;03F1;03C1;03C1; +03F2;03F2;03F2;03C2;03C2; +03F4;03F4;03F4;0398;0398; +03F5;03F5;03F5;03B5;03B5; +03F9;03F9;03F9;03A3;03A3; +0400;0400;0415 0300;0400;0415 0300; +0401;0401;0415 0308;0401;0415 0308; +0403;0403;0413 0301;0403;0413 0301; +0407;0407;0406 0308;0407;0406 0308; +040C;040C;041A 0301;040C;041A 0301; +040D;040D;0418 0300;040D;0418 0300; +040E;040E;0423 0306;040E;0423 0306; +0419;0419;0418 0306;0419;0418 0306; +0439;0439;0438 0306;0439;0438 0306; +0450;0450;0435 0300;0450;0435 0300; +0451;0451;0435 0308;0451;0435 0308; +0453;0453;0433 0301;0453;0433 0301; +0457;0457;0456 0308;0457;0456 0308; +045C;045C;043A 0301;045C;043A 0301; +045D;045D;0438 0300;045D;0438 0300; +045E;045E;0443 0306;045E;0443 0306; +0476;0476;0474 030F;0476;0474 030F; +0477;0477;0475 030F;0477;0475 030F; +04C1;04C1;0416 0306;04C1;0416 0306; +04C2;04C2;0436 0306;04C2;0436 0306; +04D0;04D0;0410 0306;04D0;0410 0306; +04D1;04D1;0430 0306;04D1;0430 0306; +04D2;04D2;0410 0308;04D2;0410 0308; +04D3;04D3;0430 0308;04D3;0430 0308; +04D6;04D6;0415 0306;04D6;0415 0306; +04D7;04D7;0435 0306;04D7;0435 0306; +04DA;04DA;04D8 0308;04DA;04D8 0308; +04DB;04DB;04D9 0308;04DB;04D9 0308; +04DC;04DC;0416 0308;04DC;0416 0308; +04DD;04DD;0436 0308;04DD;0436 0308; +04DE;04DE;0417 0308;04DE;0417 0308; +04DF;04DF;0437 0308;04DF;0437 0308; +04E2;04E2;0418 0304;04E2;0418 0304; +04E3;04E3;0438 0304;04E3;0438 0304; +04E4;04E4;0418 0308;04E4;0418 0308; +04E5;04E5;0438 0308;04E5;0438 0308; +04E6;04E6;041E 0308;04E6;041E 0308; +04E7;04E7;043E 0308;04E7;043E 0308; +04EA;04EA;04E8 0308;04EA;04E8 0308; +04EB;04EB;04E9 0308;04EB;04E9 0308; +04EC;04EC;042D 0308;04EC;042D 0308; +04ED;04ED;044D 0308;04ED;044D 0308; +04EE;04EE;0423 0304;04EE;0423 0304; +04EF;04EF;0443 0304;04EF;0443 0304; +04F0;04F0;0423 0308;04F0;0423 0308; +04F1;04F1;0443 0308;04F1;0443 0308; +04F2;04F2;0423 030B;04F2;0423 030B; +04F3;04F3;0443 030B;04F3;0443 030B; +04F4;04F4;0427 0308;04F4;0427 0308; +04F5;04F5;0447 0308;04F5;0447 0308; +04F8;04F8;042B 0308;04F8;042B 0308; +04F9;04F9;044B 0308;04F9;044B 0308; +0587;0587;0587;0565 0582;0565 0582; +0622;0622;0627 0653;0622;0627 0653; +0623;0623;0627 0654;0623;0627 0654; +0624;0624;0648 0654;0624;0648 0654; +0625;0625;0627 0655;0625;0627 0655; +0626;0626;064A 0654;0626;064A 0654; +0675;0675;0675;0627 0674;0627 0674; +0676;0676;0676;0648 0674;0648 0674; +0677;0677;0677;06C7 0674;06C7 0674; +0678;0678;0678;064A 0674;064A 0674; +06C0;06C0;06D5 0654;06C0;06D5 0654; +06C2;06C2;06C1 0654;06C2;06C1 0654; +06D3;06D3;06D2 0654;06D3;06D2 0654; +0929;0929;0928 093C;0929;0928 093C; +0931;0931;0930 093C;0931;0930 093C; +0934;0934;0933 093C;0934;0933 093C; +0958;0915 093C;0915 093C;0915 093C;0915 093C; +0959;0916 093C;0916 093C;0916 093C;0916 093C; +095A;0917 093C;0917 093C;0917 093C;0917 093C; +095B;091C 093C;091C 093C;091C 093C;091C 093C; +095C;0921 093C;0921 093C;0921 093C;0921 093C; +095D;0922 093C;0922 093C;0922 093C;0922 093C; +095E;092B 093C;092B 093C;092B 093C;092B 093C; +095F;092F 093C;092F 093C;092F 093C;092F 093C; +09CB;09CB;09C7 09BE;09CB;09C7 09BE; +09CC;09CC;09C7 09D7;09CC;09C7 09D7; +09DC;09A1 09BC;09A1 09BC;09A1 09BC;09A1 09BC; +09DD;09A2 09BC;09A2 09BC;09A2 09BC;09A2 09BC; +09DF;09AF 09BC;09AF 09BC;09AF 09BC;09AF 09BC; +0A33;0A32 0A3C;0A32 0A3C;0A32 0A3C;0A32 0A3C; +0A36;0A38 0A3C;0A38 0A3C;0A38 0A3C;0A38 0A3C; +0A59;0A16 0A3C;0A16 0A3C;0A16 0A3C;0A16 0A3C; +0A5A;0A17 0A3C;0A17 0A3C;0A17 0A3C;0A17 0A3C; +0A5B;0A1C 0A3C;0A1C 0A3C;0A1C 0A3C;0A1C 0A3C; +0A5E;0A2B 0A3C;0A2B 0A3C;0A2B 0A3C;0A2B 0A3C; +0B48;0B48;0B47 0B56;0B48;0B47 0B56; +0B4B;0B4B;0B47 0B3E;0B4B;0B47 0B3E; +0B4C;0B4C;0B47 0B57;0B4C;0B47 0B57; +0B5C;0B21 0B3C;0B21 0B3C;0B21 0B3C;0B21 0B3C; +0B5D;0B22 0B3C;0B22 0B3C;0B22 0B3C;0B22 0B3C; +0B94;0B94;0B92 0BD7;0B94;0B92 0BD7; +0BCA;0BCA;0BC6 0BBE;0BCA;0BC6 0BBE; +0BCB;0BCB;0BC7 0BBE;0BCB;0BC7 0BBE; +0BCC;0BCC;0BC6 0BD7;0BCC;0BC6 0BD7; +0C48;0C48;0C46 0C56;0C48;0C46 0C56; +0CC0;0CC0;0CBF 0CD5;0CC0;0CBF 0CD5; +0CC7;0CC7;0CC6 0CD5;0CC7;0CC6 0CD5; +0CC8;0CC8;0CC6 0CD6;0CC8;0CC6 0CD6; +0CCA;0CCA;0CC6 0CC2;0CCA;0CC6 0CC2; +0CCB;0CCB;0CC6 0CC2 0CD5;0CCB;0CC6 0CC2 0CD5; +0D4A;0D4A;0D46 0D3E;0D4A;0D46 0D3E; +0D4B;0D4B;0D47 0D3E;0D4B;0D47 0D3E; +0D4C;0D4C;0D46 0D57;0D4C;0D46 0D57; +0DDA;0DDA;0DD9 0DCA;0DDA;0DD9 0DCA; +0DDC;0DDC;0DD9 0DCF;0DDC;0DD9 0DCF; +0DDD;0DDD;0DD9 0DCF 0DCA;0DDD;0DD9 0DCF 0DCA; +0DDE;0DDE;0DD9 0DDF;0DDE;0DD9 0DDF; +0E33;0E33;0E33;0E4D 0E32;0E4D 0E32; +0EB3;0EB3;0EB3;0ECD 0EB2;0ECD 0EB2; +0EDC;0EDC;0EDC;0EAB 0E99;0EAB 0E99; +0EDD;0EDD;0EDD;0EAB 0EA1;0EAB 0EA1; +0F0C;0F0C;0F0C;0F0B;0F0B; +0F43;0F42 0FB7;0F42 0FB7;0F42 0FB7;0F42 0FB7; +0F4D;0F4C 0FB7;0F4C 0FB7;0F4C 0FB7;0F4C 0FB7; +0F52;0F51 0FB7;0F51 0FB7;0F51 0FB7;0F51 0FB7; +0F57;0F56 0FB7;0F56 0FB7;0F56 0FB7;0F56 0FB7; +0F5C;0F5B 0FB7;0F5B 0FB7;0F5B 0FB7;0F5B 0FB7; +0F69;0F40 0FB5;0F40 0FB5;0F40 0FB5;0F40 0FB5; +0F73;0F71 0F72;0F71 0F72;0F71 0F72;0F71 0F72; +0F75;0F71 0F74;0F71 0F74;0F71 0F74;0F71 0F74; +0F76;0FB2 0F80;0FB2 0F80;0FB2 0F80;0FB2 0F80; +0F77;0F77;0F77;0FB2 0F71 0F80;0FB2 0F71 0F80; +0F78;0FB3 0F80;0FB3 0F80;0FB3 0F80;0FB3 0F80; +0F79;0F79;0F79;0FB3 0F71 0F80;0FB3 0F71 0F80; +0F81;0F71 0F80;0F71 0F80;0F71 0F80;0F71 0F80; +0F93;0F92 0FB7;0F92 0FB7;0F92 0FB7;0F92 0FB7; +0F9D;0F9C 0FB7;0F9C 0FB7;0F9C 0FB7;0F9C 0FB7; +0FA2;0FA1 0FB7;0FA1 0FB7;0FA1 0FB7;0FA1 0FB7; +0FA7;0FA6 0FB7;0FA6 0FB7;0FA6 0FB7;0FA6 0FB7; +0FAC;0FAB 0FB7;0FAB 0FB7;0FAB 0FB7;0FAB 0FB7; +0FB9;0F90 0FB5;0F90 0FB5;0F90 0FB5;0F90 0FB5; +1026;1026;1025 102E;1026;1025 102E; +10FC;10FC;10FC;10DC;10DC; +1B06;1B06;1B05 1B35;1B06;1B05 1B35; +1B08;1B08;1B07 1B35;1B08;1B07 1B35; +1B0A;1B0A;1B09 1B35;1B0A;1B09 1B35; +1B0C;1B0C;1B0B 1B35;1B0C;1B0B 1B35; +1B0E;1B0E;1B0D 1B35;1B0E;1B0D 1B35; +1B12;1B12;1B11 1B35;1B12;1B11 1B35; +1B3B;1B3B;1B3A 1B35;1B3B;1B3A 1B35; +1B3D;1B3D;1B3C 1B35;1B3D;1B3C 1B35; +1B40;1B40;1B3E 1B35;1B40;1B3E 1B35; +1B41;1B41;1B3F 1B35;1B41;1B3F 1B35; +1B43;1B43;1B42 1B35;1B43;1B42 1B35; +1D2C;1D2C;1D2C;0041;0041; +1D2D;1D2D;1D2D;00C6;00C6; +1D2E;1D2E;1D2E;0042;0042; +1D30;1D30;1D30;0044;0044; +1D31;1D31;1D31;0045;0045; +1D32;1D32;1D32;018E;018E; +1D33;1D33;1D33;0047;0047; +1D34;1D34;1D34;0048;0048; +1D35;1D35;1D35;0049;0049; +1D36;1D36;1D36;004A;004A; +1D37;1D37;1D37;004B;004B; +1D38;1D38;1D38;004C;004C; +1D39;1D39;1D39;004D;004D; +1D3A;1D3A;1D3A;004E;004E; +1D3C;1D3C;1D3C;004F;004F; +1D3D;1D3D;1D3D;0222;0222; +1D3E;1D3E;1D3E;0050;0050; +1D3F;1D3F;1D3F;0052;0052; +1D40;1D40;1D40;0054;0054; +1D41;1D41;1D41;0055;0055; +1D42;1D42;1D42;0057;0057; +1D43;1D43;1D43;0061;0061; +1D44;1D44;1D44;0250;0250; +1D45;1D45;1D45;0251;0251; +1D46;1D46;1D46;1D02;1D02; +1D47;1D47;1D47;0062;0062; +1D48;1D48;1D48;0064;0064; +1D49;1D49;1D49;0065;0065; +1D4A;1D4A;1D4A;0259;0259; +1D4B;1D4B;1D4B;025B;025B; +1D4C;1D4C;1D4C;025C;025C; +1D4D;1D4D;1D4D;0067;0067; +1D4F;1D4F;1D4F;006B;006B; +1D50;1D50;1D50;006D;006D; +1D51;1D51;1D51;014B;014B; +1D52;1D52;1D52;006F;006F; +1D53;1D53;1D53;0254;0254; +1D54;1D54;1D54;1D16;1D16; +1D55;1D55;1D55;1D17;1D17; +1D56;1D56;1D56;0070;0070; +1D57;1D57;1D57;0074;0074; +1D58;1D58;1D58;0075;0075; +1D59;1D59;1D59;1D1D;1D1D; +1D5A;1D5A;1D5A;026F;026F; +1D5B;1D5B;1D5B;0076;0076; +1D5C;1D5C;1D5C;1D25;1D25; +1D5D;1D5D;1D5D;03B2;03B2; +1D5E;1D5E;1D5E;03B3;03B3; +1D5F;1D5F;1D5F;03B4;03B4; +1D60;1D60;1D60;03C6;03C6; +1D61;1D61;1D61;03C7;03C7; +1D62;1D62;1D62;0069;0069; +1D63;1D63;1D63;0072;0072; +1D64;1D64;1D64;0075;0075; +1D65;1D65;1D65;0076;0076; +1D66;1D66;1D66;03B2;03B2; +1D67;1D67;1D67;03B3;03B3; +1D68;1D68;1D68;03C1;03C1; +1D69;1D69;1D69;03C6;03C6; +1D6A;1D6A;1D6A;03C7;03C7; +1D78;1D78;1D78;043D;043D; +1D9B;1D9B;1D9B;0252;0252; +1D9C;1D9C;1D9C;0063;0063; +1D9D;1D9D;1D9D;0255;0255; +1D9E;1D9E;1D9E;00F0;00F0; +1D9F;1D9F;1D9F;025C;025C; +1DA0;1DA0;1DA0;0066;0066; +1DA1;1DA1;1DA1;025F;025F; +1DA2;1DA2;1DA2;0261;0261; +1DA3;1DA3;1DA3;0265;0265; +1DA4;1DA4;1DA4;0268;0268; +1DA5;1DA5;1DA5;0269;0269; +1DA6;1DA6;1DA6;026A;026A; +1DA7;1DA7;1DA7;1D7B;1D7B; +1DA8;1DA8;1DA8;029D;029D; +1DA9;1DA9;1DA9;026D;026D; +1DAA;1DAA;1DAA;1D85;1D85; +1DAB;1DAB;1DAB;029F;029F; +1DAC;1DAC;1DAC;0271;0271; +1DAD;1DAD;1DAD;0270;0270; +1DAE;1DAE;1DAE;0272;0272; +1DAF;1DAF;1DAF;0273;0273; +1DB0;1DB0;1DB0;0274;0274; +1DB1;1DB1;1DB1;0275;0275; +1DB2;1DB2;1DB2;0278;0278; +1DB3;1DB3;1DB3;0282;0282; +1DB4;1DB4;1DB4;0283;0283; +1DB5;1DB5;1DB5;01AB;01AB; +1DB6;1DB6;1DB6;0289;0289; +1DB7;1DB7;1DB7;028A;028A; +1DB8;1DB8;1DB8;1D1C;1D1C; +1DB9;1DB9;1DB9;028B;028B; +1DBA;1DBA;1DBA;028C;028C; +1DBB;1DBB;1DBB;007A;007A; +1DBC;1DBC;1DBC;0290;0290; +1DBD;1DBD;1DBD;0291;0291; +1DBE;1DBE;1DBE;0292;0292; +1DBF;1DBF;1DBF;03B8;03B8; +1E00;1E00;0041 0325;1E00;0041 0325; +1E01;1E01;0061 0325;1E01;0061 0325; +1E02;1E02;0042 0307;1E02;0042 0307; +1E03;1E03;0062 0307;1E03;0062 0307; +1E04;1E04;0042 0323;1E04;0042 0323; +1E05;1E05;0062 0323;1E05;0062 0323; +1E06;1E06;0042 0331;1E06;0042 0331; +1E07;1E07;0062 0331;1E07;0062 0331; +1E08;1E08;0043 0327 0301;1E08;0043 0327 0301; +1E09;1E09;0063 0327 0301;1E09;0063 0327 0301; +1E0A;1E0A;0044 0307;1E0A;0044 0307; +1E0B;1E0B;0064 0307;1E0B;0064 0307; +1E0C;1E0C;0044 0323;1E0C;0044 0323; +1E0D;1E0D;0064 0323;1E0D;0064 0323; +1E0E;1E0E;0044 0331;1E0E;0044 0331; +1E0F;1E0F;0064 0331;1E0F;0064 0331; +1E10;1E10;0044 0327;1E10;0044 0327; +1E11;1E11;0064 0327;1E11;0064 0327; +1E12;1E12;0044 032D;1E12;0044 032D; +1E13;1E13;0064 032D;1E13;0064 032D; +1E14;1E14;0045 0304 0300;1E14;0045 0304 0300; +1E15;1E15;0065 0304 0300;1E15;0065 0304 0300; +1E16;1E16;0045 0304 0301;1E16;0045 0304 0301; +1E17;1E17;0065 0304 0301;1E17;0065 0304 0301; +1E18;1E18;0045 032D;1E18;0045 032D; +1E19;1E19;0065 032D;1E19;0065 032D; +1E1A;1E1A;0045 0330;1E1A;0045 0330; +1E1B;1E1B;0065 0330;1E1B;0065 0330; +1E1C;1E1C;0045 0327 0306;1E1C;0045 0327 0306; +1E1D;1E1D;0065 0327 0306;1E1D;0065 0327 0306; +1E1E;1E1E;0046 0307;1E1E;0046 0307; +1E1F;1E1F;0066 0307;1E1F;0066 0307; +1E20;1E20;0047 0304;1E20;0047 0304; +1E21;1E21;0067 0304;1E21;0067 0304; +1E22;1E22;0048 0307;1E22;0048 0307; +1E23;1E23;0068 0307;1E23;0068 0307; +1E24;1E24;0048 0323;1E24;0048 0323; +1E25;1E25;0068 0323;1E25;0068 0323; +1E26;1E26;0048 0308;1E26;0048 0308; +1E27;1E27;0068 0308;1E27;0068 0308; +1E28;1E28;0048 0327;1E28;0048 0327; +1E29;1E29;0068 0327;1E29;0068 0327; +1E2A;1E2A;0048 032E;1E2A;0048 032E; +1E2B;1E2B;0068 032E;1E2B;0068 032E; +1E2C;1E2C;0049 0330;1E2C;0049 0330; +1E2D;1E2D;0069 0330;1E2D;0069 0330; +1E2E;1E2E;0049 0308 0301;1E2E;0049 0308 0301; +1E2F;1E2F;0069 0308 0301;1E2F;0069 0308 0301; +1E30;1E30;004B 0301;1E30;004B 0301; +1E31;1E31;006B 0301;1E31;006B 0301; +1E32;1E32;004B 0323;1E32;004B 0323; +1E33;1E33;006B 0323;1E33;006B 0323; +1E34;1E34;004B 0331;1E34;004B 0331; +1E35;1E35;006B 0331;1E35;006B 0331; +1E36;1E36;004C 0323;1E36;004C 0323; +1E37;1E37;006C 0323;1E37;006C 0323; +1E38;1E38;004C 0323 0304;1E38;004C 0323 0304; +1E39;1E39;006C 0323 0304;1E39;006C 0323 0304; +1E3A;1E3A;004C 0331;1E3A;004C 0331; +1E3B;1E3B;006C 0331;1E3B;006C 0331; +1E3C;1E3C;004C 032D;1E3C;004C 032D; +1E3D;1E3D;006C 032D;1E3D;006C 032D; +1E3E;1E3E;004D 0301;1E3E;004D 0301; +1E3F;1E3F;006D 0301;1E3F;006D 0301; +1E40;1E40;004D 0307;1E40;004D 0307; +1E41;1E41;006D 0307;1E41;006D 0307; +1E42;1E42;004D 0323;1E42;004D 0323; +1E43;1E43;006D 0323;1E43;006D 0323; +1E44;1E44;004E 0307;1E44;004E 0307; +1E45;1E45;006E 0307;1E45;006E 0307; +1E46;1E46;004E 0323;1E46;004E 0323; +1E47;1E47;006E 0323;1E47;006E 0323; +1E48;1E48;004E 0331;1E48;004E 0331; +1E49;1E49;006E 0331;1E49;006E 0331; +1E4A;1E4A;004E 032D;1E4A;004E 032D; +1E4B;1E4B;006E 032D;1E4B;006E 032D; +1E4C;1E4C;004F 0303 0301;1E4C;004F 0303 0301; +1E4D;1E4D;006F 0303 0301;1E4D;006F 0303 0301; +1E4E;1E4E;004F 0303 0308;1E4E;004F 0303 0308; +1E4F;1E4F;006F 0303 0308;1E4F;006F 0303 0308; +1E50;1E50;004F 0304 0300;1E50;004F 0304 0300; +1E51;1E51;006F 0304 0300;1E51;006F 0304 0300; +1E52;1E52;004F 0304 0301;1E52;004F 0304 0301; +1E53;1E53;006F 0304 0301;1E53;006F 0304 0301; +1E54;1E54;0050 0301;1E54;0050 0301; +1E55;1E55;0070 0301;1E55;0070 0301; +1E56;1E56;0050 0307;1E56;0050 0307; +1E57;1E57;0070 0307;1E57;0070 0307; +1E58;1E58;0052 0307;1E58;0052 0307; +1E59;1E59;0072 0307;1E59;0072 0307; +1E5A;1E5A;0052 0323;1E5A;0052 0323; +1E5B;1E5B;0072 0323;1E5B;0072 0323; +1E5C;1E5C;0052 0323 0304;1E5C;0052 0323 0304; +1E5D;1E5D;0072 0323 0304;1E5D;0072 0323 0304; +1E5E;1E5E;0052 0331;1E5E;0052 0331; +1E5F;1E5F;0072 0331;1E5F;0072 0331; +1E60;1E60;0053 0307;1E60;0053 0307; +1E61;1E61;0073 0307;1E61;0073 0307; +1E62;1E62;0053 0323;1E62;0053 0323; +1E63;1E63;0073 0323;1E63;0073 0323; +1E64;1E64;0053 0301 0307;1E64;0053 0301 0307; +1E65;1E65;0073 0301 0307;1E65;0073 0301 0307; +1E66;1E66;0053 030C 0307;1E66;0053 030C 0307; +1E67;1E67;0073 030C 0307;1E67;0073 030C 0307; +1E68;1E68;0053 0323 0307;1E68;0053 0323 0307; +1E69;1E69;0073 0323 0307;1E69;0073 0323 0307; +1E6A;1E6A;0054 0307;1E6A;0054 0307; +1E6B;1E6B;0074 0307;1E6B;0074 0307; +1E6C;1E6C;0054 0323;1E6C;0054 0323; +1E6D;1E6D;0074 0323;1E6D;0074 0323; +1E6E;1E6E;0054 0331;1E6E;0054 0331; +1E6F;1E6F;0074 0331;1E6F;0074 0331; +1E70;1E70;0054 032D;1E70;0054 032D; +1E71;1E71;0074 032D;1E71;0074 032D; +1E72;1E72;0055 0324;1E72;0055 0324; +1E73;1E73;0075 0324;1E73;0075 0324; +1E74;1E74;0055 0330;1E74;0055 0330; +1E75;1E75;0075 0330;1E75;0075 0330; +1E76;1E76;0055 032D;1E76;0055 032D; +1E77;1E77;0075 032D;1E77;0075 032D; +1E78;1E78;0055 0303 0301;1E78;0055 0303 0301; +1E79;1E79;0075 0303 0301;1E79;0075 0303 0301; +1E7A;1E7A;0055 0304 0308;1E7A;0055 0304 0308; +1E7B;1E7B;0075 0304 0308;1E7B;0075 0304 0308; +1E7C;1E7C;0056 0303;1E7C;0056 0303; +1E7D;1E7D;0076 0303;1E7D;0076 0303; +1E7E;1E7E;0056 0323;1E7E;0056 0323; +1E7F;1E7F;0076 0323;1E7F;0076 0323; +1E80;1E80;0057 0300;1E80;0057 0300; +1E81;1E81;0077 0300;1E81;0077 0300; +1E82;1E82;0057 0301;1E82;0057 0301; +1E83;1E83;0077 0301;1E83;0077 0301; +1E84;1E84;0057 0308;1E84;0057 0308; +1E85;1E85;0077 0308;1E85;0077 0308; +1E86;1E86;0057 0307;1E86;0057 0307; +1E87;1E87;0077 0307;1E87;0077 0307; +1E88;1E88;0057 0323;1E88;0057 0323; +1E89;1E89;0077 0323;1E89;0077 0323; +1E8A;1E8A;0058 0307;1E8A;0058 0307; +1E8B;1E8B;0078 0307;1E8B;0078 0307; +1E8C;1E8C;0058 0308;1E8C;0058 0308; +1E8D;1E8D;0078 0308;1E8D;0078 0308; +1E8E;1E8E;0059 0307;1E8E;0059 0307; +1E8F;1E8F;0079 0307;1E8F;0079 0307; +1E90;1E90;005A 0302;1E90;005A 0302; +1E91;1E91;007A 0302;1E91;007A 0302; +1E92;1E92;005A 0323;1E92;005A 0323; +1E93;1E93;007A 0323;1E93;007A 0323; +1E94;1E94;005A 0331;1E94;005A 0331; +1E95;1E95;007A 0331;1E95;007A 0331; +1E96;1E96;0068 0331;1E96;0068 0331; +1E97;1E97;0074 0308;1E97;0074 0308; +1E98;1E98;0077 030A;1E98;0077 030A; +1E99;1E99;0079 030A;1E99;0079 030A; +1E9A;1E9A;1E9A;0061 02BE;0061 02BE; +1E9B;1E9B;017F 0307;1E61;0073 0307; +1EA0;1EA0;0041 0323;1EA0;0041 0323; +1EA1;1EA1;0061 0323;1EA1;0061 0323; +1EA2;1EA2;0041 0309;1EA2;0041 0309; +1EA3;1EA3;0061 0309;1EA3;0061 0309; +1EA4;1EA4;0041 0302 0301;1EA4;0041 0302 0301; +1EA5;1EA5;0061 0302 0301;1EA5;0061 0302 0301; +1EA6;1EA6;0041 0302 0300;1EA6;0041 0302 0300; +1EA7;1EA7;0061 0302 0300;1EA7;0061 0302 0300; +1EA8;1EA8;0041 0302 0309;1EA8;0041 0302 0309; +1EA9;1EA9;0061 0302 0309;1EA9;0061 0302 0309; +1EAA;1EAA;0041 0302 0303;1EAA;0041 0302 0303; +1EAB;1EAB;0061 0302 0303;1EAB;0061 0302 0303; +1EAC;1EAC;0041 0323 0302;1EAC;0041 0323 0302; +1EAD;1EAD;0061 0323 0302;1EAD;0061 0323 0302; +1EAE;1EAE;0041 0306 0301;1EAE;0041 0306 0301; +1EAF;1EAF;0061 0306 0301;1EAF;0061 0306 0301; +1EB0;1EB0;0041 0306 0300;1EB0;0041 0306 0300; +1EB1;1EB1;0061 0306 0300;1EB1;0061 0306 0300; +1EB2;1EB2;0041 0306 0309;1EB2;0041 0306 0309; +1EB3;1EB3;0061 0306 0309;1EB3;0061 0306 0309; +1EB4;1EB4;0041 0306 0303;1EB4;0041 0306 0303; +1EB5;1EB5;0061 0306 0303;1EB5;0061 0306 0303; +1EB6;1EB6;0041 0323 0306;1EB6;0041 0323 0306; +1EB7;1EB7;0061 0323 0306;1EB7;0061 0323 0306; +1EB8;1EB8;0045 0323;1EB8;0045 0323; +1EB9;1EB9;0065 0323;1EB9;0065 0323; +1EBA;1EBA;0045 0309;1EBA;0045 0309; +1EBB;1EBB;0065 0309;1EBB;0065 0309; +1EBC;1EBC;0045 0303;1EBC;0045 0303; +1EBD;1EBD;0065 0303;1EBD;0065 0303; +1EBE;1EBE;0045 0302 0301;1EBE;0045 0302 0301; +1EBF;1EBF;0065 0302 0301;1EBF;0065 0302 0301; +1EC0;1EC0;0045 0302 0300;1EC0;0045 0302 0300; +1EC1;1EC1;0065 0302 0300;1EC1;0065 0302 0300; +1EC2;1EC2;0045 0302 0309;1EC2;0045 0302 0309; +1EC3;1EC3;0065 0302 0309;1EC3;0065 0302 0309; +1EC4;1EC4;0045 0302 0303;1EC4;0045 0302 0303; +1EC5;1EC5;0065 0302 0303;1EC5;0065 0302 0303; +1EC6;1EC6;0045 0323 0302;1EC6;0045 0323 0302; +1EC7;1EC7;0065 0323 0302;1EC7;0065 0323 0302; +1EC8;1EC8;0049 0309;1EC8;0049 0309; +1EC9;1EC9;0069 0309;1EC9;0069 0309; +1ECA;1ECA;0049 0323;1ECA;0049 0323; +1ECB;1ECB;0069 0323;1ECB;0069 0323; +1ECC;1ECC;004F 0323;1ECC;004F 0323; +1ECD;1ECD;006F 0323;1ECD;006F 0323; +1ECE;1ECE;004F 0309;1ECE;004F 0309; +1ECF;1ECF;006F 0309;1ECF;006F 0309; +1ED0;1ED0;004F 0302 0301;1ED0;004F 0302 0301; +1ED1;1ED1;006F 0302 0301;1ED1;006F 0302 0301; +1ED2;1ED2;004F 0302 0300;1ED2;004F 0302 0300; +1ED3;1ED3;006F 0302 0300;1ED3;006F 0302 0300; +1ED4;1ED4;004F 0302 0309;1ED4;004F 0302 0309; +1ED5;1ED5;006F 0302 0309;1ED5;006F 0302 0309; +1ED6;1ED6;004F 0302 0303;1ED6;004F 0302 0303; +1ED7;1ED7;006F 0302 0303;1ED7;006F 0302 0303; +1ED8;1ED8;004F 0323 0302;1ED8;004F 0323 0302; +1ED9;1ED9;006F 0323 0302;1ED9;006F 0323 0302; +1EDA;1EDA;004F 031B 0301;1EDA;004F 031B 0301; +1EDB;1EDB;006F 031B 0301;1EDB;006F 031B 0301; +1EDC;1EDC;004F 031B 0300;1EDC;004F 031B 0300; +1EDD;1EDD;006F 031B 0300;1EDD;006F 031B 0300; +1EDE;1EDE;004F 031B 0309;1EDE;004F 031B 0309; +1EDF;1EDF;006F 031B 0309;1EDF;006F 031B 0309; +1EE0;1EE0;004F 031B 0303;1EE0;004F 031B 0303; +1EE1;1EE1;006F 031B 0303;1EE1;006F 031B 0303; +1EE2;1EE2;004F 031B 0323;1EE2;004F 031B 0323; +1EE3;1EE3;006F 031B 0323;1EE3;006F 031B 0323; +1EE4;1EE4;0055 0323;1EE4;0055 0323; +1EE5;1EE5;0075 0323;1EE5;0075 0323; +1EE6;1EE6;0055 0309;1EE6;0055 0309; +1EE7;1EE7;0075 0309;1EE7;0075 0309; +1EE8;1EE8;0055 031B 0301;1EE8;0055 031B 0301; +1EE9;1EE9;0075 031B 0301;1EE9;0075 031B 0301; +1EEA;1EEA;0055 031B 0300;1EEA;0055 031B 0300; +1EEB;1EEB;0075 031B 0300;1EEB;0075 031B 0300; +1EEC;1EEC;0055 031B 0309;1EEC;0055 031B 0309; +1EED;1EED;0075 031B 0309;1EED;0075 031B 0309; +1EEE;1EEE;0055 031B 0303;1EEE;0055 031B 0303; +1EEF;1EEF;0075 031B 0303;1EEF;0075 031B 0303; +1EF0;1EF0;0055 031B 0323;1EF0;0055 031B 0323; +1EF1;1EF1;0075 031B 0323;1EF1;0075 031B 0323; +1EF2;1EF2;0059 0300;1EF2;0059 0300; +1EF3;1EF3;0079 0300;1EF3;0079 0300; +1EF4;1EF4;0059 0323;1EF4;0059 0323; +1EF5;1EF5;0079 0323;1EF5;0079 0323; +1EF6;1EF6;0059 0309;1EF6;0059 0309; +1EF7;1EF7;0079 0309;1EF7;0079 0309; +1EF8;1EF8;0059 0303;1EF8;0059 0303; +1EF9;1EF9;0079 0303;1EF9;0079 0303; +1F00;1F00;03B1 0313;1F00;03B1 0313; +1F01;1F01;03B1 0314;1F01;03B1 0314; +1F02;1F02;03B1 0313 0300;1F02;03B1 0313 0300; +1F03;1F03;03B1 0314 0300;1F03;03B1 0314 0300; +1F04;1F04;03B1 0313 0301;1F04;03B1 0313 0301; +1F05;1F05;03B1 0314 0301;1F05;03B1 0314 0301; +1F06;1F06;03B1 0313 0342;1F06;03B1 0313 0342; +1F07;1F07;03B1 0314 0342;1F07;03B1 0314 0342; +1F08;1F08;0391 0313;1F08;0391 0313; +1F09;1F09;0391 0314;1F09;0391 0314; +1F0A;1F0A;0391 0313 0300;1F0A;0391 0313 0300; +1F0B;1F0B;0391 0314 0300;1F0B;0391 0314 0300; +1F0C;1F0C;0391 0313 0301;1F0C;0391 0313 0301; +1F0D;1F0D;0391 0314 0301;1F0D;0391 0314 0301; +1F0E;1F0E;0391 0313 0342;1F0E;0391 0313 0342; +1F0F;1F0F;0391 0314 0342;1F0F;0391 0314 0342; +1F10;1F10;03B5 0313;1F10;03B5 0313; +1F11;1F11;03B5 0314;1F11;03B5 0314; +1F12;1F12;03B5 0313 0300;1F12;03B5 0313 0300; +1F13;1F13;03B5 0314 0300;1F13;03B5 0314 0300; +1F14;1F14;03B5 0313 0301;1F14;03B5 0313 0301; +1F15;1F15;03B5 0314 0301;1F15;03B5 0314 0301; +1F18;1F18;0395 0313;1F18;0395 0313; +1F19;1F19;0395 0314;1F19;0395 0314; +1F1A;1F1A;0395 0313 0300;1F1A;0395 0313 0300; +1F1B;1F1B;0395 0314 0300;1F1B;0395 0314 0300; +1F1C;1F1C;0395 0313 0301;1F1C;0395 0313 0301; +1F1D;1F1D;0395 0314 0301;1F1D;0395 0314 0301; +1F20;1F20;03B7 0313;1F20;03B7 0313; +1F21;1F21;03B7 0314;1F21;03B7 0314; +1F22;1F22;03B7 0313 0300;1F22;03B7 0313 0300; +1F23;1F23;03B7 0314 0300;1F23;03B7 0314 0300; +1F24;1F24;03B7 0313 0301;1F24;03B7 0313 0301; +1F25;1F25;03B7 0314 0301;1F25;03B7 0314 0301; +1F26;1F26;03B7 0313 0342;1F26;03B7 0313 0342; +1F27;1F27;03B7 0314 0342;1F27;03B7 0314 0342; +1F28;1F28;0397 0313;1F28;0397 0313; +1F29;1F29;0397 0314;1F29;0397 0314; +1F2A;1F2A;0397 0313 0300;1F2A;0397 0313 0300; +1F2B;1F2B;0397 0314 0300;1F2B;0397 0314 0300; +1F2C;1F2C;0397 0313 0301;1F2C;0397 0313 0301; +1F2D;1F2D;0397 0314 0301;1F2D;0397 0314 0301; +1F2E;1F2E;0397 0313 0342;1F2E;0397 0313 0342; +1F2F;1F2F;0397 0314 0342;1F2F;0397 0314 0342; +1F30;1F30;03B9 0313;1F30;03B9 0313; +1F31;1F31;03B9 0314;1F31;03B9 0314; +1F32;1F32;03B9 0313 0300;1F32;03B9 0313 0300; +1F33;1F33;03B9 0314 0300;1F33;03B9 0314 0300; +1F34;1F34;03B9 0313 0301;1F34;03B9 0313 0301; +1F35;1F35;03B9 0314 0301;1F35;03B9 0314 0301; +1F36;1F36;03B9 0313 0342;1F36;03B9 0313 0342; +1F37;1F37;03B9 0314 0342;1F37;03B9 0314 0342; +1F38;1F38;0399 0313;1F38;0399 0313; +1F39;1F39;0399 0314;1F39;0399 0314; +1F3A;1F3A;0399 0313 0300;1F3A;0399 0313 0300; +1F3B;1F3B;0399 0314 0300;1F3B;0399 0314 0300; +1F3C;1F3C;0399 0313 0301;1F3C;0399 0313 0301; +1F3D;1F3D;0399 0314 0301;1F3D;0399 0314 0301; +1F3E;1F3E;0399 0313 0342;1F3E;0399 0313 0342; +1F3F;1F3F;0399 0314 0342;1F3F;0399 0314 0342; +1F40;1F40;03BF 0313;1F40;03BF 0313; +1F41;1F41;03BF 0314;1F41;03BF 0314; +1F42;1F42;03BF 0313 0300;1F42;03BF 0313 0300; +1F43;1F43;03BF 0314 0300;1F43;03BF 0314 0300; +1F44;1F44;03BF 0313 0301;1F44;03BF 0313 0301; +1F45;1F45;03BF 0314 0301;1F45;03BF 0314 0301; +1F48;1F48;039F 0313;1F48;039F 0313; +1F49;1F49;039F 0314;1F49;039F 0314; +1F4A;1F4A;039F 0313 0300;1F4A;039F 0313 0300; +1F4B;1F4B;039F 0314 0300;1F4B;039F 0314 0300; +1F4C;1F4C;039F 0313 0301;1F4C;039F 0313 0301; +1F4D;1F4D;039F 0314 0301;1F4D;039F 0314 0301; +1F50;1F50;03C5 0313;1F50;03C5 0313; +1F51;1F51;03C5 0314;1F51;03C5 0314; +1F52;1F52;03C5 0313 0300;1F52;03C5 0313 0300; +1F53;1F53;03C5 0314 0300;1F53;03C5 0314 0300; +1F54;1F54;03C5 0313 0301;1F54;03C5 0313 0301; +1F55;1F55;03C5 0314 0301;1F55;03C5 0314 0301; +1F56;1F56;03C5 0313 0342;1F56;03C5 0313 0342; +1F57;1F57;03C5 0314 0342;1F57;03C5 0314 0342; +1F59;1F59;03A5 0314;1F59;03A5 0314; +1F5B;1F5B;03A5 0314 0300;1F5B;03A5 0314 0300; +1F5D;1F5D;03A5 0314 0301;1F5D;03A5 0314 0301; +1F5F;1F5F;03A5 0314 0342;1F5F;03A5 0314 0342; +1F60;1F60;03C9 0313;1F60;03C9 0313; +1F61;1F61;03C9 0314;1F61;03C9 0314; +1F62;1F62;03C9 0313 0300;1F62;03C9 0313 0300; +1F63;1F63;03C9 0314 0300;1F63;03C9 0314 0300; +1F64;1F64;03C9 0313 0301;1F64;03C9 0313 0301; +1F65;1F65;03C9 0314 0301;1F65;03C9 0314 0301; +1F66;1F66;03C9 0313 0342;1F66;03C9 0313 0342; +1F67;1F67;03C9 0314 0342;1F67;03C9 0314 0342; +1F68;1F68;03A9 0313;1F68;03A9 0313; +1F69;1F69;03A9 0314;1F69;03A9 0314; +1F6A;1F6A;03A9 0313 0300;1F6A;03A9 0313 0300; +1F6B;1F6B;03A9 0314 0300;1F6B;03A9 0314 0300; +1F6C;1F6C;03A9 0313 0301;1F6C;03A9 0313 0301; +1F6D;1F6D;03A9 0314 0301;1F6D;03A9 0314 0301; +1F6E;1F6E;03A9 0313 0342;1F6E;03A9 0313 0342; +1F6F;1F6F;03A9 0314 0342;1F6F;03A9 0314 0342; +1F70;1F70;03B1 0300;1F70;03B1 0300; +1F71;03AC;03B1 0301;03AC;03B1 0301; +1F72;1F72;03B5 0300;1F72;03B5 0300; +1F73;03AD;03B5 0301;03AD;03B5 0301; +1F74;1F74;03B7 0300;1F74;03B7 0300; +1F75;03AE;03B7 0301;03AE;03B7 0301; +1F76;1F76;03B9 0300;1F76;03B9 0300; +1F77;03AF;03B9 0301;03AF;03B9 0301; +1F78;1F78;03BF 0300;1F78;03BF 0300; +1F79;03CC;03BF 0301;03CC;03BF 0301; +1F7A;1F7A;03C5 0300;1F7A;03C5 0300; +1F7B;03CD;03C5 0301;03CD;03C5 0301; +1F7C;1F7C;03C9 0300;1F7C;03C9 0300; +1F7D;03CE;03C9 0301;03CE;03C9 0301; +1F80;1F80;03B1 0313 0345;1F80;03B1 0313 0345; +1F81;1F81;03B1 0314 0345;1F81;03B1 0314 0345; +1F82;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; +1F83;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; +1F84;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; +1F85;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; +1F86;1F86;03B1 0313 0342 0345;1F86;03B1 0313 0342 0345; +1F87;1F87;03B1 0314 0342 0345;1F87;03B1 0314 0342 0345; +1F88;1F88;0391 0313 0345;1F88;0391 0313 0345; +1F89;1F89;0391 0314 0345;1F89;0391 0314 0345; +1F8A;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; +1F8B;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; +1F8C;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; +1F8D;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; +1F8E;1F8E;0391 0313 0342 0345;1F8E;0391 0313 0342 0345; +1F8F;1F8F;0391 0314 0342 0345;1F8F;0391 0314 0342 0345; +1F90;1F90;03B7 0313 0345;1F90;03B7 0313 0345; +1F91;1F91;03B7 0314 0345;1F91;03B7 0314 0345; +1F92;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; +1F93;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; +1F94;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; +1F95;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; +1F96;1F96;03B7 0313 0342 0345;1F96;03B7 0313 0342 0345; +1F97;1F97;03B7 0314 0342 0345;1F97;03B7 0314 0342 0345; +1F98;1F98;0397 0313 0345;1F98;0397 0313 0345; +1F99;1F99;0397 0314 0345;1F99;0397 0314 0345; +1F9A;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; +1F9B;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; +1F9C;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; +1F9D;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; +1F9E;1F9E;0397 0313 0342 0345;1F9E;0397 0313 0342 0345; +1F9F;1F9F;0397 0314 0342 0345;1F9F;0397 0314 0342 0345; +1FA0;1FA0;03C9 0313 0345;1FA0;03C9 0313 0345; +1FA1;1FA1;03C9 0314 0345;1FA1;03C9 0314 0345; +1FA2;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; +1FA3;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; +1FA4;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; +1FA5;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; +1FA6;1FA6;03C9 0313 0342 0345;1FA6;03C9 0313 0342 0345; +1FA7;1FA7;03C9 0314 0342 0345;1FA7;03C9 0314 0342 0345; +1FA8;1FA8;03A9 0313 0345;1FA8;03A9 0313 0345; +1FA9;1FA9;03A9 0314 0345;1FA9;03A9 0314 0345; +1FAA;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; +1FAB;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; +1FAC;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; +1FAD;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; +1FAE;1FAE;03A9 0313 0342 0345;1FAE;03A9 0313 0342 0345; +1FAF;1FAF;03A9 0314 0342 0345;1FAF;03A9 0314 0342 0345; +1FB0;1FB0;03B1 0306;1FB0;03B1 0306; +1FB1;1FB1;03B1 0304;1FB1;03B1 0304; +1FB2;1FB2;03B1 0300 0345;1FB2;03B1 0300 0345; +1FB3;1FB3;03B1 0345;1FB3;03B1 0345; +1FB4;1FB4;03B1 0301 0345;1FB4;03B1 0301 0345; +1FB6;1FB6;03B1 0342;1FB6;03B1 0342; +1FB7;1FB7;03B1 0342 0345;1FB7;03B1 0342 0345; +1FB8;1FB8;0391 0306;1FB8;0391 0306; +1FB9;1FB9;0391 0304;1FB9;0391 0304; +1FBA;1FBA;0391 0300;1FBA;0391 0300; +1FBB;0386;0391 0301;0386;0391 0301; +1FBC;1FBC;0391 0345;1FBC;0391 0345; +1FBD;1FBD;1FBD;0020 0313;0020 0313; +1FBE;03B9;03B9;03B9;03B9; +1FBF;1FBF;1FBF;0020 0313;0020 0313; +1FC0;1FC0;1FC0;0020 0342;0020 0342; +1FC1;1FC1;00A8 0342;0020 0308 0342;0020 0308 0342; +1FC2;1FC2;03B7 0300 0345;1FC2;03B7 0300 0345; +1FC3;1FC3;03B7 0345;1FC3;03B7 0345; +1FC4;1FC4;03B7 0301 0345;1FC4;03B7 0301 0345; +1FC6;1FC6;03B7 0342;1FC6;03B7 0342; +1FC7;1FC7;03B7 0342 0345;1FC7;03B7 0342 0345; +1FC8;1FC8;0395 0300;1FC8;0395 0300; +1FC9;0388;0395 0301;0388;0395 0301; +1FCA;1FCA;0397 0300;1FCA;0397 0300; +1FCB;0389;0397 0301;0389;0397 0301; +1FCC;1FCC;0397 0345;1FCC;0397 0345; +1FCD;1FCD;1FBF 0300;0020 0313 0300;0020 0313 0300; +1FCE;1FCE;1FBF 0301;0020 0313 0301;0020 0313 0301; +1FCF;1FCF;1FBF 0342;0020 0313 0342;0020 0313 0342; +1FD0;1FD0;03B9 0306;1FD0;03B9 0306; +1FD1;1FD1;03B9 0304;1FD1;03B9 0304; +1FD2;1FD2;03B9 0308 0300;1FD2;03B9 0308 0300; +1FD3;0390;03B9 0308 0301;0390;03B9 0308 0301; +1FD6;1FD6;03B9 0342;1FD6;03B9 0342; +1FD7;1FD7;03B9 0308 0342;1FD7;03B9 0308 0342; +1FD8;1FD8;0399 0306;1FD8;0399 0306; +1FD9;1FD9;0399 0304;1FD9;0399 0304; +1FDA;1FDA;0399 0300;1FDA;0399 0300; +1FDB;038A;0399 0301;038A;0399 0301; +1FDD;1FDD;1FFE 0300;0020 0314 0300;0020 0314 0300; +1FDE;1FDE;1FFE 0301;0020 0314 0301;0020 0314 0301; +1FDF;1FDF;1FFE 0342;0020 0314 0342;0020 0314 0342; +1FE0;1FE0;03C5 0306;1FE0;03C5 0306; +1FE1;1FE1;03C5 0304;1FE1;03C5 0304; +1FE2;1FE2;03C5 0308 0300;1FE2;03C5 0308 0300; +1FE3;03B0;03C5 0308 0301;03B0;03C5 0308 0301; +1FE4;1FE4;03C1 0313;1FE4;03C1 0313; +1FE5;1FE5;03C1 0314;1FE5;03C1 0314; +1FE6;1FE6;03C5 0342;1FE6;03C5 0342; +1FE7;1FE7;03C5 0308 0342;1FE7;03C5 0308 0342; +1FE8;1FE8;03A5 0306;1FE8;03A5 0306; +1FE9;1FE9;03A5 0304;1FE9;03A5 0304; +1FEA;1FEA;03A5 0300;1FEA;03A5 0300; +1FEB;038E;03A5 0301;038E;03A5 0301; +1FEC;1FEC;03A1 0314;1FEC;03A1 0314; +1FED;1FED;00A8 0300;0020 0308 0300;0020 0308 0300; +1FEE;0385;00A8 0301;0020 0308 0301;0020 0308 0301; +1FEF;0060;0060;0060;0060; +1FF2;1FF2;03C9 0300 0345;1FF2;03C9 0300 0345; +1FF3;1FF3;03C9 0345;1FF3;03C9 0345; +1FF4;1FF4;03C9 0301 0345;1FF4;03C9 0301 0345; +1FF6;1FF6;03C9 0342;1FF6;03C9 0342; +1FF7;1FF7;03C9 0342 0345;1FF7;03C9 0342 0345; +1FF8;1FF8;039F 0300;1FF8;039F 0300; +1FF9;038C;039F 0301;038C;039F 0301; +1FFA;1FFA;03A9 0300;1FFA;03A9 0300; +1FFB;038F;03A9 0301;038F;03A9 0301; +1FFC;1FFC;03A9 0345;1FFC;03A9 0345; +1FFD;00B4;00B4;0020 0301;0020 0301; +1FFE;1FFE;1FFE;0020 0314;0020 0314; +2000;2002;2002;0020;0020; +2001;2003;2003;0020;0020; +2002;2002;2002;0020;0020; +2003;2003;2003;0020;0020; +2004;2004;2004;0020;0020; +2005;2005;2005;0020;0020; +2006;2006;2006;0020;0020; +2007;2007;2007;0020;0020; +2008;2008;2008;0020;0020; +2009;2009;2009;0020;0020; +200A;200A;200A;0020;0020; +2011;2011;2011;2010;2010; +2017;2017;2017;0020 0333;0020 0333; +2024;2024;2024;002E;002E; +2025;2025;2025;002E 002E;002E 002E; +2026;2026;2026;002E 002E 002E;002E 002E 002E; +202F;202F;202F;0020;0020; +2033;2033;2033;2032 2032;2032 2032; +2034;2034;2034;2032 2032 2032;2032 2032 2032; +2036;2036;2036;2035 2035;2035 2035; +2037;2037;2037;2035 2035 2035;2035 2035 2035; +203C;203C;203C;0021 0021;0021 0021; +203E;203E;203E;0020 0305;0020 0305; +2047;2047;2047;003F 003F;003F 003F; +2048;2048;2048;003F 0021;003F 0021; +2049;2049;2049;0021 003F;0021 003F; +2057;2057;2057;2032 2032 2032 2032;2032 2032 2032 2032; +205F;205F;205F;0020;0020; +2070;2070;2070;0030;0030; +2071;2071;2071;0069;0069; +2074;2074;2074;0034;0034; +2075;2075;2075;0035;0035; +2076;2076;2076;0036;0036; +2077;2077;2077;0037;0037; +2078;2078;2078;0038;0038; +2079;2079;2079;0039;0039; +207A;207A;207A;002B;002B; +207B;207B;207B;2212;2212; +207C;207C;207C;003D;003D; +207D;207D;207D;0028;0028; +207E;207E;207E;0029;0029; +207F;207F;207F;006E;006E; +2080;2080;2080;0030;0030; +2081;2081;2081;0031;0031; +2082;2082;2082;0032;0032; +2083;2083;2083;0033;0033; +2084;2084;2084;0034;0034; +2085;2085;2085;0035;0035; +2086;2086;2086;0036;0036; +2087;2087;2087;0037;0037; +2088;2088;2088;0038;0038; +2089;2089;2089;0039;0039; +208A;208A;208A;002B;002B; +208B;208B;208B;2212;2212; +208C;208C;208C;003D;003D; +208D;208D;208D;0028;0028; +208E;208E;208E;0029;0029; +2090;2090;2090;0061;0061; +2091;2091;2091;0065;0065; +2092;2092;2092;006F;006F; +2093;2093;2093;0078;0078; +2094;2094;2094;0259;0259; +2095;2095;2095;0068;0068; +2096;2096;2096;006B;006B; +2097;2097;2097;006C;006C; +2098;2098;2098;006D;006D; +2099;2099;2099;006E;006E; +209A;209A;209A;0070;0070; +209B;209B;209B;0073;0073; +209C;209C;209C;0074;0074; +20A8;20A8;20A8;0052 0073;0052 0073; +2100;2100;2100;0061 002F 0063;0061 002F 0063; +2101;2101;2101;0061 002F 0073;0061 002F 0073; +2102;2102;2102;0043;0043; +2103;2103;2103;00B0 0043;00B0 0043; +2105;2105;2105;0063 002F 006F;0063 002F 006F; +2106;2106;2106;0063 002F 0075;0063 002F 0075; +2107;2107;2107;0190;0190; +2109;2109;2109;00B0 0046;00B0 0046; +210A;210A;210A;0067;0067; +210B;210B;210B;0048;0048; +210C;210C;210C;0048;0048; +210D;210D;210D;0048;0048; +210E;210E;210E;0068;0068; +210F;210F;210F;0127;0127; +2110;2110;2110;0049;0049; +2111;2111;2111;0049;0049; +2112;2112;2112;004C;004C; +2113;2113;2113;006C;006C; +2115;2115;2115;004E;004E; +2116;2116;2116;004E 006F;004E 006F; +2119;2119;2119;0050;0050; +211A;211A;211A;0051;0051; +211B;211B;211B;0052;0052; +211C;211C;211C;0052;0052; +211D;211D;211D;0052;0052; +2120;2120;2120;0053 004D;0053 004D; +2121;2121;2121;0054 0045 004C;0054 0045 004C; +2122;2122;2122;0054 004D;0054 004D; +2124;2124;2124;005A;005A; +2126;03A9;03A9;03A9;03A9; +2128;2128;2128;005A;005A; +212A;004B;004B;004B;004B; +212B;00C5;0041 030A;00C5;0041 030A; +212C;212C;212C;0042;0042; +212D;212D;212D;0043;0043; +212F;212F;212F;0065;0065; +2130;2130;2130;0045;0045; +2131;2131;2131;0046;0046; +2133;2133;2133;004D;004D; +2134;2134;2134;006F;006F; +2135;2135;2135;05D0;05D0; +2136;2136;2136;05D1;05D1; +2137;2137;2137;05D2;05D2; +2138;2138;2138;05D3;05D3; +2139;2139;2139;0069;0069; +213B;213B;213B;0046 0041 0058;0046 0041 0058; +213C;213C;213C;03C0;03C0; +213D;213D;213D;03B3;03B3; +213E;213E;213E;0393;0393; +213F;213F;213F;03A0;03A0; +2140;2140;2140;2211;2211; +2145;2145;2145;0044;0044; +2146;2146;2146;0064;0064; +2147;2147;2147;0065;0065; +2148;2148;2148;0069;0069; +2149;2149;2149;006A;006A; +2150;2150;2150;0031 2044 0037;0031 2044 0037; +2151;2151;2151;0031 2044 0039;0031 2044 0039; +2152;2152;2152;0031 2044 0031 0030;0031 2044 0031 0030; +2153;2153;2153;0031 2044 0033;0031 2044 0033; +2154;2154;2154;0032 2044 0033;0032 2044 0033; +2155;2155;2155;0031 2044 0035;0031 2044 0035; +2156;2156;2156;0032 2044 0035;0032 2044 0035; +2157;2157;2157;0033 2044 0035;0033 2044 0035; +2158;2158;2158;0034 2044 0035;0034 2044 0035; +2159;2159;2159;0031 2044 0036;0031 2044 0036; +215A;215A;215A;0035 2044 0036;0035 2044 0036; +215B;215B;215B;0031 2044 0038;0031 2044 0038; +215C;215C;215C;0033 2044 0038;0033 2044 0038; +215D;215D;215D;0035 2044 0038;0035 2044 0038; +215E;215E;215E;0037 2044 0038;0037 2044 0038; +215F;215F;215F;0031 2044;0031 2044; +2160;2160;2160;0049;0049; +2161;2161;2161;0049 0049;0049 0049; +2162;2162;2162;0049 0049 0049;0049 0049 0049; +2163;2163;2163;0049 0056;0049 0056; +2164;2164;2164;0056;0056; +2165;2165;2165;0056 0049;0056 0049; +2166;2166;2166;0056 0049 0049;0056 0049 0049; +2167;2167;2167;0056 0049 0049 0049;0056 0049 0049 0049; +2168;2168;2168;0049 0058;0049 0058; +2169;2169;2169;0058;0058; +216A;216A;216A;0058 0049;0058 0049; +216B;216B;216B;0058 0049 0049;0058 0049 0049; +216C;216C;216C;004C;004C; +216D;216D;216D;0043;0043; +216E;216E;216E;0044;0044; +216F;216F;216F;004D;004D; +2170;2170;2170;0069;0069; +2171;2171;2171;0069 0069;0069 0069; +2172;2172;2172;0069 0069 0069;0069 0069 0069; +2173;2173;2173;0069 0076;0069 0076; +2174;2174;2174;0076;0076; +2175;2175;2175;0076 0069;0076 0069; +2176;2176;2176;0076 0069 0069;0076 0069 0069; +2177;2177;2177;0076 0069 0069 0069;0076 0069 0069 0069; +2178;2178;2178;0069 0078;0069 0078; +2179;2179;2179;0078;0078; +217A;217A;217A;0078 0069;0078 0069; +217B;217B;217B;0078 0069 0069;0078 0069 0069; +217C;217C;217C;006C;006C; +217D;217D;217D;0063;0063; +217E;217E;217E;0064;0064; +217F;217F;217F;006D;006D; +2189;2189;2189;0030 2044 0033;0030 2044 0033; +219A;219A;2190 0338;219A;2190 0338; +219B;219B;2192 0338;219B;2192 0338; +21AE;21AE;2194 0338;21AE;2194 0338; +21CD;21CD;21D0 0338;21CD;21D0 0338; +21CE;21CE;21D4 0338;21CE;21D4 0338; +21CF;21CF;21D2 0338;21CF;21D2 0338; +2204;2204;2203 0338;2204;2203 0338; +2209;2209;2208 0338;2209;2208 0338; +220C;220C;220B 0338;220C;220B 0338; +2224;2224;2223 0338;2224;2223 0338; +2226;2226;2225 0338;2226;2225 0338; +222C;222C;222C;222B 222B;222B 222B; +222D;222D;222D;222B 222B 222B;222B 222B 222B; +222F;222F;222F;222E 222E;222E 222E; +2230;2230;2230;222E 222E 222E;222E 222E 222E; +2241;2241;223C 0338;2241;223C 0338; +2244;2244;2243 0338;2244;2243 0338; +2247;2247;2245 0338;2247;2245 0338; +2249;2249;2248 0338;2249;2248 0338; +2260;2260;003D 0338;2260;003D 0338; +2262;2262;2261 0338;2262;2261 0338; +226D;226D;224D 0338;226D;224D 0338; +226E;226E;003C 0338;226E;003C 0338; +226F;226F;003E 0338;226F;003E 0338; +2270;2270;2264 0338;2270;2264 0338; +2271;2271;2265 0338;2271;2265 0338; +2274;2274;2272 0338;2274;2272 0338; +2275;2275;2273 0338;2275;2273 0338; +2278;2278;2276 0338;2278;2276 0338; +2279;2279;2277 0338;2279;2277 0338; +2280;2280;227A 0338;2280;227A 0338; +2281;2281;227B 0338;2281;227B 0338; +2284;2284;2282 0338;2284;2282 0338; +2285;2285;2283 0338;2285;2283 0338; +2288;2288;2286 0338;2288;2286 0338; +2289;2289;2287 0338;2289;2287 0338; +22AC;22AC;22A2 0338;22AC;22A2 0338; +22AD;22AD;22A8 0338;22AD;22A8 0338; +22AE;22AE;22A9 0338;22AE;22A9 0338; +22AF;22AF;22AB 0338;22AF;22AB 0338; +22E0;22E0;227C 0338;22E0;227C 0338; +22E1;22E1;227D 0338;22E1;227D 0338; +22E2;22E2;2291 0338;22E2;2291 0338; +22E3;22E3;2292 0338;22E3;2292 0338; +22EA;22EA;22B2 0338;22EA;22B2 0338; +22EB;22EB;22B3 0338;22EB;22B3 0338; +22EC;22EC;22B4 0338;22EC;22B4 0338; +22ED;22ED;22B5 0338;22ED;22B5 0338; +2329;3008;3008;3008;3008; +232A;3009;3009;3009;3009; +2460;2460;2460;0031;0031; +2461;2461;2461;0032;0032; +2462;2462;2462;0033;0033; +2463;2463;2463;0034;0034; +2464;2464;2464;0035;0035; +2465;2465;2465;0036;0036; +2466;2466;2466;0037;0037; +2467;2467;2467;0038;0038; +2468;2468;2468;0039;0039; +2469;2469;2469;0031 0030;0031 0030; +246A;246A;246A;0031 0031;0031 0031; +246B;246B;246B;0031 0032;0031 0032; +246C;246C;246C;0031 0033;0031 0033; +246D;246D;246D;0031 0034;0031 0034; +246E;246E;246E;0031 0035;0031 0035; +246F;246F;246F;0031 0036;0031 0036; +2470;2470;2470;0031 0037;0031 0037; +2471;2471;2471;0031 0038;0031 0038; +2472;2472;2472;0031 0039;0031 0039; +2473;2473;2473;0032 0030;0032 0030; +2474;2474;2474;0028 0031 0029;0028 0031 0029; +2475;2475;2475;0028 0032 0029;0028 0032 0029; +2476;2476;2476;0028 0033 0029;0028 0033 0029; +2477;2477;2477;0028 0034 0029;0028 0034 0029; +2478;2478;2478;0028 0035 0029;0028 0035 0029; +2479;2479;2479;0028 0036 0029;0028 0036 0029; +247A;247A;247A;0028 0037 0029;0028 0037 0029; +247B;247B;247B;0028 0038 0029;0028 0038 0029; +247C;247C;247C;0028 0039 0029;0028 0039 0029; +247D;247D;247D;0028 0031 0030 0029;0028 0031 0030 0029; +247E;247E;247E;0028 0031 0031 0029;0028 0031 0031 0029; +247F;247F;247F;0028 0031 0032 0029;0028 0031 0032 0029; +2480;2480;2480;0028 0031 0033 0029;0028 0031 0033 0029; +2481;2481;2481;0028 0031 0034 0029;0028 0031 0034 0029; +2482;2482;2482;0028 0031 0035 0029;0028 0031 0035 0029; +2483;2483;2483;0028 0031 0036 0029;0028 0031 0036 0029; +2484;2484;2484;0028 0031 0037 0029;0028 0031 0037 0029; +2485;2485;2485;0028 0031 0038 0029;0028 0031 0038 0029; +2486;2486;2486;0028 0031 0039 0029;0028 0031 0039 0029; +2487;2487;2487;0028 0032 0030 0029;0028 0032 0030 0029; +2488;2488;2488;0031 002E;0031 002E; +2489;2489;2489;0032 002E;0032 002E; +248A;248A;248A;0033 002E;0033 002E; +248B;248B;248B;0034 002E;0034 002E; +248C;248C;248C;0035 002E;0035 002E; +248D;248D;248D;0036 002E;0036 002E; +248E;248E;248E;0037 002E;0037 002E; +248F;248F;248F;0038 002E;0038 002E; +2490;2490;2490;0039 002E;0039 002E; +2491;2491;2491;0031 0030 002E;0031 0030 002E; +2492;2492;2492;0031 0031 002E;0031 0031 002E; +2493;2493;2493;0031 0032 002E;0031 0032 002E; +2494;2494;2494;0031 0033 002E;0031 0033 002E; +2495;2495;2495;0031 0034 002E;0031 0034 002E; +2496;2496;2496;0031 0035 002E;0031 0035 002E; +2497;2497;2497;0031 0036 002E;0031 0036 002E; +2498;2498;2498;0031 0037 002E;0031 0037 002E; +2499;2499;2499;0031 0038 002E;0031 0038 002E; +249A;249A;249A;0031 0039 002E;0031 0039 002E; +249B;249B;249B;0032 0030 002E;0032 0030 002E; +249C;249C;249C;0028 0061 0029;0028 0061 0029; +249D;249D;249D;0028 0062 0029;0028 0062 0029; +249E;249E;249E;0028 0063 0029;0028 0063 0029; +249F;249F;249F;0028 0064 0029;0028 0064 0029; +24A0;24A0;24A0;0028 0065 0029;0028 0065 0029; +24A1;24A1;24A1;0028 0066 0029;0028 0066 0029; +24A2;24A2;24A2;0028 0067 0029;0028 0067 0029; +24A3;24A3;24A3;0028 0068 0029;0028 0068 0029; +24A4;24A4;24A4;0028 0069 0029;0028 0069 0029; +24A5;24A5;24A5;0028 006A 0029;0028 006A 0029; +24A6;24A6;24A6;0028 006B 0029;0028 006B 0029; +24A7;24A7;24A7;0028 006C 0029;0028 006C 0029; +24A8;24A8;24A8;0028 006D 0029;0028 006D 0029; +24A9;24A9;24A9;0028 006E 0029;0028 006E 0029; +24AA;24AA;24AA;0028 006F 0029;0028 006F 0029; +24AB;24AB;24AB;0028 0070 0029;0028 0070 0029; +24AC;24AC;24AC;0028 0071 0029;0028 0071 0029; +24AD;24AD;24AD;0028 0072 0029;0028 0072 0029; +24AE;24AE;24AE;0028 0073 0029;0028 0073 0029; +24AF;24AF;24AF;0028 0074 0029;0028 0074 0029; +24B0;24B0;24B0;0028 0075 0029;0028 0075 0029; +24B1;24B1;24B1;0028 0076 0029;0028 0076 0029; +24B2;24B2;24B2;0028 0077 0029;0028 0077 0029; +24B3;24B3;24B3;0028 0078 0029;0028 0078 0029; +24B4;24B4;24B4;0028 0079 0029;0028 0079 0029; +24B5;24B5;24B5;0028 007A 0029;0028 007A 0029; +24B6;24B6;24B6;0041;0041; +24B7;24B7;24B7;0042;0042; +24B8;24B8;24B8;0043;0043; +24B9;24B9;24B9;0044;0044; +24BA;24BA;24BA;0045;0045; +24BB;24BB;24BB;0046;0046; +24BC;24BC;24BC;0047;0047; +24BD;24BD;24BD;0048;0048; +24BE;24BE;24BE;0049;0049; +24BF;24BF;24BF;004A;004A; +24C0;24C0;24C0;004B;004B; +24C1;24C1;24C1;004C;004C; +24C2;24C2;24C2;004D;004D; +24C3;24C3;24C3;004E;004E; +24C4;24C4;24C4;004F;004F; +24C5;24C5;24C5;0050;0050; +24C6;24C6;24C6;0051;0051; +24C7;24C7;24C7;0052;0052; +24C8;24C8;24C8;0053;0053; +24C9;24C9;24C9;0054;0054; +24CA;24CA;24CA;0055;0055; +24CB;24CB;24CB;0056;0056; +24CC;24CC;24CC;0057;0057; +24CD;24CD;24CD;0058;0058; +24CE;24CE;24CE;0059;0059; +24CF;24CF;24CF;005A;005A; +24D0;24D0;24D0;0061;0061; +24D1;24D1;24D1;0062;0062; +24D2;24D2;24D2;0063;0063; +24D3;24D3;24D3;0064;0064; +24D4;24D4;24D4;0065;0065; +24D5;24D5;24D5;0066;0066; +24D6;24D6;24D6;0067;0067; +24D7;24D7;24D7;0068;0068; +24D8;24D8;24D8;0069;0069; +24D9;24D9;24D9;006A;006A; +24DA;24DA;24DA;006B;006B; +24DB;24DB;24DB;006C;006C; +24DC;24DC;24DC;006D;006D; +24DD;24DD;24DD;006E;006E; +24DE;24DE;24DE;006F;006F; +24DF;24DF;24DF;0070;0070; +24E0;24E0;24E0;0071;0071; +24E1;24E1;24E1;0072;0072; +24E2;24E2;24E2;0073;0073; +24E3;24E3;24E3;0074;0074; +24E4;24E4;24E4;0075;0075; +24E5;24E5;24E5;0076;0076; +24E6;24E6;24E6;0077;0077; +24E7;24E7;24E7;0078;0078; +24E8;24E8;24E8;0079;0079; +24E9;24E9;24E9;007A;007A; +24EA;24EA;24EA;0030;0030; +2A0C;2A0C;2A0C;222B 222B 222B 222B;222B 222B 222B 222B; +2A74;2A74;2A74;003A 003A 003D;003A 003A 003D; +2A75;2A75;2A75;003D 003D;003D 003D; +2A76;2A76;2A76;003D 003D 003D;003D 003D 003D; +2ADC;2ADD 0338;2ADD 0338;2ADD 0338;2ADD 0338; +2C7C;2C7C;2C7C;006A;006A; +2C7D;2C7D;2C7D;0056;0056; +2D6F;2D6F;2D6F;2D61;2D61; +2E9F;2E9F;2E9F;6BCD;6BCD; +2EF3;2EF3;2EF3;9F9F;9F9F; +2F00;2F00;2F00;4E00;4E00; +2F01;2F01;2F01;4E28;4E28; +2F02;2F02;2F02;4E36;4E36; +2F03;2F03;2F03;4E3F;4E3F; +2F04;2F04;2F04;4E59;4E59; +2F05;2F05;2F05;4E85;4E85; +2F06;2F06;2F06;4E8C;4E8C; +2F07;2F07;2F07;4EA0;4EA0; +2F08;2F08;2F08;4EBA;4EBA; +2F09;2F09;2F09;513F;513F; +2F0A;2F0A;2F0A;5165;5165; +2F0B;2F0B;2F0B;516B;516B; +2F0C;2F0C;2F0C;5182;5182; +2F0D;2F0D;2F0D;5196;5196; +2F0E;2F0E;2F0E;51AB;51AB; +2F0F;2F0F;2F0F;51E0;51E0; +2F10;2F10;2F10;51F5;51F5; +2F11;2F11;2F11;5200;5200; +2F12;2F12;2F12;529B;529B; +2F13;2F13;2F13;52F9;52F9; +2F14;2F14;2F14;5315;5315; +2F15;2F15;2F15;531A;531A; +2F16;2F16;2F16;5338;5338; +2F17;2F17;2F17;5341;5341; +2F18;2F18;2F18;535C;535C; +2F19;2F19;2F19;5369;5369; +2F1A;2F1A;2F1A;5382;5382; +2F1B;2F1B;2F1B;53B6;53B6; +2F1C;2F1C;2F1C;53C8;53C8; +2F1D;2F1D;2F1D;53E3;53E3; +2F1E;2F1E;2F1E;56D7;56D7; +2F1F;2F1F;2F1F;571F;571F; +2F20;2F20;2F20;58EB;58EB; +2F21;2F21;2F21;5902;5902; +2F22;2F22;2F22;590A;590A; +2F23;2F23;2F23;5915;5915; +2F24;2F24;2F24;5927;5927; +2F25;2F25;2F25;5973;5973; +2F26;2F26;2F26;5B50;5B50; +2F27;2F27;2F27;5B80;5B80; +2F28;2F28;2F28;5BF8;5BF8; +2F29;2F29;2F29;5C0F;5C0F; +2F2A;2F2A;2F2A;5C22;5C22; +2F2B;2F2B;2F2B;5C38;5C38; +2F2C;2F2C;2F2C;5C6E;5C6E; +2F2D;2F2D;2F2D;5C71;5C71; +2F2E;2F2E;2F2E;5DDB;5DDB; +2F2F;2F2F;2F2F;5DE5;5DE5; +2F30;2F30;2F30;5DF1;5DF1; +2F31;2F31;2F31;5DFE;5DFE; +2F32;2F32;2F32;5E72;5E72; +2F33;2F33;2F33;5E7A;5E7A; +2F34;2F34;2F34;5E7F;5E7F; +2F35;2F35;2F35;5EF4;5EF4; +2F36;2F36;2F36;5EFE;5EFE; +2F37;2F37;2F37;5F0B;5F0B; +2F38;2F38;2F38;5F13;5F13; +2F39;2F39;2F39;5F50;5F50; +2F3A;2F3A;2F3A;5F61;5F61; +2F3B;2F3B;2F3B;5F73;5F73; +2F3C;2F3C;2F3C;5FC3;5FC3; +2F3D;2F3D;2F3D;6208;6208; +2F3E;2F3E;2F3E;6236;6236; +2F3F;2F3F;2F3F;624B;624B; +2F40;2F40;2F40;652F;652F; +2F41;2F41;2F41;6534;6534; +2F42;2F42;2F42;6587;6587; +2F43;2F43;2F43;6597;6597; +2F44;2F44;2F44;65A4;65A4; +2F45;2F45;2F45;65B9;65B9; +2F46;2F46;2F46;65E0;65E0; +2F47;2F47;2F47;65E5;65E5; +2F48;2F48;2F48;66F0;66F0; +2F49;2F49;2F49;6708;6708; +2F4A;2F4A;2F4A;6728;6728; +2F4B;2F4B;2F4B;6B20;6B20; +2F4C;2F4C;2F4C;6B62;6B62; +2F4D;2F4D;2F4D;6B79;6B79; +2F4E;2F4E;2F4E;6BB3;6BB3; +2F4F;2F4F;2F4F;6BCB;6BCB; +2F50;2F50;2F50;6BD4;6BD4; +2F51;2F51;2F51;6BDB;6BDB; +2F52;2F52;2F52;6C0F;6C0F; +2F53;2F53;2F53;6C14;6C14; +2F54;2F54;2F54;6C34;6C34; +2F55;2F55;2F55;706B;706B; +2F56;2F56;2F56;722A;722A; +2F57;2F57;2F57;7236;7236; +2F58;2F58;2F58;723B;723B; +2F59;2F59;2F59;723F;723F; +2F5A;2F5A;2F5A;7247;7247; +2F5B;2F5B;2F5B;7259;7259; +2F5C;2F5C;2F5C;725B;725B; +2F5D;2F5D;2F5D;72AC;72AC; +2F5E;2F5E;2F5E;7384;7384; +2F5F;2F5F;2F5F;7389;7389; +2F60;2F60;2F60;74DC;74DC; +2F61;2F61;2F61;74E6;74E6; +2F62;2F62;2F62;7518;7518; +2F63;2F63;2F63;751F;751F; +2F64;2F64;2F64;7528;7528; +2F65;2F65;2F65;7530;7530; +2F66;2F66;2F66;758B;758B; +2F67;2F67;2F67;7592;7592; +2F68;2F68;2F68;7676;7676; +2F69;2F69;2F69;767D;767D; +2F6A;2F6A;2F6A;76AE;76AE; +2F6B;2F6B;2F6B;76BF;76BF; +2F6C;2F6C;2F6C;76EE;76EE; +2F6D;2F6D;2F6D;77DB;77DB; +2F6E;2F6E;2F6E;77E2;77E2; +2F6F;2F6F;2F6F;77F3;77F3; +2F70;2F70;2F70;793A;793A; +2F71;2F71;2F71;79B8;79B8; +2F72;2F72;2F72;79BE;79BE; +2F73;2F73;2F73;7A74;7A74; +2F74;2F74;2F74;7ACB;7ACB; +2F75;2F75;2F75;7AF9;7AF9; +2F76;2F76;2F76;7C73;7C73; +2F77;2F77;2F77;7CF8;7CF8; +2F78;2F78;2F78;7F36;7F36; +2F79;2F79;2F79;7F51;7F51; +2F7A;2F7A;2F7A;7F8A;7F8A; +2F7B;2F7B;2F7B;7FBD;7FBD; +2F7C;2F7C;2F7C;8001;8001; +2F7D;2F7D;2F7D;800C;800C; +2F7E;2F7E;2F7E;8012;8012; +2F7F;2F7F;2F7F;8033;8033; +2F80;2F80;2F80;807F;807F; +2F81;2F81;2F81;8089;8089; +2F82;2F82;2F82;81E3;81E3; +2F83;2F83;2F83;81EA;81EA; +2F84;2F84;2F84;81F3;81F3; +2F85;2F85;2F85;81FC;81FC; +2F86;2F86;2F86;820C;820C; +2F87;2F87;2F87;821B;821B; +2F88;2F88;2F88;821F;821F; +2F89;2F89;2F89;826E;826E; +2F8A;2F8A;2F8A;8272;8272; +2F8B;2F8B;2F8B;8278;8278; +2F8C;2F8C;2F8C;864D;864D; +2F8D;2F8D;2F8D;866B;866B; +2F8E;2F8E;2F8E;8840;8840; +2F8F;2F8F;2F8F;884C;884C; +2F90;2F90;2F90;8863;8863; +2F91;2F91;2F91;897E;897E; +2F92;2F92;2F92;898B;898B; +2F93;2F93;2F93;89D2;89D2; +2F94;2F94;2F94;8A00;8A00; +2F95;2F95;2F95;8C37;8C37; +2F96;2F96;2F96;8C46;8C46; +2F97;2F97;2F97;8C55;8C55; +2F98;2F98;2F98;8C78;8C78; +2F99;2F99;2F99;8C9D;8C9D; +2F9A;2F9A;2F9A;8D64;8D64; +2F9B;2F9B;2F9B;8D70;8D70; +2F9C;2F9C;2F9C;8DB3;8DB3; +2F9D;2F9D;2F9D;8EAB;8EAB; +2F9E;2F9E;2F9E;8ECA;8ECA; +2F9F;2F9F;2F9F;8F9B;8F9B; +2FA0;2FA0;2FA0;8FB0;8FB0; +2FA1;2FA1;2FA1;8FB5;8FB5; +2FA2;2FA2;2FA2;9091;9091; +2FA3;2FA3;2FA3;9149;9149; +2FA4;2FA4;2FA4;91C6;91C6; +2FA5;2FA5;2FA5;91CC;91CC; +2FA6;2FA6;2FA6;91D1;91D1; +2FA7;2FA7;2FA7;9577;9577; +2FA8;2FA8;2FA8;9580;9580; +2FA9;2FA9;2FA9;961C;961C; +2FAA;2FAA;2FAA;96B6;96B6; +2FAB;2FAB;2FAB;96B9;96B9; +2FAC;2FAC;2FAC;96E8;96E8; +2FAD;2FAD;2FAD;9751;9751; +2FAE;2FAE;2FAE;975E;975E; +2FAF;2FAF;2FAF;9762;9762; +2FB0;2FB0;2FB0;9769;9769; +2FB1;2FB1;2FB1;97CB;97CB; +2FB2;2FB2;2FB2;97ED;97ED; +2FB3;2FB3;2FB3;97F3;97F3; +2FB4;2FB4;2FB4;9801;9801; +2FB5;2FB5;2FB5;98A8;98A8; +2FB6;2FB6;2FB6;98DB;98DB; +2FB7;2FB7;2FB7;98DF;98DF; +2FB8;2FB8;2FB8;9996;9996; +2FB9;2FB9;2FB9;9999;9999; +2FBA;2FBA;2FBA;99AC;99AC; +2FBB;2FBB;2FBB;9AA8;9AA8; +2FBC;2FBC;2FBC;9AD8;9AD8; +2FBD;2FBD;2FBD;9ADF;9ADF; +2FBE;2FBE;2FBE;9B25;9B25; +2FBF;2FBF;2FBF;9B2F;9B2F; +2FC0;2FC0;2FC0;9B32;9B32; +2FC1;2FC1;2FC1;9B3C;9B3C; +2FC2;2FC2;2FC2;9B5A;9B5A; +2FC3;2FC3;2FC3;9CE5;9CE5; +2FC4;2FC4;2FC4;9E75;9E75; +2FC5;2FC5;2FC5;9E7F;9E7F; +2FC6;2FC6;2FC6;9EA5;9EA5; +2FC7;2FC7;2FC7;9EBB;9EBB; +2FC8;2FC8;2FC8;9EC3;9EC3; +2FC9;2FC9;2FC9;9ECD;9ECD; +2FCA;2FCA;2FCA;9ED1;9ED1; +2FCB;2FCB;2FCB;9EF9;9EF9; +2FCC;2FCC;2FCC;9EFD;9EFD; +2FCD;2FCD;2FCD;9F0E;9F0E; +2FCE;2FCE;2FCE;9F13;9F13; +2FCF;2FCF;2FCF;9F20;9F20; +2FD0;2FD0;2FD0;9F3B;9F3B; +2FD1;2FD1;2FD1;9F4A;9F4A; +2FD2;2FD2;2FD2;9F52;9F52; +2FD3;2FD3;2FD3;9F8D;9F8D; +2FD4;2FD4;2FD4;9F9C;9F9C; +2FD5;2FD5;2FD5;9FA0;9FA0; +3000;3000;3000;0020;0020; +3036;3036;3036;3012;3012; +3038;3038;3038;5341;5341; +3039;3039;3039;5344;5344; +303A;303A;303A;5345;5345; +304C;304C;304B 3099;304C;304B 3099; +304E;304E;304D 3099;304E;304D 3099; +3050;3050;304F 3099;3050;304F 3099; +3052;3052;3051 3099;3052;3051 3099; +3054;3054;3053 3099;3054;3053 3099; +3056;3056;3055 3099;3056;3055 3099; +3058;3058;3057 3099;3058;3057 3099; +305A;305A;3059 3099;305A;3059 3099; +305C;305C;305B 3099;305C;305B 3099; +305E;305E;305D 3099;305E;305D 3099; +3060;3060;305F 3099;3060;305F 3099; +3062;3062;3061 3099;3062;3061 3099; +3065;3065;3064 3099;3065;3064 3099; +3067;3067;3066 3099;3067;3066 3099; +3069;3069;3068 3099;3069;3068 3099; +3070;3070;306F 3099;3070;306F 3099; +3071;3071;306F 309A;3071;306F 309A; +3073;3073;3072 3099;3073;3072 3099; +3074;3074;3072 309A;3074;3072 309A; +3076;3076;3075 3099;3076;3075 3099; +3077;3077;3075 309A;3077;3075 309A; +3079;3079;3078 3099;3079;3078 3099; +307A;307A;3078 309A;307A;3078 309A; +307C;307C;307B 3099;307C;307B 3099; +307D;307D;307B 309A;307D;307B 309A; +3094;3094;3046 3099;3094;3046 3099; +309B;309B;309B;0020 3099;0020 3099; +309C;309C;309C;0020 309A;0020 309A; +309E;309E;309D 3099;309E;309D 3099; +309F;309F;309F;3088 308A;3088 308A; +30AC;30AC;30AB 3099;30AC;30AB 3099; +30AE;30AE;30AD 3099;30AE;30AD 3099; +30B0;30B0;30AF 3099;30B0;30AF 3099; +30B2;30B2;30B1 3099;30B2;30B1 3099; +30B4;30B4;30B3 3099;30B4;30B3 3099; +30B6;30B6;30B5 3099;30B6;30B5 3099; +30B8;30B8;30B7 3099;30B8;30B7 3099; +30BA;30BA;30B9 3099;30BA;30B9 3099; +30BC;30BC;30BB 3099;30BC;30BB 3099; +30BE;30BE;30BD 3099;30BE;30BD 3099; +30C0;30C0;30BF 3099;30C0;30BF 3099; +30C2;30C2;30C1 3099;30C2;30C1 3099; +30C5;30C5;30C4 3099;30C5;30C4 3099; +30C7;30C7;30C6 3099;30C7;30C6 3099; +30C9;30C9;30C8 3099;30C9;30C8 3099; +30D0;30D0;30CF 3099;30D0;30CF 3099; +30D1;30D1;30CF 309A;30D1;30CF 309A; +30D3;30D3;30D2 3099;30D3;30D2 3099; +30D4;30D4;30D2 309A;30D4;30D2 309A; +30D6;30D6;30D5 3099;30D6;30D5 3099; +30D7;30D7;30D5 309A;30D7;30D5 309A; +30D9;30D9;30D8 3099;30D9;30D8 3099; +30DA;30DA;30D8 309A;30DA;30D8 309A; +30DC;30DC;30DB 3099;30DC;30DB 3099; +30DD;30DD;30DB 309A;30DD;30DB 309A; +30F4;30F4;30A6 3099;30F4;30A6 3099; +30F7;30F7;30EF 3099;30F7;30EF 3099; +30F8;30F8;30F0 3099;30F8;30F0 3099; +30F9;30F9;30F1 3099;30F9;30F1 3099; +30FA;30FA;30F2 3099;30FA;30F2 3099; +30FE;30FE;30FD 3099;30FE;30FD 3099; +30FF;30FF;30FF;30B3 30C8;30B3 30C8; +3131;3131;3131;1100;1100; +3132;3132;3132;1101;1101; +3133;3133;3133;11AA;11AA; +3134;3134;3134;1102;1102; +3135;3135;3135;11AC;11AC; +3136;3136;3136;11AD;11AD; +3137;3137;3137;1103;1103; +3138;3138;3138;1104;1104; +3139;3139;3139;1105;1105; +313A;313A;313A;11B0;11B0; +313B;313B;313B;11B1;11B1; +313C;313C;313C;11B2;11B2; +313D;313D;313D;11B3;11B3; +313E;313E;313E;11B4;11B4; +313F;313F;313F;11B5;11B5; +3140;3140;3140;111A;111A; +3141;3141;3141;1106;1106; +3142;3142;3142;1107;1107; +3143;3143;3143;1108;1108; +3144;3144;3144;1121;1121; +3145;3145;3145;1109;1109; +3146;3146;3146;110A;110A; +3147;3147;3147;110B;110B; +3148;3148;3148;110C;110C; +3149;3149;3149;110D;110D; +314A;314A;314A;110E;110E; +314B;314B;314B;110F;110F; +314C;314C;314C;1110;1110; +314D;314D;314D;1111;1111; +314E;314E;314E;1112;1112; +314F;314F;314F;1161;1161; +3150;3150;3150;1162;1162; +3151;3151;3151;1163;1163; +3152;3152;3152;1164;1164; +3153;3153;3153;1165;1165; +3154;3154;3154;1166;1166; +3155;3155;3155;1167;1167; +3156;3156;3156;1168;1168; +3157;3157;3157;1169;1169; +3158;3158;3158;116A;116A; +3159;3159;3159;116B;116B; +315A;315A;315A;116C;116C; +315B;315B;315B;116D;116D; +315C;315C;315C;116E;116E; +315D;315D;315D;116F;116F; +315E;315E;315E;1170;1170; +315F;315F;315F;1171;1171; +3160;3160;3160;1172;1172; +3161;3161;3161;1173;1173; +3162;3162;3162;1174;1174; +3163;3163;3163;1175;1175; +3164;3164;3164;1160;1160; +3165;3165;3165;1114;1114; +3166;3166;3166;1115;1115; +3167;3167;3167;11C7;11C7; +3168;3168;3168;11C8;11C8; +3169;3169;3169;11CC;11CC; +316A;316A;316A;11CE;11CE; +316B;316B;316B;11D3;11D3; +316C;316C;316C;11D7;11D7; +316D;316D;316D;11D9;11D9; +316E;316E;316E;111C;111C; +316F;316F;316F;11DD;11DD; +3170;3170;3170;11DF;11DF; +3171;3171;3171;111D;111D; +3172;3172;3172;111E;111E; +3173;3173;3173;1120;1120; +3174;3174;3174;1122;1122; +3175;3175;3175;1123;1123; +3176;3176;3176;1127;1127; +3177;3177;3177;1129;1129; +3178;3178;3178;112B;112B; +3179;3179;3179;112C;112C; +317A;317A;317A;112D;112D; +317B;317B;317B;112E;112E; +317C;317C;317C;112F;112F; +317D;317D;317D;1132;1132; +317E;317E;317E;1136;1136; +317F;317F;317F;1140;1140; +3180;3180;3180;1147;1147; +3181;3181;3181;114C;114C; +3182;3182;3182;11F1;11F1; +3183;3183;3183;11F2;11F2; +3184;3184;3184;1157;1157; +3185;3185;3185;1158;1158; +3186;3186;3186;1159;1159; +3187;3187;3187;1184;1184; +3188;3188;3188;1185;1185; +3189;3189;3189;1188;1188; +318A;318A;318A;1191;1191; +318B;318B;318B;1192;1192; +318C;318C;318C;1194;1194; +318D;318D;318D;119E;119E; +318E;318E;318E;11A1;11A1; +3192;3192;3192;4E00;4E00; +3193;3193;3193;4E8C;4E8C; +3194;3194;3194;4E09;4E09; +3195;3195;3195;56DB;56DB; +3196;3196;3196;4E0A;4E0A; +3197;3197;3197;4E2D;4E2D; +3198;3198;3198;4E0B;4E0B; +3199;3199;3199;7532;7532; +319A;319A;319A;4E59;4E59; +319B;319B;319B;4E19;4E19; +319C;319C;319C;4E01;4E01; +319D;319D;319D;5929;5929; +319E;319E;319E;5730;5730; +319F;319F;319F;4EBA;4EBA; +3200;3200;3200;0028 1100 0029;0028 1100 0029; +3201;3201;3201;0028 1102 0029;0028 1102 0029; +3202;3202;3202;0028 1103 0029;0028 1103 0029; +3203;3203;3203;0028 1105 0029;0028 1105 0029; +3204;3204;3204;0028 1106 0029;0028 1106 0029; +3205;3205;3205;0028 1107 0029;0028 1107 0029; +3206;3206;3206;0028 1109 0029;0028 1109 0029; +3207;3207;3207;0028 110B 0029;0028 110B 0029; +3208;3208;3208;0028 110C 0029;0028 110C 0029; +3209;3209;3209;0028 110E 0029;0028 110E 0029; +320A;320A;320A;0028 110F 0029;0028 110F 0029; +320B;320B;320B;0028 1110 0029;0028 1110 0029; +320C;320C;320C;0028 1111 0029;0028 1111 0029; +320D;320D;320D;0028 1112 0029;0028 1112 0029; +320E;320E;320E;0028 AC00 0029;0028 1100 1161 0029; +320F;320F;320F;0028 B098 0029;0028 1102 1161 0029; +3210;3210;3210;0028 B2E4 0029;0028 1103 1161 0029; +3211;3211;3211;0028 B77C 0029;0028 1105 1161 0029; +3212;3212;3212;0028 B9C8 0029;0028 1106 1161 0029; +3213;3213;3213;0028 BC14 0029;0028 1107 1161 0029; +3214;3214;3214;0028 C0AC 0029;0028 1109 1161 0029; +3215;3215;3215;0028 C544 0029;0028 110B 1161 0029; +3216;3216;3216;0028 C790 0029;0028 110C 1161 0029; +3217;3217;3217;0028 CC28 0029;0028 110E 1161 0029; +3218;3218;3218;0028 CE74 0029;0028 110F 1161 0029; +3219;3219;3219;0028 D0C0 0029;0028 1110 1161 0029; +321A;321A;321A;0028 D30C 0029;0028 1111 1161 0029; +321B;321B;321B;0028 D558 0029;0028 1112 1161 0029; +321C;321C;321C;0028 C8FC 0029;0028 110C 116E 0029; +321D;321D;321D;0028 C624 C804 0029;0028 110B 1169 110C 1165 11AB 0029; +321E;321E;321E;0028 C624 D6C4 0029;0028 110B 1169 1112 116E 0029; +3220;3220;3220;0028 4E00 0029;0028 4E00 0029; +3221;3221;3221;0028 4E8C 0029;0028 4E8C 0029; +3222;3222;3222;0028 4E09 0029;0028 4E09 0029; +3223;3223;3223;0028 56DB 0029;0028 56DB 0029; +3224;3224;3224;0028 4E94 0029;0028 4E94 0029; +3225;3225;3225;0028 516D 0029;0028 516D 0029; +3226;3226;3226;0028 4E03 0029;0028 4E03 0029; +3227;3227;3227;0028 516B 0029;0028 516B 0029; +3228;3228;3228;0028 4E5D 0029;0028 4E5D 0029; +3229;3229;3229;0028 5341 0029;0028 5341 0029; +322A;322A;322A;0028 6708 0029;0028 6708 0029; +322B;322B;322B;0028 706B 0029;0028 706B 0029; +322C;322C;322C;0028 6C34 0029;0028 6C34 0029; +322D;322D;322D;0028 6728 0029;0028 6728 0029; +322E;322E;322E;0028 91D1 0029;0028 91D1 0029; +322F;322F;322F;0028 571F 0029;0028 571F 0029; +3230;3230;3230;0028 65E5 0029;0028 65E5 0029; +3231;3231;3231;0028 682A 0029;0028 682A 0029; +3232;3232;3232;0028 6709 0029;0028 6709 0029; +3233;3233;3233;0028 793E 0029;0028 793E 0029; +3234;3234;3234;0028 540D 0029;0028 540D 0029; +3235;3235;3235;0028 7279 0029;0028 7279 0029; +3236;3236;3236;0028 8CA1 0029;0028 8CA1 0029; +3237;3237;3237;0028 795D 0029;0028 795D 0029; +3238;3238;3238;0028 52B4 0029;0028 52B4 0029; +3239;3239;3239;0028 4EE3 0029;0028 4EE3 0029; +323A;323A;323A;0028 547C 0029;0028 547C 0029; +323B;323B;323B;0028 5B66 0029;0028 5B66 0029; +323C;323C;323C;0028 76E3 0029;0028 76E3 0029; +323D;323D;323D;0028 4F01 0029;0028 4F01 0029; +323E;323E;323E;0028 8CC7 0029;0028 8CC7 0029; +323F;323F;323F;0028 5354 0029;0028 5354 0029; +3240;3240;3240;0028 796D 0029;0028 796D 0029; +3241;3241;3241;0028 4F11 0029;0028 4F11 0029; +3242;3242;3242;0028 81EA 0029;0028 81EA 0029; +3243;3243;3243;0028 81F3 0029;0028 81F3 0029; +3244;3244;3244;554F;554F; +3245;3245;3245;5E7C;5E7C; +3246;3246;3246;6587;6587; +3247;3247;3247;7B8F;7B8F; +3250;3250;3250;0050 0054 0045;0050 0054 0045; +3251;3251;3251;0032 0031;0032 0031; +3252;3252;3252;0032 0032;0032 0032; +3253;3253;3253;0032 0033;0032 0033; +3254;3254;3254;0032 0034;0032 0034; +3255;3255;3255;0032 0035;0032 0035; +3256;3256;3256;0032 0036;0032 0036; +3257;3257;3257;0032 0037;0032 0037; +3258;3258;3258;0032 0038;0032 0038; +3259;3259;3259;0032 0039;0032 0039; +325A;325A;325A;0033 0030;0033 0030; +325B;325B;325B;0033 0031;0033 0031; +325C;325C;325C;0033 0032;0033 0032; +325D;325D;325D;0033 0033;0033 0033; +325E;325E;325E;0033 0034;0033 0034; +325F;325F;325F;0033 0035;0033 0035; +3260;3260;3260;1100;1100; +3261;3261;3261;1102;1102; +3262;3262;3262;1103;1103; +3263;3263;3263;1105;1105; +3264;3264;3264;1106;1106; +3265;3265;3265;1107;1107; +3266;3266;3266;1109;1109; +3267;3267;3267;110B;110B; +3268;3268;3268;110C;110C; +3269;3269;3269;110E;110E; +326A;326A;326A;110F;110F; +326B;326B;326B;1110;1110; +326C;326C;326C;1111;1111; +326D;326D;326D;1112;1112; +326E;326E;326E;AC00;1100 1161; +326F;326F;326F;B098;1102 1161; +3270;3270;3270;B2E4;1103 1161; +3271;3271;3271;B77C;1105 1161; +3272;3272;3272;B9C8;1106 1161; +3273;3273;3273;BC14;1107 1161; +3274;3274;3274;C0AC;1109 1161; +3275;3275;3275;C544;110B 1161; +3276;3276;3276;C790;110C 1161; +3277;3277;3277;CC28;110E 1161; +3278;3278;3278;CE74;110F 1161; +3279;3279;3279;D0C0;1110 1161; +327A;327A;327A;D30C;1111 1161; +327B;327B;327B;D558;1112 1161; +327C;327C;327C;CC38 ACE0;110E 1161 11B7 1100 1169; +327D;327D;327D;C8FC C758;110C 116E 110B 1174; +327E;327E;327E;C6B0;110B 116E; +3280;3280;3280;4E00;4E00; +3281;3281;3281;4E8C;4E8C; +3282;3282;3282;4E09;4E09; +3283;3283;3283;56DB;56DB; +3284;3284;3284;4E94;4E94; +3285;3285;3285;516D;516D; +3286;3286;3286;4E03;4E03; +3287;3287;3287;516B;516B; +3288;3288;3288;4E5D;4E5D; +3289;3289;3289;5341;5341; +328A;328A;328A;6708;6708; +328B;328B;328B;706B;706B; +328C;328C;328C;6C34;6C34; +328D;328D;328D;6728;6728; +328E;328E;328E;91D1;91D1; +328F;328F;328F;571F;571F; +3290;3290;3290;65E5;65E5; +3291;3291;3291;682A;682A; +3292;3292;3292;6709;6709; +3293;3293;3293;793E;793E; +3294;3294;3294;540D;540D; +3295;3295;3295;7279;7279; +3296;3296;3296;8CA1;8CA1; +3297;3297;3297;795D;795D; +3298;3298;3298;52B4;52B4; +3299;3299;3299;79D8;79D8; +329A;329A;329A;7537;7537; +329B;329B;329B;5973;5973; +329C;329C;329C;9069;9069; +329D;329D;329D;512A;512A; +329E;329E;329E;5370;5370; +329F;329F;329F;6CE8;6CE8; +32A0;32A0;32A0;9805;9805; +32A1;32A1;32A1;4F11;4F11; +32A2;32A2;32A2;5199;5199; +32A3;32A3;32A3;6B63;6B63; +32A4;32A4;32A4;4E0A;4E0A; +32A5;32A5;32A5;4E2D;4E2D; +32A6;32A6;32A6;4E0B;4E0B; +32A7;32A7;32A7;5DE6;5DE6; +32A8;32A8;32A8;53F3;53F3; +32A9;32A9;32A9;533B;533B; +32AA;32AA;32AA;5B97;5B97; +32AB;32AB;32AB;5B66;5B66; +32AC;32AC;32AC;76E3;76E3; +32AD;32AD;32AD;4F01;4F01; +32AE;32AE;32AE;8CC7;8CC7; +32AF;32AF;32AF;5354;5354; +32B0;32B0;32B0;591C;591C; +32B1;32B1;32B1;0033 0036;0033 0036; +32B2;32B2;32B2;0033 0037;0033 0037; +32B3;32B3;32B3;0033 0038;0033 0038; +32B4;32B4;32B4;0033 0039;0033 0039; +32B5;32B5;32B5;0034 0030;0034 0030; +32B6;32B6;32B6;0034 0031;0034 0031; +32B7;32B7;32B7;0034 0032;0034 0032; +32B8;32B8;32B8;0034 0033;0034 0033; +32B9;32B9;32B9;0034 0034;0034 0034; +32BA;32BA;32BA;0034 0035;0034 0035; +32BB;32BB;32BB;0034 0036;0034 0036; +32BC;32BC;32BC;0034 0037;0034 0037; +32BD;32BD;32BD;0034 0038;0034 0038; +32BE;32BE;32BE;0034 0039;0034 0039; +32BF;32BF;32BF;0035 0030;0035 0030; +32C0;32C0;32C0;0031 6708;0031 6708; +32C1;32C1;32C1;0032 6708;0032 6708; +32C2;32C2;32C2;0033 6708;0033 6708; +32C3;32C3;32C3;0034 6708;0034 6708; +32C4;32C4;32C4;0035 6708;0035 6708; +32C5;32C5;32C5;0036 6708;0036 6708; +32C6;32C6;32C6;0037 6708;0037 6708; +32C7;32C7;32C7;0038 6708;0038 6708; +32C8;32C8;32C8;0039 6708;0039 6708; +32C9;32C9;32C9;0031 0030 6708;0031 0030 6708; +32CA;32CA;32CA;0031 0031 6708;0031 0031 6708; +32CB;32CB;32CB;0031 0032 6708;0031 0032 6708; +32CC;32CC;32CC;0048 0067;0048 0067; +32CD;32CD;32CD;0065 0072 0067;0065 0072 0067; +32CE;32CE;32CE;0065 0056;0065 0056; +32CF;32CF;32CF;004C 0054 0044;004C 0054 0044; +32D0;32D0;32D0;30A2;30A2; +32D1;32D1;32D1;30A4;30A4; +32D2;32D2;32D2;30A6;30A6; +32D3;32D3;32D3;30A8;30A8; +32D4;32D4;32D4;30AA;30AA; +32D5;32D5;32D5;30AB;30AB; +32D6;32D6;32D6;30AD;30AD; +32D7;32D7;32D7;30AF;30AF; +32D8;32D8;32D8;30B1;30B1; +32D9;32D9;32D9;30B3;30B3; +32DA;32DA;32DA;30B5;30B5; +32DB;32DB;32DB;30B7;30B7; +32DC;32DC;32DC;30B9;30B9; +32DD;32DD;32DD;30BB;30BB; +32DE;32DE;32DE;30BD;30BD; +32DF;32DF;32DF;30BF;30BF; +32E0;32E0;32E0;30C1;30C1; +32E1;32E1;32E1;30C4;30C4; +32E2;32E2;32E2;30C6;30C6; +32E3;32E3;32E3;30C8;30C8; +32E4;32E4;32E4;30CA;30CA; +32E5;32E5;32E5;30CB;30CB; +32E6;32E6;32E6;30CC;30CC; +32E7;32E7;32E7;30CD;30CD; +32E8;32E8;32E8;30CE;30CE; +32E9;32E9;32E9;30CF;30CF; +32EA;32EA;32EA;30D2;30D2; +32EB;32EB;32EB;30D5;30D5; +32EC;32EC;32EC;30D8;30D8; +32ED;32ED;32ED;30DB;30DB; +32EE;32EE;32EE;30DE;30DE; +32EF;32EF;32EF;30DF;30DF; +32F0;32F0;32F0;30E0;30E0; +32F1;32F1;32F1;30E1;30E1; +32F2;32F2;32F2;30E2;30E2; +32F3;32F3;32F3;30E4;30E4; +32F4;32F4;32F4;30E6;30E6; +32F5;32F5;32F5;30E8;30E8; +32F6;32F6;32F6;30E9;30E9; +32F7;32F7;32F7;30EA;30EA; +32F8;32F8;32F8;30EB;30EB; +32F9;32F9;32F9;30EC;30EC; +32FA;32FA;32FA;30ED;30ED; +32FB;32FB;32FB;30EF;30EF; +32FC;32FC;32FC;30F0;30F0; +32FD;32FD;32FD;30F1;30F1; +32FE;32FE;32FE;30F2;30F2; +3300;3300;3300;30A2 30D1 30FC 30C8;30A2 30CF 309A 30FC 30C8; +3301;3301;3301;30A2 30EB 30D5 30A1;30A2 30EB 30D5 30A1; +3302;3302;3302;30A2 30F3 30DA 30A2;30A2 30F3 30D8 309A 30A2; +3303;3303;3303;30A2 30FC 30EB;30A2 30FC 30EB; +3304;3304;3304;30A4 30CB 30F3 30B0;30A4 30CB 30F3 30AF 3099; +3305;3305;3305;30A4 30F3 30C1;30A4 30F3 30C1; +3306;3306;3306;30A6 30A9 30F3;30A6 30A9 30F3; +3307;3307;3307;30A8 30B9 30AF 30FC 30C9;30A8 30B9 30AF 30FC 30C8 3099; +3308;3308;3308;30A8 30FC 30AB 30FC;30A8 30FC 30AB 30FC; +3309;3309;3309;30AA 30F3 30B9;30AA 30F3 30B9; +330A;330A;330A;30AA 30FC 30E0;30AA 30FC 30E0; +330B;330B;330B;30AB 30A4 30EA;30AB 30A4 30EA; +330C;330C;330C;30AB 30E9 30C3 30C8;30AB 30E9 30C3 30C8; +330D;330D;330D;30AB 30ED 30EA 30FC;30AB 30ED 30EA 30FC; +330E;330E;330E;30AC 30ED 30F3;30AB 3099 30ED 30F3; +330F;330F;330F;30AC 30F3 30DE;30AB 3099 30F3 30DE; +3310;3310;3310;30AE 30AC;30AD 3099 30AB 3099; +3311;3311;3311;30AE 30CB 30FC;30AD 3099 30CB 30FC; +3312;3312;3312;30AD 30E5 30EA 30FC;30AD 30E5 30EA 30FC; +3313;3313;3313;30AE 30EB 30C0 30FC;30AD 3099 30EB 30BF 3099 30FC; +3314;3314;3314;30AD 30ED;30AD 30ED; +3315;3315;3315;30AD 30ED 30B0 30E9 30E0;30AD 30ED 30AF 3099 30E9 30E0; +3316;3316;3316;30AD 30ED 30E1 30FC 30C8 30EB;30AD 30ED 30E1 30FC 30C8 30EB; +3317;3317;3317;30AD 30ED 30EF 30C3 30C8;30AD 30ED 30EF 30C3 30C8; +3318;3318;3318;30B0 30E9 30E0;30AF 3099 30E9 30E0; +3319;3319;3319;30B0 30E9 30E0 30C8 30F3;30AF 3099 30E9 30E0 30C8 30F3; +331A;331A;331A;30AF 30EB 30BC 30A4 30ED;30AF 30EB 30BB 3099 30A4 30ED; +331B;331B;331B;30AF 30ED 30FC 30CD;30AF 30ED 30FC 30CD; +331C;331C;331C;30B1 30FC 30B9;30B1 30FC 30B9; +331D;331D;331D;30B3 30EB 30CA;30B3 30EB 30CA; +331E;331E;331E;30B3 30FC 30DD;30B3 30FC 30DB 309A; +331F;331F;331F;30B5 30A4 30AF 30EB;30B5 30A4 30AF 30EB; +3320;3320;3320;30B5 30F3 30C1 30FC 30E0;30B5 30F3 30C1 30FC 30E0; +3321;3321;3321;30B7 30EA 30F3 30B0;30B7 30EA 30F3 30AF 3099; +3322;3322;3322;30BB 30F3 30C1;30BB 30F3 30C1; +3323;3323;3323;30BB 30F3 30C8;30BB 30F3 30C8; +3324;3324;3324;30C0 30FC 30B9;30BF 3099 30FC 30B9; +3325;3325;3325;30C7 30B7;30C6 3099 30B7; +3326;3326;3326;30C9 30EB;30C8 3099 30EB; +3327;3327;3327;30C8 30F3;30C8 30F3; +3328;3328;3328;30CA 30CE;30CA 30CE; +3329;3329;3329;30CE 30C3 30C8;30CE 30C3 30C8; +332A;332A;332A;30CF 30A4 30C4;30CF 30A4 30C4; +332B;332B;332B;30D1 30FC 30BB 30F3 30C8;30CF 309A 30FC 30BB 30F3 30C8; +332C;332C;332C;30D1 30FC 30C4;30CF 309A 30FC 30C4; +332D;332D;332D;30D0 30FC 30EC 30EB;30CF 3099 30FC 30EC 30EB; +332E;332E;332E;30D4 30A2 30B9 30C8 30EB;30D2 309A 30A2 30B9 30C8 30EB; +332F;332F;332F;30D4 30AF 30EB;30D2 309A 30AF 30EB; +3330;3330;3330;30D4 30B3;30D2 309A 30B3; +3331;3331;3331;30D3 30EB;30D2 3099 30EB; +3332;3332;3332;30D5 30A1 30E9 30C3 30C9;30D5 30A1 30E9 30C3 30C8 3099; +3333;3333;3333;30D5 30A3 30FC 30C8;30D5 30A3 30FC 30C8; +3334;3334;3334;30D6 30C3 30B7 30A7 30EB;30D5 3099 30C3 30B7 30A7 30EB; +3335;3335;3335;30D5 30E9 30F3;30D5 30E9 30F3; +3336;3336;3336;30D8 30AF 30BF 30FC 30EB;30D8 30AF 30BF 30FC 30EB; +3337;3337;3337;30DA 30BD;30D8 309A 30BD; +3338;3338;3338;30DA 30CB 30D2;30D8 309A 30CB 30D2; +3339;3339;3339;30D8 30EB 30C4;30D8 30EB 30C4; +333A;333A;333A;30DA 30F3 30B9;30D8 309A 30F3 30B9; +333B;333B;333B;30DA 30FC 30B8;30D8 309A 30FC 30B7 3099; +333C;333C;333C;30D9 30FC 30BF;30D8 3099 30FC 30BF; +333D;333D;333D;30DD 30A4 30F3 30C8;30DB 309A 30A4 30F3 30C8; +333E;333E;333E;30DC 30EB 30C8;30DB 3099 30EB 30C8; +333F;333F;333F;30DB 30F3;30DB 30F3; +3340;3340;3340;30DD 30F3 30C9;30DB 309A 30F3 30C8 3099; +3341;3341;3341;30DB 30FC 30EB;30DB 30FC 30EB; +3342;3342;3342;30DB 30FC 30F3;30DB 30FC 30F3; +3343;3343;3343;30DE 30A4 30AF 30ED;30DE 30A4 30AF 30ED; +3344;3344;3344;30DE 30A4 30EB;30DE 30A4 30EB; +3345;3345;3345;30DE 30C3 30CF;30DE 30C3 30CF; +3346;3346;3346;30DE 30EB 30AF;30DE 30EB 30AF; +3347;3347;3347;30DE 30F3 30B7 30E7 30F3;30DE 30F3 30B7 30E7 30F3; +3348;3348;3348;30DF 30AF 30ED 30F3;30DF 30AF 30ED 30F3; +3349;3349;3349;30DF 30EA;30DF 30EA; +334A;334A;334A;30DF 30EA 30D0 30FC 30EB;30DF 30EA 30CF 3099 30FC 30EB; +334B;334B;334B;30E1 30AC;30E1 30AB 3099; +334C;334C;334C;30E1 30AC 30C8 30F3;30E1 30AB 3099 30C8 30F3; +334D;334D;334D;30E1 30FC 30C8 30EB;30E1 30FC 30C8 30EB; +334E;334E;334E;30E4 30FC 30C9;30E4 30FC 30C8 3099; +334F;334F;334F;30E4 30FC 30EB;30E4 30FC 30EB; +3350;3350;3350;30E6 30A2 30F3;30E6 30A2 30F3; +3351;3351;3351;30EA 30C3 30C8 30EB;30EA 30C3 30C8 30EB; +3352;3352;3352;30EA 30E9;30EA 30E9; +3353;3353;3353;30EB 30D4 30FC;30EB 30D2 309A 30FC; +3354;3354;3354;30EB 30FC 30D6 30EB;30EB 30FC 30D5 3099 30EB; +3355;3355;3355;30EC 30E0;30EC 30E0; +3356;3356;3356;30EC 30F3 30C8 30B2 30F3;30EC 30F3 30C8 30B1 3099 30F3; +3357;3357;3357;30EF 30C3 30C8;30EF 30C3 30C8; +3358;3358;3358;0030 70B9;0030 70B9; +3359;3359;3359;0031 70B9;0031 70B9; +335A;335A;335A;0032 70B9;0032 70B9; +335B;335B;335B;0033 70B9;0033 70B9; +335C;335C;335C;0034 70B9;0034 70B9; +335D;335D;335D;0035 70B9;0035 70B9; +335E;335E;335E;0036 70B9;0036 70B9; +335F;335F;335F;0037 70B9;0037 70B9; +3360;3360;3360;0038 70B9;0038 70B9; +3361;3361;3361;0039 70B9;0039 70B9; +3362;3362;3362;0031 0030 70B9;0031 0030 70B9; +3363;3363;3363;0031 0031 70B9;0031 0031 70B9; +3364;3364;3364;0031 0032 70B9;0031 0032 70B9; +3365;3365;3365;0031 0033 70B9;0031 0033 70B9; +3366;3366;3366;0031 0034 70B9;0031 0034 70B9; +3367;3367;3367;0031 0035 70B9;0031 0035 70B9; +3368;3368;3368;0031 0036 70B9;0031 0036 70B9; +3369;3369;3369;0031 0037 70B9;0031 0037 70B9; +336A;336A;336A;0031 0038 70B9;0031 0038 70B9; +336B;336B;336B;0031 0039 70B9;0031 0039 70B9; +336C;336C;336C;0032 0030 70B9;0032 0030 70B9; +336D;336D;336D;0032 0031 70B9;0032 0031 70B9; +336E;336E;336E;0032 0032 70B9;0032 0032 70B9; +336F;336F;336F;0032 0033 70B9;0032 0033 70B9; +3370;3370;3370;0032 0034 70B9;0032 0034 70B9; +3371;3371;3371;0068 0050 0061;0068 0050 0061; +3372;3372;3372;0064 0061;0064 0061; +3373;3373;3373;0041 0055;0041 0055; +3374;3374;3374;0062 0061 0072;0062 0061 0072; +3375;3375;3375;006F 0056;006F 0056; +3376;3376;3376;0070 0063;0070 0063; +3377;3377;3377;0064 006D;0064 006D; +3378;3378;3378;0064 006D 0032;0064 006D 0032; +3379;3379;3379;0064 006D 0033;0064 006D 0033; +337A;337A;337A;0049 0055;0049 0055; +337B;337B;337B;5E73 6210;5E73 6210; +337C;337C;337C;662D 548C;662D 548C; +337D;337D;337D;5927 6B63;5927 6B63; +337E;337E;337E;660E 6CBB;660E 6CBB; +337F;337F;337F;682A 5F0F 4F1A 793E;682A 5F0F 4F1A 793E; +3380;3380;3380;0070 0041;0070 0041; +3381;3381;3381;006E 0041;006E 0041; +3382;3382;3382;03BC 0041;03BC 0041; +3383;3383;3383;006D 0041;006D 0041; +3384;3384;3384;006B 0041;006B 0041; +3385;3385;3385;004B 0042;004B 0042; +3386;3386;3386;004D 0042;004D 0042; +3387;3387;3387;0047 0042;0047 0042; +3388;3388;3388;0063 0061 006C;0063 0061 006C; +3389;3389;3389;006B 0063 0061 006C;006B 0063 0061 006C; +338A;338A;338A;0070 0046;0070 0046; +338B;338B;338B;006E 0046;006E 0046; +338C;338C;338C;03BC 0046;03BC 0046; +338D;338D;338D;03BC 0067;03BC 0067; +338E;338E;338E;006D 0067;006D 0067; +338F;338F;338F;006B 0067;006B 0067; +3390;3390;3390;0048 007A;0048 007A; +3391;3391;3391;006B 0048 007A;006B 0048 007A; +3392;3392;3392;004D 0048 007A;004D 0048 007A; +3393;3393;3393;0047 0048 007A;0047 0048 007A; +3394;3394;3394;0054 0048 007A;0054 0048 007A; +3395;3395;3395;03BC 006C;03BC 006C; +3396;3396;3396;006D 006C;006D 006C; +3397;3397;3397;0064 006C;0064 006C; +3398;3398;3398;006B 006C;006B 006C; +3399;3399;3399;0066 006D;0066 006D; +339A;339A;339A;006E 006D;006E 006D; +339B;339B;339B;03BC 006D;03BC 006D; +339C;339C;339C;006D 006D;006D 006D; +339D;339D;339D;0063 006D;0063 006D; +339E;339E;339E;006B 006D;006B 006D; +339F;339F;339F;006D 006D 0032;006D 006D 0032; +33A0;33A0;33A0;0063 006D 0032;0063 006D 0032; +33A1;33A1;33A1;006D 0032;006D 0032; +33A2;33A2;33A2;006B 006D 0032;006B 006D 0032; +33A3;33A3;33A3;006D 006D 0033;006D 006D 0033; +33A4;33A4;33A4;0063 006D 0033;0063 006D 0033; +33A5;33A5;33A5;006D 0033;006D 0033; +33A6;33A6;33A6;006B 006D 0033;006B 006D 0033; +33A7;33A7;33A7;006D 2215 0073;006D 2215 0073; +33A8;33A8;33A8;006D 2215 0073 0032;006D 2215 0073 0032; +33A9;33A9;33A9;0050 0061;0050 0061; +33AA;33AA;33AA;006B 0050 0061;006B 0050 0061; +33AB;33AB;33AB;004D 0050 0061;004D 0050 0061; +33AC;33AC;33AC;0047 0050 0061;0047 0050 0061; +33AD;33AD;33AD;0072 0061 0064;0072 0061 0064; +33AE;33AE;33AE;0072 0061 0064 2215 0073;0072 0061 0064 2215 0073; +33AF;33AF;33AF;0072 0061 0064 2215 0073 0032;0072 0061 0064 2215 0073 0032; +33B0;33B0;33B0;0070 0073;0070 0073; +33B1;33B1;33B1;006E 0073;006E 0073; +33B2;33B2;33B2;03BC 0073;03BC 0073; +33B3;33B3;33B3;006D 0073;006D 0073; +33B4;33B4;33B4;0070 0056;0070 0056; +33B5;33B5;33B5;006E 0056;006E 0056; +33B6;33B6;33B6;03BC 0056;03BC 0056; +33B7;33B7;33B7;006D 0056;006D 0056; +33B8;33B8;33B8;006B 0056;006B 0056; +33B9;33B9;33B9;004D 0056;004D 0056; +33BA;33BA;33BA;0070 0057;0070 0057; +33BB;33BB;33BB;006E 0057;006E 0057; +33BC;33BC;33BC;03BC 0057;03BC 0057; +33BD;33BD;33BD;006D 0057;006D 0057; +33BE;33BE;33BE;006B 0057;006B 0057; +33BF;33BF;33BF;004D 0057;004D 0057; +33C0;33C0;33C0;006B 03A9;006B 03A9; +33C1;33C1;33C1;004D 03A9;004D 03A9; +33C2;33C2;33C2;0061 002E 006D 002E;0061 002E 006D 002E; +33C3;33C3;33C3;0042 0071;0042 0071; +33C4;33C4;33C4;0063 0063;0063 0063; +33C5;33C5;33C5;0063 0064;0063 0064; +33C6;33C6;33C6;0043 2215 006B 0067;0043 2215 006B 0067; +33C7;33C7;33C7;0043 006F 002E;0043 006F 002E; +33C8;33C8;33C8;0064 0042;0064 0042; +33C9;33C9;33C9;0047 0079;0047 0079; +33CA;33CA;33CA;0068 0061;0068 0061; +33CB;33CB;33CB;0048 0050;0048 0050; +33CC;33CC;33CC;0069 006E;0069 006E; +33CD;33CD;33CD;004B 004B;004B 004B; +33CE;33CE;33CE;004B 004D;004B 004D; +33CF;33CF;33CF;006B 0074;006B 0074; +33D0;33D0;33D0;006C 006D;006C 006D; +33D1;33D1;33D1;006C 006E;006C 006E; +33D2;33D2;33D2;006C 006F 0067;006C 006F 0067; +33D3;33D3;33D3;006C 0078;006C 0078; +33D4;33D4;33D4;006D 0062;006D 0062; +33D5;33D5;33D5;006D 0069 006C;006D 0069 006C; +33D6;33D6;33D6;006D 006F 006C;006D 006F 006C; +33D7;33D7;33D7;0050 0048;0050 0048; +33D8;33D8;33D8;0070 002E 006D 002E;0070 002E 006D 002E; +33D9;33D9;33D9;0050 0050 004D;0050 0050 004D; +33DA;33DA;33DA;0050 0052;0050 0052; +33DB;33DB;33DB;0073 0072;0073 0072; +33DC;33DC;33DC;0053 0076;0053 0076; +33DD;33DD;33DD;0057 0062;0057 0062; +33DE;33DE;33DE;0056 2215 006D;0056 2215 006D; +33DF;33DF;33DF;0041 2215 006D;0041 2215 006D; +33E0;33E0;33E0;0031 65E5;0031 65E5; +33E1;33E1;33E1;0032 65E5;0032 65E5; +33E2;33E2;33E2;0033 65E5;0033 65E5; +33E3;33E3;33E3;0034 65E5;0034 65E5; +33E4;33E4;33E4;0035 65E5;0035 65E5; +33E5;33E5;33E5;0036 65E5;0036 65E5; +33E6;33E6;33E6;0037 65E5;0037 65E5; +33E7;33E7;33E7;0038 65E5;0038 65E5; +33E8;33E8;33E8;0039 65E5;0039 65E5; +33E9;33E9;33E9;0031 0030 65E5;0031 0030 65E5; +33EA;33EA;33EA;0031 0031 65E5;0031 0031 65E5; +33EB;33EB;33EB;0031 0032 65E5;0031 0032 65E5; +33EC;33EC;33EC;0031 0033 65E5;0031 0033 65E5; +33ED;33ED;33ED;0031 0034 65E5;0031 0034 65E5; +33EE;33EE;33EE;0031 0035 65E5;0031 0035 65E5; +33EF;33EF;33EF;0031 0036 65E5;0031 0036 65E5; +33F0;33F0;33F0;0031 0037 65E5;0031 0037 65E5; +33F1;33F1;33F1;0031 0038 65E5;0031 0038 65E5; +33F2;33F2;33F2;0031 0039 65E5;0031 0039 65E5; +33F3;33F3;33F3;0032 0030 65E5;0032 0030 65E5; +33F4;33F4;33F4;0032 0031 65E5;0032 0031 65E5; +33F5;33F5;33F5;0032 0032 65E5;0032 0032 65E5; +33F6;33F6;33F6;0032 0033 65E5;0032 0033 65E5; +33F7;33F7;33F7;0032 0034 65E5;0032 0034 65E5; +33F8;33F8;33F8;0032 0035 65E5;0032 0035 65E5; +33F9;33F9;33F9;0032 0036 65E5;0032 0036 65E5; +33FA;33FA;33FA;0032 0037 65E5;0032 0037 65E5; +33FB;33FB;33FB;0032 0038 65E5;0032 0038 65E5; +33FC;33FC;33FC;0032 0039 65E5;0032 0039 65E5; +33FD;33FD;33FD;0033 0030 65E5;0033 0030 65E5; +33FE;33FE;33FE;0033 0031 65E5;0033 0031 65E5; +33FF;33FF;33FF;0067 0061 006C;0067 0061 006C; +A69C;A69C;A69C;044A;044A; +A69D;A69D;A69D;044C;044C; +A770;A770;A770;A76F;A76F; +A7F8;A7F8;A7F8;0126;0126; +A7F9;A7F9;A7F9;0153;0153; +AB5C;AB5C;AB5C;A727;A727; +AB5D;AB5D;AB5D;AB37;AB37; +AB5E;AB5E;AB5E;026B;026B; +AB5F;AB5F;AB5F;AB52;AB52; +AC00;AC00;1100 1161;AC00;1100 1161; +AC01;AC01;1100 1161 11A8;AC01;1100 1161 11A8; +AC02;AC02;1100 1161 11A9;AC02;1100 1161 11A9; +AC03;AC03;1100 1161 11AA;AC03;1100 1161 11AA; +AC04;AC04;1100 1161 11AB;AC04;1100 1161 11AB; +AC05;AC05;1100 1161 11AC;AC05;1100 1161 11AC; +AC06;AC06;1100 1161 11AD;AC06;1100 1161 11AD; +AC07;AC07;1100 1161 11AE;AC07;1100 1161 11AE; +AC08;AC08;1100 1161 11AF;AC08;1100 1161 11AF; +AC09;AC09;1100 1161 11B0;AC09;1100 1161 11B0; +AC0A;AC0A;1100 1161 11B1;AC0A;1100 1161 11B1; +AC0B;AC0B;1100 1161 11B2;AC0B;1100 1161 11B2; +AC0C;AC0C;1100 1161 11B3;AC0C;1100 1161 11B3; +AC0D;AC0D;1100 1161 11B4;AC0D;1100 1161 11B4; +AC0E;AC0E;1100 1161 11B5;AC0E;1100 1161 11B5; +AC0F;AC0F;1100 1161 11B6;AC0F;1100 1161 11B6; +AC10;AC10;1100 1161 11B7;AC10;1100 1161 11B7; +AC11;AC11;1100 1161 11B8;AC11;1100 1161 11B8; +AC12;AC12;1100 1161 11B9;AC12;1100 1161 11B9; +AC13;AC13;1100 1161 11BA;AC13;1100 1161 11BA; +AC14;AC14;1100 1161 11BB;AC14;1100 1161 11BB; +AC15;AC15;1100 1161 11BC;AC15;1100 1161 11BC; +AC16;AC16;1100 1161 11BD;AC16;1100 1161 11BD; +AC17;AC17;1100 1161 11BE;AC17;1100 1161 11BE; +AC18;AC18;1100 1161 11BF;AC18;1100 1161 11BF; +AC19;AC19;1100 1161 11C0;AC19;1100 1161 11C0; +AC1A;AC1A;1100 1161 11C1;AC1A;1100 1161 11C1; +AC1B;AC1B;1100 1161 11C2;AC1B;1100 1161 11C2; +AC1C;AC1C;1100 1162;AC1C;1100 1162; +AC1D;AC1D;1100 1162 11A8;AC1D;1100 1162 11A8; +AC1E;AC1E;1100 1162 11A9;AC1E;1100 1162 11A9; +AC1F;AC1F;1100 1162 11AA;AC1F;1100 1162 11AA; +AC20;AC20;1100 1162 11AB;AC20;1100 1162 11AB; +AC21;AC21;1100 1162 11AC;AC21;1100 1162 11AC; +AC22;AC22;1100 1162 11AD;AC22;1100 1162 11AD; +AC23;AC23;1100 1162 11AE;AC23;1100 1162 11AE; +AC24;AC24;1100 1162 11AF;AC24;1100 1162 11AF; +AC25;AC25;1100 1162 11B0;AC25;1100 1162 11B0; +AC26;AC26;1100 1162 11B1;AC26;1100 1162 11B1; +AC27;AC27;1100 1162 11B2;AC27;1100 1162 11B2; +AC28;AC28;1100 1162 11B3;AC28;1100 1162 11B3; +AC29;AC29;1100 1162 11B4;AC29;1100 1162 11B4; +AC2A;AC2A;1100 1162 11B5;AC2A;1100 1162 11B5; +AC2B;AC2B;1100 1162 11B6;AC2B;1100 1162 11B6; +AC2C;AC2C;1100 1162 11B7;AC2C;1100 1162 11B7; +AC2D;AC2D;1100 1162 11B8;AC2D;1100 1162 11B8; +AC2E;AC2E;1100 1162 11B9;AC2E;1100 1162 11B9; +AC2F;AC2F;1100 1162 11BA;AC2F;1100 1162 11BA; +AC30;AC30;1100 1162 11BB;AC30;1100 1162 11BB; +AC31;AC31;1100 1162 11BC;AC31;1100 1162 11BC; +AC32;AC32;1100 1162 11BD;AC32;1100 1162 11BD; +AC33;AC33;1100 1162 11BE;AC33;1100 1162 11BE; +AC34;AC34;1100 1162 11BF;AC34;1100 1162 11BF; +AC35;AC35;1100 1162 11C0;AC35;1100 1162 11C0; +AC36;AC36;1100 1162 11C1;AC36;1100 1162 11C1; +AC37;AC37;1100 1162 11C2;AC37;1100 1162 11C2; +AC38;AC38;1100 1163;AC38;1100 1163; +AC39;AC39;1100 1163 11A8;AC39;1100 1163 11A8; +AC3A;AC3A;1100 1163 11A9;AC3A;1100 1163 11A9; +AC3B;AC3B;1100 1163 11AA;AC3B;1100 1163 11AA; +AC3C;AC3C;1100 1163 11AB;AC3C;1100 1163 11AB; +AC3D;AC3D;1100 1163 11AC;AC3D;1100 1163 11AC; +AC3E;AC3E;1100 1163 11AD;AC3E;1100 1163 11AD; +AC3F;AC3F;1100 1163 11AE;AC3F;1100 1163 11AE; +AC40;AC40;1100 1163 11AF;AC40;1100 1163 11AF; +AC41;AC41;1100 1163 11B0;AC41;1100 1163 11B0; +AC42;AC42;1100 1163 11B1;AC42;1100 1163 11B1; +AC43;AC43;1100 1163 11B2;AC43;1100 1163 11B2; +AC44;AC44;1100 1163 11B3;AC44;1100 1163 11B3; +AC45;AC45;1100 1163 11B4;AC45;1100 1163 11B4; +AC46;AC46;1100 1163 11B5;AC46;1100 1163 11B5; +AC47;AC47;1100 1163 11B6;AC47;1100 1163 11B6; +AC48;AC48;1100 1163 11B7;AC48;1100 1163 11B7; +AC49;AC49;1100 1163 11B8;AC49;1100 1163 11B8; +AC4A;AC4A;1100 1163 11B9;AC4A;1100 1163 11B9; +AC4B;AC4B;1100 1163 11BA;AC4B;1100 1163 11BA; +AC4C;AC4C;1100 1163 11BB;AC4C;1100 1163 11BB; +AC4D;AC4D;1100 1163 11BC;AC4D;1100 1163 11BC; +AC4E;AC4E;1100 1163 11BD;AC4E;1100 1163 11BD; +AC4F;AC4F;1100 1163 11BE;AC4F;1100 1163 11BE; +AC50;AC50;1100 1163 11BF;AC50;1100 1163 11BF; +AC51;AC51;1100 1163 11C0;AC51;1100 1163 11C0; +AC52;AC52;1100 1163 11C1;AC52;1100 1163 11C1; +AC53;AC53;1100 1163 11C2;AC53;1100 1163 11C2; +AC54;AC54;1100 1164;AC54;1100 1164; +AC55;AC55;1100 1164 11A8;AC55;1100 1164 11A8; +AC56;AC56;1100 1164 11A9;AC56;1100 1164 11A9; +AC57;AC57;1100 1164 11AA;AC57;1100 1164 11AA; +AC58;AC58;1100 1164 11AB;AC58;1100 1164 11AB; +AC59;AC59;1100 1164 11AC;AC59;1100 1164 11AC; +AC5A;AC5A;1100 1164 11AD;AC5A;1100 1164 11AD; +AC5B;AC5B;1100 1164 11AE;AC5B;1100 1164 11AE; +AC5C;AC5C;1100 1164 11AF;AC5C;1100 1164 11AF; +AC5D;AC5D;1100 1164 11B0;AC5D;1100 1164 11B0; +AC5E;AC5E;1100 1164 11B1;AC5E;1100 1164 11B1; +AC5F;AC5F;1100 1164 11B2;AC5F;1100 1164 11B2; +AC60;AC60;1100 1164 11B3;AC60;1100 1164 11B3; +AC61;AC61;1100 1164 11B4;AC61;1100 1164 11B4; +AC62;AC62;1100 1164 11B5;AC62;1100 1164 11B5; +AC63;AC63;1100 1164 11B6;AC63;1100 1164 11B6; +AC64;AC64;1100 1164 11B7;AC64;1100 1164 11B7; +AC65;AC65;1100 1164 11B8;AC65;1100 1164 11B8; +AC66;AC66;1100 1164 11B9;AC66;1100 1164 11B9; +AC67;AC67;1100 1164 11BA;AC67;1100 1164 11BA; +AC68;AC68;1100 1164 11BB;AC68;1100 1164 11BB; +AC69;AC69;1100 1164 11BC;AC69;1100 1164 11BC; +AC6A;AC6A;1100 1164 11BD;AC6A;1100 1164 11BD; +AC6B;AC6B;1100 1164 11BE;AC6B;1100 1164 11BE; +AC6C;AC6C;1100 1164 11BF;AC6C;1100 1164 11BF; +AC6D;AC6D;1100 1164 11C0;AC6D;1100 1164 11C0; +AC6E;AC6E;1100 1164 11C1;AC6E;1100 1164 11C1; +AC6F;AC6F;1100 1164 11C2;AC6F;1100 1164 11C2; +AC70;AC70;1100 1165;AC70;1100 1165; +AC71;AC71;1100 1165 11A8;AC71;1100 1165 11A8; +AC72;AC72;1100 1165 11A9;AC72;1100 1165 11A9; +AC73;AC73;1100 1165 11AA;AC73;1100 1165 11AA; +AC74;AC74;1100 1165 11AB;AC74;1100 1165 11AB; +AC75;AC75;1100 1165 11AC;AC75;1100 1165 11AC; +AC76;AC76;1100 1165 11AD;AC76;1100 1165 11AD; +AC77;AC77;1100 1165 11AE;AC77;1100 1165 11AE; +AC78;AC78;1100 1165 11AF;AC78;1100 1165 11AF; +AC79;AC79;1100 1165 11B0;AC79;1100 1165 11B0; +AC7A;AC7A;1100 1165 11B1;AC7A;1100 1165 11B1; +AC7B;AC7B;1100 1165 11B2;AC7B;1100 1165 11B2; +AC7C;AC7C;1100 1165 11B3;AC7C;1100 1165 11B3; +AC7D;AC7D;1100 1165 11B4;AC7D;1100 1165 11B4; +AC7E;AC7E;1100 1165 11B5;AC7E;1100 1165 11B5; +AC7F;AC7F;1100 1165 11B6;AC7F;1100 1165 11B6; +AC80;AC80;1100 1165 11B7;AC80;1100 1165 11B7; +AC81;AC81;1100 1165 11B8;AC81;1100 1165 11B8; +AC82;AC82;1100 1165 11B9;AC82;1100 1165 11B9; +AC83;AC83;1100 1165 11BA;AC83;1100 1165 11BA; +AC84;AC84;1100 1165 11BB;AC84;1100 1165 11BB; +AC85;AC85;1100 1165 11BC;AC85;1100 1165 11BC; +AC86;AC86;1100 1165 11BD;AC86;1100 1165 11BD; +AC87;AC87;1100 1165 11BE;AC87;1100 1165 11BE; +AC88;AC88;1100 1165 11BF;AC88;1100 1165 11BF; +AC89;AC89;1100 1165 11C0;AC89;1100 1165 11C0; +AC8A;AC8A;1100 1165 11C1;AC8A;1100 1165 11C1; +AC8B;AC8B;1100 1165 11C2;AC8B;1100 1165 11C2; +AC8C;AC8C;1100 1166;AC8C;1100 1166; +AC8D;AC8D;1100 1166 11A8;AC8D;1100 1166 11A8; +AC8E;AC8E;1100 1166 11A9;AC8E;1100 1166 11A9; +AC8F;AC8F;1100 1166 11AA;AC8F;1100 1166 11AA; +AC90;AC90;1100 1166 11AB;AC90;1100 1166 11AB; +AC91;AC91;1100 1166 11AC;AC91;1100 1166 11AC; +AC92;AC92;1100 1166 11AD;AC92;1100 1166 11AD; +AC93;AC93;1100 1166 11AE;AC93;1100 1166 11AE; +AC94;AC94;1100 1166 11AF;AC94;1100 1166 11AF; +AC95;AC95;1100 1166 11B0;AC95;1100 1166 11B0; +AC96;AC96;1100 1166 11B1;AC96;1100 1166 11B1; +AC97;AC97;1100 1166 11B2;AC97;1100 1166 11B2; +AC98;AC98;1100 1166 11B3;AC98;1100 1166 11B3; +AC99;AC99;1100 1166 11B4;AC99;1100 1166 11B4; +AC9A;AC9A;1100 1166 11B5;AC9A;1100 1166 11B5; +AC9B;AC9B;1100 1166 11B6;AC9B;1100 1166 11B6; +AC9C;AC9C;1100 1166 11B7;AC9C;1100 1166 11B7; +AC9D;AC9D;1100 1166 11B8;AC9D;1100 1166 11B8; +AC9E;AC9E;1100 1166 11B9;AC9E;1100 1166 11B9; +AC9F;AC9F;1100 1166 11BA;AC9F;1100 1166 11BA; +ACA0;ACA0;1100 1166 11BB;ACA0;1100 1166 11BB; +ACA1;ACA1;1100 1166 11BC;ACA1;1100 1166 11BC; +ACA2;ACA2;1100 1166 11BD;ACA2;1100 1166 11BD; +ACA3;ACA3;1100 1166 11BE;ACA3;1100 1166 11BE; +ACA4;ACA4;1100 1166 11BF;ACA4;1100 1166 11BF; +ACA5;ACA5;1100 1166 11C0;ACA5;1100 1166 11C0; +ACA6;ACA6;1100 1166 11C1;ACA6;1100 1166 11C1; +ACA7;ACA7;1100 1166 11C2;ACA7;1100 1166 11C2; +ACA8;ACA8;1100 1167;ACA8;1100 1167; +ACA9;ACA9;1100 1167 11A8;ACA9;1100 1167 11A8; +ACAA;ACAA;1100 1167 11A9;ACAA;1100 1167 11A9; +ACAB;ACAB;1100 1167 11AA;ACAB;1100 1167 11AA; +ACAC;ACAC;1100 1167 11AB;ACAC;1100 1167 11AB; +ACAD;ACAD;1100 1167 11AC;ACAD;1100 1167 11AC; +ACAE;ACAE;1100 1167 11AD;ACAE;1100 1167 11AD; +ACAF;ACAF;1100 1167 11AE;ACAF;1100 1167 11AE; +ACB0;ACB0;1100 1167 11AF;ACB0;1100 1167 11AF; +ACB1;ACB1;1100 1167 11B0;ACB1;1100 1167 11B0; +ACB2;ACB2;1100 1167 11B1;ACB2;1100 1167 11B1; +ACB3;ACB3;1100 1167 11B2;ACB3;1100 1167 11B2; +ACB4;ACB4;1100 1167 11B3;ACB4;1100 1167 11B3; +ACB5;ACB5;1100 1167 11B4;ACB5;1100 1167 11B4; +ACB6;ACB6;1100 1167 11B5;ACB6;1100 1167 11B5; +ACB7;ACB7;1100 1167 11B6;ACB7;1100 1167 11B6; +ACB8;ACB8;1100 1167 11B7;ACB8;1100 1167 11B7; +ACB9;ACB9;1100 1167 11B8;ACB9;1100 1167 11B8; +ACBA;ACBA;1100 1167 11B9;ACBA;1100 1167 11B9; +ACBB;ACBB;1100 1167 11BA;ACBB;1100 1167 11BA; +ACBC;ACBC;1100 1167 11BB;ACBC;1100 1167 11BB; +ACBD;ACBD;1100 1167 11BC;ACBD;1100 1167 11BC; +ACBE;ACBE;1100 1167 11BD;ACBE;1100 1167 11BD; +ACBF;ACBF;1100 1167 11BE;ACBF;1100 1167 11BE; +ACC0;ACC0;1100 1167 11BF;ACC0;1100 1167 11BF; +ACC1;ACC1;1100 1167 11C0;ACC1;1100 1167 11C0; +ACC2;ACC2;1100 1167 11C1;ACC2;1100 1167 11C1; +ACC3;ACC3;1100 1167 11C2;ACC3;1100 1167 11C2; +ACC4;ACC4;1100 1168;ACC4;1100 1168; +ACC5;ACC5;1100 1168 11A8;ACC5;1100 1168 11A8; +ACC6;ACC6;1100 1168 11A9;ACC6;1100 1168 11A9; +ACC7;ACC7;1100 1168 11AA;ACC7;1100 1168 11AA; +ACC8;ACC8;1100 1168 11AB;ACC8;1100 1168 11AB; +ACC9;ACC9;1100 1168 11AC;ACC9;1100 1168 11AC; +ACCA;ACCA;1100 1168 11AD;ACCA;1100 1168 11AD; +ACCB;ACCB;1100 1168 11AE;ACCB;1100 1168 11AE; +ACCC;ACCC;1100 1168 11AF;ACCC;1100 1168 11AF; +ACCD;ACCD;1100 1168 11B0;ACCD;1100 1168 11B0; +ACCE;ACCE;1100 1168 11B1;ACCE;1100 1168 11B1; +ACCF;ACCF;1100 1168 11B2;ACCF;1100 1168 11B2; +ACD0;ACD0;1100 1168 11B3;ACD0;1100 1168 11B3; +ACD1;ACD1;1100 1168 11B4;ACD1;1100 1168 11B4; +ACD2;ACD2;1100 1168 11B5;ACD2;1100 1168 11B5; +ACD3;ACD3;1100 1168 11B6;ACD3;1100 1168 11B6; +ACD4;ACD4;1100 1168 11B7;ACD4;1100 1168 11B7; +ACD5;ACD5;1100 1168 11B8;ACD5;1100 1168 11B8; +ACD6;ACD6;1100 1168 11B9;ACD6;1100 1168 11B9; +ACD7;ACD7;1100 1168 11BA;ACD7;1100 1168 11BA; +ACD8;ACD8;1100 1168 11BB;ACD8;1100 1168 11BB; +ACD9;ACD9;1100 1168 11BC;ACD9;1100 1168 11BC; +ACDA;ACDA;1100 1168 11BD;ACDA;1100 1168 11BD; +ACDB;ACDB;1100 1168 11BE;ACDB;1100 1168 11BE; +ACDC;ACDC;1100 1168 11BF;ACDC;1100 1168 11BF; +ACDD;ACDD;1100 1168 11C0;ACDD;1100 1168 11C0; +ACDE;ACDE;1100 1168 11C1;ACDE;1100 1168 11C1; +ACDF;ACDF;1100 1168 11C2;ACDF;1100 1168 11C2; +ACE0;ACE0;1100 1169;ACE0;1100 1169; +ACE1;ACE1;1100 1169 11A8;ACE1;1100 1169 11A8; +ACE2;ACE2;1100 1169 11A9;ACE2;1100 1169 11A9; +ACE3;ACE3;1100 1169 11AA;ACE3;1100 1169 11AA; +ACE4;ACE4;1100 1169 11AB;ACE4;1100 1169 11AB; +ACE5;ACE5;1100 1169 11AC;ACE5;1100 1169 11AC; +ACE6;ACE6;1100 1169 11AD;ACE6;1100 1169 11AD; +ACE7;ACE7;1100 1169 11AE;ACE7;1100 1169 11AE; +ACE8;ACE8;1100 1169 11AF;ACE8;1100 1169 11AF; +ACE9;ACE9;1100 1169 11B0;ACE9;1100 1169 11B0; +ACEA;ACEA;1100 1169 11B1;ACEA;1100 1169 11B1; +ACEB;ACEB;1100 1169 11B2;ACEB;1100 1169 11B2; +ACEC;ACEC;1100 1169 11B3;ACEC;1100 1169 11B3; +ACED;ACED;1100 1169 11B4;ACED;1100 1169 11B4; +ACEE;ACEE;1100 1169 11B5;ACEE;1100 1169 11B5; +ACEF;ACEF;1100 1169 11B6;ACEF;1100 1169 11B6; +ACF0;ACF0;1100 1169 11B7;ACF0;1100 1169 11B7; +ACF1;ACF1;1100 1169 11B8;ACF1;1100 1169 11B8; +ACF2;ACF2;1100 1169 11B9;ACF2;1100 1169 11B9; +ACF3;ACF3;1100 1169 11BA;ACF3;1100 1169 11BA; +ACF4;ACF4;1100 1169 11BB;ACF4;1100 1169 11BB; +ACF5;ACF5;1100 1169 11BC;ACF5;1100 1169 11BC; +ACF6;ACF6;1100 1169 11BD;ACF6;1100 1169 11BD; +ACF7;ACF7;1100 1169 11BE;ACF7;1100 1169 11BE; +ACF8;ACF8;1100 1169 11BF;ACF8;1100 1169 11BF; +ACF9;ACF9;1100 1169 11C0;ACF9;1100 1169 11C0; +ACFA;ACFA;1100 1169 11C1;ACFA;1100 1169 11C1; +ACFB;ACFB;1100 1169 11C2;ACFB;1100 1169 11C2; +ACFC;ACFC;1100 116A;ACFC;1100 116A; +ACFD;ACFD;1100 116A 11A8;ACFD;1100 116A 11A8; +ACFE;ACFE;1100 116A 11A9;ACFE;1100 116A 11A9; +ACFF;ACFF;1100 116A 11AA;ACFF;1100 116A 11AA; +AD00;AD00;1100 116A 11AB;AD00;1100 116A 11AB; +AD01;AD01;1100 116A 11AC;AD01;1100 116A 11AC; +AD02;AD02;1100 116A 11AD;AD02;1100 116A 11AD; +AD03;AD03;1100 116A 11AE;AD03;1100 116A 11AE; +AD04;AD04;1100 116A 11AF;AD04;1100 116A 11AF; +AD05;AD05;1100 116A 11B0;AD05;1100 116A 11B0; +AD06;AD06;1100 116A 11B1;AD06;1100 116A 11B1; +AD07;AD07;1100 116A 11B2;AD07;1100 116A 11B2; +AD08;AD08;1100 116A 11B3;AD08;1100 116A 11B3; +AD09;AD09;1100 116A 11B4;AD09;1100 116A 11B4; +AD0A;AD0A;1100 116A 11B5;AD0A;1100 116A 11B5; +AD0B;AD0B;1100 116A 11B6;AD0B;1100 116A 11B6; +AD0C;AD0C;1100 116A 11B7;AD0C;1100 116A 11B7; +AD0D;AD0D;1100 116A 11B8;AD0D;1100 116A 11B8; +AD0E;AD0E;1100 116A 11B9;AD0E;1100 116A 11B9; +AD0F;AD0F;1100 116A 11BA;AD0F;1100 116A 11BA; +AD10;AD10;1100 116A 11BB;AD10;1100 116A 11BB; +AD11;AD11;1100 116A 11BC;AD11;1100 116A 11BC; +AD12;AD12;1100 116A 11BD;AD12;1100 116A 11BD; +AD13;AD13;1100 116A 11BE;AD13;1100 116A 11BE; +AD14;AD14;1100 116A 11BF;AD14;1100 116A 11BF; +AD15;AD15;1100 116A 11C0;AD15;1100 116A 11C0; +AD16;AD16;1100 116A 11C1;AD16;1100 116A 11C1; +AD17;AD17;1100 116A 11C2;AD17;1100 116A 11C2; +AD18;AD18;1100 116B;AD18;1100 116B; +AD19;AD19;1100 116B 11A8;AD19;1100 116B 11A8; +AD1A;AD1A;1100 116B 11A9;AD1A;1100 116B 11A9; +AD1B;AD1B;1100 116B 11AA;AD1B;1100 116B 11AA; +AD1C;AD1C;1100 116B 11AB;AD1C;1100 116B 11AB; +AD1D;AD1D;1100 116B 11AC;AD1D;1100 116B 11AC; +AD1E;AD1E;1100 116B 11AD;AD1E;1100 116B 11AD; +AD1F;AD1F;1100 116B 11AE;AD1F;1100 116B 11AE; +AD20;AD20;1100 116B 11AF;AD20;1100 116B 11AF; +AD21;AD21;1100 116B 11B0;AD21;1100 116B 11B0; +AD22;AD22;1100 116B 11B1;AD22;1100 116B 11B1; +AD23;AD23;1100 116B 11B2;AD23;1100 116B 11B2; +AD24;AD24;1100 116B 11B3;AD24;1100 116B 11B3; +AD25;AD25;1100 116B 11B4;AD25;1100 116B 11B4; +AD26;AD26;1100 116B 11B5;AD26;1100 116B 11B5; +AD27;AD27;1100 116B 11B6;AD27;1100 116B 11B6; +AD28;AD28;1100 116B 11B7;AD28;1100 116B 11B7; +AD29;AD29;1100 116B 11B8;AD29;1100 116B 11B8; +AD2A;AD2A;1100 116B 11B9;AD2A;1100 116B 11B9; +AD2B;AD2B;1100 116B 11BA;AD2B;1100 116B 11BA; +AD2C;AD2C;1100 116B 11BB;AD2C;1100 116B 11BB; +AD2D;AD2D;1100 116B 11BC;AD2D;1100 116B 11BC; +AD2E;AD2E;1100 116B 11BD;AD2E;1100 116B 11BD; +AD2F;AD2F;1100 116B 11BE;AD2F;1100 116B 11BE; +AD30;AD30;1100 116B 11BF;AD30;1100 116B 11BF; +AD31;AD31;1100 116B 11C0;AD31;1100 116B 11C0; +AD32;AD32;1100 116B 11C1;AD32;1100 116B 11C1; +AD33;AD33;1100 116B 11C2;AD33;1100 116B 11C2; +AD34;AD34;1100 116C;AD34;1100 116C; +AD35;AD35;1100 116C 11A8;AD35;1100 116C 11A8; +AD36;AD36;1100 116C 11A9;AD36;1100 116C 11A9; +AD37;AD37;1100 116C 11AA;AD37;1100 116C 11AA; +AD38;AD38;1100 116C 11AB;AD38;1100 116C 11AB; +AD39;AD39;1100 116C 11AC;AD39;1100 116C 11AC; +AD3A;AD3A;1100 116C 11AD;AD3A;1100 116C 11AD; +AD3B;AD3B;1100 116C 11AE;AD3B;1100 116C 11AE; +AD3C;AD3C;1100 116C 11AF;AD3C;1100 116C 11AF; +AD3D;AD3D;1100 116C 11B0;AD3D;1100 116C 11B0; +AD3E;AD3E;1100 116C 11B1;AD3E;1100 116C 11B1; +AD3F;AD3F;1100 116C 11B2;AD3F;1100 116C 11B2; +AD40;AD40;1100 116C 11B3;AD40;1100 116C 11B3; +AD41;AD41;1100 116C 11B4;AD41;1100 116C 11B4; +AD42;AD42;1100 116C 11B5;AD42;1100 116C 11B5; +AD43;AD43;1100 116C 11B6;AD43;1100 116C 11B6; +AD44;AD44;1100 116C 11B7;AD44;1100 116C 11B7; +AD45;AD45;1100 116C 11B8;AD45;1100 116C 11B8; +AD46;AD46;1100 116C 11B9;AD46;1100 116C 11B9; +AD47;AD47;1100 116C 11BA;AD47;1100 116C 11BA; +AD48;AD48;1100 116C 11BB;AD48;1100 116C 11BB; +AD49;AD49;1100 116C 11BC;AD49;1100 116C 11BC; +AD4A;AD4A;1100 116C 11BD;AD4A;1100 116C 11BD; +AD4B;AD4B;1100 116C 11BE;AD4B;1100 116C 11BE; +AD4C;AD4C;1100 116C 11BF;AD4C;1100 116C 11BF; +AD4D;AD4D;1100 116C 11C0;AD4D;1100 116C 11C0; +AD4E;AD4E;1100 116C 11C1;AD4E;1100 116C 11C1; +AD4F;AD4F;1100 116C 11C2;AD4F;1100 116C 11C2; +AD50;AD50;1100 116D;AD50;1100 116D; +AD51;AD51;1100 116D 11A8;AD51;1100 116D 11A8; +AD52;AD52;1100 116D 11A9;AD52;1100 116D 11A9; +AD53;AD53;1100 116D 11AA;AD53;1100 116D 11AA; +AD54;AD54;1100 116D 11AB;AD54;1100 116D 11AB; +AD55;AD55;1100 116D 11AC;AD55;1100 116D 11AC; +AD56;AD56;1100 116D 11AD;AD56;1100 116D 11AD; +AD57;AD57;1100 116D 11AE;AD57;1100 116D 11AE; +AD58;AD58;1100 116D 11AF;AD58;1100 116D 11AF; +AD59;AD59;1100 116D 11B0;AD59;1100 116D 11B0; +AD5A;AD5A;1100 116D 11B1;AD5A;1100 116D 11B1; +AD5B;AD5B;1100 116D 11B2;AD5B;1100 116D 11B2; +AD5C;AD5C;1100 116D 11B3;AD5C;1100 116D 11B3; +AD5D;AD5D;1100 116D 11B4;AD5D;1100 116D 11B4; +AD5E;AD5E;1100 116D 11B5;AD5E;1100 116D 11B5; +AD5F;AD5F;1100 116D 11B6;AD5F;1100 116D 11B6; +AD60;AD60;1100 116D 11B7;AD60;1100 116D 11B7; +AD61;AD61;1100 116D 11B8;AD61;1100 116D 11B8; +AD62;AD62;1100 116D 11B9;AD62;1100 116D 11B9; +AD63;AD63;1100 116D 11BA;AD63;1100 116D 11BA; +AD64;AD64;1100 116D 11BB;AD64;1100 116D 11BB; +AD65;AD65;1100 116D 11BC;AD65;1100 116D 11BC; +AD66;AD66;1100 116D 11BD;AD66;1100 116D 11BD; +AD67;AD67;1100 116D 11BE;AD67;1100 116D 11BE; +AD68;AD68;1100 116D 11BF;AD68;1100 116D 11BF; +AD69;AD69;1100 116D 11C0;AD69;1100 116D 11C0; +AD6A;AD6A;1100 116D 11C1;AD6A;1100 116D 11C1; +AD6B;AD6B;1100 116D 11C2;AD6B;1100 116D 11C2; +AD6C;AD6C;1100 116E;AD6C;1100 116E; +AD6D;AD6D;1100 116E 11A8;AD6D;1100 116E 11A8; +AD6E;AD6E;1100 116E 11A9;AD6E;1100 116E 11A9; +AD6F;AD6F;1100 116E 11AA;AD6F;1100 116E 11AA; +AD70;AD70;1100 116E 11AB;AD70;1100 116E 11AB; +AD71;AD71;1100 116E 11AC;AD71;1100 116E 11AC; +AD72;AD72;1100 116E 11AD;AD72;1100 116E 11AD; +AD73;AD73;1100 116E 11AE;AD73;1100 116E 11AE; +AD74;AD74;1100 116E 11AF;AD74;1100 116E 11AF; +AD75;AD75;1100 116E 11B0;AD75;1100 116E 11B0; +AD76;AD76;1100 116E 11B1;AD76;1100 116E 11B1; +AD77;AD77;1100 116E 11B2;AD77;1100 116E 11B2; +AD78;AD78;1100 116E 11B3;AD78;1100 116E 11B3; +AD79;AD79;1100 116E 11B4;AD79;1100 116E 11B4; +AD7A;AD7A;1100 116E 11B5;AD7A;1100 116E 11B5; +AD7B;AD7B;1100 116E 11B6;AD7B;1100 116E 11B6; +AD7C;AD7C;1100 116E 11B7;AD7C;1100 116E 11B7; +AD7D;AD7D;1100 116E 11B8;AD7D;1100 116E 11B8; +AD7E;AD7E;1100 116E 11B9;AD7E;1100 116E 11B9; +AD7F;AD7F;1100 116E 11BA;AD7F;1100 116E 11BA; +AD80;AD80;1100 116E 11BB;AD80;1100 116E 11BB; +AD81;AD81;1100 116E 11BC;AD81;1100 116E 11BC; +AD82;AD82;1100 116E 11BD;AD82;1100 116E 11BD; +AD83;AD83;1100 116E 11BE;AD83;1100 116E 11BE; +AD84;AD84;1100 116E 11BF;AD84;1100 116E 11BF; +AD85;AD85;1100 116E 11C0;AD85;1100 116E 11C0; +AD86;AD86;1100 116E 11C1;AD86;1100 116E 11C1; +AD87;AD87;1100 116E 11C2;AD87;1100 116E 11C2; +AD88;AD88;1100 116F;AD88;1100 116F; +AD89;AD89;1100 116F 11A8;AD89;1100 116F 11A8; +AD8A;AD8A;1100 116F 11A9;AD8A;1100 116F 11A9; +AD8B;AD8B;1100 116F 11AA;AD8B;1100 116F 11AA; +AD8C;AD8C;1100 116F 11AB;AD8C;1100 116F 11AB; +AD8D;AD8D;1100 116F 11AC;AD8D;1100 116F 11AC; +AD8E;AD8E;1100 116F 11AD;AD8E;1100 116F 11AD; +AD8F;AD8F;1100 116F 11AE;AD8F;1100 116F 11AE; +AD90;AD90;1100 116F 11AF;AD90;1100 116F 11AF; +AD91;AD91;1100 116F 11B0;AD91;1100 116F 11B0; +AD92;AD92;1100 116F 11B1;AD92;1100 116F 11B1; +AD93;AD93;1100 116F 11B2;AD93;1100 116F 11B2; +AD94;AD94;1100 116F 11B3;AD94;1100 116F 11B3; +AD95;AD95;1100 116F 11B4;AD95;1100 116F 11B4; +AD96;AD96;1100 116F 11B5;AD96;1100 116F 11B5; +AD97;AD97;1100 116F 11B6;AD97;1100 116F 11B6; +AD98;AD98;1100 116F 11B7;AD98;1100 116F 11B7; +AD99;AD99;1100 116F 11B8;AD99;1100 116F 11B8; +AD9A;AD9A;1100 116F 11B9;AD9A;1100 116F 11B9; +AD9B;AD9B;1100 116F 11BA;AD9B;1100 116F 11BA; +AD9C;AD9C;1100 116F 11BB;AD9C;1100 116F 11BB; +AD9D;AD9D;1100 116F 11BC;AD9D;1100 116F 11BC; +AD9E;AD9E;1100 116F 11BD;AD9E;1100 116F 11BD; +AD9F;AD9F;1100 116F 11BE;AD9F;1100 116F 11BE; +ADA0;ADA0;1100 116F 11BF;ADA0;1100 116F 11BF; +ADA1;ADA1;1100 116F 11C0;ADA1;1100 116F 11C0; +ADA2;ADA2;1100 116F 11C1;ADA2;1100 116F 11C1; +ADA3;ADA3;1100 116F 11C2;ADA3;1100 116F 11C2; +ADA4;ADA4;1100 1170;ADA4;1100 1170; +ADA5;ADA5;1100 1170 11A8;ADA5;1100 1170 11A8; +ADA6;ADA6;1100 1170 11A9;ADA6;1100 1170 11A9; +ADA7;ADA7;1100 1170 11AA;ADA7;1100 1170 11AA; +ADA8;ADA8;1100 1170 11AB;ADA8;1100 1170 11AB; +ADA9;ADA9;1100 1170 11AC;ADA9;1100 1170 11AC; +ADAA;ADAA;1100 1170 11AD;ADAA;1100 1170 11AD; +ADAB;ADAB;1100 1170 11AE;ADAB;1100 1170 11AE; +ADAC;ADAC;1100 1170 11AF;ADAC;1100 1170 11AF; +ADAD;ADAD;1100 1170 11B0;ADAD;1100 1170 11B0; +ADAE;ADAE;1100 1170 11B1;ADAE;1100 1170 11B1; +ADAF;ADAF;1100 1170 11B2;ADAF;1100 1170 11B2; +ADB0;ADB0;1100 1170 11B3;ADB0;1100 1170 11B3; +ADB1;ADB1;1100 1170 11B4;ADB1;1100 1170 11B4; +ADB2;ADB2;1100 1170 11B5;ADB2;1100 1170 11B5; +ADB3;ADB3;1100 1170 11B6;ADB3;1100 1170 11B6; +ADB4;ADB4;1100 1170 11B7;ADB4;1100 1170 11B7; +ADB5;ADB5;1100 1170 11B8;ADB5;1100 1170 11B8; +ADB6;ADB6;1100 1170 11B9;ADB6;1100 1170 11B9; +ADB7;ADB7;1100 1170 11BA;ADB7;1100 1170 11BA; +ADB8;ADB8;1100 1170 11BB;ADB8;1100 1170 11BB; +ADB9;ADB9;1100 1170 11BC;ADB9;1100 1170 11BC; +ADBA;ADBA;1100 1170 11BD;ADBA;1100 1170 11BD; +ADBB;ADBB;1100 1170 11BE;ADBB;1100 1170 11BE; +ADBC;ADBC;1100 1170 11BF;ADBC;1100 1170 11BF; +ADBD;ADBD;1100 1170 11C0;ADBD;1100 1170 11C0; +ADBE;ADBE;1100 1170 11C1;ADBE;1100 1170 11C1; +ADBF;ADBF;1100 1170 11C2;ADBF;1100 1170 11C2; +ADC0;ADC0;1100 1171;ADC0;1100 1171; +ADC1;ADC1;1100 1171 11A8;ADC1;1100 1171 11A8; +ADC2;ADC2;1100 1171 11A9;ADC2;1100 1171 11A9; +ADC3;ADC3;1100 1171 11AA;ADC3;1100 1171 11AA; +ADC4;ADC4;1100 1171 11AB;ADC4;1100 1171 11AB; +ADC5;ADC5;1100 1171 11AC;ADC5;1100 1171 11AC; +ADC6;ADC6;1100 1171 11AD;ADC6;1100 1171 11AD; +ADC7;ADC7;1100 1171 11AE;ADC7;1100 1171 11AE; +ADC8;ADC8;1100 1171 11AF;ADC8;1100 1171 11AF; +ADC9;ADC9;1100 1171 11B0;ADC9;1100 1171 11B0; +ADCA;ADCA;1100 1171 11B1;ADCA;1100 1171 11B1; +ADCB;ADCB;1100 1171 11B2;ADCB;1100 1171 11B2; +ADCC;ADCC;1100 1171 11B3;ADCC;1100 1171 11B3; +ADCD;ADCD;1100 1171 11B4;ADCD;1100 1171 11B4; +ADCE;ADCE;1100 1171 11B5;ADCE;1100 1171 11B5; +ADCF;ADCF;1100 1171 11B6;ADCF;1100 1171 11B6; +ADD0;ADD0;1100 1171 11B7;ADD0;1100 1171 11B7; +ADD1;ADD1;1100 1171 11B8;ADD1;1100 1171 11B8; +ADD2;ADD2;1100 1171 11B9;ADD2;1100 1171 11B9; +ADD3;ADD3;1100 1171 11BA;ADD3;1100 1171 11BA; +ADD4;ADD4;1100 1171 11BB;ADD4;1100 1171 11BB; +ADD5;ADD5;1100 1171 11BC;ADD5;1100 1171 11BC; +ADD6;ADD6;1100 1171 11BD;ADD6;1100 1171 11BD; +ADD7;ADD7;1100 1171 11BE;ADD7;1100 1171 11BE; +ADD8;ADD8;1100 1171 11BF;ADD8;1100 1171 11BF; +ADD9;ADD9;1100 1171 11C0;ADD9;1100 1171 11C0; +ADDA;ADDA;1100 1171 11C1;ADDA;1100 1171 11C1; +ADDB;ADDB;1100 1171 11C2;ADDB;1100 1171 11C2; +ADDC;ADDC;1100 1172;ADDC;1100 1172; +ADDD;ADDD;1100 1172 11A8;ADDD;1100 1172 11A8; +ADDE;ADDE;1100 1172 11A9;ADDE;1100 1172 11A9; +ADDF;ADDF;1100 1172 11AA;ADDF;1100 1172 11AA; +ADE0;ADE0;1100 1172 11AB;ADE0;1100 1172 11AB; +ADE1;ADE1;1100 1172 11AC;ADE1;1100 1172 11AC; +ADE2;ADE2;1100 1172 11AD;ADE2;1100 1172 11AD; +ADE3;ADE3;1100 1172 11AE;ADE3;1100 1172 11AE; +ADE4;ADE4;1100 1172 11AF;ADE4;1100 1172 11AF; +ADE5;ADE5;1100 1172 11B0;ADE5;1100 1172 11B0; +ADE6;ADE6;1100 1172 11B1;ADE6;1100 1172 11B1; +ADE7;ADE7;1100 1172 11B2;ADE7;1100 1172 11B2; +ADE8;ADE8;1100 1172 11B3;ADE8;1100 1172 11B3; +ADE9;ADE9;1100 1172 11B4;ADE9;1100 1172 11B4; +ADEA;ADEA;1100 1172 11B5;ADEA;1100 1172 11B5; +ADEB;ADEB;1100 1172 11B6;ADEB;1100 1172 11B6; +ADEC;ADEC;1100 1172 11B7;ADEC;1100 1172 11B7; +ADED;ADED;1100 1172 11B8;ADED;1100 1172 11B8; +ADEE;ADEE;1100 1172 11B9;ADEE;1100 1172 11B9; +ADEF;ADEF;1100 1172 11BA;ADEF;1100 1172 11BA; +ADF0;ADF0;1100 1172 11BB;ADF0;1100 1172 11BB; +ADF1;ADF1;1100 1172 11BC;ADF1;1100 1172 11BC; +ADF2;ADF2;1100 1172 11BD;ADF2;1100 1172 11BD; +ADF3;ADF3;1100 1172 11BE;ADF3;1100 1172 11BE; +ADF4;ADF4;1100 1172 11BF;ADF4;1100 1172 11BF; +ADF5;ADF5;1100 1172 11C0;ADF5;1100 1172 11C0; +ADF6;ADF6;1100 1172 11C1;ADF6;1100 1172 11C1; +ADF7;ADF7;1100 1172 11C2;ADF7;1100 1172 11C2; +ADF8;ADF8;1100 1173;ADF8;1100 1173; +ADF9;ADF9;1100 1173 11A8;ADF9;1100 1173 11A8; +ADFA;ADFA;1100 1173 11A9;ADFA;1100 1173 11A9; +ADFB;ADFB;1100 1173 11AA;ADFB;1100 1173 11AA; +ADFC;ADFC;1100 1173 11AB;ADFC;1100 1173 11AB; +ADFD;ADFD;1100 1173 11AC;ADFD;1100 1173 11AC; +ADFE;ADFE;1100 1173 11AD;ADFE;1100 1173 11AD; +ADFF;ADFF;1100 1173 11AE;ADFF;1100 1173 11AE; +AE00;AE00;1100 1173 11AF;AE00;1100 1173 11AF; +AE01;AE01;1100 1173 11B0;AE01;1100 1173 11B0; +AE02;AE02;1100 1173 11B1;AE02;1100 1173 11B1; +AE03;AE03;1100 1173 11B2;AE03;1100 1173 11B2; +AE04;AE04;1100 1173 11B3;AE04;1100 1173 11B3; +AE05;AE05;1100 1173 11B4;AE05;1100 1173 11B4; +AE06;AE06;1100 1173 11B5;AE06;1100 1173 11B5; +AE07;AE07;1100 1173 11B6;AE07;1100 1173 11B6; +AE08;AE08;1100 1173 11B7;AE08;1100 1173 11B7; +AE09;AE09;1100 1173 11B8;AE09;1100 1173 11B8; +AE0A;AE0A;1100 1173 11B9;AE0A;1100 1173 11B9; +AE0B;AE0B;1100 1173 11BA;AE0B;1100 1173 11BA; +AE0C;AE0C;1100 1173 11BB;AE0C;1100 1173 11BB; +AE0D;AE0D;1100 1173 11BC;AE0D;1100 1173 11BC; +AE0E;AE0E;1100 1173 11BD;AE0E;1100 1173 11BD; +AE0F;AE0F;1100 1173 11BE;AE0F;1100 1173 11BE; +AE10;AE10;1100 1173 11BF;AE10;1100 1173 11BF; +AE11;AE11;1100 1173 11C0;AE11;1100 1173 11C0; +AE12;AE12;1100 1173 11C1;AE12;1100 1173 11C1; +AE13;AE13;1100 1173 11C2;AE13;1100 1173 11C2; +AE14;AE14;1100 1174;AE14;1100 1174; +AE15;AE15;1100 1174 11A8;AE15;1100 1174 11A8; +AE16;AE16;1100 1174 11A9;AE16;1100 1174 11A9; +AE17;AE17;1100 1174 11AA;AE17;1100 1174 11AA; +AE18;AE18;1100 1174 11AB;AE18;1100 1174 11AB; +AE19;AE19;1100 1174 11AC;AE19;1100 1174 11AC; +AE1A;AE1A;1100 1174 11AD;AE1A;1100 1174 11AD; +AE1B;AE1B;1100 1174 11AE;AE1B;1100 1174 11AE; +AE1C;AE1C;1100 1174 11AF;AE1C;1100 1174 11AF; +AE1D;AE1D;1100 1174 11B0;AE1D;1100 1174 11B0; +AE1E;AE1E;1100 1174 11B1;AE1E;1100 1174 11B1; +AE1F;AE1F;1100 1174 11B2;AE1F;1100 1174 11B2; +AE20;AE20;1100 1174 11B3;AE20;1100 1174 11B3; +AE21;AE21;1100 1174 11B4;AE21;1100 1174 11B4; +AE22;AE22;1100 1174 11B5;AE22;1100 1174 11B5; +AE23;AE23;1100 1174 11B6;AE23;1100 1174 11B6; +AE24;AE24;1100 1174 11B7;AE24;1100 1174 11B7; +AE25;AE25;1100 1174 11B8;AE25;1100 1174 11B8; +AE26;AE26;1100 1174 11B9;AE26;1100 1174 11B9; +AE27;AE27;1100 1174 11BA;AE27;1100 1174 11BA; +AE28;AE28;1100 1174 11BB;AE28;1100 1174 11BB; +AE29;AE29;1100 1174 11BC;AE29;1100 1174 11BC; +AE2A;AE2A;1100 1174 11BD;AE2A;1100 1174 11BD; +AE2B;AE2B;1100 1174 11BE;AE2B;1100 1174 11BE; +AE2C;AE2C;1100 1174 11BF;AE2C;1100 1174 11BF; +AE2D;AE2D;1100 1174 11C0;AE2D;1100 1174 11C0; +AE2E;AE2E;1100 1174 11C1;AE2E;1100 1174 11C1; +AE2F;AE2F;1100 1174 11C2;AE2F;1100 1174 11C2; +AE30;AE30;1100 1175;AE30;1100 1175; +AE31;AE31;1100 1175 11A8;AE31;1100 1175 11A8; +AE32;AE32;1100 1175 11A9;AE32;1100 1175 11A9; +AE33;AE33;1100 1175 11AA;AE33;1100 1175 11AA; +AE34;AE34;1100 1175 11AB;AE34;1100 1175 11AB; +AE35;AE35;1100 1175 11AC;AE35;1100 1175 11AC; +AE36;AE36;1100 1175 11AD;AE36;1100 1175 11AD; +AE37;AE37;1100 1175 11AE;AE37;1100 1175 11AE; +AE38;AE38;1100 1175 11AF;AE38;1100 1175 11AF; +AE39;AE39;1100 1175 11B0;AE39;1100 1175 11B0; +AE3A;AE3A;1100 1175 11B1;AE3A;1100 1175 11B1; +AE3B;AE3B;1100 1175 11B2;AE3B;1100 1175 11B2; +AE3C;AE3C;1100 1175 11B3;AE3C;1100 1175 11B3; +AE3D;AE3D;1100 1175 11B4;AE3D;1100 1175 11B4; +AE3E;AE3E;1100 1175 11B5;AE3E;1100 1175 11B5; +AE3F;AE3F;1100 1175 11B6;AE3F;1100 1175 11B6; +AE40;AE40;1100 1175 11B7;AE40;1100 1175 11B7; +AE41;AE41;1100 1175 11B8;AE41;1100 1175 11B8; +AE42;AE42;1100 1175 11B9;AE42;1100 1175 11B9; +AE43;AE43;1100 1175 11BA;AE43;1100 1175 11BA; +AE44;AE44;1100 1175 11BB;AE44;1100 1175 11BB; +AE45;AE45;1100 1175 11BC;AE45;1100 1175 11BC; +AE46;AE46;1100 1175 11BD;AE46;1100 1175 11BD; +AE47;AE47;1100 1175 11BE;AE47;1100 1175 11BE; +AE48;AE48;1100 1175 11BF;AE48;1100 1175 11BF; +AE49;AE49;1100 1175 11C0;AE49;1100 1175 11C0; +AE4A;AE4A;1100 1175 11C1;AE4A;1100 1175 11C1; +AE4B;AE4B;1100 1175 11C2;AE4B;1100 1175 11C2; +AE4C;AE4C;1101 1161;AE4C;1101 1161; +AE4D;AE4D;1101 1161 11A8;AE4D;1101 1161 11A8; +AE4E;AE4E;1101 1161 11A9;AE4E;1101 1161 11A9; +AE4F;AE4F;1101 1161 11AA;AE4F;1101 1161 11AA; +AE50;AE50;1101 1161 11AB;AE50;1101 1161 11AB; +AE51;AE51;1101 1161 11AC;AE51;1101 1161 11AC; +AE52;AE52;1101 1161 11AD;AE52;1101 1161 11AD; +AE53;AE53;1101 1161 11AE;AE53;1101 1161 11AE; +AE54;AE54;1101 1161 11AF;AE54;1101 1161 11AF; +AE55;AE55;1101 1161 11B0;AE55;1101 1161 11B0; +AE56;AE56;1101 1161 11B1;AE56;1101 1161 11B1; +AE57;AE57;1101 1161 11B2;AE57;1101 1161 11B2; +AE58;AE58;1101 1161 11B3;AE58;1101 1161 11B3; +AE59;AE59;1101 1161 11B4;AE59;1101 1161 11B4; +AE5A;AE5A;1101 1161 11B5;AE5A;1101 1161 11B5; +AE5B;AE5B;1101 1161 11B6;AE5B;1101 1161 11B6; +AE5C;AE5C;1101 1161 11B7;AE5C;1101 1161 11B7; +AE5D;AE5D;1101 1161 11B8;AE5D;1101 1161 11B8; +AE5E;AE5E;1101 1161 11B9;AE5E;1101 1161 11B9; +AE5F;AE5F;1101 1161 11BA;AE5F;1101 1161 11BA; +AE60;AE60;1101 1161 11BB;AE60;1101 1161 11BB; +AE61;AE61;1101 1161 11BC;AE61;1101 1161 11BC; +AE62;AE62;1101 1161 11BD;AE62;1101 1161 11BD; +AE63;AE63;1101 1161 11BE;AE63;1101 1161 11BE; +AE64;AE64;1101 1161 11BF;AE64;1101 1161 11BF; +AE65;AE65;1101 1161 11C0;AE65;1101 1161 11C0; +AE66;AE66;1101 1161 11C1;AE66;1101 1161 11C1; +AE67;AE67;1101 1161 11C2;AE67;1101 1161 11C2; +AE68;AE68;1101 1162;AE68;1101 1162; +AE69;AE69;1101 1162 11A8;AE69;1101 1162 11A8; +AE6A;AE6A;1101 1162 11A9;AE6A;1101 1162 11A9; +AE6B;AE6B;1101 1162 11AA;AE6B;1101 1162 11AA; +AE6C;AE6C;1101 1162 11AB;AE6C;1101 1162 11AB; +AE6D;AE6D;1101 1162 11AC;AE6D;1101 1162 11AC; +AE6E;AE6E;1101 1162 11AD;AE6E;1101 1162 11AD; +AE6F;AE6F;1101 1162 11AE;AE6F;1101 1162 11AE; +AE70;AE70;1101 1162 11AF;AE70;1101 1162 11AF; +AE71;AE71;1101 1162 11B0;AE71;1101 1162 11B0; +AE72;AE72;1101 1162 11B1;AE72;1101 1162 11B1; +AE73;AE73;1101 1162 11B2;AE73;1101 1162 11B2; +AE74;AE74;1101 1162 11B3;AE74;1101 1162 11B3; +AE75;AE75;1101 1162 11B4;AE75;1101 1162 11B4; +AE76;AE76;1101 1162 11B5;AE76;1101 1162 11B5; +AE77;AE77;1101 1162 11B6;AE77;1101 1162 11B6; +AE78;AE78;1101 1162 11B7;AE78;1101 1162 11B7; +AE79;AE79;1101 1162 11B8;AE79;1101 1162 11B8; +AE7A;AE7A;1101 1162 11B9;AE7A;1101 1162 11B9; +AE7B;AE7B;1101 1162 11BA;AE7B;1101 1162 11BA; +AE7C;AE7C;1101 1162 11BB;AE7C;1101 1162 11BB; +AE7D;AE7D;1101 1162 11BC;AE7D;1101 1162 11BC; +AE7E;AE7E;1101 1162 11BD;AE7E;1101 1162 11BD; +AE7F;AE7F;1101 1162 11BE;AE7F;1101 1162 11BE; +AE80;AE80;1101 1162 11BF;AE80;1101 1162 11BF; +AE81;AE81;1101 1162 11C0;AE81;1101 1162 11C0; +AE82;AE82;1101 1162 11C1;AE82;1101 1162 11C1; +AE83;AE83;1101 1162 11C2;AE83;1101 1162 11C2; +AE84;AE84;1101 1163;AE84;1101 1163; +AE85;AE85;1101 1163 11A8;AE85;1101 1163 11A8; +AE86;AE86;1101 1163 11A9;AE86;1101 1163 11A9; +AE87;AE87;1101 1163 11AA;AE87;1101 1163 11AA; +AE88;AE88;1101 1163 11AB;AE88;1101 1163 11AB; +AE89;AE89;1101 1163 11AC;AE89;1101 1163 11AC; +AE8A;AE8A;1101 1163 11AD;AE8A;1101 1163 11AD; +AE8B;AE8B;1101 1163 11AE;AE8B;1101 1163 11AE; +AE8C;AE8C;1101 1163 11AF;AE8C;1101 1163 11AF; +AE8D;AE8D;1101 1163 11B0;AE8D;1101 1163 11B0; +AE8E;AE8E;1101 1163 11B1;AE8E;1101 1163 11B1; +AE8F;AE8F;1101 1163 11B2;AE8F;1101 1163 11B2; +AE90;AE90;1101 1163 11B3;AE90;1101 1163 11B3; +AE91;AE91;1101 1163 11B4;AE91;1101 1163 11B4; +AE92;AE92;1101 1163 11B5;AE92;1101 1163 11B5; +AE93;AE93;1101 1163 11B6;AE93;1101 1163 11B6; +AE94;AE94;1101 1163 11B7;AE94;1101 1163 11B7; +AE95;AE95;1101 1163 11B8;AE95;1101 1163 11B8; +AE96;AE96;1101 1163 11B9;AE96;1101 1163 11B9; +AE97;AE97;1101 1163 11BA;AE97;1101 1163 11BA; +AE98;AE98;1101 1163 11BB;AE98;1101 1163 11BB; +AE99;AE99;1101 1163 11BC;AE99;1101 1163 11BC; +AE9A;AE9A;1101 1163 11BD;AE9A;1101 1163 11BD; +AE9B;AE9B;1101 1163 11BE;AE9B;1101 1163 11BE; +AE9C;AE9C;1101 1163 11BF;AE9C;1101 1163 11BF; +AE9D;AE9D;1101 1163 11C0;AE9D;1101 1163 11C0; +AE9E;AE9E;1101 1163 11C1;AE9E;1101 1163 11C1; +AE9F;AE9F;1101 1163 11C2;AE9F;1101 1163 11C2; +AEA0;AEA0;1101 1164;AEA0;1101 1164; +AEA1;AEA1;1101 1164 11A8;AEA1;1101 1164 11A8; +AEA2;AEA2;1101 1164 11A9;AEA2;1101 1164 11A9; +AEA3;AEA3;1101 1164 11AA;AEA3;1101 1164 11AA; +AEA4;AEA4;1101 1164 11AB;AEA4;1101 1164 11AB; +AEA5;AEA5;1101 1164 11AC;AEA5;1101 1164 11AC; +AEA6;AEA6;1101 1164 11AD;AEA6;1101 1164 11AD; +AEA7;AEA7;1101 1164 11AE;AEA7;1101 1164 11AE; +AEA8;AEA8;1101 1164 11AF;AEA8;1101 1164 11AF; +AEA9;AEA9;1101 1164 11B0;AEA9;1101 1164 11B0; +AEAA;AEAA;1101 1164 11B1;AEAA;1101 1164 11B1; +AEAB;AEAB;1101 1164 11B2;AEAB;1101 1164 11B2; +AEAC;AEAC;1101 1164 11B3;AEAC;1101 1164 11B3; +AEAD;AEAD;1101 1164 11B4;AEAD;1101 1164 11B4; +AEAE;AEAE;1101 1164 11B5;AEAE;1101 1164 11B5; +AEAF;AEAF;1101 1164 11B6;AEAF;1101 1164 11B6; +AEB0;AEB0;1101 1164 11B7;AEB0;1101 1164 11B7; +AEB1;AEB1;1101 1164 11B8;AEB1;1101 1164 11B8; +AEB2;AEB2;1101 1164 11B9;AEB2;1101 1164 11B9; +AEB3;AEB3;1101 1164 11BA;AEB3;1101 1164 11BA; +AEB4;AEB4;1101 1164 11BB;AEB4;1101 1164 11BB; +AEB5;AEB5;1101 1164 11BC;AEB5;1101 1164 11BC; +AEB6;AEB6;1101 1164 11BD;AEB6;1101 1164 11BD; +AEB7;AEB7;1101 1164 11BE;AEB7;1101 1164 11BE; +AEB8;AEB8;1101 1164 11BF;AEB8;1101 1164 11BF; +AEB9;AEB9;1101 1164 11C0;AEB9;1101 1164 11C0; +AEBA;AEBA;1101 1164 11C1;AEBA;1101 1164 11C1; +AEBB;AEBB;1101 1164 11C2;AEBB;1101 1164 11C2; +AEBC;AEBC;1101 1165;AEBC;1101 1165; +AEBD;AEBD;1101 1165 11A8;AEBD;1101 1165 11A8; +AEBE;AEBE;1101 1165 11A9;AEBE;1101 1165 11A9; +AEBF;AEBF;1101 1165 11AA;AEBF;1101 1165 11AA; +AEC0;AEC0;1101 1165 11AB;AEC0;1101 1165 11AB; +AEC1;AEC1;1101 1165 11AC;AEC1;1101 1165 11AC; +AEC2;AEC2;1101 1165 11AD;AEC2;1101 1165 11AD; +AEC3;AEC3;1101 1165 11AE;AEC3;1101 1165 11AE; +AEC4;AEC4;1101 1165 11AF;AEC4;1101 1165 11AF; +AEC5;AEC5;1101 1165 11B0;AEC5;1101 1165 11B0; +AEC6;AEC6;1101 1165 11B1;AEC6;1101 1165 11B1; +AEC7;AEC7;1101 1165 11B2;AEC7;1101 1165 11B2; +AEC8;AEC8;1101 1165 11B3;AEC8;1101 1165 11B3; +AEC9;AEC9;1101 1165 11B4;AEC9;1101 1165 11B4; +AECA;AECA;1101 1165 11B5;AECA;1101 1165 11B5; +AECB;AECB;1101 1165 11B6;AECB;1101 1165 11B6; +AECC;AECC;1101 1165 11B7;AECC;1101 1165 11B7; +AECD;AECD;1101 1165 11B8;AECD;1101 1165 11B8; +AECE;AECE;1101 1165 11B9;AECE;1101 1165 11B9; +AECF;AECF;1101 1165 11BA;AECF;1101 1165 11BA; +AED0;AED0;1101 1165 11BB;AED0;1101 1165 11BB; +AED1;AED1;1101 1165 11BC;AED1;1101 1165 11BC; +AED2;AED2;1101 1165 11BD;AED2;1101 1165 11BD; +AED3;AED3;1101 1165 11BE;AED3;1101 1165 11BE; +AED4;AED4;1101 1165 11BF;AED4;1101 1165 11BF; +AED5;AED5;1101 1165 11C0;AED5;1101 1165 11C0; +AED6;AED6;1101 1165 11C1;AED6;1101 1165 11C1; +AED7;AED7;1101 1165 11C2;AED7;1101 1165 11C2; +AED8;AED8;1101 1166;AED8;1101 1166; +AED9;AED9;1101 1166 11A8;AED9;1101 1166 11A8; +AEDA;AEDA;1101 1166 11A9;AEDA;1101 1166 11A9; +AEDB;AEDB;1101 1166 11AA;AEDB;1101 1166 11AA; +AEDC;AEDC;1101 1166 11AB;AEDC;1101 1166 11AB; +AEDD;AEDD;1101 1166 11AC;AEDD;1101 1166 11AC; +AEDE;AEDE;1101 1166 11AD;AEDE;1101 1166 11AD; +AEDF;AEDF;1101 1166 11AE;AEDF;1101 1166 11AE; +AEE0;AEE0;1101 1166 11AF;AEE0;1101 1166 11AF; +AEE1;AEE1;1101 1166 11B0;AEE1;1101 1166 11B0; +AEE2;AEE2;1101 1166 11B1;AEE2;1101 1166 11B1; +AEE3;AEE3;1101 1166 11B2;AEE3;1101 1166 11B2; +AEE4;AEE4;1101 1166 11B3;AEE4;1101 1166 11B3; +AEE5;AEE5;1101 1166 11B4;AEE5;1101 1166 11B4; +AEE6;AEE6;1101 1166 11B5;AEE6;1101 1166 11B5; +AEE7;AEE7;1101 1166 11B6;AEE7;1101 1166 11B6; +AEE8;AEE8;1101 1166 11B7;AEE8;1101 1166 11B7; +AEE9;AEE9;1101 1166 11B8;AEE9;1101 1166 11B8; +AEEA;AEEA;1101 1166 11B9;AEEA;1101 1166 11B9; +AEEB;AEEB;1101 1166 11BA;AEEB;1101 1166 11BA; +AEEC;AEEC;1101 1166 11BB;AEEC;1101 1166 11BB; +AEED;AEED;1101 1166 11BC;AEED;1101 1166 11BC; +AEEE;AEEE;1101 1166 11BD;AEEE;1101 1166 11BD; +AEEF;AEEF;1101 1166 11BE;AEEF;1101 1166 11BE; +AEF0;AEF0;1101 1166 11BF;AEF0;1101 1166 11BF; +AEF1;AEF1;1101 1166 11C0;AEF1;1101 1166 11C0; +AEF2;AEF2;1101 1166 11C1;AEF2;1101 1166 11C1; +AEF3;AEF3;1101 1166 11C2;AEF3;1101 1166 11C2; +AEF4;AEF4;1101 1167;AEF4;1101 1167; +AEF5;AEF5;1101 1167 11A8;AEF5;1101 1167 11A8; +AEF6;AEF6;1101 1167 11A9;AEF6;1101 1167 11A9; +AEF7;AEF7;1101 1167 11AA;AEF7;1101 1167 11AA; +AEF8;AEF8;1101 1167 11AB;AEF8;1101 1167 11AB; +AEF9;AEF9;1101 1167 11AC;AEF9;1101 1167 11AC; +AEFA;AEFA;1101 1167 11AD;AEFA;1101 1167 11AD; +AEFB;AEFB;1101 1167 11AE;AEFB;1101 1167 11AE; +AEFC;AEFC;1101 1167 11AF;AEFC;1101 1167 11AF; +AEFD;AEFD;1101 1167 11B0;AEFD;1101 1167 11B0; +AEFE;AEFE;1101 1167 11B1;AEFE;1101 1167 11B1; +AEFF;AEFF;1101 1167 11B2;AEFF;1101 1167 11B2; +AF00;AF00;1101 1167 11B3;AF00;1101 1167 11B3; +AF01;AF01;1101 1167 11B4;AF01;1101 1167 11B4; +AF02;AF02;1101 1167 11B5;AF02;1101 1167 11B5; +AF03;AF03;1101 1167 11B6;AF03;1101 1167 11B6; +AF04;AF04;1101 1167 11B7;AF04;1101 1167 11B7; +AF05;AF05;1101 1167 11B8;AF05;1101 1167 11B8; +AF06;AF06;1101 1167 11B9;AF06;1101 1167 11B9; +AF07;AF07;1101 1167 11BA;AF07;1101 1167 11BA; +AF08;AF08;1101 1167 11BB;AF08;1101 1167 11BB; +AF09;AF09;1101 1167 11BC;AF09;1101 1167 11BC; +AF0A;AF0A;1101 1167 11BD;AF0A;1101 1167 11BD; +AF0B;AF0B;1101 1167 11BE;AF0B;1101 1167 11BE; +AF0C;AF0C;1101 1167 11BF;AF0C;1101 1167 11BF; +AF0D;AF0D;1101 1167 11C0;AF0D;1101 1167 11C0; +AF0E;AF0E;1101 1167 11C1;AF0E;1101 1167 11C1; +AF0F;AF0F;1101 1167 11C2;AF0F;1101 1167 11C2; +AF10;AF10;1101 1168;AF10;1101 1168; +AF11;AF11;1101 1168 11A8;AF11;1101 1168 11A8; +AF12;AF12;1101 1168 11A9;AF12;1101 1168 11A9; +AF13;AF13;1101 1168 11AA;AF13;1101 1168 11AA; +AF14;AF14;1101 1168 11AB;AF14;1101 1168 11AB; +AF15;AF15;1101 1168 11AC;AF15;1101 1168 11AC; +AF16;AF16;1101 1168 11AD;AF16;1101 1168 11AD; +AF17;AF17;1101 1168 11AE;AF17;1101 1168 11AE; +AF18;AF18;1101 1168 11AF;AF18;1101 1168 11AF; +AF19;AF19;1101 1168 11B0;AF19;1101 1168 11B0; +AF1A;AF1A;1101 1168 11B1;AF1A;1101 1168 11B1; +AF1B;AF1B;1101 1168 11B2;AF1B;1101 1168 11B2; +AF1C;AF1C;1101 1168 11B3;AF1C;1101 1168 11B3; +AF1D;AF1D;1101 1168 11B4;AF1D;1101 1168 11B4; +AF1E;AF1E;1101 1168 11B5;AF1E;1101 1168 11B5; +AF1F;AF1F;1101 1168 11B6;AF1F;1101 1168 11B6; +AF20;AF20;1101 1168 11B7;AF20;1101 1168 11B7; +AF21;AF21;1101 1168 11B8;AF21;1101 1168 11B8; +AF22;AF22;1101 1168 11B9;AF22;1101 1168 11B9; +AF23;AF23;1101 1168 11BA;AF23;1101 1168 11BA; +AF24;AF24;1101 1168 11BB;AF24;1101 1168 11BB; +AF25;AF25;1101 1168 11BC;AF25;1101 1168 11BC; +AF26;AF26;1101 1168 11BD;AF26;1101 1168 11BD; +AF27;AF27;1101 1168 11BE;AF27;1101 1168 11BE; +AF28;AF28;1101 1168 11BF;AF28;1101 1168 11BF; +AF29;AF29;1101 1168 11C0;AF29;1101 1168 11C0; +AF2A;AF2A;1101 1168 11C1;AF2A;1101 1168 11C1; +AF2B;AF2B;1101 1168 11C2;AF2B;1101 1168 11C2; +AF2C;AF2C;1101 1169;AF2C;1101 1169; +AF2D;AF2D;1101 1169 11A8;AF2D;1101 1169 11A8; +AF2E;AF2E;1101 1169 11A9;AF2E;1101 1169 11A9; +AF2F;AF2F;1101 1169 11AA;AF2F;1101 1169 11AA; +AF30;AF30;1101 1169 11AB;AF30;1101 1169 11AB; +AF31;AF31;1101 1169 11AC;AF31;1101 1169 11AC; +AF32;AF32;1101 1169 11AD;AF32;1101 1169 11AD; +AF33;AF33;1101 1169 11AE;AF33;1101 1169 11AE; +AF34;AF34;1101 1169 11AF;AF34;1101 1169 11AF; +AF35;AF35;1101 1169 11B0;AF35;1101 1169 11B0; +AF36;AF36;1101 1169 11B1;AF36;1101 1169 11B1; +AF37;AF37;1101 1169 11B2;AF37;1101 1169 11B2; +AF38;AF38;1101 1169 11B3;AF38;1101 1169 11B3; +AF39;AF39;1101 1169 11B4;AF39;1101 1169 11B4; +AF3A;AF3A;1101 1169 11B5;AF3A;1101 1169 11B5; +AF3B;AF3B;1101 1169 11B6;AF3B;1101 1169 11B6; +AF3C;AF3C;1101 1169 11B7;AF3C;1101 1169 11B7; +AF3D;AF3D;1101 1169 11B8;AF3D;1101 1169 11B8; +AF3E;AF3E;1101 1169 11B9;AF3E;1101 1169 11B9; +AF3F;AF3F;1101 1169 11BA;AF3F;1101 1169 11BA; +AF40;AF40;1101 1169 11BB;AF40;1101 1169 11BB; +AF41;AF41;1101 1169 11BC;AF41;1101 1169 11BC; +AF42;AF42;1101 1169 11BD;AF42;1101 1169 11BD; +AF43;AF43;1101 1169 11BE;AF43;1101 1169 11BE; +AF44;AF44;1101 1169 11BF;AF44;1101 1169 11BF; +AF45;AF45;1101 1169 11C0;AF45;1101 1169 11C0; +AF46;AF46;1101 1169 11C1;AF46;1101 1169 11C1; +AF47;AF47;1101 1169 11C2;AF47;1101 1169 11C2; +AF48;AF48;1101 116A;AF48;1101 116A; +AF49;AF49;1101 116A 11A8;AF49;1101 116A 11A8; +AF4A;AF4A;1101 116A 11A9;AF4A;1101 116A 11A9; +AF4B;AF4B;1101 116A 11AA;AF4B;1101 116A 11AA; +AF4C;AF4C;1101 116A 11AB;AF4C;1101 116A 11AB; +AF4D;AF4D;1101 116A 11AC;AF4D;1101 116A 11AC; +AF4E;AF4E;1101 116A 11AD;AF4E;1101 116A 11AD; +AF4F;AF4F;1101 116A 11AE;AF4F;1101 116A 11AE; +AF50;AF50;1101 116A 11AF;AF50;1101 116A 11AF; +AF51;AF51;1101 116A 11B0;AF51;1101 116A 11B0; +AF52;AF52;1101 116A 11B1;AF52;1101 116A 11B1; +AF53;AF53;1101 116A 11B2;AF53;1101 116A 11B2; +AF54;AF54;1101 116A 11B3;AF54;1101 116A 11B3; +AF55;AF55;1101 116A 11B4;AF55;1101 116A 11B4; +AF56;AF56;1101 116A 11B5;AF56;1101 116A 11B5; +AF57;AF57;1101 116A 11B6;AF57;1101 116A 11B6; +AF58;AF58;1101 116A 11B7;AF58;1101 116A 11B7; +AF59;AF59;1101 116A 11B8;AF59;1101 116A 11B8; +AF5A;AF5A;1101 116A 11B9;AF5A;1101 116A 11B9; +AF5B;AF5B;1101 116A 11BA;AF5B;1101 116A 11BA; +AF5C;AF5C;1101 116A 11BB;AF5C;1101 116A 11BB; +AF5D;AF5D;1101 116A 11BC;AF5D;1101 116A 11BC; +AF5E;AF5E;1101 116A 11BD;AF5E;1101 116A 11BD; +AF5F;AF5F;1101 116A 11BE;AF5F;1101 116A 11BE; +AF60;AF60;1101 116A 11BF;AF60;1101 116A 11BF; +AF61;AF61;1101 116A 11C0;AF61;1101 116A 11C0; +AF62;AF62;1101 116A 11C1;AF62;1101 116A 11C1; +AF63;AF63;1101 116A 11C2;AF63;1101 116A 11C2; +AF64;AF64;1101 116B;AF64;1101 116B; +AF65;AF65;1101 116B 11A8;AF65;1101 116B 11A8; +AF66;AF66;1101 116B 11A9;AF66;1101 116B 11A9; +AF67;AF67;1101 116B 11AA;AF67;1101 116B 11AA; +AF68;AF68;1101 116B 11AB;AF68;1101 116B 11AB; +AF69;AF69;1101 116B 11AC;AF69;1101 116B 11AC; +AF6A;AF6A;1101 116B 11AD;AF6A;1101 116B 11AD; +AF6B;AF6B;1101 116B 11AE;AF6B;1101 116B 11AE; +AF6C;AF6C;1101 116B 11AF;AF6C;1101 116B 11AF; +AF6D;AF6D;1101 116B 11B0;AF6D;1101 116B 11B0; +AF6E;AF6E;1101 116B 11B1;AF6E;1101 116B 11B1; +AF6F;AF6F;1101 116B 11B2;AF6F;1101 116B 11B2; +AF70;AF70;1101 116B 11B3;AF70;1101 116B 11B3; +AF71;AF71;1101 116B 11B4;AF71;1101 116B 11B4; +AF72;AF72;1101 116B 11B5;AF72;1101 116B 11B5; +AF73;AF73;1101 116B 11B6;AF73;1101 116B 11B6; +AF74;AF74;1101 116B 11B7;AF74;1101 116B 11B7; +AF75;AF75;1101 116B 11B8;AF75;1101 116B 11B8; +AF76;AF76;1101 116B 11B9;AF76;1101 116B 11B9; +AF77;AF77;1101 116B 11BA;AF77;1101 116B 11BA; +AF78;AF78;1101 116B 11BB;AF78;1101 116B 11BB; +AF79;AF79;1101 116B 11BC;AF79;1101 116B 11BC; +AF7A;AF7A;1101 116B 11BD;AF7A;1101 116B 11BD; +AF7B;AF7B;1101 116B 11BE;AF7B;1101 116B 11BE; +AF7C;AF7C;1101 116B 11BF;AF7C;1101 116B 11BF; +AF7D;AF7D;1101 116B 11C0;AF7D;1101 116B 11C0; +AF7E;AF7E;1101 116B 11C1;AF7E;1101 116B 11C1; +AF7F;AF7F;1101 116B 11C2;AF7F;1101 116B 11C2; +AF80;AF80;1101 116C;AF80;1101 116C; +AF81;AF81;1101 116C 11A8;AF81;1101 116C 11A8; +AF82;AF82;1101 116C 11A9;AF82;1101 116C 11A9; +AF83;AF83;1101 116C 11AA;AF83;1101 116C 11AA; +AF84;AF84;1101 116C 11AB;AF84;1101 116C 11AB; +AF85;AF85;1101 116C 11AC;AF85;1101 116C 11AC; +AF86;AF86;1101 116C 11AD;AF86;1101 116C 11AD; +AF87;AF87;1101 116C 11AE;AF87;1101 116C 11AE; +AF88;AF88;1101 116C 11AF;AF88;1101 116C 11AF; +AF89;AF89;1101 116C 11B0;AF89;1101 116C 11B0; +AF8A;AF8A;1101 116C 11B1;AF8A;1101 116C 11B1; +AF8B;AF8B;1101 116C 11B2;AF8B;1101 116C 11B2; +AF8C;AF8C;1101 116C 11B3;AF8C;1101 116C 11B3; +AF8D;AF8D;1101 116C 11B4;AF8D;1101 116C 11B4; +AF8E;AF8E;1101 116C 11B5;AF8E;1101 116C 11B5; +AF8F;AF8F;1101 116C 11B6;AF8F;1101 116C 11B6; +AF90;AF90;1101 116C 11B7;AF90;1101 116C 11B7; +AF91;AF91;1101 116C 11B8;AF91;1101 116C 11B8; +AF92;AF92;1101 116C 11B9;AF92;1101 116C 11B9; +AF93;AF93;1101 116C 11BA;AF93;1101 116C 11BA; +AF94;AF94;1101 116C 11BB;AF94;1101 116C 11BB; +AF95;AF95;1101 116C 11BC;AF95;1101 116C 11BC; +AF96;AF96;1101 116C 11BD;AF96;1101 116C 11BD; +AF97;AF97;1101 116C 11BE;AF97;1101 116C 11BE; +AF98;AF98;1101 116C 11BF;AF98;1101 116C 11BF; +AF99;AF99;1101 116C 11C0;AF99;1101 116C 11C0; +AF9A;AF9A;1101 116C 11C1;AF9A;1101 116C 11C1; +AF9B;AF9B;1101 116C 11C2;AF9B;1101 116C 11C2; +AF9C;AF9C;1101 116D;AF9C;1101 116D; +AF9D;AF9D;1101 116D 11A8;AF9D;1101 116D 11A8; +AF9E;AF9E;1101 116D 11A9;AF9E;1101 116D 11A9; +AF9F;AF9F;1101 116D 11AA;AF9F;1101 116D 11AA; +AFA0;AFA0;1101 116D 11AB;AFA0;1101 116D 11AB; +AFA1;AFA1;1101 116D 11AC;AFA1;1101 116D 11AC; +AFA2;AFA2;1101 116D 11AD;AFA2;1101 116D 11AD; +AFA3;AFA3;1101 116D 11AE;AFA3;1101 116D 11AE; +AFA4;AFA4;1101 116D 11AF;AFA4;1101 116D 11AF; +AFA5;AFA5;1101 116D 11B0;AFA5;1101 116D 11B0; +AFA6;AFA6;1101 116D 11B1;AFA6;1101 116D 11B1; +AFA7;AFA7;1101 116D 11B2;AFA7;1101 116D 11B2; +AFA8;AFA8;1101 116D 11B3;AFA8;1101 116D 11B3; +AFA9;AFA9;1101 116D 11B4;AFA9;1101 116D 11B4; +AFAA;AFAA;1101 116D 11B5;AFAA;1101 116D 11B5; +AFAB;AFAB;1101 116D 11B6;AFAB;1101 116D 11B6; +AFAC;AFAC;1101 116D 11B7;AFAC;1101 116D 11B7; +AFAD;AFAD;1101 116D 11B8;AFAD;1101 116D 11B8; +AFAE;AFAE;1101 116D 11B9;AFAE;1101 116D 11B9; +AFAF;AFAF;1101 116D 11BA;AFAF;1101 116D 11BA; +AFB0;AFB0;1101 116D 11BB;AFB0;1101 116D 11BB; +AFB1;AFB1;1101 116D 11BC;AFB1;1101 116D 11BC; +AFB2;AFB2;1101 116D 11BD;AFB2;1101 116D 11BD; +AFB3;AFB3;1101 116D 11BE;AFB3;1101 116D 11BE; +AFB4;AFB4;1101 116D 11BF;AFB4;1101 116D 11BF; +AFB5;AFB5;1101 116D 11C0;AFB5;1101 116D 11C0; +AFB6;AFB6;1101 116D 11C1;AFB6;1101 116D 11C1; +AFB7;AFB7;1101 116D 11C2;AFB7;1101 116D 11C2; +AFB8;AFB8;1101 116E;AFB8;1101 116E; +AFB9;AFB9;1101 116E 11A8;AFB9;1101 116E 11A8; +AFBA;AFBA;1101 116E 11A9;AFBA;1101 116E 11A9; +AFBB;AFBB;1101 116E 11AA;AFBB;1101 116E 11AA; +AFBC;AFBC;1101 116E 11AB;AFBC;1101 116E 11AB; +AFBD;AFBD;1101 116E 11AC;AFBD;1101 116E 11AC; +AFBE;AFBE;1101 116E 11AD;AFBE;1101 116E 11AD; +AFBF;AFBF;1101 116E 11AE;AFBF;1101 116E 11AE; +AFC0;AFC0;1101 116E 11AF;AFC0;1101 116E 11AF; +AFC1;AFC1;1101 116E 11B0;AFC1;1101 116E 11B0; +AFC2;AFC2;1101 116E 11B1;AFC2;1101 116E 11B1; +AFC3;AFC3;1101 116E 11B2;AFC3;1101 116E 11B2; +AFC4;AFC4;1101 116E 11B3;AFC4;1101 116E 11B3; +AFC5;AFC5;1101 116E 11B4;AFC5;1101 116E 11B4; +AFC6;AFC6;1101 116E 11B5;AFC6;1101 116E 11B5; +AFC7;AFC7;1101 116E 11B6;AFC7;1101 116E 11B6; +AFC8;AFC8;1101 116E 11B7;AFC8;1101 116E 11B7; +AFC9;AFC9;1101 116E 11B8;AFC9;1101 116E 11B8; +AFCA;AFCA;1101 116E 11B9;AFCA;1101 116E 11B9; +AFCB;AFCB;1101 116E 11BA;AFCB;1101 116E 11BA; +AFCC;AFCC;1101 116E 11BB;AFCC;1101 116E 11BB; +AFCD;AFCD;1101 116E 11BC;AFCD;1101 116E 11BC; +AFCE;AFCE;1101 116E 11BD;AFCE;1101 116E 11BD; +AFCF;AFCF;1101 116E 11BE;AFCF;1101 116E 11BE; +AFD0;AFD0;1101 116E 11BF;AFD0;1101 116E 11BF; +AFD1;AFD1;1101 116E 11C0;AFD1;1101 116E 11C0; +AFD2;AFD2;1101 116E 11C1;AFD2;1101 116E 11C1; +AFD3;AFD3;1101 116E 11C2;AFD3;1101 116E 11C2; +AFD4;AFD4;1101 116F;AFD4;1101 116F; +AFD5;AFD5;1101 116F 11A8;AFD5;1101 116F 11A8; +AFD6;AFD6;1101 116F 11A9;AFD6;1101 116F 11A9; +AFD7;AFD7;1101 116F 11AA;AFD7;1101 116F 11AA; +AFD8;AFD8;1101 116F 11AB;AFD8;1101 116F 11AB; +AFD9;AFD9;1101 116F 11AC;AFD9;1101 116F 11AC; +AFDA;AFDA;1101 116F 11AD;AFDA;1101 116F 11AD; +AFDB;AFDB;1101 116F 11AE;AFDB;1101 116F 11AE; +AFDC;AFDC;1101 116F 11AF;AFDC;1101 116F 11AF; +AFDD;AFDD;1101 116F 11B0;AFDD;1101 116F 11B0; +AFDE;AFDE;1101 116F 11B1;AFDE;1101 116F 11B1; +AFDF;AFDF;1101 116F 11B2;AFDF;1101 116F 11B2; +AFE0;AFE0;1101 116F 11B3;AFE0;1101 116F 11B3; +AFE1;AFE1;1101 116F 11B4;AFE1;1101 116F 11B4; +AFE2;AFE2;1101 116F 11B5;AFE2;1101 116F 11B5; +AFE3;AFE3;1101 116F 11B6;AFE3;1101 116F 11B6; +AFE4;AFE4;1101 116F 11B7;AFE4;1101 116F 11B7; +AFE5;AFE5;1101 116F 11B8;AFE5;1101 116F 11B8; +AFE6;AFE6;1101 116F 11B9;AFE6;1101 116F 11B9; +AFE7;AFE7;1101 116F 11BA;AFE7;1101 116F 11BA; +AFE8;AFE8;1101 116F 11BB;AFE8;1101 116F 11BB; +AFE9;AFE9;1101 116F 11BC;AFE9;1101 116F 11BC; +AFEA;AFEA;1101 116F 11BD;AFEA;1101 116F 11BD; +AFEB;AFEB;1101 116F 11BE;AFEB;1101 116F 11BE; +AFEC;AFEC;1101 116F 11BF;AFEC;1101 116F 11BF; +AFED;AFED;1101 116F 11C0;AFED;1101 116F 11C0; +AFEE;AFEE;1101 116F 11C1;AFEE;1101 116F 11C1; +AFEF;AFEF;1101 116F 11C2;AFEF;1101 116F 11C2; +AFF0;AFF0;1101 1170;AFF0;1101 1170; +AFF1;AFF1;1101 1170 11A8;AFF1;1101 1170 11A8; +AFF2;AFF2;1101 1170 11A9;AFF2;1101 1170 11A9; +AFF3;AFF3;1101 1170 11AA;AFF3;1101 1170 11AA; +AFF4;AFF4;1101 1170 11AB;AFF4;1101 1170 11AB; +AFF5;AFF5;1101 1170 11AC;AFF5;1101 1170 11AC; +AFF6;AFF6;1101 1170 11AD;AFF6;1101 1170 11AD; +AFF7;AFF7;1101 1170 11AE;AFF7;1101 1170 11AE; +AFF8;AFF8;1101 1170 11AF;AFF8;1101 1170 11AF; +AFF9;AFF9;1101 1170 11B0;AFF9;1101 1170 11B0; +AFFA;AFFA;1101 1170 11B1;AFFA;1101 1170 11B1; +AFFB;AFFB;1101 1170 11B2;AFFB;1101 1170 11B2; +AFFC;AFFC;1101 1170 11B3;AFFC;1101 1170 11B3; +AFFD;AFFD;1101 1170 11B4;AFFD;1101 1170 11B4; +AFFE;AFFE;1101 1170 11B5;AFFE;1101 1170 11B5; +AFFF;AFFF;1101 1170 11B6;AFFF;1101 1170 11B6; +B000;B000;1101 1170 11B7;B000;1101 1170 11B7; +B001;B001;1101 1170 11B8;B001;1101 1170 11B8; +B002;B002;1101 1170 11B9;B002;1101 1170 11B9; +B003;B003;1101 1170 11BA;B003;1101 1170 11BA; +B004;B004;1101 1170 11BB;B004;1101 1170 11BB; +B005;B005;1101 1170 11BC;B005;1101 1170 11BC; +B006;B006;1101 1170 11BD;B006;1101 1170 11BD; +B007;B007;1101 1170 11BE;B007;1101 1170 11BE; +B008;B008;1101 1170 11BF;B008;1101 1170 11BF; +B009;B009;1101 1170 11C0;B009;1101 1170 11C0; +B00A;B00A;1101 1170 11C1;B00A;1101 1170 11C1; +B00B;B00B;1101 1170 11C2;B00B;1101 1170 11C2; +B00C;B00C;1101 1171;B00C;1101 1171; +B00D;B00D;1101 1171 11A8;B00D;1101 1171 11A8; +B00E;B00E;1101 1171 11A9;B00E;1101 1171 11A9; +B00F;B00F;1101 1171 11AA;B00F;1101 1171 11AA; +B010;B010;1101 1171 11AB;B010;1101 1171 11AB; +B011;B011;1101 1171 11AC;B011;1101 1171 11AC; +B012;B012;1101 1171 11AD;B012;1101 1171 11AD; +B013;B013;1101 1171 11AE;B013;1101 1171 11AE; +B014;B014;1101 1171 11AF;B014;1101 1171 11AF; +B015;B015;1101 1171 11B0;B015;1101 1171 11B0; +B016;B016;1101 1171 11B1;B016;1101 1171 11B1; +B017;B017;1101 1171 11B2;B017;1101 1171 11B2; +B018;B018;1101 1171 11B3;B018;1101 1171 11B3; +B019;B019;1101 1171 11B4;B019;1101 1171 11B4; +B01A;B01A;1101 1171 11B5;B01A;1101 1171 11B5; +B01B;B01B;1101 1171 11B6;B01B;1101 1171 11B6; +B01C;B01C;1101 1171 11B7;B01C;1101 1171 11B7; +B01D;B01D;1101 1171 11B8;B01D;1101 1171 11B8; +B01E;B01E;1101 1171 11B9;B01E;1101 1171 11B9; +B01F;B01F;1101 1171 11BA;B01F;1101 1171 11BA; +B020;B020;1101 1171 11BB;B020;1101 1171 11BB; +B021;B021;1101 1171 11BC;B021;1101 1171 11BC; +B022;B022;1101 1171 11BD;B022;1101 1171 11BD; +B023;B023;1101 1171 11BE;B023;1101 1171 11BE; +B024;B024;1101 1171 11BF;B024;1101 1171 11BF; +B025;B025;1101 1171 11C0;B025;1101 1171 11C0; +B026;B026;1101 1171 11C1;B026;1101 1171 11C1; +B027;B027;1101 1171 11C2;B027;1101 1171 11C2; +B028;B028;1101 1172;B028;1101 1172; +B029;B029;1101 1172 11A8;B029;1101 1172 11A8; +B02A;B02A;1101 1172 11A9;B02A;1101 1172 11A9; +B02B;B02B;1101 1172 11AA;B02B;1101 1172 11AA; +B02C;B02C;1101 1172 11AB;B02C;1101 1172 11AB; +B02D;B02D;1101 1172 11AC;B02D;1101 1172 11AC; +B02E;B02E;1101 1172 11AD;B02E;1101 1172 11AD; +B02F;B02F;1101 1172 11AE;B02F;1101 1172 11AE; +B030;B030;1101 1172 11AF;B030;1101 1172 11AF; +B031;B031;1101 1172 11B0;B031;1101 1172 11B0; +B032;B032;1101 1172 11B1;B032;1101 1172 11B1; +B033;B033;1101 1172 11B2;B033;1101 1172 11B2; +B034;B034;1101 1172 11B3;B034;1101 1172 11B3; +B035;B035;1101 1172 11B4;B035;1101 1172 11B4; +B036;B036;1101 1172 11B5;B036;1101 1172 11B5; +B037;B037;1101 1172 11B6;B037;1101 1172 11B6; +B038;B038;1101 1172 11B7;B038;1101 1172 11B7; +B039;B039;1101 1172 11B8;B039;1101 1172 11B8; +B03A;B03A;1101 1172 11B9;B03A;1101 1172 11B9; +B03B;B03B;1101 1172 11BA;B03B;1101 1172 11BA; +B03C;B03C;1101 1172 11BB;B03C;1101 1172 11BB; +B03D;B03D;1101 1172 11BC;B03D;1101 1172 11BC; +B03E;B03E;1101 1172 11BD;B03E;1101 1172 11BD; +B03F;B03F;1101 1172 11BE;B03F;1101 1172 11BE; +B040;B040;1101 1172 11BF;B040;1101 1172 11BF; +B041;B041;1101 1172 11C0;B041;1101 1172 11C0; +B042;B042;1101 1172 11C1;B042;1101 1172 11C1; +B043;B043;1101 1172 11C2;B043;1101 1172 11C2; +B044;B044;1101 1173;B044;1101 1173; +B045;B045;1101 1173 11A8;B045;1101 1173 11A8; +B046;B046;1101 1173 11A9;B046;1101 1173 11A9; +B047;B047;1101 1173 11AA;B047;1101 1173 11AA; +B048;B048;1101 1173 11AB;B048;1101 1173 11AB; +B049;B049;1101 1173 11AC;B049;1101 1173 11AC; +B04A;B04A;1101 1173 11AD;B04A;1101 1173 11AD; +B04B;B04B;1101 1173 11AE;B04B;1101 1173 11AE; +B04C;B04C;1101 1173 11AF;B04C;1101 1173 11AF; +B04D;B04D;1101 1173 11B0;B04D;1101 1173 11B0; +B04E;B04E;1101 1173 11B1;B04E;1101 1173 11B1; +B04F;B04F;1101 1173 11B2;B04F;1101 1173 11B2; +B050;B050;1101 1173 11B3;B050;1101 1173 11B3; +B051;B051;1101 1173 11B4;B051;1101 1173 11B4; +B052;B052;1101 1173 11B5;B052;1101 1173 11B5; +B053;B053;1101 1173 11B6;B053;1101 1173 11B6; +B054;B054;1101 1173 11B7;B054;1101 1173 11B7; +B055;B055;1101 1173 11B8;B055;1101 1173 11B8; +B056;B056;1101 1173 11B9;B056;1101 1173 11B9; +B057;B057;1101 1173 11BA;B057;1101 1173 11BA; +B058;B058;1101 1173 11BB;B058;1101 1173 11BB; +B059;B059;1101 1173 11BC;B059;1101 1173 11BC; +B05A;B05A;1101 1173 11BD;B05A;1101 1173 11BD; +B05B;B05B;1101 1173 11BE;B05B;1101 1173 11BE; +B05C;B05C;1101 1173 11BF;B05C;1101 1173 11BF; +B05D;B05D;1101 1173 11C0;B05D;1101 1173 11C0; +B05E;B05E;1101 1173 11C1;B05E;1101 1173 11C1; +B05F;B05F;1101 1173 11C2;B05F;1101 1173 11C2; +B060;B060;1101 1174;B060;1101 1174; +B061;B061;1101 1174 11A8;B061;1101 1174 11A8; +B062;B062;1101 1174 11A9;B062;1101 1174 11A9; +B063;B063;1101 1174 11AA;B063;1101 1174 11AA; +B064;B064;1101 1174 11AB;B064;1101 1174 11AB; +B065;B065;1101 1174 11AC;B065;1101 1174 11AC; +B066;B066;1101 1174 11AD;B066;1101 1174 11AD; +B067;B067;1101 1174 11AE;B067;1101 1174 11AE; +B068;B068;1101 1174 11AF;B068;1101 1174 11AF; +B069;B069;1101 1174 11B0;B069;1101 1174 11B0; +B06A;B06A;1101 1174 11B1;B06A;1101 1174 11B1; +B06B;B06B;1101 1174 11B2;B06B;1101 1174 11B2; +B06C;B06C;1101 1174 11B3;B06C;1101 1174 11B3; +B06D;B06D;1101 1174 11B4;B06D;1101 1174 11B4; +B06E;B06E;1101 1174 11B5;B06E;1101 1174 11B5; +B06F;B06F;1101 1174 11B6;B06F;1101 1174 11B6; +B070;B070;1101 1174 11B7;B070;1101 1174 11B7; +B071;B071;1101 1174 11B8;B071;1101 1174 11B8; +B072;B072;1101 1174 11B9;B072;1101 1174 11B9; +B073;B073;1101 1174 11BA;B073;1101 1174 11BA; +B074;B074;1101 1174 11BB;B074;1101 1174 11BB; +B075;B075;1101 1174 11BC;B075;1101 1174 11BC; +B076;B076;1101 1174 11BD;B076;1101 1174 11BD; +B077;B077;1101 1174 11BE;B077;1101 1174 11BE; +B078;B078;1101 1174 11BF;B078;1101 1174 11BF; +B079;B079;1101 1174 11C0;B079;1101 1174 11C0; +B07A;B07A;1101 1174 11C1;B07A;1101 1174 11C1; +B07B;B07B;1101 1174 11C2;B07B;1101 1174 11C2; +B07C;B07C;1101 1175;B07C;1101 1175; +B07D;B07D;1101 1175 11A8;B07D;1101 1175 11A8; +B07E;B07E;1101 1175 11A9;B07E;1101 1175 11A9; +B07F;B07F;1101 1175 11AA;B07F;1101 1175 11AA; +B080;B080;1101 1175 11AB;B080;1101 1175 11AB; +B081;B081;1101 1175 11AC;B081;1101 1175 11AC; +B082;B082;1101 1175 11AD;B082;1101 1175 11AD; +B083;B083;1101 1175 11AE;B083;1101 1175 11AE; +B084;B084;1101 1175 11AF;B084;1101 1175 11AF; +B085;B085;1101 1175 11B0;B085;1101 1175 11B0; +B086;B086;1101 1175 11B1;B086;1101 1175 11B1; +B087;B087;1101 1175 11B2;B087;1101 1175 11B2; +B088;B088;1101 1175 11B3;B088;1101 1175 11B3; +B089;B089;1101 1175 11B4;B089;1101 1175 11B4; +B08A;B08A;1101 1175 11B5;B08A;1101 1175 11B5; +B08B;B08B;1101 1175 11B6;B08B;1101 1175 11B6; +B08C;B08C;1101 1175 11B7;B08C;1101 1175 11B7; +B08D;B08D;1101 1175 11B8;B08D;1101 1175 11B8; +B08E;B08E;1101 1175 11B9;B08E;1101 1175 11B9; +B08F;B08F;1101 1175 11BA;B08F;1101 1175 11BA; +B090;B090;1101 1175 11BB;B090;1101 1175 11BB; +B091;B091;1101 1175 11BC;B091;1101 1175 11BC; +B092;B092;1101 1175 11BD;B092;1101 1175 11BD; +B093;B093;1101 1175 11BE;B093;1101 1175 11BE; +B094;B094;1101 1175 11BF;B094;1101 1175 11BF; +B095;B095;1101 1175 11C0;B095;1101 1175 11C0; +B096;B096;1101 1175 11C1;B096;1101 1175 11C1; +B097;B097;1101 1175 11C2;B097;1101 1175 11C2; +B098;B098;1102 1161;B098;1102 1161; +B099;B099;1102 1161 11A8;B099;1102 1161 11A8; +B09A;B09A;1102 1161 11A9;B09A;1102 1161 11A9; +B09B;B09B;1102 1161 11AA;B09B;1102 1161 11AA; +B09C;B09C;1102 1161 11AB;B09C;1102 1161 11AB; +B09D;B09D;1102 1161 11AC;B09D;1102 1161 11AC; +B09E;B09E;1102 1161 11AD;B09E;1102 1161 11AD; +B09F;B09F;1102 1161 11AE;B09F;1102 1161 11AE; +B0A0;B0A0;1102 1161 11AF;B0A0;1102 1161 11AF; +B0A1;B0A1;1102 1161 11B0;B0A1;1102 1161 11B0; +B0A2;B0A2;1102 1161 11B1;B0A2;1102 1161 11B1; +B0A3;B0A3;1102 1161 11B2;B0A3;1102 1161 11B2; +B0A4;B0A4;1102 1161 11B3;B0A4;1102 1161 11B3; +B0A5;B0A5;1102 1161 11B4;B0A5;1102 1161 11B4; +B0A6;B0A6;1102 1161 11B5;B0A6;1102 1161 11B5; +B0A7;B0A7;1102 1161 11B6;B0A7;1102 1161 11B6; +B0A8;B0A8;1102 1161 11B7;B0A8;1102 1161 11B7; +B0A9;B0A9;1102 1161 11B8;B0A9;1102 1161 11B8; +B0AA;B0AA;1102 1161 11B9;B0AA;1102 1161 11B9; +B0AB;B0AB;1102 1161 11BA;B0AB;1102 1161 11BA; +B0AC;B0AC;1102 1161 11BB;B0AC;1102 1161 11BB; +B0AD;B0AD;1102 1161 11BC;B0AD;1102 1161 11BC; +B0AE;B0AE;1102 1161 11BD;B0AE;1102 1161 11BD; +B0AF;B0AF;1102 1161 11BE;B0AF;1102 1161 11BE; +B0B0;B0B0;1102 1161 11BF;B0B0;1102 1161 11BF; +B0B1;B0B1;1102 1161 11C0;B0B1;1102 1161 11C0; +B0B2;B0B2;1102 1161 11C1;B0B2;1102 1161 11C1; +B0B3;B0B3;1102 1161 11C2;B0B3;1102 1161 11C2; +B0B4;B0B4;1102 1162;B0B4;1102 1162; +B0B5;B0B5;1102 1162 11A8;B0B5;1102 1162 11A8; +B0B6;B0B6;1102 1162 11A9;B0B6;1102 1162 11A9; +B0B7;B0B7;1102 1162 11AA;B0B7;1102 1162 11AA; +B0B8;B0B8;1102 1162 11AB;B0B8;1102 1162 11AB; +B0B9;B0B9;1102 1162 11AC;B0B9;1102 1162 11AC; +B0BA;B0BA;1102 1162 11AD;B0BA;1102 1162 11AD; +B0BB;B0BB;1102 1162 11AE;B0BB;1102 1162 11AE; +B0BC;B0BC;1102 1162 11AF;B0BC;1102 1162 11AF; +B0BD;B0BD;1102 1162 11B0;B0BD;1102 1162 11B0; +B0BE;B0BE;1102 1162 11B1;B0BE;1102 1162 11B1; +B0BF;B0BF;1102 1162 11B2;B0BF;1102 1162 11B2; +B0C0;B0C0;1102 1162 11B3;B0C0;1102 1162 11B3; +B0C1;B0C1;1102 1162 11B4;B0C1;1102 1162 11B4; +B0C2;B0C2;1102 1162 11B5;B0C2;1102 1162 11B5; +B0C3;B0C3;1102 1162 11B6;B0C3;1102 1162 11B6; +B0C4;B0C4;1102 1162 11B7;B0C4;1102 1162 11B7; +B0C5;B0C5;1102 1162 11B8;B0C5;1102 1162 11B8; +B0C6;B0C6;1102 1162 11B9;B0C6;1102 1162 11B9; +B0C7;B0C7;1102 1162 11BA;B0C7;1102 1162 11BA; +B0C8;B0C8;1102 1162 11BB;B0C8;1102 1162 11BB; +B0C9;B0C9;1102 1162 11BC;B0C9;1102 1162 11BC; +B0CA;B0CA;1102 1162 11BD;B0CA;1102 1162 11BD; +B0CB;B0CB;1102 1162 11BE;B0CB;1102 1162 11BE; +B0CC;B0CC;1102 1162 11BF;B0CC;1102 1162 11BF; +B0CD;B0CD;1102 1162 11C0;B0CD;1102 1162 11C0; +B0CE;B0CE;1102 1162 11C1;B0CE;1102 1162 11C1; +B0CF;B0CF;1102 1162 11C2;B0CF;1102 1162 11C2; +B0D0;B0D0;1102 1163;B0D0;1102 1163; +B0D1;B0D1;1102 1163 11A8;B0D1;1102 1163 11A8; +B0D2;B0D2;1102 1163 11A9;B0D2;1102 1163 11A9; +B0D3;B0D3;1102 1163 11AA;B0D3;1102 1163 11AA; +B0D4;B0D4;1102 1163 11AB;B0D4;1102 1163 11AB; +B0D5;B0D5;1102 1163 11AC;B0D5;1102 1163 11AC; +B0D6;B0D6;1102 1163 11AD;B0D6;1102 1163 11AD; +B0D7;B0D7;1102 1163 11AE;B0D7;1102 1163 11AE; +B0D8;B0D8;1102 1163 11AF;B0D8;1102 1163 11AF; +B0D9;B0D9;1102 1163 11B0;B0D9;1102 1163 11B0; +B0DA;B0DA;1102 1163 11B1;B0DA;1102 1163 11B1; +B0DB;B0DB;1102 1163 11B2;B0DB;1102 1163 11B2; +B0DC;B0DC;1102 1163 11B3;B0DC;1102 1163 11B3; +B0DD;B0DD;1102 1163 11B4;B0DD;1102 1163 11B4; +B0DE;B0DE;1102 1163 11B5;B0DE;1102 1163 11B5; +B0DF;B0DF;1102 1163 11B6;B0DF;1102 1163 11B6; +B0E0;B0E0;1102 1163 11B7;B0E0;1102 1163 11B7; +B0E1;B0E1;1102 1163 11B8;B0E1;1102 1163 11B8; +B0E2;B0E2;1102 1163 11B9;B0E2;1102 1163 11B9; +B0E3;B0E3;1102 1163 11BA;B0E3;1102 1163 11BA; +B0E4;B0E4;1102 1163 11BB;B0E4;1102 1163 11BB; +B0E5;B0E5;1102 1163 11BC;B0E5;1102 1163 11BC; +B0E6;B0E6;1102 1163 11BD;B0E6;1102 1163 11BD; +B0E7;B0E7;1102 1163 11BE;B0E7;1102 1163 11BE; +B0E8;B0E8;1102 1163 11BF;B0E8;1102 1163 11BF; +B0E9;B0E9;1102 1163 11C0;B0E9;1102 1163 11C0; +B0EA;B0EA;1102 1163 11C1;B0EA;1102 1163 11C1; +B0EB;B0EB;1102 1163 11C2;B0EB;1102 1163 11C2; +B0EC;B0EC;1102 1164;B0EC;1102 1164; +B0ED;B0ED;1102 1164 11A8;B0ED;1102 1164 11A8; +B0EE;B0EE;1102 1164 11A9;B0EE;1102 1164 11A9; +B0EF;B0EF;1102 1164 11AA;B0EF;1102 1164 11AA; +B0F0;B0F0;1102 1164 11AB;B0F0;1102 1164 11AB; +B0F1;B0F1;1102 1164 11AC;B0F1;1102 1164 11AC; +B0F2;B0F2;1102 1164 11AD;B0F2;1102 1164 11AD; +B0F3;B0F3;1102 1164 11AE;B0F3;1102 1164 11AE; +B0F4;B0F4;1102 1164 11AF;B0F4;1102 1164 11AF; +B0F5;B0F5;1102 1164 11B0;B0F5;1102 1164 11B0; +B0F6;B0F6;1102 1164 11B1;B0F6;1102 1164 11B1; +B0F7;B0F7;1102 1164 11B2;B0F7;1102 1164 11B2; +B0F8;B0F8;1102 1164 11B3;B0F8;1102 1164 11B3; +B0F9;B0F9;1102 1164 11B4;B0F9;1102 1164 11B4; +B0FA;B0FA;1102 1164 11B5;B0FA;1102 1164 11B5; +B0FB;B0FB;1102 1164 11B6;B0FB;1102 1164 11B6; +B0FC;B0FC;1102 1164 11B7;B0FC;1102 1164 11B7; +B0FD;B0FD;1102 1164 11B8;B0FD;1102 1164 11B8; +B0FE;B0FE;1102 1164 11B9;B0FE;1102 1164 11B9; +B0FF;B0FF;1102 1164 11BA;B0FF;1102 1164 11BA; +B100;B100;1102 1164 11BB;B100;1102 1164 11BB; +B101;B101;1102 1164 11BC;B101;1102 1164 11BC; +B102;B102;1102 1164 11BD;B102;1102 1164 11BD; +B103;B103;1102 1164 11BE;B103;1102 1164 11BE; +B104;B104;1102 1164 11BF;B104;1102 1164 11BF; +B105;B105;1102 1164 11C0;B105;1102 1164 11C0; +B106;B106;1102 1164 11C1;B106;1102 1164 11C1; +B107;B107;1102 1164 11C2;B107;1102 1164 11C2; +B108;B108;1102 1165;B108;1102 1165; +B109;B109;1102 1165 11A8;B109;1102 1165 11A8; +B10A;B10A;1102 1165 11A9;B10A;1102 1165 11A9; +B10B;B10B;1102 1165 11AA;B10B;1102 1165 11AA; +B10C;B10C;1102 1165 11AB;B10C;1102 1165 11AB; +B10D;B10D;1102 1165 11AC;B10D;1102 1165 11AC; +B10E;B10E;1102 1165 11AD;B10E;1102 1165 11AD; +B10F;B10F;1102 1165 11AE;B10F;1102 1165 11AE; +B110;B110;1102 1165 11AF;B110;1102 1165 11AF; +B111;B111;1102 1165 11B0;B111;1102 1165 11B0; +B112;B112;1102 1165 11B1;B112;1102 1165 11B1; +B113;B113;1102 1165 11B2;B113;1102 1165 11B2; +B114;B114;1102 1165 11B3;B114;1102 1165 11B3; +B115;B115;1102 1165 11B4;B115;1102 1165 11B4; +B116;B116;1102 1165 11B5;B116;1102 1165 11B5; +B117;B117;1102 1165 11B6;B117;1102 1165 11B6; +B118;B118;1102 1165 11B7;B118;1102 1165 11B7; +B119;B119;1102 1165 11B8;B119;1102 1165 11B8; +B11A;B11A;1102 1165 11B9;B11A;1102 1165 11B9; +B11B;B11B;1102 1165 11BA;B11B;1102 1165 11BA; +B11C;B11C;1102 1165 11BB;B11C;1102 1165 11BB; +B11D;B11D;1102 1165 11BC;B11D;1102 1165 11BC; +B11E;B11E;1102 1165 11BD;B11E;1102 1165 11BD; +B11F;B11F;1102 1165 11BE;B11F;1102 1165 11BE; +B120;B120;1102 1165 11BF;B120;1102 1165 11BF; +B121;B121;1102 1165 11C0;B121;1102 1165 11C0; +B122;B122;1102 1165 11C1;B122;1102 1165 11C1; +B123;B123;1102 1165 11C2;B123;1102 1165 11C2; +B124;B124;1102 1166;B124;1102 1166; +B125;B125;1102 1166 11A8;B125;1102 1166 11A8; +B126;B126;1102 1166 11A9;B126;1102 1166 11A9; +B127;B127;1102 1166 11AA;B127;1102 1166 11AA; +B128;B128;1102 1166 11AB;B128;1102 1166 11AB; +B129;B129;1102 1166 11AC;B129;1102 1166 11AC; +B12A;B12A;1102 1166 11AD;B12A;1102 1166 11AD; +B12B;B12B;1102 1166 11AE;B12B;1102 1166 11AE; +B12C;B12C;1102 1166 11AF;B12C;1102 1166 11AF; +B12D;B12D;1102 1166 11B0;B12D;1102 1166 11B0; +B12E;B12E;1102 1166 11B1;B12E;1102 1166 11B1; +B12F;B12F;1102 1166 11B2;B12F;1102 1166 11B2; +B130;B130;1102 1166 11B3;B130;1102 1166 11B3; +B131;B131;1102 1166 11B4;B131;1102 1166 11B4; +B132;B132;1102 1166 11B5;B132;1102 1166 11B5; +B133;B133;1102 1166 11B6;B133;1102 1166 11B6; +B134;B134;1102 1166 11B7;B134;1102 1166 11B7; +B135;B135;1102 1166 11B8;B135;1102 1166 11B8; +B136;B136;1102 1166 11B9;B136;1102 1166 11B9; +B137;B137;1102 1166 11BA;B137;1102 1166 11BA; +B138;B138;1102 1166 11BB;B138;1102 1166 11BB; +B139;B139;1102 1166 11BC;B139;1102 1166 11BC; +B13A;B13A;1102 1166 11BD;B13A;1102 1166 11BD; +B13B;B13B;1102 1166 11BE;B13B;1102 1166 11BE; +B13C;B13C;1102 1166 11BF;B13C;1102 1166 11BF; +B13D;B13D;1102 1166 11C0;B13D;1102 1166 11C0; +B13E;B13E;1102 1166 11C1;B13E;1102 1166 11C1; +B13F;B13F;1102 1166 11C2;B13F;1102 1166 11C2; +B140;B140;1102 1167;B140;1102 1167; +B141;B141;1102 1167 11A8;B141;1102 1167 11A8; +B142;B142;1102 1167 11A9;B142;1102 1167 11A9; +B143;B143;1102 1167 11AA;B143;1102 1167 11AA; +B144;B144;1102 1167 11AB;B144;1102 1167 11AB; +B145;B145;1102 1167 11AC;B145;1102 1167 11AC; +B146;B146;1102 1167 11AD;B146;1102 1167 11AD; +B147;B147;1102 1167 11AE;B147;1102 1167 11AE; +B148;B148;1102 1167 11AF;B148;1102 1167 11AF; +B149;B149;1102 1167 11B0;B149;1102 1167 11B0; +B14A;B14A;1102 1167 11B1;B14A;1102 1167 11B1; +B14B;B14B;1102 1167 11B2;B14B;1102 1167 11B2; +B14C;B14C;1102 1167 11B3;B14C;1102 1167 11B3; +B14D;B14D;1102 1167 11B4;B14D;1102 1167 11B4; +B14E;B14E;1102 1167 11B5;B14E;1102 1167 11B5; +B14F;B14F;1102 1167 11B6;B14F;1102 1167 11B6; +B150;B150;1102 1167 11B7;B150;1102 1167 11B7; +B151;B151;1102 1167 11B8;B151;1102 1167 11B8; +B152;B152;1102 1167 11B9;B152;1102 1167 11B9; +B153;B153;1102 1167 11BA;B153;1102 1167 11BA; +B154;B154;1102 1167 11BB;B154;1102 1167 11BB; +B155;B155;1102 1167 11BC;B155;1102 1167 11BC; +B156;B156;1102 1167 11BD;B156;1102 1167 11BD; +B157;B157;1102 1167 11BE;B157;1102 1167 11BE; +B158;B158;1102 1167 11BF;B158;1102 1167 11BF; +B159;B159;1102 1167 11C0;B159;1102 1167 11C0; +B15A;B15A;1102 1167 11C1;B15A;1102 1167 11C1; +B15B;B15B;1102 1167 11C2;B15B;1102 1167 11C2; +B15C;B15C;1102 1168;B15C;1102 1168; +B15D;B15D;1102 1168 11A8;B15D;1102 1168 11A8; +B15E;B15E;1102 1168 11A9;B15E;1102 1168 11A9; +B15F;B15F;1102 1168 11AA;B15F;1102 1168 11AA; +B160;B160;1102 1168 11AB;B160;1102 1168 11AB; +B161;B161;1102 1168 11AC;B161;1102 1168 11AC; +B162;B162;1102 1168 11AD;B162;1102 1168 11AD; +B163;B163;1102 1168 11AE;B163;1102 1168 11AE; +B164;B164;1102 1168 11AF;B164;1102 1168 11AF; +B165;B165;1102 1168 11B0;B165;1102 1168 11B0; +B166;B166;1102 1168 11B1;B166;1102 1168 11B1; +B167;B167;1102 1168 11B2;B167;1102 1168 11B2; +B168;B168;1102 1168 11B3;B168;1102 1168 11B3; +B169;B169;1102 1168 11B4;B169;1102 1168 11B4; +B16A;B16A;1102 1168 11B5;B16A;1102 1168 11B5; +B16B;B16B;1102 1168 11B6;B16B;1102 1168 11B6; +B16C;B16C;1102 1168 11B7;B16C;1102 1168 11B7; +B16D;B16D;1102 1168 11B8;B16D;1102 1168 11B8; +B16E;B16E;1102 1168 11B9;B16E;1102 1168 11B9; +B16F;B16F;1102 1168 11BA;B16F;1102 1168 11BA; +B170;B170;1102 1168 11BB;B170;1102 1168 11BB; +B171;B171;1102 1168 11BC;B171;1102 1168 11BC; +B172;B172;1102 1168 11BD;B172;1102 1168 11BD; +B173;B173;1102 1168 11BE;B173;1102 1168 11BE; +B174;B174;1102 1168 11BF;B174;1102 1168 11BF; +B175;B175;1102 1168 11C0;B175;1102 1168 11C0; +B176;B176;1102 1168 11C1;B176;1102 1168 11C1; +B177;B177;1102 1168 11C2;B177;1102 1168 11C2; +B178;B178;1102 1169;B178;1102 1169; +B179;B179;1102 1169 11A8;B179;1102 1169 11A8; +B17A;B17A;1102 1169 11A9;B17A;1102 1169 11A9; +B17B;B17B;1102 1169 11AA;B17B;1102 1169 11AA; +B17C;B17C;1102 1169 11AB;B17C;1102 1169 11AB; +B17D;B17D;1102 1169 11AC;B17D;1102 1169 11AC; +B17E;B17E;1102 1169 11AD;B17E;1102 1169 11AD; +B17F;B17F;1102 1169 11AE;B17F;1102 1169 11AE; +B180;B180;1102 1169 11AF;B180;1102 1169 11AF; +B181;B181;1102 1169 11B0;B181;1102 1169 11B0; +B182;B182;1102 1169 11B1;B182;1102 1169 11B1; +B183;B183;1102 1169 11B2;B183;1102 1169 11B2; +B184;B184;1102 1169 11B3;B184;1102 1169 11B3; +B185;B185;1102 1169 11B4;B185;1102 1169 11B4; +B186;B186;1102 1169 11B5;B186;1102 1169 11B5; +B187;B187;1102 1169 11B6;B187;1102 1169 11B6; +B188;B188;1102 1169 11B7;B188;1102 1169 11B7; +B189;B189;1102 1169 11B8;B189;1102 1169 11B8; +B18A;B18A;1102 1169 11B9;B18A;1102 1169 11B9; +B18B;B18B;1102 1169 11BA;B18B;1102 1169 11BA; +B18C;B18C;1102 1169 11BB;B18C;1102 1169 11BB; +B18D;B18D;1102 1169 11BC;B18D;1102 1169 11BC; +B18E;B18E;1102 1169 11BD;B18E;1102 1169 11BD; +B18F;B18F;1102 1169 11BE;B18F;1102 1169 11BE; +B190;B190;1102 1169 11BF;B190;1102 1169 11BF; +B191;B191;1102 1169 11C0;B191;1102 1169 11C0; +B192;B192;1102 1169 11C1;B192;1102 1169 11C1; +B193;B193;1102 1169 11C2;B193;1102 1169 11C2; +B194;B194;1102 116A;B194;1102 116A; +B195;B195;1102 116A 11A8;B195;1102 116A 11A8; +B196;B196;1102 116A 11A9;B196;1102 116A 11A9; +B197;B197;1102 116A 11AA;B197;1102 116A 11AA; +B198;B198;1102 116A 11AB;B198;1102 116A 11AB; +B199;B199;1102 116A 11AC;B199;1102 116A 11AC; +B19A;B19A;1102 116A 11AD;B19A;1102 116A 11AD; +B19B;B19B;1102 116A 11AE;B19B;1102 116A 11AE; +B19C;B19C;1102 116A 11AF;B19C;1102 116A 11AF; +B19D;B19D;1102 116A 11B0;B19D;1102 116A 11B0; +B19E;B19E;1102 116A 11B1;B19E;1102 116A 11B1; +B19F;B19F;1102 116A 11B2;B19F;1102 116A 11B2; +B1A0;B1A0;1102 116A 11B3;B1A0;1102 116A 11B3; +B1A1;B1A1;1102 116A 11B4;B1A1;1102 116A 11B4; +B1A2;B1A2;1102 116A 11B5;B1A2;1102 116A 11B5; +B1A3;B1A3;1102 116A 11B6;B1A3;1102 116A 11B6; +B1A4;B1A4;1102 116A 11B7;B1A4;1102 116A 11B7; +B1A5;B1A5;1102 116A 11B8;B1A5;1102 116A 11B8; +B1A6;B1A6;1102 116A 11B9;B1A6;1102 116A 11B9; +B1A7;B1A7;1102 116A 11BA;B1A7;1102 116A 11BA; +B1A8;B1A8;1102 116A 11BB;B1A8;1102 116A 11BB; +B1A9;B1A9;1102 116A 11BC;B1A9;1102 116A 11BC; +B1AA;B1AA;1102 116A 11BD;B1AA;1102 116A 11BD; +B1AB;B1AB;1102 116A 11BE;B1AB;1102 116A 11BE; +B1AC;B1AC;1102 116A 11BF;B1AC;1102 116A 11BF; +B1AD;B1AD;1102 116A 11C0;B1AD;1102 116A 11C0; +B1AE;B1AE;1102 116A 11C1;B1AE;1102 116A 11C1; +B1AF;B1AF;1102 116A 11C2;B1AF;1102 116A 11C2; +B1B0;B1B0;1102 116B;B1B0;1102 116B; +B1B1;B1B1;1102 116B 11A8;B1B1;1102 116B 11A8; +B1B2;B1B2;1102 116B 11A9;B1B2;1102 116B 11A9; +B1B3;B1B3;1102 116B 11AA;B1B3;1102 116B 11AA; +B1B4;B1B4;1102 116B 11AB;B1B4;1102 116B 11AB; +B1B5;B1B5;1102 116B 11AC;B1B5;1102 116B 11AC; +B1B6;B1B6;1102 116B 11AD;B1B6;1102 116B 11AD; +B1B7;B1B7;1102 116B 11AE;B1B7;1102 116B 11AE; +B1B8;B1B8;1102 116B 11AF;B1B8;1102 116B 11AF; +B1B9;B1B9;1102 116B 11B0;B1B9;1102 116B 11B0; +B1BA;B1BA;1102 116B 11B1;B1BA;1102 116B 11B1; +B1BB;B1BB;1102 116B 11B2;B1BB;1102 116B 11B2; +B1BC;B1BC;1102 116B 11B3;B1BC;1102 116B 11B3; +B1BD;B1BD;1102 116B 11B4;B1BD;1102 116B 11B4; +B1BE;B1BE;1102 116B 11B5;B1BE;1102 116B 11B5; +B1BF;B1BF;1102 116B 11B6;B1BF;1102 116B 11B6; +B1C0;B1C0;1102 116B 11B7;B1C0;1102 116B 11B7; +B1C1;B1C1;1102 116B 11B8;B1C1;1102 116B 11B8; +B1C2;B1C2;1102 116B 11B9;B1C2;1102 116B 11B9; +B1C3;B1C3;1102 116B 11BA;B1C3;1102 116B 11BA; +B1C4;B1C4;1102 116B 11BB;B1C4;1102 116B 11BB; +B1C5;B1C5;1102 116B 11BC;B1C5;1102 116B 11BC; +B1C6;B1C6;1102 116B 11BD;B1C6;1102 116B 11BD; +B1C7;B1C7;1102 116B 11BE;B1C7;1102 116B 11BE; +B1C8;B1C8;1102 116B 11BF;B1C8;1102 116B 11BF; +B1C9;B1C9;1102 116B 11C0;B1C9;1102 116B 11C0; +B1CA;B1CA;1102 116B 11C1;B1CA;1102 116B 11C1; +B1CB;B1CB;1102 116B 11C2;B1CB;1102 116B 11C2; +B1CC;B1CC;1102 116C;B1CC;1102 116C; +B1CD;B1CD;1102 116C 11A8;B1CD;1102 116C 11A8; +B1CE;B1CE;1102 116C 11A9;B1CE;1102 116C 11A9; +B1CF;B1CF;1102 116C 11AA;B1CF;1102 116C 11AA; +B1D0;B1D0;1102 116C 11AB;B1D0;1102 116C 11AB; +B1D1;B1D1;1102 116C 11AC;B1D1;1102 116C 11AC; +B1D2;B1D2;1102 116C 11AD;B1D2;1102 116C 11AD; +B1D3;B1D3;1102 116C 11AE;B1D3;1102 116C 11AE; +B1D4;B1D4;1102 116C 11AF;B1D4;1102 116C 11AF; +B1D5;B1D5;1102 116C 11B0;B1D5;1102 116C 11B0; +B1D6;B1D6;1102 116C 11B1;B1D6;1102 116C 11B1; +B1D7;B1D7;1102 116C 11B2;B1D7;1102 116C 11B2; +B1D8;B1D8;1102 116C 11B3;B1D8;1102 116C 11B3; +B1D9;B1D9;1102 116C 11B4;B1D9;1102 116C 11B4; +B1DA;B1DA;1102 116C 11B5;B1DA;1102 116C 11B5; +B1DB;B1DB;1102 116C 11B6;B1DB;1102 116C 11B6; +B1DC;B1DC;1102 116C 11B7;B1DC;1102 116C 11B7; +B1DD;B1DD;1102 116C 11B8;B1DD;1102 116C 11B8; +B1DE;B1DE;1102 116C 11B9;B1DE;1102 116C 11B9; +B1DF;B1DF;1102 116C 11BA;B1DF;1102 116C 11BA; +B1E0;B1E0;1102 116C 11BB;B1E0;1102 116C 11BB; +B1E1;B1E1;1102 116C 11BC;B1E1;1102 116C 11BC; +B1E2;B1E2;1102 116C 11BD;B1E2;1102 116C 11BD; +B1E3;B1E3;1102 116C 11BE;B1E3;1102 116C 11BE; +B1E4;B1E4;1102 116C 11BF;B1E4;1102 116C 11BF; +B1E5;B1E5;1102 116C 11C0;B1E5;1102 116C 11C0; +B1E6;B1E6;1102 116C 11C1;B1E6;1102 116C 11C1; +B1E7;B1E7;1102 116C 11C2;B1E7;1102 116C 11C2; +B1E8;B1E8;1102 116D;B1E8;1102 116D; +B1E9;B1E9;1102 116D 11A8;B1E9;1102 116D 11A8; +B1EA;B1EA;1102 116D 11A9;B1EA;1102 116D 11A9; +B1EB;B1EB;1102 116D 11AA;B1EB;1102 116D 11AA; +B1EC;B1EC;1102 116D 11AB;B1EC;1102 116D 11AB; +B1ED;B1ED;1102 116D 11AC;B1ED;1102 116D 11AC; +B1EE;B1EE;1102 116D 11AD;B1EE;1102 116D 11AD; +B1EF;B1EF;1102 116D 11AE;B1EF;1102 116D 11AE; +B1F0;B1F0;1102 116D 11AF;B1F0;1102 116D 11AF; +B1F1;B1F1;1102 116D 11B0;B1F1;1102 116D 11B0; +B1F2;B1F2;1102 116D 11B1;B1F2;1102 116D 11B1; +B1F3;B1F3;1102 116D 11B2;B1F3;1102 116D 11B2; +B1F4;B1F4;1102 116D 11B3;B1F4;1102 116D 11B3; +B1F5;B1F5;1102 116D 11B4;B1F5;1102 116D 11B4; +B1F6;B1F6;1102 116D 11B5;B1F6;1102 116D 11B5; +B1F7;B1F7;1102 116D 11B6;B1F7;1102 116D 11B6; +B1F8;B1F8;1102 116D 11B7;B1F8;1102 116D 11B7; +B1F9;B1F9;1102 116D 11B8;B1F9;1102 116D 11B8; +B1FA;B1FA;1102 116D 11B9;B1FA;1102 116D 11B9; +B1FB;B1FB;1102 116D 11BA;B1FB;1102 116D 11BA; +B1FC;B1FC;1102 116D 11BB;B1FC;1102 116D 11BB; +B1FD;B1FD;1102 116D 11BC;B1FD;1102 116D 11BC; +B1FE;B1FE;1102 116D 11BD;B1FE;1102 116D 11BD; +B1FF;B1FF;1102 116D 11BE;B1FF;1102 116D 11BE; +B200;B200;1102 116D 11BF;B200;1102 116D 11BF; +B201;B201;1102 116D 11C0;B201;1102 116D 11C0; +B202;B202;1102 116D 11C1;B202;1102 116D 11C1; +B203;B203;1102 116D 11C2;B203;1102 116D 11C2; +B204;B204;1102 116E;B204;1102 116E; +B205;B205;1102 116E 11A8;B205;1102 116E 11A8; +B206;B206;1102 116E 11A9;B206;1102 116E 11A9; +B207;B207;1102 116E 11AA;B207;1102 116E 11AA; +B208;B208;1102 116E 11AB;B208;1102 116E 11AB; +B209;B209;1102 116E 11AC;B209;1102 116E 11AC; +B20A;B20A;1102 116E 11AD;B20A;1102 116E 11AD; +B20B;B20B;1102 116E 11AE;B20B;1102 116E 11AE; +B20C;B20C;1102 116E 11AF;B20C;1102 116E 11AF; +B20D;B20D;1102 116E 11B0;B20D;1102 116E 11B0; +B20E;B20E;1102 116E 11B1;B20E;1102 116E 11B1; +B20F;B20F;1102 116E 11B2;B20F;1102 116E 11B2; +B210;B210;1102 116E 11B3;B210;1102 116E 11B3; +B211;B211;1102 116E 11B4;B211;1102 116E 11B4; +B212;B212;1102 116E 11B5;B212;1102 116E 11B5; +B213;B213;1102 116E 11B6;B213;1102 116E 11B6; +B214;B214;1102 116E 11B7;B214;1102 116E 11B7; +B215;B215;1102 116E 11B8;B215;1102 116E 11B8; +B216;B216;1102 116E 11B9;B216;1102 116E 11B9; +B217;B217;1102 116E 11BA;B217;1102 116E 11BA; +B218;B218;1102 116E 11BB;B218;1102 116E 11BB; +B219;B219;1102 116E 11BC;B219;1102 116E 11BC; +B21A;B21A;1102 116E 11BD;B21A;1102 116E 11BD; +B21B;B21B;1102 116E 11BE;B21B;1102 116E 11BE; +B21C;B21C;1102 116E 11BF;B21C;1102 116E 11BF; +B21D;B21D;1102 116E 11C0;B21D;1102 116E 11C0; +B21E;B21E;1102 116E 11C1;B21E;1102 116E 11C1; +B21F;B21F;1102 116E 11C2;B21F;1102 116E 11C2; +B220;B220;1102 116F;B220;1102 116F; +B221;B221;1102 116F 11A8;B221;1102 116F 11A8; +B222;B222;1102 116F 11A9;B222;1102 116F 11A9; +B223;B223;1102 116F 11AA;B223;1102 116F 11AA; +B224;B224;1102 116F 11AB;B224;1102 116F 11AB; +B225;B225;1102 116F 11AC;B225;1102 116F 11AC; +B226;B226;1102 116F 11AD;B226;1102 116F 11AD; +B227;B227;1102 116F 11AE;B227;1102 116F 11AE; +B228;B228;1102 116F 11AF;B228;1102 116F 11AF; +B229;B229;1102 116F 11B0;B229;1102 116F 11B0; +B22A;B22A;1102 116F 11B1;B22A;1102 116F 11B1; +B22B;B22B;1102 116F 11B2;B22B;1102 116F 11B2; +B22C;B22C;1102 116F 11B3;B22C;1102 116F 11B3; +B22D;B22D;1102 116F 11B4;B22D;1102 116F 11B4; +B22E;B22E;1102 116F 11B5;B22E;1102 116F 11B5; +B22F;B22F;1102 116F 11B6;B22F;1102 116F 11B6; +B230;B230;1102 116F 11B7;B230;1102 116F 11B7; +B231;B231;1102 116F 11B8;B231;1102 116F 11B8; +B232;B232;1102 116F 11B9;B232;1102 116F 11B9; +B233;B233;1102 116F 11BA;B233;1102 116F 11BA; +B234;B234;1102 116F 11BB;B234;1102 116F 11BB; +B235;B235;1102 116F 11BC;B235;1102 116F 11BC; +B236;B236;1102 116F 11BD;B236;1102 116F 11BD; +B237;B237;1102 116F 11BE;B237;1102 116F 11BE; +B238;B238;1102 116F 11BF;B238;1102 116F 11BF; +B239;B239;1102 116F 11C0;B239;1102 116F 11C0; +B23A;B23A;1102 116F 11C1;B23A;1102 116F 11C1; +B23B;B23B;1102 116F 11C2;B23B;1102 116F 11C2; +B23C;B23C;1102 1170;B23C;1102 1170; +B23D;B23D;1102 1170 11A8;B23D;1102 1170 11A8; +B23E;B23E;1102 1170 11A9;B23E;1102 1170 11A9; +B23F;B23F;1102 1170 11AA;B23F;1102 1170 11AA; +B240;B240;1102 1170 11AB;B240;1102 1170 11AB; +B241;B241;1102 1170 11AC;B241;1102 1170 11AC; +B242;B242;1102 1170 11AD;B242;1102 1170 11AD; +B243;B243;1102 1170 11AE;B243;1102 1170 11AE; +B244;B244;1102 1170 11AF;B244;1102 1170 11AF; +B245;B245;1102 1170 11B0;B245;1102 1170 11B0; +B246;B246;1102 1170 11B1;B246;1102 1170 11B1; +B247;B247;1102 1170 11B2;B247;1102 1170 11B2; +B248;B248;1102 1170 11B3;B248;1102 1170 11B3; +B249;B249;1102 1170 11B4;B249;1102 1170 11B4; +B24A;B24A;1102 1170 11B5;B24A;1102 1170 11B5; +B24B;B24B;1102 1170 11B6;B24B;1102 1170 11B6; +B24C;B24C;1102 1170 11B7;B24C;1102 1170 11B7; +B24D;B24D;1102 1170 11B8;B24D;1102 1170 11B8; +B24E;B24E;1102 1170 11B9;B24E;1102 1170 11B9; +B24F;B24F;1102 1170 11BA;B24F;1102 1170 11BA; +B250;B250;1102 1170 11BB;B250;1102 1170 11BB; +B251;B251;1102 1170 11BC;B251;1102 1170 11BC; +B252;B252;1102 1170 11BD;B252;1102 1170 11BD; +B253;B253;1102 1170 11BE;B253;1102 1170 11BE; +B254;B254;1102 1170 11BF;B254;1102 1170 11BF; +B255;B255;1102 1170 11C0;B255;1102 1170 11C0; +B256;B256;1102 1170 11C1;B256;1102 1170 11C1; +B257;B257;1102 1170 11C2;B257;1102 1170 11C2; +B258;B258;1102 1171;B258;1102 1171; +B259;B259;1102 1171 11A8;B259;1102 1171 11A8; +B25A;B25A;1102 1171 11A9;B25A;1102 1171 11A9; +B25B;B25B;1102 1171 11AA;B25B;1102 1171 11AA; +B25C;B25C;1102 1171 11AB;B25C;1102 1171 11AB; +B25D;B25D;1102 1171 11AC;B25D;1102 1171 11AC; +B25E;B25E;1102 1171 11AD;B25E;1102 1171 11AD; +B25F;B25F;1102 1171 11AE;B25F;1102 1171 11AE; +B260;B260;1102 1171 11AF;B260;1102 1171 11AF; +B261;B261;1102 1171 11B0;B261;1102 1171 11B0; +B262;B262;1102 1171 11B1;B262;1102 1171 11B1; +B263;B263;1102 1171 11B2;B263;1102 1171 11B2; +B264;B264;1102 1171 11B3;B264;1102 1171 11B3; +B265;B265;1102 1171 11B4;B265;1102 1171 11B4; +B266;B266;1102 1171 11B5;B266;1102 1171 11B5; +B267;B267;1102 1171 11B6;B267;1102 1171 11B6; +B268;B268;1102 1171 11B7;B268;1102 1171 11B7; +B269;B269;1102 1171 11B8;B269;1102 1171 11B8; +B26A;B26A;1102 1171 11B9;B26A;1102 1171 11B9; +B26B;B26B;1102 1171 11BA;B26B;1102 1171 11BA; +B26C;B26C;1102 1171 11BB;B26C;1102 1171 11BB; +B26D;B26D;1102 1171 11BC;B26D;1102 1171 11BC; +B26E;B26E;1102 1171 11BD;B26E;1102 1171 11BD; +B26F;B26F;1102 1171 11BE;B26F;1102 1171 11BE; +B270;B270;1102 1171 11BF;B270;1102 1171 11BF; +B271;B271;1102 1171 11C0;B271;1102 1171 11C0; +B272;B272;1102 1171 11C1;B272;1102 1171 11C1; +B273;B273;1102 1171 11C2;B273;1102 1171 11C2; +B274;B274;1102 1172;B274;1102 1172; +B275;B275;1102 1172 11A8;B275;1102 1172 11A8; +B276;B276;1102 1172 11A9;B276;1102 1172 11A9; +B277;B277;1102 1172 11AA;B277;1102 1172 11AA; +B278;B278;1102 1172 11AB;B278;1102 1172 11AB; +B279;B279;1102 1172 11AC;B279;1102 1172 11AC; +B27A;B27A;1102 1172 11AD;B27A;1102 1172 11AD; +B27B;B27B;1102 1172 11AE;B27B;1102 1172 11AE; +B27C;B27C;1102 1172 11AF;B27C;1102 1172 11AF; +B27D;B27D;1102 1172 11B0;B27D;1102 1172 11B0; +B27E;B27E;1102 1172 11B1;B27E;1102 1172 11B1; +B27F;B27F;1102 1172 11B2;B27F;1102 1172 11B2; +B280;B280;1102 1172 11B3;B280;1102 1172 11B3; +B281;B281;1102 1172 11B4;B281;1102 1172 11B4; +B282;B282;1102 1172 11B5;B282;1102 1172 11B5; +B283;B283;1102 1172 11B6;B283;1102 1172 11B6; +B284;B284;1102 1172 11B7;B284;1102 1172 11B7; +B285;B285;1102 1172 11B8;B285;1102 1172 11B8; +B286;B286;1102 1172 11B9;B286;1102 1172 11B9; +B287;B287;1102 1172 11BA;B287;1102 1172 11BA; +B288;B288;1102 1172 11BB;B288;1102 1172 11BB; +B289;B289;1102 1172 11BC;B289;1102 1172 11BC; +B28A;B28A;1102 1172 11BD;B28A;1102 1172 11BD; +B28B;B28B;1102 1172 11BE;B28B;1102 1172 11BE; +B28C;B28C;1102 1172 11BF;B28C;1102 1172 11BF; +B28D;B28D;1102 1172 11C0;B28D;1102 1172 11C0; +B28E;B28E;1102 1172 11C1;B28E;1102 1172 11C1; +B28F;B28F;1102 1172 11C2;B28F;1102 1172 11C2; +B290;B290;1102 1173;B290;1102 1173; +B291;B291;1102 1173 11A8;B291;1102 1173 11A8; +B292;B292;1102 1173 11A9;B292;1102 1173 11A9; +B293;B293;1102 1173 11AA;B293;1102 1173 11AA; +B294;B294;1102 1173 11AB;B294;1102 1173 11AB; +B295;B295;1102 1173 11AC;B295;1102 1173 11AC; +B296;B296;1102 1173 11AD;B296;1102 1173 11AD; +B297;B297;1102 1173 11AE;B297;1102 1173 11AE; +B298;B298;1102 1173 11AF;B298;1102 1173 11AF; +B299;B299;1102 1173 11B0;B299;1102 1173 11B0; +B29A;B29A;1102 1173 11B1;B29A;1102 1173 11B1; +B29B;B29B;1102 1173 11B2;B29B;1102 1173 11B2; +B29C;B29C;1102 1173 11B3;B29C;1102 1173 11B3; +B29D;B29D;1102 1173 11B4;B29D;1102 1173 11B4; +B29E;B29E;1102 1173 11B5;B29E;1102 1173 11B5; +B29F;B29F;1102 1173 11B6;B29F;1102 1173 11B6; +B2A0;B2A0;1102 1173 11B7;B2A0;1102 1173 11B7; +B2A1;B2A1;1102 1173 11B8;B2A1;1102 1173 11B8; +B2A2;B2A2;1102 1173 11B9;B2A2;1102 1173 11B9; +B2A3;B2A3;1102 1173 11BA;B2A3;1102 1173 11BA; +B2A4;B2A4;1102 1173 11BB;B2A4;1102 1173 11BB; +B2A5;B2A5;1102 1173 11BC;B2A5;1102 1173 11BC; +B2A6;B2A6;1102 1173 11BD;B2A6;1102 1173 11BD; +B2A7;B2A7;1102 1173 11BE;B2A7;1102 1173 11BE; +B2A8;B2A8;1102 1173 11BF;B2A8;1102 1173 11BF; +B2A9;B2A9;1102 1173 11C0;B2A9;1102 1173 11C0; +B2AA;B2AA;1102 1173 11C1;B2AA;1102 1173 11C1; +B2AB;B2AB;1102 1173 11C2;B2AB;1102 1173 11C2; +B2AC;B2AC;1102 1174;B2AC;1102 1174; +B2AD;B2AD;1102 1174 11A8;B2AD;1102 1174 11A8; +B2AE;B2AE;1102 1174 11A9;B2AE;1102 1174 11A9; +B2AF;B2AF;1102 1174 11AA;B2AF;1102 1174 11AA; +B2B0;B2B0;1102 1174 11AB;B2B0;1102 1174 11AB; +B2B1;B2B1;1102 1174 11AC;B2B1;1102 1174 11AC; +B2B2;B2B2;1102 1174 11AD;B2B2;1102 1174 11AD; +B2B3;B2B3;1102 1174 11AE;B2B3;1102 1174 11AE; +B2B4;B2B4;1102 1174 11AF;B2B4;1102 1174 11AF; +B2B5;B2B5;1102 1174 11B0;B2B5;1102 1174 11B0; +B2B6;B2B6;1102 1174 11B1;B2B6;1102 1174 11B1; +B2B7;B2B7;1102 1174 11B2;B2B7;1102 1174 11B2; +B2B8;B2B8;1102 1174 11B3;B2B8;1102 1174 11B3; +B2B9;B2B9;1102 1174 11B4;B2B9;1102 1174 11B4; +B2BA;B2BA;1102 1174 11B5;B2BA;1102 1174 11B5; +B2BB;B2BB;1102 1174 11B6;B2BB;1102 1174 11B6; +B2BC;B2BC;1102 1174 11B7;B2BC;1102 1174 11B7; +B2BD;B2BD;1102 1174 11B8;B2BD;1102 1174 11B8; +B2BE;B2BE;1102 1174 11B9;B2BE;1102 1174 11B9; +B2BF;B2BF;1102 1174 11BA;B2BF;1102 1174 11BA; +B2C0;B2C0;1102 1174 11BB;B2C0;1102 1174 11BB; +B2C1;B2C1;1102 1174 11BC;B2C1;1102 1174 11BC; +B2C2;B2C2;1102 1174 11BD;B2C2;1102 1174 11BD; +B2C3;B2C3;1102 1174 11BE;B2C3;1102 1174 11BE; +B2C4;B2C4;1102 1174 11BF;B2C4;1102 1174 11BF; +B2C5;B2C5;1102 1174 11C0;B2C5;1102 1174 11C0; +B2C6;B2C6;1102 1174 11C1;B2C6;1102 1174 11C1; +B2C7;B2C7;1102 1174 11C2;B2C7;1102 1174 11C2; +B2C8;B2C8;1102 1175;B2C8;1102 1175; +B2C9;B2C9;1102 1175 11A8;B2C9;1102 1175 11A8; +B2CA;B2CA;1102 1175 11A9;B2CA;1102 1175 11A9; +B2CB;B2CB;1102 1175 11AA;B2CB;1102 1175 11AA; +B2CC;B2CC;1102 1175 11AB;B2CC;1102 1175 11AB; +B2CD;B2CD;1102 1175 11AC;B2CD;1102 1175 11AC; +B2CE;B2CE;1102 1175 11AD;B2CE;1102 1175 11AD; +B2CF;B2CF;1102 1175 11AE;B2CF;1102 1175 11AE; +B2D0;B2D0;1102 1175 11AF;B2D0;1102 1175 11AF; +B2D1;B2D1;1102 1175 11B0;B2D1;1102 1175 11B0; +B2D2;B2D2;1102 1175 11B1;B2D2;1102 1175 11B1; +B2D3;B2D3;1102 1175 11B2;B2D3;1102 1175 11B2; +B2D4;B2D4;1102 1175 11B3;B2D4;1102 1175 11B3; +B2D5;B2D5;1102 1175 11B4;B2D5;1102 1175 11B4; +B2D6;B2D6;1102 1175 11B5;B2D6;1102 1175 11B5; +B2D7;B2D7;1102 1175 11B6;B2D7;1102 1175 11B6; +B2D8;B2D8;1102 1175 11B7;B2D8;1102 1175 11B7; +B2D9;B2D9;1102 1175 11B8;B2D9;1102 1175 11B8; +B2DA;B2DA;1102 1175 11B9;B2DA;1102 1175 11B9; +B2DB;B2DB;1102 1175 11BA;B2DB;1102 1175 11BA; +B2DC;B2DC;1102 1175 11BB;B2DC;1102 1175 11BB; +B2DD;B2DD;1102 1175 11BC;B2DD;1102 1175 11BC; +B2DE;B2DE;1102 1175 11BD;B2DE;1102 1175 11BD; +B2DF;B2DF;1102 1175 11BE;B2DF;1102 1175 11BE; +B2E0;B2E0;1102 1175 11BF;B2E0;1102 1175 11BF; +B2E1;B2E1;1102 1175 11C0;B2E1;1102 1175 11C0; +B2E2;B2E2;1102 1175 11C1;B2E2;1102 1175 11C1; +B2E3;B2E3;1102 1175 11C2;B2E3;1102 1175 11C2; +B2E4;B2E4;1103 1161;B2E4;1103 1161; +B2E5;B2E5;1103 1161 11A8;B2E5;1103 1161 11A8; +B2E6;B2E6;1103 1161 11A9;B2E6;1103 1161 11A9; +B2E7;B2E7;1103 1161 11AA;B2E7;1103 1161 11AA; +B2E8;B2E8;1103 1161 11AB;B2E8;1103 1161 11AB; +B2E9;B2E9;1103 1161 11AC;B2E9;1103 1161 11AC; +B2EA;B2EA;1103 1161 11AD;B2EA;1103 1161 11AD; +B2EB;B2EB;1103 1161 11AE;B2EB;1103 1161 11AE; +B2EC;B2EC;1103 1161 11AF;B2EC;1103 1161 11AF; +B2ED;B2ED;1103 1161 11B0;B2ED;1103 1161 11B0; +B2EE;B2EE;1103 1161 11B1;B2EE;1103 1161 11B1; +B2EF;B2EF;1103 1161 11B2;B2EF;1103 1161 11B2; +B2F0;B2F0;1103 1161 11B3;B2F0;1103 1161 11B3; +B2F1;B2F1;1103 1161 11B4;B2F1;1103 1161 11B4; +B2F2;B2F2;1103 1161 11B5;B2F2;1103 1161 11B5; +B2F3;B2F3;1103 1161 11B6;B2F3;1103 1161 11B6; +B2F4;B2F4;1103 1161 11B7;B2F4;1103 1161 11B7; +B2F5;B2F5;1103 1161 11B8;B2F5;1103 1161 11B8; +B2F6;B2F6;1103 1161 11B9;B2F6;1103 1161 11B9; +B2F7;B2F7;1103 1161 11BA;B2F7;1103 1161 11BA; +B2F8;B2F8;1103 1161 11BB;B2F8;1103 1161 11BB; +B2F9;B2F9;1103 1161 11BC;B2F9;1103 1161 11BC; +B2FA;B2FA;1103 1161 11BD;B2FA;1103 1161 11BD; +B2FB;B2FB;1103 1161 11BE;B2FB;1103 1161 11BE; +B2FC;B2FC;1103 1161 11BF;B2FC;1103 1161 11BF; +B2FD;B2FD;1103 1161 11C0;B2FD;1103 1161 11C0; +B2FE;B2FE;1103 1161 11C1;B2FE;1103 1161 11C1; +B2FF;B2FF;1103 1161 11C2;B2FF;1103 1161 11C2; +B300;B300;1103 1162;B300;1103 1162; +B301;B301;1103 1162 11A8;B301;1103 1162 11A8; +B302;B302;1103 1162 11A9;B302;1103 1162 11A9; +B303;B303;1103 1162 11AA;B303;1103 1162 11AA; +B304;B304;1103 1162 11AB;B304;1103 1162 11AB; +B305;B305;1103 1162 11AC;B305;1103 1162 11AC; +B306;B306;1103 1162 11AD;B306;1103 1162 11AD; +B307;B307;1103 1162 11AE;B307;1103 1162 11AE; +B308;B308;1103 1162 11AF;B308;1103 1162 11AF; +B309;B309;1103 1162 11B0;B309;1103 1162 11B0; +B30A;B30A;1103 1162 11B1;B30A;1103 1162 11B1; +B30B;B30B;1103 1162 11B2;B30B;1103 1162 11B2; +B30C;B30C;1103 1162 11B3;B30C;1103 1162 11B3; +B30D;B30D;1103 1162 11B4;B30D;1103 1162 11B4; +B30E;B30E;1103 1162 11B5;B30E;1103 1162 11B5; +B30F;B30F;1103 1162 11B6;B30F;1103 1162 11B6; +B310;B310;1103 1162 11B7;B310;1103 1162 11B7; +B311;B311;1103 1162 11B8;B311;1103 1162 11B8; +B312;B312;1103 1162 11B9;B312;1103 1162 11B9; +B313;B313;1103 1162 11BA;B313;1103 1162 11BA; +B314;B314;1103 1162 11BB;B314;1103 1162 11BB; +B315;B315;1103 1162 11BC;B315;1103 1162 11BC; +B316;B316;1103 1162 11BD;B316;1103 1162 11BD; +B317;B317;1103 1162 11BE;B317;1103 1162 11BE; +B318;B318;1103 1162 11BF;B318;1103 1162 11BF; +B319;B319;1103 1162 11C0;B319;1103 1162 11C0; +B31A;B31A;1103 1162 11C1;B31A;1103 1162 11C1; +B31B;B31B;1103 1162 11C2;B31B;1103 1162 11C2; +B31C;B31C;1103 1163;B31C;1103 1163; +B31D;B31D;1103 1163 11A8;B31D;1103 1163 11A8; +B31E;B31E;1103 1163 11A9;B31E;1103 1163 11A9; +B31F;B31F;1103 1163 11AA;B31F;1103 1163 11AA; +B320;B320;1103 1163 11AB;B320;1103 1163 11AB; +B321;B321;1103 1163 11AC;B321;1103 1163 11AC; +B322;B322;1103 1163 11AD;B322;1103 1163 11AD; +B323;B323;1103 1163 11AE;B323;1103 1163 11AE; +B324;B324;1103 1163 11AF;B324;1103 1163 11AF; +B325;B325;1103 1163 11B0;B325;1103 1163 11B0; +B326;B326;1103 1163 11B1;B326;1103 1163 11B1; +B327;B327;1103 1163 11B2;B327;1103 1163 11B2; +B328;B328;1103 1163 11B3;B328;1103 1163 11B3; +B329;B329;1103 1163 11B4;B329;1103 1163 11B4; +B32A;B32A;1103 1163 11B5;B32A;1103 1163 11B5; +B32B;B32B;1103 1163 11B6;B32B;1103 1163 11B6; +B32C;B32C;1103 1163 11B7;B32C;1103 1163 11B7; +B32D;B32D;1103 1163 11B8;B32D;1103 1163 11B8; +B32E;B32E;1103 1163 11B9;B32E;1103 1163 11B9; +B32F;B32F;1103 1163 11BA;B32F;1103 1163 11BA; +B330;B330;1103 1163 11BB;B330;1103 1163 11BB; +B331;B331;1103 1163 11BC;B331;1103 1163 11BC; +B332;B332;1103 1163 11BD;B332;1103 1163 11BD; +B333;B333;1103 1163 11BE;B333;1103 1163 11BE; +B334;B334;1103 1163 11BF;B334;1103 1163 11BF; +B335;B335;1103 1163 11C0;B335;1103 1163 11C0; +B336;B336;1103 1163 11C1;B336;1103 1163 11C1; +B337;B337;1103 1163 11C2;B337;1103 1163 11C2; +B338;B338;1103 1164;B338;1103 1164; +B339;B339;1103 1164 11A8;B339;1103 1164 11A8; +B33A;B33A;1103 1164 11A9;B33A;1103 1164 11A9; +B33B;B33B;1103 1164 11AA;B33B;1103 1164 11AA; +B33C;B33C;1103 1164 11AB;B33C;1103 1164 11AB; +B33D;B33D;1103 1164 11AC;B33D;1103 1164 11AC; +B33E;B33E;1103 1164 11AD;B33E;1103 1164 11AD; +B33F;B33F;1103 1164 11AE;B33F;1103 1164 11AE; +B340;B340;1103 1164 11AF;B340;1103 1164 11AF; +B341;B341;1103 1164 11B0;B341;1103 1164 11B0; +B342;B342;1103 1164 11B1;B342;1103 1164 11B1; +B343;B343;1103 1164 11B2;B343;1103 1164 11B2; +B344;B344;1103 1164 11B3;B344;1103 1164 11B3; +B345;B345;1103 1164 11B4;B345;1103 1164 11B4; +B346;B346;1103 1164 11B5;B346;1103 1164 11B5; +B347;B347;1103 1164 11B6;B347;1103 1164 11B6; +B348;B348;1103 1164 11B7;B348;1103 1164 11B7; +B349;B349;1103 1164 11B8;B349;1103 1164 11B8; +B34A;B34A;1103 1164 11B9;B34A;1103 1164 11B9; +B34B;B34B;1103 1164 11BA;B34B;1103 1164 11BA; +B34C;B34C;1103 1164 11BB;B34C;1103 1164 11BB; +B34D;B34D;1103 1164 11BC;B34D;1103 1164 11BC; +B34E;B34E;1103 1164 11BD;B34E;1103 1164 11BD; +B34F;B34F;1103 1164 11BE;B34F;1103 1164 11BE; +B350;B350;1103 1164 11BF;B350;1103 1164 11BF; +B351;B351;1103 1164 11C0;B351;1103 1164 11C0; +B352;B352;1103 1164 11C1;B352;1103 1164 11C1; +B353;B353;1103 1164 11C2;B353;1103 1164 11C2; +B354;B354;1103 1165;B354;1103 1165; +B355;B355;1103 1165 11A8;B355;1103 1165 11A8; +B356;B356;1103 1165 11A9;B356;1103 1165 11A9; +B357;B357;1103 1165 11AA;B357;1103 1165 11AA; +B358;B358;1103 1165 11AB;B358;1103 1165 11AB; +B359;B359;1103 1165 11AC;B359;1103 1165 11AC; +B35A;B35A;1103 1165 11AD;B35A;1103 1165 11AD; +B35B;B35B;1103 1165 11AE;B35B;1103 1165 11AE; +B35C;B35C;1103 1165 11AF;B35C;1103 1165 11AF; +B35D;B35D;1103 1165 11B0;B35D;1103 1165 11B0; +B35E;B35E;1103 1165 11B1;B35E;1103 1165 11B1; +B35F;B35F;1103 1165 11B2;B35F;1103 1165 11B2; +B360;B360;1103 1165 11B3;B360;1103 1165 11B3; +B361;B361;1103 1165 11B4;B361;1103 1165 11B4; +B362;B362;1103 1165 11B5;B362;1103 1165 11B5; +B363;B363;1103 1165 11B6;B363;1103 1165 11B6; +B364;B364;1103 1165 11B7;B364;1103 1165 11B7; +B365;B365;1103 1165 11B8;B365;1103 1165 11B8; +B366;B366;1103 1165 11B9;B366;1103 1165 11B9; +B367;B367;1103 1165 11BA;B367;1103 1165 11BA; +B368;B368;1103 1165 11BB;B368;1103 1165 11BB; +B369;B369;1103 1165 11BC;B369;1103 1165 11BC; +B36A;B36A;1103 1165 11BD;B36A;1103 1165 11BD; +B36B;B36B;1103 1165 11BE;B36B;1103 1165 11BE; +B36C;B36C;1103 1165 11BF;B36C;1103 1165 11BF; +B36D;B36D;1103 1165 11C0;B36D;1103 1165 11C0; +B36E;B36E;1103 1165 11C1;B36E;1103 1165 11C1; +B36F;B36F;1103 1165 11C2;B36F;1103 1165 11C2; +B370;B370;1103 1166;B370;1103 1166; +B371;B371;1103 1166 11A8;B371;1103 1166 11A8; +B372;B372;1103 1166 11A9;B372;1103 1166 11A9; +B373;B373;1103 1166 11AA;B373;1103 1166 11AA; +B374;B374;1103 1166 11AB;B374;1103 1166 11AB; +B375;B375;1103 1166 11AC;B375;1103 1166 11AC; +B376;B376;1103 1166 11AD;B376;1103 1166 11AD; +B377;B377;1103 1166 11AE;B377;1103 1166 11AE; +B378;B378;1103 1166 11AF;B378;1103 1166 11AF; +B379;B379;1103 1166 11B0;B379;1103 1166 11B0; +B37A;B37A;1103 1166 11B1;B37A;1103 1166 11B1; +B37B;B37B;1103 1166 11B2;B37B;1103 1166 11B2; +B37C;B37C;1103 1166 11B3;B37C;1103 1166 11B3; +B37D;B37D;1103 1166 11B4;B37D;1103 1166 11B4; +B37E;B37E;1103 1166 11B5;B37E;1103 1166 11B5; +B37F;B37F;1103 1166 11B6;B37F;1103 1166 11B6; +B380;B380;1103 1166 11B7;B380;1103 1166 11B7; +B381;B381;1103 1166 11B8;B381;1103 1166 11B8; +B382;B382;1103 1166 11B9;B382;1103 1166 11B9; +B383;B383;1103 1166 11BA;B383;1103 1166 11BA; +B384;B384;1103 1166 11BB;B384;1103 1166 11BB; +B385;B385;1103 1166 11BC;B385;1103 1166 11BC; +B386;B386;1103 1166 11BD;B386;1103 1166 11BD; +B387;B387;1103 1166 11BE;B387;1103 1166 11BE; +B388;B388;1103 1166 11BF;B388;1103 1166 11BF; +B389;B389;1103 1166 11C0;B389;1103 1166 11C0; +B38A;B38A;1103 1166 11C1;B38A;1103 1166 11C1; +B38B;B38B;1103 1166 11C2;B38B;1103 1166 11C2; +B38C;B38C;1103 1167;B38C;1103 1167; +B38D;B38D;1103 1167 11A8;B38D;1103 1167 11A8; +B38E;B38E;1103 1167 11A9;B38E;1103 1167 11A9; +B38F;B38F;1103 1167 11AA;B38F;1103 1167 11AA; +B390;B390;1103 1167 11AB;B390;1103 1167 11AB; +B391;B391;1103 1167 11AC;B391;1103 1167 11AC; +B392;B392;1103 1167 11AD;B392;1103 1167 11AD; +B393;B393;1103 1167 11AE;B393;1103 1167 11AE; +B394;B394;1103 1167 11AF;B394;1103 1167 11AF; +B395;B395;1103 1167 11B0;B395;1103 1167 11B0; +B396;B396;1103 1167 11B1;B396;1103 1167 11B1; +B397;B397;1103 1167 11B2;B397;1103 1167 11B2; +B398;B398;1103 1167 11B3;B398;1103 1167 11B3; +B399;B399;1103 1167 11B4;B399;1103 1167 11B4; +B39A;B39A;1103 1167 11B5;B39A;1103 1167 11B5; +B39B;B39B;1103 1167 11B6;B39B;1103 1167 11B6; +B39C;B39C;1103 1167 11B7;B39C;1103 1167 11B7; +B39D;B39D;1103 1167 11B8;B39D;1103 1167 11B8; +B39E;B39E;1103 1167 11B9;B39E;1103 1167 11B9; +B39F;B39F;1103 1167 11BA;B39F;1103 1167 11BA; +B3A0;B3A0;1103 1167 11BB;B3A0;1103 1167 11BB; +B3A1;B3A1;1103 1167 11BC;B3A1;1103 1167 11BC; +B3A2;B3A2;1103 1167 11BD;B3A2;1103 1167 11BD; +B3A3;B3A3;1103 1167 11BE;B3A3;1103 1167 11BE; +B3A4;B3A4;1103 1167 11BF;B3A4;1103 1167 11BF; +B3A5;B3A5;1103 1167 11C0;B3A5;1103 1167 11C0; +B3A6;B3A6;1103 1167 11C1;B3A6;1103 1167 11C1; +B3A7;B3A7;1103 1167 11C2;B3A7;1103 1167 11C2; +B3A8;B3A8;1103 1168;B3A8;1103 1168; +B3A9;B3A9;1103 1168 11A8;B3A9;1103 1168 11A8; +B3AA;B3AA;1103 1168 11A9;B3AA;1103 1168 11A9; +B3AB;B3AB;1103 1168 11AA;B3AB;1103 1168 11AA; +B3AC;B3AC;1103 1168 11AB;B3AC;1103 1168 11AB; +B3AD;B3AD;1103 1168 11AC;B3AD;1103 1168 11AC; +B3AE;B3AE;1103 1168 11AD;B3AE;1103 1168 11AD; +B3AF;B3AF;1103 1168 11AE;B3AF;1103 1168 11AE; +B3B0;B3B0;1103 1168 11AF;B3B0;1103 1168 11AF; +B3B1;B3B1;1103 1168 11B0;B3B1;1103 1168 11B0; +B3B2;B3B2;1103 1168 11B1;B3B2;1103 1168 11B1; +B3B3;B3B3;1103 1168 11B2;B3B3;1103 1168 11B2; +B3B4;B3B4;1103 1168 11B3;B3B4;1103 1168 11B3; +B3B5;B3B5;1103 1168 11B4;B3B5;1103 1168 11B4; +B3B6;B3B6;1103 1168 11B5;B3B6;1103 1168 11B5; +B3B7;B3B7;1103 1168 11B6;B3B7;1103 1168 11B6; +B3B8;B3B8;1103 1168 11B7;B3B8;1103 1168 11B7; +B3B9;B3B9;1103 1168 11B8;B3B9;1103 1168 11B8; +B3BA;B3BA;1103 1168 11B9;B3BA;1103 1168 11B9; +B3BB;B3BB;1103 1168 11BA;B3BB;1103 1168 11BA; +B3BC;B3BC;1103 1168 11BB;B3BC;1103 1168 11BB; +B3BD;B3BD;1103 1168 11BC;B3BD;1103 1168 11BC; +B3BE;B3BE;1103 1168 11BD;B3BE;1103 1168 11BD; +B3BF;B3BF;1103 1168 11BE;B3BF;1103 1168 11BE; +B3C0;B3C0;1103 1168 11BF;B3C0;1103 1168 11BF; +B3C1;B3C1;1103 1168 11C0;B3C1;1103 1168 11C0; +B3C2;B3C2;1103 1168 11C1;B3C2;1103 1168 11C1; +B3C3;B3C3;1103 1168 11C2;B3C3;1103 1168 11C2; +B3C4;B3C4;1103 1169;B3C4;1103 1169; +B3C5;B3C5;1103 1169 11A8;B3C5;1103 1169 11A8; +B3C6;B3C6;1103 1169 11A9;B3C6;1103 1169 11A9; +B3C7;B3C7;1103 1169 11AA;B3C7;1103 1169 11AA; +B3C8;B3C8;1103 1169 11AB;B3C8;1103 1169 11AB; +B3C9;B3C9;1103 1169 11AC;B3C9;1103 1169 11AC; +B3CA;B3CA;1103 1169 11AD;B3CA;1103 1169 11AD; +B3CB;B3CB;1103 1169 11AE;B3CB;1103 1169 11AE; +B3CC;B3CC;1103 1169 11AF;B3CC;1103 1169 11AF; +B3CD;B3CD;1103 1169 11B0;B3CD;1103 1169 11B0; +B3CE;B3CE;1103 1169 11B1;B3CE;1103 1169 11B1; +B3CF;B3CF;1103 1169 11B2;B3CF;1103 1169 11B2; +B3D0;B3D0;1103 1169 11B3;B3D0;1103 1169 11B3; +B3D1;B3D1;1103 1169 11B4;B3D1;1103 1169 11B4; +B3D2;B3D2;1103 1169 11B5;B3D2;1103 1169 11B5; +B3D3;B3D3;1103 1169 11B6;B3D3;1103 1169 11B6; +B3D4;B3D4;1103 1169 11B7;B3D4;1103 1169 11B7; +B3D5;B3D5;1103 1169 11B8;B3D5;1103 1169 11B8; +B3D6;B3D6;1103 1169 11B9;B3D6;1103 1169 11B9; +B3D7;B3D7;1103 1169 11BA;B3D7;1103 1169 11BA; +B3D8;B3D8;1103 1169 11BB;B3D8;1103 1169 11BB; +B3D9;B3D9;1103 1169 11BC;B3D9;1103 1169 11BC; +B3DA;B3DA;1103 1169 11BD;B3DA;1103 1169 11BD; +B3DB;B3DB;1103 1169 11BE;B3DB;1103 1169 11BE; +B3DC;B3DC;1103 1169 11BF;B3DC;1103 1169 11BF; +B3DD;B3DD;1103 1169 11C0;B3DD;1103 1169 11C0; +B3DE;B3DE;1103 1169 11C1;B3DE;1103 1169 11C1; +B3DF;B3DF;1103 1169 11C2;B3DF;1103 1169 11C2; +B3E0;B3E0;1103 116A;B3E0;1103 116A; +B3E1;B3E1;1103 116A 11A8;B3E1;1103 116A 11A8; +B3E2;B3E2;1103 116A 11A9;B3E2;1103 116A 11A9; +B3E3;B3E3;1103 116A 11AA;B3E3;1103 116A 11AA; +B3E4;B3E4;1103 116A 11AB;B3E4;1103 116A 11AB; +B3E5;B3E5;1103 116A 11AC;B3E5;1103 116A 11AC; +B3E6;B3E6;1103 116A 11AD;B3E6;1103 116A 11AD; +B3E7;B3E7;1103 116A 11AE;B3E7;1103 116A 11AE; +B3E8;B3E8;1103 116A 11AF;B3E8;1103 116A 11AF; +B3E9;B3E9;1103 116A 11B0;B3E9;1103 116A 11B0; +B3EA;B3EA;1103 116A 11B1;B3EA;1103 116A 11B1; +B3EB;B3EB;1103 116A 11B2;B3EB;1103 116A 11B2; +B3EC;B3EC;1103 116A 11B3;B3EC;1103 116A 11B3; +B3ED;B3ED;1103 116A 11B4;B3ED;1103 116A 11B4; +B3EE;B3EE;1103 116A 11B5;B3EE;1103 116A 11B5; +B3EF;B3EF;1103 116A 11B6;B3EF;1103 116A 11B6; +B3F0;B3F0;1103 116A 11B7;B3F0;1103 116A 11B7; +B3F1;B3F1;1103 116A 11B8;B3F1;1103 116A 11B8; +B3F2;B3F2;1103 116A 11B9;B3F2;1103 116A 11B9; +B3F3;B3F3;1103 116A 11BA;B3F3;1103 116A 11BA; +B3F4;B3F4;1103 116A 11BB;B3F4;1103 116A 11BB; +B3F5;B3F5;1103 116A 11BC;B3F5;1103 116A 11BC; +B3F6;B3F6;1103 116A 11BD;B3F6;1103 116A 11BD; +B3F7;B3F7;1103 116A 11BE;B3F7;1103 116A 11BE; +B3F8;B3F8;1103 116A 11BF;B3F8;1103 116A 11BF; +B3F9;B3F9;1103 116A 11C0;B3F9;1103 116A 11C0; +B3FA;B3FA;1103 116A 11C1;B3FA;1103 116A 11C1; +B3FB;B3FB;1103 116A 11C2;B3FB;1103 116A 11C2; +B3FC;B3FC;1103 116B;B3FC;1103 116B; +B3FD;B3FD;1103 116B 11A8;B3FD;1103 116B 11A8; +B3FE;B3FE;1103 116B 11A9;B3FE;1103 116B 11A9; +B3FF;B3FF;1103 116B 11AA;B3FF;1103 116B 11AA; +B400;B400;1103 116B 11AB;B400;1103 116B 11AB; +B401;B401;1103 116B 11AC;B401;1103 116B 11AC; +B402;B402;1103 116B 11AD;B402;1103 116B 11AD; +B403;B403;1103 116B 11AE;B403;1103 116B 11AE; +B404;B404;1103 116B 11AF;B404;1103 116B 11AF; +B405;B405;1103 116B 11B0;B405;1103 116B 11B0; +B406;B406;1103 116B 11B1;B406;1103 116B 11B1; +B407;B407;1103 116B 11B2;B407;1103 116B 11B2; +B408;B408;1103 116B 11B3;B408;1103 116B 11B3; +B409;B409;1103 116B 11B4;B409;1103 116B 11B4; +B40A;B40A;1103 116B 11B5;B40A;1103 116B 11B5; +B40B;B40B;1103 116B 11B6;B40B;1103 116B 11B6; +B40C;B40C;1103 116B 11B7;B40C;1103 116B 11B7; +B40D;B40D;1103 116B 11B8;B40D;1103 116B 11B8; +B40E;B40E;1103 116B 11B9;B40E;1103 116B 11B9; +B40F;B40F;1103 116B 11BA;B40F;1103 116B 11BA; +B410;B410;1103 116B 11BB;B410;1103 116B 11BB; +B411;B411;1103 116B 11BC;B411;1103 116B 11BC; +B412;B412;1103 116B 11BD;B412;1103 116B 11BD; +B413;B413;1103 116B 11BE;B413;1103 116B 11BE; +B414;B414;1103 116B 11BF;B414;1103 116B 11BF; +B415;B415;1103 116B 11C0;B415;1103 116B 11C0; +B416;B416;1103 116B 11C1;B416;1103 116B 11C1; +B417;B417;1103 116B 11C2;B417;1103 116B 11C2; +B418;B418;1103 116C;B418;1103 116C; +B419;B419;1103 116C 11A8;B419;1103 116C 11A8; +B41A;B41A;1103 116C 11A9;B41A;1103 116C 11A9; +B41B;B41B;1103 116C 11AA;B41B;1103 116C 11AA; +B41C;B41C;1103 116C 11AB;B41C;1103 116C 11AB; +B41D;B41D;1103 116C 11AC;B41D;1103 116C 11AC; +B41E;B41E;1103 116C 11AD;B41E;1103 116C 11AD; +B41F;B41F;1103 116C 11AE;B41F;1103 116C 11AE; +B420;B420;1103 116C 11AF;B420;1103 116C 11AF; +B421;B421;1103 116C 11B0;B421;1103 116C 11B0; +B422;B422;1103 116C 11B1;B422;1103 116C 11B1; +B423;B423;1103 116C 11B2;B423;1103 116C 11B2; +B424;B424;1103 116C 11B3;B424;1103 116C 11B3; +B425;B425;1103 116C 11B4;B425;1103 116C 11B4; +B426;B426;1103 116C 11B5;B426;1103 116C 11B5; +B427;B427;1103 116C 11B6;B427;1103 116C 11B6; +B428;B428;1103 116C 11B7;B428;1103 116C 11B7; +B429;B429;1103 116C 11B8;B429;1103 116C 11B8; +B42A;B42A;1103 116C 11B9;B42A;1103 116C 11B9; +B42B;B42B;1103 116C 11BA;B42B;1103 116C 11BA; +B42C;B42C;1103 116C 11BB;B42C;1103 116C 11BB; +B42D;B42D;1103 116C 11BC;B42D;1103 116C 11BC; +B42E;B42E;1103 116C 11BD;B42E;1103 116C 11BD; +B42F;B42F;1103 116C 11BE;B42F;1103 116C 11BE; +B430;B430;1103 116C 11BF;B430;1103 116C 11BF; +B431;B431;1103 116C 11C0;B431;1103 116C 11C0; +B432;B432;1103 116C 11C1;B432;1103 116C 11C1; +B433;B433;1103 116C 11C2;B433;1103 116C 11C2; +B434;B434;1103 116D;B434;1103 116D; +B435;B435;1103 116D 11A8;B435;1103 116D 11A8; +B436;B436;1103 116D 11A9;B436;1103 116D 11A9; +B437;B437;1103 116D 11AA;B437;1103 116D 11AA; +B438;B438;1103 116D 11AB;B438;1103 116D 11AB; +B439;B439;1103 116D 11AC;B439;1103 116D 11AC; +B43A;B43A;1103 116D 11AD;B43A;1103 116D 11AD; +B43B;B43B;1103 116D 11AE;B43B;1103 116D 11AE; +B43C;B43C;1103 116D 11AF;B43C;1103 116D 11AF; +B43D;B43D;1103 116D 11B0;B43D;1103 116D 11B0; +B43E;B43E;1103 116D 11B1;B43E;1103 116D 11B1; +B43F;B43F;1103 116D 11B2;B43F;1103 116D 11B2; +B440;B440;1103 116D 11B3;B440;1103 116D 11B3; +B441;B441;1103 116D 11B4;B441;1103 116D 11B4; +B442;B442;1103 116D 11B5;B442;1103 116D 11B5; +B443;B443;1103 116D 11B6;B443;1103 116D 11B6; +B444;B444;1103 116D 11B7;B444;1103 116D 11B7; +B445;B445;1103 116D 11B8;B445;1103 116D 11B8; +B446;B446;1103 116D 11B9;B446;1103 116D 11B9; +B447;B447;1103 116D 11BA;B447;1103 116D 11BA; +B448;B448;1103 116D 11BB;B448;1103 116D 11BB; +B449;B449;1103 116D 11BC;B449;1103 116D 11BC; +B44A;B44A;1103 116D 11BD;B44A;1103 116D 11BD; +B44B;B44B;1103 116D 11BE;B44B;1103 116D 11BE; +B44C;B44C;1103 116D 11BF;B44C;1103 116D 11BF; +B44D;B44D;1103 116D 11C0;B44D;1103 116D 11C0; +B44E;B44E;1103 116D 11C1;B44E;1103 116D 11C1; +B44F;B44F;1103 116D 11C2;B44F;1103 116D 11C2; +B450;B450;1103 116E;B450;1103 116E; +B451;B451;1103 116E 11A8;B451;1103 116E 11A8; +B452;B452;1103 116E 11A9;B452;1103 116E 11A9; +B453;B453;1103 116E 11AA;B453;1103 116E 11AA; +B454;B454;1103 116E 11AB;B454;1103 116E 11AB; +B455;B455;1103 116E 11AC;B455;1103 116E 11AC; +B456;B456;1103 116E 11AD;B456;1103 116E 11AD; +B457;B457;1103 116E 11AE;B457;1103 116E 11AE; +B458;B458;1103 116E 11AF;B458;1103 116E 11AF; +B459;B459;1103 116E 11B0;B459;1103 116E 11B0; +B45A;B45A;1103 116E 11B1;B45A;1103 116E 11B1; +B45B;B45B;1103 116E 11B2;B45B;1103 116E 11B2; +B45C;B45C;1103 116E 11B3;B45C;1103 116E 11B3; +B45D;B45D;1103 116E 11B4;B45D;1103 116E 11B4; +B45E;B45E;1103 116E 11B5;B45E;1103 116E 11B5; +B45F;B45F;1103 116E 11B6;B45F;1103 116E 11B6; +B460;B460;1103 116E 11B7;B460;1103 116E 11B7; +B461;B461;1103 116E 11B8;B461;1103 116E 11B8; +B462;B462;1103 116E 11B9;B462;1103 116E 11B9; +B463;B463;1103 116E 11BA;B463;1103 116E 11BA; +B464;B464;1103 116E 11BB;B464;1103 116E 11BB; +B465;B465;1103 116E 11BC;B465;1103 116E 11BC; +B466;B466;1103 116E 11BD;B466;1103 116E 11BD; +B467;B467;1103 116E 11BE;B467;1103 116E 11BE; +B468;B468;1103 116E 11BF;B468;1103 116E 11BF; +B469;B469;1103 116E 11C0;B469;1103 116E 11C0; +B46A;B46A;1103 116E 11C1;B46A;1103 116E 11C1; +B46B;B46B;1103 116E 11C2;B46B;1103 116E 11C2; +B46C;B46C;1103 116F;B46C;1103 116F; +B46D;B46D;1103 116F 11A8;B46D;1103 116F 11A8; +B46E;B46E;1103 116F 11A9;B46E;1103 116F 11A9; +B46F;B46F;1103 116F 11AA;B46F;1103 116F 11AA; +B470;B470;1103 116F 11AB;B470;1103 116F 11AB; +B471;B471;1103 116F 11AC;B471;1103 116F 11AC; +B472;B472;1103 116F 11AD;B472;1103 116F 11AD; +B473;B473;1103 116F 11AE;B473;1103 116F 11AE; +B474;B474;1103 116F 11AF;B474;1103 116F 11AF; +B475;B475;1103 116F 11B0;B475;1103 116F 11B0; +B476;B476;1103 116F 11B1;B476;1103 116F 11B1; +B477;B477;1103 116F 11B2;B477;1103 116F 11B2; +B478;B478;1103 116F 11B3;B478;1103 116F 11B3; +B479;B479;1103 116F 11B4;B479;1103 116F 11B4; +B47A;B47A;1103 116F 11B5;B47A;1103 116F 11B5; +B47B;B47B;1103 116F 11B6;B47B;1103 116F 11B6; +B47C;B47C;1103 116F 11B7;B47C;1103 116F 11B7; +B47D;B47D;1103 116F 11B8;B47D;1103 116F 11B8; +B47E;B47E;1103 116F 11B9;B47E;1103 116F 11B9; +B47F;B47F;1103 116F 11BA;B47F;1103 116F 11BA; +B480;B480;1103 116F 11BB;B480;1103 116F 11BB; +B481;B481;1103 116F 11BC;B481;1103 116F 11BC; +B482;B482;1103 116F 11BD;B482;1103 116F 11BD; +B483;B483;1103 116F 11BE;B483;1103 116F 11BE; +B484;B484;1103 116F 11BF;B484;1103 116F 11BF; +B485;B485;1103 116F 11C0;B485;1103 116F 11C0; +B486;B486;1103 116F 11C1;B486;1103 116F 11C1; +B487;B487;1103 116F 11C2;B487;1103 116F 11C2; +B488;B488;1103 1170;B488;1103 1170; +B489;B489;1103 1170 11A8;B489;1103 1170 11A8; +B48A;B48A;1103 1170 11A9;B48A;1103 1170 11A9; +B48B;B48B;1103 1170 11AA;B48B;1103 1170 11AA; +B48C;B48C;1103 1170 11AB;B48C;1103 1170 11AB; +B48D;B48D;1103 1170 11AC;B48D;1103 1170 11AC; +B48E;B48E;1103 1170 11AD;B48E;1103 1170 11AD; +B48F;B48F;1103 1170 11AE;B48F;1103 1170 11AE; +B490;B490;1103 1170 11AF;B490;1103 1170 11AF; +B491;B491;1103 1170 11B0;B491;1103 1170 11B0; +B492;B492;1103 1170 11B1;B492;1103 1170 11B1; +B493;B493;1103 1170 11B2;B493;1103 1170 11B2; +B494;B494;1103 1170 11B3;B494;1103 1170 11B3; +B495;B495;1103 1170 11B4;B495;1103 1170 11B4; +B496;B496;1103 1170 11B5;B496;1103 1170 11B5; +B497;B497;1103 1170 11B6;B497;1103 1170 11B6; +B498;B498;1103 1170 11B7;B498;1103 1170 11B7; +B499;B499;1103 1170 11B8;B499;1103 1170 11B8; +B49A;B49A;1103 1170 11B9;B49A;1103 1170 11B9; +B49B;B49B;1103 1170 11BA;B49B;1103 1170 11BA; +B49C;B49C;1103 1170 11BB;B49C;1103 1170 11BB; +B49D;B49D;1103 1170 11BC;B49D;1103 1170 11BC; +B49E;B49E;1103 1170 11BD;B49E;1103 1170 11BD; +B49F;B49F;1103 1170 11BE;B49F;1103 1170 11BE; +B4A0;B4A0;1103 1170 11BF;B4A0;1103 1170 11BF; +B4A1;B4A1;1103 1170 11C0;B4A1;1103 1170 11C0; +B4A2;B4A2;1103 1170 11C1;B4A2;1103 1170 11C1; +B4A3;B4A3;1103 1170 11C2;B4A3;1103 1170 11C2; +B4A4;B4A4;1103 1171;B4A4;1103 1171; +B4A5;B4A5;1103 1171 11A8;B4A5;1103 1171 11A8; +B4A6;B4A6;1103 1171 11A9;B4A6;1103 1171 11A9; +B4A7;B4A7;1103 1171 11AA;B4A7;1103 1171 11AA; +B4A8;B4A8;1103 1171 11AB;B4A8;1103 1171 11AB; +B4A9;B4A9;1103 1171 11AC;B4A9;1103 1171 11AC; +B4AA;B4AA;1103 1171 11AD;B4AA;1103 1171 11AD; +B4AB;B4AB;1103 1171 11AE;B4AB;1103 1171 11AE; +B4AC;B4AC;1103 1171 11AF;B4AC;1103 1171 11AF; +B4AD;B4AD;1103 1171 11B0;B4AD;1103 1171 11B0; +B4AE;B4AE;1103 1171 11B1;B4AE;1103 1171 11B1; +B4AF;B4AF;1103 1171 11B2;B4AF;1103 1171 11B2; +B4B0;B4B0;1103 1171 11B3;B4B0;1103 1171 11B3; +B4B1;B4B1;1103 1171 11B4;B4B1;1103 1171 11B4; +B4B2;B4B2;1103 1171 11B5;B4B2;1103 1171 11B5; +B4B3;B4B3;1103 1171 11B6;B4B3;1103 1171 11B6; +B4B4;B4B4;1103 1171 11B7;B4B4;1103 1171 11B7; +B4B5;B4B5;1103 1171 11B8;B4B5;1103 1171 11B8; +B4B6;B4B6;1103 1171 11B9;B4B6;1103 1171 11B9; +B4B7;B4B7;1103 1171 11BA;B4B7;1103 1171 11BA; +B4B8;B4B8;1103 1171 11BB;B4B8;1103 1171 11BB; +B4B9;B4B9;1103 1171 11BC;B4B9;1103 1171 11BC; +B4BA;B4BA;1103 1171 11BD;B4BA;1103 1171 11BD; +B4BB;B4BB;1103 1171 11BE;B4BB;1103 1171 11BE; +B4BC;B4BC;1103 1171 11BF;B4BC;1103 1171 11BF; +B4BD;B4BD;1103 1171 11C0;B4BD;1103 1171 11C0; +B4BE;B4BE;1103 1171 11C1;B4BE;1103 1171 11C1; +B4BF;B4BF;1103 1171 11C2;B4BF;1103 1171 11C2; +B4C0;B4C0;1103 1172;B4C0;1103 1172; +B4C1;B4C1;1103 1172 11A8;B4C1;1103 1172 11A8; +B4C2;B4C2;1103 1172 11A9;B4C2;1103 1172 11A9; +B4C3;B4C3;1103 1172 11AA;B4C3;1103 1172 11AA; +B4C4;B4C4;1103 1172 11AB;B4C4;1103 1172 11AB; +B4C5;B4C5;1103 1172 11AC;B4C5;1103 1172 11AC; +B4C6;B4C6;1103 1172 11AD;B4C6;1103 1172 11AD; +B4C7;B4C7;1103 1172 11AE;B4C7;1103 1172 11AE; +B4C8;B4C8;1103 1172 11AF;B4C8;1103 1172 11AF; +B4C9;B4C9;1103 1172 11B0;B4C9;1103 1172 11B0; +B4CA;B4CA;1103 1172 11B1;B4CA;1103 1172 11B1; +B4CB;B4CB;1103 1172 11B2;B4CB;1103 1172 11B2; +B4CC;B4CC;1103 1172 11B3;B4CC;1103 1172 11B3; +B4CD;B4CD;1103 1172 11B4;B4CD;1103 1172 11B4; +B4CE;B4CE;1103 1172 11B5;B4CE;1103 1172 11B5; +B4CF;B4CF;1103 1172 11B6;B4CF;1103 1172 11B6; +B4D0;B4D0;1103 1172 11B7;B4D0;1103 1172 11B7; +B4D1;B4D1;1103 1172 11B8;B4D1;1103 1172 11B8; +B4D2;B4D2;1103 1172 11B9;B4D2;1103 1172 11B9; +B4D3;B4D3;1103 1172 11BA;B4D3;1103 1172 11BA; +B4D4;B4D4;1103 1172 11BB;B4D4;1103 1172 11BB; +B4D5;B4D5;1103 1172 11BC;B4D5;1103 1172 11BC; +B4D6;B4D6;1103 1172 11BD;B4D6;1103 1172 11BD; +B4D7;B4D7;1103 1172 11BE;B4D7;1103 1172 11BE; +B4D8;B4D8;1103 1172 11BF;B4D8;1103 1172 11BF; +B4D9;B4D9;1103 1172 11C0;B4D9;1103 1172 11C0; +B4DA;B4DA;1103 1172 11C1;B4DA;1103 1172 11C1; +B4DB;B4DB;1103 1172 11C2;B4DB;1103 1172 11C2; +B4DC;B4DC;1103 1173;B4DC;1103 1173; +B4DD;B4DD;1103 1173 11A8;B4DD;1103 1173 11A8; +B4DE;B4DE;1103 1173 11A9;B4DE;1103 1173 11A9; +B4DF;B4DF;1103 1173 11AA;B4DF;1103 1173 11AA; +B4E0;B4E0;1103 1173 11AB;B4E0;1103 1173 11AB; +B4E1;B4E1;1103 1173 11AC;B4E1;1103 1173 11AC; +B4E2;B4E2;1103 1173 11AD;B4E2;1103 1173 11AD; +B4E3;B4E3;1103 1173 11AE;B4E3;1103 1173 11AE; +B4E4;B4E4;1103 1173 11AF;B4E4;1103 1173 11AF; +B4E5;B4E5;1103 1173 11B0;B4E5;1103 1173 11B0; +B4E6;B4E6;1103 1173 11B1;B4E6;1103 1173 11B1; +B4E7;B4E7;1103 1173 11B2;B4E7;1103 1173 11B2; +B4E8;B4E8;1103 1173 11B3;B4E8;1103 1173 11B3; +B4E9;B4E9;1103 1173 11B4;B4E9;1103 1173 11B4; +B4EA;B4EA;1103 1173 11B5;B4EA;1103 1173 11B5; +B4EB;B4EB;1103 1173 11B6;B4EB;1103 1173 11B6; +B4EC;B4EC;1103 1173 11B7;B4EC;1103 1173 11B7; +B4ED;B4ED;1103 1173 11B8;B4ED;1103 1173 11B8; +B4EE;B4EE;1103 1173 11B9;B4EE;1103 1173 11B9; +B4EF;B4EF;1103 1173 11BA;B4EF;1103 1173 11BA; +B4F0;B4F0;1103 1173 11BB;B4F0;1103 1173 11BB; +B4F1;B4F1;1103 1173 11BC;B4F1;1103 1173 11BC; +B4F2;B4F2;1103 1173 11BD;B4F2;1103 1173 11BD; +B4F3;B4F3;1103 1173 11BE;B4F3;1103 1173 11BE; +B4F4;B4F4;1103 1173 11BF;B4F4;1103 1173 11BF; +B4F5;B4F5;1103 1173 11C0;B4F5;1103 1173 11C0; +B4F6;B4F6;1103 1173 11C1;B4F6;1103 1173 11C1; +B4F7;B4F7;1103 1173 11C2;B4F7;1103 1173 11C2; +B4F8;B4F8;1103 1174;B4F8;1103 1174; +B4F9;B4F9;1103 1174 11A8;B4F9;1103 1174 11A8; +B4FA;B4FA;1103 1174 11A9;B4FA;1103 1174 11A9; +B4FB;B4FB;1103 1174 11AA;B4FB;1103 1174 11AA; +B4FC;B4FC;1103 1174 11AB;B4FC;1103 1174 11AB; +B4FD;B4FD;1103 1174 11AC;B4FD;1103 1174 11AC; +B4FE;B4FE;1103 1174 11AD;B4FE;1103 1174 11AD; +B4FF;B4FF;1103 1174 11AE;B4FF;1103 1174 11AE; +B500;B500;1103 1174 11AF;B500;1103 1174 11AF; +B501;B501;1103 1174 11B0;B501;1103 1174 11B0; +B502;B502;1103 1174 11B1;B502;1103 1174 11B1; +B503;B503;1103 1174 11B2;B503;1103 1174 11B2; +B504;B504;1103 1174 11B3;B504;1103 1174 11B3; +B505;B505;1103 1174 11B4;B505;1103 1174 11B4; +B506;B506;1103 1174 11B5;B506;1103 1174 11B5; +B507;B507;1103 1174 11B6;B507;1103 1174 11B6; +B508;B508;1103 1174 11B7;B508;1103 1174 11B7; +B509;B509;1103 1174 11B8;B509;1103 1174 11B8; +B50A;B50A;1103 1174 11B9;B50A;1103 1174 11B9; +B50B;B50B;1103 1174 11BA;B50B;1103 1174 11BA; +B50C;B50C;1103 1174 11BB;B50C;1103 1174 11BB; +B50D;B50D;1103 1174 11BC;B50D;1103 1174 11BC; +B50E;B50E;1103 1174 11BD;B50E;1103 1174 11BD; +B50F;B50F;1103 1174 11BE;B50F;1103 1174 11BE; +B510;B510;1103 1174 11BF;B510;1103 1174 11BF; +B511;B511;1103 1174 11C0;B511;1103 1174 11C0; +B512;B512;1103 1174 11C1;B512;1103 1174 11C1; +B513;B513;1103 1174 11C2;B513;1103 1174 11C2; +B514;B514;1103 1175;B514;1103 1175; +B515;B515;1103 1175 11A8;B515;1103 1175 11A8; +B516;B516;1103 1175 11A9;B516;1103 1175 11A9; +B517;B517;1103 1175 11AA;B517;1103 1175 11AA; +B518;B518;1103 1175 11AB;B518;1103 1175 11AB; +B519;B519;1103 1175 11AC;B519;1103 1175 11AC; +B51A;B51A;1103 1175 11AD;B51A;1103 1175 11AD; +B51B;B51B;1103 1175 11AE;B51B;1103 1175 11AE; +B51C;B51C;1103 1175 11AF;B51C;1103 1175 11AF; +B51D;B51D;1103 1175 11B0;B51D;1103 1175 11B0; +B51E;B51E;1103 1175 11B1;B51E;1103 1175 11B1; +B51F;B51F;1103 1175 11B2;B51F;1103 1175 11B2; +B520;B520;1103 1175 11B3;B520;1103 1175 11B3; +B521;B521;1103 1175 11B4;B521;1103 1175 11B4; +B522;B522;1103 1175 11B5;B522;1103 1175 11B5; +B523;B523;1103 1175 11B6;B523;1103 1175 11B6; +B524;B524;1103 1175 11B7;B524;1103 1175 11B7; +B525;B525;1103 1175 11B8;B525;1103 1175 11B8; +B526;B526;1103 1175 11B9;B526;1103 1175 11B9; +B527;B527;1103 1175 11BA;B527;1103 1175 11BA; +B528;B528;1103 1175 11BB;B528;1103 1175 11BB; +B529;B529;1103 1175 11BC;B529;1103 1175 11BC; +B52A;B52A;1103 1175 11BD;B52A;1103 1175 11BD; +B52B;B52B;1103 1175 11BE;B52B;1103 1175 11BE; +B52C;B52C;1103 1175 11BF;B52C;1103 1175 11BF; +B52D;B52D;1103 1175 11C0;B52D;1103 1175 11C0; +B52E;B52E;1103 1175 11C1;B52E;1103 1175 11C1; +B52F;B52F;1103 1175 11C2;B52F;1103 1175 11C2; +B530;B530;1104 1161;B530;1104 1161; +B531;B531;1104 1161 11A8;B531;1104 1161 11A8; +B532;B532;1104 1161 11A9;B532;1104 1161 11A9; +B533;B533;1104 1161 11AA;B533;1104 1161 11AA; +B534;B534;1104 1161 11AB;B534;1104 1161 11AB; +B535;B535;1104 1161 11AC;B535;1104 1161 11AC; +B536;B536;1104 1161 11AD;B536;1104 1161 11AD; +B537;B537;1104 1161 11AE;B537;1104 1161 11AE; +B538;B538;1104 1161 11AF;B538;1104 1161 11AF; +B539;B539;1104 1161 11B0;B539;1104 1161 11B0; +B53A;B53A;1104 1161 11B1;B53A;1104 1161 11B1; +B53B;B53B;1104 1161 11B2;B53B;1104 1161 11B2; +B53C;B53C;1104 1161 11B3;B53C;1104 1161 11B3; +B53D;B53D;1104 1161 11B4;B53D;1104 1161 11B4; +B53E;B53E;1104 1161 11B5;B53E;1104 1161 11B5; +B53F;B53F;1104 1161 11B6;B53F;1104 1161 11B6; +B540;B540;1104 1161 11B7;B540;1104 1161 11B7; +B541;B541;1104 1161 11B8;B541;1104 1161 11B8; +B542;B542;1104 1161 11B9;B542;1104 1161 11B9; +B543;B543;1104 1161 11BA;B543;1104 1161 11BA; +B544;B544;1104 1161 11BB;B544;1104 1161 11BB; +B545;B545;1104 1161 11BC;B545;1104 1161 11BC; +B546;B546;1104 1161 11BD;B546;1104 1161 11BD; +B547;B547;1104 1161 11BE;B547;1104 1161 11BE; +B548;B548;1104 1161 11BF;B548;1104 1161 11BF; +B549;B549;1104 1161 11C0;B549;1104 1161 11C0; +B54A;B54A;1104 1161 11C1;B54A;1104 1161 11C1; +B54B;B54B;1104 1161 11C2;B54B;1104 1161 11C2; +B54C;B54C;1104 1162;B54C;1104 1162; +B54D;B54D;1104 1162 11A8;B54D;1104 1162 11A8; +B54E;B54E;1104 1162 11A9;B54E;1104 1162 11A9; +B54F;B54F;1104 1162 11AA;B54F;1104 1162 11AA; +B550;B550;1104 1162 11AB;B550;1104 1162 11AB; +B551;B551;1104 1162 11AC;B551;1104 1162 11AC; +B552;B552;1104 1162 11AD;B552;1104 1162 11AD; +B553;B553;1104 1162 11AE;B553;1104 1162 11AE; +B554;B554;1104 1162 11AF;B554;1104 1162 11AF; +B555;B555;1104 1162 11B0;B555;1104 1162 11B0; +B556;B556;1104 1162 11B1;B556;1104 1162 11B1; +B557;B557;1104 1162 11B2;B557;1104 1162 11B2; +B558;B558;1104 1162 11B3;B558;1104 1162 11B3; +B559;B559;1104 1162 11B4;B559;1104 1162 11B4; +B55A;B55A;1104 1162 11B5;B55A;1104 1162 11B5; +B55B;B55B;1104 1162 11B6;B55B;1104 1162 11B6; +B55C;B55C;1104 1162 11B7;B55C;1104 1162 11B7; +B55D;B55D;1104 1162 11B8;B55D;1104 1162 11B8; +B55E;B55E;1104 1162 11B9;B55E;1104 1162 11B9; +B55F;B55F;1104 1162 11BA;B55F;1104 1162 11BA; +B560;B560;1104 1162 11BB;B560;1104 1162 11BB; +B561;B561;1104 1162 11BC;B561;1104 1162 11BC; +B562;B562;1104 1162 11BD;B562;1104 1162 11BD; +B563;B563;1104 1162 11BE;B563;1104 1162 11BE; +B564;B564;1104 1162 11BF;B564;1104 1162 11BF; +B565;B565;1104 1162 11C0;B565;1104 1162 11C0; +B566;B566;1104 1162 11C1;B566;1104 1162 11C1; +B567;B567;1104 1162 11C2;B567;1104 1162 11C2; +B568;B568;1104 1163;B568;1104 1163; +B569;B569;1104 1163 11A8;B569;1104 1163 11A8; +B56A;B56A;1104 1163 11A9;B56A;1104 1163 11A9; +B56B;B56B;1104 1163 11AA;B56B;1104 1163 11AA; +B56C;B56C;1104 1163 11AB;B56C;1104 1163 11AB; +B56D;B56D;1104 1163 11AC;B56D;1104 1163 11AC; +B56E;B56E;1104 1163 11AD;B56E;1104 1163 11AD; +B56F;B56F;1104 1163 11AE;B56F;1104 1163 11AE; +B570;B570;1104 1163 11AF;B570;1104 1163 11AF; +B571;B571;1104 1163 11B0;B571;1104 1163 11B0; +B572;B572;1104 1163 11B1;B572;1104 1163 11B1; +B573;B573;1104 1163 11B2;B573;1104 1163 11B2; +B574;B574;1104 1163 11B3;B574;1104 1163 11B3; +B575;B575;1104 1163 11B4;B575;1104 1163 11B4; +B576;B576;1104 1163 11B5;B576;1104 1163 11B5; +B577;B577;1104 1163 11B6;B577;1104 1163 11B6; +B578;B578;1104 1163 11B7;B578;1104 1163 11B7; +B579;B579;1104 1163 11B8;B579;1104 1163 11B8; +B57A;B57A;1104 1163 11B9;B57A;1104 1163 11B9; +B57B;B57B;1104 1163 11BA;B57B;1104 1163 11BA; +B57C;B57C;1104 1163 11BB;B57C;1104 1163 11BB; +B57D;B57D;1104 1163 11BC;B57D;1104 1163 11BC; +B57E;B57E;1104 1163 11BD;B57E;1104 1163 11BD; +B57F;B57F;1104 1163 11BE;B57F;1104 1163 11BE; +B580;B580;1104 1163 11BF;B580;1104 1163 11BF; +B581;B581;1104 1163 11C0;B581;1104 1163 11C0; +B582;B582;1104 1163 11C1;B582;1104 1163 11C1; +B583;B583;1104 1163 11C2;B583;1104 1163 11C2; +B584;B584;1104 1164;B584;1104 1164; +B585;B585;1104 1164 11A8;B585;1104 1164 11A8; +B586;B586;1104 1164 11A9;B586;1104 1164 11A9; +B587;B587;1104 1164 11AA;B587;1104 1164 11AA; +B588;B588;1104 1164 11AB;B588;1104 1164 11AB; +B589;B589;1104 1164 11AC;B589;1104 1164 11AC; +B58A;B58A;1104 1164 11AD;B58A;1104 1164 11AD; +B58B;B58B;1104 1164 11AE;B58B;1104 1164 11AE; +B58C;B58C;1104 1164 11AF;B58C;1104 1164 11AF; +B58D;B58D;1104 1164 11B0;B58D;1104 1164 11B0; +B58E;B58E;1104 1164 11B1;B58E;1104 1164 11B1; +B58F;B58F;1104 1164 11B2;B58F;1104 1164 11B2; +B590;B590;1104 1164 11B3;B590;1104 1164 11B3; +B591;B591;1104 1164 11B4;B591;1104 1164 11B4; +B592;B592;1104 1164 11B5;B592;1104 1164 11B5; +B593;B593;1104 1164 11B6;B593;1104 1164 11B6; +B594;B594;1104 1164 11B7;B594;1104 1164 11B7; +B595;B595;1104 1164 11B8;B595;1104 1164 11B8; +B596;B596;1104 1164 11B9;B596;1104 1164 11B9; +B597;B597;1104 1164 11BA;B597;1104 1164 11BA; +B598;B598;1104 1164 11BB;B598;1104 1164 11BB; +B599;B599;1104 1164 11BC;B599;1104 1164 11BC; +B59A;B59A;1104 1164 11BD;B59A;1104 1164 11BD; +B59B;B59B;1104 1164 11BE;B59B;1104 1164 11BE; +B59C;B59C;1104 1164 11BF;B59C;1104 1164 11BF; +B59D;B59D;1104 1164 11C0;B59D;1104 1164 11C0; +B59E;B59E;1104 1164 11C1;B59E;1104 1164 11C1; +B59F;B59F;1104 1164 11C2;B59F;1104 1164 11C2; +B5A0;B5A0;1104 1165;B5A0;1104 1165; +B5A1;B5A1;1104 1165 11A8;B5A1;1104 1165 11A8; +B5A2;B5A2;1104 1165 11A9;B5A2;1104 1165 11A9; +B5A3;B5A3;1104 1165 11AA;B5A3;1104 1165 11AA; +B5A4;B5A4;1104 1165 11AB;B5A4;1104 1165 11AB; +B5A5;B5A5;1104 1165 11AC;B5A5;1104 1165 11AC; +B5A6;B5A6;1104 1165 11AD;B5A6;1104 1165 11AD; +B5A7;B5A7;1104 1165 11AE;B5A7;1104 1165 11AE; +B5A8;B5A8;1104 1165 11AF;B5A8;1104 1165 11AF; +B5A9;B5A9;1104 1165 11B0;B5A9;1104 1165 11B0; +B5AA;B5AA;1104 1165 11B1;B5AA;1104 1165 11B1; +B5AB;B5AB;1104 1165 11B2;B5AB;1104 1165 11B2; +B5AC;B5AC;1104 1165 11B3;B5AC;1104 1165 11B3; +B5AD;B5AD;1104 1165 11B4;B5AD;1104 1165 11B4; +B5AE;B5AE;1104 1165 11B5;B5AE;1104 1165 11B5; +B5AF;B5AF;1104 1165 11B6;B5AF;1104 1165 11B6; +B5B0;B5B0;1104 1165 11B7;B5B0;1104 1165 11B7; +B5B1;B5B1;1104 1165 11B8;B5B1;1104 1165 11B8; +B5B2;B5B2;1104 1165 11B9;B5B2;1104 1165 11B9; +B5B3;B5B3;1104 1165 11BA;B5B3;1104 1165 11BA; +B5B4;B5B4;1104 1165 11BB;B5B4;1104 1165 11BB; +B5B5;B5B5;1104 1165 11BC;B5B5;1104 1165 11BC; +B5B6;B5B6;1104 1165 11BD;B5B6;1104 1165 11BD; +B5B7;B5B7;1104 1165 11BE;B5B7;1104 1165 11BE; +B5B8;B5B8;1104 1165 11BF;B5B8;1104 1165 11BF; +B5B9;B5B9;1104 1165 11C0;B5B9;1104 1165 11C0; +B5BA;B5BA;1104 1165 11C1;B5BA;1104 1165 11C1; +B5BB;B5BB;1104 1165 11C2;B5BB;1104 1165 11C2; +B5BC;B5BC;1104 1166;B5BC;1104 1166; +B5BD;B5BD;1104 1166 11A8;B5BD;1104 1166 11A8; +B5BE;B5BE;1104 1166 11A9;B5BE;1104 1166 11A9; +B5BF;B5BF;1104 1166 11AA;B5BF;1104 1166 11AA; +B5C0;B5C0;1104 1166 11AB;B5C0;1104 1166 11AB; +B5C1;B5C1;1104 1166 11AC;B5C1;1104 1166 11AC; +B5C2;B5C2;1104 1166 11AD;B5C2;1104 1166 11AD; +B5C3;B5C3;1104 1166 11AE;B5C3;1104 1166 11AE; +B5C4;B5C4;1104 1166 11AF;B5C4;1104 1166 11AF; +B5C5;B5C5;1104 1166 11B0;B5C5;1104 1166 11B0; +B5C6;B5C6;1104 1166 11B1;B5C6;1104 1166 11B1; +B5C7;B5C7;1104 1166 11B2;B5C7;1104 1166 11B2; +B5C8;B5C8;1104 1166 11B3;B5C8;1104 1166 11B3; +B5C9;B5C9;1104 1166 11B4;B5C9;1104 1166 11B4; +B5CA;B5CA;1104 1166 11B5;B5CA;1104 1166 11B5; +B5CB;B5CB;1104 1166 11B6;B5CB;1104 1166 11B6; +B5CC;B5CC;1104 1166 11B7;B5CC;1104 1166 11B7; +B5CD;B5CD;1104 1166 11B8;B5CD;1104 1166 11B8; +B5CE;B5CE;1104 1166 11B9;B5CE;1104 1166 11B9; +B5CF;B5CF;1104 1166 11BA;B5CF;1104 1166 11BA; +B5D0;B5D0;1104 1166 11BB;B5D0;1104 1166 11BB; +B5D1;B5D1;1104 1166 11BC;B5D1;1104 1166 11BC; +B5D2;B5D2;1104 1166 11BD;B5D2;1104 1166 11BD; +B5D3;B5D3;1104 1166 11BE;B5D3;1104 1166 11BE; +B5D4;B5D4;1104 1166 11BF;B5D4;1104 1166 11BF; +B5D5;B5D5;1104 1166 11C0;B5D5;1104 1166 11C0; +B5D6;B5D6;1104 1166 11C1;B5D6;1104 1166 11C1; +B5D7;B5D7;1104 1166 11C2;B5D7;1104 1166 11C2; +B5D8;B5D8;1104 1167;B5D8;1104 1167; +B5D9;B5D9;1104 1167 11A8;B5D9;1104 1167 11A8; +B5DA;B5DA;1104 1167 11A9;B5DA;1104 1167 11A9; +B5DB;B5DB;1104 1167 11AA;B5DB;1104 1167 11AA; +B5DC;B5DC;1104 1167 11AB;B5DC;1104 1167 11AB; +B5DD;B5DD;1104 1167 11AC;B5DD;1104 1167 11AC; +B5DE;B5DE;1104 1167 11AD;B5DE;1104 1167 11AD; +B5DF;B5DF;1104 1167 11AE;B5DF;1104 1167 11AE; +B5E0;B5E0;1104 1167 11AF;B5E0;1104 1167 11AF; +B5E1;B5E1;1104 1167 11B0;B5E1;1104 1167 11B0; +B5E2;B5E2;1104 1167 11B1;B5E2;1104 1167 11B1; +B5E3;B5E3;1104 1167 11B2;B5E3;1104 1167 11B2; +B5E4;B5E4;1104 1167 11B3;B5E4;1104 1167 11B3; +B5E5;B5E5;1104 1167 11B4;B5E5;1104 1167 11B4; +B5E6;B5E6;1104 1167 11B5;B5E6;1104 1167 11B5; +B5E7;B5E7;1104 1167 11B6;B5E7;1104 1167 11B6; +B5E8;B5E8;1104 1167 11B7;B5E8;1104 1167 11B7; +B5E9;B5E9;1104 1167 11B8;B5E9;1104 1167 11B8; +B5EA;B5EA;1104 1167 11B9;B5EA;1104 1167 11B9; +B5EB;B5EB;1104 1167 11BA;B5EB;1104 1167 11BA; +B5EC;B5EC;1104 1167 11BB;B5EC;1104 1167 11BB; +B5ED;B5ED;1104 1167 11BC;B5ED;1104 1167 11BC; +B5EE;B5EE;1104 1167 11BD;B5EE;1104 1167 11BD; +B5EF;B5EF;1104 1167 11BE;B5EF;1104 1167 11BE; +B5F0;B5F0;1104 1167 11BF;B5F0;1104 1167 11BF; +B5F1;B5F1;1104 1167 11C0;B5F1;1104 1167 11C0; +B5F2;B5F2;1104 1167 11C1;B5F2;1104 1167 11C1; +B5F3;B5F3;1104 1167 11C2;B5F3;1104 1167 11C2; +B5F4;B5F4;1104 1168;B5F4;1104 1168; +B5F5;B5F5;1104 1168 11A8;B5F5;1104 1168 11A8; +B5F6;B5F6;1104 1168 11A9;B5F6;1104 1168 11A9; +B5F7;B5F7;1104 1168 11AA;B5F7;1104 1168 11AA; +B5F8;B5F8;1104 1168 11AB;B5F8;1104 1168 11AB; +B5F9;B5F9;1104 1168 11AC;B5F9;1104 1168 11AC; +B5FA;B5FA;1104 1168 11AD;B5FA;1104 1168 11AD; +B5FB;B5FB;1104 1168 11AE;B5FB;1104 1168 11AE; +B5FC;B5FC;1104 1168 11AF;B5FC;1104 1168 11AF; +B5FD;B5FD;1104 1168 11B0;B5FD;1104 1168 11B0; +B5FE;B5FE;1104 1168 11B1;B5FE;1104 1168 11B1; +B5FF;B5FF;1104 1168 11B2;B5FF;1104 1168 11B2; +B600;B600;1104 1168 11B3;B600;1104 1168 11B3; +B601;B601;1104 1168 11B4;B601;1104 1168 11B4; +B602;B602;1104 1168 11B5;B602;1104 1168 11B5; +B603;B603;1104 1168 11B6;B603;1104 1168 11B6; +B604;B604;1104 1168 11B7;B604;1104 1168 11B7; +B605;B605;1104 1168 11B8;B605;1104 1168 11B8; +B606;B606;1104 1168 11B9;B606;1104 1168 11B9; +B607;B607;1104 1168 11BA;B607;1104 1168 11BA; +B608;B608;1104 1168 11BB;B608;1104 1168 11BB; +B609;B609;1104 1168 11BC;B609;1104 1168 11BC; +B60A;B60A;1104 1168 11BD;B60A;1104 1168 11BD; +B60B;B60B;1104 1168 11BE;B60B;1104 1168 11BE; +B60C;B60C;1104 1168 11BF;B60C;1104 1168 11BF; +B60D;B60D;1104 1168 11C0;B60D;1104 1168 11C0; +B60E;B60E;1104 1168 11C1;B60E;1104 1168 11C1; +B60F;B60F;1104 1168 11C2;B60F;1104 1168 11C2; +B610;B610;1104 1169;B610;1104 1169; +B611;B611;1104 1169 11A8;B611;1104 1169 11A8; +B612;B612;1104 1169 11A9;B612;1104 1169 11A9; +B613;B613;1104 1169 11AA;B613;1104 1169 11AA; +B614;B614;1104 1169 11AB;B614;1104 1169 11AB; +B615;B615;1104 1169 11AC;B615;1104 1169 11AC; +B616;B616;1104 1169 11AD;B616;1104 1169 11AD; +B617;B617;1104 1169 11AE;B617;1104 1169 11AE; +B618;B618;1104 1169 11AF;B618;1104 1169 11AF; +B619;B619;1104 1169 11B0;B619;1104 1169 11B0; +B61A;B61A;1104 1169 11B1;B61A;1104 1169 11B1; +B61B;B61B;1104 1169 11B2;B61B;1104 1169 11B2; +B61C;B61C;1104 1169 11B3;B61C;1104 1169 11B3; +B61D;B61D;1104 1169 11B4;B61D;1104 1169 11B4; +B61E;B61E;1104 1169 11B5;B61E;1104 1169 11B5; +B61F;B61F;1104 1169 11B6;B61F;1104 1169 11B6; +B620;B620;1104 1169 11B7;B620;1104 1169 11B7; +B621;B621;1104 1169 11B8;B621;1104 1169 11B8; +B622;B622;1104 1169 11B9;B622;1104 1169 11B9; +B623;B623;1104 1169 11BA;B623;1104 1169 11BA; +B624;B624;1104 1169 11BB;B624;1104 1169 11BB; +B625;B625;1104 1169 11BC;B625;1104 1169 11BC; +B626;B626;1104 1169 11BD;B626;1104 1169 11BD; +B627;B627;1104 1169 11BE;B627;1104 1169 11BE; +B628;B628;1104 1169 11BF;B628;1104 1169 11BF; +B629;B629;1104 1169 11C0;B629;1104 1169 11C0; +B62A;B62A;1104 1169 11C1;B62A;1104 1169 11C1; +B62B;B62B;1104 1169 11C2;B62B;1104 1169 11C2; +B62C;B62C;1104 116A;B62C;1104 116A; +B62D;B62D;1104 116A 11A8;B62D;1104 116A 11A8; +B62E;B62E;1104 116A 11A9;B62E;1104 116A 11A9; +B62F;B62F;1104 116A 11AA;B62F;1104 116A 11AA; +B630;B630;1104 116A 11AB;B630;1104 116A 11AB; +B631;B631;1104 116A 11AC;B631;1104 116A 11AC; +B632;B632;1104 116A 11AD;B632;1104 116A 11AD; +B633;B633;1104 116A 11AE;B633;1104 116A 11AE; +B634;B634;1104 116A 11AF;B634;1104 116A 11AF; +B635;B635;1104 116A 11B0;B635;1104 116A 11B0; +B636;B636;1104 116A 11B1;B636;1104 116A 11B1; +B637;B637;1104 116A 11B2;B637;1104 116A 11B2; +B638;B638;1104 116A 11B3;B638;1104 116A 11B3; +B639;B639;1104 116A 11B4;B639;1104 116A 11B4; +B63A;B63A;1104 116A 11B5;B63A;1104 116A 11B5; +B63B;B63B;1104 116A 11B6;B63B;1104 116A 11B6; +B63C;B63C;1104 116A 11B7;B63C;1104 116A 11B7; +B63D;B63D;1104 116A 11B8;B63D;1104 116A 11B8; +B63E;B63E;1104 116A 11B9;B63E;1104 116A 11B9; +B63F;B63F;1104 116A 11BA;B63F;1104 116A 11BA; +B640;B640;1104 116A 11BB;B640;1104 116A 11BB; +B641;B641;1104 116A 11BC;B641;1104 116A 11BC; +B642;B642;1104 116A 11BD;B642;1104 116A 11BD; +B643;B643;1104 116A 11BE;B643;1104 116A 11BE; +B644;B644;1104 116A 11BF;B644;1104 116A 11BF; +B645;B645;1104 116A 11C0;B645;1104 116A 11C0; +B646;B646;1104 116A 11C1;B646;1104 116A 11C1; +B647;B647;1104 116A 11C2;B647;1104 116A 11C2; +B648;B648;1104 116B;B648;1104 116B; +B649;B649;1104 116B 11A8;B649;1104 116B 11A8; +B64A;B64A;1104 116B 11A9;B64A;1104 116B 11A9; +B64B;B64B;1104 116B 11AA;B64B;1104 116B 11AA; +B64C;B64C;1104 116B 11AB;B64C;1104 116B 11AB; +B64D;B64D;1104 116B 11AC;B64D;1104 116B 11AC; +B64E;B64E;1104 116B 11AD;B64E;1104 116B 11AD; +B64F;B64F;1104 116B 11AE;B64F;1104 116B 11AE; +B650;B650;1104 116B 11AF;B650;1104 116B 11AF; +B651;B651;1104 116B 11B0;B651;1104 116B 11B0; +B652;B652;1104 116B 11B1;B652;1104 116B 11B1; +B653;B653;1104 116B 11B2;B653;1104 116B 11B2; +B654;B654;1104 116B 11B3;B654;1104 116B 11B3; +B655;B655;1104 116B 11B4;B655;1104 116B 11B4; +B656;B656;1104 116B 11B5;B656;1104 116B 11B5; +B657;B657;1104 116B 11B6;B657;1104 116B 11B6; +B658;B658;1104 116B 11B7;B658;1104 116B 11B7; +B659;B659;1104 116B 11B8;B659;1104 116B 11B8; +B65A;B65A;1104 116B 11B9;B65A;1104 116B 11B9; +B65B;B65B;1104 116B 11BA;B65B;1104 116B 11BA; +B65C;B65C;1104 116B 11BB;B65C;1104 116B 11BB; +B65D;B65D;1104 116B 11BC;B65D;1104 116B 11BC; +B65E;B65E;1104 116B 11BD;B65E;1104 116B 11BD; +B65F;B65F;1104 116B 11BE;B65F;1104 116B 11BE; +B660;B660;1104 116B 11BF;B660;1104 116B 11BF; +B661;B661;1104 116B 11C0;B661;1104 116B 11C0; +B662;B662;1104 116B 11C1;B662;1104 116B 11C1; +B663;B663;1104 116B 11C2;B663;1104 116B 11C2; +B664;B664;1104 116C;B664;1104 116C; +B665;B665;1104 116C 11A8;B665;1104 116C 11A8; +B666;B666;1104 116C 11A9;B666;1104 116C 11A9; +B667;B667;1104 116C 11AA;B667;1104 116C 11AA; +B668;B668;1104 116C 11AB;B668;1104 116C 11AB; +B669;B669;1104 116C 11AC;B669;1104 116C 11AC; +B66A;B66A;1104 116C 11AD;B66A;1104 116C 11AD; +B66B;B66B;1104 116C 11AE;B66B;1104 116C 11AE; +B66C;B66C;1104 116C 11AF;B66C;1104 116C 11AF; +B66D;B66D;1104 116C 11B0;B66D;1104 116C 11B0; +B66E;B66E;1104 116C 11B1;B66E;1104 116C 11B1; +B66F;B66F;1104 116C 11B2;B66F;1104 116C 11B2; +B670;B670;1104 116C 11B3;B670;1104 116C 11B3; +B671;B671;1104 116C 11B4;B671;1104 116C 11B4; +B672;B672;1104 116C 11B5;B672;1104 116C 11B5; +B673;B673;1104 116C 11B6;B673;1104 116C 11B6; +B674;B674;1104 116C 11B7;B674;1104 116C 11B7; +B675;B675;1104 116C 11B8;B675;1104 116C 11B8; +B676;B676;1104 116C 11B9;B676;1104 116C 11B9; +B677;B677;1104 116C 11BA;B677;1104 116C 11BA; +B678;B678;1104 116C 11BB;B678;1104 116C 11BB; +B679;B679;1104 116C 11BC;B679;1104 116C 11BC; +B67A;B67A;1104 116C 11BD;B67A;1104 116C 11BD; +B67B;B67B;1104 116C 11BE;B67B;1104 116C 11BE; +B67C;B67C;1104 116C 11BF;B67C;1104 116C 11BF; +B67D;B67D;1104 116C 11C0;B67D;1104 116C 11C0; +B67E;B67E;1104 116C 11C1;B67E;1104 116C 11C1; +B67F;B67F;1104 116C 11C2;B67F;1104 116C 11C2; +B680;B680;1104 116D;B680;1104 116D; +B681;B681;1104 116D 11A8;B681;1104 116D 11A8; +B682;B682;1104 116D 11A9;B682;1104 116D 11A9; +B683;B683;1104 116D 11AA;B683;1104 116D 11AA; +B684;B684;1104 116D 11AB;B684;1104 116D 11AB; +B685;B685;1104 116D 11AC;B685;1104 116D 11AC; +B686;B686;1104 116D 11AD;B686;1104 116D 11AD; +B687;B687;1104 116D 11AE;B687;1104 116D 11AE; +B688;B688;1104 116D 11AF;B688;1104 116D 11AF; +B689;B689;1104 116D 11B0;B689;1104 116D 11B0; +B68A;B68A;1104 116D 11B1;B68A;1104 116D 11B1; +B68B;B68B;1104 116D 11B2;B68B;1104 116D 11B2; +B68C;B68C;1104 116D 11B3;B68C;1104 116D 11B3; +B68D;B68D;1104 116D 11B4;B68D;1104 116D 11B4; +B68E;B68E;1104 116D 11B5;B68E;1104 116D 11B5; +B68F;B68F;1104 116D 11B6;B68F;1104 116D 11B6; +B690;B690;1104 116D 11B7;B690;1104 116D 11B7; +B691;B691;1104 116D 11B8;B691;1104 116D 11B8; +B692;B692;1104 116D 11B9;B692;1104 116D 11B9; +B693;B693;1104 116D 11BA;B693;1104 116D 11BA; +B694;B694;1104 116D 11BB;B694;1104 116D 11BB; +B695;B695;1104 116D 11BC;B695;1104 116D 11BC; +B696;B696;1104 116D 11BD;B696;1104 116D 11BD; +B697;B697;1104 116D 11BE;B697;1104 116D 11BE; +B698;B698;1104 116D 11BF;B698;1104 116D 11BF; +B699;B699;1104 116D 11C0;B699;1104 116D 11C0; +B69A;B69A;1104 116D 11C1;B69A;1104 116D 11C1; +B69B;B69B;1104 116D 11C2;B69B;1104 116D 11C2; +B69C;B69C;1104 116E;B69C;1104 116E; +B69D;B69D;1104 116E 11A8;B69D;1104 116E 11A8; +B69E;B69E;1104 116E 11A9;B69E;1104 116E 11A9; +B69F;B69F;1104 116E 11AA;B69F;1104 116E 11AA; +B6A0;B6A0;1104 116E 11AB;B6A0;1104 116E 11AB; +B6A1;B6A1;1104 116E 11AC;B6A1;1104 116E 11AC; +B6A2;B6A2;1104 116E 11AD;B6A2;1104 116E 11AD; +B6A3;B6A3;1104 116E 11AE;B6A3;1104 116E 11AE; +B6A4;B6A4;1104 116E 11AF;B6A4;1104 116E 11AF; +B6A5;B6A5;1104 116E 11B0;B6A5;1104 116E 11B0; +B6A6;B6A6;1104 116E 11B1;B6A6;1104 116E 11B1; +B6A7;B6A7;1104 116E 11B2;B6A7;1104 116E 11B2; +B6A8;B6A8;1104 116E 11B3;B6A8;1104 116E 11B3; +B6A9;B6A9;1104 116E 11B4;B6A9;1104 116E 11B4; +B6AA;B6AA;1104 116E 11B5;B6AA;1104 116E 11B5; +B6AB;B6AB;1104 116E 11B6;B6AB;1104 116E 11B6; +B6AC;B6AC;1104 116E 11B7;B6AC;1104 116E 11B7; +B6AD;B6AD;1104 116E 11B8;B6AD;1104 116E 11B8; +B6AE;B6AE;1104 116E 11B9;B6AE;1104 116E 11B9; +B6AF;B6AF;1104 116E 11BA;B6AF;1104 116E 11BA; +B6B0;B6B0;1104 116E 11BB;B6B0;1104 116E 11BB; +B6B1;B6B1;1104 116E 11BC;B6B1;1104 116E 11BC; +B6B2;B6B2;1104 116E 11BD;B6B2;1104 116E 11BD; +B6B3;B6B3;1104 116E 11BE;B6B3;1104 116E 11BE; +B6B4;B6B4;1104 116E 11BF;B6B4;1104 116E 11BF; +B6B5;B6B5;1104 116E 11C0;B6B5;1104 116E 11C0; +B6B6;B6B6;1104 116E 11C1;B6B6;1104 116E 11C1; +B6B7;B6B7;1104 116E 11C2;B6B7;1104 116E 11C2; +B6B8;B6B8;1104 116F;B6B8;1104 116F; +B6B9;B6B9;1104 116F 11A8;B6B9;1104 116F 11A8; +B6BA;B6BA;1104 116F 11A9;B6BA;1104 116F 11A9; +B6BB;B6BB;1104 116F 11AA;B6BB;1104 116F 11AA; +B6BC;B6BC;1104 116F 11AB;B6BC;1104 116F 11AB; +B6BD;B6BD;1104 116F 11AC;B6BD;1104 116F 11AC; +B6BE;B6BE;1104 116F 11AD;B6BE;1104 116F 11AD; +B6BF;B6BF;1104 116F 11AE;B6BF;1104 116F 11AE; +B6C0;B6C0;1104 116F 11AF;B6C0;1104 116F 11AF; +B6C1;B6C1;1104 116F 11B0;B6C1;1104 116F 11B0; +B6C2;B6C2;1104 116F 11B1;B6C2;1104 116F 11B1; +B6C3;B6C3;1104 116F 11B2;B6C3;1104 116F 11B2; +B6C4;B6C4;1104 116F 11B3;B6C4;1104 116F 11B3; +B6C5;B6C5;1104 116F 11B4;B6C5;1104 116F 11B4; +B6C6;B6C6;1104 116F 11B5;B6C6;1104 116F 11B5; +B6C7;B6C7;1104 116F 11B6;B6C7;1104 116F 11B6; +B6C8;B6C8;1104 116F 11B7;B6C8;1104 116F 11B7; +B6C9;B6C9;1104 116F 11B8;B6C9;1104 116F 11B8; +B6CA;B6CA;1104 116F 11B9;B6CA;1104 116F 11B9; +B6CB;B6CB;1104 116F 11BA;B6CB;1104 116F 11BA; +B6CC;B6CC;1104 116F 11BB;B6CC;1104 116F 11BB; +B6CD;B6CD;1104 116F 11BC;B6CD;1104 116F 11BC; +B6CE;B6CE;1104 116F 11BD;B6CE;1104 116F 11BD; +B6CF;B6CF;1104 116F 11BE;B6CF;1104 116F 11BE; +B6D0;B6D0;1104 116F 11BF;B6D0;1104 116F 11BF; +B6D1;B6D1;1104 116F 11C0;B6D1;1104 116F 11C0; +B6D2;B6D2;1104 116F 11C1;B6D2;1104 116F 11C1; +B6D3;B6D3;1104 116F 11C2;B6D3;1104 116F 11C2; +B6D4;B6D4;1104 1170;B6D4;1104 1170; +B6D5;B6D5;1104 1170 11A8;B6D5;1104 1170 11A8; +B6D6;B6D6;1104 1170 11A9;B6D6;1104 1170 11A9; +B6D7;B6D7;1104 1170 11AA;B6D7;1104 1170 11AA; +B6D8;B6D8;1104 1170 11AB;B6D8;1104 1170 11AB; +B6D9;B6D9;1104 1170 11AC;B6D9;1104 1170 11AC; +B6DA;B6DA;1104 1170 11AD;B6DA;1104 1170 11AD; +B6DB;B6DB;1104 1170 11AE;B6DB;1104 1170 11AE; +B6DC;B6DC;1104 1170 11AF;B6DC;1104 1170 11AF; +B6DD;B6DD;1104 1170 11B0;B6DD;1104 1170 11B0; +B6DE;B6DE;1104 1170 11B1;B6DE;1104 1170 11B1; +B6DF;B6DF;1104 1170 11B2;B6DF;1104 1170 11B2; +B6E0;B6E0;1104 1170 11B3;B6E0;1104 1170 11B3; +B6E1;B6E1;1104 1170 11B4;B6E1;1104 1170 11B4; +B6E2;B6E2;1104 1170 11B5;B6E2;1104 1170 11B5; +B6E3;B6E3;1104 1170 11B6;B6E3;1104 1170 11B6; +B6E4;B6E4;1104 1170 11B7;B6E4;1104 1170 11B7; +B6E5;B6E5;1104 1170 11B8;B6E5;1104 1170 11B8; +B6E6;B6E6;1104 1170 11B9;B6E6;1104 1170 11B9; +B6E7;B6E7;1104 1170 11BA;B6E7;1104 1170 11BA; +B6E8;B6E8;1104 1170 11BB;B6E8;1104 1170 11BB; +B6E9;B6E9;1104 1170 11BC;B6E9;1104 1170 11BC; +B6EA;B6EA;1104 1170 11BD;B6EA;1104 1170 11BD; +B6EB;B6EB;1104 1170 11BE;B6EB;1104 1170 11BE; +B6EC;B6EC;1104 1170 11BF;B6EC;1104 1170 11BF; +B6ED;B6ED;1104 1170 11C0;B6ED;1104 1170 11C0; +B6EE;B6EE;1104 1170 11C1;B6EE;1104 1170 11C1; +B6EF;B6EF;1104 1170 11C2;B6EF;1104 1170 11C2; +B6F0;B6F0;1104 1171;B6F0;1104 1171; +B6F1;B6F1;1104 1171 11A8;B6F1;1104 1171 11A8; +B6F2;B6F2;1104 1171 11A9;B6F2;1104 1171 11A9; +B6F3;B6F3;1104 1171 11AA;B6F3;1104 1171 11AA; +B6F4;B6F4;1104 1171 11AB;B6F4;1104 1171 11AB; +B6F5;B6F5;1104 1171 11AC;B6F5;1104 1171 11AC; +B6F6;B6F6;1104 1171 11AD;B6F6;1104 1171 11AD; +B6F7;B6F7;1104 1171 11AE;B6F7;1104 1171 11AE; +B6F8;B6F8;1104 1171 11AF;B6F8;1104 1171 11AF; +B6F9;B6F9;1104 1171 11B0;B6F9;1104 1171 11B0; +B6FA;B6FA;1104 1171 11B1;B6FA;1104 1171 11B1; +B6FB;B6FB;1104 1171 11B2;B6FB;1104 1171 11B2; +B6FC;B6FC;1104 1171 11B3;B6FC;1104 1171 11B3; +B6FD;B6FD;1104 1171 11B4;B6FD;1104 1171 11B4; +B6FE;B6FE;1104 1171 11B5;B6FE;1104 1171 11B5; +B6FF;B6FF;1104 1171 11B6;B6FF;1104 1171 11B6; +B700;B700;1104 1171 11B7;B700;1104 1171 11B7; +B701;B701;1104 1171 11B8;B701;1104 1171 11B8; +B702;B702;1104 1171 11B9;B702;1104 1171 11B9; +B703;B703;1104 1171 11BA;B703;1104 1171 11BA; +B704;B704;1104 1171 11BB;B704;1104 1171 11BB; +B705;B705;1104 1171 11BC;B705;1104 1171 11BC; +B706;B706;1104 1171 11BD;B706;1104 1171 11BD; +B707;B707;1104 1171 11BE;B707;1104 1171 11BE; +B708;B708;1104 1171 11BF;B708;1104 1171 11BF; +B709;B709;1104 1171 11C0;B709;1104 1171 11C0; +B70A;B70A;1104 1171 11C1;B70A;1104 1171 11C1; +B70B;B70B;1104 1171 11C2;B70B;1104 1171 11C2; +B70C;B70C;1104 1172;B70C;1104 1172; +B70D;B70D;1104 1172 11A8;B70D;1104 1172 11A8; +B70E;B70E;1104 1172 11A9;B70E;1104 1172 11A9; +B70F;B70F;1104 1172 11AA;B70F;1104 1172 11AA; +B710;B710;1104 1172 11AB;B710;1104 1172 11AB; +B711;B711;1104 1172 11AC;B711;1104 1172 11AC; +B712;B712;1104 1172 11AD;B712;1104 1172 11AD; +B713;B713;1104 1172 11AE;B713;1104 1172 11AE; +B714;B714;1104 1172 11AF;B714;1104 1172 11AF; +B715;B715;1104 1172 11B0;B715;1104 1172 11B0; +B716;B716;1104 1172 11B1;B716;1104 1172 11B1; +B717;B717;1104 1172 11B2;B717;1104 1172 11B2; +B718;B718;1104 1172 11B3;B718;1104 1172 11B3; +B719;B719;1104 1172 11B4;B719;1104 1172 11B4; +B71A;B71A;1104 1172 11B5;B71A;1104 1172 11B5; +B71B;B71B;1104 1172 11B6;B71B;1104 1172 11B6; +B71C;B71C;1104 1172 11B7;B71C;1104 1172 11B7; +B71D;B71D;1104 1172 11B8;B71D;1104 1172 11B8; +B71E;B71E;1104 1172 11B9;B71E;1104 1172 11B9; +B71F;B71F;1104 1172 11BA;B71F;1104 1172 11BA; +B720;B720;1104 1172 11BB;B720;1104 1172 11BB; +B721;B721;1104 1172 11BC;B721;1104 1172 11BC; +B722;B722;1104 1172 11BD;B722;1104 1172 11BD; +B723;B723;1104 1172 11BE;B723;1104 1172 11BE; +B724;B724;1104 1172 11BF;B724;1104 1172 11BF; +B725;B725;1104 1172 11C0;B725;1104 1172 11C0; +B726;B726;1104 1172 11C1;B726;1104 1172 11C1; +B727;B727;1104 1172 11C2;B727;1104 1172 11C2; +B728;B728;1104 1173;B728;1104 1173; +B729;B729;1104 1173 11A8;B729;1104 1173 11A8; +B72A;B72A;1104 1173 11A9;B72A;1104 1173 11A9; +B72B;B72B;1104 1173 11AA;B72B;1104 1173 11AA; +B72C;B72C;1104 1173 11AB;B72C;1104 1173 11AB; +B72D;B72D;1104 1173 11AC;B72D;1104 1173 11AC; +B72E;B72E;1104 1173 11AD;B72E;1104 1173 11AD; +B72F;B72F;1104 1173 11AE;B72F;1104 1173 11AE; +B730;B730;1104 1173 11AF;B730;1104 1173 11AF; +B731;B731;1104 1173 11B0;B731;1104 1173 11B0; +B732;B732;1104 1173 11B1;B732;1104 1173 11B1; +B733;B733;1104 1173 11B2;B733;1104 1173 11B2; +B734;B734;1104 1173 11B3;B734;1104 1173 11B3; +B735;B735;1104 1173 11B4;B735;1104 1173 11B4; +B736;B736;1104 1173 11B5;B736;1104 1173 11B5; +B737;B737;1104 1173 11B6;B737;1104 1173 11B6; +B738;B738;1104 1173 11B7;B738;1104 1173 11B7; +B739;B739;1104 1173 11B8;B739;1104 1173 11B8; +B73A;B73A;1104 1173 11B9;B73A;1104 1173 11B9; +B73B;B73B;1104 1173 11BA;B73B;1104 1173 11BA; +B73C;B73C;1104 1173 11BB;B73C;1104 1173 11BB; +B73D;B73D;1104 1173 11BC;B73D;1104 1173 11BC; +B73E;B73E;1104 1173 11BD;B73E;1104 1173 11BD; +B73F;B73F;1104 1173 11BE;B73F;1104 1173 11BE; +B740;B740;1104 1173 11BF;B740;1104 1173 11BF; +B741;B741;1104 1173 11C0;B741;1104 1173 11C0; +B742;B742;1104 1173 11C1;B742;1104 1173 11C1; +B743;B743;1104 1173 11C2;B743;1104 1173 11C2; +B744;B744;1104 1174;B744;1104 1174; +B745;B745;1104 1174 11A8;B745;1104 1174 11A8; +B746;B746;1104 1174 11A9;B746;1104 1174 11A9; +B747;B747;1104 1174 11AA;B747;1104 1174 11AA; +B748;B748;1104 1174 11AB;B748;1104 1174 11AB; +B749;B749;1104 1174 11AC;B749;1104 1174 11AC; +B74A;B74A;1104 1174 11AD;B74A;1104 1174 11AD; +B74B;B74B;1104 1174 11AE;B74B;1104 1174 11AE; +B74C;B74C;1104 1174 11AF;B74C;1104 1174 11AF; +B74D;B74D;1104 1174 11B0;B74D;1104 1174 11B0; +B74E;B74E;1104 1174 11B1;B74E;1104 1174 11B1; +B74F;B74F;1104 1174 11B2;B74F;1104 1174 11B2; +B750;B750;1104 1174 11B3;B750;1104 1174 11B3; +B751;B751;1104 1174 11B4;B751;1104 1174 11B4; +B752;B752;1104 1174 11B5;B752;1104 1174 11B5; +B753;B753;1104 1174 11B6;B753;1104 1174 11B6; +B754;B754;1104 1174 11B7;B754;1104 1174 11B7; +B755;B755;1104 1174 11B8;B755;1104 1174 11B8; +B756;B756;1104 1174 11B9;B756;1104 1174 11B9; +B757;B757;1104 1174 11BA;B757;1104 1174 11BA; +B758;B758;1104 1174 11BB;B758;1104 1174 11BB; +B759;B759;1104 1174 11BC;B759;1104 1174 11BC; +B75A;B75A;1104 1174 11BD;B75A;1104 1174 11BD; +B75B;B75B;1104 1174 11BE;B75B;1104 1174 11BE; +B75C;B75C;1104 1174 11BF;B75C;1104 1174 11BF; +B75D;B75D;1104 1174 11C0;B75D;1104 1174 11C0; +B75E;B75E;1104 1174 11C1;B75E;1104 1174 11C1; +B75F;B75F;1104 1174 11C2;B75F;1104 1174 11C2; +B760;B760;1104 1175;B760;1104 1175; +B761;B761;1104 1175 11A8;B761;1104 1175 11A8; +B762;B762;1104 1175 11A9;B762;1104 1175 11A9; +B763;B763;1104 1175 11AA;B763;1104 1175 11AA; +B764;B764;1104 1175 11AB;B764;1104 1175 11AB; +B765;B765;1104 1175 11AC;B765;1104 1175 11AC; +B766;B766;1104 1175 11AD;B766;1104 1175 11AD; +B767;B767;1104 1175 11AE;B767;1104 1175 11AE; +B768;B768;1104 1175 11AF;B768;1104 1175 11AF; +B769;B769;1104 1175 11B0;B769;1104 1175 11B0; +B76A;B76A;1104 1175 11B1;B76A;1104 1175 11B1; +B76B;B76B;1104 1175 11B2;B76B;1104 1175 11B2; +B76C;B76C;1104 1175 11B3;B76C;1104 1175 11B3; +B76D;B76D;1104 1175 11B4;B76D;1104 1175 11B4; +B76E;B76E;1104 1175 11B5;B76E;1104 1175 11B5; +B76F;B76F;1104 1175 11B6;B76F;1104 1175 11B6; +B770;B770;1104 1175 11B7;B770;1104 1175 11B7; +B771;B771;1104 1175 11B8;B771;1104 1175 11B8; +B772;B772;1104 1175 11B9;B772;1104 1175 11B9; +B773;B773;1104 1175 11BA;B773;1104 1175 11BA; +B774;B774;1104 1175 11BB;B774;1104 1175 11BB; +B775;B775;1104 1175 11BC;B775;1104 1175 11BC; +B776;B776;1104 1175 11BD;B776;1104 1175 11BD; +B777;B777;1104 1175 11BE;B777;1104 1175 11BE; +B778;B778;1104 1175 11BF;B778;1104 1175 11BF; +B779;B779;1104 1175 11C0;B779;1104 1175 11C0; +B77A;B77A;1104 1175 11C1;B77A;1104 1175 11C1; +B77B;B77B;1104 1175 11C2;B77B;1104 1175 11C2; +B77C;B77C;1105 1161;B77C;1105 1161; +B77D;B77D;1105 1161 11A8;B77D;1105 1161 11A8; +B77E;B77E;1105 1161 11A9;B77E;1105 1161 11A9; +B77F;B77F;1105 1161 11AA;B77F;1105 1161 11AA; +B780;B780;1105 1161 11AB;B780;1105 1161 11AB; +B781;B781;1105 1161 11AC;B781;1105 1161 11AC; +B782;B782;1105 1161 11AD;B782;1105 1161 11AD; +B783;B783;1105 1161 11AE;B783;1105 1161 11AE; +B784;B784;1105 1161 11AF;B784;1105 1161 11AF; +B785;B785;1105 1161 11B0;B785;1105 1161 11B0; +B786;B786;1105 1161 11B1;B786;1105 1161 11B1; +B787;B787;1105 1161 11B2;B787;1105 1161 11B2; +B788;B788;1105 1161 11B3;B788;1105 1161 11B3; +B789;B789;1105 1161 11B4;B789;1105 1161 11B4; +B78A;B78A;1105 1161 11B5;B78A;1105 1161 11B5; +B78B;B78B;1105 1161 11B6;B78B;1105 1161 11B6; +B78C;B78C;1105 1161 11B7;B78C;1105 1161 11B7; +B78D;B78D;1105 1161 11B8;B78D;1105 1161 11B8; +B78E;B78E;1105 1161 11B9;B78E;1105 1161 11B9; +B78F;B78F;1105 1161 11BA;B78F;1105 1161 11BA; +B790;B790;1105 1161 11BB;B790;1105 1161 11BB; +B791;B791;1105 1161 11BC;B791;1105 1161 11BC; +B792;B792;1105 1161 11BD;B792;1105 1161 11BD; +B793;B793;1105 1161 11BE;B793;1105 1161 11BE; +B794;B794;1105 1161 11BF;B794;1105 1161 11BF; +B795;B795;1105 1161 11C0;B795;1105 1161 11C0; +B796;B796;1105 1161 11C1;B796;1105 1161 11C1; +B797;B797;1105 1161 11C2;B797;1105 1161 11C2; +B798;B798;1105 1162;B798;1105 1162; +B799;B799;1105 1162 11A8;B799;1105 1162 11A8; +B79A;B79A;1105 1162 11A9;B79A;1105 1162 11A9; +B79B;B79B;1105 1162 11AA;B79B;1105 1162 11AA; +B79C;B79C;1105 1162 11AB;B79C;1105 1162 11AB; +B79D;B79D;1105 1162 11AC;B79D;1105 1162 11AC; +B79E;B79E;1105 1162 11AD;B79E;1105 1162 11AD; +B79F;B79F;1105 1162 11AE;B79F;1105 1162 11AE; +B7A0;B7A0;1105 1162 11AF;B7A0;1105 1162 11AF; +B7A1;B7A1;1105 1162 11B0;B7A1;1105 1162 11B0; +B7A2;B7A2;1105 1162 11B1;B7A2;1105 1162 11B1; +B7A3;B7A3;1105 1162 11B2;B7A3;1105 1162 11B2; +B7A4;B7A4;1105 1162 11B3;B7A4;1105 1162 11B3; +B7A5;B7A5;1105 1162 11B4;B7A5;1105 1162 11B4; +B7A6;B7A6;1105 1162 11B5;B7A6;1105 1162 11B5; +B7A7;B7A7;1105 1162 11B6;B7A7;1105 1162 11B6; +B7A8;B7A8;1105 1162 11B7;B7A8;1105 1162 11B7; +B7A9;B7A9;1105 1162 11B8;B7A9;1105 1162 11B8; +B7AA;B7AA;1105 1162 11B9;B7AA;1105 1162 11B9; +B7AB;B7AB;1105 1162 11BA;B7AB;1105 1162 11BA; +B7AC;B7AC;1105 1162 11BB;B7AC;1105 1162 11BB; +B7AD;B7AD;1105 1162 11BC;B7AD;1105 1162 11BC; +B7AE;B7AE;1105 1162 11BD;B7AE;1105 1162 11BD; +B7AF;B7AF;1105 1162 11BE;B7AF;1105 1162 11BE; +B7B0;B7B0;1105 1162 11BF;B7B0;1105 1162 11BF; +B7B1;B7B1;1105 1162 11C0;B7B1;1105 1162 11C0; +B7B2;B7B2;1105 1162 11C1;B7B2;1105 1162 11C1; +B7B3;B7B3;1105 1162 11C2;B7B3;1105 1162 11C2; +B7B4;B7B4;1105 1163;B7B4;1105 1163; +B7B5;B7B5;1105 1163 11A8;B7B5;1105 1163 11A8; +B7B6;B7B6;1105 1163 11A9;B7B6;1105 1163 11A9; +B7B7;B7B7;1105 1163 11AA;B7B7;1105 1163 11AA; +B7B8;B7B8;1105 1163 11AB;B7B8;1105 1163 11AB; +B7B9;B7B9;1105 1163 11AC;B7B9;1105 1163 11AC; +B7BA;B7BA;1105 1163 11AD;B7BA;1105 1163 11AD; +B7BB;B7BB;1105 1163 11AE;B7BB;1105 1163 11AE; +B7BC;B7BC;1105 1163 11AF;B7BC;1105 1163 11AF; +B7BD;B7BD;1105 1163 11B0;B7BD;1105 1163 11B0; +B7BE;B7BE;1105 1163 11B1;B7BE;1105 1163 11B1; +B7BF;B7BF;1105 1163 11B2;B7BF;1105 1163 11B2; +B7C0;B7C0;1105 1163 11B3;B7C0;1105 1163 11B3; +B7C1;B7C1;1105 1163 11B4;B7C1;1105 1163 11B4; +B7C2;B7C2;1105 1163 11B5;B7C2;1105 1163 11B5; +B7C3;B7C3;1105 1163 11B6;B7C3;1105 1163 11B6; +B7C4;B7C4;1105 1163 11B7;B7C4;1105 1163 11B7; +B7C5;B7C5;1105 1163 11B8;B7C5;1105 1163 11B8; +B7C6;B7C6;1105 1163 11B9;B7C6;1105 1163 11B9; +B7C7;B7C7;1105 1163 11BA;B7C7;1105 1163 11BA; +B7C8;B7C8;1105 1163 11BB;B7C8;1105 1163 11BB; +B7C9;B7C9;1105 1163 11BC;B7C9;1105 1163 11BC; +B7CA;B7CA;1105 1163 11BD;B7CA;1105 1163 11BD; +B7CB;B7CB;1105 1163 11BE;B7CB;1105 1163 11BE; +B7CC;B7CC;1105 1163 11BF;B7CC;1105 1163 11BF; +B7CD;B7CD;1105 1163 11C0;B7CD;1105 1163 11C0; +B7CE;B7CE;1105 1163 11C1;B7CE;1105 1163 11C1; +B7CF;B7CF;1105 1163 11C2;B7CF;1105 1163 11C2; +B7D0;B7D0;1105 1164;B7D0;1105 1164; +B7D1;B7D1;1105 1164 11A8;B7D1;1105 1164 11A8; +B7D2;B7D2;1105 1164 11A9;B7D2;1105 1164 11A9; +B7D3;B7D3;1105 1164 11AA;B7D3;1105 1164 11AA; +B7D4;B7D4;1105 1164 11AB;B7D4;1105 1164 11AB; +B7D5;B7D5;1105 1164 11AC;B7D5;1105 1164 11AC; +B7D6;B7D6;1105 1164 11AD;B7D6;1105 1164 11AD; +B7D7;B7D7;1105 1164 11AE;B7D7;1105 1164 11AE; +B7D8;B7D8;1105 1164 11AF;B7D8;1105 1164 11AF; +B7D9;B7D9;1105 1164 11B0;B7D9;1105 1164 11B0; +B7DA;B7DA;1105 1164 11B1;B7DA;1105 1164 11B1; +B7DB;B7DB;1105 1164 11B2;B7DB;1105 1164 11B2; +B7DC;B7DC;1105 1164 11B3;B7DC;1105 1164 11B3; +B7DD;B7DD;1105 1164 11B4;B7DD;1105 1164 11B4; +B7DE;B7DE;1105 1164 11B5;B7DE;1105 1164 11B5; +B7DF;B7DF;1105 1164 11B6;B7DF;1105 1164 11B6; +B7E0;B7E0;1105 1164 11B7;B7E0;1105 1164 11B7; +B7E1;B7E1;1105 1164 11B8;B7E1;1105 1164 11B8; +B7E2;B7E2;1105 1164 11B9;B7E2;1105 1164 11B9; +B7E3;B7E3;1105 1164 11BA;B7E3;1105 1164 11BA; +B7E4;B7E4;1105 1164 11BB;B7E4;1105 1164 11BB; +B7E5;B7E5;1105 1164 11BC;B7E5;1105 1164 11BC; +B7E6;B7E6;1105 1164 11BD;B7E6;1105 1164 11BD; +B7E7;B7E7;1105 1164 11BE;B7E7;1105 1164 11BE; +B7E8;B7E8;1105 1164 11BF;B7E8;1105 1164 11BF; +B7E9;B7E9;1105 1164 11C0;B7E9;1105 1164 11C0; +B7EA;B7EA;1105 1164 11C1;B7EA;1105 1164 11C1; +B7EB;B7EB;1105 1164 11C2;B7EB;1105 1164 11C2; +B7EC;B7EC;1105 1165;B7EC;1105 1165; +B7ED;B7ED;1105 1165 11A8;B7ED;1105 1165 11A8; +B7EE;B7EE;1105 1165 11A9;B7EE;1105 1165 11A9; +B7EF;B7EF;1105 1165 11AA;B7EF;1105 1165 11AA; +B7F0;B7F0;1105 1165 11AB;B7F0;1105 1165 11AB; +B7F1;B7F1;1105 1165 11AC;B7F1;1105 1165 11AC; +B7F2;B7F2;1105 1165 11AD;B7F2;1105 1165 11AD; +B7F3;B7F3;1105 1165 11AE;B7F3;1105 1165 11AE; +B7F4;B7F4;1105 1165 11AF;B7F4;1105 1165 11AF; +B7F5;B7F5;1105 1165 11B0;B7F5;1105 1165 11B0; +B7F6;B7F6;1105 1165 11B1;B7F6;1105 1165 11B1; +B7F7;B7F7;1105 1165 11B2;B7F7;1105 1165 11B2; +B7F8;B7F8;1105 1165 11B3;B7F8;1105 1165 11B3; +B7F9;B7F9;1105 1165 11B4;B7F9;1105 1165 11B4; +B7FA;B7FA;1105 1165 11B5;B7FA;1105 1165 11B5; +B7FB;B7FB;1105 1165 11B6;B7FB;1105 1165 11B6; +B7FC;B7FC;1105 1165 11B7;B7FC;1105 1165 11B7; +B7FD;B7FD;1105 1165 11B8;B7FD;1105 1165 11B8; +B7FE;B7FE;1105 1165 11B9;B7FE;1105 1165 11B9; +B7FF;B7FF;1105 1165 11BA;B7FF;1105 1165 11BA; +B800;B800;1105 1165 11BB;B800;1105 1165 11BB; +B801;B801;1105 1165 11BC;B801;1105 1165 11BC; +B802;B802;1105 1165 11BD;B802;1105 1165 11BD; +B803;B803;1105 1165 11BE;B803;1105 1165 11BE; +B804;B804;1105 1165 11BF;B804;1105 1165 11BF; +B805;B805;1105 1165 11C0;B805;1105 1165 11C0; +B806;B806;1105 1165 11C1;B806;1105 1165 11C1; +B807;B807;1105 1165 11C2;B807;1105 1165 11C2; +B808;B808;1105 1166;B808;1105 1166; +B809;B809;1105 1166 11A8;B809;1105 1166 11A8; +B80A;B80A;1105 1166 11A9;B80A;1105 1166 11A9; +B80B;B80B;1105 1166 11AA;B80B;1105 1166 11AA; +B80C;B80C;1105 1166 11AB;B80C;1105 1166 11AB; +B80D;B80D;1105 1166 11AC;B80D;1105 1166 11AC; +B80E;B80E;1105 1166 11AD;B80E;1105 1166 11AD; +B80F;B80F;1105 1166 11AE;B80F;1105 1166 11AE; +B810;B810;1105 1166 11AF;B810;1105 1166 11AF; +B811;B811;1105 1166 11B0;B811;1105 1166 11B0; +B812;B812;1105 1166 11B1;B812;1105 1166 11B1; +B813;B813;1105 1166 11B2;B813;1105 1166 11B2; +B814;B814;1105 1166 11B3;B814;1105 1166 11B3; +B815;B815;1105 1166 11B4;B815;1105 1166 11B4; +B816;B816;1105 1166 11B5;B816;1105 1166 11B5; +B817;B817;1105 1166 11B6;B817;1105 1166 11B6; +B818;B818;1105 1166 11B7;B818;1105 1166 11B7; +B819;B819;1105 1166 11B8;B819;1105 1166 11B8; +B81A;B81A;1105 1166 11B9;B81A;1105 1166 11B9; +B81B;B81B;1105 1166 11BA;B81B;1105 1166 11BA; +B81C;B81C;1105 1166 11BB;B81C;1105 1166 11BB; +B81D;B81D;1105 1166 11BC;B81D;1105 1166 11BC; +B81E;B81E;1105 1166 11BD;B81E;1105 1166 11BD; +B81F;B81F;1105 1166 11BE;B81F;1105 1166 11BE; +B820;B820;1105 1166 11BF;B820;1105 1166 11BF; +B821;B821;1105 1166 11C0;B821;1105 1166 11C0; +B822;B822;1105 1166 11C1;B822;1105 1166 11C1; +B823;B823;1105 1166 11C2;B823;1105 1166 11C2; +B824;B824;1105 1167;B824;1105 1167; +B825;B825;1105 1167 11A8;B825;1105 1167 11A8; +B826;B826;1105 1167 11A9;B826;1105 1167 11A9; +B827;B827;1105 1167 11AA;B827;1105 1167 11AA; +B828;B828;1105 1167 11AB;B828;1105 1167 11AB; +B829;B829;1105 1167 11AC;B829;1105 1167 11AC; +B82A;B82A;1105 1167 11AD;B82A;1105 1167 11AD; +B82B;B82B;1105 1167 11AE;B82B;1105 1167 11AE; +B82C;B82C;1105 1167 11AF;B82C;1105 1167 11AF; +B82D;B82D;1105 1167 11B0;B82D;1105 1167 11B0; +B82E;B82E;1105 1167 11B1;B82E;1105 1167 11B1; +B82F;B82F;1105 1167 11B2;B82F;1105 1167 11B2; +B830;B830;1105 1167 11B3;B830;1105 1167 11B3; +B831;B831;1105 1167 11B4;B831;1105 1167 11B4; +B832;B832;1105 1167 11B5;B832;1105 1167 11B5; +B833;B833;1105 1167 11B6;B833;1105 1167 11B6; +B834;B834;1105 1167 11B7;B834;1105 1167 11B7; +B835;B835;1105 1167 11B8;B835;1105 1167 11B8; +B836;B836;1105 1167 11B9;B836;1105 1167 11B9; +B837;B837;1105 1167 11BA;B837;1105 1167 11BA; +B838;B838;1105 1167 11BB;B838;1105 1167 11BB; +B839;B839;1105 1167 11BC;B839;1105 1167 11BC; +B83A;B83A;1105 1167 11BD;B83A;1105 1167 11BD; +B83B;B83B;1105 1167 11BE;B83B;1105 1167 11BE; +B83C;B83C;1105 1167 11BF;B83C;1105 1167 11BF; +B83D;B83D;1105 1167 11C0;B83D;1105 1167 11C0; +B83E;B83E;1105 1167 11C1;B83E;1105 1167 11C1; +B83F;B83F;1105 1167 11C2;B83F;1105 1167 11C2; +B840;B840;1105 1168;B840;1105 1168; +B841;B841;1105 1168 11A8;B841;1105 1168 11A8; +B842;B842;1105 1168 11A9;B842;1105 1168 11A9; +B843;B843;1105 1168 11AA;B843;1105 1168 11AA; +B844;B844;1105 1168 11AB;B844;1105 1168 11AB; +B845;B845;1105 1168 11AC;B845;1105 1168 11AC; +B846;B846;1105 1168 11AD;B846;1105 1168 11AD; +B847;B847;1105 1168 11AE;B847;1105 1168 11AE; +B848;B848;1105 1168 11AF;B848;1105 1168 11AF; +B849;B849;1105 1168 11B0;B849;1105 1168 11B0; +B84A;B84A;1105 1168 11B1;B84A;1105 1168 11B1; +B84B;B84B;1105 1168 11B2;B84B;1105 1168 11B2; +B84C;B84C;1105 1168 11B3;B84C;1105 1168 11B3; +B84D;B84D;1105 1168 11B4;B84D;1105 1168 11B4; +B84E;B84E;1105 1168 11B5;B84E;1105 1168 11B5; +B84F;B84F;1105 1168 11B6;B84F;1105 1168 11B6; +B850;B850;1105 1168 11B7;B850;1105 1168 11B7; +B851;B851;1105 1168 11B8;B851;1105 1168 11B8; +B852;B852;1105 1168 11B9;B852;1105 1168 11B9; +B853;B853;1105 1168 11BA;B853;1105 1168 11BA; +B854;B854;1105 1168 11BB;B854;1105 1168 11BB; +B855;B855;1105 1168 11BC;B855;1105 1168 11BC; +B856;B856;1105 1168 11BD;B856;1105 1168 11BD; +B857;B857;1105 1168 11BE;B857;1105 1168 11BE; +B858;B858;1105 1168 11BF;B858;1105 1168 11BF; +B859;B859;1105 1168 11C0;B859;1105 1168 11C0; +B85A;B85A;1105 1168 11C1;B85A;1105 1168 11C1; +B85B;B85B;1105 1168 11C2;B85B;1105 1168 11C2; +B85C;B85C;1105 1169;B85C;1105 1169; +B85D;B85D;1105 1169 11A8;B85D;1105 1169 11A8; +B85E;B85E;1105 1169 11A9;B85E;1105 1169 11A9; +B85F;B85F;1105 1169 11AA;B85F;1105 1169 11AA; +B860;B860;1105 1169 11AB;B860;1105 1169 11AB; +B861;B861;1105 1169 11AC;B861;1105 1169 11AC; +B862;B862;1105 1169 11AD;B862;1105 1169 11AD; +B863;B863;1105 1169 11AE;B863;1105 1169 11AE; +B864;B864;1105 1169 11AF;B864;1105 1169 11AF; +B865;B865;1105 1169 11B0;B865;1105 1169 11B0; +B866;B866;1105 1169 11B1;B866;1105 1169 11B1; +B867;B867;1105 1169 11B2;B867;1105 1169 11B2; +B868;B868;1105 1169 11B3;B868;1105 1169 11B3; +B869;B869;1105 1169 11B4;B869;1105 1169 11B4; +B86A;B86A;1105 1169 11B5;B86A;1105 1169 11B5; +B86B;B86B;1105 1169 11B6;B86B;1105 1169 11B6; +B86C;B86C;1105 1169 11B7;B86C;1105 1169 11B7; +B86D;B86D;1105 1169 11B8;B86D;1105 1169 11B8; +B86E;B86E;1105 1169 11B9;B86E;1105 1169 11B9; +B86F;B86F;1105 1169 11BA;B86F;1105 1169 11BA; +B870;B870;1105 1169 11BB;B870;1105 1169 11BB; +B871;B871;1105 1169 11BC;B871;1105 1169 11BC; +B872;B872;1105 1169 11BD;B872;1105 1169 11BD; +B873;B873;1105 1169 11BE;B873;1105 1169 11BE; +B874;B874;1105 1169 11BF;B874;1105 1169 11BF; +B875;B875;1105 1169 11C0;B875;1105 1169 11C0; +B876;B876;1105 1169 11C1;B876;1105 1169 11C1; +B877;B877;1105 1169 11C2;B877;1105 1169 11C2; +B878;B878;1105 116A;B878;1105 116A; +B879;B879;1105 116A 11A8;B879;1105 116A 11A8; +B87A;B87A;1105 116A 11A9;B87A;1105 116A 11A9; +B87B;B87B;1105 116A 11AA;B87B;1105 116A 11AA; +B87C;B87C;1105 116A 11AB;B87C;1105 116A 11AB; +B87D;B87D;1105 116A 11AC;B87D;1105 116A 11AC; +B87E;B87E;1105 116A 11AD;B87E;1105 116A 11AD; +B87F;B87F;1105 116A 11AE;B87F;1105 116A 11AE; +B880;B880;1105 116A 11AF;B880;1105 116A 11AF; +B881;B881;1105 116A 11B0;B881;1105 116A 11B0; +B882;B882;1105 116A 11B1;B882;1105 116A 11B1; +B883;B883;1105 116A 11B2;B883;1105 116A 11B2; +B884;B884;1105 116A 11B3;B884;1105 116A 11B3; +B885;B885;1105 116A 11B4;B885;1105 116A 11B4; +B886;B886;1105 116A 11B5;B886;1105 116A 11B5; +B887;B887;1105 116A 11B6;B887;1105 116A 11B6; +B888;B888;1105 116A 11B7;B888;1105 116A 11B7; +B889;B889;1105 116A 11B8;B889;1105 116A 11B8; +B88A;B88A;1105 116A 11B9;B88A;1105 116A 11B9; +B88B;B88B;1105 116A 11BA;B88B;1105 116A 11BA; +B88C;B88C;1105 116A 11BB;B88C;1105 116A 11BB; +B88D;B88D;1105 116A 11BC;B88D;1105 116A 11BC; +B88E;B88E;1105 116A 11BD;B88E;1105 116A 11BD; +B88F;B88F;1105 116A 11BE;B88F;1105 116A 11BE; +B890;B890;1105 116A 11BF;B890;1105 116A 11BF; +B891;B891;1105 116A 11C0;B891;1105 116A 11C0; +B892;B892;1105 116A 11C1;B892;1105 116A 11C1; +B893;B893;1105 116A 11C2;B893;1105 116A 11C2; +B894;B894;1105 116B;B894;1105 116B; +B895;B895;1105 116B 11A8;B895;1105 116B 11A8; +B896;B896;1105 116B 11A9;B896;1105 116B 11A9; +B897;B897;1105 116B 11AA;B897;1105 116B 11AA; +B898;B898;1105 116B 11AB;B898;1105 116B 11AB; +B899;B899;1105 116B 11AC;B899;1105 116B 11AC; +B89A;B89A;1105 116B 11AD;B89A;1105 116B 11AD; +B89B;B89B;1105 116B 11AE;B89B;1105 116B 11AE; +B89C;B89C;1105 116B 11AF;B89C;1105 116B 11AF; +B89D;B89D;1105 116B 11B0;B89D;1105 116B 11B0; +B89E;B89E;1105 116B 11B1;B89E;1105 116B 11B1; +B89F;B89F;1105 116B 11B2;B89F;1105 116B 11B2; +B8A0;B8A0;1105 116B 11B3;B8A0;1105 116B 11B3; +B8A1;B8A1;1105 116B 11B4;B8A1;1105 116B 11B4; +B8A2;B8A2;1105 116B 11B5;B8A2;1105 116B 11B5; +B8A3;B8A3;1105 116B 11B6;B8A3;1105 116B 11B6; +B8A4;B8A4;1105 116B 11B7;B8A4;1105 116B 11B7; +B8A5;B8A5;1105 116B 11B8;B8A5;1105 116B 11B8; +B8A6;B8A6;1105 116B 11B9;B8A6;1105 116B 11B9; +B8A7;B8A7;1105 116B 11BA;B8A7;1105 116B 11BA; +B8A8;B8A8;1105 116B 11BB;B8A8;1105 116B 11BB; +B8A9;B8A9;1105 116B 11BC;B8A9;1105 116B 11BC; +B8AA;B8AA;1105 116B 11BD;B8AA;1105 116B 11BD; +B8AB;B8AB;1105 116B 11BE;B8AB;1105 116B 11BE; +B8AC;B8AC;1105 116B 11BF;B8AC;1105 116B 11BF; +B8AD;B8AD;1105 116B 11C0;B8AD;1105 116B 11C0; +B8AE;B8AE;1105 116B 11C1;B8AE;1105 116B 11C1; +B8AF;B8AF;1105 116B 11C2;B8AF;1105 116B 11C2; +B8B0;B8B0;1105 116C;B8B0;1105 116C; +B8B1;B8B1;1105 116C 11A8;B8B1;1105 116C 11A8; +B8B2;B8B2;1105 116C 11A9;B8B2;1105 116C 11A9; +B8B3;B8B3;1105 116C 11AA;B8B3;1105 116C 11AA; +B8B4;B8B4;1105 116C 11AB;B8B4;1105 116C 11AB; +B8B5;B8B5;1105 116C 11AC;B8B5;1105 116C 11AC; +B8B6;B8B6;1105 116C 11AD;B8B6;1105 116C 11AD; +B8B7;B8B7;1105 116C 11AE;B8B7;1105 116C 11AE; +B8B8;B8B8;1105 116C 11AF;B8B8;1105 116C 11AF; +B8B9;B8B9;1105 116C 11B0;B8B9;1105 116C 11B0; +B8BA;B8BA;1105 116C 11B1;B8BA;1105 116C 11B1; +B8BB;B8BB;1105 116C 11B2;B8BB;1105 116C 11B2; +B8BC;B8BC;1105 116C 11B3;B8BC;1105 116C 11B3; +B8BD;B8BD;1105 116C 11B4;B8BD;1105 116C 11B4; +B8BE;B8BE;1105 116C 11B5;B8BE;1105 116C 11B5; +B8BF;B8BF;1105 116C 11B6;B8BF;1105 116C 11B6; +B8C0;B8C0;1105 116C 11B7;B8C0;1105 116C 11B7; +B8C1;B8C1;1105 116C 11B8;B8C1;1105 116C 11B8; +B8C2;B8C2;1105 116C 11B9;B8C2;1105 116C 11B9; +B8C3;B8C3;1105 116C 11BA;B8C3;1105 116C 11BA; +B8C4;B8C4;1105 116C 11BB;B8C4;1105 116C 11BB; +B8C5;B8C5;1105 116C 11BC;B8C5;1105 116C 11BC; +B8C6;B8C6;1105 116C 11BD;B8C6;1105 116C 11BD; +B8C7;B8C7;1105 116C 11BE;B8C7;1105 116C 11BE; +B8C8;B8C8;1105 116C 11BF;B8C8;1105 116C 11BF; +B8C9;B8C9;1105 116C 11C0;B8C9;1105 116C 11C0; +B8CA;B8CA;1105 116C 11C1;B8CA;1105 116C 11C1; +B8CB;B8CB;1105 116C 11C2;B8CB;1105 116C 11C2; +B8CC;B8CC;1105 116D;B8CC;1105 116D; +B8CD;B8CD;1105 116D 11A8;B8CD;1105 116D 11A8; +B8CE;B8CE;1105 116D 11A9;B8CE;1105 116D 11A9; +B8CF;B8CF;1105 116D 11AA;B8CF;1105 116D 11AA; +B8D0;B8D0;1105 116D 11AB;B8D0;1105 116D 11AB; +B8D1;B8D1;1105 116D 11AC;B8D1;1105 116D 11AC; +B8D2;B8D2;1105 116D 11AD;B8D2;1105 116D 11AD; +B8D3;B8D3;1105 116D 11AE;B8D3;1105 116D 11AE; +B8D4;B8D4;1105 116D 11AF;B8D4;1105 116D 11AF; +B8D5;B8D5;1105 116D 11B0;B8D5;1105 116D 11B0; +B8D6;B8D6;1105 116D 11B1;B8D6;1105 116D 11B1; +B8D7;B8D7;1105 116D 11B2;B8D7;1105 116D 11B2; +B8D8;B8D8;1105 116D 11B3;B8D8;1105 116D 11B3; +B8D9;B8D9;1105 116D 11B4;B8D9;1105 116D 11B4; +B8DA;B8DA;1105 116D 11B5;B8DA;1105 116D 11B5; +B8DB;B8DB;1105 116D 11B6;B8DB;1105 116D 11B6; +B8DC;B8DC;1105 116D 11B7;B8DC;1105 116D 11B7; +B8DD;B8DD;1105 116D 11B8;B8DD;1105 116D 11B8; +B8DE;B8DE;1105 116D 11B9;B8DE;1105 116D 11B9; +B8DF;B8DF;1105 116D 11BA;B8DF;1105 116D 11BA; +B8E0;B8E0;1105 116D 11BB;B8E0;1105 116D 11BB; +B8E1;B8E1;1105 116D 11BC;B8E1;1105 116D 11BC; +B8E2;B8E2;1105 116D 11BD;B8E2;1105 116D 11BD; +B8E3;B8E3;1105 116D 11BE;B8E3;1105 116D 11BE; +B8E4;B8E4;1105 116D 11BF;B8E4;1105 116D 11BF; +B8E5;B8E5;1105 116D 11C0;B8E5;1105 116D 11C0; +B8E6;B8E6;1105 116D 11C1;B8E6;1105 116D 11C1; +B8E7;B8E7;1105 116D 11C2;B8E7;1105 116D 11C2; +B8E8;B8E8;1105 116E;B8E8;1105 116E; +B8E9;B8E9;1105 116E 11A8;B8E9;1105 116E 11A8; +B8EA;B8EA;1105 116E 11A9;B8EA;1105 116E 11A9; +B8EB;B8EB;1105 116E 11AA;B8EB;1105 116E 11AA; +B8EC;B8EC;1105 116E 11AB;B8EC;1105 116E 11AB; +B8ED;B8ED;1105 116E 11AC;B8ED;1105 116E 11AC; +B8EE;B8EE;1105 116E 11AD;B8EE;1105 116E 11AD; +B8EF;B8EF;1105 116E 11AE;B8EF;1105 116E 11AE; +B8F0;B8F0;1105 116E 11AF;B8F0;1105 116E 11AF; +B8F1;B8F1;1105 116E 11B0;B8F1;1105 116E 11B0; +B8F2;B8F2;1105 116E 11B1;B8F2;1105 116E 11B1; +B8F3;B8F3;1105 116E 11B2;B8F3;1105 116E 11B2; +B8F4;B8F4;1105 116E 11B3;B8F4;1105 116E 11B3; +B8F5;B8F5;1105 116E 11B4;B8F5;1105 116E 11B4; +B8F6;B8F6;1105 116E 11B5;B8F6;1105 116E 11B5; +B8F7;B8F7;1105 116E 11B6;B8F7;1105 116E 11B6; +B8F8;B8F8;1105 116E 11B7;B8F8;1105 116E 11B7; +B8F9;B8F9;1105 116E 11B8;B8F9;1105 116E 11B8; +B8FA;B8FA;1105 116E 11B9;B8FA;1105 116E 11B9; +B8FB;B8FB;1105 116E 11BA;B8FB;1105 116E 11BA; +B8FC;B8FC;1105 116E 11BB;B8FC;1105 116E 11BB; +B8FD;B8FD;1105 116E 11BC;B8FD;1105 116E 11BC; +B8FE;B8FE;1105 116E 11BD;B8FE;1105 116E 11BD; +B8FF;B8FF;1105 116E 11BE;B8FF;1105 116E 11BE; +B900;B900;1105 116E 11BF;B900;1105 116E 11BF; +B901;B901;1105 116E 11C0;B901;1105 116E 11C0; +B902;B902;1105 116E 11C1;B902;1105 116E 11C1; +B903;B903;1105 116E 11C2;B903;1105 116E 11C2; +B904;B904;1105 116F;B904;1105 116F; +B905;B905;1105 116F 11A8;B905;1105 116F 11A8; +B906;B906;1105 116F 11A9;B906;1105 116F 11A9; +B907;B907;1105 116F 11AA;B907;1105 116F 11AA; +B908;B908;1105 116F 11AB;B908;1105 116F 11AB; +B909;B909;1105 116F 11AC;B909;1105 116F 11AC; +B90A;B90A;1105 116F 11AD;B90A;1105 116F 11AD; +B90B;B90B;1105 116F 11AE;B90B;1105 116F 11AE; +B90C;B90C;1105 116F 11AF;B90C;1105 116F 11AF; +B90D;B90D;1105 116F 11B0;B90D;1105 116F 11B0; +B90E;B90E;1105 116F 11B1;B90E;1105 116F 11B1; +B90F;B90F;1105 116F 11B2;B90F;1105 116F 11B2; +B910;B910;1105 116F 11B3;B910;1105 116F 11B3; +B911;B911;1105 116F 11B4;B911;1105 116F 11B4; +B912;B912;1105 116F 11B5;B912;1105 116F 11B5; +B913;B913;1105 116F 11B6;B913;1105 116F 11B6; +B914;B914;1105 116F 11B7;B914;1105 116F 11B7; +B915;B915;1105 116F 11B8;B915;1105 116F 11B8; +B916;B916;1105 116F 11B9;B916;1105 116F 11B9; +B917;B917;1105 116F 11BA;B917;1105 116F 11BA; +B918;B918;1105 116F 11BB;B918;1105 116F 11BB; +B919;B919;1105 116F 11BC;B919;1105 116F 11BC; +B91A;B91A;1105 116F 11BD;B91A;1105 116F 11BD; +B91B;B91B;1105 116F 11BE;B91B;1105 116F 11BE; +B91C;B91C;1105 116F 11BF;B91C;1105 116F 11BF; +B91D;B91D;1105 116F 11C0;B91D;1105 116F 11C0; +B91E;B91E;1105 116F 11C1;B91E;1105 116F 11C1; +B91F;B91F;1105 116F 11C2;B91F;1105 116F 11C2; +B920;B920;1105 1170;B920;1105 1170; +B921;B921;1105 1170 11A8;B921;1105 1170 11A8; +B922;B922;1105 1170 11A9;B922;1105 1170 11A9; +B923;B923;1105 1170 11AA;B923;1105 1170 11AA; +B924;B924;1105 1170 11AB;B924;1105 1170 11AB; +B925;B925;1105 1170 11AC;B925;1105 1170 11AC; +B926;B926;1105 1170 11AD;B926;1105 1170 11AD; +B927;B927;1105 1170 11AE;B927;1105 1170 11AE; +B928;B928;1105 1170 11AF;B928;1105 1170 11AF; +B929;B929;1105 1170 11B0;B929;1105 1170 11B0; +B92A;B92A;1105 1170 11B1;B92A;1105 1170 11B1; +B92B;B92B;1105 1170 11B2;B92B;1105 1170 11B2; +B92C;B92C;1105 1170 11B3;B92C;1105 1170 11B3; +B92D;B92D;1105 1170 11B4;B92D;1105 1170 11B4; +B92E;B92E;1105 1170 11B5;B92E;1105 1170 11B5; +B92F;B92F;1105 1170 11B6;B92F;1105 1170 11B6; +B930;B930;1105 1170 11B7;B930;1105 1170 11B7; +B931;B931;1105 1170 11B8;B931;1105 1170 11B8; +B932;B932;1105 1170 11B9;B932;1105 1170 11B9; +B933;B933;1105 1170 11BA;B933;1105 1170 11BA; +B934;B934;1105 1170 11BB;B934;1105 1170 11BB; +B935;B935;1105 1170 11BC;B935;1105 1170 11BC; +B936;B936;1105 1170 11BD;B936;1105 1170 11BD; +B937;B937;1105 1170 11BE;B937;1105 1170 11BE; +B938;B938;1105 1170 11BF;B938;1105 1170 11BF; +B939;B939;1105 1170 11C0;B939;1105 1170 11C0; +B93A;B93A;1105 1170 11C1;B93A;1105 1170 11C1; +B93B;B93B;1105 1170 11C2;B93B;1105 1170 11C2; +B93C;B93C;1105 1171;B93C;1105 1171; +B93D;B93D;1105 1171 11A8;B93D;1105 1171 11A8; +B93E;B93E;1105 1171 11A9;B93E;1105 1171 11A9; +B93F;B93F;1105 1171 11AA;B93F;1105 1171 11AA; +B940;B940;1105 1171 11AB;B940;1105 1171 11AB; +B941;B941;1105 1171 11AC;B941;1105 1171 11AC; +B942;B942;1105 1171 11AD;B942;1105 1171 11AD; +B943;B943;1105 1171 11AE;B943;1105 1171 11AE; +B944;B944;1105 1171 11AF;B944;1105 1171 11AF; +B945;B945;1105 1171 11B0;B945;1105 1171 11B0; +B946;B946;1105 1171 11B1;B946;1105 1171 11B1; +B947;B947;1105 1171 11B2;B947;1105 1171 11B2; +B948;B948;1105 1171 11B3;B948;1105 1171 11B3; +B949;B949;1105 1171 11B4;B949;1105 1171 11B4; +B94A;B94A;1105 1171 11B5;B94A;1105 1171 11B5; +B94B;B94B;1105 1171 11B6;B94B;1105 1171 11B6; +B94C;B94C;1105 1171 11B7;B94C;1105 1171 11B7; +B94D;B94D;1105 1171 11B8;B94D;1105 1171 11B8; +B94E;B94E;1105 1171 11B9;B94E;1105 1171 11B9; +B94F;B94F;1105 1171 11BA;B94F;1105 1171 11BA; +B950;B950;1105 1171 11BB;B950;1105 1171 11BB; +B951;B951;1105 1171 11BC;B951;1105 1171 11BC; +B952;B952;1105 1171 11BD;B952;1105 1171 11BD; +B953;B953;1105 1171 11BE;B953;1105 1171 11BE; +B954;B954;1105 1171 11BF;B954;1105 1171 11BF; +B955;B955;1105 1171 11C0;B955;1105 1171 11C0; +B956;B956;1105 1171 11C1;B956;1105 1171 11C1; +B957;B957;1105 1171 11C2;B957;1105 1171 11C2; +B958;B958;1105 1172;B958;1105 1172; +B959;B959;1105 1172 11A8;B959;1105 1172 11A8; +B95A;B95A;1105 1172 11A9;B95A;1105 1172 11A9; +B95B;B95B;1105 1172 11AA;B95B;1105 1172 11AA; +B95C;B95C;1105 1172 11AB;B95C;1105 1172 11AB; +B95D;B95D;1105 1172 11AC;B95D;1105 1172 11AC; +B95E;B95E;1105 1172 11AD;B95E;1105 1172 11AD; +B95F;B95F;1105 1172 11AE;B95F;1105 1172 11AE; +B960;B960;1105 1172 11AF;B960;1105 1172 11AF; +B961;B961;1105 1172 11B0;B961;1105 1172 11B0; +B962;B962;1105 1172 11B1;B962;1105 1172 11B1; +B963;B963;1105 1172 11B2;B963;1105 1172 11B2; +B964;B964;1105 1172 11B3;B964;1105 1172 11B3; +B965;B965;1105 1172 11B4;B965;1105 1172 11B4; +B966;B966;1105 1172 11B5;B966;1105 1172 11B5; +B967;B967;1105 1172 11B6;B967;1105 1172 11B6; +B968;B968;1105 1172 11B7;B968;1105 1172 11B7; +B969;B969;1105 1172 11B8;B969;1105 1172 11B8; +B96A;B96A;1105 1172 11B9;B96A;1105 1172 11B9; +B96B;B96B;1105 1172 11BA;B96B;1105 1172 11BA; +B96C;B96C;1105 1172 11BB;B96C;1105 1172 11BB; +B96D;B96D;1105 1172 11BC;B96D;1105 1172 11BC; +B96E;B96E;1105 1172 11BD;B96E;1105 1172 11BD; +B96F;B96F;1105 1172 11BE;B96F;1105 1172 11BE; +B970;B970;1105 1172 11BF;B970;1105 1172 11BF; +B971;B971;1105 1172 11C0;B971;1105 1172 11C0; +B972;B972;1105 1172 11C1;B972;1105 1172 11C1; +B973;B973;1105 1172 11C2;B973;1105 1172 11C2; +B974;B974;1105 1173;B974;1105 1173; +B975;B975;1105 1173 11A8;B975;1105 1173 11A8; +B976;B976;1105 1173 11A9;B976;1105 1173 11A9; +B977;B977;1105 1173 11AA;B977;1105 1173 11AA; +B978;B978;1105 1173 11AB;B978;1105 1173 11AB; +B979;B979;1105 1173 11AC;B979;1105 1173 11AC; +B97A;B97A;1105 1173 11AD;B97A;1105 1173 11AD; +B97B;B97B;1105 1173 11AE;B97B;1105 1173 11AE; +B97C;B97C;1105 1173 11AF;B97C;1105 1173 11AF; +B97D;B97D;1105 1173 11B0;B97D;1105 1173 11B0; +B97E;B97E;1105 1173 11B1;B97E;1105 1173 11B1; +B97F;B97F;1105 1173 11B2;B97F;1105 1173 11B2; +B980;B980;1105 1173 11B3;B980;1105 1173 11B3; +B981;B981;1105 1173 11B4;B981;1105 1173 11B4; +B982;B982;1105 1173 11B5;B982;1105 1173 11B5; +B983;B983;1105 1173 11B6;B983;1105 1173 11B6; +B984;B984;1105 1173 11B7;B984;1105 1173 11B7; +B985;B985;1105 1173 11B8;B985;1105 1173 11B8; +B986;B986;1105 1173 11B9;B986;1105 1173 11B9; +B987;B987;1105 1173 11BA;B987;1105 1173 11BA; +B988;B988;1105 1173 11BB;B988;1105 1173 11BB; +B989;B989;1105 1173 11BC;B989;1105 1173 11BC; +B98A;B98A;1105 1173 11BD;B98A;1105 1173 11BD; +B98B;B98B;1105 1173 11BE;B98B;1105 1173 11BE; +B98C;B98C;1105 1173 11BF;B98C;1105 1173 11BF; +B98D;B98D;1105 1173 11C0;B98D;1105 1173 11C0; +B98E;B98E;1105 1173 11C1;B98E;1105 1173 11C1; +B98F;B98F;1105 1173 11C2;B98F;1105 1173 11C2; +B990;B990;1105 1174;B990;1105 1174; +B991;B991;1105 1174 11A8;B991;1105 1174 11A8; +B992;B992;1105 1174 11A9;B992;1105 1174 11A9; +B993;B993;1105 1174 11AA;B993;1105 1174 11AA; +B994;B994;1105 1174 11AB;B994;1105 1174 11AB; +B995;B995;1105 1174 11AC;B995;1105 1174 11AC; +B996;B996;1105 1174 11AD;B996;1105 1174 11AD; +B997;B997;1105 1174 11AE;B997;1105 1174 11AE; +B998;B998;1105 1174 11AF;B998;1105 1174 11AF; +B999;B999;1105 1174 11B0;B999;1105 1174 11B0; +B99A;B99A;1105 1174 11B1;B99A;1105 1174 11B1; +B99B;B99B;1105 1174 11B2;B99B;1105 1174 11B2; +B99C;B99C;1105 1174 11B3;B99C;1105 1174 11B3; +B99D;B99D;1105 1174 11B4;B99D;1105 1174 11B4; +B99E;B99E;1105 1174 11B5;B99E;1105 1174 11B5; +B99F;B99F;1105 1174 11B6;B99F;1105 1174 11B6; +B9A0;B9A0;1105 1174 11B7;B9A0;1105 1174 11B7; +B9A1;B9A1;1105 1174 11B8;B9A1;1105 1174 11B8; +B9A2;B9A2;1105 1174 11B9;B9A2;1105 1174 11B9; +B9A3;B9A3;1105 1174 11BA;B9A3;1105 1174 11BA; +B9A4;B9A4;1105 1174 11BB;B9A4;1105 1174 11BB; +B9A5;B9A5;1105 1174 11BC;B9A5;1105 1174 11BC; +B9A6;B9A6;1105 1174 11BD;B9A6;1105 1174 11BD; +B9A7;B9A7;1105 1174 11BE;B9A7;1105 1174 11BE; +B9A8;B9A8;1105 1174 11BF;B9A8;1105 1174 11BF; +B9A9;B9A9;1105 1174 11C0;B9A9;1105 1174 11C0; +B9AA;B9AA;1105 1174 11C1;B9AA;1105 1174 11C1; +B9AB;B9AB;1105 1174 11C2;B9AB;1105 1174 11C2; +B9AC;B9AC;1105 1175;B9AC;1105 1175; +B9AD;B9AD;1105 1175 11A8;B9AD;1105 1175 11A8; +B9AE;B9AE;1105 1175 11A9;B9AE;1105 1175 11A9; +B9AF;B9AF;1105 1175 11AA;B9AF;1105 1175 11AA; +B9B0;B9B0;1105 1175 11AB;B9B0;1105 1175 11AB; +B9B1;B9B1;1105 1175 11AC;B9B1;1105 1175 11AC; +B9B2;B9B2;1105 1175 11AD;B9B2;1105 1175 11AD; +B9B3;B9B3;1105 1175 11AE;B9B3;1105 1175 11AE; +B9B4;B9B4;1105 1175 11AF;B9B4;1105 1175 11AF; +B9B5;B9B5;1105 1175 11B0;B9B5;1105 1175 11B0; +B9B6;B9B6;1105 1175 11B1;B9B6;1105 1175 11B1; +B9B7;B9B7;1105 1175 11B2;B9B7;1105 1175 11B2; +B9B8;B9B8;1105 1175 11B3;B9B8;1105 1175 11B3; +B9B9;B9B9;1105 1175 11B4;B9B9;1105 1175 11B4; +B9BA;B9BA;1105 1175 11B5;B9BA;1105 1175 11B5; +B9BB;B9BB;1105 1175 11B6;B9BB;1105 1175 11B6; +B9BC;B9BC;1105 1175 11B7;B9BC;1105 1175 11B7; +B9BD;B9BD;1105 1175 11B8;B9BD;1105 1175 11B8; +B9BE;B9BE;1105 1175 11B9;B9BE;1105 1175 11B9; +B9BF;B9BF;1105 1175 11BA;B9BF;1105 1175 11BA; +B9C0;B9C0;1105 1175 11BB;B9C0;1105 1175 11BB; +B9C1;B9C1;1105 1175 11BC;B9C1;1105 1175 11BC; +B9C2;B9C2;1105 1175 11BD;B9C2;1105 1175 11BD; +B9C3;B9C3;1105 1175 11BE;B9C3;1105 1175 11BE; +B9C4;B9C4;1105 1175 11BF;B9C4;1105 1175 11BF; +B9C5;B9C5;1105 1175 11C0;B9C5;1105 1175 11C0; +B9C6;B9C6;1105 1175 11C1;B9C6;1105 1175 11C1; +B9C7;B9C7;1105 1175 11C2;B9C7;1105 1175 11C2; +B9C8;B9C8;1106 1161;B9C8;1106 1161; +B9C9;B9C9;1106 1161 11A8;B9C9;1106 1161 11A8; +B9CA;B9CA;1106 1161 11A9;B9CA;1106 1161 11A9; +B9CB;B9CB;1106 1161 11AA;B9CB;1106 1161 11AA; +B9CC;B9CC;1106 1161 11AB;B9CC;1106 1161 11AB; +B9CD;B9CD;1106 1161 11AC;B9CD;1106 1161 11AC; +B9CE;B9CE;1106 1161 11AD;B9CE;1106 1161 11AD; +B9CF;B9CF;1106 1161 11AE;B9CF;1106 1161 11AE; +B9D0;B9D0;1106 1161 11AF;B9D0;1106 1161 11AF; +B9D1;B9D1;1106 1161 11B0;B9D1;1106 1161 11B0; +B9D2;B9D2;1106 1161 11B1;B9D2;1106 1161 11B1; +B9D3;B9D3;1106 1161 11B2;B9D3;1106 1161 11B2; +B9D4;B9D4;1106 1161 11B3;B9D4;1106 1161 11B3; +B9D5;B9D5;1106 1161 11B4;B9D5;1106 1161 11B4; +B9D6;B9D6;1106 1161 11B5;B9D6;1106 1161 11B5; +B9D7;B9D7;1106 1161 11B6;B9D7;1106 1161 11B6; +B9D8;B9D8;1106 1161 11B7;B9D8;1106 1161 11B7; +B9D9;B9D9;1106 1161 11B8;B9D9;1106 1161 11B8; +B9DA;B9DA;1106 1161 11B9;B9DA;1106 1161 11B9; +B9DB;B9DB;1106 1161 11BA;B9DB;1106 1161 11BA; +B9DC;B9DC;1106 1161 11BB;B9DC;1106 1161 11BB; +B9DD;B9DD;1106 1161 11BC;B9DD;1106 1161 11BC; +B9DE;B9DE;1106 1161 11BD;B9DE;1106 1161 11BD; +B9DF;B9DF;1106 1161 11BE;B9DF;1106 1161 11BE; +B9E0;B9E0;1106 1161 11BF;B9E0;1106 1161 11BF; +B9E1;B9E1;1106 1161 11C0;B9E1;1106 1161 11C0; +B9E2;B9E2;1106 1161 11C1;B9E2;1106 1161 11C1; +B9E3;B9E3;1106 1161 11C2;B9E3;1106 1161 11C2; +B9E4;B9E4;1106 1162;B9E4;1106 1162; +B9E5;B9E5;1106 1162 11A8;B9E5;1106 1162 11A8; +B9E6;B9E6;1106 1162 11A9;B9E6;1106 1162 11A9; +B9E7;B9E7;1106 1162 11AA;B9E7;1106 1162 11AA; +B9E8;B9E8;1106 1162 11AB;B9E8;1106 1162 11AB; +B9E9;B9E9;1106 1162 11AC;B9E9;1106 1162 11AC; +B9EA;B9EA;1106 1162 11AD;B9EA;1106 1162 11AD; +B9EB;B9EB;1106 1162 11AE;B9EB;1106 1162 11AE; +B9EC;B9EC;1106 1162 11AF;B9EC;1106 1162 11AF; +B9ED;B9ED;1106 1162 11B0;B9ED;1106 1162 11B0; +B9EE;B9EE;1106 1162 11B1;B9EE;1106 1162 11B1; +B9EF;B9EF;1106 1162 11B2;B9EF;1106 1162 11B2; +B9F0;B9F0;1106 1162 11B3;B9F0;1106 1162 11B3; +B9F1;B9F1;1106 1162 11B4;B9F1;1106 1162 11B4; +B9F2;B9F2;1106 1162 11B5;B9F2;1106 1162 11B5; +B9F3;B9F3;1106 1162 11B6;B9F3;1106 1162 11B6; +B9F4;B9F4;1106 1162 11B7;B9F4;1106 1162 11B7; +B9F5;B9F5;1106 1162 11B8;B9F5;1106 1162 11B8; +B9F6;B9F6;1106 1162 11B9;B9F6;1106 1162 11B9; +B9F7;B9F7;1106 1162 11BA;B9F7;1106 1162 11BA; +B9F8;B9F8;1106 1162 11BB;B9F8;1106 1162 11BB; +B9F9;B9F9;1106 1162 11BC;B9F9;1106 1162 11BC; +B9FA;B9FA;1106 1162 11BD;B9FA;1106 1162 11BD; +B9FB;B9FB;1106 1162 11BE;B9FB;1106 1162 11BE; +B9FC;B9FC;1106 1162 11BF;B9FC;1106 1162 11BF; +B9FD;B9FD;1106 1162 11C0;B9FD;1106 1162 11C0; +B9FE;B9FE;1106 1162 11C1;B9FE;1106 1162 11C1; +B9FF;B9FF;1106 1162 11C2;B9FF;1106 1162 11C2; +BA00;BA00;1106 1163;BA00;1106 1163; +BA01;BA01;1106 1163 11A8;BA01;1106 1163 11A8; +BA02;BA02;1106 1163 11A9;BA02;1106 1163 11A9; +BA03;BA03;1106 1163 11AA;BA03;1106 1163 11AA; +BA04;BA04;1106 1163 11AB;BA04;1106 1163 11AB; +BA05;BA05;1106 1163 11AC;BA05;1106 1163 11AC; +BA06;BA06;1106 1163 11AD;BA06;1106 1163 11AD; +BA07;BA07;1106 1163 11AE;BA07;1106 1163 11AE; +BA08;BA08;1106 1163 11AF;BA08;1106 1163 11AF; +BA09;BA09;1106 1163 11B0;BA09;1106 1163 11B0; +BA0A;BA0A;1106 1163 11B1;BA0A;1106 1163 11B1; +BA0B;BA0B;1106 1163 11B2;BA0B;1106 1163 11B2; +BA0C;BA0C;1106 1163 11B3;BA0C;1106 1163 11B3; +BA0D;BA0D;1106 1163 11B4;BA0D;1106 1163 11B4; +BA0E;BA0E;1106 1163 11B5;BA0E;1106 1163 11B5; +BA0F;BA0F;1106 1163 11B6;BA0F;1106 1163 11B6; +BA10;BA10;1106 1163 11B7;BA10;1106 1163 11B7; +BA11;BA11;1106 1163 11B8;BA11;1106 1163 11B8; +BA12;BA12;1106 1163 11B9;BA12;1106 1163 11B9; +BA13;BA13;1106 1163 11BA;BA13;1106 1163 11BA; +BA14;BA14;1106 1163 11BB;BA14;1106 1163 11BB; +BA15;BA15;1106 1163 11BC;BA15;1106 1163 11BC; +BA16;BA16;1106 1163 11BD;BA16;1106 1163 11BD; +BA17;BA17;1106 1163 11BE;BA17;1106 1163 11BE; +BA18;BA18;1106 1163 11BF;BA18;1106 1163 11BF; +BA19;BA19;1106 1163 11C0;BA19;1106 1163 11C0; +BA1A;BA1A;1106 1163 11C1;BA1A;1106 1163 11C1; +BA1B;BA1B;1106 1163 11C2;BA1B;1106 1163 11C2; +BA1C;BA1C;1106 1164;BA1C;1106 1164; +BA1D;BA1D;1106 1164 11A8;BA1D;1106 1164 11A8; +BA1E;BA1E;1106 1164 11A9;BA1E;1106 1164 11A9; +BA1F;BA1F;1106 1164 11AA;BA1F;1106 1164 11AA; +BA20;BA20;1106 1164 11AB;BA20;1106 1164 11AB; +BA21;BA21;1106 1164 11AC;BA21;1106 1164 11AC; +BA22;BA22;1106 1164 11AD;BA22;1106 1164 11AD; +BA23;BA23;1106 1164 11AE;BA23;1106 1164 11AE; +BA24;BA24;1106 1164 11AF;BA24;1106 1164 11AF; +BA25;BA25;1106 1164 11B0;BA25;1106 1164 11B0; +BA26;BA26;1106 1164 11B1;BA26;1106 1164 11B1; +BA27;BA27;1106 1164 11B2;BA27;1106 1164 11B2; +BA28;BA28;1106 1164 11B3;BA28;1106 1164 11B3; +BA29;BA29;1106 1164 11B4;BA29;1106 1164 11B4; +BA2A;BA2A;1106 1164 11B5;BA2A;1106 1164 11B5; +BA2B;BA2B;1106 1164 11B6;BA2B;1106 1164 11B6; +BA2C;BA2C;1106 1164 11B7;BA2C;1106 1164 11B7; +BA2D;BA2D;1106 1164 11B8;BA2D;1106 1164 11B8; +BA2E;BA2E;1106 1164 11B9;BA2E;1106 1164 11B9; +BA2F;BA2F;1106 1164 11BA;BA2F;1106 1164 11BA; +BA30;BA30;1106 1164 11BB;BA30;1106 1164 11BB; +BA31;BA31;1106 1164 11BC;BA31;1106 1164 11BC; +BA32;BA32;1106 1164 11BD;BA32;1106 1164 11BD; +BA33;BA33;1106 1164 11BE;BA33;1106 1164 11BE; +BA34;BA34;1106 1164 11BF;BA34;1106 1164 11BF; +BA35;BA35;1106 1164 11C0;BA35;1106 1164 11C0; +BA36;BA36;1106 1164 11C1;BA36;1106 1164 11C1; +BA37;BA37;1106 1164 11C2;BA37;1106 1164 11C2; +BA38;BA38;1106 1165;BA38;1106 1165; +BA39;BA39;1106 1165 11A8;BA39;1106 1165 11A8; +BA3A;BA3A;1106 1165 11A9;BA3A;1106 1165 11A9; +BA3B;BA3B;1106 1165 11AA;BA3B;1106 1165 11AA; +BA3C;BA3C;1106 1165 11AB;BA3C;1106 1165 11AB; +BA3D;BA3D;1106 1165 11AC;BA3D;1106 1165 11AC; +BA3E;BA3E;1106 1165 11AD;BA3E;1106 1165 11AD; +BA3F;BA3F;1106 1165 11AE;BA3F;1106 1165 11AE; +BA40;BA40;1106 1165 11AF;BA40;1106 1165 11AF; +BA41;BA41;1106 1165 11B0;BA41;1106 1165 11B0; +BA42;BA42;1106 1165 11B1;BA42;1106 1165 11B1; +BA43;BA43;1106 1165 11B2;BA43;1106 1165 11B2; +BA44;BA44;1106 1165 11B3;BA44;1106 1165 11B3; +BA45;BA45;1106 1165 11B4;BA45;1106 1165 11B4; +BA46;BA46;1106 1165 11B5;BA46;1106 1165 11B5; +BA47;BA47;1106 1165 11B6;BA47;1106 1165 11B6; +BA48;BA48;1106 1165 11B7;BA48;1106 1165 11B7; +BA49;BA49;1106 1165 11B8;BA49;1106 1165 11B8; +BA4A;BA4A;1106 1165 11B9;BA4A;1106 1165 11B9; +BA4B;BA4B;1106 1165 11BA;BA4B;1106 1165 11BA; +BA4C;BA4C;1106 1165 11BB;BA4C;1106 1165 11BB; +BA4D;BA4D;1106 1165 11BC;BA4D;1106 1165 11BC; +BA4E;BA4E;1106 1165 11BD;BA4E;1106 1165 11BD; +BA4F;BA4F;1106 1165 11BE;BA4F;1106 1165 11BE; +BA50;BA50;1106 1165 11BF;BA50;1106 1165 11BF; +BA51;BA51;1106 1165 11C0;BA51;1106 1165 11C0; +BA52;BA52;1106 1165 11C1;BA52;1106 1165 11C1; +BA53;BA53;1106 1165 11C2;BA53;1106 1165 11C2; +BA54;BA54;1106 1166;BA54;1106 1166; +BA55;BA55;1106 1166 11A8;BA55;1106 1166 11A8; +BA56;BA56;1106 1166 11A9;BA56;1106 1166 11A9; +BA57;BA57;1106 1166 11AA;BA57;1106 1166 11AA; +BA58;BA58;1106 1166 11AB;BA58;1106 1166 11AB; +BA59;BA59;1106 1166 11AC;BA59;1106 1166 11AC; +BA5A;BA5A;1106 1166 11AD;BA5A;1106 1166 11AD; +BA5B;BA5B;1106 1166 11AE;BA5B;1106 1166 11AE; +BA5C;BA5C;1106 1166 11AF;BA5C;1106 1166 11AF; +BA5D;BA5D;1106 1166 11B0;BA5D;1106 1166 11B0; +BA5E;BA5E;1106 1166 11B1;BA5E;1106 1166 11B1; +BA5F;BA5F;1106 1166 11B2;BA5F;1106 1166 11B2; +BA60;BA60;1106 1166 11B3;BA60;1106 1166 11B3; +BA61;BA61;1106 1166 11B4;BA61;1106 1166 11B4; +BA62;BA62;1106 1166 11B5;BA62;1106 1166 11B5; +BA63;BA63;1106 1166 11B6;BA63;1106 1166 11B6; +BA64;BA64;1106 1166 11B7;BA64;1106 1166 11B7; +BA65;BA65;1106 1166 11B8;BA65;1106 1166 11B8; +BA66;BA66;1106 1166 11B9;BA66;1106 1166 11B9; +BA67;BA67;1106 1166 11BA;BA67;1106 1166 11BA; +BA68;BA68;1106 1166 11BB;BA68;1106 1166 11BB; +BA69;BA69;1106 1166 11BC;BA69;1106 1166 11BC; +BA6A;BA6A;1106 1166 11BD;BA6A;1106 1166 11BD; +BA6B;BA6B;1106 1166 11BE;BA6B;1106 1166 11BE; +BA6C;BA6C;1106 1166 11BF;BA6C;1106 1166 11BF; +BA6D;BA6D;1106 1166 11C0;BA6D;1106 1166 11C0; +BA6E;BA6E;1106 1166 11C1;BA6E;1106 1166 11C1; +BA6F;BA6F;1106 1166 11C2;BA6F;1106 1166 11C2; +BA70;BA70;1106 1167;BA70;1106 1167; +BA71;BA71;1106 1167 11A8;BA71;1106 1167 11A8; +BA72;BA72;1106 1167 11A9;BA72;1106 1167 11A9; +BA73;BA73;1106 1167 11AA;BA73;1106 1167 11AA; +BA74;BA74;1106 1167 11AB;BA74;1106 1167 11AB; +BA75;BA75;1106 1167 11AC;BA75;1106 1167 11AC; +BA76;BA76;1106 1167 11AD;BA76;1106 1167 11AD; +BA77;BA77;1106 1167 11AE;BA77;1106 1167 11AE; +BA78;BA78;1106 1167 11AF;BA78;1106 1167 11AF; +BA79;BA79;1106 1167 11B0;BA79;1106 1167 11B0; +BA7A;BA7A;1106 1167 11B1;BA7A;1106 1167 11B1; +BA7B;BA7B;1106 1167 11B2;BA7B;1106 1167 11B2; +BA7C;BA7C;1106 1167 11B3;BA7C;1106 1167 11B3; +BA7D;BA7D;1106 1167 11B4;BA7D;1106 1167 11B4; +BA7E;BA7E;1106 1167 11B5;BA7E;1106 1167 11B5; +BA7F;BA7F;1106 1167 11B6;BA7F;1106 1167 11B6; +BA80;BA80;1106 1167 11B7;BA80;1106 1167 11B7; +BA81;BA81;1106 1167 11B8;BA81;1106 1167 11B8; +BA82;BA82;1106 1167 11B9;BA82;1106 1167 11B9; +BA83;BA83;1106 1167 11BA;BA83;1106 1167 11BA; +BA84;BA84;1106 1167 11BB;BA84;1106 1167 11BB; +BA85;BA85;1106 1167 11BC;BA85;1106 1167 11BC; +BA86;BA86;1106 1167 11BD;BA86;1106 1167 11BD; +BA87;BA87;1106 1167 11BE;BA87;1106 1167 11BE; +BA88;BA88;1106 1167 11BF;BA88;1106 1167 11BF; +BA89;BA89;1106 1167 11C0;BA89;1106 1167 11C0; +BA8A;BA8A;1106 1167 11C1;BA8A;1106 1167 11C1; +BA8B;BA8B;1106 1167 11C2;BA8B;1106 1167 11C2; +BA8C;BA8C;1106 1168;BA8C;1106 1168; +BA8D;BA8D;1106 1168 11A8;BA8D;1106 1168 11A8; +BA8E;BA8E;1106 1168 11A9;BA8E;1106 1168 11A9; +BA8F;BA8F;1106 1168 11AA;BA8F;1106 1168 11AA; +BA90;BA90;1106 1168 11AB;BA90;1106 1168 11AB; +BA91;BA91;1106 1168 11AC;BA91;1106 1168 11AC; +BA92;BA92;1106 1168 11AD;BA92;1106 1168 11AD; +BA93;BA93;1106 1168 11AE;BA93;1106 1168 11AE; +BA94;BA94;1106 1168 11AF;BA94;1106 1168 11AF; +BA95;BA95;1106 1168 11B0;BA95;1106 1168 11B0; +BA96;BA96;1106 1168 11B1;BA96;1106 1168 11B1; +BA97;BA97;1106 1168 11B2;BA97;1106 1168 11B2; +BA98;BA98;1106 1168 11B3;BA98;1106 1168 11B3; +BA99;BA99;1106 1168 11B4;BA99;1106 1168 11B4; +BA9A;BA9A;1106 1168 11B5;BA9A;1106 1168 11B5; +BA9B;BA9B;1106 1168 11B6;BA9B;1106 1168 11B6; +BA9C;BA9C;1106 1168 11B7;BA9C;1106 1168 11B7; +BA9D;BA9D;1106 1168 11B8;BA9D;1106 1168 11B8; +BA9E;BA9E;1106 1168 11B9;BA9E;1106 1168 11B9; +BA9F;BA9F;1106 1168 11BA;BA9F;1106 1168 11BA; +BAA0;BAA0;1106 1168 11BB;BAA0;1106 1168 11BB; +BAA1;BAA1;1106 1168 11BC;BAA1;1106 1168 11BC; +BAA2;BAA2;1106 1168 11BD;BAA2;1106 1168 11BD; +BAA3;BAA3;1106 1168 11BE;BAA3;1106 1168 11BE; +BAA4;BAA4;1106 1168 11BF;BAA4;1106 1168 11BF; +BAA5;BAA5;1106 1168 11C0;BAA5;1106 1168 11C0; +BAA6;BAA6;1106 1168 11C1;BAA6;1106 1168 11C1; +BAA7;BAA7;1106 1168 11C2;BAA7;1106 1168 11C2; +BAA8;BAA8;1106 1169;BAA8;1106 1169; +BAA9;BAA9;1106 1169 11A8;BAA9;1106 1169 11A8; +BAAA;BAAA;1106 1169 11A9;BAAA;1106 1169 11A9; +BAAB;BAAB;1106 1169 11AA;BAAB;1106 1169 11AA; +BAAC;BAAC;1106 1169 11AB;BAAC;1106 1169 11AB; +BAAD;BAAD;1106 1169 11AC;BAAD;1106 1169 11AC; +BAAE;BAAE;1106 1169 11AD;BAAE;1106 1169 11AD; +BAAF;BAAF;1106 1169 11AE;BAAF;1106 1169 11AE; +BAB0;BAB0;1106 1169 11AF;BAB0;1106 1169 11AF; +BAB1;BAB1;1106 1169 11B0;BAB1;1106 1169 11B0; +BAB2;BAB2;1106 1169 11B1;BAB2;1106 1169 11B1; +BAB3;BAB3;1106 1169 11B2;BAB3;1106 1169 11B2; +BAB4;BAB4;1106 1169 11B3;BAB4;1106 1169 11B3; +BAB5;BAB5;1106 1169 11B4;BAB5;1106 1169 11B4; +BAB6;BAB6;1106 1169 11B5;BAB6;1106 1169 11B5; +BAB7;BAB7;1106 1169 11B6;BAB7;1106 1169 11B6; +BAB8;BAB8;1106 1169 11B7;BAB8;1106 1169 11B7; +BAB9;BAB9;1106 1169 11B8;BAB9;1106 1169 11B8; +BABA;BABA;1106 1169 11B9;BABA;1106 1169 11B9; +BABB;BABB;1106 1169 11BA;BABB;1106 1169 11BA; +BABC;BABC;1106 1169 11BB;BABC;1106 1169 11BB; +BABD;BABD;1106 1169 11BC;BABD;1106 1169 11BC; +BABE;BABE;1106 1169 11BD;BABE;1106 1169 11BD; +BABF;BABF;1106 1169 11BE;BABF;1106 1169 11BE; +BAC0;BAC0;1106 1169 11BF;BAC0;1106 1169 11BF; +BAC1;BAC1;1106 1169 11C0;BAC1;1106 1169 11C0; +BAC2;BAC2;1106 1169 11C1;BAC2;1106 1169 11C1; +BAC3;BAC3;1106 1169 11C2;BAC3;1106 1169 11C2; +BAC4;BAC4;1106 116A;BAC4;1106 116A; +BAC5;BAC5;1106 116A 11A8;BAC5;1106 116A 11A8; +BAC6;BAC6;1106 116A 11A9;BAC6;1106 116A 11A9; +BAC7;BAC7;1106 116A 11AA;BAC7;1106 116A 11AA; +BAC8;BAC8;1106 116A 11AB;BAC8;1106 116A 11AB; +BAC9;BAC9;1106 116A 11AC;BAC9;1106 116A 11AC; +BACA;BACA;1106 116A 11AD;BACA;1106 116A 11AD; +BACB;BACB;1106 116A 11AE;BACB;1106 116A 11AE; +BACC;BACC;1106 116A 11AF;BACC;1106 116A 11AF; +BACD;BACD;1106 116A 11B0;BACD;1106 116A 11B0; +BACE;BACE;1106 116A 11B1;BACE;1106 116A 11B1; +BACF;BACF;1106 116A 11B2;BACF;1106 116A 11B2; +BAD0;BAD0;1106 116A 11B3;BAD0;1106 116A 11B3; +BAD1;BAD1;1106 116A 11B4;BAD1;1106 116A 11B4; +BAD2;BAD2;1106 116A 11B5;BAD2;1106 116A 11B5; +BAD3;BAD3;1106 116A 11B6;BAD3;1106 116A 11B6; +BAD4;BAD4;1106 116A 11B7;BAD4;1106 116A 11B7; +BAD5;BAD5;1106 116A 11B8;BAD5;1106 116A 11B8; +BAD6;BAD6;1106 116A 11B9;BAD6;1106 116A 11B9; +BAD7;BAD7;1106 116A 11BA;BAD7;1106 116A 11BA; +BAD8;BAD8;1106 116A 11BB;BAD8;1106 116A 11BB; +BAD9;BAD9;1106 116A 11BC;BAD9;1106 116A 11BC; +BADA;BADA;1106 116A 11BD;BADA;1106 116A 11BD; +BADB;BADB;1106 116A 11BE;BADB;1106 116A 11BE; +BADC;BADC;1106 116A 11BF;BADC;1106 116A 11BF; +BADD;BADD;1106 116A 11C0;BADD;1106 116A 11C0; +BADE;BADE;1106 116A 11C1;BADE;1106 116A 11C1; +BADF;BADF;1106 116A 11C2;BADF;1106 116A 11C2; +BAE0;BAE0;1106 116B;BAE0;1106 116B; +BAE1;BAE1;1106 116B 11A8;BAE1;1106 116B 11A8; +BAE2;BAE2;1106 116B 11A9;BAE2;1106 116B 11A9; +BAE3;BAE3;1106 116B 11AA;BAE3;1106 116B 11AA; +BAE4;BAE4;1106 116B 11AB;BAE4;1106 116B 11AB; +BAE5;BAE5;1106 116B 11AC;BAE5;1106 116B 11AC; +BAE6;BAE6;1106 116B 11AD;BAE6;1106 116B 11AD; +BAE7;BAE7;1106 116B 11AE;BAE7;1106 116B 11AE; +BAE8;BAE8;1106 116B 11AF;BAE8;1106 116B 11AF; +BAE9;BAE9;1106 116B 11B0;BAE9;1106 116B 11B0; +BAEA;BAEA;1106 116B 11B1;BAEA;1106 116B 11B1; +BAEB;BAEB;1106 116B 11B2;BAEB;1106 116B 11B2; +BAEC;BAEC;1106 116B 11B3;BAEC;1106 116B 11B3; +BAED;BAED;1106 116B 11B4;BAED;1106 116B 11B4; +BAEE;BAEE;1106 116B 11B5;BAEE;1106 116B 11B5; +BAEF;BAEF;1106 116B 11B6;BAEF;1106 116B 11B6; +BAF0;BAF0;1106 116B 11B7;BAF0;1106 116B 11B7; +BAF1;BAF1;1106 116B 11B8;BAF1;1106 116B 11B8; +BAF2;BAF2;1106 116B 11B9;BAF2;1106 116B 11B9; +BAF3;BAF3;1106 116B 11BA;BAF3;1106 116B 11BA; +BAF4;BAF4;1106 116B 11BB;BAF4;1106 116B 11BB; +BAF5;BAF5;1106 116B 11BC;BAF5;1106 116B 11BC; +BAF6;BAF6;1106 116B 11BD;BAF6;1106 116B 11BD; +BAF7;BAF7;1106 116B 11BE;BAF7;1106 116B 11BE; +BAF8;BAF8;1106 116B 11BF;BAF8;1106 116B 11BF; +BAF9;BAF9;1106 116B 11C0;BAF9;1106 116B 11C0; +BAFA;BAFA;1106 116B 11C1;BAFA;1106 116B 11C1; +BAFB;BAFB;1106 116B 11C2;BAFB;1106 116B 11C2; +BAFC;BAFC;1106 116C;BAFC;1106 116C; +BAFD;BAFD;1106 116C 11A8;BAFD;1106 116C 11A8; +BAFE;BAFE;1106 116C 11A9;BAFE;1106 116C 11A9; +BAFF;BAFF;1106 116C 11AA;BAFF;1106 116C 11AA; +BB00;BB00;1106 116C 11AB;BB00;1106 116C 11AB; +BB01;BB01;1106 116C 11AC;BB01;1106 116C 11AC; +BB02;BB02;1106 116C 11AD;BB02;1106 116C 11AD; +BB03;BB03;1106 116C 11AE;BB03;1106 116C 11AE; +BB04;BB04;1106 116C 11AF;BB04;1106 116C 11AF; +BB05;BB05;1106 116C 11B0;BB05;1106 116C 11B0; +BB06;BB06;1106 116C 11B1;BB06;1106 116C 11B1; +BB07;BB07;1106 116C 11B2;BB07;1106 116C 11B2; +BB08;BB08;1106 116C 11B3;BB08;1106 116C 11B3; +BB09;BB09;1106 116C 11B4;BB09;1106 116C 11B4; +BB0A;BB0A;1106 116C 11B5;BB0A;1106 116C 11B5; +BB0B;BB0B;1106 116C 11B6;BB0B;1106 116C 11B6; +BB0C;BB0C;1106 116C 11B7;BB0C;1106 116C 11B7; +BB0D;BB0D;1106 116C 11B8;BB0D;1106 116C 11B8; +BB0E;BB0E;1106 116C 11B9;BB0E;1106 116C 11B9; +BB0F;BB0F;1106 116C 11BA;BB0F;1106 116C 11BA; +BB10;BB10;1106 116C 11BB;BB10;1106 116C 11BB; +BB11;BB11;1106 116C 11BC;BB11;1106 116C 11BC; +BB12;BB12;1106 116C 11BD;BB12;1106 116C 11BD; +BB13;BB13;1106 116C 11BE;BB13;1106 116C 11BE; +BB14;BB14;1106 116C 11BF;BB14;1106 116C 11BF; +BB15;BB15;1106 116C 11C0;BB15;1106 116C 11C0; +BB16;BB16;1106 116C 11C1;BB16;1106 116C 11C1; +BB17;BB17;1106 116C 11C2;BB17;1106 116C 11C2; +BB18;BB18;1106 116D;BB18;1106 116D; +BB19;BB19;1106 116D 11A8;BB19;1106 116D 11A8; +BB1A;BB1A;1106 116D 11A9;BB1A;1106 116D 11A9; +BB1B;BB1B;1106 116D 11AA;BB1B;1106 116D 11AA; +BB1C;BB1C;1106 116D 11AB;BB1C;1106 116D 11AB; +BB1D;BB1D;1106 116D 11AC;BB1D;1106 116D 11AC; +BB1E;BB1E;1106 116D 11AD;BB1E;1106 116D 11AD; +BB1F;BB1F;1106 116D 11AE;BB1F;1106 116D 11AE; +BB20;BB20;1106 116D 11AF;BB20;1106 116D 11AF; +BB21;BB21;1106 116D 11B0;BB21;1106 116D 11B0; +BB22;BB22;1106 116D 11B1;BB22;1106 116D 11B1; +BB23;BB23;1106 116D 11B2;BB23;1106 116D 11B2; +BB24;BB24;1106 116D 11B3;BB24;1106 116D 11B3; +BB25;BB25;1106 116D 11B4;BB25;1106 116D 11B4; +BB26;BB26;1106 116D 11B5;BB26;1106 116D 11B5; +BB27;BB27;1106 116D 11B6;BB27;1106 116D 11B6; +BB28;BB28;1106 116D 11B7;BB28;1106 116D 11B7; +BB29;BB29;1106 116D 11B8;BB29;1106 116D 11B8; +BB2A;BB2A;1106 116D 11B9;BB2A;1106 116D 11B9; +BB2B;BB2B;1106 116D 11BA;BB2B;1106 116D 11BA; +BB2C;BB2C;1106 116D 11BB;BB2C;1106 116D 11BB; +BB2D;BB2D;1106 116D 11BC;BB2D;1106 116D 11BC; +BB2E;BB2E;1106 116D 11BD;BB2E;1106 116D 11BD; +BB2F;BB2F;1106 116D 11BE;BB2F;1106 116D 11BE; +BB30;BB30;1106 116D 11BF;BB30;1106 116D 11BF; +BB31;BB31;1106 116D 11C0;BB31;1106 116D 11C0; +BB32;BB32;1106 116D 11C1;BB32;1106 116D 11C1; +BB33;BB33;1106 116D 11C2;BB33;1106 116D 11C2; +BB34;BB34;1106 116E;BB34;1106 116E; +BB35;BB35;1106 116E 11A8;BB35;1106 116E 11A8; +BB36;BB36;1106 116E 11A9;BB36;1106 116E 11A9; +BB37;BB37;1106 116E 11AA;BB37;1106 116E 11AA; +BB38;BB38;1106 116E 11AB;BB38;1106 116E 11AB; +BB39;BB39;1106 116E 11AC;BB39;1106 116E 11AC; +BB3A;BB3A;1106 116E 11AD;BB3A;1106 116E 11AD; +BB3B;BB3B;1106 116E 11AE;BB3B;1106 116E 11AE; +BB3C;BB3C;1106 116E 11AF;BB3C;1106 116E 11AF; +BB3D;BB3D;1106 116E 11B0;BB3D;1106 116E 11B0; +BB3E;BB3E;1106 116E 11B1;BB3E;1106 116E 11B1; +BB3F;BB3F;1106 116E 11B2;BB3F;1106 116E 11B2; +BB40;BB40;1106 116E 11B3;BB40;1106 116E 11B3; +BB41;BB41;1106 116E 11B4;BB41;1106 116E 11B4; +BB42;BB42;1106 116E 11B5;BB42;1106 116E 11B5; +BB43;BB43;1106 116E 11B6;BB43;1106 116E 11B6; +BB44;BB44;1106 116E 11B7;BB44;1106 116E 11B7; +BB45;BB45;1106 116E 11B8;BB45;1106 116E 11B8; +BB46;BB46;1106 116E 11B9;BB46;1106 116E 11B9; +BB47;BB47;1106 116E 11BA;BB47;1106 116E 11BA; +BB48;BB48;1106 116E 11BB;BB48;1106 116E 11BB; +BB49;BB49;1106 116E 11BC;BB49;1106 116E 11BC; +BB4A;BB4A;1106 116E 11BD;BB4A;1106 116E 11BD; +BB4B;BB4B;1106 116E 11BE;BB4B;1106 116E 11BE; +BB4C;BB4C;1106 116E 11BF;BB4C;1106 116E 11BF; +BB4D;BB4D;1106 116E 11C0;BB4D;1106 116E 11C0; +BB4E;BB4E;1106 116E 11C1;BB4E;1106 116E 11C1; +BB4F;BB4F;1106 116E 11C2;BB4F;1106 116E 11C2; +BB50;BB50;1106 116F;BB50;1106 116F; +BB51;BB51;1106 116F 11A8;BB51;1106 116F 11A8; +BB52;BB52;1106 116F 11A9;BB52;1106 116F 11A9; +BB53;BB53;1106 116F 11AA;BB53;1106 116F 11AA; +BB54;BB54;1106 116F 11AB;BB54;1106 116F 11AB; +BB55;BB55;1106 116F 11AC;BB55;1106 116F 11AC; +BB56;BB56;1106 116F 11AD;BB56;1106 116F 11AD; +BB57;BB57;1106 116F 11AE;BB57;1106 116F 11AE; +BB58;BB58;1106 116F 11AF;BB58;1106 116F 11AF; +BB59;BB59;1106 116F 11B0;BB59;1106 116F 11B0; +BB5A;BB5A;1106 116F 11B1;BB5A;1106 116F 11B1; +BB5B;BB5B;1106 116F 11B2;BB5B;1106 116F 11B2; +BB5C;BB5C;1106 116F 11B3;BB5C;1106 116F 11B3; +BB5D;BB5D;1106 116F 11B4;BB5D;1106 116F 11B4; +BB5E;BB5E;1106 116F 11B5;BB5E;1106 116F 11B5; +BB5F;BB5F;1106 116F 11B6;BB5F;1106 116F 11B6; +BB60;BB60;1106 116F 11B7;BB60;1106 116F 11B7; +BB61;BB61;1106 116F 11B8;BB61;1106 116F 11B8; +BB62;BB62;1106 116F 11B9;BB62;1106 116F 11B9; +BB63;BB63;1106 116F 11BA;BB63;1106 116F 11BA; +BB64;BB64;1106 116F 11BB;BB64;1106 116F 11BB; +BB65;BB65;1106 116F 11BC;BB65;1106 116F 11BC; +BB66;BB66;1106 116F 11BD;BB66;1106 116F 11BD; +BB67;BB67;1106 116F 11BE;BB67;1106 116F 11BE; +BB68;BB68;1106 116F 11BF;BB68;1106 116F 11BF; +BB69;BB69;1106 116F 11C0;BB69;1106 116F 11C0; +BB6A;BB6A;1106 116F 11C1;BB6A;1106 116F 11C1; +BB6B;BB6B;1106 116F 11C2;BB6B;1106 116F 11C2; +BB6C;BB6C;1106 1170;BB6C;1106 1170; +BB6D;BB6D;1106 1170 11A8;BB6D;1106 1170 11A8; +BB6E;BB6E;1106 1170 11A9;BB6E;1106 1170 11A9; +BB6F;BB6F;1106 1170 11AA;BB6F;1106 1170 11AA; +BB70;BB70;1106 1170 11AB;BB70;1106 1170 11AB; +BB71;BB71;1106 1170 11AC;BB71;1106 1170 11AC; +BB72;BB72;1106 1170 11AD;BB72;1106 1170 11AD; +BB73;BB73;1106 1170 11AE;BB73;1106 1170 11AE; +BB74;BB74;1106 1170 11AF;BB74;1106 1170 11AF; +BB75;BB75;1106 1170 11B0;BB75;1106 1170 11B0; +BB76;BB76;1106 1170 11B1;BB76;1106 1170 11B1; +BB77;BB77;1106 1170 11B2;BB77;1106 1170 11B2; +BB78;BB78;1106 1170 11B3;BB78;1106 1170 11B3; +BB79;BB79;1106 1170 11B4;BB79;1106 1170 11B4; +BB7A;BB7A;1106 1170 11B5;BB7A;1106 1170 11B5; +BB7B;BB7B;1106 1170 11B6;BB7B;1106 1170 11B6; +BB7C;BB7C;1106 1170 11B7;BB7C;1106 1170 11B7; +BB7D;BB7D;1106 1170 11B8;BB7D;1106 1170 11B8; +BB7E;BB7E;1106 1170 11B9;BB7E;1106 1170 11B9; +BB7F;BB7F;1106 1170 11BA;BB7F;1106 1170 11BA; +BB80;BB80;1106 1170 11BB;BB80;1106 1170 11BB; +BB81;BB81;1106 1170 11BC;BB81;1106 1170 11BC; +BB82;BB82;1106 1170 11BD;BB82;1106 1170 11BD; +BB83;BB83;1106 1170 11BE;BB83;1106 1170 11BE; +BB84;BB84;1106 1170 11BF;BB84;1106 1170 11BF; +BB85;BB85;1106 1170 11C0;BB85;1106 1170 11C0; +BB86;BB86;1106 1170 11C1;BB86;1106 1170 11C1; +BB87;BB87;1106 1170 11C2;BB87;1106 1170 11C2; +BB88;BB88;1106 1171;BB88;1106 1171; +BB89;BB89;1106 1171 11A8;BB89;1106 1171 11A8; +BB8A;BB8A;1106 1171 11A9;BB8A;1106 1171 11A9; +BB8B;BB8B;1106 1171 11AA;BB8B;1106 1171 11AA; +BB8C;BB8C;1106 1171 11AB;BB8C;1106 1171 11AB; +BB8D;BB8D;1106 1171 11AC;BB8D;1106 1171 11AC; +BB8E;BB8E;1106 1171 11AD;BB8E;1106 1171 11AD; +BB8F;BB8F;1106 1171 11AE;BB8F;1106 1171 11AE; +BB90;BB90;1106 1171 11AF;BB90;1106 1171 11AF; +BB91;BB91;1106 1171 11B0;BB91;1106 1171 11B0; +BB92;BB92;1106 1171 11B1;BB92;1106 1171 11B1; +BB93;BB93;1106 1171 11B2;BB93;1106 1171 11B2; +BB94;BB94;1106 1171 11B3;BB94;1106 1171 11B3; +BB95;BB95;1106 1171 11B4;BB95;1106 1171 11B4; +BB96;BB96;1106 1171 11B5;BB96;1106 1171 11B5; +BB97;BB97;1106 1171 11B6;BB97;1106 1171 11B6; +BB98;BB98;1106 1171 11B7;BB98;1106 1171 11B7; +BB99;BB99;1106 1171 11B8;BB99;1106 1171 11B8; +BB9A;BB9A;1106 1171 11B9;BB9A;1106 1171 11B9; +BB9B;BB9B;1106 1171 11BA;BB9B;1106 1171 11BA; +BB9C;BB9C;1106 1171 11BB;BB9C;1106 1171 11BB; +BB9D;BB9D;1106 1171 11BC;BB9D;1106 1171 11BC; +BB9E;BB9E;1106 1171 11BD;BB9E;1106 1171 11BD; +BB9F;BB9F;1106 1171 11BE;BB9F;1106 1171 11BE; +BBA0;BBA0;1106 1171 11BF;BBA0;1106 1171 11BF; +BBA1;BBA1;1106 1171 11C0;BBA1;1106 1171 11C0; +BBA2;BBA2;1106 1171 11C1;BBA2;1106 1171 11C1; +BBA3;BBA3;1106 1171 11C2;BBA3;1106 1171 11C2; +BBA4;BBA4;1106 1172;BBA4;1106 1172; +BBA5;BBA5;1106 1172 11A8;BBA5;1106 1172 11A8; +BBA6;BBA6;1106 1172 11A9;BBA6;1106 1172 11A9; +BBA7;BBA7;1106 1172 11AA;BBA7;1106 1172 11AA; +BBA8;BBA8;1106 1172 11AB;BBA8;1106 1172 11AB; +BBA9;BBA9;1106 1172 11AC;BBA9;1106 1172 11AC; +BBAA;BBAA;1106 1172 11AD;BBAA;1106 1172 11AD; +BBAB;BBAB;1106 1172 11AE;BBAB;1106 1172 11AE; +BBAC;BBAC;1106 1172 11AF;BBAC;1106 1172 11AF; +BBAD;BBAD;1106 1172 11B0;BBAD;1106 1172 11B0; +BBAE;BBAE;1106 1172 11B1;BBAE;1106 1172 11B1; +BBAF;BBAF;1106 1172 11B2;BBAF;1106 1172 11B2; +BBB0;BBB0;1106 1172 11B3;BBB0;1106 1172 11B3; +BBB1;BBB1;1106 1172 11B4;BBB1;1106 1172 11B4; +BBB2;BBB2;1106 1172 11B5;BBB2;1106 1172 11B5; +BBB3;BBB3;1106 1172 11B6;BBB3;1106 1172 11B6; +BBB4;BBB4;1106 1172 11B7;BBB4;1106 1172 11B7; +BBB5;BBB5;1106 1172 11B8;BBB5;1106 1172 11B8; +BBB6;BBB6;1106 1172 11B9;BBB6;1106 1172 11B9; +BBB7;BBB7;1106 1172 11BA;BBB7;1106 1172 11BA; +BBB8;BBB8;1106 1172 11BB;BBB8;1106 1172 11BB; +BBB9;BBB9;1106 1172 11BC;BBB9;1106 1172 11BC; +BBBA;BBBA;1106 1172 11BD;BBBA;1106 1172 11BD; +BBBB;BBBB;1106 1172 11BE;BBBB;1106 1172 11BE; +BBBC;BBBC;1106 1172 11BF;BBBC;1106 1172 11BF; +BBBD;BBBD;1106 1172 11C0;BBBD;1106 1172 11C0; +BBBE;BBBE;1106 1172 11C1;BBBE;1106 1172 11C1; +BBBF;BBBF;1106 1172 11C2;BBBF;1106 1172 11C2; +BBC0;BBC0;1106 1173;BBC0;1106 1173; +BBC1;BBC1;1106 1173 11A8;BBC1;1106 1173 11A8; +BBC2;BBC2;1106 1173 11A9;BBC2;1106 1173 11A9; +BBC3;BBC3;1106 1173 11AA;BBC3;1106 1173 11AA; +BBC4;BBC4;1106 1173 11AB;BBC4;1106 1173 11AB; +BBC5;BBC5;1106 1173 11AC;BBC5;1106 1173 11AC; +BBC6;BBC6;1106 1173 11AD;BBC6;1106 1173 11AD; +BBC7;BBC7;1106 1173 11AE;BBC7;1106 1173 11AE; +BBC8;BBC8;1106 1173 11AF;BBC8;1106 1173 11AF; +BBC9;BBC9;1106 1173 11B0;BBC9;1106 1173 11B0; +BBCA;BBCA;1106 1173 11B1;BBCA;1106 1173 11B1; +BBCB;BBCB;1106 1173 11B2;BBCB;1106 1173 11B2; +BBCC;BBCC;1106 1173 11B3;BBCC;1106 1173 11B3; +BBCD;BBCD;1106 1173 11B4;BBCD;1106 1173 11B4; +BBCE;BBCE;1106 1173 11B5;BBCE;1106 1173 11B5; +BBCF;BBCF;1106 1173 11B6;BBCF;1106 1173 11B6; +BBD0;BBD0;1106 1173 11B7;BBD0;1106 1173 11B7; +BBD1;BBD1;1106 1173 11B8;BBD1;1106 1173 11B8; +BBD2;BBD2;1106 1173 11B9;BBD2;1106 1173 11B9; +BBD3;BBD3;1106 1173 11BA;BBD3;1106 1173 11BA; +BBD4;BBD4;1106 1173 11BB;BBD4;1106 1173 11BB; +BBD5;BBD5;1106 1173 11BC;BBD5;1106 1173 11BC; +BBD6;BBD6;1106 1173 11BD;BBD6;1106 1173 11BD; +BBD7;BBD7;1106 1173 11BE;BBD7;1106 1173 11BE; +BBD8;BBD8;1106 1173 11BF;BBD8;1106 1173 11BF; +BBD9;BBD9;1106 1173 11C0;BBD9;1106 1173 11C0; +BBDA;BBDA;1106 1173 11C1;BBDA;1106 1173 11C1; +BBDB;BBDB;1106 1173 11C2;BBDB;1106 1173 11C2; +BBDC;BBDC;1106 1174;BBDC;1106 1174; +BBDD;BBDD;1106 1174 11A8;BBDD;1106 1174 11A8; +BBDE;BBDE;1106 1174 11A9;BBDE;1106 1174 11A9; +BBDF;BBDF;1106 1174 11AA;BBDF;1106 1174 11AA; +BBE0;BBE0;1106 1174 11AB;BBE0;1106 1174 11AB; +BBE1;BBE1;1106 1174 11AC;BBE1;1106 1174 11AC; +BBE2;BBE2;1106 1174 11AD;BBE2;1106 1174 11AD; +BBE3;BBE3;1106 1174 11AE;BBE3;1106 1174 11AE; +BBE4;BBE4;1106 1174 11AF;BBE4;1106 1174 11AF; +BBE5;BBE5;1106 1174 11B0;BBE5;1106 1174 11B0; +BBE6;BBE6;1106 1174 11B1;BBE6;1106 1174 11B1; +BBE7;BBE7;1106 1174 11B2;BBE7;1106 1174 11B2; +BBE8;BBE8;1106 1174 11B3;BBE8;1106 1174 11B3; +BBE9;BBE9;1106 1174 11B4;BBE9;1106 1174 11B4; +BBEA;BBEA;1106 1174 11B5;BBEA;1106 1174 11B5; +BBEB;BBEB;1106 1174 11B6;BBEB;1106 1174 11B6; +BBEC;BBEC;1106 1174 11B7;BBEC;1106 1174 11B7; +BBED;BBED;1106 1174 11B8;BBED;1106 1174 11B8; +BBEE;BBEE;1106 1174 11B9;BBEE;1106 1174 11B9; +BBEF;BBEF;1106 1174 11BA;BBEF;1106 1174 11BA; +BBF0;BBF0;1106 1174 11BB;BBF0;1106 1174 11BB; +BBF1;BBF1;1106 1174 11BC;BBF1;1106 1174 11BC; +BBF2;BBF2;1106 1174 11BD;BBF2;1106 1174 11BD; +BBF3;BBF3;1106 1174 11BE;BBF3;1106 1174 11BE; +BBF4;BBF4;1106 1174 11BF;BBF4;1106 1174 11BF; +BBF5;BBF5;1106 1174 11C0;BBF5;1106 1174 11C0; +BBF6;BBF6;1106 1174 11C1;BBF6;1106 1174 11C1; +BBF7;BBF7;1106 1174 11C2;BBF7;1106 1174 11C2; +BBF8;BBF8;1106 1175;BBF8;1106 1175; +BBF9;BBF9;1106 1175 11A8;BBF9;1106 1175 11A8; +BBFA;BBFA;1106 1175 11A9;BBFA;1106 1175 11A9; +BBFB;BBFB;1106 1175 11AA;BBFB;1106 1175 11AA; +BBFC;BBFC;1106 1175 11AB;BBFC;1106 1175 11AB; +BBFD;BBFD;1106 1175 11AC;BBFD;1106 1175 11AC; +BBFE;BBFE;1106 1175 11AD;BBFE;1106 1175 11AD; +BBFF;BBFF;1106 1175 11AE;BBFF;1106 1175 11AE; +BC00;BC00;1106 1175 11AF;BC00;1106 1175 11AF; +BC01;BC01;1106 1175 11B0;BC01;1106 1175 11B0; +BC02;BC02;1106 1175 11B1;BC02;1106 1175 11B1; +BC03;BC03;1106 1175 11B2;BC03;1106 1175 11B2; +BC04;BC04;1106 1175 11B3;BC04;1106 1175 11B3; +BC05;BC05;1106 1175 11B4;BC05;1106 1175 11B4; +BC06;BC06;1106 1175 11B5;BC06;1106 1175 11B5; +BC07;BC07;1106 1175 11B6;BC07;1106 1175 11B6; +BC08;BC08;1106 1175 11B7;BC08;1106 1175 11B7; +BC09;BC09;1106 1175 11B8;BC09;1106 1175 11B8; +BC0A;BC0A;1106 1175 11B9;BC0A;1106 1175 11B9; +BC0B;BC0B;1106 1175 11BA;BC0B;1106 1175 11BA; +BC0C;BC0C;1106 1175 11BB;BC0C;1106 1175 11BB; +BC0D;BC0D;1106 1175 11BC;BC0D;1106 1175 11BC; +BC0E;BC0E;1106 1175 11BD;BC0E;1106 1175 11BD; +BC0F;BC0F;1106 1175 11BE;BC0F;1106 1175 11BE; +BC10;BC10;1106 1175 11BF;BC10;1106 1175 11BF; +BC11;BC11;1106 1175 11C0;BC11;1106 1175 11C0; +BC12;BC12;1106 1175 11C1;BC12;1106 1175 11C1; +BC13;BC13;1106 1175 11C2;BC13;1106 1175 11C2; +BC14;BC14;1107 1161;BC14;1107 1161; +BC15;BC15;1107 1161 11A8;BC15;1107 1161 11A8; +BC16;BC16;1107 1161 11A9;BC16;1107 1161 11A9; +BC17;BC17;1107 1161 11AA;BC17;1107 1161 11AA; +BC18;BC18;1107 1161 11AB;BC18;1107 1161 11AB; +BC19;BC19;1107 1161 11AC;BC19;1107 1161 11AC; +BC1A;BC1A;1107 1161 11AD;BC1A;1107 1161 11AD; +BC1B;BC1B;1107 1161 11AE;BC1B;1107 1161 11AE; +BC1C;BC1C;1107 1161 11AF;BC1C;1107 1161 11AF; +BC1D;BC1D;1107 1161 11B0;BC1D;1107 1161 11B0; +BC1E;BC1E;1107 1161 11B1;BC1E;1107 1161 11B1; +BC1F;BC1F;1107 1161 11B2;BC1F;1107 1161 11B2; +BC20;BC20;1107 1161 11B3;BC20;1107 1161 11B3; +BC21;BC21;1107 1161 11B4;BC21;1107 1161 11B4; +BC22;BC22;1107 1161 11B5;BC22;1107 1161 11B5; +BC23;BC23;1107 1161 11B6;BC23;1107 1161 11B6; +BC24;BC24;1107 1161 11B7;BC24;1107 1161 11B7; +BC25;BC25;1107 1161 11B8;BC25;1107 1161 11B8; +BC26;BC26;1107 1161 11B9;BC26;1107 1161 11B9; +BC27;BC27;1107 1161 11BA;BC27;1107 1161 11BA; +BC28;BC28;1107 1161 11BB;BC28;1107 1161 11BB; +BC29;BC29;1107 1161 11BC;BC29;1107 1161 11BC; +BC2A;BC2A;1107 1161 11BD;BC2A;1107 1161 11BD; +BC2B;BC2B;1107 1161 11BE;BC2B;1107 1161 11BE; +BC2C;BC2C;1107 1161 11BF;BC2C;1107 1161 11BF; +BC2D;BC2D;1107 1161 11C0;BC2D;1107 1161 11C0; +BC2E;BC2E;1107 1161 11C1;BC2E;1107 1161 11C1; +BC2F;BC2F;1107 1161 11C2;BC2F;1107 1161 11C2; +BC30;BC30;1107 1162;BC30;1107 1162; +BC31;BC31;1107 1162 11A8;BC31;1107 1162 11A8; +BC32;BC32;1107 1162 11A9;BC32;1107 1162 11A9; +BC33;BC33;1107 1162 11AA;BC33;1107 1162 11AA; +BC34;BC34;1107 1162 11AB;BC34;1107 1162 11AB; +BC35;BC35;1107 1162 11AC;BC35;1107 1162 11AC; +BC36;BC36;1107 1162 11AD;BC36;1107 1162 11AD; +BC37;BC37;1107 1162 11AE;BC37;1107 1162 11AE; +BC38;BC38;1107 1162 11AF;BC38;1107 1162 11AF; +BC39;BC39;1107 1162 11B0;BC39;1107 1162 11B0; +BC3A;BC3A;1107 1162 11B1;BC3A;1107 1162 11B1; +BC3B;BC3B;1107 1162 11B2;BC3B;1107 1162 11B2; +BC3C;BC3C;1107 1162 11B3;BC3C;1107 1162 11B3; +BC3D;BC3D;1107 1162 11B4;BC3D;1107 1162 11B4; +BC3E;BC3E;1107 1162 11B5;BC3E;1107 1162 11B5; +BC3F;BC3F;1107 1162 11B6;BC3F;1107 1162 11B6; +BC40;BC40;1107 1162 11B7;BC40;1107 1162 11B7; +BC41;BC41;1107 1162 11B8;BC41;1107 1162 11B8; +BC42;BC42;1107 1162 11B9;BC42;1107 1162 11B9; +BC43;BC43;1107 1162 11BA;BC43;1107 1162 11BA; +BC44;BC44;1107 1162 11BB;BC44;1107 1162 11BB; +BC45;BC45;1107 1162 11BC;BC45;1107 1162 11BC; +BC46;BC46;1107 1162 11BD;BC46;1107 1162 11BD; +BC47;BC47;1107 1162 11BE;BC47;1107 1162 11BE; +BC48;BC48;1107 1162 11BF;BC48;1107 1162 11BF; +BC49;BC49;1107 1162 11C0;BC49;1107 1162 11C0; +BC4A;BC4A;1107 1162 11C1;BC4A;1107 1162 11C1; +BC4B;BC4B;1107 1162 11C2;BC4B;1107 1162 11C2; +BC4C;BC4C;1107 1163;BC4C;1107 1163; +BC4D;BC4D;1107 1163 11A8;BC4D;1107 1163 11A8; +BC4E;BC4E;1107 1163 11A9;BC4E;1107 1163 11A9; +BC4F;BC4F;1107 1163 11AA;BC4F;1107 1163 11AA; +BC50;BC50;1107 1163 11AB;BC50;1107 1163 11AB; +BC51;BC51;1107 1163 11AC;BC51;1107 1163 11AC; +BC52;BC52;1107 1163 11AD;BC52;1107 1163 11AD; +BC53;BC53;1107 1163 11AE;BC53;1107 1163 11AE; +BC54;BC54;1107 1163 11AF;BC54;1107 1163 11AF; +BC55;BC55;1107 1163 11B0;BC55;1107 1163 11B0; +BC56;BC56;1107 1163 11B1;BC56;1107 1163 11B1; +BC57;BC57;1107 1163 11B2;BC57;1107 1163 11B2; +BC58;BC58;1107 1163 11B3;BC58;1107 1163 11B3; +BC59;BC59;1107 1163 11B4;BC59;1107 1163 11B4; +BC5A;BC5A;1107 1163 11B5;BC5A;1107 1163 11B5; +BC5B;BC5B;1107 1163 11B6;BC5B;1107 1163 11B6; +BC5C;BC5C;1107 1163 11B7;BC5C;1107 1163 11B7; +BC5D;BC5D;1107 1163 11B8;BC5D;1107 1163 11B8; +BC5E;BC5E;1107 1163 11B9;BC5E;1107 1163 11B9; +BC5F;BC5F;1107 1163 11BA;BC5F;1107 1163 11BA; +BC60;BC60;1107 1163 11BB;BC60;1107 1163 11BB; +BC61;BC61;1107 1163 11BC;BC61;1107 1163 11BC; +BC62;BC62;1107 1163 11BD;BC62;1107 1163 11BD; +BC63;BC63;1107 1163 11BE;BC63;1107 1163 11BE; +BC64;BC64;1107 1163 11BF;BC64;1107 1163 11BF; +BC65;BC65;1107 1163 11C0;BC65;1107 1163 11C0; +BC66;BC66;1107 1163 11C1;BC66;1107 1163 11C1; +BC67;BC67;1107 1163 11C2;BC67;1107 1163 11C2; +BC68;BC68;1107 1164;BC68;1107 1164; +BC69;BC69;1107 1164 11A8;BC69;1107 1164 11A8; +BC6A;BC6A;1107 1164 11A9;BC6A;1107 1164 11A9; +BC6B;BC6B;1107 1164 11AA;BC6B;1107 1164 11AA; +BC6C;BC6C;1107 1164 11AB;BC6C;1107 1164 11AB; +BC6D;BC6D;1107 1164 11AC;BC6D;1107 1164 11AC; +BC6E;BC6E;1107 1164 11AD;BC6E;1107 1164 11AD; +BC6F;BC6F;1107 1164 11AE;BC6F;1107 1164 11AE; +BC70;BC70;1107 1164 11AF;BC70;1107 1164 11AF; +BC71;BC71;1107 1164 11B0;BC71;1107 1164 11B0; +BC72;BC72;1107 1164 11B1;BC72;1107 1164 11B1; +BC73;BC73;1107 1164 11B2;BC73;1107 1164 11B2; +BC74;BC74;1107 1164 11B3;BC74;1107 1164 11B3; +BC75;BC75;1107 1164 11B4;BC75;1107 1164 11B4; +BC76;BC76;1107 1164 11B5;BC76;1107 1164 11B5; +BC77;BC77;1107 1164 11B6;BC77;1107 1164 11B6; +BC78;BC78;1107 1164 11B7;BC78;1107 1164 11B7; +BC79;BC79;1107 1164 11B8;BC79;1107 1164 11B8; +BC7A;BC7A;1107 1164 11B9;BC7A;1107 1164 11B9; +BC7B;BC7B;1107 1164 11BA;BC7B;1107 1164 11BA; +BC7C;BC7C;1107 1164 11BB;BC7C;1107 1164 11BB; +BC7D;BC7D;1107 1164 11BC;BC7D;1107 1164 11BC; +BC7E;BC7E;1107 1164 11BD;BC7E;1107 1164 11BD; +BC7F;BC7F;1107 1164 11BE;BC7F;1107 1164 11BE; +BC80;BC80;1107 1164 11BF;BC80;1107 1164 11BF; +BC81;BC81;1107 1164 11C0;BC81;1107 1164 11C0; +BC82;BC82;1107 1164 11C1;BC82;1107 1164 11C1; +BC83;BC83;1107 1164 11C2;BC83;1107 1164 11C2; +BC84;BC84;1107 1165;BC84;1107 1165; +BC85;BC85;1107 1165 11A8;BC85;1107 1165 11A8; +BC86;BC86;1107 1165 11A9;BC86;1107 1165 11A9; +BC87;BC87;1107 1165 11AA;BC87;1107 1165 11AA; +BC88;BC88;1107 1165 11AB;BC88;1107 1165 11AB; +BC89;BC89;1107 1165 11AC;BC89;1107 1165 11AC; +BC8A;BC8A;1107 1165 11AD;BC8A;1107 1165 11AD; +BC8B;BC8B;1107 1165 11AE;BC8B;1107 1165 11AE; +BC8C;BC8C;1107 1165 11AF;BC8C;1107 1165 11AF; +BC8D;BC8D;1107 1165 11B0;BC8D;1107 1165 11B0; +BC8E;BC8E;1107 1165 11B1;BC8E;1107 1165 11B1; +BC8F;BC8F;1107 1165 11B2;BC8F;1107 1165 11B2; +BC90;BC90;1107 1165 11B3;BC90;1107 1165 11B3; +BC91;BC91;1107 1165 11B4;BC91;1107 1165 11B4; +BC92;BC92;1107 1165 11B5;BC92;1107 1165 11B5; +BC93;BC93;1107 1165 11B6;BC93;1107 1165 11B6; +BC94;BC94;1107 1165 11B7;BC94;1107 1165 11B7; +BC95;BC95;1107 1165 11B8;BC95;1107 1165 11B8; +BC96;BC96;1107 1165 11B9;BC96;1107 1165 11B9; +BC97;BC97;1107 1165 11BA;BC97;1107 1165 11BA; +BC98;BC98;1107 1165 11BB;BC98;1107 1165 11BB; +BC99;BC99;1107 1165 11BC;BC99;1107 1165 11BC; +BC9A;BC9A;1107 1165 11BD;BC9A;1107 1165 11BD; +BC9B;BC9B;1107 1165 11BE;BC9B;1107 1165 11BE; +BC9C;BC9C;1107 1165 11BF;BC9C;1107 1165 11BF; +BC9D;BC9D;1107 1165 11C0;BC9D;1107 1165 11C0; +BC9E;BC9E;1107 1165 11C1;BC9E;1107 1165 11C1; +BC9F;BC9F;1107 1165 11C2;BC9F;1107 1165 11C2; +BCA0;BCA0;1107 1166;BCA0;1107 1166; +BCA1;BCA1;1107 1166 11A8;BCA1;1107 1166 11A8; +BCA2;BCA2;1107 1166 11A9;BCA2;1107 1166 11A9; +BCA3;BCA3;1107 1166 11AA;BCA3;1107 1166 11AA; +BCA4;BCA4;1107 1166 11AB;BCA4;1107 1166 11AB; +BCA5;BCA5;1107 1166 11AC;BCA5;1107 1166 11AC; +BCA6;BCA6;1107 1166 11AD;BCA6;1107 1166 11AD; +BCA7;BCA7;1107 1166 11AE;BCA7;1107 1166 11AE; +BCA8;BCA8;1107 1166 11AF;BCA8;1107 1166 11AF; +BCA9;BCA9;1107 1166 11B0;BCA9;1107 1166 11B0; +BCAA;BCAA;1107 1166 11B1;BCAA;1107 1166 11B1; +BCAB;BCAB;1107 1166 11B2;BCAB;1107 1166 11B2; +BCAC;BCAC;1107 1166 11B3;BCAC;1107 1166 11B3; +BCAD;BCAD;1107 1166 11B4;BCAD;1107 1166 11B4; +BCAE;BCAE;1107 1166 11B5;BCAE;1107 1166 11B5; +BCAF;BCAF;1107 1166 11B6;BCAF;1107 1166 11B6; +BCB0;BCB0;1107 1166 11B7;BCB0;1107 1166 11B7; +BCB1;BCB1;1107 1166 11B8;BCB1;1107 1166 11B8; +BCB2;BCB2;1107 1166 11B9;BCB2;1107 1166 11B9; +BCB3;BCB3;1107 1166 11BA;BCB3;1107 1166 11BA; +BCB4;BCB4;1107 1166 11BB;BCB4;1107 1166 11BB; +BCB5;BCB5;1107 1166 11BC;BCB5;1107 1166 11BC; +BCB6;BCB6;1107 1166 11BD;BCB6;1107 1166 11BD; +BCB7;BCB7;1107 1166 11BE;BCB7;1107 1166 11BE; +BCB8;BCB8;1107 1166 11BF;BCB8;1107 1166 11BF; +BCB9;BCB9;1107 1166 11C0;BCB9;1107 1166 11C0; +BCBA;BCBA;1107 1166 11C1;BCBA;1107 1166 11C1; +BCBB;BCBB;1107 1166 11C2;BCBB;1107 1166 11C2; +BCBC;BCBC;1107 1167;BCBC;1107 1167; +BCBD;BCBD;1107 1167 11A8;BCBD;1107 1167 11A8; +BCBE;BCBE;1107 1167 11A9;BCBE;1107 1167 11A9; +BCBF;BCBF;1107 1167 11AA;BCBF;1107 1167 11AA; +BCC0;BCC0;1107 1167 11AB;BCC0;1107 1167 11AB; +BCC1;BCC1;1107 1167 11AC;BCC1;1107 1167 11AC; +BCC2;BCC2;1107 1167 11AD;BCC2;1107 1167 11AD; +BCC3;BCC3;1107 1167 11AE;BCC3;1107 1167 11AE; +BCC4;BCC4;1107 1167 11AF;BCC4;1107 1167 11AF; +BCC5;BCC5;1107 1167 11B0;BCC5;1107 1167 11B0; +BCC6;BCC6;1107 1167 11B1;BCC6;1107 1167 11B1; +BCC7;BCC7;1107 1167 11B2;BCC7;1107 1167 11B2; +BCC8;BCC8;1107 1167 11B3;BCC8;1107 1167 11B3; +BCC9;BCC9;1107 1167 11B4;BCC9;1107 1167 11B4; +BCCA;BCCA;1107 1167 11B5;BCCA;1107 1167 11B5; +BCCB;BCCB;1107 1167 11B6;BCCB;1107 1167 11B6; +BCCC;BCCC;1107 1167 11B7;BCCC;1107 1167 11B7; +BCCD;BCCD;1107 1167 11B8;BCCD;1107 1167 11B8; +BCCE;BCCE;1107 1167 11B9;BCCE;1107 1167 11B9; +BCCF;BCCF;1107 1167 11BA;BCCF;1107 1167 11BA; +BCD0;BCD0;1107 1167 11BB;BCD0;1107 1167 11BB; +BCD1;BCD1;1107 1167 11BC;BCD1;1107 1167 11BC; +BCD2;BCD2;1107 1167 11BD;BCD2;1107 1167 11BD; +BCD3;BCD3;1107 1167 11BE;BCD3;1107 1167 11BE; +BCD4;BCD4;1107 1167 11BF;BCD4;1107 1167 11BF; +BCD5;BCD5;1107 1167 11C0;BCD5;1107 1167 11C0; +BCD6;BCD6;1107 1167 11C1;BCD6;1107 1167 11C1; +BCD7;BCD7;1107 1167 11C2;BCD7;1107 1167 11C2; +BCD8;BCD8;1107 1168;BCD8;1107 1168; +BCD9;BCD9;1107 1168 11A8;BCD9;1107 1168 11A8; +BCDA;BCDA;1107 1168 11A9;BCDA;1107 1168 11A9; +BCDB;BCDB;1107 1168 11AA;BCDB;1107 1168 11AA; +BCDC;BCDC;1107 1168 11AB;BCDC;1107 1168 11AB; +BCDD;BCDD;1107 1168 11AC;BCDD;1107 1168 11AC; +BCDE;BCDE;1107 1168 11AD;BCDE;1107 1168 11AD; +BCDF;BCDF;1107 1168 11AE;BCDF;1107 1168 11AE; +BCE0;BCE0;1107 1168 11AF;BCE0;1107 1168 11AF; +BCE1;BCE1;1107 1168 11B0;BCE1;1107 1168 11B0; +BCE2;BCE2;1107 1168 11B1;BCE2;1107 1168 11B1; +BCE3;BCE3;1107 1168 11B2;BCE3;1107 1168 11B2; +BCE4;BCE4;1107 1168 11B3;BCE4;1107 1168 11B3; +BCE5;BCE5;1107 1168 11B4;BCE5;1107 1168 11B4; +BCE6;BCE6;1107 1168 11B5;BCE6;1107 1168 11B5; +BCE7;BCE7;1107 1168 11B6;BCE7;1107 1168 11B6; +BCE8;BCE8;1107 1168 11B7;BCE8;1107 1168 11B7; +BCE9;BCE9;1107 1168 11B8;BCE9;1107 1168 11B8; +BCEA;BCEA;1107 1168 11B9;BCEA;1107 1168 11B9; +BCEB;BCEB;1107 1168 11BA;BCEB;1107 1168 11BA; +BCEC;BCEC;1107 1168 11BB;BCEC;1107 1168 11BB; +BCED;BCED;1107 1168 11BC;BCED;1107 1168 11BC; +BCEE;BCEE;1107 1168 11BD;BCEE;1107 1168 11BD; +BCEF;BCEF;1107 1168 11BE;BCEF;1107 1168 11BE; +BCF0;BCF0;1107 1168 11BF;BCF0;1107 1168 11BF; +BCF1;BCF1;1107 1168 11C0;BCF1;1107 1168 11C0; +BCF2;BCF2;1107 1168 11C1;BCF2;1107 1168 11C1; +BCF3;BCF3;1107 1168 11C2;BCF3;1107 1168 11C2; +BCF4;BCF4;1107 1169;BCF4;1107 1169; +BCF5;BCF5;1107 1169 11A8;BCF5;1107 1169 11A8; +BCF6;BCF6;1107 1169 11A9;BCF6;1107 1169 11A9; +BCF7;BCF7;1107 1169 11AA;BCF7;1107 1169 11AA; +BCF8;BCF8;1107 1169 11AB;BCF8;1107 1169 11AB; +BCF9;BCF9;1107 1169 11AC;BCF9;1107 1169 11AC; +BCFA;BCFA;1107 1169 11AD;BCFA;1107 1169 11AD; +BCFB;BCFB;1107 1169 11AE;BCFB;1107 1169 11AE; +BCFC;BCFC;1107 1169 11AF;BCFC;1107 1169 11AF; +BCFD;BCFD;1107 1169 11B0;BCFD;1107 1169 11B0; +BCFE;BCFE;1107 1169 11B1;BCFE;1107 1169 11B1; +BCFF;BCFF;1107 1169 11B2;BCFF;1107 1169 11B2; +BD00;BD00;1107 1169 11B3;BD00;1107 1169 11B3; +BD01;BD01;1107 1169 11B4;BD01;1107 1169 11B4; +BD02;BD02;1107 1169 11B5;BD02;1107 1169 11B5; +BD03;BD03;1107 1169 11B6;BD03;1107 1169 11B6; +BD04;BD04;1107 1169 11B7;BD04;1107 1169 11B7; +BD05;BD05;1107 1169 11B8;BD05;1107 1169 11B8; +BD06;BD06;1107 1169 11B9;BD06;1107 1169 11B9; +BD07;BD07;1107 1169 11BA;BD07;1107 1169 11BA; +BD08;BD08;1107 1169 11BB;BD08;1107 1169 11BB; +BD09;BD09;1107 1169 11BC;BD09;1107 1169 11BC; +BD0A;BD0A;1107 1169 11BD;BD0A;1107 1169 11BD; +BD0B;BD0B;1107 1169 11BE;BD0B;1107 1169 11BE; +BD0C;BD0C;1107 1169 11BF;BD0C;1107 1169 11BF; +BD0D;BD0D;1107 1169 11C0;BD0D;1107 1169 11C0; +BD0E;BD0E;1107 1169 11C1;BD0E;1107 1169 11C1; +BD0F;BD0F;1107 1169 11C2;BD0F;1107 1169 11C2; +BD10;BD10;1107 116A;BD10;1107 116A; +BD11;BD11;1107 116A 11A8;BD11;1107 116A 11A8; +BD12;BD12;1107 116A 11A9;BD12;1107 116A 11A9; +BD13;BD13;1107 116A 11AA;BD13;1107 116A 11AA; +BD14;BD14;1107 116A 11AB;BD14;1107 116A 11AB; +BD15;BD15;1107 116A 11AC;BD15;1107 116A 11AC; +BD16;BD16;1107 116A 11AD;BD16;1107 116A 11AD; +BD17;BD17;1107 116A 11AE;BD17;1107 116A 11AE; +BD18;BD18;1107 116A 11AF;BD18;1107 116A 11AF; +BD19;BD19;1107 116A 11B0;BD19;1107 116A 11B0; +BD1A;BD1A;1107 116A 11B1;BD1A;1107 116A 11B1; +BD1B;BD1B;1107 116A 11B2;BD1B;1107 116A 11B2; +BD1C;BD1C;1107 116A 11B3;BD1C;1107 116A 11B3; +BD1D;BD1D;1107 116A 11B4;BD1D;1107 116A 11B4; +BD1E;BD1E;1107 116A 11B5;BD1E;1107 116A 11B5; +BD1F;BD1F;1107 116A 11B6;BD1F;1107 116A 11B6; +BD20;BD20;1107 116A 11B7;BD20;1107 116A 11B7; +BD21;BD21;1107 116A 11B8;BD21;1107 116A 11B8; +BD22;BD22;1107 116A 11B9;BD22;1107 116A 11B9; +BD23;BD23;1107 116A 11BA;BD23;1107 116A 11BA; +BD24;BD24;1107 116A 11BB;BD24;1107 116A 11BB; +BD25;BD25;1107 116A 11BC;BD25;1107 116A 11BC; +BD26;BD26;1107 116A 11BD;BD26;1107 116A 11BD; +BD27;BD27;1107 116A 11BE;BD27;1107 116A 11BE; +BD28;BD28;1107 116A 11BF;BD28;1107 116A 11BF; +BD29;BD29;1107 116A 11C0;BD29;1107 116A 11C0; +BD2A;BD2A;1107 116A 11C1;BD2A;1107 116A 11C1; +BD2B;BD2B;1107 116A 11C2;BD2B;1107 116A 11C2; +BD2C;BD2C;1107 116B;BD2C;1107 116B; +BD2D;BD2D;1107 116B 11A8;BD2D;1107 116B 11A8; +BD2E;BD2E;1107 116B 11A9;BD2E;1107 116B 11A9; +BD2F;BD2F;1107 116B 11AA;BD2F;1107 116B 11AA; +BD30;BD30;1107 116B 11AB;BD30;1107 116B 11AB; +BD31;BD31;1107 116B 11AC;BD31;1107 116B 11AC; +BD32;BD32;1107 116B 11AD;BD32;1107 116B 11AD; +BD33;BD33;1107 116B 11AE;BD33;1107 116B 11AE; +BD34;BD34;1107 116B 11AF;BD34;1107 116B 11AF; +BD35;BD35;1107 116B 11B0;BD35;1107 116B 11B0; +BD36;BD36;1107 116B 11B1;BD36;1107 116B 11B1; +BD37;BD37;1107 116B 11B2;BD37;1107 116B 11B2; +BD38;BD38;1107 116B 11B3;BD38;1107 116B 11B3; +BD39;BD39;1107 116B 11B4;BD39;1107 116B 11B4; +BD3A;BD3A;1107 116B 11B5;BD3A;1107 116B 11B5; +BD3B;BD3B;1107 116B 11B6;BD3B;1107 116B 11B6; +BD3C;BD3C;1107 116B 11B7;BD3C;1107 116B 11B7; +BD3D;BD3D;1107 116B 11B8;BD3D;1107 116B 11B8; +BD3E;BD3E;1107 116B 11B9;BD3E;1107 116B 11B9; +BD3F;BD3F;1107 116B 11BA;BD3F;1107 116B 11BA; +BD40;BD40;1107 116B 11BB;BD40;1107 116B 11BB; +BD41;BD41;1107 116B 11BC;BD41;1107 116B 11BC; +BD42;BD42;1107 116B 11BD;BD42;1107 116B 11BD; +BD43;BD43;1107 116B 11BE;BD43;1107 116B 11BE; +BD44;BD44;1107 116B 11BF;BD44;1107 116B 11BF; +BD45;BD45;1107 116B 11C0;BD45;1107 116B 11C0; +BD46;BD46;1107 116B 11C1;BD46;1107 116B 11C1; +BD47;BD47;1107 116B 11C2;BD47;1107 116B 11C2; +BD48;BD48;1107 116C;BD48;1107 116C; +BD49;BD49;1107 116C 11A8;BD49;1107 116C 11A8; +BD4A;BD4A;1107 116C 11A9;BD4A;1107 116C 11A9; +BD4B;BD4B;1107 116C 11AA;BD4B;1107 116C 11AA; +BD4C;BD4C;1107 116C 11AB;BD4C;1107 116C 11AB; +BD4D;BD4D;1107 116C 11AC;BD4D;1107 116C 11AC; +BD4E;BD4E;1107 116C 11AD;BD4E;1107 116C 11AD; +BD4F;BD4F;1107 116C 11AE;BD4F;1107 116C 11AE; +BD50;BD50;1107 116C 11AF;BD50;1107 116C 11AF; +BD51;BD51;1107 116C 11B0;BD51;1107 116C 11B0; +BD52;BD52;1107 116C 11B1;BD52;1107 116C 11B1; +BD53;BD53;1107 116C 11B2;BD53;1107 116C 11B2; +BD54;BD54;1107 116C 11B3;BD54;1107 116C 11B3; +BD55;BD55;1107 116C 11B4;BD55;1107 116C 11B4; +BD56;BD56;1107 116C 11B5;BD56;1107 116C 11B5; +BD57;BD57;1107 116C 11B6;BD57;1107 116C 11B6; +BD58;BD58;1107 116C 11B7;BD58;1107 116C 11B7; +BD59;BD59;1107 116C 11B8;BD59;1107 116C 11B8; +BD5A;BD5A;1107 116C 11B9;BD5A;1107 116C 11B9; +BD5B;BD5B;1107 116C 11BA;BD5B;1107 116C 11BA; +BD5C;BD5C;1107 116C 11BB;BD5C;1107 116C 11BB; +BD5D;BD5D;1107 116C 11BC;BD5D;1107 116C 11BC; +BD5E;BD5E;1107 116C 11BD;BD5E;1107 116C 11BD; +BD5F;BD5F;1107 116C 11BE;BD5F;1107 116C 11BE; +BD60;BD60;1107 116C 11BF;BD60;1107 116C 11BF; +BD61;BD61;1107 116C 11C0;BD61;1107 116C 11C0; +BD62;BD62;1107 116C 11C1;BD62;1107 116C 11C1; +BD63;BD63;1107 116C 11C2;BD63;1107 116C 11C2; +BD64;BD64;1107 116D;BD64;1107 116D; +BD65;BD65;1107 116D 11A8;BD65;1107 116D 11A8; +BD66;BD66;1107 116D 11A9;BD66;1107 116D 11A9; +BD67;BD67;1107 116D 11AA;BD67;1107 116D 11AA; +BD68;BD68;1107 116D 11AB;BD68;1107 116D 11AB; +BD69;BD69;1107 116D 11AC;BD69;1107 116D 11AC; +BD6A;BD6A;1107 116D 11AD;BD6A;1107 116D 11AD; +BD6B;BD6B;1107 116D 11AE;BD6B;1107 116D 11AE; +BD6C;BD6C;1107 116D 11AF;BD6C;1107 116D 11AF; +BD6D;BD6D;1107 116D 11B0;BD6D;1107 116D 11B0; +BD6E;BD6E;1107 116D 11B1;BD6E;1107 116D 11B1; +BD6F;BD6F;1107 116D 11B2;BD6F;1107 116D 11B2; +BD70;BD70;1107 116D 11B3;BD70;1107 116D 11B3; +BD71;BD71;1107 116D 11B4;BD71;1107 116D 11B4; +BD72;BD72;1107 116D 11B5;BD72;1107 116D 11B5; +BD73;BD73;1107 116D 11B6;BD73;1107 116D 11B6; +BD74;BD74;1107 116D 11B7;BD74;1107 116D 11B7; +BD75;BD75;1107 116D 11B8;BD75;1107 116D 11B8; +BD76;BD76;1107 116D 11B9;BD76;1107 116D 11B9; +BD77;BD77;1107 116D 11BA;BD77;1107 116D 11BA; +BD78;BD78;1107 116D 11BB;BD78;1107 116D 11BB; +BD79;BD79;1107 116D 11BC;BD79;1107 116D 11BC; +BD7A;BD7A;1107 116D 11BD;BD7A;1107 116D 11BD; +BD7B;BD7B;1107 116D 11BE;BD7B;1107 116D 11BE; +BD7C;BD7C;1107 116D 11BF;BD7C;1107 116D 11BF; +BD7D;BD7D;1107 116D 11C0;BD7D;1107 116D 11C0; +BD7E;BD7E;1107 116D 11C1;BD7E;1107 116D 11C1; +BD7F;BD7F;1107 116D 11C2;BD7F;1107 116D 11C2; +BD80;BD80;1107 116E;BD80;1107 116E; +BD81;BD81;1107 116E 11A8;BD81;1107 116E 11A8; +BD82;BD82;1107 116E 11A9;BD82;1107 116E 11A9; +BD83;BD83;1107 116E 11AA;BD83;1107 116E 11AA; +BD84;BD84;1107 116E 11AB;BD84;1107 116E 11AB; +BD85;BD85;1107 116E 11AC;BD85;1107 116E 11AC; +BD86;BD86;1107 116E 11AD;BD86;1107 116E 11AD; +BD87;BD87;1107 116E 11AE;BD87;1107 116E 11AE; +BD88;BD88;1107 116E 11AF;BD88;1107 116E 11AF; +BD89;BD89;1107 116E 11B0;BD89;1107 116E 11B0; +BD8A;BD8A;1107 116E 11B1;BD8A;1107 116E 11B1; +BD8B;BD8B;1107 116E 11B2;BD8B;1107 116E 11B2; +BD8C;BD8C;1107 116E 11B3;BD8C;1107 116E 11B3; +BD8D;BD8D;1107 116E 11B4;BD8D;1107 116E 11B4; +BD8E;BD8E;1107 116E 11B5;BD8E;1107 116E 11B5; +BD8F;BD8F;1107 116E 11B6;BD8F;1107 116E 11B6; +BD90;BD90;1107 116E 11B7;BD90;1107 116E 11B7; +BD91;BD91;1107 116E 11B8;BD91;1107 116E 11B8; +BD92;BD92;1107 116E 11B9;BD92;1107 116E 11B9; +BD93;BD93;1107 116E 11BA;BD93;1107 116E 11BA; +BD94;BD94;1107 116E 11BB;BD94;1107 116E 11BB; +BD95;BD95;1107 116E 11BC;BD95;1107 116E 11BC; +BD96;BD96;1107 116E 11BD;BD96;1107 116E 11BD; +BD97;BD97;1107 116E 11BE;BD97;1107 116E 11BE; +BD98;BD98;1107 116E 11BF;BD98;1107 116E 11BF; +BD99;BD99;1107 116E 11C0;BD99;1107 116E 11C0; +BD9A;BD9A;1107 116E 11C1;BD9A;1107 116E 11C1; +BD9B;BD9B;1107 116E 11C2;BD9B;1107 116E 11C2; +BD9C;BD9C;1107 116F;BD9C;1107 116F; +BD9D;BD9D;1107 116F 11A8;BD9D;1107 116F 11A8; +BD9E;BD9E;1107 116F 11A9;BD9E;1107 116F 11A9; +BD9F;BD9F;1107 116F 11AA;BD9F;1107 116F 11AA; +BDA0;BDA0;1107 116F 11AB;BDA0;1107 116F 11AB; +BDA1;BDA1;1107 116F 11AC;BDA1;1107 116F 11AC; +BDA2;BDA2;1107 116F 11AD;BDA2;1107 116F 11AD; +BDA3;BDA3;1107 116F 11AE;BDA3;1107 116F 11AE; +BDA4;BDA4;1107 116F 11AF;BDA4;1107 116F 11AF; +BDA5;BDA5;1107 116F 11B0;BDA5;1107 116F 11B0; +BDA6;BDA6;1107 116F 11B1;BDA6;1107 116F 11B1; +BDA7;BDA7;1107 116F 11B2;BDA7;1107 116F 11B2; +BDA8;BDA8;1107 116F 11B3;BDA8;1107 116F 11B3; +BDA9;BDA9;1107 116F 11B4;BDA9;1107 116F 11B4; +BDAA;BDAA;1107 116F 11B5;BDAA;1107 116F 11B5; +BDAB;BDAB;1107 116F 11B6;BDAB;1107 116F 11B6; +BDAC;BDAC;1107 116F 11B7;BDAC;1107 116F 11B7; +BDAD;BDAD;1107 116F 11B8;BDAD;1107 116F 11B8; +BDAE;BDAE;1107 116F 11B9;BDAE;1107 116F 11B9; +BDAF;BDAF;1107 116F 11BA;BDAF;1107 116F 11BA; +BDB0;BDB0;1107 116F 11BB;BDB0;1107 116F 11BB; +BDB1;BDB1;1107 116F 11BC;BDB1;1107 116F 11BC; +BDB2;BDB2;1107 116F 11BD;BDB2;1107 116F 11BD; +BDB3;BDB3;1107 116F 11BE;BDB3;1107 116F 11BE; +BDB4;BDB4;1107 116F 11BF;BDB4;1107 116F 11BF; +BDB5;BDB5;1107 116F 11C0;BDB5;1107 116F 11C0; +BDB6;BDB6;1107 116F 11C1;BDB6;1107 116F 11C1; +BDB7;BDB7;1107 116F 11C2;BDB7;1107 116F 11C2; +BDB8;BDB8;1107 1170;BDB8;1107 1170; +BDB9;BDB9;1107 1170 11A8;BDB9;1107 1170 11A8; +BDBA;BDBA;1107 1170 11A9;BDBA;1107 1170 11A9; +BDBB;BDBB;1107 1170 11AA;BDBB;1107 1170 11AA; +BDBC;BDBC;1107 1170 11AB;BDBC;1107 1170 11AB; +BDBD;BDBD;1107 1170 11AC;BDBD;1107 1170 11AC; +BDBE;BDBE;1107 1170 11AD;BDBE;1107 1170 11AD; +BDBF;BDBF;1107 1170 11AE;BDBF;1107 1170 11AE; +BDC0;BDC0;1107 1170 11AF;BDC0;1107 1170 11AF; +BDC1;BDC1;1107 1170 11B0;BDC1;1107 1170 11B0; +BDC2;BDC2;1107 1170 11B1;BDC2;1107 1170 11B1; +BDC3;BDC3;1107 1170 11B2;BDC3;1107 1170 11B2; +BDC4;BDC4;1107 1170 11B3;BDC4;1107 1170 11B3; +BDC5;BDC5;1107 1170 11B4;BDC5;1107 1170 11B4; +BDC6;BDC6;1107 1170 11B5;BDC6;1107 1170 11B5; +BDC7;BDC7;1107 1170 11B6;BDC7;1107 1170 11B6; +BDC8;BDC8;1107 1170 11B7;BDC8;1107 1170 11B7; +BDC9;BDC9;1107 1170 11B8;BDC9;1107 1170 11B8; +BDCA;BDCA;1107 1170 11B9;BDCA;1107 1170 11B9; +BDCB;BDCB;1107 1170 11BA;BDCB;1107 1170 11BA; +BDCC;BDCC;1107 1170 11BB;BDCC;1107 1170 11BB; +BDCD;BDCD;1107 1170 11BC;BDCD;1107 1170 11BC; +BDCE;BDCE;1107 1170 11BD;BDCE;1107 1170 11BD; +BDCF;BDCF;1107 1170 11BE;BDCF;1107 1170 11BE; +BDD0;BDD0;1107 1170 11BF;BDD0;1107 1170 11BF; +BDD1;BDD1;1107 1170 11C0;BDD1;1107 1170 11C0; +BDD2;BDD2;1107 1170 11C1;BDD2;1107 1170 11C1; +BDD3;BDD3;1107 1170 11C2;BDD3;1107 1170 11C2; +BDD4;BDD4;1107 1171;BDD4;1107 1171; +BDD5;BDD5;1107 1171 11A8;BDD5;1107 1171 11A8; +BDD6;BDD6;1107 1171 11A9;BDD6;1107 1171 11A9; +BDD7;BDD7;1107 1171 11AA;BDD7;1107 1171 11AA; +BDD8;BDD8;1107 1171 11AB;BDD8;1107 1171 11AB; +BDD9;BDD9;1107 1171 11AC;BDD9;1107 1171 11AC; +BDDA;BDDA;1107 1171 11AD;BDDA;1107 1171 11AD; +BDDB;BDDB;1107 1171 11AE;BDDB;1107 1171 11AE; +BDDC;BDDC;1107 1171 11AF;BDDC;1107 1171 11AF; +BDDD;BDDD;1107 1171 11B0;BDDD;1107 1171 11B0; +BDDE;BDDE;1107 1171 11B1;BDDE;1107 1171 11B1; +BDDF;BDDF;1107 1171 11B2;BDDF;1107 1171 11B2; +BDE0;BDE0;1107 1171 11B3;BDE0;1107 1171 11B3; +BDE1;BDE1;1107 1171 11B4;BDE1;1107 1171 11B4; +BDE2;BDE2;1107 1171 11B5;BDE2;1107 1171 11B5; +BDE3;BDE3;1107 1171 11B6;BDE3;1107 1171 11B6; +BDE4;BDE4;1107 1171 11B7;BDE4;1107 1171 11B7; +BDE5;BDE5;1107 1171 11B8;BDE5;1107 1171 11B8; +BDE6;BDE6;1107 1171 11B9;BDE6;1107 1171 11B9; +BDE7;BDE7;1107 1171 11BA;BDE7;1107 1171 11BA; +BDE8;BDE8;1107 1171 11BB;BDE8;1107 1171 11BB; +BDE9;BDE9;1107 1171 11BC;BDE9;1107 1171 11BC; +BDEA;BDEA;1107 1171 11BD;BDEA;1107 1171 11BD; +BDEB;BDEB;1107 1171 11BE;BDEB;1107 1171 11BE; +BDEC;BDEC;1107 1171 11BF;BDEC;1107 1171 11BF; +BDED;BDED;1107 1171 11C0;BDED;1107 1171 11C0; +BDEE;BDEE;1107 1171 11C1;BDEE;1107 1171 11C1; +BDEF;BDEF;1107 1171 11C2;BDEF;1107 1171 11C2; +BDF0;BDF0;1107 1172;BDF0;1107 1172; +BDF1;BDF1;1107 1172 11A8;BDF1;1107 1172 11A8; +BDF2;BDF2;1107 1172 11A9;BDF2;1107 1172 11A9; +BDF3;BDF3;1107 1172 11AA;BDF3;1107 1172 11AA; +BDF4;BDF4;1107 1172 11AB;BDF4;1107 1172 11AB; +BDF5;BDF5;1107 1172 11AC;BDF5;1107 1172 11AC; +BDF6;BDF6;1107 1172 11AD;BDF6;1107 1172 11AD; +BDF7;BDF7;1107 1172 11AE;BDF7;1107 1172 11AE; +BDF8;BDF8;1107 1172 11AF;BDF8;1107 1172 11AF; +BDF9;BDF9;1107 1172 11B0;BDF9;1107 1172 11B0; +BDFA;BDFA;1107 1172 11B1;BDFA;1107 1172 11B1; +BDFB;BDFB;1107 1172 11B2;BDFB;1107 1172 11B2; +BDFC;BDFC;1107 1172 11B3;BDFC;1107 1172 11B3; +BDFD;BDFD;1107 1172 11B4;BDFD;1107 1172 11B4; +BDFE;BDFE;1107 1172 11B5;BDFE;1107 1172 11B5; +BDFF;BDFF;1107 1172 11B6;BDFF;1107 1172 11B6; +BE00;BE00;1107 1172 11B7;BE00;1107 1172 11B7; +BE01;BE01;1107 1172 11B8;BE01;1107 1172 11B8; +BE02;BE02;1107 1172 11B9;BE02;1107 1172 11B9; +BE03;BE03;1107 1172 11BA;BE03;1107 1172 11BA; +BE04;BE04;1107 1172 11BB;BE04;1107 1172 11BB; +BE05;BE05;1107 1172 11BC;BE05;1107 1172 11BC; +BE06;BE06;1107 1172 11BD;BE06;1107 1172 11BD; +BE07;BE07;1107 1172 11BE;BE07;1107 1172 11BE; +BE08;BE08;1107 1172 11BF;BE08;1107 1172 11BF; +BE09;BE09;1107 1172 11C0;BE09;1107 1172 11C0; +BE0A;BE0A;1107 1172 11C1;BE0A;1107 1172 11C1; +BE0B;BE0B;1107 1172 11C2;BE0B;1107 1172 11C2; +BE0C;BE0C;1107 1173;BE0C;1107 1173; +BE0D;BE0D;1107 1173 11A8;BE0D;1107 1173 11A8; +BE0E;BE0E;1107 1173 11A9;BE0E;1107 1173 11A9; +BE0F;BE0F;1107 1173 11AA;BE0F;1107 1173 11AA; +BE10;BE10;1107 1173 11AB;BE10;1107 1173 11AB; +BE11;BE11;1107 1173 11AC;BE11;1107 1173 11AC; +BE12;BE12;1107 1173 11AD;BE12;1107 1173 11AD; +BE13;BE13;1107 1173 11AE;BE13;1107 1173 11AE; +BE14;BE14;1107 1173 11AF;BE14;1107 1173 11AF; +BE15;BE15;1107 1173 11B0;BE15;1107 1173 11B0; +BE16;BE16;1107 1173 11B1;BE16;1107 1173 11B1; +BE17;BE17;1107 1173 11B2;BE17;1107 1173 11B2; +BE18;BE18;1107 1173 11B3;BE18;1107 1173 11B3; +BE19;BE19;1107 1173 11B4;BE19;1107 1173 11B4; +BE1A;BE1A;1107 1173 11B5;BE1A;1107 1173 11B5; +BE1B;BE1B;1107 1173 11B6;BE1B;1107 1173 11B6; +BE1C;BE1C;1107 1173 11B7;BE1C;1107 1173 11B7; +BE1D;BE1D;1107 1173 11B8;BE1D;1107 1173 11B8; +BE1E;BE1E;1107 1173 11B9;BE1E;1107 1173 11B9; +BE1F;BE1F;1107 1173 11BA;BE1F;1107 1173 11BA; +BE20;BE20;1107 1173 11BB;BE20;1107 1173 11BB; +BE21;BE21;1107 1173 11BC;BE21;1107 1173 11BC; +BE22;BE22;1107 1173 11BD;BE22;1107 1173 11BD; +BE23;BE23;1107 1173 11BE;BE23;1107 1173 11BE; +BE24;BE24;1107 1173 11BF;BE24;1107 1173 11BF; +BE25;BE25;1107 1173 11C0;BE25;1107 1173 11C0; +BE26;BE26;1107 1173 11C1;BE26;1107 1173 11C1; +BE27;BE27;1107 1173 11C2;BE27;1107 1173 11C2; +BE28;BE28;1107 1174;BE28;1107 1174; +BE29;BE29;1107 1174 11A8;BE29;1107 1174 11A8; +BE2A;BE2A;1107 1174 11A9;BE2A;1107 1174 11A9; +BE2B;BE2B;1107 1174 11AA;BE2B;1107 1174 11AA; +BE2C;BE2C;1107 1174 11AB;BE2C;1107 1174 11AB; +BE2D;BE2D;1107 1174 11AC;BE2D;1107 1174 11AC; +BE2E;BE2E;1107 1174 11AD;BE2E;1107 1174 11AD; +BE2F;BE2F;1107 1174 11AE;BE2F;1107 1174 11AE; +BE30;BE30;1107 1174 11AF;BE30;1107 1174 11AF; +BE31;BE31;1107 1174 11B0;BE31;1107 1174 11B0; +BE32;BE32;1107 1174 11B1;BE32;1107 1174 11B1; +BE33;BE33;1107 1174 11B2;BE33;1107 1174 11B2; +BE34;BE34;1107 1174 11B3;BE34;1107 1174 11B3; +BE35;BE35;1107 1174 11B4;BE35;1107 1174 11B4; +BE36;BE36;1107 1174 11B5;BE36;1107 1174 11B5; +BE37;BE37;1107 1174 11B6;BE37;1107 1174 11B6; +BE38;BE38;1107 1174 11B7;BE38;1107 1174 11B7; +BE39;BE39;1107 1174 11B8;BE39;1107 1174 11B8; +BE3A;BE3A;1107 1174 11B9;BE3A;1107 1174 11B9; +BE3B;BE3B;1107 1174 11BA;BE3B;1107 1174 11BA; +BE3C;BE3C;1107 1174 11BB;BE3C;1107 1174 11BB; +BE3D;BE3D;1107 1174 11BC;BE3D;1107 1174 11BC; +BE3E;BE3E;1107 1174 11BD;BE3E;1107 1174 11BD; +BE3F;BE3F;1107 1174 11BE;BE3F;1107 1174 11BE; +BE40;BE40;1107 1174 11BF;BE40;1107 1174 11BF; +BE41;BE41;1107 1174 11C0;BE41;1107 1174 11C0; +BE42;BE42;1107 1174 11C1;BE42;1107 1174 11C1; +BE43;BE43;1107 1174 11C2;BE43;1107 1174 11C2; +BE44;BE44;1107 1175;BE44;1107 1175; +BE45;BE45;1107 1175 11A8;BE45;1107 1175 11A8; +BE46;BE46;1107 1175 11A9;BE46;1107 1175 11A9; +BE47;BE47;1107 1175 11AA;BE47;1107 1175 11AA; +BE48;BE48;1107 1175 11AB;BE48;1107 1175 11AB; +BE49;BE49;1107 1175 11AC;BE49;1107 1175 11AC; +BE4A;BE4A;1107 1175 11AD;BE4A;1107 1175 11AD; +BE4B;BE4B;1107 1175 11AE;BE4B;1107 1175 11AE; +BE4C;BE4C;1107 1175 11AF;BE4C;1107 1175 11AF; +BE4D;BE4D;1107 1175 11B0;BE4D;1107 1175 11B0; +BE4E;BE4E;1107 1175 11B1;BE4E;1107 1175 11B1; +BE4F;BE4F;1107 1175 11B2;BE4F;1107 1175 11B2; +BE50;BE50;1107 1175 11B3;BE50;1107 1175 11B3; +BE51;BE51;1107 1175 11B4;BE51;1107 1175 11B4; +BE52;BE52;1107 1175 11B5;BE52;1107 1175 11B5; +BE53;BE53;1107 1175 11B6;BE53;1107 1175 11B6; +BE54;BE54;1107 1175 11B7;BE54;1107 1175 11B7; +BE55;BE55;1107 1175 11B8;BE55;1107 1175 11B8; +BE56;BE56;1107 1175 11B9;BE56;1107 1175 11B9; +BE57;BE57;1107 1175 11BA;BE57;1107 1175 11BA; +BE58;BE58;1107 1175 11BB;BE58;1107 1175 11BB; +BE59;BE59;1107 1175 11BC;BE59;1107 1175 11BC; +BE5A;BE5A;1107 1175 11BD;BE5A;1107 1175 11BD; +BE5B;BE5B;1107 1175 11BE;BE5B;1107 1175 11BE; +BE5C;BE5C;1107 1175 11BF;BE5C;1107 1175 11BF; +BE5D;BE5D;1107 1175 11C0;BE5D;1107 1175 11C0; +BE5E;BE5E;1107 1175 11C1;BE5E;1107 1175 11C1; +BE5F;BE5F;1107 1175 11C2;BE5F;1107 1175 11C2; +BE60;BE60;1108 1161;BE60;1108 1161; +BE61;BE61;1108 1161 11A8;BE61;1108 1161 11A8; +BE62;BE62;1108 1161 11A9;BE62;1108 1161 11A9; +BE63;BE63;1108 1161 11AA;BE63;1108 1161 11AA; +BE64;BE64;1108 1161 11AB;BE64;1108 1161 11AB; +BE65;BE65;1108 1161 11AC;BE65;1108 1161 11AC; +BE66;BE66;1108 1161 11AD;BE66;1108 1161 11AD; +BE67;BE67;1108 1161 11AE;BE67;1108 1161 11AE; +BE68;BE68;1108 1161 11AF;BE68;1108 1161 11AF; +BE69;BE69;1108 1161 11B0;BE69;1108 1161 11B0; +BE6A;BE6A;1108 1161 11B1;BE6A;1108 1161 11B1; +BE6B;BE6B;1108 1161 11B2;BE6B;1108 1161 11B2; +BE6C;BE6C;1108 1161 11B3;BE6C;1108 1161 11B3; +BE6D;BE6D;1108 1161 11B4;BE6D;1108 1161 11B4; +BE6E;BE6E;1108 1161 11B5;BE6E;1108 1161 11B5; +BE6F;BE6F;1108 1161 11B6;BE6F;1108 1161 11B6; +BE70;BE70;1108 1161 11B7;BE70;1108 1161 11B7; +BE71;BE71;1108 1161 11B8;BE71;1108 1161 11B8; +BE72;BE72;1108 1161 11B9;BE72;1108 1161 11B9; +BE73;BE73;1108 1161 11BA;BE73;1108 1161 11BA; +BE74;BE74;1108 1161 11BB;BE74;1108 1161 11BB; +BE75;BE75;1108 1161 11BC;BE75;1108 1161 11BC; +BE76;BE76;1108 1161 11BD;BE76;1108 1161 11BD; +BE77;BE77;1108 1161 11BE;BE77;1108 1161 11BE; +BE78;BE78;1108 1161 11BF;BE78;1108 1161 11BF; +BE79;BE79;1108 1161 11C0;BE79;1108 1161 11C0; +BE7A;BE7A;1108 1161 11C1;BE7A;1108 1161 11C1; +BE7B;BE7B;1108 1161 11C2;BE7B;1108 1161 11C2; +BE7C;BE7C;1108 1162;BE7C;1108 1162; +BE7D;BE7D;1108 1162 11A8;BE7D;1108 1162 11A8; +BE7E;BE7E;1108 1162 11A9;BE7E;1108 1162 11A9; +BE7F;BE7F;1108 1162 11AA;BE7F;1108 1162 11AA; +BE80;BE80;1108 1162 11AB;BE80;1108 1162 11AB; +BE81;BE81;1108 1162 11AC;BE81;1108 1162 11AC; +BE82;BE82;1108 1162 11AD;BE82;1108 1162 11AD; +BE83;BE83;1108 1162 11AE;BE83;1108 1162 11AE; +BE84;BE84;1108 1162 11AF;BE84;1108 1162 11AF; +BE85;BE85;1108 1162 11B0;BE85;1108 1162 11B0; +BE86;BE86;1108 1162 11B1;BE86;1108 1162 11B1; +BE87;BE87;1108 1162 11B2;BE87;1108 1162 11B2; +BE88;BE88;1108 1162 11B3;BE88;1108 1162 11B3; +BE89;BE89;1108 1162 11B4;BE89;1108 1162 11B4; +BE8A;BE8A;1108 1162 11B5;BE8A;1108 1162 11B5; +BE8B;BE8B;1108 1162 11B6;BE8B;1108 1162 11B6; +BE8C;BE8C;1108 1162 11B7;BE8C;1108 1162 11B7; +BE8D;BE8D;1108 1162 11B8;BE8D;1108 1162 11B8; +BE8E;BE8E;1108 1162 11B9;BE8E;1108 1162 11B9; +BE8F;BE8F;1108 1162 11BA;BE8F;1108 1162 11BA; +BE90;BE90;1108 1162 11BB;BE90;1108 1162 11BB; +BE91;BE91;1108 1162 11BC;BE91;1108 1162 11BC; +BE92;BE92;1108 1162 11BD;BE92;1108 1162 11BD; +BE93;BE93;1108 1162 11BE;BE93;1108 1162 11BE; +BE94;BE94;1108 1162 11BF;BE94;1108 1162 11BF; +BE95;BE95;1108 1162 11C0;BE95;1108 1162 11C0; +BE96;BE96;1108 1162 11C1;BE96;1108 1162 11C1; +BE97;BE97;1108 1162 11C2;BE97;1108 1162 11C2; +BE98;BE98;1108 1163;BE98;1108 1163; +BE99;BE99;1108 1163 11A8;BE99;1108 1163 11A8; +BE9A;BE9A;1108 1163 11A9;BE9A;1108 1163 11A9; +BE9B;BE9B;1108 1163 11AA;BE9B;1108 1163 11AA; +BE9C;BE9C;1108 1163 11AB;BE9C;1108 1163 11AB; +BE9D;BE9D;1108 1163 11AC;BE9D;1108 1163 11AC; +BE9E;BE9E;1108 1163 11AD;BE9E;1108 1163 11AD; +BE9F;BE9F;1108 1163 11AE;BE9F;1108 1163 11AE; +BEA0;BEA0;1108 1163 11AF;BEA0;1108 1163 11AF; +BEA1;BEA1;1108 1163 11B0;BEA1;1108 1163 11B0; +BEA2;BEA2;1108 1163 11B1;BEA2;1108 1163 11B1; +BEA3;BEA3;1108 1163 11B2;BEA3;1108 1163 11B2; +BEA4;BEA4;1108 1163 11B3;BEA4;1108 1163 11B3; +BEA5;BEA5;1108 1163 11B4;BEA5;1108 1163 11B4; +BEA6;BEA6;1108 1163 11B5;BEA6;1108 1163 11B5; +BEA7;BEA7;1108 1163 11B6;BEA7;1108 1163 11B6; +BEA8;BEA8;1108 1163 11B7;BEA8;1108 1163 11B7; +BEA9;BEA9;1108 1163 11B8;BEA9;1108 1163 11B8; +BEAA;BEAA;1108 1163 11B9;BEAA;1108 1163 11B9; +BEAB;BEAB;1108 1163 11BA;BEAB;1108 1163 11BA; +BEAC;BEAC;1108 1163 11BB;BEAC;1108 1163 11BB; +BEAD;BEAD;1108 1163 11BC;BEAD;1108 1163 11BC; +BEAE;BEAE;1108 1163 11BD;BEAE;1108 1163 11BD; +BEAF;BEAF;1108 1163 11BE;BEAF;1108 1163 11BE; +BEB0;BEB0;1108 1163 11BF;BEB0;1108 1163 11BF; +BEB1;BEB1;1108 1163 11C0;BEB1;1108 1163 11C0; +BEB2;BEB2;1108 1163 11C1;BEB2;1108 1163 11C1; +BEB3;BEB3;1108 1163 11C2;BEB3;1108 1163 11C2; +BEB4;BEB4;1108 1164;BEB4;1108 1164; +BEB5;BEB5;1108 1164 11A8;BEB5;1108 1164 11A8; +BEB6;BEB6;1108 1164 11A9;BEB6;1108 1164 11A9; +BEB7;BEB7;1108 1164 11AA;BEB7;1108 1164 11AA; +BEB8;BEB8;1108 1164 11AB;BEB8;1108 1164 11AB; +BEB9;BEB9;1108 1164 11AC;BEB9;1108 1164 11AC; +BEBA;BEBA;1108 1164 11AD;BEBA;1108 1164 11AD; +BEBB;BEBB;1108 1164 11AE;BEBB;1108 1164 11AE; +BEBC;BEBC;1108 1164 11AF;BEBC;1108 1164 11AF; +BEBD;BEBD;1108 1164 11B0;BEBD;1108 1164 11B0; +BEBE;BEBE;1108 1164 11B1;BEBE;1108 1164 11B1; +BEBF;BEBF;1108 1164 11B2;BEBF;1108 1164 11B2; +BEC0;BEC0;1108 1164 11B3;BEC0;1108 1164 11B3; +BEC1;BEC1;1108 1164 11B4;BEC1;1108 1164 11B4; +BEC2;BEC2;1108 1164 11B5;BEC2;1108 1164 11B5; +BEC3;BEC3;1108 1164 11B6;BEC3;1108 1164 11B6; +BEC4;BEC4;1108 1164 11B7;BEC4;1108 1164 11B7; +BEC5;BEC5;1108 1164 11B8;BEC5;1108 1164 11B8; +BEC6;BEC6;1108 1164 11B9;BEC6;1108 1164 11B9; +BEC7;BEC7;1108 1164 11BA;BEC7;1108 1164 11BA; +BEC8;BEC8;1108 1164 11BB;BEC8;1108 1164 11BB; +BEC9;BEC9;1108 1164 11BC;BEC9;1108 1164 11BC; +BECA;BECA;1108 1164 11BD;BECA;1108 1164 11BD; +BECB;BECB;1108 1164 11BE;BECB;1108 1164 11BE; +BECC;BECC;1108 1164 11BF;BECC;1108 1164 11BF; +BECD;BECD;1108 1164 11C0;BECD;1108 1164 11C0; +BECE;BECE;1108 1164 11C1;BECE;1108 1164 11C1; +BECF;BECF;1108 1164 11C2;BECF;1108 1164 11C2; +BED0;BED0;1108 1165;BED0;1108 1165; +BED1;BED1;1108 1165 11A8;BED1;1108 1165 11A8; +BED2;BED2;1108 1165 11A9;BED2;1108 1165 11A9; +BED3;BED3;1108 1165 11AA;BED3;1108 1165 11AA; +BED4;BED4;1108 1165 11AB;BED4;1108 1165 11AB; +BED5;BED5;1108 1165 11AC;BED5;1108 1165 11AC; +BED6;BED6;1108 1165 11AD;BED6;1108 1165 11AD; +BED7;BED7;1108 1165 11AE;BED7;1108 1165 11AE; +BED8;BED8;1108 1165 11AF;BED8;1108 1165 11AF; +BED9;BED9;1108 1165 11B0;BED9;1108 1165 11B0; +BEDA;BEDA;1108 1165 11B1;BEDA;1108 1165 11B1; +BEDB;BEDB;1108 1165 11B2;BEDB;1108 1165 11B2; +BEDC;BEDC;1108 1165 11B3;BEDC;1108 1165 11B3; +BEDD;BEDD;1108 1165 11B4;BEDD;1108 1165 11B4; +BEDE;BEDE;1108 1165 11B5;BEDE;1108 1165 11B5; +BEDF;BEDF;1108 1165 11B6;BEDF;1108 1165 11B6; +BEE0;BEE0;1108 1165 11B7;BEE0;1108 1165 11B7; +BEE1;BEE1;1108 1165 11B8;BEE1;1108 1165 11B8; +BEE2;BEE2;1108 1165 11B9;BEE2;1108 1165 11B9; +BEE3;BEE3;1108 1165 11BA;BEE3;1108 1165 11BA; +BEE4;BEE4;1108 1165 11BB;BEE4;1108 1165 11BB; +BEE5;BEE5;1108 1165 11BC;BEE5;1108 1165 11BC; +BEE6;BEE6;1108 1165 11BD;BEE6;1108 1165 11BD; +BEE7;BEE7;1108 1165 11BE;BEE7;1108 1165 11BE; +BEE8;BEE8;1108 1165 11BF;BEE8;1108 1165 11BF; +BEE9;BEE9;1108 1165 11C0;BEE9;1108 1165 11C0; +BEEA;BEEA;1108 1165 11C1;BEEA;1108 1165 11C1; +BEEB;BEEB;1108 1165 11C2;BEEB;1108 1165 11C2; +BEEC;BEEC;1108 1166;BEEC;1108 1166; +BEED;BEED;1108 1166 11A8;BEED;1108 1166 11A8; +BEEE;BEEE;1108 1166 11A9;BEEE;1108 1166 11A9; +BEEF;BEEF;1108 1166 11AA;BEEF;1108 1166 11AA; +BEF0;BEF0;1108 1166 11AB;BEF0;1108 1166 11AB; +BEF1;BEF1;1108 1166 11AC;BEF1;1108 1166 11AC; +BEF2;BEF2;1108 1166 11AD;BEF2;1108 1166 11AD; +BEF3;BEF3;1108 1166 11AE;BEF3;1108 1166 11AE; +BEF4;BEF4;1108 1166 11AF;BEF4;1108 1166 11AF; +BEF5;BEF5;1108 1166 11B0;BEF5;1108 1166 11B0; +BEF6;BEF6;1108 1166 11B1;BEF6;1108 1166 11B1; +BEF7;BEF7;1108 1166 11B2;BEF7;1108 1166 11B2; +BEF8;BEF8;1108 1166 11B3;BEF8;1108 1166 11B3; +BEF9;BEF9;1108 1166 11B4;BEF9;1108 1166 11B4; +BEFA;BEFA;1108 1166 11B5;BEFA;1108 1166 11B5; +BEFB;BEFB;1108 1166 11B6;BEFB;1108 1166 11B6; +BEFC;BEFC;1108 1166 11B7;BEFC;1108 1166 11B7; +BEFD;BEFD;1108 1166 11B8;BEFD;1108 1166 11B8; +BEFE;BEFE;1108 1166 11B9;BEFE;1108 1166 11B9; +BEFF;BEFF;1108 1166 11BA;BEFF;1108 1166 11BA; +BF00;BF00;1108 1166 11BB;BF00;1108 1166 11BB; +BF01;BF01;1108 1166 11BC;BF01;1108 1166 11BC; +BF02;BF02;1108 1166 11BD;BF02;1108 1166 11BD; +BF03;BF03;1108 1166 11BE;BF03;1108 1166 11BE; +BF04;BF04;1108 1166 11BF;BF04;1108 1166 11BF; +BF05;BF05;1108 1166 11C0;BF05;1108 1166 11C0; +BF06;BF06;1108 1166 11C1;BF06;1108 1166 11C1; +BF07;BF07;1108 1166 11C2;BF07;1108 1166 11C2; +BF08;BF08;1108 1167;BF08;1108 1167; +BF09;BF09;1108 1167 11A8;BF09;1108 1167 11A8; +BF0A;BF0A;1108 1167 11A9;BF0A;1108 1167 11A9; +BF0B;BF0B;1108 1167 11AA;BF0B;1108 1167 11AA; +BF0C;BF0C;1108 1167 11AB;BF0C;1108 1167 11AB; +BF0D;BF0D;1108 1167 11AC;BF0D;1108 1167 11AC; +BF0E;BF0E;1108 1167 11AD;BF0E;1108 1167 11AD; +BF0F;BF0F;1108 1167 11AE;BF0F;1108 1167 11AE; +BF10;BF10;1108 1167 11AF;BF10;1108 1167 11AF; +BF11;BF11;1108 1167 11B0;BF11;1108 1167 11B0; +BF12;BF12;1108 1167 11B1;BF12;1108 1167 11B1; +BF13;BF13;1108 1167 11B2;BF13;1108 1167 11B2; +BF14;BF14;1108 1167 11B3;BF14;1108 1167 11B3; +BF15;BF15;1108 1167 11B4;BF15;1108 1167 11B4; +BF16;BF16;1108 1167 11B5;BF16;1108 1167 11B5; +BF17;BF17;1108 1167 11B6;BF17;1108 1167 11B6; +BF18;BF18;1108 1167 11B7;BF18;1108 1167 11B7; +BF19;BF19;1108 1167 11B8;BF19;1108 1167 11B8; +BF1A;BF1A;1108 1167 11B9;BF1A;1108 1167 11B9; +BF1B;BF1B;1108 1167 11BA;BF1B;1108 1167 11BA; +BF1C;BF1C;1108 1167 11BB;BF1C;1108 1167 11BB; +BF1D;BF1D;1108 1167 11BC;BF1D;1108 1167 11BC; +BF1E;BF1E;1108 1167 11BD;BF1E;1108 1167 11BD; +BF1F;BF1F;1108 1167 11BE;BF1F;1108 1167 11BE; +BF20;BF20;1108 1167 11BF;BF20;1108 1167 11BF; +BF21;BF21;1108 1167 11C0;BF21;1108 1167 11C0; +BF22;BF22;1108 1167 11C1;BF22;1108 1167 11C1; +BF23;BF23;1108 1167 11C2;BF23;1108 1167 11C2; +BF24;BF24;1108 1168;BF24;1108 1168; +BF25;BF25;1108 1168 11A8;BF25;1108 1168 11A8; +BF26;BF26;1108 1168 11A9;BF26;1108 1168 11A9; +BF27;BF27;1108 1168 11AA;BF27;1108 1168 11AA; +BF28;BF28;1108 1168 11AB;BF28;1108 1168 11AB; +BF29;BF29;1108 1168 11AC;BF29;1108 1168 11AC; +BF2A;BF2A;1108 1168 11AD;BF2A;1108 1168 11AD; +BF2B;BF2B;1108 1168 11AE;BF2B;1108 1168 11AE; +BF2C;BF2C;1108 1168 11AF;BF2C;1108 1168 11AF; +BF2D;BF2D;1108 1168 11B0;BF2D;1108 1168 11B0; +BF2E;BF2E;1108 1168 11B1;BF2E;1108 1168 11B1; +BF2F;BF2F;1108 1168 11B2;BF2F;1108 1168 11B2; +BF30;BF30;1108 1168 11B3;BF30;1108 1168 11B3; +BF31;BF31;1108 1168 11B4;BF31;1108 1168 11B4; +BF32;BF32;1108 1168 11B5;BF32;1108 1168 11B5; +BF33;BF33;1108 1168 11B6;BF33;1108 1168 11B6; +BF34;BF34;1108 1168 11B7;BF34;1108 1168 11B7; +BF35;BF35;1108 1168 11B8;BF35;1108 1168 11B8; +BF36;BF36;1108 1168 11B9;BF36;1108 1168 11B9; +BF37;BF37;1108 1168 11BA;BF37;1108 1168 11BA; +BF38;BF38;1108 1168 11BB;BF38;1108 1168 11BB; +BF39;BF39;1108 1168 11BC;BF39;1108 1168 11BC; +BF3A;BF3A;1108 1168 11BD;BF3A;1108 1168 11BD; +BF3B;BF3B;1108 1168 11BE;BF3B;1108 1168 11BE; +BF3C;BF3C;1108 1168 11BF;BF3C;1108 1168 11BF; +BF3D;BF3D;1108 1168 11C0;BF3D;1108 1168 11C0; +BF3E;BF3E;1108 1168 11C1;BF3E;1108 1168 11C1; +BF3F;BF3F;1108 1168 11C2;BF3F;1108 1168 11C2; +BF40;BF40;1108 1169;BF40;1108 1169; +BF41;BF41;1108 1169 11A8;BF41;1108 1169 11A8; +BF42;BF42;1108 1169 11A9;BF42;1108 1169 11A9; +BF43;BF43;1108 1169 11AA;BF43;1108 1169 11AA; +BF44;BF44;1108 1169 11AB;BF44;1108 1169 11AB; +BF45;BF45;1108 1169 11AC;BF45;1108 1169 11AC; +BF46;BF46;1108 1169 11AD;BF46;1108 1169 11AD; +BF47;BF47;1108 1169 11AE;BF47;1108 1169 11AE; +BF48;BF48;1108 1169 11AF;BF48;1108 1169 11AF; +BF49;BF49;1108 1169 11B0;BF49;1108 1169 11B0; +BF4A;BF4A;1108 1169 11B1;BF4A;1108 1169 11B1; +BF4B;BF4B;1108 1169 11B2;BF4B;1108 1169 11B2; +BF4C;BF4C;1108 1169 11B3;BF4C;1108 1169 11B3; +BF4D;BF4D;1108 1169 11B4;BF4D;1108 1169 11B4; +BF4E;BF4E;1108 1169 11B5;BF4E;1108 1169 11B5; +BF4F;BF4F;1108 1169 11B6;BF4F;1108 1169 11B6; +BF50;BF50;1108 1169 11B7;BF50;1108 1169 11B7; +BF51;BF51;1108 1169 11B8;BF51;1108 1169 11B8; +BF52;BF52;1108 1169 11B9;BF52;1108 1169 11B9; +BF53;BF53;1108 1169 11BA;BF53;1108 1169 11BA; +BF54;BF54;1108 1169 11BB;BF54;1108 1169 11BB; +BF55;BF55;1108 1169 11BC;BF55;1108 1169 11BC; +BF56;BF56;1108 1169 11BD;BF56;1108 1169 11BD; +BF57;BF57;1108 1169 11BE;BF57;1108 1169 11BE; +BF58;BF58;1108 1169 11BF;BF58;1108 1169 11BF; +BF59;BF59;1108 1169 11C0;BF59;1108 1169 11C0; +BF5A;BF5A;1108 1169 11C1;BF5A;1108 1169 11C1; +BF5B;BF5B;1108 1169 11C2;BF5B;1108 1169 11C2; +BF5C;BF5C;1108 116A;BF5C;1108 116A; +BF5D;BF5D;1108 116A 11A8;BF5D;1108 116A 11A8; +BF5E;BF5E;1108 116A 11A9;BF5E;1108 116A 11A9; +BF5F;BF5F;1108 116A 11AA;BF5F;1108 116A 11AA; +BF60;BF60;1108 116A 11AB;BF60;1108 116A 11AB; +BF61;BF61;1108 116A 11AC;BF61;1108 116A 11AC; +BF62;BF62;1108 116A 11AD;BF62;1108 116A 11AD; +BF63;BF63;1108 116A 11AE;BF63;1108 116A 11AE; +BF64;BF64;1108 116A 11AF;BF64;1108 116A 11AF; +BF65;BF65;1108 116A 11B0;BF65;1108 116A 11B0; +BF66;BF66;1108 116A 11B1;BF66;1108 116A 11B1; +BF67;BF67;1108 116A 11B2;BF67;1108 116A 11B2; +BF68;BF68;1108 116A 11B3;BF68;1108 116A 11B3; +BF69;BF69;1108 116A 11B4;BF69;1108 116A 11B4; +BF6A;BF6A;1108 116A 11B5;BF6A;1108 116A 11B5; +BF6B;BF6B;1108 116A 11B6;BF6B;1108 116A 11B6; +BF6C;BF6C;1108 116A 11B7;BF6C;1108 116A 11B7; +BF6D;BF6D;1108 116A 11B8;BF6D;1108 116A 11B8; +BF6E;BF6E;1108 116A 11B9;BF6E;1108 116A 11B9; +BF6F;BF6F;1108 116A 11BA;BF6F;1108 116A 11BA; +BF70;BF70;1108 116A 11BB;BF70;1108 116A 11BB; +BF71;BF71;1108 116A 11BC;BF71;1108 116A 11BC; +BF72;BF72;1108 116A 11BD;BF72;1108 116A 11BD; +BF73;BF73;1108 116A 11BE;BF73;1108 116A 11BE; +BF74;BF74;1108 116A 11BF;BF74;1108 116A 11BF; +BF75;BF75;1108 116A 11C0;BF75;1108 116A 11C0; +BF76;BF76;1108 116A 11C1;BF76;1108 116A 11C1; +BF77;BF77;1108 116A 11C2;BF77;1108 116A 11C2; +BF78;BF78;1108 116B;BF78;1108 116B; +BF79;BF79;1108 116B 11A8;BF79;1108 116B 11A8; +BF7A;BF7A;1108 116B 11A9;BF7A;1108 116B 11A9; +BF7B;BF7B;1108 116B 11AA;BF7B;1108 116B 11AA; +BF7C;BF7C;1108 116B 11AB;BF7C;1108 116B 11AB; +BF7D;BF7D;1108 116B 11AC;BF7D;1108 116B 11AC; +BF7E;BF7E;1108 116B 11AD;BF7E;1108 116B 11AD; +BF7F;BF7F;1108 116B 11AE;BF7F;1108 116B 11AE; +BF80;BF80;1108 116B 11AF;BF80;1108 116B 11AF; +BF81;BF81;1108 116B 11B0;BF81;1108 116B 11B0; +BF82;BF82;1108 116B 11B1;BF82;1108 116B 11B1; +BF83;BF83;1108 116B 11B2;BF83;1108 116B 11B2; +BF84;BF84;1108 116B 11B3;BF84;1108 116B 11B3; +BF85;BF85;1108 116B 11B4;BF85;1108 116B 11B4; +BF86;BF86;1108 116B 11B5;BF86;1108 116B 11B5; +BF87;BF87;1108 116B 11B6;BF87;1108 116B 11B6; +BF88;BF88;1108 116B 11B7;BF88;1108 116B 11B7; +BF89;BF89;1108 116B 11B8;BF89;1108 116B 11B8; +BF8A;BF8A;1108 116B 11B9;BF8A;1108 116B 11B9; +BF8B;BF8B;1108 116B 11BA;BF8B;1108 116B 11BA; +BF8C;BF8C;1108 116B 11BB;BF8C;1108 116B 11BB; +BF8D;BF8D;1108 116B 11BC;BF8D;1108 116B 11BC; +BF8E;BF8E;1108 116B 11BD;BF8E;1108 116B 11BD; +BF8F;BF8F;1108 116B 11BE;BF8F;1108 116B 11BE; +BF90;BF90;1108 116B 11BF;BF90;1108 116B 11BF; +BF91;BF91;1108 116B 11C0;BF91;1108 116B 11C0; +BF92;BF92;1108 116B 11C1;BF92;1108 116B 11C1; +BF93;BF93;1108 116B 11C2;BF93;1108 116B 11C2; +BF94;BF94;1108 116C;BF94;1108 116C; +BF95;BF95;1108 116C 11A8;BF95;1108 116C 11A8; +BF96;BF96;1108 116C 11A9;BF96;1108 116C 11A9; +BF97;BF97;1108 116C 11AA;BF97;1108 116C 11AA; +BF98;BF98;1108 116C 11AB;BF98;1108 116C 11AB; +BF99;BF99;1108 116C 11AC;BF99;1108 116C 11AC; +BF9A;BF9A;1108 116C 11AD;BF9A;1108 116C 11AD; +BF9B;BF9B;1108 116C 11AE;BF9B;1108 116C 11AE; +BF9C;BF9C;1108 116C 11AF;BF9C;1108 116C 11AF; +BF9D;BF9D;1108 116C 11B0;BF9D;1108 116C 11B0; +BF9E;BF9E;1108 116C 11B1;BF9E;1108 116C 11B1; +BF9F;BF9F;1108 116C 11B2;BF9F;1108 116C 11B2; +BFA0;BFA0;1108 116C 11B3;BFA0;1108 116C 11B3; +BFA1;BFA1;1108 116C 11B4;BFA1;1108 116C 11B4; +BFA2;BFA2;1108 116C 11B5;BFA2;1108 116C 11B5; +BFA3;BFA3;1108 116C 11B6;BFA3;1108 116C 11B6; +BFA4;BFA4;1108 116C 11B7;BFA4;1108 116C 11B7; +BFA5;BFA5;1108 116C 11B8;BFA5;1108 116C 11B8; +BFA6;BFA6;1108 116C 11B9;BFA6;1108 116C 11B9; +BFA7;BFA7;1108 116C 11BA;BFA7;1108 116C 11BA; +BFA8;BFA8;1108 116C 11BB;BFA8;1108 116C 11BB; +BFA9;BFA9;1108 116C 11BC;BFA9;1108 116C 11BC; +BFAA;BFAA;1108 116C 11BD;BFAA;1108 116C 11BD; +BFAB;BFAB;1108 116C 11BE;BFAB;1108 116C 11BE; +BFAC;BFAC;1108 116C 11BF;BFAC;1108 116C 11BF; +BFAD;BFAD;1108 116C 11C0;BFAD;1108 116C 11C0; +BFAE;BFAE;1108 116C 11C1;BFAE;1108 116C 11C1; +BFAF;BFAF;1108 116C 11C2;BFAF;1108 116C 11C2; +BFB0;BFB0;1108 116D;BFB0;1108 116D; +BFB1;BFB1;1108 116D 11A8;BFB1;1108 116D 11A8; +BFB2;BFB2;1108 116D 11A9;BFB2;1108 116D 11A9; +BFB3;BFB3;1108 116D 11AA;BFB3;1108 116D 11AA; +BFB4;BFB4;1108 116D 11AB;BFB4;1108 116D 11AB; +BFB5;BFB5;1108 116D 11AC;BFB5;1108 116D 11AC; +BFB6;BFB6;1108 116D 11AD;BFB6;1108 116D 11AD; +BFB7;BFB7;1108 116D 11AE;BFB7;1108 116D 11AE; +BFB8;BFB8;1108 116D 11AF;BFB8;1108 116D 11AF; +BFB9;BFB9;1108 116D 11B0;BFB9;1108 116D 11B0; +BFBA;BFBA;1108 116D 11B1;BFBA;1108 116D 11B1; +BFBB;BFBB;1108 116D 11B2;BFBB;1108 116D 11B2; +BFBC;BFBC;1108 116D 11B3;BFBC;1108 116D 11B3; +BFBD;BFBD;1108 116D 11B4;BFBD;1108 116D 11B4; +BFBE;BFBE;1108 116D 11B5;BFBE;1108 116D 11B5; +BFBF;BFBF;1108 116D 11B6;BFBF;1108 116D 11B6; +BFC0;BFC0;1108 116D 11B7;BFC0;1108 116D 11B7; +BFC1;BFC1;1108 116D 11B8;BFC1;1108 116D 11B8; +BFC2;BFC2;1108 116D 11B9;BFC2;1108 116D 11B9; +BFC3;BFC3;1108 116D 11BA;BFC3;1108 116D 11BA; +BFC4;BFC4;1108 116D 11BB;BFC4;1108 116D 11BB; +BFC5;BFC5;1108 116D 11BC;BFC5;1108 116D 11BC; +BFC6;BFC6;1108 116D 11BD;BFC6;1108 116D 11BD; +BFC7;BFC7;1108 116D 11BE;BFC7;1108 116D 11BE; +BFC8;BFC8;1108 116D 11BF;BFC8;1108 116D 11BF; +BFC9;BFC9;1108 116D 11C0;BFC9;1108 116D 11C0; +BFCA;BFCA;1108 116D 11C1;BFCA;1108 116D 11C1; +BFCB;BFCB;1108 116D 11C2;BFCB;1108 116D 11C2; +BFCC;BFCC;1108 116E;BFCC;1108 116E; +BFCD;BFCD;1108 116E 11A8;BFCD;1108 116E 11A8; +BFCE;BFCE;1108 116E 11A9;BFCE;1108 116E 11A9; +BFCF;BFCF;1108 116E 11AA;BFCF;1108 116E 11AA; +BFD0;BFD0;1108 116E 11AB;BFD0;1108 116E 11AB; +BFD1;BFD1;1108 116E 11AC;BFD1;1108 116E 11AC; +BFD2;BFD2;1108 116E 11AD;BFD2;1108 116E 11AD; +BFD3;BFD3;1108 116E 11AE;BFD3;1108 116E 11AE; +BFD4;BFD4;1108 116E 11AF;BFD4;1108 116E 11AF; +BFD5;BFD5;1108 116E 11B0;BFD5;1108 116E 11B0; +BFD6;BFD6;1108 116E 11B1;BFD6;1108 116E 11B1; +BFD7;BFD7;1108 116E 11B2;BFD7;1108 116E 11B2; +BFD8;BFD8;1108 116E 11B3;BFD8;1108 116E 11B3; +BFD9;BFD9;1108 116E 11B4;BFD9;1108 116E 11B4; +BFDA;BFDA;1108 116E 11B5;BFDA;1108 116E 11B5; +BFDB;BFDB;1108 116E 11B6;BFDB;1108 116E 11B6; +BFDC;BFDC;1108 116E 11B7;BFDC;1108 116E 11B7; +BFDD;BFDD;1108 116E 11B8;BFDD;1108 116E 11B8; +BFDE;BFDE;1108 116E 11B9;BFDE;1108 116E 11B9; +BFDF;BFDF;1108 116E 11BA;BFDF;1108 116E 11BA; +BFE0;BFE0;1108 116E 11BB;BFE0;1108 116E 11BB; +BFE1;BFE1;1108 116E 11BC;BFE1;1108 116E 11BC; +BFE2;BFE2;1108 116E 11BD;BFE2;1108 116E 11BD; +BFE3;BFE3;1108 116E 11BE;BFE3;1108 116E 11BE; +BFE4;BFE4;1108 116E 11BF;BFE4;1108 116E 11BF; +BFE5;BFE5;1108 116E 11C0;BFE5;1108 116E 11C0; +BFE6;BFE6;1108 116E 11C1;BFE6;1108 116E 11C1; +BFE7;BFE7;1108 116E 11C2;BFE7;1108 116E 11C2; +BFE8;BFE8;1108 116F;BFE8;1108 116F; +BFE9;BFE9;1108 116F 11A8;BFE9;1108 116F 11A8; +BFEA;BFEA;1108 116F 11A9;BFEA;1108 116F 11A9; +BFEB;BFEB;1108 116F 11AA;BFEB;1108 116F 11AA; +BFEC;BFEC;1108 116F 11AB;BFEC;1108 116F 11AB; +BFED;BFED;1108 116F 11AC;BFED;1108 116F 11AC; +BFEE;BFEE;1108 116F 11AD;BFEE;1108 116F 11AD; +BFEF;BFEF;1108 116F 11AE;BFEF;1108 116F 11AE; +BFF0;BFF0;1108 116F 11AF;BFF0;1108 116F 11AF; +BFF1;BFF1;1108 116F 11B0;BFF1;1108 116F 11B0; +BFF2;BFF2;1108 116F 11B1;BFF2;1108 116F 11B1; +BFF3;BFF3;1108 116F 11B2;BFF3;1108 116F 11B2; +BFF4;BFF4;1108 116F 11B3;BFF4;1108 116F 11B3; +BFF5;BFF5;1108 116F 11B4;BFF5;1108 116F 11B4; +BFF6;BFF6;1108 116F 11B5;BFF6;1108 116F 11B5; +BFF7;BFF7;1108 116F 11B6;BFF7;1108 116F 11B6; +BFF8;BFF8;1108 116F 11B7;BFF8;1108 116F 11B7; +BFF9;BFF9;1108 116F 11B8;BFF9;1108 116F 11B8; +BFFA;BFFA;1108 116F 11B9;BFFA;1108 116F 11B9; +BFFB;BFFB;1108 116F 11BA;BFFB;1108 116F 11BA; +BFFC;BFFC;1108 116F 11BB;BFFC;1108 116F 11BB; +BFFD;BFFD;1108 116F 11BC;BFFD;1108 116F 11BC; +BFFE;BFFE;1108 116F 11BD;BFFE;1108 116F 11BD; +BFFF;BFFF;1108 116F 11BE;BFFF;1108 116F 11BE; +C000;C000;1108 116F 11BF;C000;1108 116F 11BF; +C001;C001;1108 116F 11C0;C001;1108 116F 11C0; +C002;C002;1108 116F 11C1;C002;1108 116F 11C1; +C003;C003;1108 116F 11C2;C003;1108 116F 11C2; +C004;C004;1108 1170;C004;1108 1170; +C005;C005;1108 1170 11A8;C005;1108 1170 11A8; +C006;C006;1108 1170 11A9;C006;1108 1170 11A9; +C007;C007;1108 1170 11AA;C007;1108 1170 11AA; +C008;C008;1108 1170 11AB;C008;1108 1170 11AB; +C009;C009;1108 1170 11AC;C009;1108 1170 11AC; +C00A;C00A;1108 1170 11AD;C00A;1108 1170 11AD; +C00B;C00B;1108 1170 11AE;C00B;1108 1170 11AE; +C00C;C00C;1108 1170 11AF;C00C;1108 1170 11AF; +C00D;C00D;1108 1170 11B0;C00D;1108 1170 11B0; +C00E;C00E;1108 1170 11B1;C00E;1108 1170 11B1; +C00F;C00F;1108 1170 11B2;C00F;1108 1170 11B2; +C010;C010;1108 1170 11B3;C010;1108 1170 11B3; +C011;C011;1108 1170 11B4;C011;1108 1170 11B4; +C012;C012;1108 1170 11B5;C012;1108 1170 11B5; +C013;C013;1108 1170 11B6;C013;1108 1170 11B6; +C014;C014;1108 1170 11B7;C014;1108 1170 11B7; +C015;C015;1108 1170 11B8;C015;1108 1170 11B8; +C016;C016;1108 1170 11B9;C016;1108 1170 11B9; +C017;C017;1108 1170 11BA;C017;1108 1170 11BA; +C018;C018;1108 1170 11BB;C018;1108 1170 11BB; +C019;C019;1108 1170 11BC;C019;1108 1170 11BC; +C01A;C01A;1108 1170 11BD;C01A;1108 1170 11BD; +C01B;C01B;1108 1170 11BE;C01B;1108 1170 11BE; +C01C;C01C;1108 1170 11BF;C01C;1108 1170 11BF; +C01D;C01D;1108 1170 11C0;C01D;1108 1170 11C0; +C01E;C01E;1108 1170 11C1;C01E;1108 1170 11C1; +C01F;C01F;1108 1170 11C2;C01F;1108 1170 11C2; +C020;C020;1108 1171;C020;1108 1171; +C021;C021;1108 1171 11A8;C021;1108 1171 11A8; +C022;C022;1108 1171 11A9;C022;1108 1171 11A9; +C023;C023;1108 1171 11AA;C023;1108 1171 11AA; +C024;C024;1108 1171 11AB;C024;1108 1171 11AB; +C025;C025;1108 1171 11AC;C025;1108 1171 11AC; +C026;C026;1108 1171 11AD;C026;1108 1171 11AD; +C027;C027;1108 1171 11AE;C027;1108 1171 11AE; +C028;C028;1108 1171 11AF;C028;1108 1171 11AF; +C029;C029;1108 1171 11B0;C029;1108 1171 11B0; +C02A;C02A;1108 1171 11B1;C02A;1108 1171 11B1; +C02B;C02B;1108 1171 11B2;C02B;1108 1171 11B2; +C02C;C02C;1108 1171 11B3;C02C;1108 1171 11B3; +C02D;C02D;1108 1171 11B4;C02D;1108 1171 11B4; +C02E;C02E;1108 1171 11B5;C02E;1108 1171 11B5; +C02F;C02F;1108 1171 11B6;C02F;1108 1171 11B6; +C030;C030;1108 1171 11B7;C030;1108 1171 11B7; +C031;C031;1108 1171 11B8;C031;1108 1171 11B8; +C032;C032;1108 1171 11B9;C032;1108 1171 11B9; +C033;C033;1108 1171 11BA;C033;1108 1171 11BA; +C034;C034;1108 1171 11BB;C034;1108 1171 11BB; +C035;C035;1108 1171 11BC;C035;1108 1171 11BC; +C036;C036;1108 1171 11BD;C036;1108 1171 11BD; +C037;C037;1108 1171 11BE;C037;1108 1171 11BE; +C038;C038;1108 1171 11BF;C038;1108 1171 11BF; +C039;C039;1108 1171 11C0;C039;1108 1171 11C0; +C03A;C03A;1108 1171 11C1;C03A;1108 1171 11C1; +C03B;C03B;1108 1171 11C2;C03B;1108 1171 11C2; +C03C;C03C;1108 1172;C03C;1108 1172; +C03D;C03D;1108 1172 11A8;C03D;1108 1172 11A8; +C03E;C03E;1108 1172 11A9;C03E;1108 1172 11A9; +C03F;C03F;1108 1172 11AA;C03F;1108 1172 11AA; +C040;C040;1108 1172 11AB;C040;1108 1172 11AB; +C041;C041;1108 1172 11AC;C041;1108 1172 11AC; +C042;C042;1108 1172 11AD;C042;1108 1172 11AD; +C043;C043;1108 1172 11AE;C043;1108 1172 11AE; +C044;C044;1108 1172 11AF;C044;1108 1172 11AF; +C045;C045;1108 1172 11B0;C045;1108 1172 11B0; +C046;C046;1108 1172 11B1;C046;1108 1172 11B1; +C047;C047;1108 1172 11B2;C047;1108 1172 11B2; +C048;C048;1108 1172 11B3;C048;1108 1172 11B3; +C049;C049;1108 1172 11B4;C049;1108 1172 11B4; +C04A;C04A;1108 1172 11B5;C04A;1108 1172 11B5; +C04B;C04B;1108 1172 11B6;C04B;1108 1172 11B6; +C04C;C04C;1108 1172 11B7;C04C;1108 1172 11B7; +C04D;C04D;1108 1172 11B8;C04D;1108 1172 11B8; +C04E;C04E;1108 1172 11B9;C04E;1108 1172 11B9; +C04F;C04F;1108 1172 11BA;C04F;1108 1172 11BA; +C050;C050;1108 1172 11BB;C050;1108 1172 11BB; +C051;C051;1108 1172 11BC;C051;1108 1172 11BC; +C052;C052;1108 1172 11BD;C052;1108 1172 11BD; +C053;C053;1108 1172 11BE;C053;1108 1172 11BE; +C054;C054;1108 1172 11BF;C054;1108 1172 11BF; +C055;C055;1108 1172 11C0;C055;1108 1172 11C0; +C056;C056;1108 1172 11C1;C056;1108 1172 11C1; +C057;C057;1108 1172 11C2;C057;1108 1172 11C2; +C058;C058;1108 1173;C058;1108 1173; +C059;C059;1108 1173 11A8;C059;1108 1173 11A8; +C05A;C05A;1108 1173 11A9;C05A;1108 1173 11A9; +C05B;C05B;1108 1173 11AA;C05B;1108 1173 11AA; +C05C;C05C;1108 1173 11AB;C05C;1108 1173 11AB; +C05D;C05D;1108 1173 11AC;C05D;1108 1173 11AC; +C05E;C05E;1108 1173 11AD;C05E;1108 1173 11AD; +C05F;C05F;1108 1173 11AE;C05F;1108 1173 11AE; +C060;C060;1108 1173 11AF;C060;1108 1173 11AF; +C061;C061;1108 1173 11B0;C061;1108 1173 11B0; +C062;C062;1108 1173 11B1;C062;1108 1173 11B1; +C063;C063;1108 1173 11B2;C063;1108 1173 11B2; +C064;C064;1108 1173 11B3;C064;1108 1173 11B3; +C065;C065;1108 1173 11B4;C065;1108 1173 11B4; +C066;C066;1108 1173 11B5;C066;1108 1173 11B5; +C067;C067;1108 1173 11B6;C067;1108 1173 11B6; +C068;C068;1108 1173 11B7;C068;1108 1173 11B7; +C069;C069;1108 1173 11B8;C069;1108 1173 11B8; +C06A;C06A;1108 1173 11B9;C06A;1108 1173 11B9; +C06B;C06B;1108 1173 11BA;C06B;1108 1173 11BA; +C06C;C06C;1108 1173 11BB;C06C;1108 1173 11BB; +C06D;C06D;1108 1173 11BC;C06D;1108 1173 11BC; +C06E;C06E;1108 1173 11BD;C06E;1108 1173 11BD; +C06F;C06F;1108 1173 11BE;C06F;1108 1173 11BE; +C070;C070;1108 1173 11BF;C070;1108 1173 11BF; +C071;C071;1108 1173 11C0;C071;1108 1173 11C0; +C072;C072;1108 1173 11C1;C072;1108 1173 11C1; +C073;C073;1108 1173 11C2;C073;1108 1173 11C2; +C074;C074;1108 1174;C074;1108 1174; +C075;C075;1108 1174 11A8;C075;1108 1174 11A8; +C076;C076;1108 1174 11A9;C076;1108 1174 11A9; +C077;C077;1108 1174 11AA;C077;1108 1174 11AA; +C078;C078;1108 1174 11AB;C078;1108 1174 11AB; +C079;C079;1108 1174 11AC;C079;1108 1174 11AC; +C07A;C07A;1108 1174 11AD;C07A;1108 1174 11AD; +C07B;C07B;1108 1174 11AE;C07B;1108 1174 11AE; +C07C;C07C;1108 1174 11AF;C07C;1108 1174 11AF; +C07D;C07D;1108 1174 11B0;C07D;1108 1174 11B0; +C07E;C07E;1108 1174 11B1;C07E;1108 1174 11B1; +C07F;C07F;1108 1174 11B2;C07F;1108 1174 11B2; +C080;C080;1108 1174 11B3;C080;1108 1174 11B3; +C081;C081;1108 1174 11B4;C081;1108 1174 11B4; +C082;C082;1108 1174 11B5;C082;1108 1174 11B5; +C083;C083;1108 1174 11B6;C083;1108 1174 11B6; +C084;C084;1108 1174 11B7;C084;1108 1174 11B7; +C085;C085;1108 1174 11B8;C085;1108 1174 11B8; +C086;C086;1108 1174 11B9;C086;1108 1174 11B9; +C087;C087;1108 1174 11BA;C087;1108 1174 11BA; +C088;C088;1108 1174 11BB;C088;1108 1174 11BB; +C089;C089;1108 1174 11BC;C089;1108 1174 11BC; +C08A;C08A;1108 1174 11BD;C08A;1108 1174 11BD; +C08B;C08B;1108 1174 11BE;C08B;1108 1174 11BE; +C08C;C08C;1108 1174 11BF;C08C;1108 1174 11BF; +C08D;C08D;1108 1174 11C0;C08D;1108 1174 11C0; +C08E;C08E;1108 1174 11C1;C08E;1108 1174 11C1; +C08F;C08F;1108 1174 11C2;C08F;1108 1174 11C2; +C090;C090;1108 1175;C090;1108 1175; +C091;C091;1108 1175 11A8;C091;1108 1175 11A8; +C092;C092;1108 1175 11A9;C092;1108 1175 11A9; +C093;C093;1108 1175 11AA;C093;1108 1175 11AA; +C094;C094;1108 1175 11AB;C094;1108 1175 11AB; +C095;C095;1108 1175 11AC;C095;1108 1175 11AC; +C096;C096;1108 1175 11AD;C096;1108 1175 11AD; +C097;C097;1108 1175 11AE;C097;1108 1175 11AE; +C098;C098;1108 1175 11AF;C098;1108 1175 11AF; +C099;C099;1108 1175 11B0;C099;1108 1175 11B0; +C09A;C09A;1108 1175 11B1;C09A;1108 1175 11B1; +C09B;C09B;1108 1175 11B2;C09B;1108 1175 11B2; +C09C;C09C;1108 1175 11B3;C09C;1108 1175 11B3; +C09D;C09D;1108 1175 11B4;C09D;1108 1175 11B4; +C09E;C09E;1108 1175 11B5;C09E;1108 1175 11B5; +C09F;C09F;1108 1175 11B6;C09F;1108 1175 11B6; +C0A0;C0A0;1108 1175 11B7;C0A0;1108 1175 11B7; +C0A1;C0A1;1108 1175 11B8;C0A1;1108 1175 11B8; +C0A2;C0A2;1108 1175 11B9;C0A2;1108 1175 11B9; +C0A3;C0A3;1108 1175 11BA;C0A3;1108 1175 11BA; +C0A4;C0A4;1108 1175 11BB;C0A4;1108 1175 11BB; +C0A5;C0A5;1108 1175 11BC;C0A5;1108 1175 11BC; +C0A6;C0A6;1108 1175 11BD;C0A6;1108 1175 11BD; +C0A7;C0A7;1108 1175 11BE;C0A7;1108 1175 11BE; +C0A8;C0A8;1108 1175 11BF;C0A8;1108 1175 11BF; +C0A9;C0A9;1108 1175 11C0;C0A9;1108 1175 11C0; +C0AA;C0AA;1108 1175 11C1;C0AA;1108 1175 11C1; +C0AB;C0AB;1108 1175 11C2;C0AB;1108 1175 11C2; +C0AC;C0AC;1109 1161;C0AC;1109 1161; +C0AD;C0AD;1109 1161 11A8;C0AD;1109 1161 11A8; +C0AE;C0AE;1109 1161 11A9;C0AE;1109 1161 11A9; +C0AF;C0AF;1109 1161 11AA;C0AF;1109 1161 11AA; +C0B0;C0B0;1109 1161 11AB;C0B0;1109 1161 11AB; +C0B1;C0B1;1109 1161 11AC;C0B1;1109 1161 11AC; +C0B2;C0B2;1109 1161 11AD;C0B2;1109 1161 11AD; +C0B3;C0B3;1109 1161 11AE;C0B3;1109 1161 11AE; +C0B4;C0B4;1109 1161 11AF;C0B4;1109 1161 11AF; +C0B5;C0B5;1109 1161 11B0;C0B5;1109 1161 11B0; +C0B6;C0B6;1109 1161 11B1;C0B6;1109 1161 11B1; +C0B7;C0B7;1109 1161 11B2;C0B7;1109 1161 11B2; +C0B8;C0B8;1109 1161 11B3;C0B8;1109 1161 11B3; +C0B9;C0B9;1109 1161 11B4;C0B9;1109 1161 11B4; +C0BA;C0BA;1109 1161 11B5;C0BA;1109 1161 11B5; +C0BB;C0BB;1109 1161 11B6;C0BB;1109 1161 11B6; +C0BC;C0BC;1109 1161 11B7;C0BC;1109 1161 11B7; +C0BD;C0BD;1109 1161 11B8;C0BD;1109 1161 11B8; +C0BE;C0BE;1109 1161 11B9;C0BE;1109 1161 11B9; +C0BF;C0BF;1109 1161 11BA;C0BF;1109 1161 11BA; +C0C0;C0C0;1109 1161 11BB;C0C0;1109 1161 11BB; +C0C1;C0C1;1109 1161 11BC;C0C1;1109 1161 11BC; +C0C2;C0C2;1109 1161 11BD;C0C2;1109 1161 11BD; +C0C3;C0C3;1109 1161 11BE;C0C3;1109 1161 11BE; +C0C4;C0C4;1109 1161 11BF;C0C4;1109 1161 11BF; +C0C5;C0C5;1109 1161 11C0;C0C5;1109 1161 11C0; +C0C6;C0C6;1109 1161 11C1;C0C6;1109 1161 11C1; +C0C7;C0C7;1109 1161 11C2;C0C7;1109 1161 11C2; +C0C8;C0C8;1109 1162;C0C8;1109 1162; +C0C9;C0C9;1109 1162 11A8;C0C9;1109 1162 11A8; +C0CA;C0CA;1109 1162 11A9;C0CA;1109 1162 11A9; +C0CB;C0CB;1109 1162 11AA;C0CB;1109 1162 11AA; +C0CC;C0CC;1109 1162 11AB;C0CC;1109 1162 11AB; +C0CD;C0CD;1109 1162 11AC;C0CD;1109 1162 11AC; +C0CE;C0CE;1109 1162 11AD;C0CE;1109 1162 11AD; +C0CF;C0CF;1109 1162 11AE;C0CF;1109 1162 11AE; +C0D0;C0D0;1109 1162 11AF;C0D0;1109 1162 11AF; +C0D1;C0D1;1109 1162 11B0;C0D1;1109 1162 11B0; +C0D2;C0D2;1109 1162 11B1;C0D2;1109 1162 11B1; +C0D3;C0D3;1109 1162 11B2;C0D3;1109 1162 11B2; +C0D4;C0D4;1109 1162 11B3;C0D4;1109 1162 11B3; +C0D5;C0D5;1109 1162 11B4;C0D5;1109 1162 11B4; +C0D6;C0D6;1109 1162 11B5;C0D6;1109 1162 11B5; +C0D7;C0D7;1109 1162 11B6;C0D7;1109 1162 11B6; +C0D8;C0D8;1109 1162 11B7;C0D8;1109 1162 11B7; +C0D9;C0D9;1109 1162 11B8;C0D9;1109 1162 11B8; +C0DA;C0DA;1109 1162 11B9;C0DA;1109 1162 11B9; +C0DB;C0DB;1109 1162 11BA;C0DB;1109 1162 11BA; +C0DC;C0DC;1109 1162 11BB;C0DC;1109 1162 11BB; +C0DD;C0DD;1109 1162 11BC;C0DD;1109 1162 11BC; +C0DE;C0DE;1109 1162 11BD;C0DE;1109 1162 11BD; +C0DF;C0DF;1109 1162 11BE;C0DF;1109 1162 11BE; +C0E0;C0E0;1109 1162 11BF;C0E0;1109 1162 11BF; +C0E1;C0E1;1109 1162 11C0;C0E1;1109 1162 11C0; +C0E2;C0E2;1109 1162 11C1;C0E2;1109 1162 11C1; +C0E3;C0E3;1109 1162 11C2;C0E3;1109 1162 11C2; +C0E4;C0E4;1109 1163;C0E4;1109 1163; +C0E5;C0E5;1109 1163 11A8;C0E5;1109 1163 11A8; +C0E6;C0E6;1109 1163 11A9;C0E6;1109 1163 11A9; +C0E7;C0E7;1109 1163 11AA;C0E7;1109 1163 11AA; +C0E8;C0E8;1109 1163 11AB;C0E8;1109 1163 11AB; +C0E9;C0E9;1109 1163 11AC;C0E9;1109 1163 11AC; +C0EA;C0EA;1109 1163 11AD;C0EA;1109 1163 11AD; +C0EB;C0EB;1109 1163 11AE;C0EB;1109 1163 11AE; +C0EC;C0EC;1109 1163 11AF;C0EC;1109 1163 11AF; +C0ED;C0ED;1109 1163 11B0;C0ED;1109 1163 11B0; +C0EE;C0EE;1109 1163 11B1;C0EE;1109 1163 11B1; +C0EF;C0EF;1109 1163 11B2;C0EF;1109 1163 11B2; +C0F0;C0F0;1109 1163 11B3;C0F0;1109 1163 11B3; +C0F1;C0F1;1109 1163 11B4;C0F1;1109 1163 11B4; +C0F2;C0F2;1109 1163 11B5;C0F2;1109 1163 11B5; +C0F3;C0F3;1109 1163 11B6;C0F3;1109 1163 11B6; +C0F4;C0F4;1109 1163 11B7;C0F4;1109 1163 11B7; +C0F5;C0F5;1109 1163 11B8;C0F5;1109 1163 11B8; +C0F6;C0F6;1109 1163 11B9;C0F6;1109 1163 11B9; +C0F7;C0F7;1109 1163 11BA;C0F7;1109 1163 11BA; +C0F8;C0F8;1109 1163 11BB;C0F8;1109 1163 11BB; +C0F9;C0F9;1109 1163 11BC;C0F9;1109 1163 11BC; +C0FA;C0FA;1109 1163 11BD;C0FA;1109 1163 11BD; +C0FB;C0FB;1109 1163 11BE;C0FB;1109 1163 11BE; +C0FC;C0FC;1109 1163 11BF;C0FC;1109 1163 11BF; +C0FD;C0FD;1109 1163 11C0;C0FD;1109 1163 11C0; +C0FE;C0FE;1109 1163 11C1;C0FE;1109 1163 11C1; +C0FF;C0FF;1109 1163 11C2;C0FF;1109 1163 11C2; +C100;C100;1109 1164;C100;1109 1164; +C101;C101;1109 1164 11A8;C101;1109 1164 11A8; +C102;C102;1109 1164 11A9;C102;1109 1164 11A9; +C103;C103;1109 1164 11AA;C103;1109 1164 11AA; +C104;C104;1109 1164 11AB;C104;1109 1164 11AB; +C105;C105;1109 1164 11AC;C105;1109 1164 11AC; +C106;C106;1109 1164 11AD;C106;1109 1164 11AD; +C107;C107;1109 1164 11AE;C107;1109 1164 11AE; +C108;C108;1109 1164 11AF;C108;1109 1164 11AF; +C109;C109;1109 1164 11B0;C109;1109 1164 11B0; +C10A;C10A;1109 1164 11B1;C10A;1109 1164 11B1; +C10B;C10B;1109 1164 11B2;C10B;1109 1164 11B2; +C10C;C10C;1109 1164 11B3;C10C;1109 1164 11B3; +C10D;C10D;1109 1164 11B4;C10D;1109 1164 11B4; +C10E;C10E;1109 1164 11B5;C10E;1109 1164 11B5; +C10F;C10F;1109 1164 11B6;C10F;1109 1164 11B6; +C110;C110;1109 1164 11B7;C110;1109 1164 11B7; +C111;C111;1109 1164 11B8;C111;1109 1164 11B8; +C112;C112;1109 1164 11B9;C112;1109 1164 11B9; +C113;C113;1109 1164 11BA;C113;1109 1164 11BA; +C114;C114;1109 1164 11BB;C114;1109 1164 11BB; +C115;C115;1109 1164 11BC;C115;1109 1164 11BC; +C116;C116;1109 1164 11BD;C116;1109 1164 11BD; +C117;C117;1109 1164 11BE;C117;1109 1164 11BE; +C118;C118;1109 1164 11BF;C118;1109 1164 11BF; +C119;C119;1109 1164 11C0;C119;1109 1164 11C0; +C11A;C11A;1109 1164 11C1;C11A;1109 1164 11C1; +C11B;C11B;1109 1164 11C2;C11B;1109 1164 11C2; +C11C;C11C;1109 1165;C11C;1109 1165; +C11D;C11D;1109 1165 11A8;C11D;1109 1165 11A8; +C11E;C11E;1109 1165 11A9;C11E;1109 1165 11A9; +C11F;C11F;1109 1165 11AA;C11F;1109 1165 11AA; +C120;C120;1109 1165 11AB;C120;1109 1165 11AB; +C121;C121;1109 1165 11AC;C121;1109 1165 11AC; +C122;C122;1109 1165 11AD;C122;1109 1165 11AD; +C123;C123;1109 1165 11AE;C123;1109 1165 11AE; +C124;C124;1109 1165 11AF;C124;1109 1165 11AF; +C125;C125;1109 1165 11B0;C125;1109 1165 11B0; +C126;C126;1109 1165 11B1;C126;1109 1165 11B1; +C127;C127;1109 1165 11B2;C127;1109 1165 11B2; +C128;C128;1109 1165 11B3;C128;1109 1165 11B3; +C129;C129;1109 1165 11B4;C129;1109 1165 11B4; +C12A;C12A;1109 1165 11B5;C12A;1109 1165 11B5; +C12B;C12B;1109 1165 11B6;C12B;1109 1165 11B6; +C12C;C12C;1109 1165 11B7;C12C;1109 1165 11B7; +C12D;C12D;1109 1165 11B8;C12D;1109 1165 11B8; +C12E;C12E;1109 1165 11B9;C12E;1109 1165 11B9; +C12F;C12F;1109 1165 11BA;C12F;1109 1165 11BA; +C130;C130;1109 1165 11BB;C130;1109 1165 11BB; +C131;C131;1109 1165 11BC;C131;1109 1165 11BC; +C132;C132;1109 1165 11BD;C132;1109 1165 11BD; +C133;C133;1109 1165 11BE;C133;1109 1165 11BE; +C134;C134;1109 1165 11BF;C134;1109 1165 11BF; +C135;C135;1109 1165 11C0;C135;1109 1165 11C0; +C136;C136;1109 1165 11C1;C136;1109 1165 11C1; +C137;C137;1109 1165 11C2;C137;1109 1165 11C2; +C138;C138;1109 1166;C138;1109 1166; +C139;C139;1109 1166 11A8;C139;1109 1166 11A8; +C13A;C13A;1109 1166 11A9;C13A;1109 1166 11A9; +C13B;C13B;1109 1166 11AA;C13B;1109 1166 11AA; +C13C;C13C;1109 1166 11AB;C13C;1109 1166 11AB; +C13D;C13D;1109 1166 11AC;C13D;1109 1166 11AC; +C13E;C13E;1109 1166 11AD;C13E;1109 1166 11AD; +C13F;C13F;1109 1166 11AE;C13F;1109 1166 11AE; +C140;C140;1109 1166 11AF;C140;1109 1166 11AF; +C141;C141;1109 1166 11B0;C141;1109 1166 11B0; +C142;C142;1109 1166 11B1;C142;1109 1166 11B1; +C143;C143;1109 1166 11B2;C143;1109 1166 11B2; +C144;C144;1109 1166 11B3;C144;1109 1166 11B3; +C145;C145;1109 1166 11B4;C145;1109 1166 11B4; +C146;C146;1109 1166 11B5;C146;1109 1166 11B5; +C147;C147;1109 1166 11B6;C147;1109 1166 11B6; +C148;C148;1109 1166 11B7;C148;1109 1166 11B7; +C149;C149;1109 1166 11B8;C149;1109 1166 11B8; +C14A;C14A;1109 1166 11B9;C14A;1109 1166 11B9; +C14B;C14B;1109 1166 11BA;C14B;1109 1166 11BA; +C14C;C14C;1109 1166 11BB;C14C;1109 1166 11BB; +C14D;C14D;1109 1166 11BC;C14D;1109 1166 11BC; +C14E;C14E;1109 1166 11BD;C14E;1109 1166 11BD; +C14F;C14F;1109 1166 11BE;C14F;1109 1166 11BE; +C150;C150;1109 1166 11BF;C150;1109 1166 11BF; +C151;C151;1109 1166 11C0;C151;1109 1166 11C0; +C152;C152;1109 1166 11C1;C152;1109 1166 11C1; +C153;C153;1109 1166 11C2;C153;1109 1166 11C2; +C154;C154;1109 1167;C154;1109 1167; +C155;C155;1109 1167 11A8;C155;1109 1167 11A8; +C156;C156;1109 1167 11A9;C156;1109 1167 11A9; +C157;C157;1109 1167 11AA;C157;1109 1167 11AA; +C158;C158;1109 1167 11AB;C158;1109 1167 11AB; +C159;C159;1109 1167 11AC;C159;1109 1167 11AC; +C15A;C15A;1109 1167 11AD;C15A;1109 1167 11AD; +C15B;C15B;1109 1167 11AE;C15B;1109 1167 11AE; +C15C;C15C;1109 1167 11AF;C15C;1109 1167 11AF; +C15D;C15D;1109 1167 11B0;C15D;1109 1167 11B0; +C15E;C15E;1109 1167 11B1;C15E;1109 1167 11B1; +C15F;C15F;1109 1167 11B2;C15F;1109 1167 11B2; +C160;C160;1109 1167 11B3;C160;1109 1167 11B3; +C161;C161;1109 1167 11B4;C161;1109 1167 11B4; +C162;C162;1109 1167 11B5;C162;1109 1167 11B5; +C163;C163;1109 1167 11B6;C163;1109 1167 11B6; +C164;C164;1109 1167 11B7;C164;1109 1167 11B7; +C165;C165;1109 1167 11B8;C165;1109 1167 11B8; +C166;C166;1109 1167 11B9;C166;1109 1167 11B9; +C167;C167;1109 1167 11BA;C167;1109 1167 11BA; +C168;C168;1109 1167 11BB;C168;1109 1167 11BB; +C169;C169;1109 1167 11BC;C169;1109 1167 11BC; +C16A;C16A;1109 1167 11BD;C16A;1109 1167 11BD; +C16B;C16B;1109 1167 11BE;C16B;1109 1167 11BE; +C16C;C16C;1109 1167 11BF;C16C;1109 1167 11BF; +C16D;C16D;1109 1167 11C0;C16D;1109 1167 11C0; +C16E;C16E;1109 1167 11C1;C16E;1109 1167 11C1; +C16F;C16F;1109 1167 11C2;C16F;1109 1167 11C2; +C170;C170;1109 1168;C170;1109 1168; +C171;C171;1109 1168 11A8;C171;1109 1168 11A8; +C172;C172;1109 1168 11A9;C172;1109 1168 11A9; +C173;C173;1109 1168 11AA;C173;1109 1168 11AA; +C174;C174;1109 1168 11AB;C174;1109 1168 11AB; +C175;C175;1109 1168 11AC;C175;1109 1168 11AC; +C176;C176;1109 1168 11AD;C176;1109 1168 11AD; +C177;C177;1109 1168 11AE;C177;1109 1168 11AE; +C178;C178;1109 1168 11AF;C178;1109 1168 11AF; +C179;C179;1109 1168 11B0;C179;1109 1168 11B0; +C17A;C17A;1109 1168 11B1;C17A;1109 1168 11B1; +C17B;C17B;1109 1168 11B2;C17B;1109 1168 11B2; +C17C;C17C;1109 1168 11B3;C17C;1109 1168 11B3; +C17D;C17D;1109 1168 11B4;C17D;1109 1168 11B4; +C17E;C17E;1109 1168 11B5;C17E;1109 1168 11B5; +C17F;C17F;1109 1168 11B6;C17F;1109 1168 11B6; +C180;C180;1109 1168 11B7;C180;1109 1168 11B7; +C181;C181;1109 1168 11B8;C181;1109 1168 11B8; +C182;C182;1109 1168 11B9;C182;1109 1168 11B9; +C183;C183;1109 1168 11BA;C183;1109 1168 11BA; +C184;C184;1109 1168 11BB;C184;1109 1168 11BB; +C185;C185;1109 1168 11BC;C185;1109 1168 11BC; +C186;C186;1109 1168 11BD;C186;1109 1168 11BD; +C187;C187;1109 1168 11BE;C187;1109 1168 11BE; +C188;C188;1109 1168 11BF;C188;1109 1168 11BF; +C189;C189;1109 1168 11C0;C189;1109 1168 11C0; +C18A;C18A;1109 1168 11C1;C18A;1109 1168 11C1; +C18B;C18B;1109 1168 11C2;C18B;1109 1168 11C2; +C18C;C18C;1109 1169;C18C;1109 1169; +C18D;C18D;1109 1169 11A8;C18D;1109 1169 11A8; +C18E;C18E;1109 1169 11A9;C18E;1109 1169 11A9; +C18F;C18F;1109 1169 11AA;C18F;1109 1169 11AA; +C190;C190;1109 1169 11AB;C190;1109 1169 11AB; +C191;C191;1109 1169 11AC;C191;1109 1169 11AC; +C192;C192;1109 1169 11AD;C192;1109 1169 11AD; +C193;C193;1109 1169 11AE;C193;1109 1169 11AE; +C194;C194;1109 1169 11AF;C194;1109 1169 11AF; +C195;C195;1109 1169 11B0;C195;1109 1169 11B0; +C196;C196;1109 1169 11B1;C196;1109 1169 11B1; +C197;C197;1109 1169 11B2;C197;1109 1169 11B2; +C198;C198;1109 1169 11B3;C198;1109 1169 11B3; +C199;C199;1109 1169 11B4;C199;1109 1169 11B4; +C19A;C19A;1109 1169 11B5;C19A;1109 1169 11B5; +C19B;C19B;1109 1169 11B6;C19B;1109 1169 11B6; +C19C;C19C;1109 1169 11B7;C19C;1109 1169 11B7; +C19D;C19D;1109 1169 11B8;C19D;1109 1169 11B8; +C19E;C19E;1109 1169 11B9;C19E;1109 1169 11B9; +C19F;C19F;1109 1169 11BA;C19F;1109 1169 11BA; +C1A0;C1A0;1109 1169 11BB;C1A0;1109 1169 11BB; +C1A1;C1A1;1109 1169 11BC;C1A1;1109 1169 11BC; +C1A2;C1A2;1109 1169 11BD;C1A2;1109 1169 11BD; +C1A3;C1A3;1109 1169 11BE;C1A3;1109 1169 11BE; +C1A4;C1A4;1109 1169 11BF;C1A4;1109 1169 11BF; +C1A5;C1A5;1109 1169 11C0;C1A5;1109 1169 11C0; +C1A6;C1A6;1109 1169 11C1;C1A6;1109 1169 11C1; +C1A7;C1A7;1109 1169 11C2;C1A7;1109 1169 11C2; +C1A8;C1A8;1109 116A;C1A8;1109 116A; +C1A9;C1A9;1109 116A 11A8;C1A9;1109 116A 11A8; +C1AA;C1AA;1109 116A 11A9;C1AA;1109 116A 11A9; +C1AB;C1AB;1109 116A 11AA;C1AB;1109 116A 11AA; +C1AC;C1AC;1109 116A 11AB;C1AC;1109 116A 11AB; +C1AD;C1AD;1109 116A 11AC;C1AD;1109 116A 11AC; +C1AE;C1AE;1109 116A 11AD;C1AE;1109 116A 11AD; +C1AF;C1AF;1109 116A 11AE;C1AF;1109 116A 11AE; +C1B0;C1B0;1109 116A 11AF;C1B0;1109 116A 11AF; +C1B1;C1B1;1109 116A 11B0;C1B1;1109 116A 11B0; +C1B2;C1B2;1109 116A 11B1;C1B2;1109 116A 11B1; +C1B3;C1B3;1109 116A 11B2;C1B3;1109 116A 11B2; +C1B4;C1B4;1109 116A 11B3;C1B4;1109 116A 11B3; +C1B5;C1B5;1109 116A 11B4;C1B5;1109 116A 11B4; +C1B6;C1B6;1109 116A 11B5;C1B6;1109 116A 11B5; +C1B7;C1B7;1109 116A 11B6;C1B7;1109 116A 11B6; +C1B8;C1B8;1109 116A 11B7;C1B8;1109 116A 11B7; +C1B9;C1B9;1109 116A 11B8;C1B9;1109 116A 11B8; +C1BA;C1BA;1109 116A 11B9;C1BA;1109 116A 11B9; +C1BB;C1BB;1109 116A 11BA;C1BB;1109 116A 11BA; +C1BC;C1BC;1109 116A 11BB;C1BC;1109 116A 11BB; +C1BD;C1BD;1109 116A 11BC;C1BD;1109 116A 11BC; +C1BE;C1BE;1109 116A 11BD;C1BE;1109 116A 11BD; +C1BF;C1BF;1109 116A 11BE;C1BF;1109 116A 11BE; +C1C0;C1C0;1109 116A 11BF;C1C0;1109 116A 11BF; +C1C1;C1C1;1109 116A 11C0;C1C1;1109 116A 11C0; +C1C2;C1C2;1109 116A 11C1;C1C2;1109 116A 11C1; +C1C3;C1C3;1109 116A 11C2;C1C3;1109 116A 11C2; +C1C4;C1C4;1109 116B;C1C4;1109 116B; +C1C5;C1C5;1109 116B 11A8;C1C5;1109 116B 11A8; +C1C6;C1C6;1109 116B 11A9;C1C6;1109 116B 11A9; +C1C7;C1C7;1109 116B 11AA;C1C7;1109 116B 11AA; +C1C8;C1C8;1109 116B 11AB;C1C8;1109 116B 11AB; +C1C9;C1C9;1109 116B 11AC;C1C9;1109 116B 11AC; +C1CA;C1CA;1109 116B 11AD;C1CA;1109 116B 11AD; +C1CB;C1CB;1109 116B 11AE;C1CB;1109 116B 11AE; +C1CC;C1CC;1109 116B 11AF;C1CC;1109 116B 11AF; +C1CD;C1CD;1109 116B 11B0;C1CD;1109 116B 11B0; +C1CE;C1CE;1109 116B 11B1;C1CE;1109 116B 11B1; +C1CF;C1CF;1109 116B 11B2;C1CF;1109 116B 11B2; +C1D0;C1D0;1109 116B 11B3;C1D0;1109 116B 11B3; +C1D1;C1D1;1109 116B 11B4;C1D1;1109 116B 11B4; +C1D2;C1D2;1109 116B 11B5;C1D2;1109 116B 11B5; +C1D3;C1D3;1109 116B 11B6;C1D3;1109 116B 11B6; +C1D4;C1D4;1109 116B 11B7;C1D4;1109 116B 11B7; +C1D5;C1D5;1109 116B 11B8;C1D5;1109 116B 11B8; +C1D6;C1D6;1109 116B 11B9;C1D6;1109 116B 11B9; +C1D7;C1D7;1109 116B 11BA;C1D7;1109 116B 11BA; +C1D8;C1D8;1109 116B 11BB;C1D8;1109 116B 11BB; +C1D9;C1D9;1109 116B 11BC;C1D9;1109 116B 11BC; +C1DA;C1DA;1109 116B 11BD;C1DA;1109 116B 11BD; +C1DB;C1DB;1109 116B 11BE;C1DB;1109 116B 11BE; +C1DC;C1DC;1109 116B 11BF;C1DC;1109 116B 11BF; +C1DD;C1DD;1109 116B 11C0;C1DD;1109 116B 11C0; +C1DE;C1DE;1109 116B 11C1;C1DE;1109 116B 11C1; +C1DF;C1DF;1109 116B 11C2;C1DF;1109 116B 11C2; +C1E0;C1E0;1109 116C;C1E0;1109 116C; +C1E1;C1E1;1109 116C 11A8;C1E1;1109 116C 11A8; +C1E2;C1E2;1109 116C 11A9;C1E2;1109 116C 11A9; +C1E3;C1E3;1109 116C 11AA;C1E3;1109 116C 11AA; +C1E4;C1E4;1109 116C 11AB;C1E4;1109 116C 11AB; +C1E5;C1E5;1109 116C 11AC;C1E5;1109 116C 11AC; +C1E6;C1E6;1109 116C 11AD;C1E6;1109 116C 11AD; +C1E7;C1E7;1109 116C 11AE;C1E7;1109 116C 11AE; +C1E8;C1E8;1109 116C 11AF;C1E8;1109 116C 11AF; +C1E9;C1E9;1109 116C 11B0;C1E9;1109 116C 11B0; +C1EA;C1EA;1109 116C 11B1;C1EA;1109 116C 11B1; +C1EB;C1EB;1109 116C 11B2;C1EB;1109 116C 11B2; +C1EC;C1EC;1109 116C 11B3;C1EC;1109 116C 11B3; +C1ED;C1ED;1109 116C 11B4;C1ED;1109 116C 11B4; +C1EE;C1EE;1109 116C 11B5;C1EE;1109 116C 11B5; +C1EF;C1EF;1109 116C 11B6;C1EF;1109 116C 11B6; +C1F0;C1F0;1109 116C 11B7;C1F0;1109 116C 11B7; +C1F1;C1F1;1109 116C 11B8;C1F1;1109 116C 11B8; +C1F2;C1F2;1109 116C 11B9;C1F2;1109 116C 11B9; +C1F3;C1F3;1109 116C 11BA;C1F3;1109 116C 11BA; +C1F4;C1F4;1109 116C 11BB;C1F4;1109 116C 11BB; +C1F5;C1F5;1109 116C 11BC;C1F5;1109 116C 11BC; +C1F6;C1F6;1109 116C 11BD;C1F6;1109 116C 11BD; +C1F7;C1F7;1109 116C 11BE;C1F7;1109 116C 11BE; +C1F8;C1F8;1109 116C 11BF;C1F8;1109 116C 11BF; +C1F9;C1F9;1109 116C 11C0;C1F9;1109 116C 11C0; +C1FA;C1FA;1109 116C 11C1;C1FA;1109 116C 11C1; +C1FB;C1FB;1109 116C 11C2;C1FB;1109 116C 11C2; +C1FC;C1FC;1109 116D;C1FC;1109 116D; +C1FD;C1FD;1109 116D 11A8;C1FD;1109 116D 11A8; +C1FE;C1FE;1109 116D 11A9;C1FE;1109 116D 11A9; +C1FF;C1FF;1109 116D 11AA;C1FF;1109 116D 11AA; +C200;C200;1109 116D 11AB;C200;1109 116D 11AB; +C201;C201;1109 116D 11AC;C201;1109 116D 11AC; +C202;C202;1109 116D 11AD;C202;1109 116D 11AD; +C203;C203;1109 116D 11AE;C203;1109 116D 11AE; +C204;C204;1109 116D 11AF;C204;1109 116D 11AF; +C205;C205;1109 116D 11B0;C205;1109 116D 11B0; +C206;C206;1109 116D 11B1;C206;1109 116D 11B1; +C207;C207;1109 116D 11B2;C207;1109 116D 11B2; +C208;C208;1109 116D 11B3;C208;1109 116D 11B3; +C209;C209;1109 116D 11B4;C209;1109 116D 11B4; +C20A;C20A;1109 116D 11B5;C20A;1109 116D 11B5; +C20B;C20B;1109 116D 11B6;C20B;1109 116D 11B6; +C20C;C20C;1109 116D 11B7;C20C;1109 116D 11B7; +C20D;C20D;1109 116D 11B8;C20D;1109 116D 11B8; +C20E;C20E;1109 116D 11B9;C20E;1109 116D 11B9; +C20F;C20F;1109 116D 11BA;C20F;1109 116D 11BA; +C210;C210;1109 116D 11BB;C210;1109 116D 11BB; +C211;C211;1109 116D 11BC;C211;1109 116D 11BC; +C212;C212;1109 116D 11BD;C212;1109 116D 11BD; +C213;C213;1109 116D 11BE;C213;1109 116D 11BE; +C214;C214;1109 116D 11BF;C214;1109 116D 11BF; +C215;C215;1109 116D 11C0;C215;1109 116D 11C0; +C216;C216;1109 116D 11C1;C216;1109 116D 11C1; +C217;C217;1109 116D 11C2;C217;1109 116D 11C2; +C218;C218;1109 116E;C218;1109 116E; +C219;C219;1109 116E 11A8;C219;1109 116E 11A8; +C21A;C21A;1109 116E 11A9;C21A;1109 116E 11A9; +C21B;C21B;1109 116E 11AA;C21B;1109 116E 11AA; +C21C;C21C;1109 116E 11AB;C21C;1109 116E 11AB; +C21D;C21D;1109 116E 11AC;C21D;1109 116E 11AC; +C21E;C21E;1109 116E 11AD;C21E;1109 116E 11AD; +C21F;C21F;1109 116E 11AE;C21F;1109 116E 11AE; +C220;C220;1109 116E 11AF;C220;1109 116E 11AF; +C221;C221;1109 116E 11B0;C221;1109 116E 11B0; +C222;C222;1109 116E 11B1;C222;1109 116E 11B1; +C223;C223;1109 116E 11B2;C223;1109 116E 11B2; +C224;C224;1109 116E 11B3;C224;1109 116E 11B3; +C225;C225;1109 116E 11B4;C225;1109 116E 11B4; +C226;C226;1109 116E 11B5;C226;1109 116E 11B5; +C227;C227;1109 116E 11B6;C227;1109 116E 11B6; +C228;C228;1109 116E 11B7;C228;1109 116E 11B7; +C229;C229;1109 116E 11B8;C229;1109 116E 11B8; +C22A;C22A;1109 116E 11B9;C22A;1109 116E 11B9; +C22B;C22B;1109 116E 11BA;C22B;1109 116E 11BA; +C22C;C22C;1109 116E 11BB;C22C;1109 116E 11BB; +C22D;C22D;1109 116E 11BC;C22D;1109 116E 11BC; +C22E;C22E;1109 116E 11BD;C22E;1109 116E 11BD; +C22F;C22F;1109 116E 11BE;C22F;1109 116E 11BE; +C230;C230;1109 116E 11BF;C230;1109 116E 11BF; +C231;C231;1109 116E 11C0;C231;1109 116E 11C0; +C232;C232;1109 116E 11C1;C232;1109 116E 11C1; +C233;C233;1109 116E 11C2;C233;1109 116E 11C2; +C234;C234;1109 116F;C234;1109 116F; +C235;C235;1109 116F 11A8;C235;1109 116F 11A8; +C236;C236;1109 116F 11A9;C236;1109 116F 11A9; +C237;C237;1109 116F 11AA;C237;1109 116F 11AA; +C238;C238;1109 116F 11AB;C238;1109 116F 11AB; +C239;C239;1109 116F 11AC;C239;1109 116F 11AC; +C23A;C23A;1109 116F 11AD;C23A;1109 116F 11AD; +C23B;C23B;1109 116F 11AE;C23B;1109 116F 11AE; +C23C;C23C;1109 116F 11AF;C23C;1109 116F 11AF; +C23D;C23D;1109 116F 11B0;C23D;1109 116F 11B0; +C23E;C23E;1109 116F 11B1;C23E;1109 116F 11B1; +C23F;C23F;1109 116F 11B2;C23F;1109 116F 11B2; +C240;C240;1109 116F 11B3;C240;1109 116F 11B3; +C241;C241;1109 116F 11B4;C241;1109 116F 11B4; +C242;C242;1109 116F 11B5;C242;1109 116F 11B5; +C243;C243;1109 116F 11B6;C243;1109 116F 11B6; +C244;C244;1109 116F 11B7;C244;1109 116F 11B7; +C245;C245;1109 116F 11B8;C245;1109 116F 11B8; +C246;C246;1109 116F 11B9;C246;1109 116F 11B9; +C247;C247;1109 116F 11BA;C247;1109 116F 11BA; +C248;C248;1109 116F 11BB;C248;1109 116F 11BB; +C249;C249;1109 116F 11BC;C249;1109 116F 11BC; +C24A;C24A;1109 116F 11BD;C24A;1109 116F 11BD; +C24B;C24B;1109 116F 11BE;C24B;1109 116F 11BE; +C24C;C24C;1109 116F 11BF;C24C;1109 116F 11BF; +C24D;C24D;1109 116F 11C0;C24D;1109 116F 11C0; +C24E;C24E;1109 116F 11C1;C24E;1109 116F 11C1; +C24F;C24F;1109 116F 11C2;C24F;1109 116F 11C2; +C250;C250;1109 1170;C250;1109 1170; +C251;C251;1109 1170 11A8;C251;1109 1170 11A8; +C252;C252;1109 1170 11A9;C252;1109 1170 11A9; +C253;C253;1109 1170 11AA;C253;1109 1170 11AA; +C254;C254;1109 1170 11AB;C254;1109 1170 11AB; +C255;C255;1109 1170 11AC;C255;1109 1170 11AC; +C256;C256;1109 1170 11AD;C256;1109 1170 11AD; +C257;C257;1109 1170 11AE;C257;1109 1170 11AE; +C258;C258;1109 1170 11AF;C258;1109 1170 11AF; +C259;C259;1109 1170 11B0;C259;1109 1170 11B0; +C25A;C25A;1109 1170 11B1;C25A;1109 1170 11B1; +C25B;C25B;1109 1170 11B2;C25B;1109 1170 11B2; +C25C;C25C;1109 1170 11B3;C25C;1109 1170 11B3; +C25D;C25D;1109 1170 11B4;C25D;1109 1170 11B4; +C25E;C25E;1109 1170 11B5;C25E;1109 1170 11B5; +C25F;C25F;1109 1170 11B6;C25F;1109 1170 11B6; +C260;C260;1109 1170 11B7;C260;1109 1170 11B7; +C261;C261;1109 1170 11B8;C261;1109 1170 11B8; +C262;C262;1109 1170 11B9;C262;1109 1170 11B9; +C263;C263;1109 1170 11BA;C263;1109 1170 11BA; +C264;C264;1109 1170 11BB;C264;1109 1170 11BB; +C265;C265;1109 1170 11BC;C265;1109 1170 11BC; +C266;C266;1109 1170 11BD;C266;1109 1170 11BD; +C267;C267;1109 1170 11BE;C267;1109 1170 11BE; +C268;C268;1109 1170 11BF;C268;1109 1170 11BF; +C269;C269;1109 1170 11C0;C269;1109 1170 11C0; +C26A;C26A;1109 1170 11C1;C26A;1109 1170 11C1; +C26B;C26B;1109 1170 11C2;C26B;1109 1170 11C2; +C26C;C26C;1109 1171;C26C;1109 1171; +C26D;C26D;1109 1171 11A8;C26D;1109 1171 11A8; +C26E;C26E;1109 1171 11A9;C26E;1109 1171 11A9; +C26F;C26F;1109 1171 11AA;C26F;1109 1171 11AA; +C270;C270;1109 1171 11AB;C270;1109 1171 11AB; +C271;C271;1109 1171 11AC;C271;1109 1171 11AC; +C272;C272;1109 1171 11AD;C272;1109 1171 11AD; +C273;C273;1109 1171 11AE;C273;1109 1171 11AE; +C274;C274;1109 1171 11AF;C274;1109 1171 11AF; +C275;C275;1109 1171 11B0;C275;1109 1171 11B0; +C276;C276;1109 1171 11B1;C276;1109 1171 11B1; +C277;C277;1109 1171 11B2;C277;1109 1171 11B2; +C278;C278;1109 1171 11B3;C278;1109 1171 11B3; +C279;C279;1109 1171 11B4;C279;1109 1171 11B4; +C27A;C27A;1109 1171 11B5;C27A;1109 1171 11B5; +C27B;C27B;1109 1171 11B6;C27B;1109 1171 11B6; +C27C;C27C;1109 1171 11B7;C27C;1109 1171 11B7; +C27D;C27D;1109 1171 11B8;C27D;1109 1171 11B8; +C27E;C27E;1109 1171 11B9;C27E;1109 1171 11B9; +C27F;C27F;1109 1171 11BA;C27F;1109 1171 11BA; +C280;C280;1109 1171 11BB;C280;1109 1171 11BB; +C281;C281;1109 1171 11BC;C281;1109 1171 11BC; +C282;C282;1109 1171 11BD;C282;1109 1171 11BD; +C283;C283;1109 1171 11BE;C283;1109 1171 11BE; +C284;C284;1109 1171 11BF;C284;1109 1171 11BF; +C285;C285;1109 1171 11C0;C285;1109 1171 11C0; +C286;C286;1109 1171 11C1;C286;1109 1171 11C1; +C287;C287;1109 1171 11C2;C287;1109 1171 11C2; +C288;C288;1109 1172;C288;1109 1172; +C289;C289;1109 1172 11A8;C289;1109 1172 11A8; +C28A;C28A;1109 1172 11A9;C28A;1109 1172 11A9; +C28B;C28B;1109 1172 11AA;C28B;1109 1172 11AA; +C28C;C28C;1109 1172 11AB;C28C;1109 1172 11AB; +C28D;C28D;1109 1172 11AC;C28D;1109 1172 11AC; +C28E;C28E;1109 1172 11AD;C28E;1109 1172 11AD; +C28F;C28F;1109 1172 11AE;C28F;1109 1172 11AE; +C290;C290;1109 1172 11AF;C290;1109 1172 11AF; +C291;C291;1109 1172 11B0;C291;1109 1172 11B0; +C292;C292;1109 1172 11B1;C292;1109 1172 11B1; +C293;C293;1109 1172 11B2;C293;1109 1172 11B2; +C294;C294;1109 1172 11B3;C294;1109 1172 11B3; +C295;C295;1109 1172 11B4;C295;1109 1172 11B4; +C296;C296;1109 1172 11B5;C296;1109 1172 11B5; +C297;C297;1109 1172 11B6;C297;1109 1172 11B6; +C298;C298;1109 1172 11B7;C298;1109 1172 11B7; +C299;C299;1109 1172 11B8;C299;1109 1172 11B8; +C29A;C29A;1109 1172 11B9;C29A;1109 1172 11B9; +C29B;C29B;1109 1172 11BA;C29B;1109 1172 11BA; +C29C;C29C;1109 1172 11BB;C29C;1109 1172 11BB; +C29D;C29D;1109 1172 11BC;C29D;1109 1172 11BC; +C29E;C29E;1109 1172 11BD;C29E;1109 1172 11BD; +C29F;C29F;1109 1172 11BE;C29F;1109 1172 11BE; +C2A0;C2A0;1109 1172 11BF;C2A0;1109 1172 11BF; +C2A1;C2A1;1109 1172 11C0;C2A1;1109 1172 11C0; +C2A2;C2A2;1109 1172 11C1;C2A2;1109 1172 11C1; +C2A3;C2A3;1109 1172 11C2;C2A3;1109 1172 11C2; +C2A4;C2A4;1109 1173;C2A4;1109 1173; +C2A5;C2A5;1109 1173 11A8;C2A5;1109 1173 11A8; +C2A6;C2A6;1109 1173 11A9;C2A6;1109 1173 11A9; +C2A7;C2A7;1109 1173 11AA;C2A7;1109 1173 11AA; +C2A8;C2A8;1109 1173 11AB;C2A8;1109 1173 11AB; +C2A9;C2A9;1109 1173 11AC;C2A9;1109 1173 11AC; +C2AA;C2AA;1109 1173 11AD;C2AA;1109 1173 11AD; +C2AB;C2AB;1109 1173 11AE;C2AB;1109 1173 11AE; +C2AC;C2AC;1109 1173 11AF;C2AC;1109 1173 11AF; +C2AD;C2AD;1109 1173 11B0;C2AD;1109 1173 11B0; +C2AE;C2AE;1109 1173 11B1;C2AE;1109 1173 11B1; +C2AF;C2AF;1109 1173 11B2;C2AF;1109 1173 11B2; +C2B0;C2B0;1109 1173 11B3;C2B0;1109 1173 11B3; +C2B1;C2B1;1109 1173 11B4;C2B1;1109 1173 11B4; +C2B2;C2B2;1109 1173 11B5;C2B2;1109 1173 11B5; +C2B3;C2B3;1109 1173 11B6;C2B3;1109 1173 11B6; +C2B4;C2B4;1109 1173 11B7;C2B4;1109 1173 11B7; +C2B5;C2B5;1109 1173 11B8;C2B5;1109 1173 11B8; +C2B6;C2B6;1109 1173 11B9;C2B6;1109 1173 11B9; +C2B7;C2B7;1109 1173 11BA;C2B7;1109 1173 11BA; +C2B8;C2B8;1109 1173 11BB;C2B8;1109 1173 11BB; +C2B9;C2B9;1109 1173 11BC;C2B9;1109 1173 11BC; +C2BA;C2BA;1109 1173 11BD;C2BA;1109 1173 11BD; +C2BB;C2BB;1109 1173 11BE;C2BB;1109 1173 11BE; +C2BC;C2BC;1109 1173 11BF;C2BC;1109 1173 11BF; +C2BD;C2BD;1109 1173 11C0;C2BD;1109 1173 11C0; +C2BE;C2BE;1109 1173 11C1;C2BE;1109 1173 11C1; +C2BF;C2BF;1109 1173 11C2;C2BF;1109 1173 11C2; +C2C0;C2C0;1109 1174;C2C0;1109 1174; +C2C1;C2C1;1109 1174 11A8;C2C1;1109 1174 11A8; +C2C2;C2C2;1109 1174 11A9;C2C2;1109 1174 11A9; +C2C3;C2C3;1109 1174 11AA;C2C3;1109 1174 11AA; +C2C4;C2C4;1109 1174 11AB;C2C4;1109 1174 11AB; +C2C5;C2C5;1109 1174 11AC;C2C5;1109 1174 11AC; +C2C6;C2C6;1109 1174 11AD;C2C6;1109 1174 11AD; +C2C7;C2C7;1109 1174 11AE;C2C7;1109 1174 11AE; +C2C8;C2C8;1109 1174 11AF;C2C8;1109 1174 11AF; +C2C9;C2C9;1109 1174 11B0;C2C9;1109 1174 11B0; +C2CA;C2CA;1109 1174 11B1;C2CA;1109 1174 11B1; +C2CB;C2CB;1109 1174 11B2;C2CB;1109 1174 11B2; +C2CC;C2CC;1109 1174 11B3;C2CC;1109 1174 11B3; +C2CD;C2CD;1109 1174 11B4;C2CD;1109 1174 11B4; +C2CE;C2CE;1109 1174 11B5;C2CE;1109 1174 11B5; +C2CF;C2CF;1109 1174 11B6;C2CF;1109 1174 11B6; +C2D0;C2D0;1109 1174 11B7;C2D0;1109 1174 11B7; +C2D1;C2D1;1109 1174 11B8;C2D1;1109 1174 11B8; +C2D2;C2D2;1109 1174 11B9;C2D2;1109 1174 11B9; +C2D3;C2D3;1109 1174 11BA;C2D3;1109 1174 11BA; +C2D4;C2D4;1109 1174 11BB;C2D4;1109 1174 11BB; +C2D5;C2D5;1109 1174 11BC;C2D5;1109 1174 11BC; +C2D6;C2D6;1109 1174 11BD;C2D6;1109 1174 11BD; +C2D7;C2D7;1109 1174 11BE;C2D7;1109 1174 11BE; +C2D8;C2D8;1109 1174 11BF;C2D8;1109 1174 11BF; +C2D9;C2D9;1109 1174 11C0;C2D9;1109 1174 11C0; +C2DA;C2DA;1109 1174 11C1;C2DA;1109 1174 11C1; +C2DB;C2DB;1109 1174 11C2;C2DB;1109 1174 11C2; +C2DC;C2DC;1109 1175;C2DC;1109 1175; +C2DD;C2DD;1109 1175 11A8;C2DD;1109 1175 11A8; +C2DE;C2DE;1109 1175 11A9;C2DE;1109 1175 11A9; +C2DF;C2DF;1109 1175 11AA;C2DF;1109 1175 11AA; +C2E0;C2E0;1109 1175 11AB;C2E0;1109 1175 11AB; +C2E1;C2E1;1109 1175 11AC;C2E1;1109 1175 11AC; +C2E2;C2E2;1109 1175 11AD;C2E2;1109 1175 11AD; +C2E3;C2E3;1109 1175 11AE;C2E3;1109 1175 11AE; +C2E4;C2E4;1109 1175 11AF;C2E4;1109 1175 11AF; +C2E5;C2E5;1109 1175 11B0;C2E5;1109 1175 11B0; +C2E6;C2E6;1109 1175 11B1;C2E6;1109 1175 11B1; +C2E7;C2E7;1109 1175 11B2;C2E7;1109 1175 11B2; +C2E8;C2E8;1109 1175 11B3;C2E8;1109 1175 11B3; +C2E9;C2E9;1109 1175 11B4;C2E9;1109 1175 11B4; +C2EA;C2EA;1109 1175 11B5;C2EA;1109 1175 11B5; +C2EB;C2EB;1109 1175 11B6;C2EB;1109 1175 11B6; +C2EC;C2EC;1109 1175 11B7;C2EC;1109 1175 11B7; +C2ED;C2ED;1109 1175 11B8;C2ED;1109 1175 11B8; +C2EE;C2EE;1109 1175 11B9;C2EE;1109 1175 11B9; +C2EF;C2EF;1109 1175 11BA;C2EF;1109 1175 11BA; +C2F0;C2F0;1109 1175 11BB;C2F0;1109 1175 11BB; +C2F1;C2F1;1109 1175 11BC;C2F1;1109 1175 11BC; +C2F2;C2F2;1109 1175 11BD;C2F2;1109 1175 11BD; +C2F3;C2F3;1109 1175 11BE;C2F3;1109 1175 11BE; +C2F4;C2F4;1109 1175 11BF;C2F4;1109 1175 11BF; +C2F5;C2F5;1109 1175 11C0;C2F5;1109 1175 11C0; +C2F6;C2F6;1109 1175 11C1;C2F6;1109 1175 11C1; +C2F7;C2F7;1109 1175 11C2;C2F7;1109 1175 11C2; +C2F8;C2F8;110A 1161;C2F8;110A 1161; +C2F9;C2F9;110A 1161 11A8;C2F9;110A 1161 11A8; +C2FA;C2FA;110A 1161 11A9;C2FA;110A 1161 11A9; +C2FB;C2FB;110A 1161 11AA;C2FB;110A 1161 11AA; +C2FC;C2FC;110A 1161 11AB;C2FC;110A 1161 11AB; +C2FD;C2FD;110A 1161 11AC;C2FD;110A 1161 11AC; +C2FE;C2FE;110A 1161 11AD;C2FE;110A 1161 11AD; +C2FF;C2FF;110A 1161 11AE;C2FF;110A 1161 11AE; +C300;C300;110A 1161 11AF;C300;110A 1161 11AF; +C301;C301;110A 1161 11B0;C301;110A 1161 11B0; +C302;C302;110A 1161 11B1;C302;110A 1161 11B1; +C303;C303;110A 1161 11B2;C303;110A 1161 11B2; +C304;C304;110A 1161 11B3;C304;110A 1161 11B3; +C305;C305;110A 1161 11B4;C305;110A 1161 11B4; +C306;C306;110A 1161 11B5;C306;110A 1161 11B5; +C307;C307;110A 1161 11B6;C307;110A 1161 11B6; +C308;C308;110A 1161 11B7;C308;110A 1161 11B7; +C309;C309;110A 1161 11B8;C309;110A 1161 11B8; +C30A;C30A;110A 1161 11B9;C30A;110A 1161 11B9; +C30B;C30B;110A 1161 11BA;C30B;110A 1161 11BA; +C30C;C30C;110A 1161 11BB;C30C;110A 1161 11BB; +C30D;C30D;110A 1161 11BC;C30D;110A 1161 11BC; +C30E;C30E;110A 1161 11BD;C30E;110A 1161 11BD; +C30F;C30F;110A 1161 11BE;C30F;110A 1161 11BE; +C310;C310;110A 1161 11BF;C310;110A 1161 11BF; +C311;C311;110A 1161 11C0;C311;110A 1161 11C0; +C312;C312;110A 1161 11C1;C312;110A 1161 11C1; +C313;C313;110A 1161 11C2;C313;110A 1161 11C2; +C314;C314;110A 1162;C314;110A 1162; +C315;C315;110A 1162 11A8;C315;110A 1162 11A8; +C316;C316;110A 1162 11A9;C316;110A 1162 11A9; +C317;C317;110A 1162 11AA;C317;110A 1162 11AA; +C318;C318;110A 1162 11AB;C318;110A 1162 11AB; +C319;C319;110A 1162 11AC;C319;110A 1162 11AC; +C31A;C31A;110A 1162 11AD;C31A;110A 1162 11AD; +C31B;C31B;110A 1162 11AE;C31B;110A 1162 11AE; +C31C;C31C;110A 1162 11AF;C31C;110A 1162 11AF; +C31D;C31D;110A 1162 11B0;C31D;110A 1162 11B0; +C31E;C31E;110A 1162 11B1;C31E;110A 1162 11B1; +C31F;C31F;110A 1162 11B2;C31F;110A 1162 11B2; +C320;C320;110A 1162 11B3;C320;110A 1162 11B3; +C321;C321;110A 1162 11B4;C321;110A 1162 11B4; +C322;C322;110A 1162 11B5;C322;110A 1162 11B5; +C323;C323;110A 1162 11B6;C323;110A 1162 11B6; +C324;C324;110A 1162 11B7;C324;110A 1162 11B7; +C325;C325;110A 1162 11B8;C325;110A 1162 11B8; +C326;C326;110A 1162 11B9;C326;110A 1162 11B9; +C327;C327;110A 1162 11BA;C327;110A 1162 11BA; +C328;C328;110A 1162 11BB;C328;110A 1162 11BB; +C329;C329;110A 1162 11BC;C329;110A 1162 11BC; +C32A;C32A;110A 1162 11BD;C32A;110A 1162 11BD; +C32B;C32B;110A 1162 11BE;C32B;110A 1162 11BE; +C32C;C32C;110A 1162 11BF;C32C;110A 1162 11BF; +C32D;C32D;110A 1162 11C0;C32D;110A 1162 11C0; +C32E;C32E;110A 1162 11C1;C32E;110A 1162 11C1; +C32F;C32F;110A 1162 11C2;C32F;110A 1162 11C2; +C330;C330;110A 1163;C330;110A 1163; +C331;C331;110A 1163 11A8;C331;110A 1163 11A8; +C332;C332;110A 1163 11A9;C332;110A 1163 11A9; +C333;C333;110A 1163 11AA;C333;110A 1163 11AA; +C334;C334;110A 1163 11AB;C334;110A 1163 11AB; +C335;C335;110A 1163 11AC;C335;110A 1163 11AC; +C336;C336;110A 1163 11AD;C336;110A 1163 11AD; +C337;C337;110A 1163 11AE;C337;110A 1163 11AE; +C338;C338;110A 1163 11AF;C338;110A 1163 11AF; +C339;C339;110A 1163 11B0;C339;110A 1163 11B0; +C33A;C33A;110A 1163 11B1;C33A;110A 1163 11B1; +C33B;C33B;110A 1163 11B2;C33B;110A 1163 11B2; +C33C;C33C;110A 1163 11B3;C33C;110A 1163 11B3; +C33D;C33D;110A 1163 11B4;C33D;110A 1163 11B4; +C33E;C33E;110A 1163 11B5;C33E;110A 1163 11B5; +C33F;C33F;110A 1163 11B6;C33F;110A 1163 11B6; +C340;C340;110A 1163 11B7;C340;110A 1163 11B7; +C341;C341;110A 1163 11B8;C341;110A 1163 11B8; +C342;C342;110A 1163 11B9;C342;110A 1163 11B9; +C343;C343;110A 1163 11BA;C343;110A 1163 11BA; +C344;C344;110A 1163 11BB;C344;110A 1163 11BB; +C345;C345;110A 1163 11BC;C345;110A 1163 11BC; +C346;C346;110A 1163 11BD;C346;110A 1163 11BD; +C347;C347;110A 1163 11BE;C347;110A 1163 11BE; +C348;C348;110A 1163 11BF;C348;110A 1163 11BF; +C349;C349;110A 1163 11C0;C349;110A 1163 11C0; +C34A;C34A;110A 1163 11C1;C34A;110A 1163 11C1; +C34B;C34B;110A 1163 11C2;C34B;110A 1163 11C2; +C34C;C34C;110A 1164;C34C;110A 1164; +C34D;C34D;110A 1164 11A8;C34D;110A 1164 11A8; +C34E;C34E;110A 1164 11A9;C34E;110A 1164 11A9; +C34F;C34F;110A 1164 11AA;C34F;110A 1164 11AA; +C350;C350;110A 1164 11AB;C350;110A 1164 11AB; +C351;C351;110A 1164 11AC;C351;110A 1164 11AC; +C352;C352;110A 1164 11AD;C352;110A 1164 11AD; +C353;C353;110A 1164 11AE;C353;110A 1164 11AE; +C354;C354;110A 1164 11AF;C354;110A 1164 11AF; +C355;C355;110A 1164 11B0;C355;110A 1164 11B0; +C356;C356;110A 1164 11B1;C356;110A 1164 11B1; +C357;C357;110A 1164 11B2;C357;110A 1164 11B2; +C358;C358;110A 1164 11B3;C358;110A 1164 11B3; +C359;C359;110A 1164 11B4;C359;110A 1164 11B4; +C35A;C35A;110A 1164 11B5;C35A;110A 1164 11B5; +C35B;C35B;110A 1164 11B6;C35B;110A 1164 11B6; +C35C;C35C;110A 1164 11B7;C35C;110A 1164 11B7; +C35D;C35D;110A 1164 11B8;C35D;110A 1164 11B8; +C35E;C35E;110A 1164 11B9;C35E;110A 1164 11B9; +C35F;C35F;110A 1164 11BA;C35F;110A 1164 11BA; +C360;C360;110A 1164 11BB;C360;110A 1164 11BB; +C361;C361;110A 1164 11BC;C361;110A 1164 11BC; +C362;C362;110A 1164 11BD;C362;110A 1164 11BD; +C363;C363;110A 1164 11BE;C363;110A 1164 11BE; +C364;C364;110A 1164 11BF;C364;110A 1164 11BF; +C365;C365;110A 1164 11C0;C365;110A 1164 11C0; +C366;C366;110A 1164 11C1;C366;110A 1164 11C1; +C367;C367;110A 1164 11C2;C367;110A 1164 11C2; +C368;C368;110A 1165;C368;110A 1165; +C369;C369;110A 1165 11A8;C369;110A 1165 11A8; +C36A;C36A;110A 1165 11A9;C36A;110A 1165 11A9; +C36B;C36B;110A 1165 11AA;C36B;110A 1165 11AA; +C36C;C36C;110A 1165 11AB;C36C;110A 1165 11AB; +C36D;C36D;110A 1165 11AC;C36D;110A 1165 11AC; +C36E;C36E;110A 1165 11AD;C36E;110A 1165 11AD; +C36F;C36F;110A 1165 11AE;C36F;110A 1165 11AE; +C370;C370;110A 1165 11AF;C370;110A 1165 11AF; +C371;C371;110A 1165 11B0;C371;110A 1165 11B0; +C372;C372;110A 1165 11B1;C372;110A 1165 11B1; +C373;C373;110A 1165 11B2;C373;110A 1165 11B2; +C374;C374;110A 1165 11B3;C374;110A 1165 11B3; +C375;C375;110A 1165 11B4;C375;110A 1165 11B4; +C376;C376;110A 1165 11B5;C376;110A 1165 11B5; +C377;C377;110A 1165 11B6;C377;110A 1165 11B6; +C378;C378;110A 1165 11B7;C378;110A 1165 11B7; +C379;C379;110A 1165 11B8;C379;110A 1165 11B8; +C37A;C37A;110A 1165 11B9;C37A;110A 1165 11B9; +C37B;C37B;110A 1165 11BA;C37B;110A 1165 11BA; +C37C;C37C;110A 1165 11BB;C37C;110A 1165 11BB; +C37D;C37D;110A 1165 11BC;C37D;110A 1165 11BC; +C37E;C37E;110A 1165 11BD;C37E;110A 1165 11BD; +C37F;C37F;110A 1165 11BE;C37F;110A 1165 11BE; +C380;C380;110A 1165 11BF;C380;110A 1165 11BF; +C381;C381;110A 1165 11C0;C381;110A 1165 11C0; +C382;C382;110A 1165 11C1;C382;110A 1165 11C1; +C383;C383;110A 1165 11C2;C383;110A 1165 11C2; +C384;C384;110A 1166;C384;110A 1166; +C385;C385;110A 1166 11A8;C385;110A 1166 11A8; +C386;C386;110A 1166 11A9;C386;110A 1166 11A9; +C387;C387;110A 1166 11AA;C387;110A 1166 11AA; +C388;C388;110A 1166 11AB;C388;110A 1166 11AB; +C389;C389;110A 1166 11AC;C389;110A 1166 11AC; +C38A;C38A;110A 1166 11AD;C38A;110A 1166 11AD; +C38B;C38B;110A 1166 11AE;C38B;110A 1166 11AE; +C38C;C38C;110A 1166 11AF;C38C;110A 1166 11AF; +C38D;C38D;110A 1166 11B0;C38D;110A 1166 11B0; +C38E;C38E;110A 1166 11B1;C38E;110A 1166 11B1; +C38F;C38F;110A 1166 11B2;C38F;110A 1166 11B2; +C390;C390;110A 1166 11B3;C390;110A 1166 11B3; +C391;C391;110A 1166 11B4;C391;110A 1166 11B4; +C392;C392;110A 1166 11B5;C392;110A 1166 11B5; +C393;C393;110A 1166 11B6;C393;110A 1166 11B6; +C394;C394;110A 1166 11B7;C394;110A 1166 11B7; +C395;C395;110A 1166 11B8;C395;110A 1166 11B8; +C396;C396;110A 1166 11B9;C396;110A 1166 11B9; +C397;C397;110A 1166 11BA;C397;110A 1166 11BA; +C398;C398;110A 1166 11BB;C398;110A 1166 11BB; +C399;C399;110A 1166 11BC;C399;110A 1166 11BC; +C39A;C39A;110A 1166 11BD;C39A;110A 1166 11BD; +C39B;C39B;110A 1166 11BE;C39B;110A 1166 11BE; +C39C;C39C;110A 1166 11BF;C39C;110A 1166 11BF; +C39D;C39D;110A 1166 11C0;C39D;110A 1166 11C0; +C39E;C39E;110A 1166 11C1;C39E;110A 1166 11C1; +C39F;C39F;110A 1166 11C2;C39F;110A 1166 11C2; +C3A0;C3A0;110A 1167;C3A0;110A 1167; +C3A1;C3A1;110A 1167 11A8;C3A1;110A 1167 11A8; +C3A2;C3A2;110A 1167 11A9;C3A2;110A 1167 11A9; +C3A3;C3A3;110A 1167 11AA;C3A3;110A 1167 11AA; +C3A4;C3A4;110A 1167 11AB;C3A4;110A 1167 11AB; +C3A5;C3A5;110A 1167 11AC;C3A5;110A 1167 11AC; +C3A6;C3A6;110A 1167 11AD;C3A6;110A 1167 11AD; +C3A7;C3A7;110A 1167 11AE;C3A7;110A 1167 11AE; +C3A8;C3A8;110A 1167 11AF;C3A8;110A 1167 11AF; +C3A9;C3A9;110A 1167 11B0;C3A9;110A 1167 11B0; +C3AA;C3AA;110A 1167 11B1;C3AA;110A 1167 11B1; +C3AB;C3AB;110A 1167 11B2;C3AB;110A 1167 11B2; +C3AC;C3AC;110A 1167 11B3;C3AC;110A 1167 11B3; +C3AD;C3AD;110A 1167 11B4;C3AD;110A 1167 11B4; +C3AE;C3AE;110A 1167 11B5;C3AE;110A 1167 11B5; +C3AF;C3AF;110A 1167 11B6;C3AF;110A 1167 11B6; +C3B0;C3B0;110A 1167 11B7;C3B0;110A 1167 11B7; +C3B1;C3B1;110A 1167 11B8;C3B1;110A 1167 11B8; +C3B2;C3B2;110A 1167 11B9;C3B2;110A 1167 11B9; +C3B3;C3B3;110A 1167 11BA;C3B3;110A 1167 11BA; +C3B4;C3B4;110A 1167 11BB;C3B4;110A 1167 11BB; +C3B5;C3B5;110A 1167 11BC;C3B5;110A 1167 11BC; +C3B6;C3B6;110A 1167 11BD;C3B6;110A 1167 11BD; +C3B7;C3B7;110A 1167 11BE;C3B7;110A 1167 11BE; +C3B8;C3B8;110A 1167 11BF;C3B8;110A 1167 11BF; +C3B9;C3B9;110A 1167 11C0;C3B9;110A 1167 11C0; +C3BA;C3BA;110A 1167 11C1;C3BA;110A 1167 11C1; +C3BB;C3BB;110A 1167 11C2;C3BB;110A 1167 11C2; +C3BC;C3BC;110A 1168;C3BC;110A 1168; +C3BD;C3BD;110A 1168 11A8;C3BD;110A 1168 11A8; +C3BE;C3BE;110A 1168 11A9;C3BE;110A 1168 11A9; +C3BF;C3BF;110A 1168 11AA;C3BF;110A 1168 11AA; +C3C0;C3C0;110A 1168 11AB;C3C0;110A 1168 11AB; +C3C1;C3C1;110A 1168 11AC;C3C1;110A 1168 11AC; +C3C2;C3C2;110A 1168 11AD;C3C2;110A 1168 11AD; +C3C3;C3C3;110A 1168 11AE;C3C3;110A 1168 11AE; +C3C4;C3C4;110A 1168 11AF;C3C4;110A 1168 11AF; +C3C5;C3C5;110A 1168 11B0;C3C5;110A 1168 11B0; +C3C6;C3C6;110A 1168 11B1;C3C6;110A 1168 11B1; +C3C7;C3C7;110A 1168 11B2;C3C7;110A 1168 11B2; +C3C8;C3C8;110A 1168 11B3;C3C8;110A 1168 11B3; +C3C9;C3C9;110A 1168 11B4;C3C9;110A 1168 11B4; +C3CA;C3CA;110A 1168 11B5;C3CA;110A 1168 11B5; +C3CB;C3CB;110A 1168 11B6;C3CB;110A 1168 11B6; +C3CC;C3CC;110A 1168 11B7;C3CC;110A 1168 11B7; +C3CD;C3CD;110A 1168 11B8;C3CD;110A 1168 11B8; +C3CE;C3CE;110A 1168 11B9;C3CE;110A 1168 11B9; +C3CF;C3CF;110A 1168 11BA;C3CF;110A 1168 11BA; +C3D0;C3D0;110A 1168 11BB;C3D0;110A 1168 11BB; +C3D1;C3D1;110A 1168 11BC;C3D1;110A 1168 11BC; +C3D2;C3D2;110A 1168 11BD;C3D2;110A 1168 11BD; +C3D3;C3D3;110A 1168 11BE;C3D3;110A 1168 11BE; +C3D4;C3D4;110A 1168 11BF;C3D4;110A 1168 11BF; +C3D5;C3D5;110A 1168 11C0;C3D5;110A 1168 11C0; +C3D6;C3D6;110A 1168 11C1;C3D6;110A 1168 11C1; +C3D7;C3D7;110A 1168 11C2;C3D7;110A 1168 11C2; +C3D8;C3D8;110A 1169;C3D8;110A 1169; +C3D9;C3D9;110A 1169 11A8;C3D9;110A 1169 11A8; +C3DA;C3DA;110A 1169 11A9;C3DA;110A 1169 11A9; +C3DB;C3DB;110A 1169 11AA;C3DB;110A 1169 11AA; +C3DC;C3DC;110A 1169 11AB;C3DC;110A 1169 11AB; +C3DD;C3DD;110A 1169 11AC;C3DD;110A 1169 11AC; +C3DE;C3DE;110A 1169 11AD;C3DE;110A 1169 11AD; +C3DF;C3DF;110A 1169 11AE;C3DF;110A 1169 11AE; +C3E0;C3E0;110A 1169 11AF;C3E0;110A 1169 11AF; +C3E1;C3E1;110A 1169 11B0;C3E1;110A 1169 11B0; +C3E2;C3E2;110A 1169 11B1;C3E2;110A 1169 11B1; +C3E3;C3E3;110A 1169 11B2;C3E3;110A 1169 11B2; +C3E4;C3E4;110A 1169 11B3;C3E4;110A 1169 11B3; +C3E5;C3E5;110A 1169 11B4;C3E5;110A 1169 11B4; +C3E6;C3E6;110A 1169 11B5;C3E6;110A 1169 11B5; +C3E7;C3E7;110A 1169 11B6;C3E7;110A 1169 11B6; +C3E8;C3E8;110A 1169 11B7;C3E8;110A 1169 11B7; +C3E9;C3E9;110A 1169 11B8;C3E9;110A 1169 11B8; +C3EA;C3EA;110A 1169 11B9;C3EA;110A 1169 11B9; +C3EB;C3EB;110A 1169 11BA;C3EB;110A 1169 11BA; +C3EC;C3EC;110A 1169 11BB;C3EC;110A 1169 11BB; +C3ED;C3ED;110A 1169 11BC;C3ED;110A 1169 11BC; +C3EE;C3EE;110A 1169 11BD;C3EE;110A 1169 11BD; +C3EF;C3EF;110A 1169 11BE;C3EF;110A 1169 11BE; +C3F0;C3F0;110A 1169 11BF;C3F0;110A 1169 11BF; +C3F1;C3F1;110A 1169 11C0;C3F1;110A 1169 11C0; +C3F2;C3F2;110A 1169 11C1;C3F2;110A 1169 11C1; +C3F3;C3F3;110A 1169 11C2;C3F3;110A 1169 11C2; +C3F4;C3F4;110A 116A;C3F4;110A 116A; +C3F5;C3F5;110A 116A 11A8;C3F5;110A 116A 11A8; +C3F6;C3F6;110A 116A 11A9;C3F6;110A 116A 11A9; +C3F7;C3F7;110A 116A 11AA;C3F7;110A 116A 11AA; +C3F8;C3F8;110A 116A 11AB;C3F8;110A 116A 11AB; +C3F9;C3F9;110A 116A 11AC;C3F9;110A 116A 11AC; +C3FA;C3FA;110A 116A 11AD;C3FA;110A 116A 11AD; +C3FB;C3FB;110A 116A 11AE;C3FB;110A 116A 11AE; +C3FC;C3FC;110A 116A 11AF;C3FC;110A 116A 11AF; +C3FD;C3FD;110A 116A 11B0;C3FD;110A 116A 11B0; +C3FE;C3FE;110A 116A 11B1;C3FE;110A 116A 11B1; +C3FF;C3FF;110A 116A 11B2;C3FF;110A 116A 11B2; +C400;C400;110A 116A 11B3;C400;110A 116A 11B3; +C401;C401;110A 116A 11B4;C401;110A 116A 11B4; +C402;C402;110A 116A 11B5;C402;110A 116A 11B5; +C403;C403;110A 116A 11B6;C403;110A 116A 11B6; +C404;C404;110A 116A 11B7;C404;110A 116A 11B7; +C405;C405;110A 116A 11B8;C405;110A 116A 11B8; +C406;C406;110A 116A 11B9;C406;110A 116A 11B9; +C407;C407;110A 116A 11BA;C407;110A 116A 11BA; +C408;C408;110A 116A 11BB;C408;110A 116A 11BB; +C409;C409;110A 116A 11BC;C409;110A 116A 11BC; +C40A;C40A;110A 116A 11BD;C40A;110A 116A 11BD; +C40B;C40B;110A 116A 11BE;C40B;110A 116A 11BE; +C40C;C40C;110A 116A 11BF;C40C;110A 116A 11BF; +C40D;C40D;110A 116A 11C0;C40D;110A 116A 11C0; +C40E;C40E;110A 116A 11C1;C40E;110A 116A 11C1; +C40F;C40F;110A 116A 11C2;C40F;110A 116A 11C2; +C410;C410;110A 116B;C410;110A 116B; +C411;C411;110A 116B 11A8;C411;110A 116B 11A8; +C412;C412;110A 116B 11A9;C412;110A 116B 11A9; +C413;C413;110A 116B 11AA;C413;110A 116B 11AA; +C414;C414;110A 116B 11AB;C414;110A 116B 11AB; +C415;C415;110A 116B 11AC;C415;110A 116B 11AC; +C416;C416;110A 116B 11AD;C416;110A 116B 11AD; +C417;C417;110A 116B 11AE;C417;110A 116B 11AE; +C418;C418;110A 116B 11AF;C418;110A 116B 11AF; +C419;C419;110A 116B 11B0;C419;110A 116B 11B0; +C41A;C41A;110A 116B 11B1;C41A;110A 116B 11B1; +C41B;C41B;110A 116B 11B2;C41B;110A 116B 11B2; +C41C;C41C;110A 116B 11B3;C41C;110A 116B 11B3; +C41D;C41D;110A 116B 11B4;C41D;110A 116B 11B4; +C41E;C41E;110A 116B 11B5;C41E;110A 116B 11B5; +C41F;C41F;110A 116B 11B6;C41F;110A 116B 11B6; +C420;C420;110A 116B 11B7;C420;110A 116B 11B7; +C421;C421;110A 116B 11B8;C421;110A 116B 11B8; +C422;C422;110A 116B 11B9;C422;110A 116B 11B9; +C423;C423;110A 116B 11BA;C423;110A 116B 11BA; +C424;C424;110A 116B 11BB;C424;110A 116B 11BB; +C425;C425;110A 116B 11BC;C425;110A 116B 11BC; +C426;C426;110A 116B 11BD;C426;110A 116B 11BD; +C427;C427;110A 116B 11BE;C427;110A 116B 11BE; +C428;C428;110A 116B 11BF;C428;110A 116B 11BF; +C429;C429;110A 116B 11C0;C429;110A 116B 11C0; +C42A;C42A;110A 116B 11C1;C42A;110A 116B 11C1; +C42B;C42B;110A 116B 11C2;C42B;110A 116B 11C2; +C42C;C42C;110A 116C;C42C;110A 116C; +C42D;C42D;110A 116C 11A8;C42D;110A 116C 11A8; +C42E;C42E;110A 116C 11A9;C42E;110A 116C 11A9; +C42F;C42F;110A 116C 11AA;C42F;110A 116C 11AA; +C430;C430;110A 116C 11AB;C430;110A 116C 11AB; +C431;C431;110A 116C 11AC;C431;110A 116C 11AC; +C432;C432;110A 116C 11AD;C432;110A 116C 11AD; +C433;C433;110A 116C 11AE;C433;110A 116C 11AE; +C434;C434;110A 116C 11AF;C434;110A 116C 11AF; +C435;C435;110A 116C 11B0;C435;110A 116C 11B0; +C436;C436;110A 116C 11B1;C436;110A 116C 11B1; +C437;C437;110A 116C 11B2;C437;110A 116C 11B2; +C438;C438;110A 116C 11B3;C438;110A 116C 11B3; +C439;C439;110A 116C 11B4;C439;110A 116C 11B4; +C43A;C43A;110A 116C 11B5;C43A;110A 116C 11B5; +C43B;C43B;110A 116C 11B6;C43B;110A 116C 11B6; +C43C;C43C;110A 116C 11B7;C43C;110A 116C 11B7; +C43D;C43D;110A 116C 11B8;C43D;110A 116C 11B8; +C43E;C43E;110A 116C 11B9;C43E;110A 116C 11B9; +C43F;C43F;110A 116C 11BA;C43F;110A 116C 11BA; +C440;C440;110A 116C 11BB;C440;110A 116C 11BB; +C441;C441;110A 116C 11BC;C441;110A 116C 11BC; +C442;C442;110A 116C 11BD;C442;110A 116C 11BD; +C443;C443;110A 116C 11BE;C443;110A 116C 11BE; +C444;C444;110A 116C 11BF;C444;110A 116C 11BF; +C445;C445;110A 116C 11C0;C445;110A 116C 11C0; +C446;C446;110A 116C 11C1;C446;110A 116C 11C1; +C447;C447;110A 116C 11C2;C447;110A 116C 11C2; +C448;C448;110A 116D;C448;110A 116D; +C449;C449;110A 116D 11A8;C449;110A 116D 11A8; +C44A;C44A;110A 116D 11A9;C44A;110A 116D 11A9; +C44B;C44B;110A 116D 11AA;C44B;110A 116D 11AA; +C44C;C44C;110A 116D 11AB;C44C;110A 116D 11AB; +C44D;C44D;110A 116D 11AC;C44D;110A 116D 11AC; +C44E;C44E;110A 116D 11AD;C44E;110A 116D 11AD; +C44F;C44F;110A 116D 11AE;C44F;110A 116D 11AE; +C450;C450;110A 116D 11AF;C450;110A 116D 11AF; +C451;C451;110A 116D 11B0;C451;110A 116D 11B0; +C452;C452;110A 116D 11B1;C452;110A 116D 11B1; +C453;C453;110A 116D 11B2;C453;110A 116D 11B2; +C454;C454;110A 116D 11B3;C454;110A 116D 11B3; +C455;C455;110A 116D 11B4;C455;110A 116D 11B4; +C456;C456;110A 116D 11B5;C456;110A 116D 11B5; +C457;C457;110A 116D 11B6;C457;110A 116D 11B6; +C458;C458;110A 116D 11B7;C458;110A 116D 11B7; +C459;C459;110A 116D 11B8;C459;110A 116D 11B8; +C45A;C45A;110A 116D 11B9;C45A;110A 116D 11B9; +C45B;C45B;110A 116D 11BA;C45B;110A 116D 11BA; +C45C;C45C;110A 116D 11BB;C45C;110A 116D 11BB; +C45D;C45D;110A 116D 11BC;C45D;110A 116D 11BC; +C45E;C45E;110A 116D 11BD;C45E;110A 116D 11BD; +C45F;C45F;110A 116D 11BE;C45F;110A 116D 11BE; +C460;C460;110A 116D 11BF;C460;110A 116D 11BF; +C461;C461;110A 116D 11C0;C461;110A 116D 11C0; +C462;C462;110A 116D 11C1;C462;110A 116D 11C1; +C463;C463;110A 116D 11C2;C463;110A 116D 11C2; +C464;C464;110A 116E;C464;110A 116E; +C465;C465;110A 116E 11A8;C465;110A 116E 11A8; +C466;C466;110A 116E 11A9;C466;110A 116E 11A9; +C467;C467;110A 116E 11AA;C467;110A 116E 11AA; +C468;C468;110A 116E 11AB;C468;110A 116E 11AB; +C469;C469;110A 116E 11AC;C469;110A 116E 11AC; +C46A;C46A;110A 116E 11AD;C46A;110A 116E 11AD; +C46B;C46B;110A 116E 11AE;C46B;110A 116E 11AE; +C46C;C46C;110A 116E 11AF;C46C;110A 116E 11AF; +C46D;C46D;110A 116E 11B0;C46D;110A 116E 11B0; +C46E;C46E;110A 116E 11B1;C46E;110A 116E 11B1; +C46F;C46F;110A 116E 11B2;C46F;110A 116E 11B2; +C470;C470;110A 116E 11B3;C470;110A 116E 11B3; +C471;C471;110A 116E 11B4;C471;110A 116E 11B4; +C472;C472;110A 116E 11B5;C472;110A 116E 11B5; +C473;C473;110A 116E 11B6;C473;110A 116E 11B6; +C474;C474;110A 116E 11B7;C474;110A 116E 11B7; +C475;C475;110A 116E 11B8;C475;110A 116E 11B8; +C476;C476;110A 116E 11B9;C476;110A 116E 11B9; +C477;C477;110A 116E 11BA;C477;110A 116E 11BA; +C478;C478;110A 116E 11BB;C478;110A 116E 11BB; +C479;C479;110A 116E 11BC;C479;110A 116E 11BC; +C47A;C47A;110A 116E 11BD;C47A;110A 116E 11BD; +C47B;C47B;110A 116E 11BE;C47B;110A 116E 11BE; +C47C;C47C;110A 116E 11BF;C47C;110A 116E 11BF; +C47D;C47D;110A 116E 11C0;C47D;110A 116E 11C0; +C47E;C47E;110A 116E 11C1;C47E;110A 116E 11C1; +C47F;C47F;110A 116E 11C2;C47F;110A 116E 11C2; +C480;C480;110A 116F;C480;110A 116F; +C481;C481;110A 116F 11A8;C481;110A 116F 11A8; +C482;C482;110A 116F 11A9;C482;110A 116F 11A9; +C483;C483;110A 116F 11AA;C483;110A 116F 11AA; +C484;C484;110A 116F 11AB;C484;110A 116F 11AB; +C485;C485;110A 116F 11AC;C485;110A 116F 11AC; +C486;C486;110A 116F 11AD;C486;110A 116F 11AD; +C487;C487;110A 116F 11AE;C487;110A 116F 11AE; +C488;C488;110A 116F 11AF;C488;110A 116F 11AF; +C489;C489;110A 116F 11B0;C489;110A 116F 11B0; +C48A;C48A;110A 116F 11B1;C48A;110A 116F 11B1; +C48B;C48B;110A 116F 11B2;C48B;110A 116F 11B2; +C48C;C48C;110A 116F 11B3;C48C;110A 116F 11B3; +C48D;C48D;110A 116F 11B4;C48D;110A 116F 11B4; +C48E;C48E;110A 116F 11B5;C48E;110A 116F 11B5; +C48F;C48F;110A 116F 11B6;C48F;110A 116F 11B6; +C490;C490;110A 116F 11B7;C490;110A 116F 11B7; +C491;C491;110A 116F 11B8;C491;110A 116F 11B8; +C492;C492;110A 116F 11B9;C492;110A 116F 11B9; +C493;C493;110A 116F 11BA;C493;110A 116F 11BA; +C494;C494;110A 116F 11BB;C494;110A 116F 11BB; +C495;C495;110A 116F 11BC;C495;110A 116F 11BC; +C496;C496;110A 116F 11BD;C496;110A 116F 11BD; +C497;C497;110A 116F 11BE;C497;110A 116F 11BE; +C498;C498;110A 116F 11BF;C498;110A 116F 11BF; +C499;C499;110A 116F 11C0;C499;110A 116F 11C0; +C49A;C49A;110A 116F 11C1;C49A;110A 116F 11C1; +C49B;C49B;110A 116F 11C2;C49B;110A 116F 11C2; +C49C;C49C;110A 1170;C49C;110A 1170; +C49D;C49D;110A 1170 11A8;C49D;110A 1170 11A8; +C49E;C49E;110A 1170 11A9;C49E;110A 1170 11A9; +C49F;C49F;110A 1170 11AA;C49F;110A 1170 11AA; +C4A0;C4A0;110A 1170 11AB;C4A0;110A 1170 11AB; +C4A1;C4A1;110A 1170 11AC;C4A1;110A 1170 11AC; +C4A2;C4A2;110A 1170 11AD;C4A2;110A 1170 11AD; +C4A3;C4A3;110A 1170 11AE;C4A3;110A 1170 11AE; +C4A4;C4A4;110A 1170 11AF;C4A4;110A 1170 11AF; +C4A5;C4A5;110A 1170 11B0;C4A5;110A 1170 11B0; +C4A6;C4A6;110A 1170 11B1;C4A6;110A 1170 11B1; +C4A7;C4A7;110A 1170 11B2;C4A7;110A 1170 11B2; +C4A8;C4A8;110A 1170 11B3;C4A8;110A 1170 11B3; +C4A9;C4A9;110A 1170 11B4;C4A9;110A 1170 11B4; +C4AA;C4AA;110A 1170 11B5;C4AA;110A 1170 11B5; +C4AB;C4AB;110A 1170 11B6;C4AB;110A 1170 11B6; +C4AC;C4AC;110A 1170 11B7;C4AC;110A 1170 11B7; +C4AD;C4AD;110A 1170 11B8;C4AD;110A 1170 11B8; +C4AE;C4AE;110A 1170 11B9;C4AE;110A 1170 11B9; +C4AF;C4AF;110A 1170 11BA;C4AF;110A 1170 11BA; +C4B0;C4B0;110A 1170 11BB;C4B0;110A 1170 11BB; +C4B1;C4B1;110A 1170 11BC;C4B1;110A 1170 11BC; +C4B2;C4B2;110A 1170 11BD;C4B2;110A 1170 11BD; +C4B3;C4B3;110A 1170 11BE;C4B3;110A 1170 11BE; +C4B4;C4B4;110A 1170 11BF;C4B4;110A 1170 11BF; +C4B5;C4B5;110A 1170 11C0;C4B5;110A 1170 11C0; +C4B6;C4B6;110A 1170 11C1;C4B6;110A 1170 11C1; +C4B7;C4B7;110A 1170 11C2;C4B7;110A 1170 11C2; +C4B8;C4B8;110A 1171;C4B8;110A 1171; +C4B9;C4B9;110A 1171 11A8;C4B9;110A 1171 11A8; +C4BA;C4BA;110A 1171 11A9;C4BA;110A 1171 11A9; +C4BB;C4BB;110A 1171 11AA;C4BB;110A 1171 11AA; +C4BC;C4BC;110A 1171 11AB;C4BC;110A 1171 11AB; +C4BD;C4BD;110A 1171 11AC;C4BD;110A 1171 11AC; +C4BE;C4BE;110A 1171 11AD;C4BE;110A 1171 11AD; +C4BF;C4BF;110A 1171 11AE;C4BF;110A 1171 11AE; +C4C0;C4C0;110A 1171 11AF;C4C0;110A 1171 11AF; +C4C1;C4C1;110A 1171 11B0;C4C1;110A 1171 11B0; +C4C2;C4C2;110A 1171 11B1;C4C2;110A 1171 11B1; +C4C3;C4C3;110A 1171 11B2;C4C3;110A 1171 11B2; +C4C4;C4C4;110A 1171 11B3;C4C4;110A 1171 11B3; +C4C5;C4C5;110A 1171 11B4;C4C5;110A 1171 11B4; +C4C6;C4C6;110A 1171 11B5;C4C6;110A 1171 11B5; +C4C7;C4C7;110A 1171 11B6;C4C7;110A 1171 11B6; +C4C8;C4C8;110A 1171 11B7;C4C8;110A 1171 11B7; +C4C9;C4C9;110A 1171 11B8;C4C9;110A 1171 11B8; +C4CA;C4CA;110A 1171 11B9;C4CA;110A 1171 11B9; +C4CB;C4CB;110A 1171 11BA;C4CB;110A 1171 11BA; +C4CC;C4CC;110A 1171 11BB;C4CC;110A 1171 11BB; +C4CD;C4CD;110A 1171 11BC;C4CD;110A 1171 11BC; +C4CE;C4CE;110A 1171 11BD;C4CE;110A 1171 11BD; +C4CF;C4CF;110A 1171 11BE;C4CF;110A 1171 11BE; +C4D0;C4D0;110A 1171 11BF;C4D0;110A 1171 11BF; +C4D1;C4D1;110A 1171 11C0;C4D1;110A 1171 11C0; +C4D2;C4D2;110A 1171 11C1;C4D2;110A 1171 11C1; +C4D3;C4D3;110A 1171 11C2;C4D3;110A 1171 11C2; +C4D4;C4D4;110A 1172;C4D4;110A 1172; +C4D5;C4D5;110A 1172 11A8;C4D5;110A 1172 11A8; +C4D6;C4D6;110A 1172 11A9;C4D6;110A 1172 11A9; +C4D7;C4D7;110A 1172 11AA;C4D7;110A 1172 11AA; +C4D8;C4D8;110A 1172 11AB;C4D8;110A 1172 11AB; +C4D9;C4D9;110A 1172 11AC;C4D9;110A 1172 11AC; +C4DA;C4DA;110A 1172 11AD;C4DA;110A 1172 11AD; +C4DB;C4DB;110A 1172 11AE;C4DB;110A 1172 11AE; +C4DC;C4DC;110A 1172 11AF;C4DC;110A 1172 11AF; +C4DD;C4DD;110A 1172 11B0;C4DD;110A 1172 11B0; +C4DE;C4DE;110A 1172 11B1;C4DE;110A 1172 11B1; +C4DF;C4DF;110A 1172 11B2;C4DF;110A 1172 11B2; +C4E0;C4E0;110A 1172 11B3;C4E0;110A 1172 11B3; +C4E1;C4E1;110A 1172 11B4;C4E1;110A 1172 11B4; +C4E2;C4E2;110A 1172 11B5;C4E2;110A 1172 11B5; +C4E3;C4E3;110A 1172 11B6;C4E3;110A 1172 11B6; +C4E4;C4E4;110A 1172 11B7;C4E4;110A 1172 11B7; +C4E5;C4E5;110A 1172 11B8;C4E5;110A 1172 11B8; +C4E6;C4E6;110A 1172 11B9;C4E6;110A 1172 11B9; +C4E7;C4E7;110A 1172 11BA;C4E7;110A 1172 11BA; +C4E8;C4E8;110A 1172 11BB;C4E8;110A 1172 11BB; +C4E9;C4E9;110A 1172 11BC;C4E9;110A 1172 11BC; +C4EA;C4EA;110A 1172 11BD;C4EA;110A 1172 11BD; +C4EB;C4EB;110A 1172 11BE;C4EB;110A 1172 11BE; +C4EC;C4EC;110A 1172 11BF;C4EC;110A 1172 11BF; +C4ED;C4ED;110A 1172 11C0;C4ED;110A 1172 11C0; +C4EE;C4EE;110A 1172 11C1;C4EE;110A 1172 11C1; +C4EF;C4EF;110A 1172 11C2;C4EF;110A 1172 11C2; +C4F0;C4F0;110A 1173;C4F0;110A 1173; +C4F1;C4F1;110A 1173 11A8;C4F1;110A 1173 11A8; +C4F2;C4F2;110A 1173 11A9;C4F2;110A 1173 11A9; +C4F3;C4F3;110A 1173 11AA;C4F3;110A 1173 11AA; +C4F4;C4F4;110A 1173 11AB;C4F4;110A 1173 11AB; +C4F5;C4F5;110A 1173 11AC;C4F5;110A 1173 11AC; +C4F6;C4F6;110A 1173 11AD;C4F6;110A 1173 11AD; +C4F7;C4F7;110A 1173 11AE;C4F7;110A 1173 11AE; +C4F8;C4F8;110A 1173 11AF;C4F8;110A 1173 11AF; +C4F9;C4F9;110A 1173 11B0;C4F9;110A 1173 11B0; +C4FA;C4FA;110A 1173 11B1;C4FA;110A 1173 11B1; +C4FB;C4FB;110A 1173 11B2;C4FB;110A 1173 11B2; +C4FC;C4FC;110A 1173 11B3;C4FC;110A 1173 11B3; +C4FD;C4FD;110A 1173 11B4;C4FD;110A 1173 11B4; +C4FE;C4FE;110A 1173 11B5;C4FE;110A 1173 11B5; +C4FF;C4FF;110A 1173 11B6;C4FF;110A 1173 11B6; +C500;C500;110A 1173 11B7;C500;110A 1173 11B7; +C501;C501;110A 1173 11B8;C501;110A 1173 11B8; +C502;C502;110A 1173 11B9;C502;110A 1173 11B9; +C503;C503;110A 1173 11BA;C503;110A 1173 11BA; +C504;C504;110A 1173 11BB;C504;110A 1173 11BB; +C505;C505;110A 1173 11BC;C505;110A 1173 11BC; +C506;C506;110A 1173 11BD;C506;110A 1173 11BD; +C507;C507;110A 1173 11BE;C507;110A 1173 11BE; +C508;C508;110A 1173 11BF;C508;110A 1173 11BF; +C509;C509;110A 1173 11C0;C509;110A 1173 11C0; +C50A;C50A;110A 1173 11C1;C50A;110A 1173 11C1; +C50B;C50B;110A 1173 11C2;C50B;110A 1173 11C2; +C50C;C50C;110A 1174;C50C;110A 1174; +C50D;C50D;110A 1174 11A8;C50D;110A 1174 11A8; +C50E;C50E;110A 1174 11A9;C50E;110A 1174 11A9; +C50F;C50F;110A 1174 11AA;C50F;110A 1174 11AA; +C510;C510;110A 1174 11AB;C510;110A 1174 11AB; +C511;C511;110A 1174 11AC;C511;110A 1174 11AC; +C512;C512;110A 1174 11AD;C512;110A 1174 11AD; +C513;C513;110A 1174 11AE;C513;110A 1174 11AE; +C514;C514;110A 1174 11AF;C514;110A 1174 11AF; +C515;C515;110A 1174 11B0;C515;110A 1174 11B0; +C516;C516;110A 1174 11B1;C516;110A 1174 11B1; +C517;C517;110A 1174 11B2;C517;110A 1174 11B2; +C518;C518;110A 1174 11B3;C518;110A 1174 11B3; +C519;C519;110A 1174 11B4;C519;110A 1174 11B4; +C51A;C51A;110A 1174 11B5;C51A;110A 1174 11B5; +C51B;C51B;110A 1174 11B6;C51B;110A 1174 11B6; +C51C;C51C;110A 1174 11B7;C51C;110A 1174 11B7; +C51D;C51D;110A 1174 11B8;C51D;110A 1174 11B8; +C51E;C51E;110A 1174 11B9;C51E;110A 1174 11B9; +C51F;C51F;110A 1174 11BA;C51F;110A 1174 11BA; +C520;C520;110A 1174 11BB;C520;110A 1174 11BB; +C521;C521;110A 1174 11BC;C521;110A 1174 11BC; +C522;C522;110A 1174 11BD;C522;110A 1174 11BD; +C523;C523;110A 1174 11BE;C523;110A 1174 11BE; +C524;C524;110A 1174 11BF;C524;110A 1174 11BF; +C525;C525;110A 1174 11C0;C525;110A 1174 11C0; +C526;C526;110A 1174 11C1;C526;110A 1174 11C1; +C527;C527;110A 1174 11C2;C527;110A 1174 11C2; +C528;C528;110A 1175;C528;110A 1175; +C529;C529;110A 1175 11A8;C529;110A 1175 11A8; +C52A;C52A;110A 1175 11A9;C52A;110A 1175 11A9; +C52B;C52B;110A 1175 11AA;C52B;110A 1175 11AA; +C52C;C52C;110A 1175 11AB;C52C;110A 1175 11AB; +C52D;C52D;110A 1175 11AC;C52D;110A 1175 11AC; +C52E;C52E;110A 1175 11AD;C52E;110A 1175 11AD; +C52F;C52F;110A 1175 11AE;C52F;110A 1175 11AE; +C530;C530;110A 1175 11AF;C530;110A 1175 11AF; +C531;C531;110A 1175 11B0;C531;110A 1175 11B0; +C532;C532;110A 1175 11B1;C532;110A 1175 11B1; +C533;C533;110A 1175 11B2;C533;110A 1175 11B2; +C534;C534;110A 1175 11B3;C534;110A 1175 11B3; +C535;C535;110A 1175 11B4;C535;110A 1175 11B4; +C536;C536;110A 1175 11B5;C536;110A 1175 11B5; +C537;C537;110A 1175 11B6;C537;110A 1175 11B6; +C538;C538;110A 1175 11B7;C538;110A 1175 11B7; +C539;C539;110A 1175 11B8;C539;110A 1175 11B8; +C53A;C53A;110A 1175 11B9;C53A;110A 1175 11B9; +C53B;C53B;110A 1175 11BA;C53B;110A 1175 11BA; +C53C;C53C;110A 1175 11BB;C53C;110A 1175 11BB; +C53D;C53D;110A 1175 11BC;C53D;110A 1175 11BC; +C53E;C53E;110A 1175 11BD;C53E;110A 1175 11BD; +C53F;C53F;110A 1175 11BE;C53F;110A 1175 11BE; +C540;C540;110A 1175 11BF;C540;110A 1175 11BF; +C541;C541;110A 1175 11C0;C541;110A 1175 11C0; +C542;C542;110A 1175 11C1;C542;110A 1175 11C1; +C543;C543;110A 1175 11C2;C543;110A 1175 11C2; +C544;C544;110B 1161;C544;110B 1161; +C545;C545;110B 1161 11A8;C545;110B 1161 11A8; +C546;C546;110B 1161 11A9;C546;110B 1161 11A9; +C547;C547;110B 1161 11AA;C547;110B 1161 11AA; +C548;C548;110B 1161 11AB;C548;110B 1161 11AB; +C549;C549;110B 1161 11AC;C549;110B 1161 11AC; +C54A;C54A;110B 1161 11AD;C54A;110B 1161 11AD; +C54B;C54B;110B 1161 11AE;C54B;110B 1161 11AE; +C54C;C54C;110B 1161 11AF;C54C;110B 1161 11AF; +C54D;C54D;110B 1161 11B0;C54D;110B 1161 11B0; +C54E;C54E;110B 1161 11B1;C54E;110B 1161 11B1; +C54F;C54F;110B 1161 11B2;C54F;110B 1161 11B2; +C550;C550;110B 1161 11B3;C550;110B 1161 11B3; +C551;C551;110B 1161 11B4;C551;110B 1161 11B4; +C552;C552;110B 1161 11B5;C552;110B 1161 11B5; +C553;C553;110B 1161 11B6;C553;110B 1161 11B6; +C554;C554;110B 1161 11B7;C554;110B 1161 11B7; +C555;C555;110B 1161 11B8;C555;110B 1161 11B8; +C556;C556;110B 1161 11B9;C556;110B 1161 11B9; +C557;C557;110B 1161 11BA;C557;110B 1161 11BA; +C558;C558;110B 1161 11BB;C558;110B 1161 11BB; +C559;C559;110B 1161 11BC;C559;110B 1161 11BC; +C55A;C55A;110B 1161 11BD;C55A;110B 1161 11BD; +C55B;C55B;110B 1161 11BE;C55B;110B 1161 11BE; +C55C;C55C;110B 1161 11BF;C55C;110B 1161 11BF; +C55D;C55D;110B 1161 11C0;C55D;110B 1161 11C0; +C55E;C55E;110B 1161 11C1;C55E;110B 1161 11C1; +C55F;C55F;110B 1161 11C2;C55F;110B 1161 11C2; +C560;C560;110B 1162;C560;110B 1162; +C561;C561;110B 1162 11A8;C561;110B 1162 11A8; +C562;C562;110B 1162 11A9;C562;110B 1162 11A9; +C563;C563;110B 1162 11AA;C563;110B 1162 11AA; +C564;C564;110B 1162 11AB;C564;110B 1162 11AB; +C565;C565;110B 1162 11AC;C565;110B 1162 11AC; +C566;C566;110B 1162 11AD;C566;110B 1162 11AD; +C567;C567;110B 1162 11AE;C567;110B 1162 11AE; +C568;C568;110B 1162 11AF;C568;110B 1162 11AF; +C569;C569;110B 1162 11B0;C569;110B 1162 11B0; +C56A;C56A;110B 1162 11B1;C56A;110B 1162 11B1; +C56B;C56B;110B 1162 11B2;C56B;110B 1162 11B2; +C56C;C56C;110B 1162 11B3;C56C;110B 1162 11B3; +C56D;C56D;110B 1162 11B4;C56D;110B 1162 11B4; +C56E;C56E;110B 1162 11B5;C56E;110B 1162 11B5; +C56F;C56F;110B 1162 11B6;C56F;110B 1162 11B6; +C570;C570;110B 1162 11B7;C570;110B 1162 11B7; +C571;C571;110B 1162 11B8;C571;110B 1162 11B8; +C572;C572;110B 1162 11B9;C572;110B 1162 11B9; +C573;C573;110B 1162 11BA;C573;110B 1162 11BA; +C574;C574;110B 1162 11BB;C574;110B 1162 11BB; +C575;C575;110B 1162 11BC;C575;110B 1162 11BC; +C576;C576;110B 1162 11BD;C576;110B 1162 11BD; +C577;C577;110B 1162 11BE;C577;110B 1162 11BE; +C578;C578;110B 1162 11BF;C578;110B 1162 11BF; +C579;C579;110B 1162 11C0;C579;110B 1162 11C0; +C57A;C57A;110B 1162 11C1;C57A;110B 1162 11C1; +C57B;C57B;110B 1162 11C2;C57B;110B 1162 11C2; +C57C;C57C;110B 1163;C57C;110B 1163; +C57D;C57D;110B 1163 11A8;C57D;110B 1163 11A8; +C57E;C57E;110B 1163 11A9;C57E;110B 1163 11A9; +C57F;C57F;110B 1163 11AA;C57F;110B 1163 11AA; +C580;C580;110B 1163 11AB;C580;110B 1163 11AB; +C581;C581;110B 1163 11AC;C581;110B 1163 11AC; +C582;C582;110B 1163 11AD;C582;110B 1163 11AD; +C583;C583;110B 1163 11AE;C583;110B 1163 11AE; +C584;C584;110B 1163 11AF;C584;110B 1163 11AF; +C585;C585;110B 1163 11B0;C585;110B 1163 11B0; +C586;C586;110B 1163 11B1;C586;110B 1163 11B1; +C587;C587;110B 1163 11B2;C587;110B 1163 11B2; +C588;C588;110B 1163 11B3;C588;110B 1163 11B3; +C589;C589;110B 1163 11B4;C589;110B 1163 11B4; +C58A;C58A;110B 1163 11B5;C58A;110B 1163 11B5; +C58B;C58B;110B 1163 11B6;C58B;110B 1163 11B6; +C58C;C58C;110B 1163 11B7;C58C;110B 1163 11B7; +C58D;C58D;110B 1163 11B8;C58D;110B 1163 11B8; +C58E;C58E;110B 1163 11B9;C58E;110B 1163 11B9; +C58F;C58F;110B 1163 11BA;C58F;110B 1163 11BA; +C590;C590;110B 1163 11BB;C590;110B 1163 11BB; +C591;C591;110B 1163 11BC;C591;110B 1163 11BC; +C592;C592;110B 1163 11BD;C592;110B 1163 11BD; +C593;C593;110B 1163 11BE;C593;110B 1163 11BE; +C594;C594;110B 1163 11BF;C594;110B 1163 11BF; +C595;C595;110B 1163 11C0;C595;110B 1163 11C0; +C596;C596;110B 1163 11C1;C596;110B 1163 11C1; +C597;C597;110B 1163 11C2;C597;110B 1163 11C2; +C598;C598;110B 1164;C598;110B 1164; +C599;C599;110B 1164 11A8;C599;110B 1164 11A8; +C59A;C59A;110B 1164 11A9;C59A;110B 1164 11A9; +C59B;C59B;110B 1164 11AA;C59B;110B 1164 11AA; +C59C;C59C;110B 1164 11AB;C59C;110B 1164 11AB; +C59D;C59D;110B 1164 11AC;C59D;110B 1164 11AC; +C59E;C59E;110B 1164 11AD;C59E;110B 1164 11AD; +C59F;C59F;110B 1164 11AE;C59F;110B 1164 11AE; +C5A0;C5A0;110B 1164 11AF;C5A0;110B 1164 11AF; +C5A1;C5A1;110B 1164 11B0;C5A1;110B 1164 11B0; +C5A2;C5A2;110B 1164 11B1;C5A2;110B 1164 11B1; +C5A3;C5A3;110B 1164 11B2;C5A3;110B 1164 11B2; +C5A4;C5A4;110B 1164 11B3;C5A4;110B 1164 11B3; +C5A5;C5A5;110B 1164 11B4;C5A5;110B 1164 11B4; +C5A6;C5A6;110B 1164 11B5;C5A6;110B 1164 11B5; +C5A7;C5A7;110B 1164 11B6;C5A7;110B 1164 11B6; +C5A8;C5A8;110B 1164 11B7;C5A8;110B 1164 11B7; +C5A9;C5A9;110B 1164 11B8;C5A9;110B 1164 11B8; +C5AA;C5AA;110B 1164 11B9;C5AA;110B 1164 11B9; +C5AB;C5AB;110B 1164 11BA;C5AB;110B 1164 11BA; +C5AC;C5AC;110B 1164 11BB;C5AC;110B 1164 11BB; +C5AD;C5AD;110B 1164 11BC;C5AD;110B 1164 11BC; +C5AE;C5AE;110B 1164 11BD;C5AE;110B 1164 11BD; +C5AF;C5AF;110B 1164 11BE;C5AF;110B 1164 11BE; +C5B0;C5B0;110B 1164 11BF;C5B0;110B 1164 11BF; +C5B1;C5B1;110B 1164 11C0;C5B1;110B 1164 11C0; +C5B2;C5B2;110B 1164 11C1;C5B2;110B 1164 11C1; +C5B3;C5B3;110B 1164 11C2;C5B3;110B 1164 11C2; +C5B4;C5B4;110B 1165;C5B4;110B 1165; +C5B5;C5B5;110B 1165 11A8;C5B5;110B 1165 11A8; +C5B6;C5B6;110B 1165 11A9;C5B6;110B 1165 11A9; +C5B7;C5B7;110B 1165 11AA;C5B7;110B 1165 11AA; +C5B8;C5B8;110B 1165 11AB;C5B8;110B 1165 11AB; +C5B9;C5B9;110B 1165 11AC;C5B9;110B 1165 11AC; +C5BA;C5BA;110B 1165 11AD;C5BA;110B 1165 11AD; +C5BB;C5BB;110B 1165 11AE;C5BB;110B 1165 11AE; +C5BC;C5BC;110B 1165 11AF;C5BC;110B 1165 11AF; +C5BD;C5BD;110B 1165 11B0;C5BD;110B 1165 11B0; +C5BE;C5BE;110B 1165 11B1;C5BE;110B 1165 11B1; +C5BF;C5BF;110B 1165 11B2;C5BF;110B 1165 11B2; +C5C0;C5C0;110B 1165 11B3;C5C0;110B 1165 11B3; +C5C1;C5C1;110B 1165 11B4;C5C1;110B 1165 11B4; +C5C2;C5C2;110B 1165 11B5;C5C2;110B 1165 11B5; +C5C3;C5C3;110B 1165 11B6;C5C3;110B 1165 11B6; +C5C4;C5C4;110B 1165 11B7;C5C4;110B 1165 11B7; +C5C5;C5C5;110B 1165 11B8;C5C5;110B 1165 11B8; +C5C6;C5C6;110B 1165 11B9;C5C6;110B 1165 11B9; +C5C7;C5C7;110B 1165 11BA;C5C7;110B 1165 11BA; +C5C8;C5C8;110B 1165 11BB;C5C8;110B 1165 11BB; +C5C9;C5C9;110B 1165 11BC;C5C9;110B 1165 11BC; +C5CA;C5CA;110B 1165 11BD;C5CA;110B 1165 11BD; +C5CB;C5CB;110B 1165 11BE;C5CB;110B 1165 11BE; +C5CC;C5CC;110B 1165 11BF;C5CC;110B 1165 11BF; +C5CD;C5CD;110B 1165 11C0;C5CD;110B 1165 11C0; +C5CE;C5CE;110B 1165 11C1;C5CE;110B 1165 11C1; +C5CF;C5CF;110B 1165 11C2;C5CF;110B 1165 11C2; +C5D0;C5D0;110B 1166;C5D0;110B 1166; +C5D1;C5D1;110B 1166 11A8;C5D1;110B 1166 11A8; +C5D2;C5D2;110B 1166 11A9;C5D2;110B 1166 11A9; +C5D3;C5D3;110B 1166 11AA;C5D3;110B 1166 11AA; +C5D4;C5D4;110B 1166 11AB;C5D4;110B 1166 11AB; +C5D5;C5D5;110B 1166 11AC;C5D5;110B 1166 11AC; +C5D6;C5D6;110B 1166 11AD;C5D6;110B 1166 11AD; +C5D7;C5D7;110B 1166 11AE;C5D7;110B 1166 11AE; +C5D8;C5D8;110B 1166 11AF;C5D8;110B 1166 11AF; +C5D9;C5D9;110B 1166 11B0;C5D9;110B 1166 11B0; +C5DA;C5DA;110B 1166 11B1;C5DA;110B 1166 11B1; +C5DB;C5DB;110B 1166 11B2;C5DB;110B 1166 11B2; +C5DC;C5DC;110B 1166 11B3;C5DC;110B 1166 11B3; +C5DD;C5DD;110B 1166 11B4;C5DD;110B 1166 11B4; +C5DE;C5DE;110B 1166 11B5;C5DE;110B 1166 11B5; +C5DF;C5DF;110B 1166 11B6;C5DF;110B 1166 11B6; +C5E0;C5E0;110B 1166 11B7;C5E0;110B 1166 11B7; +C5E1;C5E1;110B 1166 11B8;C5E1;110B 1166 11B8; +C5E2;C5E2;110B 1166 11B9;C5E2;110B 1166 11B9; +C5E3;C5E3;110B 1166 11BA;C5E3;110B 1166 11BA; +C5E4;C5E4;110B 1166 11BB;C5E4;110B 1166 11BB; +C5E5;C5E5;110B 1166 11BC;C5E5;110B 1166 11BC; +C5E6;C5E6;110B 1166 11BD;C5E6;110B 1166 11BD; +C5E7;C5E7;110B 1166 11BE;C5E7;110B 1166 11BE; +C5E8;C5E8;110B 1166 11BF;C5E8;110B 1166 11BF; +C5E9;C5E9;110B 1166 11C0;C5E9;110B 1166 11C0; +C5EA;C5EA;110B 1166 11C1;C5EA;110B 1166 11C1; +C5EB;C5EB;110B 1166 11C2;C5EB;110B 1166 11C2; +C5EC;C5EC;110B 1167;C5EC;110B 1167; +C5ED;C5ED;110B 1167 11A8;C5ED;110B 1167 11A8; +C5EE;C5EE;110B 1167 11A9;C5EE;110B 1167 11A9; +C5EF;C5EF;110B 1167 11AA;C5EF;110B 1167 11AA; +C5F0;C5F0;110B 1167 11AB;C5F0;110B 1167 11AB; +C5F1;C5F1;110B 1167 11AC;C5F1;110B 1167 11AC; +C5F2;C5F2;110B 1167 11AD;C5F2;110B 1167 11AD; +C5F3;C5F3;110B 1167 11AE;C5F3;110B 1167 11AE; +C5F4;C5F4;110B 1167 11AF;C5F4;110B 1167 11AF; +C5F5;C5F5;110B 1167 11B0;C5F5;110B 1167 11B0; +C5F6;C5F6;110B 1167 11B1;C5F6;110B 1167 11B1; +C5F7;C5F7;110B 1167 11B2;C5F7;110B 1167 11B2; +C5F8;C5F8;110B 1167 11B3;C5F8;110B 1167 11B3; +C5F9;C5F9;110B 1167 11B4;C5F9;110B 1167 11B4; +C5FA;C5FA;110B 1167 11B5;C5FA;110B 1167 11B5; +C5FB;C5FB;110B 1167 11B6;C5FB;110B 1167 11B6; +C5FC;C5FC;110B 1167 11B7;C5FC;110B 1167 11B7; +C5FD;C5FD;110B 1167 11B8;C5FD;110B 1167 11B8; +C5FE;C5FE;110B 1167 11B9;C5FE;110B 1167 11B9; +C5FF;C5FF;110B 1167 11BA;C5FF;110B 1167 11BA; +C600;C600;110B 1167 11BB;C600;110B 1167 11BB; +C601;C601;110B 1167 11BC;C601;110B 1167 11BC; +C602;C602;110B 1167 11BD;C602;110B 1167 11BD; +C603;C603;110B 1167 11BE;C603;110B 1167 11BE; +C604;C604;110B 1167 11BF;C604;110B 1167 11BF; +C605;C605;110B 1167 11C0;C605;110B 1167 11C0; +C606;C606;110B 1167 11C1;C606;110B 1167 11C1; +C607;C607;110B 1167 11C2;C607;110B 1167 11C2; +C608;C608;110B 1168;C608;110B 1168; +C609;C609;110B 1168 11A8;C609;110B 1168 11A8; +C60A;C60A;110B 1168 11A9;C60A;110B 1168 11A9; +C60B;C60B;110B 1168 11AA;C60B;110B 1168 11AA; +C60C;C60C;110B 1168 11AB;C60C;110B 1168 11AB; +C60D;C60D;110B 1168 11AC;C60D;110B 1168 11AC; +C60E;C60E;110B 1168 11AD;C60E;110B 1168 11AD; +C60F;C60F;110B 1168 11AE;C60F;110B 1168 11AE; +C610;C610;110B 1168 11AF;C610;110B 1168 11AF; +C611;C611;110B 1168 11B0;C611;110B 1168 11B0; +C612;C612;110B 1168 11B1;C612;110B 1168 11B1; +C613;C613;110B 1168 11B2;C613;110B 1168 11B2; +C614;C614;110B 1168 11B3;C614;110B 1168 11B3; +C615;C615;110B 1168 11B4;C615;110B 1168 11B4; +C616;C616;110B 1168 11B5;C616;110B 1168 11B5; +C617;C617;110B 1168 11B6;C617;110B 1168 11B6; +C618;C618;110B 1168 11B7;C618;110B 1168 11B7; +C619;C619;110B 1168 11B8;C619;110B 1168 11B8; +C61A;C61A;110B 1168 11B9;C61A;110B 1168 11B9; +C61B;C61B;110B 1168 11BA;C61B;110B 1168 11BA; +C61C;C61C;110B 1168 11BB;C61C;110B 1168 11BB; +C61D;C61D;110B 1168 11BC;C61D;110B 1168 11BC; +C61E;C61E;110B 1168 11BD;C61E;110B 1168 11BD; +C61F;C61F;110B 1168 11BE;C61F;110B 1168 11BE; +C620;C620;110B 1168 11BF;C620;110B 1168 11BF; +C621;C621;110B 1168 11C0;C621;110B 1168 11C0; +C622;C622;110B 1168 11C1;C622;110B 1168 11C1; +C623;C623;110B 1168 11C2;C623;110B 1168 11C2; +C624;C624;110B 1169;C624;110B 1169; +C625;C625;110B 1169 11A8;C625;110B 1169 11A8; +C626;C626;110B 1169 11A9;C626;110B 1169 11A9; +C627;C627;110B 1169 11AA;C627;110B 1169 11AA; +C628;C628;110B 1169 11AB;C628;110B 1169 11AB; +C629;C629;110B 1169 11AC;C629;110B 1169 11AC; +C62A;C62A;110B 1169 11AD;C62A;110B 1169 11AD; +C62B;C62B;110B 1169 11AE;C62B;110B 1169 11AE; +C62C;C62C;110B 1169 11AF;C62C;110B 1169 11AF; +C62D;C62D;110B 1169 11B0;C62D;110B 1169 11B0; +C62E;C62E;110B 1169 11B1;C62E;110B 1169 11B1; +C62F;C62F;110B 1169 11B2;C62F;110B 1169 11B2; +C630;C630;110B 1169 11B3;C630;110B 1169 11B3; +C631;C631;110B 1169 11B4;C631;110B 1169 11B4; +C632;C632;110B 1169 11B5;C632;110B 1169 11B5; +C633;C633;110B 1169 11B6;C633;110B 1169 11B6; +C634;C634;110B 1169 11B7;C634;110B 1169 11B7; +C635;C635;110B 1169 11B8;C635;110B 1169 11B8; +C636;C636;110B 1169 11B9;C636;110B 1169 11B9; +C637;C637;110B 1169 11BA;C637;110B 1169 11BA; +C638;C638;110B 1169 11BB;C638;110B 1169 11BB; +C639;C639;110B 1169 11BC;C639;110B 1169 11BC; +C63A;C63A;110B 1169 11BD;C63A;110B 1169 11BD; +C63B;C63B;110B 1169 11BE;C63B;110B 1169 11BE; +C63C;C63C;110B 1169 11BF;C63C;110B 1169 11BF; +C63D;C63D;110B 1169 11C0;C63D;110B 1169 11C0; +C63E;C63E;110B 1169 11C1;C63E;110B 1169 11C1; +C63F;C63F;110B 1169 11C2;C63F;110B 1169 11C2; +C640;C640;110B 116A;C640;110B 116A; +C641;C641;110B 116A 11A8;C641;110B 116A 11A8; +C642;C642;110B 116A 11A9;C642;110B 116A 11A9; +C643;C643;110B 116A 11AA;C643;110B 116A 11AA; +C644;C644;110B 116A 11AB;C644;110B 116A 11AB; +C645;C645;110B 116A 11AC;C645;110B 116A 11AC; +C646;C646;110B 116A 11AD;C646;110B 116A 11AD; +C647;C647;110B 116A 11AE;C647;110B 116A 11AE; +C648;C648;110B 116A 11AF;C648;110B 116A 11AF; +C649;C649;110B 116A 11B0;C649;110B 116A 11B0; +C64A;C64A;110B 116A 11B1;C64A;110B 116A 11B1; +C64B;C64B;110B 116A 11B2;C64B;110B 116A 11B2; +C64C;C64C;110B 116A 11B3;C64C;110B 116A 11B3; +C64D;C64D;110B 116A 11B4;C64D;110B 116A 11B4; +C64E;C64E;110B 116A 11B5;C64E;110B 116A 11B5; +C64F;C64F;110B 116A 11B6;C64F;110B 116A 11B6; +C650;C650;110B 116A 11B7;C650;110B 116A 11B7; +C651;C651;110B 116A 11B8;C651;110B 116A 11B8; +C652;C652;110B 116A 11B9;C652;110B 116A 11B9; +C653;C653;110B 116A 11BA;C653;110B 116A 11BA; +C654;C654;110B 116A 11BB;C654;110B 116A 11BB; +C655;C655;110B 116A 11BC;C655;110B 116A 11BC; +C656;C656;110B 116A 11BD;C656;110B 116A 11BD; +C657;C657;110B 116A 11BE;C657;110B 116A 11BE; +C658;C658;110B 116A 11BF;C658;110B 116A 11BF; +C659;C659;110B 116A 11C0;C659;110B 116A 11C0; +C65A;C65A;110B 116A 11C1;C65A;110B 116A 11C1; +C65B;C65B;110B 116A 11C2;C65B;110B 116A 11C2; +C65C;C65C;110B 116B;C65C;110B 116B; +C65D;C65D;110B 116B 11A8;C65D;110B 116B 11A8; +C65E;C65E;110B 116B 11A9;C65E;110B 116B 11A9; +C65F;C65F;110B 116B 11AA;C65F;110B 116B 11AA; +C660;C660;110B 116B 11AB;C660;110B 116B 11AB; +C661;C661;110B 116B 11AC;C661;110B 116B 11AC; +C662;C662;110B 116B 11AD;C662;110B 116B 11AD; +C663;C663;110B 116B 11AE;C663;110B 116B 11AE; +C664;C664;110B 116B 11AF;C664;110B 116B 11AF; +C665;C665;110B 116B 11B0;C665;110B 116B 11B0; +C666;C666;110B 116B 11B1;C666;110B 116B 11B1; +C667;C667;110B 116B 11B2;C667;110B 116B 11B2; +C668;C668;110B 116B 11B3;C668;110B 116B 11B3; +C669;C669;110B 116B 11B4;C669;110B 116B 11B4; +C66A;C66A;110B 116B 11B5;C66A;110B 116B 11B5; +C66B;C66B;110B 116B 11B6;C66B;110B 116B 11B6; +C66C;C66C;110B 116B 11B7;C66C;110B 116B 11B7; +C66D;C66D;110B 116B 11B8;C66D;110B 116B 11B8; +C66E;C66E;110B 116B 11B9;C66E;110B 116B 11B9; +C66F;C66F;110B 116B 11BA;C66F;110B 116B 11BA; +C670;C670;110B 116B 11BB;C670;110B 116B 11BB; +C671;C671;110B 116B 11BC;C671;110B 116B 11BC; +C672;C672;110B 116B 11BD;C672;110B 116B 11BD; +C673;C673;110B 116B 11BE;C673;110B 116B 11BE; +C674;C674;110B 116B 11BF;C674;110B 116B 11BF; +C675;C675;110B 116B 11C0;C675;110B 116B 11C0; +C676;C676;110B 116B 11C1;C676;110B 116B 11C1; +C677;C677;110B 116B 11C2;C677;110B 116B 11C2; +C678;C678;110B 116C;C678;110B 116C; +C679;C679;110B 116C 11A8;C679;110B 116C 11A8; +C67A;C67A;110B 116C 11A9;C67A;110B 116C 11A9; +C67B;C67B;110B 116C 11AA;C67B;110B 116C 11AA; +C67C;C67C;110B 116C 11AB;C67C;110B 116C 11AB; +C67D;C67D;110B 116C 11AC;C67D;110B 116C 11AC; +C67E;C67E;110B 116C 11AD;C67E;110B 116C 11AD; +C67F;C67F;110B 116C 11AE;C67F;110B 116C 11AE; +C680;C680;110B 116C 11AF;C680;110B 116C 11AF; +C681;C681;110B 116C 11B0;C681;110B 116C 11B0; +C682;C682;110B 116C 11B1;C682;110B 116C 11B1; +C683;C683;110B 116C 11B2;C683;110B 116C 11B2; +C684;C684;110B 116C 11B3;C684;110B 116C 11B3; +C685;C685;110B 116C 11B4;C685;110B 116C 11B4; +C686;C686;110B 116C 11B5;C686;110B 116C 11B5; +C687;C687;110B 116C 11B6;C687;110B 116C 11B6; +C688;C688;110B 116C 11B7;C688;110B 116C 11B7; +C689;C689;110B 116C 11B8;C689;110B 116C 11B8; +C68A;C68A;110B 116C 11B9;C68A;110B 116C 11B9; +C68B;C68B;110B 116C 11BA;C68B;110B 116C 11BA; +C68C;C68C;110B 116C 11BB;C68C;110B 116C 11BB; +C68D;C68D;110B 116C 11BC;C68D;110B 116C 11BC; +C68E;C68E;110B 116C 11BD;C68E;110B 116C 11BD; +C68F;C68F;110B 116C 11BE;C68F;110B 116C 11BE; +C690;C690;110B 116C 11BF;C690;110B 116C 11BF; +C691;C691;110B 116C 11C0;C691;110B 116C 11C0; +C692;C692;110B 116C 11C1;C692;110B 116C 11C1; +C693;C693;110B 116C 11C2;C693;110B 116C 11C2; +C694;C694;110B 116D;C694;110B 116D; +C695;C695;110B 116D 11A8;C695;110B 116D 11A8; +C696;C696;110B 116D 11A9;C696;110B 116D 11A9; +C697;C697;110B 116D 11AA;C697;110B 116D 11AA; +C698;C698;110B 116D 11AB;C698;110B 116D 11AB; +C699;C699;110B 116D 11AC;C699;110B 116D 11AC; +C69A;C69A;110B 116D 11AD;C69A;110B 116D 11AD; +C69B;C69B;110B 116D 11AE;C69B;110B 116D 11AE; +C69C;C69C;110B 116D 11AF;C69C;110B 116D 11AF; +C69D;C69D;110B 116D 11B0;C69D;110B 116D 11B0; +C69E;C69E;110B 116D 11B1;C69E;110B 116D 11B1; +C69F;C69F;110B 116D 11B2;C69F;110B 116D 11B2; +C6A0;C6A0;110B 116D 11B3;C6A0;110B 116D 11B3; +C6A1;C6A1;110B 116D 11B4;C6A1;110B 116D 11B4; +C6A2;C6A2;110B 116D 11B5;C6A2;110B 116D 11B5; +C6A3;C6A3;110B 116D 11B6;C6A3;110B 116D 11B6; +C6A4;C6A4;110B 116D 11B7;C6A4;110B 116D 11B7; +C6A5;C6A5;110B 116D 11B8;C6A5;110B 116D 11B8; +C6A6;C6A6;110B 116D 11B9;C6A6;110B 116D 11B9; +C6A7;C6A7;110B 116D 11BA;C6A7;110B 116D 11BA; +C6A8;C6A8;110B 116D 11BB;C6A8;110B 116D 11BB; +C6A9;C6A9;110B 116D 11BC;C6A9;110B 116D 11BC; +C6AA;C6AA;110B 116D 11BD;C6AA;110B 116D 11BD; +C6AB;C6AB;110B 116D 11BE;C6AB;110B 116D 11BE; +C6AC;C6AC;110B 116D 11BF;C6AC;110B 116D 11BF; +C6AD;C6AD;110B 116D 11C0;C6AD;110B 116D 11C0; +C6AE;C6AE;110B 116D 11C1;C6AE;110B 116D 11C1; +C6AF;C6AF;110B 116D 11C2;C6AF;110B 116D 11C2; +C6B0;C6B0;110B 116E;C6B0;110B 116E; +C6B1;C6B1;110B 116E 11A8;C6B1;110B 116E 11A8; +C6B2;C6B2;110B 116E 11A9;C6B2;110B 116E 11A9; +C6B3;C6B3;110B 116E 11AA;C6B3;110B 116E 11AA; +C6B4;C6B4;110B 116E 11AB;C6B4;110B 116E 11AB; +C6B5;C6B5;110B 116E 11AC;C6B5;110B 116E 11AC; +C6B6;C6B6;110B 116E 11AD;C6B6;110B 116E 11AD; +C6B7;C6B7;110B 116E 11AE;C6B7;110B 116E 11AE; +C6B8;C6B8;110B 116E 11AF;C6B8;110B 116E 11AF; +C6B9;C6B9;110B 116E 11B0;C6B9;110B 116E 11B0; +C6BA;C6BA;110B 116E 11B1;C6BA;110B 116E 11B1; +C6BB;C6BB;110B 116E 11B2;C6BB;110B 116E 11B2; +C6BC;C6BC;110B 116E 11B3;C6BC;110B 116E 11B3; +C6BD;C6BD;110B 116E 11B4;C6BD;110B 116E 11B4; +C6BE;C6BE;110B 116E 11B5;C6BE;110B 116E 11B5; +C6BF;C6BF;110B 116E 11B6;C6BF;110B 116E 11B6; +C6C0;C6C0;110B 116E 11B7;C6C0;110B 116E 11B7; +C6C1;C6C1;110B 116E 11B8;C6C1;110B 116E 11B8; +C6C2;C6C2;110B 116E 11B9;C6C2;110B 116E 11B9; +C6C3;C6C3;110B 116E 11BA;C6C3;110B 116E 11BA; +C6C4;C6C4;110B 116E 11BB;C6C4;110B 116E 11BB; +C6C5;C6C5;110B 116E 11BC;C6C5;110B 116E 11BC; +C6C6;C6C6;110B 116E 11BD;C6C6;110B 116E 11BD; +C6C7;C6C7;110B 116E 11BE;C6C7;110B 116E 11BE; +C6C8;C6C8;110B 116E 11BF;C6C8;110B 116E 11BF; +C6C9;C6C9;110B 116E 11C0;C6C9;110B 116E 11C0; +C6CA;C6CA;110B 116E 11C1;C6CA;110B 116E 11C1; +C6CB;C6CB;110B 116E 11C2;C6CB;110B 116E 11C2; +C6CC;C6CC;110B 116F;C6CC;110B 116F; +C6CD;C6CD;110B 116F 11A8;C6CD;110B 116F 11A8; +C6CE;C6CE;110B 116F 11A9;C6CE;110B 116F 11A9; +C6CF;C6CF;110B 116F 11AA;C6CF;110B 116F 11AA; +C6D0;C6D0;110B 116F 11AB;C6D0;110B 116F 11AB; +C6D1;C6D1;110B 116F 11AC;C6D1;110B 116F 11AC; +C6D2;C6D2;110B 116F 11AD;C6D2;110B 116F 11AD; +C6D3;C6D3;110B 116F 11AE;C6D3;110B 116F 11AE; +C6D4;C6D4;110B 116F 11AF;C6D4;110B 116F 11AF; +C6D5;C6D5;110B 116F 11B0;C6D5;110B 116F 11B0; +C6D6;C6D6;110B 116F 11B1;C6D6;110B 116F 11B1; +C6D7;C6D7;110B 116F 11B2;C6D7;110B 116F 11B2; +C6D8;C6D8;110B 116F 11B3;C6D8;110B 116F 11B3; +C6D9;C6D9;110B 116F 11B4;C6D9;110B 116F 11B4; +C6DA;C6DA;110B 116F 11B5;C6DA;110B 116F 11B5; +C6DB;C6DB;110B 116F 11B6;C6DB;110B 116F 11B6; +C6DC;C6DC;110B 116F 11B7;C6DC;110B 116F 11B7; +C6DD;C6DD;110B 116F 11B8;C6DD;110B 116F 11B8; +C6DE;C6DE;110B 116F 11B9;C6DE;110B 116F 11B9; +C6DF;C6DF;110B 116F 11BA;C6DF;110B 116F 11BA; +C6E0;C6E0;110B 116F 11BB;C6E0;110B 116F 11BB; +C6E1;C6E1;110B 116F 11BC;C6E1;110B 116F 11BC; +C6E2;C6E2;110B 116F 11BD;C6E2;110B 116F 11BD; +C6E3;C6E3;110B 116F 11BE;C6E3;110B 116F 11BE; +C6E4;C6E4;110B 116F 11BF;C6E4;110B 116F 11BF; +C6E5;C6E5;110B 116F 11C0;C6E5;110B 116F 11C0; +C6E6;C6E6;110B 116F 11C1;C6E6;110B 116F 11C1; +C6E7;C6E7;110B 116F 11C2;C6E7;110B 116F 11C2; +C6E8;C6E8;110B 1170;C6E8;110B 1170; +C6E9;C6E9;110B 1170 11A8;C6E9;110B 1170 11A8; +C6EA;C6EA;110B 1170 11A9;C6EA;110B 1170 11A9; +C6EB;C6EB;110B 1170 11AA;C6EB;110B 1170 11AA; +C6EC;C6EC;110B 1170 11AB;C6EC;110B 1170 11AB; +C6ED;C6ED;110B 1170 11AC;C6ED;110B 1170 11AC; +C6EE;C6EE;110B 1170 11AD;C6EE;110B 1170 11AD; +C6EF;C6EF;110B 1170 11AE;C6EF;110B 1170 11AE; +C6F0;C6F0;110B 1170 11AF;C6F0;110B 1170 11AF; +C6F1;C6F1;110B 1170 11B0;C6F1;110B 1170 11B0; +C6F2;C6F2;110B 1170 11B1;C6F2;110B 1170 11B1; +C6F3;C6F3;110B 1170 11B2;C6F3;110B 1170 11B2; +C6F4;C6F4;110B 1170 11B3;C6F4;110B 1170 11B3; +C6F5;C6F5;110B 1170 11B4;C6F5;110B 1170 11B4; +C6F6;C6F6;110B 1170 11B5;C6F6;110B 1170 11B5; +C6F7;C6F7;110B 1170 11B6;C6F7;110B 1170 11B6; +C6F8;C6F8;110B 1170 11B7;C6F8;110B 1170 11B7; +C6F9;C6F9;110B 1170 11B8;C6F9;110B 1170 11B8; +C6FA;C6FA;110B 1170 11B9;C6FA;110B 1170 11B9; +C6FB;C6FB;110B 1170 11BA;C6FB;110B 1170 11BA; +C6FC;C6FC;110B 1170 11BB;C6FC;110B 1170 11BB; +C6FD;C6FD;110B 1170 11BC;C6FD;110B 1170 11BC; +C6FE;C6FE;110B 1170 11BD;C6FE;110B 1170 11BD; +C6FF;C6FF;110B 1170 11BE;C6FF;110B 1170 11BE; +C700;C700;110B 1170 11BF;C700;110B 1170 11BF; +C701;C701;110B 1170 11C0;C701;110B 1170 11C0; +C702;C702;110B 1170 11C1;C702;110B 1170 11C1; +C703;C703;110B 1170 11C2;C703;110B 1170 11C2; +C704;C704;110B 1171;C704;110B 1171; +C705;C705;110B 1171 11A8;C705;110B 1171 11A8; +C706;C706;110B 1171 11A9;C706;110B 1171 11A9; +C707;C707;110B 1171 11AA;C707;110B 1171 11AA; +C708;C708;110B 1171 11AB;C708;110B 1171 11AB; +C709;C709;110B 1171 11AC;C709;110B 1171 11AC; +C70A;C70A;110B 1171 11AD;C70A;110B 1171 11AD; +C70B;C70B;110B 1171 11AE;C70B;110B 1171 11AE; +C70C;C70C;110B 1171 11AF;C70C;110B 1171 11AF; +C70D;C70D;110B 1171 11B0;C70D;110B 1171 11B0; +C70E;C70E;110B 1171 11B1;C70E;110B 1171 11B1; +C70F;C70F;110B 1171 11B2;C70F;110B 1171 11B2; +C710;C710;110B 1171 11B3;C710;110B 1171 11B3; +C711;C711;110B 1171 11B4;C711;110B 1171 11B4; +C712;C712;110B 1171 11B5;C712;110B 1171 11B5; +C713;C713;110B 1171 11B6;C713;110B 1171 11B6; +C714;C714;110B 1171 11B7;C714;110B 1171 11B7; +C715;C715;110B 1171 11B8;C715;110B 1171 11B8; +C716;C716;110B 1171 11B9;C716;110B 1171 11B9; +C717;C717;110B 1171 11BA;C717;110B 1171 11BA; +C718;C718;110B 1171 11BB;C718;110B 1171 11BB; +C719;C719;110B 1171 11BC;C719;110B 1171 11BC; +C71A;C71A;110B 1171 11BD;C71A;110B 1171 11BD; +C71B;C71B;110B 1171 11BE;C71B;110B 1171 11BE; +C71C;C71C;110B 1171 11BF;C71C;110B 1171 11BF; +C71D;C71D;110B 1171 11C0;C71D;110B 1171 11C0; +C71E;C71E;110B 1171 11C1;C71E;110B 1171 11C1; +C71F;C71F;110B 1171 11C2;C71F;110B 1171 11C2; +C720;C720;110B 1172;C720;110B 1172; +C721;C721;110B 1172 11A8;C721;110B 1172 11A8; +C722;C722;110B 1172 11A9;C722;110B 1172 11A9; +C723;C723;110B 1172 11AA;C723;110B 1172 11AA; +C724;C724;110B 1172 11AB;C724;110B 1172 11AB; +C725;C725;110B 1172 11AC;C725;110B 1172 11AC; +C726;C726;110B 1172 11AD;C726;110B 1172 11AD; +C727;C727;110B 1172 11AE;C727;110B 1172 11AE; +C728;C728;110B 1172 11AF;C728;110B 1172 11AF; +C729;C729;110B 1172 11B0;C729;110B 1172 11B0; +C72A;C72A;110B 1172 11B1;C72A;110B 1172 11B1; +C72B;C72B;110B 1172 11B2;C72B;110B 1172 11B2; +C72C;C72C;110B 1172 11B3;C72C;110B 1172 11B3; +C72D;C72D;110B 1172 11B4;C72D;110B 1172 11B4; +C72E;C72E;110B 1172 11B5;C72E;110B 1172 11B5; +C72F;C72F;110B 1172 11B6;C72F;110B 1172 11B6; +C730;C730;110B 1172 11B7;C730;110B 1172 11B7; +C731;C731;110B 1172 11B8;C731;110B 1172 11B8; +C732;C732;110B 1172 11B9;C732;110B 1172 11B9; +C733;C733;110B 1172 11BA;C733;110B 1172 11BA; +C734;C734;110B 1172 11BB;C734;110B 1172 11BB; +C735;C735;110B 1172 11BC;C735;110B 1172 11BC; +C736;C736;110B 1172 11BD;C736;110B 1172 11BD; +C737;C737;110B 1172 11BE;C737;110B 1172 11BE; +C738;C738;110B 1172 11BF;C738;110B 1172 11BF; +C739;C739;110B 1172 11C0;C739;110B 1172 11C0; +C73A;C73A;110B 1172 11C1;C73A;110B 1172 11C1; +C73B;C73B;110B 1172 11C2;C73B;110B 1172 11C2; +C73C;C73C;110B 1173;C73C;110B 1173; +C73D;C73D;110B 1173 11A8;C73D;110B 1173 11A8; +C73E;C73E;110B 1173 11A9;C73E;110B 1173 11A9; +C73F;C73F;110B 1173 11AA;C73F;110B 1173 11AA; +C740;C740;110B 1173 11AB;C740;110B 1173 11AB; +C741;C741;110B 1173 11AC;C741;110B 1173 11AC; +C742;C742;110B 1173 11AD;C742;110B 1173 11AD; +C743;C743;110B 1173 11AE;C743;110B 1173 11AE; +C744;C744;110B 1173 11AF;C744;110B 1173 11AF; +C745;C745;110B 1173 11B0;C745;110B 1173 11B0; +C746;C746;110B 1173 11B1;C746;110B 1173 11B1; +C747;C747;110B 1173 11B2;C747;110B 1173 11B2; +C748;C748;110B 1173 11B3;C748;110B 1173 11B3; +C749;C749;110B 1173 11B4;C749;110B 1173 11B4; +C74A;C74A;110B 1173 11B5;C74A;110B 1173 11B5; +C74B;C74B;110B 1173 11B6;C74B;110B 1173 11B6; +C74C;C74C;110B 1173 11B7;C74C;110B 1173 11B7; +C74D;C74D;110B 1173 11B8;C74D;110B 1173 11B8; +C74E;C74E;110B 1173 11B9;C74E;110B 1173 11B9; +C74F;C74F;110B 1173 11BA;C74F;110B 1173 11BA; +C750;C750;110B 1173 11BB;C750;110B 1173 11BB; +C751;C751;110B 1173 11BC;C751;110B 1173 11BC; +C752;C752;110B 1173 11BD;C752;110B 1173 11BD; +C753;C753;110B 1173 11BE;C753;110B 1173 11BE; +C754;C754;110B 1173 11BF;C754;110B 1173 11BF; +C755;C755;110B 1173 11C0;C755;110B 1173 11C0; +C756;C756;110B 1173 11C1;C756;110B 1173 11C1; +C757;C757;110B 1173 11C2;C757;110B 1173 11C2; +C758;C758;110B 1174;C758;110B 1174; +C759;C759;110B 1174 11A8;C759;110B 1174 11A8; +C75A;C75A;110B 1174 11A9;C75A;110B 1174 11A9; +C75B;C75B;110B 1174 11AA;C75B;110B 1174 11AA; +C75C;C75C;110B 1174 11AB;C75C;110B 1174 11AB; +C75D;C75D;110B 1174 11AC;C75D;110B 1174 11AC; +C75E;C75E;110B 1174 11AD;C75E;110B 1174 11AD; +C75F;C75F;110B 1174 11AE;C75F;110B 1174 11AE; +C760;C760;110B 1174 11AF;C760;110B 1174 11AF; +C761;C761;110B 1174 11B0;C761;110B 1174 11B0; +C762;C762;110B 1174 11B1;C762;110B 1174 11B1; +C763;C763;110B 1174 11B2;C763;110B 1174 11B2; +C764;C764;110B 1174 11B3;C764;110B 1174 11B3; +C765;C765;110B 1174 11B4;C765;110B 1174 11B4; +C766;C766;110B 1174 11B5;C766;110B 1174 11B5; +C767;C767;110B 1174 11B6;C767;110B 1174 11B6; +C768;C768;110B 1174 11B7;C768;110B 1174 11B7; +C769;C769;110B 1174 11B8;C769;110B 1174 11B8; +C76A;C76A;110B 1174 11B9;C76A;110B 1174 11B9; +C76B;C76B;110B 1174 11BA;C76B;110B 1174 11BA; +C76C;C76C;110B 1174 11BB;C76C;110B 1174 11BB; +C76D;C76D;110B 1174 11BC;C76D;110B 1174 11BC; +C76E;C76E;110B 1174 11BD;C76E;110B 1174 11BD; +C76F;C76F;110B 1174 11BE;C76F;110B 1174 11BE; +C770;C770;110B 1174 11BF;C770;110B 1174 11BF; +C771;C771;110B 1174 11C0;C771;110B 1174 11C0; +C772;C772;110B 1174 11C1;C772;110B 1174 11C1; +C773;C773;110B 1174 11C2;C773;110B 1174 11C2; +C774;C774;110B 1175;C774;110B 1175; +C775;C775;110B 1175 11A8;C775;110B 1175 11A8; +C776;C776;110B 1175 11A9;C776;110B 1175 11A9; +C777;C777;110B 1175 11AA;C777;110B 1175 11AA; +C778;C778;110B 1175 11AB;C778;110B 1175 11AB; +C779;C779;110B 1175 11AC;C779;110B 1175 11AC; +C77A;C77A;110B 1175 11AD;C77A;110B 1175 11AD; +C77B;C77B;110B 1175 11AE;C77B;110B 1175 11AE; +C77C;C77C;110B 1175 11AF;C77C;110B 1175 11AF; +C77D;C77D;110B 1175 11B0;C77D;110B 1175 11B0; +C77E;C77E;110B 1175 11B1;C77E;110B 1175 11B1; +C77F;C77F;110B 1175 11B2;C77F;110B 1175 11B2; +C780;C780;110B 1175 11B3;C780;110B 1175 11B3; +C781;C781;110B 1175 11B4;C781;110B 1175 11B4; +C782;C782;110B 1175 11B5;C782;110B 1175 11B5; +C783;C783;110B 1175 11B6;C783;110B 1175 11B6; +C784;C784;110B 1175 11B7;C784;110B 1175 11B7; +C785;C785;110B 1175 11B8;C785;110B 1175 11B8; +C786;C786;110B 1175 11B9;C786;110B 1175 11B9; +C787;C787;110B 1175 11BA;C787;110B 1175 11BA; +C788;C788;110B 1175 11BB;C788;110B 1175 11BB; +C789;C789;110B 1175 11BC;C789;110B 1175 11BC; +C78A;C78A;110B 1175 11BD;C78A;110B 1175 11BD; +C78B;C78B;110B 1175 11BE;C78B;110B 1175 11BE; +C78C;C78C;110B 1175 11BF;C78C;110B 1175 11BF; +C78D;C78D;110B 1175 11C0;C78D;110B 1175 11C0; +C78E;C78E;110B 1175 11C1;C78E;110B 1175 11C1; +C78F;C78F;110B 1175 11C2;C78F;110B 1175 11C2; +C790;C790;110C 1161;C790;110C 1161; +C791;C791;110C 1161 11A8;C791;110C 1161 11A8; +C792;C792;110C 1161 11A9;C792;110C 1161 11A9; +C793;C793;110C 1161 11AA;C793;110C 1161 11AA; +C794;C794;110C 1161 11AB;C794;110C 1161 11AB; +C795;C795;110C 1161 11AC;C795;110C 1161 11AC; +C796;C796;110C 1161 11AD;C796;110C 1161 11AD; +C797;C797;110C 1161 11AE;C797;110C 1161 11AE; +C798;C798;110C 1161 11AF;C798;110C 1161 11AF; +C799;C799;110C 1161 11B0;C799;110C 1161 11B0; +C79A;C79A;110C 1161 11B1;C79A;110C 1161 11B1; +C79B;C79B;110C 1161 11B2;C79B;110C 1161 11B2; +C79C;C79C;110C 1161 11B3;C79C;110C 1161 11B3; +C79D;C79D;110C 1161 11B4;C79D;110C 1161 11B4; +C79E;C79E;110C 1161 11B5;C79E;110C 1161 11B5; +C79F;C79F;110C 1161 11B6;C79F;110C 1161 11B6; +C7A0;C7A0;110C 1161 11B7;C7A0;110C 1161 11B7; +C7A1;C7A1;110C 1161 11B8;C7A1;110C 1161 11B8; +C7A2;C7A2;110C 1161 11B9;C7A2;110C 1161 11B9; +C7A3;C7A3;110C 1161 11BA;C7A3;110C 1161 11BA; +C7A4;C7A4;110C 1161 11BB;C7A4;110C 1161 11BB; +C7A5;C7A5;110C 1161 11BC;C7A5;110C 1161 11BC; +C7A6;C7A6;110C 1161 11BD;C7A6;110C 1161 11BD; +C7A7;C7A7;110C 1161 11BE;C7A7;110C 1161 11BE; +C7A8;C7A8;110C 1161 11BF;C7A8;110C 1161 11BF; +C7A9;C7A9;110C 1161 11C0;C7A9;110C 1161 11C0; +C7AA;C7AA;110C 1161 11C1;C7AA;110C 1161 11C1; +C7AB;C7AB;110C 1161 11C2;C7AB;110C 1161 11C2; +C7AC;C7AC;110C 1162;C7AC;110C 1162; +C7AD;C7AD;110C 1162 11A8;C7AD;110C 1162 11A8; +C7AE;C7AE;110C 1162 11A9;C7AE;110C 1162 11A9; +C7AF;C7AF;110C 1162 11AA;C7AF;110C 1162 11AA; +C7B0;C7B0;110C 1162 11AB;C7B0;110C 1162 11AB; +C7B1;C7B1;110C 1162 11AC;C7B1;110C 1162 11AC; +C7B2;C7B2;110C 1162 11AD;C7B2;110C 1162 11AD; +C7B3;C7B3;110C 1162 11AE;C7B3;110C 1162 11AE; +C7B4;C7B4;110C 1162 11AF;C7B4;110C 1162 11AF; +C7B5;C7B5;110C 1162 11B0;C7B5;110C 1162 11B0; +C7B6;C7B6;110C 1162 11B1;C7B6;110C 1162 11B1; +C7B7;C7B7;110C 1162 11B2;C7B7;110C 1162 11B2; +C7B8;C7B8;110C 1162 11B3;C7B8;110C 1162 11B3; +C7B9;C7B9;110C 1162 11B4;C7B9;110C 1162 11B4; +C7BA;C7BA;110C 1162 11B5;C7BA;110C 1162 11B5; +C7BB;C7BB;110C 1162 11B6;C7BB;110C 1162 11B6; +C7BC;C7BC;110C 1162 11B7;C7BC;110C 1162 11B7; +C7BD;C7BD;110C 1162 11B8;C7BD;110C 1162 11B8; +C7BE;C7BE;110C 1162 11B9;C7BE;110C 1162 11B9; +C7BF;C7BF;110C 1162 11BA;C7BF;110C 1162 11BA; +C7C0;C7C0;110C 1162 11BB;C7C0;110C 1162 11BB; +C7C1;C7C1;110C 1162 11BC;C7C1;110C 1162 11BC; +C7C2;C7C2;110C 1162 11BD;C7C2;110C 1162 11BD; +C7C3;C7C3;110C 1162 11BE;C7C3;110C 1162 11BE; +C7C4;C7C4;110C 1162 11BF;C7C4;110C 1162 11BF; +C7C5;C7C5;110C 1162 11C0;C7C5;110C 1162 11C0; +C7C6;C7C6;110C 1162 11C1;C7C6;110C 1162 11C1; +C7C7;C7C7;110C 1162 11C2;C7C7;110C 1162 11C2; +C7C8;C7C8;110C 1163;C7C8;110C 1163; +C7C9;C7C9;110C 1163 11A8;C7C9;110C 1163 11A8; +C7CA;C7CA;110C 1163 11A9;C7CA;110C 1163 11A9; +C7CB;C7CB;110C 1163 11AA;C7CB;110C 1163 11AA; +C7CC;C7CC;110C 1163 11AB;C7CC;110C 1163 11AB; +C7CD;C7CD;110C 1163 11AC;C7CD;110C 1163 11AC; +C7CE;C7CE;110C 1163 11AD;C7CE;110C 1163 11AD; +C7CF;C7CF;110C 1163 11AE;C7CF;110C 1163 11AE; +C7D0;C7D0;110C 1163 11AF;C7D0;110C 1163 11AF; +C7D1;C7D1;110C 1163 11B0;C7D1;110C 1163 11B0; +C7D2;C7D2;110C 1163 11B1;C7D2;110C 1163 11B1; +C7D3;C7D3;110C 1163 11B2;C7D3;110C 1163 11B2; +C7D4;C7D4;110C 1163 11B3;C7D4;110C 1163 11B3; +C7D5;C7D5;110C 1163 11B4;C7D5;110C 1163 11B4; +C7D6;C7D6;110C 1163 11B5;C7D6;110C 1163 11B5; +C7D7;C7D7;110C 1163 11B6;C7D7;110C 1163 11B6; +C7D8;C7D8;110C 1163 11B7;C7D8;110C 1163 11B7; +C7D9;C7D9;110C 1163 11B8;C7D9;110C 1163 11B8; +C7DA;C7DA;110C 1163 11B9;C7DA;110C 1163 11B9; +C7DB;C7DB;110C 1163 11BA;C7DB;110C 1163 11BA; +C7DC;C7DC;110C 1163 11BB;C7DC;110C 1163 11BB; +C7DD;C7DD;110C 1163 11BC;C7DD;110C 1163 11BC; +C7DE;C7DE;110C 1163 11BD;C7DE;110C 1163 11BD; +C7DF;C7DF;110C 1163 11BE;C7DF;110C 1163 11BE; +C7E0;C7E0;110C 1163 11BF;C7E0;110C 1163 11BF; +C7E1;C7E1;110C 1163 11C0;C7E1;110C 1163 11C0; +C7E2;C7E2;110C 1163 11C1;C7E2;110C 1163 11C1; +C7E3;C7E3;110C 1163 11C2;C7E3;110C 1163 11C2; +C7E4;C7E4;110C 1164;C7E4;110C 1164; +C7E5;C7E5;110C 1164 11A8;C7E5;110C 1164 11A8; +C7E6;C7E6;110C 1164 11A9;C7E6;110C 1164 11A9; +C7E7;C7E7;110C 1164 11AA;C7E7;110C 1164 11AA; +C7E8;C7E8;110C 1164 11AB;C7E8;110C 1164 11AB; +C7E9;C7E9;110C 1164 11AC;C7E9;110C 1164 11AC; +C7EA;C7EA;110C 1164 11AD;C7EA;110C 1164 11AD; +C7EB;C7EB;110C 1164 11AE;C7EB;110C 1164 11AE; +C7EC;C7EC;110C 1164 11AF;C7EC;110C 1164 11AF; +C7ED;C7ED;110C 1164 11B0;C7ED;110C 1164 11B0; +C7EE;C7EE;110C 1164 11B1;C7EE;110C 1164 11B1; +C7EF;C7EF;110C 1164 11B2;C7EF;110C 1164 11B2; +C7F0;C7F0;110C 1164 11B3;C7F0;110C 1164 11B3; +C7F1;C7F1;110C 1164 11B4;C7F1;110C 1164 11B4; +C7F2;C7F2;110C 1164 11B5;C7F2;110C 1164 11B5; +C7F3;C7F3;110C 1164 11B6;C7F3;110C 1164 11B6; +C7F4;C7F4;110C 1164 11B7;C7F4;110C 1164 11B7; +C7F5;C7F5;110C 1164 11B8;C7F5;110C 1164 11B8; +C7F6;C7F6;110C 1164 11B9;C7F6;110C 1164 11B9; +C7F7;C7F7;110C 1164 11BA;C7F7;110C 1164 11BA; +C7F8;C7F8;110C 1164 11BB;C7F8;110C 1164 11BB; +C7F9;C7F9;110C 1164 11BC;C7F9;110C 1164 11BC; +C7FA;C7FA;110C 1164 11BD;C7FA;110C 1164 11BD; +C7FB;C7FB;110C 1164 11BE;C7FB;110C 1164 11BE; +C7FC;C7FC;110C 1164 11BF;C7FC;110C 1164 11BF; +C7FD;C7FD;110C 1164 11C0;C7FD;110C 1164 11C0; +C7FE;C7FE;110C 1164 11C1;C7FE;110C 1164 11C1; +C7FF;C7FF;110C 1164 11C2;C7FF;110C 1164 11C2; +C800;C800;110C 1165;C800;110C 1165; +C801;C801;110C 1165 11A8;C801;110C 1165 11A8; +C802;C802;110C 1165 11A9;C802;110C 1165 11A9; +C803;C803;110C 1165 11AA;C803;110C 1165 11AA; +C804;C804;110C 1165 11AB;C804;110C 1165 11AB; +C805;C805;110C 1165 11AC;C805;110C 1165 11AC; +C806;C806;110C 1165 11AD;C806;110C 1165 11AD; +C807;C807;110C 1165 11AE;C807;110C 1165 11AE; +C808;C808;110C 1165 11AF;C808;110C 1165 11AF; +C809;C809;110C 1165 11B0;C809;110C 1165 11B0; +C80A;C80A;110C 1165 11B1;C80A;110C 1165 11B1; +C80B;C80B;110C 1165 11B2;C80B;110C 1165 11B2; +C80C;C80C;110C 1165 11B3;C80C;110C 1165 11B3; +C80D;C80D;110C 1165 11B4;C80D;110C 1165 11B4; +C80E;C80E;110C 1165 11B5;C80E;110C 1165 11B5; +C80F;C80F;110C 1165 11B6;C80F;110C 1165 11B6; +C810;C810;110C 1165 11B7;C810;110C 1165 11B7; +C811;C811;110C 1165 11B8;C811;110C 1165 11B8; +C812;C812;110C 1165 11B9;C812;110C 1165 11B9; +C813;C813;110C 1165 11BA;C813;110C 1165 11BA; +C814;C814;110C 1165 11BB;C814;110C 1165 11BB; +C815;C815;110C 1165 11BC;C815;110C 1165 11BC; +C816;C816;110C 1165 11BD;C816;110C 1165 11BD; +C817;C817;110C 1165 11BE;C817;110C 1165 11BE; +C818;C818;110C 1165 11BF;C818;110C 1165 11BF; +C819;C819;110C 1165 11C0;C819;110C 1165 11C0; +C81A;C81A;110C 1165 11C1;C81A;110C 1165 11C1; +C81B;C81B;110C 1165 11C2;C81B;110C 1165 11C2; +C81C;C81C;110C 1166;C81C;110C 1166; +C81D;C81D;110C 1166 11A8;C81D;110C 1166 11A8; +C81E;C81E;110C 1166 11A9;C81E;110C 1166 11A9; +C81F;C81F;110C 1166 11AA;C81F;110C 1166 11AA; +C820;C820;110C 1166 11AB;C820;110C 1166 11AB; +C821;C821;110C 1166 11AC;C821;110C 1166 11AC; +C822;C822;110C 1166 11AD;C822;110C 1166 11AD; +C823;C823;110C 1166 11AE;C823;110C 1166 11AE; +C824;C824;110C 1166 11AF;C824;110C 1166 11AF; +C825;C825;110C 1166 11B0;C825;110C 1166 11B0; +C826;C826;110C 1166 11B1;C826;110C 1166 11B1; +C827;C827;110C 1166 11B2;C827;110C 1166 11B2; +C828;C828;110C 1166 11B3;C828;110C 1166 11B3; +C829;C829;110C 1166 11B4;C829;110C 1166 11B4; +C82A;C82A;110C 1166 11B5;C82A;110C 1166 11B5; +C82B;C82B;110C 1166 11B6;C82B;110C 1166 11B6; +C82C;C82C;110C 1166 11B7;C82C;110C 1166 11B7; +C82D;C82D;110C 1166 11B8;C82D;110C 1166 11B8; +C82E;C82E;110C 1166 11B9;C82E;110C 1166 11B9; +C82F;C82F;110C 1166 11BA;C82F;110C 1166 11BA; +C830;C830;110C 1166 11BB;C830;110C 1166 11BB; +C831;C831;110C 1166 11BC;C831;110C 1166 11BC; +C832;C832;110C 1166 11BD;C832;110C 1166 11BD; +C833;C833;110C 1166 11BE;C833;110C 1166 11BE; +C834;C834;110C 1166 11BF;C834;110C 1166 11BF; +C835;C835;110C 1166 11C0;C835;110C 1166 11C0; +C836;C836;110C 1166 11C1;C836;110C 1166 11C1; +C837;C837;110C 1166 11C2;C837;110C 1166 11C2; +C838;C838;110C 1167;C838;110C 1167; +C839;C839;110C 1167 11A8;C839;110C 1167 11A8; +C83A;C83A;110C 1167 11A9;C83A;110C 1167 11A9; +C83B;C83B;110C 1167 11AA;C83B;110C 1167 11AA; +C83C;C83C;110C 1167 11AB;C83C;110C 1167 11AB; +C83D;C83D;110C 1167 11AC;C83D;110C 1167 11AC; +C83E;C83E;110C 1167 11AD;C83E;110C 1167 11AD; +C83F;C83F;110C 1167 11AE;C83F;110C 1167 11AE; +C840;C840;110C 1167 11AF;C840;110C 1167 11AF; +C841;C841;110C 1167 11B0;C841;110C 1167 11B0; +C842;C842;110C 1167 11B1;C842;110C 1167 11B1; +C843;C843;110C 1167 11B2;C843;110C 1167 11B2; +C844;C844;110C 1167 11B3;C844;110C 1167 11B3; +C845;C845;110C 1167 11B4;C845;110C 1167 11B4; +C846;C846;110C 1167 11B5;C846;110C 1167 11B5; +C847;C847;110C 1167 11B6;C847;110C 1167 11B6; +C848;C848;110C 1167 11B7;C848;110C 1167 11B7; +C849;C849;110C 1167 11B8;C849;110C 1167 11B8; +C84A;C84A;110C 1167 11B9;C84A;110C 1167 11B9; +C84B;C84B;110C 1167 11BA;C84B;110C 1167 11BA; +C84C;C84C;110C 1167 11BB;C84C;110C 1167 11BB; +C84D;C84D;110C 1167 11BC;C84D;110C 1167 11BC; +C84E;C84E;110C 1167 11BD;C84E;110C 1167 11BD; +C84F;C84F;110C 1167 11BE;C84F;110C 1167 11BE; +C850;C850;110C 1167 11BF;C850;110C 1167 11BF; +C851;C851;110C 1167 11C0;C851;110C 1167 11C0; +C852;C852;110C 1167 11C1;C852;110C 1167 11C1; +C853;C853;110C 1167 11C2;C853;110C 1167 11C2; +C854;C854;110C 1168;C854;110C 1168; +C855;C855;110C 1168 11A8;C855;110C 1168 11A8; +C856;C856;110C 1168 11A9;C856;110C 1168 11A9; +C857;C857;110C 1168 11AA;C857;110C 1168 11AA; +C858;C858;110C 1168 11AB;C858;110C 1168 11AB; +C859;C859;110C 1168 11AC;C859;110C 1168 11AC; +C85A;C85A;110C 1168 11AD;C85A;110C 1168 11AD; +C85B;C85B;110C 1168 11AE;C85B;110C 1168 11AE; +C85C;C85C;110C 1168 11AF;C85C;110C 1168 11AF; +C85D;C85D;110C 1168 11B0;C85D;110C 1168 11B0; +C85E;C85E;110C 1168 11B1;C85E;110C 1168 11B1; +C85F;C85F;110C 1168 11B2;C85F;110C 1168 11B2; +C860;C860;110C 1168 11B3;C860;110C 1168 11B3; +C861;C861;110C 1168 11B4;C861;110C 1168 11B4; +C862;C862;110C 1168 11B5;C862;110C 1168 11B5; +C863;C863;110C 1168 11B6;C863;110C 1168 11B6; +C864;C864;110C 1168 11B7;C864;110C 1168 11B7; +C865;C865;110C 1168 11B8;C865;110C 1168 11B8; +C866;C866;110C 1168 11B9;C866;110C 1168 11B9; +C867;C867;110C 1168 11BA;C867;110C 1168 11BA; +C868;C868;110C 1168 11BB;C868;110C 1168 11BB; +C869;C869;110C 1168 11BC;C869;110C 1168 11BC; +C86A;C86A;110C 1168 11BD;C86A;110C 1168 11BD; +C86B;C86B;110C 1168 11BE;C86B;110C 1168 11BE; +C86C;C86C;110C 1168 11BF;C86C;110C 1168 11BF; +C86D;C86D;110C 1168 11C0;C86D;110C 1168 11C0; +C86E;C86E;110C 1168 11C1;C86E;110C 1168 11C1; +C86F;C86F;110C 1168 11C2;C86F;110C 1168 11C2; +C870;C870;110C 1169;C870;110C 1169; +C871;C871;110C 1169 11A8;C871;110C 1169 11A8; +C872;C872;110C 1169 11A9;C872;110C 1169 11A9; +C873;C873;110C 1169 11AA;C873;110C 1169 11AA; +C874;C874;110C 1169 11AB;C874;110C 1169 11AB; +C875;C875;110C 1169 11AC;C875;110C 1169 11AC; +C876;C876;110C 1169 11AD;C876;110C 1169 11AD; +C877;C877;110C 1169 11AE;C877;110C 1169 11AE; +C878;C878;110C 1169 11AF;C878;110C 1169 11AF; +C879;C879;110C 1169 11B0;C879;110C 1169 11B0; +C87A;C87A;110C 1169 11B1;C87A;110C 1169 11B1; +C87B;C87B;110C 1169 11B2;C87B;110C 1169 11B2; +C87C;C87C;110C 1169 11B3;C87C;110C 1169 11B3; +C87D;C87D;110C 1169 11B4;C87D;110C 1169 11B4; +C87E;C87E;110C 1169 11B5;C87E;110C 1169 11B5; +C87F;C87F;110C 1169 11B6;C87F;110C 1169 11B6; +C880;C880;110C 1169 11B7;C880;110C 1169 11B7; +C881;C881;110C 1169 11B8;C881;110C 1169 11B8; +C882;C882;110C 1169 11B9;C882;110C 1169 11B9; +C883;C883;110C 1169 11BA;C883;110C 1169 11BA; +C884;C884;110C 1169 11BB;C884;110C 1169 11BB; +C885;C885;110C 1169 11BC;C885;110C 1169 11BC; +C886;C886;110C 1169 11BD;C886;110C 1169 11BD; +C887;C887;110C 1169 11BE;C887;110C 1169 11BE; +C888;C888;110C 1169 11BF;C888;110C 1169 11BF; +C889;C889;110C 1169 11C0;C889;110C 1169 11C0; +C88A;C88A;110C 1169 11C1;C88A;110C 1169 11C1; +C88B;C88B;110C 1169 11C2;C88B;110C 1169 11C2; +C88C;C88C;110C 116A;C88C;110C 116A; +C88D;C88D;110C 116A 11A8;C88D;110C 116A 11A8; +C88E;C88E;110C 116A 11A9;C88E;110C 116A 11A9; +C88F;C88F;110C 116A 11AA;C88F;110C 116A 11AA; +C890;C890;110C 116A 11AB;C890;110C 116A 11AB; +C891;C891;110C 116A 11AC;C891;110C 116A 11AC; +C892;C892;110C 116A 11AD;C892;110C 116A 11AD; +C893;C893;110C 116A 11AE;C893;110C 116A 11AE; +C894;C894;110C 116A 11AF;C894;110C 116A 11AF; +C895;C895;110C 116A 11B0;C895;110C 116A 11B0; +C896;C896;110C 116A 11B1;C896;110C 116A 11B1; +C897;C897;110C 116A 11B2;C897;110C 116A 11B2; +C898;C898;110C 116A 11B3;C898;110C 116A 11B3; +C899;C899;110C 116A 11B4;C899;110C 116A 11B4; +C89A;C89A;110C 116A 11B5;C89A;110C 116A 11B5; +C89B;C89B;110C 116A 11B6;C89B;110C 116A 11B6; +C89C;C89C;110C 116A 11B7;C89C;110C 116A 11B7; +C89D;C89D;110C 116A 11B8;C89D;110C 116A 11B8; +C89E;C89E;110C 116A 11B9;C89E;110C 116A 11B9; +C89F;C89F;110C 116A 11BA;C89F;110C 116A 11BA; +C8A0;C8A0;110C 116A 11BB;C8A0;110C 116A 11BB; +C8A1;C8A1;110C 116A 11BC;C8A1;110C 116A 11BC; +C8A2;C8A2;110C 116A 11BD;C8A2;110C 116A 11BD; +C8A3;C8A3;110C 116A 11BE;C8A3;110C 116A 11BE; +C8A4;C8A4;110C 116A 11BF;C8A4;110C 116A 11BF; +C8A5;C8A5;110C 116A 11C0;C8A5;110C 116A 11C0; +C8A6;C8A6;110C 116A 11C1;C8A6;110C 116A 11C1; +C8A7;C8A7;110C 116A 11C2;C8A7;110C 116A 11C2; +C8A8;C8A8;110C 116B;C8A8;110C 116B; +C8A9;C8A9;110C 116B 11A8;C8A9;110C 116B 11A8; +C8AA;C8AA;110C 116B 11A9;C8AA;110C 116B 11A9; +C8AB;C8AB;110C 116B 11AA;C8AB;110C 116B 11AA; +C8AC;C8AC;110C 116B 11AB;C8AC;110C 116B 11AB; +C8AD;C8AD;110C 116B 11AC;C8AD;110C 116B 11AC; +C8AE;C8AE;110C 116B 11AD;C8AE;110C 116B 11AD; +C8AF;C8AF;110C 116B 11AE;C8AF;110C 116B 11AE; +C8B0;C8B0;110C 116B 11AF;C8B0;110C 116B 11AF; +C8B1;C8B1;110C 116B 11B0;C8B1;110C 116B 11B0; +C8B2;C8B2;110C 116B 11B1;C8B2;110C 116B 11B1; +C8B3;C8B3;110C 116B 11B2;C8B3;110C 116B 11B2; +C8B4;C8B4;110C 116B 11B3;C8B4;110C 116B 11B3; +C8B5;C8B5;110C 116B 11B4;C8B5;110C 116B 11B4; +C8B6;C8B6;110C 116B 11B5;C8B6;110C 116B 11B5; +C8B7;C8B7;110C 116B 11B6;C8B7;110C 116B 11B6; +C8B8;C8B8;110C 116B 11B7;C8B8;110C 116B 11B7; +C8B9;C8B9;110C 116B 11B8;C8B9;110C 116B 11B8; +C8BA;C8BA;110C 116B 11B9;C8BA;110C 116B 11B9; +C8BB;C8BB;110C 116B 11BA;C8BB;110C 116B 11BA; +C8BC;C8BC;110C 116B 11BB;C8BC;110C 116B 11BB; +C8BD;C8BD;110C 116B 11BC;C8BD;110C 116B 11BC; +C8BE;C8BE;110C 116B 11BD;C8BE;110C 116B 11BD; +C8BF;C8BF;110C 116B 11BE;C8BF;110C 116B 11BE; +C8C0;C8C0;110C 116B 11BF;C8C0;110C 116B 11BF; +C8C1;C8C1;110C 116B 11C0;C8C1;110C 116B 11C0; +C8C2;C8C2;110C 116B 11C1;C8C2;110C 116B 11C1; +C8C3;C8C3;110C 116B 11C2;C8C3;110C 116B 11C2; +C8C4;C8C4;110C 116C;C8C4;110C 116C; +C8C5;C8C5;110C 116C 11A8;C8C5;110C 116C 11A8; +C8C6;C8C6;110C 116C 11A9;C8C6;110C 116C 11A9; +C8C7;C8C7;110C 116C 11AA;C8C7;110C 116C 11AA; +C8C8;C8C8;110C 116C 11AB;C8C8;110C 116C 11AB; +C8C9;C8C9;110C 116C 11AC;C8C9;110C 116C 11AC; +C8CA;C8CA;110C 116C 11AD;C8CA;110C 116C 11AD; +C8CB;C8CB;110C 116C 11AE;C8CB;110C 116C 11AE; +C8CC;C8CC;110C 116C 11AF;C8CC;110C 116C 11AF; +C8CD;C8CD;110C 116C 11B0;C8CD;110C 116C 11B0; +C8CE;C8CE;110C 116C 11B1;C8CE;110C 116C 11B1; +C8CF;C8CF;110C 116C 11B2;C8CF;110C 116C 11B2; +C8D0;C8D0;110C 116C 11B3;C8D0;110C 116C 11B3; +C8D1;C8D1;110C 116C 11B4;C8D1;110C 116C 11B4; +C8D2;C8D2;110C 116C 11B5;C8D2;110C 116C 11B5; +C8D3;C8D3;110C 116C 11B6;C8D3;110C 116C 11B6; +C8D4;C8D4;110C 116C 11B7;C8D4;110C 116C 11B7; +C8D5;C8D5;110C 116C 11B8;C8D5;110C 116C 11B8; +C8D6;C8D6;110C 116C 11B9;C8D6;110C 116C 11B9; +C8D7;C8D7;110C 116C 11BA;C8D7;110C 116C 11BA; +C8D8;C8D8;110C 116C 11BB;C8D8;110C 116C 11BB; +C8D9;C8D9;110C 116C 11BC;C8D9;110C 116C 11BC; +C8DA;C8DA;110C 116C 11BD;C8DA;110C 116C 11BD; +C8DB;C8DB;110C 116C 11BE;C8DB;110C 116C 11BE; +C8DC;C8DC;110C 116C 11BF;C8DC;110C 116C 11BF; +C8DD;C8DD;110C 116C 11C0;C8DD;110C 116C 11C0; +C8DE;C8DE;110C 116C 11C1;C8DE;110C 116C 11C1; +C8DF;C8DF;110C 116C 11C2;C8DF;110C 116C 11C2; +C8E0;C8E0;110C 116D;C8E0;110C 116D; +C8E1;C8E1;110C 116D 11A8;C8E1;110C 116D 11A8; +C8E2;C8E2;110C 116D 11A9;C8E2;110C 116D 11A9; +C8E3;C8E3;110C 116D 11AA;C8E3;110C 116D 11AA; +C8E4;C8E4;110C 116D 11AB;C8E4;110C 116D 11AB; +C8E5;C8E5;110C 116D 11AC;C8E5;110C 116D 11AC; +C8E6;C8E6;110C 116D 11AD;C8E6;110C 116D 11AD; +C8E7;C8E7;110C 116D 11AE;C8E7;110C 116D 11AE; +C8E8;C8E8;110C 116D 11AF;C8E8;110C 116D 11AF; +C8E9;C8E9;110C 116D 11B0;C8E9;110C 116D 11B0; +C8EA;C8EA;110C 116D 11B1;C8EA;110C 116D 11B1; +C8EB;C8EB;110C 116D 11B2;C8EB;110C 116D 11B2; +C8EC;C8EC;110C 116D 11B3;C8EC;110C 116D 11B3; +C8ED;C8ED;110C 116D 11B4;C8ED;110C 116D 11B4; +C8EE;C8EE;110C 116D 11B5;C8EE;110C 116D 11B5; +C8EF;C8EF;110C 116D 11B6;C8EF;110C 116D 11B6; +C8F0;C8F0;110C 116D 11B7;C8F0;110C 116D 11B7; +C8F1;C8F1;110C 116D 11B8;C8F1;110C 116D 11B8; +C8F2;C8F2;110C 116D 11B9;C8F2;110C 116D 11B9; +C8F3;C8F3;110C 116D 11BA;C8F3;110C 116D 11BA; +C8F4;C8F4;110C 116D 11BB;C8F4;110C 116D 11BB; +C8F5;C8F5;110C 116D 11BC;C8F5;110C 116D 11BC; +C8F6;C8F6;110C 116D 11BD;C8F6;110C 116D 11BD; +C8F7;C8F7;110C 116D 11BE;C8F7;110C 116D 11BE; +C8F8;C8F8;110C 116D 11BF;C8F8;110C 116D 11BF; +C8F9;C8F9;110C 116D 11C0;C8F9;110C 116D 11C0; +C8FA;C8FA;110C 116D 11C1;C8FA;110C 116D 11C1; +C8FB;C8FB;110C 116D 11C2;C8FB;110C 116D 11C2; +C8FC;C8FC;110C 116E;C8FC;110C 116E; +C8FD;C8FD;110C 116E 11A8;C8FD;110C 116E 11A8; +C8FE;C8FE;110C 116E 11A9;C8FE;110C 116E 11A9; +C8FF;C8FF;110C 116E 11AA;C8FF;110C 116E 11AA; +C900;C900;110C 116E 11AB;C900;110C 116E 11AB; +C901;C901;110C 116E 11AC;C901;110C 116E 11AC; +C902;C902;110C 116E 11AD;C902;110C 116E 11AD; +C903;C903;110C 116E 11AE;C903;110C 116E 11AE; +C904;C904;110C 116E 11AF;C904;110C 116E 11AF; +C905;C905;110C 116E 11B0;C905;110C 116E 11B0; +C906;C906;110C 116E 11B1;C906;110C 116E 11B1; +C907;C907;110C 116E 11B2;C907;110C 116E 11B2; +C908;C908;110C 116E 11B3;C908;110C 116E 11B3; +C909;C909;110C 116E 11B4;C909;110C 116E 11B4; +C90A;C90A;110C 116E 11B5;C90A;110C 116E 11B5; +C90B;C90B;110C 116E 11B6;C90B;110C 116E 11B6; +C90C;C90C;110C 116E 11B7;C90C;110C 116E 11B7; +C90D;C90D;110C 116E 11B8;C90D;110C 116E 11B8; +C90E;C90E;110C 116E 11B9;C90E;110C 116E 11B9; +C90F;C90F;110C 116E 11BA;C90F;110C 116E 11BA; +C910;C910;110C 116E 11BB;C910;110C 116E 11BB; +C911;C911;110C 116E 11BC;C911;110C 116E 11BC; +C912;C912;110C 116E 11BD;C912;110C 116E 11BD; +C913;C913;110C 116E 11BE;C913;110C 116E 11BE; +C914;C914;110C 116E 11BF;C914;110C 116E 11BF; +C915;C915;110C 116E 11C0;C915;110C 116E 11C0; +C916;C916;110C 116E 11C1;C916;110C 116E 11C1; +C917;C917;110C 116E 11C2;C917;110C 116E 11C2; +C918;C918;110C 116F;C918;110C 116F; +C919;C919;110C 116F 11A8;C919;110C 116F 11A8; +C91A;C91A;110C 116F 11A9;C91A;110C 116F 11A9; +C91B;C91B;110C 116F 11AA;C91B;110C 116F 11AA; +C91C;C91C;110C 116F 11AB;C91C;110C 116F 11AB; +C91D;C91D;110C 116F 11AC;C91D;110C 116F 11AC; +C91E;C91E;110C 116F 11AD;C91E;110C 116F 11AD; +C91F;C91F;110C 116F 11AE;C91F;110C 116F 11AE; +C920;C920;110C 116F 11AF;C920;110C 116F 11AF; +C921;C921;110C 116F 11B0;C921;110C 116F 11B0; +C922;C922;110C 116F 11B1;C922;110C 116F 11B1; +C923;C923;110C 116F 11B2;C923;110C 116F 11B2; +C924;C924;110C 116F 11B3;C924;110C 116F 11B3; +C925;C925;110C 116F 11B4;C925;110C 116F 11B4; +C926;C926;110C 116F 11B5;C926;110C 116F 11B5; +C927;C927;110C 116F 11B6;C927;110C 116F 11B6; +C928;C928;110C 116F 11B7;C928;110C 116F 11B7; +C929;C929;110C 116F 11B8;C929;110C 116F 11B8; +C92A;C92A;110C 116F 11B9;C92A;110C 116F 11B9; +C92B;C92B;110C 116F 11BA;C92B;110C 116F 11BA; +C92C;C92C;110C 116F 11BB;C92C;110C 116F 11BB; +C92D;C92D;110C 116F 11BC;C92D;110C 116F 11BC; +C92E;C92E;110C 116F 11BD;C92E;110C 116F 11BD; +C92F;C92F;110C 116F 11BE;C92F;110C 116F 11BE; +C930;C930;110C 116F 11BF;C930;110C 116F 11BF; +C931;C931;110C 116F 11C0;C931;110C 116F 11C0; +C932;C932;110C 116F 11C1;C932;110C 116F 11C1; +C933;C933;110C 116F 11C2;C933;110C 116F 11C2; +C934;C934;110C 1170;C934;110C 1170; +C935;C935;110C 1170 11A8;C935;110C 1170 11A8; +C936;C936;110C 1170 11A9;C936;110C 1170 11A9; +C937;C937;110C 1170 11AA;C937;110C 1170 11AA; +C938;C938;110C 1170 11AB;C938;110C 1170 11AB; +C939;C939;110C 1170 11AC;C939;110C 1170 11AC; +C93A;C93A;110C 1170 11AD;C93A;110C 1170 11AD; +C93B;C93B;110C 1170 11AE;C93B;110C 1170 11AE; +C93C;C93C;110C 1170 11AF;C93C;110C 1170 11AF; +C93D;C93D;110C 1170 11B0;C93D;110C 1170 11B0; +C93E;C93E;110C 1170 11B1;C93E;110C 1170 11B1; +C93F;C93F;110C 1170 11B2;C93F;110C 1170 11B2; +C940;C940;110C 1170 11B3;C940;110C 1170 11B3; +C941;C941;110C 1170 11B4;C941;110C 1170 11B4; +C942;C942;110C 1170 11B5;C942;110C 1170 11B5; +C943;C943;110C 1170 11B6;C943;110C 1170 11B6; +C944;C944;110C 1170 11B7;C944;110C 1170 11B7; +C945;C945;110C 1170 11B8;C945;110C 1170 11B8; +C946;C946;110C 1170 11B9;C946;110C 1170 11B9; +C947;C947;110C 1170 11BA;C947;110C 1170 11BA; +C948;C948;110C 1170 11BB;C948;110C 1170 11BB; +C949;C949;110C 1170 11BC;C949;110C 1170 11BC; +C94A;C94A;110C 1170 11BD;C94A;110C 1170 11BD; +C94B;C94B;110C 1170 11BE;C94B;110C 1170 11BE; +C94C;C94C;110C 1170 11BF;C94C;110C 1170 11BF; +C94D;C94D;110C 1170 11C0;C94D;110C 1170 11C0; +C94E;C94E;110C 1170 11C1;C94E;110C 1170 11C1; +C94F;C94F;110C 1170 11C2;C94F;110C 1170 11C2; +C950;C950;110C 1171;C950;110C 1171; +C951;C951;110C 1171 11A8;C951;110C 1171 11A8; +C952;C952;110C 1171 11A9;C952;110C 1171 11A9; +C953;C953;110C 1171 11AA;C953;110C 1171 11AA; +C954;C954;110C 1171 11AB;C954;110C 1171 11AB; +C955;C955;110C 1171 11AC;C955;110C 1171 11AC; +C956;C956;110C 1171 11AD;C956;110C 1171 11AD; +C957;C957;110C 1171 11AE;C957;110C 1171 11AE; +C958;C958;110C 1171 11AF;C958;110C 1171 11AF; +C959;C959;110C 1171 11B0;C959;110C 1171 11B0; +C95A;C95A;110C 1171 11B1;C95A;110C 1171 11B1; +C95B;C95B;110C 1171 11B2;C95B;110C 1171 11B2; +C95C;C95C;110C 1171 11B3;C95C;110C 1171 11B3; +C95D;C95D;110C 1171 11B4;C95D;110C 1171 11B4; +C95E;C95E;110C 1171 11B5;C95E;110C 1171 11B5; +C95F;C95F;110C 1171 11B6;C95F;110C 1171 11B6; +C960;C960;110C 1171 11B7;C960;110C 1171 11B7; +C961;C961;110C 1171 11B8;C961;110C 1171 11B8; +C962;C962;110C 1171 11B9;C962;110C 1171 11B9; +C963;C963;110C 1171 11BA;C963;110C 1171 11BA; +C964;C964;110C 1171 11BB;C964;110C 1171 11BB; +C965;C965;110C 1171 11BC;C965;110C 1171 11BC; +C966;C966;110C 1171 11BD;C966;110C 1171 11BD; +C967;C967;110C 1171 11BE;C967;110C 1171 11BE; +C968;C968;110C 1171 11BF;C968;110C 1171 11BF; +C969;C969;110C 1171 11C0;C969;110C 1171 11C0; +C96A;C96A;110C 1171 11C1;C96A;110C 1171 11C1; +C96B;C96B;110C 1171 11C2;C96B;110C 1171 11C2; +C96C;C96C;110C 1172;C96C;110C 1172; +C96D;C96D;110C 1172 11A8;C96D;110C 1172 11A8; +C96E;C96E;110C 1172 11A9;C96E;110C 1172 11A9; +C96F;C96F;110C 1172 11AA;C96F;110C 1172 11AA; +C970;C970;110C 1172 11AB;C970;110C 1172 11AB; +C971;C971;110C 1172 11AC;C971;110C 1172 11AC; +C972;C972;110C 1172 11AD;C972;110C 1172 11AD; +C973;C973;110C 1172 11AE;C973;110C 1172 11AE; +C974;C974;110C 1172 11AF;C974;110C 1172 11AF; +C975;C975;110C 1172 11B0;C975;110C 1172 11B0; +C976;C976;110C 1172 11B1;C976;110C 1172 11B1; +C977;C977;110C 1172 11B2;C977;110C 1172 11B2; +C978;C978;110C 1172 11B3;C978;110C 1172 11B3; +C979;C979;110C 1172 11B4;C979;110C 1172 11B4; +C97A;C97A;110C 1172 11B5;C97A;110C 1172 11B5; +C97B;C97B;110C 1172 11B6;C97B;110C 1172 11B6; +C97C;C97C;110C 1172 11B7;C97C;110C 1172 11B7; +C97D;C97D;110C 1172 11B8;C97D;110C 1172 11B8; +C97E;C97E;110C 1172 11B9;C97E;110C 1172 11B9; +C97F;C97F;110C 1172 11BA;C97F;110C 1172 11BA; +C980;C980;110C 1172 11BB;C980;110C 1172 11BB; +C981;C981;110C 1172 11BC;C981;110C 1172 11BC; +C982;C982;110C 1172 11BD;C982;110C 1172 11BD; +C983;C983;110C 1172 11BE;C983;110C 1172 11BE; +C984;C984;110C 1172 11BF;C984;110C 1172 11BF; +C985;C985;110C 1172 11C0;C985;110C 1172 11C0; +C986;C986;110C 1172 11C1;C986;110C 1172 11C1; +C987;C987;110C 1172 11C2;C987;110C 1172 11C2; +C988;C988;110C 1173;C988;110C 1173; +C989;C989;110C 1173 11A8;C989;110C 1173 11A8; +C98A;C98A;110C 1173 11A9;C98A;110C 1173 11A9; +C98B;C98B;110C 1173 11AA;C98B;110C 1173 11AA; +C98C;C98C;110C 1173 11AB;C98C;110C 1173 11AB; +C98D;C98D;110C 1173 11AC;C98D;110C 1173 11AC; +C98E;C98E;110C 1173 11AD;C98E;110C 1173 11AD; +C98F;C98F;110C 1173 11AE;C98F;110C 1173 11AE; +C990;C990;110C 1173 11AF;C990;110C 1173 11AF; +C991;C991;110C 1173 11B0;C991;110C 1173 11B0; +C992;C992;110C 1173 11B1;C992;110C 1173 11B1; +C993;C993;110C 1173 11B2;C993;110C 1173 11B2; +C994;C994;110C 1173 11B3;C994;110C 1173 11B3; +C995;C995;110C 1173 11B4;C995;110C 1173 11B4; +C996;C996;110C 1173 11B5;C996;110C 1173 11B5; +C997;C997;110C 1173 11B6;C997;110C 1173 11B6; +C998;C998;110C 1173 11B7;C998;110C 1173 11B7; +C999;C999;110C 1173 11B8;C999;110C 1173 11B8; +C99A;C99A;110C 1173 11B9;C99A;110C 1173 11B9; +C99B;C99B;110C 1173 11BA;C99B;110C 1173 11BA; +C99C;C99C;110C 1173 11BB;C99C;110C 1173 11BB; +C99D;C99D;110C 1173 11BC;C99D;110C 1173 11BC; +C99E;C99E;110C 1173 11BD;C99E;110C 1173 11BD; +C99F;C99F;110C 1173 11BE;C99F;110C 1173 11BE; +C9A0;C9A0;110C 1173 11BF;C9A0;110C 1173 11BF; +C9A1;C9A1;110C 1173 11C0;C9A1;110C 1173 11C0; +C9A2;C9A2;110C 1173 11C1;C9A2;110C 1173 11C1; +C9A3;C9A3;110C 1173 11C2;C9A3;110C 1173 11C2; +C9A4;C9A4;110C 1174;C9A4;110C 1174; +C9A5;C9A5;110C 1174 11A8;C9A5;110C 1174 11A8; +C9A6;C9A6;110C 1174 11A9;C9A6;110C 1174 11A9; +C9A7;C9A7;110C 1174 11AA;C9A7;110C 1174 11AA; +C9A8;C9A8;110C 1174 11AB;C9A8;110C 1174 11AB; +C9A9;C9A9;110C 1174 11AC;C9A9;110C 1174 11AC; +C9AA;C9AA;110C 1174 11AD;C9AA;110C 1174 11AD; +C9AB;C9AB;110C 1174 11AE;C9AB;110C 1174 11AE; +C9AC;C9AC;110C 1174 11AF;C9AC;110C 1174 11AF; +C9AD;C9AD;110C 1174 11B0;C9AD;110C 1174 11B0; +C9AE;C9AE;110C 1174 11B1;C9AE;110C 1174 11B1; +C9AF;C9AF;110C 1174 11B2;C9AF;110C 1174 11B2; +C9B0;C9B0;110C 1174 11B3;C9B0;110C 1174 11B3; +C9B1;C9B1;110C 1174 11B4;C9B1;110C 1174 11B4; +C9B2;C9B2;110C 1174 11B5;C9B2;110C 1174 11B5; +C9B3;C9B3;110C 1174 11B6;C9B3;110C 1174 11B6; +C9B4;C9B4;110C 1174 11B7;C9B4;110C 1174 11B7; +C9B5;C9B5;110C 1174 11B8;C9B5;110C 1174 11B8; +C9B6;C9B6;110C 1174 11B9;C9B6;110C 1174 11B9; +C9B7;C9B7;110C 1174 11BA;C9B7;110C 1174 11BA; +C9B8;C9B8;110C 1174 11BB;C9B8;110C 1174 11BB; +C9B9;C9B9;110C 1174 11BC;C9B9;110C 1174 11BC; +C9BA;C9BA;110C 1174 11BD;C9BA;110C 1174 11BD; +C9BB;C9BB;110C 1174 11BE;C9BB;110C 1174 11BE; +C9BC;C9BC;110C 1174 11BF;C9BC;110C 1174 11BF; +C9BD;C9BD;110C 1174 11C0;C9BD;110C 1174 11C0; +C9BE;C9BE;110C 1174 11C1;C9BE;110C 1174 11C1; +C9BF;C9BF;110C 1174 11C2;C9BF;110C 1174 11C2; +C9C0;C9C0;110C 1175;C9C0;110C 1175; +C9C1;C9C1;110C 1175 11A8;C9C1;110C 1175 11A8; +C9C2;C9C2;110C 1175 11A9;C9C2;110C 1175 11A9; +C9C3;C9C3;110C 1175 11AA;C9C3;110C 1175 11AA; +C9C4;C9C4;110C 1175 11AB;C9C4;110C 1175 11AB; +C9C5;C9C5;110C 1175 11AC;C9C5;110C 1175 11AC; +C9C6;C9C6;110C 1175 11AD;C9C6;110C 1175 11AD; +C9C7;C9C7;110C 1175 11AE;C9C7;110C 1175 11AE; +C9C8;C9C8;110C 1175 11AF;C9C8;110C 1175 11AF; +C9C9;C9C9;110C 1175 11B0;C9C9;110C 1175 11B0; +C9CA;C9CA;110C 1175 11B1;C9CA;110C 1175 11B1; +C9CB;C9CB;110C 1175 11B2;C9CB;110C 1175 11B2; +C9CC;C9CC;110C 1175 11B3;C9CC;110C 1175 11B3; +C9CD;C9CD;110C 1175 11B4;C9CD;110C 1175 11B4; +C9CE;C9CE;110C 1175 11B5;C9CE;110C 1175 11B5; +C9CF;C9CF;110C 1175 11B6;C9CF;110C 1175 11B6; +C9D0;C9D0;110C 1175 11B7;C9D0;110C 1175 11B7; +C9D1;C9D1;110C 1175 11B8;C9D1;110C 1175 11B8; +C9D2;C9D2;110C 1175 11B9;C9D2;110C 1175 11B9; +C9D3;C9D3;110C 1175 11BA;C9D3;110C 1175 11BA; +C9D4;C9D4;110C 1175 11BB;C9D4;110C 1175 11BB; +C9D5;C9D5;110C 1175 11BC;C9D5;110C 1175 11BC; +C9D6;C9D6;110C 1175 11BD;C9D6;110C 1175 11BD; +C9D7;C9D7;110C 1175 11BE;C9D7;110C 1175 11BE; +C9D8;C9D8;110C 1175 11BF;C9D8;110C 1175 11BF; +C9D9;C9D9;110C 1175 11C0;C9D9;110C 1175 11C0; +C9DA;C9DA;110C 1175 11C1;C9DA;110C 1175 11C1; +C9DB;C9DB;110C 1175 11C2;C9DB;110C 1175 11C2; +C9DC;C9DC;110D 1161;C9DC;110D 1161; +C9DD;C9DD;110D 1161 11A8;C9DD;110D 1161 11A8; +C9DE;C9DE;110D 1161 11A9;C9DE;110D 1161 11A9; +C9DF;C9DF;110D 1161 11AA;C9DF;110D 1161 11AA; +C9E0;C9E0;110D 1161 11AB;C9E0;110D 1161 11AB; +C9E1;C9E1;110D 1161 11AC;C9E1;110D 1161 11AC; +C9E2;C9E2;110D 1161 11AD;C9E2;110D 1161 11AD; +C9E3;C9E3;110D 1161 11AE;C9E3;110D 1161 11AE; +C9E4;C9E4;110D 1161 11AF;C9E4;110D 1161 11AF; +C9E5;C9E5;110D 1161 11B0;C9E5;110D 1161 11B0; +C9E6;C9E6;110D 1161 11B1;C9E6;110D 1161 11B1; +C9E7;C9E7;110D 1161 11B2;C9E7;110D 1161 11B2; +C9E8;C9E8;110D 1161 11B3;C9E8;110D 1161 11B3; +C9E9;C9E9;110D 1161 11B4;C9E9;110D 1161 11B4; +C9EA;C9EA;110D 1161 11B5;C9EA;110D 1161 11B5; +C9EB;C9EB;110D 1161 11B6;C9EB;110D 1161 11B6; +C9EC;C9EC;110D 1161 11B7;C9EC;110D 1161 11B7; +C9ED;C9ED;110D 1161 11B8;C9ED;110D 1161 11B8; +C9EE;C9EE;110D 1161 11B9;C9EE;110D 1161 11B9; +C9EF;C9EF;110D 1161 11BA;C9EF;110D 1161 11BA; +C9F0;C9F0;110D 1161 11BB;C9F0;110D 1161 11BB; +C9F1;C9F1;110D 1161 11BC;C9F1;110D 1161 11BC; +C9F2;C9F2;110D 1161 11BD;C9F2;110D 1161 11BD; +C9F3;C9F3;110D 1161 11BE;C9F3;110D 1161 11BE; +C9F4;C9F4;110D 1161 11BF;C9F4;110D 1161 11BF; +C9F5;C9F5;110D 1161 11C0;C9F5;110D 1161 11C0; +C9F6;C9F6;110D 1161 11C1;C9F6;110D 1161 11C1; +C9F7;C9F7;110D 1161 11C2;C9F7;110D 1161 11C2; +C9F8;C9F8;110D 1162;C9F8;110D 1162; +C9F9;C9F9;110D 1162 11A8;C9F9;110D 1162 11A8; +C9FA;C9FA;110D 1162 11A9;C9FA;110D 1162 11A9; +C9FB;C9FB;110D 1162 11AA;C9FB;110D 1162 11AA; +C9FC;C9FC;110D 1162 11AB;C9FC;110D 1162 11AB; +C9FD;C9FD;110D 1162 11AC;C9FD;110D 1162 11AC; +C9FE;C9FE;110D 1162 11AD;C9FE;110D 1162 11AD; +C9FF;C9FF;110D 1162 11AE;C9FF;110D 1162 11AE; +CA00;CA00;110D 1162 11AF;CA00;110D 1162 11AF; +CA01;CA01;110D 1162 11B0;CA01;110D 1162 11B0; +CA02;CA02;110D 1162 11B1;CA02;110D 1162 11B1; +CA03;CA03;110D 1162 11B2;CA03;110D 1162 11B2; +CA04;CA04;110D 1162 11B3;CA04;110D 1162 11B3; +CA05;CA05;110D 1162 11B4;CA05;110D 1162 11B4; +CA06;CA06;110D 1162 11B5;CA06;110D 1162 11B5; +CA07;CA07;110D 1162 11B6;CA07;110D 1162 11B6; +CA08;CA08;110D 1162 11B7;CA08;110D 1162 11B7; +CA09;CA09;110D 1162 11B8;CA09;110D 1162 11B8; +CA0A;CA0A;110D 1162 11B9;CA0A;110D 1162 11B9; +CA0B;CA0B;110D 1162 11BA;CA0B;110D 1162 11BA; +CA0C;CA0C;110D 1162 11BB;CA0C;110D 1162 11BB; +CA0D;CA0D;110D 1162 11BC;CA0D;110D 1162 11BC; +CA0E;CA0E;110D 1162 11BD;CA0E;110D 1162 11BD; +CA0F;CA0F;110D 1162 11BE;CA0F;110D 1162 11BE; +CA10;CA10;110D 1162 11BF;CA10;110D 1162 11BF; +CA11;CA11;110D 1162 11C0;CA11;110D 1162 11C0; +CA12;CA12;110D 1162 11C1;CA12;110D 1162 11C1; +CA13;CA13;110D 1162 11C2;CA13;110D 1162 11C2; +CA14;CA14;110D 1163;CA14;110D 1163; +CA15;CA15;110D 1163 11A8;CA15;110D 1163 11A8; +CA16;CA16;110D 1163 11A9;CA16;110D 1163 11A9; +CA17;CA17;110D 1163 11AA;CA17;110D 1163 11AA; +CA18;CA18;110D 1163 11AB;CA18;110D 1163 11AB; +CA19;CA19;110D 1163 11AC;CA19;110D 1163 11AC; +CA1A;CA1A;110D 1163 11AD;CA1A;110D 1163 11AD; +CA1B;CA1B;110D 1163 11AE;CA1B;110D 1163 11AE; +CA1C;CA1C;110D 1163 11AF;CA1C;110D 1163 11AF; +CA1D;CA1D;110D 1163 11B0;CA1D;110D 1163 11B0; +CA1E;CA1E;110D 1163 11B1;CA1E;110D 1163 11B1; +CA1F;CA1F;110D 1163 11B2;CA1F;110D 1163 11B2; +CA20;CA20;110D 1163 11B3;CA20;110D 1163 11B3; +CA21;CA21;110D 1163 11B4;CA21;110D 1163 11B4; +CA22;CA22;110D 1163 11B5;CA22;110D 1163 11B5; +CA23;CA23;110D 1163 11B6;CA23;110D 1163 11B6; +CA24;CA24;110D 1163 11B7;CA24;110D 1163 11B7; +CA25;CA25;110D 1163 11B8;CA25;110D 1163 11B8; +CA26;CA26;110D 1163 11B9;CA26;110D 1163 11B9; +CA27;CA27;110D 1163 11BA;CA27;110D 1163 11BA; +CA28;CA28;110D 1163 11BB;CA28;110D 1163 11BB; +CA29;CA29;110D 1163 11BC;CA29;110D 1163 11BC; +CA2A;CA2A;110D 1163 11BD;CA2A;110D 1163 11BD; +CA2B;CA2B;110D 1163 11BE;CA2B;110D 1163 11BE; +CA2C;CA2C;110D 1163 11BF;CA2C;110D 1163 11BF; +CA2D;CA2D;110D 1163 11C0;CA2D;110D 1163 11C0; +CA2E;CA2E;110D 1163 11C1;CA2E;110D 1163 11C1; +CA2F;CA2F;110D 1163 11C2;CA2F;110D 1163 11C2; +CA30;CA30;110D 1164;CA30;110D 1164; +CA31;CA31;110D 1164 11A8;CA31;110D 1164 11A8; +CA32;CA32;110D 1164 11A9;CA32;110D 1164 11A9; +CA33;CA33;110D 1164 11AA;CA33;110D 1164 11AA; +CA34;CA34;110D 1164 11AB;CA34;110D 1164 11AB; +CA35;CA35;110D 1164 11AC;CA35;110D 1164 11AC; +CA36;CA36;110D 1164 11AD;CA36;110D 1164 11AD; +CA37;CA37;110D 1164 11AE;CA37;110D 1164 11AE; +CA38;CA38;110D 1164 11AF;CA38;110D 1164 11AF; +CA39;CA39;110D 1164 11B0;CA39;110D 1164 11B0; +CA3A;CA3A;110D 1164 11B1;CA3A;110D 1164 11B1; +CA3B;CA3B;110D 1164 11B2;CA3B;110D 1164 11B2; +CA3C;CA3C;110D 1164 11B3;CA3C;110D 1164 11B3; +CA3D;CA3D;110D 1164 11B4;CA3D;110D 1164 11B4; +CA3E;CA3E;110D 1164 11B5;CA3E;110D 1164 11B5; +CA3F;CA3F;110D 1164 11B6;CA3F;110D 1164 11B6; +CA40;CA40;110D 1164 11B7;CA40;110D 1164 11B7; +CA41;CA41;110D 1164 11B8;CA41;110D 1164 11B8; +CA42;CA42;110D 1164 11B9;CA42;110D 1164 11B9; +CA43;CA43;110D 1164 11BA;CA43;110D 1164 11BA; +CA44;CA44;110D 1164 11BB;CA44;110D 1164 11BB; +CA45;CA45;110D 1164 11BC;CA45;110D 1164 11BC; +CA46;CA46;110D 1164 11BD;CA46;110D 1164 11BD; +CA47;CA47;110D 1164 11BE;CA47;110D 1164 11BE; +CA48;CA48;110D 1164 11BF;CA48;110D 1164 11BF; +CA49;CA49;110D 1164 11C0;CA49;110D 1164 11C0; +CA4A;CA4A;110D 1164 11C1;CA4A;110D 1164 11C1; +CA4B;CA4B;110D 1164 11C2;CA4B;110D 1164 11C2; +CA4C;CA4C;110D 1165;CA4C;110D 1165; +CA4D;CA4D;110D 1165 11A8;CA4D;110D 1165 11A8; +CA4E;CA4E;110D 1165 11A9;CA4E;110D 1165 11A9; +CA4F;CA4F;110D 1165 11AA;CA4F;110D 1165 11AA; +CA50;CA50;110D 1165 11AB;CA50;110D 1165 11AB; +CA51;CA51;110D 1165 11AC;CA51;110D 1165 11AC; +CA52;CA52;110D 1165 11AD;CA52;110D 1165 11AD; +CA53;CA53;110D 1165 11AE;CA53;110D 1165 11AE; +CA54;CA54;110D 1165 11AF;CA54;110D 1165 11AF; +CA55;CA55;110D 1165 11B0;CA55;110D 1165 11B0; +CA56;CA56;110D 1165 11B1;CA56;110D 1165 11B1; +CA57;CA57;110D 1165 11B2;CA57;110D 1165 11B2; +CA58;CA58;110D 1165 11B3;CA58;110D 1165 11B3; +CA59;CA59;110D 1165 11B4;CA59;110D 1165 11B4; +CA5A;CA5A;110D 1165 11B5;CA5A;110D 1165 11B5; +CA5B;CA5B;110D 1165 11B6;CA5B;110D 1165 11B6; +CA5C;CA5C;110D 1165 11B7;CA5C;110D 1165 11B7; +CA5D;CA5D;110D 1165 11B8;CA5D;110D 1165 11B8; +CA5E;CA5E;110D 1165 11B9;CA5E;110D 1165 11B9; +CA5F;CA5F;110D 1165 11BA;CA5F;110D 1165 11BA; +CA60;CA60;110D 1165 11BB;CA60;110D 1165 11BB; +CA61;CA61;110D 1165 11BC;CA61;110D 1165 11BC; +CA62;CA62;110D 1165 11BD;CA62;110D 1165 11BD; +CA63;CA63;110D 1165 11BE;CA63;110D 1165 11BE; +CA64;CA64;110D 1165 11BF;CA64;110D 1165 11BF; +CA65;CA65;110D 1165 11C0;CA65;110D 1165 11C0; +CA66;CA66;110D 1165 11C1;CA66;110D 1165 11C1; +CA67;CA67;110D 1165 11C2;CA67;110D 1165 11C2; +CA68;CA68;110D 1166;CA68;110D 1166; +CA69;CA69;110D 1166 11A8;CA69;110D 1166 11A8; +CA6A;CA6A;110D 1166 11A9;CA6A;110D 1166 11A9; +CA6B;CA6B;110D 1166 11AA;CA6B;110D 1166 11AA; +CA6C;CA6C;110D 1166 11AB;CA6C;110D 1166 11AB; +CA6D;CA6D;110D 1166 11AC;CA6D;110D 1166 11AC; +CA6E;CA6E;110D 1166 11AD;CA6E;110D 1166 11AD; +CA6F;CA6F;110D 1166 11AE;CA6F;110D 1166 11AE; +CA70;CA70;110D 1166 11AF;CA70;110D 1166 11AF; +CA71;CA71;110D 1166 11B0;CA71;110D 1166 11B0; +CA72;CA72;110D 1166 11B1;CA72;110D 1166 11B1; +CA73;CA73;110D 1166 11B2;CA73;110D 1166 11B2; +CA74;CA74;110D 1166 11B3;CA74;110D 1166 11B3; +CA75;CA75;110D 1166 11B4;CA75;110D 1166 11B4; +CA76;CA76;110D 1166 11B5;CA76;110D 1166 11B5; +CA77;CA77;110D 1166 11B6;CA77;110D 1166 11B6; +CA78;CA78;110D 1166 11B7;CA78;110D 1166 11B7; +CA79;CA79;110D 1166 11B8;CA79;110D 1166 11B8; +CA7A;CA7A;110D 1166 11B9;CA7A;110D 1166 11B9; +CA7B;CA7B;110D 1166 11BA;CA7B;110D 1166 11BA; +CA7C;CA7C;110D 1166 11BB;CA7C;110D 1166 11BB; +CA7D;CA7D;110D 1166 11BC;CA7D;110D 1166 11BC; +CA7E;CA7E;110D 1166 11BD;CA7E;110D 1166 11BD; +CA7F;CA7F;110D 1166 11BE;CA7F;110D 1166 11BE; +CA80;CA80;110D 1166 11BF;CA80;110D 1166 11BF; +CA81;CA81;110D 1166 11C0;CA81;110D 1166 11C0; +CA82;CA82;110D 1166 11C1;CA82;110D 1166 11C1; +CA83;CA83;110D 1166 11C2;CA83;110D 1166 11C2; +CA84;CA84;110D 1167;CA84;110D 1167; +CA85;CA85;110D 1167 11A8;CA85;110D 1167 11A8; +CA86;CA86;110D 1167 11A9;CA86;110D 1167 11A9; +CA87;CA87;110D 1167 11AA;CA87;110D 1167 11AA; +CA88;CA88;110D 1167 11AB;CA88;110D 1167 11AB; +CA89;CA89;110D 1167 11AC;CA89;110D 1167 11AC; +CA8A;CA8A;110D 1167 11AD;CA8A;110D 1167 11AD; +CA8B;CA8B;110D 1167 11AE;CA8B;110D 1167 11AE; +CA8C;CA8C;110D 1167 11AF;CA8C;110D 1167 11AF; +CA8D;CA8D;110D 1167 11B0;CA8D;110D 1167 11B0; +CA8E;CA8E;110D 1167 11B1;CA8E;110D 1167 11B1; +CA8F;CA8F;110D 1167 11B2;CA8F;110D 1167 11B2; +CA90;CA90;110D 1167 11B3;CA90;110D 1167 11B3; +CA91;CA91;110D 1167 11B4;CA91;110D 1167 11B4; +CA92;CA92;110D 1167 11B5;CA92;110D 1167 11B5; +CA93;CA93;110D 1167 11B6;CA93;110D 1167 11B6; +CA94;CA94;110D 1167 11B7;CA94;110D 1167 11B7; +CA95;CA95;110D 1167 11B8;CA95;110D 1167 11B8; +CA96;CA96;110D 1167 11B9;CA96;110D 1167 11B9; +CA97;CA97;110D 1167 11BA;CA97;110D 1167 11BA; +CA98;CA98;110D 1167 11BB;CA98;110D 1167 11BB; +CA99;CA99;110D 1167 11BC;CA99;110D 1167 11BC; +CA9A;CA9A;110D 1167 11BD;CA9A;110D 1167 11BD; +CA9B;CA9B;110D 1167 11BE;CA9B;110D 1167 11BE; +CA9C;CA9C;110D 1167 11BF;CA9C;110D 1167 11BF; +CA9D;CA9D;110D 1167 11C0;CA9D;110D 1167 11C0; +CA9E;CA9E;110D 1167 11C1;CA9E;110D 1167 11C1; +CA9F;CA9F;110D 1167 11C2;CA9F;110D 1167 11C2; +CAA0;CAA0;110D 1168;CAA0;110D 1168; +CAA1;CAA1;110D 1168 11A8;CAA1;110D 1168 11A8; +CAA2;CAA2;110D 1168 11A9;CAA2;110D 1168 11A9; +CAA3;CAA3;110D 1168 11AA;CAA3;110D 1168 11AA; +CAA4;CAA4;110D 1168 11AB;CAA4;110D 1168 11AB; +CAA5;CAA5;110D 1168 11AC;CAA5;110D 1168 11AC; +CAA6;CAA6;110D 1168 11AD;CAA6;110D 1168 11AD; +CAA7;CAA7;110D 1168 11AE;CAA7;110D 1168 11AE; +CAA8;CAA8;110D 1168 11AF;CAA8;110D 1168 11AF; +CAA9;CAA9;110D 1168 11B0;CAA9;110D 1168 11B0; +CAAA;CAAA;110D 1168 11B1;CAAA;110D 1168 11B1; +CAAB;CAAB;110D 1168 11B2;CAAB;110D 1168 11B2; +CAAC;CAAC;110D 1168 11B3;CAAC;110D 1168 11B3; +CAAD;CAAD;110D 1168 11B4;CAAD;110D 1168 11B4; +CAAE;CAAE;110D 1168 11B5;CAAE;110D 1168 11B5; +CAAF;CAAF;110D 1168 11B6;CAAF;110D 1168 11B6; +CAB0;CAB0;110D 1168 11B7;CAB0;110D 1168 11B7; +CAB1;CAB1;110D 1168 11B8;CAB1;110D 1168 11B8; +CAB2;CAB2;110D 1168 11B9;CAB2;110D 1168 11B9; +CAB3;CAB3;110D 1168 11BA;CAB3;110D 1168 11BA; +CAB4;CAB4;110D 1168 11BB;CAB4;110D 1168 11BB; +CAB5;CAB5;110D 1168 11BC;CAB5;110D 1168 11BC; +CAB6;CAB6;110D 1168 11BD;CAB6;110D 1168 11BD; +CAB7;CAB7;110D 1168 11BE;CAB7;110D 1168 11BE; +CAB8;CAB8;110D 1168 11BF;CAB8;110D 1168 11BF; +CAB9;CAB9;110D 1168 11C0;CAB9;110D 1168 11C0; +CABA;CABA;110D 1168 11C1;CABA;110D 1168 11C1; +CABB;CABB;110D 1168 11C2;CABB;110D 1168 11C2; +CABC;CABC;110D 1169;CABC;110D 1169; +CABD;CABD;110D 1169 11A8;CABD;110D 1169 11A8; +CABE;CABE;110D 1169 11A9;CABE;110D 1169 11A9; +CABF;CABF;110D 1169 11AA;CABF;110D 1169 11AA; +CAC0;CAC0;110D 1169 11AB;CAC0;110D 1169 11AB; +CAC1;CAC1;110D 1169 11AC;CAC1;110D 1169 11AC; +CAC2;CAC2;110D 1169 11AD;CAC2;110D 1169 11AD; +CAC3;CAC3;110D 1169 11AE;CAC3;110D 1169 11AE; +CAC4;CAC4;110D 1169 11AF;CAC4;110D 1169 11AF; +CAC5;CAC5;110D 1169 11B0;CAC5;110D 1169 11B0; +CAC6;CAC6;110D 1169 11B1;CAC6;110D 1169 11B1; +CAC7;CAC7;110D 1169 11B2;CAC7;110D 1169 11B2; +CAC8;CAC8;110D 1169 11B3;CAC8;110D 1169 11B3; +CAC9;CAC9;110D 1169 11B4;CAC9;110D 1169 11B4; +CACA;CACA;110D 1169 11B5;CACA;110D 1169 11B5; +CACB;CACB;110D 1169 11B6;CACB;110D 1169 11B6; +CACC;CACC;110D 1169 11B7;CACC;110D 1169 11B7; +CACD;CACD;110D 1169 11B8;CACD;110D 1169 11B8; +CACE;CACE;110D 1169 11B9;CACE;110D 1169 11B9; +CACF;CACF;110D 1169 11BA;CACF;110D 1169 11BA; +CAD0;CAD0;110D 1169 11BB;CAD0;110D 1169 11BB; +CAD1;CAD1;110D 1169 11BC;CAD1;110D 1169 11BC; +CAD2;CAD2;110D 1169 11BD;CAD2;110D 1169 11BD; +CAD3;CAD3;110D 1169 11BE;CAD3;110D 1169 11BE; +CAD4;CAD4;110D 1169 11BF;CAD4;110D 1169 11BF; +CAD5;CAD5;110D 1169 11C0;CAD5;110D 1169 11C0; +CAD6;CAD6;110D 1169 11C1;CAD6;110D 1169 11C1; +CAD7;CAD7;110D 1169 11C2;CAD7;110D 1169 11C2; +CAD8;CAD8;110D 116A;CAD8;110D 116A; +CAD9;CAD9;110D 116A 11A8;CAD9;110D 116A 11A8; +CADA;CADA;110D 116A 11A9;CADA;110D 116A 11A9; +CADB;CADB;110D 116A 11AA;CADB;110D 116A 11AA; +CADC;CADC;110D 116A 11AB;CADC;110D 116A 11AB; +CADD;CADD;110D 116A 11AC;CADD;110D 116A 11AC; +CADE;CADE;110D 116A 11AD;CADE;110D 116A 11AD; +CADF;CADF;110D 116A 11AE;CADF;110D 116A 11AE; +CAE0;CAE0;110D 116A 11AF;CAE0;110D 116A 11AF; +CAE1;CAE1;110D 116A 11B0;CAE1;110D 116A 11B0; +CAE2;CAE2;110D 116A 11B1;CAE2;110D 116A 11B1; +CAE3;CAE3;110D 116A 11B2;CAE3;110D 116A 11B2; +CAE4;CAE4;110D 116A 11B3;CAE4;110D 116A 11B3; +CAE5;CAE5;110D 116A 11B4;CAE5;110D 116A 11B4; +CAE6;CAE6;110D 116A 11B5;CAE6;110D 116A 11B5; +CAE7;CAE7;110D 116A 11B6;CAE7;110D 116A 11B6; +CAE8;CAE8;110D 116A 11B7;CAE8;110D 116A 11B7; +CAE9;CAE9;110D 116A 11B8;CAE9;110D 116A 11B8; +CAEA;CAEA;110D 116A 11B9;CAEA;110D 116A 11B9; +CAEB;CAEB;110D 116A 11BA;CAEB;110D 116A 11BA; +CAEC;CAEC;110D 116A 11BB;CAEC;110D 116A 11BB; +CAED;CAED;110D 116A 11BC;CAED;110D 116A 11BC; +CAEE;CAEE;110D 116A 11BD;CAEE;110D 116A 11BD; +CAEF;CAEF;110D 116A 11BE;CAEF;110D 116A 11BE; +CAF0;CAF0;110D 116A 11BF;CAF0;110D 116A 11BF; +CAF1;CAF1;110D 116A 11C0;CAF1;110D 116A 11C0; +CAF2;CAF2;110D 116A 11C1;CAF2;110D 116A 11C1; +CAF3;CAF3;110D 116A 11C2;CAF3;110D 116A 11C2; +CAF4;CAF4;110D 116B;CAF4;110D 116B; +CAF5;CAF5;110D 116B 11A8;CAF5;110D 116B 11A8; +CAF6;CAF6;110D 116B 11A9;CAF6;110D 116B 11A9; +CAF7;CAF7;110D 116B 11AA;CAF7;110D 116B 11AA; +CAF8;CAF8;110D 116B 11AB;CAF8;110D 116B 11AB; +CAF9;CAF9;110D 116B 11AC;CAF9;110D 116B 11AC; +CAFA;CAFA;110D 116B 11AD;CAFA;110D 116B 11AD; +CAFB;CAFB;110D 116B 11AE;CAFB;110D 116B 11AE; +CAFC;CAFC;110D 116B 11AF;CAFC;110D 116B 11AF; +CAFD;CAFD;110D 116B 11B0;CAFD;110D 116B 11B0; +CAFE;CAFE;110D 116B 11B1;CAFE;110D 116B 11B1; +CAFF;CAFF;110D 116B 11B2;CAFF;110D 116B 11B2; +CB00;CB00;110D 116B 11B3;CB00;110D 116B 11B3; +CB01;CB01;110D 116B 11B4;CB01;110D 116B 11B4; +CB02;CB02;110D 116B 11B5;CB02;110D 116B 11B5; +CB03;CB03;110D 116B 11B6;CB03;110D 116B 11B6; +CB04;CB04;110D 116B 11B7;CB04;110D 116B 11B7; +CB05;CB05;110D 116B 11B8;CB05;110D 116B 11B8; +CB06;CB06;110D 116B 11B9;CB06;110D 116B 11B9; +CB07;CB07;110D 116B 11BA;CB07;110D 116B 11BA; +CB08;CB08;110D 116B 11BB;CB08;110D 116B 11BB; +CB09;CB09;110D 116B 11BC;CB09;110D 116B 11BC; +CB0A;CB0A;110D 116B 11BD;CB0A;110D 116B 11BD; +CB0B;CB0B;110D 116B 11BE;CB0B;110D 116B 11BE; +CB0C;CB0C;110D 116B 11BF;CB0C;110D 116B 11BF; +CB0D;CB0D;110D 116B 11C0;CB0D;110D 116B 11C0; +CB0E;CB0E;110D 116B 11C1;CB0E;110D 116B 11C1; +CB0F;CB0F;110D 116B 11C2;CB0F;110D 116B 11C2; +CB10;CB10;110D 116C;CB10;110D 116C; +CB11;CB11;110D 116C 11A8;CB11;110D 116C 11A8; +CB12;CB12;110D 116C 11A9;CB12;110D 116C 11A9; +CB13;CB13;110D 116C 11AA;CB13;110D 116C 11AA; +CB14;CB14;110D 116C 11AB;CB14;110D 116C 11AB; +CB15;CB15;110D 116C 11AC;CB15;110D 116C 11AC; +CB16;CB16;110D 116C 11AD;CB16;110D 116C 11AD; +CB17;CB17;110D 116C 11AE;CB17;110D 116C 11AE; +CB18;CB18;110D 116C 11AF;CB18;110D 116C 11AF; +CB19;CB19;110D 116C 11B0;CB19;110D 116C 11B0; +CB1A;CB1A;110D 116C 11B1;CB1A;110D 116C 11B1; +CB1B;CB1B;110D 116C 11B2;CB1B;110D 116C 11B2; +CB1C;CB1C;110D 116C 11B3;CB1C;110D 116C 11B3; +CB1D;CB1D;110D 116C 11B4;CB1D;110D 116C 11B4; +CB1E;CB1E;110D 116C 11B5;CB1E;110D 116C 11B5; +CB1F;CB1F;110D 116C 11B6;CB1F;110D 116C 11B6; +CB20;CB20;110D 116C 11B7;CB20;110D 116C 11B7; +CB21;CB21;110D 116C 11B8;CB21;110D 116C 11B8; +CB22;CB22;110D 116C 11B9;CB22;110D 116C 11B9; +CB23;CB23;110D 116C 11BA;CB23;110D 116C 11BA; +CB24;CB24;110D 116C 11BB;CB24;110D 116C 11BB; +CB25;CB25;110D 116C 11BC;CB25;110D 116C 11BC; +CB26;CB26;110D 116C 11BD;CB26;110D 116C 11BD; +CB27;CB27;110D 116C 11BE;CB27;110D 116C 11BE; +CB28;CB28;110D 116C 11BF;CB28;110D 116C 11BF; +CB29;CB29;110D 116C 11C0;CB29;110D 116C 11C0; +CB2A;CB2A;110D 116C 11C1;CB2A;110D 116C 11C1; +CB2B;CB2B;110D 116C 11C2;CB2B;110D 116C 11C2; +CB2C;CB2C;110D 116D;CB2C;110D 116D; +CB2D;CB2D;110D 116D 11A8;CB2D;110D 116D 11A8; +CB2E;CB2E;110D 116D 11A9;CB2E;110D 116D 11A9; +CB2F;CB2F;110D 116D 11AA;CB2F;110D 116D 11AA; +CB30;CB30;110D 116D 11AB;CB30;110D 116D 11AB; +CB31;CB31;110D 116D 11AC;CB31;110D 116D 11AC; +CB32;CB32;110D 116D 11AD;CB32;110D 116D 11AD; +CB33;CB33;110D 116D 11AE;CB33;110D 116D 11AE; +CB34;CB34;110D 116D 11AF;CB34;110D 116D 11AF; +CB35;CB35;110D 116D 11B0;CB35;110D 116D 11B0; +CB36;CB36;110D 116D 11B1;CB36;110D 116D 11B1; +CB37;CB37;110D 116D 11B2;CB37;110D 116D 11B2; +CB38;CB38;110D 116D 11B3;CB38;110D 116D 11B3; +CB39;CB39;110D 116D 11B4;CB39;110D 116D 11B4; +CB3A;CB3A;110D 116D 11B5;CB3A;110D 116D 11B5; +CB3B;CB3B;110D 116D 11B6;CB3B;110D 116D 11B6; +CB3C;CB3C;110D 116D 11B7;CB3C;110D 116D 11B7; +CB3D;CB3D;110D 116D 11B8;CB3D;110D 116D 11B8; +CB3E;CB3E;110D 116D 11B9;CB3E;110D 116D 11B9; +CB3F;CB3F;110D 116D 11BA;CB3F;110D 116D 11BA; +CB40;CB40;110D 116D 11BB;CB40;110D 116D 11BB; +CB41;CB41;110D 116D 11BC;CB41;110D 116D 11BC; +CB42;CB42;110D 116D 11BD;CB42;110D 116D 11BD; +CB43;CB43;110D 116D 11BE;CB43;110D 116D 11BE; +CB44;CB44;110D 116D 11BF;CB44;110D 116D 11BF; +CB45;CB45;110D 116D 11C0;CB45;110D 116D 11C0; +CB46;CB46;110D 116D 11C1;CB46;110D 116D 11C1; +CB47;CB47;110D 116D 11C2;CB47;110D 116D 11C2; +CB48;CB48;110D 116E;CB48;110D 116E; +CB49;CB49;110D 116E 11A8;CB49;110D 116E 11A8; +CB4A;CB4A;110D 116E 11A9;CB4A;110D 116E 11A9; +CB4B;CB4B;110D 116E 11AA;CB4B;110D 116E 11AA; +CB4C;CB4C;110D 116E 11AB;CB4C;110D 116E 11AB; +CB4D;CB4D;110D 116E 11AC;CB4D;110D 116E 11AC; +CB4E;CB4E;110D 116E 11AD;CB4E;110D 116E 11AD; +CB4F;CB4F;110D 116E 11AE;CB4F;110D 116E 11AE; +CB50;CB50;110D 116E 11AF;CB50;110D 116E 11AF; +CB51;CB51;110D 116E 11B0;CB51;110D 116E 11B0; +CB52;CB52;110D 116E 11B1;CB52;110D 116E 11B1; +CB53;CB53;110D 116E 11B2;CB53;110D 116E 11B2; +CB54;CB54;110D 116E 11B3;CB54;110D 116E 11B3; +CB55;CB55;110D 116E 11B4;CB55;110D 116E 11B4; +CB56;CB56;110D 116E 11B5;CB56;110D 116E 11B5; +CB57;CB57;110D 116E 11B6;CB57;110D 116E 11B6; +CB58;CB58;110D 116E 11B7;CB58;110D 116E 11B7; +CB59;CB59;110D 116E 11B8;CB59;110D 116E 11B8; +CB5A;CB5A;110D 116E 11B9;CB5A;110D 116E 11B9; +CB5B;CB5B;110D 116E 11BA;CB5B;110D 116E 11BA; +CB5C;CB5C;110D 116E 11BB;CB5C;110D 116E 11BB; +CB5D;CB5D;110D 116E 11BC;CB5D;110D 116E 11BC; +CB5E;CB5E;110D 116E 11BD;CB5E;110D 116E 11BD; +CB5F;CB5F;110D 116E 11BE;CB5F;110D 116E 11BE; +CB60;CB60;110D 116E 11BF;CB60;110D 116E 11BF; +CB61;CB61;110D 116E 11C0;CB61;110D 116E 11C0; +CB62;CB62;110D 116E 11C1;CB62;110D 116E 11C1; +CB63;CB63;110D 116E 11C2;CB63;110D 116E 11C2; +CB64;CB64;110D 116F;CB64;110D 116F; +CB65;CB65;110D 116F 11A8;CB65;110D 116F 11A8; +CB66;CB66;110D 116F 11A9;CB66;110D 116F 11A9; +CB67;CB67;110D 116F 11AA;CB67;110D 116F 11AA; +CB68;CB68;110D 116F 11AB;CB68;110D 116F 11AB; +CB69;CB69;110D 116F 11AC;CB69;110D 116F 11AC; +CB6A;CB6A;110D 116F 11AD;CB6A;110D 116F 11AD; +CB6B;CB6B;110D 116F 11AE;CB6B;110D 116F 11AE; +CB6C;CB6C;110D 116F 11AF;CB6C;110D 116F 11AF; +CB6D;CB6D;110D 116F 11B0;CB6D;110D 116F 11B0; +CB6E;CB6E;110D 116F 11B1;CB6E;110D 116F 11B1; +CB6F;CB6F;110D 116F 11B2;CB6F;110D 116F 11B2; +CB70;CB70;110D 116F 11B3;CB70;110D 116F 11B3; +CB71;CB71;110D 116F 11B4;CB71;110D 116F 11B4; +CB72;CB72;110D 116F 11B5;CB72;110D 116F 11B5; +CB73;CB73;110D 116F 11B6;CB73;110D 116F 11B6; +CB74;CB74;110D 116F 11B7;CB74;110D 116F 11B7; +CB75;CB75;110D 116F 11B8;CB75;110D 116F 11B8; +CB76;CB76;110D 116F 11B9;CB76;110D 116F 11B9; +CB77;CB77;110D 116F 11BA;CB77;110D 116F 11BA; +CB78;CB78;110D 116F 11BB;CB78;110D 116F 11BB; +CB79;CB79;110D 116F 11BC;CB79;110D 116F 11BC; +CB7A;CB7A;110D 116F 11BD;CB7A;110D 116F 11BD; +CB7B;CB7B;110D 116F 11BE;CB7B;110D 116F 11BE; +CB7C;CB7C;110D 116F 11BF;CB7C;110D 116F 11BF; +CB7D;CB7D;110D 116F 11C0;CB7D;110D 116F 11C0; +CB7E;CB7E;110D 116F 11C1;CB7E;110D 116F 11C1; +CB7F;CB7F;110D 116F 11C2;CB7F;110D 116F 11C2; +CB80;CB80;110D 1170;CB80;110D 1170; +CB81;CB81;110D 1170 11A8;CB81;110D 1170 11A8; +CB82;CB82;110D 1170 11A9;CB82;110D 1170 11A9; +CB83;CB83;110D 1170 11AA;CB83;110D 1170 11AA; +CB84;CB84;110D 1170 11AB;CB84;110D 1170 11AB; +CB85;CB85;110D 1170 11AC;CB85;110D 1170 11AC; +CB86;CB86;110D 1170 11AD;CB86;110D 1170 11AD; +CB87;CB87;110D 1170 11AE;CB87;110D 1170 11AE; +CB88;CB88;110D 1170 11AF;CB88;110D 1170 11AF; +CB89;CB89;110D 1170 11B0;CB89;110D 1170 11B0; +CB8A;CB8A;110D 1170 11B1;CB8A;110D 1170 11B1; +CB8B;CB8B;110D 1170 11B2;CB8B;110D 1170 11B2; +CB8C;CB8C;110D 1170 11B3;CB8C;110D 1170 11B3; +CB8D;CB8D;110D 1170 11B4;CB8D;110D 1170 11B4; +CB8E;CB8E;110D 1170 11B5;CB8E;110D 1170 11B5; +CB8F;CB8F;110D 1170 11B6;CB8F;110D 1170 11B6; +CB90;CB90;110D 1170 11B7;CB90;110D 1170 11B7; +CB91;CB91;110D 1170 11B8;CB91;110D 1170 11B8; +CB92;CB92;110D 1170 11B9;CB92;110D 1170 11B9; +CB93;CB93;110D 1170 11BA;CB93;110D 1170 11BA; +CB94;CB94;110D 1170 11BB;CB94;110D 1170 11BB; +CB95;CB95;110D 1170 11BC;CB95;110D 1170 11BC; +CB96;CB96;110D 1170 11BD;CB96;110D 1170 11BD; +CB97;CB97;110D 1170 11BE;CB97;110D 1170 11BE; +CB98;CB98;110D 1170 11BF;CB98;110D 1170 11BF; +CB99;CB99;110D 1170 11C0;CB99;110D 1170 11C0; +CB9A;CB9A;110D 1170 11C1;CB9A;110D 1170 11C1; +CB9B;CB9B;110D 1170 11C2;CB9B;110D 1170 11C2; +CB9C;CB9C;110D 1171;CB9C;110D 1171; +CB9D;CB9D;110D 1171 11A8;CB9D;110D 1171 11A8; +CB9E;CB9E;110D 1171 11A9;CB9E;110D 1171 11A9; +CB9F;CB9F;110D 1171 11AA;CB9F;110D 1171 11AA; +CBA0;CBA0;110D 1171 11AB;CBA0;110D 1171 11AB; +CBA1;CBA1;110D 1171 11AC;CBA1;110D 1171 11AC; +CBA2;CBA2;110D 1171 11AD;CBA2;110D 1171 11AD; +CBA3;CBA3;110D 1171 11AE;CBA3;110D 1171 11AE; +CBA4;CBA4;110D 1171 11AF;CBA4;110D 1171 11AF; +CBA5;CBA5;110D 1171 11B0;CBA5;110D 1171 11B0; +CBA6;CBA6;110D 1171 11B1;CBA6;110D 1171 11B1; +CBA7;CBA7;110D 1171 11B2;CBA7;110D 1171 11B2; +CBA8;CBA8;110D 1171 11B3;CBA8;110D 1171 11B3; +CBA9;CBA9;110D 1171 11B4;CBA9;110D 1171 11B4; +CBAA;CBAA;110D 1171 11B5;CBAA;110D 1171 11B5; +CBAB;CBAB;110D 1171 11B6;CBAB;110D 1171 11B6; +CBAC;CBAC;110D 1171 11B7;CBAC;110D 1171 11B7; +CBAD;CBAD;110D 1171 11B8;CBAD;110D 1171 11B8; +CBAE;CBAE;110D 1171 11B9;CBAE;110D 1171 11B9; +CBAF;CBAF;110D 1171 11BA;CBAF;110D 1171 11BA; +CBB0;CBB0;110D 1171 11BB;CBB0;110D 1171 11BB; +CBB1;CBB1;110D 1171 11BC;CBB1;110D 1171 11BC; +CBB2;CBB2;110D 1171 11BD;CBB2;110D 1171 11BD; +CBB3;CBB3;110D 1171 11BE;CBB3;110D 1171 11BE; +CBB4;CBB4;110D 1171 11BF;CBB4;110D 1171 11BF; +CBB5;CBB5;110D 1171 11C0;CBB5;110D 1171 11C0; +CBB6;CBB6;110D 1171 11C1;CBB6;110D 1171 11C1; +CBB7;CBB7;110D 1171 11C2;CBB7;110D 1171 11C2; +CBB8;CBB8;110D 1172;CBB8;110D 1172; +CBB9;CBB9;110D 1172 11A8;CBB9;110D 1172 11A8; +CBBA;CBBA;110D 1172 11A9;CBBA;110D 1172 11A9; +CBBB;CBBB;110D 1172 11AA;CBBB;110D 1172 11AA; +CBBC;CBBC;110D 1172 11AB;CBBC;110D 1172 11AB; +CBBD;CBBD;110D 1172 11AC;CBBD;110D 1172 11AC; +CBBE;CBBE;110D 1172 11AD;CBBE;110D 1172 11AD; +CBBF;CBBF;110D 1172 11AE;CBBF;110D 1172 11AE; +CBC0;CBC0;110D 1172 11AF;CBC0;110D 1172 11AF; +CBC1;CBC1;110D 1172 11B0;CBC1;110D 1172 11B0; +CBC2;CBC2;110D 1172 11B1;CBC2;110D 1172 11B1; +CBC3;CBC3;110D 1172 11B2;CBC3;110D 1172 11B2; +CBC4;CBC4;110D 1172 11B3;CBC4;110D 1172 11B3; +CBC5;CBC5;110D 1172 11B4;CBC5;110D 1172 11B4; +CBC6;CBC6;110D 1172 11B5;CBC6;110D 1172 11B5; +CBC7;CBC7;110D 1172 11B6;CBC7;110D 1172 11B6; +CBC8;CBC8;110D 1172 11B7;CBC8;110D 1172 11B7; +CBC9;CBC9;110D 1172 11B8;CBC9;110D 1172 11B8; +CBCA;CBCA;110D 1172 11B9;CBCA;110D 1172 11B9; +CBCB;CBCB;110D 1172 11BA;CBCB;110D 1172 11BA; +CBCC;CBCC;110D 1172 11BB;CBCC;110D 1172 11BB; +CBCD;CBCD;110D 1172 11BC;CBCD;110D 1172 11BC; +CBCE;CBCE;110D 1172 11BD;CBCE;110D 1172 11BD; +CBCF;CBCF;110D 1172 11BE;CBCF;110D 1172 11BE; +CBD0;CBD0;110D 1172 11BF;CBD0;110D 1172 11BF; +CBD1;CBD1;110D 1172 11C0;CBD1;110D 1172 11C0; +CBD2;CBD2;110D 1172 11C1;CBD2;110D 1172 11C1; +CBD3;CBD3;110D 1172 11C2;CBD3;110D 1172 11C2; +CBD4;CBD4;110D 1173;CBD4;110D 1173; +CBD5;CBD5;110D 1173 11A8;CBD5;110D 1173 11A8; +CBD6;CBD6;110D 1173 11A9;CBD6;110D 1173 11A9; +CBD7;CBD7;110D 1173 11AA;CBD7;110D 1173 11AA; +CBD8;CBD8;110D 1173 11AB;CBD8;110D 1173 11AB; +CBD9;CBD9;110D 1173 11AC;CBD9;110D 1173 11AC; +CBDA;CBDA;110D 1173 11AD;CBDA;110D 1173 11AD; +CBDB;CBDB;110D 1173 11AE;CBDB;110D 1173 11AE; +CBDC;CBDC;110D 1173 11AF;CBDC;110D 1173 11AF; +CBDD;CBDD;110D 1173 11B0;CBDD;110D 1173 11B0; +CBDE;CBDE;110D 1173 11B1;CBDE;110D 1173 11B1; +CBDF;CBDF;110D 1173 11B2;CBDF;110D 1173 11B2; +CBE0;CBE0;110D 1173 11B3;CBE0;110D 1173 11B3; +CBE1;CBE1;110D 1173 11B4;CBE1;110D 1173 11B4; +CBE2;CBE2;110D 1173 11B5;CBE2;110D 1173 11B5; +CBE3;CBE3;110D 1173 11B6;CBE3;110D 1173 11B6; +CBE4;CBE4;110D 1173 11B7;CBE4;110D 1173 11B7; +CBE5;CBE5;110D 1173 11B8;CBE5;110D 1173 11B8; +CBE6;CBE6;110D 1173 11B9;CBE6;110D 1173 11B9; +CBE7;CBE7;110D 1173 11BA;CBE7;110D 1173 11BA; +CBE8;CBE8;110D 1173 11BB;CBE8;110D 1173 11BB; +CBE9;CBE9;110D 1173 11BC;CBE9;110D 1173 11BC; +CBEA;CBEA;110D 1173 11BD;CBEA;110D 1173 11BD; +CBEB;CBEB;110D 1173 11BE;CBEB;110D 1173 11BE; +CBEC;CBEC;110D 1173 11BF;CBEC;110D 1173 11BF; +CBED;CBED;110D 1173 11C0;CBED;110D 1173 11C0; +CBEE;CBEE;110D 1173 11C1;CBEE;110D 1173 11C1; +CBEF;CBEF;110D 1173 11C2;CBEF;110D 1173 11C2; +CBF0;CBF0;110D 1174;CBF0;110D 1174; +CBF1;CBF1;110D 1174 11A8;CBF1;110D 1174 11A8; +CBF2;CBF2;110D 1174 11A9;CBF2;110D 1174 11A9; +CBF3;CBF3;110D 1174 11AA;CBF3;110D 1174 11AA; +CBF4;CBF4;110D 1174 11AB;CBF4;110D 1174 11AB; +CBF5;CBF5;110D 1174 11AC;CBF5;110D 1174 11AC; +CBF6;CBF6;110D 1174 11AD;CBF6;110D 1174 11AD; +CBF7;CBF7;110D 1174 11AE;CBF7;110D 1174 11AE; +CBF8;CBF8;110D 1174 11AF;CBF8;110D 1174 11AF; +CBF9;CBF9;110D 1174 11B0;CBF9;110D 1174 11B0; +CBFA;CBFA;110D 1174 11B1;CBFA;110D 1174 11B1; +CBFB;CBFB;110D 1174 11B2;CBFB;110D 1174 11B2; +CBFC;CBFC;110D 1174 11B3;CBFC;110D 1174 11B3; +CBFD;CBFD;110D 1174 11B4;CBFD;110D 1174 11B4; +CBFE;CBFE;110D 1174 11B5;CBFE;110D 1174 11B5; +CBFF;CBFF;110D 1174 11B6;CBFF;110D 1174 11B6; +CC00;CC00;110D 1174 11B7;CC00;110D 1174 11B7; +CC01;CC01;110D 1174 11B8;CC01;110D 1174 11B8; +CC02;CC02;110D 1174 11B9;CC02;110D 1174 11B9; +CC03;CC03;110D 1174 11BA;CC03;110D 1174 11BA; +CC04;CC04;110D 1174 11BB;CC04;110D 1174 11BB; +CC05;CC05;110D 1174 11BC;CC05;110D 1174 11BC; +CC06;CC06;110D 1174 11BD;CC06;110D 1174 11BD; +CC07;CC07;110D 1174 11BE;CC07;110D 1174 11BE; +CC08;CC08;110D 1174 11BF;CC08;110D 1174 11BF; +CC09;CC09;110D 1174 11C0;CC09;110D 1174 11C0; +CC0A;CC0A;110D 1174 11C1;CC0A;110D 1174 11C1; +CC0B;CC0B;110D 1174 11C2;CC0B;110D 1174 11C2; +CC0C;CC0C;110D 1175;CC0C;110D 1175; +CC0D;CC0D;110D 1175 11A8;CC0D;110D 1175 11A8; +CC0E;CC0E;110D 1175 11A9;CC0E;110D 1175 11A9; +CC0F;CC0F;110D 1175 11AA;CC0F;110D 1175 11AA; +CC10;CC10;110D 1175 11AB;CC10;110D 1175 11AB; +CC11;CC11;110D 1175 11AC;CC11;110D 1175 11AC; +CC12;CC12;110D 1175 11AD;CC12;110D 1175 11AD; +CC13;CC13;110D 1175 11AE;CC13;110D 1175 11AE; +CC14;CC14;110D 1175 11AF;CC14;110D 1175 11AF; +CC15;CC15;110D 1175 11B0;CC15;110D 1175 11B0; +CC16;CC16;110D 1175 11B1;CC16;110D 1175 11B1; +CC17;CC17;110D 1175 11B2;CC17;110D 1175 11B2; +CC18;CC18;110D 1175 11B3;CC18;110D 1175 11B3; +CC19;CC19;110D 1175 11B4;CC19;110D 1175 11B4; +CC1A;CC1A;110D 1175 11B5;CC1A;110D 1175 11B5; +CC1B;CC1B;110D 1175 11B6;CC1B;110D 1175 11B6; +CC1C;CC1C;110D 1175 11B7;CC1C;110D 1175 11B7; +CC1D;CC1D;110D 1175 11B8;CC1D;110D 1175 11B8; +CC1E;CC1E;110D 1175 11B9;CC1E;110D 1175 11B9; +CC1F;CC1F;110D 1175 11BA;CC1F;110D 1175 11BA; +CC20;CC20;110D 1175 11BB;CC20;110D 1175 11BB; +CC21;CC21;110D 1175 11BC;CC21;110D 1175 11BC; +CC22;CC22;110D 1175 11BD;CC22;110D 1175 11BD; +CC23;CC23;110D 1175 11BE;CC23;110D 1175 11BE; +CC24;CC24;110D 1175 11BF;CC24;110D 1175 11BF; +CC25;CC25;110D 1175 11C0;CC25;110D 1175 11C0; +CC26;CC26;110D 1175 11C1;CC26;110D 1175 11C1; +CC27;CC27;110D 1175 11C2;CC27;110D 1175 11C2; +CC28;CC28;110E 1161;CC28;110E 1161; +CC29;CC29;110E 1161 11A8;CC29;110E 1161 11A8; +CC2A;CC2A;110E 1161 11A9;CC2A;110E 1161 11A9; +CC2B;CC2B;110E 1161 11AA;CC2B;110E 1161 11AA; +CC2C;CC2C;110E 1161 11AB;CC2C;110E 1161 11AB; +CC2D;CC2D;110E 1161 11AC;CC2D;110E 1161 11AC; +CC2E;CC2E;110E 1161 11AD;CC2E;110E 1161 11AD; +CC2F;CC2F;110E 1161 11AE;CC2F;110E 1161 11AE; +CC30;CC30;110E 1161 11AF;CC30;110E 1161 11AF; +CC31;CC31;110E 1161 11B0;CC31;110E 1161 11B0; +CC32;CC32;110E 1161 11B1;CC32;110E 1161 11B1; +CC33;CC33;110E 1161 11B2;CC33;110E 1161 11B2; +CC34;CC34;110E 1161 11B3;CC34;110E 1161 11B3; +CC35;CC35;110E 1161 11B4;CC35;110E 1161 11B4; +CC36;CC36;110E 1161 11B5;CC36;110E 1161 11B5; +CC37;CC37;110E 1161 11B6;CC37;110E 1161 11B6; +CC38;CC38;110E 1161 11B7;CC38;110E 1161 11B7; +CC39;CC39;110E 1161 11B8;CC39;110E 1161 11B8; +CC3A;CC3A;110E 1161 11B9;CC3A;110E 1161 11B9; +CC3B;CC3B;110E 1161 11BA;CC3B;110E 1161 11BA; +CC3C;CC3C;110E 1161 11BB;CC3C;110E 1161 11BB; +CC3D;CC3D;110E 1161 11BC;CC3D;110E 1161 11BC; +CC3E;CC3E;110E 1161 11BD;CC3E;110E 1161 11BD; +CC3F;CC3F;110E 1161 11BE;CC3F;110E 1161 11BE; +CC40;CC40;110E 1161 11BF;CC40;110E 1161 11BF; +CC41;CC41;110E 1161 11C0;CC41;110E 1161 11C0; +CC42;CC42;110E 1161 11C1;CC42;110E 1161 11C1; +CC43;CC43;110E 1161 11C2;CC43;110E 1161 11C2; +CC44;CC44;110E 1162;CC44;110E 1162; +CC45;CC45;110E 1162 11A8;CC45;110E 1162 11A8; +CC46;CC46;110E 1162 11A9;CC46;110E 1162 11A9; +CC47;CC47;110E 1162 11AA;CC47;110E 1162 11AA; +CC48;CC48;110E 1162 11AB;CC48;110E 1162 11AB; +CC49;CC49;110E 1162 11AC;CC49;110E 1162 11AC; +CC4A;CC4A;110E 1162 11AD;CC4A;110E 1162 11AD; +CC4B;CC4B;110E 1162 11AE;CC4B;110E 1162 11AE; +CC4C;CC4C;110E 1162 11AF;CC4C;110E 1162 11AF; +CC4D;CC4D;110E 1162 11B0;CC4D;110E 1162 11B0; +CC4E;CC4E;110E 1162 11B1;CC4E;110E 1162 11B1; +CC4F;CC4F;110E 1162 11B2;CC4F;110E 1162 11B2; +CC50;CC50;110E 1162 11B3;CC50;110E 1162 11B3; +CC51;CC51;110E 1162 11B4;CC51;110E 1162 11B4; +CC52;CC52;110E 1162 11B5;CC52;110E 1162 11B5; +CC53;CC53;110E 1162 11B6;CC53;110E 1162 11B6; +CC54;CC54;110E 1162 11B7;CC54;110E 1162 11B7; +CC55;CC55;110E 1162 11B8;CC55;110E 1162 11B8; +CC56;CC56;110E 1162 11B9;CC56;110E 1162 11B9; +CC57;CC57;110E 1162 11BA;CC57;110E 1162 11BA; +CC58;CC58;110E 1162 11BB;CC58;110E 1162 11BB; +CC59;CC59;110E 1162 11BC;CC59;110E 1162 11BC; +CC5A;CC5A;110E 1162 11BD;CC5A;110E 1162 11BD; +CC5B;CC5B;110E 1162 11BE;CC5B;110E 1162 11BE; +CC5C;CC5C;110E 1162 11BF;CC5C;110E 1162 11BF; +CC5D;CC5D;110E 1162 11C0;CC5D;110E 1162 11C0; +CC5E;CC5E;110E 1162 11C1;CC5E;110E 1162 11C1; +CC5F;CC5F;110E 1162 11C2;CC5F;110E 1162 11C2; +CC60;CC60;110E 1163;CC60;110E 1163; +CC61;CC61;110E 1163 11A8;CC61;110E 1163 11A8; +CC62;CC62;110E 1163 11A9;CC62;110E 1163 11A9; +CC63;CC63;110E 1163 11AA;CC63;110E 1163 11AA; +CC64;CC64;110E 1163 11AB;CC64;110E 1163 11AB; +CC65;CC65;110E 1163 11AC;CC65;110E 1163 11AC; +CC66;CC66;110E 1163 11AD;CC66;110E 1163 11AD; +CC67;CC67;110E 1163 11AE;CC67;110E 1163 11AE; +CC68;CC68;110E 1163 11AF;CC68;110E 1163 11AF; +CC69;CC69;110E 1163 11B0;CC69;110E 1163 11B0; +CC6A;CC6A;110E 1163 11B1;CC6A;110E 1163 11B1; +CC6B;CC6B;110E 1163 11B2;CC6B;110E 1163 11B2; +CC6C;CC6C;110E 1163 11B3;CC6C;110E 1163 11B3; +CC6D;CC6D;110E 1163 11B4;CC6D;110E 1163 11B4; +CC6E;CC6E;110E 1163 11B5;CC6E;110E 1163 11B5; +CC6F;CC6F;110E 1163 11B6;CC6F;110E 1163 11B6; +CC70;CC70;110E 1163 11B7;CC70;110E 1163 11B7; +CC71;CC71;110E 1163 11B8;CC71;110E 1163 11B8; +CC72;CC72;110E 1163 11B9;CC72;110E 1163 11B9; +CC73;CC73;110E 1163 11BA;CC73;110E 1163 11BA; +CC74;CC74;110E 1163 11BB;CC74;110E 1163 11BB; +CC75;CC75;110E 1163 11BC;CC75;110E 1163 11BC; +CC76;CC76;110E 1163 11BD;CC76;110E 1163 11BD; +CC77;CC77;110E 1163 11BE;CC77;110E 1163 11BE; +CC78;CC78;110E 1163 11BF;CC78;110E 1163 11BF; +CC79;CC79;110E 1163 11C0;CC79;110E 1163 11C0; +CC7A;CC7A;110E 1163 11C1;CC7A;110E 1163 11C1; +CC7B;CC7B;110E 1163 11C2;CC7B;110E 1163 11C2; +CC7C;CC7C;110E 1164;CC7C;110E 1164; +CC7D;CC7D;110E 1164 11A8;CC7D;110E 1164 11A8; +CC7E;CC7E;110E 1164 11A9;CC7E;110E 1164 11A9; +CC7F;CC7F;110E 1164 11AA;CC7F;110E 1164 11AA; +CC80;CC80;110E 1164 11AB;CC80;110E 1164 11AB; +CC81;CC81;110E 1164 11AC;CC81;110E 1164 11AC; +CC82;CC82;110E 1164 11AD;CC82;110E 1164 11AD; +CC83;CC83;110E 1164 11AE;CC83;110E 1164 11AE; +CC84;CC84;110E 1164 11AF;CC84;110E 1164 11AF; +CC85;CC85;110E 1164 11B0;CC85;110E 1164 11B0; +CC86;CC86;110E 1164 11B1;CC86;110E 1164 11B1; +CC87;CC87;110E 1164 11B2;CC87;110E 1164 11B2; +CC88;CC88;110E 1164 11B3;CC88;110E 1164 11B3; +CC89;CC89;110E 1164 11B4;CC89;110E 1164 11B4; +CC8A;CC8A;110E 1164 11B5;CC8A;110E 1164 11B5; +CC8B;CC8B;110E 1164 11B6;CC8B;110E 1164 11B6; +CC8C;CC8C;110E 1164 11B7;CC8C;110E 1164 11B7; +CC8D;CC8D;110E 1164 11B8;CC8D;110E 1164 11B8; +CC8E;CC8E;110E 1164 11B9;CC8E;110E 1164 11B9; +CC8F;CC8F;110E 1164 11BA;CC8F;110E 1164 11BA; +CC90;CC90;110E 1164 11BB;CC90;110E 1164 11BB; +CC91;CC91;110E 1164 11BC;CC91;110E 1164 11BC; +CC92;CC92;110E 1164 11BD;CC92;110E 1164 11BD; +CC93;CC93;110E 1164 11BE;CC93;110E 1164 11BE; +CC94;CC94;110E 1164 11BF;CC94;110E 1164 11BF; +CC95;CC95;110E 1164 11C0;CC95;110E 1164 11C0; +CC96;CC96;110E 1164 11C1;CC96;110E 1164 11C1; +CC97;CC97;110E 1164 11C2;CC97;110E 1164 11C2; +CC98;CC98;110E 1165;CC98;110E 1165; +CC99;CC99;110E 1165 11A8;CC99;110E 1165 11A8; +CC9A;CC9A;110E 1165 11A9;CC9A;110E 1165 11A9; +CC9B;CC9B;110E 1165 11AA;CC9B;110E 1165 11AA; +CC9C;CC9C;110E 1165 11AB;CC9C;110E 1165 11AB; +CC9D;CC9D;110E 1165 11AC;CC9D;110E 1165 11AC; +CC9E;CC9E;110E 1165 11AD;CC9E;110E 1165 11AD; +CC9F;CC9F;110E 1165 11AE;CC9F;110E 1165 11AE; +CCA0;CCA0;110E 1165 11AF;CCA0;110E 1165 11AF; +CCA1;CCA1;110E 1165 11B0;CCA1;110E 1165 11B0; +CCA2;CCA2;110E 1165 11B1;CCA2;110E 1165 11B1; +CCA3;CCA3;110E 1165 11B2;CCA3;110E 1165 11B2; +CCA4;CCA4;110E 1165 11B3;CCA4;110E 1165 11B3; +CCA5;CCA5;110E 1165 11B4;CCA5;110E 1165 11B4; +CCA6;CCA6;110E 1165 11B5;CCA6;110E 1165 11B5; +CCA7;CCA7;110E 1165 11B6;CCA7;110E 1165 11B6; +CCA8;CCA8;110E 1165 11B7;CCA8;110E 1165 11B7; +CCA9;CCA9;110E 1165 11B8;CCA9;110E 1165 11B8; +CCAA;CCAA;110E 1165 11B9;CCAA;110E 1165 11B9; +CCAB;CCAB;110E 1165 11BA;CCAB;110E 1165 11BA; +CCAC;CCAC;110E 1165 11BB;CCAC;110E 1165 11BB; +CCAD;CCAD;110E 1165 11BC;CCAD;110E 1165 11BC; +CCAE;CCAE;110E 1165 11BD;CCAE;110E 1165 11BD; +CCAF;CCAF;110E 1165 11BE;CCAF;110E 1165 11BE; +CCB0;CCB0;110E 1165 11BF;CCB0;110E 1165 11BF; +CCB1;CCB1;110E 1165 11C0;CCB1;110E 1165 11C0; +CCB2;CCB2;110E 1165 11C1;CCB2;110E 1165 11C1; +CCB3;CCB3;110E 1165 11C2;CCB3;110E 1165 11C2; +CCB4;CCB4;110E 1166;CCB4;110E 1166; +CCB5;CCB5;110E 1166 11A8;CCB5;110E 1166 11A8; +CCB6;CCB6;110E 1166 11A9;CCB6;110E 1166 11A9; +CCB7;CCB7;110E 1166 11AA;CCB7;110E 1166 11AA; +CCB8;CCB8;110E 1166 11AB;CCB8;110E 1166 11AB; +CCB9;CCB9;110E 1166 11AC;CCB9;110E 1166 11AC; +CCBA;CCBA;110E 1166 11AD;CCBA;110E 1166 11AD; +CCBB;CCBB;110E 1166 11AE;CCBB;110E 1166 11AE; +CCBC;CCBC;110E 1166 11AF;CCBC;110E 1166 11AF; +CCBD;CCBD;110E 1166 11B0;CCBD;110E 1166 11B0; +CCBE;CCBE;110E 1166 11B1;CCBE;110E 1166 11B1; +CCBF;CCBF;110E 1166 11B2;CCBF;110E 1166 11B2; +CCC0;CCC0;110E 1166 11B3;CCC0;110E 1166 11B3; +CCC1;CCC1;110E 1166 11B4;CCC1;110E 1166 11B4; +CCC2;CCC2;110E 1166 11B5;CCC2;110E 1166 11B5; +CCC3;CCC3;110E 1166 11B6;CCC3;110E 1166 11B6; +CCC4;CCC4;110E 1166 11B7;CCC4;110E 1166 11B7; +CCC5;CCC5;110E 1166 11B8;CCC5;110E 1166 11B8; +CCC6;CCC6;110E 1166 11B9;CCC6;110E 1166 11B9; +CCC7;CCC7;110E 1166 11BA;CCC7;110E 1166 11BA; +CCC8;CCC8;110E 1166 11BB;CCC8;110E 1166 11BB; +CCC9;CCC9;110E 1166 11BC;CCC9;110E 1166 11BC; +CCCA;CCCA;110E 1166 11BD;CCCA;110E 1166 11BD; +CCCB;CCCB;110E 1166 11BE;CCCB;110E 1166 11BE; +CCCC;CCCC;110E 1166 11BF;CCCC;110E 1166 11BF; +CCCD;CCCD;110E 1166 11C0;CCCD;110E 1166 11C0; +CCCE;CCCE;110E 1166 11C1;CCCE;110E 1166 11C1; +CCCF;CCCF;110E 1166 11C2;CCCF;110E 1166 11C2; +CCD0;CCD0;110E 1167;CCD0;110E 1167; +CCD1;CCD1;110E 1167 11A8;CCD1;110E 1167 11A8; +CCD2;CCD2;110E 1167 11A9;CCD2;110E 1167 11A9; +CCD3;CCD3;110E 1167 11AA;CCD3;110E 1167 11AA; +CCD4;CCD4;110E 1167 11AB;CCD4;110E 1167 11AB; +CCD5;CCD5;110E 1167 11AC;CCD5;110E 1167 11AC; +CCD6;CCD6;110E 1167 11AD;CCD6;110E 1167 11AD; +CCD7;CCD7;110E 1167 11AE;CCD7;110E 1167 11AE; +CCD8;CCD8;110E 1167 11AF;CCD8;110E 1167 11AF; +CCD9;CCD9;110E 1167 11B0;CCD9;110E 1167 11B0; +CCDA;CCDA;110E 1167 11B1;CCDA;110E 1167 11B1; +CCDB;CCDB;110E 1167 11B2;CCDB;110E 1167 11B2; +CCDC;CCDC;110E 1167 11B3;CCDC;110E 1167 11B3; +CCDD;CCDD;110E 1167 11B4;CCDD;110E 1167 11B4; +CCDE;CCDE;110E 1167 11B5;CCDE;110E 1167 11B5; +CCDF;CCDF;110E 1167 11B6;CCDF;110E 1167 11B6; +CCE0;CCE0;110E 1167 11B7;CCE0;110E 1167 11B7; +CCE1;CCE1;110E 1167 11B8;CCE1;110E 1167 11B8; +CCE2;CCE2;110E 1167 11B9;CCE2;110E 1167 11B9; +CCE3;CCE3;110E 1167 11BA;CCE3;110E 1167 11BA; +CCE4;CCE4;110E 1167 11BB;CCE4;110E 1167 11BB; +CCE5;CCE5;110E 1167 11BC;CCE5;110E 1167 11BC; +CCE6;CCE6;110E 1167 11BD;CCE6;110E 1167 11BD; +CCE7;CCE7;110E 1167 11BE;CCE7;110E 1167 11BE; +CCE8;CCE8;110E 1167 11BF;CCE8;110E 1167 11BF; +CCE9;CCE9;110E 1167 11C0;CCE9;110E 1167 11C0; +CCEA;CCEA;110E 1167 11C1;CCEA;110E 1167 11C1; +CCEB;CCEB;110E 1167 11C2;CCEB;110E 1167 11C2; +CCEC;CCEC;110E 1168;CCEC;110E 1168; +CCED;CCED;110E 1168 11A8;CCED;110E 1168 11A8; +CCEE;CCEE;110E 1168 11A9;CCEE;110E 1168 11A9; +CCEF;CCEF;110E 1168 11AA;CCEF;110E 1168 11AA; +CCF0;CCF0;110E 1168 11AB;CCF0;110E 1168 11AB; +CCF1;CCF1;110E 1168 11AC;CCF1;110E 1168 11AC; +CCF2;CCF2;110E 1168 11AD;CCF2;110E 1168 11AD; +CCF3;CCF3;110E 1168 11AE;CCF3;110E 1168 11AE; +CCF4;CCF4;110E 1168 11AF;CCF4;110E 1168 11AF; +CCF5;CCF5;110E 1168 11B0;CCF5;110E 1168 11B0; +CCF6;CCF6;110E 1168 11B1;CCF6;110E 1168 11B1; +CCF7;CCF7;110E 1168 11B2;CCF7;110E 1168 11B2; +CCF8;CCF8;110E 1168 11B3;CCF8;110E 1168 11B3; +CCF9;CCF9;110E 1168 11B4;CCF9;110E 1168 11B4; +CCFA;CCFA;110E 1168 11B5;CCFA;110E 1168 11B5; +CCFB;CCFB;110E 1168 11B6;CCFB;110E 1168 11B6; +CCFC;CCFC;110E 1168 11B7;CCFC;110E 1168 11B7; +CCFD;CCFD;110E 1168 11B8;CCFD;110E 1168 11B8; +CCFE;CCFE;110E 1168 11B9;CCFE;110E 1168 11B9; +CCFF;CCFF;110E 1168 11BA;CCFF;110E 1168 11BA; +CD00;CD00;110E 1168 11BB;CD00;110E 1168 11BB; +CD01;CD01;110E 1168 11BC;CD01;110E 1168 11BC; +CD02;CD02;110E 1168 11BD;CD02;110E 1168 11BD; +CD03;CD03;110E 1168 11BE;CD03;110E 1168 11BE; +CD04;CD04;110E 1168 11BF;CD04;110E 1168 11BF; +CD05;CD05;110E 1168 11C0;CD05;110E 1168 11C0; +CD06;CD06;110E 1168 11C1;CD06;110E 1168 11C1; +CD07;CD07;110E 1168 11C2;CD07;110E 1168 11C2; +CD08;CD08;110E 1169;CD08;110E 1169; +CD09;CD09;110E 1169 11A8;CD09;110E 1169 11A8; +CD0A;CD0A;110E 1169 11A9;CD0A;110E 1169 11A9; +CD0B;CD0B;110E 1169 11AA;CD0B;110E 1169 11AA; +CD0C;CD0C;110E 1169 11AB;CD0C;110E 1169 11AB; +CD0D;CD0D;110E 1169 11AC;CD0D;110E 1169 11AC; +CD0E;CD0E;110E 1169 11AD;CD0E;110E 1169 11AD; +CD0F;CD0F;110E 1169 11AE;CD0F;110E 1169 11AE; +CD10;CD10;110E 1169 11AF;CD10;110E 1169 11AF; +CD11;CD11;110E 1169 11B0;CD11;110E 1169 11B0; +CD12;CD12;110E 1169 11B1;CD12;110E 1169 11B1; +CD13;CD13;110E 1169 11B2;CD13;110E 1169 11B2; +CD14;CD14;110E 1169 11B3;CD14;110E 1169 11B3; +CD15;CD15;110E 1169 11B4;CD15;110E 1169 11B4; +CD16;CD16;110E 1169 11B5;CD16;110E 1169 11B5; +CD17;CD17;110E 1169 11B6;CD17;110E 1169 11B6; +CD18;CD18;110E 1169 11B7;CD18;110E 1169 11B7; +CD19;CD19;110E 1169 11B8;CD19;110E 1169 11B8; +CD1A;CD1A;110E 1169 11B9;CD1A;110E 1169 11B9; +CD1B;CD1B;110E 1169 11BA;CD1B;110E 1169 11BA; +CD1C;CD1C;110E 1169 11BB;CD1C;110E 1169 11BB; +CD1D;CD1D;110E 1169 11BC;CD1D;110E 1169 11BC; +CD1E;CD1E;110E 1169 11BD;CD1E;110E 1169 11BD; +CD1F;CD1F;110E 1169 11BE;CD1F;110E 1169 11BE; +CD20;CD20;110E 1169 11BF;CD20;110E 1169 11BF; +CD21;CD21;110E 1169 11C0;CD21;110E 1169 11C0; +CD22;CD22;110E 1169 11C1;CD22;110E 1169 11C1; +CD23;CD23;110E 1169 11C2;CD23;110E 1169 11C2; +CD24;CD24;110E 116A;CD24;110E 116A; +CD25;CD25;110E 116A 11A8;CD25;110E 116A 11A8; +CD26;CD26;110E 116A 11A9;CD26;110E 116A 11A9; +CD27;CD27;110E 116A 11AA;CD27;110E 116A 11AA; +CD28;CD28;110E 116A 11AB;CD28;110E 116A 11AB; +CD29;CD29;110E 116A 11AC;CD29;110E 116A 11AC; +CD2A;CD2A;110E 116A 11AD;CD2A;110E 116A 11AD; +CD2B;CD2B;110E 116A 11AE;CD2B;110E 116A 11AE; +CD2C;CD2C;110E 116A 11AF;CD2C;110E 116A 11AF; +CD2D;CD2D;110E 116A 11B0;CD2D;110E 116A 11B0; +CD2E;CD2E;110E 116A 11B1;CD2E;110E 116A 11B1; +CD2F;CD2F;110E 116A 11B2;CD2F;110E 116A 11B2; +CD30;CD30;110E 116A 11B3;CD30;110E 116A 11B3; +CD31;CD31;110E 116A 11B4;CD31;110E 116A 11B4; +CD32;CD32;110E 116A 11B5;CD32;110E 116A 11B5; +CD33;CD33;110E 116A 11B6;CD33;110E 116A 11B6; +CD34;CD34;110E 116A 11B7;CD34;110E 116A 11B7; +CD35;CD35;110E 116A 11B8;CD35;110E 116A 11B8; +CD36;CD36;110E 116A 11B9;CD36;110E 116A 11B9; +CD37;CD37;110E 116A 11BA;CD37;110E 116A 11BA; +CD38;CD38;110E 116A 11BB;CD38;110E 116A 11BB; +CD39;CD39;110E 116A 11BC;CD39;110E 116A 11BC; +CD3A;CD3A;110E 116A 11BD;CD3A;110E 116A 11BD; +CD3B;CD3B;110E 116A 11BE;CD3B;110E 116A 11BE; +CD3C;CD3C;110E 116A 11BF;CD3C;110E 116A 11BF; +CD3D;CD3D;110E 116A 11C0;CD3D;110E 116A 11C0; +CD3E;CD3E;110E 116A 11C1;CD3E;110E 116A 11C1; +CD3F;CD3F;110E 116A 11C2;CD3F;110E 116A 11C2; +CD40;CD40;110E 116B;CD40;110E 116B; +CD41;CD41;110E 116B 11A8;CD41;110E 116B 11A8; +CD42;CD42;110E 116B 11A9;CD42;110E 116B 11A9; +CD43;CD43;110E 116B 11AA;CD43;110E 116B 11AA; +CD44;CD44;110E 116B 11AB;CD44;110E 116B 11AB; +CD45;CD45;110E 116B 11AC;CD45;110E 116B 11AC; +CD46;CD46;110E 116B 11AD;CD46;110E 116B 11AD; +CD47;CD47;110E 116B 11AE;CD47;110E 116B 11AE; +CD48;CD48;110E 116B 11AF;CD48;110E 116B 11AF; +CD49;CD49;110E 116B 11B0;CD49;110E 116B 11B0; +CD4A;CD4A;110E 116B 11B1;CD4A;110E 116B 11B1; +CD4B;CD4B;110E 116B 11B2;CD4B;110E 116B 11B2; +CD4C;CD4C;110E 116B 11B3;CD4C;110E 116B 11B3; +CD4D;CD4D;110E 116B 11B4;CD4D;110E 116B 11B4; +CD4E;CD4E;110E 116B 11B5;CD4E;110E 116B 11B5; +CD4F;CD4F;110E 116B 11B6;CD4F;110E 116B 11B6; +CD50;CD50;110E 116B 11B7;CD50;110E 116B 11B7; +CD51;CD51;110E 116B 11B8;CD51;110E 116B 11B8; +CD52;CD52;110E 116B 11B9;CD52;110E 116B 11B9; +CD53;CD53;110E 116B 11BA;CD53;110E 116B 11BA; +CD54;CD54;110E 116B 11BB;CD54;110E 116B 11BB; +CD55;CD55;110E 116B 11BC;CD55;110E 116B 11BC; +CD56;CD56;110E 116B 11BD;CD56;110E 116B 11BD; +CD57;CD57;110E 116B 11BE;CD57;110E 116B 11BE; +CD58;CD58;110E 116B 11BF;CD58;110E 116B 11BF; +CD59;CD59;110E 116B 11C0;CD59;110E 116B 11C0; +CD5A;CD5A;110E 116B 11C1;CD5A;110E 116B 11C1; +CD5B;CD5B;110E 116B 11C2;CD5B;110E 116B 11C2; +CD5C;CD5C;110E 116C;CD5C;110E 116C; +CD5D;CD5D;110E 116C 11A8;CD5D;110E 116C 11A8; +CD5E;CD5E;110E 116C 11A9;CD5E;110E 116C 11A9; +CD5F;CD5F;110E 116C 11AA;CD5F;110E 116C 11AA; +CD60;CD60;110E 116C 11AB;CD60;110E 116C 11AB; +CD61;CD61;110E 116C 11AC;CD61;110E 116C 11AC; +CD62;CD62;110E 116C 11AD;CD62;110E 116C 11AD; +CD63;CD63;110E 116C 11AE;CD63;110E 116C 11AE; +CD64;CD64;110E 116C 11AF;CD64;110E 116C 11AF; +CD65;CD65;110E 116C 11B0;CD65;110E 116C 11B0; +CD66;CD66;110E 116C 11B1;CD66;110E 116C 11B1; +CD67;CD67;110E 116C 11B2;CD67;110E 116C 11B2; +CD68;CD68;110E 116C 11B3;CD68;110E 116C 11B3; +CD69;CD69;110E 116C 11B4;CD69;110E 116C 11B4; +CD6A;CD6A;110E 116C 11B5;CD6A;110E 116C 11B5; +CD6B;CD6B;110E 116C 11B6;CD6B;110E 116C 11B6; +CD6C;CD6C;110E 116C 11B7;CD6C;110E 116C 11B7; +CD6D;CD6D;110E 116C 11B8;CD6D;110E 116C 11B8; +CD6E;CD6E;110E 116C 11B9;CD6E;110E 116C 11B9; +CD6F;CD6F;110E 116C 11BA;CD6F;110E 116C 11BA; +CD70;CD70;110E 116C 11BB;CD70;110E 116C 11BB; +CD71;CD71;110E 116C 11BC;CD71;110E 116C 11BC; +CD72;CD72;110E 116C 11BD;CD72;110E 116C 11BD; +CD73;CD73;110E 116C 11BE;CD73;110E 116C 11BE; +CD74;CD74;110E 116C 11BF;CD74;110E 116C 11BF; +CD75;CD75;110E 116C 11C0;CD75;110E 116C 11C0; +CD76;CD76;110E 116C 11C1;CD76;110E 116C 11C1; +CD77;CD77;110E 116C 11C2;CD77;110E 116C 11C2; +CD78;CD78;110E 116D;CD78;110E 116D; +CD79;CD79;110E 116D 11A8;CD79;110E 116D 11A8; +CD7A;CD7A;110E 116D 11A9;CD7A;110E 116D 11A9; +CD7B;CD7B;110E 116D 11AA;CD7B;110E 116D 11AA; +CD7C;CD7C;110E 116D 11AB;CD7C;110E 116D 11AB; +CD7D;CD7D;110E 116D 11AC;CD7D;110E 116D 11AC; +CD7E;CD7E;110E 116D 11AD;CD7E;110E 116D 11AD; +CD7F;CD7F;110E 116D 11AE;CD7F;110E 116D 11AE; +CD80;CD80;110E 116D 11AF;CD80;110E 116D 11AF; +CD81;CD81;110E 116D 11B0;CD81;110E 116D 11B0; +CD82;CD82;110E 116D 11B1;CD82;110E 116D 11B1; +CD83;CD83;110E 116D 11B2;CD83;110E 116D 11B2; +CD84;CD84;110E 116D 11B3;CD84;110E 116D 11B3; +CD85;CD85;110E 116D 11B4;CD85;110E 116D 11B4; +CD86;CD86;110E 116D 11B5;CD86;110E 116D 11B5; +CD87;CD87;110E 116D 11B6;CD87;110E 116D 11B6; +CD88;CD88;110E 116D 11B7;CD88;110E 116D 11B7; +CD89;CD89;110E 116D 11B8;CD89;110E 116D 11B8; +CD8A;CD8A;110E 116D 11B9;CD8A;110E 116D 11B9; +CD8B;CD8B;110E 116D 11BA;CD8B;110E 116D 11BA; +CD8C;CD8C;110E 116D 11BB;CD8C;110E 116D 11BB; +CD8D;CD8D;110E 116D 11BC;CD8D;110E 116D 11BC; +CD8E;CD8E;110E 116D 11BD;CD8E;110E 116D 11BD; +CD8F;CD8F;110E 116D 11BE;CD8F;110E 116D 11BE; +CD90;CD90;110E 116D 11BF;CD90;110E 116D 11BF; +CD91;CD91;110E 116D 11C0;CD91;110E 116D 11C0; +CD92;CD92;110E 116D 11C1;CD92;110E 116D 11C1; +CD93;CD93;110E 116D 11C2;CD93;110E 116D 11C2; +CD94;CD94;110E 116E;CD94;110E 116E; +CD95;CD95;110E 116E 11A8;CD95;110E 116E 11A8; +CD96;CD96;110E 116E 11A9;CD96;110E 116E 11A9; +CD97;CD97;110E 116E 11AA;CD97;110E 116E 11AA; +CD98;CD98;110E 116E 11AB;CD98;110E 116E 11AB; +CD99;CD99;110E 116E 11AC;CD99;110E 116E 11AC; +CD9A;CD9A;110E 116E 11AD;CD9A;110E 116E 11AD; +CD9B;CD9B;110E 116E 11AE;CD9B;110E 116E 11AE; +CD9C;CD9C;110E 116E 11AF;CD9C;110E 116E 11AF; +CD9D;CD9D;110E 116E 11B0;CD9D;110E 116E 11B0; +CD9E;CD9E;110E 116E 11B1;CD9E;110E 116E 11B1; +CD9F;CD9F;110E 116E 11B2;CD9F;110E 116E 11B2; +CDA0;CDA0;110E 116E 11B3;CDA0;110E 116E 11B3; +CDA1;CDA1;110E 116E 11B4;CDA1;110E 116E 11B4; +CDA2;CDA2;110E 116E 11B5;CDA2;110E 116E 11B5; +CDA3;CDA3;110E 116E 11B6;CDA3;110E 116E 11B6; +CDA4;CDA4;110E 116E 11B7;CDA4;110E 116E 11B7; +CDA5;CDA5;110E 116E 11B8;CDA5;110E 116E 11B8; +CDA6;CDA6;110E 116E 11B9;CDA6;110E 116E 11B9; +CDA7;CDA7;110E 116E 11BA;CDA7;110E 116E 11BA; +CDA8;CDA8;110E 116E 11BB;CDA8;110E 116E 11BB; +CDA9;CDA9;110E 116E 11BC;CDA9;110E 116E 11BC; +CDAA;CDAA;110E 116E 11BD;CDAA;110E 116E 11BD; +CDAB;CDAB;110E 116E 11BE;CDAB;110E 116E 11BE; +CDAC;CDAC;110E 116E 11BF;CDAC;110E 116E 11BF; +CDAD;CDAD;110E 116E 11C0;CDAD;110E 116E 11C0; +CDAE;CDAE;110E 116E 11C1;CDAE;110E 116E 11C1; +CDAF;CDAF;110E 116E 11C2;CDAF;110E 116E 11C2; +CDB0;CDB0;110E 116F;CDB0;110E 116F; +CDB1;CDB1;110E 116F 11A8;CDB1;110E 116F 11A8; +CDB2;CDB2;110E 116F 11A9;CDB2;110E 116F 11A9; +CDB3;CDB3;110E 116F 11AA;CDB3;110E 116F 11AA; +CDB4;CDB4;110E 116F 11AB;CDB4;110E 116F 11AB; +CDB5;CDB5;110E 116F 11AC;CDB5;110E 116F 11AC; +CDB6;CDB6;110E 116F 11AD;CDB6;110E 116F 11AD; +CDB7;CDB7;110E 116F 11AE;CDB7;110E 116F 11AE; +CDB8;CDB8;110E 116F 11AF;CDB8;110E 116F 11AF; +CDB9;CDB9;110E 116F 11B0;CDB9;110E 116F 11B0; +CDBA;CDBA;110E 116F 11B1;CDBA;110E 116F 11B1; +CDBB;CDBB;110E 116F 11B2;CDBB;110E 116F 11B2; +CDBC;CDBC;110E 116F 11B3;CDBC;110E 116F 11B3; +CDBD;CDBD;110E 116F 11B4;CDBD;110E 116F 11B4; +CDBE;CDBE;110E 116F 11B5;CDBE;110E 116F 11B5; +CDBF;CDBF;110E 116F 11B6;CDBF;110E 116F 11B6; +CDC0;CDC0;110E 116F 11B7;CDC0;110E 116F 11B7; +CDC1;CDC1;110E 116F 11B8;CDC1;110E 116F 11B8; +CDC2;CDC2;110E 116F 11B9;CDC2;110E 116F 11B9; +CDC3;CDC3;110E 116F 11BA;CDC3;110E 116F 11BA; +CDC4;CDC4;110E 116F 11BB;CDC4;110E 116F 11BB; +CDC5;CDC5;110E 116F 11BC;CDC5;110E 116F 11BC; +CDC6;CDC6;110E 116F 11BD;CDC6;110E 116F 11BD; +CDC7;CDC7;110E 116F 11BE;CDC7;110E 116F 11BE; +CDC8;CDC8;110E 116F 11BF;CDC8;110E 116F 11BF; +CDC9;CDC9;110E 116F 11C0;CDC9;110E 116F 11C0; +CDCA;CDCA;110E 116F 11C1;CDCA;110E 116F 11C1; +CDCB;CDCB;110E 116F 11C2;CDCB;110E 116F 11C2; +CDCC;CDCC;110E 1170;CDCC;110E 1170; +CDCD;CDCD;110E 1170 11A8;CDCD;110E 1170 11A8; +CDCE;CDCE;110E 1170 11A9;CDCE;110E 1170 11A9; +CDCF;CDCF;110E 1170 11AA;CDCF;110E 1170 11AA; +CDD0;CDD0;110E 1170 11AB;CDD0;110E 1170 11AB; +CDD1;CDD1;110E 1170 11AC;CDD1;110E 1170 11AC; +CDD2;CDD2;110E 1170 11AD;CDD2;110E 1170 11AD; +CDD3;CDD3;110E 1170 11AE;CDD3;110E 1170 11AE; +CDD4;CDD4;110E 1170 11AF;CDD4;110E 1170 11AF; +CDD5;CDD5;110E 1170 11B0;CDD5;110E 1170 11B0; +CDD6;CDD6;110E 1170 11B1;CDD6;110E 1170 11B1; +CDD7;CDD7;110E 1170 11B2;CDD7;110E 1170 11B2; +CDD8;CDD8;110E 1170 11B3;CDD8;110E 1170 11B3; +CDD9;CDD9;110E 1170 11B4;CDD9;110E 1170 11B4; +CDDA;CDDA;110E 1170 11B5;CDDA;110E 1170 11B5; +CDDB;CDDB;110E 1170 11B6;CDDB;110E 1170 11B6; +CDDC;CDDC;110E 1170 11B7;CDDC;110E 1170 11B7; +CDDD;CDDD;110E 1170 11B8;CDDD;110E 1170 11B8; +CDDE;CDDE;110E 1170 11B9;CDDE;110E 1170 11B9; +CDDF;CDDF;110E 1170 11BA;CDDF;110E 1170 11BA; +CDE0;CDE0;110E 1170 11BB;CDE0;110E 1170 11BB; +CDE1;CDE1;110E 1170 11BC;CDE1;110E 1170 11BC; +CDE2;CDE2;110E 1170 11BD;CDE2;110E 1170 11BD; +CDE3;CDE3;110E 1170 11BE;CDE3;110E 1170 11BE; +CDE4;CDE4;110E 1170 11BF;CDE4;110E 1170 11BF; +CDE5;CDE5;110E 1170 11C0;CDE5;110E 1170 11C0; +CDE6;CDE6;110E 1170 11C1;CDE6;110E 1170 11C1; +CDE7;CDE7;110E 1170 11C2;CDE7;110E 1170 11C2; +CDE8;CDE8;110E 1171;CDE8;110E 1171; +CDE9;CDE9;110E 1171 11A8;CDE9;110E 1171 11A8; +CDEA;CDEA;110E 1171 11A9;CDEA;110E 1171 11A9; +CDEB;CDEB;110E 1171 11AA;CDEB;110E 1171 11AA; +CDEC;CDEC;110E 1171 11AB;CDEC;110E 1171 11AB; +CDED;CDED;110E 1171 11AC;CDED;110E 1171 11AC; +CDEE;CDEE;110E 1171 11AD;CDEE;110E 1171 11AD; +CDEF;CDEF;110E 1171 11AE;CDEF;110E 1171 11AE; +CDF0;CDF0;110E 1171 11AF;CDF0;110E 1171 11AF; +CDF1;CDF1;110E 1171 11B0;CDF1;110E 1171 11B0; +CDF2;CDF2;110E 1171 11B1;CDF2;110E 1171 11B1; +CDF3;CDF3;110E 1171 11B2;CDF3;110E 1171 11B2; +CDF4;CDF4;110E 1171 11B3;CDF4;110E 1171 11B3; +CDF5;CDF5;110E 1171 11B4;CDF5;110E 1171 11B4; +CDF6;CDF6;110E 1171 11B5;CDF6;110E 1171 11B5; +CDF7;CDF7;110E 1171 11B6;CDF7;110E 1171 11B6; +CDF8;CDF8;110E 1171 11B7;CDF8;110E 1171 11B7; +CDF9;CDF9;110E 1171 11B8;CDF9;110E 1171 11B8; +CDFA;CDFA;110E 1171 11B9;CDFA;110E 1171 11B9; +CDFB;CDFB;110E 1171 11BA;CDFB;110E 1171 11BA; +CDFC;CDFC;110E 1171 11BB;CDFC;110E 1171 11BB; +CDFD;CDFD;110E 1171 11BC;CDFD;110E 1171 11BC; +CDFE;CDFE;110E 1171 11BD;CDFE;110E 1171 11BD; +CDFF;CDFF;110E 1171 11BE;CDFF;110E 1171 11BE; +CE00;CE00;110E 1171 11BF;CE00;110E 1171 11BF; +CE01;CE01;110E 1171 11C0;CE01;110E 1171 11C0; +CE02;CE02;110E 1171 11C1;CE02;110E 1171 11C1; +CE03;CE03;110E 1171 11C2;CE03;110E 1171 11C2; +CE04;CE04;110E 1172;CE04;110E 1172; +CE05;CE05;110E 1172 11A8;CE05;110E 1172 11A8; +CE06;CE06;110E 1172 11A9;CE06;110E 1172 11A9; +CE07;CE07;110E 1172 11AA;CE07;110E 1172 11AA; +CE08;CE08;110E 1172 11AB;CE08;110E 1172 11AB; +CE09;CE09;110E 1172 11AC;CE09;110E 1172 11AC; +CE0A;CE0A;110E 1172 11AD;CE0A;110E 1172 11AD; +CE0B;CE0B;110E 1172 11AE;CE0B;110E 1172 11AE; +CE0C;CE0C;110E 1172 11AF;CE0C;110E 1172 11AF; +CE0D;CE0D;110E 1172 11B0;CE0D;110E 1172 11B0; +CE0E;CE0E;110E 1172 11B1;CE0E;110E 1172 11B1; +CE0F;CE0F;110E 1172 11B2;CE0F;110E 1172 11B2; +CE10;CE10;110E 1172 11B3;CE10;110E 1172 11B3; +CE11;CE11;110E 1172 11B4;CE11;110E 1172 11B4; +CE12;CE12;110E 1172 11B5;CE12;110E 1172 11B5; +CE13;CE13;110E 1172 11B6;CE13;110E 1172 11B6; +CE14;CE14;110E 1172 11B7;CE14;110E 1172 11B7; +CE15;CE15;110E 1172 11B8;CE15;110E 1172 11B8; +CE16;CE16;110E 1172 11B9;CE16;110E 1172 11B9; +CE17;CE17;110E 1172 11BA;CE17;110E 1172 11BA; +CE18;CE18;110E 1172 11BB;CE18;110E 1172 11BB; +CE19;CE19;110E 1172 11BC;CE19;110E 1172 11BC; +CE1A;CE1A;110E 1172 11BD;CE1A;110E 1172 11BD; +CE1B;CE1B;110E 1172 11BE;CE1B;110E 1172 11BE; +CE1C;CE1C;110E 1172 11BF;CE1C;110E 1172 11BF; +CE1D;CE1D;110E 1172 11C0;CE1D;110E 1172 11C0; +CE1E;CE1E;110E 1172 11C1;CE1E;110E 1172 11C1; +CE1F;CE1F;110E 1172 11C2;CE1F;110E 1172 11C2; +CE20;CE20;110E 1173;CE20;110E 1173; +CE21;CE21;110E 1173 11A8;CE21;110E 1173 11A8; +CE22;CE22;110E 1173 11A9;CE22;110E 1173 11A9; +CE23;CE23;110E 1173 11AA;CE23;110E 1173 11AA; +CE24;CE24;110E 1173 11AB;CE24;110E 1173 11AB; +CE25;CE25;110E 1173 11AC;CE25;110E 1173 11AC; +CE26;CE26;110E 1173 11AD;CE26;110E 1173 11AD; +CE27;CE27;110E 1173 11AE;CE27;110E 1173 11AE; +CE28;CE28;110E 1173 11AF;CE28;110E 1173 11AF; +CE29;CE29;110E 1173 11B0;CE29;110E 1173 11B0; +CE2A;CE2A;110E 1173 11B1;CE2A;110E 1173 11B1; +CE2B;CE2B;110E 1173 11B2;CE2B;110E 1173 11B2; +CE2C;CE2C;110E 1173 11B3;CE2C;110E 1173 11B3; +CE2D;CE2D;110E 1173 11B4;CE2D;110E 1173 11B4; +CE2E;CE2E;110E 1173 11B5;CE2E;110E 1173 11B5; +CE2F;CE2F;110E 1173 11B6;CE2F;110E 1173 11B6; +CE30;CE30;110E 1173 11B7;CE30;110E 1173 11B7; +CE31;CE31;110E 1173 11B8;CE31;110E 1173 11B8; +CE32;CE32;110E 1173 11B9;CE32;110E 1173 11B9; +CE33;CE33;110E 1173 11BA;CE33;110E 1173 11BA; +CE34;CE34;110E 1173 11BB;CE34;110E 1173 11BB; +CE35;CE35;110E 1173 11BC;CE35;110E 1173 11BC; +CE36;CE36;110E 1173 11BD;CE36;110E 1173 11BD; +CE37;CE37;110E 1173 11BE;CE37;110E 1173 11BE; +CE38;CE38;110E 1173 11BF;CE38;110E 1173 11BF; +CE39;CE39;110E 1173 11C0;CE39;110E 1173 11C0; +CE3A;CE3A;110E 1173 11C1;CE3A;110E 1173 11C1; +CE3B;CE3B;110E 1173 11C2;CE3B;110E 1173 11C2; +CE3C;CE3C;110E 1174;CE3C;110E 1174; +CE3D;CE3D;110E 1174 11A8;CE3D;110E 1174 11A8; +CE3E;CE3E;110E 1174 11A9;CE3E;110E 1174 11A9; +CE3F;CE3F;110E 1174 11AA;CE3F;110E 1174 11AA; +CE40;CE40;110E 1174 11AB;CE40;110E 1174 11AB; +CE41;CE41;110E 1174 11AC;CE41;110E 1174 11AC; +CE42;CE42;110E 1174 11AD;CE42;110E 1174 11AD; +CE43;CE43;110E 1174 11AE;CE43;110E 1174 11AE; +CE44;CE44;110E 1174 11AF;CE44;110E 1174 11AF; +CE45;CE45;110E 1174 11B0;CE45;110E 1174 11B0; +CE46;CE46;110E 1174 11B1;CE46;110E 1174 11B1; +CE47;CE47;110E 1174 11B2;CE47;110E 1174 11B2; +CE48;CE48;110E 1174 11B3;CE48;110E 1174 11B3; +CE49;CE49;110E 1174 11B4;CE49;110E 1174 11B4; +CE4A;CE4A;110E 1174 11B5;CE4A;110E 1174 11B5; +CE4B;CE4B;110E 1174 11B6;CE4B;110E 1174 11B6; +CE4C;CE4C;110E 1174 11B7;CE4C;110E 1174 11B7; +CE4D;CE4D;110E 1174 11B8;CE4D;110E 1174 11B8; +CE4E;CE4E;110E 1174 11B9;CE4E;110E 1174 11B9; +CE4F;CE4F;110E 1174 11BA;CE4F;110E 1174 11BA; +CE50;CE50;110E 1174 11BB;CE50;110E 1174 11BB; +CE51;CE51;110E 1174 11BC;CE51;110E 1174 11BC; +CE52;CE52;110E 1174 11BD;CE52;110E 1174 11BD; +CE53;CE53;110E 1174 11BE;CE53;110E 1174 11BE; +CE54;CE54;110E 1174 11BF;CE54;110E 1174 11BF; +CE55;CE55;110E 1174 11C0;CE55;110E 1174 11C0; +CE56;CE56;110E 1174 11C1;CE56;110E 1174 11C1; +CE57;CE57;110E 1174 11C2;CE57;110E 1174 11C2; +CE58;CE58;110E 1175;CE58;110E 1175; +CE59;CE59;110E 1175 11A8;CE59;110E 1175 11A8; +CE5A;CE5A;110E 1175 11A9;CE5A;110E 1175 11A9; +CE5B;CE5B;110E 1175 11AA;CE5B;110E 1175 11AA; +CE5C;CE5C;110E 1175 11AB;CE5C;110E 1175 11AB; +CE5D;CE5D;110E 1175 11AC;CE5D;110E 1175 11AC; +CE5E;CE5E;110E 1175 11AD;CE5E;110E 1175 11AD; +CE5F;CE5F;110E 1175 11AE;CE5F;110E 1175 11AE; +CE60;CE60;110E 1175 11AF;CE60;110E 1175 11AF; +CE61;CE61;110E 1175 11B0;CE61;110E 1175 11B0; +CE62;CE62;110E 1175 11B1;CE62;110E 1175 11B1; +CE63;CE63;110E 1175 11B2;CE63;110E 1175 11B2; +CE64;CE64;110E 1175 11B3;CE64;110E 1175 11B3; +CE65;CE65;110E 1175 11B4;CE65;110E 1175 11B4; +CE66;CE66;110E 1175 11B5;CE66;110E 1175 11B5; +CE67;CE67;110E 1175 11B6;CE67;110E 1175 11B6; +CE68;CE68;110E 1175 11B7;CE68;110E 1175 11B7; +CE69;CE69;110E 1175 11B8;CE69;110E 1175 11B8; +CE6A;CE6A;110E 1175 11B9;CE6A;110E 1175 11B9; +CE6B;CE6B;110E 1175 11BA;CE6B;110E 1175 11BA; +CE6C;CE6C;110E 1175 11BB;CE6C;110E 1175 11BB; +CE6D;CE6D;110E 1175 11BC;CE6D;110E 1175 11BC; +CE6E;CE6E;110E 1175 11BD;CE6E;110E 1175 11BD; +CE6F;CE6F;110E 1175 11BE;CE6F;110E 1175 11BE; +CE70;CE70;110E 1175 11BF;CE70;110E 1175 11BF; +CE71;CE71;110E 1175 11C0;CE71;110E 1175 11C0; +CE72;CE72;110E 1175 11C1;CE72;110E 1175 11C1; +CE73;CE73;110E 1175 11C2;CE73;110E 1175 11C2; +CE74;CE74;110F 1161;CE74;110F 1161; +CE75;CE75;110F 1161 11A8;CE75;110F 1161 11A8; +CE76;CE76;110F 1161 11A9;CE76;110F 1161 11A9; +CE77;CE77;110F 1161 11AA;CE77;110F 1161 11AA; +CE78;CE78;110F 1161 11AB;CE78;110F 1161 11AB; +CE79;CE79;110F 1161 11AC;CE79;110F 1161 11AC; +CE7A;CE7A;110F 1161 11AD;CE7A;110F 1161 11AD; +CE7B;CE7B;110F 1161 11AE;CE7B;110F 1161 11AE; +CE7C;CE7C;110F 1161 11AF;CE7C;110F 1161 11AF; +CE7D;CE7D;110F 1161 11B0;CE7D;110F 1161 11B0; +CE7E;CE7E;110F 1161 11B1;CE7E;110F 1161 11B1; +CE7F;CE7F;110F 1161 11B2;CE7F;110F 1161 11B2; +CE80;CE80;110F 1161 11B3;CE80;110F 1161 11B3; +CE81;CE81;110F 1161 11B4;CE81;110F 1161 11B4; +CE82;CE82;110F 1161 11B5;CE82;110F 1161 11B5; +CE83;CE83;110F 1161 11B6;CE83;110F 1161 11B6; +CE84;CE84;110F 1161 11B7;CE84;110F 1161 11B7; +CE85;CE85;110F 1161 11B8;CE85;110F 1161 11B8; +CE86;CE86;110F 1161 11B9;CE86;110F 1161 11B9; +CE87;CE87;110F 1161 11BA;CE87;110F 1161 11BA; +CE88;CE88;110F 1161 11BB;CE88;110F 1161 11BB; +CE89;CE89;110F 1161 11BC;CE89;110F 1161 11BC; +CE8A;CE8A;110F 1161 11BD;CE8A;110F 1161 11BD; +CE8B;CE8B;110F 1161 11BE;CE8B;110F 1161 11BE; +CE8C;CE8C;110F 1161 11BF;CE8C;110F 1161 11BF; +CE8D;CE8D;110F 1161 11C0;CE8D;110F 1161 11C0; +CE8E;CE8E;110F 1161 11C1;CE8E;110F 1161 11C1; +CE8F;CE8F;110F 1161 11C2;CE8F;110F 1161 11C2; +CE90;CE90;110F 1162;CE90;110F 1162; +CE91;CE91;110F 1162 11A8;CE91;110F 1162 11A8; +CE92;CE92;110F 1162 11A9;CE92;110F 1162 11A9; +CE93;CE93;110F 1162 11AA;CE93;110F 1162 11AA; +CE94;CE94;110F 1162 11AB;CE94;110F 1162 11AB; +CE95;CE95;110F 1162 11AC;CE95;110F 1162 11AC; +CE96;CE96;110F 1162 11AD;CE96;110F 1162 11AD; +CE97;CE97;110F 1162 11AE;CE97;110F 1162 11AE; +CE98;CE98;110F 1162 11AF;CE98;110F 1162 11AF; +CE99;CE99;110F 1162 11B0;CE99;110F 1162 11B0; +CE9A;CE9A;110F 1162 11B1;CE9A;110F 1162 11B1; +CE9B;CE9B;110F 1162 11B2;CE9B;110F 1162 11B2; +CE9C;CE9C;110F 1162 11B3;CE9C;110F 1162 11B3; +CE9D;CE9D;110F 1162 11B4;CE9D;110F 1162 11B4; +CE9E;CE9E;110F 1162 11B5;CE9E;110F 1162 11B5; +CE9F;CE9F;110F 1162 11B6;CE9F;110F 1162 11B6; +CEA0;CEA0;110F 1162 11B7;CEA0;110F 1162 11B7; +CEA1;CEA1;110F 1162 11B8;CEA1;110F 1162 11B8; +CEA2;CEA2;110F 1162 11B9;CEA2;110F 1162 11B9; +CEA3;CEA3;110F 1162 11BA;CEA3;110F 1162 11BA; +CEA4;CEA4;110F 1162 11BB;CEA4;110F 1162 11BB; +CEA5;CEA5;110F 1162 11BC;CEA5;110F 1162 11BC; +CEA6;CEA6;110F 1162 11BD;CEA6;110F 1162 11BD; +CEA7;CEA7;110F 1162 11BE;CEA7;110F 1162 11BE; +CEA8;CEA8;110F 1162 11BF;CEA8;110F 1162 11BF; +CEA9;CEA9;110F 1162 11C0;CEA9;110F 1162 11C0; +CEAA;CEAA;110F 1162 11C1;CEAA;110F 1162 11C1; +CEAB;CEAB;110F 1162 11C2;CEAB;110F 1162 11C2; +CEAC;CEAC;110F 1163;CEAC;110F 1163; +CEAD;CEAD;110F 1163 11A8;CEAD;110F 1163 11A8; +CEAE;CEAE;110F 1163 11A9;CEAE;110F 1163 11A9; +CEAF;CEAF;110F 1163 11AA;CEAF;110F 1163 11AA; +CEB0;CEB0;110F 1163 11AB;CEB0;110F 1163 11AB; +CEB1;CEB1;110F 1163 11AC;CEB1;110F 1163 11AC; +CEB2;CEB2;110F 1163 11AD;CEB2;110F 1163 11AD; +CEB3;CEB3;110F 1163 11AE;CEB3;110F 1163 11AE; +CEB4;CEB4;110F 1163 11AF;CEB4;110F 1163 11AF; +CEB5;CEB5;110F 1163 11B0;CEB5;110F 1163 11B0; +CEB6;CEB6;110F 1163 11B1;CEB6;110F 1163 11B1; +CEB7;CEB7;110F 1163 11B2;CEB7;110F 1163 11B2; +CEB8;CEB8;110F 1163 11B3;CEB8;110F 1163 11B3; +CEB9;CEB9;110F 1163 11B4;CEB9;110F 1163 11B4; +CEBA;CEBA;110F 1163 11B5;CEBA;110F 1163 11B5; +CEBB;CEBB;110F 1163 11B6;CEBB;110F 1163 11B6; +CEBC;CEBC;110F 1163 11B7;CEBC;110F 1163 11B7; +CEBD;CEBD;110F 1163 11B8;CEBD;110F 1163 11B8; +CEBE;CEBE;110F 1163 11B9;CEBE;110F 1163 11B9; +CEBF;CEBF;110F 1163 11BA;CEBF;110F 1163 11BA; +CEC0;CEC0;110F 1163 11BB;CEC0;110F 1163 11BB; +CEC1;CEC1;110F 1163 11BC;CEC1;110F 1163 11BC; +CEC2;CEC2;110F 1163 11BD;CEC2;110F 1163 11BD; +CEC3;CEC3;110F 1163 11BE;CEC3;110F 1163 11BE; +CEC4;CEC4;110F 1163 11BF;CEC4;110F 1163 11BF; +CEC5;CEC5;110F 1163 11C0;CEC5;110F 1163 11C0; +CEC6;CEC6;110F 1163 11C1;CEC6;110F 1163 11C1; +CEC7;CEC7;110F 1163 11C2;CEC7;110F 1163 11C2; +CEC8;CEC8;110F 1164;CEC8;110F 1164; +CEC9;CEC9;110F 1164 11A8;CEC9;110F 1164 11A8; +CECA;CECA;110F 1164 11A9;CECA;110F 1164 11A9; +CECB;CECB;110F 1164 11AA;CECB;110F 1164 11AA; +CECC;CECC;110F 1164 11AB;CECC;110F 1164 11AB; +CECD;CECD;110F 1164 11AC;CECD;110F 1164 11AC; +CECE;CECE;110F 1164 11AD;CECE;110F 1164 11AD; +CECF;CECF;110F 1164 11AE;CECF;110F 1164 11AE; +CED0;CED0;110F 1164 11AF;CED0;110F 1164 11AF; +CED1;CED1;110F 1164 11B0;CED1;110F 1164 11B0; +CED2;CED2;110F 1164 11B1;CED2;110F 1164 11B1; +CED3;CED3;110F 1164 11B2;CED3;110F 1164 11B2; +CED4;CED4;110F 1164 11B3;CED4;110F 1164 11B3; +CED5;CED5;110F 1164 11B4;CED5;110F 1164 11B4; +CED6;CED6;110F 1164 11B5;CED6;110F 1164 11B5; +CED7;CED7;110F 1164 11B6;CED7;110F 1164 11B6; +CED8;CED8;110F 1164 11B7;CED8;110F 1164 11B7; +CED9;CED9;110F 1164 11B8;CED9;110F 1164 11B8; +CEDA;CEDA;110F 1164 11B9;CEDA;110F 1164 11B9; +CEDB;CEDB;110F 1164 11BA;CEDB;110F 1164 11BA; +CEDC;CEDC;110F 1164 11BB;CEDC;110F 1164 11BB; +CEDD;CEDD;110F 1164 11BC;CEDD;110F 1164 11BC; +CEDE;CEDE;110F 1164 11BD;CEDE;110F 1164 11BD; +CEDF;CEDF;110F 1164 11BE;CEDF;110F 1164 11BE; +CEE0;CEE0;110F 1164 11BF;CEE0;110F 1164 11BF; +CEE1;CEE1;110F 1164 11C0;CEE1;110F 1164 11C0; +CEE2;CEE2;110F 1164 11C1;CEE2;110F 1164 11C1; +CEE3;CEE3;110F 1164 11C2;CEE3;110F 1164 11C2; +CEE4;CEE4;110F 1165;CEE4;110F 1165; +CEE5;CEE5;110F 1165 11A8;CEE5;110F 1165 11A8; +CEE6;CEE6;110F 1165 11A9;CEE6;110F 1165 11A9; +CEE7;CEE7;110F 1165 11AA;CEE7;110F 1165 11AA; +CEE8;CEE8;110F 1165 11AB;CEE8;110F 1165 11AB; +CEE9;CEE9;110F 1165 11AC;CEE9;110F 1165 11AC; +CEEA;CEEA;110F 1165 11AD;CEEA;110F 1165 11AD; +CEEB;CEEB;110F 1165 11AE;CEEB;110F 1165 11AE; +CEEC;CEEC;110F 1165 11AF;CEEC;110F 1165 11AF; +CEED;CEED;110F 1165 11B0;CEED;110F 1165 11B0; +CEEE;CEEE;110F 1165 11B1;CEEE;110F 1165 11B1; +CEEF;CEEF;110F 1165 11B2;CEEF;110F 1165 11B2; +CEF0;CEF0;110F 1165 11B3;CEF0;110F 1165 11B3; +CEF1;CEF1;110F 1165 11B4;CEF1;110F 1165 11B4; +CEF2;CEF2;110F 1165 11B5;CEF2;110F 1165 11B5; +CEF3;CEF3;110F 1165 11B6;CEF3;110F 1165 11B6; +CEF4;CEF4;110F 1165 11B7;CEF4;110F 1165 11B7; +CEF5;CEF5;110F 1165 11B8;CEF5;110F 1165 11B8; +CEF6;CEF6;110F 1165 11B9;CEF6;110F 1165 11B9; +CEF7;CEF7;110F 1165 11BA;CEF7;110F 1165 11BA; +CEF8;CEF8;110F 1165 11BB;CEF8;110F 1165 11BB; +CEF9;CEF9;110F 1165 11BC;CEF9;110F 1165 11BC; +CEFA;CEFA;110F 1165 11BD;CEFA;110F 1165 11BD; +CEFB;CEFB;110F 1165 11BE;CEFB;110F 1165 11BE; +CEFC;CEFC;110F 1165 11BF;CEFC;110F 1165 11BF; +CEFD;CEFD;110F 1165 11C0;CEFD;110F 1165 11C0; +CEFE;CEFE;110F 1165 11C1;CEFE;110F 1165 11C1; +CEFF;CEFF;110F 1165 11C2;CEFF;110F 1165 11C2; +CF00;CF00;110F 1166;CF00;110F 1166; +CF01;CF01;110F 1166 11A8;CF01;110F 1166 11A8; +CF02;CF02;110F 1166 11A9;CF02;110F 1166 11A9; +CF03;CF03;110F 1166 11AA;CF03;110F 1166 11AA; +CF04;CF04;110F 1166 11AB;CF04;110F 1166 11AB; +CF05;CF05;110F 1166 11AC;CF05;110F 1166 11AC; +CF06;CF06;110F 1166 11AD;CF06;110F 1166 11AD; +CF07;CF07;110F 1166 11AE;CF07;110F 1166 11AE; +CF08;CF08;110F 1166 11AF;CF08;110F 1166 11AF; +CF09;CF09;110F 1166 11B0;CF09;110F 1166 11B0; +CF0A;CF0A;110F 1166 11B1;CF0A;110F 1166 11B1; +CF0B;CF0B;110F 1166 11B2;CF0B;110F 1166 11B2; +CF0C;CF0C;110F 1166 11B3;CF0C;110F 1166 11B3; +CF0D;CF0D;110F 1166 11B4;CF0D;110F 1166 11B4; +CF0E;CF0E;110F 1166 11B5;CF0E;110F 1166 11B5; +CF0F;CF0F;110F 1166 11B6;CF0F;110F 1166 11B6; +CF10;CF10;110F 1166 11B7;CF10;110F 1166 11B7; +CF11;CF11;110F 1166 11B8;CF11;110F 1166 11B8; +CF12;CF12;110F 1166 11B9;CF12;110F 1166 11B9; +CF13;CF13;110F 1166 11BA;CF13;110F 1166 11BA; +CF14;CF14;110F 1166 11BB;CF14;110F 1166 11BB; +CF15;CF15;110F 1166 11BC;CF15;110F 1166 11BC; +CF16;CF16;110F 1166 11BD;CF16;110F 1166 11BD; +CF17;CF17;110F 1166 11BE;CF17;110F 1166 11BE; +CF18;CF18;110F 1166 11BF;CF18;110F 1166 11BF; +CF19;CF19;110F 1166 11C0;CF19;110F 1166 11C0; +CF1A;CF1A;110F 1166 11C1;CF1A;110F 1166 11C1; +CF1B;CF1B;110F 1166 11C2;CF1B;110F 1166 11C2; +CF1C;CF1C;110F 1167;CF1C;110F 1167; +CF1D;CF1D;110F 1167 11A8;CF1D;110F 1167 11A8; +CF1E;CF1E;110F 1167 11A9;CF1E;110F 1167 11A9; +CF1F;CF1F;110F 1167 11AA;CF1F;110F 1167 11AA; +CF20;CF20;110F 1167 11AB;CF20;110F 1167 11AB; +CF21;CF21;110F 1167 11AC;CF21;110F 1167 11AC; +CF22;CF22;110F 1167 11AD;CF22;110F 1167 11AD; +CF23;CF23;110F 1167 11AE;CF23;110F 1167 11AE; +CF24;CF24;110F 1167 11AF;CF24;110F 1167 11AF; +CF25;CF25;110F 1167 11B0;CF25;110F 1167 11B0; +CF26;CF26;110F 1167 11B1;CF26;110F 1167 11B1; +CF27;CF27;110F 1167 11B2;CF27;110F 1167 11B2; +CF28;CF28;110F 1167 11B3;CF28;110F 1167 11B3; +CF29;CF29;110F 1167 11B4;CF29;110F 1167 11B4; +CF2A;CF2A;110F 1167 11B5;CF2A;110F 1167 11B5; +CF2B;CF2B;110F 1167 11B6;CF2B;110F 1167 11B6; +CF2C;CF2C;110F 1167 11B7;CF2C;110F 1167 11B7; +CF2D;CF2D;110F 1167 11B8;CF2D;110F 1167 11B8; +CF2E;CF2E;110F 1167 11B9;CF2E;110F 1167 11B9; +CF2F;CF2F;110F 1167 11BA;CF2F;110F 1167 11BA; +CF30;CF30;110F 1167 11BB;CF30;110F 1167 11BB; +CF31;CF31;110F 1167 11BC;CF31;110F 1167 11BC; +CF32;CF32;110F 1167 11BD;CF32;110F 1167 11BD; +CF33;CF33;110F 1167 11BE;CF33;110F 1167 11BE; +CF34;CF34;110F 1167 11BF;CF34;110F 1167 11BF; +CF35;CF35;110F 1167 11C0;CF35;110F 1167 11C0; +CF36;CF36;110F 1167 11C1;CF36;110F 1167 11C1; +CF37;CF37;110F 1167 11C2;CF37;110F 1167 11C2; +CF38;CF38;110F 1168;CF38;110F 1168; +CF39;CF39;110F 1168 11A8;CF39;110F 1168 11A8; +CF3A;CF3A;110F 1168 11A9;CF3A;110F 1168 11A9; +CF3B;CF3B;110F 1168 11AA;CF3B;110F 1168 11AA; +CF3C;CF3C;110F 1168 11AB;CF3C;110F 1168 11AB; +CF3D;CF3D;110F 1168 11AC;CF3D;110F 1168 11AC; +CF3E;CF3E;110F 1168 11AD;CF3E;110F 1168 11AD; +CF3F;CF3F;110F 1168 11AE;CF3F;110F 1168 11AE; +CF40;CF40;110F 1168 11AF;CF40;110F 1168 11AF; +CF41;CF41;110F 1168 11B0;CF41;110F 1168 11B0; +CF42;CF42;110F 1168 11B1;CF42;110F 1168 11B1; +CF43;CF43;110F 1168 11B2;CF43;110F 1168 11B2; +CF44;CF44;110F 1168 11B3;CF44;110F 1168 11B3; +CF45;CF45;110F 1168 11B4;CF45;110F 1168 11B4; +CF46;CF46;110F 1168 11B5;CF46;110F 1168 11B5; +CF47;CF47;110F 1168 11B6;CF47;110F 1168 11B6; +CF48;CF48;110F 1168 11B7;CF48;110F 1168 11B7; +CF49;CF49;110F 1168 11B8;CF49;110F 1168 11B8; +CF4A;CF4A;110F 1168 11B9;CF4A;110F 1168 11B9; +CF4B;CF4B;110F 1168 11BA;CF4B;110F 1168 11BA; +CF4C;CF4C;110F 1168 11BB;CF4C;110F 1168 11BB; +CF4D;CF4D;110F 1168 11BC;CF4D;110F 1168 11BC; +CF4E;CF4E;110F 1168 11BD;CF4E;110F 1168 11BD; +CF4F;CF4F;110F 1168 11BE;CF4F;110F 1168 11BE; +CF50;CF50;110F 1168 11BF;CF50;110F 1168 11BF; +CF51;CF51;110F 1168 11C0;CF51;110F 1168 11C0; +CF52;CF52;110F 1168 11C1;CF52;110F 1168 11C1; +CF53;CF53;110F 1168 11C2;CF53;110F 1168 11C2; +CF54;CF54;110F 1169;CF54;110F 1169; +CF55;CF55;110F 1169 11A8;CF55;110F 1169 11A8; +CF56;CF56;110F 1169 11A9;CF56;110F 1169 11A9; +CF57;CF57;110F 1169 11AA;CF57;110F 1169 11AA; +CF58;CF58;110F 1169 11AB;CF58;110F 1169 11AB; +CF59;CF59;110F 1169 11AC;CF59;110F 1169 11AC; +CF5A;CF5A;110F 1169 11AD;CF5A;110F 1169 11AD; +CF5B;CF5B;110F 1169 11AE;CF5B;110F 1169 11AE; +CF5C;CF5C;110F 1169 11AF;CF5C;110F 1169 11AF; +CF5D;CF5D;110F 1169 11B0;CF5D;110F 1169 11B0; +CF5E;CF5E;110F 1169 11B1;CF5E;110F 1169 11B1; +CF5F;CF5F;110F 1169 11B2;CF5F;110F 1169 11B2; +CF60;CF60;110F 1169 11B3;CF60;110F 1169 11B3; +CF61;CF61;110F 1169 11B4;CF61;110F 1169 11B4; +CF62;CF62;110F 1169 11B5;CF62;110F 1169 11B5; +CF63;CF63;110F 1169 11B6;CF63;110F 1169 11B6; +CF64;CF64;110F 1169 11B7;CF64;110F 1169 11B7; +CF65;CF65;110F 1169 11B8;CF65;110F 1169 11B8; +CF66;CF66;110F 1169 11B9;CF66;110F 1169 11B9; +CF67;CF67;110F 1169 11BA;CF67;110F 1169 11BA; +CF68;CF68;110F 1169 11BB;CF68;110F 1169 11BB; +CF69;CF69;110F 1169 11BC;CF69;110F 1169 11BC; +CF6A;CF6A;110F 1169 11BD;CF6A;110F 1169 11BD; +CF6B;CF6B;110F 1169 11BE;CF6B;110F 1169 11BE; +CF6C;CF6C;110F 1169 11BF;CF6C;110F 1169 11BF; +CF6D;CF6D;110F 1169 11C0;CF6D;110F 1169 11C0; +CF6E;CF6E;110F 1169 11C1;CF6E;110F 1169 11C1; +CF6F;CF6F;110F 1169 11C2;CF6F;110F 1169 11C2; +CF70;CF70;110F 116A;CF70;110F 116A; +CF71;CF71;110F 116A 11A8;CF71;110F 116A 11A8; +CF72;CF72;110F 116A 11A9;CF72;110F 116A 11A9; +CF73;CF73;110F 116A 11AA;CF73;110F 116A 11AA; +CF74;CF74;110F 116A 11AB;CF74;110F 116A 11AB; +CF75;CF75;110F 116A 11AC;CF75;110F 116A 11AC; +CF76;CF76;110F 116A 11AD;CF76;110F 116A 11AD; +CF77;CF77;110F 116A 11AE;CF77;110F 116A 11AE; +CF78;CF78;110F 116A 11AF;CF78;110F 116A 11AF; +CF79;CF79;110F 116A 11B0;CF79;110F 116A 11B0; +CF7A;CF7A;110F 116A 11B1;CF7A;110F 116A 11B1; +CF7B;CF7B;110F 116A 11B2;CF7B;110F 116A 11B2; +CF7C;CF7C;110F 116A 11B3;CF7C;110F 116A 11B3; +CF7D;CF7D;110F 116A 11B4;CF7D;110F 116A 11B4; +CF7E;CF7E;110F 116A 11B5;CF7E;110F 116A 11B5; +CF7F;CF7F;110F 116A 11B6;CF7F;110F 116A 11B6; +CF80;CF80;110F 116A 11B7;CF80;110F 116A 11B7; +CF81;CF81;110F 116A 11B8;CF81;110F 116A 11B8; +CF82;CF82;110F 116A 11B9;CF82;110F 116A 11B9; +CF83;CF83;110F 116A 11BA;CF83;110F 116A 11BA; +CF84;CF84;110F 116A 11BB;CF84;110F 116A 11BB; +CF85;CF85;110F 116A 11BC;CF85;110F 116A 11BC; +CF86;CF86;110F 116A 11BD;CF86;110F 116A 11BD; +CF87;CF87;110F 116A 11BE;CF87;110F 116A 11BE; +CF88;CF88;110F 116A 11BF;CF88;110F 116A 11BF; +CF89;CF89;110F 116A 11C0;CF89;110F 116A 11C0; +CF8A;CF8A;110F 116A 11C1;CF8A;110F 116A 11C1; +CF8B;CF8B;110F 116A 11C2;CF8B;110F 116A 11C2; +CF8C;CF8C;110F 116B;CF8C;110F 116B; +CF8D;CF8D;110F 116B 11A8;CF8D;110F 116B 11A8; +CF8E;CF8E;110F 116B 11A9;CF8E;110F 116B 11A9; +CF8F;CF8F;110F 116B 11AA;CF8F;110F 116B 11AA; +CF90;CF90;110F 116B 11AB;CF90;110F 116B 11AB; +CF91;CF91;110F 116B 11AC;CF91;110F 116B 11AC; +CF92;CF92;110F 116B 11AD;CF92;110F 116B 11AD; +CF93;CF93;110F 116B 11AE;CF93;110F 116B 11AE; +CF94;CF94;110F 116B 11AF;CF94;110F 116B 11AF; +CF95;CF95;110F 116B 11B0;CF95;110F 116B 11B0; +CF96;CF96;110F 116B 11B1;CF96;110F 116B 11B1; +CF97;CF97;110F 116B 11B2;CF97;110F 116B 11B2; +CF98;CF98;110F 116B 11B3;CF98;110F 116B 11B3; +CF99;CF99;110F 116B 11B4;CF99;110F 116B 11B4; +CF9A;CF9A;110F 116B 11B5;CF9A;110F 116B 11B5; +CF9B;CF9B;110F 116B 11B6;CF9B;110F 116B 11B6; +CF9C;CF9C;110F 116B 11B7;CF9C;110F 116B 11B7; +CF9D;CF9D;110F 116B 11B8;CF9D;110F 116B 11B8; +CF9E;CF9E;110F 116B 11B9;CF9E;110F 116B 11B9; +CF9F;CF9F;110F 116B 11BA;CF9F;110F 116B 11BA; +CFA0;CFA0;110F 116B 11BB;CFA0;110F 116B 11BB; +CFA1;CFA1;110F 116B 11BC;CFA1;110F 116B 11BC; +CFA2;CFA2;110F 116B 11BD;CFA2;110F 116B 11BD; +CFA3;CFA3;110F 116B 11BE;CFA3;110F 116B 11BE; +CFA4;CFA4;110F 116B 11BF;CFA4;110F 116B 11BF; +CFA5;CFA5;110F 116B 11C0;CFA5;110F 116B 11C0; +CFA6;CFA6;110F 116B 11C1;CFA6;110F 116B 11C1; +CFA7;CFA7;110F 116B 11C2;CFA7;110F 116B 11C2; +CFA8;CFA8;110F 116C;CFA8;110F 116C; +CFA9;CFA9;110F 116C 11A8;CFA9;110F 116C 11A8; +CFAA;CFAA;110F 116C 11A9;CFAA;110F 116C 11A9; +CFAB;CFAB;110F 116C 11AA;CFAB;110F 116C 11AA; +CFAC;CFAC;110F 116C 11AB;CFAC;110F 116C 11AB; +CFAD;CFAD;110F 116C 11AC;CFAD;110F 116C 11AC; +CFAE;CFAE;110F 116C 11AD;CFAE;110F 116C 11AD; +CFAF;CFAF;110F 116C 11AE;CFAF;110F 116C 11AE; +CFB0;CFB0;110F 116C 11AF;CFB0;110F 116C 11AF; +CFB1;CFB1;110F 116C 11B0;CFB1;110F 116C 11B0; +CFB2;CFB2;110F 116C 11B1;CFB2;110F 116C 11B1; +CFB3;CFB3;110F 116C 11B2;CFB3;110F 116C 11B2; +CFB4;CFB4;110F 116C 11B3;CFB4;110F 116C 11B3; +CFB5;CFB5;110F 116C 11B4;CFB5;110F 116C 11B4; +CFB6;CFB6;110F 116C 11B5;CFB6;110F 116C 11B5; +CFB7;CFB7;110F 116C 11B6;CFB7;110F 116C 11B6; +CFB8;CFB8;110F 116C 11B7;CFB8;110F 116C 11B7; +CFB9;CFB9;110F 116C 11B8;CFB9;110F 116C 11B8; +CFBA;CFBA;110F 116C 11B9;CFBA;110F 116C 11B9; +CFBB;CFBB;110F 116C 11BA;CFBB;110F 116C 11BA; +CFBC;CFBC;110F 116C 11BB;CFBC;110F 116C 11BB; +CFBD;CFBD;110F 116C 11BC;CFBD;110F 116C 11BC; +CFBE;CFBE;110F 116C 11BD;CFBE;110F 116C 11BD; +CFBF;CFBF;110F 116C 11BE;CFBF;110F 116C 11BE; +CFC0;CFC0;110F 116C 11BF;CFC0;110F 116C 11BF; +CFC1;CFC1;110F 116C 11C0;CFC1;110F 116C 11C0; +CFC2;CFC2;110F 116C 11C1;CFC2;110F 116C 11C1; +CFC3;CFC3;110F 116C 11C2;CFC3;110F 116C 11C2; +CFC4;CFC4;110F 116D;CFC4;110F 116D; +CFC5;CFC5;110F 116D 11A8;CFC5;110F 116D 11A8; +CFC6;CFC6;110F 116D 11A9;CFC6;110F 116D 11A9; +CFC7;CFC7;110F 116D 11AA;CFC7;110F 116D 11AA; +CFC8;CFC8;110F 116D 11AB;CFC8;110F 116D 11AB; +CFC9;CFC9;110F 116D 11AC;CFC9;110F 116D 11AC; +CFCA;CFCA;110F 116D 11AD;CFCA;110F 116D 11AD; +CFCB;CFCB;110F 116D 11AE;CFCB;110F 116D 11AE; +CFCC;CFCC;110F 116D 11AF;CFCC;110F 116D 11AF; +CFCD;CFCD;110F 116D 11B0;CFCD;110F 116D 11B0; +CFCE;CFCE;110F 116D 11B1;CFCE;110F 116D 11B1; +CFCF;CFCF;110F 116D 11B2;CFCF;110F 116D 11B2; +CFD0;CFD0;110F 116D 11B3;CFD0;110F 116D 11B3; +CFD1;CFD1;110F 116D 11B4;CFD1;110F 116D 11B4; +CFD2;CFD2;110F 116D 11B5;CFD2;110F 116D 11B5; +CFD3;CFD3;110F 116D 11B6;CFD3;110F 116D 11B6; +CFD4;CFD4;110F 116D 11B7;CFD4;110F 116D 11B7; +CFD5;CFD5;110F 116D 11B8;CFD5;110F 116D 11B8; +CFD6;CFD6;110F 116D 11B9;CFD6;110F 116D 11B9; +CFD7;CFD7;110F 116D 11BA;CFD7;110F 116D 11BA; +CFD8;CFD8;110F 116D 11BB;CFD8;110F 116D 11BB; +CFD9;CFD9;110F 116D 11BC;CFD9;110F 116D 11BC; +CFDA;CFDA;110F 116D 11BD;CFDA;110F 116D 11BD; +CFDB;CFDB;110F 116D 11BE;CFDB;110F 116D 11BE; +CFDC;CFDC;110F 116D 11BF;CFDC;110F 116D 11BF; +CFDD;CFDD;110F 116D 11C0;CFDD;110F 116D 11C0; +CFDE;CFDE;110F 116D 11C1;CFDE;110F 116D 11C1; +CFDF;CFDF;110F 116D 11C2;CFDF;110F 116D 11C2; +CFE0;CFE0;110F 116E;CFE0;110F 116E; +CFE1;CFE1;110F 116E 11A8;CFE1;110F 116E 11A8; +CFE2;CFE2;110F 116E 11A9;CFE2;110F 116E 11A9; +CFE3;CFE3;110F 116E 11AA;CFE3;110F 116E 11AA; +CFE4;CFE4;110F 116E 11AB;CFE4;110F 116E 11AB; +CFE5;CFE5;110F 116E 11AC;CFE5;110F 116E 11AC; +CFE6;CFE6;110F 116E 11AD;CFE6;110F 116E 11AD; +CFE7;CFE7;110F 116E 11AE;CFE7;110F 116E 11AE; +CFE8;CFE8;110F 116E 11AF;CFE8;110F 116E 11AF; +CFE9;CFE9;110F 116E 11B0;CFE9;110F 116E 11B0; +CFEA;CFEA;110F 116E 11B1;CFEA;110F 116E 11B1; +CFEB;CFEB;110F 116E 11B2;CFEB;110F 116E 11B2; +CFEC;CFEC;110F 116E 11B3;CFEC;110F 116E 11B3; +CFED;CFED;110F 116E 11B4;CFED;110F 116E 11B4; +CFEE;CFEE;110F 116E 11B5;CFEE;110F 116E 11B5; +CFEF;CFEF;110F 116E 11B6;CFEF;110F 116E 11B6; +CFF0;CFF0;110F 116E 11B7;CFF0;110F 116E 11B7; +CFF1;CFF1;110F 116E 11B8;CFF1;110F 116E 11B8; +CFF2;CFF2;110F 116E 11B9;CFF2;110F 116E 11B9; +CFF3;CFF3;110F 116E 11BA;CFF3;110F 116E 11BA; +CFF4;CFF4;110F 116E 11BB;CFF4;110F 116E 11BB; +CFF5;CFF5;110F 116E 11BC;CFF5;110F 116E 11BC; +CFF6;CFF6;110F 116E 11BD;CFF6;110F 116E 11BD; +CFF7;CFF7;110F 116E 11BE;CFF7;110F 116E 11BE; +CFF8;CFF8;110F 116E 11BF;CFF8;110F 116E 11BF; +CFF9;CFF9;110F 116E 11C0;CFF9;110F 116E 11C0; +CFFA;CFFA;110F 116E 11C1;CFFA;110F 116E 11C1; +CFFB;CFFB;110F 116E 11C2;CFFB;110F 116E 11C2; +CFFC;CFFC;110F 116F;CFFC;110F 116F; +CFFD;CFFD;110F 116F 11A8;CFFD;110F 116F 11A8; +CFFE;CFFE;110F 116F 11A9;CFFE;110F 116F 11A9; +CFFF;CFFF;110F 116F 11AA;CFFF;110F 116F 11AA; +D000;D000;110F 116F 11AB;D000;110F 116F 11AB; +D001;D001;110F 116F 11AC;D001;110F 116F 11AC; +D002;D002;110F 116F 11AD;D002;110F 116F 11AD; +D003;D003;110F 116F 11AE;D003;110F 116F 11AE; +D004;D004;110F 116F 11AF;D004;110F 116F 11AF; +D005;D005;110F 116F 11B0;D005;110F 116F 11B0; +D006;D006;110F 116F 11B1;D006;110F 116F 11B1; +D007;D007;110F 116F 11B2;D007;110F 116F 11B2; +D008;D008;110F 116F 11B3;D008;110F 116F 11B3; +D009;D009;110F 116F 11B4;D009;110F 116F 11B4; +D00A;D00A;110F 116F 11B5;D00A;110F 116F 11B5; +D00B;D00B;110F 116F 11B6;D00B;110F 116F 11B6; +D00C;D00C;110F 116F 11B7;D00C;110F 116F 11B7; +D00D;D00D;110F 116F 11B8;D00D;110F 116F 11B8; +D00E;D00E;110F 116F 11B9;D00E;110F 116F 11B9; +D00F;D00F;110F 116F 11BA;D00F;110F 116F 11BA; +D010;D010;110F 116F 11BB;D010;110F 116F 11BB; +D011;D011;110F 116F 11BC;D011;110F 116F 11BC; +D012;D012;110F 116F 11BD;D012;110F 116F 11BD; +D013;D013;110F 116F 11BE;D013;110F 116F 11BE; +D014;D014;110F 116F 11BF;D014;110F 116F 11BF; +D015;D015;110F 116F 11C0;D015;110F 116F 11C0; +D016;D016;110F 116F 11C1;D016;110F 116F 11C1; +D017;D017;110F 116F 11C2;D017;110F 116F 11C2; +D018;D018;110F 1170;D018;110F 1170; +D019;D019;110F 1170 11A8;D019;110F 1170 11A8; +D01A;D01A;110F 1170 11A9;D01A;110F 1170 11A9; +D01B;D01B;110F 1170 11AA;D01B;110F 1170 11AA; +D01C;D01C;110F 1170 11AB;D01C;110F 1170 11AB; +D01D;D01D;110F 1170 11AC;D01D;110F 1170 11AC; +D01E;D01E;110F 1170 11AD;D01E;110F 1170 11AD; +D01F;D01F;110F 1170 11AE;D01F;110F 1170 11AE; +D020;D020;110F 1170 11AF;D020;110F 1170 11AF; +D021;D021;110F 1170 11B0;D021;110F 1170 11B0; +D022;D022;110F 1170 11B1;D022;110F 1170 11B1; +D023;D023;110F 1170 11B2;D023;110F 1170 11B2; +D024;D024;110F 1170 11B3;D024;110F 1170 11B3; +D025;D025;110F 1170 11B4;D025;110F 1170 11B4; +D026;D026;110F 1170 11B5;D026;110F 1170 11B5; +D027;D027;110F 1170 11B6;D027;110F 1170 11B6; +D028;D028;110F 1170 11B7;D028;110F 1170 11B7; +D029;D029;110F 1170 11B8;D029;110F 1170 11B8; +D02A;D02A;110F 1170 11B9;D02A;110F 1170 11B9; +D02B;D02B;110F 1170 11BA;D02B;110F 1170 11BA; +D02C;D02C;110F 1170 11BB;D02C;110F 1170 11BB; +D02D;D02D;110F 1170 11BC;D02D;110F 1170 11BC; +D02E;D02E;110F 1170 11BD;D02E;110F 1170 11BD; +D02F;D02F;110F 1170 11BE;D02F;110F 1170 11BE; +D030;D030;110F 1170 11BF;D030;110F 1170 11BF; +D031;D031;110F 1170 11C0;D031;110F 1170 11C0; +D032;D032;110F 1170 11C1;D032;110F 1170 11C1; +D033;D033;110F 1170 11C2;D033;110F 1170 11C2; +D034;D034;110F 1171;D034;110F 1171; +D035;D035;110F 1171 11A8;D035;110F 1171 11A8; +D036;D036;110F 1171 11A9;D036;110F 1171 11A9; +D037;D037;110F 1171 11AA;D037;110F 1171 11AA; +D038;D038;110F 1171 11AB;D038;110F 1171 11AB; +D039;D039;110F 1171 11AC;D039;110F 1171 11AC; +D03A;D03A;110F 1171 11AD;D03A;110F 1171 11AD; +D03B;D03B;110F 1171 11AE;D03B;110F 1171 11AE; +D03C;D03C;110F 1171 11AF;D03C;110F 1171 11AF; +D03D;D03D;110F 1171 11B0;D03D;110F 1171 11B0; +D03E;D03E;110F 1171 11B1;D03E;110F 1171 11B1; +D03F;D03F;110F 1171 11B2;D03F;110F 1171 11B2; +D040;D040;110F 1171 11B3;D040;110F 1171 11B3; +D041;D041;110F 1171 11B4;D041;110F 1171 11B4; +D042;D042;110F 1171 11B5;D042;110F 1171 11B5; +D043;D043;110F 1171 11B6;D043;110F 1171 11B6; +D044;D044;110F 1171 11B7;D044;110F 1171 11B7; +D045;D045;110F 1171 11B8;D045;110F 1171 11B8; +D046;D046;110F 1171 11B9;D046;110F 1171 11B9; +D047;D047;110F 1171 11BA;D047;110F 1171 11BA; +D048;D048;110F 1171 11BB;D048;110F 1171 11BB; +D049;D049;110F 1171 11BC;D049;110F 1171 11BC; +D04A;D04A;110F 1171 11BD;D04A;110F 1171 11BD; +D04B;D04B;110F 1171 11BE;D04B;110F 1171 11BE; +D04C;D04C;110F 1171 11BF;D04C;110F 1171 11BF; +D04D;D04D;110F 1171 11C0;D04D;110F 1171 11C0; +D04E;D04E;110F 1171 11C1;D04E;110F 1171 11C1; +D04F;D04F;110F 1171 11C2;D04F;110F 1171 11C2; +D050;D050;110F 1172;D050;110F 1172; +D051;D051;110F 1172 11A8;D051;110F 1172 11A8; +D052;D052;110F 1172 11A9;D052;110F 1172 11A9; +D053;D053;110F 1172 11AA;D053;110F 1172 11AA; +D054;D054;110F 1172 11AB;D054;110F 1172 11AB; +D055;D055;110F 1172 11AC;D055;110F 1172 11AC; +D056;D056;110F 1172 11AD;D056;110F 1172 11AD; +D057;D057;110F 1172 11AE;D057;110F 1172 11AE; +D058;D058;110F 1172 11AF;D058;110F 1172 11AF; +D059;D059;110F 1172 11B0;D059;110F 1172 11B0; +D05A;D05A;110F 1172 11B1;D05A;110F 1172 11B1; +D05B;D05B;110F 1172 11B2;D05B;110F 1172 11B2; +D05C;D05C;110F 1172 11B3;D05C;110F 1172 11B3; +D05D;D05D;110F 1172 11B4;D05D;110F 1172 11B4; +D05E;D05E;110F 1172 11B5;D05E;110F 1172 11B5; +D05F;D05F;110F 1172 11B6;D05F;110F 1172 11B6; +D060;D060;110F 1172 11B7;D060;110F 1172 11B7; +D061;D061;110F 1172 11B8;D061;110F 1172 11B8; +D062;D062;110F 1172 11B9;D062;110F 1172 11B9; +D063;D063;110F 1172 11BA;D063;110F 1172 11BA; +D064;D064;110F 1172 11BB;D064;110F 1172 11BB; +D065;D065;110F 1172 11BC;D065;110F 1172 11BC; +D066;D066;110F 1172 11BD;D066;110F 1172 11BD; +D067;D067;110F 1172 11BE;D067;110F 1172 11BE; +D068;D068;110F 1172 11BF;D068;110F 1172 11BF; +D069;D069;110F 1172 11C0;D069;110F 1172 11C0; +D06A;D06A;110F 1172 11C1;D06A;110F 1172 11C1; +D06B;D06B;110F 1172 11C2;D06B;110F 1172 11C2; +D06C;D06C;110F 1173;D06C;110F 1173; +D06D;D06D;110F 1173 11A8;D06D;110F 1173 11A8; +D06E;D06E;110F 1173 11A9;D06E;110F 1173 11A9; +D06F;D06F;110F 1173 11AA;D06F;110F 1173 11AA; +D070;D070;110F 1173 11AB;D070;110F 1173 11AB; +D071;D071;110F 1173 11AC;D071;110F 1173 11AC; +D072;D072;110F 1173 11AD;D072;110F 1173 11AD; +D073;D073;110F 1173 11AE;D073;110F 1173 11AE; +D074;D074;110F 1173 11AF;D074;110F 1173 11AF; +D075;D075;110F 1173 11B0;D075;110F 1173 11B0; +D076;D076;110F 1173 11B1;D076;110F 1173 11B1; +D077;D077;110F 1173 11B2;D077;110F 1173 11B2; +D078;D078;110F 1173 11B3;D078;110F 1173 11B3; +D079;D079;110F 1173 11B4;D079;110F 1173 11B4; +D07A;D07A;110F 1173 11B5;D07A;110F 1173 11B5; +D07B;D07B;110F 1173 11B6;D07B;110F 1173 11B6; +D07C;D07C;110F 1173 11B7;D07C;110F 1173 11B7; +D07D;D07D;110F 1173 11B8;D07D;110F 1173 11B8; +D07E;D07E;110F 1173 11B9;D07E;110F 1173 11B9; +D07F;D07F;110F 1173 11BA;D07F;110F 1173 11BA; +D080;D080;110F 1173 11BB;D080;110F 1173 11BB; +D081;D081;110F 1173 11BC;D081;110F 1173 11BC; +D082;D082;110F 1173 11BD;D082;110F 1173 11BD; +D083;D083;110F 1173 11BE;D083;110F 1173 11BE; +D084;D084;110F 1173 11BF;D084;110F 1173 11BF; +D085;D085;110F 1173 11C0;D085;110F 1173 11C0; +D086;D086;110F 1173 11C1;D086;110F 1173 11C1; +D087;D087;110F 1173 11C2;D087;110F 1173 11C2; +D088;D088;110F 1174;D088;110F 1174; +D089;D089;110F 1174 11A8;D089;110F 1174 11A8; +D08A;D08A;110F 1174 11A9;D08A;110F 1174 11A9; +D08B;D08B;110F 1174 11AA;D08B;110F 1174 11AA; +D08C;D08C;110F 1174 11AB;D08C;110F 1174 11AB; +D08D;D08D;110F 1174 11AC;D08D;110F 1174 11AC; +D08E;D08E;110F 1174 11AD;D08E;110F 1174 11AD; +D08F;D08F;110F 1174 11AE;D08F;110F 1174 11AE; +D090;D090;110F 1174 11AF;D090;110F 1174 11AF; +D091;D091;110F 1174 11B0;D091;110F 1174 11B0; +D092;D092;110F 1174 11B1;D092;110F 1174 11B1; +D093;D093;110F 1174 11B2;D093;110F 1174 11B2; +D094;D094;110F 1174 11B3;D094;110F 1174 11B3; +D095;D095;110F 1174 11B4;D095;110F 1174 11B4; +D096;D096;110F 1174 11B5;D096;110F 1174 11B5; +D097;D097;110F 1174 11B6;D097;110F 1174 11B6; +D098;D098;110F 1174 11B7;D098;110F 1174 11B7; +D099;D099;110F 1174 11B8;D099;110F 1174 11B8; +D09A;D09A;110F 1174 11B9;D09A;110F 1174 11B9; +D09B;D09B;110F 1174 11BA;D09B;110F 1174 11BA; +D09C;D09C;110F 1174 11BB;D09C;110F 1174 11BB; +D09D;D09D;110F 1174 11BC;D09D;110F 1174 11BC; +D09E;D09E;110F 1174 11BD;D09E;110F 1174 11BD; +D09F;D09F;110F 1174 11BE;D09F;110F 1174 11BE; +D0A0;D0A0;110F 1174 11BF;D0A0;110F 1174 11BF; +D0A1;D0A1;110F 1174 11C0;D0A1;110F 1174 11C0; +D0A2;D0A2;110F 1174 11C1;D0A2;110F 1174 11C1; +D0A3;D0A3;110F 1174 11C2;D0A3;110F 1174 11C2; +D0A4;D0A4;110F 1175;D0A4;110F 1175; +D0A5;D0A5;110F 1175 11A8;D0A5;110F 1175 11A8; +D0A6;D0A6;110F 1175 11A9;D0A6;110F 1175 11A9; +D0A7;D0A7;110F 1175 11AA;D0A7;110F 1175 11AA; +D0A8;D0A8;110F 1175 11AB;D0A8;110F 1175 11AB; +D0A9;D0A9;110F 1175 11AC;D0A9;110F 1175 11AC; +D0AA;D0AA;110F 1175 11AD;D0AA;110F 1175 11AD; +D0AB;D0AB;110F 1175 11AE;D0AB;110F 1175 11AE; +D0AC;D0AC;110F 1175 11AF;D0AC;110F 1175 11AF; +D0AD;D0AD;110F 1175 11B0;D0AD;110F 1175 11B0; +D0AE;D0AE;110F 1175 11B1;D0AE;110F 1175 11B1; +D0AF;D0AF;110F 1175 11B2;D0AF;110F 1175 11B2; +D0B0;D0B0;110F 1175 11B3;D0B0;110F 1175 11B3; +D0B1;D0B1;110F 1175 11B4;D0B1;110F 1175 11B4; +D0B2;D0B2;110F 1175 11B5;D0B2;110F 1175 11B5; +D0B3;D0B3;110F 1175 11B6;D0B3;110F 1175 11B6; +D0B4;D0B4;110F 1175 11B7;D0B4;110F 1175 11B7; +D0B5;D0B5;110F 1175 11B8;D0B5;110F 1175 11B8; +D0B6;D0B6;110F 1175 11B9;D0B6;110F 1175 11B9; +D0B7;D0B7;110F 1175 11BA;D0B7;110F 1175 11BA; +D0B8;D0B8;110F 1175 11BB;D0B8;110F 1175 11BB; +D0B9;D0B9;110F 1175 11BC;D0B9;110F 1175 11BC; +D0BA;D0BA;110F 1175 11BD;D0BA;110F 1175 11BD; +D0BB;D0BB;110F 1175 11BE;D0BB;110F 1175 11BE; +D0BC;D0BC;110F 1175 11BF;D0BC;110F 1175 11BF; +D0BD;D0BD;110F 1175 11C0;D0BD;110F 1175 11C0; +D0BE;D0BE;110F 1175 11C1;D0BE;110F 1175 11C1; +D0BF;D0BF;110F 1175 11C2;D0BF;110F 1175 11C2; +D0C0;D0C0;1110 1161;D0C0;1110 1161; +D0C1;D0C1;1110 1161 11A8;D0C1;1110 1161 11A8; +D0C2;D0C2;1110 1161 11A9;D0C2;1110 1161 11A9; +D0C3;D0C3;1110 1161 11AA;D0C3;1110 1161 11AA; +D0C4;D0C4;1110 1161 11AB;D0C4;1110 1161 11AB; +D0C5;D0C5;1110 1161 11AC;D0C5;1110 1161 11AC; +D0C6;D0C6;1110 1161 11AD;D0C6;1110 1161 11AD; +D0C7;D0C7;1110 1161 11AE;D0C7;1110 1161 11AE; +D0C8;D0C8;1110 1161 11AF;D0C8;1110 1161 11AF; +D0C9;D0C9;1110 1161 11B0;D0C9;1110 1161 11B0; +D0CA;D0CA;1110 1161 11B1;D0CA;1110 1161 11B1; +D0CB;D0CB;1110 1161 11B2;D0CB;1110 1161 11B2; +D0CC;D0CC;1110 1161 11B3;D0CC;1110 1161 11B3; +D0CD;D0CD;1110 1161 11B4;D0CD;1110 1161 11B4; +D0CE;D0CE;1110 1161 11B5;D0CE;1110 1161 11B5; +D0CF;D0CF;1110 1161 11B6;D0CF;1110 1161 11B6; +D0D0;D0D0;1110 1161 11B7;D0D0;1110 1161 11B7; +D0D1;D0D1;1110 1161 11B8;D0D1;1110 1161 11B8; +D0D2;D0D2;1110 1161 11B9;D0D2;1110 1161 11B9; +D0D3;D0D3;1110 1161 11BA;D0D3;1110 1161 11BA; +D0D4;D0D4;1110 1161 11BB;D0D4;1110 1161 11BB; +D0D5;D0D5;1110 1161 11BC;D0D5;1110 1161 11BC; +D0D6;D0D6;1110 1161 11BD;D0D6;1110 1161 11BD; +D0D7;D0D7;1110 1161 11BE;D0D7;1110 1161 11BE; +D0D8;D0D8;1110 1161 11BF;D0D8;1110 1161 11BF; +D0D9;D0D9;1110 1161 11C0;D0D9;1110 1161 11C0; +D0DA;D0DA;1110 1161 11C1;D0DA;1110 1161 11C1; +D0DB;D0DB;1110 1161 11C2;D0DB;1110 1161 11C2; +D0DC;D0DC;1110 1162;D0DC;1110 1162; +D0DD;D0DD;1110 1162 11A8;D0DD;1110 1162 11A8; +D0DE;D0DE;1110 1162 11A9;D0DE;1110 1162 11A9; +D0DF;D0DF;1110 1162 11AA;D0DF;1110 1162 11AA; +D0E0;D0E0;1110 1162 11AB;D0E0;1110 1162 11AB; +D0E1;D0E1;1110 1162 11AC;D0E1;1110 1162 11AC; +D0E2;D0E2;1110 1162 11AD;D0E2;1110 1162 11AD; +D0E3;D0E3;1110 1162 11AE;D0E3;1110 1162 11AE; +D0E4;D0E4;1110 1162 11AF;D0E4;1110 1162 11AF; +D0E5;D0E5;1110 1162 11B0;D0E5;1110 1162 11B0; +D0E6;D0E6;1110 1162 11B1;D0E6;1110 1162 11B1; +D0E7;D0E7;1110 1162 11B2;D0E7;1110 1162 11B2; +D0E8;D0E8;1110 1162 11B3;D0E8;1110 1162 11B3; +D0E9;D0E9;1110 1162 11B4;D0E9;1110 1162 11B4; +D0EA;D0EA;1110 1162 11B5;D0EA;1110 1162 11B5; +D0EB;D0EB;1110 1162 11B6;D0EB;1110 1162 11B6; +D0EC;D0EC;1110 1162 11B7;D0EC;1110 1162 11B7; +D0ED;D0ED;1110 1162 11B8;D0ED;1110 1162 11B8; +D0EE;D0EE;1110 1162 11B9;D0EE;1110 1162 11B9; +D0EF;D0EF;1110 1162 11BA;D0EF;1110 1162 11BA; +D0F0;D0F0;1110 1162 11BB;D0F0;1110 1162 11BB; +D0F1;D0F1;1110 1162 11BC;D0F1;1110 1162 11BC; +D0F2;D0F2;1110 1162 11BD;D0F2;1110 1162 11BD; +D0F3;D0F3;1110 1162 11BE;D0F3;1110 1162 11BE; +D0F4;D0F4;1110 1162 11BF;D0F4;1110 1162 11BF; +D0F5;D0F5;1110 1162 11C0;D0F5;1110 1162 11C0; +D0F6;D0F6;1110 1162 11C1;D0F6;1110 1162 11C1; +D0F7;D0F7;1110 1162 11C2;D0F7;1110 1162 11C2; +D0F8;D0F8;1110 1163;D0F8;1110 1163; +D0F9;D0F9;1110 1163 11A8;D0F9;1110 1163 11A8; +D0FA;D0FA;1110 1163 11A9;D0FA;1110 1163 11A9; +D0FB;D0FB;1110 1163 11AA;D0FB;1110 1163 11AA; +D0FC;D0FC;1110 1163 11AB;D0FC;1110 1163 11AB; +D0FD;D0FD;1110 1163 11AC;D0FD;1110 1163 11AC; +D0FE;D0FE;1110 1163 11AD;D0FE;1110 1163 11AD; +D0FF;D0FF;1110 1163 11AE;D0FF;1110 1163 11AE; +D100;D100;1110 1163 11AF;D100;1110 1163 11AF; +D101;D101;1110 1163 11B0;D101;1110 1163 11B0; +D102;D102;1110 1163 11B1;D102;1110 1163 11B1; +D103;D103;1110 1163 11B2;D103;1110 1163 11B2; +D104;D104;1110 1163 11B3;D104;1110 1163 11B3; +D105;D105;1110 1163 11B4;D105;1110 1163 11B4; +D106;D106;1110 1163 11B5;D106;1110 1163 11B5; +D107;D107;1110 1163 11B6;D107;1110 1163 11B6; +D108;D108;1110 1163 11B7;D108;1110 1163 11B7; +D109;D109;1110 1163 11B8;D109;1110 1163 11B8; +D10A;D10A;1110 1163 11B9;D10A;1110 1163 11B9; +D10B;D10B;1110 1163 11BA;D10B;1110 1163 11BA; +D10C;D10C;1110 1163 11BB;D10C;1110 1163 11BB; +D10D;D10D;1110 1163 11BC;D10D;1110 1163 11BC; +D10E;D10E;1110 1163 11BD;D10E;1110 1163 11BD; +D10F;D10F;1110 1163 11BE;D10F;1110 1163 11BE; +D110;D110;1110 1163 11BF;D110;1110 1163 11BF; +D111;D111;1110 1163 11C0;D111;1110 1163 11C0; +D112;D112;1110 1163 11C1;D112;1110 1163 11C1; +D113;D113;1110 1163 11C2;D113;1110 1163 11C2; +D114;D114;1110 1164;D114;1110 1164; +D115;D115;1110 1164 11A8;D115;1110 1164 11A8; +D116;D116;1110 1164 11A9;D116;1110 1164 11A9; +D117;D117;1110 1164 11AA;D117;1110 1164 11AA; +D118;D118;1110 1164 11AB;D118;1110 1164 11AB; +D119;D119;1110 1164 11AC;D119;1110 1164 11AC; +D11A;D11A;1110 1164 11AD;D11A;1110 1164 11AD; +D11B;D11B;1110 1164 11AE;D11B;1110 1164 11AE; +D11C;D11C;1110 1164 11AF;D11C;1110 1164 11AF; +D11D;D11D;1110 1164 11B0;D11D;1110 1164 11B0; +D11E;D11E;1110 1164 11B1;D11E;1110 1164 11B1; +D11F;D11F;1110 1164 11B2;D11F;1110 1164 11B2; +D120;D120;1110 1164 11B3;D120;1110 1164 11B3; +D121;D121;1110 1164 11B4;D121;1110 1164 11B4; +D122;D122;1110 1164 11B5;D122;1110 1164 11B5; +D123;D123;1110 1164 11B6;D123;1110 1164 11B6; +D124;D124;1110 1164 11B7;D124;1110 1164 11B7; +D125;D125;1110 1164 11B8;D125;1110 1164 11B8; +D126;D126;1110 1164 11B9;D126;1110 1164 11B9; +D127;D127;1110 1164 11BA;D127;1110 1164 11BA; +D128;D128;1110 1164 11BB;D128;1110 1164 11BB; +D129;D129;1110 1164 11BC;D129;1110 1164 11BC; +D12A;D12A;1110 1164 11BD;D12A;1110 1164 11BD; +D12B;D12B;1110 1164 11BE;D12B;1110 1164 11BE; +D12C;D12C;1110 1164 11BF;D12C;1110 1164 11BF; +D12D;D12D;1110 1164 11C0;D12D;1110 1164 11C0; +D12E;D12E;1110 1164 11C1;D12E;1110 1164 11C1; +D12F;D12F;1110 1164 11C2;D12F;1110 1164 11C2; +D130;D130;1110 1165;D130;1110 1165; +D131;D131;1110 1165 11A8;D131;1110 1165 11A8; +D132;D132;1110 1165 11A9;D132;1110 1165 11A9; +D133;D133;1110 1165 11AA;D133;1110 1165 11AA; +D134;D134;1110 1165 11AB;D134;1110 1165 11AB; +D135;D135;1110 1165 11AC;D135;1110 1165 11AC; +D136;D136;1110 1165 11AD;D136;1110 1165 11AD; +D137;D137;1110 1165 11AE;D137;1110 1165 11AE; +D138;D138;1110 1165 11AF;D138;1110 1165 11AF; +D139;D139;1110 1165 11B0;D139;1110 1165 11B0; +D13A;D13A;1110 1165 11B1;D13A;1110 1165 11B1; +D13B;D13B;1110 1165 11B2;D13B;1110 1165 11B2; +D13C;D13C;1110 1165 11B3;D13C;1110 1165 11B3; +D13D;D13D;1110 1165 11B4;D13D;1110 1165 11B4; +D13E;D13E;1110 1165 11B5;D13E;1110 1165 11B5; +D13F;D13F;1110 1165 11B6;D13F;1110 1165 11B6; +D140;D140;1110 1165 11B7;D140;1110 1165 11B7; +D141;D141;1110 1165 11B8;D141;1110 1165 11B8; +D142;D142;1110 1165 11B9;D142;1110 1165 11B9; +D143;D143;1110 1165 11BA;D143;1110 1165 11BA; +D144;D144;1110 1165 11BB;D144;1110 1165 11BB; +D145;D145;1110 1165 11BC;D145;1110 1165 11BC; +D146;D146;1110 1165 11BD;D146;1110 1165 11BD; +D147;D147;1110 1165 11BE;D147;1110 1165 11BE; +D148;D148;1110 1165 11BF;D148;1110 1165 11BF; +D149;D149;1110 1165 11C0;D149;1110 1165 11C0; +D14A;D14A;1110 1165 11C1;D14A;1110 1165 11C1; +D14B;D14B;1110 1165 11C2;D14B;1110 1165 11C2; +D14C;D14C;1110 1166;D14C;1110 1166; +D14D;D14D;1110 1166 11A8;D14D;1110 1166 11A8; +D14E;D14E;1110 1166 11A9;D14E;1110 1166 11A9; +D14F;D14F;1110 1166 11AA;D14F;1110 1166 11AA; +D150;D150;1110 1166 11AB;D150;1110 1166 11AB; +D151;D151;1110 1166 11AC;D151;1110 1166 11AC; +D152;D152;1110 1166 11AD;D152;1110 1166 11AD; +D153;D153;1110 1166 11AE;D153;1110 1166 11AE; +D154;D154;1110 1166 11AF;D154;1110 1166 11AF; +D155;D155;1110 1166 11B0;D155;1110 1166 11B0; +D156;D156;1110 1166 11B1;D156;1110 1166 11B1; +D157;D157;1110 1166 11B2;D157;1110 1166 11B2; +D158;D158;1110 1166 11B3;D158;1110 1166 11B3; +D159;D159;1110 1166 11B4;D159;1110 1166 11B4; +D15A;D15A;1110 1166 11B5;D15A;1110 1166 11B5; +D15B;D15B;1110 1166 11B6;D15B;1110 1166 11B6; +D15C;D15C;1110 1166 11B7;D15C;1110 1166 11B7; +D15D;D15D;1110 1166 11B8;D15D;1110 1166 11B8; +D15E;D15E;1110 1166 11B9;D15E;1110 1166 11B9; +D15F;D15F;1110 1166 11BA;D15F;1110 1166 11BA; +D160;D160;1110 1166 11BB;D160;1110 1166 11BB; +D161;D161;1110 1166 11BC;D161;1110 1166 11BC; +D162;D162;1110 1166 11BD;D162;1110 1166 11BD; +D163;D163;1110 1166 11BE;D163;1110 1166 11BE; +D164;D164;1110 1166 11BF;D164;1110 1166 11BF; +D165;D165;1110 1166 11C0;D165;1110 1166 11C0; +D166;D166;1110 1166 11C1;D166;1110 1166 11C1; +D167;D167;1110 1166 11C2;D167;1110 1166 11C2; +D168;D168;1110 1167;D168;1110 1167; +D169;D169;1110 1167 11A8;D169;1110 1167 11A8; +D16A;D16A;1110 1167 11A9;D16A;1110 1167 11A9; +D16B;D16B;1110 1167 11AA;D16B;1110 1167 11AA; +D16C;D16C;1110 1167 11AB;D16C;1110 1167 11AB; +D16D;D16D;1110 1167 11AC;D16D;1110 1167 11AC; +D16E;D16E;1110 1167 11AD;D16E;1110 1167 11AD; +D16F;D16F;1110 1167 11AE;D16F;1110 1167 11AE; +D170;D170;1110 1167 11AF;D170;1110 1167 11AF; +D171;D171;1110 1167 11B0;D171;1110 1167 11B0; +D172;D172;1110 1167 11B1;D172;1110 1167 11B1; +D173;D173;1110 1167 11B2;D173;1110 1167 11B2; +D174;D174;1110 1167 11B3;D174;1110 1167 11B3; +D175;D175;1110 1167 11B4;D175;1110 1167 11B4; +D176;D176;1110 1167 11B5;D176;1110 1167 11B5; +D177;D177;1110 1167 11B6;D177;1110 1167 11B6; +D178;D178;1110 1167 11B7;D178;1110 1167 11B7; +D179;D179;1110 1167 11B8;D179;1110 1167 11B8; +D17A;D17A;1110 1167 11B9;D17A;1110 1167 11B9; +D17B;D17B;1110 1167 11BA;D17B;1110 1167 11BA; +D17C;D17C;1110 1167 11BB;D17C;1110 1167 11BB; +D17D;D17D;1110 1167 11BC;D17D;1110 1167 11BC; +D17E;D17E;1110 1167 11BD;D17E;1110 1167 11BD; +D17F;D17F;1110 1167 11BE;D17F;1110 1167 11BE; +D180;D180;1110 1167 11BF;D180;1110 1167 11BF; +D181;D181;1110 1167 11C0;D181;1110 1167 11C0; +D182;D182;1110 1167 11C1;D182;1110 1167 11C1; +D183;D183;1110 1167 11C2;D183;1110 1167 11C2; +D184;D184;1110 1168;D184;1110 1168; +D185;D185;1110 1168 11A8;D185;1110 1168 11A8; +D186;D186;1110 1168 11A9;D186;1110 1168 11A9; +D187;D187;1110 1168 11AA;D187;1110 1168 11AA; +D188;D188;1110 1168 11AB;D188;1110 1168 11AB; +D189;D189;1110 1168 11AC;D189;1110 1168 11AC; +D18A;D18A;1110 1168 11AD;D18A;1110 1168 11AD; +D18B;D18B;1110 1168 11AE;D18B;1110 1168 11AE; +D18C;D18C;1110 1168 11AF;D18C;1110 1168 11AF; +D18D;D18D;1110 1168 11B0;D18D;1110 1168 11B0; +D18E;D18E;1110 1168 11B1;D18E;1110 1168 11B1; +D18F;D18F;1110 1168 11B2;D18F;1110 1168 11B2; +D190;D190;1110 1168 11B3;D190;1110 1168 11B3; +D191;D191;1110 1168 11B4;D191;1110 1168 11B4; +D192;D192;1110 1168 11B5;D192;1110 1168 11B5; +D193;D193;1110 1168 11B6;D193;1110 1168 11B6; +D194;D194;1110 1168 11B7;D194;1110 1168 11B7; +D195;D195;1110 1168 11B8;D195;1110 1168 11B8; +D196;D196;1110 1168 11B9;D196;1110 1168 11B9; +D197;D197;1110 1168 11BA;D197;1110 1168 11BA; +D198;D198;1110 1168 11BB;D198;1110 1168 11BB; +D199;D199;1110 1168 11BC;D199;1110 1168 11BC; +D19A;D19A;1110 1168 11BD;D19A;1110 1168 11BD; +D19B;D19B;1110 1168 11BE;D19B;1110 1168 11BE; +D19C;D19C;1110 1168 11BF;D19C;1110 1168 11BF; +D19D;D19D;1110 1168 11C0;D19D;1110 1168 11C0; +D19E;D19E;1110 1168 11C1;D19E;1110 1168 11C1; +D19F;D19F;1110 1168 11C2;D19F;1110 1168 11C2; +D1A0;D1A0;1110 1169;D1A0;1110 1169; +D1A1;D1A1;1110 1169 11A8;D1A1;1110 1169 11A8; +D1A2;D1A2;1110 1169 11A9;D1A2;1110 1169 11A9; +D1A3;D1A3;1110 1169 11AA;D1A3;1110 1169 11AA; +D1A4;D1A4;1110 1169 11AB;D1A4;1110 1169 11AB; +D1A5;D1A5;1110 1169 11AC;D1A5;1110 1169 11AC; +D1A6;D1A6;1110 1169 11AD;D1A6;1110 1169 11AD; +D1A7;D1A7;1110 1169 11AE;D1A7;1110 1169 11AE; +D1A8;D1A8;1110 1169 11AF;D1A8;1110 1169 11AF; +D1A9;D1A9;1110 1169 11B0;D1A9;1110 1169 11B0; +D1AA;D1AA;1110 1169 11B1;D1AA;1110 1169 11B1; +D1AB;D1AB;1110 1169 11B2;D1AB;1110 1169 11B2; +D1AC;D1AC;1110 1169 11B3;D1AC;1110 1169 11B3; +D1AD;D1AD;1110 1169 11B4;D1AD;1110 1169 11B4; +D1AE;D1AE;1110 1169 11B5;D1AE;1110 1169 11B5; +D1AF;D1AF;1110 1169 11B6;D1AF;1110 1169 11B6; +D1B0;D1B0;1110 1169 11B7;D1B0;1110 1169 11B7; +D1B1;D1B1;1110 1169 11B8;D1B1;1110 1169 11B8; +D1B2;D1B2;1110 1169 11B9;D1B2;1110 1169 11B9; +D1B3;D1B3;1110 1169 11BA;D1B3;1110 1169 11BA; +D1B4;D1B4;1110 1169 11BB;D1B4;1110 1169 11BB; +D1B5;D1B5;1110 1169 11BC;D1B5;1110 1169 11BC; +D1B6;D1B6;1110 1169 11BD;D1B6;1110 1169 11BD; +D1B7;D1B7;1110 1169 11BE;D1B7;1110 1169 11BE; +D1B8;D1B8;1110 1169 11BF;D1B8;1110 1169 11BF; +D1B9;D1B9;1110 1169 11C0;D1B9;1110 1169 11C0; +D1BA;D1BA;1110 1169 11C1;D1BA;1110 1169 11C1; +D1BB;D1BB;1110 1169 11C2;D1BB;1110 1169 11C2; +D1BC;D1BC;1110 116A;D1BC;1110 116A; +D1BD;D1BD;1110 116A 11A8;D1BD;1110 116A 11A8; +D1BE;D1BE;1110 116A 11A9;D1BE;1110 116A 11A9; +D1BF;D1BF;1110 116A 11AA;D1BF;1110 116A 11AA; +D1C0;D1C0;1110 116A 11AB;D1C0;1110 116A 11AB; +D1C1;D1C1;1110 116A 11AC;D1C1;1110 116A 11AC; +D1C2;D1C2;1110 116A 11AD;D1C2;1110 116A 11AD; +D1C3;D1C3;1110 116A 11AE;D1C3;1110 116A 11AE; +D1C4;D1C4;1110 116A 11AF;D1C4;1110 116A 11AF; +D1C5;D1C5;1110 116A 11B0;D1C5;1110 116A 11B0; +D1C6;D1C6;1110 116A 11B1;D1C6;1110 116A 11B1; +D1C7;D1C7;1110 116A 11B2;D1C7;1110 116A 11B2; +D1C8;D1C8;1110 116A 11B3;D1C8;1110 116A 11B3; +D1C9;D1C9;1110 116A 11B4;D1C9;1110 116A 11B4; +D1CA;D1CA;1110 116A 11B5;D1CA;1110 116A 11B5; +D1CB;D1CB;1110 116A 11B6;D1CB;1110 116A 11B6; +D1CC;D1CC;1110 116A 11B7;D1CC;1110 116A 11B7; +D1CD;D1CD;1110 116A 11B8;D1CD;1110 116A 11B8; +D1CE;D1CE;1110 116A 11B9;D1CE;1110 116A 11B9; +D1CF;D1CF;1110 116A 11BA;D1CF;1110 116A 11BA; +D1D0;D1D0;1110 116A 11BB;D1D0;1110 116A 11BB; +D1D1;D1D1;1110 116A 11BC;D1D1;1110 116A 11BC; +D1D2;D1D2;1110 116A 11BD;D1D2;1110 116A 11BD; +D1D3;D1D3;1110 116A 11BE;D1D3;1110 116A 11BE; +D1D4;D1D4;1110 116A 11BF;D1D4;1110 116A 11BF; +D1D5;D1D5;1110 116A 11C0;D1D5;1110 116A 11C0; +D1D6;D1D6;1110 116A 11C1;D1D6;1110 116A 11C1; +D1D7;D1D7;1110 116A 11C2;D1D7;1110 116A 11C2; +D1D8;D1D8;1110 116B;D1D8;1110 116B; +D1D9;D1D9;1110 116B 11A8;D1D9;1110 116B 11A8; +D1DA;D1DA;1110 116B 11A9;D1DA;1110 116B 11A9; +D1DB;D1DB;1110 116B 11AA;D1DB;1110 116B 11AA; +D1DC;D1DC;1110 116B 11AB;D1DC;1110 116B 11AB; +D1DD;D1DD;1110 116B 11AC;D1DD;1110 116B 11AC; +D1DE;D1DE;1110 116B 11AD;D1DE;1110 116B 11AD; +D1DF;D1DF;1110 116B 11AE;D1DF;1110 116B 11AE; +D1E0;D1E0;1110 116B 11AF;D1E0;1110 116B 11AF; +D1E1;D1E1;1110 116B 11B0;D1E1;1110 116B 11B0; +D1E2;D1E2;1110 116B 11B1;D1E2;1110 116B 11B1; +D1E3;D1E3;1110 116B 11B2;D1E3;1110 116B 11B2; +D1E4;D1E4;1110 116B 11B3;D1E4;1110 116B 11B3; +D1E5;D1E5;1110 116B 11B4;D1E5;1110 116B 11B4; +D1E6;D1E6;1110 116B 11B5;D1E6;1110 116B 11B5; +D1E7;D1E7;1110 116B 11B6;D1E7;1110 116B 11B6; +D1E8;D1E8;1110 116B 11B7;D1E8;1110 116B 11B7; +D1E9;D1E9;1110 116B 11B8;D1E9;1110 116B 11B8; +D1EA;D1EA;1110 116B 11B9;D1EA;1110 116B 11B9; +D1EB;D1EB;1110 116B 11BA;D1EB;1110 116B 11BA; +D1EC;D1EC;1110 116B 11BB;D1EC;1110 116B 11BB; +D1ED;D1ED;1110 116B 11BC;D1ED;1110 116B 11BC; +D1EE;D1EE;1110 116B 11BD;D1EE;1110 116B 11BD; +D1EF;D1EF;1110 116B 11BE;D1EF;1110 116B 11BE; +D1F0;D1F0;1110 116B 11BF;D1F0;1110 116B 11BF; +D1F1;D1F1;1110 116B 11C0;D1F1;1110 116B 11C0; +D1F2;D1F2;1110 116B 11C1;D1F2;1110 116B 11C1; +D1F3;D1F3;1110 116B 11C2;D1F3;1110 116B 11C2; +D1F4;D1F4;1110 116C;D1F4;1110 116C; +D1F5;D1F5;1110 116C 11A8;D1F5;1110 116C 11A8; +D1F6;D1F6;1110 116C 11A9;D1F6;1110 116C 11A9; +D1F7;D1F7;1110 116C 11AA;D1F7;1110 116C 11AA; +D1F8;D1F8;1110 116C 11AB;D1F8;1110 116C 11AB; +D1F9;D1F9;1110 116C 11AC;D1F9;1110 116C 11AC; +D1FA;D1FA;1110 116C 11AD;D1FA;1110 116C 11AD; +D1FB;D1FB;1110 116C 11AE;D1FB;1110 116C 11AE; +D1FC;D1FC;1110 116C 11AF;D1FC;1110 116C 11AF; +D1FD;D1FD;1110 116C 11B0;D1FD;1110 116C 11B0; +D1FE;D1FE;1110 116C 11B1;D1FE;1110 116C 11B1; +D1FF;D1FF;1110 116C 11B2;D1FF;1110 116C 11B2; +D200;D200;1110 116C 11B3;D200;1110 116C 11B3; +D201;D201;1110 116C 11B4;D201;1110 116C 11B4; +D202;D202;1110 116C 11B5;D202;1110 116C 11B5; +D203;D203;1110 116C 11B6;D203;1110 116C 11B6; +D204;D204;1110 116C 11B7;D204;1110 116C 11B7; +D205;D205;1110 116C 11B8;D205;1110 116C 11B8; +D206;D206;1110 116C 11B9;D206;1110 116C 11B9; +D207;D207;1110 116C 11BA;D207;1110 116C 11BA; +D208;D208;1110 116C 11BB;D208;1110 116C 11BB; +D209;D209;1110 116C 11BC;D209;1110 116C 11BC; +D20A;D20A;1110 116C 11BD;D20A;1110 116C 11BD; +D20B;D20B;1110 116C 11BE;D20B;1110 116C 11BE; +D20C;D20C;1110 116C 11BF;D20C;1110 116C 11BF; +D20D;D20D;1110 116C 11C0;D20D;1110 116C 11C0; +D20E;D20E;1110 116C 11C1;D20E;1110 116C 11C1; +D20F;D20F;1110 116C 11C2;D20F;1110 116C 11C2; +D210;D210;1110 116D;D210;1110 116D; +D211;D211;1110 116D 11A8;D211;1110 116D 11A8; +D212;D212;1110 116D 11A9;D212;1110 116D 11A9; +D213;D213;1110 116D 11AA;D213;1110 116D 11AA; +D214;D214;1110 116D 11AB;D214;1110 116D 11AB; +D215;D215;1110 116D 11AC;D215;1110 116D 11AC; +D216;D216;1110 116D 11AD;D216;1110 116D 11AD; +D217;D217;1110 116D 11AE;D217;1110 116D 11AE; +D218;D218;1110 116D 11AF;D218;1110 116D 11AF; +D219;D219;1110 116D 11B0;D219;1110 116D 11B0; +D21A;D21A;1110 116D 11B1;D21A;1110 116D 11B1; +D21B;D21B;1110 116D 11B2;D21B;1110 116D 11B2; +D21C;D21C;1110 116D 11B3;D21C;1110 116D 11B3; +D21D;D21D;1110 116D 11B4;D21D;1110 116D 11B4; +D21E;D21E;1110 116D 11B5;D21E;1110 116D 11B5; +D21F;D21F;1110 116D 11B6;D21F;1110 116D 11B6; +D220;D220;1110 116D 11B7;D220;1110 116D 11B7; +D221;D221;1110 116D 11B8;D221;1110 116D 11B8; +D222;D222;1110 116D 11B9;D222;1110 116D 11B9; +D223;D223;1110 116D 11BA;D223;1110 116D 11BA; +D224;D224;1110 116D 11BB;D224;1110 116D 11BB; +D225;D225;1110 116D 11BC;D225;1110 116D 11BC; +D226;D226;1110 116D 11BD;D226;1110 116D 11BD; +D227;D227;1110 116D 11BE;D227;1110 116D 11BE; +D228;D228;1110 116D 11BF;D228;1110 116D 11BF; +D229;D229;1110 116D 11C0;D229;1110 116D 11C0; +D22A;D22A;1110 116D 11C1;D22A;1110 116D 11C1; +D22B;D22B;1110 116D 11C2;D22B;1110 116D 11C2; +D22C;D22C;1110 116E;D22C;1110 116E; +D22D;D22D;1110 116E 11A8;D22D;1110 116E 11A8; +D22E;D22E;1110 116E 11A9;D22E;1110 116E 11A9; +D22F;D22F;1110 116E 11AA;D22F;1110 116E 11AA; +D230;D230;1110 116E 11AB;D230;1110 116E 11AB; +D231;D231;1110 116E 11AC;D231;1110 116E 11AC; +D232;D232;1110 116E 11AD;D232;1110 116E 11AD; +D233;D233;1110 116E 11AE;D233;1110 116E 11AE; +D234;D234;1110 116E 11AF;D234;1110 116E 11AF; +D235;D235;1110 116E 11B0;D235;1110 116E 11B0; +D236;D236;1110 116E 11B1;D236;1110 116E 11B1; +D237;D237;1110 116E 11B2;D237;1110 116E 11B2; +D238;D238;1110 116E 11B3;D238;1110 116E 11B3; +D239;D239;1110 116E 11B4;D239;1110 116E 11B4; +D23A;D23A;1110 116E 11B5;D23A;1110 116E 11B5; +D23B;D23B;1110 116E 11B6;D23B;1110 116E 11B6; +D23C;D23C;1110 116E 11B7;D23C;1110 116E 11B7; +D23D;D23D;1110 116E 11B8;D23D;1110 116E 11B8; +D23E;D23E;1110 116E 11B9;D23E;1110 116E 11B9; +D23F;D23F;1110 116E 11BA;D23F;1110 116E 11BA; +D240;D240;1110 116E 11BB;D240;1110 116E 11BB; +D241;D241;1110 116E 11BC;D241;1110 116E 11BC; +D242;D242;1110 116E 11BD;D242;1110 116E 11BD; +D243;D243;1110 116E 11BE;D243;1110 116E 11BE; +D244;D244;1110 116E 11BF;D244;1110 116E 11BF; +D245;D245;1110 116E 11C0;D245;1110 116E 11C0; +D246;D246;1110 116E 11C1;D246;1110 116E 11C1; +D247;D247;1110 116E 11C2;D247;1110 116E 11C2; +D248;D248;1110 116F;D248;1110 116F; +D249;D249;1110 116F 11A8;D249;1110 116F 11A8; +D24A;D24A;1110 116F 11A9;D24A;1110 116F 11A9; +D24B;D24B;1110 116F 11AA;D24B;1110 116F 11AA; +D24C;D24C;1110 116F 11AB;D24C;1110 116F 11AB; +D24D;D24D;1110 116F 11AC;D24D;1110 116F 11AC; +D24E;D24E;1110 116F 11AD;D24E;1110 116F 11AD; +D24F;D24F;1110 116F 11AE;D24F;1110 116F 11AE; +D250;D250;1110 116F 11AF;D250;1110 116F 11AF; +D251;D251;1110 116F 11B0;D251;1110 116F 11B0; +D252;D252;1110 116F 11B1;D252;1110 116F 11B1; +D253;D253;1110 116F 11B2;D253;1110 116F 11B2; +D254;D254;1110 116F 11B3;D254;1110 116F 11B3; +D255;D255;1110 116F 11B4;D255;1110 116F 11B4; +D256;D256;1110 116F 11B5;D256;1110 116F 11B5; +D257;D257;1110 116F 11B6;D257;1110 116F 11B6; +D258;D258;1110 116F 11B7;D258;1110 116F 11B7; +D259;D259;1110 116F 11B8;D259;1110 116F 11B8; +D25A;D25A;1110 116F 11B9;D25A;1110 116F 11B9; +D25B;D25B;1110 116F 11BA;D25B;1110 116F 11BA; +D25C;D25C;1110 116F 11BB;D25C;1110 116F 11BB; +D25D;D25D;1110 116F 11BC;D25D;1110 116F 11BC; +D25E;D25E;1110 116F 11BD;D25E;1110 116F 11BD; +D25F;D25F;1110 116F 11BE;D25F;1110 116F 11BE; +D260;D260;1110 116F 11BF;D260;1110 116F 11BF; +D261;D261;1110 116F 11C0;D261;1110 116F 11C0; +D262;D262;1110 116F 11C1;D262;1110 116F 11C1; +D263;D263;1110 116F 11C2;D263;1110 116F 11C2; +D264;D264;1110 1170;D264;1110 1170; +D265;D265;1110 1170 11A8;D265;1110 1170 11A8; +D266;D266;1110 1170 11A9;D266;1110 1170 11A9; +D267;D267;1110 1170 11AA;D267;1110 1170 11AA; +D268;D268;1110 1170 11AB;D268;1110 1170 11AB; +D269;D269;1110 1170 11AC;D269;1110 1170 11AC; +D26A;D26A;1110 1170 11AD;D26A;1110 1170 11AD; +D26B;D26B;1110 1170 11AE;D26B;1110 1170 11AE; +D26C;D26C;1110 1170 11AF;D26C;1110 1170 11AF; +D26D;D26D;1110 1170 11B0;D26D;1110 1170 11B0; +D26E;D26E;1110 1170 11B1;D26E;1110 1170 11B1; +D26F;D26F;1110 1170 11B2;D26F;1110 1170 11B2; +D270;D270;1110 1170 11B3;D270;1110 1170 11B3; +D271;D271;1110 1170 11B4;D271;1110 1170 11B4; +D272;D272;1110 1170 11B5;D272;1110 1170 11B5; +D273;D273;1110 1170 11B6;D273;1110 1170 11B6; +D274;D274;1110 1170 11B7;D274;1110 1170 11B7; +D275;D275;1110 1170 11B8;D275;1110 1170 11B8; +D276;D276;1110 1170 11B9;D276;1110 1170 11B9; +D277;D277;1110 1170 11BA;D277;1110 1170 11BA; +D278;D278;1110 1170 11BB;D278;1110 1170 11BB; +D279;D279;1110 1170 11BC;D279;1110 1170 11BC; +D27A;D27A;1110 1170 11BD;D27A;1110 1170 11BD; +D27B;D27B;1110 1170 11BE;D27B;1110 1170 11BE; +D27C;D27C;1110 1170 11BF;D27C;1110 1170 11BF; +D27D;D27D;1110 1170 11C0;D27D;1110 1170 11C0; +D27E;D27E;1110 1170 11C1;D27E;1110 1170 11C1; +D27F;D27F;1110 1170 11C2;D27F;1110 1170 11C2; +D280;D280;1110 1171;D280;1110 1171; +D281;D281;1110 1171 11A8;D281;1110 1171 11A8; +D282;D282;1110 1171 11A9;D282;1110 1171 11A9; +D283;D283;1110 1171 11AA;D283;1110 1171 11AA; +D284;D284;1110 1171 11AB;D284;1110 1171 11AB; +D285;D285;1110 1171 11AC;D285;1110 1171 11AC; +D286;D286;1110 1171 11AD;D286;1110 1171 11AD; +D287;D287;1110 1171 11AE;D287;1110 1171 11AE; +D288;D288;1110 1171 11AF;D288;1110 1171 11AF; +D289;D289;1110 1171 11B0;D289;1110 1171 11B0; +D28A;D28A;1110 1171 11B1;D28A;1110 1171 11B1; +D28B;D28B;1110 1171 11B2;D28B;1110 1171 11B2; +D28C;D28C;1110 1171 11B3;D28C;1110 1171 11B3; +D28D;D28D;1110 1171 11B4;D28D;1110 1171 11B4; +D28E;D28E;1110 1171 11B5;D28E;1110 1171 11B5; +D28F;D28F;1110 1171 11B6;D28F;1110 1171 11B6; +D290;D290;1110 1171 11B7;D290;1110 1171 11B7; +D291;D291;1110 1171 11B8;D291;1110 1171 11B8; +D292;D292;1110 1171 11B9;D292;1110 1171 11B9; +D293;D293;1110 1171 11BA;D293;1110 1171 11BA; +D294;D294;1110 1171 11BB;D294;1110 1171 11BB; +D295;D295;1110 1171 11BC;D295;1110 1171 11BC; +D296;D296;1110 1171 11BD;D296;1110 1171 11BD; +D297;D297;1110 1171 11BE;D297;1110 1171 11BE; +D298;D298;1110 1171 11BF;D298;1110 1171 11BF; +D299;D299;1110 1171 11C0;D299;1110 1171 11C0; +D29A;D29A;1110 1171 11C1;D29A;1110 1171 11C1; +D29B;D29B;1110 1171 11C2;D29B;1110 1171 11C2; +D29C;D29C;1110 1172;D29C;1110 1172; +D29D;D29D;1110 1172 11A8;D29D;1110 1172 11A8; +D29E;D29E;1110 1172 11A9;D29E;1110 1172 11A9; +D29F;D29F;1110 1172 11AA;D29F;1110 1172 11AA; +D2A0;D2A0;1110 1172 11AB;D2A0;1110 1172 11AB; +D2A1;D2A1;1110 1172 11AC;D2A1;1110 1172 11AC; +D2A2;D2A2;1110 1172 11AD;D2A2;1110 1172 11AD; +D2A3;D2A3;1110 1172 11AE;D2A3;1110 1172 11AE; +D2A4;D2A4;1110 1172 11AF;D2A4;1110 1172 11AF; +D2A5;D2A5;1110 1172 11B0;D2A5;1110 1172 11B0; +D2A6;D2A6;1110 1172 11B1;D2A6;1110 1172 11B1; +D2A7;D2A7;1110 1172 11B2;D2A7;1110 1172 11B2; +D2A8;D2A8;1110 1172 11B3;D2A8;1110 1172 11B3; +D2A9;D2A9;1110 1172 11B4;D2A9;1110 1172 11B4; +D2AA;D2AA;1110 1172 11B5;D2AA;1110 1172 11B5; +D2AB;D2AB;1110 1172 11B6;D2AB;1110 1172 11B6; +D2AC;D2AC;1110 1172 11B7;D2AC;1110 1172 11B7; +D2AD;D2AD;1110 1172 11B8;D2AD;1110 1172 11B8; +D2AE;D2AE;1110 1172 11B9;D2AE;1110 1172 11B9; +D2AF;D2AF;1110 1172 11BA;D2AF;1110 1172 11BA; +D2B0;D2B0;1110 1172 11BB;D2B0;1110 1172 11BB; +D2B1;D2B1;1110 1172 11BC;D2B1;1110 1172 11BC; +D2B2;D2B2;1110 1172 11BD;D2B2;1110 1172 11BD; +D2B3;D2B3;1110 1172 11BE;D2B3;1110 1172 11BE; +D2B4;D2B4;1110 1172 11BF;D2B4;1110 1172 11BF; +D2B5;D2B5;1110 1172 11C0;D2B5;1110 1172 11C0; +D2B6;D2B6;1110 1172 11C1;D2B6;1110 1172 11C1; +D2B7;D2B7;1110 1172 11C2;D2B7;1110 1172 11C2; +D2B8;D2B8;1110 1173;D2B8;1110 1173; +D2B9;D2B9;1110 1173 11A8;D2B9;1110 1173 11A8; +D2BA;D2BA;1110 1173 11A9;D2BA;1110 1173 11A9; +D2BB;D2BB;1110 1173 11AA;D2BB;1110 1173 11AA; +D2BC;D2BC;1110 1173 11AB;D2BC;1110 1173 11AB; +D2BD;D2BD;1110 1173 11AC;D2BD;1110 1173 11AC; +D2BE;D2BE;1110 1173 11AD;D2BE;1110 1173 11AD; +D2BF;D2BF;1110 1173 11AE;D2BF;1110 1173 11AE; +D2C0;D2C0;1110 1173 11AF;D2C0;1110 1173 11AF; +D2C1;D2C1;1110 1173 11B0;D2C1;1110 1173 11B0; +D2C2;D2C2;1110 1173 11B1;D2C2;1110 1173 11B1; +D2C3;D2C3;1110 1173 11B2;D2C3;1110 1173 11B2; +D2C4;D2C4;1110 1173 11B3;D2C4;1110 1173 11B3; +D2C5;D2C5;1110 1173 11B4;D2C5;1110 1173 11B4; +D2C6;D2C6;1110 1173 11B5;D2C6;1110 1173 11B5; +D2C7;D2C7;1110 1173 11B6;D2C7;1110 1173 11B6; +D2C8;D2C8;1110 1173 11B7;D2C8;1110 1173 11B7; +D2C9;D2C9;1110 1173 11B8;D2C9;1110 1173 11B8; +D2CA;D2CA;1110 1173 11B9;D2CA;1110 1173 11B9; +D2CB;D2CB;1110 1173 11BA;D2CB;1110 1173 11BA; +D2CC;D2CC;1110 1173 11BB;D2CC;1110 1173 11BB; +D2CD;D2CD;1110 1173 11BC;D2CD;1110 1173 11BC; +D2CE;D2CE;1110 1173 11BD;D2CE;1110 1173 11BD; +D2CF;D2CF;1110 1173 11BE;D2CF;1110 1173 11BE; +D2D0;D2D0;1110 1173 11BF;D2D0;1110 1173 11BF; +D2D1;D2D1;1110 1173 11C0;D2D1;1110 1173 11C0; +D2D2;D2D2;1110 1173 11C1;D2D2;1110 1173 11C1; +D2D3;D2D3;1110 1173 11C2;D2D3;1110 1173 11C2; +D2D4;D2D4;1110 1174;D2D4;1110 1174; +D2D5;D2D5;1110 1174 11A8;D2D5;1110 1174 11A8; +D2D6;D2D6;1110 1174 11A9;D2D6;1110 1174 11A9; +D2D7;D2D7;1110 1174 11AA;D2D7;1110 1174 11AA; +D2D8;D2D8;1110 1174 11AB;D2D8;1110 1174 11AB; +D2D9;D2D9;1110 1174 11AC;D2D9;1110 1174 11AC; +D2DA;D2DA;1110 1174 11AD;D2DA;1110 1174 11AD; +D2DB;D2DB;1110 1174 11AE;D2DB;1110 1174 11AE; +D2DC;D2DC;1110 1174 11AF;D2DC;1110 1174 11AF; +D2DD;D2DD;1110 1174 11B0;D2DD;1110 1174 11B0; +D2DE;D2DE;1110 1174 11B1;D2DE;1110 1174 11B1; +D2DF;D2DF;1110 1174 11B2;D2DF;1110 1174 11B2; +D2E0;D2E0;1110 1174 11B3;D2E0;1110 1174 11B3; +D2E1;D2E1;1110 1174 11B4;D2E1;1110 1174 11B4; +D2E2;D2E2;1110 1174 11B5;D2E2;1110 1174 11B5; +D2E3;D2E3;1110 1174 11B6;D2E3;1110 1174 11B6; +D2E4;D2E4;1110 1174 11B7;D2E4;1110 1174 11B7; +D2E5;D2E5;1110 1174 11B8;D2E5;1110 1174 11B8; +D2E6;D2E6;1110 1174 11B9;D2E6;1110 1174 11B9; +D2E7;D2E7;1110 1174 11BA;D2E7;1110 1174 11BA; +D2E8;D2E8;1110 1174 11BB;D2E8;1110 1174 11BB; +D2E9;D2E9;1110 1174 11BC;D2E9;1110 1174 11BC; +D2EA;D2EA;1110 1174 11BD;D2EA;1110 1174 11BD; +D2EB;D2EB;1110 1174 11BE;D2EB;1110 1174 11BE; +D2EC;D2EC;1110 1174 11BF;D2EC;1110 1174 11BF; +D2ED;D2ED;1110 1174 11C0;D2ED;1110 1174 11C0; +D2EE;D2EE;1110 1174 11C1;D2EE;1110 1174 11C1; +D2EF;D2EF;1110 1174 11C2;D2EF;1110 1174 11C2; +D2F0;D2F0;1110 1175;D2F0;1110 1175; +D2F1;D2F1;1110 1175 11A8;D2F1;1110 1175 11A8; +D2F2;D2F2;1110 1175 11A9;D2F2;1110 1175 11A9; +D2F3;D2F3;1110 1175 11AA;D2F3;1110 1175 11AA; +D2F4;D2F4;1110 1175 11AB;D2F4;1110 1175 11AB; +D2F5;D2F5;1110 1175 11AC;D2F5;1110 1175 11AC; +D2F6;D2F6;1110 1175 11AD;D2F6;1110 1175 11AD; +D2F7;D2F7;1110 1175 11AE;D2F7;1110 1175 11AE; +D2F8;D2F8;1110 1175 11AF;D2F8;1110 1175 11AF; +D2F9;D2F9;1110 1175 11B0;D2F9;1110 1175 11B0; +D2FA;D2FA;1110 1175 11B1;D2FA;1110 1175 11B1; +D2FB;D2FB;1110 1175 11B2;D2FB;1110 1175 11B2; +D2FC;D2FC;1110 1175 11B3;D2FC;1110 1175 11B3; +D2FD;D2FD;1110 1175 11B4;D2FD;1110 1175 11B4; +D2FE;D2FE;1110 1175 11B5;D2FE;1110 1175 11B5; +D2FF;D2FF;1110 1175 11B6;D2FF;1110 1175 11B6; +D300;D300;1110 1175 11B7;D300;1110 1175 11B7; +D301;D301;1110 1175 11B8;D301;1110 1175 11B8; +D302;D302;1110 1175 11B9;D302;1110 1175 11B9; +D303;D303;1110 1175 11BA;D303;1110 1175 11BA; +D304;D304;1110 1175 11BB;D304;1110 1175 11BB; +D305;D305;1110 1175 11BC;D305;1110 1175 11BC; +D306;D306;1110 1175 11BD;D306;1110 1175 11BD; +D307;D307;1110 1175 11BE;D307;1110 1175 11BE; +D308;D308;1110 1175 11BF;D308;1110 1175 11BF; +D309;D309;1110 1175 11C0;D309;1110 1175 11C0; +D30A;D30A;1110 1175 11C1;D30A;1110 1175 11C1; +D30B;D30B;1110 1175 11C2;D30B;1110 1175 11C2; +D30C;D30C;1111 1161;D30C;1111 1161; +D30D;D30D;1111 1161 11A8;D30D;1111 1161 11A8; +D30E;D30E;1111 1161 11A9;D30E;1111 1161 11A9; +D30F;D30F;1111 1161 11AA;D30F;1111 1161 11AA; +D310;D310;1111 1161 11AB;D310;1111 1161 11AB; +D311;D311;1111 1161 11AC;D311;1111 1161 11AC; +D312;D312;1111 1161 11AD;D312;1111 1161 11AD; +D313;D313;1111 1161 11AE;D313;1111 1161 11AE; +D314;D314;1111 1161 11AF;D314;1111 1161 11AF; +D315;D315;1111 1161 11B0;D315;1111 1161 11B0; +D316;D316;1111 1161 11B1;D316;1111 1161 11B1; +D317;D317;1111 1161 11B2;D317;1111 1161 11B2; +D318;D318;1111 1161 11B3;D318;1111 1161 11B3; +D319;D319;1111 1161 11B4;D319;1111 1161 11B4; +D31A;D31A;1111 1161 11B5;D31A;1111 1161 11B5; +D31B;D31B;1111 1161 11B6;D31B;1111 1161 11B6; +D31C;D31C;1111 1161 11B7;D31C;1111 1161 11B7; +D31D;D31D;1111 1161 11B8;D31D;1111 1161 11B8; +D31E;D31E;1111 1161 11B9;D31E;1111 1161 11B9; +D31F;D31F;1111 1161 11BA;D31F;1111 1161 11BA; +D320;D320;1111 1161 11BB;D320;1111 1161 11BB; +D321;D321;1111 1161 11BC;D321;1111 1161 11BC; +D322;D322;1111 1161 11BD;D322;1111 1161 11BD; +D323;D323;1111 1161 11BE;D323;1111 1161 11BE; +D324;D324;1111 1161 11BF;D324;1111 1161 11BF; +D325;D325;1111 1161 11C0;D325;1111 1161 11C0; +D326;D326;1111 1161 11C1;D326;1111 1161 11C1; +D327;D327;1111 1161 11C2;D327;1111 1161 11C2; +D328;D328;1111 1162;D328;1111 1162; +D329;D329;1111 1162 11A8;D329;1111 1162 11A8; +D32A;D32A;1111 1162 11A9;D32A;1111 1162 11A9; +D32B;D32B;1111 1162 11AA;D32B;1111 1162 11AA; +D32C;D32C;1111 1162 11AB;D32C;1111 1162 11AB; +D32D;D32D;1111 1162 11AC;D32D;1111 1162 11AC; +D32E;D32E;1111 1162 11AD;D32E;1111 1162 11AD; +D32F;D32F;1111 1162 11AE;D32F;1111 1162 11AE; +D330;D330;1111 1162 11AF;D330;1111 1162 11AF; +D331;D331;1111 1162 11B0;D331;1111 1162 11B0; +D332;D332;1111 1162 11B1;D332;1111 1162 11B1; +D333;D333;1111 1162 11B2;D333;1111 1162 11B2; +D334;D334;1111 1162 11B3;D334;1111 1162 11B3; +D335;D335;1111 1162 11B4;D335;1111 1162 11B4; +D336;D336;1111 1162 11B5;D336;1111 1162 11B5; +D337;D337;1111 1162 11B6;D337;1111 1162 11B6; +D338;D338;1111 1162 11B7;D338;1111 1162 11B7; +D339;D339;1111 1162 11B8;D339;1111 1162 11B8; +D33A;D33A;1111 1162 11B9;D33A;1111 1162 11B9; +D33B;D33B;1111 1162 11BA;D33B;1111 1162 11BA; +D33C;D33C;1111 1162 11BB;D33C;1111 1162 11BB; +D33D;D33D;1111 1162 11BC;D33D;1111 1162 11BC; +D33E;D33E;1111 1162 11BD;D33E;1111 1162 11BD; +D33F;D33F;1111 1162 11BE;D33F;1111 1162 11BE; +D340;D340;1111 1162 11BF;D340;1111 1162 11BF; +D341;D341;1111 1162 11C0;D341;1111 1162 11C0; +D342;D342;1111 1162 11C1;D342;1111 1162 11C1; +D343;D343;1111 1162 11C2;D343;1111 1162 11C2; +D344;D344;1111 1163;D344;1111 1163; +D345;D345;1111 1163 11A8;D345;1111 1163 11A8; +D346;D346;1111 1163 11A9;D346;1111 1163 11A9; +D347;D347;1111 1163 11AA;D347;1111 1163 11AA; +D348;D348;1111 1163 11AB;D348;1111 1163 11AB; +D349;D349;1111 1163 11AC;D349;1111 1163 11AC; +D34A;D34A;1111 1163 11AD;D34A;1111 1163 11AD; +D34B;D34B;1111 1163 11AE;D34B;1111 1163 11AE; +D34C;D34C;1111 1163 11AF;D34C;1111 1163 11AF; +D34D;D34D;1111 1163 11B0;D34D;1111 1163 11B0; +D34E;D34E;1111 1163 11B1;D34E;1111 1163 11B1; +D34F;D34F;1111 1163 11B2;D34F;1111 1163 11B2; +D350;D350;1111 1163 11B3;D350;1111 1163 11B3; +D351;D351;1111 1163 11B4;D351;1111 1163 11B4; +D352;D352;1111 1163 11B5;D352;1111 1163 11B5; +D353;D353;1111 1163 11B6;D353;1111 1163 11B6; +D354;D354;1111 1163 11B7;D354;1111 1163 11B7; +D355;D355;1111 1163 11B8;D355;1111 1163 11B8; +D356;D356;1111 1163 11B9;D356;1111 1163 11B9; +D357;D357;1111 1163 11BA;D357;1111 1163 11BA; +D358;D358;1111 1163 11BB;D358;1111 1163 11BB; +D359;D359;1111 1163 11BC;D359;1111 1163 11BC; +D35A;D35A;1111 1163 11BD;D35A;1111 1163 11BD; +D35B;D35B;1111 1163 11BE;D35B;1111 1163 11BE; +D35C;D35C;1111 1163 11BF;D35C;1111 1163 11BF; +D35D;D35D;1111 1163 11C0;D35D;1111 1163 11C0; +D35E;D35E;1111 1163 11C1;D35E;1111 1163 11C1; +D35F;D35F;1111 1163 11C2;D35F;1111 1163 11C2; +D360;D360;1111 1164;D360;1111 1164; +D361;D361;1111 1164 11A8;D361;1111 1164 11A8; +D362;D362;1111 1164 11A9;D362;1111 1164 11A9; +D363;D363;1111 1164 11AA;D363;1111 1164 11AA; +D364;D364;1111 1164 11AB;D364;1111 1164 11AB; +D365;D365;1111 1164 11AC;D365;1111 1164 11AC; +D366;D366;1111 1164 11AD;D366;1111 1164 11AD; +D367;D367;1111 1164 11AE;D367;1111 1164 11AE; +D368;D368;1111 1164 11AF;D368;1111 1164 11AF; +D369;D369;1111 1164 11B0;D369;1111 1164 11B0; +D36A;D36A;1111 1164 11B1;D36A;1111 1164 11B1; +D36B;D36B;1111 1164 11B2;D36B;1111 1164 11B2; +D36C;D36C;1111 1164 11B3;D36C;1111 1164 11B3; +D36D;D36D;1111 1164 11B4;D36D;1111 1164 11B4; +D36E;D36E;1111 1164 11B5;D36E;1111 1164 11B5; +D36F;D36F;1111 1164 11B6;D36F;1111 1164 11B6; +D370;D370;1111 1164 11B7;D370;1111 1164 11B7; +D371;D371;1111 1164 11B8;D371;1111 1164 11B8; +D372;D372;1111 1164 11B9;D372;1111 1164 11B9; +D373;D373;1111 1164 11BA;D373;1111 1164 11BA; +D374;D374;1111 1164 11BB;D374;1111 1164 11BB; +D375;D375;1111 1164 11BC;D375;1111 1164 11BC; +D376;D376;1111 1164 11BD;D376;1111 1164 11BD; +D377;D377;1111 1164 11BE;D377;1111 1164 11BE; +D378;D378;1111 1164 11BF;D378;1111 1164 11BF; +D379;D379;1111 1164 11C0;D379;1111 1164 11C0; +D37A;D37A;1111 1164 11C1;D37A;1111 1164 11C1; +D37B;D37B;1111 1164 11C2;D37B;1111 1164 11C2; +D37C;D37C;1111 1165;D37C;1111 1165; +D37D;D37D;1111 1165 11A8;D37D;1111 1165 11A8; +D37E;D37E;1111 1165 11A9;D37E;1111 1165 11A9; +D37F;D37F;1111 1165 11AA;D37F;1111 1165 11AA; +D380;D380;1111 1165 11AB;D380;1111 1165 11AB; +D381;D381;1111 1165 11AC;D381;1111 1165 11AC; +D382;D382;1111 1165 11AD;D382;1111 1165 11AD; +D383;D383;1111 1165 11AE;D383;1111 1165 11AE; +D384;D384;1111 1165 11AF;D384;1111 1165 11AF; +D385;D385;1111 1165 11B0;D385;1111 1165 11B0; +D386;D386;1111 1165 11B1;D386;1111 1165 11B1; +D387;D387;1111 1165 11B2;D387;1111 1165 11B2; +D388;D388;1111 1165 11B3;D388;1111 1165 11B3; +D389;D389;1111 1165 11B4;D389;1111 1165 11B4; +D38A;D38A;1111 1165 11B5;D38A;1111 1165 11B5; +D38B;D38B;1111 1165 11B6;D38B;1111 1165 11B6; +D38C;D38C;1111 1165 11B7;D38C;1111 1165 11B7; +D38D;D38D;1111 1165 11B8;D38D;1111 1165 11B8; +D38E;D38E;1111 1165 11B9;D38E;1111 1165 11B9; +D38F;D38F;1111 1165 11BA;D38F;1111 1165 11BA; +D390;D390;1111 1165 11BB;D390;1111 1165 11BB; +D391;D391;1111 1165 11BC;D391;1111 1165 11BC; +D392;D392;1111 1165 11BD;D392;1111 1165 11BD; +D393;D393;1111 1165 11BE;D393;1111 1165 11BE; +D394;D394;1111 1165 11BF;D394;1111 1165 11BF; +D395;D395;1111 1165 11C0;D395;1111 1165 11C0; +D396;D396;1111 1165 11C1;D396;1111 1165 11C1; +D397;D397;1111 1165 11C2;D397;1111 1165 11C2; +D398;D398;1111 1166;D398;1111 1166; +D399;D399;1111 1166 11A8;D399;1111 1166 11A8; +D39A;D39A;1111 1166 11A9;D39A;1111 1166 11A9; +D39B;D39B;1111 1166 11AA;D39B;1111 1166 11AA; +D39C;D39C;1111 1166 11AB;D39C;1111 1166 11AB; +D39D;D39D;1111 1166 11AC;D39D;1111 1166 11AC; +D39E;D39E;1111 1166 11AD;D39E;1111 1166 11AD; +D39F;D39F;1111 1166 11AE;D39F;1111 1166 11AE; +D3A0;D3A0;1111 1166 11AF;D3A0;1111 1166 11AF; +D3A1;D3A1;1111 1166 11B0;D3A1;1111 1166 11B0; +D3A2;D3A2;1111 1166 11B1;D3A2;1111 1166 11B1; +D3A3;D3A3;1111 1166 11B2;D3A3;1111 1166 11B2; +D3A4;D3A4;1111 1166 11B3;D3A4;1111 1166 11B3; +D3A5;D3A5;1111 1166 11B4;D3A5;1111 1166 11B4; +D3A6;D3A6;1111 1166 11B5;D3A6;1111 1166 11B5; +D3A7;D3A7;1111 1166 11B6;D3A7;1111 1166 11B6; +D3A8;D3A8;1111 1166 11B7;D3A8;1111 1166 11B7; +D3A9;D3A9;1111 1166 11B8;D3A9;1111 1166 11B8; +D3AA;D3AA;1111 1166 11B9;D3AA;1111 1166 11B9; +D3AB;D3AB;1111 1166 11BA;D3AB;1111 1166 11BA; +D3AC;D3AC;1111 1166 11BB;D3AC;1111 1166 11BB; +D3AD;D3AD;1111 1166 11BC;D3AD;1111 1166 11BC; +D3AE;D3AE;1111 1166 11BD;D3AE;1111 1166 11BD; +D3AF;D3AF;1111 1166 11BE;D3AF;1111 1166 11BE; +D3B0;D3B0;1111 1166 11BF;D3B0;1111 1166 11BF; +D3B1;D3B1;1111 1166 11C0;D3B1;1111 1166 11C0; +D3B2;D3B2;1111 1166 11C1;D3B2;1111 1166 11C1; +D3B3;D3B3;1111 1166 11C2;D3B3;1111 1166 11C2; +D3B4;D3B4;1111 1167;D3B4;1111 1167; +D3B5;D3B5;1111 1167 11A8;D3B5;1111 1167 11A8; +D3B6;D3B6;1111 1167 11A9;D3B6;1111 1167 11A9; +D3B7;D3B7;1111 1167 11AA;D3B7;1111 1167 11AA; +D3B8;D3B8;1111 1167 11AB;D3B8;1111 1167 11AB; +D3B9;D3B9;1111 1167 11AC;D3B9;1111 1167 11AC; +D3BA;D3BA;1111 1167 11AD;D3BA;1111 1167 11AD; +D3BB;D3BB;1111 1167 11AE;D3BB;1111 1167 11AE; +D3BC;D3BC;1111 1167 11AF;D3BC;1111 1167 11AF; +D3BD;D3BD;1111 1167 11B0;D3BD;1111 1167 11B0; +D3BE;D3BE;1111 1167 11B1;D3BE;1111 1167 11B1; +D3BF;D3BF;1111 1167 11B2;D3BF;1111 1167 11B2; +D3C0;D3C0;1111 1167 11B3;D3C0;1111 1167 11B3; +D3C1;D3C1;1111 1167 11B4;D3C1;1111 1167 11B4; +D3C2;D3C2;1111 1167 11B5;D3C2;1111 1167 11B5; +D3C3;D3C3;1111 1167 11B6;D3C3;1111 1167 11B6; +D3C4;D3C4;1111 1167 11B7;D3C4;1111 1167 11B7; +D3C5;D3C5;1111 1167 11B8;D3C5;1111 1167 11B8; +D3C6;D3C6;1111 1167 11B9;D3C6;1111 1167 11B9; +D3C7;D3C7;1111 1167 11BA;D3C7;1111 1167 11BA; +D3C8;D3C8;1111 1167 11BB;D3C8;1111 1167 11BB; +D3C9;D3C9;1111 1167 11BC;D3C9;1111 1167 11BC; +D3CA;D3CA;1111 1167 11BD;D3CA;1111 1167 11BD; +D3CB;D3CB;1111 1167 11BE;D3CB;1111 1167 11BE; +D3CC;D3CC;1111 1167 11BF;D3CC;1111 1167 11BF; +D3CD;D3CD;1111 1167 11C0;D3CD;1111 1167 11C0; +D3CE;D3CE;1111 1167 11C1;D3CE;1111 1167 11C1; +D3CF;D3CF;1111 1167 11C2;D3CF;1111 1167 11C2; +D3D0;D3D0;1111 1168;D3D0;1111 1168; +D3D1;D3D1;1111 1168 11A8;D3D1;1111 1168 11A8; +D3D2;D3D2;1111 1168 11A9;D3D2;1111 1168 11A9; +D3D3;D3D3;1111 1168 11AA;D3D3;1111 1168 11AA; +D3D4;D3D4;1111 1168 11AB;D3D4;1111 1168 11AB; +D3D5;D3D5;1111 1168 11AC;D3D5;1111 1168 11AC; +D3D6;D3D6;1111 1168 11AD;D3D6;1111 1168 11AD; +D3D7;D3D7;1111 1168 11AE;D3D7;1111 1168 11AE; +D3D8;D3D8;1111 1168 11AF;D3D8;1111 1168 11AF; +D3D9;D3D9;1111 1168 11B0;D3D9;1111 1168 11B0; +D3DA;D3DA;1111 1168 11B1;D3DA;1111 1168 11B1; +D3DB;D3DB;1111 1168 11B2;D3DB;1111 1168 11B2; +D3DC;D3DC;1111 1168 11B3;D3DC;1111 1168 11B3; +D3DD;D3DD;1111 1168 11B4;D3DD;1111 1168 11B4; +D3DE;D3DE;1111 1168 11B5;D3DE;1111 1168 11B5; +D3DF;D3DF;1111 1168 11B6;D3DF;1111 1168 11B6; +D3E0;D3E0;1111 1168 11B7;D3E0;1111 1168 11B7; +D3E1;D3E1;1111 1168 11B8;D3E1;1111 1168 11B8; +D3E2;D3E2;1111 1168 11B9;D3E2;1111 1168 11B9; +D3E3;D3E3;1111 1168 11BA;D3E3;1111 1168 11BA; +D3E4;D3E4;1111 1168 11BB;D3E4;1111 1168 11BB; +D3E5;D3E5;1111 1168 11BC;D3E5;1111 1168 11BC; +D3E6;D3E6;1111 1168 11BD;D3E6;1111 1168 11BD; +D3E7;D3E7;1111 1168 11BE;D3E7;1111 1168 11BE; +D3E8;D3E8;1111 1168 11BF;D3E8;1111 1168 11BF; +D3E9;D3E9;1111 1168 11C0;D3E9;1111 1168 11C0; +D3EA;D3EA;1111 1168 11C1;D3EA;1111 1168 11C1; +D3EB;D3EB;1111 1168 11C2;D3EB;1111 1168 11C2; +D3EC;D3EC;1111 1169;D3EC;1111 1169; +D3ED;D3ED;1111 1169 11A8;D3ED;1111 1169 11A8; +D3EE;D3EE;1111 1169 11A9;D3EE;1111 1169 11A9; +D3EF;D3EF;1111 1169 11AA;D3EF;1111 1169 11AA; +D3F0;D3F0;1111 1169 11AB;D3F0;1111 1169 11AB; +D3F1;D3F1;1111 1169 11AC;D3F1;1111 1169 11AC; +D3F2;D3F2;1111 1169 11AD;D3F2;1111 1169 11AD; +D3F3;D3F3;1111 1169 11AE;D3F3;1111 1169 11AE; +D3F4;D3F4;1111 1169 11AF;D3F4;1111 1169 11AF; +D3F5;D3F5;1111 1169 11B0;D3F5;1111 1169 11B0; +D3F6;D3F6;1111 1169 11B1;D3F6;1111 1169 11B1; +D3F7;D3F7;1111 1169 11B2;D3F7;1111 1169 11B2; +D3F8;D3F8;1111 1169 11B3;D3F8;1111 1169 11B3; +D3F9;D3F9;1111 1169 11B4;D3F9;1111 1169 11B4; +D3FA;D3FA;1111 1169 11B5;D3FA;1111 1169 11B5; +D3FB;D3FB;1111 1169 11B6;D3FB;1111 1169 11B6; +D3FC;D3FC;1111 1169 11B7;D3FC;1111 1169 11B7; +D3FD;D3FD;1111 1169 11B8;D3FD;1111 1169 11B8; +D3FE;D3FE;1111 1169 11B9;D3FE;1111 1169 11B9; +D3FF;D3FF;1111 1169 11BA;D3FF;1111 1169 11BA; +D400;D400;1111 1169 11BB;D400;1111 1169 11BB; +D401;D401;1111 1169 11BC;D401;1111 1169 11BC; +D402;D402;1111 1169 11BD;D402;1111 1169 11BD; +D403;D403;1111 1169 11BE;D403;1111 1169 11BE; +D404;D404;1111 1169 11BF;D404;1111 1169 11BF; +D405;D405;1111 1169 11C0;D405;1111 1169 11C0; +D406;D406;1111 1169 11C1;D406;1111 1169 11C1; +D407;D407;1111 1169 11C2;D407;1111 1169 11C2; +D408;D408;1111 116A;D408;1111 116A; +D409;D409;1111 116A 11A8;D409;1111 116A 11A8; +D40A;D40A;1111 116A 11A9;D40A;1111 116A 11A9; +D40B;D40B;1111 116A 11AA;D40B;1111 116A 11AA; +D40C;D40C;1111 116A 11AB;D40C;1111 116A 11AB; +D40D;D40D;1111 116A 11AC;D40D;1111 116A 11AC; +D40E;D40E;1111 116A 11AD;D40E;1111 116A 11AD; +D40F;D40F;1111 116A 11AE;D40F;1111 116A 11AE; +D410;D410;1111 116A 11AF;D410;1111 116A 11AF; +D411;D411;1111 116A 11B0;D411;1111 116A 11B0; +D412;D412;1111 116A 11B1;D412;1111 116A 11B1; +D413;D413;1111 116A 11B2;D413;1111 116A 11B2; +D414;D414;1111 116A 11B3;D414;1111 116A 11B3; +D415;D415;1111 116A 11B4;D415;1111 116A 11B4; +D416;D416;1111 116A 11B5;D416;1111 116A 11B5; +D417;D417;1111 116A 11B6;D417;1111 116A 11B6; +D418;D418;1111 116A 11B7;D418;1111 116A 11B7; +D419;D419;1111 116A 11B8;D419;1111 116A 11B8; +D41A;D41A;1111 116A 11B9;D41A;1111 116A 11B9; +D41B;D41B;1111 116A 11BA;D41B;1111 116A 11BA; +D41C;D41C;1111 116A 11BB;D41C;1111 116A 11BB; +D41D;D41D;1111 116A 11BC;D41D;1111 116A 11BC; +D41E;D41E;1111 116A 11BD;D41E;1111 116A 11BD; +D41F;D41F;1111 116A 11BE;D41F;1111 116A 11BE; +D420;D420;1111 116A 11BF;D420;1111 116A 11BF; +D421;D421;1111 116A 11C0;D421;1111 116A 11C0; +D422;D422;1111 116A 11C1;D422;1111 116A 11C1; +D423;D423;1111 116A 11C2;D423;1111 116A 11C2; +D424;D424;1111 116B;D424;1111 116B; +D425;D425;1111 116B 11A8;D425;1111 116B 11A8; +D426;D426;1111 116B 11A9;D426;1111 116B 11A9; +D427;D427;1111 116B 11AA;D427;1111 116B 11AA; +D428;D428;1111 116B 11AB;D428;1111 116B 11AB; +D429;D429;1111 116B 11AC;D429;1111 116B 11AC; +D42A;D42A;1111 116B 11AD;D42A;1111 116B 11AD; +D42B;D42B;1111 116B 11AE;D42B;1111 116B 11AE; +D42C;D42C;1111 116B 11AF;D42C;1111 116B 11AF; +D42D;D42D;1111 116B 11B0;D42D;1111 116B 11B0; +D42E;D42E;1111 116B 11B1;D42E;1111 116B 11B1; +D42F;D42F;1111 116B 11B2;D42F;1111 116B 11B2; +D430;D430;1111 116B 11B3;D430;1111 116B 11B3; +D431;D431;1111 116B 11B4;D431;1111 116B 11B4; +D432;D432;1111 116B 11B5;D432;1111 116B 11B5; +D433;D433;1111 116B 11B6;D433;1111 116B 11B6; +D434;D434;1111 116B 11B7;D434;1111 116B 11B7; +D435;D435;1111 116B 11B8;D435;1111 116B 11B8; +D436;D436;1111 116B 11B9;D436;1111 116B 11B9; +D437;D437;1111 116B 11BA;D437;1111 116B 11BA; +D438;D438;1111 116B 11BB;D438;1111 116B 11BB; +D439;D439;1111 116B 11BC;D439;1111 116B 11BC; +D43A;D43A;1111 116B 11BD;D43A;1111 116B 11BD; +D43B;D43B;1111 116B 11BE;D43B;1111 116B 11BE; +D43C;D43C;1111 116B 11BF;D43C;1111 116B 11BF; +D43D;D43D;1111 116B 11C0;D43D;1111 116B 11C0; +D43E;D43E;1111 116B 11C1;D43E;1111 116B 11C1; +D43F;D43F;1111 116B 11C2;D43F;1111 116B 11C2; +D440;D440;1111 116C;D440;1111 116C; +D441;D441;1111 116C 11A8;D441;1111 116C 11A8; +D442;D442;1111 116C 11A9;D442;1111 116C 11A9; +D443;D443;1111 116C 11AA;D443;1111 116C 11AA; +D444;D444;1111 116C 11AB;D444;1111 116C 11AB; +D445;D445;1111 116C 11AC;D445;1111 116C 11AC; +D446;D446;1111 116C 11AD;D446;1111 116C 11AD; +D447;D447;1111 116C 11AE;D447;1111 116C 11AE; +D448;D448;1111 116C 11AF;D448;1111 116C 11AF; +D449;D449;1111 116C 11B0;D449;1111 116C 11B0; +D44A;D44A;1111 116C 11B1;D44A;1111 116C 11B1; +D44B;D44B;1111 116C 11B2;D44B;1111 116C 11B2; +D44C;D44C;1111 116C 11B3;D44C;1111 116C 11B3; +D44D;D44D;1111 116C 11B4;D44D;1111 116C 11B4; +D44E;D44E;1111 116C 11B5;D44E;1111 116C 11B5; +D44F;D44F;1111 116C 11B6;D44F;1111 116C 11B6; +D450;D450;1111 116C 11B7;D450;1111 116C 11B7; +D451;D451;1111 116C 11B8;D451;1111 116C 11B8; +D452;D452;1111 116C 11B9;D452;1111 116C 11B9; +D453;D453;1111 116C 11BA;D453;1111 116C 11BA; +D454;D454;1111 116C 11BB;D454;1111 116C 11BB; +D455;D455;1111 116C 11BC;D455;1111 116C 11BC; +D456;D456;1111 116C 11BD;D456;1111 116C 11BD; +D457;D457;1111 116C 11BE;D457;1111 116C 11BE; +D458;D458;1111 116C 11BF;D458;1111 116C 11BF; +D459;D459;1111 116C 11C0;D459;1111 116C 11C0; +D45A;D45A;1111 116C 11C1;D45A;1111 116C 11C1; +D45B;D45B;1111 116C 11C2;D45B;1111 116C 11C2; +D45C;D45C;1111 116D;D45C;1111 116D; +D45D;D45D;1111 116D 11A8;D45D;1111 116D 11A8; +D45E;D45E;1111 116D 11A9;D45E;1111 116D 11A9; +D45F;D45F;1111 116D 11AA;D45F;1111 116D 11AA; +D460;D460;1111 116D 11AB;D460;1111 116D 11AB; +D461;D461;1111 116D 11AC;D461;1111 116D 11AC; +D462;D462;1111 116D 11AD;D462;1111 116D 11AD; +D463;D463;1111 116D 11AE;D463;1111 116D 11AE; +D464;D464;1111 116D 11AF;D464;1111 116D 11AF; +D465;D465;1111 116D 11B0;D465;1111 116D 11B0; +D466;D466;1111 116D 11B1;D466;1111 116D 11B1; +D467;D467;1111 116D 11B2;D467;1111 116D 11B2; +D468;D468;1111 116D 11B3;D468;1111 116D 11B3; +D469;D469;1111 116D 11B4;D469;1111 116D 11B4; +D46A;D46A;1111 116D 11B5;D46A;1111 116D 11B5; +D46B;D46B;1111 116D 11B6;D46B;1111 116D 11B6; +D46C;D46C;1111 116D 11B7;D46C;1111 116D 11B7; +D46D;D46D;1111 116D 11B8;D46D;1111 116D 11B8; +D46E;D46E;1111 116D 11B9;D46E;1111 116D 11B9; +D46F;D46F;1111 116D 11BA;D46F;1111 116D 11BA; +D470;D470;1111 116D 11BB;D470;1111 116D 11BB; +D471;D471;1111 116D 11BC;D471;1111 116D 11BC; +D472;D472;1111 116D 11BD;D472;1111 116D 11BD; +D473;D473;1111 116D 11BE;D473;1111 116D 11BE; +D474;D474;1111 116D 11BF;D474;1111 116D 11BF; +D475;D475;1111 116D 11C0;D475;1111 116D 11C0; +D476;D476;1111 116D 11C1;D476;1111 116D 11C1; +D477;D477;1111 116D 11C2;D477;1111 116D 11C2; +D478;D478;1111 116E;D478;1111 116E; +D479;D479;1111 116E 11A8;D479;1111 116E 11A8; +D47A;D47A;1111 116E 11A9;D47A;1111 116E 11A9; +D47B;D47B;1111 116E 11AA;D47B;1111 116E 11AA; +D47C;D47C;1111 116E 11AB;D47C;1111 116E 11AB; +D47D;D47D;1111 116E 11AC;D47D;1111 116E 11AC; +D47E;D47E;1111 116E 11AD;D47E;1111 116E 11AD; +D47F;D47F;1111 116E 11AE;D47F;1111 116E 11AE; +D480;D480;1111 116E 11AF;D480;1111 116E 11AF; +D481;D481;1111 116E 11B0;D481;1111 116E 11B0; +D482;D482;1111 116E 11B1;D482;1111 116E 11B1; +D483;D483;1111 116E 11B2;D483;1111 116E 11B2; +D484;D484;1111 116E 11B3;D484;1111 116E 11B3; +D485;D485;1111 116E 11B4;D485;1111 116E 11B4; +D486;D486;1111 116E 11B5;D486;1111 116E 11B5; +D487;D487;1111 116E 11B6;D487;1111 116E 11B6; +D488;D488;1111 116E 11B7;D488;1111 116E 11B7; +D489;D489;1111 116E 11B8;D489;1111 116E 11B8; +D48A;D48A;1111 116E 11B9;D48A;1111 116E 11B9; +D48B;D48B;1111 116E 11BA;D48B;1111 116E 11BA; +D48C;D48C;1111 116E 11BB;D48C;1111 116E 11BB; +D48D;D48D;1111 116E 11BC;D48D;1111 116E 11BC; +D48E;D48E;1111 116E 11BD;D48E;1111 116E 11BD; +D48F;D48F;1111 116E 11BE;D48F;1111 116E 11BE; +D490;D490;1111 116E 11BF;D490;1111 116E 11BF; +D491;D491;1111 116E 11C0;D491;1111 116E 11C0; +D492;D492;1111 116E 11C1;D492;1111 116E 11C1; +D493;D493;1111 116E 11C2;D493;1111 116E 11C2; +D494;D494;1111 116F;D494;1111 116F; +D495;D495;1111 116F 11A8;D495;1111 116F 11A8; +D496;D496;1111 116F 11A9;D496;1111 116F 11A9; +D497;D497;1111 116F 11AA;D497;1111 116F 11AA; +D498;D498;1111 116F 11AB;D498;1111 116F 11AB; +D499;D499;1111 116F 11AC;D499;1111 116F 11AC; +D49A;D49A;1111 116F 11AD;D49A;1111 116F 11AD; +D49B;D49B;1111 116F 11AE;D49B;1111 116F 11AE; +D49C;D49C;1111 116F 11AF;D49C;1111 116F 11AF; +D49D;D49D;1111 116F 11B0;D49D;1111 116F 11B0; +D49E;D49E;1111 116F 11B1;D49E;1111 116F 11B1; +D49F;D49F;1111 116F 11B2;D49F;1111 116F 11B2; +D4A0;D4A0;1111 116F 11B3;D4A0;1111 116F 11B3; +D4A1;D4A1;1111 116F 11B4;D4A1;1111 116F 11B4; +D4A2;D4A2;1111 116F 11B5;D4A2;1111 116F 11B5; +D4A3;D4A3;1111 116F 11B6;D4A3;1111 116F 11B6; +D4A4;D4A4;1111 116F 11B7;D4A4;1111 116F 11B7; +D4A5;D4A5;1111 116F 11B8;D4A5;1111 116F 11B8; +D4A6;D4A6;1111 116F 11B9;D4A6;1111 116F 11B9; +D4A7;D4A7;1111 116F 11BA;D4A7;1111 116F 11BA; +D4A8;D4A8;1111 116F 11BB;D4A8;1111 116F 11BB; +D4A9;D4A9;1111 116F 11BC;D4A9;1111 116F 11BC; +D4AA;D4AA;1111 116F 11BD;D4AA;1111 116F 11BD; +D4AB;D4AB;1111 116F 11BE;D4AB;1111 116F 11BE; +D4AC;D4AC;1111 116F 11BF;D4AC;1111 116F 11BF; +D4AD;D4AD;1111 116F 11C0;D4AD;1111 116F 11C0; +D4AE;D4AE;1111 116F 11C1;D4AE;1111 116F 11C1; +D4AF;D4AF;1111 116F 11C2;D4AF;1111 116F 11C2; +D4B0;D4B0;1111 1170;D4B0;1111 1170; +D4B1;D4B1;1111 1170 11A8;D4B1;1111 1170 11A8; +D4B2;D4B2;1111 1170 11A9;D4B2;1111 1170 11A9; +D4B3;D4B3;1111 1170 11AA;D4B3;1111 1170 11AA; +D4B4;D4B4;1111 1170 11AB;D4B4;1111 1170 11AB; +D4B5;D4B5;1111 1170 11AC;D4B5;1111 1170 11AC; +D4B6;D4B6;1111 1170 11AD;D4B6;1111 1170 11AD; +D4B7;D4B7;1111 1170 11AE;D4B7;1111 1170 11AE; +D4B8;D4B8;1111 1170 11AF;D4B8;1111 1170 11AF; +D4B9;D4B9;1111 1170 11B0;D4B9;1111 1170 11B0; +D4BA;D4BA;1111 1170 11B1;D4BA;1111 1170 11B1; +D4BB;D4BB;1111 1170 11B2;D4BB;1111 1170 11B2; +D4BC;D4BC;1111 1170 11B3;D4BC;1111 1170 11B3; +D4BD;D4BD;1111 1170 11B4;D4BD;1111 1170 11B4; +D4BE;D4BE;1111 1170 11B5;D4BE;1111 1170 11B5; +D4BF;D4BF;1111 1170 11B6;D4BF;1111 1170 11B6; +D4C0;D4C0;1111 1170 11B7;D4C0;1111 1170 11B7; +D4C1;D4C1;1111 1170 11B8;D4C1;1111 1170 11B8; +D4C2;D4C2;1111 1170 11B9;D4C2;1111 1170 11B9; +D4C3;D4C3;1111 1170 11BA;D4C3;1111 1170 11BA; +D4C4;D4C4;1111 1170 11BB;D4C4;1111 1170 11BB; +D4C5;D4C5;1111 1170 11BC;D4C5;1111 1170 11BC; +D4C6;D4C6;1111 1170 11BD;D4C6;1111 1170 11BD; +D4C7;D4C7;1111 1170 11BE;D4C7;1111 1170 11BE; +D4C8;D4C8;1111 1170 11BF;D4C8;1111 1170 11BF; +D4C9;D4C9;1111 1170 11C0;D4C9;1111 1170 11C0; +D4CA;D4CA;1111 1170 11C1;D4CA;1111 1170 11C1; +D4CB;D4CB;1111 1170 11C2;D4CB;1111 1170 11C2; +D4CC;D4CC;1111 1171;D4CC;1111 1171; +D4CD;D4CD;1111 1171 11A8;D4CD;1111 1171 11A8; +D4CE;D4CE;1111 1171 11A9;D4CE;1111 1171 11A9; +D4CF;D4CF;1111 1171 11AA;D4CF;1111 1171 11AA; +D4D0;D4D0;1111 1171 11AB;D4D0;1111 1171 11AB; +D4D1;D4D1;1111 1171 11AC;D4D1;1111 1171 11AC; +D4D2;D4D2;1111 1171 11AD;D4D2;1111 1171 11AD; +D4D3;D4D3;1111 1171 11AE;D4D3;1111 1171 11AE; +D4D4;D4D4;1111 1171 11AF;D4D4;1111 1171 11AF; +D4D5;D4D5;1111 1171 11B0;D4D5;1111 1171 11B0; +D4D6;D4D6;1111 1171 11B1;D4D6;1111 1171 11B1; +D4D7;D4D7;1111 1171 11B2;D4D7;1111 1171 11B2; +D4D8;D4D8;1111 1171 11B3;D4D8;1111 1171 11B3; +D4D9;D4D9;1111 1171 11B4;D4D9;1111 1171 11B4; +D4DA;D4DA;1111 1171 11B5;D4DA;1111 1171 11B5; +D4DB;D4DB;1111 1171 11B6;D4DB;1111 1171 11B6; +D4DC;D4DC;1111 1171 11B7;D4DC;1111 1171 11B7; +D4DD;D4DD;1111 1171 11B8;D4DD;1111 1171 11B8; +D4DE;D4DE;1111 1171 11B9;D4DE;1111 1171 11B9; +D4DF;D4DF;1111 1171 11BA;D4DF;1111 1171 11BA; +D4E0;D4E0;1111 1171 11BB;D4E0;1111 1171 11BB; +D4E1;D4E1;1111 1171 11BC;D4E1;1111 1171 11BC; +D4E2;D4E2;1111 1171 11BD;D4E2;1111 1171 11BD; +D4E3;D4E3;1111 1171 11BE;D4E3;1111 1171 11BE; +D4E4;D4E4;1111 1171 11BF;D4E4;1111 1171 11BF; +D4E5;D4E5;1111 1171 11C0;D4E5;1111 1171 11C0; +D4E6;D4E6;1111 1171 11C1;D4E6;1111 1171 11C1; +D4E7;D4E7;1111 1171 11C2;D4E7;1111 1171 11C2; +D4E8;D4E8;1111 1172;D4E8;1111 1172; +D4E9;D4E9;1111 1172 11A8;D4E9;1111 1172 11A8; +D4EA;D4EA;1111 1172 11A9;D4EA;1111 1172 11A9; +D4EB;D4EB;1111 1172 11AA;D4EB;1111 1172 11AA; +D4EC;D4EC;1111 1172 11AB;D4EC;1111 1172 11AB; +D4ED;D4ED;1111 1172 11AC;D4ED;1111 1172 11AC; +D4EE;D4EE;1111 1172 11AD;D4EE;1111 1172 11AD; +D4EF;D4EF;1111 1172 11AE;D4EF;1111 1172 11AE; +D4F0;D4F0;1111 1172 11AF;D4F0;1111 1172 11AF; +D4F1;D4F1;1111 1172 11B0;D4F1;1111 1172 11B0; +D4F2;D4F2;1111 1172 11B1;D4F2;1111 1172 11B1; +D4F3;D4F3;1111 1172 11B2;D4F3;1111 1172 11B2; +D4F4;D4F4;1111 1172 11B3;D4F4;1111 1172 11B3; +D4F5;D4F5;1111 1172 11B4;D4F5;1111 1172 11B4; +D4F6;D4F6;1111 1172 11B5;D4F6;1111 1172 11B5; +D4F7;D4F7;1111 1172 11B6;D4F7;1111 1172 11B6; +D4F8;D4F8;1111 1172 11B7;D4F8;1111 1172 11B7; +D4F9;D4F9;1111 1172 11B8;D4F9;1111 1172 11B8; +D4FA;D4FA;1111 1172 11B9;D4FA;1111 1172 11B9; +D4FB;D4FB;1111 1172 11BA;D4FB;1111 1172 11BA; +D4FC;D4FC;1111 1172 11BB;D4FC;1111 1172 11BB; +D4FD;D4FD;1111 1172 11BC;D4FD;1111 1172 11BC; +D4FE;D4FE;1111 1172 11BD;D4FE;1111 1172 11BD; +D4FF;D4FF;1111 1172 11BE;D4FF;1111 1172 11BE; +D500;D500;1111 1172 11BF;D500;1111 1172 11BF; +D501;D501;1111 1172 11C0;D501;1111 1172 11C0; +D502;D502;1111 1172 11C1;D502;1111 1172 11C1; +D503;D503;1111 1172 11C2;D503;1111 1172 11C2; +D504;D504;1111 1173;D504;1111 1173; +D505;D505;1111 1173 11A8;D505;1111 1173 11A8; +D506;D506;1111 1173 11A9;D506;1111 1173 11A9; +D507;D507;1111 1173 11AA;D507;1111 1173 11AA; +D508;D508;1111 1173 11AB;D508;1111 1173 11AB; +D509;D509;1111 1173 11AC;D509;1111 1173 11AC; +D50A;D50A;1111 1173 11AD;D50A;1111 1173 11AD; +D50B;D50B;1111 1173 11AE;D50B;1111 1173 11AE; +D50C;D50C;1111 1173 11AF;D50C;1111 1173 11AF; +D50D;D50D;1111 1173 11B0;D50D;1111 1173 11B0; +D50E;D50E;1111 1173 11B1;D50E;1111 1173 11B1; +D50F;D50F;1111 1173 11B2;D50F;1111 1173 11B2; +D510;D510;1111 1173 11B3;D510;1111 1173 11B3; +D511;D511;1111 1173 11B4;D511;1111 1173 11B4; +D512;D512;1111 1173 11B5;D512;1111 1173 11B5; +D513;D513;1111 1173 11B6;D513;1111 1173 11B6; +D514;D514;1111 1173 11B7;D514;1111 1173 11B7; +D515;D515;1111 1173 11B8;D515;1111 1173 11B8; +D516;D516;1111 1173 11B9;D516;1111 1173 11B9; +D517;D517;1111 1173 11BA;D517;1111 1173 11BA; +D518;D518;1111 1173 11BB;D518;1111 1173 11BB; +D519;D519;1111 1173 11BC;D519;1111 1173 11BC; +D51A;D51A;1111 1173 11BD;D51A;1111 1173 11BD; +D51B;D51B;1111 1173 11BE;D51B;1111 1173 11BE; +D51C;D51C;1111 1173 11BF;D51C;1111 1173 11BF; +D51D;D51D;1111 1173 11C0;D51D;1111 1173 11C0; +D51E;D51E;1111 1173 11C1;D51E;1111 1173 11C1; +D51F;D51F;1111 1173 11C2;D51F;1111 1173 11C2; +D520;D520;1111 1174;D520;1111 1174; +D521;D521;1111 1174 11A8;D521;1111 1174 11A8; +D522;D522;1111 1174 11A9;D522;1111 1174 11A9; +D523;D523;1111 1174 11AA;D523;1111 1174 11AA; +D524;D524;1111 1174 11AB;D524;1111 1174 11AB; +D525;D525;1111 1174 11AC;D525;1111 1174 11AC; +D526;D526;1111 1174 11AD;D526;1111 1174 11AD; +D527;D527;1111 1174 11AE;D527;1111 1174 11AE; +D528;D528;1111 1174 11AF;D528;1111 1174 11AF; +D529;D529;1111 1174 11B0;D529;1111 1174 11B0; +D52A;D52A;1111 1174 11B1;D52A;1111 1174 11B1; +D52B;D52B;1111 1174 11B2;D52B;1111 1174 11B2; +D52C;D52C;1111 1174 11B3;D52C;1111 1174 11B3; +D52D;D52D;1111 1174 11B4;D52D;1111 1174 11B4; +D52E;D52E;1111 1174 11B5;D52E;1111 1174 11B5; +D52F;D52F;1111 1174 11B6;D52F;1111 1174 11B6; +D530;D530;1111 1174 11B7;D530;1111 1174 11B7; +D531;D531;1111 1174 11B8;D531;1111 1174 11B8; +D532;D532;1111 1174 11B9;D532;1111 1174 11B9; +D533;D533;1111 1174 11BA;D533;1111 1174 11BA; +D534;D534;1111 1174 11BB;D534;1111 1174 11BB; +D535;D535;1111 1174 11BC;D535;1111 1174 11BC; +D536;D536;1111 1174 11BD;D536;1111 1174 11BD; +D537;D537;1111 1174 11BE;D537;1111 1174 11BE; +D538;D538;1111 1174 11BF;D538;1111 1174 11BF; +D539;D539;1111 1174 11C0;D539;1111 1174 11C0; +D53A;D53A;1111 1174 11C1;D53A;1111 1174 11C1; +D53B;D53B;1111 1174 11C2;D53B;1111 1174 11C2; +D53C;D53C;1111 1175;D53C;1111 1175; +D53D;D53D;1111 1175 11A8;D53D;1111 1175 11A8; +D53E;D53E;1111 1175 11A9;D53E;1111 1175 11A9; +D53F;D53F;1111 1175 11AA;D53F;1111 1175 11AA; +D540;D540;1111 1175 11AB;D540;1111 1175 11AB; +D541;D541;1111 1175 11AC;D541;1111 1175 11AC; +D542;D542;1111 1175 11AD;D542;1111 1175 11AD; +D543;D543;1111 1175 11AE;D543;1111 1175 11AE; +D544;D544;1111 1175 11AF;D544;1111 1175 11AF; +D545;D545;1111 1175 11B0;D545;1111 1175 11B0; +D546;D546;1111 1175 11B1;D546;1111 1175 11B1; +D547;D547;1111 1175 11B2;D547;1111 1175 11B2; +D548;D548;1111 1175 11B3;D548;1111 1175 11B3; +D549;D549;1111 1175 11B4;D549;1111 1175 11B4; +D54A;D54A;1111 1175 11B5;D54A;1111 1175 11B5; +D54B;D54B;1111 1175 11B6;D54B;1111 1175 11B6; +D54C;D54C;1111 1175 11B7;D54C;1111 1175 11B7; +D54D;D54D;1111 1175 11B8;D54D;1111 1175 11B8; +D54E;D54E;1111 1175 11B9;D54E;1111 1175 11B9; +D54F;D54F;1111 1175 11BA;D54F;1111 1175 11BA; +D550;D550;1111 1175 11BB;D550;1111 1175 11BB; +D551;D551;1111 1175 11BC;D551;1111 1175 11BC; +D552;D552;1111 1175 11BD;D552;1111 1175 11BD; +D553;D553;1111 1175 11BE;D553;1111 1175 11BE; +D554;D554;1111 1175 11BF;D554;1111 1175 11BF; +D555;D555;1111 1175 11C0;D555;1111 1175 11C0; +D556;D556;1111 1175 11C1;D556;1111 1175 11C1; +D557;D557;1111 1175 11C2;D557;1111 1175 11C2; +D558;D558;1112 1161;D558;1112 1161; +D559;D559;1112 1161 11A8;D559;1112 1161 11A8; +D55A;D55A;1112 1161 11A9;D55A;1112 1161 11A9; +D55B;D55B;1112 1161 11AA;D55B;1112 1161 11AA; +D55C;D55C;1112 1161 11AB;D55C;1112 1161 11AB; +D55D;D55D;1112 1161 11AC;D55D;1112 1161 11AC; +D55E;D55E;1112 1161 11AD;D55E;1112 1161 11AD; +D55F;D55F;1112 1161 11AE;D55F;1112 1161 11AE; +D560;D560;1112 1161 11AF;D560;1112 1161 11AF; +D561;D561;1112 1161 11B0;D561;1112 1161 11B0; +D562;D562;1112 1161 11B1;D562;1112 1161 11B1; +D563;D563;1112 1161 11B2;D563;1112 1161 11B2; +D564;D564;1112 1161 11B3;D564;1112 1161 11B3; +D565;D565;1112 1161 11B4;D565;1112 1161 11B4; +D566;D566;1112 1161 11B5;D566;1112 1161 11B5; +D567;D567;1112 1161 11B6;D567;1112 1161 11B6; +D568;D568;1112 1161 11B7;D568;1112 1161 11B7; +D569;D569;1112 1161 11B8;D569;1112 1161 11B8; +D56A;D56A;1112 1161 11B9;D56A;1112 1161 11B9; +D56B;D56B;1112 1161 11BA;D56B;1112 1161 11BA; +D56C;D56C;1112 1161 11BB;D56C;1112 1161 11BB; +D56D;D56D;1112 1161 11BC;D56D;1112 1161 11BC; +D56E;D56E;1112 1161 11BD;D56E;1112 1161 11BD; +D56F;D56F;1112 1161 11BE;D56F;1112 1161 11BE; +D570;D570;1112 1161 11BF;D570;1112 1161 11BF; +D571;D571;1112 1161 11C0;D571;1112 1161 11C0; +D572;D572;1112 1161 11C1;D572;1112 1161 11C1; +D573;D573;1112 1161 11C2;D573;1112 1161 11C2; +D574;D574;1112 1162;D574;1112 1162; +D575;D575;1112 1162 11A8;D575;1112 1162 11A8; +D576;D576;1112 1162 11A9;D576;1112 1162 11A9; +D577;D577;1112 1162 11AA;D577;1112 1162 11AA; +D578;D578;1112 1162 11AB;D578;1112 1162 11AB; +D579;D579;1112 1162 11AC;D579;1112 1162 11AC; +D57A;D57A;1112 1162 11AD;D57A;1112 1162 11AD; +D57B;D57B;1112 1162 11AE;D57B;1112 1162 11AE; +D57C;D57C;1112 1162 11AF;D57C;1112 1162 11AF; +D57D;D57D;1112 1162 11B0;D57D;1112 1162 11B0; +D57E;D57E;1112 1162 11B1;D57E;1112 1162 11B1; +D57F;D57F;1112 1162 11B2;D57F;1112 1162 11B2; +D580;D580;1112 1162 11B3;D580;1112 1162 11B3; +D581;D581;1112 1162 11B4;D581;1112 1162 11B4; +D582;D582;1112 1162 11B5;D582;1112 1162 11B5; +D583;D583;1112 1162 11B6;D583;1112 1162 11B6; +D584;D584;1112 1162 11B7;D584;1112 1162 11B7; +D585;D585;1112 1162 11B8;D585;1112 1162 11B8; +D586;D586;1112 1162 11B9;D586;1112 1162 11B9; +D587;D587;1112 1162 11BA;D587;1112 1162 11BA; +D588;D588;1112 1162 11BB;D588;1112 1162 11BB; +D589;D589;1112 1162 11BC;D589;1112 1162 11BC; +D58A;D58A;1112 1162 11BD;D58A;1112 1162 11BD; +D58B;D58B;1112 1162 11BE;D58B;1112 1162 11BE; +D58C;D58C;1112 1162 11BF;D58C;1112 1162 11BF; +D58D;D58D;1112 1162 11C0;D58D;1112 1162 11C0; +D58E;D58E;1112 1162 11C1;D58E;1112 1162 11C1; +D58F;D58F;1112 1162 11C2;D58F;1112 1162 11C2; +D590;D590;1112 1163;D590;1112 1163; +D591;D591;1112 1163 11A8;D591;1112 1163 11A8; +D592;D592;1112 1163 11A9;D592;1112 1163 11A9; +D593;D593;1112 1163 11AA;D593;1112 1163 11AA; +D594;D594;1112 1163 11AB;D594;1112 1163 11AB; +D595;D595;1112 1163 11AC;D595;1112 1163 11AC; +D596;D596;1112 1163 11AD;D596;1112 1163 11AD; +D597;D597;1112 1163 11AE;D597;1112 1163 11AE; +D598;D598;1112 1163 11AF;D598;1112 1163 11AF; +D599;D599;1112 1163 11B0;D599;1112 1163 11B0; +D59A;D59A;1112 1163 11B1;D59A;1112 1163 11B1; +D59B;D59B;1112 1163 11B2;D59B;1112 1163 11B2; +D59C;D59C;1112 1163 11B3;D59C;1112 1163 11B3; +D59D;D59D;1112 1163 11B4;D59D;1112 1163 11B4; +D59E;D59E;1112 1163 11B5;D59E;1112 1163 11B5; +D59F;D59F;1112 1163 11B6;D59F;1112 1163 11B6; +D5A0;D5A0;1112 1163 11B7;D5A0;1112 1163 11B7; +D5A1;D5A1;1112 1163 11B8;D5A1;1112 1163 11B8; +D5A2;D5A2;1112 1163 11B9;D5A2;1112 1163 11B9; +D5A3;D5A3;1112 1163 11BA;D5A3;1112 1163 11BA; +D5A4;D5A4;1112 1163 11BB;D5A4;1112 1163 11BB; +D5A5;D5A5;1112 1163 11BC;D5A5;1112 1163 11BC; +D5A6;D5A6;1112 1163 11BD;D5A6;1112 1163 11BD; +D5A7;D5A7;1112 1163 11BE;D5A7;1112 1163 11BE; +D5A8;D5A8;1112 1163 11BF;D5A8;1112 1163 11BF; +D5A9;D5A9;1112 1163 11C0;D5A9;1112 1163 11C0; +D5AA;D5AA;1112 1163 11C1;D5AA;1112 1163 11C1; +D5AB;D5AB;1112 1163 11C2;D5AB;1112 1163 11C2; +D5AC;D5AC;1112 1164;D5AC;1112 1164; +D5AD;D5AD;1112 1164 11A8;D5AD;1112 1164 11A8; +D5AE;D5AE;1112 1164 11A9;D5AE;1112 1164 11A9; +D5AF;D5AF;1112 1164 11AA;D5AF;1112 1164 11AA; +D5B0;D5B0;1112 1164 11AB;D5B0;1112 1164 11AB; +D5B1;D5B1;1112 1164 11AC;D5B1;1112 1164 11AC; +D5B2;D5B2;1112 1164 11AD;D5B2;1112 1164 11AD; +D5B3;D5B3;1112 1164 11AE;D5B3;1112 1164 11AE; +D5B4;D5B4;1112 1164 11AF;D5B4;1112 1164 11AF; +D5B5;D5B5;1112 1164 11B0;D5B5;1112 1164 11B0; +D5B6;D5B6;1112 1164 11B1;D5B6;1112 1164 11B1; +D5B7;D5B7;1112 1164 11B2;D5B7;1112 1164 11B2; +D5B8;D5B8;1112 1164 11B3;D5B8;1112 1164 11B3; +D5B9;D5B9;1112 1164 11B4;D5B9;1112 1164 11B4; +D5BA;D5BA;1112 1164 11B5;D5BA;1112 1164 11B5; +D5BB;D5BB;1112 1164 11B6;D5BB;1112 1164 11B6; +D5BC;D5BC;1112 1164 11B7;D5BC;1112 1164 11B7; +D5BD;D5BD;1112 1164 11B8;D5BD;1112 1164 11B8; +D5BE;D5BE;1112 1164 11B9;D5BE;1112 1164 11B9; +D5BF;D5BF;1112 1164 11BA;D5BF;1112 1164 11BA; +D5C0;D5C0;1112 1164 11BB;D5C0;1112 1164 11BB; +D5C1;D5C1;1112 1164 11BC;D5C1;1112 1164 11BC; +D5C2;D5C2;1112 1164 11BD;D5C2;1112 1164 11BD; +D5C3;D5C3;1112 1164 11BE;D5C3;1112 1164 11BE; +D5C4;D5C4;1112 1164 11BF;D5C4;1112 1164 11BF; +D5C5;D5C5;1112 1164 11C0;D5C5;1112 1164 11C0; +D5C6;D5C6;1112 1164 11C1;D5C6;1112 1164 11C1; +D5C7;D5C7;1112 1164 11C2;D5C7;1112 1164 11C2; +D5C8;D5C8;1112 1165;D5C8;1112 1165; +D5C9;D5C9;1112 1165 11A8;D5C9;1112 1165 11A8; +D5CA;D5CA;1112 1165 11A9;D5CA;1112 1165 11A9; +D5CB;D5CB;1112 1165 11AA;D5CB;1112 1165 11AA; +D5CC;D5CC;1112 1165 11AB;D5CC;1112 1165 11AB; +D5CD;D5CD;1112 1165 11AC;D5CD;1112 1165 11AC; +D5CE;D5CE;1112 1165 11AD;D5CE;1112 1165 11AD; +D5CF;D5CF;1112 1165 11AE;D5CF;1112 1165 11AE; +D5D0;D5D0;1112 1165 11AF;D5D0;1112 1165 11AF; +D5D1;D5D1;1112 1165 11B0;D5D1;1112 1165 11B0; +D5D2;D5D2;1112 1165 11B1;D5D2;1112 1165 11B1; +D5D3;D5D3;1112 1165 11B2;D5D3;1112 1165 11B2; +D5D4;D5D4;1112 1165 11B3;D5D4;1112 1165 11B3; +D5D5;D5D5;1112 1165 11B4;D5D5;1112 1165 11B4; +D5D6;D5D6;1112 1165 11B5;D5D6;1112 1165 11B5; +D5D7;D5D7;1112 1165 11B6;D5D7;1112 1165 11B6; +D5D8;D5D8;1112 1165 11B7;D5D8;1112 1165 11B7; +D5D9;D5D9;1112 1165 11B8;D5D9;1112 1165 11B8; +D5DA;D5DA;1112 1165 11B9;D5DA;1112 1165 11B9; +D5DB;D5DB;1112 1165 11BA;D5DB;1112 1165 11BA; +D5DC;D5DC;1112 1165 11BB;D5DC;1112 1165 11BB; +D5DD;D5DD;1112 1165 11BC;D5DD;1112 1165 11BC; +D5DE;D5DE;1112 1165 11BD;D5DE;1112 1165 11BD; +D5DF;D5DF;1112 1165 11BE;D5DF;1112 1165 11BE; +D5E0;D5E0;1112 1165 11BF;D5E0;1112 1165 11BF; +D5E1;D5E1;1112 1165 11C0;D5E1;1112 1165 11C0; +D5E2;D5E2;1112 1165 11C1;D5E2;1112 1165 11C1; +D5E3;D5E3;1112 1165 11C2;D5E3;1112 1165 11C2; +D5E4;D5E4;1112 1166;D5E4;1112 1166; +D5E5;D5E5;1112 1166 11A8;D5E5;1112 1166 11A8; +D5E6;D5E6;1112 1166 11A9;D5E6;1112 1166 11A9; +D5E7;D5E7;1112 1166 11AA;D5E7;1112 1166 11AA; +D5E8;D5E8;1112 1166 11AB;D5E8;1112 1166 11AB; +D5E9;D5E9;1112 1166 11AC;D5E9;1112 1166 11AC; +D5EA;D5EA;1112 1166 11AD;D5EA;1112 1166 11AD; +D5EB;D5EB;1112 1166 11AE;D5EB;1112 1166 11AE; +D5EC;D5EC;1112 1166 11AF;D5EC;1112 1166 11AF; +D5ED;D5ED;1112 1166 11B0;D5ED;1112 1166 11B0; +D5EE;D5EE;1112 1166 11B1;D5EE;1112 1166 11B1; +D5EF;D5EF;1112 1166 11B2;D5EF;1112 1166 11B2; +D5F0;D5F0;1112 1166 11B3;D5F0;1112 1166 11B3; +D5F1;D5F1;1112 1166 11B4;D5F1;1112 1166 11B4; +D5F2;D5F2;1112 1166 11B5;D5F2;1112 1166 11B5; +D5F3;D5F3;1112 1166 11B6;D5F3;1112 1166 11B6; +D5F4;D5F4;1112 1166 11B7;D5F4;1112 1166 11B7; +D5F5;D5F5;1112 1166 11B8;D5F5;1112 1166 11B8; +D5F6;D5F6;1112 1166 11B9;D5F6;1112 1166 11B9; +D5F7;D5F7;1112 1166 11BA;D5F7;1112 1166 11BA; +D5F8;D5F8;1112 1166 11BB;D5F8;1112 1166 11BB; +D5F9;D5F9;1112 1166 11BC;D5F9;1112 1166 11BC; +D5FA;D5FA;1112 1166 11BD;D5FA;1112 1166 11BD; +D5FB;D5FB;1112 1166 11BE;D5FB;1112 1166 11BE; +D5FC;D5FC;1112 1166 11BF;D5FC;1112 1166 11BF; +D5FD;D5FD;1112 1166 11C0;D5FD;1112 1166 11C0; +D5FE;D5FE;1112 1166 11C1;D5FE;1112 1166 11C1; +D5FF;D5FF;1112 1166 11C2;D5FF;1112 1166 11C2; +D600;D600;1112 1167;D600;1112 1167; +D601;D601;1112 1167 11A8;D601;1112 1167 11A8; +D602;D602;1112 1167 11A9;D602;1112 1167 11A9; +D603;D603;1112 1167 11AA;D603;1112 1167 11AA; +D604;D604;1112 1167 11AB;D604;1112 1167 11AB; +D605;D605;1112 1167 11AC;D605;1112 1167 11AC; +D606;D606;1112 1167 11AD;D606;1112 1167 11AD; +D607;D607;1112 1167 11AE;D607;1112 1167 11AE; +D608;D608;1112 1167 11AF;D608;1112 1167 11AF; +D609;D609;1112 1167 11B0;D609;1112 1167 11B0; +D60A;D60A;1112 1167 11B1;D60A;1112 1167 11B1; +D60B;D60B;1112 1167 11B2;D60B;1112 1167 11B2; +D60C;D60C;1112 1167 11B3;D60C;1112 1167 11B3; +D60D;D60D;1112 1167 11B4;D60D;1112 1167 11B4; +D60E;D60E;1112 1167 11B5;D60E;1112 1167 11B5; +D60F;D60F;1112 1167 11B6;D60F;1112 1167 11B6; +D610;D610;1112 1167 11B7;D610;1112 1167 11B7; +D611;D611;1112 1167 11B8;D611;1112 1167 11B8; +D612;D612;1112 1167 11B9;D612;1112 1167 11B9; +D613;D613;1112 1167 11BA;D613;1112 1167 11BA; +D614;D614;1112 1167 11BB;D614;1112 1167 11BB; +D615;D615;1112 1167 11BC;D615;1112 1167 11BC; +D616;D616;1112 1167 11BD;D616;1112 1167 11BD; +D617;D617;1112 1167 11BE;D617;1112 1167 11BE; +D618;D618;1112 1167 11BF;D618;1112 1167 11BF; +D619;D619;1112 1167 11C0;D619;1112 1167 11C0; +D61A;D61A;1112 1167 11C1;D61A;1112 1167 11C1; +D61B;D61B;1112 1167 11C2;D61B;1112 1167 11C2; +D61C;D61C;1112 1168;D61C;1112 1168; +D61D;D61D;1112 1168 11A8;D61D;1112 1168 11A8; +D61E;D61E;1112 1168 11A9;D61E;1112 1168 11A9; +D61F;D61F;1112 1168 11AA;D61F;1112 1168 11AA; +D620;D620;1112 1168 11AB;D620;1112 1168 11AB; +D621;D621;1112 1168 11AC;D621;1112 1168 11AC; +D622;D622;1112 1168 11AD;D622;1112 1168 11AD; +D623;D623;1112 1168 11AE;D623;1112 1168 11AE; +D624;D624;1112 1168 11AF;D624;1112 1168 11AF; +D625;D625;1112 1168 11B0;D625;1112 1168 11B0; +D626;D626;1112 1168 11B1;D626;1112 1168 11B1; +D627;D627;1112 1168 11B2;D627;1112 1168 11B2; +D628;D628;1112 1168 11B3;D628;1112 1168 11B3; +D629;D629;1112 1168 11B4;D629;1112 1168 11B4; +D62A;D62A;1112 1168 11B5;D62A;1112 1168 11B5; +D62B;D62B;1112 1168 11B6;D62B;1112 1168 11B6; +D62C;D62C;1112 1168 11B7;D62C;1112 1168 11B7; +D62D;D62D;1112 1168 11B8;D62D;1112 1168 11B8; +D62E;D62E;1112 1168 11B9;D62E;1112 1168 11B9; +D62F;D62F;1112 1168 11BA;D62F;1112 1168 11BA; +D630;D630;1112 1168 11BB;D630;1112 1168 11BB; +D631;D631;1112 1168 11BC;D631;1112 1168 11BC; +D632;D632;1112 1168 11BD;D632;1112 1168 11BD; +D633;D633;1112 1168 11BE;D633;1112 1168 11BE; +D634;D634;1112 1168 11BF;D634;1112 1168 11BF; +D635;D635;1112 1168 11C0;D635;1112 1168 11C0; +D636;D636;1112 1168 11C1;D636;1112 1168 11C1; +D637;D637;1112 1168 11C2;D637;1112 1168 11C2; +D638;D638;1112 1169;D638;1112 1169; +D639;D639;1112 1169 11A8;D639;1112 1169 11A8; +D63A;D63A;1112 1169 11A9;D63A;1112 1169 11A9; +D63B;D63B;1112 1169 11AA;D63B;1112 1169 11AA; +D63C;D63C;1112 1169 11AB;D63C;1112 1169 11AB; +D63D;D63D;1112 1169 11AC;D63D;1112 1169 11AC; +D63E;D63E;1112 1169 11AD;D63E;1112 1169 11AD; +D63F;D63F;1112 1169 11AE;D63F;1112 1169 11AE; +D640;D640;1112 1169 11AF;D640;1112 1169 11AF; +D641;D641;1112 1169 11B0;D641;1112 1169 11B0; +D642;D642;1112 1169 11B1;D642;1112 1169 11B1; +D643;D643;1112 1169 11B2;D643;1112 1169 11B2; +D644;D644;1112 1169 11B3;D644;1112 1169 11B3; +D645;D645;1112 1169 11B4;D645;1112 1169 11B4; +D646;D646;1112 1169 11B5;D646;1112 1169 11B5; +D647;D647;1112 1169 11B6;D647;1112 1169 11B6; +D648;D648;1112 1169 11B7;D648;1112 1169 11B7; +D649;D649;1112 1169 11B8;D649;1112 1169 11B8; +D64A;D64A;1112 1169 11B9;D64A;1112 1169 11B9; +D64B;D64B;1112 1169 11BA;D64B;1112 1169 11BA; +D64C;D64C;1112 1169 11BB;D64C;1112 1169 11BB; +D64D;D64D;1112 1169 11BC;D64D;1112 1169 11BC; +D64E;D64E;1112 1169 11BD;D64E;1112 1169 11BD; +D64F;D64F;1112 1169 11BE;D64F;1112 1169 11BE; +D650;D650;1112 1169 11BF;D650;1112 1169 11BF; +D651;D651;1112 1169 11C0;D651;1112 1169 11C0; +D652;D652;1112 1169 11C1;D652;1112 1169 11C1; +D653;D653;1112 1169 11C2;D653;1112 1169 11C2; +D654;D654;1112 116A;D654;1112 116A; +D655;D655;1112 116A 11A8;D655;1112 116A 11A8; +D656;D656;1112 116A 11A9;D656;1112 116A 11A9; +D657;D657;1112 116A 11AA;D657;1112 116A 11AA; +D658;D658;1112 116A 11AB;D658;1112 116A 11AB; +D659;D659;1112 116A 11AC;D659;1112 116A 11AC; +D65A;D65A;1112 116A 11AD;D65A;1112 116A 11AD; +D65B;D65B;1112 116A 11AE;D65B;1112 116A 11AE; +D65C;D65C;1112 116A 11AF;D65C;1112 116A 11AF; +D65D;D65D;1112 116A 11B0;D65D;1112 116A 11B0; +D65E;D65E;1112 116A 11B1;D65E;1112 116A 11B1; +D65F;D65F;1112 116A 11B2;D65F;1112 116A 11B2; +D660;D660;1112 116A 11B3;D660;1112 116A 11B3; +D661;D661;1112 116A 11B4;D661;1112 116A 11B4; +D662;D662;1112 116A 11B5;D662;1112 116A 11B5; +D663;D663;1112 116A 11B6;D663;1112 116A 11B6; +D664;D664;1112 116A 11B7;D664;1112 116A 11B7; +D665;D665;1112 116A 11B8;D665;1112 116A 11B8; +D666;D666;1112 116A 11B9;D666;1112 116A 11B9; +D667;D667;1112 116A 11BA;D667;1112 116A 11BA; +D668;D668;1112 116A 11BB;D668;1112 116A 11BB; +D669;D669;1112 116A 11BC;D669;1112 116A 11BC; +D66A;D66A;1112 116A 11BD;D66A;1112 116A 11BD; +D66B;D66B;1112 116A 11BE;D66B;1112 116A 11BE; +D66C;D66C;1112 116A 11BF;D66C;1112 116A 11BF; +D66D;D66D;1112 116A 11C0;D66D;1112 116A 11C0; +D66E;D66E;1112 116A 11C1;D66E;1112 116A 11C1; +D66F;D66F;1112 116A 11C2;D66F;1112 116A 11C2; +D670;D670;1112 116B;D670;1112 116B; +D671;D671;1112 116B 11A8;D671;1112 116B 11A8; +D672;D672;1112 116B 11A9;D672;1112 116B 11A9; +D673;D673;1112 116B 11AA;D673;1112 116B 11AA; +D674;D674;1112 116B 11AB;D674;1112 116B 11AB; +D675;D675;1112 116B 11AC;D675;1112 116B 11AC; +D676;D676;1112 116B 11AD;D676;1112 116B 11AD; +D677;D677;1112 116B 11AE;D677;1112 116B 11AE; +D678;D678;1112 116B 11AF;D678;1112 116B 11AF; +D679;D679;1112 116B 11B0;D679;1112 116B 11B0; +D67A;D67A;1112 116B 11B1;D67A;1112 116B 11B1; +D67B;D67B;1112 116B 11B2;D67B;1112 116B 11B2; +D67C;D67C;1112 116B 11B3;D67C;1112 116B 11B3; +D67D;D67D;1112 116B 11B4;D67D;1112 116B 11B4; +D67E;D67E;1112 116B 11B5;D67E;1112 116B 11B5; +D67F;D67F;1112 116B 11B6;D67F;1112 116B 11B6; +D680;D680;1112 116B 11B7;D680;1112 116B 11B7; +D681;D681;1112 116B 11B8;D681;1112 116B 11B8; +D682;D682;1112 116B 11B9;D682;1112 116B 11B9; +D683;D683;1112 116B 11BA;D683;1112 116B 11BA; +D684;D684;1112 116B 11BB;D684;1112 116B 11BB; +D685;D685;1112 116B 11BC;D685;1112 116B 11BC; +D686;D686;1112 116B 11BD;D686;1112 116B 11BD; +D687;D687;1112 116B 11BE;D687;1112 116B 11BE; +D688;D688;1112 116B 11BF;D688;1112 116B 11BF; +D689;D689;1112 116B 11C0;D689;1112 116B 11C0; +D68A;D68A;1112 116B 11C1;D68A;1112 116B 11C1; +D68B;D68B;1112 116B 11C2;D68B;1112 116B 11C2; +D68C;D68C;1112 116C;D68C;1112 116C; +D68D;D68D;1112 116C 11A8;D68D;1112 116C 11A8; +D68E;D68E;1112 116C 11A9;D68E;1112 116C 11A9; +D68F;D68F;1112 116C 11AA;D68F;1112 116C 11AA; +D690;D690;1112 116C 11AB;D690;1112 116C 11AB; +D691;D691;1112 116C 11AC;D691;1112 116C 11AC; +D692;D692;1112 116C 11AD;D692;1112 116C 11AD; +D693;D693;1112 116C 11AE;D693;1112 116C 11AE; +D694;D694;1112 116C 11AF;D694;1112 116C 11AF; +D695;D695;1112 116C 11B0;D695;1112 116C 11B0; +D696;D696;1112 116C 11B1;D696;1112 116C 11B1; +D697;D697;1112 116C 11B2;D697;1112 116C 11B2; +D698;D698;1112 116C 11B3;D698;1112 116C 11B3; +D699;D699;1112 116C 11B4;D699;1112 116C 11B4; +D69A;D69A;1112 116C 11B5;D69A;1112 116C 11B5; +D69B;D69B;1112 116C 11B6;D69B;1112 116C 11B6; +D69C;D69C;1112 116C 11B7;D69C;1112 116C 11B7; +D69D;D69D;1112 116C 11B8;D69D;1112 116C 11B8; +D69E;D69E;1112 116C 11B9;D69E;1112 116C 11B9; +D69F;D69F;1112 116C 11BA;D69F;1112 116C 11BA; +D6A0;D6A0;1112 116C 11BB;D6A0;1112 116C 11BB; +D6A1;D6A1;1112 116C 11BC;D6A1;1112 116C 11BC; +D6A2;D6A2;1112 116C 11BD;D6A2;1112 116C 11BD; +D6A3;D6A3;1112 116C 11BE;D6A3;1112 116C 11BE; +D6A4;D6A4;1112 116C 11BF;D6A4;1112 116C 11BF; +D6A5;D6A5;1112 116C 11C0;D6A5;1112 116C 11C0; +D6A6;D6A6;1112 116C 11C1;D6A6;1112 116C 11C1; +D6A7;D6A7;1112 116C 11C2;D6A7;1112 116C 11C2; +D6A8;D6A8;1112 116D;D6A8;1112 116D; +D6A9;D6A9;1112 116D 11A8;D6A9;1112 116D 11A8; +D6AA;D6AA;1112 116D 11A9;D6AA;1112 116D 11A9; +D6AB;D6AB;1112 116D 11AA;D6AB;1112 116D 11AA; +D6AC;D6AC;1112 116D 11AB;D6AC;1112 116D 11AB; +D6AD;D6AD;1112 116D 11AC;D6AD;1112 116D 11AC; +D6AE;D6AE;1112 116D 11AD;D6AE;1112 116D 11AD; +D6AF;D6AF;1112 116D 11AE;D6AF;1112 116D 11AE; +D6B0;D6B0;1112 116D 11AF;D6B0;1112 116D 11AF; +D6B1;D6B1;1112 116D 11B0;D6B1;1112 116D 11B0; +D6B2;D6B2;1112 116D 11B1;D6B2;1112 116D 11B1; +D6B3;D6B3;1112 116D 11B2;D6B3;1112 116D 11B2; +D6B4;D6B4;1112 116D 11B3;D6B4;1112 116D 11B3; +D6B5;D6B5;1112 116D 11B4;D6B5;1112 116D 11B4; +D6B6;D6B6;1112 116D 11B5;D6B6;1112 116D 11B5; +D6B7;D6B7;1112 116D 11B6;D6B7;1112 116D 11B6; +D6B8;D6B8;1112 116D 11B7;D6B8;1112 116D 11B7; +D6B9;D6B9;1112 116D 11B8;D6B9;1112 116D 11B8; +D6BA;D6BA;1112 116D 11B9;D6BA;1112 116D 11B9; +D6BB;D6BB;1112 116D 11BA;D6BB;1112 116D 11BA; +D6BC;D6BC;1112 116D 11BB;D6BC;1112 116D 11BB; +D6BD;D6BD;1112 116D 11BC;D6BD;1112 116D 11BC; +D6BE;D6BE;1112 116D 11BD;D6BE;1112 116D 11BD; +D6BF;D6BF;1112 116D 11BE;D6BF;1112 116D 11BE; +D6C0;D6C0;1112 116D 11BF;D6C0;1112 116D 11BF; +D6C1;D6C1;1112 116D 11C0;D6C1;1112 116D 11C0; +D6C2;D6C2;1112 116D 11C1;D6C2;1112 116D 11C1; +D6C3;D6C3;1112 116D 11C2;D6C3;1112 116D 11C2; +D6C4;D6C4;1112 116E;D6C4;1112 116E; +D6C5;D6C5;1112 116E 11A8;D6C5;1112 116E 11A8; +D6C6;D6C6;1112 116E 11A9;D6C6;1112 116E 11A9; +D6C7;D6C7;1112 116E 11AA;D6C7;1112 116E 11AA; +D6C8;D6C8;1112 116E 11AB;D6C8;1112 116E 11AB; +D6C9;D6C9;1112 116E 11AC;D6C9;1112 116E 11AC; +D6CA;D6CA;1112 116E 11AD;D6CA;1112 116E 11AD; +D6CB;D6CB;1112 116E 11AE;D6CB;1112 116E 11AE; +D6CC;D6CC;1112 116E 11AF;D6CC;1112 116E 11AF; +D6CD;D6CD;1112 116E 11B0;D6CD;1112 116E 11B0; +D6CE;D6CE;1112 116E 11B1;D6CE;1112 116E 11B1; +D6CF;D6CF;1112 116E 11B2;D6CF;1112 116E 11B2; +D6D0;D6D0;1112 116E 11B3;D6D0;1112 116E 11B3; +D6D1;D6D1;1112 116E 11B4;D6D1;1112 116E 11B4; +D6D2;D6D2;1112 116E 11B5;D6D2;1112 116E 11B5; +D6D3;D6D3;1112 116E 11B6;D6D3;1112 116E 11B6; +D6D4;D6D4;1112 116E 11B7;D6D4;1112 116E 11B7; +D6D5;D6D5;1112 116E 11B8;D6D5;1112 116E 11B8; +D6D6;D6D6;1112 116E 11B9;D6D6;1112 116E 11B9; +D6D7;D6D7;1112 116E 11BA;D6D7;1112 116E 11BA; +D6D8;D6D8;1112 116E 11BB;D6D8;1112 116E 11BB; +D6D9;D6D9;1112 116E 11BC;D6D9;1112 116E 11BC; +D6DA;D6DA;1112 116E 11BD;D6DA;1112 116E 11BD; +D6DB;D6DB;1112 116E 11BE;D6DB;1112 116E 11BE; +D6DC;D6DC;1112 116E 11BF;D6DC;1112 116E 11BF; +D6DD;D6DD;1112 116E 11C0;D6DD;1112 116E 11C0; +D6DE;D6DE;1112 116E 11C1;D6DE;1112 116E 11C1; +D6DF;D6DF;1112 116E 11C2;D6DF;1112 116E 11C2; +D6E0;D6E0;1112 116F;D6E0;1112 116F; +D6E1;D6E1;1112 116F 11A8;D6E1;1112 116F 11A8; +D6E2;D6E2;1112 116F 11A9;D6E2;1112 116F 11A9; +D6E3;D6E3;1112 116F 11AA;D6E3;1112 116F 11AA; +D6E4;D6E4;1112 116F 11AB;D6E4;1112 116F 11AB; +D6E5;D6E5;1112 116F 11AC;D6E5;1112 116F 11AC; +D6E6;D6E6;1112 116F 11AD;D6E6;1112 116F 11AD; +D6E7;D6E7;1112 116F 11AE;D6E7;1112 116F 11AE; +D6E8;D6E8;1112 116F 11AF;D6E8;1112 116F 11AF; +D6E9;D6E9;1112 116F 11B0;D6E9;1112 116F 11B0; +D6EA;D6EA;1112 116F 11B1;D6EA;1112 116F 11B1; +D6EB;D6EB;1112 116F 11B2;D6EB;1112 116F 11B2; +D6EC;D6EC;1112 116F 11B3;D6EC;1112 116F 11B3; +D6ED;D6ED;1112 116F 11B4;D6ED;1112 116F 11B4; +D6EE;D6EE;1112 116F 11B5;D6EE;1112 116F 11B5; +D6EF;D6EF;1112 116F 11B6;D6EF;1112 116F 11B6; +D6F0;D6F0;1112 116F 11B7;D6F0;1112 116F 11B7; +D6F1;D6F1;1112 116F 11B8;D6F1;1112 116F 11B8; +D6F2;D6F2;1112 116F 11B9;D6F2;1112 116F 11B9; +D6F3;D6F3;1112 116F 11BA;D6F3;1112 116F 11BA; +D6F4;D6F4;1112 116F 11BB;D6F4;1112 116F 11BB; +D6F5;D6F5;1112 116F 11BC;D6F5;1112 116F 11BC; +D6F6;D6F6;1112 116F 11BD;D6F6;1112 116F 11BD; +D6F7;D6F7;1112 116F 11BE;D6F7;1112 116F 11BE; +D6F8;D6F8;1112 116F 11BF;D6F8;1112 116F 11BF; +D6F9;D6F9;1112 116F 11C0;D6F9;1112 116F 11C0; +D6FA;D6FA;1112 116F 11C1;D6FA;1112 116F 11C1; +D6FB;D6FB;1112 116F 11C2;D6FB;1112 116F 11C2; +D6FC;D6FC;1112 1170;D6FC;1112 1170; +D6FD;D6FD;1112 1170 11A8;D6FD;1112 1170 11A8; +D6FE;D6FE;1112 1170 11A9;D6FE;1112 1170 11A9; +D6FF;D6FF;1112 1170 11AA;D6FF;1112 1170 11AA; +D700;D700;1112 1170 11AB;D700;1112 1170 11AB; +D701;D701;1112 1170 11AC;D701;1112 1170 11AC; +D702;D702;1112 1170 11AD;D702;1112 1170 11AD; +D703;D703;1112 1170 11AE;D703;1112 1170 11AE; +D704;D704;1112 1170 11AF;D704;1112 1170 11AF; +D705;D705;1112 1170 11B0;D705;1112 1170 11B0; +D706;D706;1112 1170 11B1;D706;1112 1170 11B1; +D707;D707;1112 1170 11B2;D707;1112 1170 11B2; +D708;D708;1112 1170 11B3;D708;1112 1170 11B3; +D709;D709;1112 1170 11B4;D709;1112 1170 11B4; +D70A;D70A;1112 1170 11B5;D70A;1112 1170 11B5; +D70B;D70B;1112 1170 11B6;D70B;1112 1170 11B6; +D70C;D70C;1112 1170 11B7;D70C;1112 1170 11B7; +D70D;D70D;1112 1170 11B8;D70D;1112 1170 11B8; +D70E;D70E;1112 1170 11B9;D70E;1112 1170 11B9; +D70F;D70F;1112 1170 11BA;D70F;1112 1170 11BA; +D710;D710;1112 1170 11BB;D710;1112 1170 11BB; +D711;D711;1112 1170 11BC;D711;1112 1170 11BC; +D712;D712;1112 1170 11BD;D712;1112 1170 11BD; +D713;D713;1112 1170 11BE;D713;1112 1170 11BE; +D714;D714;1112 1170 11BF;D714;1112 1170 11BF; +D715;D715;1112 1170 11C0;D715;1112 1170 11C0; +D716;D716;1112 1170 11C1;D716;1112 1170 11C1; +D717;D717;1112 1170 11C2;D717;1112 1170 11C2; +D718;D718;1112 1171;D718;1112 1171; +D719;D719;1112 1171 11A8;D719;1112 1171 11A8; +D71A;D71A;1112 1171 11A9;D71A;1112 1171 11A9; +D71B;D71B;1112 1171 11AA;D71B;1112 1171 11AA; +D71C;D71C;1112 1171 11AB;D71C;1112 1171 11AB; +D71D;D71D;1112 1171 11AC;D71D;1112 1171 11AC; +D71E;D71E;1112 1171 11AD;D71E;1112 1171 11AD; +D71F;D71F;1112 1171 11AE;D71F;1112 1171 11AE; +D720;D720;1112 1171 11AF;D720;1112 1171 11AF; +D721;D721;1112 1171 11B0;D721;1112 1171 11B0; +D722;D722;1112 1171 11B1;D722;1112 1171 11B1; +D723;D723;1112 1171 11B2;D723;1112 1171 11B2; +D724;D724;1112 1171 11B3;D724;1112 1171 11B3; +D725;D725;1112 1171 11B4;D725;1112 1171 11B4; +D726;D726;1112 1171 11B5;D726;1112 1171 11B5; +D727;D727;1112 1171 11B6;D727;1112 1171 11B6; +D728;D728;1112 1171 11B7;D728;1112 1171 11B7; +D729;D729;1112 1171 11B8;D729;1112 1171 11B8; +D72A;D72A;1112 1171 11B9;D72A;1112 1171 11B9; +D72B;D72B;1112 1171 11BA;D72B;1112 1171 11BA; +D72C;D72C;1112 1171 11BB;D72C;1112 1171 11BB; +D72D;D72D;1112 1171 11BC;D72D;1112 1171 11BC; +D72E;D72E;1112 1171 11BD;D72E;1112 1171 11BD; +D72F;D72F;1112 1171 11BE;D72F;1112 1171 11BE; +D730;D730;1112 1171 11BF;D730;1112 1171 11BF; +D731;D731;1112 1171 11C0;D731;1112 1171 11C0; +D732;D732;1112 1171 11C1;D732;1112 1171 11C1; +D733;D733;1112 1171 11C2;D733;1112 1171 11C2; +D734;D734;1112 1172;D734;1112 1172; +D735;D735;1112 1172 11A8;D735;1112 1172 11A8; +D736;D736;1112 1172 11A9;D736;1112 1172 11A9; +D737;D737;1112 1172 11AA;D737;1112 1172 11AA; +D738;D738;1112 1172 11AB;D738;1112 1172 11AB; +D739;D739;1112 1172 11AC;D739;1112 1172 11AC; +D73A;D73A;1112 1172 11AD;D73A;1112 1172 11AD; +D73B;D73B;1112 1172 11AE;D73B;1112 1172 11AE; +D73C;D73C;1112 1172 11AF;D73C;1112 1172 11AF; +D73D;D73D;1112 1172 11B0;D73D;1112 1172 11B0; +D73E;D73E;1112 1172 11B1;D73E;1112 1172 11B1; +D73F;D73F;1112 1172 11B2;D73F;1112 1172 11B2; +D740;D740;1112 1172 11B3;D740;1112 1172 11B3; +D741;D741;1112 1172 11B4;D741;1112 1172 11B4; +D742;D742;1112 1172 11B5;D742;1112 1172 11B5; +D743;D743;1112 1172 11B6;D743;1112 1172 11B6; +D744;D744;1112 1172 11B7;D744;1112 1172 11B7; +D745;D745;1112 1172 11B8;D745;1112 1172 11B8; +D746;D746;1112 1172 11B9;D746;1112 1172 11B9; +D747;D747;1112 1172 11BA;D747;1112 1172 11BA; +D748;D748;1112 1172 11BB;D748;1112 1172 11BB; +D749;D749;1112 1172 11BC;D749;1112 1172 11BC; +D74A;D74A;1112 1172 11BD;D74A;1112 1172 11BD; +D74B;D74B;1112 1172 11BE;D74B;1112 1172 11BE; +D74C;D74C;1112 1172 11BF;D74C;1112 1172 11BF; +D74D;D74D;1112 1172 11C0;D74D;1112 1172 11C0; +D74E;D74E;1112 1172 11C1;D74E;1112 1172 11C1; +D74F;D74F;1112 1172 11C2;D74F;1112 1172 11C2; +D750;D750;1112 1173;D750;1112 1173; +D751;D751;1112 1173 11A8;D751;1112 1173 11A8; +D752;D752;1112 1173 11A9;D752;1112 1173 11A9; +D753;D753;1112 1173 11AA;D753;1112 1173 11AA; +D754;D754;1112 1173 11AB;D754;1112 1173 11AB; +D755;D755;1112 1173 11AC;D755;1112 1173 11AC; +D756;D756;1112 1173 11AD;D756;1112 1173 11AD; +D757;D757;1112 1173 11AE;D757;1112 1173 11AE; +D758;D758;1112 1173 11AF;D758;1112 1173 11AF; +D759;D759;1112 1173 11B0;D759;1112 1173 11B0; +D75A;D75A;1112 1173 11B1;D75A;1112 1173 11B1; +D75B;D75B;1112 1173 11B2;D75B;1112 1173 11B2; +D75C;D75C;1112 1173 11B3;D75C;1112 1173 11B3; +D75D;D75D;1112 1173 11B4;D75D;1112 1173 11B4; +D75E;D75E;1112 1173 11B5;D75E;1112 1173 11B5; +D75F;D75F;1112 1173 11B6;D75F;1112 1173 11B6; +D760;D760;1112 1173 11B7;D760;1112 1173 11B7; +D761;D761;1112 1173 11B8;D761;1112 1173 11B8; +D762;D762;1112 1173 11B9;D762;1112 1173 11B9; +D763;D763;1112 1173 11BA;D763;1112 1173 11BA; +D764;D764;1112 1173 11BB;D764;1112 1173 11BB; +D765;D765;1112 1173 11BC;D765;1112 1173 11BC; +D766;D766;1112 1173 11BD;D766;1112 1173 11BD; +D767;D767;1112 1173 11BE;D767;1112 1173 11BE; +D768;D768;1112 1173 11BF;D768;1112 1173 11BF; +D769;D769;1112 1173 11C0;D769;1112 1173 11C0; +D76A;D76A;1112 1173 11C1;D76A;1112 1173 11C1; +D76B;D76B;1112 1173 11C2;D76B;1112 1173 11C2; +D76C;D76C;1112 1174;D76C;1112 1174; +D76D;D76D;1112 1174 11A8;D76D;1112 1174 11A8; +D76E;D76E;1112 1174 11A9;D76E;1112 1174 11A9; +D76F;D76F;1112 1174 11AA;D76F;1112 1174 11AA; +D770;D770;1112 1174 11AB;D770;1112 1174 11AB; +D771;D771;1112 1174 11AC;D771;1112 1174 11AC; +D772;D772;1112 1174 11AD;D772;1112 1174 11AD; +D773;D773;1112 1174 11AE;D773;1112 1174 11AE; +D774;D774;1112 1174 11AF;D774;1112 1174 11AF; +D775;D775;1112 1174 11B0;D775;1112 1174 11B0; +D776;D776;1112 1174 11B1;D776;1112 1174 11B1; +D777;D777;1112 1174 11B2;D777;1112 1174 11B2; +D778;D778;1112 1174 11B3;D778;1112 1174 11B3; +D779;D779;1112 1174 11B4;D779;1112 1174 11B4; +D77A;D77A;1112 1174 11B5;D77A;1112 1174 11B5; +D77B;D77B;1112 1174 11B6;D77B;1112 1174 11B6; +D77C;D77C;1112 1174 11B7;D77C;1112 1174 11B7; +D77D;D77D;1112 1174 11B8;D77D;1112 1174 11B8; +D77E;D77E;1112 1174 11B9;D77E;1112 1174 11B9; +D77F;D77F;1112 1174 11BA;D77F;1112 1174 11BA; +D780;D780;1112 1174 11BB;D780;1112 1174 11BB; +D781;D781;1112 1174 11BC;D781;1112 1174 11BC; +D782;D782;1112 1174 11BD;D782;1112 1174 11BD; +D783;D783;1112 1174 11BE;D783;1112 1174 11BE; +D784;D784;1112 1174 11BF;D784;1112 1174 11BF; +D785;D785;1112 1174 11C0;D785;1112 1174 11C0; +D786;D786;1112 1174 11C1;D786;1112 1174 11C1; +D787;D787;1112 1174 11C2;D787;1112 1174 11C2; +D788;D788;1112 1175;D788;1112 1175; +D789;D789;1112 1175 11A8;D789;1112 1175 11A8; +D78A;D78A;1112 1175 11A9;D78A;1112 1175 11A9; +D78B;D78B;1112 1175 11AA;D78B;1112 1175 11AA; +D78C;D78C;1112 1175 11AB;D78C;1112 1175 11AB; +D78D;D78D;1112 1175 11AC;D78D;1112 1175 11AC; +D78E;D78E;1112 1175 11AD;D78E;1112 1175 11AD; +D78F;D78F;1112 1175 11AE;D78F;1112 1175 11AE; +D790;D790;1112 1175 11AF;D790;1112 1175 11AF; +D791;D791;1112 1175 11B0;D791;1112 1175 11B0; +D792;D792;1112 1175 11B1;D792;1112 1175 11B1; +D793;D793;1112 1175 11B2;D793;1112 1175 11B2; +D794;D794;1112 1175 11B3;D794;1112 1175 11B3; +D795;D795;1112 1175 11B4;D795;1112 1175 11B4; +D796;D796;1112 1175 11B5;D796;1112 1175 11B5; +D797;D797;1112 1175 11B6;D797;1112 1175 11B6; +D798;D798;1112 1175 11B7;D798;1112 1175 11B7; +D799;D799;1112 1175 11B8;D799;1112 1175 11B8; +D79A;D79A;1112 1175 11B9;D79A;1112 1175 11B9; +D79B;D79B;1112 1175 11BA;D79B;1112 1175 11BA; +D79C;D79C;1112 1175 11BB;D79C;1112 1175 11BB; +D79D;D79D;1112 1175 11BC;D79D;1112 1175 11BC; +D79E;D79E;1112 1175 11BD;D79E;1112 1175 11BD; +D79F;D79F;1112 1175 11BE;D79F;1112 1175 11BE; +D7A0;D7A0;1112 1175 11BF;D7A0;1112 1175 11BF; +D7A1;D7A1;1112 1175 11C0;D7A1;1112 1175 11C0; +D7A2;D7A2;1112 1175 11C1;D7A2;1112 1175 11C1; +D7A3;D7A3;1112 1175 11C2;D7A3;1112 1175 11C2; +F900;8C48;8C48;8C48;8C48; +F901;66F4;66F4;66F4;66F4; +F902;8ECA;8ECA;8ECA;8ECA; +F903;8CC8;8CC8;8CC8;8CC8; +F904;6ED1;6ED1;6ED1;6ED1; +F905;4E32;4E32;4E32;4E32; +F906;53E5;53E5;53E5;53E5; +F907;9F9C;9F9C;9F9C;9F9C; +F908;9F9C;9F9C;9F9C;9F9C; +F909;5951;5951;5951;5951; +F90A;91D1;91D1;91D1;91D1; +F90B;5587;5587;5587;5587; +F90C;5948;5948;5948;5948; +F90D;61F6;61F6;61F6;61F6; +F90E;7669;7669;7669;7669; +F90F;7F85;7F85;7F85;7F85; +F910;863F;863F;863F;863F; +F911;87BA;87BA;87BA;87BA; +F912;88F8;88F8;88F8;88F8; +F913;908F;908F;908F;908F; +F914;6A02;6A02;6A02;6A02; +F915;6D1B;6D1B;6D1B;6D1B; +F916;70D9;70D9;70D9;70D9; +F917;73DE;73DE;73DE;73DE; +F918;843D;843D;843D;843D; +F919;916A;916A;916A;916A; +F91A;99F1;99F1;99F1;99F1; +F91B;4E82;4E82;4E82;4E82; +F91C;5375;5375;5375;5375; +F91D;6B04;6B04;6B04;6B04; +F91E;721B;721B;721B;721B; +F91F;862D;862D;862D;862D; +F920;9E1E;9E1E;9E1E;9E1E; +F921;5D50;5D50;5D50;5D50; +F922;6FEB;6FEB;6FEB;6FEB; +F923;85CD;85CD;85CD;85CD; +F924;8964;8964;8964;8964; +F925;62C9;62C9;62C9;62C9; +F926;81D8;81D8;81D8;81D8; +F927;881F;881F;881F;881F; +F928;5ECA;5ECA;5ECA;5ECA; +F929;6717;6717;6717;6717; +F92A;6D6A;6D6A;6D6A;6D6A; +F92B;72FC;72FC;72FC;72FC; +F92C;90CE;90CE;90CE;90CE; +F92D;4F86;4F86;4F86;4F86; +F92E;51B7;51B7;51B7;51B7; +F92F;52DE;52DE;52DE;52DE; +F930;64C4;64C4;64C4;64C4; +F931;6AD3;6AD3;6AD3;6AD3; +F932;7210;7210;7210;7210; +F933;76E7;76E7;76E7;76E7; +F934;8001;8001;8001;8001; +F935;8606;8606;8606;8606; +F936;865C;865C;865C;865C; +F937;8DEF;8DEF;8DEF;8DEF; +F938;9732;9732;9732;9732; +F939;9B6F;9B6F;9B6F;9B6F; +F93A;9DFA;9DFA;9DFA;9DFA; +F93B;788C;788C;788C;788C; +F93C;797F;797F;797F;797F; +F93D;7DA0;7DA0;7DA0;7DA0; +F93E;83C9;83C9;83C9;83C9; +F93F;9304;9304;9304;9304; +F940;9E7F;9E7F;9E7F;9E7F; +F941;8AD6;8AD6;8AD6;8AD6; +F942;58DF;58DF;58DF;58DF; +F943;5F04;5F04;5F04;5F04; +F944;7C60;7C60;7C60;7C60; +F945;807E;807E;807E;807E; +F946;7262;7262;7262;7262; +F947;78CA;78CA;78CA;78CA; +F948;8CC2;8CC2;8CC2;8CC2; +F949;96F7;96F7;96F7;96F7; +F94A;58D8;58D8;58D8;58D8; +F94B;5C62;5C62;5C62;5C62; +F94C;6A13;6A13;6A13;6A13; +F94D;6DDA;6DDA;6DDA;6DDA; +F94E;6F0F;6F0F;6F0F;6F0F; +F94F;7D2F;7D2F;7D2F;7D2F; +F950;7E37;7E37;7E37;7E37; +F951;964B;964B;964B;964B; +F952;52D2;52D2;52D2;52D2; +F953;808B;808B;808B;808B; +F954;51DC;51DC;51DC;51DC; +F955;51CC;51CC;51CC;51CC; +F956;7A1C;7A1C;7A1C;7A1C; +F957;7DBE;7DBE;7DBE;7DBE; +F958;83F1;83F1;83F1;83F1; +F959;9675;9675;9675;9675; +F95A;8B80;8B80;8B80;8B80; +F95B;62CF;62CF;62CF;62CF; +F95C;6A02;6A02;6A02;6A02; +F95D;8AFE;8AFE;8AFE;8AFE; +F95E;4E39;4E39;4E39;4E39; +F95F;5BE7;5BE7;5BE7;5BE7; +F960;6012;6012;6012;6012; +F961;7387;7387;7387;7387; +F962;7570;7570;7570;7570; +F963;5317;5317;5317;5317; +F964;78FB;78FB;78FB;78FB; +F965;4FBF;4FBF;4FBF;4FBF; +F966;5FA9;5FA9;5FA9;5FA9; +F967;4E0D;4E0D;4E0D;4E0D; +F968;6CCC;6CCC;6CCC;6CCC; +F969;6578;6578;6578;6578; +F96A;7D22;7D22;7D22;7D22; +F96B;53C3;53C3;53C3;53C3; +F96C;585E;585E;585E;585E; +F96D;7701;7701;7701;7701; +F96E;8449;8449;8449;8449; +F96F;8AAA;8AAA;8AAA;8AAA; +F970;6BBA;6BBA;6BBA;6BBA; +F971;8FB0;8FB0;8FB0;8FB0; +F972;6C88;6C88;6C88;6C88; +F973;62FE;62FE;62FE;62FE; +F974;82E5;82E5;82E5;82E5; +F975;63A0;63A0;63A0;63A0; +F976;7565;7565;7565;7565; +F977;4EAE;4EAE;4EAE;4EAE; +F978;5169;5169;5169;5169; +F979;51C9;51C9;51C9;51C9; +F97A;6881;6881;6881;6881; +F97B;7CE7;7CE7;7CE7;7CE7; +F97C;826F;826F;826F;826F; +F97D;8AD2;8AD2;8AD2;8AD2; +F97E;91CF;91CF;91CF;91CF; +F97F;52F5;52F5;52F5;52F5; +F980;5442;5442;5442;5442; +F981;5973;5973;5973;5973; +F982;5EEC;5EEC;5EEC;5EEC; +F983;65C5;65C5;65C5;65C5; +F984;6FFE;6FFE;6FFE;6FFE; +F985;792A;792A;792A;792A; +F986;95AD;95AD;95AD;95AD; +F987;9A6A;9A6A;9A6A;9A6A; +F988;9E97;9E97;9E97;9E97; +F989;9ECE;9ECE;9ECE;9ECE; +F98A;529B;529B;529B;529B; +F98B;66C6;66C6;66C6;66C6; +F98C;6B77;6B77;6B77;6B77; +F98D;8F62;8F62;8F62;8F62; +F98E;5E74;5E74;5E74;5E74; +F98F;6190;6190;6190;6190; +F990;6200;6200;6200;6200; +F991;649A;649A;649A;649A; +F992;6F23;6F23;6F23;6F23; +F993;7149;7149;7149;7149; +F994;7489;7489;7489;7489; +F995;79CA;79CA;79CA;79CA; +F996;7DF4;7DF4;7DF4;7DF4; +F997;806F;806F;806F;806F; +F998;8F26;8F26;8F26;8F26; +F999;84EE;84EE;84EE;84EE; +F99A;9023;9023;9023;9023; +F99B;934A;934A;934A;934A; +F99C;5217;5217;5217;5217; +F99D;52A3;52A3;52A3;52A3; +F99E;54BD;54BD;54BD;54BD; +F99F;70C8;70C8;70C8;70C8; +F9A0;88C2;88C2;88C2;88C2; +F9A1;8AAA;8AAA;8AAA;8AAA; +F9A2;5EC9;5EC9;5EC9;5EC9; +F9A3;5FF5;5FF5;5FF5;5FF5; +F9A4;637B;637B;637B;637B; +F9A5;6BAE;6BAE;6BAE;6BAE; +F9A6;7C3E;7C3E;7C3E;7C3E; +F9A7;7375;7375;7375;7375; +F9A8;4EE4;4EE4;4EE4;4EE4; +F9A9;56F9;56F9;56F9;56F9; +F9AA;5BE7;5BE7;5BE7;5BE7; +F9AB;5DBA;5DBA;5DBA;5DBA; +F9AC;601C;601C;601C;601C; +F9AD;73B2;73B2;73B2;73B2; +F9AE;7469;7469;7469;7469; +F9AF;7F9A;7F9A;7F9A;7F9A; +F9B0;8046;8046;8046;8046; +F9B1;9234;9234;9234;9234; +F9B2;96F6;96F6;96F6;96F6; +F9B3;9748;9748;9748;9748; +F9B4;9818;9818;9818;9818; +F9B5;4F8B;4F8B;4F8B;4F8B; +F9B6;79AE;79AE;79AE;79AE; +F9B7;91B4;91B4;91B4;91B4; +F9B8;96B8;96B8;96B8;96B8; +F9B9;60E1;60E1;60E1;60E1; +F9BA;4E86;4E86;4E86;4E86; +F9BB;50DA;50DA;50DA;50DA; +F9BC;5BEE;5BEE;5BEE;5BEE; +F9BD;5C3F;5C3F;5C3F;5C3F; +F9BE;6599;6599;6599;6599; +F9BF;6A02;6A02;6A02;6A02; +F9C0;71CE;71CE;71CE;71CE; +F9C1;7642;7642;7642;7642; +F9C2;84FC;84FC;84FC;84FC; +F9C3;907C;907C;907C;907C; +F9C4;9F8D;9F8D;9F8D;9F8D; +F9C5;6688;6688;6688;6688; +F9C6;962E;962E;962E;962E; +F9C7;5289;5289;5289;5289; +F9C8;677B;677B;677B;677B; +F9C9;67F3;67F3;67F3;67F3; +F9CA;6D41;6D41;6D41;6D41; +F9CB;6E9C;6E9C;6E9C;6E9C; +F9CC;7409;7409;7409;7409; +F9CD;7559;7559;7559;7559; +F9CE;786B;786B;786B;786B; +F9CF;7D10;7D10;7D10;7D10; +F9D0;985E;985E;985E;985E; +F9D1;516D;516D;516D;516D; +F9D2;622E;622E;622E;622E; +F9D3;9678;9678;9678;9678; +F9D4;502B;502B;502B;502B; +F9D5;5D19;5D19;5D19;5D19; +F9D6;6DEA;6DEA;6DEA;6DEA; +F9D7;8F2A;8F2A;8F2A;8F2A; +F9D8;5F8B;5F8B;5F8B;5F8B; +F9D9;6144;6144;6144;6144; +F9DA;6817;6817;6817;6817; +F9DB;7387;7387;7387;7387; +F9DC;9686;9686;9686;9686; +F9DD;5229;5229;5229;5229; +F9DE;540F;540F;540F;540F; +F9DF;5C65;5C65;5C65;5C65; +F9E0;6613;6613;6613;6613; +F9E1;674E;674E;674E;674E; +F9E2;68A8;68A8;68A8;68A8; +F9E3;6CE5;6CE5;6CE5;6CE5; +F9E4;7406;7406;7406;7406; +F9E5;75E2;75E2;75E2;75E2; +F9E6;7F79;7F79;7F79;7F79; +F9E7;88CF;88CF;88CF;88CF; +F9E8;88E1;88E1;88E1;88E1; +F9E9;91CC;91CC;91CC;91CC; +F9EA;96E2;96E2;96E2;96E2; +F9EB;533F;533F;533F;533F; +F9EC;6EBA;6EBA;6EBA;6EBA; +F9ED;541D;541D;541D;541D; +F9EE;71D0;71D0;71D0;71D0; +F9EF;7498;7498;7498;7498; +F9F0;85FA;85FA;85FA;85FA; +F9F1;96A3;96A3;96A3;96A3; +F9F2;9C57;9C57;9C57;9C57; +F9F3;9E9F;9E9F;9E9F;9E9F; +F9F4;6797;6797;6797;6797; +F9F5;6DCB;6DCB;6DCB;6DCB; +F9F6;81E8;81E8;81E8;81E8; +F9F7;7ACB;7ACB;7ACB;7ACB; +F9F8;7B20;7B20;7B20;7B20; +F9F9;7C92;7C92;7C92;7C92; +F9FA;72C0;72C0;72C0;72C0; +F9FB;7099;7099;7099;7099; +F9FC;8B58;8B58;8B58;8B58; +F9FD;4EC0;4EC0;4EC0;4EC0; +F9FE;8336;8336;8336;8336; +F9FF;523A;523A;523A;523A; +FA00;5207;5207;5207;5207; +FA01;5EA6;5EA6;5EA6;5EA6; +FA02;62D3;62D3;62D3;62D3; +FA03;7CD6;7CD6;7CD6;7CD6; +FA04;5B85;5B85;5B85;5B85; +FA05;6D1E;6D1E;6D1E;6D1E; +FA06;66B4;66B4;66B4;66B4; +FA07;8F3B;8F3B;8F3B;8F3B; +FA08;884C;884C;884C;884C; +FA09;964D;964D;964D;964D; +FA0A;898B;898B;898B;898B; +FA0B;5ED3;5ED3;5ED3;5ED3; +FA0C;5140;5140;5140;5140; +FA0D;55C0;55C0;55C0;55C0; +FA10;585A;585A;585A;585A; +FA12;6674;6674;6674;6674; +FA15;51DE;51DE;51DE;51DE; +FA16;732A;732A;732A;732A; +FA17;76CA;76CA;76CA;76CA; +FA18;793C;793C;793C;793C; +FA19;795E;795E;795E;795E; +FA1A;7965;7965;7965;7965; +FA1B;798F;798F;798F;798F; +FA1C;9756;9756;9756;9756; +FA1D;7CBE;7CBE;7CBE;7CBE; +FA1E;7FBD;7FBD;7FBD;7FBD; +FA20;8612;8612;8612;8612; +FA22;8AF8;8AF8;8AF8;8AF8; +FA25;9038;9038;9038;9038; +FA26;90FD;90FD;90FD;90FD; +FA2A;98EF;98EF;98EF;98EF; +FA2B;98FC;98FC;98FC;98FC; +FA2C;9928;9928;9928;9928; +FA2D;9DB4;9DB4;9DB4;9DB4; +FA2E;90DE;90DE;90DE;90DE; +FA2F;96B7;96B7;96B7;96B7; +FA30;4FAE;4FAE;4FAE;4FAE; +FA31;50E7;50E7;50E7;50E7; +FA32;514D;514D;514D;514D; +FA33;52C9;52C9;52C9;52C9; +FA34;52E4;52E4;52E4;52E4; +FA35;5351;5351;5351;5351; +FA36;559D;559D;559D;559D; +FA37;5606;5606;5606;5606; +FA38;5668;5668;5668;5668; +FA39;5840;5840;5840;5840; +FA3A;58A8;58A8;58A8;58A8; +FA3B;5C64;5C64;5C64;5C64; +FA3C;5C6E;5C6E;5C6E;5C6E; +FA3D;6094;6094;6094;6094; +FA3E;6168;6168;6168;6168; +FA3F;618E;618E;618E;618E; +FA40;61F2;61F2;61F2;61F2; +FA41;654F;654F;654F;654F; +FA42;65E2;65E2;65E2;65E2; +FA43;6691;6691;6691;6691; +FA44;6885;6885;6885;6885; +FA45;6D77;6D77;6D77;6D77; +FA46;6E1A;6E1A;6E1A;6E1A; +FA47;6F22;6F22;6F22;6F22; +FA48;716E;716E;716E;716E; +FA49;722B;722B;722B;722B; +FA4A;7422;7422;7422;7422; +FA4B;7891;7891;7891;7891; +FA4C;793E;793E;793E;793E; +FA4D;7949;7949;7949;7949; +FA4E;7948;7948;7948;7948; +FA4F;7950;7950;7950;7950; +FA50;7956;7956;7956;7956; +FA51;795D;795D;795D;795D; +FA52;798D;798D;798D;798D; +FA53;798E;798E;798E;798E; +FA54;7A40;7A40;7A40;7A40; +FA55;7A81;7A81;7A81;7A81; +FA56;7BC0;7BC0;7BC0;7BC0; +FA57;7DF4;7DF4;7DF4;7DF4; +FA58;7E09;7E09;7E09;7E09; +FA59;7E41;7E41;7E41;7E41; +FA5A;7F72;7F72;7F72;7F72; +FA5B;8005;8005;8005;8005; +FA5C;81ED;81ED;81ED;81ED; +FA5D;8279;8279;8279;8279; +FA5E;8279;8279;8279;8279; +FA5F;8457;8457;8457;8457; +FA60;8910;8910;8910;8910; +FA61;8996;8996;8996;8996; +FA62;8B01;8B01;8B01;8B01; +FA63;8B39;8B39;8B39;8B39; +FA64;8CD3;8CD3;8CD3;8CD3; +FA65;8D08;8D08;8D08;8D08; +FA66;8FB6;8FB6;8FB6;8FB6; +FA67;9038;9038;9038;9038; +FA68;96E3;96E3;96E3;96E3; +FA69;97FF;97FF;97FF;97FF; +FA6A;983B;983B;983B;983B; +FA6B;6075;6075;6075;6075; +FA6C;242EE;242EE;242EE;242EE; +FA6D;8218;8218;8218;8218; +FA70;4E26;4E26;4E26;4E26; +FA71;51B5;51B5;51B5;51B5; +FA72;5168;5168;5168;5168; +FA73;4F80;4F80;4F80;4F80; +FA74;5145;5145;5145;5145; +FA75;5180;5180;5180;5180; +FA76;52C7;52C7;52C7;52C7; +FA77;52FA;52FA;52FA;52FA; +FA78;559D;559D;559D;559D; +FA79;5555;5555;5555;5555; +FA7A;5599;5599;5599;5599; +FA7B;55E2;55E2;55E2;55E2; +FA7C;585A;585A;585A;585A; +FA7D;58B3;58B3;58B3;58B3; +FA7E;5944;5944;5944;5944; +FA7F;5954;5954;5954;5954; +FA80;5A62;5A62;5A62;5A62; +FA81;5B28;5B28;5B28;5B28; +FA82;5ED2;5ED2;5ED2;5ED2; +FA83;5ED9;5ED9;5ED9;5ED9; +FA84;5F69;5F69;5F69;5F69; +FA85;5FAD;5FAD;5FAD;5FAD; +FA86;60D8;60D8;60D8;60D8; +FA87;614E;614E;614E;614E; +FA88;6108;6108;6108;6108; +FA89;618E;618E;618E;618E; +FA8A;6160;6160;6160;6160; +FA8B;61F2;61F2;61F2;61F2; +FA8C;6234;6234;6234;6234; +FA8D;63C4;63C4;63C4;63C4; +FA8E;641C;641C;641C;641C; +FA8F;6452;6452;6452;6452; +FA90;6556;6556;6556;6556; +FA91;6674;6674;6674;6674; +FA92;6717;6717;6717;6717; +FA93;671B;671B;671B;671B; +FA94;6756;6756;6756;6756; +FA95;6B79;6B79;6B79;6B79; +FA96;6BBA;6BBA;6BBA;6BBA; +FA97;6D41;6D41;6D41;6D41; +FA98;6EDB;6EDB;6EDB;6EDB; +FA99;6ECB;6ECB;6ECB;6ECB; +FA9A;6F22;6F22;6F22;6F22; +FA9B;701E;701E;701E;701E; +FA9C;716E;716E;716E;716E; +FA9D;77A7;77A7;77A7;77A7; +FA9E;7235;7235;7235;7235; +FA9F;72AF;72AF;72AF;72AF; +FAA0;732A;732A;732A;732A; +FAA1;7471;7471;7471;7471; +FAA2;7506;7506;7506;7506; +FAA3;753B;753B;753B;753B; +FAA4;761D;761D;761D;761D; +FAA5;761F;761F;761F;761F; +FAA6;76CA;76CA;76CA;76CA; +FAA7;76DB;76DB;76DB;76DB; +FAA8;76F4;76F4;76F4;76F4; +FAA9;774A;774A;774A;774A; +FAAA;7740;7740;7740;7740; +FAAB;78CC;78CC;78CC;78CC; +FAAC;7AB1;7AB1;7AB1;7AB1; +FAAD;7BC0;7BC0;7BC0;7BC0; +FAAE;7C7B;7C7B;7C7B;7C7B; +FAAF;7D5B;7D5B;7D5B;7D5B; +FAB0;7DF4;7DF4;7DF4;7DF4; +FAB1;7F3E;7F3E;7F3E;7F3E; +FAB2;8005;8005;8005;8005; +FAB3;8352;8352;8352;8352; +FAB4;83EF;83EF;83EF;83EF; +FAB5;8779;8779;8779;8779; +FAB6;8941;8941;8941;8941; +FAB7;8986;8986;8986;8986; +FAB8;8996;8996;8996;8996; +FAB9;8ABF;8ABF;8ABF;8ABF; +FABA;8AF8;8AF8;8AF8;8AF8; +FABB;8ACB;8ACB;8ACB;8ACB; +FABC;8B01;8B01;8B01;8B01; +FABD;8AFE;8AFE;8AFE;8AFE; +FABE;8AED;8AED;8AED;8AED; +FABF;8B39;8B39;8B39;8B39; +FAC0;8B8A;8B8A;8B8A;8B8A; +FAC1;8D08;8D08;8D08;8D08; +FAC2;8F38;8F38;8F38;8F38; +FAC3;9072;9072;9072;9072; +FAC4;9199;9199;9199;9199; +FAC5;9276;9276;9276;9276; +FAC6;967C;967C;967C;967C; +FAC7;96E3;96E3;96E3;96E3; +FAC8;9756;9756;9756;9756; +FAC9;97DB;97DB;97DB;97DB; +FACA;97FF;97FF;97FF;97FF; +FACB;980B;980B;980B;980B; +FACC;983B;983B;983B;983B; +FACD;9B12;9B12;9B12;9B12; +FACE;9F9C;9F9C;9F9C;9F9C; +FACF;2284A;2284A;2284A;2284A; +FAD0;22844;22844;22844;22844; +FAD1;233D5;233D5;233D5;233D5; +FAD2;3B9D;3B9D;3B9D;3B9D; +FAD3;4018;4018;4018;4018; +FAD4;4039;4039;4039;4039; +FAD5;25249;25249;25249;25249; +FAD6;25CD0;25CD0;25CD0;25CD0; +FAD7;27ED3;27ED3;27ED3;27ED3; +FAD8;9F43;9F43;9F43;9F43; +FAD9;9F8E;9F8E;9F8E;9F8E; +FB00;FB00;FB00;0066 0066;0066 0066; +FB01;FB01;FB01;0066 0069;0066 0069; +FB02;FB02;FB02;0066 006C;0066 006C; +FB03;FB03;FB03;0066 0066 0069;0066 0066 0069; +FB04;FB04;FB04;0066 0066 006C;0066 0066 006C; +FB05;FB05;FB05;0073 0074;0073 0074; +FB06;FB06;FB06;0073 0074;0073 0074; +FB13;FB13;FB13;0574 0576;0574 0576; +FB14;FB14;FB14;0574 0565;0574 0565; +FB15;FB15;FB15;0574 056B;0574 056B; +FB16;FB16;FB16;057E 0576;057E 0576; +FB17;FB17;FB17;0574 056D;0574 056D; +FB1D;05D9 05B4;05D9 05B4;05D9 05B4;05D9 05B4; +FB1F;05F2 05B7;05F2 05B7;05F2 05B7;05F2 05B7; +FB20;FB20;FB20;05E2;05E2; +FB21;FB21;FB21;05D0;05D0; +FB22;FB22;FB22;05D3;05D3; +FB23;FB23;FB23;05D4;05D4; +FB24;FB24;FB24;05DB;05DB; +FB25;FB25;FB25;05DC;05DC; +FB26;FB26;FB26;05DD;05DD; +FB27;FB27;FB27;05E8;05E8; +FB28;FB28;FB28;05EA;05EA; +FB29;FB29;FB29;002B;002B; +FB2A;05E9 05C1;05E9 05C1;05E9 05C1;05E9 05C1; +FB2B;05E9 05C2;05E9 05C2;05E9 05C2;05E9 05C2; +FB2C;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1; +FB2D;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2; +FB2E;05D0 05B7;05D0 05B7;05D0 05B7;05D0 05B7; +FB2F;05D0 05B8;05D0 05B8;05D0 05B8;05D0 05B8; +FB30;05D0 05BC;05D0 05BC;05D0 05BC;05D0 05BC; +FB31;05D1 05BC;05D1 05BC;05D1 05BC;05D1 05BC; +FB32;05D2 05BC;05D2 05BC;05D2 05BC;05D2 05BC; +FB33;05D3 05BC;05D3 05BC;05D3 05BC;05D3 05BC; +FB34;05D4 05BC;05D4 05BC;05D4 05BC;05D4 05BC; +FB35;05D5 05BC;05D5 05BC;05D5 05BC;05D5 05BC; +FB36;05D6 05BC;05D6 05BC;05D6 05BC;05D6 05BC; +FB38;05D8 05BC;05D8 05BC;05D8 05BC;05D8 05BC; +FB39;05D9 05BC;05D9 05BC;05D9 05BC;05D9 05BC; +FB3A;05DA 05BC;05DA 05BC;05DA 05BC;05DA 05BC; +FB3B;05DB 05BC;05DB 05BC;05DB 05BC;05DB 05BC; +FB3C;05DC 05BC;05DC 05BC;05DC 05BC;05DC 05BC; +FB3E;05DE 05BC;05DE 05BC;05DE 05BC;05DE 05BC; +FB40;05E0 05BC;05E0 05BC;05E0 05BC;05E0 05BC; +FB41;05E1 05BC;05E1 05BC;05E1 05BC;05E1 05BC; +FB43;05E3 05BC;05E3 05BC;05E3 05BC;05E3 05BC; +FB44;05E4 05BC;05E4 05BC;05E4 05BC;05E4 05BC; +FB46;05E6 05BC;05E6 05BC;05E6 05BC;05E6 05BC; +FB47;05E7 05BC;05E7 05BC;05E7 05BC;05E7 05BC; +FB48;05E8 05BC;05E8 05BC;05E8 05BC;05E8 05BC; +FB49;05E9 05BC;05E9 05BC;05E9 05BC;05E9 05BC; +FB4A;05EA 05BC;05EA 05BC;05EA 05BC;05EA 05BC; +FB4B;05D5 05B9;05D5 05B9;05D5 05B9;05D5 05B9; +FB4C;05D1 05BF;05D1 05BF;05D1 05BF;05D1 05BF; +FB4D;05DB 05BF;05DB 05BF;05DB 05BF;05DB 05BF; +FB4E;05E4 05BF;05E4 05BF;05E4 05BF;05E4 05BF; +FB4F;FB4F;FB4F;05D0 05DC;05D0 05DC; +FB50;FB50;FB50;0671;0671; +FB51;FB51;FB51;0671;0671; +FB52;FB52;FB52;067B;067B; +FB53;FB53;FB53;067B;067B; +FB54;FB54;FB54;067B;067B; +FB55;FB55;FB55;067B;067B; +FB56;FB56;FB56;067E;067E; +FB57;FB57;FB57;067E;067E; +FB58;FB58;FB58;067E;067E; +FB59;FB59;FB59;067E;067E; +FB5A;FB5A;FB5A;0680;0680; +FB5B;FB5B;FB5B;0680;0680; +FB5C;FB5C;FB5C;0680;0680; +FB5D;FB5D;FB5D;0680;0680; +FB5E;FB5E;FB5E;067A;067A; +FB5F;FB5F;FB5F;067A;067A; +FB60;FB60;FB60;067A;067A; +FB61;FB61;FB61;067A;067A; +FB62;FB62;FB62;067F;067F; +FB63;FB63;FB63;067F;067F; +FB64;FB64;FB64;067F;067F; +FB65;FB65;FB65;067F;067F; +FB66;FB66;FB66;0679;0679; +FB67;FB67;FB67;0679;0679; +FB68;FB68;FB68;0679;0679; +FB69;FB69;FB69;0679;0679; +FB6A;FB6A;FB6A;06A4;06A4; +FB6B;FB6B;FB6B;06A4;06A4; +FB6C;FB6C;FB6C;06A4;06A4; +FB6D;FB6D;FB6D;06A4;06A4; +FB6E;FB6E;FB6E;06A6;06A6; +FB6F;FB6F;FB6F;06A6;06A6; +FB70;FB70;FB70;06A6;06A6; +FB71;FB71;FB71;06A6;06A6; +FB72;FB72;FB72;0684;0684; +FB73;FB73;FB73;0684;0684; +FB74;FB74;FB74;0684;0684; +FB75;FB75;FB75;0684;0684; +FB76;FB76;FB76;0683;0683; +FB77;FB77;FB77;0683;0683; +FB78;FB78;FB78;0683;0683; +FB79;FB79;FB79;0683;0683; +FB7A;FB7A;FB7A;0686;0686; +FB7B;FB7B;FB7B;0686;0686; +FB7C;FB7C;FB7C;0686;0686; +FB7D;FB7D;FB7D;0686;0686; +FB7E;FB7E;FB7E;0687;0687; +FB7F;FB7F;FB7F;0687;0687; +FB80;FB80;FB80;0687;0687; +FB81;FB81;FB81;0687;0687; +FB82;FB82;FB82;068D;068D; +FB83;FB83;FB83;068D;068D; +FB84;FB84;FB84;068C;068C; +FB85;FB85;FB85;068C;068C; +FB86;FB86;FB86;068E;068E; +FB87;FB87;FB87;068E;068E; +FB88;FB88;FB88;0688;0688; +FB89;FB89;FB89;0688;0688; +FB8A;FB8A;FB8A;0698;0698; +FB8B;FB8B;FB8B;0698;0698; +FB8C;FB8C;FB8C;0691;0691; +FB8D;FB8D;FB8D;0691;0691; +FB8E;FB8E;FB8E;06A9;06A9; +FB8F;FB8F;FB8F;06A9;06A9; +FB90;FB90;FB90;06A9;06A9; +FB91;FB91;FB91;06A9;06A9; +FB92;FB92;FB92;06AF;06AF; +FB93;FB93;FB93;06AF;06AF; +FB94;FB94;FB94;06AF;06AF; +FB95;FB95;FB95;06AF;06AF; +FB96;FB96;FB96;06B3;06B3; +FB97;FB97;FB97;06B3;06B3; +FB98;FB98;FB98;06B3;06B3; +FB99;FB99;FB99;06B3;06B3; +FB9A;FB9A;FB9A;06B1;06B1; +FB9B;FB9B;FB9B;06B1;06B1; +FB9C;FB9C;FB9C;06B1;06B1; +FB9D;FB9D;FB9D;06B1;06B1; +FB9E;FB9E;FB9E;06BA;06BA; +FB9F;FB9F;FB9F;06BA;06BA; +FBA0;FBA0;FBA0;06BB;06BB; +FBA1;FBA1;FBA1;06BB;06BB; +FBA2;FBA2;FBA2;06BB;06BB; +FBA3;FBA3;FBA3;06BB;06BB; +FBA4;FBA4;FBA4;06C0;06D5 0654; +FBA5;FBA5;FBA5;06C0;06D5 0654; +FBA6;FBA6;FBA6;06C1;06C1; +FBA7;FBA7;FBA7;06C1;06C1; +FBA8;FBA8;FBA8;06C1;06C1; +FBA9;FBA9;FBA9;06C1;06C1; +FBAA;FBAA;FBAA;06BE;06BE; +FBAB;FBAB;FBAB;06BE;06BE; +FBAC;FBAC;FBAC;06BE;06BE; +FBAD;FBAD;FBAD;06BE;06BE; +FBAE;FBAE;FBAE;06D2;06D2; +FBAF;FBAF;FBAF;06D2;06D2; +FBB0;FBB0;FBB0;06D3;06D2 0654; +FBB1;FBB1;FBB1;06D3;06D2 0654; +FBD3;FBD3;FBD3;06AD;06AD; +FBD4;FBD4;FBD4;06AD;06AD; +FBD5;FBD5;FBD5;06AD;06AD; +FBD6;FBD6;FBD6;06AD;06AD; +FBD7;FBD7;FBD7;06C7;06C7; +FBD8;FBD8;FBD8;06C7;06C7; +FBD9;FBD9;FBD9;06C6;06C6; +FBDA;FBDA;FBDA;06C6;06C6; +FBDB;FBDB;FBDB;06C8;06C8; +FBDC;FBDC;FBDC;06C8;06C8; +FBDD;FBDD;FBDD;06C7 0674;06C7 0674; +FBDE;FBDE;FBDE;06CB;06CB; +FBDF;FBDF;FBDF;06CB;06CB; +FBE0;FBE0;FBE0;06C5;06C5; +FBE1;FBE1;FBE1;06C5;06C5; +FBE2;FBE2;FBE2;06C9;06C9; +FBE3;FBE3;FBE3;06C9;06C9; +FBE4;FBE4;FBE4;06D0;06D0; +FBE5;FBE5;FBE5;06D0;06D0; +FBE6;FBE6;FBE6;06D0;06D0; +FBE7;FBE7;FBE7;06D0;06D0; +FBE8;FBE8;FBE8;0649;0649; +FBE9;FBE9;FBE9;0649;0649; +FBEA;FBEA;FBEA;0626 0627;064A 0654 0627; +FBEB;FBEB;FBEB;0626 0627;064A 0654 0627; +FBEC;FBEC;FBEC;0626 06D5;064A 0654 06D5; +FBED;FBED;FBED;0626 06D5;064A 0654 06D5; +FBEE;FBEE;FBEE;0626 0648;064A 0654 0648; +FBEF;FBEF;FBEF;0626 0648;064A 0654 0648; +FBF0;FBF0;FBF0;0626 06C7;064A 0654 06C7; +FBF1;FBF1;FBF1;0626 06C7;064A 0654 06C7; +FBF2;FBF2;FBF2;0626 06C6;064A 0654 06C6; +FBF3;FBF3;FBF3;0626 06C6;064A 0654 06C6; +FBF4;FBF4;FBF4;0626 06C8;064A 0654 06C8; +FBF5;FBF5;FBF5;0626 06C8;064A 0654 06C8; +FBF6;FBF6;FBF6;0626 06D0;064A 0654 06D0; +FBF7;FBF7;FBF7;0626 06D0;064A 0654 06D0; +FBF8;FBF8;FBF8;0626 06D0;064A 0654 06D0; +FBF9;FBF9;FBF9;0626 0649;064A 0654 0649; +FBFA;FBFA;FBFA;0626 0649;064A 0654 0649; +FBFB;FBFB;FBFB;0626 0649;064A 0654 0649; +FBFC;FBFC;FBFC;06CC;06CC; +FBFD;FBFD;FBFD;06CC;06CC; +FBFE;FBFE;FBFE;06CC;06CC; +FBFF;FBFF;FBFF;06CC;06CC; +FC00;FC00;FC00;0626 062C;064A 0654 062C; +FC01;FC01;FC01;0626 062D;064A 0654 062D; +FC02;FC02;FC02;0626 0645;064A 0654 0645; +FC03;FC03;FC03;0626 0649;064A 0654 0649; +FC04;FC04;FC04;0626 064A;064A 0654 064A; +FC05;FC05;FC05;0628 062C;0628 062C; +FC06;FC06;FC06;0628 062D;0628 062D; +FC07;FC07;FC07;0628 062E;0628 062E; +FC08;FC08;FC08;0628 0645;0628 0645; +FC09;FC09;FC09;0628 0649;0628 0649; +FC0A;FC0A;FC0A;0628 064A;0628 064A; +FC0B;FC0B;FC0B;062A 062C;062A 062C; +FC0C;FC0C;FC0C;062A 062D;062A 062D; +FC0D;FC0D;FC0D;062A 062E;062A 062E; +FC0E;FC0E;FC0E;062A 0645;062A 0645; +FC0F;FC0F;FC0F;062A 0649;062A 0649; +FC10;FC10;FC10;062A 064A;062A 064A; +FC11;FC11;FC11;062B 062C;062B 062C; +FC12;FC12;FC12;062B 0645;062B 0645; +FC13;FC13;FC13;062B 0649;062B 0649; +FC14;FC14;FC14;062B 064A;062B 064A; +FC15;FC15;FC15;062C 062D;062C 062D; +FC16;FC16;FC16;062C 0645;062C 0645; +FC17;FC17;FC17;062D 062C;062D 062C; +FC18;FC18;FC18;062D 0645;062D 0645; +FC19;FC19;FC19;062E 062C;062E 062C; +FC1A;FC1A;FC1A;062E 062D;062E 062D; +FC1B;FC1B;FC1B;062E 0645;062E 0645; +FC1C;FC1C;FC1C;0633 062C;0633 062C; +FC1D;FC1D;FC1D;0633 062D;0633 062D; +FC1E;FC1E;FC1E;0633 062E;0633 062E; +FC1F;FC1F;FC1F;0633 0645;0633 0645; +FC20;FC20;FC20;0635 062D;0635 062D; +FC21;FC21;FC21;0635 0645;0635 0645; +FC22;FC22;FC22;0636 062C;0636 062C; +FC23;FC23;FC23;0636 062D;0636 062D; +FC24;FC24;FC24;0636 062E;0636 062E; +FC25;FC25;FC25;0636 0645;0636 0645; +FC26;FC26;FC26;0637 062D;0637 062D; +FC27;FC27;FC27;0637 0645;0637 0645; +FC28;FC28;FC28;0638 0645;0638 0645; +FC29;FC29;FC29;0639 062C;0639 062C; +FC2A;FC2A;FC2A;0639 0645;0639 0645; +FC2B;FC2B;FC2B;063A 062C;063A 062C; +FC2C;FC2C;FC2C;063A 0645;063A 0645; +FC2D;FC2D;FC2D;0641 062C;0641 062C; +FC2E;FC2E;FC2E;0641 062D;0641 062D; +FC2F;FC2F;FC2F;0641 062E;0641 062E; +FC30;FC30;FC30;0641 0645;0641 0645; +FC31;FC31;FC31;0641 0649;0641 0649; +FC32;FC32;FC32;0641 064A;0641 064A; +FC33;FC33;FC33;0642 062D;0642 062D; +FC34;FC34;FC34;0642 0645;0642 0645; +FC35;FC35;FC35;0642 0649;0642 0649; +FC36;FC36;FC36;0642 064A;0642 064A; +FC37;FC37;FC37;0643 0627;0643 0627; +FC38;FC38;FC38;0643 062C;0643 062C; +FC39;FC39;FC39;0643 062D;0643 062D; +FC3A;FC3A;FC3A;0643 062E;0643 062E; +FC3B;FC3B;FC3B;0643 0644;0643 0644; +FC3C;FC3C;FC3C;0643 0645;0643 0645; +FC3D;FC3D;FC3D;0643 0649;0643 0649; +FC3E;FC3E;FC3E;0643 064A;0643 064A; +FC3F;FC3F;FC3F;0644 062C;0644 062C; +FC40;FC40;FC40;0644 062D;0644 062D; +FC41;FC41;FC41;0644 062E;0644 062E; +FC42;FC42;FC42;0644 0645;0644 0645; +FC43;FC43;FC43;0644 0649;0644 0649; +FC44;FC44;FC44;0644 064A;0644 064A; +FC45;FC45;FC45;0645 062C;0645 062C; +FC46;FC46;FC46;0645 062D;0645 062D; +FC47;FC47;FC47;0645 062E;0645 062E; +FC48;FC48;FC48;0645 0645;0645 0645; +FC49;FC49;FC49;0645 0649;0645 0649; +FC4A;FC4A;FC4A;0645 064A;0645 064A; +FC4B;FC4B;FC4B;0646 062C;0646 062C; +FC4C;FC4C;FC4C;0646 062D;0646 062D; +FC4D;FC4D;FC4D;0646 062E;0646 062E; +FC4E;FC4E;FC4E;0646 0645;0646 0645; +FC4F;FC4F;FC4F;0646 0649;0646 0649; +FC50;FC50;FC50;0646 064A;0646 064A; +FC51;FC51;FC51;0647 062C;0647 062C; +FC52;FC52;FC52;0647 0645;0647 0645; +FC53;FC53;FC53;0647 0649;0647 0649; +FC54;FC54;FC54;0647 064A;0647 064A; +FC55;FC55;FC55;064A 062C;064A 062C; +FC56;FC56;FC56;064A 062D;064A 062D; +FC57;FC57;FC57;064A 062E;064A 062E; +FC58;FC58;FC58;064A 0645;064A 0645; +FC59;FC59;FC59;064A 0649;064A 0649; +FC5A;FC5A;FC5A;064A 064A;064A 064A; +FC5B;FC5B;FC5B;0630 0670;0630 0670; +FC5C;FC5C;FC5C;0631 0670;0631 0670; +FC5D;FC5D;FC5D;0649 0670;0649 0670; +FC5E;FC5E;FC5E;0020 064C 0651;0020 064C 0651; +FC5F;FC5F;FC5F;0020 064D 0651;0020 064D 0651; +FC60;FC60;FC60;0020 064E 0651;0020 064E 0651; +FC61;FC61;FC61;0020 064F 0651;0020 064F 0651; +FC62;FC62;FC62;0020 0650 0651;0020 0650 0651; +FC63;FC63;FC63;0020 0651 0670;0020 0651 0670; +FC64;FC64;FC64;0626 0631;064A 0654 0631; +FC65;FC65;FC65;0626 0632;064A 0654 0632; +FC66;FC66;FC66;0626 0645;064A 0654 0645; +FC67;FC67;FC67;0626 0646;064A 0654 0646; +FC68;FC68;FC68;0626 0649;064A 0654 0649; +FC69;FC69;FC69;0626 064A;064A 0654 064A; +FC6A;FC6A;FC6A;0628 0631;0628 0631; +FC6B;FC6B;FC6B;0628 0632;0628 0632; +FC6C;FC6C;FC6C;0628 0645;0628 0645; +FC6D;FC6D;FC6D;0628 0646;0628 0646; +FC6E;FC6E;FC6E;0628 0649;0628 0649; +FC6F;FC6F;FC6F;0628 064A;0628 064A; +FC70;FC70;FC70;062A 0631;062A 0631; +FC71;FC71;FC71;062A 0632;062A 0632; +FC72;FC72;FC72;062A 0645;062A 0645; +FC73;FC73;FC73;062A 0646;062A 0646; +FC74;FC74;FC74;062A 0649;062A 0649; +FC75;FC75;FC75;062A 064A;062A 064A; +FC76;FC76;FC76;062B 0631;062B 0631; +FC77;FC77;FC77;062B 0632;062B 0632; +FC78;FC78;FC78;062B 0645;062B 0645; +FC79;FC79;FC79;062B 0646;062B 0646; +FC7A;FC7A;FC7A;062B 0649;062B 0649; +FC7B;FC7B;FC7B;062B 064A;062B 064A; +FC7C;FC7C;FC7C;0641 0649;0641 0649; +FC7D;FC7D;FC7D;0641 064A;0641 064A; +FC7E;FC7E;FC7E;0642 0649;0642 0649; +FC7F;FC7F;FC7F;0642 064A;0642 064A; +FC80;FC80;FC80;0643 0627;0643 0627; +FC81;FC81;FC81;0643 0644;0643 0644; +FC82;FC82;FC82;0643 0645;0643 0645; +FC83;FC83;FC83;0643 0649;0643 0649; +FC84;FC84;FC84;0643 064A;0643 064A; +FC85;FC85;FC85;0644 0645;0644 0645; +FC86;FC86;FC86;0644 0649;0644 0649; +FC87;FC87;FC87;0644 064A;0644 064A; +FC88;FC88;FC88;0645 0627;0645 0627; +FC89;FC89;FC89;0645 0645;0645 0645; +FC8A;FC8A;FC8A;0646 0631;0646 0631; +FC8B;FC8B;FC8B;0646 0632;0646 0632; +FC8C;FC8C;FC8C;0646 0645;0646 0645; +FC8D;FC8D;FC8D;0646 0646;0646 0646; +FC8E;FC8E;FC8E;0646 0649;0646 0649; +FC8F;FC8F;FC8F;0646 064A;0646 064A; +FC90;FC90;FC90;0649 0670;0649 0670; +FC91;FC91;FC91;064A 0631;064A 0631; +FC92;FC92;FC92;064A 0632;064A 0632; +FC93;FC93;FC93;064A 0645;064A 0645; +FC94;FC94;FC94;064A 0646;064A 0646; +FC95;FC95;FC95;064A 0649;064A 0649; +FC96;FC96;FC96;064A 064A;064A 064A; +FC97;FC97;FC97;0626 062C;064A 0654 062C; +FC98;FC98;FC98;0626 062D;064A 0654 062D; +FC99;FC99;FC99;0626 062E;064A 0654 062E; +FC9A;FC9A;FC9A;0626 0645;064A 0654 0645; +FC9B;FC9B;FC9B;0626 0647;064A 0654 0647; +FC9C;FC9C;FC9C;0628 062C;0628 062C; +FC9D;FC9D;FC9D;0628 062D;0628 062D; +FC9E;FC9E;FC9E;0628 062E;0628 062E; +FC9F;FC9F;FC9F;0628 0645;0628 0645; +FCA0;FCA0;FCA0;0628 0647;0628 0647; +FCA1;FCA1;FCA1;062A 062C;062A 062C; +FCA2;FCA2;FCA2;062A 062D;062A 062D; +FCA3;FCA3;FCA3;062A 062E;062A 062E; +FCA4;FCA4;FCA4;062A 0645;062A 0645; +FCA5;FCA5;FCA5;062A 0647;062A 0647; +FCA6;FCA6;FCA6;062B 0645;062B 0645; +FCA7;FCA7;FCA7;062C 062D;062C 062D; +FCA8;FCA8;FCA8;062C 0645;062C 0645; +FCA9;FCA9;FCA9;062D 062C;062D 062C; +FCAA;FCAA;FCAA;062D 0645;062D 0645; +FCAB;FCAB;FCAB;062E 062C;062E 062C; +FCAC;FCAC;FCAC;062E 0645;062E 0645; +FCAD;FCAD;FCAD;0633 062C;0633 062C; +FCAE;FCAE;FCAE;0633 062D;0633 062D; +FCAF;FCAF;FCAF;0633 062E;0633 062E; +FCB0;FCB0;FCB0;0633 0645;0633 0645; +FCB1;FCB1;FCB1;0635 062D;0635 062D; +FCB2;FCB2;FCB2;0635 062E;0635 062E; +FCB3;FCB3;FCB3;0635 0645;0635 0645; +FCB4;FCB4;FCB4;0636 062C;0636 062C; +FCB5;FCB5;FCB5;0636 062D;0636 062D; +FCB6;FCB6;FCB6;0636 062E;0636 062E; +FCB7;FCB7;FCB7;0636 0645;0636 0645; +FCB8;FCB8;FCB8;0637 062D;0637 062D; +FCB9;FCB9;FCB9;0638 0645;0638 0645; +FCBA;FCBA;FCBA;0639 062C;0639 062C; +FCBB;FCBB;FCBB;0639 0645;0639 0645; +FCBC;FCBC;FCBC;063A 062C;063A 062C; +FCBD;FCBD;FCBD;063A 0645;063A 0645; +FCBE;FCBE;FCBE;0641 062C;0641 062C; +FCBF;FCBF;FCBF;0641 062D;0641 062D; +FCC0;FCC0;FCC0;0641 062E;0641 062E; +FCC1;FCC1;FCC1;0641 0645;0641 0645; +FCC2;FCC2;FCC2;0642 062D;0642 062D; +FCC3;FCC3;FCC3;0642 0645;0642 0645; +FCC4;FCC4;FCC4;0643 062C;0643 062C; +FCC5;FCC5;FCC5;0643 062D;0643 062D; +FCC6;FCC6;FCC6;0643 062E;0643 062E; +FCC7;FCC7;FCC7;0643 0644;0643 0644; +FCC8;FCC8;FCC8;0643 0645;0643 0645; +FCC9;FCC9;FCC9;0644 062C;0644 062C; +FCCA;FCCA;FCCA;0644 062D;0644 062D; +FCCB;FCCB;FCCB;0644 062E;0644 062E; +FCCC;FCCC;FCCC;0644 0645;0644 0645; +FCCD;FCCD;FCCD;0644 0647;0644 0647; +FCCE;FCCE;FCCE;0645 062C;0645 062C; +FCCF;FCCF;FCCF;0645 062D;0645 062D; +FCD0;FCD0;FCD0;0645 062E;0645 062E; +FCD1;FCD1;FCD1;0645 0645;0645 0645; +FCD2;FCD2;FCD2;0646 062C;0646 062C; +FCD3;FCD3;FCD3;0646 062D;0646 062D; +FCD4;FCD4;FCD4;0646 062E;0646 062E; +FCD5;FCD5;FCD5;0646 0645;0646 0645; +FCD6;FCD6;FCD6;0646 0647;0646 0647; +FCD7;FCD7;FCD7;0647 062C;0647 062C; +FCD8;FCD8;FCD8;0647 0645;0647 0645; +FCD9;FCD9;FCD9;0647 0670;0647 0670; +FCDA;FCDA;FCDA;064A 062C;064A 062C; +FCDB;FCDB;FCDB;064A 062D;064A 062D; +FCDC;FCDC;FCDC;064A 062E;064A 062E; +FCDD;FCDD;FCDD;064A 0645;064A 0645; +FCDE;FCDE;FCDE;064A 0647;064A 0647; +FCDF;FCDF;FCDF;0626 0645;064A 0654 0645; +FCE0;FCE0;FCE0;0626 0647;064A 0654 0647; +FCE1;FCE1;FCE1;0628 0645;0628 0645; +FCE2;FCE2;FCE2;0628 0647;0628 0647; +FCE3;FCE3;FCE3;062A 0645;062A 0645; +FCE4;FCE4;FCE4;062A 0647;062A 0647; +FCE5;FCE5;FCE5;062B 0645;062B 0645; +FCE6;FCE6;FCE6;062B 0647;062B 0647; +FCE7;FCE7;FCE7;0633 0645;0633 0645; +FCE8;FCE8;FCE8;0633 0647;0633 0647; +FCE9;FCE9;FCE9;0634 0645;0634 0645; +FCEA;FCEA;FCEA;0634 0647;0634 0647; +FCEB;FCEB;FCEB;0643 0644;0643 0644; +FCEC;FCEC;FCEC;0643 0645;0643 0645; +FCED;FCED;FCED;0644 0645;0644 0645; +FCEE;FCEE;FCEE;0646 0645;0646 0645; +FCEF;FCEF;FCEF;0646 0647;0646 0647; +FCF0;FCF0;FCF0;064A 0645;064A 0645; +FCF1;FCF1;FCF1;064A 0647;064A 0647; +FCF2;FCF2;FCF2;0640 064E 0651;0640 064E 0651; +FCF3;FCF3;FCF3;0640 064F 0651;0640 064F 0651; +FCF4;FCF4;FCF4;0640 0650 0651;0640 0650 0651; +FCF5;FCF5;FCF5;0637 0649;0637 0649; +FCF6;FCF6;FCF6;0637 064A;0637 064A; +FCF7;FCF7;FCF7;0639 0649;0639 0649; +FCF8;FCF8;FCF8;0639 064A;0639 064A; +FCF9;FCF9;FCF9;063A 0649;063A 0649; +FCFA;FCFA;FCFA;063A 064A;063A 064A; +FCFB;FCFB;FCFB;0633 0649;0633 0649; +FCFC;FCFC;FCFC;0633 064A;0633 064A; +FCFD;FCFD;FCFD;0634 0649;0634 0649; +FCFE;FCFE;FCFE;0634 064A;0634 064A; +FCFF;FCFF;FCFF;062D 0649;062D 0649; +FD00;FD00;FD00;062D 064A;062D 064A; +FD01;FD01;FD01;062C 0649;062C 0649; +FD02;FD02;FD02;062C 064A;062C 064A; +FD03;FD03;FD03;062E 0649;062E 0649; +FD04;FD04;FD04;062E 064A;062E 064A; +FD05;FD05;FD05;0635 0649;0635 0649; +FD06;FD06;FD06;0635 064A;0635 064A; +FD07;FD07;FD07;0636 0649;0636 0649; +FD08;FD08;FD08;0636 064A;0636 064A; +FD09;FD09;FD09;0634 062C;0634 062C; +FD0A;FD0A;FD0A;0634 062D;0634 062D; +FD0B;FD0B;FD0B;0634 062E;0634 062E; +FD0C;FD0C;FD0C;0634 0645;0634 0645; +FD0D;FD0D;FD0D;0634 0631;0634 0631; +FD0E;FD0E;FD0E;0633 0631;0633 0631; +FD0F;FD0F;FD0F;0635 0631;0635 0631; +FD10;FD10;FD10;0636 0631;0636 0631; +FD11;FD11;FD11;0637 0649;0637 0649; +FD12;FD12;FD12;0637 064A;0637 064A; +FD13;FD13;FD13;0639 0649;0639 0649; +FD14;FD14;FD14;0639 064A;0639 064A; +FD15;FD15;FD15;063A 0649;063A 0649; +FD16;FD16;FD16;063A 064A;063A 064A; +FD17;FD17;FD17;0633 0649;0633 0649; +FD18;FD18;FD18;0633 064A;0633 064A; +FD19;FD19;FD19;0634 0649;0634 0649; +FD1A;FD1A;FD1A;0634 064A;0634 064A; +FD1B;FD1B;FD1B;062D 0649;062D 0649; +FD1C;FD1C;FD1C;062D 064A;062D 064A; +FD1D;FD1D;FD1D;062C 0649;062C 0649; +FD1E;FD1E;FD1E;062C 064A;062C 064A; +FD1F;FD1F;FD1F;062E 0649;062E 0649; +FD20;FD20;FD20;062E 064A;062E 064A; +FD21;FD21;FD21;0635 0649;0635 0649; +FD22;FD22;FD22;0635 064A;0635 064A; +FD23;FD23;FD23;0636 0649;0636 0649; +FD24;FD24;FD24;0636 064A;0636 064A; +FD25;FD25;FD25;0634 062C;0634 062C; +FD26;FD26;FD26;0634 062D;0634 062D; +FD27;FD27;FD27;0634 062E;0634 062E; +FD28;FD28;FD28;0634 0645;0634 0645; +FD29;FD29;FD29;0634 0631;0634 0631; +FD2A;FD2A;FD2A;0633 0631;0633 0631; +FD2B;FD2B;FD2B;0635 0631;0635 0631; +FD2C;FD2C;FD2C;0636 0631;0636 0631; +FD2D;FD2D;FD2D;0634 062C;0634 062C; +FD2E;FD2E;FD2E;0634 062D;0634 062D; +FD2F;FD2F;FD2F;0634 062E;0634 062E; +FD30;FD30;FD30;0634 0645;0634 0645; +FD31;FD31;FD31;0633 0647;0633 0647; +FD32;FD32;FD32;0634 0647;0634 0647; +FD33;FD33;FD33;0637 0645;0637 0645; +FD34;FD34;FD34;0633 062C;0633 062C; +FD35;FD35;FD35;0633 062D;0633 062D; +FD36;FD36;FD36;0633 062E;0633 062E; +FD37;FD37;FD37;0634 062C;0634 062C; +FD38;FD38;FD38;0634 062D;0634 062D; +FD39;FD39;FD39;0634 062E;0634 062E; +FD3A;FD3A;FD3A;0637 0645;0637 0645; +FD3B;FD3B;FD3B;0638 0645;0638 0645; +FD3C;FD3C;FD3C;0627 064B;0627 064B; +FD3D;FD3D;FD3D;0627 064B;0627 064B; +FD50;FD50;FD50;062A 062C 0645;062A 062C 0645; +FD51;FD51;FD51;062A 062D 062C;062A 062D 062C; +FD52;FD52;FD52;062A 062D 062C;062A 062D 062C; +FD53;FD53;FD53;062A 062D 0645;062A 062D 0645; +FD54;FD54;FD54;062A 062E 0645;062A 062E 0645; +FD55;FD55;FD55;062A 0645 062C;062A 0645 062C; +FD56;FD56;FD56;062A 0645 062D;062A 0645 062D; +FD57;FD57;FD57;062A 0645 062E;062A 0645 062E; +FD58;FD58;FD58;062C 0645 062D;062C 0645 062D; +FD59;FD59;FD59;062C 0645 062D;062C 0645 062D; +FD5A;FD5A;FD5A;062D 0645 064A;062D 0645 064A; +FD5B;FD5B;FD5B;062D 0645 0649;062D 0645 0649; +FD5C;FD5C;FD5C;0633 062D 062C;0633 062D 062C; +FD5D;FD5D;FD5D;0633 062C 062D;0633 062C 062D; +FD5E;FD5E;FD5E;0633 062C 0649;0633 062C 0649; +FD5F;FD5F;FD5F;0633 0645 062D;0633 0645 062D; +FD60;FD60;FD60;0633 0645 062D;0633 0645 062D; +FD61;FD61;FD61;0633 0645 062C;0633 0645 062C; +FD62;FD62;FD62;0633 0645 0645;0633 0645 0645; +FD63;FD63;FD63;0633 0645 0645;0633 0645 0645; +FD64;FD64;FD64;0635 062D 062D;0635 062D 062D; +FD65;FD65;FD65;0635 062D 062D;0635 062D 062D; +FD66;FD66;FD66;0635 0645 0645;0635 0645 0645; +FD67;FD67;FD67;0634 062D 0645;0634 062D 0645; +FD68;FD68;FD68;0634 062D 0645;0634 062D 0645; +FD69;FD69;FD69;0634 062C 064A;0634 062C 064A; +FD6A;FD6A;FD6A;0634 0645 062E;0634 0645 062E; +FD6B;FD6B;FD6B;0634 0645 062E;0634 0645 062E; +FD6C;FD6C;FD6C;0634 0645 0645;0634 0645 0645; +FD6D;FD6D;FD6D;0634 0645 0645;0634 0645 0645; +FD6E;FD6E;FD6E;0636 062D 0649;0636 062D 0649; +FD6F;FD6F;FD6F;0636 062E 0645;0636 062E 0645; +FD70;FD70;FD70;0636 062E 0645;0636 062E 0645; +FD71;FD71;FD71;0637 0645 062D;0637 0645 062D; +FD72;FD72;FD72;0637 0645 062D;0637 0645 062D; +FD73;FD73;FD73;0637 0645 0645;0637 0645 0645; +FD74;FD74;FD74;0637 0645 064A;0637 0645 064A; +FD75;FD75;FD75;0639 062C 0645;0639 062C 0645; +FD76;FD76;FD76;0639 0645 0645;0639 0645 0645; +FD77;FD77;FD77;0639 0645 0645;0639 0645 0645; +FD78;FD78;FD78;0639 0645 0649;0639 0645 0649; +FD79;FD79;FD79;063A 0645 0645;063A 0645 0645; +FD7A;FD7A;FD7A;063A 0645 064A;063A 0645 064A; +FD7B;FD7B;FD7B;063A 0645 0649;063A 0645 0649; +FD7C;FD7C;FD7C;0641 062E 0645;0641 062E 0645; +FD7D;FD7D;FD7D;0641 062E 0645;0641 062E 0645; +FD7E;FD7E;FD7E;0642 0645 062D;0642 0645 062D; +FD7F;FD7F;FD7F;0642 0645 0645;0642 0645 0645; +FD80;FD80;FD80;0644 062D 0645;0644 062D 0645; +FD81;FD81;FD81;0644 062D 064A;0644 062D 064A; +FD82;FD82;FD82;0644 062D 0649;0644 062D 0649; +FD83;FD83;FD83;0644 062C 062C;0644 062C 062C; +FD84;FD84;FD84;0644 062C 062C;0644 062C 062C; +FD85;FD85;FD85;0644 062E 0645;0644 062E 0645; +FD86;FD86;FD86;0644 062E 0645;0644 062E 0645; +FD87;FD87;FD87;0644 0645 062D;0644 0645 062D; +FD88;FD88;FD88;0644 0645 062D;0644 0645 062D; +FD89;FD89;FD89;0645 062D 062C;0645 062D 062C; +FD8A;FD8A;FD8A;0645 062D 0645;0645 062D 0645; +FD8B;FD8B;FD8B;0645 062D 064A;0645 062D 064A; +FD8C;FD8C;FD8C;0645 062C 062D;0645 062C 062D; +FD8D;FD8D;FD8D;0645 062C 0645;0645 062C 0645; +FD8E;FD8E;FD8E;0645 062E 062C;0645 062E 062C; +FD8F;FD8F;FD8F;0645 062E 0645;0645 062E 0645; +FD92;FD92;FD92;0645 062C 062E;0645 062C 062E; +FD93;FD93;FD93;0647 0645 062C;0647 0645 062C; +FD94;FD94;FD94;0647 0645 0645;0647 0645 0645; +FD95;FD95;FD95;0646 062D 0645;0646 062D 0645; +FD96;FD96;FD96;0646 062D 0649;0646 062D 0649; +FD97;FD97;FD97;0646 062C 0645;0646 062C 0645; +FD98;FD98;FD98;0646 062C 0645;0646 062C 0645; +FD99;FD99;FD99;0646 062C 0649;0646 062C 0649; +FD9A;FD9A;FD9A;0646 0645 064A;0646 0645 064A; +FD9B;FD9B;FD9B;0646 0645 0649;0646 0645 0649; +FD9C;FD9C;FD9C;064A 0645 0645;064A 0645 0645; +FD9D;FD9D;FD9D;064A 0645 0645;064A 0645 0645; +FD9E;FD9E;FD9E;0628 062E 064A;0628 062E 064A; +FD9F;FD9F;FD9F;062A 062C 064A;062A 062C 064A; +FDA0;FDA0;FDA0;062A 062C 0649;062A 062C 0649; +FDA1;FDA1;FDA1;062A 062E 064A;062A 062E 064A; +FDA2;FDA2;FDA2;062A 062E 0649;062A 062E 0649; +FDA3;FDA3;FDA3;062A 0645 064A;062A 0645 064A; +FDA4;FDA4;FDA4;062A 0645 0649;062A 0645 0649; +FDA5;FDA5;FDA5;062C 0645 064A;062C 0645 064A; +FDA6;FDA6;FDA6;062C 062D 0649;062C 062D 0649; +FDA7;FDA7;FDA7;062C 0645 0649;062C 0645 0649; +FDA8;FDA8;FDA8;0633 062E 0649;0633 062E 0649; +FDA9;FDA9;FDA9;0635 062D 064A;0635 062D 064A; +FDAA;FDAA;FDAA;0634 062D 064A;0634 062D 064A; +FDAB;FDAB;FDAB;0636 062D 064A;0636 062D 064A; +FDAC;FDAC;FDAC;0644 062C 064A;0644 062C 064A; +FDAD;FDAD;FDAD;0644 0645 064A;0644 0645 064A; +FDAE;FDAE;FDAE;064A 062D 064A;064A 062D 064A; +FDAF;FDAF;FDAF;064A 062C 064A;064A 062C 064A; +FDB0;FDB0;FDB0;064A 0645 064A;064A 0645 064A; +FDB1;FDB1;FDB1;0645 0645 064A;0645 0645 064A; +FDB2;FDB2;FDB2;0642 0645 064A;0642 0645 064A; +FDB3;FDB3;FDB3;0646 062D 064A;0646 062D 064A; +FDB4;FDB4;FDB4;0642 0645 062D;0642 0645 062D; +FDB5;FDB5;FDB5;0644 062D 0645;0644 062D 0645; +FDB6;FDB6;FDB6;0639 0645 064A;0639 0645 064A; +FDB7;FDB7;FDB7;0643 0645 064A;0643 0645 064A; +FDB8;FDB8;FDB8;0646 062C 062D;0646 062C 062D; +FDB9;FDB9;FDB9;0645 062E 064A;0645 062E 064A; +FDBA;FDBA;FDBA;0644 062C 0645;0644 062C 0645; +FDBB;FDBB;FDBB;0643 0645 0645;0643 0645 0645; +FDBC;FDBC;FDBC;0644 062C 0645;0644 062C 0645; +FDBD;FDBD;FDBD;0646 062C 062D;0646 062C 062D; +FDBE;FDBE;FDBE;062C 062D 064A;062C 062D 064A; +FDBF;FDBF;FDBF;062D 062C 064A;062D 062C 064A; +FDC0;FDC0;FDC0;0645 062C 064A;0645 062C 064A; +FDC1;FDC1;FDC1;0641 0645 064A;0641 0645 064A; +FDC2;FDC2;FDC2;0628 062D 064A;0628 062D 064A; +FDC3;FDC3;FDC3;0643 0645 0645;0643 0645 0645; +FDC4;FDC4;FDC4;0639 062C 0645;0639 062C 0645; +FDC5;FDC5;FDC5;0635 0645 0645;0635 0645 0645; +FDC6;FDC6;FDC6;0633 062E 064A;0633 062E 064A; +FDC7;FDC7;FDC7;0646 062C 064A;0646 062C 064A; +FDF0;FDF0;FDF0;0635 0644 06D2;0635 0644 06D2; +FDF1;FDF1;FDF1;0642 0644 06D2;0642 0644 06D2; +FDF2;FDF2;FDF2;0627 0644 0644 0647;0627 0644 0644 0647; +FDF3;FDF3;FDF3;0627 0643 0628 0631;0627 0643 0628 0631; +FDF4;FDF4;FDF4;0645 062D 0645 062F;0645 062D 0645 062F; +FDF5;FDF5;FDF5;0635 0644 0639 0645;0635 0644 0639 0645; +FDF6;FDF6;FDF6;0631 0633 0648 0644;0631 0633 0648 0644; +FDF7;FDF7;FDF7;0639 0644 064A 0647;0639 0644 064A 0647; +FDF8;FDF8;FDF8;0648 0633 0644 0645;0648 0633 0644 0645; +FDF9;FDF9;FDF9;0635 0644 0649;0635 0644 0649; +FDFA;FDFA;FDFA;0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645; +FDFB;FDFB;FDFB;062C 0644 0020 062C 0644 0627 0644 0647;062C 0644 0020 062C 0644 0627 0644 0647; +FDFC;FDFC;FDFC;0631 06CC 0627 0644;0631 06CC 0627 0644; +FE10;FE10;FE10;002C;002C; +FE11;FE11;FE11;3001;3001; +FE12;FE12;FE12;3002;3002; +FE13;FE13;FE13;003A;003A; +FE14;FE14;FE14;003B;003B; +FE15;FE15;FE15;0021;0021; +FE16;FE16;FE16;003F;003F; +FE17;FE17;FE17;3016;3016; +FE18;FE18;FE18;3017;3017; +FE19;FE19;FE19;002E 002E 002E;002E 002E 002E; +FE30;FE30;FE30;002E 002E;002E 002E; +FE31;FE31;FE31;2014;2014; +FE32;FE32;FE32;2013;2013; +FE33;FE33;FE33;005F;005F; +FE34;FE34;FE34;005F;005F; +FE35;FE35;FE35;0028;0028; +FE36;FE36;FE36;0029;0029; +FE37;FE37;FE37;007B;007B; +FE38;FE38;FE38;007D;007D; +FE39;FE39;FE39;3014;3014; +FE3A;FE3A;FE3A;3015;3015; +FE3B;FE3B;FE3B;3010;3010; +FE3C;FE3C;FE3C;3011;3011; +FE3D;FE3D;FE3D;300A;300A; +FE3E;FE3E;FE3E;300B;300B; +FE3F;FE3F;FE3F;3008;3008; +FE40;FE40;FE40;3009;3009; +FE41;FE41;FE41;300C;300C; +FE42;FE42;FE42;300D;300D; +FE43;FE43;FE43;300E;300E; +FE44;FE44;FE44;300F;300F; +FE47;FE47;FE47;005B;005B; +FE48;FE48;FE48;005D;005D; +FE49;FE49;FE49;0020 0305;0020 0305; +FE4A;FE4A;FE4A;0020 0305;0020 0305; +FE4B;FE4B;FE4B;0020 0305;0020 0305; +FE4C;FE4C;FE4C;0020 0305;0020 0305; +FE4D;FE4D;FE4D;005F;005F; +FE4E;FE4E;FE4E;005F;005F; +FE4F;FE4F;FE4F;005F;005F; +FE50;FE50;FE50;002C;002C; +FE51;FE51;FE51;3001;3001; +FE52;FE52;FE52;002E;002E; +FE54;FE54;FE54;003B;003B; +FE55;FE55;FE55;003A;003A; +FE56;FE56;FE56;003F;003F; +FE57;FE57;FE57;0021;0021; +FE58;FE58;FE58;2014;2014; +FE59;FE59;FE59;0028;0028; +FE5A;FE5A;FE5A;0029;0029; +FE5B;FE5B;FE5B;007B;007B; +FE5C;FE5C;FE5C;007D;007D; +FE5D;FE5D;FE5D;3014;3014; +FE5E;FE5E;FE5E;3015;3015; +FE5F;FE5F;FE5F;0023;0023; +FE60;FE60;FE60;0026;0026; +FE61;FE61;FE61;002A;002A; +FE62;FE62;FE62;002B;002B; +FE63;FE63;FE63;002D;002D; +FE64;FE64;FE64;003C;003C; +FE65;FE65;FE65;003E;003E; +FE66;FE66;FE66;003D;003D; +FE68;FE68;FE68;005C;005C; +FE69;FE69;FE69;0024;0024; +FE6A;FE6A;FE6A;0025;0025; +FE6B;FE6B;FE6B;0040;0040; +FE70;FE70;FE70;0020 064B;0020 064B; +FE71;FE71;FE71;0640 064B;0640 064B; +FE72;FE72;FE72;0020 064C;0020 064C; +FE74;FE74;FE74;0020 064D;0020 064D; +FE76;FE76;FE76;0020 064E;0020 064E; +FE77;FE77;FE77;0640 064E;0640 064E; +FE78;FE78;FE78;0020 064F;0020 064F; +FE79;FE79;FE79;0640 064F;0640 064F; +FE7A;FE7A;FE7A;0020 0650;0020 0650; +FE7B;FE7B;FE7B;0640 0650;0640 0650; +FE7C;FE7C;FE7C;0020 0651;0020 0651; +FE7D;FE7D;FE7D;0640 0651;0640 0651; +FE7E;FE7E;FE7E;0020 0652;0020 0652; +FE7F;FE7F;FE7F;0640 0652;0640 0652; +FE80;FE80;FE80;0621;0621; +FE81;FE81;FE81;0622;0627 0653; +FE82;FE82;FE82;0622;0627 0653; +FE83;FE83;FE83;0623;0627 0654; +FE84;FE84;FE84;0623;0627 0654; +FE85;FE85;FE85;0624;0648 0654; +FE86;FE86;FE86;0624;0648 0654; +FE87;FE87;FE87;0625;0627 0655; +FE88;FE88;FE88;0625;0627 0655; +FE89;FE89;FE89;0626;064A 0654; +FE8A;FE8A;FE8A;0626;064A 0654; +FE8B;FE8B;FE8B;0626;064A 0654; +FE8C;FE8C;FE8C;0626;064A 0654; +FE8D;FE8D;FE8D;0627;0627; +FE8E;FE8E;FE8E;0627;0627; +FE8F;FE8F;FE8F;0628;0628; +FE90;FE90;FE90;0628;0628; +FE91;FE91;FE91;0628;0628; +FE92;FE92;FE92;0628;0628; +FE93;FE93;FE93;0629;0629; +FE94;FE94;FE94;0629;0629; +FE95;FE95;FE95;062A;062A; +FE96;FE96;FE96;062A;062A; +FE97;FE97;FE97;062A;062A; +FE98;FE98;FE98;062A;062A; +FE99;FE99;FE99;062B;062B; +FE9A;FE9A;FE9A;062B;062B; +FE9B;FE9B;FE9B;062B;062B; +FE9C;FE9C;FE9C;062B;062B; +FE9D;FE9D;FE9D;062C;062C; +FE9E;FE9E;FE9E;062C;062C; +FE9F;FE9F;FE9F;062C;062C; +FEA0;FEA0;FEA0;062C;062C; +FEA1;FEA1;FEA1;062D;062D; +FEA2;FEA2;FEA2;062D;062D; +FEA3;FEA3;FEA3;062D;062D; +FEA4;FEA4;FEA4;062D;062D; +FEA5;FEA5;FEA5;062E;062E; +FEA6;FEA6;FEA6;062E;062E; +FEA7;FEA7;FEA7;062E;062E; +FEA8;FEA8;FEA8;062E;062E; +FEA9;FEA9;FEA9;062F;062F; +FEAA;FEAA;FEAA;062F;062F; +FEAB;FEAB;FEAB;0630;0630; +FEAC;FEAC;FEAC;0630;0630; +FEAD;FEAD;FEAD;0631;0631; +FEAE;FEAE;FEAE;0631;0631; +FEAF;FEAF;FEAF;0632;0632; +FEB0;FEB0;FEB0;0632;0632; +FEB1;FEB1;FEB1;0633;0633; +FEB2;FEB2;FEB2;0633;0633; +FEB3;FEB3;FEB3;0633;0633; +FEB4;FEB4;FEB4;0633;0633; +FEB5;FEB5;FEB5;0634;0634; +FEB6;FEB6;FEB6;0634;0634; +FEB7;FEB7;FEB7;0634;0634; +FEB8;FEB8;FEB8;0634;0634; +FEB9;FEB9;FEB9;0635;0635; +FEBA;FEBA;FEBA;0635;0635; +FEBB;FEBB;FEBB;0635;0635; +FEBC;FEBC;FEBC;0635;0635; +FEBD;FEBD;FEBD;0636;0636; +FEBE;FEBE;FEBE;0636;0636; +FEBF;FEBF;FEBF;0636;0636; +FEC0;FEC0;FEC0;0636;0636; +FEC1;FEC1;FEC1;0637;0637; +FEC2;FEC2;FEC2;0637;0637; +FEC3;FEC3;FEC3;0637;0637; +FEC4;FEC4;FEC4;0637;0637; +FEC5;FEC5;FEC5;0638;0638; +FEC6;FEC6;FEC6;0638;0638; +FEC7;FEC7;FEC7;0638;0638; +FEC8;FEC8;FEC8;0638;0638; +FEC9;FEC9;FEC9;0639;0639; +FECA;FECA;FECA;0639;0639; +FECB;FECB;FECB;0639;0639; +FECC;FECC;FECC;0639;0639; +FECD;FECD;FECD;063A;063A; +FECE;FECE;FECE;063A;063A; +FECF;FECF;FECF;063A;063A; +FED0;FED0;FED0;063A;063A; +FED1;FED1;FED1;0641;0641; +FED2;FED2;FED2;0641;0641; +FED3;FED3;FED3;0641;0641; +FED4;FED4;FED4;0641;0641; +FED5;FED5;FED5;0642;0642; +FED6;FED6;FED6;0642;0642; +FED7;FED7;FED7;0642;0642; +FED8;FED8;FED8;0642;0642; +FED9;FED9;FED9;0643;0643; +FEDA;FEDA;FEDA;0643;0643; +FEDB;FEDB;FEDB;0643;0643; +FEDC;FEDC;FEDC;0643;0643; +FEDD;FEDD;FEDD;0644;0644; +FEDE;FEDE;FEDE;0644;0644; +FEDF;FEDF;FEDF;0644;0644; +FEE0;FEE0;FEE0;0644;0644; +FEE1;FEE1;FEE1;0645;0645; +FEE2;FEE2;FEE2;0645;0645; +FEE3;FEE3;FEE3;0645;0645; +FEE4;FEE4;FEE4;0645;0645; +FEE5;FEE5;FEE5;0646;0646; +FEE6;FEE6;FEE6;0646;0646; +FEE7;FEE7;FEE7;0646;0646; +FEE8;FEE8;FEE8;0646;0646; +FEE9;FEE9;FEE9;0647;0647; +FEEA;FEEA;FEEA;0647;0647; +FEEB;FEEB;FEEB;0647;0647; +FEEC;FEEC;FEEC;0647;0647; +FEED;FEED;FEED;0648;0648; +FEEE;FEEE;FEEE;0648;0648; +FEEF;FEEF;FEEF;0649;0649; +FEF0;FEF0;FEF0;0649;0649; +FEF1;FEF1;FEF1;064A;064A; +FEF2;FEF2;FEF2;064A;064A; +FEF3;FEF3;FEF3;064A;064A; +FEF4;FEF4;FEF4;064A;064A; +FEF5;FEF5;FEF5;0644 0622;0644 0627 0653; +FEF6;FEF6;FEF6;0644 0622;0644 0627 0653; +FEF7;FEF7;FEF7;0644 0623;0644 0627 0654; +FEF8;FEF8;FEF8;0644 0623;0644 0627 0654; +FEF9;FEF9;FEF9;0644 0625;0644 0627 0655; +FEFA;FEFA;FEFA;0644 0625;0644 0627 0655; +FEFB;FEFB;FEFB;0644 0627;0644 0627; +FEFC;FEFC;FEFC;0644 0627;0644 0627; +FF01;FF01;FF01;0021;0021; +FF02;FF02;FF02;0022;0022; +FF03;FF03;FF03;0023;0023; +FF04;FF04;FF04;0024;0024; +FF05;FF05;FF05;0025;0025; +FF06;FF06;FF06;0026;0026; +FF07;FF07;FF07;0027;0027; +FF08;FF08;FF08;0028;0028; +FF09;FF09;FF09;0029;0029; +FF0A;FF0A;FF0A;002A;002A; +FF0B;FF0B;FF0B;002B;002B; +FF0C;FF0C;FF0C;002C;002C; +FF0D;FF0D;FF0D;002D;002D; +FF0E;FF0E;FF0E;002E;002E; +FF0F;FF0F;FF0F;002F;002F; +FF10;FF10;FF10;0030;0030; +FF11;FF11;FF11;0031;0031; +FF12;FF12;FF12;0032;0032; +FF13;FF13;FF13;0033;0033; +FF14;FF14;FF14;0034;0034; +FF15;FF15;FF15;0035;0035; +FF16;FF16;FF16;0036;0036; +FF17;FF17;FF17;0037;0037; +FF18;FF18;FF18;0038;0038; +FF19;FF19;FF19;0039;0039; +FF1A;FF1A;FF1A;003A;003A; +FF1B;FF1B;FF1B;003B;003B; +FF1C;FF1C;FF1C;003C;003C; +FF1D;FF1D;FF1D;003D;003D; +FF1E;FF1E;FF1E;003E;003E; +FF1F;FF1F;FF1F;003F;003F; +FF20;FF20;FF20;0040;0040; +FF21;FF21;FF21;0041;0041; +FF22;FF22;FF22;0042;0042; +FF23;FF23;FF23;0043;0043; +FF24;FF24;FF24;0044;0044; +FF25;FF25;FF25;0045;0045; +FF26;FF26;FF26;0046;0046; +FF27;FF27;FF27;0047;0047; +FF28;FF28;FF28;0048;0048; +FF29;FF29;FF29;0049;0049; +FF2A;FF2A;FF2A;004A;004A; +FF2B;FF2B;FF2B;004B;004B; +FF2C;FF2C;FF2C;004C;004C; +FF2D;FF2D;FF2D;004D;004D; +FF2E;FF2E;FF2E;004E;004E; +FF2F;FF2F;FF2F;004F;004F; +FF30;FF30;FF30;0050;0050; +FF31;FF31;FF31;0051;0051; +FF32;FF32;FF32;0052;0052; +FF33;FF33;FF33;0053;0053; +FF34;FF34;FF34;0054;0054; +FF35;FF35;FF35;0055;0055; +FF36;FF36;FF36;0056;0056; +FF37;FF37;FF37;0057;0057; +FF38;FF38;FF38;0058;0058; +FF39;FF39;FF39;0059;0059; +FF3A;FF3A;FF3A;005A;005A; +FF3B;FF3B;FF3B;005B;005B; +FF3C;FF3C;FF3C;005C;005C; +FF3D;FF3D;FF3D;005D;005D; +FF3E;FF3E;FF3E;005E;005E; +FF3F;FF3F;FF3F;005F;005F; +FF40;FF40;FF40;0060;0060; +FF41;FF41;FF41;0061;0061; +FF42;FF42;FF42;0062;0062; +FF43;FF43;FF43;0063;0063; +FF44;FF44;FF44;0064;0064; +FF45;FF45;FF45;0065;0065; +FF46;FF46;FF46;0066;0066; +FF47;FF47;FF47;0067;0067; +FF48;FF48;FF48;0068;0068; +FF49;FF49;FF49;0069;0069; +FF4A;FF4A;FF4A;006A;006A; +FF4B;FF4B;FF4B;006B;006B; +FF4C;FF4C;FF4C;006C;006C; +FF4D;FF4D;FF4D;006D;006D; +FF4E;FF4E;FF4E;006E;006E; +FF4F;FF4F;FF4F;006F;006F; +FF50;FF50;FF50;0070;0070; +FF51;FF51;FF51;0071;0071; +FF52;FF52;FF52;0072;0072; +FF53;FF53;FF53;0073;0073; +FF54;FF54;FF54;0074;0074; +FF55;FF55;FF55;0075;0075; +FF56;FF56;FF56;0076;0076; +FF57;FF57;FF57;0077;0077; +FF58;FF58;FF58;0078;0078; +FF59;FF59;FF59;0079;0079; +FF5A;FF5A;FF5A;007A;007A; +FF5B;FF5B;FF5B;007B;007B; +FF5C;FF5C;FF5C;007C;007C; +FF5D;FF5D;FF5D;007D;007D; +FF5E;FF5E;FF5E;007E;007E; +FF5F;FF5F;FF5F;2985;2985; +FF60;FF60;FF60;2986;2986; +FF61;FF61;FF61;3002;3002; +FF62;FF62;FF62;300C;300C; +FF63;FF63;FF63;300D;300D; +FF64;FF64;FF64;3001;3001; +FF65;FF65;FF65;30FB;30FB; +FF66;FF66;FF66;30F2;30F2; +FF67;FF67;FF67;30A1;30A1; +FF68;FF68;FF68;30A3;30A3; +FF69;FF69;FF69;30A5;30A5; +FF6A;FF6A;FF6A;30A7;30A7; +FF6B;FF6B;FF6B;30A9;30A9; +FF6C;FF6C;FF6C;30E3;30E3; +FF6D;FF6D;FF6D;30E5;30E5; +FF6E;FF6E;FF6E;30E7;30E7; +FF6F;FF6F;FF6F;30C3;30C3; +FF70;FF70;FF70;30FC;30FC; +FF71;FF71;FF71;30A2;30A2; +FF72;FF72;FF72;30A4;30A4; +FF73;FF73;FF73;30A6;30A6; +FF74;FF74;FF74;30A8;30A8; +FF75;FF75;FF75;30AA;30AA; +FF76;FF76;FF76;30AB;30AB; +FF77;FF77;FF77;30AD;30AD; +FF78;FF78;FF78;30AF;30AF; +FF79;FF79;FF79;30B1;30B1; +FF7A;FF7A;FF7A;30B3;30B3; +FF7B;FF7B;FF7B;30B5;30B5; +FF7C;FF7C;FF7C;30B7;30B7; +FF7D;FF7D;FF7D;30B9;30B9; +FF7E;FF7E;FF7E;30BB;30BB; +FF7F;FF7F;FF7F;30BD;30BD; +FF80;FF80;FF80;30BF;30BF; +FF81;FF81;FF81;30C1;30C1; +FF82;FF82;FF82;30C4;30C4; +FF83;FF83;FF83;30C6;30C6; +FF84;FF84;FF84;30C8;30C8; +FF85;FF85;FF85;30CA;30CA; +FF86;FF86;FF86;30CB;30CB; +FF87;FF87;FF87;30CC;30CC; +FF88;FF88;FF88;30CD;30CD; +FF89;FF89;FF89;30CE;30CE; +FF8A;FF8A;FF8A;30CF;30CF; +FF8B;FF8B;FF8B;30D2;30D2; +FF8C;FF8C;FF8C;30D5;30D5; +FF8D;FF8D;FF8D;30D8;30D8; +FF8E;FF8E;FF8E;30DB;30DB; +FF8F;FF8F;FF8F;30DE;30DE; +FF90;FF90;FF90;30DF;30DF; +FF91;FF91;FF91;30E0;30E0; +FF92;FF92;FF92;30E1;30E1; +FF93;FF93;FF93;30E2;30E2; +FF94;FF94;FF94;30E4;30E4; +FF95;FF95;FF95;30E6;30E6; +FF96;FF96;FF96;30E8;30E8; +FF97;FF97;FF97;30E9;30E9; +FF98;FF98;FF98;30EA;30EA; +FF99;FF99;FF99;30EB;30EB; +FF9A;FF9A;FF9A;30EC;30EC; +FF9B;FF9B;FF9B;30ED;30ED; +FF9C;FF9C;FF9C;30EF;30EF; +FF9D;FF9D;FF9D;30F3;30F3; +FF9E;FF9E;FF9E;3099;3099; +FF9F;FF9F;FF9F;309A;309A; +FFA0;FFA0;FFA0;1160;1160; +FFA1;FFA1;FFA1;1100;1100; +FFA2;FFA2;FFA2;1101;1101; +FFA3;FFA3;FFA3;11AA;11AA; +FFA4;FFA4;FFA4;1102;1102; +FFA5;FFA5;FFA5;11AC;11AC; +FFA6;FFA6;FFA6;11AD;11AD; +FFA7;FFA7;FFA7;1103;1103; +FFA8;FFA8;FFA8;1104;1104; +FFA9;FFA9;FFA9;1105;1105; +FFAA;FFAA;FFAA;11B0;11B0; +FFAB;FFAB;FFAB;11B1;11B1; +FFAC;FFAC;FFAC;11B2;11B2; +FFAD;FFAD;FFAD;11B3;11B3; +FFAE;FFAE;FFAE;11B4;11B4; +FFAF;FFAF;FFAF;11B5;11B5; +FFB0;FFB0;FFB0;111A;111A; +FFB1;FFB1;FFB1;1106;1106; +FFB2;FFB2;FFB2;1107;1107; +FFB3;FFB3;FFB3;1108;1108; +FFB4;FFB4;FFB4;1121;1121; +FFB5;FFB5;FFB5;1109;1109; +FFB6;FFB6;FFB6;110A;110A; +FFB7;FFB7;FFB7;110B;110B; +FFB8;FFB8;FFB8;110C;110C; +FFB9;FFB9;FFB9;110D;110D; +FFBA;FFBA;FFBA;110E;110E; +FFBB;FFBB;FFBB;110F;110F; +FFBC;FFBC;FFBC;1110;1110; +FFBD;FFBD;FFBD;1111;1111; +FFBE;FFBE;FFBE;1112;1112; +FFC2;FFC2;FFC2;1161;1161; +FFC3;FFC3;FFC3;1162;1162; +FFC4;FFC4;FFC4;1163;1163; +FFC5;FFC5;FFC5;1164;1164; +FFC6;FFC6;FFC6;1165;1165; +FFC7;FFC7;FFC7;1166;1166; +FFCA;FFCA;FFCA;1167;1167; +FFCB;FFCB;FFCB;1168;1168; +FFCC;FFCC;FFCC;1169;1169; +FFCD;FFCD;FFCD;116A;116A; +FFCE;FFCE;FFCE;116B;116B; +FFCF;FFCF;FFCF;116C;116C; +FFD2;FFD2;FFD2;116D;116D; +FFD3;FFD3;FFD3;116E;116E; +FFD4;FFD4;FFD4;116F;116F; +FFD5;FFD5;FFD5;1170;1170; +FFD6;FFD6;FFD6;1171;1171; +FFD7;FFD7;FFD7;1172;1172; +FFDA;FFDA;FFDA;1173;1173; +FFDB;FFDB;FFDB;1174;1174; +FFDC;FFDC;FFDC;1175;1175; +FFE0;FFE0;FFE0;00A2;00A2; +FFE1;FFE1;FFE1;00A3;00A3; +FFE2;FFE2;FFE2;00AC;00AC; +FFE3;FFE3;FFE3;0020 0304;0020 0304; +FFE4;FFE4;FFE4;00A6;00A6; +FFE5;FFE5;FFE5;00A5;00A5; +FFE6;FFE6;FFE6;20A9;20A9; +FFE8;FFE8;FFE8;2502;2502; +FFE9;FFE9;FFE9;2190;2190; +FFEA;FFEA;FFEA;2191;2191; +FFEB;FFEB;FFEB;2192;2192; +FFEC;FFEC;FFEC;2193;2193; +FFED;FFED;FFED;25A0;25A0; +FFEE;FFEE;FFEE;25CB;25CB; +1109A;1109A;11099 110BA;1109A;11099 110BA; +1109C;1109C;1109B 110BA;1109C;1109B 110BA; +110AB;110AB;110A5 110BA;110AB;110A5 110BA; +1112E;1112E;11131 11127;1112E;11131 11127; +1112F;1112F;11132 11127;1112F;11132 11127; +1134B;1134B;11347 1133E;1134B;11347 1133E; +1134C;1134C;11347 11357;1134C;11347 11357; +114BB;114BB;114B9 114BA;114BB;114B9 114BA; +114BC;114BC;114B9 114B0;114BC;114B9 114B0; +114BE;114BE;114B9 114BD;114BE;114B9 114BD; +115BA;115BA;115B8 115AF;115BA;115B8 115AF; +115BB;115BB;115B9 115AF;115BB;115B9 115AF; +1D15E;1D157 1D165;1D157 1D165;1D157 1D165;1D157 1D165; +1D15F;1D158 1D165;1D158 1D165;1D158 1D165;1D158 1D165; +1D160;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E; +1D161;1D158 1D165 1D16F;1D158 1D165 1D16F;1D158 1D165 1D16F;1D158 1D165 1D16F; +1D162;1D158 1D165 1D170;1D158 1D165 1D170;1D158 1D165 1D170;1D158 1D165 1D170; +1D163;1D158 1D165 1D171;1D158 1D165 1D171;1D158 1D165 1D171;1D158 1D165 1D171; +1D164;1D158 1D165 1D172;1D158 1D165 1D172;1D158 1D165 1D172;1D158 1D165 1D172; +1D1BB;1D1B9 1D165;1D1B9 1D165;1D1B9 1D165;1D1B9 1D165; +1D1BC;1D1BA 1D165;1D1BA 1D165;1D1BA 1D165;1D1BA 1D165; +1D1BD;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E; +1D1BE;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E; +1D1BF;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F; +1D1C0;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F; +1D400;1D400;1D400;0041;0041; +1D401;1D401;1D401;0042;0042; +1D402;1D402;1D402;0043;0043; +1D403;1D403;1D403;0044;0044; +1D404;1D404;1D404;0045;0045; +1D405;1D405;1D405;0046;0046; +1D406;1D406;1D406;0047;0047; +1D407;1D407;1D407;0048;0048; +1D408;1D408;1D408;0049;0049; +1D409;1D409;1D409;004A;004A; +1D40A;1D40A;1D40A;004B;004B; +1D40B;1D40B;1D40B;004C;004C; +1D40C;1D40C;1D40C;004D;004D; +1D40D;1D40D;1D40D;004E;004E; +1D40E;1D40E;1D40E;004F;004F; +1D40F;1D40F;1D40F;0050;0050; +1D410;1D410;1D410;0051;0051; +1D411;1D411;1D411;0052;0052; +1D412;1D412;1D412;0053;0053; +1D413;1D413;1D413;0054;0054; +1D414;1D414;1D414;0055;0055; +1D415;1D415;1D415;0056;0056; +1D416;1D416;1D416;0057;0057; +1D417;1D417;1D417;0058;0058; +1D418;1D418;1D418;0059;0059; +1D419;1D419;1D419;005A;005A; +1D41A;1D41A;1D41A;0061;0061; +1D41B;1D41B;1D41B;0062;0062; +1D41C;1D41C;1D41C;0063;0063; +1D41D;1D41D;1D41D;0064;0064; +1D41E;1D41E;1D41E;0065;0065; +1D41F;1D41F;1D41F;0066;0066; +1D420;1D420;1D420;0067;0067; +1D421;1D421;1D421;0068;0068; +1D422;1D422;1D422;0069;0069; +1D423;1D423;1D423;006A;006A; +1D424;1D424;1D424;006B;006B; +1D425;1D425;1D425;006C;006C; +1D426;1D426;1D426;006D;006D; +1D427;1D427;1D427;006E;006E; +1D428;1D428;1D428;006F;006F; +1D429;1D429;1D429;0070;0070; +1D42A;1D42A;1D42A;0071;0071; +1D42B;1D42B;1D42B;0072;0072; +1D42C;1D42C;1D42C;0073;0073; +1D42D;1D42D;1D42D;0074;0074; +1D42E;1D42E;1D42E;0075;0075; +1D42F;1D42F;1D42F;0076;0076; +1D430;1D430;1D430;0077;0077; +1D431;1D431;1D431;0078;0078; +1D432;1D432;1D432;0079;0079; +1D433;1D433;1D433;007A;007A; +1D434;1D434;1D434;0041;0041; +1D435;1D435;1D435;0042;0042; +1D436;1D436;1D436;0043;0043; +1D437;1D437;1D437;0044;0044; +1D438;1D438;1D438;0045;0045; +1D439;1D439;1D439;0046;0046; +1D43A;1D43A;1D43A;0047;0047; +1D43B;1D43B;1D43B;0048;0048; +1D43C;1D43C;1D43C;0049;0049; +1D43D;1D43D;1D43D;004A;004A; +1D43E;1D43E;1D43E;004B;004B; +1D43F;1D43F;1D43F;004C;004C; +1D440;1D440;1D440;004D;004D; +1D441;1D441;1D441;004E;004E; +1D442;1D442;1D442;004F;004F; +1D443;1D443;1D443;0050;0050; +1D444;1D444;1D444;0051;0051; +1D445;1D445;1D445;0052;0052; +1D446;1D446;1D446;0053;0053; +1D447;1D447;1D447;0054;0054; +1D448;1D448;1D448;0055;0055; +1D449;1D449;1D449;0056;0056; +1D44A;1D44A;1D44A;0057;0057; +1D44B;1D44B;1D44B;0058;0058; +1D44C;1D44C;1D44C;0059;0059; +1D44D;1D44D;1D44D;005A;005A; +1D44E;1D44E;1D44E;0061;0061; +1D44F;1D44F;1D44F;0062;0062; +1D450;1D450;1D450;0063;0063; +1D451;1D451;1D451;0064;0064; +1D452;1D452;1D452;0065;0065; +1D453;1D453;1D453;0066;0066; +1D454;1D454;1D454;0067;0067; +1D456;1D456;1D456;0069;0069; +1D457;1D457;1D457;006A;006A; +1D458;1D458;1D458;006B;006B; +1D459;1D459;1D459;006C;006C; +1D45A;1D45A;1D45A;006D;006D; +1D45B;1D45B;1D45B;006E;006E; +1D45C;1D45C;1D45C;006F;006F; +1D45D;1D45D;1D45D;0070;0070; +1D45E;1D45E;1D45E;0071;0071; +1D45F;1D45F;1D45F;0072;0072; +1D460;1D460;1D460;0073;0073; +1D461;1D461;1D461;0074;0074; +1D462;1D462;1D462;0075;0075; +1D463;1D463;1D463;0076;0076; +1D464;1D464;1D464;0077;0077; +1D465;1D465;1D465;0078;0078; +1D466;1D466;1D466;0079;0079; +1D467;1D467;1D467;007A;007A; +1D468;1D468;1D468;0041;0041; +1D469;1D469;1D469;0042;0042; +1D46A;1D46A;1D46A;0043;0043; +1D46B;1D46B;1D46B;0044;0044; +1D46C;1D46C;1D46C;0045;0045; +1D46D;1D46D;1D46D;0046;0046; +1D46E;1D46E;1D46E;0047;0047; +1D46F;1D46F;1D46F;0048;0048; +1D470;1D470;1D470;0049;0049; +1D471;1D471;1D471;004A;004A; +1D472;1D472;1D472;004B;004B; +1D473;1D473;1D473;004C;004C; +1D474;1D474;1D474;004D;004D; +1D475;1D475;1D475;004E;004E; +1D476;1D476;1D476;004F;004F; +1D477;1D477;1D477;0050;0050; +1D478;1D478;1D478;0051;0051; +1D479;1D479;1D479;0052;0052; +1D47A;1D47A;1D47A;0053;0053; +1D47B;1D47B;1D47B;0054;0054; +1D47C;1D47C;1D47C;0055;0055; +1D47D;1D47D;1D47D;0056;0056; +1D47E;1D47E;1D47E;0057;0057; +1D47F;1D47F;1D47F;0058;0058; +1D480;1D480;1D480;0059;0059; +1D481;1D481;1D481;005A;005A; +1D482;1D482;1D482;0061;0061; +1D483;1D483;1D483;0062;0062; +1D484;1D484;1D484;0063;0063; +1D485;1D485;1D485;0064;0064; +1D486;1D486;1D486;0065;0065; +1D487;1D487;1D487;0066;0066; +1D488;1D488;1D488;0067;0067; +1D489;1D489;1D489;0068;0068; +1D48A;1D48A;1D48A;0069;0069; +1D48B;1D48B;1D48B;006A;006A; +1D48C;1D48C;1D48C;006B;006B; +1D48D;1D48D;1D48D;006C;006C; +1D48E;1D48E;1D48E;006D;006D; +1D48F;1D48F;1D48F;006E;006E; +1D490;1D490;1D490;006F;006F; +1D491;1D491;1D491;0070;0070; +1D492;1D492;1D492;0071;0071; +1D493;1D493;1D493;0072;0072; +1D494;1D494;1D494;0073;0073; +1D495;1D495;1D495;0074;0074; +1D496;1D496;1D496;0075;0075; +1D497;1D497;1D497;0076;0076; +1D498;1D498;1D498;0077;0077; +1D499;1D499;1D499;0078;0078; +1D49A;1D49A;1D49A;0079;0079; +1D49B;1D49B;1D49B;007A;007A; +1D49C;1D49C;1D49C;0041;0041; +1D49E;1D49E;1D49E;0043;0043; +1D49F;1D49F;1D49F;0044;0044; +1D4A2;1D4A2;1D4A2;0047;0047; +1D4A5;1D4A5;1D4A5;004A;004A; +1D4A6;1D4A6;1D4A6;004B;004B; +1D4A9;1D4A9;1D4A9;004E;004E; +1D4AA;1D4AA;1D4AA;004F;004F; +1D4AB;1D4AB;1D4AB;0050;0050; +1D4AC;1D4AC;1D4AC;0051;0051; +1D4AE;1D4AE;1D4AE;0053;0053; +1D4AF;1D4AF;1D4AF;0054;0054; +1D4B0;1D4B0;1D4B0;0055;0055; +1D4B1;1D4B1;1D4B1;0056;0056; +1D4B2;1D4B2;1D4B2;0057;0057; +1D4B3;1D4B3;1D4B3;0058;0058; +1D4B4;1D4B4;1D4B4;0059;0059; +1D4B5;1D4B5;1D4B5;005A;005A; +1D4B6;1D4B6;1D4B6;0061;0061; +1D4B7;1D4B7;1D4B7;0062;0062; +1D4B8;1D4B8;1D4B8;0063;0063; +1D4B9;1D4B9;1D4B9;0064;0064; +1D4BB;1D4BB;1D4BB;0066;0066; +1D4BD;1D4BD;1D4BD;0068;0068; +1D4BE;1D4BE;1D4BE;0069;0069; +1D4BF;1D4BF;1D4BF;006A;006A; +1D4C0;1D4C0;1D4C0;006B;006B; +1D4C1;1D4C1;1D4C1;006C;006C; +1D4C2;1D4C2;1D4C2;006D;006D; +1D4C3;1D4C3;1D4C3;006E;006E; +1D4C5;1D4C5;1D4C5;0070;0070; +1D4C6;1D4C6;1D4C6;0071;0071; +1D4C7;1D4C7;1D4C7;0072;0072; +1D4C8;1D4C8;1D4C8;0073;0073; +1D4C9;1D4C9;1D4C9;0074;0074; +1D4CA;1D4CA;1D4CA;0075;0075; +1D4CB;1D4CB;1D4CB;0076;0076; +1D4CC;1D4CC;1D4CC;0077;0077; +1D4CD;1D4CD;1D4CD;0078;0078; +1D4CE;1D4CE;1D4CE;0079;0079; +1D4CF;1D4CF;1D4CF;007A;007A; +1D4D0;1D4D0;1D4D0;0041;0041; +1D4D1;1D4D1;1D4D1;0042;0042; +1D4D2;1D4D2;1D4D2;0043;0043; +1D4D3;1D4D3;1D4D3;0044;0044; +1D4D4;1D4D4;1D4D4;0045;0045; +1D4D5;1D4D5;1D4D5;0046;0046; +1D4D6;1D4D6;1D4D6;0047;0047; +1D4D7;1D4D7;1D4D7;0048;0048; +1D4D8;1D4D8;1D4D8;0049;0049; +1D4D9;1D4D9;1D4D9;004A;004A; +1D4DA;1D4DA;1D4DA;004B;004B; +1D4DB;1D4DB;1D4DB;004C;004C; +1D4DC;1D4DC;1D4DC;004D;004D; +1D4DD;1D4DD;1D4DD;004E;004E; +1D4DE;1D4DE;1D4DE;004F;004F; +1D4DF;1D4DF;1D4DF;0050;0050; +1D4E0;1D4E0;1D4E0;0051;0051; +1D4E1;1D4E1;1D4E1;0052;0052; +1D4E2;1D4E2;1D4E2;0053;0053; +1D4E3;1D4E3;1D4E3;0054;0054; +1D4E4;1D4E4;1D4E4;0055;0055; +1D4E5;1D4E5;1D4E5;0056;0056; +1D4E6;1D4E6;1D4E6;0057;0057; +1D4E7;1D4E7;1D4E7;0058;0058; +1D4E8;1D4E8;1D4E8;0059;0059; +1D4E9;1D4E9;1D4E9;005A;005A; +1D4EA;1D4EA;1D4EA;0061;0061; +1D4EB;1D4EB;1D4EB;0062;0062; +1D4EC;1D4EC;1D4EC;0063;0063; +1D4ED;1D4ED;1D4ED;0064;0064; +1D4EE;1D4EE;1D4EE;0065;0065; +1D4EF;1D4EF;1D4EF;0066;0066; +1D4F0;1D4F0;1D4F0;0067;0067; +1D4F1;1D4F1;1D4F1;0068;0068; +1D4F2;1D4F2;1D4F2;0069;0069; +1D4F3;1D4F3;1D4F3;006A;006A; +1D4F4;1D4F4;1D4F4;006B;006B; +1D4F5;1D4F5;1D4F5;006C;006C; +1D4F6;1D4F6;1D4F6;006D;006D; +1D4F7;1D4F7;1D4F7;006E;006E; +1D4F8;1D4F8;1D4F8;006F;006F; +1D4F9;1D4F9;1D4F9;0070;0070; +1D4FA;1D4FA;1D4FA;0071;0071; +1D4FB;1D4FB;1D4FB;0072;0072; +1D4FC;1D4FC;1D4FC;0073;0073; +1D4FD;1D4FD;1D4FD;0074;0074; +1D4FE;1D4FE;1D4FE;0075;0075; +1D4FF;1D4FF;1D4FF;0076;0076; +1D500;1D500;1D500;0077;0077; +1D501;1D501;1D501;0078;0078; +1D502;1D502;1D502;0079;0079; +1D503;1D503;1D503;007A;007A; +1D504;1D504;1D504;0041;0041; +1D505;1D505;1D505;0042;0042; +1D507;1D507;1D507;0044;0044; +1D508;1D508;1D508;0045;0045; +1D509;1D509;1D509;0046;0046; +1D50A;1D50A;1D50A;0047;0047; +1D50D;1D50D;1D50D;004A;004A; +1D50E;1D50E;1D50E;004B;004B; +1D50F;1D50F;1D50F;004C;004C; +1D510;1D510;1D510;004D;004D; +1D511;1D511;1D511;004E;004E; +1D512;1D512;1D512;004F;004F; +1D513;1D513;1D513;0050;0050; +1D514;1D514;1D514;0051;0051; +1D516;1D516;1D516;0053;0053; +1D517;1D517;1D517;0054;0054; +1D518;1D518;1D518;0055;0055; +1D519;1D519;1D519;0056;0056; +1D51A;1D51A;1D51A;0057;0057; +1D51B;1D51B;1D51B;0058;0058; +1D51C;1D51C;1D51C;0059;0059; +1D51E;1D51E;1D51E;0061;0061; +1D51F;1D51F;1D51F;0062;0062; +1D520;1D520;1D520;0063;0063; +1D521;1D521;1D521;0064;0064; +1D522;1D522;1D522;0065;0065; +1D523;1D523;1D523;0066;0066; +1D524;1D524;1D524;0067;0067; +1D525;1D525;1D525;0068;0068; +1D526;1D526;1D526;0069;0069; +1D527;1D527;1D527;006A;006A; +1D528;1D528;1D528;006B;006B; +1D529;1D529;1D529;006C;006C; +1D52A;1D52A;1D52A;006D;006D; +1D52B;1D52B;1D52B;006E;006E; +1D52C;1D52C;1D52C;006F;006F; +1D52D;1D52D;1D52D;0070;0070; +1D52E;1D52E;1D52E;0071;0071; +1D52F;1D52F;1D52F;0072;0072; +1D530;1D530;1D530;0073;0073; +1D531;1D531;1D531;0074;0074; +1D532;1D532;1D532;0075;0075; +1D533;1D533;1D533;0076;0076; +1D534;1D534;1D534;0077;0077; +1D535;1D535;1D535;0078;0078; +1D536;1D536;1D536;0079;0079; +1D537;1D537;1D537;007A;007A; +1D538;1D538;1D538;0041;0041; +1D539;1D539;1D539;0042;0042; +1D53B;1D53B;1D53B;0044;0044; +1D53C;1D53C;1D53C;0045;0045; +1D53D;1D53D;1D53D;0046;0046; +1D53E;1D53E;1D53E;0047;0047; +1D540;1D540;1D540;0049;0049; +1D541;1D541;1D541;004A;004A; +1D542;1D542;1D542;004B;004B; +1D543;1D543;1D543;004C;004C; +1D544;1D544;1D544;004D;004D; +1D546;1D546;1D546;004F;004F; +1D54A;1D54A;1D54A;0053;0053; +1D54B;1D54B;1D54B;0054;0054; +1D54C;1D54C;1D54C;0055;0055; +1D54D;1D54D;1D54D;0056;0056; +1D54E;1D54E;1D54E;0057;0057; +1D54F;1D54F;1D54F;0058;0058; +1D550;1D550;1D550;0059;0059; +1D552;1D552;1D552;0061;0061; +1D553;1D553;1D553;0062;0062; +1D554;1D554;1D554;0063;0063; +1D555;1D555;1D555;0064;0064; +1D556;1D556;1D556;0065;0065; +1D557;1D557;1D557;0066;0066; +1D558;1D558;1D558;0067;0067; +1D559;1D559;1D559;0068;0068; +1D55A;1D55A;1D55A;0069;0069; +1D55B;1D55B;1D55B;006A;006A; +1D55C;1D55C;1D55C;006B;006B; +1D55D;1D55D;1D55D;006C;006C; +1D55E;1D55E;1D55E;006D;006D; +1D55F;1D55F;1D55F;006E;006E; +1D560;1D560;1D560;006F;006F; +1D561;1D561;1D561;0070;0070; +1D562;1D562;1D562;0071;0071; +1D563;1D563;1D563;0072;0072; +1D564;1D564;1D564;0073;0073; +1D565;1D565;1D565;0074;0074; +1D566;1D566;1D566;0075;0075; +1D567;1D567;1D567;0076;0076; +1D568;1D568;1D568;0077;0077; +1D569;1D569;1D569;0078;0078; +1D56A;1D56A;1D56A;0079;0079; +1D56B;1D56B;1D56B;007A;007A; +1D56C;1D56C;1D56C;0041;0041; +1D56D;1D56D;1D56D;0042;0042; +1D56E;1D56E;1D56E;0043;0043; +1D56F;1D56F;1D56F;0044;0044; +1D570;1D570;1D570;0045;0045; +1D571;1D571;1D571;0046;0046; +1D572;1D572;1D572;0047;0047; +1D573;1D573;1D573;0048;0048; +1D574;1D574;1D574;0049;0049; +1D575;1D575;1D575;004A;004A; +1D576;1D576;1D576;004B;004B; +1D577;1D577;1D577;004C;004C; +1D578;1D578;1D578;004D;004D; +1D579;1D579;1D579;004E;004E; +1D57A;1D57A;1D57A;004F;004F; +1D57B;1D57B;1D57B;0050;0050; +1D57C;1D57C;1D57C;0051;0051; +1D57D;1D57D;1D57D;0052;0052; +1D57E;1D57E;1D57E;0053;0053; +1D57F;1D57F;1D57F;0054;0054; +1D580;1D580;1D580;0055;0055; +1D581;1D581;1D581;0056;0056; +1D582;1D582;1D582;0057;0057; +1D583;1D583;1D583;0058;0058; +1D584;1D584;1D584;0059;0059; +1D585;1D585;1D585;005A;005A; +1D586;1D586;1D586;0061;0061; +1D587;1D587;1D587;0062;0062; +1D588;1D588;1D588;0063;0063; +1D589;1D589;1D589;0064;0064; +1D58A;1D58A;1D58A;0065;0065; +1D58B;1D58B;1D58B;0066;0066; +1D58C;1D58C;1D58C;0067;0067; +1D58D;1D58D;1D58D;0068;0068; +1D58E;1D58E;1D58E;0069;0069; +1D58F;1D58F;1D58F;006A;006A; +1D590;1D590;1D590;006B;006B; +1D591;1D591;1D591;006C;006C; +1D592;1D592;1D592;006D;006D; +1D593;1D593;1D593;006E;006E; +1D594;1D594;1D594;006F;006F; +1D595;1D595;1D595;0070;0070; +1D596;1D596;1D596;0071;0071; +1D597;1D597;1D597;0072;0072; +1D598;1D598;1D598;0073;0073; +1D599;1D599;1D599;0074;0074; +1D59A;1D59A;1D59A;0075;0075; +1D59B;1D59B;1D59B;0076;0076; +1D59C;1D59C;1D59C;0077;0077; +1D59D;1D59D;1D59D;0078;0078; +1D59E;1D59E;1D59E;0079;0079; +1D59F;1D59F;1D59F;007A;007A; +1D5A0;1D5A0;1D5A0;0041;0041; +1D5A1;1D5A1;1D5A1;0042;0042; +1D5A2;1D5A2;1D5A2;0043;0043; +1D5A3;1D5A3;1D5A3;0044;0044; +1D5A4;1D5A4;1D5A4;0045;0045; +1D5A5;1D5A5;1D5A5;0046;0046; +1D5A6;1D5A6;1D5A6;0047;0047; +1D5A7;1D5A7;1D5A7;0048;0048; +1D5A8;1D5A8;1D5A8;0049;0049; +1D5A9;1D5A9;1D5A9;004A;004A; +1D5AA;1D5AA;1D5AA;004B;004B; +1D5AB;1D5AB;1D5AB;004C;004C; +1D5AC;1D5AC;1D5AC;004D;004D; +1D5AD;1D5AD;1D5AD;004E;004E; +1D5AE;1D5AE;1D5AE;004F;004F; +1D5AF;1D5AF;1D5AF;0050;0050; +1D5B0;1D5B0;1D5B0;0051;0051; +1D5B1;1D5B1;1D5B1;0052;0052; +1D5B2;1D5B2;1D5B2;0053;0053; +1D5B3;1D5B3;1D5B3;0054;0054; +1D5B4;1D5B4;1D5B4;0055;0055; +1D5B5;1D5B5;1D5B5;0056;0056; +1D5B6;1D5B6;1D5B6;0057;0057; +1D5B7;1D5B7;1D5B7;0058;0058; +1D5B8;1D5B8;1D5B8;0059;0059; +1D5B9;1D5B9;1D5B9;005A;005A; +1D5BA;1D5BA;1D5BA;0061;0061; +1D5BB;1D5BB;1D5BB;0062;0062; +1D5BC;1D5BC;1D5BC;0063;0063; +1D5BD;1D5BD;1D5BD;0064;0064; +1D5BE;1D5BE;1D5BE;0065;0065; +1D5BF;1D5BF;1D5BF;0066;0066; +1D5C0;1D5C0;1D5C0;0067;0067; +1D5C1;1D5C1;1D5C1;0068;0068; +1D5C2;1D5C2;1D5C2;0069;0069; +1D5C3;1D5C3;1D5C3;006A;006A; +1D5C4;1D5C4;1D5C4;006B;006B; +1D5C5;1D5C5;1D5C5;006C;006C; +1D5C6;1D5C6;1D5C6;006D;006D; +1D5C7;1D5C7;1D5C7;006E;006E; +1D5C8;1D5C8;1D5C8;006F;006F; +1D5C9;1D5C9;1D5C9;0070;0070; +1D5CA;1D5CA;1D5CA;0071;0071; +1D5CB;1D5CB;1D5CB;0072;0072; +1D5CC;1D5CC;1D5CC;0073;0073; +1D5CD;1D5CD;1D5CD;0074;0074; +1D5CE;1D5CE;1D5CE;0075;0075; +1D5CF;1D5CF;1D5CF;0076;0076; +1D5D0;1D5D0;1D5D0;0077;0077; +1D5D1;1D5D1;1D5D1;0078;0078; +1D5D2;1D5D2;1D5D2;0079;0079; +1D5D3;1D5D3;1D5D3;007A;007A; +1D5D4;1D5D4;1D5D4;0041;0041; +1D5D5;1D5D5;1D5D5;0042;0042; +1D5D6;1D5D6;1D5D6;0043;0043; +1D5D7;1D5D7;1D5D7;0044;0044; +1D5D8;1D5D8;1D5D8;0045;0045; +1D5D9;1D5D9;1D5D9;0046;0046; +1D5DA;1D5DA;1D5DA;0047;0047; +1D5DB;1D5DB;1D5DB;0048;0048; +1D5DC;1D5DC;1D5DC;0049;0049; +1D5DD;1D5DD;1D5DD;004A;004A; +1D5DE;1D5DE;1D5DE;004B;004B; +1D5DF;1D5DF;1D5DF;004C;004C; +1D5E0;1D5E0;1D5E0;004D;004D; +1D5E1;1D5E1;1D5E1;004E;004E; +1D5E2;1D5E2;1D5E2;004F;004F; +1D5E3;1D5E3;1D5E3;0050;0050; +1D5E4;1D5E4;1D5E4;0051;0051; +1D5E5;1D5E5;1D5E5;0052;0052; +1D5E6;1D5E6;1D5E6;0053;0053; +1D5E7;1D5E7;1D5E7;0054;0054; +1D5E8;1D5E8;1D5E8;0055;0055; +1D5E9;1D5E9;1D5E9;0056;0056; +1D5EA;1D5EA;1D5EA;0057;0057; +1D5EB;1D5EB;1D5EB;0058;0058; +1D5EC;1D5EC;1D5EC;0059;0059; +1D5ED;1D5ED;1D5ED;005A;005A; +1D5EE;1D5EE;1D5EE;0061;0061; +1D5EF;1D5EF;1D5EF;0062;0062; +1D5F0;1D5F0;1D5F0;0063;0063; +1D5F1;1D5F1;1D5F1;0064;0064; +1D5F2;1D5F2;1D5F2;0065;0065; +1D5F3;1D5F3;1D5F3;0066;0066; +1D5F4;1D5F4;1D5F4;0067;0067; +1D5F5;1D5F5;1D5F5;0068;0068; +1D5F6;1D5F6;1D5F6;0069;0069; +1D5F7;1D5F7;1D5F7;006A;006A; +1D5F8;1D5F8;1D5F8;006B;006B; +1D5F9;1D5F9;1D5F9;006C;006C; +1D5FA;1D5FA;1D5FA;006D;006D; +1D5FB;1D5FB;1D5FB;006E;006E; +1D5FC;1D5FC;1D5FC;006F;006F; +1D5FD;1D5FD;1D5FD;0070;0070; +1D5FE;1D5FE;1D5FE;0071;0071; +1D5FF;1D5FF;1D5FF;0072;0072; +1D600;1D600;1D600;0073;0073; +1D601;1D601;1D601;0074;0074; +1D602;1D602;1D602;0075;0075; +1D603;1D603;1D603;0076;0076; +1D604;1D604;1D604;0077;0077; +1D605;1D605;1D605;0078;0078; +1D606;1D606;1D606;0079;0079; +1D607;1D607;1D607;007A;007A; +1D608;1D608;1D608;0041;0041; +1D609;1D609;1D609;0042;0042; +1D60A;1D60A;1D60A;0043;0043; +1D60B;1D60B;1D60B;0044;0044; +1D60C;1D60C;1D60C;0045;0045; +1D60D;1D60D;1D60D;0046;0046; +1D60E;1D60E;1D60E;0047;0047; +1D60F;1D60F;1D60F;0048;0048; +1D610;1D610;1D610;0049;0049; +1D611;1D611;1D611;004A;004A; +1D612;1D612;1D612;004B;004B; +1D613;1D613;1D613;004C;004C; +1D614;1D614;1D614;004D;004D; +1D615;1D615;1D615;004E;004E; +1D616;1D616;1D616;004F;004F; +1D617;1D617;1D617;0050;0050; +1D618;1D618;1D618;0051;0051; +1D619;1D619;1D619;0052;0052; +1D61A;1D61A;1D61A;0053;0053; +1D61B;1D61B;1D61B;0054;0054; +1D61C;1D61C;1D61C;0055;0055; +1D61D;1D61D;1D61D;0056;0056; +1D61E;1D61E;1D61E;0057;0057; +1D61F;1D61F;1D61F;0058;0058; +1D620;1D620;1D620;0059;0059; +1D621;1D621;1D621;005A;005A; +1D622;1D622;1D622;0061;0061; +1D623;1D623;1D623;0062;0062; +1D624;1D624;1D624;0063;0063; +1D625;1D625;1D625;0064;0064; +1D626;1D626;1D626;0065;0065; +1D627;1D627;1D627;0066;0066; +1D628;1D628;1D628;0067;0067; +1D629;1D629;1D629;0068;0068; +1D62A;1D62A;1D62A;0069;0069; +1D62B;1D62B;1D62B;006A;006A; +1D62C;1D62C;1D62C;006B;006B; +1D62D;1D62D;1D62D;006C;006C; +1D62E;1D62E;1D62E;006D;006D; +1D62F;1D62F;1D62F;006E;006E; +1D630;1D630;1D630;006F;006F; +1D631;1D631;1D631;0070;0070; +1D632;1D632;1D632;0071;0071; +1D633;1D633;1D633;0072;0072; +1D634;1D634;1D634;0073;0073; +1D635;1D635;1D635;0074;0074; +1D636;1D636;1D636;0075;0075; +1D637;1D637;1D637;0076;0076; +1D638;1D638;1D638;0077;0077; +1D639;1D639;1D639;0078;0078; +1D63A;1D63A;1D63A;0079;0079; +1D63B;1D63B;1D63B;007A;007A; +1D63C;1D63C;1D63C;0041;0041; +1D63D;1D63D;1D63D;0042;0042; +1D63E;1D63E;1D63E;0043;0043; +1D63F;1D63F;1D63F;0044;0044; +1D640;1D640;1D640;0045;0045; +1D641;1D641;1D641;0046;0046; +1D642;1D642;1D642;0047;0047; +1D643;1D643;1D643;0048;0048; +1D644;1D644;1D644;0049;0049; +1D645;1D645;1D645;004A;004A; +1D646;1D646;1D646;004B;004B; +1D647;1D647;1D647;004C;004C; +1D648;1D648;1D648;004D;004D; +1D649;1D649;1D649;004E;004E; +1D64A;1D64A;1D64A;004F;004F; +1D64B;1D64B;1D64B;0050;0050; +1D64C;1D64C;1D64C;0051;0051; +1D64D;1D64D;1D64D;0052;0052; +1D64E;1D64E;1D64E;0053;0053; +1D64F;1D64F;1D64F;0054;0054; +1D650;1D650;1D650;0055;0055; +1D651;1D651;1D651;0056;0056; +1D652;1D652;1D652;0057;0057; +1D653;1D653;1D653;0058;0058; +1D654;1D654;1D654;0059;0059; +1D655;1D655;1D655;005A;005A; +1D656;1D656;1D656;0061;0061; +1D657;1D657;1D657;0062;0062; +1D658;1D658;1D658;0063;0063; +1D659;1D659;1D659;0064;0064; +1D65A;1D65A;1D65A;0065;0065; +1D65B;1D65B;1D65B;0066;0066; +1D65C;1D65C;1D65C;0067;0067; +1D65D;1D65D;1D65D;0068;0068; +1D65E;1D65E;1D65E;0069;0069; +1D65F;1D65F;1D65F;006A;006A; +1D660;1D660;1D660;006B;006B; +1D661;1D661;1D661;006C;006C; +1D662;1D662;1D662;006D;006D; +1D663;1D663;1D663;006E;006E; +1D664;1D664;1D664;006F;006F; +1D665;1D665;1D665;0070;0070; +1D666;1D666;1D666;0071;0071; +1D667;1D667;1D667;0072;0072; +1D668;1D668;1D668;0073;0073; +1D669;1D669;1D669;0074;0074; +1D66A;1D66A;1D66A;0075;0075; +1D66B;1D66B;1D66B;0076;0076; +1D66C;1D66C;1D66C;0077;0077; +1D66D;1D66D;1D66D;0078;0078; +1D66E;1D66E;1D66E;0079;0079; +1D66F;1D66F;1D66F;007A;007A; +1D670;1D670;1D670;0041;0041; +1D671;1D671;1D671;0042;0042; +1D672;1D672;1D672;0043;0043; +1D673;1D673;1D673;0044;0044; +1D674;1D674;1D674;0045;0045; +1D675;1D675;1D675;0046;0046; +1D676;1D676;1D676;0047;0047; +1D677;1D677;1D677;0048;0048; +1D678;1D678;1D678;0049;0049; +1D679;1D679;1D679;004A;004A; +1D67A;1D67A;1D67A;004B;004B; +1D67B;1D67B;1D67B;004C;004C; +1D67C;1D67C;1D67C;004D;004D; +1D67D;1D67D;1D67D;004E;004E; +1D67E;1D67E;1D67E;004F;004F; +1D67F;1D67F;1D67F;0050;0050; +1D680;1D680;1D680;0051;0051; +1D681;1D681;1D681;0052;0052; +1D682;1D682;1D682;0053;0053; +1D683;1D683;1D683;0054;0054; +1D684;1D684;1D684;0055;0055; +1D685;1D685;1D685;0056;0056; +1D686;1D686;1D686;0057;0057; +1D687;1D687;1D687;0058;0058; +1D688;1D688;1D688;0059;0059; +1D689;1D689;1D689;005A;005A; +1D68A;1D68A;1D68A;0061;0061; +1D68B;1D68B;1D68B;0062;0062; +1D68C;1D68C;1D68C;0063;0063; +1D68D;1D68D;1D68D;0064;0064; +1D68E;1D68E;1D68E;0065;0065; +1D68F;1D68F;1D68F;0066;0066; +1D690;1D690;1D690;0067;0067; +1D691;1D691;1D691;0068;0068; +1D692;1D692;1D692;0069;0069; +1D693;1D693;1D693;006A;006A; +1D694;1D694;1D694;006B;006B; +1D695;1D695;1D695;006C;006C; +1D696;1D696;1D696;006D;006D; +1D697;1D697;1D697;006E;006E; +1D698;1D698;1D698;006F;006F; +1D699;1D699;1D699;0070;0070; +1D69A;1D69A;1D69A;0071;0071; +1D69B;1D69B;1D69B;0072;0072; +1D69C;1D69C;1D69C;0073;0073; +1D69D;1D69D;1D69D;0074;0074; +1D69E;1D69E;1D69E;0075;0075; +1D69F;1D69F;1D69F;0076;0076; +1D6A0;1D6A0;1D6A0;0077;0077; +1D6A1;1D6A1;1D6A1;0078;0078; +1D6A2;1D6A2;1D6A2;0079;0079; +1D6A3;1D6A3;1D6A3;007A;007A; +1D6A4;1D6A4;1D6A4;0131;0131; +1D6A5;1D6A5;1D6A5;0237;0237; +1D6A8;1D6A8;1D6A8;0391;0391; +1D6A9;1D6A9;1D6A9;0392;0392; +1D6AA;1D6AA;1D6AA;0393;0393; +1D6AB;1D6AB;1D6AB;0394;0394; +1D6AC;1D6AC;1D6AC;0395;0395; +1D6AD;1D6AD;1D6AD;0396;0396; +1D6AE;1D6AE;1D6AE;0397;0397; +1D6AF;1D6AF;1D6AF;0398;0398; +1D6B0;1D6B0;1D6B0;0399;0399; +1D6B1;1D6B1;1D6B1;039A;039A; +1D6B2;1D6B2;1D6B2;039B;039B; +1D6B3;1D6B3;1D6B3;039C;039C; +1D6B4;1D6B4;1D6B4;039D;039D; +1D6B5;1D6B5;1D6B5;039E;039E; +1D6B6;1D6B6;1D6B6;039F;039F; +1D6B7;1D6B7;1D6B7;03A0;03A0; +1D6B8;1D6B8;1D6B8;03A1;03A1; +1D6B9;1D6B9;1D6B9;0398;0398; +1D6BA;1D6BA;1D6BA;03A3;03A3; +1D6BB;1D6BB;1D6BB;03A4;03A4; +1D6BC;1D6BC;1D6BC;03A5;03A5; +1D6BD;1D6BD;1D6BD;03A6;03A6; +1D6BE;1D6BE;1D6BE;03A7;03A7; +1D6BF;1D6BF;1D6BF;03A8;03A8; +1D6C0;1D6C0;1D6C0;03A9;03A9; +1D6C1;1D6C1;1D6C1;2207;2207; +1D6C2;1D6C2;1D6C2;03B1;03B1; +1D6C3;1D6C3;1D6C3;03B2;03B2; +1D6C4;1D6C4;1D6C4;03B3;03B3; +1D6C5;1D6C5;1D6C5;03B4;03B4; +1D6C6;1D6C6;1D6C6;03B5;03B5; +1D6C7;1D6C7;1D6C7;03B6;03B6; +1D6C8;1D6C8;1D6C8;03B7;03B7; +1D6C9;1D6C9;1D6C9;03B8;03B8; +1D6CA;1D6CA;1D6CA;03B9;03B9; +1D6CB;1D6CB;1D6CB;03BA;03BA; +1D6CC;1D6CC;1D6CC;03BB;03BB; +1D6CD;1D6CD;1D6CD;03BC;03BC; +1D6CE;1D6CE;1D6CE;03BD;03BD; +1D6CF;1D6CF;1D6CF;03BE;03BE; +1D6D0;1D6D0;1D6D0;03BF;03BF; +1D6D1;1D6D1;1D6D1;03C0;03C0; +1D6D2;1D6D2;1D6D2;03C1;03C1; +1D6D3;1D6D3;1D6D3;03C2;03C2; +1D6D4;1D6D4;1D6D4;03C3;03C3; +1D6D5;1D6D5;1D6D5;03C4;03C4; +1D6D6;1D6D6;1D6D6;03C5;03C5; +1D6D7;1D6D7;1D6D7;03C6;03C6; +1D6D8;1D6D8;1D6D8;03C7;03C7; +1D6D9;1D6D9;1D6D9;03C8;03C8; +1D6DA;1D6DA;1D6DA;03C9;03C9; +1D6DB;1D6DB;1D6DB;2202;2202; +1D6DC;1D6DC;1D6DC;03B5;03B5; +1D6DD;1D6DD;1D6DD;03B8;03B8; +1D6DE;1D6DE;1D6DE;03BA;03BA; +1D6DF;1D6DF;1D6DF;03C6;03C6; +1D6E0;1D6E0;1D6E0;03C1;03C1; +1D6E1;1D6E1;1D6E1;03C0;03C0; +1D6E2;1D6E2;1D6E2;0391;0391; +1D6E3;1D6E3;1D6E3;0392;0392; +1D6E4;1D6E4;1D6E4;0393;0393; +1D6E5;1D6E5;1D6E5;0394;0394; +1D6E6;1D6E6;1D6E6;0395;0395; +1D6E7;1D6E7;1D6E7;0396;0396; +1D6E8;1D6E8;1D6E8;0397;0397; +1D6E9;1D6E9;1D6E9;0398;0398; +1D6EA;1D6EA;1D6EA;0399;0399; +1D6EB;1D6EB;1D6EB;039A;039A; +1D6EC;1D6EC;1D6EC;039B;039B; +1D6ED;1D6ED;1D6ED;039C;039C; +1D6EE;1D6EE;1D6EE;039D;039D; +1D6EF;1D6EF;1D6EF;039E;039E; +1D6F0;1D6F0;1D6F0;039F;039F; +1D6F1;1D6F1;1D6F1;03A0;03A0; +1D6F2;1D6F2;1D6F2;03A1;03A1; +1D6F3;1D6F3;1D6F3;0398;0398; +1D6F4;1D6F4;1D6F4;03A3;03A3; +1D6F5;1D6F5;1D6F5;03A4;03A4; +1D6F6;1D6F6;1D6F6;03A5;03A5; +1D6F7;1D6F7;1D6F7;03A6;03A6; +1D6F8;1D6F8;1D6F8;03A7;03A7; +1D6F9;1D6F9;1D6F9;03A8;03A8; +1D6FA;1D6FA;1D6FA;03A9;03A9; +1D6FB;1D6FB;1D6FB;2207;2207; +1D6FC;1D6FC;1D6FC;03B1;03B1; +1D6FD;1D6FD;1D6FD;03B2;03B2; +1D6FE;1D6FE;1D6FE;03B3;03B3; +1D6FF;1D6FF;1D6FF;03B4;03B4; +1D700;1D700;1D700;03B5;03B5; +1D701;1D701;1D701;03B6;03B6; +1D702;1D702;1D702;03B7;03B7; +1D703;1D703;1D703;03B8;03B8; +1D704;1D704;1D704;03B9;03B9; +1D705;1D705;1D705;03BA;03BA; +1D706;1D706;1D706;03BB;03BB; +1D707;1D707;1D707;03BC;03BC; +1D708;1D708;1D708;03BD;03BD; +1D709;1D709;1D709;03BE;03BE; +1D70A;1D70A;1D70A;03BF;03BF; +1D70B;1D70B;1D70B;03C0;03C0; +1D70C;1D70C;1D70C;03C1;03C1; +1D70D;1D70D;1D70D;03C2;03C2; +1D70E;1D70E;1D70E;03C3;03C3; +1D70F;1D70F;1D70F;03C4;03C4; +1D710;1D710;1D710;03C5;03C5; +1D711;1D711;1D711;03C6;03C6; +1D712;1D712;1D712;03C7;03C7; +1D713;1D713;1D713;03C8;03C8; +1D714;1D714;1D714;03C9;03C9; +1D715;1D715;1D715;2202;2202; +1D716;1D716;1D716;03B5;03B5; +1D717;1D717;1D717;03B8;03B8; +1D718;1D718;1D718;03BA;03BA; +1D719;1D719;1D719;03C6;03C6; +1D71A;1D71A;1D71A;03C1;03C1; +1D71B;1D71B;1D71B;03C0;03C0; +1D71C;1D71C;1D71C;0391;0391; +1D71D;1D71D;1D71D;0392;0392; +1D71E;1D71E;1D71E;0393;0393; +1D71F;1D71F;1D71F;0394;0394; +1D720;1D720;1D720;0395;0395; +1D721;1D721;1D721;0396;0396; +1D722;1D722;1D722;0397;0397; +1D723;1D723;1D723;0398;0398; +1D724;1D724;1D724;0399;0399; +1D725;1D725;1D725;039A;039A; +1D726;1D726;1D726;039B;039B; +1D727;1D727;1D727;039C;039C; +1D728;1D728;1D728;039D;039D; +1D729;1D729;1D729;039E;039E; +1D72A;1D72A;1D72A;039F;039F; +1D72B;1D72B;1D72B;03A0;03A0; +1D72C;1D72C;1D72C;03A1;03A1; +1D72D;1D72D;1D72D;0398;0398; +1D72E;1D72E;1D72E;03A3;03A3; +1D72F;1D72F;1D72F;03A4;03A4; +1D730;1D730;1D730;03A5;03A5; +1D731;1D731;1D731;03A6;03A6; +1D732;1D732;1D732;03A7;03A7; +1D733;1D733;1D733;03A8;03A8; +1D734;1D734;1D734;03A9;03A9; +1D735;1D735;1D735;2207;2207; +1D736;1D736;1D736;03B1;03B1; +1D737;1D737;1D737;03B2;03B2; +1D738;1D738;1D738;03B3;03B3; +1D739;1D739;1D739;03B4;03B4; +1D73A;1D73A;1D73A;03B5;03B5; +1D73B;1D73B;1D73B;03B6;03B6; +1D73C;1D73C;1D73C;03B7;03B7; +1D73D;1D73D;1D73D;03B8;03B8; +1D73E;1D73E;1D73E;03B9;03B9; +1D73F;1D73F;1D73F;03BA;03BA; +1D740;1D740;1D740;03BB;03BB; +1D741;1D741;1D741;03BC;03BC; +1D742;1D742;1D742;03BD;03BD; +1D743;1D743;1D743;03BE;03BE; +1D744;1D744;1D744;03BF;03BF; +1D745;1D745;1D745;03C0;03C0; +1D746;1D746;1D746;03C1;03C1; +1D747;1D747;1D747;03C2;03C2; +1D748;1D748;1D748;03C3;03C3; +1D749;1D749;1D749;03C4;03C4; +1D74A;1D74A;1D74A;03C5;03C5; +1D74B;1D74B;1D74B;03C6;03C6; +1D74C;1D74C;1D74C;03C7;03C7; +1D74D;1D74D;1D74D;03C8;03C8; +1D74E;1D74E;1D74E;03C9;03C9; +1D74F;1D74F;1D74F;2202;2202; +1D750;1D750;1D750;03B5;03B5; +1D751;1D751;1D751;03B8;03B8; +1D752;1D752;1D752;03BA;03BA; +1D753;1D753;1D753;03C6;03C6; +1D754;1D754;1D754;03C1;03C1; +1D755;1D755;1D755;03C0;03C0; +1D756;1D756;1D756;0391;0391; +1D757;1D757;1D757;0392;0392; +1D758;1D758;1D758;0393;0393; +1D759;1D759;1D759;0394;0394; +1D75A;1D75A;1D75A;0395;0395; +1D75B;1D75B;1D75B;0396;0396; +1D75C;1D75C;1D75C;0397;0397; +1D75D;1D75D;1D75D;0398;0398; +1D75E;1D75E;1D75E;0399;0399; +1D75F;1D75F;1D75F;039A;039A; +1D760;1D760;1D760;039B;039B; +1D761;1D761;1D761;039C;039C; +1D762;1D762;1D762;039D;039D; +1D763;1D763;1D763;039E;039E; +1D764;1D764;1D764;039F;039F; +1D765;1D765;1D765;03A0;03A0; +1D766;1D766;1D766;03A1;03A1; +1D767;1D767;1D767;0398;0398; +1D768;1D768;1D768;03A3;03A3; +1D769;1D769;1D769;03A4;03A4; +1D76A;1D76A;1D76A;03A5;03A5; +1D76B;1D76B;1D76B;03A6;03A6; +1D76C;1D76C;1D76C;03A7;03A7; +1D76D;1D76D;1D76D;03A8;03A8; +1D76E;1D76E;1D76E;03A9;03A9; +1D76F;1D76F;1D76F;2207;2207; +1D770;1D770;1D770;03B1;03B1; +1D771;1D771;1D771;03B2;03B2; +1D772;1D772;1D772;03B3;03B3; +1D773;1D773;1D773;03B4;03B4; +1D774;1D774;1D774;03B5;03B5; +1D775;1D775;1D775;03B6;03B6; +1D776;1D776;1D776;03B7;03B7; +1D777;1D777;1D777;03B8;03B8; +1D778;1D778;1D778;03B9;03B9; +1D779;1D779;1D779;03BA;03BA; +1D77A;1D77A;1D77A;03BB;03BB; +1D77B;1D77B;1D77B;03BC;03BC; +1D77C;1D77C;1D77C;03BD;03BD; +1D77D;1D77D;1D77D;03BE;03BE; +1D77E;1D77E;1D77E;03BF;03BF; +1D77F;1D77F;1D77F;03C0;03C0; +1D780;1D780;1D780;03C1;03C1; +1D781;1D781;1D781;03C2;03C2; +1D782;1D782;1D782;03C3;03C3; +1D783;1D783;1D783;03C4;03C4; +1D784;1D784;1D784;03C5;03C5; +1D785;1D785;1D785;03C6;03C6; +1D786;1D786;1D786;03C7;03C7; +1D787;1D787;1D787;03C8;03C8; +1D788;1D788;1D788;03C9;03C9; +1D789;1D789;1D789;2202;2202; +1D78A;1D78A;1D78A;03B5;03B5; +1D78B;1D78B;1D78B;03B8;03B8; +1D78C;1D78C;1D78C;03BA;03BA; +1D78D;1D78D;1D78D;03C6;03C6; +1D78E;1D78E;1D78E;03C1;03C1; +1D78F;1D78F;1D78F;03C0;03C0; +1D790;1D790;1D790;0391;0391; +1D791;1D791;1D791;0392;0392; +1D792;1D792;1D792;0393;0393; +1D793;1D793;1D793;0394;0394; +1D794;1D794;1D794;0395;0395; +1D795;1D795;1D795;0396;0396; +1D796;1D796;1D796;0397;0397; +1D797;1D797;1D797;0398;0398; +1D798;1D798;1D798;0399;0399; +1D799;1D799;1D799;039A;039A; +1D79A;1D79A;1D79A;039B;039B; +1D79B;1D79B;1D79B;039C;039C; +1D79C;1D79C;1D79C;039D;039D; +1D79D;1D79D;1D79D;039E;039E; +1D79E;1D79E;1D79E;039F;039F; +1D79F;1D79F;1D79F;03A0;03A0; +1D7A0;1D7A0;1D7A0;03A1;03A1; +1D7A1;1D7A1;1D7A1;0398;0398; +1D7A2;1D7A2;1D7A2;03A3;03A3; +1D7A3;1D7A3;1D7A3;03A4;03A4; +1D7A4;1D7A4;1D7A4;03A5;03A5; +1D7A5;1D7A5;1D7A5;03A6;03A6; +1D7A6;1D7A6;1D7A6;03A7;03A7; +1D7A7;1D7A7;1D7A7;03A8;03A8; +1D7A8;1D7A8;1D7A8;03A9;03A9; +1D7A9;1D7A9;1D7A9;2207;2207; +1D7AA;1D7AA;1D7AA;03B1;03B1; +1D7AB;1D7AB;1D7AB;03B2;03B2; +1D7AC;1D7AC;1D7AC;03B3;03B3; +1D7AD;1D7AD;1D7AD;03B4;03B4; +1D7AE;1D7AE;1D7AE;03B5;03B5; +1D7AF;1D7AF;1D7AF;03B6;03B6; +1D7B0;1D7B0;1D7B0;03B7;03B7; +1D7B1;1D7B1;1D7B1;03B8;03B8; +1D7B2;1D7B2;1D7B2;03B9;03B9; +1D7B3;1D7B3;1D7B3;03BA;03BA; +1D7B4;1D7B4;1D7B4;03BB;03BB; +1D7B5;1D7B5;1D7B5;03BC;03BC; +1D7B6;1D7B6;1D7B6;03BD;03BD; +1D7B7;1D7B7;1D7B7;03BE;03BE; +1D7B8;1D7B8;1D7B8;03BF;03BF; +1D7B9;1D7B9;1D7B9;03C0;03C0; +1D7BA;1D7BA;1D7BA;03C1;03C1; +1D7BB;1D7BB;1D7BB;03C2;03C2; +1D7BC;1D7BC;1D7BC;03C3;03C3; +1D7BD;1D7BD;1D7BD;03C4;03C4; +1D7BE;1D7BE;1D7BE;03C5;03C5; +1D7BF;1D7BF;1D7BF;03C6;03C6; +1D7C0;1D7C0;1D7C0;03C7;03C7; +1D7C1;1D7C1;1D7C1;03C8;03C8; +1D7C2;1D7C2;1D7C2;03C9;03C9; +1D7C3;1D7C3;1D7C3;2202;2202; +1D7C4;1D7C4;1D7C4;03B5;03B5; +1D7C5;1D7C5;1D7C5;03B8;03B8; +1D7C6;1D7C6;1D7C6;03BA;03BA; +1D7C7;1D7C7;1D7C7;03C6;03C6; +1D7C8;1D7C8;1D7C8;03C1;03C1; +1D7C9;1D7C9;1D7C9;03C0;03C0; +1D7CA;1D7CA;1D7CA;03DC;03DC; +1D7CB;1D7CB;1D7CB;03DD;03DD; +1D7CE;1D7CE;1D7CE;0030;0030; +1D7CF;1D7CF;1D7CF;0031;0031; +1D7D0;1D7D0;1D7D0;0032;0032; +1D7D1;1D7D1;1D7D1;0033;0033; +1D7D2;1D7D2;1D7D2;0034;0034; +1D7D3;1D7D3;1D7D3;0035;0035; +1D7D4;1D7D4;1D7D4;0036;0036; +1D7D5;1D7D5;1D7D5;0037;0037; +1D7D6;1D7D6;1D7D6;0038;0038; +1D7D7;1D7D7;1D7D7;0039;0039; +1D7D8;1D7D8;1D7D8;0030;0030; +1D7D9;1D7D9;1D7D9;0031;0031; +1D7DA;1D7DA;1D7DA;0032;0032; +1D7DB;1D7DB;1D7DB;0033;0033; +1D7DC;1D7DC;1D7DC;0034;0034; +1D7DD;1D7DD;1D7DD;0035;0035; +1D7DE;1D7DE;1D7DE;0036;0036; +1D7DF;1D7DF;1D7DF;0037;0037; +1D7E0;1D7E0;1D7E0;0038;0038; +1D7E1;1D7E1;1D7E1;0039;0039; +1D7E2;1D7E2;1D7E2;0030;0030; +1D7E3;1D7E3;1D7E3;0031;0031; +1D7E4;1D7E4;1D7E4;0032;0032; +1D7E5;1D7E5;1D7E5;0033;0033; +1D7E6;1D7E6;1D7E6;0034;0034; +1D7E7;1D7E7;1D7E7;0035;0035; +1D7E8;1D7E8;1D7E8;0036;0036; +1D7E9;1D7E9;1D7E9;0037;0037; +1D7EA;1D7EA;1D7EA;0038;0038; +1D7EB;1D7EB;1D7EB;0039;0039; +1D7EC;1D7EC;1D7EC;0030;0030; +1D7ED;1D7ED;1D7ED;0031;0031; +1D7EE;1D7EE;1D7EE;0032;0032; +1D7EF;1D7EF;1D7EF;0033;0033; +1D7F0;1D7F0;1D7F0;0034;0034; +1D7F1;1D7F1;1D7F1;0035;0035; +1D7F2;1D7F2;1D7F2;0036;0036; +1D7F3;1D7F3;1D7F3;0037;0037; +1D7F4;1D7F4;1D7F4;0038;0038; +1D7F5;1D7F5;1D7F5;0039;0039; +1D7F6;1D7F6;1D7F6;0030;0030; +1D7F7;1D7F7;1D7F7;0031;0031; +1D7F8;1D7F8;1D7F8;0032;0032; +1D7F9;1D7F9;1D7F9;0033;0033; +1D7FA;1D7FA;1D7FA;0034;0034; +1D7FB;1D7FB;1D7FB;0035;0035; +1D7FC;1D7FC;1D7FC;0036;0036; +1D7FD;1D7FD;1D7FD;0037;0037; +1D7FE;1D7FE;1D7FE;0038;0038; +1D7FF;1D7FF;1D7FF;0039;0039; +1EE00;1EE00;1EE00;0627;0627; +1EE01;1EE01;1EE01;0628;0628; +1EE02;1EE02;1EE02;062C;062C; +1EE03;1EE03;1EE03;062F;062F; +1EE05;1EE05;1EE05;0648;0648; +1EE06;1EE06;1EE06;0632;0632; +1EE07;1EE07;1EE07;062D;062D; +1EE08;1EE08;1EE08;0637;0637; +1EE09;1EE09;1EE09;064A;064A; +1EE0A;1EE0A;1EE0A;0643;0643; +1EE0B;1EE0B;1EE0B;0644;0644; +1EE0C;1EE0C;1EE0C;0645;0645; +1EE0D;1EE0D;1EE0D;0646;0646; +1EE0E;1EE0E;1EE0E;0633;0633; +1EE0F;1EE0F;1EE0F;0639;0639; +1EE10;1EE10;1EE10;0641;0641; +1EE11;1EE11;1EE11;0635;0635; +1EE12;1EE12;1EE12;0642;0642; +1EE13;1EE13;1EE13;0631;0631; +1EE14;1EE14;1EE14;0634;0634; +1EE15;1EE15;1EE15;062A;062A; +1EE16;1EE16;1EE16;062B;062B; +1EE17;1EE17;1EE17;062E;062E; +1EE18;1EE18;1EE18;0630;0630; +1EE19;1EE19;1EE19;0636;0636; +1EE1A;1EE1A;1EE1A;0638;0638; +1EE1B;1EE1B;1EE1B;063A;063A; +1EE1C;1EE1C;1EE1C;066E;066E; +1EE1D;1EE1D;1EE1D;06BA;06BA; +1EE1E;1EE1E;1EE1E;06A1;06A1; +1EE1F;1EE1F;1EE1F;066F;066F; +1EE21;1EE21;1EE21;0628;0628; +1EE22;1EE22;1EE22;062C;062C; +1EE24;1EE24;1EE24;0647;0647; +1EE27;1EE27;1EE27;062D;062D; +1EE29;1EE29;1EE29;064A;064A; +1EE2A;1EE2A;1EE2A;0643;0643; +1EE2B;1EE2B;1EE2B;0644;0644; +1EE2C;1EE2C;1EE2C;0645;0645; +1EE2D;1EE2D;1EE2D;0646;0646; +1EE2E;1EE2E;1EE2E;0633;0633; +1EE2F;1EE2F;1EE2F;0639;0639; +1EE30;1EE30;1EE30;0641;0641; +1EE31;1EE31;1EE31;0635;0635; +1EE32;1EE32;1EE32;0642;0642; +1EE34;1EE34;1EE34;0634;0634; +1EE35;1EE35;1EE35;062A;062A; +1EE36;1EE36;1EE36;062B;062B; +1EE37;1EE37;1EE37;062E;062E; +1EE39;1EE39;1EE39;0636;0636; +1EE3B;1EE3B;1EE3B;063A;063A; +1EE42;1EE42;1EE42;062C;062C; +1EE47;1EE47;1EE47;062D;062D; +1EE49;1EE49;1EE49;064A;064A; +1EE4B;1EE4B;1EE4B;0644;0644; +1EE4D;1EE4D;1EE4D;0646;0646; +1EE4E;1EE4E;1EE4E;0633;0633; +1EE4F;1EE4F;1EE4F;0639;0639; +1EE51;1EE51;1EE51;0635;0635; +1EE52;1EE52;1EE52;0642;0642; +1EE54;1EE54;1EE54;0634;0634; +1EE57;1EE57;1EE57;062E;062E; +1EE59;1EE59;1EE59;0636;0636; +1EE5B;1EE5B;1EE5B;063A;063A; +1EE5D;1EE5D;1EE5D;06BA;06BA; +1EE5F;1EE5F;1EE5F;066F;066F; +1EE61;1EE61;1EE61;0628;0628; +1EE62;1EE62;1EE62;062C;062C; +1EE64;1EE64;1EE64;0647;0647; +1EE67;1EE67;1EE67;062D;062D; +1EE68;1EE68;1EE68;0637;0637; +1EE69;1EE69;1EE69;064A;064A; +1EE6A;1EE6A;1EE6A;0643;0643; +1EE6C;1EE6C;1EE6C;0645;0645; +1EE6D;1EE6D;1EE6D;0646;0646; +1EE6E;1EE6E;1EE6E;0633;0633; +1EE6F;1EE6F;1EE6F;0639;0639; +1EE70;1EE70;1EE70;0641;0641; +1EE71;1EE71;1EE71;0635;0635; +1EE72;1EE72;1EE72;0642;0642; +1EE74;1EE74;1EE74;0634;0634; +1EE75;1EE75;1EE75;062A;062A; +1EE76;1EE76;1EE76;062B;062B; +1EE77;1EE77;1EE77;062E;062E; +1EE79;1EE79;1EE79;0636;0636; +1EE7A;1EE7A;1EE7A;0638;0638; +1EE7B;1EE7B;1EE7B;063A;063A; +1EE7C;1EE7C;1EE7C;066E;066E; +1EE7E;1EE7E;1EE7E;06A1;06A1; +1EE80;1EE80;1EE80;0627;0627; +1EE81;1EE81;1EE81;0628;0628; +1EE82;1EE82;1EE82;062C;062C; +1EE83;1EE83;1EE83;062F;062F; +1EE84;1EE84;1EE84;0647;0647; +1EE85;1EE85;1EE85;0648;0648; +1EE86;1EE86;1EE86;0632;0632; +1EE87;1EE87;1EE87;062D;062D; +1EE88;1EE88;1EE88;0637;0637; +1EE89;1EE89;1EE89;064A;064A; +1EE8B;1EE8B;1EE8B;0644;0644; +1EE8C;1EE8C;1EE8C;0645;0645; +1EE8D;1EE8D;1EE8D;0646;0646; +1EE8E;1EE8E;1EE8E;0633;0633; +1EE8F;1EE8F;1EE8F;0639;0639; +1EE90;1EE90;1EE90;0641;0641; +1EE91;1EE91;1EE91;0635;0635; +1EE92;1EE92;1EE92;0642;0642; +1EE93;1EE93;1EE93;0631;0631; +1EE94;1EE94;1EE94;0634;0634; +1EE95;1EE95;1EE95;062A;062A; +1EE96;1EE96;1EE96;062B;062B; +1EE97;1EE97;1EE97;062E;062E; +1EE98;1EE98;1EE98;0630;0630; +1EE99;1EE99;1EE99;0636;0636; +1EE9A;1EE9A;1EE9A;0638;0638; +1EE9B;1EE9B;1EE9B;063A;063A; +1EEA1;1EEA1;1EEA1;0628;0628; +1EEA2;1EEA2;1EEA2;062C;062C; +1EEA3;1EEA3;1EEA3;062F;062F; +1EEA5;1EEA5;1EEA5;0648;0648; +1EEA6;1EEA6;1EEA6;0632;0632; +1EEA7;1EEA7;1EEA7;062D;062D; +1EEA8;1EEA8;1EEA8;0637;0637; +1EEA9;1EEA9;1EEA9;064A;064A; +1EEAB;1EEAB;1EEAB;0644;0644; +1EEAC;1EEAC;1EEAC;0645;0645; +1EEAD;1EEAD;1EEAD;0646;0646; +1EEAE;1EEAE;1EEAE;0633;0633; +1EEAF;1EEAF;1EEAF;0639;0639; +1EEB0;1EEB0;1EEB0;0641;0641; +1EEB1;1EEB1;1EEB1;0635;0635; +1EEB2;1EEB2;1EEB2;0642;0642; +1EEB3;1EEB3;1EEB3;0631;0631; +1EEB4;1EEB4;1EEB4;0634;0634; +1EEB5;1EEB5;1EEB5;062A;062A; +1EEB6;1EEB6;1EEB6;062B;062B; +1EEB7;1EEB7;1EEB7;062E;062E; +1EEB8;1EEB8;1EEB8;0630;0630; +1EEB9;1EEB9;1EEB9;0636;0636; +1EEBA;1EEBA;1EEBA;0638;0638; +1EEBB;1EEBB;1EEBB;063A;063A; +1F100;1F100;1F100;0030 002E;0030 002E; +1F101;1F101;1F101;0030 002C;0030 002C; +1F102;1F102;1F102;0031 002C;0031 002C; +1F103;1F103;1F103;0032 002C;0032 002C; +1F104;1F104;1F104;0033 002C;0033 002C; +1F105;1F105;1F105;0034 002C;0034 002C; +1F106;1F106;1F106;0035 002C;0035 002C; +1F107;1F107;1F107;0036 002C;0036 002C; +1F108;1F108;1F108;0037 002C;0037 002C; +1F109;1F109;1F109;0038 002C;0038 002C; +1F10A;1F10A;1F10A;0039 002C;0039 002C; +1F110;1F110;1F110;0028 0041 0029;0028 0041 0029; +1F111;1F111;1F111;0028 0042 0029;0028 0042 0029; +1F112;1F112;1F112;0028 0043 0029;0028 0043 0029; +1F113;1F113;1F113;0028 0044 0029;0028 0044 0029; +1F114;1F114;1F114;0028 0045 0029;0028 0045 0029; +1F115;1F115;1F115;0028 0046 0029;0028 0046 0029; +1F116;1F116;1F116;0028 0047 0029;0028 0047 0029; +1F117;1F117;1F117;0028 0048 0029;0028 0048 0029; +1F118;1F118;1F118;0028 0049 0029;0028 0049 0029; +1F119;1F119;1F119;0028 004A 0029;0028 004A 0029; +1F11A;1F11A;1F11A;0028 004B 0029;0028 004B 0029; +1F11B;1F11B;1F11B;0028 004C 0029;0028 004C 0029; +1F11C;1F11C;1F11C;0028 004D 0029;0028 004D 0029; +1F11D;1F11D;1F11D;0028 004E 0029;0028 004E 0029; +1F11E;1F11E;1F11E;0028 004F 0029;0028 004F 0029; +1F11F;1F11F;1F11F;0028 0050 0029;0028 0050 0029; +1F120;1F120;1F120;0028 0051 0029;0028 0051 0029; +1F121;1F121;1F121;0028 0052 0029;0028 0052 0029; +1F122;1F122;1F122;0028 0053 0029;0028 0053 0029; +1F123;1F123;1F123;0028 0054 0029;0028 0054 0029; +1F124;1F124;1F124;0028 0055 0029;0028 0055 0029; +1F125;1F125;1F125;0028 0056 0029;0028 0056 0029; +1F126;1F126;1F126;0028 0057 0029;0028 0057 0029; +1F127;1F127;1F127;0028 0058 0029;0028 0058 0029; +1F128;1F128;1F128;0028 0059 0029;0028 0059 0029; +1F129;1F129;1F129;0028 005A 0029;0028 005A 0029; +1F12A;1F12A;1F12A;3014 0053 3015;3014 0053 3015; +1F12B;1F12B;1F12B;0043;0043; +1F12C;1F12C;1F12C;0052;0052; +1F12D;1F12D;1F12D;0043 0044;0043 0044; +1F12E;1F12E;1F12E;0057 005A;0057 005A; +1F130;1F130;1F130;0041;0041; +1F131;1F131;1F131;0042;0042; +1F132;1F132;1F132;0043;0043; +1F133;1F133;1F133;0044;0044; +1F134;1F134;1F134;0045;0045; +1F135;1F135;1F135;0046;0046; +1F136;1F136;1F136;0047;0047; +1F137;1F137;1F137;0048;0048; +1F138;1F138;1F138;0049;0049; +1F139;1F139;1F139;004A;004A; +1F13A;1F13A;1F13A;004B;004B; +1F13B;1F13B;1F13B;004C;004C; +1F13C;1F13C;1F13C;004D;004D; +1F13D;1F13D;1F13D;004E;004E; +1F13E;1F13E;1F13E;004F;004F; +1F13F;1F13F;1F13F;0050;0050; +1F140;1F140;1F140;0051;0051; +1F141;1F141;1F141;0052;0052; +1F142;1F142;1F142;0053;0053; +1F143;1F143;1F143;0054;0054; +1F144;1F144;1F144;0055;0055; +1F145;1F145;1F145;0056;0056; +1F146;1F146;1F146;0057;0057; +1F147;1F147;1F147;0058;0058; +1F148;1F148;1F148;0059;0059; +1F149;1F149;1F149;005A;005A; +1F14A;1F14A;1F14A;0048 0056;0048 0056; +1F14B;1F14B;1F14B;004D 0056;004D 0056; +1F14C;1F14C;1F14C;0053 0044;0053 0044; +1F14D;1F14D;1F14D;0053 0053;0053 0053; +1F14E;1F14E;1F14E;0050 0050 0056;0050 0050 0056; +1F14F;1F14F;1F14F;0057 0043;0057 0043; +1F16A;1F16A;1F16A;004D 0043;004D 0043; +1F16B;1F16B;1F16B;004D 0044;004D 0044; +1F190;1F190;1F190;0044 004A;0044 004A; +1F200;1F200;1F200;307B 304B;307B 304B; +1F201;1F201;1F201;30B3 30B3;30B3 30B3; +1F202;1F202;1F202;30B5;30B5; +1F210;1F210;1F210;624B;624B; +1F211;1F211;1F211;5B57;5B57; +1F212;1F212;1F212;53CC;53CC; +1F213;1F213;1F213;30C7;30C6 3099; +1F214;1F214;1F214;4E8C;4E8C; +1F215;1F215;1F215;591A;591A; +1F216;1F216;1F216;89E3;89E3; +1F217;1F217;1F217;5929;5929; +1F218;1F218;1F218;4EA4;4EA4; +1F219;1F219;1F219;6620;6620; +1F21A;1F21A;1F21A;7121;7121; +1F21B;1F21B;1F21B;6599;6599; +1F21C;1F21C;1F21C;524D;524D; +1F21D;1F21D;1F21D;5F8C;5F8C; +1F21E;1F21E;1F21E;518D;518D; +1F21F;1F21F;1F21F;65B0;65B0; +1F220;1F220;1F220;521D;521D; +1F221;1F221;1F221;7D42;7D42; +1F222;1F222;1F222;751F;751F; +1F223;1F223;1F223;8CA9;8CA9; +1F224;1F224;1F224;58F0;58F0; +1F225;1F225;1F225;5439;5439; +1F226;1F226;1F226;6F14;6F14; +1F227;1F227;1F227;6295;6295; +1F228;1F228;1F228;6355;6355; +1F229;1F229;1F229;4E00;4E00; +1F22A;1F22A;1F22A;4E09;4E09; +1F22B;1F22B;1F22B;904A;904A; +1F22C;1F22C;1F22C;5DE6;5DE6; +1F22D;1F22D;1F22D;4E2D;4E2D; +1F22E;1F22E;1F22E;53F3;53F3; +1F22F;1F22F;1F22F;6307;6307; +1F230;1F230;1F230;8D70;8D70; +1F231;1F231;1F231;6253;6253; +1F232;1F232;1F232;7981;7981; +1F233;1F233;1F233;7A7A;7A7A; +1F234;1F234;1F234;5408;5408; +1F235;1F235;1F235;6E80;6E80; +1F236;1F236;1F236;6709;6709; +1F237;1F237;1F237;6708;6708; +1F238;1F238;1F238;7533;7533; +1F239;1F239;1F239;5272;5272; +1F23A;1F23A;1F23A;55B6;55B6; +1F23B;1F23B;1F23B;914D;914D; +1F240;1F240;1F240;3014 672C 3015;3014 672C 3015; +1F241;1F241;1F241;3014 4E09 3015;3014 4E09 3015; +1F242;1F242;1F242;3014 4E8C 3015;3014 4E8C 3015; +1F243;1F243;1F243;3014 5B89 3015;3014 5B89 3015; +1F244;1F244;1F244;3014 70B9 3015;3014 70B9 3015; +1F245;1F245;1F245;3014 6253 3015;3014 6253 3015; +1F246;1F246;1F246;3014 76D7 3015;3014 76D7 3015; +1F247;1F247;1F247;3014 52DD 3015;3014 52DD 3015; +1F248;1F248;1F248;3014 6557 3015;3014 6557 3015; +1F250;1F250;1F250;5F97;5F97; +1F251;1F251;1F251;53EF;53EF; +2F800;4E3D;4E3D;4E3D;4E3D; +2F801;4E38;4E38;4E38;4E38; +2F802;4E41;4E41;4E41;4E41; +2F803;20122;20122;20122;20122; +2F804;4F60;4F60;4F60;4F60; +2F805;4FAE;4FAE;4FAE;4FAE; +2F806;4FBB;4FBB;4FBB;4FBB; +2F807;5002;5002;5002;5002; +2F808;507A;507A;507A;507A; +2F809;5099;5099;5099;5099; +2F80A;50E7;50E7;50E7;50E7; +2F80B;50CF;50CF;50CF;50CF; +2F80C;349E;349E;349E;349E; +2F80D;2063A;2063A;2063A;2063A; +2F80E;514D;514D;514D;514D; +2F80F;5154;5154;5154;5154; +2F810;5164;5164;5164;5164; +2F811;5177;5177;5177;5177; +2F812;2051C;2051C;2051C;2051C; +2F813;34B9;34B9;34B9;34B9; +2F814;5167;5167;5167;5167; +2F815;518D;518D;518D;518D; +2F816;2054B;2054B;2054B;2054B; +2F817;5197;5197;5197;5197; +2F818;51A4;51A4;51A4;51A4; +2F819;4ECC;4ECC;4ECC;4ECC; +2F81A;51AC;51AC;51AC;51AC; +2F81B;51B5;51B5;51B5;51B5; +2F81C;291DF;291DF;291DF;291DF; +2F81D;51F5;51F5;51F5;51F5; +2F81E;5203;5203;5203;5203; +2F81F;34DF;34DF;34DF;34DF; +2F820;523B;523B;523B;523B; +2F821;5246;5246;5246;5246; +2F822;5272;5272;5272;5272; +2F823;5277;5277;5277;5277; +2F824;3515;3515;3515;3515; +2F825;52C7;52C7;52C7;52C7; +2F826;52C9;52C9;52C9;52C9; +2F827;52E4;52E4;52E4;52E4; +2F828;52FA;52FA;52FA;52FA; +2F829;5305;5305;5305;5305; +2F82A;5306;5306;5306;5306; +2F82B;5317;5317;5317;5317; +2F82C;5349;5349;5349;5349; +2F82D;5351;5351;5351;5351; +2F82E;535A;535A;535A;535A; +2F82F;5373;5373;5373;5373; +2F830;537D;537D;537D;537D; +2F831;537F;537F;537F;537F; +2F832;537F;537F;537F;537F; +2F833;537F;537F;537F;537F; +2F834;20A2C;20A2C;20A2C;20A2C; +2F835;7070;7070;7070;7070; +2F836;53CA;53CA;53CA;53CA; +2F837;53DF;53DF;53DF;53DF; +2F838;20B63;20B63;20B63;20B63; +2F839;53EB;53EB;53EB;53EB; +2F83A;53F1;53F1;53F1;53F1; +2F83B;5406;5406;5406;5406; +2F83C;549E;549E;549E;549E; +2F83D;5438;5438;5438;5438; +2F83E;5448;5448;5448;5448; +2F83F;5468;5468;5468;5468; +2F840;54A2;54A2;54A2;54A2; +2F841;54F6;54F6;54F6;54F6; +2F842;5510;5510;5510;5510; +2F843;5553;5553;5553;5553; +2F844;5563;5563;5563;5563; +2F845;5584;5584;5584;5584; +2F846;5584;5584;5584;5584; +2F847;5599;5599;5599;5599; +2F848;55AB;55AB;55AB;55AB; +2F849;55B3;55B3;55B3;55B3; +2F84A;55C2;55C2;55C2;55C2; +2F84B;5716;5716;5716;5716; +2F84C;5606;5606;5606;5606; +2F84D;5717;5717;5717;5717; +2F84E;5651;5651;5651;5651; +2F84F;5674;5674;5674;5674; +2F850;5207;5207;5207;5207; +2F851;58EE;58EE;58EE;58EE; +2F852;57CE;57CE;57CE;57CE; +2F853;57F4;57F4;57F4;57F4; +2F854;580D;580D;580D;580D; +2F855;578B;578B;578B;578B; +2F856;5832;5832;5832;5832; +2F857;5831;5831;5831;5831; +2F858;58AC;58AC;58AC;58AC; +2F859;214E4;214E4;214E4;214E4; +2F85A;58F2;58F2;58F2;58F2; +2F85B;58F7;58F7;58F7;58F7; +2F85C;5906;5906;5906;5906; +2F85D;591A;591A;591A;591A; +2F85E;5922;5922;5922;5922; +2F85F;5962;5962;5962;5962; +2F860;216A8;216A8;216A8;216A8; +2F861;216EA;216EA;216EA;216EA; +2F862;59EC;59EC;59EC;59EC; +2F863;5A1B;5A1B;5A1B;5A1B; +2F864;5A27;5A27;5A27;5A27; +2F865;59D8;59D8;59D8;59D8; +2F866;5A66;5A66;5A66;5A66; +2F867;36EE;36EE;36EE;36EE; +2F868;36FC;36FC;36FC;36FC; +2F869;5B08;5B08;5B08;5B08; +2F86A;5B3E;5B3E;5B3E;5B3E; +2F86B;5B3E;5B3E;5B3E;5B3E; +2F86C;219C8;219C8;219C8;219C8; +2F86D;5BC3;5BC3;5BC3;5BC3; +2F86E;5BD8;5BD8;5BD8;5BD8; +2F86F;5BE7;5BE7;5BE7;5BE7; +2F870;5BF3;5BF3;5BF3;5BF3; +2F871;21B18;21B18;21B18;21B18; +2F872;5BFF;5BFF;5BFF;5BFF; +2F873;5C06;5C06;5C06;5C06; +2F874;5F53;5F53;5F53;5F53; +2F875;5C22;5C22;5C22;5C22; +2F876;3781;3781;3781;3781; +2F877;5C60;5C60;5C60;5C60; +2F878;5C6E;5C6E;5C6E;5C6E; +2F879;5CC0;5CC0;5CC0;5CC0; +2F87A;5C8D;5C8D;5C8D;5C8D; +2F87B;21DE4;21DE4;21DE4;21DE4; +2F87C;5D43;5D43;5D43;5D43; +2F87D;21DE6;21DE6;21DE6;21DE6; +2F87E;5D6E;5D6E;5D6E;5D6E; +2F87F;5D6B;5D6B;5D6B;5D6B; +2F880;5D7C;5D7C;5D7C;5D7C; +2F881;5DE1;5DE1;5DE1;5DE1; +2F882;5DE2;5DE2;5DE2;5DE2; +2F883;382F;382F;382F;382F; +2F884;5DFD;5DFD;5DFD;5DFD; +2F885;5E28;5E28;5E28;5E28; +2F886;5E3D;5E3D;5E3D;5E3D; +2F887;5E69;5E69;5E69;5E69; +2F888;3862;3862;3862;3862; +2F889;22183;22183;22183;22183; +2F88A;387C;387C;387C;387C; +2F88B;5EB0;5EB0;5EB0;5EB0; +2F88C;5EB3;5EB3;5EB3;5EB3; +2F88D;5EB6;5EB6;5EB6;5EB6; +2F88E;5ECA;5ECA;5ECA;5ECA; +2F88F;2A392;2A392;2A392;2A392; +2F890;5EFE;5EFE;5EFE;5EFE; +2F891;22331;22331;22331;22331; +2F892;22331;22331;22331;22331; +2F893;8201;8201;8201;8201; +2F894;5F22;5F22;5F22;5F22; +2F895;5F22;5F22;5F22;5F22; +2F896;38C7;38C7;38C7;38C7; +2F897;232B8;232B8;232B8;232B8; +2F898;261DA;261DA;261DA;261DA; +2F899;5F62;5F62;5F62;5F62; +2F89A;5F6B;5F6B;5F6B;5F6B; +2F89B;38E3;38E3;38E3;38E3; +2F89C;5F9A;5F9A;5F9A;5F9A; +2F89D;5FCD;5FCD;5FCD;5FCD; +2F89E;5FD7;5FD7;5FD7;5FD7; +2F89F;5FF9;5FF9;5FF9;5FF9; +2F8A0;6081;6081;6081;6081; +2F8A1;393A;393A;393A;393A; +2F8A2;391C;391C;391C;391C; +2F8A3;6094;6094;6094;6094; +2F8A4;226D4;226D4;226D4;226D4; +2F8A5;60C7;60C7;60C7;60C7; +2F8A6;6148;6148;6148;6148; +2F8A7;614C;614C;614C;614C; +2F8A8;614E;614E;614E;614E; +2F8A9;614C;614C;614C;614C; +2F8AA;617A;617A;617A;617A; +2F8AB;618E;618E;618E;618E; +2F8AC;61B2;61B2;61B2;61B2; +2F8AD;61A4;61A4;61A4;61A4; +2F8AE;61AF;61AF;61AF;61AF; +2F8AF;61DE;61DE;61DE;61DE; +2F8B0;61F2;61F2;61F2;61F2; +2F8B1;61F6;61F6;61F6;61F6; +2F8B2;6210;6210;6210;6210; +2F8B3;621B;621B;621B;621B; +2F8B4;625D;625D;625D;625D; +2F8B5;62B1;62B1;62B1;62B1; +2F8B6;62D4;62D4;62D4;62D4; +2F8B7;6350;6350;6350;6350; +2F8B8;22B0C;22B0C;22B0C;22B0C; +2F8B9;633D;633D;633D;633D; +2F8BA;62FC;62FC;62FC;62FC; +2F8BB;6368;6368;6368;6368; +2F8BC;6383;6383;6383;6383; +2F8BD;63E4;63E4;63E4;63E4; +2F8BE;22BF1;22BF1;22BF1;22BF1; +2F8BF;6422;6422;6422;6422; +2F8C0;63C5;63C5;63C5;63C5; +2F8C1;63A9;63A9;63A9;63A9; +2F8C2;3A2E;3A2E;3A2E;3A2E; +2F8C3;6469;6469;6469;6469; +2F8C4;647E;647E;647E;647E; +2F8C5;649D;649D;649D;649D; +2F8C6;6477;6477;6477;6477; +2F8C7;3A6C;3A6C;3A6C;3A6C; +2F8C8;654F;654F;654F;654F; +2F8C9;656C;656C;656C;656C; +2F8CA;2300A;2300A;2300A;2300A; +2F8CB;65E3;65E3;65E3;65E3; +2F8CC;66F8;66F8;66F8;66F8; +2F8CD;6649;6649;6649;6649; +2F8CE;3B19;3B19;3B19;3B19; +2F8CF;6691;6691;6691;6691; +2F8D0;3B08;3B08;3B08;3B08; +2F8D1;3AE4;3AE4;3AE4;3AE4; +2F8D2;5192;5192;5192;5192; +2F8D3;5195;5195;5195;5195; +2F8D4;6700;6700;6700;6700; +2F8D5;669C;669C;669C;669C; +2F8D6;80AD;80AD;80AD;80AD; +2F8D7;43D9;43D9;43D9;43D9; +2F8D8;6717;6717;6717;6717; +2F8D9;671B;671B;671B;671B; +2F8DA;6721;6721;6721;6721; +2F8DB;675E;675E;675E;675E; +2F8DC;6753;6753;6753;6753; +2F8DD;233C3;233C3;233C3;233C3; +2F8DE;3B49;3B49;3B49;3B49; +2F8DF;67FA;67FA;67FA;67FA; +2F8E0;6785;6785;6785;6785; +2F8E1;6852;6852;6852;6852; +2F8E2;6885;6885;6885;6885; +2F8E3;2346D;2346D;2346D;2346D; +2F8E4;688E;688E;688E;688E; +2F8E5;681F;681F;681F;681F; +2F8E6;6914;6914;6914;6914; +2F8E7;3B9D;3B9D;3B9D;3B9D; +2F8E8;6942;6942;6942;6942; +2F8E9;69A3;69A3;69A3;69A3; +2F8EA;69EA;69EA;69EA;69EA; +2F8EB;6AA8;6AA8;6AA8;6AA8; +2F8EC;236A3;236A3;236A3;236A3; +2F8ED;6ADB;6ADB;6ADB;6ADB; +2F8EE;3C18;3C18;3C18;3C18; +2F8EF;6B21;6B21;6B21;6B21; +2F8F0;238A7;238A7;238A7;238A7; +2F8F1;6B54;6B54;6B54;6B54; +2F8F2;3C4E;3C4E;3C4E;3C4E; +2F8F3;6B72;6B72;6B72;6B72; +2F8F4;6B9F;6B9F;6B9F;6B9F; +2F8F5;6BBA;6BBA;6BBA;6BBA; +2F8F6;6BBB;6BBB;6BBB;6BBB; +2F8F7;23A8D;23A8D;23A8D;23A8D; +2F8F8;21D0B;21D0B;21D0B;21D0B; +2F8F9;23AFA;23AFA;23AFA;23AFA; +2F8FA;6C4E;6C4E;6C4E;6C4E; +2F8FB;23CBC;23CBC;23CBC;23CBC; +2F8FC;6CBF;6CBF;6CBF;6CBF; +2F8FD;6CCD;6CCD;6CCD;6CCD; +2F8FE;6C67;6C67;6C67;6C67; +2F8FF;6D16;6D16;6D16;6D16; +2F900;6D3E;6D3E;6D3E;6D3E; +2F901;6D77;6D77;6D77;6D77; +2F902;6D41;6D41;6D41;6D41; +2F903;6D69;6D69;6D69;6D69; +2F904;6D78;6D78;6D78;6D78; +2F905;6D85;6D85;6D85;6D85; +2F906;23D1E;23D1E;23D1E;23D1E; +2F907;6D34;6D34;6D34;6D34; +2F908;6E2F;6E2F;6E2F;6E2F; +2F909;6E6E;6E6E;6E6E;6E6E; +2F90A;3D33;3D33;3D33;3D33; +2F90B;6ECB;6ECB;6ECB;6ECB; +2F90C;6EC7;6EC7;6EC7;6EC7; +2F90D;23ED1;23ED1;23ED1;23ED1; +2F90E;6DF9;6DF9;6DF9;6DF9; +2F90F;6F6E;6F6E;6F6E;6F6E; +2F910;23F5E;23F5E;23F5E;23F5E; +2F911;23F8E;23F8E;23F8E;23F8E; +2F912;6FC6;6FC6;6FC6;6FC6; +2F913;7039;7039;7039;7039; +2F914;701E;701E;701E;701E; +2F915;701B;701B;701B;701B; +2F916;3D96;3D96;3D96;3D96; +2F917;704A;704A;704A;704A; +2F918;707D;707D;707D;707D; +2F919;7077;7077;7077;7077; +2F91A;70AD;70AD;70AD;70AD; +2F91B;20525;20525;20525;20525; +2F91C;7145;7145;7145;7145; +2F91D;24263;24263;24263;24263; +2F91E;719C;719C;719C;719C; +2F91F;243AB;243AB;243AB;243AB; +2F920;7228;7228;7228;7228; +2F921;7235;7235;7235;7235; +2F922;7250;7250;7250;7250; +2F923;24608;24608;24608;24608; +2F924;7280;7280;7280;7280; +2F925;7295;7295;7295;7295; +2F926;24735;24735;24735;24735; +2F927;24814;24814;24814;24814; +2F928;737A;737A;737A;737A; +2F929;738B;738B;738B;738B; +2F92A;3EAC;3EAC;3EAC;3EAC; +2F92B;73A5;73A5;73A5;73A5; +2F92C;3EB8;3EB8;3EB8;3EB8; +2F92D;3EB8;3EB8;3EB8;3EB8; +2F92E;7447;7447;7447;7447; +2F92F;745C;745C;745C;745C; +2F930;7471;7471;7471;7471; +2F931;7485;7485;7485;7485; +2F932;74CA;74CA;74CA;74CA; +2F933;3F1B;3F1B;3F1B;3F1B; +2F934;7524;7524;7524;7524; +2F935;24C36;24C36;24C36;24C36; +2F936;753E;753E;753E;753E; +2F937;24C92;24C92;24C92;24C92; +2F938;7570;7570;7570;7570; +2F939;2219F;2219F;2219F;2219F; +2F93A;7610;7610;7610;7610; +2F93B;24FA1;24FA1;24FA1;24FA1; +2F93C;24FB8;24FB8;24FB8;24FB8; +2F93D;25044;25044;25044;25044; +2F93E;3FFC;3FFC;3FFC;3FFC; +2F93F;4008;4008;4008;4008; +2F940;76F4;76F4;76F4;76F4; +2F941;250F3;250F3;250F3;250F3; +2F942;250F2;250F2;250F2;250F2; +2F943;25119;25119;25119;25119; +2F944;25133;25133;25133;25133; +2F945;771E;771E;771E;771E; +2F946;771F;771F;771F;771F; +2F947;771F;771F;771F;771F; +2F948;774A;774A;774A;774A; +2F949;4039;4039;4039;4039; +2F94A;778B;778B;778B;778B; +2F94B;4046;4046;4046;4046; +2F94C;4096;4096;4096;4096; +2F94D;2541D;2541D;2541D;2541D; +2F94E;784E;784E;784E;784E; +2F94F;788C;788C;788C;788C; +2F950;78CC;78CC;78CC;78CC; +2F951;40E3;40E3;40E3;40E3; +2F952;25626;25626;25626;25626; +2F953;7956;7956;7956;7956; +2F954;2569A;2569A;2569A;2569A; +2F955;256C5;256C5;256C5;256C5; +2F956;798F;798F;798F;798F; +2F957;79EB;79EB;79EB;79EB; +2F958;412F;412F;412F;412F; +2F959;7A40;7A40;7A40;7A40; +2F95A;7A4A;7A4A;7A4A;7A4A; +2F95B;7A4F;7A4F;7A4F;7A4F; +2F95C;2597C;2597C;2597C;2597C; +2F95D;25AA7;25AA7;25AA7;25AA7; +2F95E;25AA7;25AA7;25AA7;25AA7; +2F95F;7AEE;7AEE;7AEE;7AEE; +2F960;4202;4202;4202;4202; +2F961;25BAB;25BAB;25BAB;25BAB; +2F962;7BC6;7BC6;7BC6;7BC6; +2F963;7BC9;7BC9;7BC9;7BC9; +2F964;4227;4227;4227;4227; +2F965;25C80;25C80;25C80;25C80; +2F966;7CD2;7CD2;7CD2;7CD2; +2F967;42A0;42A0;42A0;42A0; +2F968;7CE8;7CE8;7CE8;7CE8; +2F969;7CE3;7CE3;7CE3;7CE3; +2F96A;7D00;7D00;7D00;7D00; +2F96B;25F86;25F86;25F86;25F86; +2F96C;7D63;7D63;7D63;7D63; +2F96D;4301;4301;4301;4301; +2F96E;7DC7;7DC7;7DC7;7DC7; +2F96F;7E02;7E02;7E02;7E02; +2F970;7E45;7E45;7E45;7E45; +2F971;4334;4334;4334;4334; +2F972;26228;26228;26228;26228; +2F973;26247;26247;26247;26247; +2F974;4359;4359;4359;4359; +2F975;262D9;262D9;262D9;262D9; +2F976;7F7A;7F7A;7F7A;7F7A; +2F977;2633E;2633E;2633E;2633E; +2F978;7F95;7F95;7F95;7F95; +2F979;7FFA;7FFA;7FFA;7FFA; +2F97A;8005;8005;8005;8005; +2F97B;264DA;264DA;264DA;264DA; +2F97C;26523;26523;26523;26523; +2F97D;8060;8060;8060;8060; +2F97E;265A8;265A8;265A8;265A8; +2F97F;8070;8070;8070;8070; +2F980;2335F;2335F;2335F;2335F; +2F981;43D5;43D5;43D5;43D5; +2F982;80B2;80B2;80B2;80B2; +2F983;8103;8103;8103;8103; +2F984;440B;440B;440B;440B; +2F985;813E;813E;813E;813E; +2F986;5AB5;5AB5;5AB5;5AB5; +2F987;267A7;267A7;267A7;267A7; +2F988;267B5;267B5;267B5;267B5; +2F989;23393;23393;23393;23393; +2F98A;2339C;2339C;2339C;2339C; +2F98B;8201;8201;8201;8201; +2F98C;8204;8204;8204;8204; +2F98D;8F9E;8F9E;8F9E;8F9E; +2F98E;446B;446B;446B;446B; +2F98F;8291;8291;8291;8291; +2F990;828B;828B;828B;828B; +2F991;829D;829D;829D;829D; +2F992;52B3;52B3;52B3;52B3; +2F993;82B1;82B1;82B1;82B1; +2F994;82B3;82B3;82B3;82B3; +2F995;82BD;82BD;82BD;82BD; +2F996;82E6;82E6;82E6;82E6; +2F997;26B3C;26B3C;26B3C;26B3C; +2F998;82E5;82E5;82E5;82E5; +2F999;831D;831D;831D;831D; +2F99A;8363;8363;8363;8363; +2F99B;83AD;83AD;83AD;83AD; +2F99C;8323;8323;8323;8323; +2F99D;83BD;83BD;83BD;83BD; +2F99E;83E7;83E7;83E7;83E7; +2F99F;8457;8457;8457;8457; +2F9A0;8353;8353;8353;8353; +2F9A1;83CA;83CA;83CA;83CA; +2F9A2;83CC;83CC;83CC;83CC; +2F9A3;83DC;83DC;83DC;83DC; +2F9A4;26C36;26C36;26C36;26C36; +2F9A5;26D6B;26D6B;26D6B;26D6B; +2F9A6;26CD5;26CD5;26CD5;26CD5; +2F9A7;452B;452B;452B;452B; +2F9A8;84F1;84F1;84F1;84F1; +2F9A9;84F3;84F3;84F3;84F3; +2F9AA;8516;8516;8516;8516; +2F9AB;273CA;273CA;273CA;273CA; +2F9AC;8564;8564;8564;8564; +2F9AD;26F2C;26F2C;26F2C;26F2C; +2F9AE;455D;455D;455D;455D; +2F9AF;4561;4561;4561;4561; +2F9B0;26FB1;26FB1;26FB1;26FB1; +2F9B1;270D2;270D2;270D2;270D2; +2F9B2;456B;456B;456B;456B; +2F9B3;8650;8650;8650;8650; +2F9B4;865C;865C;865C;865C; +2F9B5;8667;8667;8667;8667; +2F9B6;8669;8669;8669;8669; +2F9B7;86A9;86A9;86A9;86A9; +2F9B8;8688;8688;8688;8688; +2F9B9;870E;870E;870E;870E; +2F9BA;86E2;86E2;86E2;86E2; +2F9BB;8779;8779;8779;8779; +2F9BC;8728;8728;8728;8728; +2F9BD;876B;876B;876B;876B; +2F9BE;8786;8786;8786;8786; +2F9BF;45D7;45D7;45D7;45D7; +2F9C0;87E1;87E1;87E1;87E1; +2F9C1;8801;8801;8801;8801; +2F9C2;45F9;45F9;45F9;45F9; +2F9C3;8860;8860;8860;8860; +2F9C4;8863;8863;8863;8863; +2F9C5;27667;27667;27667;27667; +2F9C6;88D7;88D7;88D7;88D7; +2F9C7;88DE;88DE;88DE;88DE; +2F9C8;4635;4635;4635;4635; +2F9C9;88FA;88FA;88FA;88FA; +2F9CA;34BB;34BB;34BB;34BB; +2F9CB;278AE;278AE;278AE;278AE; +2F9CC;27966;27966;27966;27966; +2F9CD;46BE;46BE;46BE;46BE; +2F9CE;46C7;46C7;46C7;46C7; +2F9CF;8AA0;8AA0;8AA0;8AA0; +2F9D0;8AED;8AED;8AED;8AED; +2F9D1;8B8A;8B8A;8B8A;8B8A; +2F9D2;8C55;8C55;8C55;8C55; +2F9D3;27CA8;27CA8;27CA8;27CA8; +2F9D4;8CAB;8CAB;8CAB;8CAB; +2F9D5;8CC1;8CC1;8CC1;8CC1; +2F9D6;8D1B;8D1B;8D1B;8D1B; +2F9D7;8D77;8D77;8D77;8D77; +2F9D8;27F2F;27F2F;27F2F;27F2F; +2F9D9;20804;20804;20804;20804; +2F9DA;8DCB;8DCB;8DCB;8DCB; +2F9DB;8DBC;8DBC;8DBC;8DBC; +2F9DC;8DF0;8DF0;8DF0;8DF0; +2F9DD;208DE;208DE;208DE;208DE; +2F9DE;8ED4;8ED4;8ED4;8ED4; +2F9DF;8F38;8F38;8F38;8F38; +2F9E0;285D2;285D2;285D2;285D2; +2F9E1;285ED;285ED;285ED;285ED; +2F9E2;9094;9094;9094;9094; +2F9E3;90F1;90F1;90F1;90F1; +2F9E4;9111;9111;9111;9111; +2F9E5;2872E;2872E;2872E;2872E; +2F9E6;911B;911B;911B;911B; +2F9E7;9238;9238;9238;9238; +2F9E8;92D7;92D7;92D7;92D7; +2F9E9;92D8;92D8;92D8;92D8; +2F9EA;927C;927C;927C;927C; +2F9EB;93F9;93F9;93F9;93F9; +2F9EC;9415;9415;9415;9415; +2F9ED;28BFA;28BFA;28BFA;28BFA; +2F9EE;958B;958B;958B;958B; +2F9EF;4995;4995;4995;4995; +2F9F0;95B7;95B7;95B7;95B7; +2F9F1;28D77;28D77;28D77;28D77; +2F9F2;49E6;49E6;49E6;49E6; +2F9F3;96C3;96C3;96C3;96C3; +2F9F4;5DB2;5DB2;5DB2;5DB2; +2F9F5;9723;9723;9723;9723; +2F9F6;29145;29145;29145;29145; +2F9F7;2921A;2921A;2921A;2921A; +2F9F8;4A6E;4A6E;4A6E;4A6E; +2F9F9;4A76;4A76;4A76;4A76; +2F9FA;97E0;97E0;97E0;97E0; +2F9FB;2940A;2940A;2940A;2940A; +2F9FC;4AB2;4AB2;4AB2;4AB2; +2F9FD;29496;29496;29496;29496; +2F9FE;980B;980B;980B;980B; +2F9FF;980B;980B;980B;980B; +2FA00;9829;9829;9829;9829; +2FA01;295B6;295B6;295B6;295B6; +2FA02;98E2;98E2;98E2;98E2; +2FA03;4B33;4B33;4B33;4B33; +2FA04;9929;9929;9929;9929; +2FA05;99A7;99A7;99A7;99A7; +2FA06;99C2;99C2;99C2;99C2; +2FA07;99FE;99FE;99FE;99FE; +2FA08;4BCE;4BCE;4BCE;4BCE; +2FA09;29B30;29B30;29B30;29B30; +2FA0A;9B12;9B12;9B12;9B12; +2FA0B;9C40;9C40;9C40;9C40; +2FA0C;9CFD;9CFD;9CFD;9CFD; +2FA0D;4CCE;4CCE;4CCE;4CCE; +2FA0E;4CED;4CED;4CED;4CED; +2FA0F;9D67;9D67;9D67;9D67; +2FA10;2A0CE;2A0CE;2A0CE;2A0CE; +2FA11;4CF8;4CF8;4CF8;4CF8; +2FA12;2A105;2A105;2A105;2A105; +2FA13;2A20E;2A20E;2A20E;2A20E; +2FA14;2A291;2A291;2A291;2A291; +2FA15;9EBB;9EBB;9EBB;9EBB; +2FA16;4D56;4D56;4D56;4D56; +2FA17;9EF9;9EF9;9EF9;9EF9; +2FA18;9EFE;9EFE;9EFE;9EFE; +2FA19;9F05;9F05;9F05;9F05; +2FA1A;9F0F;9F0F;9F0F;9F0F; +2FA1B;9F16;9F16;9F16;9F16; +2FA1C;9F3B;9F3B;9F3B;9F3B; +2FA1D;2A600;2A600;2A600;2A600; +# +@Part2 # Canonical Order Test +# +0061 0315 0300 05AE 0300 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; +0061 0300 0315 0300 05AE 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; +0061 0315 0300 05AE 0301 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062; +0061 0301 0315 0300 05AE 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062; +0061 0315 0300 05AE 0302 0062;00E0 05AE 0302 0315 0062;0061 05AE 0300 0302 0315 0062;00E0 05AE 0302 0315 0062;0061 05AE 0300 0302 0315 0062; +0061 0302 0315 0300 05AE 0062;1EA7 05AE 0315 0062;0061 05AE 0302 0300 0315 0062;1EA7 05AE 0315 0062;0061 05AE 0302 0300 0315 0062; +0061 0315 0300 05AE 0303 0062;00E0 05AE 0303 0315 0062;0061 05AE 0300 0303 0315 0062;00E0 05AE 0303 0315 0062;0061 05AE 0300 0303 0315 0062; +0061 0303 0315 0300 05AE 0062;00E3 05AE 0300 0315 0062;0061 05AE 0303 0300 0315 0062;00E3 05AE 0300 0315 0062;0061 05AE 0303 0300 0315 0062; +0061 0315 0300 05AE 0304 0062;00E0 05AE 0304 0315 0062;0061 05AE 0300 0304 0315 0062;00E0 05AE 0304 0315 0062;0061 05AE 0300 0304 0315 0062; +0061 0304 0315 0300 05AE 0062;0101 05AE 0300 0315 0062;0061 05AE 0304 0300 0315 0062;0101 05AE 0300 0315 0062;0061 05AE 0304 0300 0315 0062; +0061 0315 0300 05AE 0305 0062;00E0 05AE 0305 0315 0062;0061 05AE 0300 0305 0315 0062;00E0 05AE 0305 0315 0062;0061 05AE 0300 0305 0315 0062; +0061 0305 0315 0300 05AE 0062;0061 05AE 0305 0300 0315 0062;0061 05AE 0305 0300 0315 0062;0061 05AE 0305 0300 0315 0062;0061 05AE 0305 0300 0315 0062; +0061 0315 0300 05AE 0306 0062;00E0 05AE 0306 0315 0062;0061 05AE 0300 0306 0315 0062;00E0 05AE 0306 0315 0062;0061 05AE 0300 0306 0315 0062; +0061 0306 0315 0300 05AE 0062;1EB1 05AE 0315 0062;0061 05AE 0306 0300 0315 0062;1EB1 05AE 0315 0062;0061 05AE 0306 0300 0315 0062; +0061 0315 0300 05AE 0307 0062;00E0 05AE 0307 0315 0062;0061 05AE 0300 0307 0315 0062;00E0 05AE 0307 0315 0062;0061 05AE 0300 0307 0315 0062; +0061 0307 0315 0300 05AE 0062;0227 05AE 0300 0315 0062;0061 05AE 0307 0300 0315 0062;0227 05AE 0300 0315 0062;0061 05AE 0307 0300 0315 0062; +0061 0315 0300 05AE 0308 0062;00E0 05AE 0308 0315 0062;0061 05AE 0300 0308 0315 0062;00E0 05AE 0308 0315 0062;0061 05AE 0300 0308 0315 0062; +0061 0308 0315 0300 05AE 0062;00E4 05AE 0300 0315 0062;0061 05AE 0308 0300 0315 0062;00E4 05AE 0300 0315 0062;0061 05AE 0308 0300 0315 0062; +0061 0315 0300 05AE 0309 0062;00E0 05AE 0309 0315 0062;0061 05AE 0300 0309 0315 0062;00E0 05AE 0309 0315 0062;0061 05AE 0300 0309 0315 0062; +0061 0309 0315 0300 05AE 0062;1EA3 05AE 0300 0315 0062;0061 05AE 0309 0300 0315 0062;1EA3 05AE 0300 0315 0062;0061 05AE 0309 0300 0315 0062; +0061 0315 0300 05AE 030A 0062;00E0 05AE 030A 0315 0062;0061 05AE 0300 030A 0315 0062;00E0 05AE 030A 0315 0062;0061 05AE 0300 030A 0315 0062; +0061 030A 0315 0300 05AE 0062;00E5 05AE 0300 0315 0062;0061 05AE 030A 0300 0315 0062;00E5 05AE 0300 0315 0062;0061 05AE 030A 0300 0315 0062; +0061 0315 0300 05AE 030B 0062;00E0 05AE 030B 0315 0062;0061 05AE 0300 030B 0315 0062;00E0 05AE 030B 0315 0062;0061 05AE 0300 030B 0315 0062; +0061 030B 0315 0300 05AE 0062;0061 05AE 030B 0300 0315 0062;0061 05AE 030B 0300 0315 0062;0061 05AE 030B 0300 0315 0062;0061 05AE 030B 0300 0315 0062; +0061 0315 0300 05AE 030C 0062;00E0 05AE 030C 0315 0062;0061 05AE 0300 030C 0315 0062;00E0 05AE 030C 0315 0062;0061 05AE 0300 030C 0315 0062; +0061 030C 0315 0300 05AE 0062;01CE 05AE 0300 0315 0062;0061 05AE 030C 0300 0315 0062;01CE 05AE 0300 0315 0062;0061 05AE 030C 0300 0315 0062; +0061 0315 0300 05AE 030D 0062;00E0 05AE 030D 0315 0062;0061 05AE 0300 030D 0315 0062;00E0 05AE 030D 0315 0062;0061 05AE 0300 030D 0315 0062; +0061 030D 0315 0300 05AE 0062;0061 05AE 030D 0300 0315 0062;0061 05AE 030D 0300 0315 0062;0061 05AE 030D 0300 0315 0062;0061 05AE 030D 0300 0315 0062; +0061 0315 0300 05AE 030E 0062;00E0 05AE 030E 0315 0062;0061 05AE 0300 030E 0315 0062;00E0 05AE 030E 0315 0062;0061 05AE 0300 030E 0315 0062; +0061 030E 0315 0300 05AE 0062;0061 05AE 030E 0300 0315 0062;0061 05AE 030E 0300 0315 0062;0061 05AE 030E 0300 0315 0062;0061 05AE 030E 0300 0315 0062; +0061 0315 0300 05AE 030F 0062;00E0 05AE 030F 0315 0062;0061 05AE 0300 030F 0315 0062;00E0 05AE 030F 0315 0062;0061 05AE 0300 030F 0315 0062; +0061 030F 0315 0300 05AE 0062;0201 05AE 0300 0315 0062;0061 05AE 030F 0300 0315 0062;0201 05AE 0300 0315 0062;0061 05AE 030F 0300 0315 0062; +0061 0315 0300 05AE 0310 0062;00E0 05AE 0310 0315 0062;0061 05AE 0300 0310 0315 0062;00E0 05AE 0310 0315 0062;0061 05AE 0300 0310 0315 0062; +0061 0310 0315 0300 05AE 0062;0061 05AE 0310 0300 0315 0062;0061 05AE 0310 0300 0315 0062;0061 05AE 0310 0300 0315 0062;0061 05AE 0310 0300 0315 0062; +0061 0315 0300 05AE 0311 0062;00E0 05AE 0311 0315 0062;0061 05AE 0300 0311 0315 0062;00E0 05AE 0311 0315 0062;0061 05AE 0300 0311 0315 0062; +0061 0311 0315 0300 05AE 0062;0203 05AE 0300 0315 0062;0061 05AE 0311 0300 0315 0062;0203 05AE 0300 0315 0062;0061 05AE 0311 0300 0315 0062; +0061 0315 0300 05AE 0312 0062;00E0 05AE 0312 0315 0062;0061 05AE 0300 0312 0315 0062;00E0 05AE 0312 0315 0062;0061 05AE 0300 0312 0315 0062; +0061 0312 0315 0300 05AE 0062;0061 05AE 0312 0300 0315 0062;0061 05AE 0312 0300 0315 0062;0061 05AE 0312 0300 0315 0062;0061 05AE 0312 0300 0315 0062; +0061 0315 0300 05AE 0313 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062; +0061 0313 0315 0300 05AE 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062; +0061 0315 0300 05AE 0314 0062;00E0 05AE 0314 0315 0062;0061 05AE 0300 0314 0315 0062;00E0 05AE 0314 0315 0062;0061 05AE 0300 0314 0315 0062; +0061 0314 0315 0300 05AE 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062; +0061 035C 0315 0300 0315 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062; +0061 0315 035C 0315 0300 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062; +0061 059A 0316 302A 0316 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062; +0061 0316 059A 0316 302A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062; +0061 059A 0316 302A 0317 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062; +0061 0317 059A 0316 302A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062; +0061 059A 0316 302A 0318 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062; +0061 0318 059A 0316 302A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062; +0061 059A 0316 302A 0319 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062; +0061 0319 059A 0316 302A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062; +0061 035C 0315 0300 031A 0062;00E0 0315 031A 035C 0062;0061 0300 0315 031A 035C 0062;00E0 0315 031A 035C 0062;0061 0300 0315 031A 035C 0062; +0061 031A 035C 0315 0300 0062;00E0 031A 0315 035C 0062;0061 0300 031A 0315 035C 0062;00E0 031A 0315 035C 0062;0061 0300 031A 0315 035C 0062; +0061 302A 031B 1DCE 031B 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062; +0061 031B 302A 031B 1DCE 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062; +0061 059A 0316 302A 031C 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062; +0061 031C 059A 0316 302A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062; +0061 059A 0316 302A 031D 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062; +0061 031D 059A 0316 302A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062; +0061 059A 0316 302A 031E 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062; +0061 031E 059A 0316 302A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062; +0061 059A 0316 302A 031F 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062; +0061 031F 059A 0316 302A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062; +0061 059A 0316 302A 0320 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062; +0061 0320 059A 0316 302A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062; +0061 1DCE 0321 0F74 0321 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062; +0061 0321 1DCE 0321 0F74 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062; +0061 1DCE 0321 0F74 0322 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062; +0061 0322 1DCE 0321 0F74 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062; +0061 059A 0316 302A 0323 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062; +0061 0323 059A 0316 302A 0062;1EA1 302A 0316 059A 0062;0061 302A 0323 0316 059A 0062;1EA1 302A 0316 059A 0062;0061 302A 0323 0316 059A 0062; +0061 059A 0316 302A 0324 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062; +0061 0324 059A 0316 302A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062; +0061 059A 0316 302A 0325 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062; +0061 0325 059A 0316 302A 0062;1E01 302A 0316 059A 0062;0061 302A 0325 0316 059A 0062;1E01 302A 0316 059A 0062;0061 302A 0325 0316 059A 0062; +0061 059A 0316 302A 0326 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062; +0061 0326 059A 0316 302A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062; +0061 1DCE 0321 0F74 0327 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062; +0061 0327 1DCE 0321 0F74 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062; +0061 1DCE 0321 0F74 0328 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062; +0061 0328 1DCE 0321 0F74 0062;0105 0F74 0321 1DCE 0062;0061 0F74 0328 0321 1DCE 0062;0105 0F74 0321 1DCE 0062;0061 0F74 0328 0321 1DCE 0062; +0061 059A 0316 302A 0329 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062; +0061 0329 059A 0316 302A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062; +0061 059A 0316 302A 032A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062; +0061 032A 059A 0316 302A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062; +0061 059A 0316 302A 032B 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062; +0061 032B 059A 0316 302A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062; +0061 059A 0316 302A 032C 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062; +0061 032C 059A 0316 302A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062; +0061 059A 0316 302A 032D 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062; +0061 032D 059A 0316 302A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062; +0061 059A 0316 302A 032E 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062; +0061 032E 059A 0316 302A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062; +0061 059A 0316 302A 032F 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062; +0061 032F 059A 0316 302A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062; +0061 059A 0316 302A 0330 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062; +0061 0330 059A 0316 302A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062; +0061 059A 0316 302A 0331 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062; +0061 0331 059A 0316 302A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062; +0061 059A 0316 302A 0332 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062; +0061 0332 059A 0316 302A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062; +0061 059A 0316 302A 0333 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062; +0061 0333 059A 0316 302A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062; +0061 093C 0334 0334 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062; +0061 0334 093C 0334 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062; +0061 093C 0334 0335 0062;0061 0334 0335 093C 0062;0061 0334 0335 093C 0062;0061 0334 0335 093C 0062;0061 0334 0335 093C 0062; +0061 0335 093C 0334 0062;0061 0335 0334 093C 0062;0061 0335 0334 093C 0062;0061 0335 0334 093C 0062;0061 0335 0334 093C 0062; +0061 093C 0334 0336 0062;0061 0334 0336 093C 0062;0061 0334 0336 093C 0062;0061 0334 0336 093C 0062;0061 0334 0336 093C 0062; +0061 0336 093C 0334 0062;0061 0336 0334 093C 0062;0061 0336 0334 093C 0062;0061 0336 0334 093C 0062;0061 0336 0334 093C 0062; +0061 093C 0334 0337 0062;0061 0334 0337 093C 0062;0061 0334 0337 093C 0062;0061 0334 0337 093C 0062;0061 0334 0337 093C 0062; +0061 0337 093C 0334 0062;0061 0337 0334 093C 0062;0061 0337 0334 093C 0062;0061 0337 0334 093C 0062;0061 0337 0334 093C 0062; +0061 093C 0334 0338 0062;0061 0334 0338 093C 0062;0061 0334 0338 093C 0062;0061 0334 0338 093C 0062;0061 0334 0338 093C 0062; +0061 0338 093C 0334 0062;0061 0338 0334 093C 0062;0061 0338 0334 093C 0062;0061 0338 0334 093C 0062;0061 0338 0334 093C 0062; +0061 059A 0316 302A 0339 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062; +0061 0339 059A 0316 302A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062; +0061 059A 0316 302A 033A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062; +0061 033A 059A 0316 302A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062; +0061 059A 0316 302A 033B 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062; +0061 033B 059A 0316 302A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062; +0061 059A 0316 302A 033C 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062; +0061 033C 059A 0316 302A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062; +0061 0315 0300 05AE 033D 0062;00E0 05AE 033D 0315 0062;0061 05AE 0300 033D 0315 0062;00E0 05AE 033D 0315 0062;0061 05AE 0300 033D 0315 0062; +0061 033D 0315 0300 05AE 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062; +0061 0315 0300 05AE 033E 0062;00E0 05AE 033E 0315 0062;0061 05AE 0300 033E 0315 0062;00E0 05AE 033E 0315 0062;0061 05AE 0300 033E 0315 0062; +0061 033E 0315 0300 05AE 0062;0061 05AE 033E 0300 0315 0062;0061 05AE 033E 0300 0315 0062;0061 05AE 033E 0300 0315 0062;0061 05AE 033E 0300 0315 0062; +0061 0315 0300 05AE 033F 0062;00E0 05AE 033F 0315 0062;0061 05AE 0300 033F 0315 0062;00E0 05AE 033F 0315 0062;0061 05AE 0300 033F 0315 0062; +0061 033F 0315 0300 05AE 0062;0061 05AE 033F 0300 0315 0062;0061 05AE 033F 0300 0315 0062;0061 05AE 033F 0300 0315 0062;0061 05AE 033F 0300 0315 0062; +0061 0315 0300 05AE 0340 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; +0061 0340 0315 0300 05AE 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; +0061 0315 0300 05AE 0341 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062; +0061 0341 0315 0300 05AE 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062; +0061 0315 0300 05AE 0342 0062;00E0 05AE 0342 0315 0062;0061 05AE 0300 0342 0315 0062;00E0 05AE 0342 0315 0062;0061 05AE 0300 0342 0315 0062; +0061 0342 0315 0300 05AE 0062;0061 05AE 0342 0300 0315 0062;0061 05AE 0342 0300 0315 0062;0061 05AE 0342 0300 0315 0062;0061 05AE 0342 0300 0315 0062; +0061 0315 0300 05AE 0343 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062; +0061 0343 0315 0300 05AE 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062; +0061 0315 0300 05AE 0344 0062;00E0 05AE 0308 0301 0315 0062;0061 05AE 0300 0308 0301 0315 0062;00E0 05AE 0308 0301 0315 0062;0061 05AE 0300 0308 0301 0315 0062; +0061 0344 0315 0300 05AE 0062;00E4 05AE 0301 0300 0315 0062;0061 05AE 0308 0301 0300 0315 0062;00E4 05AE 0301 0300 0315 0062;0061 05AE 0308 0301 0300 0315 0062; +0061 0345 035D 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062; +0061 0345 0345 035D 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062; +0061 0315 0300 05AE 0346 0062;00E0 05AE 0346 0315 0062;0061 05AE 0300 0346 0315 0062;00E0 05AE 0346 0315 0062;0061 05AE 0300 0346 0315 0062; +0061 0346 0315 0300 05AE 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062; +0061 059A 0316 302A 0347 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062; +0061 0347 059A 0316 302A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062; +0061 059A 0316 302A 0348 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062; +0061 0348 059A 0316 302A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062; +0061 059A 0316 302A 0349 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062; +0061 0349 059A 0316 302A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062; +0061 0315 0300 05AE 034A 0062;00E0 05AE 034A 0315 0062;0061 05AE 0300 034A 0315 0062;00E0 05AE 034A 0315 0062;0061 05AE 0300 034A 0315 0062; +0061 034A 0315 0300 05AE 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062; +0061 0315 0300 05AE 034B 0062;00E0 05AE 034B 0315 0062;0061 05AE 0300 034B 0315 0062;00E0 05AE 034B 0315 0062;0061 05AE 0300 034B 0315 0062; +0061 034B 0315 0300 05AE 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062; +0061 0315 0300 05AE 034C 0062;00E0 05AE 034C 0315 0062;0061 05AE 0300 034C 0315 0062;00E0 05AE 034C 0315 0062;0061 05AE 0300 034C 0315 0062; +0061 034C 0315 0300 05AE 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062; +0061 059A 0316 302A 034D 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062; +0061 034D 059A 0316 302A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062; +0061 059A 0316 302A 034E 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062; +0061 034E 059A 0316 302A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062; +0061 0315 0300 05AE 0350 0062;00E0 05AE 0350 0315 0062;0061 05AE 0300 0350 0315 0062;00E0 05AE 0350 0315 0062;0061 05AE 0300 0350 0315 0062; +0061 0350 0315 0300 05AE 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062; +0061 0315 0300 05AE 0351 0062;00E0 05AE 0351 0315 0062;0061 05AE 0300 0351 0315 0062;00E0 05AE 0351 0315 0062;0061 05AE 0300 0351 0315 0062; +0061 0351 0315 0300 05AE 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062; +0061 0315 0300 05AE 0352 0062;00E0 05AE 0352 0315 0062;0061 05AE 0300 0352 0315 0062;00E0 05AE 0352 0315 0062;0061 05AE 0300 0352 0315 0062; +0061 0352 0315 0300 05AE 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062; +0061 059A 0316 302A 0353 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062; +0061 0353 059A 0316 302A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062; +0061 059A 0316 302A 0354 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062; +0061 0354 059A 0316 302A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062; +0061 059A 0316 302A 0355 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062; +0061 0355 059A 0316 302A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062; +0061 059A 0316 302A 0356 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062; +0061 0356 059A 0316 302A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062; +0061 0315 0300 05AE 0357 0062;00E0 05AE 0357 0315 0062;0061 05AE 0300 0357 0315 0062;00E0 05AE 0357 0315 0062;0061 05AE 0300 0357 0315 0062; +0061 0357 0315 0300 05AE 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062; +0061 035C 0315 0300 0358 0062;00E0 0315 0358 035C 0062;0061 0300 0315 0358 035C 0062;00E0 0315 0358 035C 0062;0061 0300 0315 0358 035C 0062; +0061 0358 035C 0315 0300 0062;00E0 0358 0315 035C 0062;0061 0300 0358 0315 035C 0062;00E0 0358 0315 035C 0062;0061 0300 0358 0315 035C 0062; +0061 059A 0316 302A 0359 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062; +0061 0359 059A 0316 302A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062; +0061 059A 0316 302A 035A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062; +0061 035A 059A 0316 302A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062; +0061 0315 0300 05AE 035B 0062;00E0 05AE 035B 0315 0062;0061 05AE 0300 035B 0315 0062;00E0 05AE 035B 0315 0062;0061 05AE 0300 035B 0315 0062; +0061 035B 0315 0300 05AE 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062; +0061 035D 035C 0315 035C 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062; +0061 035C 035D 035C 0315 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062; +0061 0345 035D 035C 035D 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062; +0061 035D 0345 035D 035C 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062; +0061 0345 035D 035C 035E 0062;0061 035C 035D 035E 0345 0062;0061 035C 035D 035E 0345 0062;0061 035C 035D 035E 0345 0062;0061 035C 035D 035E 0345 0062; +0061 035E 0345 035D 035C 0062;0061 035C 035E 035D 0345 0062;0061 035C 035E 035D 0345 0062;0061 035C 035E 035D 0345 0062;0061 035C 035E 035D 0345 0062; +0061 035D 035C 0315 035F 0062;0061 0315 035C 035F 035D 0062;0061 0315 035C 035F 035D 0062;0061 0315 035C 035F 035D 0062;0061 0315 035C 035F 035D 0062; +0061 035F 035D 035C 0315 0062;0061 0315 035F 035C 035D 0062;0061 0315 035F 035C 035D 0062;0061 0315 035F 035C 035D 0062;0061 0315 035F 035C 035D 0062; +0061 0345 035D 035C 0360 0062;0061 035C 035D 0360 0345 0062;0061 035C 035D 0360 0345 0062;0061 035C 035D 0360 0345 0062;0061 035C 035D 0360 0345 0062; +0061 0360 0345 035D 035C 0062;0061 035C 0360 035D 0345 0062;0061 035C 0360 035D 0345 0062;0061 035C 0360 035D 0345 0062;0061 035C 0360 035D 0345 0062; +0061 0345 035D 035C 0361 0062;0061 035C 035D 0361 0345 0062;0061 035C 035D 0361 0345 0062;0061 035C 035D 0361 0345 0062;0061 035C 035D 0361 0345 0062; +0061 0361 0345 035D 035C 0062;0061 035C 0361 035D 0345 0062;0061 035C 0361 035D 0345 0062;0061 035C 0361 035D 0345 0062;0061 035C 0361 035D 0345 0062; +0061 035D 035C 0315 0362 0062;0061 0315 035C 0362 035D 0062;0061 0315 035C 0362 035D 0062;0061 0315 035C 0362 035D 0062;0061 0315 035C 0362 035D 0062; +0061 0362 035D 035C 0315 0062;0061 0315 0362 035C 035D 0062;0061 0315 0362 035C 035D 0062;0061 0315 0362 035C 035D 0062;0061 0315 0362 035C 035D 0062; +0061 0315 0300 05AE 0363 0062;00E0 05AE 0363 0315 0062;0061 05AE 0300 0363 0315 0062;00E0 05AE 0363 0315 0062;0061 05AE 0300 0363 0315 0062; +0061 0363 0315 0300 05AE 0062;0061 05AE 0363 0300 0315 0062;0061 05AE 0363 0300 0315 0062;0061 05AE 0363 0300 0315 0062;0061 05AE 0363 0300 0315 0062; +0061 0315 0300 05AE 0364 0062;00E0 05AE 0364 0315 0062;0061 05AE 0300 0364 0315 0062;00E0 05AE 0364 0315 0062;0061 05AE 0300 0364 0315 0062; +0061 0364 0315 0300 05AE 0062;0061 05AE 0364 0300 0315 0062;0061 05AE 0364 0300 0315 0062;0061 05AE 0364 0300 0315 0062;0061 05AE 0364 0300 0315 0062; +0061 0315 0300 05AE 0365 0062;00E0 05AE 0365 0315 0062;0061 05AE 0300 0365 0315 0062;00E0 05AE 0365 0315 0062;0061 05AE 0300 0365 0315 0062; +0061 0365 0315 0300 05AE 0062;0061 05AE 0365 0300 0315 0062;0061 05AE 0365 0300 0315 0062;0061 05AE 0365 0300 0315 0062;0061 05AE 0365 0300 0315 0062; +0061 0315 0300 05AE 0366 0062;00E0 05AE 0366 0315 0062;0061 05AE 0300 0366 0315 0062;00E0 05AE 0366 0315 0062;0061 05AE 0300 0366 0315 0062; +0061 0366 0315 0300 05AE 0062;0061 05AE 0366 0300 0315 0062;0061 05AE 0366 0300 0315 0062;0061 05AE 0366 0300 0315 0062;0061 05AE 0366 0300 0315 0062; +0061 0315 0300 05AE 0367 0062;00E0 05AE 0367 0315 0062;0061 05AE 0300 0367 0315 0062;00E0 05AE 0367 0315 0062;0061 05AE 0300 0367 0315 0062; +0061 0367 0315 0300 05AE 0062;0061 05AE 0367 0300 0315 0062;0061 05AE 0367 0300 0315 0062;0061 05AE 0367 0300 0315 0062;0061 05AE 0367 0300 0315 0062; +0061 0315 0300 05AE 0368 0062;00E0 05AE 0368 0315 0062;0061 05AE 0300 0368 0315 0062;00E0 05AE 0368 0315 0062;0061 05AE 0300 0368 0315 0062; +0061 0368 0315 0300 05AE 0062;0061 05AE 0368 0300 0315 0062;0061 05AE 0368 0300 0315 0062;0061 05AE 0368 0300 0315 0062;0061 05AE 0368 0300 0315 0062; +0061 0315 0300 05AE 0369 0062;00E0 05AE 0369 0315 0062;0061 05AE 0300 0369 0315 0062;00E0 05AE 0369 0315 0062;0061 05AE 0300 0369 0315 0062; +0061 0369 0315 0300 05AE 0062;0061 05AE 0369 0300 0315 0062;0061 05AE 0369 0300 0315 0062;0061 05AE 0369 0300 0315 0062;0061 05AE 0369 0300 0315 0062; +0061 0315 0300 05AE 036A 0062;00E0 05AE 036A 0315 0062;0061 05AE 0300 036A 0315 0062;00E0 05AE 036A 0315 0062;0061 05AE 0300 036A 0315 0062; +0061 036A 0315 0300 05AE 0062;0061 05AE 036A 0300 0315 0062;0061 05AE 036A 0300 0315 0062;0061 05AE 036A 0300 0315 0062;0061 05AE 036A 0300 0315 0062; +0061 0315 0300 05AE 036B 0062;00E0 05AE 036B 0315 0062;0061 05AE 0300 036B 0315 0062;00E0 05AE 036B 0315 0062;0061 05AE 0300 036B 0315 0062; +0061 036B 0315 0300 05AE 0062;0061 05AE 036B 0300 0315 0062;0061 05AE 036B 0300 0315 0062;0061 05AE 036B 0300 0315 0062;0061 05AE 036B 0300 0315 0062; +0061 0315 0300 05AE 036C 0062;00E0 05AE 036C 0315 0062;0061 05AE 0300 036C 0315 0062;00E0 05AE 036C 0315 0062;0061 05AE 0300 036C 0315 0062; +0061 036C 0315 0300 05AE 0062;0061 05AE 036C 0300 0315 0062;0061 05AE 036C 0300 0315 0062;0061 05AE 036C 0300 0315 0062;0061 05AE 036C 0300 0315 0062; +0061 0315 0300 05AE 036D 0062;00E0 05AE 036D 0315 0062;0061 05AE 0300 036D 0315 0062;00E0 05AE 036D 0315 0062;0061 05AE 0300 036D 0315 0062; +0061 036D 0315 0300 05AE 0062;0061 05AE 036D 0300 0315 0062;0061 05AE 036D 0300 0315 0062;0061 05AE 036D 0300 0315 0062;0061 05AE 036D 0300 0315 0062; +0061 0315 0300 05AE 036E 0062;00E0 05AE 036E 0315 0062;0061 05AE 0300 036E 0315 0062;00E0 05AE 036E 0315 0062;0061 05AE 0300 036E 0315 0062; +0061 036E 0315 0300 05AE 0062;0061 05AE 036E 0300 0315 0062;0061 05AE 036E 0300 0315 0062;0061 05AE 036E 0300 0315 0062;0061 05AE 036E 0300 0315 0062; +0061 0315 0300 05AE 036F 0062;00E0 05AE 036F 0315 0062;0061 05AE 0300 036F 0315 0062;00E0 05AE 036F 0315 0062;0061 05AE 0300 036F 0315 0062; +0061 036F 0315 0300 05AE 0062;0061 05AE 036F 0300 0315 0062;0061 05AE 036F 0300 0315 0062;0061 05AE 036F 0300 0315 0062;0061 05AE 036F 0300 0315 0062; +0061 0315 0300 05AE 0483 0062;00E0 05AE 0483 0315 0062;0061 05AE 0300 0483 0315 0062;00E0 05AE 0483 0315 0062;0061 05AE 0300 0483 0315 0062; +0061 0483 0315 0300 05AE 0062;0061 05AE 0483 0300 0315 0062;0061 05AE 0483 0300 0315 0062;0061 05AE 0483 0300 0315 0062;0061 05AE 0483 0300 0315 0062; +0061 0315 0300 05AE 0484 0062;00E0 05AE 0484 0315 0062;0061 05AE 0300 0484 0315 0062;00E0 05AE 0484 0315 0062;0061 05AE 0300 0484 0315 0062; +0061 0484 0315 0300 05AE 0062;0061 05AE 0484 0300 0315 0062;0061 05AE 0484 0300 0315 0062;0061 05AE 0484 0300 0315 0062;0061 05AE 0484 0300 0315 0062; +0061 0315 0300 05AE 0485 0062;00E0 05AE 0485 0315 0062;0061 05AE 0300 0485 0315 0062;00E0 05AE 0485 0315 0062;0061 05AE 0300 0485 0315 0062; +0061 0485 0315 0300 05AE 0062;0061 05AE 0485 0300 0315 0062;0061 05AE 0485 0300 0315 0062;0061 05AE 0485 0300 0315 0062;0061 05AE 0485 0300 0315 0062; +0061 0315 0300 05AE 0486 0062;00E0 05AE 0486 0315 0062;0061 05AE 0300 0486 0315 0062;00E0 05AE 0486 0315 0062;0061 05AE 0300 0486 0315 0062; +0061 0486 0315 0300 05AE 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062; +0061 0315 0300 05AE 0487 0062;00E0 05AE 0487 0315 0062;0061 05AE 0300 0487 0315 0062;00E0 05AE 0487 0315 0062;0061 05AE 0300 0487 0315 0062; +0061 0487 0315 0300 05AE 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062; +0061 059A 0316 302A 0591 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062; +0061 0591 059A 0316 302A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062; +0061 0315 0300 05AE 0592 0062;00E0 05AE 0592 0315 0062;0061 05AE 0300 0592 0315 0062;00E0 05AE 0592 0315 0062;0061 05AE 0300 0592 0315 0062; +0061 0592 0315 0300 05AE 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062; +0061 0315 0300 05AE 0593 0062;00E0 05AE 0593 0315 0062;0061 05AE 0300 0593 0315 0062;00E0 05AE 0593 0315 0062;0061 05AE 0300 0593 0315 0062; +0061 0593 0315 0300 05AE 0062;0061 05AE 0593 0300 0315 0062;0061 05AE 0593 0300 0315 0062;0061 05AE 0593 0300 0315 0062;0061 05AE 0593 0300 0315 0062; +0061 0315 0300 05AE 0594 0062;00E0 05AE 0594 0315 0062;0061 05AE 0300 0594 0315 0062;00E0 05AE 0594 0315 0062;0061 05AE 0300 0594 0315 0062; +0061 0594 0315 0300 05AE 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062; +0061 0315 0300 05AE 0595 0062;00E0 05AE 0595 0315 0062;0061 05AE 0300 0595 0315 0062;00E0 05AE 0595 0315 0062;0061 05AE 0300 0595 0315 0062; +0061 0595 0315 0300 05AE 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062; +0061 059A 0316 302A 0596 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062; +0061 0596 059A 0316 302A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062; +0061 0315 0300 05AE 0597 0062;00E0 05AE 0597 0315 0062;0061 05AE 0300 0597 0315 0062;00E0 05AE 0597 0315 0062;0061 05AE 0300 0597 0315 0062; +0061 0597 0315 0300 05AE 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062; +0061 0315 0300 05AE 0598 0062;00E0 05AE 0598 0315 0062;0061 05AE 0300 0598 0315 0062;00E0 05AE 0598 0315 0062;0061 05AE 0300 0598 0315 0062; +0061 0598 0315 0300 05AE 0062;0061 05AE 0598 0300 0315 0062;0061 05AE 0598 0300 0315 0062;0061 05AE 0598 0300 0315 0062;0061 05AE 0598 0300 0315 0062; +0061 0315 0300 05AE 0599 0062;00E0 05AE 0599 0315 0062;0061 05AE 0300 0599 0315 0062;00E0 05AE 0599 0315 0062;0061 05AE 0300 0599 0315 0062; +0061 0599 0315 0300 05AE 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062; +0061 302E 059A 0316 059A 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062; +0061 059A 302E 059A 0316 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062; +0061 059A 0316 302A 059B 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062; +0061 059B 059A 0316 302A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062; +0061 0315 0300 05AE 059C 0062;00E0 05AE 059C 0315 0062;0061 05AE 0300 059C 0315 0062;00E0 05AE 059C 0315 0062;0061 05AE 0300 059C 0315 0062; +0061 059C 0315 0300 05AE 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062; +0061 0315 0300 05AE 059D 0062;00E0 05AE 059D 0315 0062;0061 05AE 0300 059D 0315 0062;00E0 05AE 059D 0315 0062;0061 05AE 0300 059D 0315 0062; +0061 059D 0315 0300 05AE 0062;0061 05AE 059D 0300 0315 0062;0061 05AE 059D 0300 0315 0062;0061 05AE 059D 0300 0315 0062;0061 05AE 059D 0300 0315 0062; +0061 0315 0300 05AE 059E 0062;00E0 05AE 059E 0315 0062;0061 05AE 0300 059E 0315 0062;00E0 05AE 059E 0315 0062;0061 05AE 0300 059E 0315 0062; +0061 059E 0315 0300 05AE 0062;0061 05AE 059E 0300 0315 0062;0061 05AE 059E 0300 0315 0062;0061 05AE 059E 0300 0315 0062;0061 05AE 059E 0300 0315 0062; +0061 0315 0300 05AE 059F 0062;00E0 05AE 059F 0315 0062;0061 05AE 0300 059F 0315 0062;00E0 05AE 059F 0315 0062;0061 05AE 0300 059F 0315 0062; +0061 059F 0315 0300 05AE 0062;0061 05AE 059F 0300 0315 0062;0061 05AE 059F 0300 0315 0062;0061 05AE 059F 0300 0315 0062;0061 05AE 059F 0300 0315 0062; +0061 0315 0300 05AE 05A0 0062;00E0 05AE 05A0 0315 0062;0061 05AE 0300 05A0 0315 0062;00E0 05AE 05A0 0315 0062;0061 05AE 0300 05A0 0315 0062; +0061 05A0 0315 0300 05AE 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062; +0061 0315 0300 05AE 05A1 0062;00E0 05AE 05A1 0315 0062;0061 05AE 0300 05A1 0315 0062;00E0 05AE 05A1 0315 0062;0061 05AE 0300 05A1 0315 0062; +0061 05A1 0315 0300 05AE 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062; +0061 059A 0316 302A 05A2 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062; +0061 05A2 059A 0316 302A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062; +0061 059A 0316 302A 05A3 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062; +0061 05A3 059A 0316 302A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062; +0061 059A 0316 302A 05A4 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062; +0061 05A4 059A 0316 302A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062; +0061 059A 0316 302A 05A5 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062; +0061 05A5 059A 0316 302A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062; +0061 059A 0316 302A 05A6 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062; +0061 05A6 059A 0316 302A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062; +0061 059A 0316 302A 05A7 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062; +0061 05A7 059A 0316 302A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062; +0061 0315 0300 05AE 05A8 0062;00E0 05AE 05A8 0315 0062;0061 05AE 0300 05A8 0315 0062;00E0 05AE 05A8 0315 0062;0061 05AE 0300 05A8 0315 0062; +0061 05A8 0315 0300 05AE 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062; +0061 0315 0300 05AE 05A9 0062;00E0 05AE 05A9 0315 0062;0061 05AE 0300 05A9 0315 0062;00E0 05AE 05A9 0315 0062;0061 05AE 0300 05A9 0315 0062; +0061 05A9 0315 0300 05AE 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062; +0061 059A 0316 302A 05AA 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062; +0061 05AA 059A 0316 302A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062; +0061 0315 0300 05AE 05AB 0062;00E0 05AE 05AB 0315 0062;0061 05AE 0300 05AB 0315 0062;00E0 05AE 05AB 0315 0062;0061 05AE 0300 05AB 0315 0062; +0061 05AB 0315 0300 05AE 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062; +0061 0315 0300 05AE 05AC 0062;00E0 05AE 05AC 0315 0062;0061 05AE 0300 05AC 0315 0062;00E0 05AE 05AC 0315 0062;0061 05AE 0300 05AC 0315 0062; +0061 05AC 0315 0300 05AE 0062;0061 05AE 05AC 0300 0315 0062;0061 05AE 05AC 0300 0315 0062;0061 05AE 05AC 0300 0315 0062;0061 05AE 05AC 0300 0315 0062; +0061 302E 059A 0316 05AD 0062;0061 0316 059A 05AD 302E 0062;0061 0316 059A 05AD 302E 0062;0061 0316 059A 05AD 302E 0062;0061 0316 059A 05AD 302E 0062; +0061 05AD 302E 059A 0316 0062;0061 0316 05AD 059A 302E 0062;0061 0316 05AD 059A 302E 0062;0061 0316 05AD 059A 302E 0062;0061 0316 05AD 059A 302E 0062; +0061 0300 05AE 1D16D 05AE 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062; +0061 05AE 0300 05AE 1D16D 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062; +0061 0315 0300 05AE 05AF 0062;00E0 05AE 05AF 0315 0062;0061 05AE 0300 05AF 0315 0062;00E0 05AE 05AF 0315 0062;0061 05AE 0300 05AF 0315 0062; +0061 05AF 0315 0300 05AE 0062;0061 05AE 05AF 0300 0315 0062;0061 05AE 05AF 0300 0315 0062;0061 05AE 05AF 0300 0315 0062;0061 05AE 05AF 0300 0315 0062; +0061 05B1 05B0 094D 05B0 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062; +0061 05B0 05B1 05B0 094D 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062; +0061 05B2 05B1 05B0 05B1 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062; +0061 05B1 05B2 05B1 05B0 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062; +0061 05B3 05B2 05B1 05B2 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062; +0061 05B2 05B3 05B2 05B1 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062; +0061 05B4 05B3 05B2 05B3 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062; +0061 05B3 05B4 05B3 05B2 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062; +0061 05B5 05B4 05B3 05B4 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062; +0061 05B4 05B5 05B4 05B3 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062; +0061 05B6 05B5 05B4 05B5 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062; +0061 05B5 05B6 05B5 05B4 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062; +0061 05B7 05B6 05B5 05B6 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062; +0061 05B6 05B7 05B6 05B5 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062; +0061 05B8 05B7 05B6 05B7 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062; +0061 05B7 05B8 05B7 05B6 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062; +0061 05B9 05B8 05B7 05B8 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062; +0061 05B8 05B9 05B8 05B7 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062; +0061 05BB 05B9 05B8 05B9 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062; +0061 05B9 05BB 05B9 05B8 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062; +0061 05BB 05B9 05B8 05BA 0062;0061 05B8 05B9 05BA 05BB 0062;0061 05B8 05B9 05BA 05BB 0062;0061 05B8 05B9 05BA 05BB 0062;0061 05B8 05B9 05BA 05BB 0062; +0061 05BA 05BB 05B9 05B8 0062;0061 05B8 05BA 05B9 05BB 0062;0061 05B8 05BA 05B9 05BB 0062;0061 05B8 05BA 05B9 05BB 0062;0061 05B8 05BA 05B9 05BB 0062; +0061 05BC 05BB 05B9 05BB 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062; +0061 05BB 05BC 05BB 05B9 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062; +0061 05BD 05BC 05BB 05BC 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062; +0061 05BC 05BD 05BC 05BB 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062; +0061 05BF 05BD 05BC 05BD 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062; +0061 05BD 05BF 05BD 05BC 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062; +0061 05C1 05BF 05BD 05BF 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062; +0061 05BF 05C1 05BF 05BD 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062; +0061 05C2 05C1 05BF 05C1 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062; +0061 05C1 05C2 05C1 05BF 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062; +0061 FB1E 05C2 05C1 05C2 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062; +0061 05C2 FB1E 05C2 05C1 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062; +0061 0315 0300 05AE 05C4 0062;00E0 05AE 05C4 0315 0062;0061 05AE 0300 05C4 0315 0062;00E0 05AE 05C4 0315 0062;0061 05AE 0300 05C4 0315 0062; +0061 05C4 0315 0300 05AE 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062; +0061 059A 0316 302A 05C5 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062; +0061 05C5 059A 0316 302A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062; +0061 05B9 05B8 05B7 05C7 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062; +0061 05C7 05B9 05B8 05B7 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062; +0061 0315 0300 05AE 0610 0062;00E0 05AE 0610 0315 0062;0061 05AE 0300 0610 0315 0062;00E0 05AE 0610 0315 0062;0061 05AE 0300 0610 0315 0062; +0061 0610 0315 0300 05AE 0062;0061 05AE 0610 0300 0315 0062;0061 05AE 0610 0300 0315 0062;0061 05AE 0610 0300 0315 0062;0061 05AE 0610 0300 0315 0062; +0061 0315 0300 05AE 0611 0062;00E0 05AE 0611 0315 0062;0061 05AE 0300 0611 0315 0062;00E0 05AE 0611 0315 0062;0061 05AE 0300 0611 0315 0062; +0061 0611 0315 0300 05AE 0062;0061 05AE 0611 0300 0315 0062;0061 05AE 0611 0300 0315 0062;0061 05AE 0611 0300 0315 0062;0061 05AE 0611 0300 0315 0062; +0061 0315 0300 05AE 0612 0062;00E0 05AE 0612 0315 0062;0061 05AE 0300 0612 0315 0062;00E0 05AE 0612 0315 0062;0061 05AE 0300 0612 0315 0062; +0061 0612 0315 0300 05AE 0062;0061 05AE 0612 0300 0315 0062;0061 05AE 0612 0300 0315 0062;0061 05AE 0612 0300 0315 0062;0061 05AE 0612 0300 0315 0062; +0061 0315 0300 05AE 0613 0062;00E0 05AE 0613 0315 0062;0061 05AE 0300 0613 0315 0062;00E0 05AE 0613 0315 0062;0061 05AE 0300 0613 0315 0062; +0061 0613 0315 0300 05AE 0062;0061 05AE 0613 0300 0315 0062;0061 05AE 0613 0300 0315 0062;0061 05AE 0613 0300 0315 0062;0061 05AE 0613 0300 0315 0062; +0061 0315 0300 05AE 0614 0062;00E0 05AE 0614 0315 0062;0061 05AE 0300 0614 0315 0062;00E0 05AE 0614 0315 0062;0061 05AE 0300 0614 0315 0062; +0061 0614 0315 0300 05AE 0062;0061 05AE 0614 0300 0315 0062;0061 05AE 0614 0300 0315 0062;0061 05AE 0614 0300 0315 0062;0061 05AE 0614 0300 0315 0062; +0061 0315 0300 05AE 0615 0062;00E0 05AE 0615 0315 0062;0061 05AE 0300 0615 0315 0062;00E0 05AE 0615 0315 0062;0061 05AE 0300 0615 0315 0062; +0061 0615 0315 0300 05AE 0062;0061 05AE 0615 0300 0315 0062;0061 05AE 0615 0300 0315 0062;0061 05AE 0615 0300 0315 0062;0061 05AE 0615 0300 0315 0062; +0061 0315 0300 05AE 0616 0062;00E0 05AE 0616 0315 0062;0061 05AE 0300 0616 0315 0062;00E0 05AE 0616 0315 0062;0061 05AE 0300 0616 0315 0062; +0061 0616 0315 0300 05AE 0062;0061 05AE 0616 0300 0315 0062;0061 05AE 0616 0300 0315 0062;0061 05AE 0616 0300 0315 0062;0061 05AE 0616 0300 0315 0062; +0061 0315 0300 05AE 0617 0062;00E0 05AE 0617 0315 0062;0061 05AE 0300 0617 0315 0062;00E0 05AE 0617 0315 0062;0061 05AE 0300 0617 0315 0062; +0061 0617 0315 0300 05AE 0062;0061 05AE 0617 0300 0315 0062;0061 05AE 0617 0300 0315 0062;0061 05AE 0617 0300 0315 0062;0061 05AE 0617 0300 0315 0062; +0061 0619 0618 064D 0618 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062; +0061 0618 0619 0618 064D 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062; +0061 061A 0619 0618 0619 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062; +0061 0619 061A 0619 0618 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062; +0061 0651 061A 0619 061A 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062; +0061 061A 0651 061A 0619 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062; +0061 064C 064B FB1E 064B 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062; +0061 064B 064C 064B FB1E 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062; +0061 064D 064C 064B 064C 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062; +0061 064C 064D 064C 064B 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062; +0061 0618 064D 064C 064D 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062; +0061 064D 0618 064D 064C 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062; +0061 0619 0618 064D 064E 0062;0061 064D 0618 064E 0619 0062;0061 064D 0618 064E 0619 0062;0061 064D 0618 064E 0619 0062;0061 064D 0618 064E 0619 0062; +0061 064E 0619 0618 064D 0062;0061 064D 064E 0618 0619 0062;0061 064D 064E 0618 0619 0062;0061 064D 064E 0618 0619 0062;0061 064D 064E 0618 0619 0062; +0061 061A 0619 0618 064F 0062;0061 0618 0619 064F 061A 0062;0061 0618 0619 064F 061A 0062;0061 0618 0619 064F 061A 0062;0061 0618 0619 064F 061A 0062; +0061 064F 061A 0619 0618 0062;0061 0618 064F 0619 061A 0062;0061 0618 064F 0619 061A 0062;0061 0618 064F 0619 061A 0062;0061 0618 064F 0619 061A 0062; +0061 0651 061A 0619 0650 0062;0061 0619 061A 0650 0651 0062;0061 0619 061A 0650 0651 0062;0061 0619 061A 0650 0651 0062;0061 0619 061A 0650 0651 0062; +0061 0650 0651 061A 0619 0062;0061 0619 0650 061A 0651 0062;0061 0619 0650 061A 0651 0062;0061 0619 0650 061A 0651 0062;0061 0619 0650 061A 0651 0062; +0061 0652 0651 061A 0651 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062; +0061 0651 0652 0651 061A 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062; +0061 0670 0652 0651 0652 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062; +0061 0652 0670 0652 0651 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062; +0061 0315 0300 05AE 0653 0062;00E0 05AE 0653 0315 0062;0061 05AE 0300 0653 0315 0062;00E0 05AE 0653 0315 0062;0061 05AE 0300 0653 0315 0062; +0061 0653 0315 0300 05AE 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062; +0061 0315 0300 05AE 0654 0062;00E0 05AE 0654 0315 0062;0061 05AE 0300 0654 0315 0062;00E0 05AE 0654 0315 0062;0061 05AE 0300 0654 0315 0062; +0061 0654 0315 0300 05AE 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062; +0061 059A 0316 302A 0655 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062; +0061 0655 059A 0316 302A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062; +0061 059A 0316 302A 0656 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062; +0061 0656 059A 0316 302A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062; +0061 0315 0300 05AE 0657 0062;00E0 05AE 0657 0315 0062;0061 05AE 0300 0657 0315 0062;00E0 05AE 0657 0315 0062;0061 05AE 0300 0657 0315 0062; +0061 0657 0315 0300 05AE 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062; +0061 0315 0300 05AE 0658 0062;00E0 05AE 0658 0315 0062;0061 05AE 0300 0658 0315 0062;00E0 05AE 0658 0315 0062;0061 05AE 0300 0658 0315 0062; +0061 0658 0315 0300 05AE 0062;0061 05AE 0658 0300 0315 0062;0061 05AE 0658 0300 0315 0062;0061 05AE 0658 0300 0315 0062;0061 05AE 0658 0300 0315 0062; +0061 0315 0300 05AE 0659 0062;00E0 05AE 0659 0315 0062;0061 05AE 0300 0659 0315 0062;00E0 05AE 0659 0315 0062;0061 05AE 0300 0659 0315 0062; +0061 0659 0315 0300 05AE 0062;0061 05AE 0659 0300 0315 0062;0061 05AE 0659 0300 0315 0062;0061 05AE 0659 0300 0315 0062;0061 05AE 0659 0300 0315 0062; +0061 0315 0300 05AE 065A 0062;00E0 05AE 065A 0315 0062;0061 05AE 0300 065A 0315 0062;00E0 05AE 065A 0315 0062;0061 05AE 0300 065A 0315 0062; +0061 065A 0315 0300 05AE 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062; +0061 0315 0300 05AE 065B 0062;00E0 05AE 065B 0315 0062;0061 05AE 0300 065B 0315 0062;00E0 05AE 065B 0315 0062;0061 05AE 0300 065B 0315 0062; +0061 065B 0315 0300 05AE 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062; +0061 059A 0316 302A 065C 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062; +0061 065C 059A 0316 302A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062; +0061 0315 0300 05AE 065D 0062;00E0 05AE 065D 0315 0062;0061 05AE 0300 065D 0315 0062;00E0 05AE 065D 0315 0062;0061 05AE 0300 065D 0315 0062; +0061 065D 0315 0300 05AE 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062; +0061 0315 0300 05AE 065E 0062;00E0 05AE 065E 0315 0062;0061 05AE 0300 065E 0315 0062;00E0 05AE 065E 0315 0062;0061 05AE 0300 065E 0315 0062; +0061 065E 0315 0300 05AE 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062; +0061 059A 0316 302A 065F 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062; +0061 065F 059A 0316 302A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062; +0061 0711 0670 0652 0670 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062; +0061 0670 0711 0670 0652 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062; +0061 0315 0300 05AE 06D6 0062;00E0 05AE 06D6 0315 0062;0061 05AE 0300 06D6 0315 0062;00E0 05AE 06D6 0315 0062;0061 05AE 0300 06D6 0315 0062; +0061 06D6 0315 0300 05AE 0062;0061 05AE 06D6 0300 0315 0062;0061 05AE 06D6 0300 0315 0062;0061 05AE 06D6 0300 0315 0062;0061 05AE 06D6 0300 0315 0062; +0061 0315 0300 05AE 06D7 0062;00E0 05AE 06D7 0315 0062;0061 05AE 0300 06D7 0315 0062;00E0 05AE 06D7 0315 0062;0061 05AE 0300 06D7 0315 0062; +0061 06D7 0315 0300 05AE 0062;0061 05AE 06D7 0300 0315 0062;0061 05AE 06D7 0300 0315 0062;0061 05AE 06D7 0300 0315 0062;0061 05AE 06D7 0300 0315 0062; +0061 0315 0300 05AE 06D8 0062;00E0 05AE 06D8 0315 0062;0061 05AE 0300 06D8 0315 0062;00E0 05AE 06D8 0315 0062;0061 05AE 0300 06D8 0315 0062; +0061 06D8 0315 0300 05AE 0062;0061 05AE 06D8 0300 0315 0062;0061 05AE 06D8 0300 0315 0062;0061 05AE 06D8 0300 0315 0062;0061 05AE 06D8 0300 0315 0062; +0061 0315 0300 05AE 06D9 0062;00E0 05AE 06D9 0315 0062;0061 05AE 0300 06D9 0315 0062;00E0 05AE 06D9 0315 0062;0061 05AE 0300 06D9 0315 0062; +0061 06D9 0315 0300 05AE 0062;0061 05AE 06D9 0300 0315 0062;0061 05AE 06D9 0300 0315 0062;0061 05AE 06D9 0300 0315 0062;0061 05AE 06D9 0300 0315 0062; +0061 0315 0300 05AE 06DA 0062;00E0 05AE 06DA 0315 0062;0061 05AE 0300 06DA 0315 0062;00E0 05AE 06DA 0315 0062;0061 05AE 0300 06DA 0315 0062; +0061 06DA 0315 0300 05AE 0062;0061 05AE 06DA 0300 0315 0062;0061 05AE 06DA 0300 0315 0062;0061 05AE 06DA 0300 0315 0062;0061 05AE 06DA 0300 0315 0062; +0061 0315 0300 05AE 06DB 0062;00E0 05AE 06DB 0315 0062;0061 05AE 0300 06DB 0315 0062;00E0 05AE 06DB 0315 0062;0061 05AE 0300 06DB 0315 0062; +0061 06DB 0315 0300 05AE 0062;0061 05AE 06DB 0300 0315 0062;0061 05AE 06DB 0300 0315 0062;0061 05AE 06DB 0300 0315 0062;0061 05AE 06DB 0300 0315 0062; +0061 0315 0300 05AE 06DC 0062;00E0 05AE 06DC 0315 0062;0061 05AE 0300 06DC 0315 0062;00E0 05AE 06DC 0315 0062;0061 05AE 0300 06DC 0315 0062; +0061 06DC 0315 0300 05AE 0062;0061 05AE 06DC 0300 0315 0062;0061 05AE 06DC 0300 0315 0062;0061 05AE 06DC 0300 0315 0062;0061 05AE 06DC 0300 0315 0062; +0061 0315 0300 05AE 06DF 0062;00E0 05AE 06DF 0315 0062;0061 05AE 0300 06DF 0315 0062;00E0 05AE 06DF 0315 0062;0061 05AE 0300 06DF 0315 0062; +0061 06DF 0315 0300 05AE 0062;0061 05AE 06DF 0300 0315 0062;0061 05AE 06DF 0300 0315 0062;0061 05AE 06DF 0300 0315 0062;0061 05AE 06DF 0300 0315 0062; +0061 0315 0300 05AE 06E0 0062;00E0 05AE 06E0 0315 0062;0061 05AE 0300 06E0 0315 0062;00E0 05AE 06E0 0315 0062;0061 05AE 0300 06E0 0315 0062; +0061 06E0 0315 0300 05AE 0062;0061 05AE 06E0 0300 0315 0062;0061 05AE 06E0 0300 0315 0062;0061 05AE 06E0 0300 0315 0062;0061 05AE 06E0 0300 0315 0062; +0061 0315 0300 05AE 06E1 0062;00E0 05AE 06E1 0315 0062;0061 05AE 0300 06E1 0315 0062;00E0 05AE 06E1 0315 0062;0061 05AE 0300 06E1 0315 0062; +0061 06E1 0315 0300 05AE 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062; +0061 0315 0300 05AE 06E2 0062;00E0 05AE 06E2 0315 0062;0061 05AE 0300 06E2 0315 0062;00E0 05AE 06E2 0315 0062;0061 05AE 0300 06E2 0315 0062; +0061 06E2 0315 0300 05AE 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062; +0061 059A 0316 302A 06E3 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062; +0061 06E3 059A 0316 302A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062; +0061 0315 0300 05AE 06E4 0062;00E0 05AE 06E4 0315 0062;0061 05AE 0300 06E4 0315 0062;00E0 05AE 06E4 0315 0062;0061 05AE 0300 06E4 0315 0062; +0061 06E4 0315 0300 05AE 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062; +0061 0315 0300 05AE 06E7 0062;00E0 05AE 06E7 0315 0062;0061 05AE 0300 06E7 0315 0062;00E0 05AE 06E7 0315 0062;0061 05AE 0300 06E7 0315 0062; +0061 06E7 0315 0300 05AE 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062; +0061 0315 0300 05AE 06E8 0062;00E0 05AE 06E8 0315 0062;0061 05AE 0300 06E8 0315 0062;00E0 05AE 06E8 0315 0062;0061 05AE 0300 06E8 0315 0062; +0061 06E8 0315 0300 05AE 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062; +0061 059A 0316 302A 06EA 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062; +0061 06EA 059A 0316 302A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062; +0061 0315 0300 05AE 06EB 0062;00E0 05AE 06EB 0315 0062;0061 05AE 0300 06EB 0315 0062;00E0 05AE 06EB 0315 0062;0061 05AE 0300 06EB 0315 0062; +0061 06EB 0315 0300 05AE 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062; +0061 0315 0300 05AE 06EC 0062;00E0 05AE 06EC 0315 0062;0061 05AE 0300 06EC 0315 0062;00E0 05AE 06EC 0315 0062;0061 05AE 0300 06EC 0315 0062; +0061 06EC 0315 0300 05AE 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062; +0061 059A 0316 302A 06ED 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062; +0061 06ED 059A 0316 302A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062; +0061 0C55 0711 0670 0711 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062; +0061 0711 0C55 0711 0670 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062; +0061 0315 0300 05AE 0730 0062;00E0 05AE 0730 0315 0062;0061 05AE 0300 0730 0315 0062;00E0 05AE 0730 0315 0062;0061 05AE 0300 0730 0315 0062; +0061 0730 0315 0300 05AE 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062; +0061 059A 0316 302A 0731 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062; +0061 0731 059A 0316 302A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062; +0061 0315 0300 05AE 0732 0062;00E0 05AE 0732 0315 0062;0061 05AE 0300 0732 0315 0062;00E0 05AE 0732 0315 0062;0061 05AE 0300 0732 0315 0062; +0061 0732 0315 0300 05AE 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062; +0061 0315 0300 05AE 0733 0062;00E0 05AE 0733 0315 0062;0061 05AE 0300 0733 0315 0062;00E0 05AE 0733 0315 0062;0061 05AE 0300 0733 0315 0062; +0061 0733 0315 0300 05AE 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062; +0061 059A 0316 302A 0734 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062; +0061 0734 059A 0316 302A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062; +0061 0315 0300 05AE 0735 0062;00E0 05AE 0735 0315 0062;0061 05AE 0300 0735 0315 0062;00E0 05AE 0735 0315 0062;0061 05AE 0300 0735 0315 0062; +0061 0735 0315 0300 05AE 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062; +0061 0315 0300 05AE 0736 0062;00E0 05AE 0736 0315 0062;0061 05AE 0300 0736 0315 0062;00E0 05AE 0736 0315 0062;0061 05AE 0300 0736 0315 0062; +0061 0736 0315 0300 05AE 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062; +0061 059A 0316 302A 0737 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062; +0061 0737 059A 0316 302A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062; +0061 059A 0316 302A 0738 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062; +0061 0738 059A 0316 302A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062; +0061 059A 0316 302A 0739 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062; +0061 0739 059A 0316 302A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062; +0061 0315 0300 05AE 073A 0062;00E0 05AE 073A 0315 0062;0061 05AE 0300 073A 0315 0062;00E0 05AE 073A 0315 0062;0061 05AE 0300 073A 0315 0062; +0061 073A 0315 0300 05AE 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062; +0061 059A 0316 302A 073B 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062; +0061 073B 059A 0316 302A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062; +0061 059A 0316 302A 073C 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062; +0061 073C 059A 0316 302A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062; +0061 0315 0300 05AE 073D 0062;00E0 05AE 073D 0315 0062;0061 05AE 0300 073D 0315 0062;00E0 05AE 073D 0315 0062;0061 05AE 0300 073D 0315 0062; +0061 073D 0315 0300 05AE 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062; +0061 059A 0316 302A 073E 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062; +0061 073E 059A 0316 302A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062; +0061 0315 0300 05AE 073F 0062;00E0 05AE 073F 0315 0062;0061 05AE 0300 073F 0315 0062;00E0 05AE 073F 0315 0062;0061 05AE 0300 073F 0315 0062; +0061 073F 0315 0300 05AE 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062; +0061 0315 0300 05AE 0740 0062;00E0 05AE 0740 0315 0062;0061 05AE 0300 0740 0315 0062;00E0 05AE 0740 0315 0062;0061 05AE 0300 0740 0315 0062; +0061 0740 0315 0300 05AE 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062; +0061 0315 0300 05AE 0741 0062;00E0 05AE 0741 0315 0062;0061 05AE 0300 0741 0315 0062;00E0 05AE 0741 0315 0062;0061 05AE 0300 0741 0315 0062; +0061 0741 0315 0300 05AE 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062; +0061 059A 0316 302A 0742 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062; +0061 0742 059A 0316 302A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062; +0061 0315 0300 05AE 0743 0062;00E0 05AE 0743 0315 0062;0061 05AE 0300 0743 0315 0062;00E0 05AE 0743 0315 0062;0061 05AE 0300 0743 0315 0062; +0061 0743 0315 0300 05AE 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062; +0061 059A 0316 302A 0744 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062; +0061 0744 059A 0316 302A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062; +0061 0315 0300 05AE 0745 0062;00E0 05AE 0745 0315 0062;0061 05AE 0300 0745 0315 0062;00E0 05AE 0745 0315 0062;0061 05AE 0300 0745 0315 0062; +0061 0745 0315 0300 05AE 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062; +0061 059A 0316 302A 0746 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062; +0061 0746 059A 0316 302A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062; +0061 0315 0300 05AE 0747 0062;00E0 05AE 0747 0315 0062;0061 05AE 0300 0747 0315 0062;00E0 05AE 0747 0315 0062;0061 05AE 0300 0747 0315 0062; +0061 0747 0315 0300 05AE 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062; +0061 059A 0316 302A 0748 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062; +0061 0748 059A 0316 302A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062; +0061 0315 0300 05AE 0749 0062;00E0 05AE 0749 0315 0062;0061 05AE 0300 0749 0315 0062;00E0 05AE 0749 0315 0062;0061 05AE 0300 0749 0315 0062; +0061 0749 0315 0300 05AE 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062; +0061 0315 0300 05AE 074A 0062;00E0 05AE 074A 0315 0062;0061 05AE 0300 074A 0315 0062;00E0 05AE 074A 0315 0062;0061 05AE 0300 074A 0315 0062; +0061 074A 0315 0300 05AE 0062;0061 05AE 074A 0300 0315 0062;0061 05AE 074A 0300 0315 0062;0061 05AE 074A 0300 0315 0062;0061 05AE 074A 0300 0315 0062; +0061 0315 0300 05AE 07EB 0062;00E0 05AE 07EB 0315 0062;0061 05AE 0300 07EB 0315 0062;00E0 05AE 07EB 0315 0062;0061 05AE 0300 07EB 0315 0062; +0061 07EB 0315 0300 05AE 0062;0061 05AE 07EB 0300 0315 0062;0061 05AE 07EB 0300 0315 0062;0061 05AE 07EB 0300 0315 0062;0061 05AE 07EB 0300 0315 0062; +0061 0315 0300 05AE 07EC 0062;00E0 05AE 07EC 0315 0062;0061 05AE 0300 07EC 0315 0062;00E0 05AE 07EC 0315 0062;0061 05AE 0300 07EC 0315 0062; +0061 07EC 0315 0300 05AE 0062;0061 05AE 07EC 0300 0315 0062;0061 05AE 07EC 0300 0315 0062;0061 05AE 07EC 0300 0315 0062;0061 05AE 07EC 0300 0315 0062; +0061 0315 0300 05AE 07ED 0062;00E0 05AE 07ED 0315 0062;0061 05AE 0300 07ED 0315 0062;00E0 05AE 07ED 0315 0062;0061 05AE 0300 07ED 0315 0062; +0061 07ED 0315 0300 05AE 0062;0061 05AE 07ED 0300 0315 0062;0061 05AE 07ED 0300 0315 0062;0061 05AE 07ED 0300 0315 0062;0061 05AE 07ED 0300 0315 0062; +0061 0315 0300 05AE 07EE 0062;00E0 05AE 07EE 0315 0062;0061 05AE 0300 07EE 0315 0062;00E0 05AE 07EE 0315 0062;0061 05AE 0300 07EE 0315 0062; +0061 07EE 0315 0300 05AE 0062;0061 05AE 07EE 0300 0315 0062;0061 05AE 07EE 0300 0315 0062;0061 05AE 07EE 0300 0315 0062;0061 05AE 07EE 0300 0315 0062; +0061 0315 0300 05AE 07EF 0062;00E0 05AE 07EF 0315 0062;0061 05AE 0300 07EF 0315 0062;00E0 05AE 07EF 0315 0062;0061 05AE 0300 07EF 0315 0062; +0061 07EF 0315 0300 05AE 0062;0061 05AE 07EF 0300 0315 0062;0061 05AE 07EF 0300 0315 0062;0061 05AE 07EF 0300 0315 0062;0061 05AE 07EF 0300 0315 0062; +0061 0315 0300 05AE 07F0 0062;00E0 05AE 07F0 0315 0062;0061 05AE 0300 07F0 0315 0062;00E0 05AE 07F0 0315 0062;0061 05AE 0300 07F0 0315 0062; +0061 07F0 0315 0300 05AE 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062; +0061 0315 0300 05AE 07F1 0062;00E0 05AE 07F1 0315 0062;0061 05AE 0300 07F1 0315 0062;00E0 05AE 07F1 0315 0062;0061 05AE 0300 07F1 0315 0062; +0061 07F1 0315 0300 05AE 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062; +0061 059A 0316 302A 07F2 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062; +0061 07F2 059A 0316 302A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062; +0061 0315 0300 05AE 07F3 0062;00E0 05AE 07F3 0315 0062;0061 05AE 0300 07F3 0315 0062;00E0 05AE 07F3 0315 0062;0061 05AE 0300 07F3 0315 0062; +0061 07F3 0315 0300 05AE 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062; +0061 059A 0316 302A 07FD 0062;0061 302A 0316 07FD 059A 0062;0061 302A 0316 07FD 059A 0062;0061 302A 0316 07FD 059A 0062;0061 302A 0316 07FD 059A 0062; +0061 07FD 059A 0316 302A 0062;0061 302A 07FD 0316 059A 0062;0061 302A 07FD 0316 059A 0062;0061 302A 07FD 0316 059A 0062;0061 302A 07FD 0316 059A 0062; +0061 0315 0300 05AE 0816 0062;00E0 05AE 0816 0315 0062;0061 05AE 0300 0816 0315 0062;00E0 05AE 0816 0315 0062;0061 05AE 0300 0816 0315 0062; +0061 0816 0315 0300 05AE 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062; +0061 0315 0300 05AE 0817 0062;00E0 05AE 0817 0315 0062;0061 05AE 0300 0817 0315 0062;00E0 05AE 0817 0315 0062;0061 05AE 0300 0817 0315 0062; +0061 0817 0315 0300 05AE 0062;0061 05AE 0817 0300 0315 0062;0061 05AE 0817 0300 0315 0062;0061 05AE 0817 0300 0315 0062;0061 05AE 0817 0300 0315 0062; +0061 0315 0300 05AE 0818 0062;00E0 05AE 0818 0315 0062;0061 05AE 0300 0818 0315 0062;00E0 05AE 0818 0315 0062;0061 05AE 0300 0818 0315 0062; +0061 0818 0315 0300 05AE 0062;0061 05AE 0818 0300 0315 0062;0061 05AE 0818 0300 0315 0062;0061 05AE 0818 0300 0315 0062;0061 05AE 0818 0300 0315 0062; +0061 0315 0300 05AE 0819 0062;00E0 05AE 0819 0315 0062;0061 05AE 0300 0819 0315 0062;00E0 05AE 0819 0315 0062;0061 05AE 0300 0819 0315 0062; +0061 0819 0315 0300 05AE 0062;0061 05AE 0819 0300 0315 0062;0061 05AE 0819 0300 0315 0062;0061 05AE 0819 0300 0315 0062;0061 05AE 0819 0300 0315 0062; +0061 0315 0300 05AE 081B 0062;00E0 05AE 081B 0315 0062;0061 05AE 0300 081B 0315 0062;00E0 05AE 081B 0315 0062;0061 05AE 0300 081B 0315 0062; +0061 081B 0315 0300 05AE 0062;0061 05AE 081B 0300 0315 0062;0061 05AE 081B 0300 0315 0062;0061 05AE 081B 0300 0315 0062;0061 05AE 081B 0300 0315 0062; +0061 0315 0300 05AE 081C 0062;00E0 05AE 081C 0315 0062;0061 05AE 0300 081C 0315 0062;00E0 05AE 081C 0315 0062;0061 05AE 0300 081C 0315 0062; +0061 081C 0315 0300 05AE 0062;0061 05AE 081C 0300 0315 0062;0061 05AE 081C 0300 0315 0062;0061 05AE 081C 0300 0315 0062;0061 05AE 081C 0300 0315 0062; +0061 0315 0300 05AE 081D 0062;00E0 05AE 081D 0315 0062;0061 05AE 0300 081D 0315 0062;00E0 05AE 081D 0315 0062;0061 05AE 0300 081D 0315 0062; +0061 081D 0315 0300 05AE 0062;0061 05AE 081D 0300 0315 0062;0061 05AE 081D 0300 0315 0062;0061 05AE 081D 0300 0315 0062;0061 05AE 081D 0300 0315 0062; +0061 0315 0300 05AE 081E 0062;00E0 05AE 081E 0315 0062;0061 05AE 0300 081E 0315 0062;00E0 05AE 081E 0315 0062;0061 05AE 0300 081E 0315 0062; +0061 081E 0315 0300 05AE 0062;0061 05AE 081E 0300 0315 0062;0061 05AE 081E 0300 0315 0062;0061 05AE 081E 0300 0315 0062;0061 05AE 081E 0300 0315 0062; +0061 0315 0300 05AE 081F 0062;00E0 05AE 081F 0315 0062;0061 05AE 0300 081F 0315 0062;00E0 05AE 081F 0315 0062;0061 05AE 0300 081F 0315 0062; +0061 081F 0315 0300 05AE 0062;0061 05AE 081F 0300 0315 0062;0061 05AE 081F 0300 0315 0062;0061 05AE 081F 0300 0315 0062;0061 05AE 081F 0300 0315 0062; +0061 0315 0300 05AE 0820 0062;00E0 05AE 0820 0315 0062;0061 05AE 0300 0820 0315 0062;00E0 05AE 0820 0315 0062;0061 05AE 0300 0820 0315 0062; +0061 0820 0315 0300 05AE 0062;0061 05AE 0820 0300 0315 0062;0061 05AE 0820 0300 0315 0062;0061 05AE 0820 0300 0315 0062;0061 05AE 0820 0300 0315 0062; +0061 0315 0300 05AE 0821 0062;00E0 05AE 0821 0315 0062;0061 05AE 0300 0821 0315 0062;00E0 05AE 0821 0315 0062;0061 05AE 0300 0821 0315 0062; +0061 0821 0315 0300 05AE 0062;0061 05AE 0821 0300 0315 0062;0061 05AE 0821 0300 0315 0062;0061 05AE 0821 0300 0315 0062;0061 05AE 0821 0300 0315 0062; +0061 0315 0300 05AE 0822 0062;00E0 05AE 0822 0315 0062;0061 05AE 0300 0822 0315 0062;00E0 05AE 0822 0315 0062;0061 05AE 0300 0822 0315 0062; +0061 0822 0315 0300 05AE 0062;0061 05AE 0822 0300 0315 0062;0061 05AE 0822 0300 0315 0062;0061 05AE 0822 0300 0315 0062;0061 05AE 0822 0300 0315 0062; +0061 0315 0300 05AE 0823 0062;00E0 05AE 0823 0315 0062;0061 05AE 0300 0823 0315 0062;00E0 05AE 0823 0315 0062;0061 05AE 0300 0823 0315 0062; +0061 0823 0315 0300 05AE 0062;0061 05AE 0823 0300 0315 0062;0061 05AE 0823 0300 0315 0062;0061 05AE 0823 0300 0315 0062;0061 05AE 0823 0300 0315 0062; +0061 0315 0300 05AE 0825 0062;00E0 05AE 0825 0315 0062;0061 05AE 0300 0825 0315 0062;00E0 05AE 0825 0315 0062;0061 05AE 0300 0825 0315 0062; +0061 0825 0315 0300 05AE 0062;0061 05AE 0825 0300 0315 0062;0061 05AE 0825 0300 0315 0062;0061 05AE 0825 0300 0315 0062;0061 05AE 0825 0300 0315 0062; +0061 0315 0300 05AE 0826 0062;00E0 05AE 0826 0315 0062;0061 05AE 0300 0826 0315 0062;00E0 05AE 0826 0315 0062;0061 05AE 0300 0826 0315 0062; +0061 0826 0315 0300 05AE 0062;0061 05AE 0826 0300 0315 0062;0061 05AE 0826 0300 0315 0062;0061 05AE 0826 0300 0315 0062;0061 05AE 0826 0300 0315 0062; +0061 0315 0300 05AE 0827 0062;00E0 05AE 0827 0315 0062;0061 05AE 0300 0827 0315 0062;00E0 05AE 0827 0315 0062;0061 05AE 0300 0827 0315 0062; +0061 0827 0315 0300 05AE 0062;0061 05AE 0827 0300 0315 0062;0061 05AE 0827 0300 0315 0062;0061 05AE 0827 0300 0315 0062;0061 05AE 0827 0300 0315 0062; +0061 0315 0300 05AE 0829 0062;00E0 05AE 0829 0315 0062;0061 05AE 0300 0829 0315 0062;00E0 05AE 0829 0315 0062;0061 05AE 0300 0829 0315 0062; +0061 0829 0315 0300 05AE 0062;0061 05AE 0829 0300 0315 0062;0061 05AE 0829 0300 0315 0062;0061 05AE 0829 0300 0315 0062;0061 05AE 0829 0300 0315 0062; +0061 0315 0300 05AE 082A 0062;00E0 05AE 082A 0315 0062;0061 05AE 0300 082A 0315 0062;00E0 05AE 082A 0315 0062;0061 05AE 0300 082A 0315 0062; +0061 082A 0315 0300 05AE 0062;0061 05AE 082A 0300 0315 0062;0061 05AE 082A 0300 0315 0062;0061 05AE 082A 0300 0315 0062;0061 05AE 082A 0300 0315 0062; +0061 0315 0300 05AE 082B 0062;00E0 05AE 082B 0315 0062;0061 05AE 0300 082B 0315 0062;00E0 05AE 082B 0315 0062;0061 05AE 0300 082B 0315 0062; +0061 082B 0315 0300 05AE 0062;0061 05AE 082B 0300 0315 0062;0061 05AE 082B 0300 0315 0062;0061 05AE 082B 0300 0315 0062;0061 05AE 082B 0300 0315 0062; +0061 0315 0300 05AE 082C 0062;00E0 05AE 082C 0315 0062;0061 05AE 0300 082C 0315 0062;00E0 05AE 082C 0315 0062;0061 05AE 0300 082C 0315 0062; +0061 082C 0315 0300 05AE 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062; +0061 0315 0300 05AE 082D 0062;00E0 05AE 082D 0315 0062;0061 05AE 0300 082D 0315 0062;00E0 05AE 082D 0315 0062;0061 05AE 0300 082D 0315 0062; +0061 082D 0315 0300 05AE 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062; +0061 059A 0316 302A 0859 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062; +0061 0859 059A 0316 302A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062; +0061 059A 0316 302A 085A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062; +0061 085A 059A 0316 302A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062; +0061 059A 0316 302A 085B 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062; +0061 085B 059A 0316 302A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062; +0061 059A 0316 302A 08D3 0062;0061 302A 0316 08D3 059A 0062;0061 302A 0316 08D3 059A 0062;0061 302A 0316 08D3 059A 0062;0061 302A 0316 08D3 059A 0062; +0061 08D3 059A 0316 302A 0062;0061 302A 08D3 0316 059A 0062;0061 302A 08D3 0316 059A 0062;0061 302A 08D3 0316 059A 0062;0061 302A 08D3 0316 059A 0062; +0061 0315 0300 05AE 08D4 0062;00E0 05AE 08D4 0315 0062;0061 05AE 0300 08D4 0315 0062;00E0 05AE 08D4 0315 0062;0061 05AE 0300 08D4 0315 0062; +0061 08D4 0315 0300 05AE 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062; +0061 0315 0300 05AE 08D5 0062;00E0 05AE 08D5 0315 0062;0061 05AE 0300 08D5 0315 0062;00E0 05AE 08D5 0315 0062;0061 05AE 0300 08D5 0315 0062; +0061 08D5 0315 0300 05AE 0062;0061 05AE 08D5 0300 0315 0062;0061 05AE 08D5 0300 0315 0062;0061 05AE 08D5 0300 0315 0062;0061 05AE 08D5 0300 0315 0062; +0061 0315 0300 05AE 08D6 0062;00E0 05AE 08D6 0315 0062;0061 05AE 0300 08D6 0315 0062;00E0 05AE 08D6 0315 0062;0061 05AE 0300 08D6 0315 0062; +0061 08D6 0315 0300 05AE 0062;0061 05AE 08D6 0300 0315 0062;0061 05AE 08D6 0300 0315 0062;0061 05AE 08D6 0300 0315 0062;0061 05AE 08D6 0300 0315 0062; +0061 0315 0300 05AE 08D7 0062;00E0 05AE 08D7 0315 0062;0061 05AE 0300 08D7 0315 0062;00E0 05AE 08D7 0315 0062;0061 05AE 0300 08D7 0315 0062; +0061 08D7 0315 0300 05AE 0062;0061 05AE 08D7 0300 0315 0062;0061 05AE 08D7 0300 0315 0062;0061 05AE 08D7 0300 0315 0062;0061 05AE 08D7 0300 0315 0062; +0061 0315 0300 05AE 08D8 0062;00E0 05AE 08D8 0315 0062;0061 05AE 0300 08D8 0315 0062;00E0 05AE 08D8 0315 0062;0061 05AE 0300 08D8 0315 0062; +0061 08D8 0315 0300 05AE 0062;0061 05AE 08D8 0300 0315 0062;0061 05AE 08D8 0300 0315 0062;0061 05AE 08D8 0300 0315 0062;0061 05AE 08D8 0300 0315 0062; +0061 0315 0300 05AE 08D9 0062;00E0 05AE 08D9 0315 0062;0061 05AE 0300 08D9 0315 0062;00E0 05AE 08D9 0315 0062;0061 05AE 0300 08D9 0315 0062; +0061 08D9 0315 0300 05AE 0062;0061 05AE 08D9 0300 0315 0062;0061 05AE 08D9 0300 0315 0062;0061 05AE 08D9 0300 0315 0062;0061 05AE 08D9 0300 0315 0062; +0061 0315 0300 05AE 08DA 0062;00E0 05AE 08DA 0315 0062;0061 05AE 0300 08DA 0315 0062;00E0 05AE 08DA 0315 0062;0061 05AE 0300 08DA 0315 0062; +0061 08DA 0315 0300 05AE 0062;0061 05AE 08DA 0300 0315 0062;0061 05AE 08DA 0300 0315 0062;0061 05AE 08DA 0300 0315 0062;0061 05AE 08DA 0300 0315 0062; +0061 0315 0300 05AE 08DB 0062;00E0 05AE 08DB 0315 0062;0061 05AE 0300 08DB 0315 0062;00E0 05AE 08DB 0315 0062;0061 05AE 0300 08DB 0315 0062; +0061 08DB 0315 0300 05AE 0062;0061 05AE 08DB 0300 0315 0062;0061 05AE 08DB 0300 0315 0062;0061 05AE 08DB 0300 0315 0062;0061 05AE 08DB 0300 0315 0062; +0061 0315 0300 05AE 08DC 0062;00E0 05AE 08DC 0315 0062;0061 05AE 0300 08DC 0315 0062;00E0 05AE 08DC 0315 0062;0061 05AE 0300 08DC 0315 0062; +0061 08DC 0315 0300 05AE 0062;0061 05AE 08DC 0300 0315 0062;0061 05AE 08DC 0300 0315 0062;0061 05AE 08DC 0300 0315 0062;0061 05AE 08DC 0300 0315 0062; +0061 0315 0300 05AE 08DD 0062;00E0 05AE 08DD 0315 0062;0061 05AE 0300 08DD 0315 0062;00E0 05AE 08DD 0315 0062;0061 05AE 0300 08DD 0315 0062; +0061 08DD 0315 0300 05AE 0062;0061 05AE 08DD 0300 0315 0062;0061 05AE 08DD 0300 0315 0062;0061 05AE 08DD 0300 0315 0062;0061 05AE 08DD 0300 0315 0062; +0061 0315 0300 05AE 08DE 0062;00E0 05AE 08DE 0315 0062;0061 05AE 0300 08DE 0315 0062;00E0 05AE 08DE 0315 0062;0061 05AE 0300 08DE 0315 0062; +0061 08DE 0315 0300 05AE 0062;0061 05AE 08DE 0300 0315 0062;0061 05AE 08DE 0300 0315 0062;0061 05AE 08DE 0300 0315 0062;0061 05AE 08DE 0300 0315 0062; +0061 0315 0300 05AE 08DF 0062;00E0 05AE 08DF 0315 0062;0061 05AE 0300 08DF 0315 0062;00E0 05AE 08DF 0315 0062;0061 05AE 0300 08DF 0315 0062; +0061 08DF 0315 0300 05AE 0062;0061 05AE 08DF 0300 0315 0062;0061 05AE 08DF 0300 0315 0062;0061 05AE 08DF 0300 0315 0062;0061 05AE 08DF 0300 0315 0062; +0061 0315 0300 05AE 08E0 0062;00E0 05AE 08E0 0315 0062;0061 05AE 0300 08E0 0315 0062;00E0 05AE 08E0 0315 0062;0061 05AE 0300 08E0 0315 0062; +0061 08E0 0315 0300 05AE 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062; +0061 0315 0300 05AE 08E1 0062;00E0 05AE 08E1 0315 0062;0061 05AE 0300 08E1 0315 0062;00E0 05AE 08E1 0315 0062;0061 05AE 0300 08E1 0315 0062; +0061 08E1 0315 0300 05AE 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062; +0061 059A 0316 302A 08E3 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062; +0061 08E3 059A 0316 302A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062; +0061 0315 0300 05AE 08E4 0062;00E0 05AE 08E4 0315 0062;0061 05AE 0300 08E4 0315 0062;00E0 05AE 08E4 0315 0062;0061 05AE 0300 08E4 0315 0062; +0061 08E4 0315 0300 05AE 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062; +0061 0315 0300 05AE 08E5 0062;00E0 05AE 08E5 0315 0062;0061 05AE 0300 08E5 0315 0062;00E0 05AE 08E5 0315 0062;0061 05AE 0300 08E5 0315 0062; +0061 08E5 0315 0300 05AE 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062; +0061 059A 0316 302A 08E6 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062; +0061 08E6 059A 0316 302A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062; +0061 0315 0300 05AE 08E7 0062;00E0 05AE 08E7 0315 0062;0061 05AE 0300 08E7 0315 0062;00E0 05AE 08E7 0315 0062;0061 05AE 0300 08E7 0315 0062; +0061 08E7 0315 0300 05AE 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062; +0061 0315 0300 05AE 08E8 0062;00E0 05AE 08E8 0315 0062;0061 05AE 0300 08E8 0315 0062;00E0 05AE 08E8 0315 0062;0061 05AE 0300 08E8 0315 0062; +0061 08E8 0315 0300 05AE 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062; +0061 059A 0316 302A 08E9 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062; +0061 08E9 059A 0316 302A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062; +0061 0315 0300 05AE 08EA 0062;00E0 05AE 08EA 0315 0062;0061 05AE 0300 08EA 0315 0062;00E0 05AE 08EA 0315 0062;0061 05AE 0300 08EA 0315 0062; +0061 08EA 0315 0300 05AE 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062; +0061 0315 0300 05AE 08EB 0062;00E0 05AE 08EB 0315 0062;0061 05AE 0300 08EB 0315 0062;00E0 05AE 08EB 0315 0062;0061 05AE 0300 08EB 0315 0062; +0061 08EB 0315 0300 05AE 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062; +0061 0315 0300 05AE 08EC 0062;00E0 05AE 08EC 0315 0062;0061 05AE 0300 08EC 0315 0062;00E0 05AE 08EC 0315 0062;0061 05AE 0300 08EC 0315 0062; +0061 08EC 0315 0300 05AE 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062; +0061 059A 0316 302A 08ED 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062; +0061 08ED 059A 0316 302A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062; +0061 059A 0316 302A 08EE 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062; +0061 08EE 059A 0316 302A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062; +0061 059A 0316 302A 08EF 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062; +0061 08EF 059A 0316 302A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062; +0061 064C 064B FB1E 08F0 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062; +0061 08F0 064C 064B FB1E 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062; +0061 064D 064C 064B 08F1 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062; +0061 08F1 064D 064C 064B 0062;0061 064B 08F1 064C 064D 0062;0061 064B 08F1 064C 064D 0062;0061 064B 08F1 064C 064D 0062;0061 064B 08F1 064C 064D 0062; +0061 0618 064D 064C 08F2 0062;0061 064C 064D 08F2 0618 0062;0061 064C 064D 08F2 0618 0062;0061 064C 064D 08F2 0618 0062;0061 064C 064D 08F2 0618 0062; +0061 08F2 0618 064D 064C 0062;0061 064C 08F2 064D 0618 0062;0061 064C 08F2 064D 0618 0062;0061 064C 08F2 064D 0618 0062;0061 064C 08F2 064D 0618 0062; +0061 0315 0300 05AE 08F3 0062;00E0 05AE 08F3 0315 0062;0061 05AE 0300 08F3 0315 0062;00E0 05AE 08F3 0315 0062;0061 05AE 0300 08F3 0315 0062; +0061 08F3 0315 0300 05AE 0062;0061 05AE 08F3 0300 0315 0062;0061 05AE 08F3 0300 0315 0062;0061 05AE 08F3 0300 0315 0062;0061 05AE 08F3 0300 0315 0062; +0061 0315 0300 05AE 08F4 0062;00E0 05AE 08F4 0315 0062;0061 05AE 0300 08F4 0315 0062;00E0 05AE 08F4 0315 0062;0061 05AE 0300 08F4 0315 0062; +0061 08F4 0315 0300 05AE 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062; +0061 0315 0300 05AE 08F5 0062;00E0 05AE 08F5 0315 0062;0061 05AE 0300 08F5 0315 0062;00E0 05AE 08F5 0315 0062;0061 05AE 0300 08F5 0315 0062; +0061 08F5 0315 0300 05AE 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062; +0061 059A 0316 302A 08F6 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062; +0061 08F6 059A 0316 302A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062; +0061 0315 0300 05AE 08F7 0062;00E0 05AE 08F7 0315 0062;0061 05AE 0300 08F7 0315 0062;00E0 05AE 08F7 0315 0062;0061 05AE 0300 08F7 0315 0062; +0061 08F7 0315 0300 05AE 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062; +0061 0315 0300 05AE 08F8 0062;00E0 05AE 08F8 0315 0062;0061 05AE 0300 08F8 0315 0062;00E0 05AE 08F8 0315 0062;0061 05AE 0300 08F8 0315 0062; +0061 08F8 0315 0300 05AE 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062; +0061 059A 0316 302A 08F9 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062; +0061 08F9 059A 0316 302A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062; +0061 059A 0316 302A 08FA 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062; +0061 08FA 059A 0316 302A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062; +0061 0315 0300 05AE 08FB 0062;00E0 05AE 08FB 0315 0062;0061 05AE 0300 08FB 0315 0062;00E0 05AE 08FB 0315 0062;0061 05AE 0300 08FB 0315 0062; +0061 08FB 0315 0300 05AE 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062; +0061 0315 0300 05AE 08FC 0062;00E0 05AE 08FC 0315 0062;0061 05AE 0300 08FC 0315 0062;00E0 05AE 08FC 0315 0062;0061 05AE 0300 08FC 0315 0062; +0061 08FC 0315 0300 05AE 0062;0061 05AE 08FC 0300 0315 0062;0061 05AE 08FC 0300 0315 0062;0061 05AE 08FC 0300 0315 0062;0061 05AE 08FC 0300 0315 0062; +0061 0315 0300 05AE 08FD 0062;00E0 05AE 08FD 0315 0062;0061 05AE 0300 08FD 0315 0062;00E0 05AE 08FD 0315 0062;0061 05AE 0300 08FD 0315 0062; +0061 08FD 0315 0300 05AE 0062;0061 05AE 08FD 0300 0315 0062;0061 05AE 08FD 0300 0315 0062;0061 05AE 08FD 0300 0315 0062;0061 05AE 08FD 0300 0315 0062; +0061 0315 0300 05AE 08FE 0062;00E0 05AE 08FE 0315 0062;0061 05AE 0300 08FE 0315 0062;00E0 05AE 08FE 0315 0062;0061 05AE 0300 08FE 0315 0062; +0061 08FE 0315 0300 05AE 0062;0061 05AE 08FE 0300 0315 0062;0061 05AE 08FE 0300 0315 0062;0061 05AE 08FE 0300 0315 0062;0061 05AE 08FE 0300 0315 0062; +0061 0315 0300 05AE 08FF 0062;00E0 05AE 08FF 0315 0062;0061 05AE 0300 08FF 0315 0062;00E0 05AE 08FF 0315 0062;0061 05AE 0300 08FF 0315 0062; +0061 08FF 0315 0300 05AE 0062;0061 05AE 08FF 0300 0315 0062;0061 05AE 08FF 0300 0315 0062;0061 05AE 08FF 0300 0315 0062;0061 05AE 08FF 0300 0315 0062; +0061 3099 093C 0334 093C 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062; +0061 093C 3099 093C 0334 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062; +0061 05B0 094D 3099 094D 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062; +0061 094D 05B0 094D 3099 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062; +0061 0315 0300 05AE 0951 0062;00E0 05AE 0951 0315 0062;0061 05AE 0300 0951 0315 0062;00E0 05AE 0951 0315 0062;0061 05AE 0300 0951 0315 0062; +0061 0951 0315 0300 05AE 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062; +0061 059A 0316 302A 0952 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062; +0061 0952 059A 0316 302A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062; +0061 0315 0300 05AE 0953 0062;00E0 05AE 0953 0315 0062;0061 05AE 0300 0953 0315 0062;00E0 05AE 0953 0315 0062;0061 05AE 0300 0953 0315 0062; +0061 0953 0315 0300 05AE 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062; +0061 0315 0300 05AE 0954 0062;00E0 05AE 0954 0315 0062;0061 05AE 0300 0954 0315 0062;00E0 05AE 0954 0315 0062;0061 05AE 0300 0954 0315 0062; +0061 0954 0315 0300 05AE 0062;0061 05AE 0954 0300 0315 0062;0061 05AE 0954 0300 0315 0062;0061 05AE 0954 0300 0315 0062;0061 05AE 0954 0300 0315 0062; +0061 3099 093C 0334 09BC 0062;0061 0334 093C 09BC 3099 0062;0061 0334 093C 09BC 3099 0062;0061 0334 093C 09BC 3099 0062;0061 0334 093C 09BC 3099 0062; +0061 09BC 3099 093C 0334 0062;0061 0334 09BC 093C 3099 0062;0061 0334 09BC 093C 3099 0062;0061 0334 09BC 093C 3099 0062;0061 0334 09BC 093C 3099 0062; +0061 05B0 094D 3099 09CD 0062;0061 3099 094D 09CD 05B0 0062;0061 3099 094D 09CD 05B0 0062;0061 3099 094D 09CD 05B0 0062;0061 3099 094D 09CD 05B0 0062; +0061 09CD 05B0 094D 3099 0062;0061 3099 09CD 094D 05B0 0062;0061 3099 09CD 094D 05B0 0062;0061 3099 09CD 094D 05B0 0062;0061 3099 09CD 094D 05B0 0062; +0061 0315 0300 05AE 09FE 0062;00E0 05AE 09FE 0315 0062;0061 05AE 0300 09FE 0315 0062;00E0 05AE 09FE 0315 0062;0061 05AE 0300 09FE 0315 0062; +0061 09FE 0315 0300 05AE 0062;0061 05AE 09FE 0300 0315 0062;0061 05AE 09FE 0300 0315 0062;0061 05AE 09FE 0300 0315 0062;0061 05AE 09FE 0300 0315 0062; +0061 3099 093C 0334 0A3C 0062;0061 0334 093C 0A3C 3099 0062;0061 0334 093C 0A3C 3099 0062;0061 0334 093C 0A3C 3099 0062;0061 0334 093C 0A3C 3099 0062; +0061 0A3C 3099 093C 0334 0062;0061 0334 0A3C 093C 3099 0062;0061 0334 0A3C 093C 3099 0062;0061 0334 0A3C 093C 3099 0062;0061 0334 0A3C 093C 3099 0062; +0061 05B0 094D 3099 0A4D 0062;0061 3099 094D 0A4D 05B0 0062;0061 3099 094D 0A4D 05B0 0062;0061 3099 094D 0A4D 05B0 0062;0061 3099 094D 0A4D 05B0 0062; +0061 0A4D 05B0 094D 3099 0062;0061 3099 0A4D 094D 05B0 0062;0061 3099 0A4D 094D 05B0 0062;0061 3099 0A4D 094D 05B0 0062;0061 3099 0A4D 094D 05B0 0062; +0061 3099 093C 0334 0ABC 0062;0061 0334 093C 0ABC 3099 0062;0061 0334 093C 0ABC 3099 0062;0061 0334 093C 0ABC 3099 0062;0061 0334 093C 0ABC 3099 0062; +0061 0ABC 3099 093C 0334 0062;0061 0334 0ABC 093C 3099 0062;0061 0334 0ABC 093C 3099 0062;0061 0334 0ABC 093C 3099 0062;0061 0334 0ABC 093C 3099 0062; +0061 05B0 094D 3099 0ACD 0062;0061 3099 094D 0ACD 05B0 0062;0061 3099 094D 0ACD 05B0 0062;0061 3099 094D 0ACD 05B0 0062;0061 3099 094D 0ACD 05B0 0062; +0061 0ACD 05B0 094D 3099 0062;0061 3099 0ACD 094D 05B0 0062;0061 3099 0ACD 094D 05B0 0062;0061 3099 0ACD 094D 05B0 0062;0061 3099 0ACD 094D 05B0 0062; +0061 3099 093C 0334 0B3C 0062;0061 0334 093C 0B3C 3099 0062;0061 0334 093C 0B3C 3099 0062;0061 0334 093C 0B3C 3099 0062;0061 0334 093C 0B3C 3099 0062; +0061 0B3C 3099 093C 0334 0062;0061 0334 0B3C 093C 3099 0062;0061 0334 0B3C 093C 3099 0062;0061 0334 0B3C 093C 3099 0062;0061 0334 0B3C 093C 3099 0062; +0061 05B0 094D 3099 0B4D 0062;0061 3099 094D 0B4D 05B0 0062;0061 3099 094D 0B4D 05B0 0062;0061 3099 094D 0B4D 05B0 0062;0061 3099 094D 0B4D 05B0 0062; +0061 0B4D 05B0 094D 3099 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062; +0061 05B0 094D 3099 0BCD 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062; +0061 0BCD 05B0 094D 3099 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062; +0061 05B0 094D 3099 0C4D 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062; +0061 0C4D 05B0 094D 3099 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062; +0061 0C56 0C55 0711 0C55 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062; +0061 0C55 0C56 0C55 0711 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062; +0061 0E38 0C56 0C55 0C56 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062; +0061 0C56 0E38 0C56 0C55 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062; +0061 3099 093C 0334 0CBC 0062;0061 0334 093C 0CBC 3099 0062;0061 0334 093C 0CBC 3099 0062;0061 0334 093C 0CBC 3099 0062;0061 0334 093C 0CBC 3099 0062; +0061 0CBC 3099 093C 0334 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062; +0061 05B0 094D 3099 0CCD 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062; +0061 0CCD 05B0 094D 3099 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062; +0061 05B0 094D 3099 0D3B 0062;0061 3099 094D 0D3B 05B0 0062;0061 3099 094D 0D3B 05B0 0062;0061 3099 094D 0D3B 05B0 0062;0061 3099 094D 0D3B 05B0 0062; +0061 0D3B 05B0 094D 3099 0062;0061 3099 0D3B 094D 05B0 0062;0061 3099 0D3B 094D 05B0 0062;0061 3099 0D3B 094D 05B0 0062;0061 3099 0D3B 094D 05B0 0062; +0061 05B0 094D 3099 0D3C 0062;0061 3099 094D 0D3C 05B0 0062;0061 3099 094D 0D3C 05B0 0062;0061 3099 094D 0D3C 05B0 0062;0061 3099 094D 0D3C 05B0 0062; +0061 0D3C 05B0 094D 3099 0062;0061 3099 0D3C 094D 05B0 0062;0061 3099 0D3C 094D 05B0 0062;0061 3099 0D3C 094D 05B0 0062;0061 3099 0D3C 094D 05B0 0062; +0061 05B0 094D 3099 0D4D 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062; +0061 0D4D 05B0 094D 3099 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062; +0061 05B0 094D 3099 0DCA 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062; +0061 0DCA 05B0 094D 3099 0062;0061 3099 0DCA 094D 05B0 0062;0061 3099 0DCA 094D 05B0 0062;0061 3099 0DCA 094D 05B0 0062;0061 3099 0DCA 094D 05B0 0062; +0061 0E48 0E38 0C56 0E38 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062; +0061 0E38 0E48 0E38 0C56 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062; +0061 0E48 0E38 0C56 0E39 0062;0061 0C56 0E38 0E39 0E48 0062;0061 0C56 0E38 0E39 0E48 0062;0061 0C56 0E38 0E39 0E48 0062;0061 0C56 0E38 0E39 0E48 0062; +0061 0E39 0E48 0E38 0C56 0062;0061 0C56 0E39 0E38 0E48 0062;0061 0C56 0E39 0E38 0E48 0062;0061 0C56 0E39 0E38 0E48 0062;0061 0C56 0E39 0E38 0E48 0062; +0061 05B0 094D 3099 0E3A 0062;0061 3099 094D 0E3A 05B0 0062;0061 3099 094D 0E3A 05B0 0062;0061 3099 094D 0E3A 05B0 0062;0061 3099 094D 0E3A 05B0 0062; +0061 0E3A 05B0 094D 3099 0062;0061 3099 0E3A 094D 05B0 0062;0061 3099 0E3A 094D 05B0 0062;0061 3099 0E3A 094D 05B0 0062;0061 3099 0E3A 094D 05B0 0062; +0061 0EB8 0E48 0E38 0E48 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062; +0061 0E48 0EB8 0E48 0E38 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062; +0061 0EB8 0E48 0E38 0E49 0062;0061 0E38 0E48 0E49 0EB8 0062;0061 0E38 0E48 0E49 0EB8 0062;0061 0E38 0E48 0E49 0EB8 0062;0061 0E38 0E48 0E49 0EB8 0062; +0061 0E49 0EB8 0E48 0E38 0062;0061 0E38 0E49 0E48 0EB8 0062;0061 0E38 0E49 0E48 0EB8 0062;0061 0E38 0E49 0E48 0EB8 0062;0061 0E38 0E49 0E48 0EB8 0062; +0061 0EB8 0E48 0E38 0E4A 0062;0061 0E38 0E48 0E4A 0EB8 0062;0061 0E38 0E48 0E4A 0EB8 0062;0061 0E38 0E48 0E4A 0EB8 0062;0061 0E38 0E48 0E4A 0EB8 0062; +0061 0E4A 0EB8 0E48 0E38 0062;0061 0E38 0E4A 0E48 0EB8 0062;0061 0E38 0E4A 0E48 0EB8 0062;0061 0E38 0E4A 0E48 0EB8 0062;0061 0E38 0E4A 0E48 0EB8 0062; +0061 0EB8 0E48 0E38 0E4B 0062;0061 0E38 0E48 0E4B 0EB8 0062;0061 0E38 0E48 0E4B 0EB8 0062;0061 0E38 0E48 0E4B 0EB8 0062;0061 0E38 0E48 0E4B 0EB8 0062; +0061 0E4B 0EB8 0E48 0E38 0062;0061 0E38 0E4B 0E48 0EB8 0062;0061 0E38 0E4B 0E48 0EB8 0062;0061 0E38 0E4B 0E48 0EB8 0062;0061 0E38 0E4B 0E48 0EB8 0062; +0061 0EC8 0EB8 0E48 0EB8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062; +0061 0EB8 0EC8 0EB8 0E48 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062; +0061 0EC8 0EB8 0E48 0EB9 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062; +0061 0EB9 0EC8 0EB8 0E48 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062; +0061 0F71 0EC8 0EB8 0EC8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062; +0061 0EC8 0F71 0EC8 0EB8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062; +0061 0F71 0EC8 0EB8 0EC9 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062; +0061 0EC9 0F71 0EC8 0EB8 0062;0061 0EB8 0EC9 0EC8 0F71 0062;0061 0EB8 0EC9 0EC8 0F71 0062;0061 0EB8 0EC9 0EC8 0F71 0062;0061 0EB8 0EC9 0EC8 0F71 0062; +0061 0F71 0EC8 0EB8 0ECA 0062;0061 0EB8 0EC8 0ECA 0F71 0062;0061 0EB8 0EC8 0ECA 0F71 0062;0061 0EB8 0EC8 0ECA 0F71 0062;0061 0EB8 0EC8 0ECA 0F71 0062; +0061 0ECA 0F71 0EC8 0EB8 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062; +0061 0F71 0EC8 0EB8 0ECB 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062; +0061 0ECB 0F71 0EC8 0EB8 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062; +0061 059A 0316 302A 0F18 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062; +0061 0F18 059A 0316 302A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062; +0061 059A 0316 302A 0F19 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062; +0061 0F19 059A 0316 302A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062; +0061 059A 0316 302A 0F35 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062; +0061 0F35 059A 0316 302A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062; +0061 059A 0316 302A 0F37 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062; +0061 0F37 059A 0316 302A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062; +0061 302A 031B 1DCE 0F39 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062; +0061 0F39 302A 031B 1DCE 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062; +0061 0F72 0F71 0EC8 0F71 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062; +0061 0F71 0F72 0F71 0EC8 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062; +0061 0F74 0F72 0F71 0F72 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062; +0061 0F72 0F74 0F72 0F71 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062; +0061 0321 0F74 0F72 0F74 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062; +0061 0F74 0321 0F74 0F72 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062; +0061 0F74 0F72 0F71 0F7A 0062;0061 0F71 0F72 0F7A 0F74 0062;0061 0F71 0F72 0F7A 0F74 0062;0061 0F71 0F72 0F7A 0F74 0062;0061 0F71 0F72 0F7A 0F74 0062; +0061 0F7A 0F74 0F72 0F71 0062;0061 0F71 0F7A 0F72 0F74 0062;0061 0F71 0F7A 0F72 0F74 0062;0061 0F71 0F7A 0F72 0F74 0062;0061 0F71 0F7A 0F72 0F74 0062; +0061 0F74 0F72 0F71 0F7B 0062;0061 0F71 0F72 0F7B 0F74 0062;0061 0F71 0F72 0F7B 0F74 0062;0061 0F71 0F72 0F7B 0F74 0062;0061 0F71 0F72 0F7B 0F74 0062; +0061 0F7B 0F74 0F72 0F71 0062;0061 0F71 0F7B 0F72 0F74 0062;0061 0F71 0F7B 0F72 0F74 0062;0061 0F71 0F7B 0F72 0F74 0062;0061 0F71 0F7B 0F72 0F74 0062; +0061 0F74 0F72 0F71 0F7C 0062;0061 0F71 0F72 0F7C 0F74 0062;0061 0F71 0F72 0F7C 0F74 0062;0061 0F71 0F72 0F7C 0F74 0062;0061 0F71 0F72 0F7C 0F74 0062; +0061 0F7C 0F74 0F72 0F71 0062;0061 0F71 0F7C 0F72 0F74 0062;0061 0F71 0F7C 0F72 0F74 0062;0061 0F71 0F7C 0F72 0F74 0062;0061 0F71 0F7C 0F72 0F74 0062; +0061 0F74 0F72 0F71 0F7D 0062;0061 0F71 0F72 0F7D 0F74 0062;0061 0F71 0F72 0F7D 0F74 0062;0061 0F71 0F72 0F7D 0F74 0062;0061 0F71 0F72 0F7D 0F74 0062; +0061 0F7D 0F74 0F72 0F71 0062;0061 0F71 0F7D 0F72 0F74 0062;0061 0F71 0F7D 0F72 0F74 0062;0061 0F71 0F7D 0F72 0F74 0062;0061 0F71 0F7D 0F72 0F74 0062; +0061 0F74 0F72 0F71 0F80 0062;0061 0F71 0F72 0F80 0F74 0062;0061 0F71 0F72 0F80 0F74 0062;0061 0F71 0F72 0F80 0F74 0062;0061 0F71 0F72 0F80 0F74 0062; +0061 0F80 0F74 0F72 0F71 0062;0061 0F71 0F80 0F72 0F74 0062;0061 0F71 0F80 0F72 0F74 0062;0061 0F71 0F80 0F72 0F74 0062;0061 0F71 0F80 0F72 0F74 0062; +0061 0315 0300 05AE 0F82 0062;00E0 05AE 0F82 0315 0062;0061 05AE 0300 0F82 0315 0062;00E0 05AE 0F82 0315 0062;0061 05AE 0300 0F82 0315 0062; +0061 0F82 0315 0300 05AE 0062;0061 05AE 0F82 0300 0315 0062;0061 05AE 0F82 0300 0315 0062;0061 05AE 0F82 0300 0315 0062;0061 05AE 0F82 0300 0315 0062; +0061 0315 0300 05AE 0F83 0062;00E0 05AE 0F83 0315 0062;0061 05AE 0300 0F83 0315 0062;00E0 05AE 0F83 0315 0062;0061 05AE 0300 0F83 0315 0062; +0061 0F83 0315 0300 05AE 0062;0061 05AE 0F83 0300 0315 0062;0061 05AE 0F83 0300 0315 0062;0061 05AE 0F83 0300 0315 0062;0061 05AE 0F83 0300 0315 0062; +0061 05B0 094D 3099 0F84 0062;0061 3099 094D 0F84 05B0 0062;0061 3099 094D 0F84 05B0 0062;0061 3099 094D 0F84 05B0 0062;0061 3099 094D 0F84 05B0 0062; +0061 0F84 05B0 094D 3099 0062;0061 3099 0F84 094D 05B0 0062;0061 3099 0F84 094D 05B0 0062;0061 3099 0F84 094D 05B0 0062;0061 3099 0F84 094D 05B0 0062; +0061 0315 0300 05AE 0F86 0062;00E0 05AE 0F86 0315 0062;0061 05AE 0300 0F86 0315 0062;00E0 05AE 0F86 0315 0062;0061 05AE 0300 0F86 0315 0062; +0061 0F86 0315 0300 05AE 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062; +0061 0315 0300 05AE 0F87 0062;00E0 05AE 0F87 0315 0062;0061 05AE 0300 0F87 0315 0062;00E0 05AE 0F87 0315 0062;0061 05AE 0300 0F87 0315 0062; +0061 0F87 0315 0300 05AE 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062; +0061 059A 0316 302A 0FC6 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062; +0061 0FC6 059A 0316 302A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062; +0061 3099 093C 0334 1037 0062;0061 0334 093C 1037 3099 0062;0061 0334 093C 1037 3099 0062;0061 0334 093C 1037 3099 0062;0061 0334 093C 1037 3099 0062; +0061 1037 3099 093C 0334 0062;0061 0334 1037 093C 3099 0062;0061 0334 1037 093C 3099 0062;0061 0334 1037 093C 3099 0062;0061 0334 1037 093C 3099 0062; +0061 05B0 094D 3099 1039 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062; +0061 1039 05B0 094D 3099 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062; +0061 05B0 094D 3099 103A 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062; +0061 103A 05B0 094D 3099 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062; +0061 059A 0316 302A 108D 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062; +0061 108D 059A 0316 302A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062; +0061 0315 0300 05AE 135D 0062;00E0 05AE 135D 0315 0062;0061 05AE 0300 135D 0315 0062;00E0 05AE 135D 0315 0062;0061 05AE 0300 135D 0315 0062; +0061 135D 0315 0300 05AE 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062; +0061 0315 0300 05AE 135E 0062;00E0 05AE 135E 0315 0062;0061 05AE 0300 135E 0315 0062;00E0 05AE 135E 0315 0062;0061 05AE 0300 135E 0315 0062; +0061 135E 0315 0300 05AE 0062;0061 05AE 135E 0300 0315 0062;0061 05AE 135E 0300 0315 0062;0061 05AE 135E 0300 0315 0062;0061 05AE 135E 0300 0315 0062; +0061 0315 0300 05AE 135F 0062;00E0 05AE 135F 0315 0062;0061 05AE 0300 135F 0315 0062;00E0 05AE 135F 0315 0062;0061 05AE 0300 135F 0315 0062; +0061 135F 0315 0300 05AE 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062; +0061 05B0 094D 3099 1714 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062; +0061 1714 05B0 094D 3099 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062; +0061 05B0 094D 3099 1734 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062; +0061 1734 05B0 094D 3099 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062; +0061 05B0 094D 3099 17D2 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062; +0061 17D2 05B0 094D 3099 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062; +0061 0315 0300 05AE 17DD 0062;00E0 05AE 17DD 0315 0062;0061 05AE 0300 17DD 0315 0062;00E0 05AE 17DD 0315 0062;0061 05AE 0300 17DD 0315 0062; +0061 17DD 0315 0300 05AE 0062;0061 05AE 17DD 0300 0315 0062;0061 05AE 17DD 0300 0315 0062;0061 05AE 17DD 0300 0315 0062;0061 05AE 17DD 0300 0315 0062; +0061 0300 05AE 1D16D 18A9 0062;00E0 1D16D 05AE 18A9 0062;0061 1D16D 05AE 18A9 0300 0062;00E0 1D16D 05AE 18A9 0062;0061 1D16D 05AE 18A9 0300 0062; +0061 18A9 0300 05AE 1D16D 0062;00E0 1D16D 18A9 05AE 0062;0061 1D16D 18A9 05AE 0300 0062;00E0 1D16D 18A9 05AE 0062;0061 1D16D 18A9 05AE 0300 0062; +0061 302E 059A 0316 1939 0062;0061 0316 059A 1939 302E 0062;0061 0316 059A 1939 302E 0062;0061 0316 059A 1939 302E 0062;0061 0316 059A 1939 302E 0062; +0061 1939 302E 059A 0316 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062; +0061 0315 0300 05AE 193A 0062;00E0 05AE 193A 0315 0062;0061 05AE 0300 193A 0315 0062;00E0 05AE 193A 0315 0062;0061 05AE 0300 193A 0315 0062; +0061 193A 0315 0300 05AE 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062; +0061 059A 0316 302A 193B 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062; +0061 193B 059A 0316 302A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062; +0061 0315 0300 05AE 1A17 0062;00E0 05AE 1A17 0315 0062;0061 05AE 0300 1A17 0315 0062;00E0 05AE 1A17 0315 0062;0061 05AE 0300 1A17 0315 0062; +0061 1A17 0315 0300 05AE 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062; +0061 059A 0316 302A 1A18 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062; +0061 1A18 059A 0316 302A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062; +0061 05B0 094D 3099 1A60 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062; +0061 1A60 05B0 094D 3099 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062; +0061 0315 0300 05AE 1A75 0062;00E0 05AE 1A75 0315 0062;0061 05AE 0300 1A75 0315 0062;00E0 05AE 1A75 0315 0062;0061 05AE 0300 1A75 0315 0062; +0061 1A75 0315 0300 05AE 0062;0061 05AE 1A75 0300 0315 0062;0061 05AE 1A75 0300 0315 0062;0061 05AE 1A75 0300 0315 0062;0061 05AE 1A75 0300 0315 0062; +0061 0315 0300 05AE 1A76 0062;00E0 05AE 1A76 0315 0062;0061 05AE 0300 1A76 0315 0062;00E0 05AE 1A76 0315 0062;0061 05AE 0300 1A76 0315 0062; +0061 1A76 0315 0300 05AE 0062;0061 05AE 1A76 0300 0315 0062;0061 05AE 1A76 0300 0315 0062;0061 05AE 1A76 0300 0315 0062;0061 05AE 1A76 0300 0315 0062; +0061 0315 0300 05AE 1A77 0062;00E0 05AE 1A77 0315 0062;0061 05AE 0300 1A77 0315 0062;00E0 05AE 1A77 0315 0062;0061 05AE 0300 1A77 0315 0062; +0061 1A77 0315 0300 05AE 0062;0061 05AE 1A77 0300 0315 0062;0061 05AE 1A77 0300 0315 0062;0061 05AE 1A77 0300 0315 0062;0061 05AE 1A77 0300 0315 0062; +0061 0315 0300 05AE 1A78 0062;00E0 05AE 1A78 0315 0062;0061 05AE 0300 1A78 0315 0062;00E0 05AE 1A78 0315 0062;0061 05AE 0300 1A78 0315 0062; +0061 1A78 0315 0300 05AE 0062;0061 05AE 1A78 0300 0315 0062;0061 05AE 1A78 0300 0315 0062;0061 05AE 1A78 0300 0315 0062;0061 05AE 1A78 0300 0315 0062; +0061 0315 0300 05AE 1A79 0062;00E0 05AE 1A79 0315 0062;0061 05AE 0300 1A79 0315 0062;00E0 05AE 1A79 0315 0062;0061 05AE 0300 1A79 0315 0062; +0061 1A79 0315 0300 05AE 0062;0061 05AE 1A79 0300 0315 0062;0061 05AE 1A79 0300 0315 0062;0061 05AE 1A79 0300 0315 0062;0061 05AE 1A79 0300 0315 0062; +0061 0315 0300 05AE 1A7A 0062;00E0 05AE 1A7A 0315 0062;0061 05AE 0300 1A7A 0315 0062;00E0 05AE 1A7A 0315 0062;0061 05AE 0300 1A7A 0315 0062; +0061 1A7A 0315 0300 05AE 0062;0061 05AE 1A7A 0300 0315 0062;0061 05AE 1A7A 0300 0315 0062;0061 05AE 1A7A 0300 0315 0062;0061 05AE 1A7A 0300 0315 0062; +0061 0315 0300 05AE 1A7B 0062;00E0 05AE 1A7B 0315 0062;0061 05AE 0300 1A7B 0315 0062;00E0 05AE 1A7B 0315 0062;0061 05AE 0300 1A7B 0315 0062; +0061 1A7B 0315 0300 05AE 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062; +0061 0315 0300 05AE 1A7C 0062;00E0 05AE 1A7C 0315 0062;0061 05AE 0300 1A7C 0315 0062;00E0 05AE 1A7C 0315 0062;0061 05AE 0300 1A7C 0315 0062; +0061 1A7C 0315 0300 05AE 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062; +0061 059A 0316 302A 1A7F 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062; +0061 1A7F 059A 0316 302A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062; +0061 0315 0300 05AE 1AB0 0062;00E0 05AE 1AB0 0315 0062;0061 05AE 0300 1AB0 0315 0062;00E0 05AE 1AB0 0315 0062;0061 05AE 0300 1AB0 0315 0062; +0061 1AB0 0315 0300 05AE 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062; +0061 0315 0300 05AE 1AB1 0062;00E0 05AE 1AB1 0315 0062;0061 05AE 0300 1AB1 0315 0062;00E0 05AE 1AB1 0315 0062;0061 05AE 0300 1AB1 0315 0062; +0061 1AB1 0315 0300 05AE 0062;0061 05AE 1AB1 0300 0315 0062;0061 05AE 1AB1 0300 0315 0062;0061 05AE 1AB1 0300 0315 0062;0061 05AE 1AB1 0300 0315 0062; +0061 0315 0300 05AE 1AB2 0062;00E0 05AE 1AB2 0315 0062;0061 05AE 0300 1AB2 0315 0062;00E0 05AE 1AB2 0315 0062;0061 05AE 0300 1AB2 0315 0062; +0061 1AB2 0315 0300 05AE 0062;0061 05AE 1AB2 0300 0315 0062;0061 05AE 1AB2 0300 0315 0062;0061 05AE 1AB2 0300 0315 0062;0061 05AE 1AB2 0300 0315 0062; +0061 0315 0300 05AE 1AB3 0062;00E0 05AE 1AB3 0315 0062;0061 05AE 0300 1AB3 0315 0062;00E0 05AE 1AB3 0315 0062;0061 05AE 0300 1AB3 0315 0062; +0061 1AB3 0315 0300 05AE 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062; +0061 0315 0300 05AE 1AB4 0062;00E0 05AE 1AB4 0315 0062;0061 05AE 0300 1AB4 0315 0062;00E0 05AE 1AB4 0315 0062;0061 05AE 0300 1AB4 0315 0062; +0061 1AB4 0315 0300 05AE 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062; +0061 059A 0316 302A 1AB5 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062; +0061 1AB5 059A 0316 302A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062; +0061 059A 0316 302A 1AB6 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062; +0061 1AB6 059A 0316 302A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062; +0061 059A 0316 302A 1AB7 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062; +0061 1AB7 059A 0316 302A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062; +0061 059A 0316 302A 1AB8 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062; +0061 1AB8 059A 0316 302A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062; +0061 059A 0316 302A 1AB9 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062; +0061 1AB9 059A 0316 302A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062; +0061 059A 0316 302A 1ABA 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062; +0061 1ABA 059A 0316 302A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062; +0061 0315 0300 05AE 1ABB 0062;00E0 05AE 1ABB 0315 0062;0061 05AE 0300 1ABB 0315 0062;00E0 05AE 1ABB 0315 0062;0061 05AE 0300 1ABB 0315 0062; +0061 1ABB 0315 0300 05AE 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062; +0061 0315 0300 05AE 1ABC 0062;00E0 05AE 1ABC 0315 0062;0061 05AE 0300 1ABC 0315 0062;00E0 05AE 1ABC 0315 0062;0061 05AE 0300 1ABC 0315 0062; +0061 1ABC 0315 0300 05AE 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062; +0061 059A 0316 302A 1ABD 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062; +0061 1ABD 059A 0316 302A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062; +0061 3099 093C 0334 1B34 0062;0061 0334 093C 1B34 3099 0062;0061 0334 093C 1B34 3099 0062;0061 0334 093C 1B34 3099 0062;0061 0334 093C 1B34 3099 0062; +0061 1B34 3099 093C 0334 0062;0061 0334 1B34 093C 3099 0062;0061 0334 1B34 093C 3099 0062;0061 0334 1B34 093C 3099 0062;0061 0334 1B34 093C 3099 0062; +0061 05B0 094D 3099 1B44 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062; +0061 1B44 05B0 094D 3099 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062; +0061 0315 0300 05AE 1B6B 0062;00E0 05AE 1B6B 0315 0062;0061 05AE 0300 1B6B 0315 0062;00E0 05AE 1B6B 0315 0062;0061 05AE 0300 1B6B 0315 0062; +0061 1B6B 0315 0300 05AE 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062; +0061 059A 0316 302A 1B6C 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062; +0061 1B6C 059A 0316 302A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062; +0061 0315 0300 05AE 1B6D 0062;00E0 05AE 1B6D 0315 0062;0061 05AE 0300 1B6D 0315 0062;00E0 05AE 1B6D 0315 0062;0061 05AE 0300 1B6D 0315 0062; +0061 1B6D 0315 0300 05AE 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062; +0061 0315 0300 05AE 1B6E 0062;00E0 05AE 1B6E 0315 0062;0061 05AE 0300 1B6E 0315 0062;00E0 05AE 1B6E 0315 0062;0061 05AE 0300 1B6E 0315 0062; +0061 1B6E 0315 0300 05AE 0062;0061 05AE 1B6E 0300 0315 0062;0061 05AE 1B6E 0300 0315 0062;0061 05AE 1B6E 0300 0315 0062;0061 05AE 1B6E 0300 0315 0062; +0061 0315 0300 05AE 1B6F 0062;00E0 05AE 1B6F 0315 0062;0061 05AE 0300 1B6F 0315 0062;00E0 05AE 1B6F 0315 0062;0061 05AE 0300 1B6F 0315 0062; +0061 1B6F 0315 0300 05AE 0062;0061 05AE 1B6F 0300 0315 0062;0061 05AE 1B6F 0300 0315 0062;0061 05AE 1B6F 0300 0315 0062;0061 05AE 1B6F 0300 0315 0062; +0061 0315 0300 05AE 1B70 0062;00E0 05AE 1B70 0315 0062;0061 05AE 0300 1B70 0315 0062;00E0 05AE 1B70 0315 0062;0061 05AE 0300 1B70 0315 0062; +0061 1B70 0315 0300 05AE 0062;0061 05AE 1B70 0300 0315 0062;0061 05AE 1B70 0300 0315 0062;0061 05AE 1B70 0300 0315 0062;0061 05AE 1B70 0300 0315 0062; +0061 0315 0300 05AE 1B71 0062;00E0 05AE 1B71 0315 0062;0061 05AE 0300 1B71 0315 0062;00E0 05AE 1B71 0315 0062;0061 05AE 0300 1B71 0315 0062; +0061 1B71 0315 0300 05AE 0062;0061 05AE 1B71 0300 0315 0062;0061 05AE 1B71 0300 0315 0062;0061 05AE 1B71 0300 0315 0062;0061 05AE 1B71 0300 0315 0062; +0061 0315 0300 05AE 1B72 0062;00E0 05AE 1B72 0315 0062;0061 05AE 0300 1B72 0315 0062;00E0 05AE 1B72 0315 0062;0061 05AE 0300 1B72 0315 0062; +0061 1B72 0315 0300 05AE 0062;0061 05AE 1B72 0300 0315 0062;0061 05AE 1B72 0300 0315 0062;0061 05AE 1B72 0300 0315 0062;0061 05AE 1B72 0300 0315 0062; +0061 0315 0300 05AE 1B73 0062;00E0 05AE 1B73 0315 0062;0061 05AE 0300 1B73 0315 0062;00E0 05AE 1B73 0315 0062;0061 05AE 0300 1B73 0315 0062; +0061 1B73 0315 0300 05AE 0062;0061 05AE 1B73 0300 0315 0062;0061 05AE 1B73 0300 0315 0062;0061 05AE 1B73 0300 0315 0062;0061 05AE 1B73 0300 0315 0062; +0061 05B0 094D 3099 1BAA 0062;0061 3099 094D 1BAA 05B0 0062;0061 3099 094D 1BAA 05B0 0062;0061 3099 094D 1BAA 05B0 0062;0061 3099 094D 1BAA 05B0 0062; +0061 1BAA 05B0 094D 3099 0062;0061 3099 1BAA 094D 05B0 0062;0061 3099 1BAA 094D 05B0 0062;0061 3099 1BAA 094D 05B0 0062;0061 3099 1BAA 094D 05B0 0062; +0061 05B0 094D 3099 1BAB 0062;0061 3099 094D 1BAB 05B0 0062;0061 3099 094D 1BAB 05B0 0062;0061 3099 094D 1BAB 05B0 0062;0061 3099 094D 1BAB 05B0 0062; +0061 1BAB 05B0 094D 3099 0062;0061 3099 1BAB 094D 05B0 0062;0061 3099 1BAB 094D 05B0 0062;0061 3099 1BAB 094D 05B0 0062;0061 3099 1BAB 094D 05B0 0062; +0061 3099 093C 0334 1BE6 0062;0061 0334 093C 1BE6 3099 0062;0061 0334 093C 1BE6 3099 0062;0061 0334 093C 1BE6 3099 0062;0061 0334 093C 1BE6 3099 0062; +0061 1BE6 3099 093C 0334 0062;0061 0334 1BE6 093C 3099 0062;0061 0334 1BE6 093C 3099 0062;0061 0334 1BE6 093C 3099 0062;0061 0334 1BE6 093C 3099 0062; +0061 05B0 094D 3099 1BF2 0062;0061 3099 094D 1BF2 05B0 0062;0061 3099 094D 1BF2 05B0 0062;0061 3099 094D 1BF2 05B0 0062;0061 3099 094D 1BF2 05B0 0062; +0061 1BF2 05B0 094D 3099 0062;0061 3099 1BF2 094D 05B0 0062;0061 3099 1BF2 094D 05B0 0062;0061 3099 1BF2 094D 05B0 0062;0061 3099 1BF2 094D 05B0 0062; +0061 05B0 094D 3099 1BF3 0062;0061 3099 094D 1BF3 05B0 0062;0061 3099 094D 1BF3 05B0 0062;0061 3099 094D 1BF3 05B0 0062;0061 3099 094D 1BF3 05B0 0062; +0061 1BF3 05B0 094D 3099 0062;0061 3099 1BF3 094D 05B0 0062;0061 3099 1BF3 094D 05B0 0062;0061 3099 1BF3 094D 05B0 0062;0061 3099 1BF3 094D 05B0 0062; +0061 3099 093C 0334 1C37 0062;0061 0334 093C 1C37 3099 0062;0061 0334 093C 1C37 3099 0062;0061 0334 093C 1C37 3099 0062;0061 0334 093C 1C37 3099 0062; +0061 1C37 3099 093C 0334 0062;0061 0334 1C37 093C 3099 0062;0061 0334 1C37 093C 3099 0062;0061 0334 1C37 093C 3099 0062;0061 0334 1C37 093C 3099 0062; +0061 0315 0300 05AE 1CD0 0062;00E0 05AE 1CD0 0315 0062;0061 05AE 0300 1CD0 0315 0062;00E0 05AE 1CD0 0315 0062;0061 05AE 0300 1CD0 0315 0062; +0061 1CD0 0315 0300 05AE 0062;0061 05AE 1CD0 0300 0315 0062;0061 05AE 1CD0 0300 0315 0062;0061 05AE 1CD0 0300 0315 0062;0061 05AE 1CD0 0300 0315 0062; +0061 0315 0300 05AE 1CD1 0062;00E0 05AE 1CD1 0315 0062;0061 05AE 0300 1CD1 0315 0062;00E0 05AE 1CD1 0315 0062;0061 05AE 0300 1CD1 0315 0062; +0061 1CD1 0315 0300 05AE 0062;0061 05AE 1CD1 0300 0315 0062;0061 05AE 1CD1 0300 0315 0062;0061 05AE 1CD1 0300 0315 0062;0061 05AE 1CD1 0300 0315 0062; +0061 0315 0300 05AE 1CD2 0062;00E0 05AE 1CD2 0315 0062;0061 05AE 0300 1CD2 0315 0062;00E0 05AE 1CD2 0315 0062;0061 05AE 0300 1CD2 0315 0062; +0061 1CD2 0315 0300 05AE 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062; +0061 093C 0334 1CD4 0062;0061 0334 1CD4 093C 0062;0061 0334 1CD4 093C 0062;0061 0334 1CD4 093C 0062;0061 0334 1CD4 093C 0062; +0061 1CD4 093C 0334 0062;0061 1CD4 0334 093C 0062;0061 1CD4 0334 093C 0062;0061 1CD4 0334 093C 0062;0061 1CD4 0334 093C 0062; +0061 059A 0316 302A 1CD5 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062; +0061 1CD5 059A 0316 302A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062; +0061 059A 0316 302A 1CD6 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062; +0061 1CD6 059A 0316 302A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062; +0061 059A 0316 302A 1CD7 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062; +0061 1CD7 059A 0316 302A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062; +0061 059A 0316 302A 1CD8 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062; +0061 1CD8 059A 0316 302A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062; +0061 059A 0316 302A 1CD9 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062; +0061 1CD9 059A 0316 302A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062; +0061 0315 0300 05AE 1CDA 0062;00E0 05AE 1CDA 0315 0062;0061 05AE 0300 1CDA 0315 0062;00E0 05AE 1CDA 0315 0062;0061 05AE 0300 1CDA 0315 0062; +0061 1CDA 0315 0300 05AE 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062; +0061 0315 0300 05AE 1CDB 0062;00E0 05AE 1CDB 0315 0062;0061 05AE 0300 1CDB 0315 0062;00E0 05AE 1CDB 0315 0062;0061 05AE 0300 1CDB 0315 0062; +0061 1CDB 0315 0300 05AE 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062; +0061 059A 0316 302A 1CDC 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062; +0061 1CDC 059A 0316 302A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062; +0061 059A 0316 302A 1CDD 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062; +0061 1CDD 059A 0316 302A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062; +0061 059A 0316 302A 1CDE 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062; +0061 1CDE 059A 0316 302A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062; +0061 059A 0316 302A 1CDF 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062; +0061 1CDF 059A 0316 302A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062; +0061 0315 0300 05AE 1CE0 0062;00E0 05AE 1CE0 0315 0062;0061 05AE 0300 1CE0 0315 0062;00E0 05AE 1CE0 0315 0062;0061 05AE 0300 1CE0 0315 0062; +0061 1CE0 0315 0300 05AE 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062; +0061 093C 0334 1CE2 0062;0061 0334 1CE2 093C 0062;0061 0334 1CE2 093C 0062;0061 0334 1CE2 093C 0062;0061 0334 1CE2 093C 0062; +0061 1CE2 093C 0334 0062;0061 1CE2 0334 093C 0062;0061 1CE2 0334 093C 0062;0061 1CE2 0334 093C 0062;0061 1CE2 0334 093C 0062; +0061 093C 0334 1CE3 0062;0061 0334 1CE3 093C 0062;0061 0334 1CE3 093C 0062;0061 0334 1CE3 093C 0062;0061 0334 1CE3 093C 0062; +0061 1CE3 093C 0334 0062;0061 1CE3 0334 093C 0062;0061 1CE3 0334 093C 0062;0061 1CE3 0334 093C 0062;0061 1CE3 0334 093C 0062; +0061 093C 0334 1CE4 0062;0061 0334 1CE4 093C 0062;0061 0334 1CE4 093C 0062;0061 0334 1CE4 093C 0062;0061 0334 1CE4 093C 0062; +0061 1CE4 093C 0334 0062;0061 1CE4 0334 093C 0062;0061 1CE4 0334 093C 0062;0061 1CE4 0334 093C 0062;0061 1CE4 0334 093C 0062; +0061 093C 0334 1CE5 0062;0061 0334 1CE5 093C 0062;0061 0334 1CE5 093C 0062;0061 0334 1CE5 093C 0062;0061 0334 1CE5 093C 0062; +0061 1CE5 093C 0334 0062;0061 1CE5 0334 093C 0062;0061 1CE5 0334 093C 0062;0061 1CE5 0334 093C 0062;0061 1CE5 0334 093C 0062; +0061 093C 0334 1CE6 0062;0061 0334 1CE6 093C 0062;0061 0334 1CE6 093C 0062;0061 0334 1CE6 093C 0062;0061 0334 1CE6 093C 0062; +0061 1CE6 093C 0334 0062;0061 1CE6 0334 093C 0062;0061 1CE6 0334 093C 0062;0061 1CE6 0334 093C 0062;0061 1CE6 0334 093C 0062; +0061 093C 0334 1CE7 0062;0061 0334 1CE7 093C 0062;0061 0334 1CE7 093C 0062;0061 0334 1CE7 093C 0062;0061 0334 1CE7 093C 0062; +0061 1CE7 093C 0334 0062;0061 1CE7 0334 093C 0062;0061 1CE7 0334 093C 0062;0061 1CE7 0334 093C 0062;0061 1CE7 0334 093C 0062; +0061 093C 0334 1CE8 0062;0061 0334 1CE8 093C 0062;0061 0334 1CE8 093C 0062;0061 0334 1CE8 093C 0062;0061 0334 1CE8 093C 0062; +0061 1CE8 093C 0334 0062;0061 1CE8 0334 093C 0062;0061 1CE8 0334 093C 0062;0061 1CE8 0334 093C 0062;0061 1CE8 0334 093C 0062; +0061 059A 0316 302A 1CED 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062; +0061 1CED 059A 0316 302A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062; +0061 0315 0300 05AE 1CF4 0062;00E0 05AE 1CF4 0315 0062;0061 05AE 0300 1CF4 0315 0062;00E0 05AE 1CF4 0315 0062;0061 05AE 0300 1CF4 0315 0062; +0061 1CF4 0315 0300 05AE 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062; +0061 0315 0300 05AE 1CF8 0062;00E0 05AE 1CF8 0315 0062;0061 05AE 0300 1CF8 0315 0062;00E0 05AE 1CF8 0315 0062;0061 05AE 0300 1CF8 0315 0062; +0061 1CF8 0315 0300 05AE 0062;0061 05AE 1CF8 0300 0315 0062;0061 05AE 1CF8 0300 0315 0062;0061 05AE 1CF8 0300 0315 0062;0061 05AE 1CF8 0300 0315 0062; +0061 0315 0300 05AE 1CF9 0062;00E0 05AE 1CF9 0315 0062;0061 05AE 0300 1CF9 0315 0062;00E0 05AE 1CF9 0315 0062;0061 05AE 0300 1CF9 0315 0062; +0061 1CF9 0315 0300 05AE 0062;0061 05AE 1CF9 0300 0315 0062;0061 05AE 1CF9 0300 0315 0062;0061 05AE 1CF9 0300 0315 0062;0061 05AE 1CF9 0300 0315 0062; +0061 0315 0300 05AE 1DC0 0062;00E0 05AE 1DC0 0315 0062;0061 05AE 0300 1DC0 0315 0062;00E0 05AE 1DC0 0315 0062;0061 05AE 0300 1DC0 0315 0062; +0061 1DC0 0315 0300 05AE 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062; +0061 0315 0300 05AE 1DC1 0062;00E0 05AE 1DC1 0315 0062;0061 05AE 0300 1DC1 0315 0062;00E0 05AE 1DC1 0315 0062;0061 05AE 0300 1DC1 0315 0062; +0061 1DC1 0315 0300 05AE 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062; +0061 059A 0316 302A 1DC2 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062; +0061 1DC2 059A 0316 302A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062; +0061 0315 0300 05AE 1DC3 0062;00E0 05AE 1DC3 0315 0062;0061 05AE 0300 1DC3 0315 0062;00E0 05AE 1DC3 0315 0062;0061 05AE 0300 1DC3 0315 0062; +0061 1DC3 0315 0300 05AE 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062; +0061 0315 0300 05AE 1DC4 0062;00E0 05AE 1DC4 0315 0062;0061 05AE 0300 1DC4 0315 0062;00E0 05AE 1DC4 0315 0062;0061 05AE 0300 1DC4 0315 0062; +0061 1DC4 0315 0300 05AE 0062;0061 05AE 1DC4 0300 0315 0062;0061 05AE 1DC4 0300 0315 0062;0061 05AE 1DC4 0300 0315 0062;0061 05AE 1DC4 0300 0315 0062; +0061 0315 0300 05AE 1DC5 0062;00E0 05AE 1DC5 0315 0062;0061 05AE 0300 1DC5 0315 0062;00E0 05AE 1DC5 0315 0062;0061 05AE 0300 1DC5 0315 0062; +0061 1DC5 0315 0300 05AE 0062;0061 05AE 1DC5 0300 0315 0062;0061 05AE 1DC5 0300 0315 0062;0061 05AE 1DC5 0300 0315 0062;0061 05AE 1DC5 0300 0315 0062; +0061 0315 0300 05AE 1DC6 0062;00E0 05AE 1DC6 0315 0062;0061 05AE 0300 1DC6 0315 0062;00E0 05AE 1DC6 0315 0062;0061 05AE 0300 1DC6 0315 0062; +0061 1DC6 0315 0300 05AE 0062;0061 05AE 1DC6 0300 0315 0062;0061 05AE 1DC6 0300 0315 0062;0061 05AE 1DC6 0300 0315 0062;0061 05AE 1DC6 0300 0315 0062; +0061 0315 0300 05AE 1DC7 0062;00E0 05AE 1DC7 0315 0062;0061 05AE 0300 1DC7 0315 0062;00E0 05AE 1DC7 0315 0062;0061 05AE 0300 1DC7 0315 0062; +0061 1DC7 0315 0300 05AE 0062;0061 05AE 1DC7 0300 0315 0062;0061 05AE 1DC7 0300 0315 0062;0061 05AE 1DC7 0300 0315 0062;0061 05AE 1DC7 0300 0315 0062; +0061 0315 0300 05AE 1DC8 0062;00E0 05AE 1DC8 0315 0062;0061 05AE 0300 1DC8 0315 0062;00E0 05AE 1DC8 0315 0062;0061 05AE 0300 1DC8 0315 0062; +0061 1DC8 0315 0300 05AE 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062; +0061 0315 0300 05AE 1DC9 0062;00E0 05AE 1DC9 0315 0062;0061 05AE 0300 1DC9 0315 0062;00E0 05AE 1DC9 0315 0062;0061 05AE 0300 1DC9 0315 0062; +0061 1DC9 0315 0300 05AE 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062; +0061 059A 0316 302A 1DCA 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062; +0061 1DCA 059A 0316 302A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062; +0061 0315 0300 05AE 1DCB 0062;00E0 05AE 1DCB 0315 0062;0061 05AE 0300 1DCB 0315 0062;00E0 05AE 1DCB 0315 0062;0061 05AE 0300 1DCB 0315 0062; +0061 1DCB 0315 0300 05AE 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062; +0061 0315 0300 05AE 1DCC 0062;00E0 05AE 1DCC 0315 0062;0061 05AE 0300 1DCC 0315 0062;00E0 05AE 1DCC 0315 0062;0061 05AE 0300 1DCC 0315 0062; +0061 1DCC 0315 0300 05AE 0062;0061 05AE 1DCC 0300 0315 0062;0061 05AE 1DCC 0300 0315 0062;0061 05AE 1DCC 0300 0315 0062;0061 05AE 1DCC 0300 0315 0062; +0061 0345 035D 035C 1DCD 0062;0061 035C 035D 1DCD 0345 0062;0061 035C 035D 1DCD 0345 0062;0061 035C 035D 1DCD 0345 0062;0061 035C 035D 1DCD 0345 0062; +0061 1DCD 0345 035D 035C 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062; +0061 031B 1DCE 0321 1DCE 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062; +0061 1DCE 031B 1DCE 0321 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062; +0061 059A 0316 302A 1DCF 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062; +0061 1DCF 059A 0316 302A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062; +0061 1DCE 0321 0F74 1DD0 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062; +0061 1DD0 1DCE 0321 0F74 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062; +0061 0315 0300 05AE 1DD1 0062;00E0 05AE 1DD1 0315 0062;0061 05AE 0300 1DD1 0315 0062;00E0 05AE 1DD1 0315 0062;0061 05AE 0300 1DD1 0315 0062; +0061 1DD1 0315 0300 05AE 0062;0061 05AE 1DD1 0300 0315 0062;0061 05AE 1DD1 0300 0315 0062;0061 05AE 1DD1 0300 0315 0062;0061 05AE 1DD1 0300 0315 0062; +0061 0315 0300 05AE 1DD2 0062;00E0 05AE 1DD2 0315 0062;0061 05AE 0300 1DD2 0315 0062;00E0 05AE 1DD2 0315 0062;0061 05AE 0300 1DD2 0315 0062; +0061 1DD2 0315 0300 05AE 0062;0061 05AE 1DD2 0300 0315 0062;0061 05AE 1DD2 0300 0315 0062;0061 05AE 1DD2 0300 0315 0062;0061 05AE 1DD2 0300 0315 0062; +0061 0315 0300 05AE 1DD3 0062;00E0 05AE 1DD3 0315 0062;0061 05AE 0300 1DD3 0315 0062;00E0 05AE 1DD3 0315 0062;0061 05AE 0300 1DD3 0315 0062; +0061 1DD3 0315 0300 05AE 0062;0061 05AE 1DD3 0300 0315 0062;0061 05AE 1DD3 0300 0315 0062;0061 05AE 1DD3 0300 0315 0062;0061 05AE 1DD3 0300 0315 0062; +0061 0315 0300 05AE 1DD4 0062;00E0 05AE 1DD4 0315 0062;0061 05AE 0300 1DD4 0315 0062;00E0 05AE 1DD4 0315 0062;0061 05AE 0300 1DD4 0315 0062; +0061 1DD4 0315 0300 05AE 0062;0061 05AE 1DD4 0300 0315 0062;0061 05AE 1DD4 0300 0315 0062;0061 05AE 1DD4 0300 0315 0062;0061 05AE 1DD4 0300 0315 0062; +0061 0315 0300 05AE 1DD5 0062;00E0 05AE 1DD5 0315 0062;0061 05AE 0300 1DD5 0315 0062;00E0 05AE 1DD5 0315 0062;0061 05AE 0300 1DD5 0315 0062; +0061 1DD5 0315 0300 05AE 0062;0061 05AE 1DD5 0300 0315 0062;0061 05AE 1DD5 0300 0315 0062;0061 05AE 1DD5 0300 0315 0062;0061 05AE 1DD5 0300 0315 0062; +0061 0315 0300 05AE 1DD6 0062;00E0 05AE 1DD6 0315 0062;0061 05AE 0300 1DD6 0315 0062;00E0 05AE 1DD6 0315 0062;0061 05AE 0300 1DD6 0315 0062; +0061 1DD6 0315 0300 05AE 0062;0061 05AE 1DD6 0300 0315 0062;0061 05AE 1DD6 0300 0315 0062;0061 05AE 1DD6 0300 0315 0062;0061 05AE 1DD6 0300 0315 0062; +0061 0315 0300 05AE 1DD7 0062;00E0 05AE 1DD7 0315 0062;0061 05AE 0300 1DD7 0315 0062;00E0 05AE 1DD7 0315 0062;0061 05AE 0300 1DD7 0315 0062; +0061 1DD7 0315 0300 05AE 0062;0061 05AE 1DD7 0300 0315 0062;0061 05AE 1DD7 0300 0315 0062;0061 05AE 1DD7 0300 0315 0062;0061 05AE 1DD7 0300 0315 0062; +0061 0315 0300 05AE 1DD8 0062;00E0 05AE 1DD8 0315 0062;0061 05AE 0300 1DD8 0315 0062;00E0 05AE 1DD8 0315 0062;0061 05AE 0300 1DD8 0315 0062; +0061 1DD8 0315 0300 05AE 0062;0061 05AE 1DD8 0300 0315 0062;0061 05AE 1DD8 0300 0315 0062;0061 05AE 1DD8 0300 0315 0062;0061 05AE 1DD8 0300 0315 0062; +0061 0315 0300 05AE 1DD9 0062;00E0 05AE 1DD9 0315 0062;0061 05AE 0300 1DD9 0315 0062;00E0 05AE 1DD9 0315 0062;0061 05AE 0300 1DD9 0315 0062; +0061 1DD9 0315 0300 05AE 0062;0061 05AE 1DD9 0300 0315 0062;0061 05AE 1DD9 0300 0315 0062;0061 05AE 1DD9 0300 0315 0062;0061 05AE 1DD9 0300 0315 0062; +0061 0315 0300 05AE 1DDA 0062;00E0 05AE 1DDA 0315 0062;0061 05AE 0300 1DDA 0315 0062;00E0 05AE 1DDA 0315 0062;0061 05AE 0300 1DDA 0315 0062; +0061 1DDA 0315 0300 05AE 0062;0061 05AE 1DDA 0300 0315 0062;0061 05AE 1DDA 0300 0315 0062;0061 05AE 1DDA 0300 0315 0062;0061 05AE 1DDA 0300 0315 0062; +0061 0315 0300 05AE 1DDB 0062;00E0 05AE 1DDB 0315 0062;0061 05AE 0300 1DDB 0315 0062;00E0 05AE 1DDB 0315 0062;0061 05AE 0300 1DDB 0315 0062; +0061 1DDB 0315 0300 05AE 0062;0061 05AE 1DDB 0300 0315 0062;0061 05AE 1DDB 0300 0315 0062;0061 05AE 1DDB 0300 0315 0062;0061 05AE 1DDB 0300 0315 0062; +0061 0315 0300 05AE 1DDC 0062;00E0 05AE 1DDC 0315 0062;0061 05AE 0300 1DDC 0315 0062;00E0 05AE 1DDC 0315 0062;0061 05AE 0300 1DDC 0315 0062; +0061 1DDC 0315 0300 05AE 0062;0061 05AE 1DDC 0300 0315 0062;0061 05AE 1DDC 0300 0315 0062;0061 05AE 1DDC 0300 0315 0062;0061 05AE 1DDC 0300 0315 0062; +0061 0315 0300 05AE 1DDD 0062;00E0 05AE 1DDD 0315 0062;0061 05AE 0300 1DDD 0315 0062;00E0 05AE 1DDD 0315 0062;0061 05AE 0300 1DDD 0315 0062; +0061 1DDD 0315 0300 05AE 0062;0061 05AE 1DDD 0300 0315 0062;0061 05AE 1DDD 0300 0315 0062;0061 05AE 1DDD 0300 0315 0062;0061 05AE 1DDD 0300 0315 0062; +0061 0315 0300 05AE 1DDE 0062;00E0 05AE 1DDE 0315 0062;0061 05AE 0300 1DDE 0315 0062;00E0 05AE 1DDE 0315 0062;0061 05AE 0300 1DDE 0315 0062; +0061 1DDE 0315 0300 05AE 0062;0061 05AE 1DDE 0300 0315 0062;0061 05AE 1DDE 0300 0315 0062;0061 05AE 1DDE 0300 0315 0062;0061 05AE 1DDE 0300 0315 0062; +0061 0315 0300 05AE 1DDF 0062;00E0 05AE 1DDF 0315 0062;0061 05AE 0300 1DDF 0315 0062;00E0 05AE 1DDF 0315 0062;0061 05AE 0300 1DDF 0315 0062; +0061 1DDF 0315 0300 05AE 0062;0061 05AE 1DDF 0300 0315 0062;0061 05AE 1DDF 0300 0315 0062;0061 05AE 1DDF 0300 0315 0062;0061 05AE 1DDF 0300 0315 0062; +0061 0315 0300 05AE 1DE0 0062;00E0 05AE 1DE0 0315 0062;0061 05AE 0300 1DE0 0315 0062;00E0 05AE 1DE0 0315 0062;0061 05AE 0300 1DE0 0315 0062; +0061 1DE0 0315 0300 05AE 0062;0061 05AE 1DE0 0300 0315 0062;0061 05AE 1DE0 0300 0315 0062;0061 05AE 1DE0 0300 0315 0062;0061 05AE 1DE0 0300 0315 0062; +0061 0315 0300 05AE 1DE1 0062;00E0 05AE 1DE1 0315 0062;0061 05AE 0300 1DE1 0315 0062;00E0 05AE 1DE1 0315 0062;0061 05AE 0300 1DE1 0315 0062; +0061 1DE1 0315 0300 05AE 0062;0061 05AE 1DE1 0300 0315 0062;0061 05AE 1DE1 0300 0315 0062;0061 05AE 1DE1 0300 0315 0062;0061 05AE 1DE1 0300 0315 0062; +0061 0315 0300 05AE 1DE2 0062;00E0 05AE 1DE2 0315 0062;0061 05AE 0300 1DE2 0315 0062;00E0 05AE 1DE2 0315 0062;0061 05AE 0300 1DE2 0315 0062; +0061 1DE2 0315 0300 05AE 0062;0061 05AE 1DE2 0300 0315 0062;0061 05AE 1DE2 0300 0315 0062;0061 05AE 1DE2 0300 0315 0062;0061 05AE 1DE2 0300 0315 0062; +0061 0315 0300 05AE 1DE3 0062;00E0 05AE 1DE3 0315 0062;0061 05AE 0300 1DE3 0315 0062;00E0 05AE 1DE3 0315 0062;0061 05AE 0300 1DE3 0315 0062; +0061 1DE3 0315 0300 05AE 0062;0061 05AE 1DE3 0300 0315 0062;0061 05AE 1DE3 0300 0315 0062;0061 05AE 1DE3 0300 0315 0062;0061 05AE 1DE3 0300 0315 0062; +0061 0315 0300 05AE 1DE4 0062;00E0 05AE 1DE4 0315 0062;0061 05AE 0300 1DE4 0315 0062;00E0 05AE 1DE4 0315 0062;0061 05AE 0300 1DE4 0315 0062; +0061 1DE4 0315 0300 05AE 0062;0061 05AE 1DE4 0300 0315 0062;0061 05AE 1DE4 0300 0315 0062;0061 05AE 1DE4 0300 0315 0062;0061 05AE 1DE4 0300 0315 0062; +0061 0315 0300 05AE 1DE5 0062;00E0 05AE 1DE5 0315 0062;0061 05AE 0300 1DE5 0315 0062;00E0 05AE 1DE5 0315 0062;0061 05AE 0300 1DE5 0315 0062; +0061 1DE5 0315 0300 05AE 0062;0061 05AE 1DE5 0300 0315 0062;0061 05AE 1DE5 0300 0315 0062;0061 05AE 1DE5 0300 0315 0062;0061 05AE 1DE5 0300 0315 0062; +0061 0315 0300 05AE 1DE6 0062;00E0 05AE 1DE6 0315 0062;0061 05AE 0300 1DE6 0315 0062;00E0 05AE 1DE6 0315 0062;0061 05AE 0300 1DE6 0315 0062; +0061 1DE6 0315 0300 05AE 0062;0061 05AE 1DE6 0300 0315 0062;0061 05AE 1DE6 0300 0315 0062;0061 05AE 1DE6 0300 0315 0062;0061 05AE 1DE6 0300 0315 0062; +0061 0315 0300 05AE 1DE7 0062;00E0 05AE 1DE7 0315 0062;0061 05AE 0300 1DE7 0315 0062;00E0 05AE 1DE7 0315 0062;0061 05AE 0300 1DE7 0315 0062; +0061 1DE7 0315 0300 05AE 0062;0061 05AE 1DE7 0300 0315 0062;0061 05AE 1DE7 0300 0315 0062;0061 05AE 1DE7 0300 0315 0062;0061 05AE 1DE7 0300 0315 0062; +0061 0315 0300 05AE 1DE8 0062;00E0 05AE 1DE8 0315 0062;0061 05AE 0300 1DE8 0315 0062;00E0 05AE 1DE8 0315 0062;0061 05AE 0300 1DE8 0315 0062; +0061 1DE8 0315 0300 05AE 0062;0061 05AE 1DE8 0300 0315 0062;0061 05AE 1DE8 0300 0315 0062;0061 05AE 1DE8 0300 0315 0062;0061 05AE 1DE8 0300 0315 0062; +0061 0315 0300 05AE 1DE9 0062;00E0 05AE 1DE9 0315 0062;0061 05AE 0300 1DE9 0315 0062;00E0 05AE 1DE9 0315 0062;0061 05AE 0300 1DE9 0315 0062; +0061 1DE9 0315 0300 05AE 0062;0061 05AE 1DE9 0300 0315 0062;0061 05AE 1DE9 0300 0315 0062;0061 05AE 1DE9 0300 0315 0062;0061 05AE 1DE9 0300 0315 0062; +0061 0315 0300 05AE 1DEA 0062;00E0 05AE 1DEA 0315 0062;0061 05AE 0300 1DEA 0315 0062;00E0 05AE 1DEA 0315 0062;0061 05AE 0300 1DEA 0315 0062; +0061 1DEA 0315 0300 05AE 0062;0061 05AE 1DEA 0300 0315 0062;0061 05AE 1DEA 0300 0315 0062;0061 05AE 1DEA 0300 0315 0062;0061 05AE 1DEA 0300 0315 0062; +0061 0315 0300 05AE 1DEB 0062;00E0 05AE 1DEB 0315 0062;0061 05AE 0300 1DEB 0315 0062;00E0 05AE 1DEB 0315 0062;0061 05AE 0300 1DEB 0315 0062; +0061 1DEB 0315 0300 05AE 0062;0061 05AE 1DEB 0300 0315 0062;0061 05AE 1DEB 0300 0315 0062;0061 05AE 1DEB 0300 0315 0062;0061 05AE 1DEB 0300 0315 0062; +0061 0315 0300 05AE 1DEC 0062;00E0 05AE 1DEC 0315 0062;0061 05AE 0300 1DEC 0315 0062;00E0 05AE 1DEC 0315 0062;0061 05AE 0300 1DEC 0315 0062; +0061 1DEC 0315 0300 05AE 0062;0061 05AE 1DEC 0300 0315 0062;0061 05AE 1DEC 0300 0315 0062;0061 05AE 1DEC 0300 0315 0062;0061 05AE 1DEC 0300 0315 0062; +0061 0315 0300 05AE 1DED 0062;00E0 05AE 1DED 0315 0062;0061 05AE 0300 1DED 0315 0062;00E0 05AE 1DED 0315 0062;0061 05AE 0300 1DED 0315 0062; +0061 1DED 0315 0300 05AE 0062;0061 05AE 1DED 0300 0315 0062;0061 05AE 1DED 0300 0315 0062;0061 05AE 1DED 0300 0315 0062;0061 05AE 1DED 0300 0315 0062; +0061 0315 0300 05AE 1DEE 0062;00E0 05AE 1DEE 0315 0062;0061 05AE 0300 1DEE 0315 0062;00E0 05AE 1DEE 0315 0062;0061 05AE 0300 1DEE 0315 0062; +0061 1DEE 0315 0300 05AE 0062;0061 05AE 1DEE 0300 0315 0062;0061 05AE 1DEE 0300 0315 0062;0061 05AE 1DEE 0300 0315 0062;0061 05AE 1DEE 0300 0315 0062; +0061 0315 0300 05AE 1DEF 0062;00E0 05AE 1DEF 0315 0062;0061 05AE 0300 1DEF 0315 0062;00E0 05AE 1DEF 0315 0062;0061 05AE 0300 1DEF 0315 0062; +0061 1DEF 0315 0300 05AE 0062;0061 05AE 1DEF 0300 0315 0062;0061 05AE 1DEF 0300 0315 0062;0061 05AE 1DEF 0300 0315 0062;0061 05AE 1DEF 0300 0315 0062; +0061 0315 0300 05AE 1DF0 0062;00E0 05AE 1DF0 0315 0062;0061 05AE 0300 1DF0 0315 0062;00E0 05AE 1DF0 0315 0062;0061 05AE 0300 1DF0 0315 0062; +0061 1DF0 0315 0300 05AE 0062;0061 05AE 1DF0 0300 0315 0062;0061 05AE 1DF0 0300 0315 0062;0061 05AE 1DF0 0300 0315 0062;0061 05AE 1DF0 0300 0315 0062; +0061 0315 0300 05AE 1DF1 0062;00E0 05AE 1DF1 0315 0062;0061 05AE 0300 1DF1 0315 0062;00E0 05AE 1DF1 0315 0062;0061 05AE 0300 1DF1 0315 0062; +0061 1DF1 0315 0300 05AE 0062;0061 05AE 1DF1 0300 0315 0062;0061 05AE 1DF1 0300 0315 0062;0061 05AE 1DF1 0300 0315 0062;0061 05AE 1DF1 0300 0315 0062; +0061 0315 0300 05AE 1DF2 0062;00E0 05AE 1DF2 0315 0062;0061 05AE 0300 1DF2 0315 0062;00E0 05AE 1DF2 0315 0062;0061 05AE 0300 1DF2 0315 0062; +0061 1DF2 0315 0300 05AE 0062;0061 05AE 1DF2 0300 0315 0062;0061 05AE 1DF2 0300 0315 0062;0061 05AE 1DF2 0300 0315 0062;0061 05AE 1DF2 0300 0315 0062; +0061 0315 0300 05AE 1DF3 0062;00E0 05AE 1DF3 0315 0062;0061 05AE 0300 1DF3 0315 0062;00E0 05AE 1DF3 0315 0062;0061 05AE 0300 1DF3 0315 0062; +0061 1DF3 0315 0300 05AE 0062;0061 05AE 1DF3 0300 0315 0062;0061 05AE 1DF3 0300 0315 0062;0061 05AE 1DF3 0300 0315 0062;0061 05AE 1DF3 0300 0315 0062; +0061 0315 0300 05AE 1DF4 0062;00E0 05AE 1DF4 0315 0062;0061 05AE 0300 1DF4 0315 0062;00E0 05AE 1DF4 0315 0062;0061 05AE 0300 1DF4 0315 0062; +0061 1DF4 0315 0300 05AE 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062; +0061 0315 0300 05AE 1DF5 0062;00E0 05AE 1DF5 0315 0062;0061 05AE 0300 1DF5 0315 0062;00E0 05AE 1DF5 0315 0062;0061 05AE 0300 1DF5 0315 0062; +0061 1DF5 0315 0300 05AE 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062; +0061 035C 0315 0300 1DF6 0062;00E0 0315 1DF6 035C 0062;0061 0300 0315 1DF6 035C 0062;00E0 0315 1DF6 035C 0062;0061 0300 0315 1DF6 035C 0062; +0061 1DF6 035C 0315 0300 0062;00E0 1DF6 0315 035C 0062;0061 0300 1DF6 0315 035C 0062;00E0 1DF6 0315 035C 0062;0061 0300 1DF6 0315 035C 0062; +0061 0300 05AE 1D16D 1DF7 0062;00E0 1D16D 05AE 1DF7 0062;0061 1D16D 05AE 1DF7 0300 0062;00E0 1D16D 05AE 1DF7 0062;0061 1D16D 05AE 1DF7 0300 0062; +0061 1DF7 0300 05AE 1D16D 0062;00E0 1D16D 1DF7 05AE 0062;0061 1D16D 1DF7 05AE 0300 0062;00E0 1D16D 1DF7 05AE 0062;0061 1D16D 1DF7 05AE 0300 0062; +0061 0300 05AE 1D16D 1DF8 0062;00E0 1D16D 05AE 1DF8 0062;0061 1D16D 05AE 1DF8 0300 0062;00E0 1D16D 05AE 1DF8 0062;0061 1D16D 05AE 1DF8 0300 0062; +0061 1DF8 0300 05AE 1D16D 0062;00E0 1D16D 1DF8 05AE 0062;0061 1D16D 1DF8 05AE 0300 0062;00E0 1D16D 1DF8 05AE 0062;0061 1D16D 1DF8 05AE 0300 0062; +0061 059A 0316 302A 1DF9 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062; +0061 1DF9 059A 0316 302A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062; +0061 0315 0300 05AE 1DFB 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 0315 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 0315 0062; +0061 1DFB 0315 0300 05AE 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062; +0061 035D 035C 0315 1DFC 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062; +0061 1DFC 035D 035C 0315 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062; +0061 059A 0316 302A 1DFD 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062; +0061 1DFD 059A 0316 302A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062; +0061 0315 0300 05AE 1DFE 0062;00E0 05AE 1DFE 0315 0062;0061 05AE 0300 1DFE 0315 0062;00E0 05AE 1DFE 0315 0062;0061 05AE 0300 1DFE 0315 0062; +0061 1DFE 0315 0300 05AE 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062; +0061 059A 0316 302A 1DFF 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062; +0061 1DFF 059A 0316 302A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062; +0061 0315 0300 05AE 20D0 0062;00E0 05AE 20D0 0315 0062;0061 05AE 0300 20D0 0315 0062;00E0 05AE 20D0 0315 0062;0061 05AE 0300 20D0 0315 0062; +0061 20D0 0315 0300 05AE 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062; +0061 0315 0300 05AE 20D1 0062;00E0 05AE 20D1 0315 0062;0061 05AE 0300 20D1 0315 0062;00E0 05AE 20D1 0315 0062;0061 05AE 0300 20D1 0315 0062; +0061 20D1 0315 0300 05AE 0062;0061 05AE 20D1 0300 0315 0062;0061 05AE 20D1 0300 0315 0062;0061 05AE 20D1 0300 0315 0062;0061 05AE 20D1 0300 0315 0062; +0061 093C 0334 20D2 0062;0061 0334 20D2 093C 0062;0061 0334 20D2 093C 0062;0061 0334 20D2 093C 0062;0061 0334 20D2 093C 0062; +0061 20D2 093C 0334 0062;0061 20D2 0334 093C 0062;0061 20D2 0334 093C 0062;0061 20D2 0334 093C 0062;0061 20D2 0334 093C 0062; +0061 093C 0334 20D3 0062;0061 0334 20D3 093C 0062;0061 0334 20D3 093C 0062;0061 0334 20D3 093C 0062;0061 0334 20D3 093C 0062; +0061 20D3 093C 0334 0062;0061 20D3 0334 093C 0062;0061 20D3 0334 093C 0062;0061 20D3 0334 093C 0062;0061 20D3 0334 093C 0062; +0061 0315 0300 05AE 20D4 0062;00E0 05AE 20D4 0315 0062;0061 05AE 0300 20D4 0315 0062;00E0 05AE 20D4 0315 0062;0061 05AE 0300 20D4 0315 0062; +0061 20D4 0315 0300 05AE 0062;0061 05AE 20D4 0300 0315 0062;0061 05AE 20D4 0300 0315 0062;0061 05AE 20D4 0300 0315 0062;0061 05AE 20D4 0300 0315 0062; +0061 0315 0300 05AE 20D5 0062;00E0 05AE 20D5 0315 0062;0061 05AE 0300 20D5 0315 0062;00E0 05AE 20D5 0315 0062;0061 05AE 0300 20D5 0315 0062; +0061 20D5 0315 0300 05AE 0062;0061 05AE 20D5 0300 0315 0062;0061 05AE 20D5 0300 0315 0062;0061 05AE 20D5 0300 0315 0062;0061 05AE 20D5 0300 0315 0062; +0061 0315 0300 05AE 20D6 0062;00E0 05AE 20D6 0315 0062;0061 05AE 0300 20D6 0315 0062;00E0 05AE 20D6 0315 0062;0061 05AE 0300 20D6 0315 0062; +0061 20D6 0315 0300 05AE 0062;0061 05AE 20D6 0300 0315 0062;0061 05AE 20D6 0300 0315 0062;0061 05AE 20D6 0300 0315 0062;0061 05AE 20D6 0300 0315 0062; +0061 0315 0300 05AE 20D7 0062;00E0 05AE 20D7 0315 0062;0061 05AE 0300 20D7 0315 0062;00E0 05AE 20D7 0315 0062;0061 05AE 0300 20D7 0315 0062; +0061 20D7 0315 0300 05AE 0062;0061 05AE 20D7 0300 0315 0062;0061 05AE 20D7 0300 0315 0062;0061 05AE 20D7 0300 0315 0062;0061 05AE 20D7 0300 0315 0062; +0061 093C 0334 20D8 0062;0061 0334 20D8 093C 0062;0061 0334 20D8 093C 0062;0061 0334 20D8 093C 0062;0061 0334 20D8 093C 0062; +0061 20D8 093C 0334 0062;0061 20D8 0334 093C 0062;0061 20D8 0334 093C 0062;0061 20D8 0334 093C 0062;0061 20D8 0334 093C 0062; +0061 093C 0334 20D9 0062;0061 0334 20D9 093C 0062;0061 0334 20D9 093C 0062;0061 0334 20D9 093C 0062;0061 0334 20D9 093C 0062; +0061 20D9 093C 0334 0062;0061 20D9 0334 093C 0062;0061 20D9 0334 093C 0062;0061 20D9 0334 093C 0062;0061 20D9 0334 093C 0062; +0061 093C 0334 20DA 0062;0061 0334 20DA 093C 0062;0061 0334 20DA 093C 0062;0061 0334 20DA 093C 0062;0061 0334 20DA 093C 0062; +0061 20DA 093C 0334 0062;0061 20DA 0334 093C 0062;0061 20DA 0334 093C 0062;0061 20DA 0334 093C 0062;0061 20DA 0334 093C 0062; +0061 0315 0300 05AE 20DB 0062;00E0 05AE 20DB 0315 0062;0061 05AE 0300 20DB 0315 0062;00E0 05AE 20DB 0315 0062;0061 05AE 0300 20DB 0315 0062; +0061 20DB 0315 0300 05AE 0062;0061 05AE 20DB 0300 0315 0062;0061 05AE 20DB 0300 0315 0062;0061 05AE 20DB 0300 0315 0062;0061 05AE 20DB 0300 0315 0062; +0061 0315 0300 05AE 20DC 0062;00E0 05AE 20DC 0315 0062;0061 05AE 0300 20DC 0315 0062;00E0 05AE 20DC 0315 0062;0061 05AE 0300 20DC 0315 0062; +0061 20DC 0315 0300 05AE 0062;0061 05AE 20DC 0300 0315 0062;0061 05AE 20DC 0300 0315 0062;0061 05AE 20DC 0300 0315 0062;0061 05AE 20DC 0300 0315 0062; +0061 0315 0300 05AE 20E1 0062;00E0 05AE 20E1 0315 0062;0061 05AE 0300 20E1 0315 0062;00E0 05AE 20E1 0315 0062;0061 05AE 0300 20E1 0315 0062; +0061 20E1 0315 0300 05AE 0062;0061 05AE 20E1 0300 0315 0062;0061 05AE 20E1 0300 0315 0062;0061 05AE 20E1 0300 0315 0062;0061 05AE 20E1 0300 0315 0062; +0061 093C 0334 20E5 0062;0061 0334 20E5 093C 0062;0061 0334 20E5 093C 0062;0061 0334 20E5 093C 0062;0061 0334 20E5 093C 0062; +0061 20E5 093C 0334 0062;0061 20E5 0334 093C 0062;0061 20E5 0334 093C 0062;0061 20E5 0334 093C 0062;0061 20E5 0334 093C 0062; +0061 093C 0334 20E6 0062;0061 0334 20E6 093C 0062;0061 0334 20E6 093C 0062;0061 0334 20E6 093C 0062;0061 0334 20E6 093C 0062; +0061 20E6 093C 0334 0062;0061 20E6 0334 093C 0062;0061 20E6 0334 093C 0062;0061 20E6 0334 093C 0062;0061 20E6 0334 093C 0062; +0061 0315 0300 05AE 20E7 0062;00E0 05AE 20E7 0315 0062;0061 05AE 0300 20E7 0315 0062;00E0 05AE 20E7 0315 0062;0061 05AE 0300 20E7 0315 0062; +0061 20E7 0315 0300 05AE 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062; +0061 059A 0316 302A 20E8 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062; +0061 20E8 059A 0316 302A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062; +0061 0315 0300 05AE 20E9 0062;00E0 05AE 20E9 0315 0062;0061 05AE 0300 20E9 0315 0062;00E0 05AE 20E9 0315 0062;0061 05AE 0300 20E9 0315 0062; +0061 20E9 0315 0300 05AE 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062; +0061 093C 0334 20EA 0062;0061 0334 20EA 093C 0062;0061 0334 20EA 093C 0062;0061 0334 20EA 093C 0062;0061 0334 20EA 093C 0062; +0061 20EA 093C 0334 0062;0061 20EA 0334 093C 0062;0061 20EA 0334 093C 0062;0061 20EA 0334 093C 0062;0061 20EA 0334 093C 0062; +0061 093C 0334 20EB 0062;0061 0334 20EB 093C 0062;0061 0334 20EB 093C 0062;0061 0334 20EB 093C 0062;0061 0334 20EB 093C 0062; +0061 20EB 093C 0334 0062;0061 20EB 0334 093C 0062;0061 20EB 0334 093C 0062;0061 20EB 0334 093C 0062;0061 20EB 0334 093C 0062; +0061 059A 0316 302A 20EC 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062; +0061 20EC 059A 0316 302A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062; +0061 059A 0316 302A 20ED 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062; +0061 20ED 059A 0316 302A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062; +0061 059A 0316 302A 20EE 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062; +0061 20EE 059A 0316 302A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062; +0061 059A 0316 302A 20EF 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062; +0061 20EF 059A 0316 302A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062; +0061 0315 0300 05AE 20F0 0062;00E0 05AE 20F0 0315 0062;0061 05AE 0300 20F0 0315 0062;00E0 05AE 20F0 0315 0062;0061 05AE 0300 20F0 0315 0062; +0061 20F0 0315 0300 05AE 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062; +0061 0315 0300 05AE 2CEF 0062;00E0 05AE 2CEF 0315 0062;0061 05AE 0300 2CEF 0315 0062;00E0 05AE 2CEF 0315 0062;0061 05AE 0300 2CEF 0315 0062; +0061 2CEF 0315 0300 05AE 0062;0061 05AE 2CEF 0300 0315 0062;0061 05AE 2CEF 0300 0315 0062;0061 05AE 2CEF 0300 0315 0062;0061 05AE 2CEF 0300 0315 0062; +0061 0315 0300 05AE 2CF0 0062;00E0 05AE 2CF0 0315 0062;0061 05AE 0300 2CF0 0315 0062;00E0 05AE 2CF0 0315 0062;0061 05AE 0300 2CF0 0315 0062; +0061 2CF0 0315 0300 05AE 0062;0061 05AE 2CF0 0300 0315 0062;0061 05AE 2CF0 0300 0315 0062;0061 05AE 2CF0 0300 0315 0062;0061 05AE 2CF0 0300 0315 0062; +0061 0315 0300 05AE 2CF1 0062;00E0 05AE 2CF1 0315 0062;0061 05AE 0300 2CF1 0315 0062;00E0 05AE 2CF1 0315 0062;0061 05AE 0300 2CF1 0315 0062; +0061 2CF1 0315 0300 05AE 0062;0061 05AE 2CF1 0300 0315 0062;0061 05AE 2CF1 0300 0315 0062;0061 05AE 2CF1 0300 0315 0062;0061 05AE 2CF1 0300 0315 0062; +0061 05B0 094D 3099 2D7F 0062;0061 3099 094D 2D7F 05B0 0062;0061 3099 094D 2D7F 05B0 0062;0061 3099 094D 2D7F 05B0 0062;0061 3099 094D 2D7F 05B0 0062; +0061 2D7F 05B0 094D 3099 0062;0061 3099 2D7F 094D 05B0 0062;0061 3099 2D7F 094D 05B0 0062;0061 3099 2D7F 094D 05B0 0062;0061 3099 2D7F 094D 05B0 0062; +0061 0315 0300 05AE 2DE0 0062;00E0 05AE 2DE0 0315 0062;0061 05AE 0300 2DE0 0315 0062;00E0 05AE 2DE0 0315 0062;0061 05AE 0300 2DE0 0315 0062; +0061 2DE0 0315 0300 05AE 0062;0061 05AE 2DE0 0300 0315 0062;0061 05AE 2DE0 0300 0315 0062;0061 05AE 2DE0 0300 0315 0062;0061 05AE 2DE0 0300 0315 0062; +0061 0315 0300 05AE 2DE1 0062;00E0 05AE 2DE1 0315 0062;0061 05AE 0300 2DE1 0315 0062;00E0 05AE 2DE1 0315 0062;0061 05AE 0300 2DE1 0315 0062; +0061 2DE1 0315 0300 05AE 0062;0061 05AE 2DE1 0300 0315 0062;0061 05AE 2DE1 0300 0315 0062;0061 05AE 2DE1 0300 0315 0062;0061 05AE 2DE1 0300 0315 0062; +0061 0315 0300 05AE 2DE2 0062;00E0 05AE 2DE2 0315 0062;0061 05AE 0300 2DE2 0315 0062;00E0 05AE 2DE2 0315 0062;0061 05AE 0300 2DE2 0315 0062; +0061 2DE2 0315 0300 05AE 0062;0061 05AE 2DE2 0300 0315 0062;0061 05AE 2DE2 0300 0315 0062;0061 05AE 2DE2 0300 0315 0062;0061 05AE 2DE2 0300 0315 0062; +0061 0315 0300 05AE 2DE3 0062;00E0 05AE 2DE3 0315 0062;0061 05AE 0300 2DE3 0315 0062;00E0 05AE 2DE3 0315 0062;0061 05AE 0300 2DE3 0315 0062; +0061 2DE3 0315 0300 05AE 0062;0061 05AE 2DE3 0300 0315 0062;0061 05AE 2DE3 0300 0315 0062;0061 05AE 2DE3 0300 0315 0062;0061 05AE 2DE3 0300 0315 0062; +0061 0315 0300 05AE 2DE4 0062;00E0 05AE 2DE4 0315 0062;0061 05AE 0300 2DE4 0315 0062;00E0 05AE 2DE4 0315 0062;0061 05AE 0300 2DE4 0315 0062; +0061 2DE4 0315 0300 05AE 0062;0061 05AE 2DE4 0300 0315 0062;0061 05AE 2DE4 0300 0315 0062;0061 05AE 2DE4 0300 0315 0062;0061 05AE 2DE4 0300 0315 0062; +0061 0315 0300 05AE 2DE5 0062;00E0 05AE 2DE5 0315 0062;0061 05AE 0300 2DE5 0315 0062;00E0 05AE 2DE5 0315 0062;0061 05AE 0300 2DE5 0315 0062; +0061 2DE5 0315 0300 05AE 0062;0061 05AE 2DE5 0300 0315 0062;0061 05AE 2DE5 0300 0315 0062;0061 05AE 2DE5 0300 0315 0062;0061 05AE 2DE5 0300 0315 0062; +0061 0315 0300 05AE 2DE6 0062;00E0 05AE 2DE6 0315 0062;0061 05AE 0300 2DE6 0315 0062;00E0 05AE 2DE6 0315 0062;0061 05AE 0300 2DE6 0315 0062; +0061 2DE6 0315 0300 05AE 0062;0061 05AE 2DE6 0300 0315 0062;0061 05AE 2DE6 0300 0315 0062;0061 05AE 2DE6 0300 0315 0062;0061 05AE 2DE6 0300 0315 0062; +0061 0315 0300 05AE 2DE7 0062;00E0 05AE 2DE7 0315 0062;0061 05AE 0300 2DE7 0315 0062;00E0 05AE 2DE7 0315 0062;0061 05AE 0300 2DE7 0315 0062; +0061 2DE7 0315 0300 05AE 0062;0061 05AE 2DE7 0300 0315 0062;0061 05AE 2DE7 0300 0315 0062;0061 05AE 2DE7 0300 0315 0062;0061 05AE 2DE7 0300 0315 0062; +0061 0315 0300 05AE 2DE8 0062;00E0 05AE 2DE8 0315 0062;0061 05AE 0300 2DE8 0315 0062;00E0 05AE 2DE8 0315 0062;0061 05AE 0300 2DE8 0315 0062; +0061 2DE8 0315 0300 05AE 0062;0061 05AE 2DE8 0300 0315 0062;0061 05AE 2DE8 0300 0315 0062;0061 05AE 2DE8 0300 0315 0062;0061 05AE 2DE8 0300 0315 0062; +0061 0315 0300 05AE 2DE9 0062;00E0 05AE 2DE9 0315 0062;0061 05AE 0300 2DE9 0315 0062;00E0 05AE 2DE9 0315 0062;0061 05AE 0300 2DE9 0315 0062; +0061 2DE9 0315 0300 05AE 0062;0061 05AE 2DE9 0300 0315 0062;0061 05AE 2DE9 0300 0315 0062;0061 05AE 2DE9 0300 0315 0062;0061 05AE 2DE9 0300 0315 0062; +0061 0315 0300 05AE 2DEA 0062;00E0 05AE 2DEA 0315 0062;0061 05AE 0300 2DEA 0315 0062;00E0 05AE 2DEA 0315 0062;0061 05AE 0300 2DEA 0315 0062; +0061 2DEA 0315 0300 05AE 0062;0061 05AE 2DEA 0300 0315 0062;0061 05AE 2DEA 0300 0315 0062;0061 05AE 2DEA 0300 0315 0062;0061 05AE 2DEA 0300 0315 0062; +0061 0315 0300 05AE 2DEB 0062;00E0 05AE 2DEB 0315 0062;0061 05AE 0300 2DEB 0315 0062;00E0 05AE 2DEB 0315 0062;0061 05AE 0300 2DEB 0315 0062; +0061 2DEB 0315 0300 05AE 0062;0061 05AE 2DEB 0300 0315 0062;0061 05AE 2DEB 0300 0315 0062;0061 05AE 2DEB 0300 0315 0062;0061 05AE 2DEB 0300 0315 0062; +0061 0315 0300 05AE 2DEC 0062;00E0 05AE 2DEC 0315 0062;0061 05AE 0300 2DEC 0315 0062;00E0 05AE 2DEC 0315 0062;0061 05AE 0300 2DEC 0315 0062; +0061 2DEC 0315 0300 05AE 0062;0061 05AE 2DEC 0300 0315 0062;0061 05AE 2DEC 0300 0315 0062;0061 05AE 2DEC 0300 0315 0062;0061 05AE 2DEC 0300 0315 0062; +0061 0315 0300 05AE 2DED 0062;00E0 05AE 2DED 0315 0062;0061 05AE 0300 2DED 0315 0062;00E0 05AE 2DED 0315 0062;0061 05AE 0300 2DED 0315 0062; +0061 2DED 0315 0300 05AE 0062;0061 05AE 2DED 0300 0315 0062;0061 05AE 2DED 0300 0315 0062;0061 05AE 2DED 0300 0315 0062;0061 05AE 2DED 0300 0315 0062; +0061 0315 0300 05AE 2DEE 0062;00E0 05AE 2DEE 0315 0062;0061 05AE 0300 2DEE 0315 0062;00E0 05AE 2DEE 0315 0062;0061 05AE 0300 2DEE 0315 0062; +0061 2DEE 0315 0300 05AE 0062;0061 05AE 2DEE 0300 0315 0062;0061 05AE 2DEE 0300 0315 0062;0061 05AE 2DEE 0300 0315 0062;0061 05AE 2DEE 0300 0315 0062; +0061 0315 0300 05AE 2DEF 0062;00E0 05AE 2DEF 0315 0062;0061 05AE 0300 2DEF 0315 0062;00E0 05AE 2DEF 0315 0062;0061 05AE 0300 2DEF 0315 0062; +0061 2DEF 0315 0300 05AE 0062;0061 05AE 2DEF 0300 0315 0062;0061 05AE 2DEF 0300 0315 0062;0061 05AE 2DEF 0300 0315 0062;0061 05AE 2DEF 0300 0315 0062; +0061 0315 0300 05AE 2DF0 0062;00E0 05AE 2DF0 0315 0062;0061 05AE 0300 2DF0 0315 0062;00E0 05AE 2DF0 0315 0062;0061 05AE 0300 2DF0 0315 0062; +0061 2DF0 0315 0300 05AE 0062;0061 05AE 2DF0 0300 0315 0062;0061 05AE 2DF0 0300 0315 0062;0061 05AE 2DF0 0300 0315 0062;0061 05AE 2DF0 0300 0315 0062; +0061 0315 0300 05AE 2DF1 0062;00E0 05AE 2DF1 0315 0062;0061 05AE 0300 2DF1 0315 0062;00E0 05AE 2DF1 0315 0062;0061 05AE 0300 2DF1 0315 0062; +0061 2DF1 0315 0300 05AE 0062;0061 05AE 2DF1 0300 0315 0062;0061 05AE 2DF1 0300 0315 0062;0061 05AE 2DF1 0300 0315 0062;0061 05AE 2DF1 0300 0315 0062; +0061 0315 0300 05AE 2DF2 0062;00E0 05AE 2DF2 0315 0062;0061 05AE 0300 2DF2 0315 0062;00E0 05AE 2DF2 0315 0062;0061 05AE 0300 2DF2 0315 0062; +0061 2DF2 0315 0300 05AE 0062;0061 05AE 2DF2 0300 0315 0062;0061 05AE 2DF2 0300 0315 0062;0061 05AE 2DF2 0300 0315 0062;0061 05AE 2DF2 0300 0315 0062; +0061 0315 0300 05AE 2DF3 0062;00E0 05AE 2DF3 0315 0062;0061 05AE 0300 2DF3 0315 0062;00E0 05AE 2DF3 0315 0062;0061 05AE 0300 2DF3 0315 0062; +0061 2DF3 0315 0300 05AE 0062;0061 05AE 2DF3 0300 0315 0062;0061 05AE 2DF3 0300 0315 0062;0061 05AE 2DF3 0300 0315 0062;0061 05AE 2DF3 0300 0315 0062; +0061 0315 0300 05AE 2DF4 0062;00E0 05AE 2DF4 0315 0062;0061 05AE 0300 2DF4 0315 0062;00E0 05AE 2DF4 0315 0062;0061 05AE 0300 2DF4 0315 0062; +0061 2DF4 0315 0300 05AE 0062;0061 05AE 2DF4 0300 0315 0062;0061 05AE 2DF4 0300 0315 0062;0061 05AE 2DF4 0300 0315 0062;0061 05AE 2DF4 0300 0315 0062; +0061 0315 0300 05AE 2DF5 0062;00E0 05AE 2DF5 0315 0062;0061 05AE 0300 2DF5 0315 0062;00E0 05AE 2DF5 0315 0062;0061 05AE 0300 2DF5 0315 0062; +0061 2DF5 0315 0300 05AE 0062;0061 05AE 2DF5 0300 0315 0062;0061 05AE 2DF5 0300 0315 0062;0061 05AE 2DF5 0300 0315 0062;0061 05AE 2DF5 0300 0315 0062; +0061 0315 0300 05AE 2DF6 0062;00E0 05AE 2DF6 0315 0062;0061 05AE 0300 2DF6 0315 0062;00E0 05AE 2DF6 0315 0062;0061 05AE 0300 2DF6 0315 0062; +0061 2DF6 0315 0300 05AE 0062;0061 05AE 2DF6 0300 0315 0062;0061 05AE 2DF6 0300 0315 0062;0061 05AE 2DF6 0300 0315 0062;0061 05AE 2DF6 0300 0315 0062; +0061 0315 0300 05AE 2DF7 0062;00E0 05AE 2DF7 0315 0062;0061 05AE 0300 2DF7 0315 0062;00E0 05AE 2DF7 0315 0062;0061 05AE 0300 2DF7 0315 0062; +0061 2DF7 0315 0300 05AE 0062;0061 05AE 2DF7 0300 0315 0062;0061 05AE 2DF7 0300 0315 0062;0061 05AE 2DF7 0300 0315 0062;0061 05AE 2DF7 0300 0315 0062; +0061 0315 0300 05AE 2DF8 0062;00E0 05AE 2DF8 0315 0062;0061 05AE 0300 2DF8 0315 0062;00E0 05AE 2DF8 0315 0062;0061 05AE 0300 2DF8 0315 0062; +0061 2DF8 0315 0300 05AE 0062;0061 05AE 2DF8 0300 0315 0062;0061 05AE 2DF8 0300 0315 0062;0061 05AE 2DF8 0300 0315 0062;0061 05AE 2DF8 0300 0315 0062; +0061 0315 0300 05AE 2DF9 0062;00E0 05AE 2DF9 0315 0062;0061 05AE 0300 2DF9 0315 0062;00E0 05AE 2DF9 0315 0062;0061 05AE 0300 2DF9 0315 0062; +0061 2DF9 0315 0300 05AE 0062;0061 05AE 2DF9 0300 0315 0062;0061 05AE 2DF9 0300 0315 0062;0061 05AE 2DF9 0300 0315 0062;0061 05AE 2DF9 0300 0315 0062; +0061 0315 0300 05AE 2DFA 0062;00E0 05AE 2DFA 0315 0062;0061 05AE 0300 2DFA 0315 0062;00E0 05AE 2DFA 0315 0062;0061 05AE 0300 2DFA 0315 0062; +0061 2DFA 0315 0300 05AE 0062;0061 05AE 2DFA 0300 0315 0062;0061 05AE 2DFA 0300 0315 0062;0061 05AE 2DFA 0300 0315 0062;0061 05AE 2DFA 0300 0315 0062; +0061 0315 0300 05AE 2DFB 0062;00E0 05AE 2DFB 0315 0062;0061 05AE 0300 2DFB 0315 0062;00E0 05AE 2DFB 0315 0062;0061 05AE 0300 2DFB 0315 0062; +0061 2DFB 0315 0300 05AE 0062;0061 05AE 2DFB 0300 0315 0062;0061 05AE 2DFB 0300 0315 0062;0061 05AE 2DFB 0300 0315 0062;0061 05AE 2DFB 0300 0315 0062; +0061 0315 0300 05AE 2DFC 0062;00E0 05AE 2DFC 0315 0062;0061 05AE 0300 2DFC 0315 0062;00E0 05AE 2DFC 0315 0062;0061 05AE 0300 2DFC 0315 0062; +0061 2DFC 0315 0300 05AE 0062;0061 05AE 2DFC 0300 0315 0062;0061 05AE 2DFC 0300 0315 0062;0061 05AE 2DFC 0300 0315 0062;0061 05AE 2DFC 0300 0315 0062; +0061 0315 0300 05AE 2DFD 0062;00E0 05AE 2DFD 0315 0062;0061 05AE 0300 2DFD 0315 0062;00E0 05AE 2DFD 0315 0062;0061 05AE 0300 2DFD 0315 0062; +0061 2DFD 0315 0300 05AE 0062;0061 05AE 2DFD 0300 0315 0062;0061 05AE 2DFD 0300 0315 0062;0061 05AE 2DFD 0300 0315 0062;0061 05AE 2DFD 0300 0315 0062; +0061 0315 0300 05AE 2DFE 0062;00E0 05AE 2DFE 0315 0062;0061 05AE 0300 2DFE 0315 0062;00E0 05AE 2DFE 0315 0062;0061 05AE 0300 2DFE 0315 0062; +0061 2DFE 0315 0300 05AE 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062; +0061 0315 0300 05AE 2DFF 0062;00E0 05AE 2DFF 0315 0062;0061 05AE 0300 2DFF 0315 0062;00E0 05AE 2DFF 0315 0062;0061 05AE 0300 2DFF 0315 0062; +0061 2DFF 0315 0300 05AE 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062; +0061 0316 302A 031B 302A 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062; +0061 302A 0316 302A 031B 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062; +0061 0300 05AE 1D16D 302B 0062;00E0 1D16D 05AE 302B 0062;0061 1D16D 05AE 302B 0300 0062;00E0 1D16D 05AE 302B 0062;0061 1D16D 05AE 302B 0300 0062; +0061 302B 0300 05AE 1D16D 0062;00E0 1D16D 302B 05AE 0062;0061 1D16D 302B 05AE 0300 0062;00E0 1D16D 302B 05AE 0062;0061 1D16D 302B 05AE 0300 0062; +0061 035C 0315 0300 302C 0062;00E0 0315 302C 035C 0062;0061 0300 0315 302C 035C 0062;00E0 0315 302C 035C 0062;0061 0300 0315 302C 035C 0062; +0061 302C 035C 0315 0300 0062;00E0 302C 0315 035C 0062;0061 0300 302C 0315 035C 0062;00E0 302C 0315 035C 0062;0061 0300 302C 0315 035C 0062; +0061 302E 059A 0316 302D 0062;0061 0316 059A 302D 302E 0062;0061 0316 059A 302D 302E 0062;0061 0316 059A 302D 302E 0062;0061 0316 059A 302D 302E 0062; +0061 302D 302E 059A 0316 0062;0061 0316 302D 059A 302E 0062;0061 0316 302D 059A 302E 0062;0061 0316 302D 059A 302E 0062;0061 0316 302D 059A 302E 0062; +0061 1D16D 302E 059A 302E 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062; +0061 302E 1D16D 302E 059A 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062; +0061 1D16D 302E 059A 302F 0062;0061 059A 302E 302F 1D16D 0062;0061 059A 302E 302F 1D16D 0062;0061 059A 302E 302F 1D16D 0062;0061 059A 302E 302F 1D16D 0062; +0061 302F 1D16D 302E 059A 0062;0061 059A 302F 302E 1D16D 0062;0061 059A 302F 302E 1D16D 0062;0061 059A 302F 302E 1D16D 0062;0061 059A 302F 302E 1D16D 0062; +0061 094D 3099 093C 3099 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062; +0061 3099 094D 3099 093C 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062; +0061 094D 3099 093C 309A 0062;0061 093C 3099 309A 094D 0062;0061 093C 3099 309A 094D 0062;0061 093C 3099 309A 094D 0062;0061 093C 3099 309A 094D 0062; +0061 309A 094D 3099 093C 0062;0061 093C 309A 3099 094D 0062;0061 093C 309A 3099 094D 0062;0061 093C 309A 3099 094D 0062;0061 093C 309A 3099 094D 0062; +0061 0315 0300 05AE A66F 0062;00E0 05AE A66F 0315 0062;0061 05AE 0300 A66F 0315 0062;00E0 05AE A66F 0315 0062;0061 05AE 0300 A66F 0315 0062; +0061 A66F 0315 0300 05AE 0062;0061 05AE A66F 0300 0315 0062;0061 05AE A66F 0300 0315 0062;0061 05AE A66F 0300 0315 0062;0061 05AE A66F 0300 0315 0062; +0061 0315 0300 05AE A674 0062;00E0 05AE A674 0315 0062;0061 05AE 0300 A674 0315 0062;00E0 05AE A674 0315 0062;0061 05AE 0300 A674 0315 0062; +0061 A674 0315 0300 05AE 0062;0061 05AE A674 0300 0315 0062;0061 05AE A674 0300 0315 0062;0061 05AE A674 0300 0315 0062;0061 05AE A674 0300 0315 0062; +0061 0315 0300 05AE A675 0062;00E0 05AE A675 0315 0062;0061 05AE 0300 A675 0315 0062;00E0 05AE A675 0315 0062;0061 05AE 0300 A675 0315 0062; +0061 A675 0315 0300 05AE 0062;0061 05AE A675 0300 0315 0062;0061 05AE A675 0300 0315 0062;0061 05AE A675 0300 0315 0062;0061 05AE A675 0300 0315 0062; +0061 0315 0300 05AE A676 0062;00E0 05AE A676 0315 0062;0061 05AE 0300 A676 0315 0062;00E0 05AE A676 0315 0062;0061 05AE 0300 A676 0315 0062; +0061 A676 0315 0300 05AE 0062;0061 05AE A676 0300 0315 0062;0061 05AE A676 0300 0315 0062;0061 05AE A676 0300 0315 0062;0061 05AE A676 0300 0315 0062; +0061 0315 0300 05AE A677 0062;00E0 05AE A677 0315 0062;0061 05AE 0300 A677 0315 0062;00E0 05AE A677 0315 0062;0061 05AE 0300 A677 0315 0062; +0061 A677 0315 0300 05AE 0062;0061 05AE A677 0300 0315 0062;0061 05AE A677 0300 0315 0062;0061 05AE A677 0300 0315 0062;0061 05AE A677 0300 0315 0062; +0061 0315 0300 05AE A678 0062;00E0 05AE A678 0315 0062;0061 05AE 0300 A678 0315 0062;00E0 05AE A678 0315 0062;0061 05AE 0300 A678 0315 0062; +0061 A678 0315 0300 05AE 0062;0061 05AE A678 0300 0315 0062;0061 05AE A678 0300 0315 0062;0061 05AE A678 0300 0315 0062;0061 05AE A678 0300 0315 0062; +0061 0315 0300 05AE A679 0062;00E0 05AE A679 0315 0062;0061 05AE 0300 A679 0315 0062;00E0 05AE A679 0315 0062;0061 05AE 0300 A679 0315 0062; +0061 A679 0315 0300 05AE 0062;0061 05AE A679 0300 0315 0062;0061 05AE A679 0300 0315 0062;0061 05AE A679 0300 0315 0062;0061 05AE A679 0300 0315 0062; +0061 0315 0300 05AE A67A 0062;00E0 05AE A67A 0315 0062;0061 05AE 0300 A67A 0315 0062;00E0 05AE A67A 0315 0062;0061 05AE 0300 A67A 0315 0062; +0061 A67A 0315 0300 05AE 0062;0061 05AE A67A 0300 0315 0062;0061 05AE A67A 0300 0315 0062;0061 05AE A67A 0300 0315 0062;0061 05AE A67A 0300 0315 0062; +0061 0315 0300 05AE A67B 0062;00E0 05AE A67B 0315 0062;0061 05AE 0300 A67B 0315 0062;00E0 05AE A67B 0315 0062;0061 05AE 0300 A67B 0315 0062; +0061 A67B 0315 0300 05AE 0062;0061 05AE A67B 0300 0315 0062;0061 05AE A67B 0300 0315 0062;0061 05AE A67B 0300 0315 0062;0061 05AE A67B 0300 0315 0062; +0061 0315 0300 05AE A67C 0062;00E0 05AE A67C 0315 0062;0061 05AE 0300 A67C 0315 0062;00E0 05AE A67C 0315 0062;0061 05AE 0300 A67C 0315 0062; +0061 A67C 0315 0300 05AE 0062;0061 05AE A67C 0300 0315 0062;0061 05AE A67C 0300 0315 0062;0061 05AE A67C 0300 0315 0062;0061 05AE A67C 0300 0315 0062; +0061 0315 0300 05AE A67D 0062;00E0 05AE A67D 0315 0062;0061 05AE 0300 A67D 0315 0062;00E0 05AE A67D 0315 0062;0061 05AE 0300 A67D 0315 0062; +0061 A67D 0315 0300 05AE 0062;0061 05AE A67D 0300 0315 0062;0061 05AE A67D 0300 0315 0062;0061 05AE A67D 0300 0315 0062;0061 05AE A67D 0300 0315 0062; +0061 0315 0300 05AE A69E 0062;00E0 05AE A69E 0315 0062;0061 05AE 0300 A69E 0315 0062;00E0 05AE A69E 0315 0062;0061 05AE 0300 A69E 0315 0062; +0061 A69E 0315 0300 05AE 0062;0061 05AE A69E 0300 0315 0062;0061 05AE A69E 0300 0315 0062;0061 05AE A69E 0300 0315 0062;0061 05AE A69E 0300 0315 0062; +0061 0315 0300 05AE A69F 0062;00E0 05AE A69F 0315 0062;0061 05AE 0300 A69F 0315 0062;00E0 05AE A69F 0315 0062;0061 05AE 0300 A69F 0315 0062; +0061 A69F 0315 0300 05AE 0062;0061 05AE A69F 0300 0315 0062;0061 05AE A69F 0300 0315 0062;0061 05AE A69F 0300 0315 0062;0061 05AE A69F 0300 0315 0062; +0061 0315 0300 05AE A6F0 0062;00E0 05AE A6F0 0315 0062;0061 05AE 0300 A6F0 0315 0062;00E0 05AE A6F0 0315 0062;0061 05AE 0300 A6F0 0315 0062; +0061 A6F0 0315 0300 05AE 0062;0061 05AE A6F0 0300 0315 0062;0061 05AE A6F0 0300 0315 0062;0061 05AE A6F0 0300 0315 0062;0061 05AE A6F0 0300 0315 0062; +0061 0315 0300 05AE A6F1 0062;00E0 05AE A6F1 0315 0062;0061 05AE 0300 A6F1 0315 0062;00E0 05AE A6F1 0315 0062;0061 05AE 0300 A6F1 0315 0062; +0061 A6F1 0315 0300 05AE 0062;0061 05AE A6F1 0300 0315 0062;0061 05AE A6F1 0300 0315 0062;0061 05AE A6F1 0300 0315 0062;0061 05AE A6F1 0300 0315 0062; +0061 05B0 094D 3099 A806 0062;0061 3099 094D A806 05B0 0062;0061 3099 094D A806 05B0 0062;0061 3099 094D A806 05B0 0062;0061 3099 094D A806 05B0 0062; +0061 A806 05B0 094D 3099 0062;0061 3099 A806 094D 05B0 0062;0061 3099 A806 094D 05B0 0062;0061 3099 A806 094D 05B0 0062;0061 3099 A806 094D 05B0 0062; +0061 05B0 094D 3099 A8C4 0062;0061 3099 094D A8C4 05B0 0062;0061 3099 094D A8C4 05B0 0062;0061 3099 094D A8C4 05B0 0062;0061 3099 094D A8C4 05B0 0062; +0061 A8C4 05B0 094D 3099 0062;0061 3099 A8C4 094D 05B0 0062;0061 3099 A8C4 094D 05B0 0062;0061 3099 A8C4 094D 05B0 0062;0061 3099 A8C4 094D 05B0 0062; +0061 0315 0300 05AE A8E0 0062;00E0 05AE A8E0 0315 0062;0061 05AE 0300 A8E0 0315 0062;00E0 05AE A8E0 0315 0062;0061 05AE 0300 A8E0 0315 0062; +0061 A8E0 0315 0300 05AE 0062;0061 05AE A8E0 0300 0315 0062;0061 05AE A8E0 0300 0315 0062;0061 05AE A8E0 0300 0315 0062;0061 05AE A8E0 0300 0315 0062; +0061 0315 0300 05AE A8E1 0062;00E0 05AE A8E1 0315 0062;0061 05AE 0300 A8E1 0315 0062;00E0 05AE A8E1 0315 0062;0061 05AE 0300 A8E1 0315 0062; +0061 A8E1 0315 0300 05AE 0062;0061 05AE A8E1 0300 0315 0062;0061 05AE A8E1 0300 0315 0062;0061 05AE A8E1 0300 0315 0062;0061 05AE A8E1 0300 0315 0062; +0061 0315 0300 05AE A8E2 0062;00E0 05AE A8E2 0315 0062;0061 05AE 0300 A8E2 0315 0062;00E0 05AE A8E2 0315 0062;0061 05AE 0300 A8E2 0315 0062; +0061 A8E2 0315 0300 05AE 0062;0061 05AE A8E2 0300 0315 0062;0061 05AE A8E2 0300 0315 0062;0061 05AE A8E2 0300 0315 0062;0061 05AE A8E2 0300 0315 0062; +0061 0315 0300 05AE A8E3 0062;00E0 05AE A8E3 0315 0062;0061 05AE 0300 A8E3 0315 0062;00E0 05AE A8E3 0315 0062;0061 05AE 0300 A8E3 0315 0062; +0061 A8E3 0315 0300 05AE 0062;0061 05AE A8E3 0300 0315 0062;0061 05AE A8E3 0300 0315 0062;0061 05AE A8E3 0300 0315 0062;0061 05AE A8E3 0300 0315 0062; +0061 0315 0300 05AE A8E4 0062;00E0 05AE A8E4 0315 0062;0061 05AE 0300 A8E4 0315 0062;00E0 05AE A8E4 0315 0062;0061 05AE 0300 A8E4 0315 0062; +0061 A8E4 0315 0300 05AE 0062;0061 05AE A8E4 0300 0315 0062;0061 05AE A8E4 0300 0315 0062;0061 05AE A8E4 0300 0315 0062;0061 05AE A8E4 0300 0315 0062; +0061 0315 0300 05AE A8E5 0062;00E0 05AE A8E5 0315 0062;0061 05AE 0300 A8E5 0315 0062;00E0 05AE A8E5 0315 0062;0061 05AE 0300 A8E5 0315 0062; +0061 A8E5 0315 0300 05AE 0062;0061 05AE A8E5 0300 0315 0062;0061 05AE A8E5 0300 0315 0062;0061 05AE A8E5 0300 0315 0062;0061 05AE A8E5 0300 0315 0062; +0061 0315 0300 05AE A8E6 0062;00E0 05AE A8E6 0315 0062;0061 05AE 0300 A8E6 0315 0062;00E0 05AE A8E6 0315 0062;0061 05AE 0300 A8E6 0315 0062; +0061 A8E6 0315 0300 05AE 0062;0061 05AE A8E6 0300 0315 0062;0061 05AE A8E6 0300 0315 0062;0061 05AE A8E6 0300 0315 0062;0061 05AE A8E6 0300 0315 0062; +0061 0315 0300 05AE A8E7 0062;00E0 05AE A8E7 0315 0062;0061 05AE 0300 A8E7 0315 0062;00E0 05AE A8E7 0315 0062;0061 05AE 0300 A8E7 0315 0062; +0061 A8E7 0315 0300 05AE 0062;0061 05AE A8E7 0300 0315 0062;0061 05AE A8E7 0300 0315 0062;0061 05AE A8E7 0300 0315 0062;0061 05AE A8E7 0300 0315 0062; +0061 0315 0300 05AE A8E8 0062;00E0 05AE A8E8 0315 0062;0061 05AE 0300 A8E8 0315 0062;00E0 05AE A8E8 0315 0062;0061 05AE 0300 A8E8 0315 0062; +0061 A8E8 0315 0300 05AE 0062;0061 05AE A8E8 0300 0315 0062;0061 05AE A8E8 0300 0315 0062;0061 05AE A8E8 0300 0315 0062;0061 05AE A8E8 0300 0315 0062; +0061 0315 0300 05AE A8E9 0062;00E0 05AE A8E9 0315 0062;0061 05AE 0300 A8E9 0315 0062;00E0 05AE A8E9 0315 0062;0061 05AE 0300 A8E9 0315 0062; +0061 A8E9 0315 0300 05AE 0062;0061 05AE A8E9 0300 0315 0062;0061 05AE A8E9 0300 0315 0062;0061 05AE A8E9 0300 0315 0062;0061 05AE A8E9 0300 0315 0062; +0061 0315 0300 05AE A8EA 0062;00E0 05AE A8EA 0315 0062;0061 05AE 0300 A8EA 0315 0062;00E0 05AE A8EA 0315 0062;0061 05AE 0300 A8EA 0315 0062; +0061 A8EA 0315 0300 05AE 0062;0061 05AE A8EA 0300 0315 0062;0061 05AE A8EA 0300 0315 0062;0061 05AE A8EA 0300 0315 0062;0061 05AE A8EA 0300 0315 0062; +0061 0315 0300 05AE A8EB 0062;00E0 05AE A8EB 0315 0062;0061 05AE 0300 A8EB 0315 0062;00E0 05AE A8EB 0315 0062;0061 05AE 0300 A8EB 0315 0062; +0061 A8EB 0315 0300 05AE 0062;0061 05AE A8EB 0300 0315 0062;0061 05AE A8EB 0300 0315 0062;0061 05AE A8EB 0300 0315 0062;0061 05AE A8EB 0300 0315 0062; +0061 0315 0300 05AE A8EC 0062;00E0 05AE A8EC 0315 0062;0061 05AE 0300 A8EC 0315 0062;00E0 05AE A8EC 0315 0062;0061 05AE 0300 A8EC 0315 0062; +0061 A8EC 0315 0300 05AE 0062;0061 05AE A8EC 0300 0315 0062;0061 05AE A8EC 0300 0315 0062;0061 05AE A8EC 0300 0315 0062;0061 05AE A8EC 0300 0315 0062; +0061 0315 0300 05AE A8ED 0062;00E0 05AE A8ED 0315 0062;0061 05AE 0300 A8ED 0315 0062;00E0 05AE A8ED 0315 0062;0061 05AE 0300 A8ED 0315 0062; +0061 A8ED 0315 0300 05AE 0062;0061 05AE A8ED 0300 0315 0062;0061 05AE A8ED 0300 0315 0062;0061 05AE A8ED 0300 0315 0062;0061 05AE A8ED 0300 0315 0062; +0061 0315 0300 05AE A8EE 0062;00E0 05AE A8EE 0315 0062;0061 05AE 0300 A8EE 0315 0062;00E0 05AE A8EE 0315 0062;0061 05AE 0300 A8EE 0315 0062; +0061 A8EE 0315 0300 05AE 0062;0061 05AE A8EE 0300 0315 0062;0061 05AE A8EE 0300 0315 0062;0061 05AE A8EE 0300 0315 0062;0061 05AE A8EE 0300 0315 0062; +0061 0315 0300 05AE A8EF 0062;00E0 05AE A8EF 0315 0062;0061 05AE 0300 A8EF 0315 0062;00E0 05AE A8EF 0315 0062;0061 05AE 0300 A8EF 0315 0062; +0061 A8EF 0315 0300 05AE 0062;0061 05AE A8EF 0300 0315 0062;0061 05AE A8EF 0300 0315 0062;0061 05AE A8EF 0300 0315 0062;0061 05AE A8EF 0300 0315 0062; +0061 0315 0300 05AE A8F0 0062;00E0 05AE A8F0 0315 0062;0061 05AE 0300 A8F0 0315 0062;00E0 05AE A8F0 0315 0062;0061 05AE 0300 A8F0 0315 0062; +0061 A8F0 0315 0300 05AE 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062; +0061 0315 0300 05AE A8F1 0062;00E0 05AE A8F1 0315 0062;0061 05AE 0300 A8F1 0315 0062;00E0 05AE A8F1 0315 0062;0061 05AE 0300 A8F1 0315 0062; +0061 A8F1 0315 0300 05AE 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062; +0061 059A 0316 302A A92B 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062; +0061 A92B 059A 0316 302A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062; +0061 059A 0316 302A A92C 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062; +0061 A92C 059A 0316 302A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062; +0061 059A 0316 302A A92D 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062; +0061 A92D 059A 0316 302A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062; +0061 05B0 094D 3099 A953 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062; +0061 A953 05B0 094D 3099 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062; +0061 3099 093C 0334 A9B3 0062;0061 0334 093C A9B3 3099 0062;0061 0334 093C A9B3 3099 0062;0061 0334 093C A9B3 3099 0062;0061 0334 093C A9B3 3099 0062; +0061 A9B3 3099 093C 0334 0062;0061 0334 A9B3 093C 3099 0062;0061 0334 A9B3 093C 3099 0062;0061 0334 A9B3 093C 3099 0062;0061 0334 A9B3 093C 3099 0062; +0061 05B0 094D 3099 A9C0 0062;0061 3099 094D A9C0 05B0 0062;0061 3099 094D A9C0 05B0 0062;0061 3099 094D A9C0 05B0 0062;0061 3099 094D A9C0 05B0 0062; +0061 A9C0 05B0 094D 3099 0062;0061 3099 A9C0 094D 05B0 0062;0061 3099 A9C0 094D 05B0 0062;0061 3099 A9C0 094D 05B0 0062;0061 3099 A9C0 094D 05B0 0062; +0061 0315 0300 05AE AAB0 0062;00E0 05AE AAB0 0315 0062;0061 05AE 0300 AAB0 0315 0062;00E0 05AE AAB0 0315 0062;0061 05AE 0300 AAB0 0315 0062; +0061 AAB0 0315 0300 05AE 0062;0061 05AE AAB0 0300 0315 0062;0061 05AE AAB0 0300 0315 0062;0061 05AE AAB0 0300 0315 0062;0061 05AE AAB0 0300 0315 0062; +0061 0315 0300 05AE AAB2 0062;00E0 05AE AAB2 0315 0062;0061 05AE 0300 AAB2 0315 0062;00E0 05AE AAB2 0315 0062;0061 05AE 0300 AAB2 0315 0062; +0061 AAB2 0315 0300 05AE 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062; +0061 0315 0300 05AE AAB3 0062;00E0 05AE AAB3 0315 0062;0061 05AE 0300 AAB3 0315 0062;00E0 05AE AAB3 0315 0062;0061 05AE 0300 AAB3 0315 0062; +0061 AAB3 0315 0300 05AE 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062; +0061 059A 0316 302A AAB4 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062; +0061 AAB4 059A 0316 302A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062; +0061 0315 0300 05AE AAB7 0062;00E0 05AE AAB7 0315 0062;0061 05AE 0300 AAB7 0315 0062;00E0 05AE AAB7 0315 0062;0061 05AE 0300 AAB7 0315 0062; +0061 AAB7 0315 0300 05AE 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062; +0061 0315 0300 05AE AAB8 0062;00E0 05AE AAB8 0315 0062;0061 05AE 0300 AAB8 0315 0062;00E0 05AE AAB8 0315 0062;0061 05AE 0300 AAB8 0315 0062; +0061 AAB8 0315 0300 05AE 0062;0061 05AE AAB8 0300 0315 0062;0061 05AE AAB8 0300 0315 0062;0061 05AE AAB8 0300 0315 0062;0061 05AE AAB8 0300 0315 0062; +0061 0315 0300 05AE AABE 0062;00E0 05AE AABE 0315 0062;0061 05AE 0300 AABE 0315 0062;00E0 05AE AABE 0315 0062;0061 05AE 0300 AABE 0315 0062; +0061 AABE 0315 0300 05AE 0062;0061 05AE AABE 0300 0315 0062;0061 05AE AABE 0300 0315 0062;0061 05AE AABE 0300 0315 0062;0061 05AE AABE 0300 0315 0062; +0061 0315 0300 05AE AABF 0062;00E0 05AE AABF 0315 0062;0061 05AE 0300 AABF 0315 0062;00E0 05AE AABF 0315 0062;0061 05AE 0300 AABF 0315 0062; +0061 AABF 0315 0300 05AE 0062;0061 05AE AABF 0300 0315 0062;0061 05AE AABF 0300 0315 0062;0061 05AE AABF 0300 0315 0062;0061 05AE AABF 0300 0315 0062; +0061 0315 0300 05AE AAC1 0062;00E0 05AE AAC1 0315 0062;0061 05AE 0300 AAC1 0315 0062;00E0 05AE AAC1 0315 0062;0061 05AE 0300 AAC1 0315 0062; +0061 AAC1 0315 0300 05AE 0062;0061 05AE AAC1 0300 0315 0062;0061 05AE AAC1 0300 0315 0062;0061 05AE AAC1 0300 0315 0062;0061 05AE AAC1 0300 0315 0062; +0061 05B0 094D 3099 AAF6 0062;0061 3099 094D AAF6 05B0 0062;0061 3099 094D AAF6 05B0 0062;0061 3099 094D AAF6 05B0 0062;0061 3099 094D AAF6 05B0 0062; +0061 AAF6 05B0 094D 3099 0062;0061 3099 AAF6 094D 05B0 0062;0061 3099 AAF6 094D 05B0 0062;0061 3099 AAF6 094D 05B0 0062;0061 3099 AAF6 094D 05B0 0062; +0061 05B0 094D 3099 ABED 0062;0061 3099 094D ABED 05B0 0062;0061 3099 094D ABED 05B0 0062;0061 3099 094D ABED 05B0 0062;0061 3099 094D ABED 05B0 0062; +0061 ABED 05B0 094D 3099 0062;0061 3099 ABED 094D 05B0 0062;0061 3099 ABED 094D 05B0 0062;0061 3099 ABED 094D 05B0 0062;0061 3099 ABED 094D 05B0 0062; +0061 064B FB1E 05C2 FB1E 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062; +0061 FB1E 064B FB1E 05C2 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062; +0061 0315 0300 05AE FE20 0062;00E0 05AE FE20 0315 0062;0061 05AE 0300 FE20 0315 0062;00E0 05AE FE20 0315 0062;0061 05AE 0300 FE20 0315 0062; +0061 FE20 0315 0300 05AE 0062;0061 05AE FE20 0300 0315 0062;0061 05AE FE20 0300 0315 0062;0061 05AE FE20 0300 0315 0062;0061 05AE FE20 0300 0315 0062; +0061 0315 0300 05AE FE21 0062;00E0 05AE FE21 0315 0062;0061 05AE 0300 FE21 0315 0062;00E0 05AE FE21 0315 0062;0061 05AE 0300 FE21 0315 0062; +0061 FE21 0315 0300 05AE 0062;0061 05AE FE21 0300 0315 0062;0061 05AE FE21 0300 0315 0062;0061 05AE FE21 0300 0315 0062;0061 05AE FE21 0300 0315 0062; +0061 0315 0300 05AE FE22 0062;00E0 05AE FE22 0315 0062;0061 05AE 0300 FE22 0315 0062;00E0 05AE FE22 0315 0062;0061 05AE 0300 FE22 0315 0062; +0061 FE22 0315 0300 05AE 0062;0061 05AE FE22 0300 0315 0062;0061 05AE FE22 0300 0315 0062;0061 05AE FE22 0300 0315 0062;0061 05AE FE22 0300 0315 0062; +0061 0315 0300 05AE FE23 0062;00E0 05AE FE23 0315 0062;0061 05AE 0300 FE23 0315 0062;00E0 05AE FE23 0315 0062;0061 05AE 0300 FE23 0315 0062; +0061 FE23 0315 0300 05AE 0062;0061 05AE FE23 0300 0315 0062;0061 05AE FE23 0300 0315 0062;0061 05AE FE23 0300 0315 0062;0061 05AE FE23 0300 0315 0062; +0061 0315 0300 05AE FE24 0062;00E0 05AE FE24 0315 0062;0061 05AE 0300 FE24 0315 0062;00E0 05AE FE24 0315 0062;0061 05AE 0300 FE24 0315 0062; +0061 FE24 0315 0300 05AE 0062;0061 05AE FE24 0300 0315 0062;0061 05AE FE24 0300 0315 0062;0061 05AE FE24 0300 0315 0062;0061 05AE FE24 0300 0315 0062; +0061 0315 0300 05AE FE25 0062;00E0 05AE FE25 0315 0062;0061 05AE 0300 FE25 0315 0062;00E0 05AE FE25 0315 0062;0061 05AE 0300 FE25 0315 0062; +0061 FE25 0315 0300 05AE 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062; +0061 0315 0300 05AE FE26 0062;00E0 05AE FE26 0315 0062;0061 05AE 0300 FE26 0315 0062;00E0 05AE FE26 0315 0062;0061 05AE 0300 FE26 0315 0062; +0061 FE26 0315 0300 05AE 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062; +0061 059A 0316 302A FE27 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062; +0061 FE27 059A 0316 302A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062; +0061 059A 0316 302A FE28 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062; +0061 FE28 059A 0316 302A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062; +0061 059A 0316 302A FE29 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062; +0061 FE29 059A 0316 302A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062; +0061 059A 0316 302A FE2A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062; +0061 FE2A 059A 0316 302A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062; +0061 059A 0316 302A FE2B 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062; +0061 FE2B 059A 0316 302A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062; +0061 059A 0316 302A FE2C 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062; +0061 FE2C 059A 0316 302A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062; +0061 059A 0316 302A FE2D 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062; +0061 FE2D 059A 0316 302A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062; +0061 0315 0300 05AE FE2E 0062;00E0 05AE FE2E 0315 0062;0061 05AE 0300 FE2E 0315 0062;00E0 05AE FE2E 0315 0062;0061 05AE 0300 FE2E 0315 0062; +0061 FE2E 0315 0300 05AE 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062; +0061 0315 0300 05AE FE2F 0062;00E0 05AE FE2F 0315 0062;0061 05AE 0300 FE2F 0315 0062;00E0 05AE FE2F 0315 0062;0061 05AE 0300 FE2F 0315 0062; +0061 FE2F 0315 0300 05AE 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062; +0061 059A 0316 302A 101FD 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062; +0061 101FD 059A 0316 302A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062; +0061 059A 0316 302A 102E0 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062; +0061 102E0 059A 0316 302A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062; +0061 0315 0300 05AE 10376 0062;00E0 05AE 10376 0315 0062;0061 05AE 0300 10376 0315 0062;00E0 05AE 10376 0315 0062;0061 05AE 0300 10376 0315 0062; +0061 10376 0315 0300 05AE 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062; +0061 0315 0300 05AE 10377 0062;00E0 05AE 10377 0315 0062;0061 05AE 0300 10377 0315 0062;00E0 05AE 10377 0315 0062;0061 05AE 0300 10377 0315 0062; +0061 10377 0315 0300 05AE 0062;0061 05AE 10377 0300 0315 0062;0061 05AE 10377 0300 0315 0062;0061 05AE 10377 0300 0315 0062;0061 05AE 10377 0300 0315 0062; +0061 0315 0300 05AE 10378 0062;00E0 05AE 10378 0315 0062;0061 05AE 0300 10378 0315 0062;00E0 05AE 10378 0315 0062;0061 05AE 0300 10378 0315 0062; +0061 10378 0315 0300 05AE 0062;0061 05AE 10378 0300 0315 0062;0061 05AE 10378 0300 0315 0062;0061 05AE 10378 0300 0315 0062;0061 05AE 10378 0300 0315 0062; +0061 0315 0300 05AE 10379 0062;00E0 05AE 10379 0315 0062;0061 05AE 0300 10379 0315 0062;00E0 05AE 10379 0315 0062;0061 05AE 0300 10379 0315 0062; +0061 10379 0315 0300 05AE 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062; +0061 0315 0300 05AE 1037A 0062;00E0 05AE 1037A 0315 0062;0061 05AE 0300 1037A 0315 0062;00E0 05AE 1037A 0315 0062;0061 05AE 0300 1037A 0315 0062; +0061 1037A 0315 0300 05AE 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062; +0061 059A 0316 302A 10A0D 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062; +0061 10A0D 059A 0316 302A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062; +0061 0315 0300 05AE 10A0F 0062;00E0 05AE 10A0F 0315 0062;0061 05AE 0300 10A0F 0315 0062;00E0 05AE 10A0F 0315 0062;0061 05AE 0300 10A0F 0315 0062; +0061 10A0F 0315 0300 05AE 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062; +0061 0315 0300 05AE 10A38 0062;00E0 05AE 10A38 0315 0062;0061 05AE 0300 10A38 0315 0062;00E0 05AE 10A38 0315 0062;0061 05AE 0300 10A38 0315 0062; +0061 10A38 0315 0300 05AE 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062; +0061 093C 0334 10A39 0062;0061 0334 10A39 093C 0062;0061 0334 10A39 093C 0062;0061 0334 10A39 093C 0062;0061 0334 10A39 093C 0062; +0061 10A39 093C 0334 0062;0061 10A39 0334 093C 0062;0061 10A39 0334 093C 0062;0061 10A39 0334 093C 0062;0061 10A39 0334 093C 0062; +0061 059A 0316 302A 10A3A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062; +0061 10A3A 059A 0316 302A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062; +0061 05B0 094D 3099 10A3F 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062; +0061 10A3F 05B0 094D 3099 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062; +0061 0315 0300 05AE 10AE5 0062;00E0 05AE 10AE5 0315 0062;0061 05AE 0300 10AE5 0315 0062;00E0 05AE 10AE5 0315 0062;0061 05AE 0300 10AE5 0315 0062; +0061 10AE5 0315 0300 05AE 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062; +0061 059A 0316 302A 10AE6 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062; +0061 10AE6 059A 0316 302A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062; +0061 0315 0300 05AE 10D24 0062;00E0 05AE 10D24 0315 0062;0061 05AE 0300 10D24 0315 0062;00E0 05AE 10D24 0315 0062;0061 05AE 0300 10D24 0315 0062; +0061 10D24 0315 0300 05AE 0062;0061 05AE 10D24 0300 0315 0062;0061 05AE 10D24 0300 0315 0062;0061 05AE 10D24 0300 0315 0062;0061 05AE 10D24 0300 0315 0062; +0061 0315 0300 05AE 10D25 0062;00E0 05AE 10D25 0315 0062;0061 05AE 0300 10D25 0315 0062;00E0 05AE 10D25 0315 0062;0061 05AE 0300 10D25 0315 0062; +0061 10D25 0315 0300 05AE 0062;0061 05AE 10D25 0300 0315 0062;0061 05AE 10D25 0300 0315 0062;0061 05AE 10D25 0300 0315 0062;0061 05AE 10D25 0300 0315 0062; +0061 0315 0300 05AE 10D26 0062;00E0 05AE 10D26 0315 0062;0061 05AE 0300 10D26 0315 0062;00E0 05AE 10D26 0315 0062;0061 05AE 0300 10D26 0315 0062; +0061 10D26 0315 0300 05AE 0062;0061 05AE 10D26 0300 0315 0062;0061 05AE 10D26 0300 0315 0062;0061 05AE 10D26 0300 0315 0062;0061 05AE 10D26 0300 0315 0062; +0061 0315 0300 05AE 10D27 0062;00E0 05AE 10D27 0315 0062;0061 05AE 0300 10D27 0315 0062;00E0 05AE 10D27 0315 0062;0061 05AE 0300 10D27 0315 0062; +0061 10D27 0315 0300 05AE 0062;0061 05AE 10D27 0300 0315 0062;0061 05AE 10D27 0300 0315 0062;0061 05AE 10D27 0300 0315 0062;0061 05AE 10D27 0300 0315 0062; +0061 059A 0316 302A 10F46 0062;0061 302A 0316 10F46 059A 0062;0061 302A 0316 10F46 059A 0062;0061 302A 0316 10F46 059A 0062;0061 302A 0316 10F46 059A 0062; +0061 10F46 059A 0316 302A 0062;0061 302A 10F46 0316 059A 0062;0061 302A 10F46 0316 059A 0062;0061 302A 10F46 0316 059A 0062;0061 302A 10F46 0316 059A 0062; +0061 059A 0316 302A 10F47 0062;0061 302A 0316 10F47 059A 0062;0061 302A 0316 10F47 059A 0062;0061 302A 0316 10F47 059A 0062;0061 302A 0316 10F47 059A 0062; +0061 10F47 059A 0316 302A 0062;0061 302A 10F47 0316 059A 0062;0061 302A 10F47 0316 059A 0062;0061 302A 10F47 0316 059A 0062;0061 302A 10F47 0316 059A 0062; +0061 0315 0300 05AE 10F48 0062;00E0 05AE 10F48 0315 0062;0061 05AE 0300 10F48 0315 0062;00E0 05AE 10F48 0315 0062;0061 05AE 0300 10F48 0315 0062; +0061 10F48 0315 0300 05AE 0062;0061 05AE 10F48 0300 0315 0062;0061 05AE 10F48 0300 0315 0062;0061 05AE 10F48 0300 0315 0062;0061 05AE 10F48 0300 0315 0062; +0061 0315 0300 05AE 10F49 0062;00E0 05AE 10F49 0315 0062;0061 05AE 0300 10F49 0315 0062;00E0 05AE 10F49 0315 0062;0061 05AE 0300 10F49 0315 0062; +0061 10F49 0315 0300 05AE 0062;0061 05AE 10F49 0300 0315 0062;0061 05AE 10F49 0300 0315 0062;0061 05AE 10F49 0300 0315 0062;0061 05AE 10F49 0300 0315 0062; +0061 0315 0300 05AE 10F4A 0062;00E0 05AE 10F4A 0315 0062;0061 05AE 0300 10F4A 0315 0062;00E0 05AE 10F4A 0315 0062;0061 05AE 0300 10F4A 0315 0062; +0061 10F4A 0315 0300 05AE 0062;0061 05AE 10F4A 0300 0315 0062;0061 05AE 10F4A 0300 0315 0062;0061 05AE 10F4A 0300 0315 0062;0061 05AE 10F4A 0300 0315 0062; +0061 059A 0316 302A 10F4B 0062;0061 302A 0316 10F4B 059A 0062;0061 302A 0316 10F4B 059A 0062;0061 302A 0316 10F4B 059A 0062;0061 302A 0316 10F4B 059A 0062; +0061 10F4B 059A 0316 302A 0062;0061 302A 10F4B 0316 059A 0062;0061 302A 10F4B 0316 059A 0062;0061 302A 10F4B 0316 059A 0062;0061 302A 10F4B 0316 059A 0062; +0061 0315 0300 05AE 10F4C 0062;00E0 05AE 10F4C 0315 0062;0061 05AE 0300 10F4C 0315 0062;00E0 05AE 10F4C 0315 0062;0061 05AE 0300 10F4C 0315 0062; +0061 10F4C 0315 0300 05AE 0062;0061 05AE 10F4C 0300 0315 0062;0061 05AE 10F4C 0300 0315 0062;0061 05AE 10F4C 0300 0315 0062;0061 05AE 10F4C 0300 0315 0062; +0061 059A 0316 302A 10F4D 0062;0061 302A 0316 10F4D 059A 0062;0061 302A 0316 10F4D 059A 0062;0061 302A 0316 10F4D 059A 0062;0061 302A 0316 10F4D 059A 0062; +0061 10F4D 059A 0316 302A 0062;0061 302A 10F4D 0316 059A 0062;0061 302A 10F4D 0316 059A 0062;0061 302A 10F4D 0316 059A 0062;0061 302A 10F4D 0316 059A 0062; +0061 059A 0316 302A 10F4E 0062;0061 302A 0316 10F4E 059A 0062;0061 302A 0316 10F4E 059A 0062;0061 302A 0316 10F4E 059A 0062;0061 302A 0316 10F4E 059A 0062; +0061 10F4E 059A 0316 302A 0062;0061 302A 10F4E 0316 059A 0062;0061 302A 10F4E 0316 059A 0062;0061 302A 10F4E 0316 059A 0062;0061 302A 10F4E 0316 059A 0062; +0061 059A 0316 302A 10F4F 0062;0061 302A 0316 10F4F 059A 0062;0061 302A 0316 10F4F 059A 0062;0061 302A 0316 10F4F 059A 0062;0061 302A 0316 10F4F 059A 0062; +0061 10F4F 059A 0316 302A 0062;0061 302A 10F4F 0316 059A 0062;0061 302A 10F4F 0316 059A 0062;0061 302A 10F4F 0316 059A 0062;0061 302A 10F4F 0316 059A 0062; +0061 059A 0316 302A 10F50 0062;0061 302A 0316 10F50 059A 0062;0061 302A 0316 10F50 059A 0062;0061 302A 0316 10F50 059A 0062;0061 302A 0316 10F50 059A 0062; +0061 10F50 059A 0316 302A 0062;0061 302A 10F50 0316 059A 0062;0061 302A 10F50 0316 059A 0062;0061 302A 10F50 0316 059A 0062;0061 302A 10F50 0316 059A 0062; +0061 05B0 094D 3099 11046 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062; +0061 11046 05B0 094D 3099 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062; +0061 05B0 094D 3099 1107F 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062; +0061 1107F 05B0 094D 3099 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062; +0061 05B0 094D 3099 110B9 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062; +0061 110B9 05B0 094D 3099 0062;0061 3099 110B9 094D 05B0 0062;0061 3099 110B9 094D 05B0 0062;0061 3099 110B9 094D 05B0 0062;0061 3099 110B9 094D 05B0 0062; +0061 3099 093C 0334 110BA 0062;0061 0334 093C 110BA 3099 0062;0061 0334 093C 110BA 3099 0062;0061 0334 093C 110BA 3099 0062;0061 0334 093C 110BA 3099 0062; +0061 110BA 3099 093C 0334 0062;0061 0334 110BA 093C 3099 0062;0061 0334 110BA 093C 3099 0062;0061 0334 110BA 093C 3099 0062;0061 0334 110BA 093C 3099 0062; +0061 0315 0300 05AE 11100 0062;00E0 05AE 11100 0315 0062;0061 05AE 0300 11100 0315 0062;00E0 05AE 11100 0315 0062;0061 05AE 0300 11100 0315 0062; +0061 11100 0315 0300 05AE 0062;0061 05AE 11100 0300 0315 0062;0061 05AE 11100 0300 0315 0062;0061 05AE 11100 0300 0315 0062;0061 05AE 11100 0300 0315 0062; +0061 0315 0300 05AE 11101 0062;00E0 05AE 11101 0315 0062;0061 05AE 0300 11101 0315 0062;00E0 05AE 11101 0315 0062;0061 05AE 0300 11101 0315 0062; +0061 11101 0315 0300 05AE 0062;0061 05AE 11101 0300 0315 0062;0061 05AE 11101 0300 0315 0062;0061 05AE 11101 0300 0315 0062;0061 05AE 11101 0300 0315 0062; +0061 0315 0300 05AE 11102 0062;00E0 05AE 11102 0315 0062;0061 05AE 0300 11102 0315 0062;00E0 05AE 11102 0315 0062;0061 05AE 0300 11102 0315 0062; +0061 11102 0315 0300 05AE 0062;0061 05AE 11102 0300 0315 0062;0061 05AE 11102 0300 0315 0062;0061 05AE 11102 0300 0315 0062;0061 05AE 11102 0300 0315 0062; +0061 05B0 094D 3099 11133 0062;0061 3099 094D 11133 05B0 0062;0061 3099 094D 11133 05B0 0062;0061 3099 094D 11133 05B0 0062;0061 3099 094D 11133 05B0 0062; +0061 11133 05B0 094D 3099 0062;0061 3099 11133 094D 05B0 0062;0061 3099 11133 094D 05B0 0062;0061 3099 11133 094D 05B0 0062;0061 3099 11133 094D 05B0 0062; +0061 05B0 094D 3099 11134 0062;0061 3099 094D 11134 05B0 0062;0061 3099 094D 11134 05B0 0062;0061 3099 094D 11134 05B0 0062;0061 3099 094D 11134 05B0 0062; +0061 11134 05B0 094D 3099 0062;0061 3099 11134 094D 05B0 0062;0061 3099 11134 094D 05B0 0062;0061 3099 11134 094D 05B0 0062;0061 3099 11134 094D 05B0 0062; +0061 3099 093C 0334 11173 0062;0061 0334 093C 11173 3099 0062;0061 0334 093C 11173 3099 0062;0061 0334 093C 11173 3099 0062;0061 0334 093C 11173 3099 0062; +0061 11173 3099 093C 0334 0062;0061 0334 11173 093C 3099 0062;0061 0334 11173 093C 3099 0062;0061 0334 11173 093C 3099 0062;0061 0334 11173 093C 3099 0062; +0061 05B0 094D 3099 111C0 0062;0061 3099 094D 111C0 05B0 0062;0061 3099 094D 111C0 05B0 0062;0061 3099 094D 111C0 05B0 0062;0061 3099 094D 111C0 05B0 0062; +0061 111C0 05B0 094D 3099 0062;0061 3099 111C0 094D 05B0 0062;0061 3099 111C0 094D 05B0 0062;0061 3099 111C0 094D 05B0 0062;0061 3099 111C0 094D 05B0 0062; +0061 3099 093C 0334 111CA 0062;0061 0334 093C 111CA 3099 0062;0061 0334 093C 111CA 3099 0062;0061 0334 093C 111CA 3099 0062;0061 0334 093C 111CA 3099 0062; +0061 111CA 3099 093C 0334 0062;0061 0334 111CA 093C 3099 0062;0061 0334 111CA 093C 3099 0062;0061 0334 111CA 093C 3099 0062;0061 0334 111CA 093C 3099 0062; +0061 05B0 094D 3099 11235 0062;0061 3099 094D 11235 05B0 0062;0061 3099 094D 11235 05B0 0062;0061 3099 094D 11235 05B0 0062;0061 3099 094D 11235 05B0 0062; +0061 11235 05B0 094D 3099 0062;0061 3099 11235 094D 05B0 0062;0061 3099 11235 094D 05B0 0062;0061 3099 11235 094D 05B0 0062;0061 3099 11235 094D 05B0 0062; +0061 3099 093C 0334 11236 0062;0061 0334 093C 11236 3099 0062;0061 0334 093C 11236 3099 0062;0061 0334 093C 11236 3099 0062;0061 0334 093C 11236 3099 0062; +0061 11236 3099 093C 0334 0062;0061 0334 11236 093C 3099 0062;0061 0334 11236 093C 3099 0062;0061 0334 11236 093C 3099 0062;0061 0334 11236 093C 3099 0062; +0061 3099 093C 0334 112E9 0062;0061 0334 093C 112E9 3099 0062;0061 0334 093C 112E9 3099 0062;0061 0334 093C 112E9 3099 0062;0061 0334 093C 112E9 3099 0062; +0061 112E9 3099 093C 0334 0062;0061 0334 112E9 093C 3099 0062;0061 0334 112E9 093C 3099 0062;0061 0334 112E9 093C 3099 0062;0061 0334 112E9 093C 3099 0062; +0061 05B0 094D 3099 112EA 0062;0061 3099 094D 112EA 05B0 0062;0061 3099 094D 112EA 05B0 0062;0061 3099 094D 112EA 05B0 0062;0061 3099 094D 112EA 05B0 0062; +0061 112EA 05B0 094D 3099 0062;0061 3099 112EA 094D 05B0 0062;0061 3099 112EA 094D 05B0 0062;0061 3099 112EA 094D 05B0 0062;0061 3099 112EA 094D 05B0 0062; +0061 3099 093C 0334 1133B 0062;0061 0334 093C 1133B 3099 0062;0061 0334 093C 1133B 3099 0062;0061 0334 093C 1133B 3099 0062;0061 0334 093C 1133B 3099 0062; +0061 1133B 3099 093C 0334 0062;0061 0334 1133B 093C 3099 0062;0061 0334 1133B 093C 3099 0062;0061 0334 1133B 093C 3099 0062;0061 0334 1133B 093C 3099 0062; +0061 3099 093C 0334 1133C 0062;0061 0334 093C 1133C 3099 0062;0061 0334 093C 1133C 3099 0062;0061 0334 093C 1133C 3099 0062;0061 0334 093C 1133C 3099 0062; +0061 1133C 3099 093C 0334 0062;0061 0334 1133C 093C 3099 0062;0061 0334 1133C 093C 3099 0062;0061 0334 1133C 093C 3099 0062;0061 0334 1133C 093C 3099 0062; +0061 05B0 094D 3099 1134D 0062;0061 3099 094D 1134D 05B0 0062;0061 3099 094D 1134D 05B0 0062;0061 3099 094D 1134D 05B0 0062;0061 3099 094D 1134D 05B0 0062; +0061 1134D 05B0 094D 3099 0062;0061 3099 1134D 094D 05B0 0062;0061 3099 1134D 094D 05B0 0062;0061 3099 1134D 094D 05B0 0062;0061 3099 1134D 094D 05B0 0062; +0061 0315 0300 05AE 11366 0062;00E0 05AE 11366 0315 0062;0061 05AE 0300 11366 0315 0062;00E0 05AE 11366 0315 0062;0061 05AE 0300 11366 0315 0062; +0061 11366 0315 0300 05AE 0062;0061 05AE 11366 0300 0315 0062;0061 05AE 11366 0300 0315 0062;0061 05AE 11366 0300 0315 0062;0061 05AE 11366 0300 0315 0062; +0061 0315 0300 05AE 11367 0062;00E0 05AE 11367 0315 0062;0061 05AE 0300 11367 0315 0062;00E0 05AE 11367 0315 0062;0061 05AE 0300 11367 0315 0062; +0061 11367 0315 0300 05AE 0062;0061 05AE 11367 0300 0315 0062;0061 05AE 11367 0300 0315 0062;0061 05AE 11367 0300 0315 0062;0061 05AE 11367 0300 0315 0062; +0061 0315 0300 05AE 11368 0062;00E0 05AE 11368 0315 0062;0061 05AE 0300 11368 0315 0062;00E0 05AE 11368 0315 0062;0061 05AE 0300 11368 0315 0062; +0061 11368 0315 0300 05AE 0062;0061 05AE 11368 0300 0315 0062;0061 05AE 11368 0300 0315 0062;0061 05AE 11368 0300 0315 0062;0061 05AE 11368 0300 0315 0062; +0061 0315 0300 05AE 11369 0062;00E0 05AE 11369 0315 0062;0061 05AE 0300 11369 0315 0062;00E0 05AE 11369 0315 0062;0061 05AE 0300 11369 0315 0062; +0061 11369 0315 0300 05AE 0062;0061 05AE 11369 0300 0315 0062;0061 05AE 11369 0300 0315 0062;0061 05AE 11369 0300 0315 0062;0061 05AE 11369 0300 0315 0062; +0061 0315 0300 05AE 1136A 0062;00E0 05AE 1136A 0315 0062;0061 05AE 0300 1136A 0315 0062;00E0 05AE 1136A 0315 0062;0061 05AE 0300 1136A 0315 0062; +0061 1136A 0315 0300 05AE 0062;0061 05AE 1136A 0300 0315 0062;0061 05AE 1136A 0300 0315 0062;0061 05AE 1136A 0300 0315 0062;0061 05AE 1136A 0300 0315 0062; +0061 0315 0300 05AE 1136B 0062;00E0 05AE 1136B 0315 0062;0061 05AE 0300 1136B 0315 0062;00E0 05AE 1136B 0315 0062;0061 05AE 0300 1136B 0315 0062; +0061 1136B 0315 0300 05AE 0062;0061 05AE 1136B 0300 0315 0062;0061 05AE 1136B 0300 0315 0062;0061 05AE 1136B 0300 0315 0062;0061 05AE 1136B 0300 0315 0062; +0061 0315 0300 05AE 1136C 0062;00E0 05AE 1136C 0315 0062;0061 05AE 0300 1136C 0315 0062;00E0 05AE 1136C 0315 0062;0061 05AE 0300 1136C 0315 0062; +0061 1136C 0315 0300 05AE 0062;0061 05AE 1136C 0300 0315 0062;0061 05AE 1136C 0300 0315 0062;0061 05AE 1136C 0300 0315 0062;0061 05AE 1136C 0300 0315 0062; +0061 0315 0300 05AE 11370 0062;00E0 05AE 11370 0315 0062;0061 05AE 0300 11370 0315 0062;00E0 05AE 11370 0315 0062;0061 05AE 0300 11370 0315 0062; +0061 11370 0315 0300 05AE 0062;0061 05AE 11370 0300 0315 0062;0061 05AE 11370 0300 0315 0062;0061 05AE 11370 0300 0315 0062;0061 05AE 11370 0300 0315 0062; +0061 0315 0300 05AE 11371 0062;00E0 05AE 11371 0315 0062;0061 05AE 0300 11371 0315 0062;00E0 05AE 11371 0315 0062;0061 05AE 0300 11371 0315 0062; +0061 11371 0315 0300 05AE 0062;0061 05AE 11371 0300 0315 0062;0061 05AE 11371 0300 0315 0062;0061 05AE 11371 0300 0315 0062;0061 05AE 11371 0300 0315 0062; +0061 0315 0300 05AE 11372 0062;00E0 05AE 11372 0315 0062;0061 05AE 0300 11372 0315 0062;00E0 05AE 11372 0315 0062;0061 05AE 0300 11372 0315 0062; +0061 11372 0315 0300 05AE 0062;0061 05AE 11372 0300 0315 0062;0061 05AE 11372 0300 0315 0062;0061 05AE 11372 0300 0315 0062;0061 05AE 11372 0300 0315 0062; +0061 0315 0300 05AE 11373 0062;00E0 05AE 11373 0315 0062;0061 05AE 0300 11373 0315 0062;00E0 05AE 11373 0315 0062;0061 05AE 0300 11373 0315 0062; +0061 11373 0315 0300 05AE 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062; +0061 0315 0300 05AE 11374 0062;00E0 05AE 11374 0315 0062;0061 05AE 0300 11374 0315 0062;00E0 05AE 11374 0315 0062;0061 05AE 0300 11374 0315 0062; +0061 11374 0315 0300 05AE 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062; +0061 05B0 094D 3099 11442 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062; +0061 11442 05B0 094D 3099 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062; +0061 3099 093C 0334 11446 0062;0061 0334 093C 11446 3099 0062;0061 0334 093C 11446 3099 0062;0061 0334 093C 11446 3099 0062;0061 0334 093C 11446 3099 0062; +0061 11446 3099 093C 0334 0062;0061 0334 11446 093C 3099 0062;0061 0334 11446 093C 3099 0062;0061 0334 11446 093C 3099 0062;0061 0334 11446 093C 3099 0062; +0061 0315 0300 05AE 1145E 0062;00E0 05AE 1145E 0315 0062;0061 05AE 0300 1145E 0315 0062;00E0 05AE 1145E 0315 0062;0061 05AE 0300 1145E 0315 0062; +0061 1145E 0315 0300 05AE 0062;0061 05AE 1145E 0300 0315 0062;0061 05AE 1145E 0300 0315 0062;0061 05AE 1145E 0300 0315 0062;0061 05AE 1145E 0300 0315 0062; +0061 05B0 094D 3099 114C2 0062;0061 3099 094D 114C2 05B0 0062;0061 3099 094D 114C2 05B0 0062;0061 3099 094D 114C2 05B0 0062;0061 3099 094D 114C2 05B0 0062; +0061 114C2 05B0 094D 3099 0062;0061 3099 114C2 094D 05B0 0062;0061 3099 114C2 094D 05B0 0062;0061 3099 114C2 094D 05B0 0062;0061 3099 114C2 094D 05B0 0062; +0061 3099 093C 0334 114C3 0062;0061 0334 093C 114C3 3099 0062;0061 0334 093C 114C3 3099 0062;0061 0334 093C 114C3 3099 0062;0061 0334 093C 114C3 3099 0062; +0061 114C3 3099 093C 0334 0062;0061 0334 114C3 093C 3099 0062;0061 0334 114C3 093C 3099 0062;0061 0334 114C3 093C 3099 0062;0061 0334 114C3 093C 3099 0062; +0061 05B0 094D 3099 115BF 0062;0061 3099 094D 115BF 05B0 0062;0061 3099 094D 115BF 05B0 0062;0061 3099 094D 115BF 05B0 0062;0061 3099 094D 115BF 05B0 0062; +0061 115BF 05B0 094D 3099 0062;0061 3099 115BF 094D 05B0 0062;0061 3099 115BF 094D 05B0 0062;0061 3099 115BF 094D 05B0 0062;0061 3099 115BF 094D 05B0 0062; +0061 3099 093C 0334 115C0 0062;0061 0334 093C 115C0 3099 0062;0061 0334 093C 115C0 3099 0062;0061 0334 093C 115C0 3099 0062;0061 0334 093C 115C0 3099 0062; +0061 115C0 3099 093C 0334 0062;0061 0334 115C0 093C 3099 0062;0061 0334 115C0 093C 3099 0062;0061 0334 115C0 093C 3099 0062;0061 0334 115C0 093C 3099 0062; +0061 05B0 094D 3099 1163F 0062;0061 3099 094D 1163F 05B0 0062;0061 3099 094D 1163F 05B0 0062;0061 3099 094D 1163F 05B0 0062;0061 3099 094D 1163F 05B0 0062; +0061 1163F 05B0 094D 3099 0062;0061 3099 1163F 094D 05B0 0062;0061 3099 1163F 094D 05B0 0062;0061 3099 1163F 094D 05B0 0062;0061 3099 1163F 094D 05B0 0062; +0061 05B0 094D 3099 116B6 0062;0061 3099 094D 116B6 05B0 0062;0061 3099 094D 116B6 05B0 0062;0061 3099 094D 116B6 05B0 0062;0061 3099 094D 116B6 05B0 0062; +0061 116B6 05B0 094D 3099 0062;0061 3099 116B6 094D 05B0 0062;0061 3099 116B6 094D 05B0 0062;0061 3099 116B6 094D 05B0 0062;0061 3099 116B6 094D 05B0 0062; +0061 3099 093C 0334 116B7 0062;0061 0334 093C 116B7 3099 0062;0061 0334 093C 116B7 3099 0062;0061 0334 093C 116B7 3099 0062;0061 0334 093C 116B7 3099 0062; +0061 116B7 3099 093C 0334 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062; +0061 05B0 094D 3099 1172B 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062; +0061 1172B 05B0 094D 3099 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062; +0061 05B0 094D 3099 11839 0062;0061 3099 094D 11839 05B0 0062;0061 3099 094D 11839 05B0 0062;0061 3099 094D 11839 05B0 0062;0061 3099 094D 11839 05B0 0062; +0061 11839 05B0 094D 3099 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062; +0061 3099 093C 0334 1183A 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062; +0061 1183A 3099 093C 0334 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062; +0061 05B0 094D 3099 11A34 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062; +0061 11A34 05B0 094D 3099 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062; +0061 05B0 094D 3099 11A47 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062; +0061 11A47 05B0 094D 3099 0062;0061 3099 11A47 094D 05B0 0062;0061 3099 11A47 094D 05B0 0062;0061 3099 11A47 094D 05B0 0062;0061 3099 11A47 094D 05B0 0062; +0061 05B0 094D 3099 11A99 0062;0061 3099 094D 11A99 05B0 0062;0061 3099 094D 11A99 05B0 0062;0061 3099 094D 11A99 05B0 0062;0061 3099 094D 11A99 05B0 0062; +0061 11A99 05B0 094D 3099 0062;0061 3099 11A99 094D 05B0 0062;0061 3099 11A99 094D 05B0 0062;0061 3099 11A99 094D 05B0 0062;0061 3099 11A99 094D 05B0 0062; +0061 05B0 094D 3099 11C3F 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062; +0061 11C3F 05B0 094D 3099 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062; +0061 3099 093C 0334 11D42 0062;0061 0334 093C 11D42 3099 0062;0061 0334 093C 11D42 3099 0062;0061 0334 093C 11D42 3099 0062;0061 0334 093C 11D42 3099 0062; +0061 11D42 3099 093C 0334 0062;0061 0334 11D42 093C 3099 0062;0061 0334 11D42 093C 3099 0062;0061 0334 11D42 093C 3099 0062;0061 0334 11D42 093C 3099 0062; +0061 05B0 094D 3099 11D44 0062;0061 3099 094D 11D44 05B0 0062;0061 3099 094D 11D44 05B0 0062;0061 3099 094D 11D44 05B0 0062;0061 3099 094D 11D44 05B0 0062; +0061 11D44 05B0 094D 3099 0062;0061 3099 11D44 094D 05B0 0062;0061 3099 11D44 094D 05B0 0062;0061 3099 11D44 094D 05B0 0062;0061 3099 11D44 094D 05B0 0062; +0061 05B0 094D 3099 11D45 0062;0061 3099 094D 11D45 05B0 0062;0061 3099 094D 11D45 05B0 0062;0061 3099 094D 11D45 05B0 0062;0061 3099 094D 11D45 05B0 0062; +0061 11D45 05B0 094D 3099 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062; +0061 05B0 094D 3099 11D97 0062;0061 3099 094D 11D97 05B0 0062;0061 3099 094D 11D97 05B0 0062;0061 3099 094D 11D97 05B0 0062;0061 3099 094D 11D97 05B0 0062; +0061 11D97 05B0 094D 3099 0062;0061 3099 11D97 094D 05B0 0062;0061 3099 11D97 094D 05B0 0062;0061 3099 11D97 094D 05B0 0062;0061 3099 11D97 094D 05B0 0062; +0061 093C 0334 16AF0 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062; +0061 16AF0 093C 0334 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062; +0061 093C 0334 16AF1 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062; +0061 16AF1 093C 0334 0062;0061 16AF1 0334 093C 0062;0061 16AF1 0334 093C 0062;0061 16AF1 0334 093C 0062;0061 16AF1 0334 093C 0062; +0061 093C 0334 16AF2 0062;0061 0334 16AF2 093C 0062;0061 0334 16AF2 093C 0062;0061 0334 16AF2 093C 0062;0061 0334 16AF2 093C 0062; +0061 16AF2 093C 0334 0062;0061 16AF2 0334 093C 0062;0061 16AF2 0334 093C 0062;0061 16AF2 0334 093C 0062;0061 16AF2 0334 093C 0062; +0061 093C 0334 16AF3 0062;0061 0334 16AF3 093C 0062;0061 0334 16AF3 093C 0062;0061 0334 16AF3 093C 0062;0061 0334 16AF3 093C 0062; +0061 16AF3 093C 0334 0062;0061 16AF3 0334 093C 0062;0061 16AF3 0334 093C 0062;0061 16AF3 0334 093C 0062;0061 16AF3 0334 093C 0062; +0061 093C 0334 16AF4 0062;0061 0334 16AF4 093C 0062;0061 0334 16AF4 093C 0062;0061 0334 16AF4 093C 0062;0061 0334 16AF4 093C 0062; +0061 16AF4 093C 0334 0062;0061 16AF4 0334 093C 0062;0061 16AF4 0334 093C 0062;0061 16AF4 0334 093C 0062;0061 16AF4 0334 093C 0062; +0061 0315 0300 05AE 16B30 0062;00E0 05AE 16B30 0315 0062;0061 05AE 0300 16B30 0315 0062;00E0 05AE 16B30 0315 0062;0061 05AE 0300 16B30 0315 0062; +0061 16B30 0315 0300 05AE 0062;0061 05AE 16B30 0300 0315 0062;0061 05AE 16B30 0300 0315 0062;0061 05AE 16B30 0300 0315 0062;0061 05AE 16B30 0300 0315 0062; +0061 0315 0300 05AE 16B31 0062;00E0 05AE 16B31 0315 0062;0061 05AE 0300 16B31 0315 0062;00E0 05AE 16B31 0315 0062;0061 05AE 0300 16B31 0315 0062; +0061 16B31 0315 0300 05AE 0062;0061 05AE 16B31 0300 0315 0062;0061 05AE 16B31 0300 0315 0062;0061 05AE 16B31 0300 0315 0062;0061 05AE 16B31 0300 0315 0062; +0061 0315 0300 05AE 16B32 0062;00E0 05AE 16B32 0315 0062;0061 05AE 0300 16B32 0315 0062;00E0 05AE 16B32 0315 0062;0061 05AE 0300 16B32 0315 0062; +0061 16B32 0315 0300 05AE 0062;0061 05AE 16B32 0300 0315 0062;0061 05AE 16B32 0300 0315 0062;0061 05AE 16B32 0300 0315 0062;0061 05AE 16B32 0300 0315 0062; +0061 0315 0300 05AE 16B33 0062;00E0 05AE 16B33 0315 0062;0061 05AE 0300 16B33 0315 0062;00E0 05AE 16B33 0315 0062;0061 05AE 0300 16B33 0315 0062; +0061 16B33 0315 0300 05AE 0062;0061 05AE 16B33 0300 0315 0062;0061 05AE 16B33 0300 0315 0062;0061 05AE 16B33 0300 0315 0062;0061 05AE 16B33 0300 0315 0062; +0061 0315 0300 05AE 16B34 0062;00E0 05AE 16B34 0315 0062;0061 05AE 0300 16B34 0315 0062;00E0 05AE 16B34 0315 0062;0061 05AE 0300 16B34 0315 0062; +0061 16B34 0315 0300 05AE 0062;0061 05AE 16B34 0300 0315 0062;0061 05AE 16B34 0300 0315 0062;0061 05AE 16B34 0300 0315 0062;0061 05AE 16B34 0300 0315 0062; +0061 0315 0300 05AE 16B35 0062;00E0 05AE 16B35 0315 0062;0061 05AE 0300 16B35 0315 0062;00E0 05AE 16B35 0315 0062;0061 05AE 0300 16B35 0315 0062; +0061 16B35 0315 0300 05AE 0062;0061 05AE 16B35 0300 0315 0062;0061 05AE 16B35 0300 0315 0062;0061 05AE 16B35 0300 0315 0062;0061 05AE 16B35 0300 0315 0062; +0061 0315 0300 05AE 16B36 0062;00E0 05AE 16B36 0315 0062;0061 05AE 0300 16B36 0315 0062;00E0 05AE 16B36 0315 0062;0061 05AE 0300 16B36 0315 0062; +0061 16B36 0315 0300 05AE 0062;0061 05AE 16B36 0300 0315 0062;0061 05AE 16B36 0300 0315 0062;0061 05AE 16B36 0300 0315 0062;0061 05AE 16B36 0300 0315 0062; +0061 093C 0334 1BC9E 0062;0061 0334 1BC9E 093C 0062;0061 0334 1BC9E 093C 0062;0061 0334 1BC9E 093C 0062;0061 0334 1BC9E 093C 0062; +0061 1BC9E 093C 0334 0062;0061 1BC9E 0334 093C 0062;0061 1BC9E 0334 093C 0062;0061 1BC9E 0334 093C 0062;0061 1BC9E 0334 093C 0062; +0061 302A 031B 1DCE 1D165 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062; +0061 1D165 302A 031B 1DCE 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062; +0061 302A 031B 1DCE 1D166 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062; +0061 1D166 302A 031B 1DCE 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062; +0061 093C 0334 1D167 0062;0061 0334 1D167 093C 0062;0061 0334 1D167 093C 0062;0061 0334 1D167 093C 0062;0061 0334 1D167 093C 0062; +0061 1D167 093C 0334 0062;0061 1D167 0334 093C 0062;0061 1D167 0334 093C 0062;0061 1D167 0334 093C 0062;0061 1D167 0334 093C 0062; +0061 093C 0334 1D168 0062;0061 0334 1D168 093C 0062;0061 0334 1D168 093C 0062;0061 0334 1D168 093C 0062;0061 0334 1D168 093C 0062; +0061 1D168 093C 0334 0062;0061 1D168 0334 093C 0062;0061 1D168 0334 093C 0062;0061 1D168 0334 093C 0062;0061 1D168 0334 093C 0062; +0061 093C 0334 1D169 0062;0061 0334 1D169 093C 0062;0061 0334 1D169 093C 0062;0061 0334 1D169 093C 0062;0061 0334 1D169 093C 0062; +0061 1D169 093C 0334 0062;0061 1D169 0334 093C 0062;0061 1D169 0334 093C 0062;0061 1D169 0334 093C 0062;0061 1D169 0334 093C 0062; +0061 05AE 1D16D 302E 1D16D 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062; +0061 1D16D 05AE 1D16D 302E 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062; +0061 302A 031B 1DCE 1D16E 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062; +0061 1D16E 302A 031B 1DCE 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062; +0061 302A 031B 1DCE 1D16F 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062; +0061 1D16F 302A 031B 1DCE 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062; +0061 302A 031B 1DCE 1D170 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062; +0061 1D170 302A 031B 1DCE 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062; +0061 302A 031B 1DCE 1D171 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062; +0061 1D171 302A 031B 1DCE 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062; +0061 302A 031B 1DCE 1D172 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062; +0061 1D172 302A 031B 1DCE 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062; +0061 059A 0316 302A 1D17B 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062; +0061 1D17B 059A 0316 302A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062; +0061 059A 0316 302A 1D17C 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062; +0061 1D17C 059A 0316 302A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062; +0061 059A 0316 302A 1D17D 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062; +0061 1D17D 059A 0316 302A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062; +0061 059A 0316 302A 1D17E 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062; +0061 1D17E 059A 0316 302A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062; +0061 059A 0316 302A 1D17F 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062; +0061 1D17F 059A 0316 302A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062; +0061 059A 0316 302A 1D180 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062; +0061 1D180 059A 0316 302A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062; +0061 059A 0316 302A 1D181 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062; +0061 1D181 059A 0316 302A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062; +0061 059A 0316 302A 1D182 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062; +0061 1D182 059A 0316 302A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062; +0061 0315 0300 05AE 1D185 0062;00E0 05AE 1D185 0315 0062;0061 05AE 0300 1D185 0315 0062;00E0 05AE 1D185 0315 0062;0061 05AE 0300 1D185 0315 0062; +0061 1D185 0315 0300 05AE 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062; +0061 0315 0300 05AE 1D186 0062;00E0 05AE 1D186 0315 0062;0061 05AE 0300 1D186 0315 0062;00E0 05AE 1D186 0315 0062;0061 05AE 0300 1D186 0315 0062; +0061 1D186 0315 0300 05AE 0062;0061 05AE 1D186 0300 0315 0062;0061 05AE 1D186 0300 0315 0062;0061 05AE 1D186 0300 0315 0062;0061 05AE 1D186 0300 0315 0062; +0061 0315 0300 05AE 1D187 0062;00E0 05AE 1D187 0315 0062;0061 05AE 0300 1D187 0315 0062;00E0 05AE 1D187 0315 0062;0061 05AE 0300 1D187 0315 0062; +0061 1D187 0315 0300 05AE 0062;0061 05AE 1D187 0300 0315 0062;0061 05AE 1D187 0300 0315 0062;0061 05AE 1D187 0300 0315 0062;0061 05AE 1D187 0300 0315 0062; +0061 0315 0300 05AE 1D188 0062;00E0 05AE 1D188 0315 0062;0061 05AE 0300 1D188 0315 0062;00E0 05AE 1D188 0315 0062;0061 05AE 0300 1D188 0315 0062; +0061 1D188 0315 0300 05AE 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062; +0061 0315 0300 05AE 1D189 0062;00E0 05AE 1D189 0315 0062;0061 05AE 0300 1D189 0315 0062;00E0 05AE 1D189 0315 0062;0061 05AE 0300 1D189 0315 0062; +0061 1D189 0315 0300 05AE 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062; +0061 059A 0316 302A 1D18A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062; +0061 1D18A 059A 0316 302A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062; +0061 059A 0316 302A 1D18B 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062; +0061 1D18B 059A 0316 302A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062; +0061 0315 0300 05AE 1D1AA 0062;00E0 05AE 1D1AA 0315 0062;0061 05AE 0300 1D1AA 0315 0062;00E0 05AE 1D1AA 0315 0062;0061 05AE 0300 1D1AA 0315 0062; +0061 1D1AA 0315 0300 05AE 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062; +0061 0315 0300 05AE 1D1AB 0062;00E0 05AE 1D1AB 0315 0062;0061 05AE 0300 1D1AB 0315 0062;00E0 05AE 1D1AB 0315 0062;0061 05AE 0300 1D1AB 0315 0062; +0061 1D1AB 0315 0300 05AE 0062;0061 05AE 1D1AB 0300 0315 0062;0061 05AE 1D1AB 0300 0315 0062;0061 05AE 1D1AB 0300 0315 0062;0061 05AE 1D1AB 0300 0315 0062; +0061 0315 0300 05AE 1D1AC 0062;00E0 05AE 1D1AC 0315 0062;0061 05AE 0300 1D1AC 0315 0062;00E0 05AE 1D1AC 0315 0062;0061 05AE 0300 1D1AC 0315 0062; +0061 1D1AC 0315 0300 05AE 0062;0061 05AE 1D1AC 0300 0315 0062;0061 05AE 1D1AC 0300 0315 0062;0061 05AE 1D1AC 0300 0315 0062;0061 05AE 1D1AC 0300 0315 0062; +0061 0315 0300 05AE 1D1AD 0062;00E0 05AE 1D1AD 0315 0062;0061 05AE 0300 1D1AD 0315 0062;00E0 05AE 1D1AD 0315 0062;0061 05AE 0300 1D1AD 0315 0062; +0061 1D1AD 0315 0300 05AE 0062;0061 05AE 1D1AD 0300 0315 0062;0061 05AE 1D1AD 0300 0315 0062;0061 05AE 1D1AD 0300 0315 0062;0061 05AE 1D1AD 0300 0315 0062; +0061 0315 0300 05AE 1D242 0062;00E0 05AE 1D242 0315 0062;0061 05AE 0300 1D242 0315 0062;00E0 05AE 1D242 0315 0062;0061 05AE 0300 1D242 0315 0062; +0061 1D242 0315 0300 05AE 0062;0061 05AE 1D242 0300 0315 0062;0061 05AE 1D242 0300 0315 0062;0061 05AE 1D242 0300 0315 0062;0061 05AE 1D242 0300 0315 0062; +0061 0315 0300 05AE 1D243 0062;00E0 05AE 1D243 0315 0062;0061 05AE 0300 1D243 0315 0062;00E0 05AE 1D243 0315 0062;0061 05AE 0300 1D243 0315 0062; +0061 1D243 0315 0300 05AE 0062;0061 05AE 1D243 0300 0315 0062;0061 05AE 1D243 0300 0315 0062;0061 05AE 1D243 0300 0315 0062;0061 05AE 1D243 0300 0315 0062; +0061 0315 0300 05AE 1D244 0062;00E0 05AE 1D244 0315 0062;0061 05AE 0300 1D244 0315 0062;00E0 05AE 1D244 0315 0062;0061 05AE 0300 1D244 0315 0062; +0061 1D244 0315 0300 05AE 0062;0061 05AE 1D244 0300 0315 0062;0061 05AE 1D244 0300 0315 0062;0061 05AE 1D244 0300 0315 0062;0061 05AE 1D244 0300 0315 0062; +0061 0315 0300 05AE 1E000 0062;00E0 05AE 1E000 0315 0062;0061 05AE 0300 1E000 0315 0062;00E0 05AE 1E000 0315 0062;0061 05AE 0300 1E000 0315 0062; +0061 1E000 0315 0300 05AE 0062;0061 05AE 1E000 0300 0315 0062;0061 05AE 1E000 0300 0315 0062;0061 05AE 1E000 0300 0315 0062;0061 05AE 1E000 0300 0315 0062; +0061 0315 0300 05AE 1E001 0062;00E0 05AE 1E001 0315 0062;0061 05AE 0300 1E001 0315 0062;00E0 05AE 1E001 0315 0062;0061 05AE 0300 1E001 0315 0062; +0061 1E001 0315 0300 05AE 0062;0061 05AE 1E001 0300 0315 0062;0061 05AE 1E001 0300 0315 0062;0061 05AE 1E001 0300 0315 0062;0061 05AE 1E001 0300 0315 0062; +0061 0315 0300 05AE 1E002 0062;00E0 05AE 1E002 0315 0062;0061 05AE 0300 1E002 0315 0062;00E0 05AE 1E002 0315 0062;0061 05AE 0300 1E002 0315 0062; +0061 1E002 0315 0300 05AE 0062;0061 05AE 1E002 0300 0315 0062;0061 05AE 1E002 0300 0315 0062;0061 05AE 1E002 0300 0315 0062;0061 05AE 1E002 0300 0315 0062; +0061 0315 0300 05AE 1E003 0062;00E0 05AE 1E003 0315 0062;0061 05AE 0300 1E003 0315 0062;00E0 05AE 1E003 0315 0062;0061 05AE 0300 1E003 0315 0062; +0061 1E003 0315 0300 05AE 0062;0061 05AE 1E003 0300 0315 0062;0061 05AE 1E003 0300 0315 0062;0061 05AE 1E003 0300 0315 0062;0061 05AE 1E003 0300 0315 0062; +0061 0315 0300 05AE 1E004 0062;00E0 05AE 1E004 0315 0062;0061 05AE 0300 1E004 0315 0062;00E0 05AE 1E004 0315 0062;0061 05AE 0300 1E004 0315 0062; +0061 1E004 0315 0300 05AE 0062;0061 05AE 1E004 0300 0315 0062;0061 05AE 1E004 0300 0315 0062;0061 05AE 1E004 0300 0315 0062;0061 05AE 1E004 0300 0315 0062; +0061 0315 0300 05AE 1E005 0062;00E0 05AE 1E005 0315 0062;0061 05AE 0300 1E005 0315 0062;00E0 05AE 1E005 0315 0062;0061 05AE 0300 1E005 0315 0062; +0061 1E005 0315 0300 05AE 0062;0061 05AE 1E005 0300 0315 0062;0061 05AE 1E005 0300 0315 0062;0061 05AE 1E005 0300 0315 0062;0061 05AE 1E005 0300 0315 0062; +0061 0315 0300 05AE 1E006 0062;00E0 05AE 1E006 0315 0062;0061 05AE 0300 1E006 0315 0062;00E0 05AE 1E006 0315 0062;0061 05AE 0300 1E006 0315 0062; +0061 1E006 0315 0300 05AE 0062;0061 05AE 1E006 0300 0315 0062;0061 05AE 1E006 0300 0315 0062;0061 05AE 1E006 0300 0315 0062;0061 05AE 1E006 0300 0315 0062; +0061 0315 0300 05AE 1E008 0062;00E0 05AE 1E008 0315 0062;0061 05AE 0300 1E008 0315 0062;00E0 05AE 1E008 0315 0062;0061 05AE 0300 1E008 0315 0062; +0061 1E008 0315 0300 05AE 0062;0061 05AE 1E008 0300 0315 0062;0061 05AE 1E008 0300 0315 0062;0061 05AE 1E008 0300 0315 0062;0061 05AE 1E008 0300 0315 0062; +0061 0315 0300 05AE 1E009 0062;00E0 05AE 1E009 0315 0062;0061 05AE 0300 1E009 0315 0062;00E0 05AE 1E009 0315 0062;0061 05AE 0300 1E009 0315 0062; +0061 1E009 0315 0300 05AE 0062;0061 05AE 1E009 0300 0315 0062;0061 05AE 1E009 0300 0315 0062;0061 05AE 1E009 0300 0315 0062;0061 05AE 1E009 0300 0315 0062; +0061 0315 0300 05AE 1E00A 0062;00E0 05AE 1E00A 0315 0062;0061 05AE 0300 1E00A 0315 0062;00E0 05AE 1E00A 0315 0062;0061 05AE 0300 1E00A 0315 0062; +0061 1E00A 0315 0300 05AE 0062;0061 05AE 1E00A 0300 0315 0062;0061 05AE 1E00A 0300 0315 0062;0061 05AE 1E00A 0300 0315 0062;0061 05AE 1E00A 0300 0315 0062; +0061 0315 0300 05AE 1E00B 0062;00E0 05AE 1E00B 0315 0062;0061 05AE 0300 1E00B 0315 0062;00E0 05AE 1E00B 0315 0062;0061 05AE 0300 1E00B 0315 0062; +0061 1E00B 0315 0300 05AE 0062;0061 05AE 1E00B 0300 0315 0062;0061 05AE 1E00B 0300 0315 0062;0061 05AE 1E00B 0300 0315 0062;0061 05AE 1E00B 0300 0315 0062; +0061 0315 0300 05AE 1E00C 0062;00E0 05AE 1E00C 0315 0062;0061 05AE 0300 1E00C 0315 0062;00E0 05AE 1E00C 0315 0062;0061 05AE 0300 1E00C 0315 0062; +0061 1E00C 0315 0300 05AE 0062;0061 05AE 1E00C 0300 0315 0062;0061 05AE 1E00C 0300 0315 0062;0061 05AE 1E00C 0300 0315 0062;0061 05AE 1E00C 0300 0315 0062; +0061 0315 0300 05AE 1E00D 0062;00E0 05AE 1E00D 0315 0062;0061 05AE 0300 1E00D 0315 0062;00E0 05AE 1E00D 0315 0062;0061 05AE 0300 1E00D 0315 0062; +0061 1E00D 0315 0300 05AE 0062;0061 05AE 1E00D 0300 0315 0062;0061 05AE 1E00D 0300 0315 0062;0061 05AE 1E00D 0300 0315 0062;0061 05AE 1E00D 0300 0315 0062; +0061 0315 0300 05AE 1E00E 0062;00E0 05AE 1E00E 0315 0062;0061 05AE 0300 1E00E 0315 0062;00E0 05AE 1E00E 0315 0062;0061 05AE 0300 1E00E 0315 0062; +0061 1E00E 0315 0300 05AE 0062;0061 05AE 1E00E 0300 0315 0062;0061 05AE 1E00E 0300 0315 0062;0061 05AE 1E00E 0300 0315 0062;0061 05AE 1E00E 0300 0315 0062; +0061 0315 0300 05AE 1E00F 0062;00E0 05AE 1E00F 0315 0062;0061 05AE 0300 1E00F 0315 0062;00E0 05AE 1E00F 0315 0062;0061 05AE 0300 1E00F 0315 0062; +0061 1E00F 0315 0300 05AE 0062;0061 05AE 1E00F 0300 0315 0062;0061 05AE 1E00F 0300 0315 0062;0061 05AE 1E00F 0300 0315 0062;0061 05AE 1E00F 0300 0315 0062; +0061 0315 0300 05AE 1E010 0062;00E0 05AE 1E010 0315 0062;0061 05AE 0300 1E010 0315 0062;00E0 05AE 1E010 0315 0062;0061 05AE 0300 1E010 0315 0062; +0061 1E010 0315 0300 05AE 0062;0061 05AE 1E010 0300 0315 0062;0061 05AE 1E010 0300 0315 0062;0061 05AE 1E010 0300 0315 0062;0061 05AE 1E010 0300 0315 0062; +0061 0315 0300 05AE 1E011 0062;00E0 05AE 1E011 0315 0062;0061 05AE 0300 1E011 0315 0062;00E0 05AE 1E011 0315 0062;0061 05AE 0300 1E011 0315 0062; +0061 1E011 0315 0300 05AE 0062;0061 05AE 1E011 0300 0315 0062;0061 05AE 1E011 0300 0315 0062;0061 05AE 1E011 0300 0315 0062;0061 05AE 1E011 0300 0315 0062; +0061 0315 0300 05AE 1E012 0062;00E0 05AE 1E012 0315 0062;0061 05AE 0300 1E012 0315 0062;00E0 05AE 1E012 0315 0062;0061 05AE 0300 1E012 0315 0062; +0061 1E012 0315 0300 05AE 0062;0061 05AE 1E012 0300 0315 0062;0061 05AE 1E012 0300 0315 0062;0061 05AE 1E012 0300 0315 0062;0061 05AE 1E012 0300 0315 0062; +0061 0315 0300 05AE 1E013 0062;00E0 05AE 1E013 0315 0062;0061 05AE 0300 1E013 0315 0062;00E0 05AE 1E013 0315 0062;0061 05AE 0300 1E013 0315 0062; +0061 1E013 0315 0300 05AE 0062;0061 05AE 1E013 0300 0315 0062;0061 05AE 1E013 0300 0315 0062;0061 05AE 1E013 0300 0315 0062;0061 05AE 1E013 0300 0315 0062; +0061 0315 0300 05AE 1E014 0062;00E0 05AE 1E014 0315 0062;0061 05AE 0300 1E014 0315 0062;00E0 05AE 1E014 0315 0062;0061 05AE 0300 1E014 0315 0062; +0061 1E014 0315 0300 05AE 0062;0061 05AE 1E014 0300 0315 0062;0061 05AE 1E014 0300 0315 0062;0061 05AE 1E014 0300 0315 0062;0061 05AE 1E014 0300 0315 0062; +0061 0315 0300 05AE 1E015 0062;00E0 05AE 1E015 0315 0062;0061 05AE 0300 1E015 0315 0062;00E0 05AE 1E015 0315 0062;0061 05AE 0300 1E015 0315 0062; +0061 1E015 0315 0300 05AE 0062;0061 05AE 1E015 0300 0315 0062;0061 05AE 1E015 0300 0315 0062;0061 05AE 1E015 0300 0315 0062;0061 05AE 1E015 0300 0315 0062; +0061 0315 0300 05AE 1E016 0062;00E0 05AE 1E016 0315 0062;0061 05AE 0300 1E016 0315 0062;00E0 05AE 1E016 0315 0062;0061 05AE 0300 1E016 0315 0062; +0061 1E016 0315 0300 05AE 0062;0061 05AE 1E016 0300 0315 0062;0061 05AE 1E016 0300 0315 0062;0061 05AE 1E016 0300 0315 0062;0061 05AE 1E016 0300 0315 0062; +0061 0315 0300 05AE 1E017 0062;00E0 05AE 1E017 0315 0062;0061 05AE 0300 1E017 0315 0062;00E0 05AE 1E017 0315 0062;0061 05AE 0300 1E017 0315 0062; +0061 1E017 0315 0300 05AE 0062;0061 05AE 1E017 0300 0315 0062;0061 05AE 1E017 0300 0315 0062;0061 05AE 1E017 0300 0315 0062;0061 05AE 1E017 0300 0315 0062; +0061 0315 0300 05AE 1E018 0062;00E0 05AE 1E018 0315 0062;0061 05AE 0300 1E018 0315 0062;00E0 05AE 1E018 0315 0062;0061 05AE 0300 1E018 0315 0062; +0061 1E018 0315 0300 05AE 0062;0061 05AE 1E018 0300 0315 0062;0061 05AE 1E018 0300 0315 0062;0061 05AE 1E018 0300 0315 0062;0061 05AE 1E018 0300 0315 0062; +0061 0315 0300 05AE 1E01B 0062;00E0 05AE 1E01B 0315 0062;0061 05AE 0300 1E01B 0315 0062;00E0 05AE 1E01B 0315 0062;0061 05AE 0300 1E01B 0315 0062; +0061 1E01B 0315 0300 05AE 0062;0061 05AE 1E01B 0300 0315 0062;0061 05AE 1E01B 0300 0315 0062;0061 05AE 1E01B 0300 0315 0062;0061 05AE 1E01B 0300 0315 0062; +0061 0315 0300 05AE 1E01C 0062;00E0 05AE 1E01C 0315 0062;0061 05AE 0300 1E01C 0315 0062;00E0 05AE 1E01C 0315 0062;0061 05AE 0300 1E01C 0315 0062; +0061 1E01C 0315 0300 05AE 0062;0061 05AE 1E01C 0300 0315 0062;0061 05AE 1E01C 0300 0315 0062;0061 05AE 1E01C 0300 0315 0062;0061 05AE 1E01C 0300 0315 0062; +0061 0315 0300 05AE 1E01D 0062;00E0 05AE 1E01D 0315 0062;0061 05AE 0300 1E01D 0315 0062;00E0 05AE 1E01D 0315 0062;0061 05AE 0300 1E01D 0315 0062; +0061 1E01D 0315 0300 05AE 0062;0061 05AE 1E01D 0300 0315 0062;0061 05AE 1E01D 0300 0315 0062;0061 05AE 1E01D 0300 0315 0062;0061 05AE 1E01D 0300 0315 0062; +0061 0315 0300 05AE 1E01E 0062;00E0 05AE 1E01E 0315 0062;0061 05AE 0300 1E01E 0315 0062;00E0 05AE 1E01E 0315 0062;0061 05AE 0300 1E01E 0315 0062; +0061 1E01E 0315 0300 05AE 0062;0061 05AE 1E01E 0300 0315 0062;0061 05AE 1E01E 0300 0315 0062;0061 05AE 1E01E 0300 0315 0062;0061 05AE 1E01E 0300 0315 0062; +0061 0315 0300 05AE 1E01F 0062;00E0 05AE 1E01F 0315 0062;0061 05AE 0300 1E01F 0315 0062;00E0 05AE 1E01F 0315 0062;0061 05AE 0300 1E01F 0315 0062; +0061 1E01F 0315 0300 05AE 0062;0061 05AE 1E01F 0300 0315 0062;0061 05AE 1E01F 0300 0315 0062;0061 05AE 1E01F 0300 0315 0062;0061 05AE 1E01F 0300 0315 0062; +0061 0315 0300 05AE 1E020 0062;00E0 05AE 1E020 0315 0062;0061 05AE 0300 1E020 0315 0062;00E0 05AE 1E020 0315 0062;0061 05AE 0300 1E020 0315 0062; +0061 1E020 0315 0300 05AE 0062;0061 05AE 1E020 0300 0315 0062;0061 05AE 1E020 0300 0315 0062;0061 05AE 1E020 0300 0315 0062;0061 05AE 1E020 0300 0315 0062; +0061 0315 0300 05AE 1E021 0062;00E0 05AE 1E021 0315 0062;0061 05AE 0300 1E021 0315 0062;00E0 05AE 1E021 0315 0062;0061 05AE 0300 1E021 0315 0062; +0061 1E021 0315 0300 05AE 0062;0061 05AE 1E021 0300 0315 0062;0061 05AE 1E021 0300 0315 0062;0061 05AE 1E021 0300 0315 0062;0061 05AE 1E021 0300 0315 0062; +0061 0315 0300 05AE 1E023 0062;00E0 05AE 1E023 0315 0062;0061 05AE 0300 1E023 0315 0062;00E0 05AE 1E023 0315 0062;0061 05AE 0300 1E023 0315 0062; +0061 1E023 0315 0300 05AE 0062;0061 05AE 1E023 0300 0315 0062;0061 05AE 1E023 0300 0315 0062;0061 05AE 1E023 0300 0315 0062;0061 05AE 1E023 0300 0315 0062; +0061 0315 0300 05AE 1E024 0062;00E0 05AE 1E024 0315 0062;0061 05AE 0300 1E024 0315 0062;00E0 05AE 1E024 0315 0062;0061 05AE 0300 1E024 0315 0062; +0061 1E024 0315 0300 05AE 0062;0061 05AE 1E024 0300 0315 0062;0061 05AE 1E024 0300 0315 0062;0061 05AE 1E024 0300 0315 0062;0061 05AE 1E024 0300 0315 0062; +0061 0315 0300 05AE 1E026 0062;00E0 05AE 1E026 0315 0062;0061 05AE 0300 1E026 0315 0062;00E0 05AE 1E026 0315 0062;0061 05AE 0300 1E026 0315 0062; +0061 1E026 0315 0300 05AE 0062;0061 05AE 1E026 0300 0315 0062;0061 05AE 1E026 0300 0315 0062;0061 05AE 1E026 0300 0315 0062;0061 05AE 1E026 0300 0315 0062; +0061 0315 0300 05AE 1E027 0062;00E0 05AE 1E027 0315 0062;0061 05AE 0300 1E027 0315 0062;00E0 05AE 1E027 0315 0062;0061 05AE 0300 1E027 0315 0062; +0061 1E027 0315 0300 05AE 0062;0061 05AE 1E027 0300 0315 0062;0061 05AE 1E027 0300 0315 0062;0061 05AE 1E027 0300 0315 0062;0061 05AE 1E027 0300 0315 0062; +0061 0315 0300 05AE 1E028 0062;00E0 05AE 1E028 0315 0062;0061 05AE 0300 1E028 0315 0062;00E0 05AE 1E028 0315 0062;0061 05AE 0300 1E028 0315 0062; +0061 1E028 0315 0300 05AE 0062;0061 05AE 1E028 0300 0315 0062;0061 05AE 1E028 0300 0315 0062;0061 05AE 1E028 0300 0315 0062;0061 05AE 1E028 0300 0315 0062; +0061 0315 0300 05AE 1E029 0062;00E0 05AE 1E029 0315 0062;0061 05AE 0300 1E029 0315 0062;00E0 05AE 1E029 0315 0062;0061 05AE 0300 1E029 0315 0062; +0061 1E029 0315 0300 05AE 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062; +0061 0315 0300 05AE 1E02A 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062; +0061 1E02A 0315 0300 05AE 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062; +0061 059A 0316 302A 1E8D0 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062; +0061 1E8D0 059A 0316 302A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062; +0061 059A 0316 302A 1E8D1 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062; +0061 1E8D1 059A 0316 302A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062; +0061 059A 0316 302A 1E8D2 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062; +0061 1E8D2 059A 0316 302A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062; +0061 059A 0316 302A 1E8D3 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062; +0061 1E8D3 059A 0316 302A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062; +0061 059A 0316 302A 1E8D4 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062; +0061 1E8D4 059A 0316 302A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062; +0061 059A 0316 302A 1E8D5 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062; +0061 1E8D5 059A 0316 302A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062; +0061 059A 0316 302A 1E8D6 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062; +0061 1E8D6 059A 0316 302A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062; +0061 0315 0300 05AE 1E944 0062;00E0 05AE 1E944 0315 0062;0061 05AE 0300 1E944 0315 0062;00E0 05AE 1E944 0315 0062;0061 05AE 0300 1E944 0315 0062; +0061 1E944 0315 0300 05AE 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062; +0061 0315 0300 05AE 1E945 0062;00E0 05AE 1E945 0315 0062;0061 05AE 0300 1E945 0315 0062;00E0 05AE 1E945 0315 0062;0061 05AE 0300 1E945 0315 0062; +0061 1E945 0315 0300 05AE 0062;0061 05AE 1E945 0300 0315 0062;0061 05AE 1E945 0300 0315 0062;0061 05AE 1E945 0300 0315 0062;0061 05AE 1E945 0300 0315 0062; +0061 0315 0300 05AE 1E946 0062;00E0 05AE 1E946 0315 0062;0061 05AE 0300 1E946 0315 0062;00E0 05AE 1E946 0315 0062;0061 05AE 0300 1E946 0315 0062; +0061 1E946 0315 0300 05AE 0062;0061 05AE 1E946 0300 0315 0062;0061 05AE 1E946 0300 0315 0062;0061 05AE 1E946 0300 0315 0062;0061 05AE 1E946 0300 0315 0062; +0061 0315 0300 05AE 1E947 0062;00E0 05AE 1E947 0315 0062;0061 05AE 0300 1E947 0315 0062;00E0 05AE 1E947 0315 0062;0061 05AE 0300 1E947 0315 0062; +0061 1E947 0315 0300 05AE 0062;0061 05AE 1E947 0300 0315 0062;0061 05AE 1E947 0300 0315 0062;0061 05AE 1E947 0300 0315 0062;0061 05AE 1E947 0300 0315 0062; +0061 0315 0300 05AE 1E948 0062;00E0 05AE 1E948 0315 0062;0061 05AE 0300 1E948 0315 0062;00E0 05AE 1E948 0315 0062;0061 05AE 0300 1E948 0315 0062; +0061 1E948 0315 0300 05AE 0062;0061 05AE 1E948 0300 0315 0062;0061 05AE 1E948 0300 0315 0062;0061 05AE 1E948 0300 0315 0062;0061 05AE 1E948 0300 0315 0062; +0061 0315 0300 05AE 1E949 0062;00E0 05AE 1E949 0315 0062;0061 05AE 0300 1E949 0315 0062;00E0 05AE 1E949 0315 0062;0061 05AE 0300 1E949 0315 0062; +0061 1E949 0315 0300 05AE 0062;0061 05AE 1E949 0300 0315 0062;0061 05AE 1E949 0300 0315 0062;0061 05AE 1E949 0300 0315 0062;0061 05AE 1E949 0300 0315 0062; +0061 3099 093C 0334 1E94A 0062;0061 0334 093C 1E94A 3099 0062;0061 0334 093C 1E94A 3099 0062;0061 0334 093C 1E94A 3099 0062;0061 0334 093C 1E94A 3099 0062; +0061 1E94A 3099 093C 0334 0062;0061 0334 1E94A 093C 3099 0062;0061 0334 1E94A 093C 3099 0062;0061 0334 1E94A 093C 3099 0062;0061 0334 1E94A 093C 3099 0062; +# +@Part3 # PRI #29 Test +# +09C7 0334 09BE;09C7 0334 09BE;09C7 0334 09BE;09C7 0334 09BE;09C7 0334 09BE; +09C7 0334 09D7;09C7 0334 09D7;09C7 0334 09D7;09C7 0334 09D7;09C7 0334 09D7; +0B47 0334 0B3E;0B47 0334 0B3E;0B47 0334 0B3E;0B47 0334 0B3E;0B47 0334 0B3E; +0B47 0334 0B56;0B47 0334 0B56;0B47 0334 0B56;0B47 0334 0B56;0B47 0334 0B56; +0B47 0334 0B57;0B47 0334 0B57;0B47 0334 0B57;0B47 0334 0B57;0B47 0334 0B57; +0B92 0334 0BD7;0B92 0334 0BD7;0B92 0334 0BD7;0B92 0334 0BD7;0B92 0334 0BD7; +0BC6 0334 0BBE;0BC6 0334 0BBE;0BC6 0334 0BBE;0BC6 0334 0BBE;0BC6 0334 0BBE; +0BC6 0334 0BD7;0BC6 0334 0BD7;0BC6 0334 0BD7;0BC6 0334 0BD7;0BC6 0334 0BD7; +0BC7 0334 0BBE;0BC7 0334 0BBE;0BC7 0334 0BBE;0BC7 0334 0BBE;0BC7 0334 0BBE; +0CBF 0334 0CD5;0CBF 0334 0CD5;0CBF 0334 0CD5;0CBF 0334 0CD5;0CBF 0334 0CD5; +0CC6 0334 0CC2;0CC6 0334 0CC2;0CC6 0334 0CC2;0CC6 0334 0CC2;0CC6 0334 0CC2; +0CC6 0334 0CD5;0CC6 0334 0CD5;0CC6 0334 0CD5;0CC6 0334 0CD5;0CC6 0334 0CD5; +0CC6 0334 0CD6;0CC6 0334 0CD6;0CC6 0334 0CD6;0CC6 0334 0CD6;0CC6 0334 0CD6; +0CCA 0334 0CD5;0CCA 0334 0CD5;0CC6 0CC2 0334 0CD5;0CCA 0334 0CD5;0CC6 0CC2 0334 0CD5; +0D46 0334 0D3E;0D46 0334 0D3E;0D46 0334 0D3E;0D46 0334 0D3E;0D46 0334 0D3E; +0D46 0334 0D57;0D46 0334 0D57;0D46 0334 0D57;0D46 0334 0D57;0D46 0334 0D57; +0D47 0334 0D3E;0D47 0334 0D3E;0D47 0334 0D3E;0D47 0334 0D3E;0D47 0334 0D3E; +0DD9 0334 0DCF;0DD9 0334 0DCF;0DD9 0334 0DCF;0DD9 0334 0DCF;0DD9 0334 0DCF; +0DD9 0334 0DDF;0DD9 0334 0DDF;0DD9 0334 0DDF;0DD9 0334 0DDF;0DD9 0334 0DDF; +0F40 0334 0FB5;0F40 0334 0FB5;0F40 0334 0FB5;0F40 0334 0FB5;0F40 0334 0FB5; +0F42 0334 0FB7;0F42 0334 0FB7;0F42 0334 0FB7;0F42 0334 0FB7;0F42 0334 0FB7; +0F4C 0334 0FB7;0F4C 0334 0FB7;0F4C 0334 0FB7;0F4C 0334 0FB7;0F4C 0334 0FB7; +0F51 0334 0FB7;0F51 0334 0FB7;0F51 0334 0FB7;0F51 0334 0FB7;0F51 0334 0FB7; +0F56 0334 0FB7;0F56 0334 0FB7;0F56 0334 0FB7;0F56 0334 0FB7;0F56 0334 0FB7; +0F5B 0334 0FB7;0F5B 0334 0FB7;0F5B 0334 0FB7;0F5B 0334 0FB7;0F5B 0334 0FB7; +0F90 0334 0FB5;0F90 0334 0FB5;0F90 0334 0FB5;0F90 0334 0FB5;0F90 0334 0FB5; +0F92 0334 0FB7;0F92 0334 0FB7;0F92 0334 0FB7;0F92 0334 0FB7;0F92 0334 0FB7; +0F9C 0334 0FB7;0F9C 0334 0FB7;0F9C 0334 0FB7;0F9C 0334 0FB7;0F9C 0334 0FB7; +0FA1 0334 0FB7;0FA1 0334 0FB7;0FA1 0334 0FB7;0FA1 0334 0FB7;0FA1 0334 0FB7; +0FA6 0334 0FB7;0FA6 0334 0FB7;0FA6 0334 0FB7;0FA6 0334 0FB7;0FA6 0334 0FB7; +0FAB 0334 0FB7;0FAB 0334 0FB7;0FAB 0334 0FB7;0FAB 0334 0FB7;0FAB 0334 0FB7; +1025 0334 102E;1025 0334 102E;1025 0334 102E;1025 0334 102E;1025 0334 102E; +1100 0334 1161;1100 0334 1161;1100 0334 1161;1100 0334 1161;1100 0334 1161; +1100 0334 116E;1100 0334 116E;1100 0334 116E;1100 0334 116E;1100 0334 116E; +1101 0334 1166;1101 0334 1166;1101 0334 1166;1101 0334 1166;1101 0334 1166; +1101 0334 1173;1101 0334 1173;1101 0334 1173;1101 0334 1173;1101 0334 1173; +1102 0334 116B;1102 0334 116B;1102 0334 116B;1102 0334 116B;1102 0334 116B; +1103 0334 1163;1103 0334 1163;1103 0334 1163;1103 0334 1163;1103 0334 1163; +1103 0334 1170;1103 0334 1170;1103 0334 1170;1103 0334 1170;1103 0334 1170; +1104 0334 1168;1104 0334 1168;1104 0334 1168;1104 0334 1168;1104 0334 1168; +1104 0334 1175;1104 0334 1175;1104 0334 1175;1104 0334 1175;1104 0334 1175; +1105 0334 116D;1105 0334 116D;1105 0334 116D;1105 0334 116D;1105 0334 116D; +1106 0334 1165;1106 0334 1165;1106 0334 1165;1106 0334 1165;1106 0334 1165; +1106 0334 1172;1106 0334 1172;1106 0334 1172;1106 0334 1172;1106 0334 1172; +1107 0334 116A;1107 0334 116A;1107 0334 116A;1107 0334 116A;1107 0334 116A; +1108 0334 1162;1108 0334 1162;1108 0334 1162;1108 0334 1162;1108 0334 1162; +1108 0334 116F;1108 0334 116F;1108 0334 116F;1108 0334 116F;1108 0334 116F; +1109 0334 1167;1109 0334 1167;1109 0334 1167;1109 0334 1167;1109 0334 1167; +1109 0334 1174;1109 0334 1174;1109 0334 1174;1109 0334 1174;1109 0334 1174; +110A 0334 116C;110A 0334 116C;110A 0334 116C;110A 0334 116C;110A 0334 116C; +110B 0334 1164;110B 0334 1164;110B 0334 1164;110B 0334 1164;110B 0334 1164; +110B 0334 1171;110B 0334 1171;110B 0334 1171;110B 0334 1171;110B 0334 1171; +110C 0334 1169;110C 0334 1169;110C 0334 1169;110C 0334 1169;110C 0334 1169; +110D 0334 1161;110D 0334 1161;110D 0334 1161;110D 0334 1161;110D 0334 1161; +110D 0334 116E;110D 0334 116E;110D 0334 116E;110D 0334 116E;110D 0334 116E; +110E 0334 1166;110E 0334 1166;110E 0334 1166;110E 0334 1166;110E 0334 1166; +110E 0334 1173;110E 0334 1173;110E 0334 1173;110E 0334 1173;110E 0334 1173; +110F 0334 116B;110F 0334 116B;110F 0334 116B;110F 0334 116B;110F 0334 116B; +1110 0334 1163;1110 0334 1163;1110 0334 1163;1110 0334 1163;1110 0334 1163; +1110 0334 1170;1110 0334 1170;1110 0334 1170;1110 0334 1170;1110 0334 1170; +1111 0334 1168;1111 0334 1168;1111 0334 1168;1111 0334 1168;1111 0334 1168; +1111 0334 1175;1111 0334 1175;1111 0334 1175;1111 0334 1175;1111 0334 1175; +1112 0334 116D;1112 0334 116D;1112 0334 116D;1112 0334 116D;1112 0334 116D; +1B05 0334 1B35;1B05 0334 1B35;1B05 0334 1B35;1B05 0334 1B35;1B05 0334 1B35; +1B07 0334 1B35;1B07 0334 1B35;1B07 0334 1B35;1B07 0334 1B35;1B07 0334 1B35; +1B09 0334 1B35;1B09 0334 1B35;1B09 0334 1B35;1B09 0334 1B35;1B09 0334 1B35; +1B0B 0334 1B35;1B0B 0334 1B35;1B0B 0334 1B35;1B0B 0334 1B35;1B0B 0334 1B35; +1B0D 0334 1B35;1B0D 0334 1B35;1B0D 0334 1B35;1B0D 0334 1B35;1B0D 0334 1B35; +1B11 0334 1B35;1B11 0334 1B35;1B11 0334 1B35;1B11 0334 1B35;1B11 0334 1B35; +1B3A 0334 1B35;1B3A 0334 1B35;1B3A 0334 1B35;1B3A 0334 1B35;1B3A 0334 1B35; +1B3C 0334 1B35;1B3C 0334 1B35;1B3C 0334 1B35;1B3C 0334 1B35;1B3C 0334 1B35; +1B3E 0334 1B35;1B3E 0334 1B35;1B3E 0334 1B35;1B3E 0334 1B35;1B3E 0334 1B35; +1B3F 0334 1B35;1B3F 0334 1B35;1B3F 0334 1B35;1B3F 0334 1B35;1B3F 0334 1B35; +1B42 0334 1B35;1B42 0334 1B35;1B42 0334 1B35;1B42 0334 1B35;1B42 0334 1B35; +AC54 0334 11AE;AC54 0334 11AE;1100 1164 0334 11AE;AC54 0334 11AE;1100 1164 0334 11AE; +ACA8 0334 11B5;ACA8 0334 11B5;1100 1167 0334 11B5;ACA8 0334 11B5;1100 1167 0334 11B5; +ACFC 0334 11BC;ACFC 0334 11BC;1100 116A 0334 11BC;ACFC 0334 11BC;1100 116A 0334 11BC; +ADC0 0334 11AE;ADC0 0334 11AE;1100 1171 0334 11AE;ADC0 0334 11AE;1100 1171 0334 11AE; +AE14 0334 11B5;AE14 0334 11B5;1100 1174 0334 11B5;AE14 0334 11B5;1100 1174 0334 11B5; +AE68 0334 11BC;AE68 0334 11BC;1101 1162 0334 11BC;AE68 0334 11BC;1101 1162 0334 11BC; +AF2C 0334 11AE;AF2C 0334 11AE;1101 1169 0334 11AE;AF2C 0334 11AE;1101 1169 0334 11AE; +AF80 0334 11B5;AF80 0334 11B5;1101 116C 0334 11B5;AF80 0334 11B5;1101 116C 0334 11B5; +AFD4 0334 11BC;AFD4 0334 11BC;1101 116F 0334 11BC;AFD4 0334 11BC;1101 116F 0334 11BC; +B098 0334 11AE;B098 0334 11AE;1102 1161 0334 11AE;B098 0334 11AE;1102 1161 0334 11AE; +B0EC 0334 11B5;B0EC 0334 11B5;1102 1164 0334 11B5;B0EC 0334 11B5;1102 1164 0334 11B5; +B140 0334 11BC;B140 0334 11BC;1102 1167 0334 11BC;B140 0334 11BC;1102 1167 0334 11BC; +B204 0334 11AE;B204 0334 11AE;1102 116E 0334 11AE;B204 0334 11AE;1102 116E 0334 11AE; +B258 0334 11B5;B258 0334 11B5;1102 1171 0334 11B5;B258 0334 11B5;1102 1171 0334 11B5; +B2AC 0334 11BC;B2AC 0334 11BC;1102 1174 0334 11BC;B2AC 0334 11BC;1102 1174 0334 11BC; +B370 0334 11AE;B370 0334 11AE;1103 1166 0334 11AE;B370 0334 11AE;1103 1166 0334 11AE; +B3C4 0334 11B5;B3C4 0334 11B5;1103 1169 0334 11B5;B3C4 0334 11B5;1103 1169 0334 11B5; +B418 0334 11BC;B418 0334 11BC;1103 116C 0334 11BC;B418 0334 11BC;1103 116C 0334 11BC; +B4DC 0334 11AE;B4DC 0334 11AE;1103 1173 0334 11AE;B4DC 0334 11AE;1103 1173 0334 11AE; +B530 0334 11B5;B530 0334 11B5;1104 1161 0334 11B5;B530 0334 11B5;1104 1161 0334 11B5; +B584 0334 11BC;B584 0334 11BC;1104 1164 0334 11BC;B584 0334 11BC;1104 1164 0334 11BC; +B648 0334 11AE;B648 0334 11AE;1104 116B 0334 11AE;B648 0334 11AE;1104 116B 0334 11AE; +B69C 0334 11B5;B69C 0334 11B5;1104 116E 0334 11B5;B69C 0334 11B5;1104 116E 0334 11B5; +B6F0 0334 11BC;B6F0 0334 11BC;1104 1171 0334 11BC;B6F0 0334 11BC;1104 1171 0334 11BC; +B7B4 0334 11AE;B7B4 0334 11AE;1105 1163 0334 11AE;B7B4 0334 11AE;1105 1163 0334 11AE; +B808 0334 11B5;B808 0334 11B5;1105 1166 0334 11B5;B808 0334 11B5;1105 1166 0334 11B5; +B85C 0334 11BC;B85C 0334 11BC;1105 1169 0334 11BC;B85C 0334 11BC;1105 1169 0334 11BC; +B920 0334 11AE;B920 0334 11AE;1105 1170 0334 11AE;B920 0334 11AE;1105 1170 0334 11AE; +B974 0334 11B5;B974 0334 11B5;1105 1173 0334 11B5;B974 0334 11B5;1105 1173 0334 11B5; +B9C8 0334 11BC;B9C8 0334 11BC;1106 1161 0334 11BC;B9C8 0334 11BC;1106 1161 0334 11BC; +BA8C 0334 11AE;BA8C 0334 11AE;1106 1168 0334 11AE;BA8C 0334 11AE;1106 1168 0334 11AE; +BAE0 0334 11B5;BAE0 0334 11B5;1106 116B 0334 11B5;BAE0 0334 11B5;1106 116B 0334 11B5; +BB34 0334 11BC;BB34 0334 11BC;1106 116E 0334 11BC;BB34 0334 11BC;1106 116E 0334 11BC; +BBF8 0334 11AE;BBF8 0334 11AE;1106 1175 0334 11AE;BBF8 0334 11AE;1106 1175 0334 11AE; +BC4C 0334 11B5;BC4C 0334 11B5;1107 1163 0334 11B5;BC4C 0334 11B5;1107 1163 0334 11B5; +BCA0 0334 11BC;BCA0 0334 11BC;1107 1166 0334 11BC;BCA0 0334 11BC;1107 1166 0334 11BC; +BD64 0334 11AE;BD64 0334 11AE;1107 116D 0334 11AE;BD64 0334 11AE;1107 116D 0334 11AE; +BDB8 0334 11B5;BDB8 0334 11B5;1107 1170 0334 11B5;BDB8 0334 11B5;1107 1170 0334 11B5; +BE0C 0334 11BC;BE0C 0334 11BC;1107 1173 0334 11BC;BE0C 0334 11BC;1107 1173 0334 11BC; +BED0 0334 11AE;BED0 0334 11AE;1108 1165 0334 11AE;BED0 0334 11AE;1108 1165 0334 11AE; +BF24 0334 11B5;BF24 0334 11B5;1108 1168 0334 11B5;BF24 0334 11B5;1108 1168 0334 11B5; +BF78 0334 11BC;BF78 0334 11BC;1108 116B 0334 11BC;BF78 0334 11BC;1108 116B 0334 11BC; +C03C 0334 11AE;C03C 0334 11AE;1108 1172 0334 11AE;C03C 0334 11AE;1108 1172 0334 11AE; +C090 0334 11B5;C090 0334 11B5;1108 1175 0334 11B5;C090 0334 11B5;1108 1175 0334 11B5; +C0E4 0334 11BC;C0E4 0334 11BC;1109 1163 0334 11BC;C0E4 0334 11BC;1109 1163 0334 11BC; +C1A8 0334 11AE;C1A8 0334 11AE;1109 116A 0334 11AE;C1A8 0334 11AE;1109 116A 0334 11AE; +C1FC 0334 11B5;C1FC 0334 11B5;1109 116D 0334 11B5;C1FC 0334 11B5;1109 116D 0334 11B5; +C250 0334 11BC;C250 0334 11BC;1109 1170 0334 11BC;C250 0334 11BC;1109 1170 0334 11BC; +C314 0334 11AE;C314 0334 11AE;110A 1162 0334 11AE;C314 0334 11AE;110A 1162 0334 11AE; +C368 0334 11B5;C368 0334 11B5;110A 1165 0334 11B5;C368 0334 11B5;110A 1165 0334 11B5; +C3BC 0334 11BC;C3BC 0334 11BC;110A 1168 0334 11BC;C3BC 0334 11BC;110A 1168 0334 11BC; +C480 0334 11AE;C480 0334 11AE;110A 116F 0334 11AE;C480 0334 11AE;110A 116F 0334 11AE; +C4D4 0334 11B5;C4D4 0334 11B5;110A 1172 0334 11B5;C4D4 0334 11B5;110A 1172 0334 11B5; +C528 0334 11BC;C528 0334 11BC;110A 1175 0334 11BC;C528 0334 11BC;110A 1175 0334 11BC; +C5EC 0334 11AE;C5EC 0334 11AE;110B 1167 0334 11AE;C5EC 0334 11AE;110B 1167 0334 11AE; +C640 0334 11B5;C640 0334 11B5;110B 116A 0334 11B5;C640 0334 11B5;110B 116A 0334 11B5; +C694 0334 11BC;C694 0334 11BC;110B 116D 0334 11BC;C694 0334 11BC;110B 116D 0334 11BC; +C758 0334 11AE;C758 0334 11AE;110B 1174 0334 11AE;C758 0334 11AE;110B 1174 0334 11AE; +C7AC 0334 11B5;C7AC 0334 11B5;110C 1162 0334 11B5;C7AC 0334 11B5;110C 1162 0334 11B5; +C800 0334 11BC;C800 0334 11BC;110C 1165 0334 11BC;C800 0334 11BC;110C 1165 0334 11BC; +C8C4 0334 11AE;C8C4 0334 11AE;110C 116C 0334 11AE;C8C4 0334 11AE;110C 116C 0334 11AE; +C918 0334 11B5;C918 0334 11B5;110C 116F 0334 11B5;C918 0334 11B5;110C 116F 0334 11B5; +C96C 0334 11BC;C96C 0334 11BC;110C 1172 0334 11BC;C96C 0334 11BC;110C 1172 0334 11BC; +CA30 0334 11AE;CA30 0334 11AE;110D 1164 0334 11AE;CA30 0334 11AE;110D 1164 0334 11AE; +CA84 0334 11B5;CA84 0334 11B5;110D 1167 0334 11B5;CA84 0334 11B5;110D 1167 0334 11B5; +CAD8 0334 11BC;CAD8 0334 11BC;110D 116A 0334 11BC;CAD8 0334 11BC;110D 116A 0334 11BC; +CB9C 0334 11AE;CB9C 0334 11AE;110D 1171 0334 11AE;CB9C 0334 11AE;110D 1171 0334 11AE; +CBF0 0334 11B5;CBF0 0334 11B5;110D 1174 0334 11B5;CBF0 0334 11B5;110D 1174 0334 11B5; +CC44 0334 11BC;CC44 0334 11BC;110E 1162 0334 11BC;CC44 0334 11BC;110E 1162 0334 11BC; +CD08 0334 11AE;CD08 0334 11AE;110E 1169 0334 11AE;CD08 0334 11AE;110E 1169 0334 11AE; +CD5C 0334 11B5;CD5C 0334 11B5;110E 116C 0334 11B5;CD5C 0334 11B5;110E 116C 0334 11B5; +CDB0 0334 11BC;CDB0 0334 11BC;110E 116F 0334 11BC;CDB0 0334 11BC;110E 116F 0334 11BC; +CE74 0334 11AE;CE74 0334 11AE;110F 1161 0334 11AE;CE74 0334 11AE;110F 1161 0334 11AE; +CEC8 0334 11B5;CEC8 0334 11B5;110F 1164 0334 11B5;CEC8 0334 11B5;110F 1164 0334 11B5; +CF1C 0334 11BC;CF1C 0334 11BC;110F 1167 0334 11BC;CF1C 0334 11BC;110F 1167 0334 11BC; +CFE0 0334 11AE;CFE0 0334 11AE;110F 116E 0334 11AE;CFE0 0334 11AE;110F 116E 0334 11AE; +D034 0334 11B5;D034 0334 11B5;110F 1171 0334 11B5;D034 0334 11B5;110F 1171 0334 11B5; +D088 0334 11BC;D088 0334 11BC;110F 1174 0334 11BC;D088 0334 11BC;110F 1174 0334 11BC; +D14C 0334 11AE;D14C 0334 11AE;1110 1166 0334 11AE;D14C 0334 11AE;1110 1166 0334 11AE; +D1A0 0334 11B5;D1A0 0334 11B5;1110 1169 0334 11B5;D1A0 0334 11B5;1110 1169 0334 11B5; +D1F4 0334 11BC;D1F4 0334 11BC;1110 116C 0334 11BC;D1F4 0334 11BC;1110 116C 0334 11BC; +D2B8 0334 11AE;D2B8 0334 11AE;1110 1173 0334 11AE;D2B8 0334 11AE;1110 1173 0334 11AE; +D30C 0334 11B5;D30C 0334 11B5;1111 1161 0334 11B5;D30C 0334 11B5;1111 1161 0334 11B5; +D360 0334 11BC;D360 0334 11BC;1111 1164 0334 11BC;D360 0334 11BC;1111 1164 0334 11BC; +D424 0334 11AE;D424 0334 11AE;1111 116B 0334 11AE;D424 0334 11AE;1111 116B 0334 11AE; +D478 0334 11B5;D478 0334 11B5;1111 116E 0334 11B5;D478 0334 11B5;1111 116E 0334 11B5; +D4CC 0334 11BC;D4CC 0334 11BC;1111 1171 0334 11BC;D4CC 0334 11BC;1111 1171 0334 11BC; +D590 0334 11AE;D590 0334 11AE;1112 1163 0334 11AE;D590 0334 11AE;1112 1163 0334 11AE; +D5E4 0334 11B5;D5E4 0334 11B5;1112 1166 0334 11B5;D5E4 0334 11B5;1112 1166 0334 11B5; +D638 0334 11BC;D638 0334 11BC;1112 1169 0334 11BC;D638 0334 11BC;1112 1169 0334 11BC; +D6FC 0334 11AE;D6FC 0334 11AE;1112 1170 0334 11AE;D6FC 0334 11AE;1112 1170 0334 11AE; +D750 0334 11B5;D750 0334 11B5;1112 1173 0334 11B5;D750 0334 11B5;1112 1173 0334 11B5; +11131 0334 11127;11131 0334 11127;11131 0334 11127;11131 0334 11127;11131 0334 11127; +11132 0334 11127;11132 0334 11127;11132 0334 11127;11132 0334 11127;11132 0334 11127; +11347 0334 1133E;11347 0334 1133E;11347 0334 1133E;11347 0334 1133E;11347 0334 1133E; +11347 0334 11357;11347 0334 11357;11347 0334 11357;11347 0334 11357;11347 0334 11357; +114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0; +114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA; +114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD; +115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF; +115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF; +# +# EOF \ No newline at end of file diff --git a/claimtrie/normalization/case_folder.go b/claimtrie/normalization/case_folder.go index 0d7e5747..7e4298ff 100644 --- a/claimtrie/normalization/case_folder.go +++ b/claimtrie/normalization/case_folder.go @@ -38,7 +38,7 @@ func init() { } } -func CaseFold(name []byte) []byte { +func caseFold(name []byte) []byte { var b bytes.Buffer b.Grow(len(name)) for i := 0; i < len(name); { diff --git a/claimtrie/normalization/char_decomposer.go b/claimtrie/normalization/char_decomposer.go new file mode 100644 index 00000000..8631cd31 --- /dev/null +++ b/claimtrie/normalization/char_decomposer.go @@ -0,0 +1,177 @@ +package normalization + +import ( + "bufio" + _ "embed" + "strconv" + "strings" + "unicode/utf8" +) + +//go:embed NFC_v11.txt +var decompositions string // the data file that came from ICU 63.2 + +var nfdMap map[rune][]rune +var nfdOrder map[rune]int32 + +func init() { + nfdMap = map[rune][]rune{} + nfdOrder = map[rune]int32{} + scanner := bufio.NewScanner(strings.NewReader(decompositions)) + for scanner.Scan() { + line := scanner.Text() + if len(line) <= 0 || line[0] == '#' || line[0] == '*' { + continue + } + if strings.ContainsAny(line, ":") { + // it's a ordering def: + addOrdering(line) + continue + } + splits := strings.Split(line, "=") + if len(splits) <= 1 { + splits = strings.Split(line, ">") + if len(splits) <= 1 { + continue + } + } + key, err := strconv.ParseUint(splits[0], 16, len(splits[0])*4) + if err != nil { + panic(err) + } + splits = strings.Split(splits[1], " ") + values := make([]rune, 0, len(splits)) + for j := range splits { + value, err := strconv.ParseUint(splits[j], 16, len(splits[j])*4) + if err != nil { + panic(err) + } + existing := nfdMap[rune(value)] + if len(existing) > 0 { + values = append(values, existing...) + } else { + values = append(values, rune(value)) + } + } + nfdMap[rune(key)] = values + } + + // run one more expansion pass to catch stragglers + for key, values := range nfdMap { + for i, value := range values { + other := nfdMap[value] + if len(other) > 0 { + newValues := make([]rune, len(values)+len(other)-1) + copy(newValues, values[:i]) + copy(newValues[i:i+len(other)], other) + copy(newValues[i+len(other):], values[i+1:]) + nfdMap[key] = newValues + } + } + } + + // assert no more expansions are necessary: + for _, values := range nfdMap { + for _, value := range values { + other := nfdMap[value] + if len(other) > 0 { + panic("Failed in NFD expansion") + } + } + } +} + +func addOrdering(line string) { + splits := strings.Split(line, ":") + ranges := strings.Split(splits[0], "..") + + value, err := strconv.ParseUint(splits[1], 16, len(splits[1])*4) + if err != nil { + panic(err) + } + + start, err := strconv.ParseUint(ranges[0], 16, len(ranges[0])*4) + if err != nil { + panic(err) + } + end := start + if len(ranges) > 1 { + end, err = strconv.ParseUint(ranges[1], 16, len(ranges[0])*4) + if err != nil { + panic(err) + } + } + for i := start; i <= end; i++ { + nfdOrder[rune(i)] = int32(value) + } +} + +func decompose(name []byte) []byte { + // see https://unicode.org/reports/tr15/ section 1.3 + runes := make([]rune, 0, len(name)) // we typically use ascii don't increase the length + for i := 0; i < len(name); { + r, w := utf8.DecodeRune(name[i:]) + if r == utf8.RuneError && w < 2 { + // HACK: their RuneError is actually a valid character if coming from a width of 2 or more + return name + } + replacements := nfdMap[r] + if len(replacements) > 0 { + runes = append(runes, replacements...) + } else { + hanguls := decomposeHangul(r) + if len(hanguls) > 0 { + runes = append(runes, hanguls...) + } else { + runes = append(runes, r) + } + } + i += w + } + repairOrdering(runes) + return []byte(string(runes)) +} + +func decomposeHangul(s rune) []rune { + // see https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf + + const SBase int32 = 0xAC00 + const LBase int32 = 0x1100 + const VBase int32 = 0x1161 + const TBase int32 = 0x11A7 + const LCount int32 = 19 + const VCount int32 = 21 + const TCount int32 = 28 + const NCount = VCount * TCount // 588 + const SCount = LCount * NCount // 11172 + + SIndex := s - SBase + if SIndex < 0 || SIndex >= SCount { + return nil + } + L := LBase + SIndex/NCount + V := VBase + (SIndex%NCount)/TCount + T := TBase + SIndex%TCount + result := []rune{L, V} + if T != TBase { + result = append(result, T) + } + return result +} + +func repairOrdering(runes []rune) { + for i := 1; i < len(runes); i++ { + a := runes[i-1] + b := runes[i] + oa := nfdOrder[a] + ob := nfdOrder[b] + if oa > ob && ob > 0 { + runes[i-1], runes[i] = b, a + if i >= 2 { + i -= 2 + } else { + i = 0 + } + } + } +} diff --git a/claimtrie/normalization/normalizer.go b/claimtrie/normalization/normalizer.go index 55275105..2bd4fa53 100644 --- a/claimtrie/normalization/normalizer.go +++ b/claimtrie/normalization/normalizer.go @@ -2,11 +2,10 @@ package normalization import ( "github.com/lbryio/lbcd/claimtrie/param" - "golang.org/x/text/unicode/norm" ) var Normalize = normalizeGo -var NormalizeTitle = "Normalizing strings via Go. Casefold table version = 11.0.0, NFD version = " + norm.Version +var NormalizeTitle = "Normalizing strings via Go. Casefold and NFD table versions: 11.0.0 (from ICU 63.2)" func NormalizeIfNecessary(name []byte, height int32) []byte { if height < param.ActiveParams.NormalizedNameForkHeight { @@ -17,7 +16,7 @@ func NormalizeIfNecessary(name []byte, height int32) []byte { func normalizeGo(value []byte) []byte { - normalized := norm.NFD.Bytes(value) // may need to hard-code the version on this + normalized := decompose(value) // may need to hard-code the version on this // not using x/text/cases because it does too good of a job; it seems to use v14 tables even when it claims v13 - return CaseFold(normalized) + return caseFold(normalized) } diff --git a/claimtrie/normalization/normalizer_icu.go b/claimtrie/normalization/normalizer_icu.go index d5093ba2..8302cc68 100644 --- a/claimtrie/normalization/normalizer_icu.go +++ b/claimtrie/normalization/normalizer_icu.go @@ -31,6 +31,8 @@ package normalization // } import "C" import ( + "bytes" + "encoding/hex" "fmt" "unsafe" ) @@ -47,21 +49,29 @@ func IcuVersion() string { } func normalizeICU(value []byte) []byte { + original := value if len(value) <= 0 { return value } + + other := normalizeGo(value) + name := (*C.char)(unsafe.Pointer(&value[0])) length := C.int(len(value)) // hopefully this is a stack alloc (but it may be a bit large for that): var resultName [512]byte // inputs are restricted to 255 chars; it shouldn't expand too much past that - result := unsafe.Pointer(&resultName[0]) + pointer := unsafe.Pointer(&resultName[0]) - resultLength := C.normalize(name, length, (*C.char)(result)) - if resultLength == 0 { - return value + resultLength := C.normalize(name, length, (*C.char)(pointer)) + if resultLength > 0 { + value = C.GoBytes(pointer, resultLength) } - // return resultName[0:resultLength] -- we want to shrink the result (not use a slice on 1024) - return C.GoBytes(result, resultLength) + // return resultName[0:resultLength] -- we want to shrink the pointer (not use a slice on 1024) + if !bytes.Equal(other, value) { + fmt.Printf("Failed with %s, %s != %s,\n\t%s, %s != %s,\n", original, value, other, + hex.EncodeToString(original), hex.EncodeToString(value), hex.EncodeToString(other)) + } + return value } diff --git a/claimtrie/normalization/normalizer_icu_test.go b/claimtrie/normalization/normalizer_icu_test.go index b02f315a..3702a772 100644 --- a/claimtrie/normalization/normalizer_icu_test.go +++ b/claimtrie/normalization/normalizer_icu_test.go @@ -4,6 +4,7 @@ package normalization import ( + "bytes" "encoding/hex" "testing" "unicode/utf8" @@ -63,3 +64,11 @@ func TestBlock760150_1020105(t *testing.T) { // t.Logf("%s -> %s", s, string(b)) } } + +func TestBlock1085612(t *testing.T) { + s, err := hex.DecodeString("6eccb7cd9dcc92cd90cc86cc80cc80cd91cd9dcd8acd80cd92cc94cc85cc8fccbdcda0ccbdcd80cda0cd84cc94cc8ccc9acd84cc94cd9bcda0cca7cc99ccaccd99cca9cca7") + assert.NoError(t, err) + a := normalizeICU(s) + b := normalizeGo(s) + assert.Equal(t, a, b, "%s != %s, %v", string(a), string(b), bytes.Equal(b, s)) +} diff --git a/claimtrie/normalization/normalizer_test.go b/claimtrie/normalization/normalizer_test.go index ea43b677..6adcff67 100644 --- a/claimtrie/normalization/normalizer_test.go +++ b/claimtrie/normalization/normalizer_test.go @@ -1,7 +1,12 @@ package normalization import ( + "bufio" + "bytes" + _ "embed" "math/rand" + "strconv" + "strings" "testing" "github.com/stretchr/testify/require" @@ -52,3 +57,33 @@ func benchmarkNormalize(b *testing.B, normalize func(value []byte) []byte) { require.True(b, len(s) >= 8) } } + +//go:embed NormalizationTest_v11.txt +var nfdTests string + +func TestDecomposition(t *testing.T) { + r := require.New(t) + + scanner := bufio.NewScanner(strings.NewReader(nfdTests)) + for scanner.Scan() { + line := scanner.Text() + if len(line) <= 0 || line[0] == '@' || line[0] == '#' { + continue + } + splits := strings.Split(line, ";") + source := convertToBytes(splits[0]) + targetNFD := convertToBytes(splits[2]) + fixed := decompose(source) + r.True(bytes.Equal(targetNFD, fixed), "Failed on %s -> %s. Got %U, not %U", splits[0], splits[2], fixed, targetNFD) + } +} + +func convertToBytes(s string) []byte { + splits := strings.Split(s, " ") + var b bytes.Buffer + for i := range splits { + value, _ := strconv.ParseUint(splits[i], 16, len(splits[i])*4) + b.WriteRune(rune(value)) + } + return b.Bytes() +} diff --git a/go.mod b/go.mod index 9ac89078..9fdeef01 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,6 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/vmihailenco/msgpack/v5 v5.3.2 golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b - golang.org/x/text v0.3.7 ) require ( -- 2.45.2 From 6da78c0bf150cf143cb2a2349b11bfd30ddb0a31 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Wed, 29 Dec 2021 14:30:17 -0500 Subject: [PATCH 173/459] [lbry] bump the version number --- cmd/lbcctl/version.go | 2 +- version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/lbcctl/version.go b/cmd/lbcctl/version.go index fcd70ce4..588ccf34 100644 --- a/cmd/lbcctl/version.go +++ b/cmd/lbcctl/version.go @@ -18,7 +18,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr const ( appMajor uint = 0 appMinor uint = 22 - appPatch uint = 100 + appPatch uint = 200 // appPreRelease MUST only contain characters from semanticAlphabet // per the semantic versioning spec. diff --git a/version.go b/version.go index 89c3ff19..852e3ae8 100644 --- a/version.go +++ b/version.go @@ -18,7 +18,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr const ( appMajor uint = 0 appMinor uint = 22 - appPatch uint = 100 + appPatch uint = 200 // appPreRelease MUST only contain characters from semanticAlphabet // per the semantic versioning spec. -- 2.45.2 From 8b11a933c1b868f02b7ebd29469ef335920aac52 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Wed, 29 Dec 2021 16:58:17 -0500 Subject: [PATCH 174/459] [lbry] rpc: made invalidate/reconsiderBlock return RPC errors --- rpcserver.go | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 195d1c6c..378155a0 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3012,10 +3012,20 @@ func handleInvalidateBlock(s *rpcServer, cmd interface{}, closeChan <-chan struc hash, err := chainhash.NewHashFromStr(c.BlockHash) if err != nil { - return nil, err + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Unable to parse hash: " + err.Error(), + } } - return nil, s.cfg.Chain.InvalidateBlock(hash) + err = s.cfg.Chain.InvalidateBlock(hash) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: "Unable to invalidate block: " + err.Error(), + } + } + return nil, nil } // handleReconsiderBlock implements the reconsiderblock command @@ -3024,10 +3034,20 @@ func handleReconsiderBlock(s *rpcServer, cmd interface{}, closeChan <-chan struc hash, err := chainhash.NewHashFromStr(c.BlockHash) if err != nil { - return nil, err + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Unable to parse hash: " + err.Error(), + } } - return nil, s.cfg.Chain.ReconsiderBlock(hash) + err = s.cfg.Chain.ReconsiderBlock(hash) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: "Unable to reconsider block: " + err.Error(), + } + } + return nil, nil } // handleHelp implements the help command. @@ -4303,7 +4323,7 @@ func (s *rpcServer) processRequest(request *btcjson.Request, isAdmin bool, close } else { jsonErr = &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidRequest.Code, - Message: "Invalid request: malformed", + Message: "Invalid request: " + err.Error(), } } } -- 2.45.2 From 92a934df533257f73667e50ba3b3f1bf567ef189 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Wed, 29 Dec 2021 21:30:44 -0800 Subject: [PATCH 175/459] [lbry] blockchain: clear statusValid upon statusValidateFailed is set The status management of index does need some refactoring. For now, we just manually clear the statusValid in every occurance of statusValidateFailed being set. Co-authored-by: Roy Lee --- blockchain/chain.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/blockchain/chain.go b/blockchain/chain.go index 4da5fbc1..70f6e7a7 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1004,6 +1004,7 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error err = b.checkConnectBlock(n, block, view, nil) if err != nil { if _, ok := err.(RuleError); ok { + b.index.UnsetStatusFlags(n, statusValid) b.index.SetStatusFlags(n, statusValidateFailed) for de := e.Next(); de != nil; de = de.Next() { dn := de.Value.(*blockNode) @@ -1141,6 +1142,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla if err == nil { b.index.SetStatusFlags(node, statusValid) } else if _, ok := err.(RuleError); ok { + b.index.UnsetStatusFlags(node, statusValid) b.index.SetStatusFlags(node, statusValidateFailed) } else { return false, err @@ -1175,6 +1177,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla // that status of the block as invalid and flush the // index state to disk before returning with the error. if _, ok := err.(RuleError); ok { + b.index.UnsetStatusFlags(node, statusValid) b.index.SetStatusFlags( node, statusValidateFailed, ) -- 2.45.2 From 0f48f40cd7a4aac4ebb3c7ceb2c612fd1127fee6 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 30 Dec 2021 09:50:16 -0500 Subject: [PATCH 176/459] [lbry] work around existing bug with block validation flags --- blockchain/chain.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index 70f6e7a7..9a6ec216 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1723,7 +1723,7 @@ func (b *BlockChain) reconsiderBlock(hash *chainhash.Hash) error { } // No need to reconsider, it is already valid. - if node.status.KnownValid() { + if node.status.KnownValid() && !node.status.KnownInvalid() { // second clause works around old bug err := fmt.Errorf("block %s is already valid", hash) return err } -- 2.45.2 From 1e6d53b950ec9ac5c9dee1bd842f32a3b24e6e6d Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 4 Jan 2022 09:52:39 -0800 Subject: [PATCH 177/459] [lbry] rpc: add a blocknotify example using lbcd websocket --- rpcclient/examples/lbcdblocknotify/README.md | 34 ++++++++++ rpcclient/examples/lbcdblocknotify/main.go | 67 ++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 rpcclient/examples/lbcdblocknotify/README.md create mode 100644 rpcclient/examples/lbcdblocknotify/main.go diff --git a/rpcclient/examples/lbcdblocknotify/README.md b/rpcclient/examples/lbcdblocknotify/README.md new file mode 100644 index 00000000..dd284f2c --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/README.md @@ -0,0 +1,34 @@ +lbcd Websockets Example +======================= + +This example shows how to use the rpcclient package to connect to a btcd RPC +server using TLS-secured websockets, register for block connected and block +disconnected notifications, and get the current block count. + +## Running the Example + +The first step is to use `go get` to download and install the rpcclient package: + +```bash +$ go get github.com/lbryio/lbcd/rpcclient +``` + +Next, modify the `main.go` source to specify the correct RPC username and +password for the RPC server: + +```Go + User: "yourrpcuser", + Pass: "yourrpcpass", +``` + +Finally, navigate to the example's directory and run it with: + +```bash +$ git clone github.com/lbryio/lbcd +$ cd rpcclient/examples/lbcdblocknotify +$ go run . +``` + +## License + +This example is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/rpcclient/examples/lbcdblocknotify/main.go b/rpcclient/examples/lbcdblocknotify/main.go new file mode 100644 index 00000000..0949d2be --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/main.go @@ -0,0 +1,67 @@ +// Copyright (c) 2014-2017 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package main + +import ( + "io/ioutil" + "log" + "path/filepath" + + "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/wire" + "github.com/lbryio/lbcutil" +) + +func main() { + // Only override the handlers for notifications you care about. + // Also note most of these handlers will only be called if you register + // for notifications. See the documentation of the rpcclient + // NotificationHandlers type for more details about each handler. + ntfnHandlers := rpcclient.NotificationHandlers{ + OnFilteredBlockConnected: func(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) { + log.Printf("Block connected: %v (%d) %v", + header.BlockHash(), height, header.Timestamp) + }, + OnFilteredBlockDisconnected: func(height int32, header *wire.BlockHeader) { + log.Printf("Block disconnected: %v (%d) %v", + header.BlockHash(), height, header.Timestamp) + }, + } + + // Connect to local lbcd RPC server using websockets. + lbcdHomeDir := lbcutil.AppDataDir("lbcd", false) + certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) + if err != nil { + log.Fatal(err) + } + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:9245", + Endpoint: "ws", + User: "rpcuser", + Pass: "rpcpass", + Certificates: certs, + } + client, err := rpcclient.New(connCfg, &ntfnHandlers) + if err != nil { + log.Fatalln(err) + } + + // Register for block connect and disconnect notifications. + if err := client.NotifyBlocks(); err != nil { + log.Fatalln(err) + } + log.Println("NotifyBlocks: Registration Complete") + + // Get the current block count. + blockCount, err := client.GetBlockCount() + if err != nil { + log.Fatal(err) + } + log.Printf("Block count: %d", blockCount) + + // Wait until the client either shuts down gracefully (or the user + // terminates the process with Ctrl+C). + client.WaitForShutdown() +} -- 2.45.2 From b6d3f5d21e8a020debebe8c5424e8f16eb9d9d33 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 4 Jan 2022 09:59:47 -0800 Subject: [PATCH 178/459] [lbry] rpc: update README.md for examples --- rpcclient/examples/lbcdblocknotify/README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/rpcclient/examples/lbcdblocknotify/README.md b/rpcclient/examples/lbcdblocknotify/README.md index dd284f2c..12d8a80a 100644 --- a/rpcclient/examples/lbcdblocknotify/README.md +++ b/rpcclient/examples/lbcdblocknotify/README.md @@ -1,5 +1,4 @@ -lbcd Websockets Example -======================= +# lbcd Websockets Example This example shows how to use the rpcclient package to connect to a btcd RPC server using TLS-secured websockets, register for block connected and block @@ -7,25 +6,27 @@ disconnected notifications, and get the current block count. ## Running the Example -The first step is to use `go get` to download and install the rpcclient package: +The first step is to clone the lbcd package: ```bash -$ go get github.com/lbryio/lbcd/rpcclient +$ git clone github.com/lbryio/lbcd ``` -Next, modify the `main.go` source to specify the correct RPC username and -password for the RPC server: +Next, navigate to the example's directory and modify the `main.go` source to +specify the correct RPC username and password for the RPC server: + +```bash +$ cd rpcclient/examples/lbcdblocknotify +``` ```Go User: "yourrpcuser", Pass: "yourrpcpass", ``` -Finally, navigate to the example's directory and run it with: +Finally, run it with: ```bash -$ git clone github.com/lbryio/lbcd -$ cd rpcclient/examples/lbcdblocknotify $ go run . ``` -- 2.45.2 From be1b16b9fdb75be193ddf8c742a3ea92454de11a Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 10 Jan 2022 22:41:24 -0800 Subject: [PATCH 179/459] [lbry] examples: update lbcdblocknotify to support Stratum --- rpcclient/examples/lbcdblocknotify/README.md | 31 +++++--- rpcclient/examples/lbcdblocknotify/main.go | 74 +++++++++++++++----- 2 files changed, 76 insertions(+), 29 deletions(-) diff --git a/rpcclient/examples/lbcdblocknotify/README.md b/rpcclient/examples/lbcdblocknotify/README.md index 12d8a80a..45ab3b29 100644 --- a/rpcclient/examples/lbcdblocknotify/README.md +++ b/rpcclient/examples/lbcdblocknotify/README.md @@ -12,22 +12,33 @@ The first step is to clone the lbcd package: $ git clone github.com/lbryio/lbcd ``` -Next, navigate to the example's directory and modify the `main.go` source to -specify the correct RPC username and password for the RPC server: +Display available options: ```bash -$ cd rpcclient/examples/lbcdblocknotify +$ go run . -h + + -coinid string + Coin ID (default "1425") + -rpcpass string + LBCD RPC password (default "rpcpass") + -rpcserver string + LBCD RPC server (default "localhost:9245") + -rpcuser string + LBCD RPC username (default "rpcuser") + -stratum string + Stratum server (default "lbrypool.net:3334") + -stratumpass string + Stratum server password (default "password") ``` -```Go - User: "yourrpcuser", - Pass: "yourrpcpass", -``` - -Finally, run it with: +Start the program: ```bash -$ go run . +$ go run . -stratumpass -rpcuser -rpcpass + +2022/01/10 23:16:21 NotifyBlocks: Registration Complete +2022/01/10 23:16:21 Block count: 1093112 +... ``` ## License diff --git a/rpcclient/examples/lbcdblocknotify/main.go b/rpcclient/examples/lbcdblocknotify/main.go index 0949d2be..591ab731 100644 --- a/rpcclient/examples/lbcdblocknotify/main.go +++ b/rpcclient/examples/lbcdblocknotify/main.go @@ -5,8 +5,11 @@ package main import ( + "flag" + "fmt" "io/ioutil" "log" + "net" "path/filepath" "github.com/lbryio/lbcd/rpcclient" @@ -14,19 +17,52 @@ import ( "github.com/lbryio/lbcutil" ) +func send(stratum, stratumPass, coinid, blockHash string) error { + addr, err := net.ResolveTCPAddr("tcp", stratum) + if err != nil { + return fmt.Errorf("can't resolve addr: %w", err) + } + + conn, err := net.DialTCP("tcp", nil, addr) + if err != nil { + return fmt.Errorf("can't dial tcp: %w", err) + } + defer conn.Close() + + msg := fmt.Sprintf(`{"id":1,"method":"mining.update_block","params":[%q,%q,%q]}`, + stratumPass, coinid, blockHash) + + _, err = conn.Write([]byte(msg)) + if err != nil { + return fmt.Errorf("can't write message: %w", err) + } + + return nil +} + func main() { - // Only override the handlers for notifications you care about. - // Also note most of these handlers will only be called if you register - // for notifications. See the documentation of the rpcclient - // NotificationHandlers type for more details about each handler. + + var ( + coinid = flag.String("coinid", "1425", "Coin ID") + stratum = flag.String("stratum", "lbrypool.net:3334", "Stratum server") + stratumPass = flag.String("stratumpass", "password", "Stratum server password") + rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server") + rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username") + rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password") + ) + + flag.Parse() + ntfnHandlers := rpcclient.NotificationHandlers{ OnFilteredBlockConnected: func(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) { - log.Printf("Block connected: %v (%d) %v", - header.BlockHash(), height, header.Timestamp) - }, - OnFilteredBlockDisconnected: func(height int32, header *wire.BlockHeader) { - log.Printf("Block disconnected: %v (%d) %v", - header.BlockHash(), height, header.Timestamp) + + blockHash := header.BlockHash().String() + + log.Printf("Block connected: %v (%d) %v", blockHash, height, header.Timestamp) + + if err := send(*stratum, *stratumPass, *coinid, blockHash); err != nil { + log.Printf("ERROR: failed to notify stratum: %s", err) + } }, } @@ -34,30 +70,30 @@ func main() { lbcdHomeDir := lbcutil.AppDataDir("lbcd", false) certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) if err != nil { - log.Fatal(err) + log.Fatalf("can't read lbcd certificate: %s", err) } connCfg := &rpcclient.ConnConfig{ - Host: "localhost:9245", + Host: *rpcserver, Endpoint: "ws", - User: "rpcuser", - Pass: "rpcpass", + User: *rpcuser, + Pass: *rpcpass, Certificates: certs, } client, err := rpcclient.New(connCfg, &ntfnHandlers) if err != nil { - log.Fatalln(err) + log.Fatalf("can't create rpc client: %s", err) } // Register for block connect and disconnect notifications. - if err := client.NotifyBlocks(); err != nil { - log.Fatalln(err) + if err = client.NotifyBlocks(); err != nil { + log.Fatalf("can't register block notification: %s", err) } - log.Println("NotifyBlocks: Registration Complete") + log.Printf("NotifyBlocks: Registration Complete") // Get the current block count. blockCount, err := client.GetBlockCount() if err != nil { - log.Fatal(err) + log.Fatalf("can't get block count: %s", err) } log.Printf("Block count: %d", blockCount) -- 2.45.2 From 2cb03c8c3dad1296dca63d3656e6ee0975b9141a Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Fri, 14 Jan 2022 15:49:33 -0500 Subject: [PATCH 180/459] add GetChainTips rpc command --- rpcclient/chain.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/rpcclient/chain.go b/rpcclient/chain.go index b3735cee..d2ee97b6 100644 --- a/rpcclient/chain.go +++ b/rpcclient/chain.go @@ -380,6 +380,49 @@ func (c *Client) GetChainTxStatsNBlocksBlockHash(nBlocks int32, blockHash chainh return c.GetChainTxStatsNBlocksBlockHashAsync(nBlocks, blockHash).Receive() } +// FutureGetChainTipsResult is a future promise to deliver the result of a +// GetChainTipsAsync RPC invocation (or an applicable error). +type FutureGetChainTipsResult chan *Response + +// Receive waits for the Response promised by the future and returns transaction statistics +func (r FutureGetChainTipsResult) Receive() ([]btcjson.GetChainTipsResult, error) { + res, err := ReceiveFuture(r) + if err != nil { + return nil, err + } + + var chainTips []btcjson.GetChainTipsResult + err = json.Unmarshal(res, &chainTips) + if err != nil { + return nil, err + } + + return chainTips, nil +} + +// GetChainTipsAsync returns an instance of a type that can be used to get +// the result of the RPC at some future time by invoking the Receive function on +// the returned instance. +// +// See GetChainTips for the blocking version and more details. +func (c *Client) GetChainTipsAsync() FutureGetChainTipsResult { + cmd := btcjson.NewGetChainTipsCmd() + return c.SendCmd(cmd) +} + +// GetChainTips returns information about all known tips in the block tree, +// including the main chain as well as orphaned branches. +// +// Possible values for status: +// "invalid" This branch contains at least one invalid block +// "headers-only" Not all blocks for this branch are available, but the headers are valid +// "valid-headers" All blocks are available for this branch, but they were never fully validated +// "valid-fork" This branch is not part of the active chain, but is fully validated +// "active" This is the tip of the active main chain, which is certainly valid +func (c *Client) GetChainTips() ([]btcjson.GetChainTipsResult, error) { + return c.GetChainTipsAsync().Receive() +} + // FutureGetDifficultyResult is a future promise to deliver the result of a // GetDifficultyAsync RPC invocation (or an applicable error). type FutureGetDifficultyResult chan *Response -- 2.45.2 From 5c1d4918d542e8974e75a14c33704a4cd917fb6d Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 11 Jan 2022 23:13:56 -0800 Subject: [PATCH 181/459] [lbry] examples: (lbcdblocknotify) connect to LBCD without TLS --- rpcclient/examples/lbcdblocknotify/main.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpcclient/examples/lbcdblocknotify/main.go b/rpcclient/examples/lbcdblocknotify/main.go index 591ab731..431331ee 100644 --- a/rpcclient/examples/lbcdblocknotify/main.go +++ b/rpcclient/examples/lbcdblocknotify/main.go @@ -49,6 +49,7 @@ func main() { rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server") rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username") rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password") + notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled") ) flag.Parse() @@ -78,6 +79,7 @@ func main() { User: *rpcuser, Pass: *rpcpass, Certificates: certs, + DisableTLS: *notls, } client, err := rpcclient.New(connCfg, &ntfnHandlers) if err != nil { -- 2.45.2 From 7bfbc8802bbc93f9c7b8e90284836171a51a62be Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 23 Jan 2022 23:06:30 -0800 Subject: [PATCH 182/459] [lbry] rpc: update getrawtransaction to take verbose as boolean --- btcjson/chainsvrcmds.go | 4 ++-- btcjson/chainsvrcmds_test.go | 10 +++++----- docs/json_rpc_api.md | 2 +- rpcclient/rawtransactions.go | 4 ++-- rpcserver.go | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index 0cfb2e17..95993dac 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -650,7 +650,7 @@ func NewGetRawMempoolCmd(verbose *bool) *GetRawMempoolCmd { // Core even though it really should be a bool. type GetRawTransactionCmd struct { Txid string - Verbose *int `jsonrpcdefault:"0"` + Verbose *bool `jsonrpcdefault:"false"` } // NewGetRawTransactionCmd returns a new instance which can be used to issue a @@ -658,7 +658,7 @@ type GetRawTransactionCmd struct { // // The parameters which are pointers indicate they are optional. Passing nil // for optional parameters will use the default value. -func NewGetRawTransactionCmd(txHash string, verbose *int) *GetRawTransactionCmd { +func NewGetRawTransactionCmd(txHash string, verbose *bool) *GetRawTransactionCmd { return &GetRawTransactionCmd{ Txid: txHash, Verbose: verbose, diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index 95320dbd..824e87d7 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -872,21 +872,21 @@ func TestChainSvrCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123"],"id":1}`, unmarshalled: &btcjson.GetRawTransactionCmd{ Txid: "123", - Verbose: btcjson.Int(0), + Verbose: btcjson.Bool(false), }, }, { name: "getrawtransaction optional", newCmd: func() (interface{}, error) { - return btcjson.NewCmd("getrawtransaction", "123", 1) + return btcjson.NewCmd("getrawtransaction", "123", true) }, staticCmd: func() interface{} { - return btcjson.NewGetRawTransactionCmd("123", btcjson.Int(1)) + return btcjson.NewGetRawTransactionCmd("123", btcjson.Bool(true)) }, - marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123",1],"id":1}`, + marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123",true],"id":1}`, unmarshalled: &btcjson.GetRawTransactionCmd{ Txid: "123", - Verbose: btcjson.Int(1), + Verbose: btcjson.Bool(true), }, }, { diff --git a/docs/json_rpc_api.md b/docs/json_rpc_api.md index 17ccba64..195b227c 100644 --- a/docs/json_rpc_api.md +++ b/docs/json_rpc_api.md @@ -436,7 +436,7 @@ the method name for further details such as parameter and return information. | | | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Method | getrawtransaction | -| Parameters | 1. transaction hash (string, required) - the hash of the transaction
2. verbose (int, optional, default=0) - specifies the transaction is returned as a JSON object instead of hex-encoded string | +| Parameters | 1. transaction hash (string, required) - the hash of the transaction
2. verbose (bool, optional, default=false) - specifies the transaction is returned as a JSON object instead of hex-encoded string | | Description | Returns information about a transaction given its hash. | | Returns (verbose=0) | `"data" (string) hex-encoded bytes of the serialized transaction` | | Returns (verbose=1) | `{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}` | diff --git a/rpcclient/rawtransactions.go b/rpcclient/rawtransactions.go index 3512ccb7..e4402f1d 100644 --- a/rpcclient/rawtransactions.go +++ b/rpcclient/rawtransactions.go @@ -108,7 +108,7 @@ func (c *Client) GetRawTransactionAsync(txHash *chainhash.Hash) FutureGetRawTran hash = txHash.String() } - cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(0)) + cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Bool(false)) return c.SendCmd(cmd) } @@ -154,7 +154,7 @@ func (c *Client) GetRawTransactionVerboseAsync(txHash *chainhash.Hash) FutureGet hash = txHash.String() } - cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(1)) + cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Bool(true)) return c.SendCmd(cmd) } diff --git a/rpcserver.go b/rpcserver.go index 378155a0..64732e6d 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -2782,7 +2782,7 @@ func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan str verbose := false if c.Verbose != nil { - verbose = *c.Verbose != 0 + verbose = *c.Verbose } // Try to fetch the transaction from the memory pool and if that fails, -- 2.45.2 From f35fcb7215a83031d3c472f88d3a3e7f080969b3 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 26 Jan 2022 20:11:56 -0800 Subject: [PATCH 183/459] [lbry] fees: initial import from DCRD vendored https://github.com/decred/dcrd/tree/master/internal/fees Commit of the last modification commit a6e205b88fbb44f7ee85be25a81f4dad155670d8 Author: Dave Collins Date: Sat Dec 26 12:17:48 2020 -0600 fees: Remove deprecated DisableLog. --- fees/README.md | 23 + fees/cmd/dumpfeedb/dumpfeedb.go | 52 ++ fees/doc.go | 107 ++++ fees/estimator.go | 920 ++++++++++++++++++++++++++++++++ fees/log.go | 21 + 5 files changed, 1123 insertions(+) create mode 100644 fees/README.md create mode 100644 fees/cmd/dumpfeedb/dumpfeedb.go create mode 100644 fees/doc.go create mode 100644 fees/estimator.go create mode 100644 fees/log.go diff --git a/fees/README.md b/fees/README.md new file mode 100644 index 00000000..03b85696 --- /dev/null +++ b/fees/README.md @@ -0,0 +1,23 @@ +fees +==== + + +[![Build Status](https://github.com/decred/dcrd/workflows/Build%20and%20Test/badge.svg)](https://github.com/decred/dcrd/actions) +[![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![Doc](https://img.shields.io/badge/doc-reference-blue.svg)](https://pkg.go.dev/github.com/decred/dcrd/internal/fees) + +Package fees provides decred-specific methods for tracking and estimating fee +rates for new transactions to be mined into the network. Fee rate estimation has +two main goals: + +- Ensuring transactions are mined within a target _confirmation range_ + (expressed in blocks); +- Attempting to minimize fees while maintaining be above restriction. + +This package was started in order to resolve issue decred/dcrd#1412 and related. +See that issue for discussion of the selected approach. + +## License + +Package dcrutil is licensed under the [copyfree](http://copyfree.org) ISC +License. diff --git a/fees/cmd/dumpfeedb/dumpfeedb.go b/fees/cmd/dumpfeedb/dumpfeedb.go new file mode 100644 index 00000000..38e2492a --- /dev/null +++ b/fees/cmd/dumpfeedb/dumpfeedb.go @@ -0,0 +1,52 @@ +// Copyright (c) 2018-2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +// Tool dumpfeedb can be used to dump the internal state of the buckets of an +// estimator's feedb so that it can be externally analyzed. +package main + +import ( + "errors" + "fmt" + "os" + "path" + + "github.com/decred/dcrd/dcrutil/v4" + "github.com/decred/dcrd/internal/fees" + flags "github.com/jessevdk/go-flags" +) + +type config struct { + DB string `short:"b" long:"db" description:"Path to fee database"` +} + +func main() { + cfg := config{ + DB: path.Join(dcrutil.AppDataDir("dcrd", false), "data", "mainnet", "feesdb"), + } + + parser := flags.NewParser(&cfg, flags.Default) + _, err := parser.Parse() + if err != nil { + var e *flags.Error + if !errors.As(err, &e) || e.Type != flags.ErrHelp { + parser.WriteHelp(os.Stderr) + } + return + } + + ecfg := fees.EstimatorConfig{ + DatabaseFile: cfg.DB, + ReplaceBucketsOnLoad: true, + MinBucketFee: 1, + MaxBucketFee: 2, + FeeRateStep: fees.DefaultFeeRateStep, + } + est, err := fees.NewEstimator(&ecfg) + if err != nil { + panic(err) + } + + fmt.Println(est.DumpBuckets()) +} diff --git a/fees/doc.go b/fees/doc.go new file mode 100644 index 00000000..77419317 --- /dev/null +++ b/fees/doc.go @@ -0,0 +1,107 @@ +// Copyright (c) 2018-2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +Package fees provides decred-specific methods for tracking and estimating fee +rates for new transactions to be mined into the network. Fee rate estimation has +two main goals: + +- Ensuring transactions are mined within a target _confirmation range_ + (expressed in blocks); +- Attempting to minimize fees while maintaining be above restriction. + +Preliminaries + +There are two main regimes against which fee estimation needs to be evaluated +according to how full blocks being mined are (and consequently how important fee +rates are): _low contention_ and _high contention_: + +In a low contention regime, the mempool sits mostly empty, transactions are +usually mined very soon after being published and transaction fees are mostly +sent using the minimum relay fee. + +In a high contention regime, the mempool is usually filled with unmined +transactions, there is active dispute for space in a block (by transactions +using higher fees) and blocks are usually full. + +The exact point of where these two regimes intersect is arbitrary, but it should +be clear in the examples and simulations which of these is being discussed. + +Note: a very high contention scenario (> 90% of blocks being full and +transactions remaining in the mempool indefinitely) is one in which stakeholders +should be discussing alternative solutions (increase block size, provide other +second layer alternatives, etc). Also, the current fill rate of blocks in decred +is low, so while we try to account for this regime, I personally expect that the +implementation will need more tweaks as it approaches this. + +The current approach to implement this estimation is based on bitcoin core's +algorithm. References [1] and [2] provide a high level description of how it +works there. Actual code is linked in references [3] and [4]. + +Outline of the Algorithm + +The algorithm is currently based in fee estimation as used in v0.14 of bitcoin +core (which is also the basis for the v0.15+ method). A more comprehensive +overview is available in reference [1]. + +This particular version was chosen because it's simpler to implement and should +be sufficient for low contention regimes. It probably overestimates fees in +higher contention regimes and longer target confirmation windows, but as pointed +out earlier should be sufficient for current fill rate of decred's network. + +The basic algorithm is as follows (as executed by a single full node): + +Stats building stage: + +- For each transaction observed entering mempool, record the block at which it + was first seen +- For each mined transaction which was previously observed to enter the mempool, + record how long (in blocks) it took to be mined and its fee rate +- Group mined transactions into fee rate _buckets_ and _confirmation ranges_, + creating a table of how many transactions were mined at each confirmation + range and fee rate bucket and their total committed fee +- Whenever a new block is mined, decay older transactions to account for a + dynamic fee environment + +Estimation stage: + +- Input a target confirmation range (how many blocks to wait for the tx to be + mined) +- Starting at the highest fee bucket, look for buckets where the chance of + confirmation within the desired confirmation window is > 95% +- Average all such buckets to get the estimated fee rate + +Simulation + +Development of the estimator was originally performed and simulated using the +code in [5]. Simulation of the current code can be performed by using the +dcrfeesim tool available in [6]. + +Acknowledgements + +Thanks to @davecgh for providing the initial review of the results and the +original developers of the bitcoin core code (the brunt of which seems to have +been made by @morcos). + +## References + +[1] Introduction to Bitcoin Core Estimation: +https://bitcointechtalk.com/an-introduction-to-bitcoin-core-fee-estimation-27920880ad0 + +[2] Proposed Changes to Fee Estimation in version 0.15: +https://gist.github.com/morcos/d3637f015bc4e607e1fd10d8351e9f41 + +[3] Source for fee estimation in v0.14: +https://github.com/bitcoin/bitcoin/blob/v0.14.2/src/policy/fees.cpp + +[4] Source for fee estimation in version 0.16.2: +https://github.com/bitcoin/bitcoin/blob/v0.16.2/src/policy/fees.cpp + +[5] Source for the original dcrfeesim and estimator work: +https://github.com/matheusd/dcrfeesim_dev + +[6] Source for the current dcrfeesim, using this module: +https://github.com/matheusd/dcrfeesim +*/ +package fees diff --git a/fees/estimator.go b/fees/estimator.go new file mode 100644 index 00000000..d98f037f --- /dev/null +++ b/fees/estimator.go @@ -0,0 +1,920 @@ +// Copyright (c) 2018-2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package fees + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "math" + "sort" + "sync" + + "github.com/decred/dcrd/blockchain/stake/v4" + "github.com/decred/dcrd/chaincfg/chainhash" + "github.com/decred/dcrd/dcrutil/v4" + "github.com/syndtr/goleveldb/leveldb" + ldbutil "github.com/syndtr/goleveldb/leveldb/util" +) + +const ( + // DefaultMaxBucketFeeMultiplier is the default multiplier used to find the + // largest fee bucket, starting at the minimum fee. + DefaultMaxBucketFeeMultiplier int = 100 + + // DefaultMaxConfirmations is the default number of confirmation ranges to + // track in the estimator. + DefaultMaxConfirmations uint32 = 32 + + // DefaultFeeRateStep is the default multiplier between two consecutive fee + // rate buckets. + DefaultFeeRateStep float64 = 1.1 + + // defaultDecay is the default value used to decay old transactions from the + // estimator. + defaultDecay float64 = 0.998 + + // maxAllowedBucketFees is an upper bound of how many bucket fees can be + // used in the estimator. This is verified during estimator initialization + // and database loading. + maxAllowedBucketFees = 2000 + + // maxAllowedConfirms is an upper bound of how many confirmation ranges can + // be used in the estimator. This is verified during estimator + // initialization and database loading. + maxAllowedConfirms = 788 +) + +var ( + // ErrNoSuccessPctBucketFound is the error returned when no bucket has been + // found with the minimum required percentage success. + ErrNoSuccessPctBucketFound = errors.New("no bucket with the minimum " + + "required success percentage found") + + // ErrNotEnoughTxsForEstimate is the error returned when not enough + // transactions have been seen by the fee generator to give an estimate. + ErrNotEnoughTxsForEstimate = errors.New("not enough transactions seen for " + + "estimation") + + dbByteOrder = binary.BigEndian + + dbKeyVersion = []byte("version") + dbKeyBucketFees = []byte("bucketFeeBounds") + dbKeyMaxConfirms = []byte("maxConfirms") + dbKeyBestHeight = []byte("bestHeight") + dbKeyBucketPrefix = []byte{0x01, 0x70, 0x1d, 0x00} +) + +// ErrTargetConfTooLarge is the type of error returned when an user of the +// estimator requested a confirmation range higher than tracked by the estimator. +type ErrTargetConfTooLarge struct { + MaxConfirms int32 + ReqConfirms int32 +} + +func (e ErrTargetConfTooLarge) Error() string { + return fmt.Sprintf("target confirmation requested (%d) higher than "+ + "maximum confirmation range tracked by estimator (%d)", e.ReqConfirms, + e.MaxConfirms) +} + +type feeRate float64 + +type txConfirmStatBucketCount struct { + txCount float64 + feeSum float64 +} + +type txConfirmStatBucket struct { + confirmed []txConfirmStatBucketCount + confirmCount float64 + feeSum float64 +} + +// EstimatorConfig stores the configuration parameters for a given fee +// estimator. It is used to initialize an empty fee estimator. +type EstimatorConfig struct { + // MaxConfirms is the maximum number of confirmation ranges to check. + MaxConfirms uint32 + + // MinBucketFee is the value of the fee rate of the lowest bucket for which + // estimation is tracked. + MinBucketFee dcrutil.Amount + + // MaxBucketFee is the value of the fee for the highest bucket for which + // estimation is tracked. + // + // It MUST be higher than MinBucketFee. + MaxBucketFee dcrutil.Amount + + // ExtraBucketFee is an additional bucket fee rate to include in the + // database for tracking transactions. Specifying this can be useful when + // the default relay fee of the network is undergoing change (due to a new + // release of the software for example), so that the older fee can be + // tracked exactly. + // + // It MUST have a value between MinBucketFee and MaxBucketFee, otherwise + // it's ignored. + ExtraBucketFee dcrutil.Amount + + // FeeRateStep is the multiplier to generate the fee rate buckets (each + // bucket is higher than the previous one by this factor). + // + // It MUST have a value > 1.0. + FeeRateStep float64 + + // DatabaseFile is the location of the estimator database file. If empty, + // updates to the estimator state are not backed by the filesystem. + DatabaseFile string + + // ReplaceBucketsOnLoad indicates whether to replace the buckets in the + // current estimator by those stored in the feesdb file instead of + // validating that they are both using the same set of fees. + ReplaceBucketsOnLoad bool +} + +// memPoolTxDesc is an aux structure used to track the local estimator mempool. +type memPoolTxDesc struct { + addedHeight int64 + bucketIndex int32 + fees feeRate +} + +// Estimator tracks historical data for published and mined transactions in +// order to estimate fees to be used in new transactions for confirmation +// within a target block window. +type Estimator struct { + // bucketFeeBounds are the upper bounds for each individual fee bucket. + bucketFeeBounds []feeRate + + // buckets are the confirmed tx count and fee sum by bucket fee. + buckets []txConfirmStatBucket + + // memPool are the mempool transaction count and fee sum by bucket fee. + memPool []txConfirmStatBucket + + // memPoolTxs is the map of transaction hashes and data of known mempool txs. + memPoolTxs map[chainhash.Hash]memPoolTxDesc + + maxConfirms int32 + decay float64 + bestHeight int64 + db *leveldb.DB + lock sync.RWMutex +} + +// NewEstimator returns an empty estimator given a config. This estimator +// then needs to be fed data for published and mined transactions before it can +// be used to estimate fees for new transactions. +func NewEstimator(cfg *EstimatorConfig) (*Estimator, error) { + // Sanity check the config. + if cfg.MaxBucketFee <= cfg.MinBucketFee { + return nil, errors.New("maximum bucket fee should not be lower than " + + "minimum bucket fee") + } + if cfg.FeeRateStep <= 1.0 { + return nil, errors.New("fee rate step should not be <= 1.0") + } + if cfg.MinBucketFee <= 0 { + return nil, errors.New("minimum bucket fee rate cannot be <= 0") + } + if cfg.MaxConfirms > maxAllowedConfirms { + return nil, fmt.Errorf("confirmation count requested (%d) larger than "+ + "maximum allowed (%d)", cfg.MaxConfirms, maxAllowedConfirms) + } + + decay := defaultDecay + maxConfirms := cfg.MaxConfirms + max := float64(cfg.MaxBucketFee) + var bucketFees []feeRate + prevF := 0.0 + extraBucketFee := float64(cfg.ExtraBucketFee) + for f := float64(cfg.MinBucketFee); f < max; f *= cfg.FeeRateStep { + if (f > extraBucketFee) && (prevF < extraBucketFee) { + // Add the extra bucket fee for tracking. + bucketFees = append(bucketFees, feeRate(extraBucketFee)) + } + bucketFees = append(bucketFees, feeRate(f)) + prevF = f + } + + // The last bucket catches everything else, so it uses an upper bound of + // +inf which any rate must be lower than. + bucketFees = append(bucketFees, feeRate(math.Inf(1))) + + nbBuckets := len(bucketFees) + res := &Estimator{ + bucketFeeBounds: bucketFees, + buckets: make([]txConfirmStatBucket, nbBuckets), + memPool: make([]txConfirmStatBucket, nbBuckets), + maxConfirms: int32(maxConfirms), + decay: decay, + memPoolTxs: make(map[chainhash.Hash]memPoolTxDesc), + bestHeight: -1, + } + + for i := range bucketFees { + res.buckets[i] = txConfirmStatBucket{ + confirmed: make([]txConfirmStatBucketCount, maxConfirms), + } + res.memPool[i] = txConfirmStatBucket{ + confirmed: make([]txConfirmStatBucketCount, maxConfirms), + } + } + + if cfg.DatabaseFile != "" { + db, err := leveldb.OpenFile(cfg.DatabaseFile, nil) + if err != nil { + return nil, fmt.Errorf("error opening estimator database: %v", err) + } + res.db = db + + err = res.loadFromDatabase(cfg.ReplaceBucketsOnLoad) + if err != nil { + return nil, fmt.Errorf("error loading estimator data from db: %v", + err) + } + } + + return res, nil +} + +// DumpBuckets returns the internal estimator state as a string. +func (stats *Estimator) DumpBuckets() string { + res := " |" + for c := 0; c < int(stats.maxConfirms); c++ { + if c == int(stats.maxConfirms)-1 { + res += fmt.Sprintf(" %15s", "+Inf") + } else { + res += fmt.Sprintf(" %15d|", c+1) + } + } + res += "\n" + + l := len(stats.bucketFeeBounds) + for i := 0; i < l; i++ { + res += fmt.Sprintf("%10.8f", stats.bucketFeeBounds[i]/1e8) + for c := 0; c < int(stats.maxConfirms); c++ { + avg := float64(0) + count := stats.buckets[i].confirmed[c].txCount + if stats.buckets[i].confirmed[c].txCount > 0 { + avg = stats.buckets[i].confirmed[c].feeSum / + stats.buckets[i].confirmed[c].txCount / 1e8 + } + + res += fmt.Sprintf("| %.8f %6.1f", avg, count) + } + res += "\n" + } + + return res +} + +// loadFromDatabase loads the estimator data from the currently opened database +// and performs any db upgrades if required. After loading, it updates the db +// with the current estimator configuration. +// +// Argument replaceBuckets indicates if the buckets in the current stats should +// be completely replaced by what is stored in the database or if the data +// should be validated against what is current in the estimator. +// +// The database should *not* be used while loading is taking place. +// +// The current code does not support loading from a database created with a +// different set of configuration parameters (fee rate buckets, max confirmation +// range, etc) than the current estimator is configured with. If an incompatible +// file is detected during loading, an error is returned and the user must +// either reconfigure the estimator to use the same parameters to allow the +// database to be loaded or they must ignore the database file (possibly by +// deleting it) so that the new parameters are used. In the future it might be +// possible to load from a different set of configuration parameters. +// +// The current code does not currently save mempool information, since saving +// information in the estimator without saving the corresponding data in the +// mempool itself could result in transactions lingering in the mempool +// estimator forever. +func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error { + if stats.db == nil { + return errors.New("estimator database is not open") + } + + // Database version is currently hardcoded here as this is the only + // place that uses it. + currentDbVersion := []byte{1} + + version, err := stats.db.Get(dbKeyVersion, nil) + if err != nil && !errors.Is(err, leveldb.ErrNotFound) { + return fmt.Errorf("error reading version from db: %v", err) + } + if len(version) < 1 { + // No data in the file. Fill with the current config. + batch := new(leveldb.Batch) + b := bytes.NewBuffer(nil) + var maxConfirmsBytes [4]byte + var bestHeightBytes [8]byte + + batch.Put(dbKeyVersion, currentDbVersion) + + dbByteOrder.PutUint32(maxConfirmsBytes[:], uint32(stats.maxConfirms)) + batch.Put(dbKeyMaxConfirms, maxConfirmsBytes[:]) + + dbByteOrder.PutUint64(bestHeightBytes[:], uint64(stats.bestHeight)) + batch.Put(dbKeyBestHeight, bestHeightBytes[:]) + + err := binary.Write(b, dbByteOrder, stats.bucketFeeBounds) + if err != nil { + return fmt.Errorf("error writing bucket fees to db: %v", err) + } + batch.Put(dbKeyBucketFees, b.Bytes()) + + err = stats.db.Write(batch, nil) + if err != nil { + return fmt.Errorf("error writing initial estimator db file: %v", + err) + } + + err = stats.updateDatabase() + if err != nil { + return fmt.Errorf("error adding initial estimator data to db: %v", + err) + } + + log.Debug("Initialized fee estimator database") + + return nil + } + + if !bytes.Equal(currentDbVersion, version) { + return fmt.Errorf("incompatible database version: %d", version) + } + + maxConfirmsBytes, err := stats.db.Get(dbKeyMaxConfirms, nil) + if err != nil { + return fmt.Errorf("error reading max confirmation range from db file: "+ + "%v", err) + } + if len(maxConfirmsBytes) != 4 { + return errors.New("wrong number of bytes in stored maxConfirms") + } + fileMaxConfirms := int32(dbByteOrder.Uint32(maxConfirmsBytes)) + if fileMaxConfirms > maxAllowedConfirms { + return fmt.Errorf("confirmation count stored in database (%d) larger "+ + "than maximum allowed (%d)", fileMaxConfirms, maxAllowedConfirms) + } + + feesBytes, err := stats.db.Get(dbKeyBucketFees, nil) + if err != nil { + return fmt.Errorf("error reading fee bounds from db file: %v", err) + } + if feesBytes == nil { + return errors.New("fee bounds not found in database file") + } + fileNbBucketFees := len(feesBytes) / 8 + if fileNbBucketFees > maxAllowedBucketFees { + return fmt.Errorf("more fee buckets stored in file (%d) than allowed "+ + "(%d)", fileNbBucketFees, maxAllowedBucketFees) + } + fileBucketFees := make([]feeRate, fileNbBucketFees) + err = binary.Read(bytes.NewReader(feesBytes), dbByteOrder, + &fileBucketFees) + if err != nil { + return fmt.Errorf("error decoding file bucket fees: %v", err) + } + + if !replaceBuckets { + if stats.maxConfirms != fileMaxConfirms { + return errors.New("max confirmation range in database file different " + + "than currently configured max confirmation") + } + + if len(stats.bucketFeeBounds) != len(fileBucketFees) { + return errors.New("number of bucket fees stored in database file " + + "different than currently configured bucket fees") + } + + for i, f := range fileBucketFees { + if stats.bucketFeeBounds[i] != f { + return errors.New("bucket fee rates stored in database file " + + "different than currently configured fees") + } + } + } + + fileBuckets := make([]txConfirmStatBucket, fileNbBucketFees) + + iter := stats.db.NewIterator(ldbutil.BytesPrefix(dbKeyBucketPrefix), nil) + err = nil + var fbytes [8]byte + for iter.Next() { + key := iter.Key() + if len(key) != 8 { + err = fmt.Errorf("bucket key read from db has wrong length (%d)", + len(key)) + break + } + idx := int(int32(dbByteOrder.Uint32(key[4:]))) + if (idx >= len(fileBuckets)) || (idx < 0) { + err = fmt.Errorf("wrong bucket index read from db (%d vs %d)", + idx, len(fileBuckets)) + break + } + value := iter.Value() + if len(value) != 8+8+int(fileMaxConfirms)*16 { + err = errors.New("wrong size of data in bucket read from db") + break + } + + b := bytes.NewBuffer(value) + readf := func() float64 { + // We ignore the error here because the only possible one is EOF and + // we already previously checked the length of the source byte array + // for consistency. + b.Read(fbytes[:]) + return math.Float64frombits(dbByteOrder.Uint64(fbytes[:])) + } + + fileBuckets[idx].confirmCount = readf() + fileBuckets[idx].feeSum = readf() + fileBuckets[idx].confirmed = make([]txConfirmStatBucketCount, fileMaxConfirms) + for i := range fileBuckets[idx].confirmed { + fileBuckets[idx].confirmed[i].txCount = readf() + fileBuckets[idx].confirmed[i].feeSum = readf() + } + } + iter.Release() + if err != nil { + return err + } + err = iter.Error() + if err != nil { + return fmt.Errorf("error on bucket iterator: %v", err) + } + + stats.bucketFeeBounds = fileBucketFees + stats.buckets = fileBuckets + stats.maxConfirms = fileMaxConfirms + log.Debug("Loaded fee estimator database") + + return nil +} + +// updateDatabase updates the current database file with the current bucket +// data. This is called during normal operation after processing mined +// transactions, so it only updates data that might have changed. +func (stats *Estimator) updateDatabase() error { + if stats.db == nil { + return errors.New("estimator database is closed") + } + + batch := new(leveldb.Batch) + buf := bytes.NewBuffer(nil) + + var key [8]byte + copy(key[:], dbKeyBucketPrefix) + var fbytes [8]byte + writef := func(f float64) { + dbByteOrder.PutUint64(fbytes[:], math.Float64bits(f)) + _, err := buf.Write(fbytes[:]) + if err != nil { + panic(err) // only possible error is ErrTooLarge + } + } + + for i, b := range stats.buckets { + dbByteOrder.PutUint32(key[4:], uint32(i)) + buf.Reset() + writef(b.confirmCount) + writef(b.feeSum) + for _, c := range b.confirmed { + writef(c.txCount) + writef(c.feeSum) + } + batch.Put(key[:], buf.Bytes()) + } + + var bestHeightBytes [8]byte + + dbByteOrder.PutUint64(bestHeightBytes[:], uint64(stats.bestHeight)) + batch.Put(dbKeyBestHeight, bestHeightBytes[:]) + + err := stats.db.Write(batch, nil) + if err != nil { + return fmt.Errorf("error writing update to estimator db file: %v", + err) + } + + return nil +} + +// lowerBucket returns the bucket that has the highest upperBound such that it +// is still lower than rate. +func (stats *Estimator) lowerBucket(rate feeRate) int32 { + res := sort.Search(len(stats.bucketFeeBounds), func(i int) bool { + return stats.bucketFeeBounds[i] >= rate + }) + return int32(res) +} + +// confirmRange returns the confirmation range index to be used for the given +// number of blocks to confirm. The last confirmation range has an upper bound +// of +inf to mean that it represents all confirmations higher than the second +// to last bucket. +func (stats *Estimator) confirmRange(blocksToConfirm int32) int32 { + idx := blocksToConfirm - 1 + if idx >= stats.maxConfirms { + return stats.maxConfirms - 1 + } + return idx +} + +// updateMovingAverages updates the moving averages for the existing confirmed +// statistics and increases the confirmation ranges for mempool txs. This is +// meant to be called when a new block is mined, so that we discount older +// information. +func (stats *Estimator) updateMovingAverages(newHeight int64) { + log.Debugf("Updated moving averages into block %d", newHeight) + + // decay the existing stats so that, over time, we rely on more up to date + // information regarding fees. + for b := 0; b < len(stats.buckets); b++ { + bucket := &stats.buckets[b] + bucket.feeSum *= stats.decay + bucket.confirmCount *= stats.decay + for c := 0; c < len(bucket.confirmed); c++ { + conf := &bucket.confirmed[c] + conf.feeSum *= stats.decay + conf.txCount *= stats.decay + } + } + + // For unconfirmed (mempool) transactions, every transaction will now take + // at least one additional block to confirm. So for every fee bucket, we + // move the stats up one confirmation range. + for b := 0; b < len(stats.memPool); b++ { + bucket := &stats.memPool[b] + + // The last confirmation range represents all txs confirmed at >= than + // the initial maxConfirms, so we *add* the second to last range into + // the last range. + c := len(bucket.confirmed) - 1 + bucket.confirmed[c].txCount += bucket.confirmed[c-1].txCount + bucket.confirmed[c].feeSum += bucket.confirmed[c-1].feeSum + + // For the other ranges, just move up the stats. + for c--; c > 0; c-- { + bucket.confirmed[c] = bucket.confirmed[c-1] + } + + // and finally, the very first confirmation range (ie, what will enter + // the mempool now that a new block has been mined) is zeroed so we can + // start tracking brand new txs. + bucket.confirmed[0].txCount = 0 + bucket.confirmed[0].feeSum = 0 + } + + stats.bestHeight = newHeight +} + +// newMemPoolTx records a new memPool transaction into the stats. A brand new +// mempool transaction has a minimum confirmation range of 1, so it is inserted +// into the very first confirmation range bucket of the appropriate fee rate +// bucket. +func (stats *Estimator) newMemPoolTx(bucketIdx int32, fees feeRate) { + conf := &stats.memPool[bucketIdx].confirmed[0] + conf.feeSum += float64(fees) + conf.txCount++ +} + +// newMinedTx moves a mined tx from the mempool into the confirmed statistics. +// Note that this should only be called if the transaction had been seen and +// previously tracked by calling newMemPoolTx for it. Failing to observe that +// will result in undefined statistical results. +func (stats *Estimator) newMinedTx(blocksToConfirm int32, rate feeRate) { + bucketIdx := stats.lowerBucket(rate) + confirmIdx := stats.confirmRange(blocksToConfirm) + bucket := &stats.buckets[bucketIdx] + + // increase the counts for all confirmation ranges starting at the first + // confirmIdx because it took at least `blocksToConfirm` for this tx to be + // mined. This is used to simplify the bucket selection during estimation, + // so that we only need to check a single confirmation range (instead of + // iterating to sum all confirmations with <= `minConfs`). + for c := int(confirmIdx); c < len(bucket.confirmed); c++ { + conf := &bucket.confirmed[c] + conf.feeSum += float64(rate) + conf.txCount++ + } + bucket.confirmCount++ + bucket.feeSum += float64(rate) +} + +func (stats *Estimator) removeFromMemPool(blocksInMemPool int32, rate feeRate) { + bucketIdx := stats.lowerBucket(rate) + confirmIdx := stats.confirmRange(blocksInMemPool + 1) + bucket := &stats.memPool[bucketIdx] + conf := &bucket.confirmed[confirmIdx] + conf.feeSum -= float64(rate) + conf.txCount-- + if conf.txCount < 0 { + // If this happens, it means a transaction has been called on this + // function but not on a previous newMemPoolTx. This leaves the fee db + // in an undefined state and should never happen in regular use. If this + // happens, then there is a logic or coding error somewhere, either in + // the estimator itself or on its hooking to the mempool/network sync + // manager. Either way, the easiest way to fix this is to completely + // delete the database and start again. During development, you can use + // a panic() here and we might return it after being confident that the + // estimator is completely bug free. + log.Errorf("Transaction count in bucket index %d and confirmation "+ + "index %d became < 0", bucketIdx, confirmIdx) + } +} + +// estimateMedianFee estimates the median fee rate for the current recorded +// statistics such that at least successPct transactions have been mined on all +// tracked fee rate buckets with fee >= to the median. +// In other words, this is the median fee of the lowest bucket such that it and +// all higher fee buckets have >= successPct transactions confirmed in at most +// `targetConfs` confirmations. +// Note that sometimes the requested combination of targetConfs and successPct is +// not achievable (hypothetical example: 99% of txs confirmed within 1 block) +// or there are not enough recorded statistics to derive a successful estimate +// (eg: confirmation tracking has only started or there was a period of very few +// transactions). In those situations, the appropriate error is returned. +func (stats *Estimator) estimateMedianFee(targetConfs int32, successPct float64) (feeRate, error) { + if targetConfs <= 0 { + return 0, errors.New("target confirmation range cannot be <= 0") + } + + const minTxCount float64 = 1 + + if (targetConfs - 1) >= stats.maxConfirms { + // We might want to add support to use a targetConf at +infinity to + // allow us to make estimates at confirmation interval higher than what + // we currently track. + return 0, ErrTargetConfTooLarge{MaxConfirms: stats.maxConfirms, + ReqConfirms: targetConfs} + } + + startIdx := len(stats.buckets) - 1 + confirmRangeIdx := stats.confirmRange(targetConfs) + + var totalTxs, confirmedTxs float64 + bestBucketsStt := startIdx + bestBucketsEnd := startIdx + curBucketsEnd := startIdx + + for b := startIdx; b >= 0; b-- { + totalTxs += stats.buckets[b].confirmCount + confirmedTxs += stats.buckets[b].confirmed[confirmRangeIdx].txCount + + // Add the mempool (unconfirmed) transactions to the total tx count + // since a very large mempool for the given bucket might mean that + // miners are reluctant to include these in their mined blocks. + totalTxs += stats.memPool[b].confirmed[confirmRangeIdx].txCount + + if totalTxs > minTxCount { + if confirmedTxs/totalTxs < successPct { + if curBucketsEnd == startIdx { + return 0, ErrNoSuccessPctBucketFound + } + break + } + + bestBucketsStt = b + bestBucketsEnd = curBucketsEnd + curBucketsEnd = b - 1 + totalTxs = 0 + confirmedTxs = 0 + } + } + + txCount := float64(0) + for b := bestBucketsStt; b <= bestBucketsEnd; b++ { + txCount += stats.buckets[b].confirmCount + } + if txCount <= 0 { + return 0, ErrNotEnoughTxsForEstimate + } + txCount /= 2 + for b := bestBucketsStt; b <= bestBucketsEnd; b++ { + if stats.buckets[b].confirmCount < txCount { + txCount -= stats.buckets[b].confirmCount + } else { + median := stats.buckets[b].feeSum / stats.buckets[b].confirmCount + return feeRate(median), nil + } + } + + return 0, errors.New("this isn't supposed to be reached") +} + +// EstimateFee is the public version of estimateMedianFee. It calculates the +// suggested fee for a transaction to be confirmed in at most `targetConf` +// blocks after publishing with a high degree of certainty. +// +// This function is safe to be called from multiple goroutines but might block +// until concurrent modifications to the internal database state are complete. +func (stats *Estimator) EstimateFee(targetConfs int32) (dcrutil.Amount, error) { + stats.lock.RLock() + rate, err := stats.estimateMedianFee(targetConfs, 0.95) + stats.lock.RUnlock() + + if err != nil { + return 0, err + } + + rate = feeRate(math.Round(float64(rate))) + if rate < stats.bucketFeeBounds[0] { + // Prevent our public facing api to ever return something lower than the + // minimum fee + rate = stats.bucketFeeBounds[0] + } + + return dcrutil.Amount(rate), nil +} + +// Enable establishes the current best height of the blockchain after +// initializing the chain. All new mempool transactions will be added at this +// block height. +func (stats *Estimator) Enable(bestHeight int64) { + log.Debugf("Setting best height as %d", bestHeight) + stats.lock.Lock() + stats.bestHeight = bestHeight + stats.lock.Unlock() +} + +// IsEnabled returns whether the fee estimator is ready to accept new mined and +// mempool transactions. +func (stats *Estimator) IsEnabled() bool { + stats.lock.RLock() + enabled := stats.bestHeight > -1 + stats.lock.RUnlock() + return enabled +} + +// AddMemPoolTransaction adds a mempool transaction to the estimator in order to +// account for it in the estimations. It assumes that this transaction is +// entering the mempool at the currently recorded best chain hash, using the +// total fee amount (in atoms) and with the provided size (in bytes). +// +// This is safe to be called from multiple goroutines. +func (stats *Estimator) AddMemPoolTransaction(txHash *chainhash.Hash, fee, size int64, txType stake.TxType) { + stats.lock.Lock() + defer stats.lock.Unlock() + + if stats.bestHeight < 0 { + return + } + + if _, exists := stats.memPoolTxs[*txHash]; exists { + // we should not double count transactions + return + } + + // Ignore tspends for the purposes of fee estimation, since they remain + // in the mempool for a long time and have special rules about when + // they can be included in blocks. + if txType == stake.TxTypeTSpend { + return + } + + // Note that we use this less exact version instead of fee * 1000 / size + // (using ints) because it naturally "downsamples" the fee rates towards the + // minimum at values less than 0.001 DCR/KB. This is needed because due to + // how the wallet estimates the final fee given an input rate and the final + // tx size, there's usually a small discrepancy towards a higher effective + // rate in the published tx. + rate := feeRate(fee / size * 1000) + + if rate < stats.bucketFeeBounds[0] { + // Transactions paying less than the current relaying fee can only + // possibly be included in the high priority/zero fee area of blocks, + // which are usually of limited size, so we explicitly don't track + // those. + // This also naturally handles votes (SSGen transactions) which don't + // carry a tx fee and are required for inclusion in blocks. Note that + // the test is explicitly < instead of <= so that we *can* track + // transactions that pay *exactly* the minimum fee. + return + } + + log.Debugf("Adding mempool tx %s using fee rate %.8f", txHash, rate/1e8) + + tx := memPoolTxDesc{ + addedHeight: stats.bestHeight, + bucketIndex: stats.lowerBucket(rate), + fees: rate, + } + stats.memPoolTxs[*txHash] = tx + stats.newMemPoolTx(tx.bucketIndex, rate) +} + +// RemoveMemPoolTransaction removes a mempool transaction from statistics +// tracking. +// +// This is safe to be called from multiple goroutines. +func (stats *Estimator) RemoveMemPoolTransaction(txHash *chainhash.Hash) { + stats.lock.Lock() + defer stats.lock.Unlock() + + desc, exists := stats.memPoolTxs[*txHash] + if !exists { + return + } + + log.Debugf("Removing tx %s from mempool", txHash) + + stats.removeFromMemPool(int32(stats.bestHeight-desc.addedHeight), desc.fees) + delete(stats.memPoolTxs, *txHash) +} + +// processMinedTransaction moves the transaction that exist in the currently +// tracked mempool into a mined state. +// +// This function is *not* safe to be called from multiple goroutines. +func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhash.Hash) { + desc, exists := stats.memPoolTxs[*txh] + if !exists { + // We cannot use transactions that we didn't know about to estimate + // because that opens up the possibility of miners introducing dummy, + // high fee transactions which would tend to then increase the average + // fee estimate. + // Tracking only previously known transactions forces miners trying to + // pull off this attack to broadcast their transactions and possibly + // forfeit their coins by having the transaction mined by a competitor. + log.Tracef("Processing previously unknown mined tx %s", txh) + return + } + + stats.removeFromMemPool(int32(blockHeight-desc.addedHeight), desc.fees) + delete(stats.memPoolTxs, *txh) + + if blockHeight <= desc.addedHeight { + // This shouldn't usually happen but we need to explicitly test for + // because we can't account for non positive confirmation ranges in + // mined transactions. + log.Errorf("Mined transaction %s (%d) that was known from "+ + "mempool at a higher block height (%d)", txh, blockHeight, + desc.addedHeight) + return + } + + mineDelay := int32(blockHeight - desc.addedHeight) + log.Debugf("Processing mined tx %s (rate %.8f, delay %d)", txh, + desc.fees/1e8, mineDelay) + stats.newMinedTx(mineDelay, desc.fees) +} + +// ProcessBlock processes all mined transactions in the provided block. +// +// This function is safe to be called from multiple goroutines. +func (stats *Estimator) ProcessBlock(block *dcrutil.Block) error { + stats.lock.Lock() + defer stats.lock.Unlock() + + if stats.bestHeight < 0 { + return nil + } + + blockHeight := block.Height() + if blockHeight <= stats.bestHeight { + // we don't explicitly track reorgs right now + log.Warnf("Trying to process mined transactions at block %d when "+ + "previous best block was at height %d", blockHeight, + stats.bestHeight) + return nil + } + + stats.updateMovingAverages(blockHeight) + + for _, tx := range block.Transactions() { + stats.processMinedTransaction(blockHeight, tx.Hash()) + } + + for _, tx := range block.STransactions() { + stats.processMinedTransaction(blockHeight, tx.Hash()) + } + + if stats.db != nil { + return stats.updateDatabase() + } + + return nil +} + +// Close closes the database (if it is currently opened). +func (stats *Estimator) Close() { + stats.lock.Lock() + + if stats.db != nil { + log.Trace("Closing fee estimator database") + stats.db.Close() + stats.db = nil + } + + stats.lock.Unlock() +} diff --git a/fees/log.go b/fees/log.go new file mode 100644 index 00000000..08793d69 --- /dev/null +++ b/fees/log.go @@ -0,0 +1,21 @@ +// Copyright (c) 2018-2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package fees + +import ( + "github.com/decred/slog" +) + +// log is a logger that is initialized with no output filters. This means the +// package will not perform any logging by default until the caller requests it. +// The default amount of logging is none. +var log = slog.Disabled + +// UseLogger uses a specified Logger to output fee estimator logging info. This +// should be used in preference to SetLogWriter if the caller is also using +// slog. +func UseLogger(logger slog.Logger) { + log = logger +} -- 2.45.2 From 811741d09946aaf83b66ef633a6e68dccdd4c9ca Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 26 Jan 2022 20:42:17 -0800 Subject: [PATCH 184/459] [lbry] fees: port estimatesmartfee from DCRD 1. logger 2. blockheight: int64 -> int32 3. dcrutil -> lbcutl 4. MaxConfirimation: 42 5. MinBucketFee: mempool.MinRelayFee (default 1000) 6. BucketFee Spacing: 1.1 -> 1.05 Note: DCRD implementation of estimatesmartfee is based on bitcoin core 0.14 Lbrycrd (0.17) includes the updates of bitcoin core 0.15. They are slightly different, but shouldn't matter much. --- fees/cmd/dumpfeedb/dumpfeedb.go | 10 +++++-- fees/estimator.go | 52 +++++++++++++-------------------- fees/log.go | 18 ++++++++---- log.go | 27 +++++++++-------- 4 files changed, 54 insertions(+), 53 deletions(-) diff --git a/fees/cmd/dumpfeedb/dumpfeedb.go b/fees/cmd/dumpfeedb/dumpfeedb.go index 38e2492a..b15974bf 100644 --- a/fees/cmd/dumpfeedb/dumpfeedb.go +++ b/fees/cmd/dumpfeedb/dumpfeedb.go @@ -12,20 +12,24 @@ import ( "os" "path" - "github.com/decred/dcrd/dcrutil/v4" - "github.com/decred/dcrd/internal/fees" + "github.com/btcsuite/btclog" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/fees" + "github.com/lbryio/lbcutil" ) type config struct { DB string `short:"b" long:"db" description:"Path to fee database"` } +var feesLog = btclog.NewBackend(os.Stdout).Logger("FEES") + func main() { cfg := config{ - DB: path.Join(dcrutil.AppDataDir("dcrd", false), "data", "mainnet", "feesdb"), + DB: path.Join(lbcutil.AppDataDir("lbcd", false), "data", "mainnet", "feesdb"), } + fees.UseLogger(feesLog) parser := flags.NewParser(&cfg, flags.Default) _, err := parser.Parse() if err != nil { diff --git a/fees/estimator.go b/fees/estimator.go index d98f037f..7f7a8751 100644 --- a/fees/estimator.go +++ b/fees/estimator.go @@ -13,9 +13,8 @@ import ( "sort" "sync" - "github.com/decred/dcrd/blockchain/stake/v4" - "github.com/decred/dcrd/chaincfg/chainhash" - "github.com/decred/dcrd/dcrutil/v4" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcutil" "github.com/syndtr/goleveldb/leveldb" ldbutil "github.com/syndtr/goleveldb/leveldb/util" ) @@ -27,11 +26,11 @@ const ( // DefaultMaxConfirmations is the default number of confirmation ranges to // track in the estimator. - DefaultMaxConfirmations uint32 = 32 + DefaultMaxConfirmations uint32 = 42 // DefaultFeeRateStep is the default multiplier between two consecutive fee // rate buckets. - DefaultFeeRateStep float64 = 1.1 + DefaultFeeRateStep float64 = 1.05 // defaultDecay is the default value used to decay old transactions from the // estimator. @@ -102,13 +101,13 @@ type EstimatorConfig struct { // MinBucketFee is the value of the fee rate of the lowest bucket for which // estimation is tracked. - MinBucketFee dcrutil.Amount + MinBucketFee lbcutil.Amount // MaxBucketFee is the value of the fee for the highest bucket for which // estimation is tracked. // // It MUST be higher than MinBucketFee. - MaxBucketFee dcrutil.Amount + MaxBucketFee lbcutil.Amount // ExtraBucketFee is an additional bucket fee rate to include in the // database for tracking transactions. Specifying this can be useful when @@ -118,7 +117,7 @@ type EstimatorConfig struct { // // It MUST have a value between MinBucketFee and MaxBucketFee, otherwise // it's ignored. - ExtraBucketFee dcrutil.Amount + ExtraBucketFee lbcutil.Amount // FeeRateStep is the multiplier to generate the fee rate buckets (each // bucket is higher than the previous one by this factor). @@ -138,7 +137,7 @@ type EstimatorConfig struct { // memPoolTxDesc is an aux structure used to track the local estimator mempool. type memPoolTxDesc struct { - addedHeight int64 + addedHeight int32 bucketIndex int32 fees feeRate } @@ -161,7 +160,7 @@ type Estimator struct { maxConfirms int32 decay float64 - bestHeight int64 + bestHeight int32 db *leveldb.DB lock sync.RWMutex } @@ -324,7 +323,7 @@ func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error { dbByteOrder.PutUint64(bestHeightBytes[:], uint64(stats.bestHeight)) batch.Put(dbKeyBestHeight, bestHeightBytes[:]) - err := binary.Write(b, dbByteOrder, stats.bucketFeeBounds) + err = binary.Write(b, dbByteOrder, stats.bucketFeeBounds) if err != nil { return fmt.Errorf("error writing bucket fees to db: %v", err) } @@ -534,7 +533,7 @@ func (stats *Estimator) confirmRange(blocksToConfirm int32) int32 { // statistics and increases the confirmation ranges for mempool txs. This is // meant to be called when a new block is mined, so that we discount older // information. -func (stats *Estimator) updateMovingAverages(newHeight int64) { +func (stats *Estimator) updateMovingAverages(newHeight int32) { log.Debugf("Updated moving averages into block %d", newHeight) // decay the existing stats so that, over time, we rely on more up to date @@ -718,7 +717,7 @@ func (stats *Estimator) estimateMedianFee(targetConfs int32, successPct float64) // // This function is safe to be called from multiple goroutines but might block // until concurrent modifications to the internal database state are complete. -func (stats *Estimator) EstimateFee(targetConfs int32) (dcrutil.Amount, error) { +func (stats *Estimator) EstimateFee(targetConfs int32) (lbcutil.Amount, error) { stats.lock.RLock() rate, err := stats.estimateMedianFee(targetConfs, 0.95) stats.lock.RUnlock() @@ -734,13 +733,13 @@ func (stats *Estimator) EstimateFee(targetConfs int32) (dcrutil.Amount, error) { rate = stats.bucketFeeBounds[0] } - return dcrutil.Amount(rate), nil + return lbcutil.Amount(rate), nil } // Enable establishes the current best height of the blockchain after // initializing the chain. All new mempool transactions will be added at this // block height. -func (stats *Estimator) Enable(bestHeight int64) { +func (stats *Estimator) Enable(bestHeight int32) { log.Debugf("Setting best height as %d", bestHeight) stats.lock.Lock() stats.bestHeight = bestHeight @@ -762,7 +761,7 @@ func (stats *Estimator) IsEnabled() bool { // total fee amount (in atoms) and with the provided size (in bytes). // // This is safe to be called from multiple goroutines. -func (stats *Estimator) AddMemPoolTransaction(txHash *chainhash.Hash, fee, size int64, txType stake.TxType) { +func (stats *Estimator) AddMemPoolTransaction(txHash *chainhash.Hash, fee, size int64) { stats.lock.Lock() defer stats.lock.Unlock() @@ -775,13 +774,6 @@ func (stats *Estimator) AddMemPoolTransaction(txHash *chainhash.Hash, fee, size return } - // Ignore tspends for the purposes of fee estimation, since they remain - // in the mempool for a long time and have special rules about when - // they can be included in blocks. - if txType == stake.TxTypeTSpend { - return - } - // Note that we use this less exact version instead of fee * 1000 / size // (using ints) because it naturally "downsamples" the fee rates towards the // minimum at values less than 0.001 DCR/KB. This is needed because due to @@ -828,7 +820,7 @@ func (stats *Estimator) RemoveMemPoolTransaction(txHash *chainhash.Hash) { log.Debugf("Removing tx %s from mempool", txHash) - stats.removeFromMemPool(int32(stats.bestHeight-desc.addedHeight), desc.fees) + stats.removeFromMemPool(stats.bestHeight-desc.addedHeight, desc.fees) delete(stats.memPoolTxs, *txHash) } @@ -836,7 +828,7 @@ func (stats *Estimator) RemoveMemPoolTransaction(txHash *chainhash.Hash) { // tracked mempool into a mined state. // // This function is *not* safe to be called from multiple goroutines. -func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhash.Hash) { +func (stats *Estimator) processMinedTransaction(blockHeight int32, txh *chainhash.Hash) { desc, exists := stats.memPoolTxs[*txh] if !exists { // We cannot use transactions that we didn't know about to estimate @@ -850,7 +842,7 @@ func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhas return } - stats.removeFromMemPool(int32(blockHeight-desc.addedHeight), desc.fees) + stats.removeFromMemPool(blockHeight-desc.addedHeight, desc.fees) delete(stats.memPoolTxs, *txh) if blockHeight <= desc.addedHeight { @@ -863,7 +855,7 @@ func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhas return } - mineDelay := int32(blockHeight - desc.addedHeight) + mineDelay := blockHeight - desc.addedHeight log.Debugf("Processing mined tx %s (rate %.8f, delay %d)", txh, desc.fees/1e8, mineDelay) stats.newMinedTx(mineDelay, desc.fees) @@ -872,7 +864,7 @@ func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhas // ProcessBlock processes all mined transactions in the provided block. // // This function is safe to be called from multiple goroutines. -func (stats *Estimator) ProcessBlock(block *dcrutil.Block) error { +func (stats *Estimator) ProcessBlock(block *lbcutil.Block) error { stats.lock.Lock() defer stats.lock.Unlock() @@ -895,10 +887,6 @@ func (stats *Estimator) ProcessBlock(block *dcrutil.Block) error { stats.processMinedTransaction(blockHeight, tx.Hash()) } - for _, tx := range block.STransactions() { - stats.processMinedTransaction(blockHeight, tx.Hash()) - } - if stats.db != nil { return stats.updateDatabase() } diff --git a/fees/log.go b/fees/log.go index 08793d69..769c320d 100644 --- a/fees/log.go +++ b/fees/log.go @@ -5,17 +5,23 @@ package fees import ( - "github.com/decred/slog" + "github.com/btcsuite/btclog" ) // log is a logger that is initialized with no output filters. This means the // package will not perform any logging by default until the caller requests it. // The default amount of logging is none. -var log = slog.Disabled +var log btclog.Logger -// UseLogger uses a specified Logger to output fee estimator logging info. This -// should be used in preference to SetLogWriter if the caller is also using -// slog. -func UseLogger(logger slog.Logger) { +// DisableLog disables all library log output. Logging output is disabled +// by default until either UseLogger or SetLogWriter are called. +func DisableLog() { + log = btclog.Disabled +} + +// UseLogger uses a specified Logger to output package logging info. +// This should be used in preference to SetLogWriter if the caller is also +// using btclog. +func UseLogger(logger btclog.Logger) { log = logger } diff --git a/log.go b/log.go index cc845475..2809b1a7 100644 --- a/log.go +++ b/log.go @@ -16,6 +16,7 @@ import ( "github.com/lbryio/lbcd/claimtrie/node" "github.com/lbryio/lbcd/connmgr" "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" "github.com/lbryio/lbcd/mining" "github.com/lbryio/lbcd/mining/cpuminer" @@ -57,13 +58,14 @@ var ( adxrLog = backendLog.Logger("ADXR") amgrLog = backendLog.Logger("AMGR") - cmgrLog = backendLog.Logger("CMGR") bcdbLog = backendLog.Logger("BCDB") btcdLog = backendLog.Logger("MAIN") chanLog = backendLog.Logger("CHAN") - lbryLog = backendLog.Logger("LBRY") + cmgrLog = backendLog.Logger("CMGR") discLog = backendLog.Logger("DISC") + feesLog = backendLog.Logger("FEES") indxLog = backendLog.Logger("INDX") + lbryLog = backendLog.Logger("LBRY") minrLog = backendLog.Logger("MINR") peerLog = backendLog.Logger("PEER") rpcsLog = backendLog.Logger("RPCS") @@ -76,30 +78,31 @@ var ( // Initialize package-global logger variables. func init() { addrmgr.UseLogger(amgrLog) - connmgr.UseLogger(cmgrLog) - database.UseLogger(bcdbLog) blockchain.UseLogger(chanLog) - node.UseLogger(lbryLog) - indexers.UseLogger(indxLog) - mining.UseLogger(minrLog) + connmgr.UseLogger(cmgrLog) cpuminer.UseLogger(minrLog) + database.UseLogger(bcdbLog) + fees.UseLogger(feesLog) + indexers.UseLogger(indxLog) + mempool.UseLogger(txmpLog) + mining.UseLogger(minrLog) + netsync.UseLogger(syncLog) + node.UseLogger(lbryLog) peer.UseLogger(peerLog) txscript.UseLogger(scrpLog) - netsync.UseLogger(syncLog) - mempool.UseLogger(txmpLog) } // subsystemLoggers maps each subsystem identifier to its associated logger. var subsystemLoggers = map[string]btclog.Logger{ "ADXR": adxrLog, "AMGR": amgrLog, - "CMGR": cmgrLog, "BCDB": bcdbLog, - "MAIN": btcdLog, "CHAN": chanLog, - "LBRY": lbryLog, + "CMGR": cmgrLog, "DISC": discLog, "INDX": indxLog, + "LBRY": lbryLog, + "MAIN": btcdLog, "MINR": minrLog, "PEER": peerLog, "RPCS": rpcsLog, -- 2.45.2 From 8d9e9feb2eaead0f04ab3d38486cc0aee11764b9 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sat, 29 Jan 2022 16:27:52 -0800 Subject: [PATCH 185/459] [lbry] fees: replace estimatefee with esimatesmartfee --- mempool/mempool.go | 27 ++++++++++++++---- netsync/interface.go | 3 +- netsync/manager.go | 34 ++++++++++------------ rpcserver.go | 35 ++++++++++++++++++++--- server.go | 68 ++++++++++++++++++-------------------------- 5 files changed, 97 insertions(+), 70 deletions(-) diff --git a/mempool/mempool.go b/mempool/mempool.go index de3b8028..a2dc5c20 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -100,9 +100,15 @@ type Config struct { // This can be nil if the address index is not enabled. AddrIndex *indexers.AddrIndex - // FeeEstimatator provides a feeEstimator. If it is not nil, the mempool - // records all new transactions it observes into the feeEstimator. - FeeEstimator *FeeEstimator + // AddTxToFeeEstimation defines an optional function to be called whenever a + // new transaction is added to the mempool, which can be used to track fees + // for the purposes of smart fee estimation. + AddTxToFeeEstimation func(txHash *chainhash.Hash, fee, size int64) + + // RemoveTxFromFeeEstimation defines an optional function to be called + // whenever a transaction is removed from the mempool in order to track fee + // estimation. + RemoveTxFromFeeEstimation func(txHash *chainhash.Hash) } // Policy houses the policy (configuration parameters) which is used to @@ -491,6 +497,13 @@ func (mp *TxPool) removeTransaction(tx *btcutil.Tx, removeRedeemers bool) { delete(mp.outpoints, txIn.PreviousOutPoint) } delete(mp.pool, *txHash) + + // Inform associated fee estimator that the transaction has been removed + // from the mempool + if mp.cfg.RemoveTxFromFeeEstimation != nil { + mp.cfg.RemoveTxFromFeeEstimation(txHash) + } + atomic.StoreInt64(&mp.lastUpdated, time.Now().Unix()) } } @@ -559,9 +572,11 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil mp.cfg.AddrIndex.AddUnconfirmedTx(tx, utxoView) } - // Record this tx for fee estimation if enabled. - if mp.cfg.FeeEstimator != nil { - mp.cfg.FeeEstimator.ObserveTransaction(txD) + // Inform the associated fee estimator that a new transaction has been added + // to the mempool. + size := GetTxVirtualSize(txD.Tx) + if mp.cfg.AddTxToFeeEstimation != nil { + mp.cfg.AddTxToFeeEstimation(txD.Tx.Hash(), txD.Fee, size) } return txD diff --git a/netsync/interface.go b/netsync/interface.go index 9361bfbc..2a646f07 100644 --- a/netsync/interface.go +++ b/netsync/interface.go @@ -8,6 +8,7 @@ import ( "github.com/lbryio/lbcd/blockchain" "github.com/lbryio/lbcd/chaincfg" "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" "github.com/lbryio/lbcd/peer" "github.com/lbryio/lbcd/wire" @@ -37,5 +38,5 @@ type Config struct { DisableCheckpoints bool MaxPeers int - FeeEstimator *mempool.FeeEstimator + FeeEstimator *fees.Estimator } diff --git a/netsync/manager.go b/netsync/manager.go index 69093610..72fce625 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -16,6 +16,7 @@ import ( "github.com/lbryio/lbcd/chaincfg" "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" peerpkg "github.com/lbryio/lbcd/peer" "github.com/lbryio/lbcd/wire" @@ -205,7 +206,7 @@ type SyncManager struct { nextCheckpoint *chaincfg.Checkpoint // An optional fee estimator. - feeEstimator *mempool.FeeEstimator + feeEstimator *fees.Estimator } // resetHeaderState sets the headers-first mode state to values appropriate for @@ -1414,6 +1415,13 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not iv := wire.NewInvVect(wire.InvTypeBlock, block.Hash()) sm.peerNotifier.RelayInventory(iv, block.MsgBlock().Header) + if !sm.feeEstimator.IsEnabled() { + // fee estimation can only start after we have performed an initial + // sync, otherwise we'll start adding mempool transactions at the + // wrong height. + sm.feeEstimator.Enable(block.Height()) + } + // A block has been connected to the main block chain. case blockchain.NTBlockConnected: block, ok := notification.Data.(*btcutil.Block) @@ -1422,6 +1430,12 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not break } + // Account for transactions mined in the newly connected block for fee + // estimation. This must be done before attempting to remove + // transactions from the mempool because the mempool will alert the + // estimator of the txs that are leaving + sm.feeEstimator.ProcessBlock(block) + // Remove all of the transactions (except the coinbase) in the // connected block from the transaction pool. Secondly, remove any // transactions which are now double spends as a result of these @@ -1438,20 +1452,6 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not sm.peerNotifier.AnnounceNewTransactions(acceptedTxs) } - // Register block with the fee estimator, if it exists. - if sm.feeEstimator != nil { - err := sm.feeEstimator.RegisterBlock(block) - - // If an error is somehow generated then the fee estimator - // has entered an invalid state. Since it doesn't know how - // to recover, create a new one. - if err != nil { - sm.feeEstimator = mempool.NewFeeEstimator( - mempool.DefaultEstimateFeeMaxRollback, - mempool.DefaultEstimateFeeMinRegisteredBlocks) - } - } - // A block has been disconnected from the main block chain. case blockchain.NTBlockDisconnected: block, ok := notification.Data.(*btcutil.Block) @@ -1473,10 +1473,6 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not } } - // Rollback previous block recorded by the fee estimator. - if sm.feeEstimator != nil { - sm.feeEstimator.Rollback(block.Hash()) - } } } diff --git a/rpcserver.go b/rpcserver.go index 64732e6d..baccf7fe 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -36,6 +36,7 @@ import ( "github.com/lbryio/lbcd/chaincfg" "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" "github.com/lbryio/lbcd/mining" "github.com/lbryio/lbcd/mining/cpuminer" @@ -893,7 +894,7 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) } } - feeRate, err := s.cfg.FeeEstimator.EstimateFee(uint32(c.NumBlocks)) + feeRate, err := s.cfg.FeeEstimator.EstimateFee(int32(c.NumBlocks)) if err != nil { return nil, &btcjson.RPCError{ @@ -906,12 +907,36 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) return float64(feeRate), nil } +// handleEstimateSmartFee implements the estimatesmartfee command. +// +// The default estimation mode when unset is assumed as "conservative". As of +// 2018-12, the only supported mode is "conservative". func handleEstimateSmartFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*btcjson.EstimateSmartFeeCmd) - rpcsLog.Debugf("EstimateSmartFee is not implemented; falling back to EstimateFee. Requested mode: %s", c.EstimateMode) + mode := btcjson.EstimateModeConservative + if c.EstimateMode != nil { + mode = *c.EstimateMode + } - return handleEstimateFee(s, &btcjson.EstimateFeeCmd{NumBlocks: c.ConfTarget}, closeChan) + if mode != btcjson.EstimateModeConservative { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Only the default and conservative modes " + + "are supported for smart fee estimation at the moment", + } + } + + fee, err := s.cfg.FeeEstimator.EstimateFee(int32(c.ConfTarget)) + if err != nil { + return nil, internalRPCError(err.Error(), "Could not estimate fee") + } + + feeRate := float64(fee) / btcutil.SatoshiPerBitcoin + return &btcjson.EstimateSmartFeeResult{ + FeeRate: &feeRate, + Blocks: c.ConfTarget, + }, nil } func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { @@ -4012,6 +4037,7 @@ type rpcServer struct { gbtWorkState *gbtWorkState helpCacher *helpCacher requestProcessShutdown chan struct{} + feeEstimator *fees.Estimator quit chan int } @@ -4845,7 +4871,7 @@ type rpcserverConfig struct { // The fee estimator keeps track of how long transactions are left in // the mempool before they are mined into blocks. - FeeEstimator *mempool.FeeEstimator + FeeEstimator *fees.Estimator // Services represents the services supported by this node. Services wire.ServiceFlag @@ -4859,6 +4885,7 @@ func newRPCServer(config *rpcserverConfig) (*rpcServer, error) { gbtWorkState: newGbtWorkState(config.TimeSource), helpCacher: newHelpCacher(), requestProcessShutdown: make(chan struct{}), + feeEstimator: config.FeeEstimator, quit: make(chan int), } if cfg.RPCUser != "" && cfg.RPCPass != "" { diff --git a/server.go b/server.go index d0a7ad1c..a9a9193a 100644 --- a/server.go +++ b/server.go @@ -14,6 +14,7 @@ import ( "fmt" "math" "net" + "path" "runtime" "sort" "strconv" @@ -31,6 +32,7 @@ import ( claimtrieconfig "github.com/lbryio/lbcd/claimtrie/config" "github.com/lbryio/lbcd/connmgr" "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" "github.com/lbryio/lbcd/mining" "github.com/lbryio/lbcd/mining/cpuminer" @@ -38,6 +40,7 @@ import ( "github.com/lbryio/lbcd/peer" "github.com/lbryio/lbcd/txscript" "github.com/lbryio/lbcd/wire" + "github.com/lbryio/lbcutil" btcutil "github.com/lbryio/lbcutil" "github.com/lbryio/lbcutil/bloom" ) @@ -241,7 +244,7 @@ type server struct { // The fee estimator keeps track of how long transactions are left in // the mempool before they are mined into blocks. - feeEstimator *mempool.FeeEstimator + feeEstimator *fees.Estimator // cfCheckptCaches stores a cached slice of filter headers for cfcheckpt // messages for each filter type. @@ -2417,13 +2420,7 @@ func (s *server) Stop() error { s.rpcServer.Stop() } - // Save fee estimator state in the database. - s.db.Update(func(tx database.Tx) error { - metadata := tx.Metadata() - metadata.Put(mempool.EstimateFeeDatabaseKey, s.feeEstimator.Save()) - - return nil - }) + s.feeEstimator.Close() // Signal the remaining goroutines to quit. close(s.quit) @@ -2755,35 +2752,25 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, return nil, err } - // Search for a FeeEstimator state in the database. If none can be found - // or if it cannot be loaded, create a new one. - db.Update(func(tx database.Tx) error { - metadata := tx.Metadata() - feeEstimationData := metadata.Get(mempool.EstimateFeeDatabaseKey) - if feeEstimationData != nil { - // delete it from the database so that we don't try to restore the - // same thing again somehow. - metadata.Delete(mempool.EstimateFeeDatabaseKey) + feC := fees.EstimatorConfig{ + MinBucketFee: cfg.minRelayTxFee, + MaxBucketFee: lbcutil.Amount(fees.DefaultMaxBucketFeeMultiplier) * cfg.minRelayTxFee, + MaxConfirms: fees.DefaultMaxConfirmations, + FeeRateStep: fees.DefaultFeeRateStep, + DatabaseFile: path.Join(cfg.DataDir, "feesdb"), - // If there is an error, log it and make a new fee estimator. - var err error - s.feeEstimator, err = mempool.RestoreFeeEstimator(feeEstimationData) - - if err != nil { - peerLog.Errorf("Failed to restore fee estimator %v", err) - } - } - - return nil - }) - - // If no feeEstimator has been found, or if the one that has been found - // is behind somehow, create a new one and start over. - if s.feeEstimator == nil || s.feeEstimator.LastKnownHeight() != s.chain.BestSnapshot().Height { - s.feeEstimator = mempool.NewFeeEstimator( - mempool.DefaultEstimateFeeMaxRollback, - mempool.DefaultEstimateFeeMinRegisteredBlocks) + // 1e5 is the previous (up to 1.1.0) mempool.DefaultMinRelayTxFee that + // un-upgraded wallets will be using, so track this particular rate + // explicitly. Note that bumping this value will cause the existing fees + // database to become invalid and will force nodes to explicitly delete + // it. + ExtraBucketFee: 1e5, } + fe, err := fees.NewEstimator(&feC) + if err != nil { + return nil, err + } + s.feeEstimator = fe txC := mempool.Config{ Policy: mempool.Policy{ @@ -2804,11 +2791,12 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, CalcSequenceLock: func(tx *btcutil.Tx, view *blockchain.UtxoViewpoint) (*blockchain.SequenceLock, error) { return s.chain.CalcSequenceLock(tx, view, true) }, - IsDeploymentActive: s.chain.IsDeploymentActive, - SigCache: s.sigCache, - HashCache: s.hashCache, - AddrIndex: s.addrIndex, - FeeEstimator: s.feeEstimator, + IsDeploymentActive: s.chain.IsDeploymentActive, + SigCache: s.sigCache, + HashCache: s.hashCache, + AddrIndex: s.addrIndex, + AddTxToFeeEstimation: s.feeEstimator.AddMemPoolTransaction, + RemoveTxFromFeeEstimation: s.feeEstimator.RemoveMemPoolTransaction, } s.txMemPool = mempool.New(&txC) -- 2.45.2 From 99f85504129c5cc01987f187862399edeed3de8b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 3 Feb 2022 22:43:34 -0800 Subject: [PATCH 186/459] [lbry] Increase wire.MaxBlockPayload to 8MB --- wire/msgblock.go | 4 ++-- wire/msgblock_test.go | 2 +- wire/msgmerkleblock_test.go | 2 +- wire/msgtx_test.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wire/msgblock.go b/wire/msgblock.go index c940b971..b66db374 100644 --- a/wire/msgblock.go +++ b/wire/msgblock.go @@ -23,8 +23,8 @@ const defaultTransactionAlloc = 2048 const MaxBlocksPerMsg = 500 // MaxBlockPayload is the maximum bytes a block message can be in bytes. -// After Segregated Witness, the max block payload has been raised to 4MB. -const MaxBlockPayload = 4000000 +// After Segregated Witness, the max block payload has been raised to 8MB. +const MaxBlockPayload = 8000000 // maxTxPerBlock is the maximum number of transactions that could // possibly fit into a block. diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index f906892a..c2f92bad 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -36,7 +36,7 @@ func TestBlock(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num addresses (varInt) + max allowed addresses. - wantPayload := uint32(4000000) + wantPayload := uint32(8000000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ diff --git a/wire/msgmerkleblock_test.go b/wire/msgmerkleblock_test.go index 9f7a8403..cda9865a 100644 --- a/wire/msgmerkleblock_test.go +++ b/wire/msgmerkleblock_test.go @@ -38,7 +38,7 @@ func TestMerkleBlock(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num addresses (varInt) + max allowed addresses. - wantPayload := uint32(4000000) + wantPayload := uint32(8000000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index 11f67293..66288882 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -35,7 +35,7 @@ func TestTx(t *testing.T) { } // Ensure max payload is expected value for latest protocol version. - wantPayload := uint32(1000 * 4000) + wantPayload := uint32(1000 * 8000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ -- 2.45.2 From 3424fdc6d7e3b46e5315516fcb9e6fe4f9870004 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 7 Feb 2022 23:18:14 -0800 Subject: [PATCH 187/459] mining: return witness_script instead of raw witness_commitment in GBT --- mining/mining.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mining/mining.go b/mining/mining.go index 6eb00316..4f3ac9e5 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -868,7 +868,7 @@ mempoolLoop: } // AddWitnessCommitment adds the witness commitment as an OP_RETURN outpout -// within the coinbase tx. The raw commitment is returned. +// within the coinbase tx. The witness script is returned. func AddWitnessCommitment(coinbaseTx *btcutil.Tx, blockTxns []*btcutil.Tx) []byte { @@ -907,7 +907,7 @@ func AddWitnessCommitment(coinbaseTx *btcutil.Tx, coinbaseTx.MsgTx().TxOut = append(coinbaseTx.MsgTx().TxOut, commitmentOutput) - return witnessCommitment + return witnessScript } // UpdateBlockTime updates the timestamp in the header of the passed block to -- 2.45.2 From 20d761441c604282518e5e6f3881053702488987 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 8 Feb 2022 00:34:09 -0800 Subject: [PATCH 188/459] go mod: bump github.com/shirou/gopsutil/v3 to 3.22.1 To include a few fixes for MacOS Monterey. --- go.mod | 11 ++++++----- go.sum | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 9fdeef01..129c3f44 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/jrick/logrotate v1.0.0 github.com/lbryio/lbcutil v1.0.202-rc3 github.com/pkg/errors v0.9.1 - github.com/shirou/gopsutil/v3 v3.21.7 + github.com/shirou/gopsutil/v3 v3.22.1 github.com/spf13/cobra v1.1.3 github.com/stretchr/testify v1.7.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 @@ -32,7 +32,7 @@ require ( github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect github.com/cockroachdb/redact v1.1.3 // indirect github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 // indirect - github.com/go-ole/go-ole v1.2.5 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/pprof v0.0.0-20200615235658-03e1cf38a040 // indirect @@ -43,11 +43,12 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect + github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/tklauser/go-sysconf v0.3.7 // indirect - github.com/tklauser/numcpus v0.2.3 // indirect + github.com/tklauser/go-sysconf v0.3.9 // indirect + github.com/tklauser/numcpus v0.3.0 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect golang.org/x/exp v0.0.0-20211123021643-48cbe7f80d7c // indirect - golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab // indirect + golang.org/x/sys v0.0.0-20220111092808-5a964db01320 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index 987e44d5..bc353fc7 100644 --- a/go.sum +++ b/go.sum @@ -175,6 +175,8 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -225,6 +227,9 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -338,6 +343,7 @@ github.com/lbryio/lbcutil v1.0.202-rc3 h1:J7zYnIj3iN/ndPYKqMKBukLaLM1GhCEaiaMOYI github.com/lbryio/lbcutil v1.0.202-rc3/go.mod h1:LGPtVBBzh4cFXfLFb8ginlFcbA2QwumLNFd0yk/as2o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -422,6 +428,7 @@ github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6J github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -459,8 +466,12 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil/v3 v3.21.7 h1:PnTqQamUjwEDSgn+nBGu0qSDV/CfvyiR/gwTH3i7HTU= github.com/shirou/gopsutil/v3 v3.21.7/go.mod h1:RGl11Y7XMTQPmHh8F0ayC6haKNBgH4PXMJuTAcMOlz4= +github.com/shirou/gopsutil/v3 v3.22.1 h1:33y31Q8J32+KstqPfscvFwBlNJ6xLaBy4xqBXzlYV5w= +github.com/shirou/gopsutil/v3 v3.22.1/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -500,8 +511,12 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.7 h1:HT7h4+536gjqeq1ZIJPgOl1rg1XFatQGVZWp7Py53eg= github.com/tklauser/go-sysconf v0.3.7/go.mod h1:JZIdXh4RmBvZDBZ41ld2bGxRV3n4daiiqA3skYhAoQ4= +github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo= +github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.2.3 h1:nQ0QYpiritP6ViFhrKYsiv6VVxOpum2Gks5GhnJbS/8= github.com/tklauser/numcpus v0.2.3/go.mod h1:vpEPS/JC+oZGGQ/My/vJnNsvMDQL6PwOqt8dsCw5j+E= +github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= +github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -530,6 +545,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= @@ -683,6 +699,7 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -690,10 +707,13 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab h1:rfJ1bsoJQQIAoAxTxB7bme+vHrNkRw8CqfsYh9w54cw= golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320 h1:0jf+tOCoZ3LyutmCOWpVni1chK4VfFLhRsDK7MhqGRY= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -- 2.45.2 From eecc55d94ce422ceddb668ce5d1c0946ebc1ff34 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 10 Feb 2022 14:47:25 -0800 Subject: [PATCH 189/459] rpc: take integers for boolean parameters. This is for backward compatibility with lbrycrd/bitcoind where some clients use intger values (0/1) for boolean. --- btcjson/cmdparse.go | 10 +++++ btcjson/cmdparse_test.go | 83 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/btcjson/cmdparse.go b/btcjson/cmdparse.go index 4fb8dd62..c0190bf3 100644 --- a/btcjson/cmdparse.go +++ b/btcjson/cmdparse.go @@ -134,6 +134,16 @@ func UnmarshalCmd(r *Request) (interface{}, error) { // Unmarshal the parameter into the struct field. concreteVal := rvf.Addr().Interface() if err := json.Unmarshal(r.Params[i], &concreteVal); err != nil { + // Parse Integer into Bool for compatibility with lbrycrd. + if rvf.Kind() == reflect.Ptr && + rvf.Elem().Type().Kind() == reflect.Bool { + boolInt, errBoolInt := strconv.Atoi(string(r.Params[i])) + if errBoolInt == nil { + rvf.Elem().SetBool(boolInt != 0) + continue + } + } + // The most common error is the wrong type, so // explicitly detect that error and make it nicer. fieldName := strings.ToLower(rt.Field(i).Name) diff --git a/btcjson/cmdparse_test.go b/btcjson/cmdparse_test.go index c1414c64..0da6442c 100644 --- a/btcjson/cmdparse_test.go +++ b/btcjson/cmdparse_test.go @@ -557,7 +557,7 @@ func TestUnmarshalCmdErrors(t *testing.T) { request: btcjson.Request{ Jsonrpc: btcjson.RpcVersion1, Method: "getblock", - Params: []json.RawMessage{[]byte("1")}, + Params: []json.RawMessage{[]byte("1.0")}, ID: nil, }, err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType}, @@ -591,3 +591,84 @@ func TestUnmarshalCmdErrors(t *testing.T) { } } } + +// TestUnmarshalCmdBoolParams tests the parsing of boolean paramers of the UnmarshalCmd function. +func TestUnmarshalCmdBoolParams(t *testing.T) { + t.Parallel() + + txid := []byte(`"ab91c149aff2b37a4a1856e9935ea623c973f47886d032ed7511ad8ca37855bb"`) + tests := []struct { + name string + request btcjson.Request + expect bool + }{ + { + name: "parse true", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("true")}, + ID: nil, + }, + expect: true, + }, + { + name: "parse false", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("false")}, + ID: nil, + }, + expect: false, + }, + { + name: "parse integer 0 to false", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("0")}, + ID: nil, + }, + expect: false, + }, + { + name: "parse integer 1 to true", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("1")}, + ID: nil, + }, + expect: true, + }, + { + name: "parse integer 100 to true", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("100")}, + ID: nil, + }, + expect: true, + }, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + cmd, err := btcjson.UnmarshalCmd(&test.request) + if err != nil { + t.Errorf("Test #%d (%s) error - got %T (%v)", i, test.name, + err, err) + continue + } + cc := cmd.(*btcjson.GetRawTransactionCmd) + verbose := *cc.Verbose + if verbose != test.expect { + t.Errorf("Test #%d (%s) got %t, want %v", i, test.name, + verbose, test.expect) + continue + } + + } +} -- 2.45.2 From 31c404baaa4e79afadcd81a75b7a4a1c3fff4a43 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 17 Feb 2022 20:58:10 -0800 Subject: [PATCH 190/459] [lbry] ci: bump to Go 1.17.7 --- .github/workflows/basic-check.yml | 2 +- .github/workflows/full-sync-part-1.yml | 2 +- .github/workflows/full-sync-part-2.yml | 2 +- .github/workflows/release.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/basic-check.yml b/.github/workflows/basic-check.yml index 4a644e87..09e6a01d 100644 --- a/.github/workflows/basic-check.yml +++ b/.github/workflows/basic-check.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: [1.16.8, 1.17.5] + go: [1.16.14, 1.17.7] steps: - name: Set up Go uses: actions/setup-go@v2 diff --git a/.github/workflows/full-sync-part-1.yml b/.github/workflows/full-sync-part-1.yml index 280fb2b2..6f831d96 100644 --- a/.github/workflows/full-sync-part-1.yml +++ b/.github/workflows/full-sync-part-1.yml @@ -14,7 +14,7 @@ jobs: runs-on: self-hosted strategy: matrix: - go: [1.17.5] + go: [1.17.7] steps: - run: | echo "Note ${{ github.event.inputs.note }}!" diff --git a/.github/workflows/full-sync-part-2.yml b/.github/workflows/full-sync-part-2.yml index bc72cf62..d4c672fd 100644 --- a/.github/workflows/full-sync-part-2.yml +++ b/.github/workflows/full-sync-part-2.yml @@ -14,7 +14,7 @@ jobs: runs-on: self-hosted strategy: matrix: - go: [1.17.5] + go: [1.17.7] steps: - run: | echo "Note ${{ github.event.inputs.note }}!" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5ab6d24b..dee83027 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.17.5 + go-version: 1.17.7 - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 -- 2.45.2 From 1bab29aa69f229173d0e3875abab80325dfd8138 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 15 Feb 2022 23:08:44 -0800 Subject: [PATCH 191/459] wip: update getrawmempool and implement getmempoolentry TODO:: 1. Populate Ancestor and decsendent related fields instead of mocking. 2. Move and refator the implementation of getmempoolentry to the mempool package. --- btcjson/chainsvrresults.go | 1 + mempool/mempool.go | 44 +++++++++++++++++-------------- rpcserver.go | 53 ++++++++++++++++++++++++++++++++++++-- rpcserverhelp.go | 29 +++++++++++++++++++++ 4 files changed, 106 insertions(+), 21 deletions(-) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 811883c7..ffa0a103 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -323,6 +323,7 @@ type GetMempoolEntryResult struct { WTxId string `json:"wtxid"` Fees MempoolFees `json:"fees"` Depends []string `json:"depends"` + SpentBy []string `json:"spentby"` } // GetChainTipsResult models the data returns from the getchaintips command. diff --git a/mempool/mempool.go b/mempool/mempool.go index a2dc5c20..45cf602b 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -1507,36 +1507,42 @@ func (mp *TxPool) MiningDescs() []*mining.TxDesc { // populated btcjson result. // // This function is safe for concurrent access. -func (mp *TxPool) RawMempoolVerbose() map[string]*btcjson.GetRawMempoolVerboseResult { +func (mp *TxPool) RawMempoolVerbose() map[string]*btcjson.GetMempoolEntryResult { mp.mtx.RLock() defer mp.mtx.RUnlock() - result := make(map[string]*btcjson.GetRawMempoolVerboseResult, + result := make(map[string]*btcjson.GetMempoolEntryResult, len(mp.pool)) - bestHeight := mp.cfg.BestHeight() for _, desc := range mp.pool { // Calculate the current priority based on the inputs to // the transaction. Use zero if one or more of the // input transactions can't be found for some reason. tx := desc.Tx - var currentPriority float64 - utxos, err := mp.fetchInputUtxos(tx) - if err == nil { - currentPriority = mining.CalcPriority(tx.MsgTx(), utxos, - bestHeight+1) - } - mpd := &btcjson.GetRawMempoolVerboseResult{ - Size: int32(tx.MsgTx().SerializeSize()), - Vsize: int32(GetTxVirtualSize(tx)), - Weight: int32(blockchain.GetTransactionWeight(tx)), - Fee: btcutil.Amount(desc.Fee).ToBTC(), - Time: desc.Added.Unix(), - Height: int64(desc.Height), - StartingPriority: desc.StartingPriority, - CurrentPriority: currentPriority, - Depends: make([]string, 0), + mpd := &btcjson.GetMempoolEntryResult{ + VSize: int32(GetTxVirtualSize(tx)), + Size: int32(tx.MsgTx().SerializeSize()), + Weight: blockchain.GetTransactionWeight(tx), + Fee: btcutil.Amount(desc.Fee).ToBTC(), + ModifiedFee: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + Time: desc.Added.Unix(), + Height: int64(desc.Height), + DescendantCount: 1, // TODO + DescendantSize: GetTxVirtualSize(tx), // TODO + DescendantFees: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + AncestorCount: 1, // TODO + AncestorSize: GetTxVirtualSize(tx), // TODO + AncestorFees: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + WTxId: desc.Tx.WitnessHash().String(), + Fees: btcjson.MempoolFees{ + Base: btcutil.Amount(desc.Fee).ToBTC(), + Modified: btcutil.Amount(desc.Fee).ToBTC(), // TODO + Ancestor: btcutil.Amount(desc.Fee).ToBTC(), // TODO + Descendant: btcutil.Amount(desc.Fee).ToBTC(), // TODO + }, + Depends: make([]string, 0), // TODO + SpentBy: make([]string, 0), // TODO } for _, txIn := range tx.MsgTx().TxIn { hash := &txIn.PreviousOutPoint.Hash diff --git a/rpcserver.go b/rpcserver.go index baccf7fe..23fb126e 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -161,6 +161,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getheaders": handleGetHeaders, "getinfo": handleGetInfo, "getmempoolinfo": handleGetMempoolInfo, + "getmempoolentry": handleGetMempoolEntry, "getmininginfo": handleGetMiningInfo, "getnettotals": handleGetNetTotals, "getnetworkhashps": handleGetNetworkHashPS, @@ -239,8 +240,6 @@ var rpcAskWallet = map[string]struct{}{ // Commands that are currently unimplemented, but should ultimately be. var rpcUnimplemented = map[string]struct{}{ "estimatepriority": {}, - "getchaintips": {}, - "getmempoolentry": {}, "getwork": {}, "preciousblock": {}, } @@ -2483,6 +2482,56 @@ func handleGetMempoolInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct return ret, nil } +// handleGetMempoolEntry implements the getmempoolentry command. +func handleGetMempoolEntry(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetMempoolEntryCmd) + txHash, err := chainhash.NewHashFromStr(c.TxID) + if err != nil { + if err != nil { + return nil, rpcDecodeHexError(c.TxID) + } + } + + mp := s.cfg.TxMemPool + for _, desc := range mp.TxDescs() { + tx := desc.Tx + if tx.Hash().IsEqual(txHash) { + continue + } + desc.Tx.WitnessHash() + + ret := &btcjson.GetMempoolEntryResult{ + VSize: int32(mempool.GetTxVirtualSize(tx)), + Size: int32(tx.MsgTx().SerializeSize()), + Weight: blockchain.GetTransactionWeight(tx), + Fee: btcutil.Amount(desc.Fee).ToBTC(), + ModifiedFee: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + Time: desc.Added.Unix(), + Height: int64(desc.Height), + DescendantCount: 1, // TODO + DescendantSize: mempool.GetTxVirtualSize(tx), // TODO + DescendantFees: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + AncestorCount: 1, // TODO + AncestorSize: mempool.GetTxVirtualSize(tx), // TODO + AncestorFees: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + WTxId: desc.Tx.WitnessHash().String(), + Fees: btcjson.MempoolFees{ + Base: btcutil.Amount(desc.Fee).ToBTC(), + Modified: btcutil.Amount(desc.Fee).ToBTC(), // TODO + Ancestor: btcutil.Amount(desc.Fee).ToBTC(), // TODO + Descendant: btcutil.Amount(desc.Fee).ToBTC(), // TODO + }, + Depends: make([]string, 0), // TODO + SpentBy: make([]string, 0), // TODO + } + + return ret, nil + } + + return nil, rpcNoTxInfoError(txHash) +} + // handleGetMiningInfo implements the getmininginfo command. We only return the // fields that are not related to wallet functionality. func handleGetMiningInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 881cfeb5..4cfde4d3 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -470,6 +470,34 @@ var helpDescsEnUS = map[string]string{ "getmininginforesult-pooledtx": "Number of transactions in the memory pool", "getmininginforesult-testnet": "Whether or not server is using testnet", + "mempoolfees-base": "Transaction fee in LBC", + "mempoolfees-modified": "Transaction fee with fee deltas used for mining priority in LBC", + "mempoolfees-ancestor": "Modified fees (see above) of in-mempool ancestors (including this one) in LBC", + "mempoolfees-descendant": "modified fees (see above) of in-mempool descendants (including this one) in LBC", + + // GetMempoolEntryCmd help. + "getmempoolentry--synopsis": "Returns mempool data for given transaction.", + "getmempoolentry-txid": "The hash of the transaction", + + // GetMempoolEntryResult help. + "getmempoolentryresult-vsize": "Virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted.", + "getmempoolentryresult-size": "(DEPRECATED) same as vsize. ", + "getmempoolentryresult-weight": "Transaction weight as defined in BIP 141.", + "getmempoolentryresult-fee": "(DEPRECATED)Transaction fee in LBC", + "getmempoolentryresult-modifiedfee": "(DEPRECATED)Transaction fee with fee deltas used for mining priority", + "getmempoolentryresult-time": "Local time transaction entered pool in seconds since 1 Jan 1970 GMT", + "getmempoolentryresult-height": "Block height when transaction entered pool", + "getmempoolentryresult-descendantcount": "Number of in-mempool descendant transactions (including this one)", + "getmempoolentryresult-descendantsize": "Virtual transaction size of in-mempool descendants (including this one)", + "getmempoolentryresult-descendantfees": "(DEPRECATED)Modified fees (see above) of in-mempool descendants (including this one)", + "getmempoolentryresult-ancestorcount": "Number of in-mempool ancestor transactions (including this one)", + "getmempoolentryresult-ancestorsize": "Virtual transaction size of in-mempool ancestors (including this one)", + "getmempoolentryresult-ancestorfees": "(DEPRECATED)Modified fees (see above) of in-mempool ancestors (including this one)", + "getmempoolentryresult-wtxid": "hash of serialized transaction, including witness data", + "getmempoolentryresult-fees": "(json object)", + "getmempoolentryresult-depends": "Unconfirmed transactions used as inputs for this transaction", + "getmempoolentryresult-spentby": "Unconfirmed transactions spending outputs from this transaction", + // GetMiningInfoCmd help. "getmininginfo--synopsis": "Returns a JSON object containing mining-related information.", @@ -872,6 +900,7 @@ var rpcResultTypes = map[string][]interface{}{ "gethashespersec": {(*float64)(nil)}, "getheaders": {(*[]string)(nil)}, "getinfo": {(*btcjson.InfoChainResult)(nil)}, + "getmempoolentry": {(*btcjson.GetMempoolEntryResult)(nil)}, "getmempoolinfo": {(*btcjson.GetMempoolInfoResult)(nil)}, "getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)}, "getnettotals": {(*btcjson.GetNetTotalsResult)(nil)}, -- 2.45.2 From 9e352f8141f96354514ab10e3178c44d0aaa4f19 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 19 Apr 2022 18:51:23 -0700 Subject: [PATCH 192/459] ci: bump to Go 1.18.1 --- .github/workflows/basic-check.yml | 2 +- .github/workflows/full-sync-part-1.yml | 2 +- .github/workflows/full-sync-part-2.yml | 2 +- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/release.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/basic-check.yml b/.github/workflows/basic-check.yml index 09e6a01d..c0ef7b2a 100644 --- a/.github/workflows/basic-check.yml +++ b/.github/workflows/basic-check.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: [1.16.14, 1.17.7] + go: [1.18.1, 1.17.7] steps: - name: Set up Go uses: actions/setup-go@v2 diff --git a/.github/workflows/full-sync-part-1.yml b/.github/workflows/full-sync-part-1.yml index 6f831d96..a13bf2f7 100644 --- a/.github/workflows/full-sync-part-1.yml +++ b/.github/workflows/full-sync-part-1.yml @@ -14,7 +14,7 @@ jobs: runs-on: self-hosted strategy: matrix: - go: [1.17.7] + go: [1.18.1] steps: - run: | echo "Note ${{ github.event.inputs.note }}!" diff --git a/.github/workflows/full-sync-part-2.yml b/.github/workflows/full-sync-part-2.yml index d4c672fd..756bfa66 100644 --- a/.github/workflows/full-sync-part-2.yml +++ b/.github/workflows/full-sync-part-2.yml @@ -14,7 +14,7 @@ jobs: runs-on: self-hosted strategy: matrix: - go: [1.17.7] + go: [1.18.1] steps: - run: | echo "Note ${{ github.event.inputs.note }}!" diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index b0a478d4..70df90d6 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -4,7 +4,7 @@ env: # go needs absolute directories, using the $HOME variable doesn't work here. GOCACHE: /home/runner/work/go/pkg/build GOPATH: /home/runner/work/go - GO_VERSION: '^1.17.0' + GO_VERSION: '^1.18.1' on: push: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dee83027..64444cf1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.17.7 + go-version: 1.18.1 - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 -- 2.45.2 From d3bfed9a66e31a7e7e29a5842ef47fb0aa7a2a33 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 19 Apr 2022 19:01:56 -0700 Subject: [PATCH 193/459] mempool: fix ia lint error in test thanks to @moodyjon --- mempool/mempool_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index b4070dd7..17d2d452 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -560,7 +560,7 @@ func TestOrphanReject(t *testing.T) { // Ensure no transactions were reported as accepted. if len(acceptedTxns) != 0 { - t.Fatal("ProcessTransaction: reported %d accepted "+ + t.Fatalf("ProcessTransaction: reported %d accepted "+ "transactions from failed orphan attempt", len(acceptedTxns)) } -- 2.45.2 From 4cb86f88208549d80f16b999911417ea8aa7f337 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Tue, 19 Apr 2022 15:31:00 -0400 Subject: [PATCH 194/459] Embed sample-lbcd.conf contents at build time. Use embedded config if the sample-lbcd.conf is not found at runtime. --- config.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/config.go b/config.go index 15b80921..c1c181cf 100644 --- a/config.go +++ b/config.go @@ -7,6 +7,7 @@ package main import ( "bufio" "crypto/rand" + _ "embed" "encoding/base64" "encoding/hex" "errors" @@ -78,6 +79,9 @@ var ( defaultLogDir = filepath.Join(defaultHomeDir, defaultLogDirname) ) +//go:embed sample-lbcd.conf +var sampleConfig string + // runServiceCommand is only set to a real function on Windows. It is used // to parse and execute service commands specified via the -s flag. var runServiceCommand func(string) error @@ -1176,11 +1180,15 @@ func createDefaultConfigFile(destinationPath string) error { } generatedRPCPass := base64.StdEncoding.EncodeToString(randomBytes) + var reader *bufio.Reader src, err := os.Open(sampleConfigPath) if err != nil { - return err + // Fall back to sample config embedded at build time. + reader = bufio.NewReader(strings.NewReader(sampleConfig)) + } else { + reader = bufio.NewReader(src) + defer src.Close() } - defer src.Close() dest, err := os.OpenFile(destinationPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) @@ -1191,7 +1199,6 @@ func createDefaultConfigFile(destinationPath string) error { // We copy every line from the sample config file to the destination, // only replacing the two lines for rpcuser and rpcpass - reader := bufio.NewReader(src) for err != io.EOF { var line string line, err = reader.ReadString('\n') -- 2.45.2 From 4772e2e7fb4fc46312883993db69ca9a45971cad Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:30:24 -0400 Subject: [PATCH 195/459] Add a number of missing options to sample-lbcd.conf. Note that "noupnp" appears to be the successor to "upnp" which is no longer supported. Correct "blacklist is applied before the blacklist" typo in help text. --- config.go | 2 +- sample-lbcd.conf | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/config.go b/config.go index c1c181cf..15758a7d 100644 --- a/config.go +++ b/config.go @@ -103,7 +103,7 @@ type config struct { AddPeers []string `short:"a" long:"addpeer" description:"Add a peer to connect with at startup"` AddrIndex bool `long:"addrindex" description:"Maintain a full address-based transaction index which makes the searchrawtransactions RPC available"` AgentBlacklist []string `long:"agentblacklist" description:"A comma separated list of user-agent substrings which will cause lbcd to reject any peers whose user-agent contains any of the blacklisted substrings."` - AgentWhitelist []string `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause lbcd to require all peers' user-agents to contain one of the whitelisted substrings. The blacklist is applied before the blacklist, and an empty whitelist will allow all agents that do not fail the blacklist."` + AgentWhitelist []string `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause lbcd to require all peers' user-agents to contain one of the whitelisted substrings. The blacklist is applied before the whitelist, and an empty whitelist will allow all agents that do not fail the blacklist."` BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"` BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."` BlockMaxSize uint32 `long:"blockmaxsize" description:"Maximum block size in bytes to be used when creating a block"` diff --git a/sample-lbcd.conf b/sample-lbcd.conf index dbff2949..34af9327 100644 --- a/sample-lbcd.conf +++ b/sample-lbcd.conf @@ -46,10 +46,10 @@ ; to correlate connections. ; torisolation=1 -; Use Universal Plug and Play (UPnP) to automatically open the listen port +; Do NOT use Universal Plug and Play (UPnP) to automatically open the listen port ; and obtain the external IP address from supported devices. NOTE: This option ; will have no effect if exernal IP addresses are specified. -; upnp=1 +; noupnp=0 ; Specify the external IP addresses your node is listening on. One address per ; line. lbcd will not contact 3rd-party sites to obtain external ip addresses. @@ -114,6 +114,9 @@ ; banduration=24h ; banduration=11h30m15s +; Minimum time between attempts to send new inventory to a connected peer. +; trickleinterval=10s + ; Add whitelisted IP networks and IPs. Connected peers whose IP matches a ; whitelist will not have their ban score increased. ; whitelist=127.0.0.1 @@ -167,6 +170,16 @@ ; Must not include characters '/', ':', '(' and ')'. ; uacomment= +; A comma separated list of user-agent substrings which will cause lbcd to reject +; any peers whose user-agent contains any of the blacklisted substrings. +; agentblacklist= + +; A comma separated list of user-agent substrings which will cause lbcd to require +; all peers' user-agents to contain one of the whitelisted substrings. The blacklist +; is applied before the whitelist, and an empty whitelist will allow all agents that +; do not fail the blacklist. +; agentwhitelist= + ; Disable committed peer filtering (CF). ; nocfilters=1 @@ -223,6 +236,9 @@ ; Specify the maximum number of concurrent RPC websocket clients. ; rpcmaxwebsockets=25 +; Max number of concurrent RPC requests that may be processed concurrently. +; rpcmaxconcurrentreqs=20 + ; Mirror some JSON-RPC quirks of Bitcoin Core -- NOTE: Discouraged unless ; interoperability issues need to be worked around ; rpcquirks=1 @@ -237,6 +253,12 @@ ; the default). ; notls=1 +; File containing the certificate file. +; rpccert=~/.lbcd/rpc.cert + +; File containing the certificate key. +; rpckey=~/.lbcd/rpc.key + ; ------------------------------------------------------------------------------ ; Mempool Settings - The following options @@ -264,6 +286,10 @@ ; Reject non-standard transactions regardless of default network settings. ; rejectnonstd=1 +; Reject transactions that attempt to replace existing transactions within +; the mempool through the Replace-By-Fee (RBF) signaling policy. +; rejectreplacement=0 + ; ------------------------------------------------------------------------------ ; Optional Indexes @@ -319,6 +345,12 @@ ; to the consensus limit if it is larger than that value. ; blockmaxsize=750000 +; Mininum block weight to be used when creating a block. +; blockminweight=0 + +; Maximum block weight to be used when creating a block. +; blockmaxweight=3000000 + ; Specify the size in bytes of the high-priority/low-fee area when creating a ; block. Transactions which consist of large amounts, old inputs, and small ; sizes have the highest priority. One consequence of this is that as low-fee @@ -331,6 +363,8 @@ ; ------------------------------------------------------------------------------ ; Debug ; ------------------------------------------------------------------------------ +; Directory to log output. +; logdir=~/.lbcd/logs ; Debug logging level. ; Valid levels are {trace, debug, info, warn, error, critical} @@ -339,6 +373,9 @@ ; available subsystems. ; debuglevel=info +; Write CPU profile to the specified file. +; cpuprofile= + ; The port used to listen for HTTP profile requests. The profile server will ; be disabled if this option is not specified. The profile information can be ; accessed at http://localhost:/debug/pprof once running. -- 2.45.2 From 67b68d39173660d7a745148499a9ae0d2dfa58b5 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:33:36 -0400 Subject: [PATCH 196/459] Verify completeness of sample-lbcd.conf using reflection on config struct. --- config_test.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/config_test.go b/config_test.go index 84e7d444..15953b15 100644 --- a/config_test.go +++ b/config_test.go @@ -1,9 +1,11 @@ package main import ( + "fmt" "io/ioutil" "os" "path/filepath" + "reflect" "regexp" "runtime" "testing" @@ -14,6 +16,108 @@ var ( rpcpassRegexp = regexp.MustCompile("(?m)^rpcpass=.+$") ) +// Define a struct "configCmdLineOnly" containing a subset of configuration +// parameters which are command-line only. These fields are copied line-by-line +// from "config" struct in "config.go", and the field names, types, and tags must +// match for the test to work. +// +type configCmdLineOnly struct { + ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"` + DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` + DropCfIndex bool `long:"dropcfindex" description:"Deletes the index used for committed filtering (CF) support from the database on start up and then exits."` + DropTxIndex bool `long:"droptxindex" description:"Deletes the hash-based transaction index from the database on start up and then exits."` + DisableCheckpoints bool `long:"nocheckpoints" description:"Disable built-in checkpoints. Don't do this unless you know what you're doing."` + NoWinService bool `long:"nowinservice" description:"Do not start as a background service on Windows -- NOTE: This flag only works on the command line, not in the config file"` + DisableStallHandler bool `long:"nostalldetect" description:"Disables the stall handler system for each peer, useful in simnet/regtest integration tests frameworks"` + RegressionTest bool `long:"regtest" description:"Use the regression test network"` + SimNet bool `long:"simnet" description:"Use the simulation test network"` + SigNet bool `long:"signet" description:"Use the signet test network"` + SigNetChallenge string `long:"signetchallenge" description:"Connect to a custom signet network defined by this challenge instead of using the global default signet test network -- Can be specified multiple times"` + SigNetSeedNode []string `long:"signetseednode" description:"Specify a seed node for the signet network instead of using the global default signet network seed nodes"` + ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` +} + +func fieldEq(f1, f2 reflect.StructField) bool { + return (f1.Name == f2.Name) && (f1.Type == f2.Type) && (f1.Tag == f2.Tag) +} + +func TestSampleConfigFileComplete(t *testing.T) { + // find out where the sample config lives + _, path, _, ok := runtime.Caller(0) + if !ok { + t.Fatalf("Failed finding config file path") + } + sampleConfigFile := filepath.Join(filepath.Dir(path), sampleConfigFilename) + + // Read the sample config file + content, err := ioutil.ReadFile(sampleConfigFile) + if err != nil { + t.Fatalf("Failed reading sample config file: %v", err) + } + + allFields := reflect.VisibleFields(reflect.TypeOf(config{})) + cmdlineFields := reflect.VisibleFields(reflect.TypeOf(configCmdLineOnly{})) + + // Verify cmdlineFields is a subset of allFields. + for _, cf := range cmdlineFields { + // Check for presence of field "cf" in config struct. + var field *reflect.StructField + for _, f := range allFields { + f := f // new instance of loop var for return + if fieldEq(cf, f) { + field = &f + break + } + } + if field == nil { + t.Errorf("cmdline field: %s type: %s is not present in type %s", + cf.Name, cf.Type, reflect.TypeOf(config{})) + } + } + + // Verify sample config covers all parameters. + for _, f := range allFields { + longname, ok := f.Tag.Lookup("long") + if !ok { + // Field has no long-form name, so not eligible for + // inclusion in sample config. + continue + } + + // Check for presence of field "f" in our configCmdLineOnly struct. + var cmdline *reflect.StructField + for _, cf := range cmdlineFields { + cf := cf // new instance of loop var for return + if fieldEq(cf, f) { + cmdline = &cf + break + } + } + + // Look for assignment (="), or commented assignment ("; ="). + pattern := fmt.Sprintf("(?m)^(;\\s*)?%s=.*$", longname) + assignment, err := regexp.Compile(pattern) + if err != nil { + t.Errorf("config field: %s longname: %s failed compiling regexp (%s): %v", + f.Name, longname, pattern, err) + continue + } + + assigned := assignment.Match(content) + + // Field "f" must be present in either the sample config (=X), + // or it must be one of the command line only fields, but not both. + if !assigned && (cmdline == nil) { + t.Errorf("config field: %s longname: %s assignment (%s) should be present in %s", + f.Name, longname, assignment, sampleConfigFilename) + } + if assigned && (cmdline != nil) { + t.Errorf("config field: %s longname: %s should not be present in both %s and type %s", + f.Name, longname, sampleConfigFilename, reflect.TypeOf(configCmdLineOnly{}).Name()) + } + } +} + func TestCreateDefaultConfigFile(t *testing.T) { // find out where the sample config lives _, path, _, ok := runtime.Caller(0) -- 2.45.2 From 3f3752628dc20a8d2383b2d43979634e5482c198 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 10 Mar 2022 10:44:54 -0800 Subject: [PATCH 197/459] .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 11125e86..2095e17a 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ lbcctl # CI artifacts dist +debug -- 2.45.2 From 9b313b3914899cff81e0e9b9e35c74729b92d90b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 19 Apr 2022 18:41:17 -0700 Subject: [PATCH 198/459] rpc: log the reason of submitblock rejection --- rpcserver.go | 1 + 1 file changed, 1 insertion(+) diff --git a/rpcserver.go b/rpcserver.go index 23fb126e..0724a757 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3882,6 +3882,7 @@ func handleSubmitBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) // nodes. This will in turn relay it to the network like normal. _, err = s.cfg.SyncMgr.SubmitBlock(block, blockchain.BFNone) if err != nil { + rpcsLog.Infof("Rejected block %s via submitblock: %s", block.Hash(), err) return fmt.Sprintf("rejected: %s", err.Error()), nil } -- 2.45.2 From 240eebe403fa5277c25f742e6226e51b9d2d222f Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 24 Apr 2022 22:36:13 -0700 Subject: [PATCH 199/459] docker: update to Go 1.18.1 and debian:bullseye-slim as base --- Dockerfile | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 17009ce2..d52b168a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,20 +11,14 @@ # For more information how to use this docker image visit: # https://github.com/lbryio/lbcd/tree/master/docs # -# 9246 Mainnet Bitcoin peer-to-peer port +# 9246 Mainnet LBRY peer-to-peer port # 9245 Mainet RPC port ARG ARCH=amd64 -# using the SHA256 instead of tags -# https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests -# https://cloud.google.com/architecture/using-container-images -# https://github.com/google/go-containerregistry/blob/main/cmd/crane/README.md -# ➜ ~ crane digest golang:1.16-alpine3.12 -# sha256:db2475a1dbb2149508e5db31d7d77a75e6600d54be645f37681f03f2762169ba -FROM golang@sha256:db2475a1dbb2149508e5db31d7d77a75e6600d54be645f37681f03f2762169ba AS build-container + +FROM golang:1.18.1 AS build-container ARG ARCH -ENV GO111MODULE=on ADD . /app WORKDIR /app @@ -35,7 +29,7 @@ RUN set -ex \ && echo "Compiling for $GOARCH" \ && go install -v . ./cmd/... -FROM $ARCH/alpine:3.12 +FROM $ARCH/debian:bullseye-20220418-slim COPY --from=build-container /go/bin /bin -- 2.45.2 From 7bb4dd677aa4070b27c2f3411eb3d24441445437 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 5 May 2022 10:51:20 -0400 Subject: [PATCH 200/459] don't recall appendchanges from dropchanges --- claimtrie/node/noderepo/pebble.go | 38 ++++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/claimtrie/node/noderepo/pebble.go b/claimtrie/node/noderepo/pebble.go index a13dda82..cb5d25e4 100644 --- a/claimtrie/node/noderepo/pebble.go +++ b/claimtrie/node/noderepo/pebble.go @@ -21,7 +21,6 @@ func NewPebble(path string) (*Pebble, error) { return repo, errors.Wrapf(err, "unable to open %s", path) } -// AppendChanges makes an assumption that anything you pass to it is newer than what was saved before. func (repo *Pebble) AppendChanges(changes []change.Change) error { batch := repo.db.NewBatch() @@ -62,6 +61,7 @@ func unmarshalChanges(name, data []byte) ([]change.Change, error) { changes := make([]change.Change, 0, len(data)/84+1) // average is 5.1 changes buffer := bytes.NewBuffer(data) + sortNeeded := false for buffer.Len() > 0 { var chg change.Change err := chg.Unmarshal(buffer) @@ -69,14 +69,18 @@ func unmarshalChanges(name, data []byte) ([]change.Change, error) { return nil, errors.Wrap(err, "in decode") } chg.Name = name + if len(changes) > 0 && chg.Height < changes[len(changes)-1].Height { + sortNeeded = true // alternately: sortNeeded || chg.Height != chg.VisibleHeight + } changes = append(changes, chg) } - // this was required for the normalization stuff: - sort.SliceStable(changes, func(i, j int) bool { - return changes[i].Height < changes[j].Height - }) - + if sortNeeded { + // this was required for the normalization stuff: + sort.SliceStable(changes, func(i, j int) bool { + return changes[i].Height < changes[j].Height + }) + } return changes, nil } @@ -85,22 +89,24 @@ func (repo *Pebble) DropChanges(name []byte, finalHeight int32) error { if err != nil { return errors.Wrapf(err, "in load changes for %s", name) } - i := 0 - for ; i < len(changes); i++ { // assuming changes are ordered by height + buffer := bytes.NewBuffer(nil) + for i := 0; i < len(changes); i++ { // assuming changes are ordered by height if changes[i].Height > finalHeight { break } - if changes[i].VisibleHeight > finalHeight { // created after this height has to be deleted - changes = append(changes[:i], changes[i+1:]...) - i-- + if changes[i].VisibleHeight > finalHeight { // created after this height has to be skipped + continue + } + // having to sort the changes really messes up performance here. It would be better to not remarshal + err := changes[i].Marshal(buffer) + if err != nil { + return errors.Wrap(err, "in marshaller") } } + // making a performance assumption that DropChanges won't happen often: - err = repo.db.Set(name, []byte{}, pebble.NoSync) - if err != nil { - return errors.Wrapf(err, "in set at %s", name) - } - return repo.AppendChanges(changes[:i]) + err = repo.db.Set(name, buffer.Bytes(), pebble.NoSync) + return errors.Wrapf(err, "in set at %s", name) } func (repo *Pebble) IterateChildren(name []byte, f func(changes []change.Change) bool) error { -- 2.45.2 From f59366c60deb058da652b44785bd75e76e5de24f Mon Sep 17 00:00:00 2001 From: Brannon King Date: Mon, 9 May 2022 10:46:40 -0400 Subject: [PATCH 201/459] make the miner not persist node changes fix formatting --- blockchain/claimtrie.go | 2 +- claimtrie/claimtrie.go | 16 +++--- claimtrie/claimtrie_test.go | 6 +-- claimtrie/cmd/cmd/chain.go | 2 +- claimtrie/node/manager.go | 51 ++++++++++++++----- claimtrie/node/manager_test.go | 73 ++++++++++++++++++++++----- claimtrie/node/normalizing_manager.go | 6 +-- 7 files changed, 117 insertions(+), 39 deletions(-) diff --git a/blockchain/claimtrie.go b/blockchain/claimtrie.go index b9913203..f821537a 100644 --- a/blockchain/claimtrie.go +++ b/blockchain/claimtrie.go @@ -44,7 +44,7 @@ func (b *BlockChain) ParseClaimScripts(block *btcutil.Block, bn *blockNode, view } } - err := b.claimTrie.AppendBlock() + err := b.claimTrie.AppendBlock(bn == nil) if err != nil { return errors.Wrapf(err, "in append block") } diff --git a/claimtrie/claimtrie.go b/claimtrie/claimtrie.go index 05d423be..68ef6488 100644 --- a/claimtrie/claimtrie.go +++ b/claimtrie/claimtrie.go @@ -133,7 +133,7 @@ func New(cfg config.Config) (*ClaimTrie, error) { ct.Close() // TODO: the cleanups aren't run when we exit with an err above here (but should be) return nil, errors.Wrap(err, "block repo get") } - _, err = nodeManager.IncrementHeightTo(previousHeight) + _, err = nodeManager.IncrementHeightTo(previousHeight, false) if err != nil { ct.Close() return nil, errors.Wrap(err, "increment height to") @@ -221,11 +221,11 @@ func (ct *ClaimTrie) SpendSupport(name []byte, op wire.OutPoint, id change.Claim } // AppendBlock increases block by one. -func (ct *ClaimTrie) AppendBlock() error { +func (ct *ClaimTrie) AppendBlock(temporary bool) error { ct.height++ - names, err := ct.nodeManager.IncrementHeightTo(ct.height) + names, err := ct.nodeManager.IncrementHeightTo(ct.height, temporary) if err != nil { return errors.Wrap(err, "node manager increment") } @@ -258,7 +258,7 @@ func (ct *ClaimTrie) AppendBlock() error { updateNames = append(updateNames, newName) updateHeights = append(updateHeights, nhn.Next) } - if len(updateNames) != 0 { + if !temporary && len(updateNames) > 0 { err = ct.temporalRepo.SetNodesAt(updateNames, updateHeights) if err != nil { return errors.Wrap(err, "temporal repo set") @@ -266,9 +266,11 @@ func (ct *ClaimTrie) AppendBlock() error { } hitFork := ct.updateTrieForHashForkIfNecessary() - h := ct.MerkleHash() - ct.blockRepo.Set(ct.height, h) + + if !temporary { + ct.blockRepo.Set(ct.height, h) + } if hitFork { err = ct.merkleTrie.SetRoot(h) // for clearing the memory entirely @@ -311,7 +313,7 @@ func (ct *ClaimTrie) ResetHeight(height int32) error { } names = append(names, results...) } - err := ct.nodeManager.DecrementHeightTo(names, height) + names, err := ct.nodeManager.DecrementHeightTo(names, height) if err != nil { return err } diff --git a/claimtrie/claimtrie_test.go b/claimtrie/claimtrie_test.go index 7cd1432b..61194f1a 100644 --- a/claimtrie/claimtrie_test.go +++ b/claimtrie/claimtrie_test.go @@ -81,7 +81,7 @@ func TestEmptyHashFork(t *testing.T) { defer ct.Close() for i := 0; i < 5; i++ { - err := ct.AppendBlock() + err := ct.AppendBlock(false) r.NoError(err) } } @@ -378,7 +378,7 @@ func incrementBlock(r *require.Assertions, ct *ClaimTrie, c int32) { r.NoError(err) } else { for ; c > 0; c-- { - err := ct.AppendBlock() + err := ct.AppendBlock(false) r.NoError(err) } } @@ -996,7 +996,7 @@ func TestBlock884431(t *testing.T) { o6 := add("testing", 20) for i := 0; i < 10; i++ { - err = ct.AppendBlock() + err = ct.AppendBlock(false) r.NoError(err) } n, err := ct.NodeAt(ct.height, []byte("go")) diff --git a/claimtrie/cmd/cmd/chain.go b/claimtrie/cmd/cmd/chain.go index 92e52816..b16ec599 100644 --- a/claimtrie/cmd/cmd/chain.go +++ b/claimtrie/cmd/cmd/chain.go @@ -193,7 +193,7 @@ func NewChainReplayCommand() *cobra.Command { func appendBlock(ct *claimtrie.ClaimTrie, chain *blockchain.BlockChain) error { - err := ct.AppendBlock() + err := ct.AppendBlock(false) if err != nil { return errors.Wrapf(err, "append block: %w") } diff --git a/claimtrie/node/manager.go b/claimtrie/node/manager.go index 605b7123..814bfc80 100644 --- a/claimtrie/node/manager.go +++ b/claimtrie/node/manager.go @@ -13,8 +13,8 @@ import ( type Manager interface { AppendChange(chg change.Change) - IncrementHeightTo(height int32) ([][]byte, error) - DecrementHeightTo(affectedNames [][]byte, height int32) error + IncrementHeightTo(height int32, temporary bool) ([][]byte, error) + DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) Height() int32 Close() error NodeAt(height int32, name []byte) (*Node, error) @@ -28,6 +28,8 @@ type BaseManager struct { height int32 changes []change.Change + + tempChanges map[string][]change.Change } func NewBaseManager(repo Repo) (*BaseManager, error) { @@ -46,6 +48,10 @@ func (nm *BaseManager) NodeAt(height int32, name []byte) (*Node, error) { return nil, errors.Wrap(err, "in load changes") } + if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block + changes = append(changes, nm.tempChanges[string(name)]...) + } + n, err := nm.newNodeFromChanges(changes, height) if err != nil { return nil, errors.Wrap(err, "in new node") @@ -187,7 +193,7 @@ func collectChildNames(changes []change.Change) { // } //} -func (nm *BaseManager) IncrementHeightTo(height int32) ([][]byte, error) { +func (nm *BaseManager) IncrementHeightTo(height int32, temporary bool) ([][]byte, error) { if height <= nm.height { panic("invalid height") @@ -198,13 +204,25 @@ func (nm *BaseManager) IncrementHeightTo(height int32) ([][]byte, error) { collectChildNames(nm.changes) } + if temporary { + if nm.tempChanges != nil { + return nil, errors.Errorf("expected nil temporary changes") + } + nm.tempChanges = map[string][]change.Change{} + } names := make([][]byte, 0, len(nm.changes)) for i := range nm.changes { names = append(names, nm.changes[i].Name) + if temporary { + name := string(nm.changes[i].Name) + nm.tempChanges[name] = append(nm.tempChanges[name], nm.changes[i]) + } } - if err := nm.repo.AppendChanges(nm.changes); err != nil { // destroys names - return nil, errors.Wrap(err, "in append changes") + if !temporary { + if err := nm.repo.AppendChanges(nm.changes); err != nil { // destroys names + return nil, errors.Wrap(err, "in append changes") + } } // Truncate the buffer size to zero. @@ -218,20 +236,29 @@ func (nm *BaseManager) IncrementHeightTo(height int32) ([][]byte, error) { return names, nil } -func (nm *BaseManager) DecrementHeightTo(affectedNames [][]byte, height int32) error { +func (nm *BaseManager) DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) { if height >= nm.height { - return errors.Errorf("invalid height of %d for %d", height, nm.height) + return affectedNames, errors.Errorf("invalid height of %d for %d", height, nm.height) } - for _, name := range affectedNames { - if err := nm.repo.DropChanges(name, height); err != nil { - return errors.Wrap(err, "in drop changes") + if nm.tempChanges != nil { + if height != nm.height-1 { + return affectedNames, errors.Errorf("invalid temporary rollback at %d to %d", height, nm.height) + } + for key := range nm.tempChanges { + affectedNames = append(affectedNames, []byte(key)) + } + nm.tempChanges = nil + } else { + for _, name := range affectedNames { + if err := nm.repo.DropChanges(name, height); err != nil { + return affectedNames, errors.Wrap(err, "in drop changes") + } } } - nm.height = height - return nil + return affectedNames, nil } func (nm *BaseManager) getDelayForName(n *Node, chg change.Change) int32 { diff --git a/claimtrie/node/manager_test.go b/claimtrie/node/manager_test.go index 705080c8..c907bb4c 100644 --- a/claimtrie/node/manager_test.go +++ b/claimtrie/node/manager_test.go @@ -54,17 +54,17 @@ func TestSimpleAddClaim(t *testing.T) { r.NoError(err) defer m.Close() - _, err = m.IncrementHeightTo(10) + _, err = m.IncrementHeightTo(10, false) r.NoError(err) chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11) m.AppendChange(chg) - _, err = m.IncrementHeightTo(11) + _, err = m.IncrementHeightTo(11, false) r.NoError(err) chg = chg.SetName(name2).SetOutPoint(out2).SetHeight(12) m.AppendChange(chg) - _, err = m.IncrementHeightTo(12) + _, err = m.IncrementHeightTo(12, false) r.NoError(err) n1, err := m.node(name1) @@ -77,13 +77,13 @@ func TestSimpleAddClaim(t *testing.T) { r.Equal(1, len(n2.Claims)) r.NotNil(n2.Claims.find(byOut(*out2))) - err = m.DecrementHeightTo([][]byte{name2}, 11) + _, err = m.DecrementHeightTo([][]byte{name2}, 11) r.NoError(err) n2, err = m.node(name2) r.NoError(err) r.Nil(n2) - err = m.DecrementHeightTo([][]byte{name1}, 1) + _, err = m.DecrementHeightTo([][]byte{name1}, 1) r.NoError(err) n2, err = m.node(name1) r.NoError(err) @@ -102,7 +102,7 @@ func TestSupportAmounts(t *testing.T) { r.NoError(err) defer m.Close() - _, err = m.IncrementHeightTo(10) + _, err = m.IncrementHeightTo(10, false) r.NoError(err) chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11).SetAmount(3) @@ -113,7 +113,7 @@ func TestSupportAmounts(t *testing.T) { chg.ClaimID = change.NewClaimID(*out2) m.AppendChange(chg) - _, err = m.IncrementHeightTo(11) + _, err = m.IncrementHeightTo(11, false) r.NoError(err) chg = change.NewChange(change.AddSupport).SetName(name1).SetOutPoint(out3).SetHeight(12).SetAmount(2) @@ -128,7 +128,7 @@ func TestSupportAmounts(t *testing.T) { chg.ClaimID = change.NewClaimID(*out2) m.AppendChange(chg) - _, err = m.IncrementHeightTo(20) + _, err = m.IncrementHeightTo(20, false) r.NoError(err) n1, err := m.node(name1) @@ -194,14 +194,14 @@ func TestHasChildren(t *testing.T) { chg := change.NewChange(change.AddClaim).SetName([]byte("a")).SetOutPoint(out1).SetHeight(1).SetAmount(2) chg.ClaimID = change.NewClaimID(*out1) m.AppendChange(chg) - _, err = m.IncrementHeightTo(1) + _, err = m.IncrementHeightTo(1, false) r.NoError(err) r.False(m.hasChildren([]byte("a"), 1, nil, 1)) chg = change.NewChange(change.AddClaim).SetName([]byte("ab")).SetOutPoint(out2).SetHeight(2).SetAmount(2) chg.ClaimID = change.NewClaimID(*out2) m.AppendChange(chg) - _, err = m.IncrementHeightTo(2) + _, err = m.IncrementHeightTo(2, false) r.NoError(err) r.False(m.hasChildren([]byte("a"), 2, nil, 2)) r.True(m.hasChildren([]byte("a"), 2, nil, 1)) @@ -209,14 +209,14 @@ func TestHasChildren(t *testing.T) { chg = change.NewChange(change.AddClaim).SetName([]byte("abc")).SetOutPoint(out3).SetHeight(3).SetAmount(2) chg.ClaimID = change.NewClaimID(*out3) m.AppendChange(chg) - _, err = m.IncrementHeightTo(3) + _, err = m.IncrementHeightTo(3, false) r.NoError(err) r.False(m.hasChildren([]byte("a"), 3, nil, 2)) chg = change.NewChange(change.AddClaim).SetName([]byte("ac")).SetOutPoint(out1).SetHeight(4).SetAmount(2) chg.ClaimID = change.NewClaimID(*out4) m.AppendChange(chg) - _, err = m.IncrementHeightTo(4) + _, err = m.IncrementHeightTo(4, false) r.NoError(err) r.True(m.hasChildren([]byte("a"), 4, nil, 2)) } @@ -248,3 +248,52 @@ func TestCollectChildren(t *testing.T) { r.Len(c[7].SpentChildren, 0) } + +func TestTemporaryAddClaim(t *testing.T) { + + r := require.New(t) + + param.SetNetwork(wire.TestNet) + repo, err := noderepo.NewPebble(t.TempDir()) + r.NoError(err) + + m, err := NewBaseManager(repo) + r.NoError(err) + defer m.Close() + + _, err = m.IncrementHeightTo(10, false) + r.NoError(err) + + chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(11, false) + r.NoError(err) + + chg = chg.SetName(name2).SetOutPoint(out2).SetHeight(12) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(12, true) + r.NoError(err) + + n1, err := m.node(name1) + r.NoError(err) + r.Equal(1, len(n1.Claims)) + r.NotNil(n1.Claims.find(byOut(*out1))) + + n2, err := m.node(name2) + r.NoError(err) + r.Equal(1, len(n2.Claims)) + r.NotNil(n2.Claims.find(byOut(*out2))) + + names, err := m.DecrementHeightTo([][]byte{name2}, 11) + r.Equal(names[0], name2) + r.NoError(err) + n2, err = m.node(name2) + r.NoError(err) + r.Nil(n2) + + _, err = m.DecrementHeightTo([][]byte{name1}, 1) + r.NoError(err) + n2, err = m.node(name1) + r.NoError(err) + r.Nil(n2) +} diff --git a/claimtrie/node/normalizing_manager.go b/claimtrie/node/normalizing_manager.go index d35403cd..2f6c4cfe 100644 --- a/claimtrie/node/normalizing_manager.go +++ b/claimtrie/node/normalizing_manager.go @@ -26,12 +26,12 @@ func (nm *NormalizingManager) AppendChange(chg change.Change) { nm.Manager.AppendChange(chg) } -func (nm *NormalizingManager) IncrementHeightTo(height int32) ([][]byte, error) { +func (nm *NormalizingManager) IncrementHeightTo(height int32, temporary bool) ([][]byte, error) { nm.addNormalizationForkChangesIfNecessary(height) - return nm.Manager.IncrementHeightTo(height) + return nm.Manager.IncrementHeightTo(height, temporary) } -func (nm *NormalizingManager) DecrementHeightTo(affectedNames [][]byte, height int32) error { +func (nm *NormalizingManager) DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) { if nm.normalizedAt > height { nm.normalizedAt = -1 } -- 2.45.2 From f28e8d11b85cf55a056ec9a0d91a0986e514c56c Mon Sep 17 00:00:00 2001 From: kodxana Date: Fri, 13 May 2022 00:44:19 +0200 Subject: [PATCH 202/459] Update Dockerfile Enable txindex for docker by default --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index d52b168a..ffa48fd3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,6 +35,8 @@ COPY --from=build-container /go/bin /bin VOLUME ["/root/.lbcd"] +RUN echo "txindex=1" >> /root/.lbcd/lbcd.conf + EXPOSE 9245 9246 ENTRYPOINT ["lbcd"] -- 2.45.2 From 7aa99ae8e125e0c0da93bd79a3a848c0bfd34726 Mon Sep 17 00:00:00 2001 From: kodxana Date: Fri, 13 May 2022 15:45:36 +0200 Subject: [PATCH 203/459] Create docker-publish.yml --- .github/workflows/docker-publish.yml | 91 ++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 .github/workflows/docker-publish.yml diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 00000000..f05001a2 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,91 @@ +name: Docker + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +on: + push: + branches: [ master ] + # Publish semver tags as releases. + tags: [ 'v*.*.*' ] + pull_request: + branches: [ master ] + +env: + # Use docker.io for Docker Hub if empty + REGISTRY: ghcr.io + # github.repository as / + IMAGE_NAME: ${{ github.repository }} + + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Install the cosign tool except on PR + # https://github.com/sigstore/cosign-installer + - name: Install cosign + if: github.event_name != 'pull_request' + uses: sigstore/cosign-installer@d6a3abf1bdea83574e28d40543793018b6035605 + with: + cosign-release: 'v1.7.1' + + + # Workaround: https://github.com/docker/build-push-action/issues/461 + - name: Setup Docker buildx + uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + # Sign the resulting Docker image digest except on PRs. + # This will only write to the public Rekor transparency log when the Docker + # repository is public to avoid leaking data. If you would like to publish + # transparency data even for private images, pass --force to cosign below. + # https://github.com/sigstore/cosign + - name: Sign the published Docker image + if: ${{ github.event_name != 'pull_request' }} + env: + COSIGN_EXPERIMENTAL: "true" + # This step uses the identity token to provision an ephemeral certificate + # against the sigstore community Fulcio instance. + run: cosign sign ${{ steps.meta.outputs.tags }}@${{ steps.build-and-push.outputs.digest }} -- 2.45.2 From 82485f4c50c56841052cecde6fa5eaed0fe1c51b Mon Sep 17 00:00:00 2001 From: kodxana Date: Fri, 13 May 2022 15:47:50 +0200 Subject: [PATCH 204/459] Update Dockerfile --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index ffa48fd3..d52b168a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,8 +35,6 @@ COPY --from=build-container /go/bin /bin VOLUME ["/root/.lbcd"] -RUN echo "txindex=1" >> /root/.lbcd/lbcd.conf - EXPOSE 9245 9246 ENTRYPOINT ["lbcd"] -- 2.45.2 From 6417b262e2b5bbf2c525be147f3faf6ae226cf98 Mon Sep 17 00:00:00 2001 From: kodxana Date: Fri, 13 May 2022 15:48:16 +0200 Subject: [PATCH 205/459] Enable txindex --- sample-lbcd.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sample-lbcd.conf b/sample-lbcd.conf index 34af9327..90f430dd 100644 --- a/sample-lbcd.conf +++ b/sample-lbcd.conf @@ -380,3 +380,5 @@ ; be disabled if this option is not specified. The profile information can be ; accessed at http://localhost:/debug/pprof once running. ; profile=6061 + +txindex=1 -- 2.45.2 From 2c2f76d2d5a2a423db88d9ef2d1a8d84430c3ace Mon Sep 17 00:00:00 2001 From: kodxana Date: Fri, 13 May 2022 15:55:51 +0200 Subject: [PATCH 206/459] Update docker-publish.yml --- .github/workflows/docker-publish.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index f05001a2..885ad616 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -15,7 +15,7 @@ on: env: # Use docker.io for Docker Hub if empty - REGISTRY: ghcr.io + REGISTRY: docker.io # github.repository as / IMAGE_NAME: ${{ github.repository }} @@ -55,8 +55,8 @@ jobs: uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c with: registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} # Extract metadata (tags, labels) for Docker # https://github.com/docker/metadata-action -- 2.45.2 From 9981dcfe8c959f6d45c5d3d4c2acc671a2b664a5 Mon Sep 17 00:00:00 2001 From: kodxana Date: Fri, 13 May 2022 15:59:56 +0200 Subject: [PATCH 207/459] Update docker-publish.yml --- .github/workflows/docker-publish.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 885ad616..a3135bff 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -14,8 +14,6 @@ on: branches: [ master ] env: - # Use docker.io for Docker Hub if empty - REGISTRY: docker.io # github.repository as / IMAGE_NAME: ${{ github.repository }} @@ -54,7 +52,6 @@ jobs: if: github.event_name != 'pull_request' uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c with: - registry: ${{ env.REGISTRY }} username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} -- 2.45.2 From 655c29aef86f06e467d79b022a82940adf069ef8 Mon Sep 17 00:00:00 2001 From: kodxana Date: Fri, 13 May 2022 16:02:02 +0200 Subject: [PATCH 208/459] Update docker-publish.yml --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index a3135bff..da10f503 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -15,7 +15,7 @@ on: env: # github.repository as / - IMAGE_NAME: ${{ github.repository }} + IMAGE_NAME: madiator2011/lbcd jobs: -- 2.45.2 From fe443c47fb126a9e4bcd9a60b2ee81e0f7292592 Mon Sep 17 00:00:00 2001 From: kodxana Date: Fri, 13 May 2022 16:04:26 +0200 Subject: [PATCH 209/459] Update docker-publish.yml --- .github/workflows/docker-publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index da10f503..4fe5c215 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -9,7 +9,7 @@ on: push: branches: [ master ] # Publish semver tags as releases. - tags: [ 'v*.*.*' ] + tags: [ 'latest' ] pull_request: branches: [ master ] @@ -61,7 +61,7 @@ jobs: id: meta uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + images: madiator2011/lbcd # Build and push Docker image with Buildx (don't push on PR) # https://github.com/docker/build-push-action -- 2.45.2 From 328c74fe57b45f3672d987ce398604a3e2fc4dd7 Mon Sep 17 00:00:00 2001 From: kodxana Date: Fri, 13 May 2022 17:53:42 +0200 Subject: [PATCH 210/459] Update sample-lbcd.conf Reverted changes and uncomented txindex=1 --- sample-lbcd.conf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sample-lbcd.conf b/sample-lbcd.conf index 90f430dd..57da5b87 100644 --- a/sample-lbcd.conf +++ b/sample-lbcd.conf @@ -297,7 +297,7 @@ ; Build and maintain a full hash-based transaction index which makes all ; transactions available via the getrawtransaction RPC. -; txindex=1 + txindex=1 ; Build and maintain a full address-based transaction index which makes the ; searchrawtransactions RPC available. @@ -380,5 +380,3 @@ ; be disabled if this option is not specified. The profile information can be ; accessed at http://localhost:/debug/pprof once running. ; profile=6061 - -txindex=1 -- 2.45.2 From 42f4b4025cbab75b82c0dd07c94af48ed293ca70 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:00 -0500 Subject: [PATCH 211/459] txscript: Add benchmark for CalcSignatureHash --- txscript/bench_test.go | 52 ++++++++++++++++++++++++++++++++ txscript/data/many_inputs_tx.hex | 1 + 2 files changed, 53 insertions(+) create mode 100644 txscript/bench_test.go create mode 100644 txscript/data/many_inputs_tx.hex diff --git a/txscript/bench_test.go b/txscript/bench_test.go new file mode 100644 index 00000000..b129b803 --- /dev/null +++ b/txscript/bench_test.go @@ -0,0 +1,52 @@ +// Copyright (c) 2018-2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package txscript + +import ( + "bytes" + "fmt" + "io/ioutil" + "testing" + + "github.com/btcsuite/btcd/wire" +) + +var ( + // manyInputsBenchTx is a transaction that contains a lot of inputs which is + // useful for benchmarking signature hash calculation. + manyInputsBenchTx wire.MsgTx + + // A mock previous output script to use in the signing benchmark. + prevOutScript = hexToBytes("a914f5916158e3e2c4551c1796708db8367207ed13bb87") +) + +func init() { + // tx 620f57c92cf05a7f7e7f7d28255d5f7089437bc48e34dcfebf7751d08b7fb8f5 + txHex, err := ioutil.ReadFile("data/many_inputs_tx.hex") + if err != nil { + panic(fmt.Sprintf("unable to read benchmark tx file: %v", err)) + } + + txBytes := hexToBytes(string(txHex)) + err = manyInputsBenchTx.Deserialize(bytes.NewReader(txBytes)) + if err != nil { + panic(err) + } +} + +// BenchmarkCalcSigHash benchmarks how long it takes to calculate the signature +// hashes for all inputs of a transaction with many inputs. +func BenchmarkCalcSigHash(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + for j := 0; j < len(manyInputsBenchTx.TxIn); j++ { + _, err := CalcSignatureHash(prevOutScript, SigHashAll, + &manyInputsBenchTx, j) + if err != nil { + b.Fatalf("failed to calc signature hash: %v", err) + } + } + } +} diff --git a/txscript/data/many_inputs_tx.hex b/txscript/data/many_inputs_tx.hex new file mode 100644 index 00000000..2f9833de --- /dev/null +++ b/txscript/data/many_inputs_tx.hex @@ -0,0 +1 @@ +010000005901fa054079e69a46e5aacd8b57f94c3c99744d68c6097957eaa9021c344141a90000000000ffffffff020706fa6444e4c9d110274488a4641161165370cd11a208ad3a3a00178e1d9c0000000000ffffffff0210805cd4cceae0873daaf8b81d2eb7122cdcdf2dfae5a90569378f847e293c0000000000ffffffff021d93a6970f13f10f6b8b1b5763f772f1f37350f893cb305005319a76069f5a0000000000ffffffff021fa71c8d5f8c455820e6d83c6fca218ed2e70391c7dfba4119168c7ebc68c30000000000ffffffff0227b4b9041f1c8ac86ea16f48909c94adac7081b26a36ed5863e4c53175262b0000000000ffffffff0228a49d6e91275b9d0d8aa5f6e81d4e1e9cd957ecfdabd6df68fe6f4970a0b60000000000ffffffff022db9dd2128b6d1f1eba30a681f062f6eaad362e58b23e6cadcd2cb8d65d6880000000000ffffffff0243411baa5b4b3357849e505310dbd29a8a50e6324c4655e403043ac07ce9d10000000000ffffffff024b630ce631441c527d555c237bb68b694d50010b7723957ef4537185eef6c40000000000ffffffff025312b6a2f95a25a109b4f0b46fb35abd74b15a39241291dd3673f1dd58fd3b0000000000ffffffff02554f0d7fe6df9454c8152c6f46429596abc08b57d7cfbc7f5f22db8a0787e00000000000ffffffff025793409101621f48c0f9ebdef0867088c015c5e412ccbdd1d32a5de62ae1b80000000000ffffffff025b53aa8359a7a3fd92d69ef96be30dfed1ea99fa03db0050f3f6d3b9e2b7320000000000ffffffff025cfc35711a57b373b807bbfaadf0950b81a74d0215a0508f2e62989bdbb4aa0000000000ffffffff025ddd8921db66b54f1ad8ef2eae70913d22e5579e2781a1e485fc6a555f6e410000000000ffffffff026466da9b3ebf93b07e7de704789d5ae04f584fa39043716a9830edf5bf99140000000000ffffffff027904d29d4cb521d7c884325b1d42434bc99b6d712681e5e254597821a944550000000000ffffffff027c662f67150bca47a7b23f0fb7c50956b21a4f46b9f4c4a304d51ce9c5900f0000000000ffffffff027ef5afdeab2ec6515a739dc00c2ef8994303c19a74fd0512f8306fb601d10f0000000000ffffffff0284cdef7bdd0c45efdecb2a3a68079d7e01ccc8e229a3e72160ec93218b1ad90000000000ffffffff028885c672656acd03755167361be6ccd94ad72c5e3890773f11a5c627f046890000000000ffffffff028b372c55109471551db0aa772aa66321862fb3a11e4cd7a31cdc4ed989436d0000000000ffffffff0290198f3a73a8febae55d559676303ae495acbad11dde304c21483a951078270000000000ffffffff0298dc5698fb1823ee1ec7469936e0b9b71e69e843d993b2c0096ac3c1d86bb20000000000ffffffff029c5d6da641328e356368383951c5dad56398f29f58a922eb54afaf888e41430000000000ffffffff02d702320af97f4f498aedf0886cd6123692f6d7b6f0b1da3910703648bc80c40000000000ffffffff02d90670fc2d34b7fcfce03ecb3a3650a4cd384eca645c2b05263721e9a5c19f0000000000ffffffff02de1f9e03b532c0bd6a28a7066c81b7abf0f9dc7e40003f638b9a872fa9a74c0000000000ffffffff02ded955aaf74a935a479fb08d4e8ded2a99664cb2235bc617627616e0e313630000000000ffffffff02e3f8ded8a0d2716817259e4144faa83facd27a5c9550c7c65835cc2c93738a0000000000ffffffff03012cf75972966f2c7abb609b43c7e85dd65cada0ee20118c80d92d766a32400000000000ffffffff0307efdd04c2f3e033a0294aaa894b4245695876fc76c12b8523d448ef05e6620000000000ffffffff030db2a3d8afa67b68f0ae663cc88bee0af0a8900e88f099d2ee648603e7b0e30000000000ffffffff03133fb852424925f55c8a660fdec8a10dce9bb9b500bf07bc73e2641f1a55310000000000ffffffff0313954647c73d9c63e4e83d36e337b17797be10eb0d641deaff0c768aa6db060000000000ffffffff031bfd6a0bfc310e204fc0eb5e1c83b9d21dab82847b909db111a371ffdcb5a20000000000ffffffff032588268e35fbd648c621638633ef8188e8b946ebd3d5833a18d9bae556ee5c0000000000ffffffff03378677fc365f67102c2559a2a4300344d41a63920e7450951fc6d8d63fb0110000000000ffffffff033c9955351d351b4f5ac398adce94b2a7ed3ab14a1c790c8e4742b1558c6b200000000000ffffffff034061cfcca9fb77d28d2411f4502c3696e0aa28b040f6780a4bd00c3fa8a02b0000000000ffffffff034b063b587eb75409e56b5ff2f9cc24a994e3ecbf9de56bd46983443067e81b0000000000ffffffff034cb2f8a145b3a55bb07dcdb904859808b29a5f53a01ba3a3cd707211afb7190000000000ffffffff034f96fa5e134b5310731b23fa9235aad58008c7c61f1b8128542b51622a52250000000000ffffffff0357236d19aef1428f117c3067a89adbecfe234ef32d744acdd6b6a5107a95e90000000000ffffffff0362504fcc65272e50ba6cc4583b4b1486592b59d943ab375ea7d6f44ba8038c0000000000ffffffff0369b02dad4259759408f8a3b1fad3c24df0873b767a9d0f1d50bd68f18c789d0000000000ffffffff036e080ba3f983e5bd7d8700dfd4b510a502231d0112c38e804b59d8a84026230000000000ffffffff038298149c290f73c535c3a184d181316ef695146a58d3bb3d2e61ed993cc11c0000000000ffffffff038538c9d6b8200609e4ca2443910daa6d9bbe772b2793e11fcf1763202c998b0000000000ffffffff038aad027dade93191c546648f7125bda82c895f1d80bf174d9637e533e12a1a0000000000ffffffff03960708a37a5654abd75755d1b8f49a84cdbde4676e14fd4863b125a94e9fc40000000000ffffffff03b0e09c55ecabf221c30a086c812e35bc9b586547cde8a83961a7ffa9067cb20000000000ffffffff03b28e682c13e7ada60cb905f8070109ec5a7800a0424c5f7afb6bd3039d48cd0000000000ffffffff03b7e8adc6174ca369ec31b4f944a6b74231d09254fde6b2bfe3416f3c6096ad0000000000ffffffff03c4f1eef6176ce6a2114dce78dd292f6db20fdae7c534d22cbada58befad6cf0000000000ffffffff03c7b5bf7fef69ae11c467f68fb551d58424e8723d05ce3ccf88385187898a710000000000ffffffff03d5150f5295b1e817f44fa34cade950c13789c4129e98eb32634aaad2abe13e0000000000ffffffff03d8250c9557188c7672009c4b14f37f96528e3f9c6889607b2e25299efe08720000000000ffffffff03de1dc49d0146dcc0cdbeb84c68a14ecb7075aba67d6494a5c8d098147843640000000000ffffffff03df8c8392bc17eddab688530697c2c221420464eb643ca8edfd30d7371ed5460000000000ffffffff03ea1dbbe72e20229648695a9b01e09b6080fb1c4632931fb810c5bfbe4b4eed0000000000ffffffff03ebf599f34a7d2cfe7bda1722f76e3df5c7fe299fd5c6e4099cfec4f551f46b0000000000ffffffff03edf95bb2c93c07d734ee8b3b1de4d4085c6b65cdbc3ca23eceec0c4d2b29a00000000000ffffffff03fe259ab7c4c03447011200d7d5236f4b1eeffd075926b78650cf1a59d570590000000000ffffffff040f71baef9c5273ac67fcba44ab29456a820274654624255c27e53ff62fdf8e0000000000ffffffff042938cae95e712592060f872cca771dfcd0218562928311c81127c3170a57bc0000000000ffffffff043a09d788547db3d1bfd8512000f9ad8bb3caab6fc24fd186663542c9f06d750000000000ffffffff043fe8a5586d0309c8dad9277bfba04fb27e7a39d279c0c9a2232e2927874d470000000000ffffffff04426f1fb4981529c32ba5756f59a2211ee9d2b9cab2c5de06a07680e833c33c0000000000ffffffff04454fa62f2c03d785307982ae406224025343f19f183e0fdff83d8e1d4cc1500000000000ffffffff04496141484d641e3b0a661210b225df50221b13bcbcb3cb8c86786890c745db0000000000ffffffff045731a8be6bfab1f9d62d2b2158591029cae655fbde8c8bdee80f183e72ca4e0000000000ffffffff04610a21533b98d3360a6f2c65be5685a1bb3a43f67da08dc1674a0f517618990000000000ffffffff0471b7883558587879bd53e13694069d95acc0d809fd0a65125ba3acdcfd66900000000000ffffffff04729b78d9b706fcb20c9cbb49ec1baf5fa782ff44d45d9a23868bcbdcbca1330000000000ffffffff04747b056b7cdd34c9891845220c2b7227a7c7c4f90e1ced6f36fd2197b26af90000000000ffffffff047a37d63a2a17986896072c77fa2e068f6e593dc64bf2ad8e180fde729fe3250000000000ffffffff04875cf5c94486e6596beaffbd7d08cf5e3111df06a89f59d65989d1485949190000000000ffffffff048944d4aa4d42ae9e864bea755a4c934713c63ce1c61d177a1ef03fd679ee330000000000ffffffff0489d5c9638a3f689c232fc1b9b59e5f82bd2e720744c4405d6537d7931edb030000000000ffffffff04a206bfdb054b041ddca180111aad2abf7b31813e4551da3a29bfb16c03534c0000000000ffffffff04a5feab7629e0cd9569aa62ea70f7ab3fdd58d3aa9bf73e8f76ac32a949d31a0000000000ffffffff04a70237d798a0b48b5abf682b806f31ff425406d93e74cde1ab4b9939ce9bc20000000000ffffffff04acd550baa26049b3dc52fb9efef1cca0b8dfa228c64482440d7217a81e587a0000000000ffffffff04b1caf936f5746da6d683eb00ae36b885fd031a8928df91e3172b1ca17f4e520000000000ffffffff04c45bd25f17cc765d8a67ca80a801c1f1c2131eb51b7b8ceb71eb898582b0380000000000ffffffff04c99a8ab69a640f9891aff371876a9d0c9043cda0430cbd436145c5574c124b0000000000ffffffff04cc0c4723cf9952c0a51db275c9d11370a95f478de98dce603d09de8e3d8e680000000000ffffffff02c6afbe970400000000001976a914c055f905fe8d14a2766801307a418f1e03ba566e88ac5ee85e0d00000000000017a914f5916158e3e2c4551c1796708db8367207ed13bb8700000000000000005923aaa80d0000000018f6020000000000fd4301473044022044e60dc7ff9d720bdc8329f97c5b321a84e0846fed248b23d399d222a074bff402204aaab1ed5df1e4b94d627d8b06171df51140e65eb056536e91103b75d032cacf0147304402200fcc38b7bff890fbd390f4bd1057c72df74c2487a3cd20edee80a20d6b2ce02902200b7893fa29f24e09358b6777a946d40166bc71c25f8e5f850059a1914e25959401473044022006430580bc312023db40b6928ba0c39141a8a59bb0613c5f6feca1c1f9b2bce90220055ffd441357bc34c246024281a7b394c7ee6a2a3c013689d95a3b9dbbb98d9e014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000009503030000000000fd4501473044022059a8f1680e80b50cb8a9180c1fabe8a66e84b34fb6c10912715fa71a5bc0f9770220531c0836d4de61d8e291c517cda25919a8b822b80b5737068120411976e5577e01483045022100a48b720930c142235cc5585a97a11d20e73a81049791526cdcee34d36f92fcef02204d2523393dfc4ba21451fa563b08f53df7c7115b65a9f2f01fd578474d308eaa01483045022100a73d3ebefadefc6dd9c7041b32bf7a3a25e49afd41bb3251c502ae6fef89316102201652f9ee39ef09335f5c8e83b3fc7591b592ff0651c5e8c4786875710cb9d1bb014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006113030000000000fd4501483045022100a5af3c72e2e15539caf81189fa020cd4b3ac5432c512dc48772d825dfca7c60802203ad5f3caaf54593b8068ce50db67111ac166c2efb73b52b30dfb7884682faadc0147304402207796a265903387a8a612cf47a8df0aae7c251a339590b24b6d813fb4cfb2dacc022076df8e67ec560d8fb74ec7ed0cd368a4da09c98846635c662e5484f5ac5b862101483045022100eb3318b340dd14f8fb797af81d8c1784668f082e54e58cd59c1224890d7f6c19022064ce22ff6bb93806930dd34dcbc846d38028db4d4d4b9c5527b6d493dba01cbd014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000099f2020000000000fd460148304502210081e68619898e8b0f9eadf2b5a324fdd7a684f935bf2cb72eef221e4310631ebc02206c7d5f1067d2980a95bfdf3b8530898ee94138dd99715c44e30b0894a5a6031b01483045022100f675ced0b828f2bae7a8046b41869ff865c081a79e32cbd400baa8ad99a975cb022075f347b57272df25c5d49c810af71fd1ba515b27166e61ad0c2bcbbd746a818101483045022100f271a0a0a8c5cfd149bf99411c4504d9905e6f9ce9f9787744c9593cab7f1c1b0220527057676ffcdd60caf0812b20b08b94ee1f935b44614b29bb9ab59e5bc0080c014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000001b02030000000000fd4401483045022100d068f2da5ba187b9d16b06dc87f1ff241063efaa786e07668abd06f8c2bea77e02206c541479ba49347104b386c36df7e14bc087bff7a17bd9c4096356a8c780fb2701473044022027336ad739d3ae08d1d136a9b7002a97873199d82abdd4bfd0531d62294116a9022001925305ccab8a328b873126baf7977b51154b4f0436685fc21f483ad347fb8b01473044022031a20fbdd66cf2a0d59ed37eda8ac50772c25adc62035b53ea675200fc85cc1c02204c1ab7d35c53ab9a5086fbcb669452367d68c8a3f07e47843c8fc2e2dbbbccc2014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000c7f9020000000000fd4301473044022022bfa36e676571479c3dff1d1a5a5c0cee3677b5ac45c14314d242bee32664270220736875bcd0807c93c3a542dbf98c753c7164ad6830acec833cc43e157eb665180147304402203c2d6ce11bff536cd9bd4f58a930649f708a5735a26971dfd8d4efa7748c48b302201e4c69309d99c41d1c19ee200fe23547f1972173f0954e8833b8ba8ecedb6aca0147304402200e9ac49f352071840f13104f247d1a506a637d898495ffcc4aec7743ca56a2e702203e279aea8208e3128dc27173a6cfbab2bd8c2bc8f273794028ac77a129d5cab7014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000005210030000000000fd4401483045022100d8e2743e7051807e428574f9c881781b40daf0ec572dcc30357350c48683fd84022032a131a11df9571b53284a2cdceb7668e7b6442897fbfd54dfc7e26f8a3a19130147304402207798db2d9031f37eca9788b63869a91b100abfff8ba9966c91c42636e43c56bc0220499af71936bfae1579f6ae8d88dd6ff980ae1dc4fa8d1c5585d08a6461ce1e1301473044022062d193f3c5f74685fbccdd8795515f67b88c8a9aac089591fdc07a8238cbf5390220200f0d61cf48c33f7800150c8af578107c20875846b4a0f2af2a4aff9d2b172e014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000dcfb020000000000fd4501483045022100e4711a4de4d6cb64e8cdaae2a4a5033c1ae87549c8d419b42b8170ee5217e04602202784ec57a6591083dbabaabd49dea7cddd3f8a32d9497e23d4b4219a56a9395f01483045022100fd776ca1d482c1d39e3a414bd0e6d353637ef626929ca5ee37db62e3dbe3501802202abe2e1279e5a354745fc5c8f8dcf367c616d82f91052925b1e2880f3906e7670147304402201976bceee0c3bb19da53e80a10a92dd6d135c86e581f349268f58b7d6b387bb5022042616ed8eee7f19ba7bee1fd5ae5415b521615aae99c45d56f9bde39d2577b9c014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000008f00030000000000fd4501483045022100fda77866c51a7ded28a6e12d3459e32b33401b1c0426f3c727ba4542ded40d1302205981be0eafc9b2c702038844769765df04bef8e17c80d1fef65c2bdba0a8e6ca01473044022018343c7eb59ef103fe102361f9ab8c789dadcfb3e60dc9b25b429165a9625af10220367f3f95f988ae6bc29c8a400687ffd70d009fe0b650994f48c1875620440fe501483045022100ac63791400e4ab5fee7f8c8ac602017409764dd7ef7ffc07d793298277661a2202200c3de5c22cad718ae83c101e987b66f31f62cc3364e8c8505407ebf11b392b66014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006211030000000000fd4501473044022029a09ec85ea2c7741cdab03fb1185d94029a5511bbe830d11ac22dfa7f21f452022060d4039356c9cf06be106dc81390025735cde670de5c0a5a38e3946cca95211e01483045022100ca82755fa0c2a23e207c665099d102d13a393ace8cfabee79b1a6f97ffb001a2022014e2ef964e3fb5e90743c54e620d40d79ef111be1299d917f762c442d40c2f770148304502210094e9d5926748124f8c215fb006ec2bec55e4cf469a7f8579a339c08a267ed2540220323b0224d9964cd55b9ccc3f1dd919073d83edb293d022b00497b8681624bec3014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000b009030000000000fd4501483045022100a308d49610b603e9ff378fb40620f255216f3325aedc8d9a909f9c5e8983cd4e02205c93d14a43aa5d4cf7a3d4d483c6d47ccb8c2c4b78647e6cbe490ca6e03cfad601473044022004b8e60724ecba532e2677411e2617cbc49ba42cd4843423d724797aed8ba60f0220198d033cf732b5451d5ef00666ecd19bf4ea8a08f6c5fc16f4e153f1759021ba01483045022100e6217183d6869b431befccd5f4b12372028e7975640cebaeefd5f5172b871ad10220152db2015f3a8c16129f34e2488a4cf19a85f26956e3818f2cf76fdc9c43fd35014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000005805030000000000fd4401473044022011d6116b37d985ed52d59aa4fee1c67a44668f55d2db37fcecc3cf89245994a002202ecb47c384e42351995cfac7ee0fa8f55053dbaa11784a1890be84c164a5cdfd01483045022100922746c881c2becbadee3859902d93c9f623d1ccf3cdc0231d31e3ee806a1db90220715d1689faa159f4abe4959063e4dd8f108b4dae79167367843dc31e0fd46e97014730440220280556147f23f8cad1907869154a98b025baae29367cc80c6d23a3a0d3b6443e02207a62c31f1331459885ee236245d3e122013b77b304ed512914b05acd1886ce79014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000004bff020000000000fd45014730440220053f5cb6b633930fc7ccd1abd012292cee5b64d6d5c25220f9d9f22ab16d1df40220430e464f5823ee503616dfbfca55fdd01949cca336c8586f4e1de72ec3f3063201483045022100e16f4708245ca99bb01ab257f495d6a33b2db4ee9ee5089a6a2074ea9070d8f602201d3302d14c85f11b2f42af10e2ac31739f085036f26aa1723c3cfd2d4b35b2b501483045022100a0be245e53ce42f783481e3ff658c13ac850eda7ad21b8206bb48fa20fa2bc5d022072963db0ace1449652a083be585dc75574490248d1069c0a48f7f7a6902fddc2014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000001703030000000000fd4401473044022029960cfa720d3818d4d2d7a55fb1a68323e34678a2a8fa3e68505cd78184cf9d0220723861ca8cee7eaed1f503a9668d9866ccae44f15a3e9da77e4dd23679715e4201483045022100f3054837f1aa88101e983b28466b679fc43fac26c48d0359c4b881ed3cf8e73b02204f4579fffdb2a96fc82b0ede6bb5eab53a86b0bc04e1ea0fc1bae9953ff5a7f90147304402207e3132303406ca2924ad934d49e4027f52083638f08d73bed7138b6d267948ea022018720dc7f47cb13d3d37555c0abeca90cb00060ce1308a3de317d63da5d1f4f1014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000002f3020000000000fd4301473044022012cdbabc4d98705db72c8a6448d8b5e5483b404ce0ff26fad16b3751ccd667be022044bda8f743f51515281b41e7b7a0347e8d52e9aff07ad0c4c84486034b2257a201473044022021e2029bd87c699931a5eb4f997e56f1efe1dcc26a7fb8c8147a762bbea389ac02202ff5feed06720f5bba0c12107dca3d83c349a35c43256429b8f12eacc6b5df16014730440220269980cf3256b87c9ff83b29e3005b6af9c85c5a8fb7a501055b486bb51fe3e0022073196474be83c9cc24a843777835b97c4eca0ddf7956547f6cdc48a1cb42ddb3014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000030f9020000000000fd450147304402204442fa3cbc6d9ca9a217069f984e8fa1bda35a825d6bf39804c92faed97f2b8d02200976a8fa7653918fa23dc3adf15408d09a8069b033f4addb723a028f9928fbda01483045022100a36c038f7e49fea33c9f2a26a4d8e510095d42912ba1cabdd7da19ceccd2466802203b78e02c86e2fec18eea2ae2b94f1e6736dfa7a3453be9ee571c90832978509901483045022100af4a52bf94e8618d387c8f54feccdf0ef49b6b5503102cd405ab28c48c6597ea022031053ae17323c0fb24dc2cbd3107ca374279cac0b54c4a6633747effec83fc9c014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006508030000000000fd440147304402206391486dc686a643c26e9b43038b2cb1b465ee6ba81ba9203d0d82f9550bd26602202ca9ebd53b20a6238c3d8abd4236b10d9ca304f5e5808db4d5004ab9ede10ad101483045022100e419233679a71a3380b662425657eca9ad26cb425a8aaaceb10de1847b3957ae02206780b4b428765f9bcee90443aaa497ade22fb813951205fd53c999f7ae27c168014730440220656dd7808be7db3a7e448608ccd3b8696cdefb687de8a4e37a58a2a0db8c714b022044683a0d0299b6eaed1ef4162d85f563aced9306d3e4a84961a301604234649d014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000cb13030000000000fd440147304402200ec0afc3a6b07063c61400fdd53e5419bb755bfcc99b1d6d2cf275b3f6848c75022036fa64742979454ce0c6b2e16963dca1d4509360cd35cb85fe533982a2ad9e690147304402206ca03acffd0198c7ea1d78e713eb45812dd0a296929bd679137dfe56f3f0601702201b9d6b25d85e86bc747b8c9d19a1a2329b02ca9de22a914419cec25bcd68e6fe01483045022100d22e473e19fda86e31314fedde03e1710f5de93efa284dab5f86817c99c9417602200bc43a59bee8a46bbc813ce52cdc76066903820af43d4caf173000543f672c6d014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000005efd020000000000fd440147304402205b7ef22035cfb0b11b62354d91f97910937de864369708e3e35376d4f620a1780220496aa95cdab061367e571568269afdc2d0a8fbb83b1bfd08c062d057041fada001483045022100db48444eda15deaab63bc6f3f5f31546d3b44a5a9412323445eb3e0853b440c80220201d7c95c47b5beed4a1139c27a79dbcd30f288ac106a208f43c61a0989f3e0801473044022040693ca2c95a33d5e8e7218b99a6df8507e9b8bf72014d19cae77d489b57b76102201883ef3c9df0b017e8fcf5b0af1bfbd61556d5bf347d77544e3bd263641fcd1c014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000046fb020000000000fd4301473044022005b50050f39f996b5f91e8e2c297e66521d5f72f2f4bec9993dbc44908f662be022001734f6df9a192f00e131fd8627b37b2afdbac8afafc38513b02c52ff305efad014730440220749ef2b72f235127bcc7c949f171ccfcc1ee87a9979543df9b568b323d9707260220440ae76846f8691bc471aa479e876a5fe01ce0e1f8311045cd8de1e7e58e4f890147304402201f5d4ea7f8fe9f08dac2020f4a2242645b27541b3cc591235fe927bfeed375a8022077627f400a799de27063ca0f2ea2d3ba5b8398bbac368a0501066097ad649e3a014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000009a09030000000000fd4501483045022100b83b84be0a0e613dd5e9dd7c6bec573a81bf95f83b546a4a717e3b708cc18bc802204bf97f877e03608103e30aeb9aab39c8f8d6e22cd9e89e66e7be74277bd7b7e201483045022100a9fe153e507bdebaf820f73e016ca8c7c61e3a07cfe7c79d74d674219c3aeb94022030abb047356650b8bb79d9eee45a9030c5cc55466568285e6d6f97cd6be577830147304402203da91297cb8e456b0089bbae43ad02d636f3f3777017c5b0224da4cf31ac5e5c022002a0ab0167395ee04f8e0f37fa261a80bff532c118a6f9fef229c5a9315115bb014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000cd0e030000000000fd4401473044022002012e7841bfd2dca62a5667f9bda8cc9b9e4ef86f8d0d6cca322b5bdb06a9b702206d5428e45ed0e18cb980b385cebc86eb6dcac59ee19f84afdc0c95ef0e782bfd01473044022073c34e5025fda812d8990f1f8cb16fbd4665554e8c467527b2c5c21132fbdf0b02206c22e854f2b704932e8134c46c40c738fc65939b2a516cceeafadd0c80f85efe01483045022100d808f0812a4a124c074166d87084bb3a38a6c632846a8ab4be7c69bda49b880702201a3625f5641c6a3a414196dc3b356f59b9bb8a44cd7623d601f28cb03691cd39014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000007fb020000000000fd4401483045022100e5357e2b20252b028d10d746c386959ba296630f08d94906a36251bf331073b102202c55e9e3a482e27326731821d25fa4c09103ec60c4cdced3f6774e6f1bc929970147304402202e58674ad455a4172f87439beaee82f59842d0c4565a88a358ebe8db35e2204702203cbffea9df59094f823f598cdb252927b1af451f522c8ca24d52274baa2c5f440147304402201a078f0959625258d4ef1bf7918b852bcf1629f8e79e2a95c1e6ffca017b7417022071dfe182e18f1debf0163e85ece438f1f3326e2eae39eab8d9c7a6cd8f179bd6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000043fc020000000000fd450147304402201d697bdcd56006044872b398bac35b2c736f6bc22080ba7c81f5038de6a87a3702204c832224547a5bd89dbc5639e763dba74e3b35e77234078b425b7157b67f401e01483045022100bd54f0d2fdb584b15215e1eb8af08a2094f9ebabe0db8b01e107d0d6ca7c55f402204b1c9e9d368361903fe3cc99e48d045672818ae5ee15b3fc46e1c84049ed1c7a01483045022100e62ff90682934ec550ea89646de3a8d8bad4919bfd7d04a343aa490ca380d49d022046b3c4d8354661d6061798201cdec35744471b61bc55d83fa403d1aa6aa3b2b0014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000000cf6020000000000fd450147304402202d47018ec27c8d18a170cf22fa9f16df5da26c9ec85b5e7ab1220d7619d3bfb80220391bce1206a19b54496101317aa853f59fe8685f4ef1080525ec13149bfbe0e801483045022100ebab59d9714232e70788b14713364d8fa9c6284e0c2f173a3376521fffcdc80e0220624b5b801a7127e41c4378582026262e917a35c69ddb6fdf0de7ecaa26017904014830450221008905e07026703b5c1f6793fa9d749981369235d540fe0127be7b5d8cd18e401f022017b7e658adf3ad47487dc49c6aa8e88cc4d3b97f87ed0771299ef4026a8d8995014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aea4a2d10a00000000c506030000000000fd4401483045022100c73924d67aaa9977d5b85fbad560b5315d36a657a402913be2aa90a1d12300e2022048b79577559462b4fd8c348a0b4d98caa20cff2c8a0363eda46037fd11782432014730440220345499c9d88b6989f158f7f980fa6f78f0a4b57d70f159739bf631b788fdbd3702207340e0fb636061cd9b7de0723d196b5f406d24120cb84f1236e3873f6e2fd6540147304402203332474e7a96938334a32052a802abb131d7a5000fb8fe1b903ca2474217d514022022533f3d58829d55689671efa27901878cfb75b20f5c696bb00ef4fcabde125f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000002afd020000000000fd4601483045022100e7e10b3fa44e3bac1a8a5baa89ee3f34f437a37572a111d75ebc323007220956022007332c4fa0a81b99711a87342f7e13e720d09122f6f8d91ba093346d17cacbbf01483045022100d8f075435a1f1e6b3352beb482e899b95ee611551a499539c0004d703588a4cc02201b339915bf5cc5b1f4ca95d507576e58dfe20b2a2a3f9e97adc37c8f1f2921b301483045022100a25df71a3f33e602652db2a3ea88a65522edaf1e05c0900c87ef7149dafa9ed80220300d23d4abf09c979ad36916da78de09656f4c38a4fdac72454a888babc3f22b014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000b90f030000000000fd4501483045022100b6240b6c0f35b38bfc074939789eb53550f6c570487245666cdb825c13b95fe002200789f35de73db6342d1a3fd381ae55f5e801e1d170e7c9672c8179ddb7c9738101483045022100fb1a47917fef805908d2e02ff317a685a9550e5edc0aa8ef8568282575d4f6c802204a6b7a54338332ccff52ba21310cb0dca6a6b97370f1a621566c9214e03b49d20147304402203ef5647f608b1e921ed139dc54bfaf5e5ac3d959b88f3dc7a2ade0729f62818002205df3b44fab36a105bcecbe1f6b2794f692e0fe65eaa6d78126279c52db2a438e014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000004b10030000000000fd450147304402204cdd0d63816bd37ceaf959d323788b35a629d6b167cb2337ac81c0adae1366450220271435beb70cd8a18ddbcf98356de296ec16847a7a3e1a7c36d400f332374af601483045022100842dbb08884f9834eae867feedfa0ed158175348ee671aca1b470a9c5a723ee202201b9c8ffb52dc70fde054f18ab5a0419b603880bba4c9dec47d46bafb25c061dc01483045022100848c18295767444c5e0670930a0e0436fad251964bd4884ff5671db1a3f19d76022016edbdb3e65f99cdede5e957a941f3f35889342818f6805e0126e715a335aefe014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000001402030000000000fd430147304402202b7fe153e0a3f19123f677cfde86578aa546f8a46550806758b053d0b45b89710220792803175b29dab2c6e8c751436b30213a3b409c8d7cb0299f29a69522b120880147304402204e67807d8a30c8358cec44173c7a0727f542b4dc131f9701f2555a27cc17b628022044487b404d9edc2e2e8f553ac874c5dc549d9b261694752759d101ec00cc44c10147304402206d537d0aa88752db936ee48e986afd68338411ff68797ee2f80ce537bbf41d9002201d276c24365b68d18ce4020792c5d9558c7134495af96bcc55721d795c7662c2014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aee854ed0a00000000f1fe020000000000fd4501483045022100a53176fb86d2190592abe80725917bfd5ab910b942d6f9648510e91730f3986b02205db19b272d2a2be3e315f2c9526a02c23f043c7b643128284faf734ce1d8930401483045022100be116b856b1f0ecac3c621c21a09d484a4bb86468a93e37f7c6d684c74c9031202205bcb65f89495e4575a1e5babb08cbd2aa21b200bbb9af1bd789b2a5b68c804f50147304402202a0dffdd955e6a5764e06113b5b712e789e956e7b6bcfaa225da8ef66e446c1b0220455f54d546976dd492b94f1693aa9d7e76dfffe3a7e861cec5f809fd5ac18caa014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000b305030000000000fd450148304502210098e4071de0540dd5d502e71a962803452695d3033ae1df83855e238197e2073e02202b825fb2190c784c050c375e1f520c0a2a85f9925fb43ffe58cdd25708e2877701483045022100892cb91af82982c870671e956805fa7aec721b82962311f4c51f959889ca8efc022051766e50a95d2ac480851b98f129889a4dd566c69b6ecda9654b3d4064aa40760147304402206ad1b9cd9af3c1e69ce32f42f1eb9ceab84e99b9f04cd14ab8842ad065a5589e022020b98e515e17d59e415d11b1be3e4fc34783d547200960ec96a4f67b6741aa58014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000018f8020000000000fd4501483045022100e500b89edaca4c2408069dd40b9645eec796f536ed10811016aceaaeba48b9b102201bc364c56b9647a7c6c53b235418a78c8d8faddf793bf3ffdbba41818b9a401601483045022100a9695d1776c81442dfc4931a960188be256f58c46ff546d1e872015c8ddf56a2022012443c230d3257b64bc8ee05d18269c211becf4b9ed3a5c7a3b63e2e216dabd8014730440220073a21f37e0d3cf9d706dde6e4fc2232395f4bf1982785ed04c61b1144f7c00f02202c7b18f4893413590bb4fb139896826bba6fc3e1205fa43fae30d8e7cce48edc014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000fe08030000000000fd4401483045022100ed3f9d7fedec8c9f8bbf1afb2b7b1edb3e4e8b9dfaf789f1effe19a32dea4728022046cba3fe18f0c1107d3fe2436d037aa8fee47e830cef788fa86541c84ac02a490147304402207326ffc63de54f4554f56a7da2072cb4bf89479bbdcf22d00169f4c3d7054a5c0220717c3c86a5470ad7f7a4900cc13e05a0a929ecc00e3ad58ac5850508ebcf7a6a01473044022052cfcc5fcd981d38c150af8897bbad4541a8aa2742d31369bf0c37c4670ec5eb02206031643bea000d5d33e180a75627cfa7bacd9eedc0926eaec773e529255c6262014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aea4a2d10a00000000e001030000000000fd450147304402206c7e38bf498a7ff831513413e5bf283b93fa456993162fb698a88933e1451fa60220669d5f75d9817f3ec08607f4b3b0ffc3f4190b5f7cbfa3336f1b64dac28178f001483045022100d8a58946dc73974ead5766e023a11eb2f32d3b7d7e482ff92255137fa6aede21022040c02e902a208a25b10296ee0a5466c6a8ce211ae2a6e2b7a541d2ea69fa4fbb014830450221009bafaf344ef873797281daf907d4e1171d8220e47bac5888e5cc72f3e219ef85022029773c52b7785abb77d72c22fbda1f9cc2a8536ccca43ec756bc9655ce6a9a84014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000980a030000000000fd45014830450221009be858cd5d4a8bce15d433d040be529a38cf38d9358919a9c04a1ca26127e3e402203de44aed9159f37e4b04ca449621d82040eab2528e2cdb7539708574899175c80147304402207271dd94d087a7b2174f3c3ccea7b92e29c84c6471224269f30faea34f2b77bb022000c9e94e92ea9f311d7a6260a2283f879115eb84d319d0da3cdb724b2b66da890148304502210093397c395481625411641fec29b5f8c37b4163e6bf886843080082f14dc716c402202f1b776d07f69ac148ec36a257ed43a2a016cc3257b091f1180bdffe9fb8fd39014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aee854ed0a0000000047f3020000000000fd4401483045022100e59a2bba52457cd3a884568aefb50a2500309e0262243553b31da735cd281d1402201c238950f19cff6cecb3e75a7308c6a0e9addb39001b36e12454575dd695ef07014730440220679cb79f57fdabea76ea42e3f145aea59f3cfd4401c4c5b1693b2ba03a2054b202205e3e2accd4d889e6fe4ce0a4ee8d6618dc79aa1f3b2d3bfb664d83d25d6562b501473044022043b80b0e55ea34ff22377a57c4633c1c5fdb57d53d04176c1673cc67e56d63a802207081bacf923edaa05c4848a11fbac160eaf3a33bb495c26361f85f3ff1fc482b014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000be08030000000000fd4601483045022100ebac21191cfac6123e0a66e7c6af7febc1a1ce2e63c4e6fa1e4f75d6d2f39dab02203d592a16f40f8c8c88817d0788457d66bdb35dde14b02b90c7c353d040d4af9101483045022100827b7e2ef669a5d1407b98562a4cd45f302f6e2489c1bef3b8bdc6a0592bd922022036fd1961511848f84c9e8c633044033501091c5e756e28a4787846156cb00f9201483045022100e330508c7b1072b3644bdaab4a6219a7cd7ddd364ec0729534385e2e6e7fdf5502200dfa2bc091014c8cc134728c60c40f21f737203e5c5c04740fbea54bba8eed04014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000f5f2020000000000fd45014830450221009db0475dc62ee80b8b49bac4d0138de52f985642f5ac40b75f46b643e4115767022042a464c53ebf57bfcefa05634ceb14e7669b86e94bea517c68e2264d676c70f80147304402205e563709bdcb24975892a67eddf3958a31d3a58471c6c0e0cb6891be80b9eeb802203c69bdf9042af7429f1555cba2180108834b3d3b139514274fe5c30aeb9f054901483045022100f792db494bef64ca96ec49891434bd33f511db09d214a3ac323343d758e2d3c702203a86fd817a81cb84610fb948d6b3ec7f4d4fed24da15ae9ee245606c4f5c42ab014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000bef8020000000000fd4501483045022100ca7a5b358614ba7615381667ed1d6ee7b2332d520caa6c5c6c1b4aab12fc4bd9022062990a8aef2fa44dc073cafaa2f3e95c3534ee075ba998beb716756f985b8f4601483045022100eb982763c3fdacf7bb59642df124f090cc5e55287b28c206a47c8a3ec8f08add0220668510362e0da663f117235f3aacdfa7fce13abfdd2c54425cf63d1b32c0b56d014730440220447bb198dc7466bfcf815e6b91e2431b970f6eba34a02260c224e503622e126902207c8fd1e1bdd32def46f7442df011f58a561b04477b372da26888c2a38d2bbb53014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000580a030000000000fd45014730440220702dd862dda92c7b3b214909a1f9dab7653a2f9103b7a62d6646d02c651b34e7022022e3c90cbf41c1fa2a5aa89ee139eee2e656a640947e8431c63c54e1e944763501483045022100f0781151a884d97b3de74df629265914f8d0253581e789a2eb511ef76568a4d602200f33782718c74ed75c25d66426f2037690d0ef3734fd06017bbd65d992b68bbe014830450221009d56003be4df82e009e4584088807d5f4a4322151865681dd04645c63b7a5a010220584ade2f5b18756f6c3cec7dd391cd174fa9103c747c8ea0d0fdf6877a4fc882014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006407030000000000fd440147304402205d00ab5aa7656681bcde46fb484802c2a304249dddee6555e680067577805f2b02207541b235dbef5e123e7b392c63497ea074c26f08d004e766a7711dca4e2696ec01483045022100fed3c2fa5de22702bfb31075897e03b433fa593ae0fb80794103566c490a595102203f5b01c8e7296be4e2f1a836b9be4d073bd2378816ed09baf416188d9b25c3b00147304402202cc6e2988cf32e02b25b2a2d853a507857ff6eac50427c4def421f20aa36e9cc02201313060f0fedb86d1dc00b41b437705fae3e5e3df23b254a2343afde89e17ee9014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000074f3020000000000fd44014730440220681a9e9bcbffa35a8328fbbdb173d803042ab1a858c4ca9ed0e4f5a67d453c8e02205820f9fcbb4414d41c28e3509806443a869168cd1e17b428549ec2495161f5180147304402201339021529c4f6eb6dd22b56752ad5b2df7e1e8d978439c9578f0e907974711002202c63c6b1386bea4536364610c38ac0994ae863f9f35bef25850d6173901f794701483045022100bb021e7846352c38f3fd4fd21179b448a8d34295de73fa41c57a5f972e91c355022008f06f8bd66571e4027556cfa9124b4e1e518a9e82470261db3f0a3972efbcb6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000e1f8020000000000fd4601483045022100f30681d06bbe18241bfeeb7cdd484bfb44efcd579f2c2e2ae53cdb68fa5032e202200d96812f571f9d8e8fa0756e351c7a779c46cf4ac62a6825f14a5020b771988c01483045022100996344d3a16c60b94789cd5ae4d3cfd8f0b660520c8e7602e0f8a7aae705b127022008d6d5577a2b90e2462bbccb88c79cfa2936d001e1b14ea530261235460c0778014830450221009a64402bdfdaaa64d429576b0c77601e8da643dab7437e8cfd27db5a56c05d2002202d263058b96116381e1879ad483c664341174f341537665c1ba7b8a33e378e75014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000086f9020000000000fd46014830450221009b8535b0fbf8f854787cd30b5109010183dae5807fa34e66e15cd6066dcb6b2502200783da464daec7780b546c0b6a4c274afe5f4698987820d36d6f9d5798ba2b7b01483045022100ccf647bcc6a89c6cca668aa5d4cb8577b8b1ebde8caf476c4270d96c631f6b8b022072e9d434ae2130352841477494a39168fda21ba51af04f372416a12b2a3eeb3601483045022100b71cf0b31f05baf22586a01f0e1869e8a37c9fb50e1470c6d82f0e8c7e709bff022050bb9d7638620264be1f8d69a477be454dd753beaf0ad6dd92f3d996f62910ac014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000007e08030000000000fd44014730440220563b7ed04dfec4aa05efd0911b384ae4995b1ec21be2572013f924268db89c9902205b3c939ecf522cfcd9d4678bcbfe23a31a3fab94043725be1d1e0c2a1ac6faf001483045022100bcfa16f8de773f97dbf9dcab27ead17ac1b3bfaeb16733d1bc355380595730a7022000d0125f418f48606a41c8b6f3e7dbcc21fd45f8c64be25513d58f56a0cbb0bc01473044022038b52dabadc8e617c7efaea42019fb8732a1bec5fa7a696c4c050b36968b637f02205b0bb3befba6a9fad35b34b99280523ebc37c20ba2eb9996d91c3f25a8d2a933014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000001c0b030000000000fd4601483045022100df6c07633b6669c8a73e33a004924e1a1e488329a165bf73871a6153cd222b9b0220240131a2687dcb6ce091ddb241d9e533362b29e351a7e181180b09a6c395a3e301483045022100884e519da7405180a348e67a6f9065d6a28520168924cebdc291f00aa28901e402204ff72a4d9bdb0f4fe667eeb0ef658a0414fe978c71193649235251ec99e0ea1d01483045022100c54d7fc08cca52150fe97c943e8d174306f125a459f3e71b489e7d497cea63270220101d71cd023d9131e98a1630a1566ba445b8e006aed4171d09f859aedbfb010a014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000befa020000000000fd4401483045022100e1c1a88390bc698025e6e40d1005a028e02f48f4708a2d8adb6b388e8ff83c33022013afc0b581e7b70d7f515d32bb1c7da68ff84dd741dbfb35855213467fc04cd30147304402205775454f05bf5fdd98df0d27b91eeb68955477768b9f50015f41a79b6f55b67002206861d59d11023c98d3a8df4edbc30a6008f615624fb18bc7d09c76d91f3abace01473044022055e4148ace2edcef6fd14e2aa7524ba7cdc397eaa025d2decfe8dff9ef93cfd402203cbdf55e08018990bcea1255149f31661fd568f1542c3c34ad9865161382a845014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000005507030000000000fd4501483045022100db1d65c4c10c62a9a727e8702730347528a810c18734666efbb8a9fb372d553c02205e3c8dee1c43ada5aab36e5e91291129dc06bca5dbcb2f72b143e98bbf8b506a01483045022100c824496528cf45264250c975ad4926e216c51a757aafe4d374b43d20fc3f108802205f3555d6c1c819be780e0fdb0b73e90727a9ffd86620c2eae6e71dba4bbb696001473044022045e218224cb0e51b36a8fedba5309d4bd0e0f3b3c89eaca58c1100a658f5370702202aefbb0c45f6044af9e8f873909e122f317c0d70872374308b6a4506ca4918fe014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000ba10030000000000fd4501483045022100a5ad7fa4026ee61e4c1e390a9d7cad33e7a23c8e84eac552ed5bd226350f2cec0220053a68add02401a90cbe70dd3ca95e02f7f3fa9c7554c9b85eb2ef9dbd7570d3014730440220458d2a918740dd329e7d3cfdb2035251503a472138b9ab19f18361ba1c05c40e0220523a8a265bbab021a019d54934bbccf0d7070342acf3ddbfb4c4d85671b34fcb01483045022100f8a7da4ff094abe375185b727847cbcf4dfb9edc7aa2c7d067153c6e4f59a479022001e0b4d4b71c818e3790accac1fcc7ab94c7949c9942224ab8146f31fe5b1fd8014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000003d0b030000000000fd44014830450221009ff8642e68b10e870a62eef426786fd90385f27ad7aeb2ed86313ef5572cf69202206ae5e31a87ee7537329c5a791ad06666797542d0d53e5e803565c46e850fdbe10147304402206477af187868ba99a2fd16ef32c5718e0710e497cf3b63c8d0451fc91aa2973e0220756a79e9d3c7ab5478caaa194c620ef6c5cb051105cd8d5906d2234226bf17420147304402200b6bec9b2956c32bdc2d39dd77790ee8469253cbed7ae4b1006eea6786bff7ab02207fde3b16eb595c5cbe2c022907f157a64a5d8dde2ce2a354228f6bf447a7b874014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aea4a2d10a00000000f301030000000000fd4601483045022100b927e3f030945624fb57a1c78083dd5ecbd16bee095f1427fee2dcd8fe3571b4022059fae4cbe0bea4848e4d1e398f4d2aa4b2a17614fdbad4f1448a920cf73e189001483045022100f7fff756ed604f5239b0312d195e67880242c4090d92df66c2ee925c88acad9e02201aa1785336c8bdb7c604ba39809d889fcf5ee8eb63c90f4a04fe2726c58418fa01483045022100bda45c1641278939fa116163fbefbe1977628506882f873768a3c478739727d802200498f9e44d1e820ebc8e5d77e961aaf889bb72935b9274085fed3fa15f77e2f2014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000078f7020000000000fd440147304402207d4a786eaf1b2a169916850e5452c4e220b790fb3f2ad669a75aa54aed1a469c02205bce95b79ea705713d6c78fed676d2f0a0af31e4716b3d91f4f3722ac571357a01483045022100e5aa71c4430cc8acbec03d7a666c90e675df226bfd9e64f36e72da3fa3615a1c022038b8e99f6a16de52780723ee3f2b72ecd193002222df75db1035629ecce2a03b014730440220097f37a7c2996aa2e49aa2f36dc1669912a4cf2e5dd092751ed9df53188e078c0220676faaa01133f821bb044cf2d6f50a459c25c4b19eaf0145b4430967db73b01d014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aee854ed0a00000000dcfd020000000000fd4501483045022100e60da48ef5ba5b29ab98cbe2ef99ff0a2bc92cd85024e49e5ca3597f12bcf300022048e6b0090e5c8057477dd7eb3789ae0b8fbdf5362421eda08c76d859ad7b544b01483045022100b4cdbbd212bbda1f70d6793d9956039d7edaa8fd70bfea7fb6a04bed7319e3780220425f48e5b29e7452107e19fddaec28e5846e04a2df14b80fc143bfd71e6266df014730440220279c65bad108d0007d821385aaad55ecad775a436de2b4e32988815020764847022067a86c7c33ece430d743102f84a9c48b29b9de9da821b6666929b13fb34e96e0014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000000f8020000000000fd4501483045022100e0d21364935dc638b62cc87e9a198a47afaa348143c28c35e3c1d4424bdf4121022008bd790132b5f6192ea6187f5cb5a9ffc6435eff720357382739d1a961fd9d890147304402203aab999b99e7753f39e2ef8d450241b911f6ffc4d9e858ca6743b2a5b7ff236802206344c728587b60b56672c4ada3fa58778cf4905697d46d026e1019eba70d1e3d014830450221009525cca77d25075ea465237b5259c3227c2924507e74851db33a71d6434a90fa02207fad277b64c89ade6a42a682f049b462e8257be13ee27cd16145b52bf60847ec014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000004ef5020000000000fd430147304402205879477cf645049300fbcb532853fd3672c4f00ebe8866df4479feec600e4217022021e95feaf3015d9d03fe78b3a0b5b61003e4182709aa7db198a050d9ca6d54be0147304402202df5b7711a3ca99433ca9a6bc6894e95ee4f1c5c94811f771e22fc7eba8514ed02206a2763d0ccd7a641d2bbca36110a4d0972bf5ab2e4660306bf8af866117759670147304402202a22e0d36d9f55d479414abfdba71a933083f44704997d0eeafca51a3dd8d37802201a4ec8031ee9325834f31805fa8bd50e5f9fa165b965f2027500ef0ee0b8138d014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453aea4a2d10a000000004412030000000000fd43014730440220221ca9f2149986b521ded423d8bf044b33502c128d5820c7ef6ea240a5bac8cb0220567cfd17e603a28a961f2a2ee88443ae709f5fab0d3cea9aa6232f5ea2570e000147304402202e38267764d91a348d25b328c11ad05323228bb3769334527418cc83df6815b7022072d856c6d2d45b1947f99e9c8e695da78c97e956eec9d75e2ac2f7cb450ae4240147304402202baa2f128838ad113ebdd95bd16db144ccd1f29be98fe435f145e7ca954c44b40220279934a60ff066f77c05031d6624cd1c7de4e120835162a2d43021526ad84bd1014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000006c0a030000000000fd4601483045022100c858877b7ebab9df2f7b0681239c92e6c03e95d963e42a075fad8c452e045b3a02202e04bbef330e7fbec49a7ba9859a6cadfd61830ab858362a2a695ad4db84ec8c014830450221009139aef771bb21f6ccd0b357d5e62f0991f98e67039b4ef146ca74c7a95883a00220268ea8e98573e4199ddaa75d2bb08f6b694af8bd383614f59e8699eacd7850be014830450221009694018de0f453d6732941e22309064ef42127d412ad135808acd9031e058fbd02202b4d893c63a553fe2401c983d4ab5a2f1ae9d411c195470be7d895ea4284b86f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000ed10030000000000fd450147304402204a295e4d135f4f6421bea46bdd97d452b23b262408d77fe38c1f090f5f88651f02206f79e3a47f198091c92cf5733f9ab0acb3347e21f1d66ebc53e01db3dbd6845701483045022100a606efb31d0eb4cc4112721878cc3bf2fd0fa2b2cd3337a98cd3304e0cd2e38c02204b6117547daae39c06d7477c8f5e9e0e0d767007326df7b027cf80ec36282af1014830450221009d3a3360ead284b47ccc8a13eb1ad8de55563dbc5ff0a98744fde8947ff5484202203c350ab88bd4650aaa762bb1379022abedfd9316e9771e3c516190d07fce0349014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000be09030000000000fd4501483045022100bc76c0450c83c1a704cebf734d36f64e1ecdc76fdc1cd6e5f7986caab2d1dea902206bd1907f48bde52c8761bea4b7cbb848b2331ea58e6fbe683ecf2d60990001400147304402203287582617de76c70e8f73fba20100471cd40b4d6cff4b883a9ed88922c96dde02206e36f90628e7822206d93fb668e759ed62d6b73d3ecde935187d239c84d296a401483045022100957d7302576e215c6e97eeab33854a139f88839377eaf10edd1f80d7567ed5e102204452ec2dd7f273d586d7ca83f80c554c73531ec689bd961b524c2d0f2b16049e014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000fa10030000000000fd4501483045022100abeb8758b4ccf148e91c24c43b46c34330210bfa56eda2afa91c64f496215b21022046c5ac2cdb04ff964369cc6137b8c6b1133422640769d9f7bcd66cc45bea71b501483045022100901da0b92045f0c0195447fd2ef83b9cd6944e75e685e38a6ebafb16a03087a0022031f2261fa0f6486d000daa590875596ddd40fe99e943ee9d6bb8bd9129b0f90801473044022021e942e7c2e562631492f4c7bdab659af69efec054e5cf8432b9cca6e2b35579022051ce1c6da198abca7414783ef73e9119d6a345a0f0f989c53d74fb506c5c8fc8014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000850a030000000000fd44014730440220132a4fcc7f1a8f6f3fe4cd9ccb32fe3433a4e450f8594424e2389368f6a7203b0220075d01f8b9ed12b416d1d04cb9e95ceccfeeb420fb49720b4a3f0d1404be2f390147304402203707b8551104cac7c862aab1a2f730208f8ecee7180ac474b409be4c6af73fe0022023e293d0368a43397a93928d61586bc41c6c7bb1793b2bd2639ba8520014783a01483045022100d4504304bfa64c675045ffedf26e9b85a3ab839df273d93e2b1b9ff12338c7c50220080f395e7663fb9539181eee186a6960d69319333cbeb4fd5d596226c7cafa34014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000066f7020000000000fd44014730440220048efe6d5dd87a48a1deba890723e0e568ba8fe0112d29537237e0a1ea1c38070220197fda66031d9df627b79538eb4de824b9b49d94fab8aed185674ea4beac7bb901473044022006bc3ef529905db1a6729c0c8755267f63b3de05a0e1df68f9a2a983596e780e0220017582ffba0935ae9c8739bd6be3d21f9aec531ebe36e12073a5ee985df0110a01483045022100ef338afebdcddc9f46ac98ae9d9f936e44241cc46584096980690174b223da3b022062e0cbe00bc6ee9588ddf92e3c9c74f55632743d3d43dba4e43747fb380a4727014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000003901030000000000fd4601483045022100b21b940e774245ff2cbd5e797973a36ae61bd59c5a24081e73894f5823150d4202207c90190110b9607b151db47b81e7008b3fbf18ab952f83cae3189e4324a21709014830450221008949ea570a61d78294fbe8c2453a211e152b0b2190078b3cb085ef58fa2d47de02206dcede7043213254f01ed0e4b73d1f5d4550ac5fdcb815972b788edd1dc626b901483045022100f8b59f01836c28cbde52114bc8bebf8ece08f45ffe1660266e0dcdc187687bed02200b59ef8ca9b9a4d8d9c937014ac9bf66b7638101c89f10549cb28ee2bd7ce63f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000004313030000000000fd440147304402205cfc98a5c55837d45207a22a7e20b646d0805a4d35e4bd10b2bbf3fff6ec0f1502207df92aa9d79c5eca866ddc95c446c774947a824e0901361dd42073f277212b66014830450221008845063e4b5c6387f1333d76010493b23d79d47f19b227b659daf8c12369e87a02203b7002cdd2ebf3974be41a5c0dd6ed267cad19b2fdd0526260e52a738bba2de4014730440220575a271b955e464d335bb32cece0813fc730be1c98f3b41d70739e9457c8b6d602206dba0e5fb0f0b3465736cfed2bab04e8f7defbb9f11c35cf1601b95fdaaa8829014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000a8f6020000000000fd45014830450221009cb6793416713945a3b6b08e10139d5c58f3ad21ba52f45913bbeb33d8ce1f5d02202e550c9d430adfaa81b4c9f6f27c2de234dfdf3936c5ad8a3beead34a8a62fde01483045022100807dfe6e8df9e514b6850f94c04efae0e927466c88bae4985d1f5a8014a5504302205265e75bb3d7b2ecbed322b35e998d904a2e4f2a44d5906807ed06566dbf14320147304402204a629c423c8ddb65ebfd05dccc9510aa3e8119b02d73e5997d559b7f9ad6a87d022029190b7200278ad005bf2f1a7aed9c864f9733ac3ec5bd7102ab18de6f44cd17014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000a6f5020000000000fd450148304502210094ef0e131bead508301ecf03a7ffa18ec9263bc3666450d2bddcfa752107310002207b8cac555f7a132aa98e41d2feff833fed68752601d0f84031eb870307630a480147304402203dffac6f1e5b22325cf2ff59a98665a827852a36225bb7db58c013022ce037cf0220502c495cfae8edbd53ca9e8b6b9bb4efbd1278966fd9156297959696d445c06f01483045022100f9d9f9b2058abc9aeb02bcebf6f5b22faaa6356ca640550b3c20744cbdee77fb022051c28736be4150081d5aef3e2253a5ce9d3ab9c4578beb398561029be530ebf3014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000003307030000000000fd44014730440220521bdce46b83ae123bcc4f0a008d2bd5cf76e76e0f98f21e029cdb2d0a4f868d02201d3abecb1216d4b41e6c6b23ad87feb8f7ba7735508a4f33d701289f736f366d0147304402203d15fd7c4c578a8acc93a1ec867199efec7f3cd532adf75e9a689af0a2b9399d0220598e77fbdb195843a2699c3464bbb5ccc55e608ec06fb2723c449469766d212c01483045022100e82cc5d9dde9a9086518ec2c18fa867ebb46112e37d65d9f34d88ac741996c95022053e900ac59bb0a391677ea209611b858a89540e59d66056852f8bf23fe5670d6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000007eff020000000000fd4401483045022100d71d8a50ea69c55f7fd08defa76bf1b4da053e3575544b0471c461bf5aef137902207fd9f81b4a551bb7afa8dd1b69a0f6b1f2c4e24aa93c992fa82f82471aa8f72701473044022047ab50ee3683939bfef7410135d6b8de00f9405ca5f2faf22979df74bd4ce974022077f23743ab8ae449862ffd48caf40cbac62fdad49e005b7212852d085e82ee020147304402202e98296f1568f3b1fae805d2d6bc6fccd59bf4c5d6f1565b644d142297d7c40902207abe8a1988115e0ab88180cf90821005e645d97ce360d372f2f329fe2a284f76014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000008604030000000000fd4601483045022100d0befa3dba35057e2ef9b8b6d873dbe983166816ceb84eb875b346ce720a6b33022018d3acee74afd13496e6f1c06e7802d7813ad42a890be8a83280dc06ea23941c01483045022100822d27a60f0e4a8c37acfaadbb0be6d49c0981613610fa63c1f162d24e79e4500220316448804078b2df0d126fb9ec97dc1584ca84567332aa3dc2acab6f573856b0014830450221008fd2b5a6421611baaa3deb3739720dfec37f5cf95f93aff572dd92dca8925fa202205d2b99181fc69d7a46c7c58367a3927b1f6fdcf136142cf85f250837fe643454014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000180c030000000000fd44014830450221009c3ccf4b91b6e425a70216bafbcd277682da8bdbdff336b6f58cb97dfc3204cb022058f650ea3ad9d26b2c66f17cacdd10bee5446caa1ee34145061c227a56620225014730440220092afde83e1995e9964b85224dfc4a3782df00a0f982eb4ad3b38d083428149b02207669684a16f7af5563fe061874c80d9e35e745abbaf7396c7f71267f50fe52010147304402202858c626b1245cdfceefa6440e0c0ca838c10d6114098fca6df76559577de29302203fac70696457e9bfec335fa3a892ec3a2161a34c5bdec4a375d63f76a8d51fbe014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000066f4020000000000fd440147304402202397ebef3e1c8008050009f306560d15c5395fa07fae571fb55910749c3fb321022044acc8eab9dc7e1a9b4ab2cb167d0f944398a0b5e2c4d6e007f6f64779ab011301483045022100f4da2295f9558216c77cd9a0c56e0afc84e3ff1e6ec6b286ea5d7ab5a9f0b4b9022047d7353598ee12ea23234fa4fcdc05d7f9930f276cf4ecee76d128fe148596700147304402205216b5502fa0f62c6d5c9844f7b29ada8cda0fdce7d4dbacf8466adffb0eb6680220735d293adb02fb781f1cc02f9d1ef5a64c9436a95b4fc111dc0d69525ebadb03014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000004e09030000000000fd4501483045022100972f0d3af3ad98263fb8f500d6dc9bc75a589148b712ac0c7f95c78feb5a516102207316e12601bfb099b54075e67563a09df9e023094411ad19cbb5850a3778f067014830450221008ef3b3fc80b147b0ec47663d8756ee4d59e6ebbfd53a6d8629d1f30e9d17b70c02206583b2dd5b4f25d219e05da7fc34203ef667e0d49530e6211827f9f3041d3092014730440220088d12eb6a4424bb67b1aa85b8854cec0a959a62ee26e825a64bdc69c5e1219602206912f9adc20c5fe9f46ec852a6f433f276d1480f6a495a7984cf676a925a4f02014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000d80b030000000000fd4401473044022061236f509bf2232223af7219d64a2064dc4c12de828d46a1313b8f97b8a1b73b022043e93a6c2884668dc499ef67e370a6d736318ad39708183d2a702945a53e7cb2014830450221008e6deec7ff876824ee0f5a61f874eb5c303edd2717f5ca866afac208d591cb1502202fef21def83459e46dcb60387fa6ecac65adaf2ebec8d1c4bad92d1b0a928dda014730440220298c9412d02c1c39acfcb9dffa66cb5745904dae9d5f619b29d909cb9d6538ea02201dd6ca43c5fbe2038b6c347ce4e6a35e6d3e6f9703647661f0aa941cfd6136bc014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000b70c030000000000fd4501483045022100ed44d291e5e7c67d7817a0c1efead142048af4b2925df521f5ee011a6bbb797c0220268bc28e0b7f3cefd25b765801d25bc6de760361d5efc4ff4cc37721f191770c0147304402203425355cf89de0872aac696e9a54e1eb47d71b67a878b4291e505f5358b4c8f102205b7bf0aecb2c022fb93d72512fe820b1f9c0f396a80a75dbc72517d41006e12001483045022100b73867e6de73cf880d7eaa7a70f74685284ea52f3fae71eca4e8905d88367248022033f60a882ec544e5607201602229ddc7508c39ec25de2ee9e18e0bffc8f1130f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000dcfe020000000000fd4501483045022100e565de2989fb12d59dceb8717fa7efe1d430031701a178e93a860b6e7c593b5302207a2c8ee53cc8deceb79e959fdbe72f7fc30e97e51652ee6043687a9f68e24eee01473044022035da650da8f643511b343b3314aab45635f5c7a70d09a34eccf208ee8c0285a602206d3125eeb0ba309c14dbac2a67fc807f8e805d210e8b4d36966ca67e80e8c5a001483045022100d2336814da44438d4e6792dec2ed9017ffe295dff7877a326eda47e76bfa587302200e5ddfdf57537fb32b0ff333744c4a426488b8199923de93691e138e7a00928a014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000ca0e030000000000fd440148304502210085f57e21fb1cd388db4e5c62353dc7f520eab422f3d7ef8624552d1385199ce502206565aa1221fc512ae6236bafc08cb8157d774e1d499ebbbe712c10032f5aaf1601473044022047a029d05cfc8da77b76625abb93ee65fa4ffd23672a7d0348e45c145cba13050220740e4bb703957e56da185bfcaece5e4d3cc602271201dadb2d5afb5475c96283014730440220573c5fd3b203915a057765b361f08082e2d891e57bcd010ecaf6e8d307358b54022018848d5a770f33d667e792853f454359d1bf1c1c846dd00ee3cb3296602dd5b8014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d000000000bf8020000000000fd450147304402203b89df3d311981d4918681f0ee17a629ea632592342085cf1c1794f75626b7d00220141f2bb0d18b5f07d5549d279437c82319ba23b5e23d8b37ee217150331fe05f01483045022100a5b0d516a0457646836b850c195c8389b2747abbf747a557e96059190ad1e38302202ab7e8d5001290350544299dc3556e9abb9da2e8f91dd2ce3b00fa0c718cdec601483045022100f7f5b03dd0f3d6a7edf18847427ac60fb49cb626b074cae1ea95f233960a0729022000aff8e788a856b194effca3a08594ce28d97138143f0b205556886b4a098fec014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000008705030000000000fd4501483045022100c9728ad82c64ab5d548752adf590654a58eb4bfaba85f1f504b57708abc3eb5902204c36886103e1aa4da4c96bb52182710806b25b9b18310d4b9eb574027eddb3100147304402205017577d2e107371b7c8bd17bc15e128e4e1186cef93ed260d6f54947e94382602200ef247802da72844a33163e6d12136027538c6855ff5761aa5ffc65fda7c810a01483045022100b56e938da3ea2ae0248afa7f6be5e8f7ddb81cd3c82e16a41919864482c28ca102202eeb3e20e95448e46c340736d980fc1b75d860264edb814f01e0e430521f51d4014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000004203030000000000fd4501473044022032a1358398cad98c16a8829ffc75fc7b44f77b93d5627dc717b66a44b59dff7102207b0472f44654abdfe1a24eda879f28838bd5184dfba238fb1b3d4ed0adba15a7014830450221008cbaf2f1616afd756d773443a52e55acafdf5202c7cecc5d0775d681de0e903902201218f989b0300a0d75672676a20c3136ef671f5a4c52ea34213eed22b3ee382401483045022100bb7ccc2f7822a511aac2104ef57e34a04c37f3e09bcff1bc779df446a0840d020220789dece4f3172564a56b6001dfddfc1b79e41ab6d156a40f020bb5dde18877a6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d0000000054fc020000000000fd4401473044022021c6612e0d9d3a57628d54fdfb7ee9756d41ad3247c8c460c499164b6ced3fb302206cb072bf1b753b8ff407b767160acf074f6f34286f4caf3ab5061fb4c980fd270147304402203b4f06ae4d5314e5dd95341c9668b16bc4a71efa1ea4bda2403d2be25e9baf8e02200f09352867d755d614bdb6af4cf22211c93c420fec4fa6fcdacae32b11d1036a01483045022100efd849b2c87782427ce6241c9cb87c60eb0202c12d1ce5f2306b25e857aa8f8d02202eac2b493b0be06093bd4c35d111fb5bdcf24d5795449ebdcbbf234237ecb837014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae23aaa80d00000000c2f3020000000000fd450147304402202649f1955b9a482cab0eef5bde264adf912f5c9351c5d9c10ebd74a7b41dda4602205675c9cfb36ad8ed29e7d431bb7b362e001e999b52d10939636147d19d8de00a01483045022100cbe00b8a033296b9b9e269388a63fb96c4a8f75085c941fa32b037a5991932cb0220020788969972594ccac489afad39bcad1534628f6a649ad5b34f14e5e9421d8401483045022100b7160b1edb5919751ecf6d18c98cceeac9f5941c1854af8560432b34b77dd74b02207105457d94cc4839df8af02f9abc34302eca1b061666e6516d859ec73d89a748014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000009209030000000000fd4401483045022100a54e526956343cfc84ce3e428c138d40381003386375d4ebf9d246101ff678e402201c80e61034511ae79e486380e3a652af58ad5b489aa15f29ec56fb84864e768f0147304402203bdeb20123223d56f13e68817d4a29c87e690540019813b2cdcb4fecbab7044b0220396a1d6971b69b4ef3e63e8727f093b3d7bface1d677a798b4a2d5ece218e8fb0147304402203ff11e576e45e7254fa5959c93956a97c09bb123e95da708001f2ede5f9ba8c602200f9f36ba15933a54a4758d97b7842776bd9706c6a8fab6a58649b9040824634f014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000670a030000000000fd4301473044022029bb920d11e2bf9201d18e7730f3bc5f6553e62bc8314336ae9c8a5859914c1502203bdacff928d4d666507dd2583b9442959c88726a817c67348817cd65e6c3606601473044022077a8ad215d7005f651f3b73a4f5a2e33e98dd2168268e04eb41af2ed6435ce2d02200af0d91cd2880f4158d175e28bce4ddc3fe50ad78b87f969c3662ae242930d980147304402205479fac1941e63c1de3cb25c4760b13f6b62ca59cf7942fb3170fd2d195678f9022040e827f224ea5551a4dad03daaf0ad63ea470b4fceffa8e4bd495e7560f32289014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000fc11030000000000fd440147304402205c09825c601853704b1b0231fbee7591c79b6cbaf30e2e955a0b6a72793b370502203fa13d433613f7e6e63419d5db0ade84cb18d699da64a2138fc086afb6066e8301483045022100eafd46546faf8c4e1152145d0a5c30ef070d5e455b6b3b685e1cb8f47cc2a0030220452568d3b52d7a6f7b1f30f321cb4481aaf8af3d7223d5e3de2d6612fa2c41bc01473044022012fc1168c457070445b883dfbbad6996a9dca5eb006b3755daeee5908918a6bc022063b589fae666c446199742cd78eb1843385660f2a962492476c6cacf3997c9eb014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000a60f030000000000fd4501483045022100872b40bd06e8bcf66cbc8ce478d9ccb62972670682146d19b06e63b919a86da0022071cf9163b60e61078f4a5be7a46cee4978585f7eb27387c0b27ae696c3d79f4701483045022100848eb32ab0284db06df29338a34ec5d63660d8ff8838501acc00694b203a346b02203f67e1f2a8d05894f14e965748ef9391675c263afc356519f3516df5adbc87ff0147304402201a20d9f8b3e236b0807d84a7d7e041d77ee26f002d2b77c695fecca316c01b5e022035edbd8bbd6917b892166fcf4b8202b93609e04440ef7b6d850c12409cb3c1e5014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d000000008409030000000000fd4401473044022009153c7b1bfdfe8ac504213c3ba3321ede43e2dc89261d803601ed6e87cace55022051969259b11cacb80d06ca68563ebdbf8a6e85fa88e9c14afc5797dc82f0fdca01483045022100951209e2d941dd5ba148ef2a0d4a0eaf09c9e0c22051719cb5f3a762517964ab02204acdcfddb8b8aa6a1f61b5126dfb607a472b22d5f731e1318f2405732fc54e750147304402200cd5be575d4b681975316726c211db5fbbc3037d29acdeb06bb7c72119fce5db0220514ea54faba32014d3422ca09c2ebcd332888370249af76809a9f5e4c380dfe6014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000e600030000000000fd45014830450221008d99ed1beda44a35e04ed4b6a20a9335c29d6fa974011c06f7a4467420b7ea39022041faf1da827bf32bc43e56a3de62512491209b1175c8779afe3e07731db7620001483045022100f38d3d3adec74d05204c0c9f0b79521abdc57f23d9599a0423d0227294a0ae3e02204ffe4c18ccf208ce95ade49bb78cfdd86aded1071e1fcede37e19252ee0b7882014730440220477a3fa0d716f8ca73d0f5cd55508231dc05d90d14ee670527f30c7f68406e4302201ee6504b744a53375afb2e84fab902ff8d299d6d897bed9db8dcbd85fd890bad014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae4e0b860d00000000ed13030000000000fd4301473044022075d9d2d1d73ff65f1c3cb5fc705aa3f117b866901a527607c81807408fc924180220062031fca37eed36da2f119ad7f5018f8fdd6ca01f42c4bfebbe8550c17e8d690147304402202897a5b6ecb4426de79bc5be348c4b359c7a9adfec0c152345538bfd5279a3e8022053992fd5f382089e1f41e0c47a1ecc11cdd604dfc46210e6053b7f690e7ec0bb01473044022031a31eeaac96cce93cd3a5fe3d75e7faf99f17a5bba04a6a8387057815663ced0220266867c47ad462ab2e5a794b5db1325e0dd75588aa45e10dfb9c219918eb7af3014c69532102bc2a9206d10e5d5173583cbafebc78998745abeca13ed33151c93afbd850ca8e2103c995ce342de266d561d6ab4b06c7a14adb0f0b30002997f076f71c8f8ac93c98210330d6c9371b561d2b961a5987d336c0186a9c5dacd6ed4551420b5977e46a29b453ae \ No newline at end of file -- 2.45.2 From b2784102f46ecd8c0398c4824e7dd41d727920ed Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 23:45:31 -0800 Subject: [PATCH 212/459] txscript: Add benchmark for CalcWitnessSigHash --- txscript/bench_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index b129b803..037ce531 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -50,3 +50,23 @@ func BenchmarkCalcSigHash(b *testing.B) { } } } + +// BenchmarkCalcWitnessSigHash benchmarks how long it takes to calculate the +// witness signature hashes for all inputs of a transaction with many inputs. +func BenchmarkCalcWitnessSigHash(b *testing.B) { + sigHashes := NewTxSigHashes(&manyInputsBenchTx) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + for j := 0; j < len(manyInputsBenchTx.TxIn); j++ { + _, err := CalcWitnessSigHash( + prevOutScript, sigHashes, SigHashAll, + &manyInputsBenchTx, j, 5, + ) + if err != nil { + b.Fatalf("failed to calc signature hash: %v", err) + } + } + } +} -- 2.45.2 From fc5b1a817c29221d165e9aa6d1341a5740b472a0 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:02 -0500 Subject: [PATCH 213/459] txscript: Add benchmark for script parsing. --- txscript/bench_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 037ce531..51f9aeab 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -70,3 +70,43 @@ func BenchmarkCalcWitnessSigHash(b *testing.B) { } } } + +// genComplexScript returns a script comprised of half as many opcodes as the +// maximum allowed followed by as many max size data pushes fit without +// exceeding the max allowed script size. +func genComplexScript() ([]byte, error) { + var scriptLen int + builder := NewScriptBuilder() + for i := 0; i < MaxOpsPerScript/2; i++ { + builder.AddOp(OP_TRUE) + scriptLen++ + } + maxData := bytes.Repeat([]byte{0x02}, MaxScriptElementSize) + for i := 0; i < (MaxScriptSize-scriptLen)/(MaxScriptElementSize+3); i++ { + builder.AddData(maxData) + } + return builder.Script() +} + +// BenchmarkScriptParsing benchmarks how long it takes to parse a very large +// script. +func BenchmarkScriptParsing(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + pops, err := parseScript(script) + if err != nil { + b.Fatalf("failed to parse script: %v", err) + } + + for _, pop := range pops { + _ = pop.opcode + _ = pop.data + } + } +} -- 2.45.2 From ac002d6422e3019180183bd55597f00ed2dc3d77 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:03 -0500 Subject: [PATCH 214/459] txscript: Introduce zero-alloc script tokenizer. This implements an efficient and zero-allocation script tokenizer that is exported to both provide a new capability to tokenize scripts to external consumers of the API as well as to serve as a base for refactoring the existing highly inefficient internal code. It is important to note that this tokenizer is intended to be used in consensus critical code in the future, so it must exactly follow the existing semantics. The current script parsing mechanism used throughout the txscript module is to fully tokenize the scripts into an array of internal parsed opcodes which are then examined and passed around in order to implement virtually everything related to scripts. While that approach does simplify the analysis of certain scripts and thus provide some nice properties in that regard, it is both extremely inefficient in many cases, and makes it impossible for external consumers of the API to implement any form of custom script analysis without manually implementing a bunch of error prone tokenizing code or, alternatively, the script engine exposing internal structures. For example, as shown by profiling the total memory allocations of an initial sync, the existing script parsing code allocates a total of around 295.12GB, which equates to around 50% of all allocations performed. The zero-alloc tokenizer this introduces will allow that to be reduced to virtually zero. The following is a before and after comparison of tokenizing a large script with a high opcode count using the existing code versus the tokenizer this introduces for both speed and memory allocations: benchmark old ns/op new ns/op delta BenchmarkScriptParsing-8 63464 677 -98.93% benchmark old allocs new allocs delta BenchmarkScriptParsing-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkScriptParsing-8 311299 0 -100.00% The following is an overview of the changes: - Introduce new error code ErrUnsupportedScriptVersion - Implement zero-allocation script tokenizer - Add a full suite of tests to ensure the tokenizer works as intended and follows the required consensus semantics - Add an example of using the new tokenizer to count the number of opcodes in a script - Update README.md to include the new example - Update script parsing benchmark to use the new tokenizer --- txscript/README.md | 4 + txscript/bench_test.go | 15 ++- txscript/error.go | 6 + txscript/error_test.go | 2 + txscript/example_test.go | 32 +++++ txscript/tokenizer.go | 186 ++++++++++++++++++++++++++ txscript/tokenizer_test.go | 259 +++++++++++++++++++++++++++++++++++++ 7 files changed, 497 insertions(+), 7 deletions(-) create mode 100644 txscript/tokenizer.go create mode 100644 txscript/tokenizer_test.go diff --git a/txscript/README.md b/txscript/README.md index 004c586d..f0abb518 100644 --- a/txscript/README.md +++ b/txscript/README.md @@ -37,6 +37,10 @@ $ go get -u github.com/btcsuite/btcd/txscript * [Manually Signing a Transaction Output](https://pkg.go.dev/github.com/btcsuite/btcd/txscript#example-SignTxOutput) Demonstrates manually creating and signing a redeem transaction. +* [Counting Opcodes in Scripts](http://godoc.org/github.com/decred/dcrd/txscript#example-ScriptTokenizer) + Demonstrates creating a script tokenizer instance and using it to count the + number of opcodes a script contains. + ## GPG Verification Key All official release tags are signed by Conformal so users can ensure the code diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 51f9aeab..673d1cc3 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -96,17 +96,18 @@ func BenchmarkScriptParsing(b *testing.B) { b.Fatalf("failed to create benchmark script: %v", err) } + const scriptVersion = 0 b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { - pops, err := parseScript(script) - if err != nil { - b.Fatalf("failed to parse script: %v", err) + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + _ = tokenizer.Opcode() + _ = tokenizer.Data() + _ = tokenizer.ByteIndex() } - - for _, pop := range pops { - _ = pop.opcode - _ = pop.data + if err := tokenizer.Err(); err != nil { + b.Fatalf("failed to parse script: %v", err) } } } diff --git a/txscript/error.go b/txscript/error.go index a61d0272..f42b893e 100644 --- a/txscript/error.go +++ b/txscript/error.go @@ -1,4 +1,5 @@ // Copyright (c) 2013-2017 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -47,6 +48,10 @@ const ( // the provided data exceeds MaxDataCarrierSize. ErrTooMuchNullData + // ErrUnsupportedScriptVersion is returned when an unsupported script + // version is passed to a function which deals with script analysis. + ErrUnsupportedScriptVersion + // ------------------------------------------ // Failures related to final execution state. // ------------------------------------------ @@ -352,6 +357,7 @@ var errorCodeStrings = map[ErrorCode]string{ ErrNotMultisigScript: "ErrNotMultisigScript", ErrTooManyRequiredSigs: "ErrTooManyRequiredSigs", ErrTooMuchNullData: "ErrTooMuchNullData", + ErrUnsupportedScriptVersion: "ErrUnsupportedScriptVersion", ErrEarlyReturn: "ErrEarlyReturn", ErrEmptyStack: "ErrEmptyStack", ErrEvalFalse: "ErrEvalFalse", diff --git a/txscript/error_test.go b/txscript/error_test.go index ebac85fd..abfa1565 100644 --- a/txscript/error_test.go +++ b/txscript/error_test.go @@ -1,4 +1,5 @@ // Copyright (c) 2017 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -22,6 +23,7 @@ func TestErrorCodeStringer(t *testing.T) { {ErrUnsupportedAddress, "ErrUnsupportedAddress"}, {ErrTooManyRequiredSigs, "ErrTooManyRequiredSigs"}, {ErrTooMuchNullData, "ErrTooMuchNullData"}, + {ErrUnsupportedScriptVersion, "ErrUnsupportedScriptVersion"}, {ErrNotMultisigScript, "ErrNotMultisigScript"}, {ErrEarlyReturn, "ErrEarlyReturn"}, {ErrEmptyStack, "ErrEmptyStack"}, diff --git a/txscript/example_test.go b/txscript/example_test.go index 7bf2b3f0..6e17341c 100644 --- a/txscript/example_test.go +++ b/txscript/example_test.go @@ -1,4 +1,5 @@ // Copyright (c) 2014-2016 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -180,3 +181,34 @@ func ExampleSignTxOutput() { // Output: // Transaction successfully signed } + +// This example demonstrates creating a script tokenizer instance and using it +// to count the number of opcodes a script contains. +func ExampleScriptTokenizer() { + // Create a script to use in the example. Ordinarily this would come from + // some other source. + hash160 := btcutil.Hash160([]byte("example")) + script, err := txscript.NewScriptBuilder().AddOp(txscript.OP_DUP). + AddOp(txscript.OP_HASH160).AddData(hash160). + AddOp(txscript.OP_EQUALVERIFY).AddOp(txscript.OP_CHECKSIG).Script() + if err != nil { + fmt.Printf("failed to build script: %v\n", err) + return + } + + // Create a tokenizer to iterate the script and count the number of opcodes. + const scriptVersion = 0 + var numOpcodes int + tokenizer := txscript.MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + numOpcodes++ + } + if tokenizer.Err() != nil { + fmt.Printf("script failed to parse: %v\n", err) + } else { + fmt.Printf("script contains %d opcode(s)\n", numOpcodes) + } + + // Output: + // script contains 5 opcode(s) +} diff --git a/txscript/tokenizer.go b/txscript/tokenizer.go new file mode 100644 index 00000000..72e00f07 --- /dev/null +++ b/txscript/tokenizer.go @@ -0,0 +1,186 @@ +// Copyright (c) 2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package txscript + +import ( + "encoding/binary" + "fmt" +) + +// opcodeArrayRef is used to break initialization cycles. +var opcodeArrayRef *[256]opcode + +func init() { + opcodeArrayRef = &opcodeArray +} + +// ScriptTokenizer provides a facility for easily and efficiently tokenizing +// transaction scripts without creating allocations. Each successive opcode is +// parsed with the Next function, which returns false when iteration is +// complete, either due to successfully tokenizing the entire script or +// encountering a parse error. In the case of failure, the Err function may be +// used to obtain the specific parse error. +// +// Upon successfully parsing an opcode, the opcode and data associated with it +// may be obtained via the Opcode and Data functions, respectively. +// +// The ByteIndex function may be used to obtain the tokenizer's current offset +// into the raw script. +type ScriptTokenizer struct { + script []byte + version uint16 + offset int32 + op *opcode + data []byte + err error +} + +// Done returns true when either all opcodes have been exhausted or a parse +// failure was encountered and therefore the state has an associated error. +func (t *ScriptTokenizer) Done() bool { + return t.err != nil || t.offset >= int32(len(t.script)) +} + +// Next attempts to parse the next opcode and returns whether or not it was +// successful. It will not be successful if invoked when already at the end of +// the script, a parse failure is encountered, or an associated error already +// exists due to a previous parse failure. +// +// In the case of a true return, the parsed opcode and data can be obtained with +// the associated functions and the offset into the script will either point to +// the next opcode or the end of the script if the final opcode was parsed. +// +// In the case of a false return, the parsed opcode and data will be the last +// successfully parsed values (if any) and the offset into the script will +// either point to the failing opcode or the end of the script if the function +// was invoked when already at the end of the script. +// +// Invoking this function when already at the end of the script is not +// considered an error and will simply return false. +func (t *ScriptTokenizer) Next() bool { + if t.Done() { + return false + } + + op := &opcodeArrayRef[t.script[t.offset]] + switch { + // No additional data. Note that some of the opcodes, notably OP_1NEGATE, + // OP_0, and OP_[1-16] represent the data themselves. + case op.length == 1: + t.offset++ + t.op = op + t.data = nil + return true + + // Data pushes of specific lengths -- OP_DATA_[1-75]. + case op.length > 1: + script := t.script[t.offset:] + if len(script) < op.length { + str := fmt.Sprintf("opcode %s requires %d bytes, but script only "+ + "has %d remaining", op.name, op.length, len(script)) + t.err = scriptError(ErrMalformedPush, str) + return false + } + + // Move the offset forward and set the opcode and data accordingly. + t.offset += int32(op.length) + t.op = op + t.data = script[1:op.length] + return true + + // Data pushes with parsed lengths -- OP_PUSHDATA{1,2,4}. + case op.length < 0: + script := t.script[t.offset+1:] + if len(script) < -op.length { + str := fmt.Sprintf("opcode %s requires %d bytes, but script only "+ + "has %d remaining", op.name, -op.length, len(script)) + t.err = scriptError(ErrMalformedPush, str) + return false + } + + // Next -length bytes are little endian length of data. + var dataLen int32 + switch op.length { + case -1: + dataLen = int32(script[0]) + case -2: + dataLen = int32(binary.LittleEndian.Uint16(script[:2])) + case -4: + dataLen = int32(binary.LittleEndian.Uint32(script[:4])) + default: + // In practice it should be impossible to hit this + // check as each op code is predefined, and only uses + // the specified lengths. + str := fmt.Sprintf("invalid opcode length %d", op.length) + t.err = scriptError(ErrMalformedPush, str) + return false + } + + // Move to the beginning of the data. + script = script[-op.length:] + + // Disallow entries that do not fit script or were sign extended. + if dataLen > int32(len(script)) || dataLen < 0 { + str := fmt.Sprintf("opcode %s pushes %d bytes, but script only "+ + "has %d remaining", op.name, dataLen, len(script)) + t.err = scriptError(ErrMalformedPush, str) + return false + } + + // Move the offset forward and set the opcode and data accordingly. + t.offset += 1 + int32(-op.length) + dataLen + t.op = op + t.data = script[:dataLen] + return true + } + + // The only remaining case is an opcode with length zero which is + // impossible. + panic("unreachable") +} + +// Script returns the full script associated with the tokenizer. +func (t *ScriptTokenizer) Script() []byte { + return t.script +} + +// ByteIndex returns the current offset into the full script that will be parsed +// next and therefore also implies everything before it has already been parsed. +func (t *ScriptTokenizer) ByteIndex() int32 { + return t.offset +} + +// Opcode returns the current opcode associated with the tokenizer. +func (t *ScriptTokenizer) Opcode() byte { + return t.op.value +} + +// Data returns the data associated with the most recently successfully parsed +// opcode. +func (t *ScriptTokenizer) Data() []byte { + return t.data +} + +// Err returns any errors currently associated with the tokenizer. This will +// only be non-nil in the case a parsing error was encountered. +func (t *ScriptTokenizer) Err() error { + return t.err +} + +// MakeScriptTokenizer returns a new instance of a script tokenizer. Passing +// an unsupported script version will result in the returned tokenizer +// immediately having an err set accordingly. +// +// See the docs for ScriptTokenizer for more details. +func MakeScriptTokenizer(scriptVersion uint16, script []byte) ScriptTokenizer { + // Only version 0 scripts are currently supported. + var err error + if scriptVersion != 0 { + str := fmt.Sprintf("script version %d is not supported", scriptVersion) + err = scriptError(ErrUnsupportedScriptVersion, str) + + } + return ScriptTokenizer{version: scriptVersion, script: script, err: err} +} diff --git a/txscript/tokenizer_test.go b/txscript/tokenizer_test.go new file mode 100644 index 00000000..fd008bfc --- /dev/null +++ b/txscript/tokenizer_test.go @@ -0,0 +1,259 @@ +// Copyright (c) 2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package txscript + +import ( + "bytes" + "fmt" + "testing" +) + +// TestScriptTokenizer ensures a wide variety of behavior provided by the script +// tokenizer performs as expected. +func TestScriptTokenizer(t *testing.T) { + t.Skip() + + type expectedResult struct { + op byte // expected parsed opcode + data []byte // expected parsed data + index int32 // expected index into raw script after parsing token + } + + type tokenizerTest struct { + name string // test description + script []byte // the script to tokenize + expected []expectedResult // the expected info after parsing each token + finalIdx int32 // the expected final byte index + err error // expected error + } + + // Add both positive and negative tests for OP_DATA_1 through OP_DATA_75. + const numTestsHint = 100 // Make prealloc linter happy. + tests := make([]tokenizerTest, 0, numTestsHint) + for op := byte(OP_DATA_1); op < OP_DATA_75; op++ { + data := bytes.Repeat([]byte{0x01}, int(op)) + tests = append(tests, tokenizerTest{ + name: fmt.Sprintf("OP_DATA_%d", op), + script: append([]byte{op}, data...), + expected: []expectedResult{{op, data, 1 + int32(op)}}, + finalIdx: 1 + int32(op), + err: nil, + }) + + // Create test that provides one less byte than the data push requires. + tests = append(tests, tokenizerTest{ + name: fmt.Sprintf("short OP_DATA_%d", op), + script: append([]byte{op}, data[1:]...), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }) + } + + // Add both positive and negative tests for OP_PUSHDATA{1,2,4}. + data := mustParseShortForm("0x01{76}") + tests = append(tests, []tokenizerTest{{ + name: "OP_PUSHDATA1", + script: mustParseShortForm("OP_PUSHDATA1 0x4c 0x01{76}"), + expected: []expectedResult{{OP_PUSHDATA1, data, 2 + int32(len(data))}}, + finalIdx: 2 + int32(len(data)), + err: nil, + }, { + name: "OP_PUSHDATA1 no data length", + script: mustParseShortForm("OP_PUSHDATA1"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA1 short data by 1 byte", + script: mustParseShortForm("OP_PUSHDATA1 0x4c 0x01{75}"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA2", + script: mustParseShortForm("OP_PUSHDATA2 0x4c00 0x01{76}"), + expected: []expectedResult{{OP_PUSHDATA2, data, 3 + int32(len(data))}}, + finalIdx: 3 + int32(len(data)), + err: nil, + }, { + name: "OP_PUSHDATA2 no data length", + script: mustParseShortForm("OP_PUSHDATA2"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA2 short data by 1 byte", + script: mustParseShortForm("OP_PUSHDATA2 0x4c00 0x01{75}"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA4", + script: mustParseShortForm("OP_PUSHDATA4 0x4c000000 0x01{76}"), + expected: []expectedResult{{OP_PUSHDATA4, data, 5 + int32(len(data))}}, + finalIdx: 5 + int32(len(data)), + err: nil, + }, { + name: "OP_PUSHDATA4 no data length", + script: mustParseShortForm("OP_PUSHDATA4"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "OP_PUSHDATA4 short data by 1 byte", + script: mustParseShortForm("OP_PUSHDATA4 0x4c000000 0x01{75}"), + expected: nil, + finalIdx: 0, + err: scriptError(ErrMalformedPush, ""), + }}...) + + // Add tests for OP_0, and OP_1 through OP_16 (small integers/true/false). + opcodes := []byte{OP_0} + for op := byte(OP_1); op < OP_16; op++ { + opcodes = append(opcodes, op) + } + for _, op := range opcodes { + tests = append(tests, tokenizerTest{ + name: fmt.Sprintf("OP_%d", op), + script: []byte{op}, + expected: []expectedResult{{op, nil, 1}}, + finalIdx: 1, + err: nil, + }) + } + + // Add various positive and negative tests for multi-opcode scripts. + tests = append(tests, []tokenizerTest{{ + name: "pay-to-pubkey-hash", + script: mustParseShortForm("DUP HASH160 DATA_20 0x01{20} EQUAL CHECKSIG"), + expected: []expectedResult{ + {OP_DUP, nil, 1}, {OP_HASH160, nil, 2}, + {OP_DATA_20, mustParseShortForm("0x01{20}"), 23}, + {OP_EQUAL, nil, 24}, {OP_CHECKSIG, nil, 25}, + }, + finalIdx: 25, + err: nil, + }, { + name: "almost pay-to-pubkey-hash (short data)", + script: mustParseShortForm("DUP HASH160 DATA_20 0x01{17} EQUAL CHECKSIG"), + expected: []expectedResult{ + {OP_DUP, nil, 1}, {OP_HASH160, nil, 2}, + }, + finalIdx: 2, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "almost pay-to-pubkey-hash (overlapped data)", + script: mustParseShortForm("DUP HASH160 DATA_20 0x01{19} EQUAL CHECKSIG"), + expected: []expectedResult{ + {OP_DUP, nil, 1}, {OP_HASH160, nil, 2}, + {OP_DATA_20, mustParseShortForm("0x01{19} EQUAL"), 23}, + {OP_CHECKSIG, nil, 24}, + }, + finalIdx: 24, + err: nil, + }, { + name: "pay-to-script-hash", + script: mustParseShortForm("HASH160 DATA_20 0x01{20} EQUAL"), + expected: []expectedResult{ + {OP_HASH160, nil, 1}, + {OP_DATA_20, mustParseShortForm("0x01{20}"), 22}, + {OP_EQUAL, nil, 23}, + }, + finalIdx: 23, + err: nil, + }, { + name: "almost pay-to-script-hash (short data)", + script: mustParseShortForm("HASH160 DATA_20 0x01{18} EQUAL"), + expected: []expectedResult{ + {OP_HASH160, nil, 1}, + }, + finalIdx: 1, + err: scriptError(ErrMalformedPush, ""), + }, { + name: "almost pay-to-script-hash (overlapped data)", + script: mustParseShortForm("HASH160 DATA_20 0x01{19} EQUAL"), + expected: []expectedResult{ + {OP_HASH160, nil, 1}, + {OP_DATA_20, mustParseShortForm("0x01{19} EQUAL"), 22}, + }, + finalIdx: 22, + err: nil, + }}...) + + const scriptVersion = 0 + for _, test := range tests { + tokenizer := MakeScriptTokenizer(scriptVersion, test.script) + var opcodeNum int + for tokenizer.Next() { + // Ensure Next never returns true when there is an error set. + if err := tokenizer.Err(); err != nil { + t.Fatalf("%q: Next returned true when tokenizer has err: %v", + test.name, err) + } + + // Ensure the test data expects a token to be parsed. + op := tokenizer.Opcode() + data := tokenizer.Data() + if opcodeNum >= len(test.expected) { + t.Fatalf("%q: unexpected token '%d' (data: '%x')", test.name, + op, data) + } + expected := &test.expected[opcodeNum] + + // Ensure the opcode and data are the expected values. + if op != expected.op { + t.Fatalf("%q: unexpected opcode -- got %v, want %v", test.name, + op, expected.op) + } + if !bytes.Equal(data, expected.data) { + t.Fatalf("%q: unexpected data -- got %x, want %x", test.name, + data, expected.data) + } + + tokenizerIdx := tokenizer.ByteIndex() + if tokenizerIdx != expected.index { + t.Fatalf("%q: unexpected byte index -- got %d, want %d", + test.name, tokenizerIdx, expected.index) + } + + opcodeNum++ + } + + // Ensure the tokenizer claims it is done. This should be the case + // regardless of whether or not there was a parse error. + if !tokenizer.Done() { + t.Fatalf("%q: tokenizer claims it is not done", test.name) + } + + // Ensure the error is as expected. + if test.err == nil && tokenizer.Err() != nil { + t.Fatalf("%q: unexpected tokenizer err -- got %v, want nil", + test.name, tokenizer.Err()) + } else if test.err != nil { + if !IsErrorCode(tokenizer.Err(), test.err.(Error).ErrorCode) { + t.Fatalf("%q: unexpected tokenizer err -- got %v, want %v", + test.name, tokenizer.Err(), test.err.(Error).ErrorCode) + } + } + + // Ensure the final index is the expected value. + tokenizerIdx := tokenizer.ByteIndex() + if tokenizerIdx != test.finalIdx { + t.Fatalf("%q: unexpected final byte index -- got %d, want %d", + test.name, tokenizerIdx, test.finalIdx) + } + } +} + +// TestScriptTokenizerUnsupportedVersion ensures the tokenizer fails immediately +// with an unsupported script version. +func TestScriptTokenizerUnsupportedVersion(t *testing.T) { + const scriptVersion = 65535 + tokenizer := MakeScriptTokenizer(scriptVersion, nil) + if !IsErrorCode(tokenizer.Err(), ErrUnsupportedScriptVersion) { + t.Fatalf("script tokenizer did not error with unsupported version") + } +} -- 2.45.2 From 94bb41664b5065530bf7cd6e802079139d461525 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:04 -0500 Subject: [PATCH 215/459] txscript: Add benchmark for DisasmString. --- txscript/bench_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 673d1cc3..3b1ed40d 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -111,3 +111,21 @@ func BenchmarkScriptParsing(b *testing.B) { } } } + +// BenchmarkDisasmString benchmarks how long it takes to disassemble a very +// large script. +func BenchmarkDisasmString(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, err := DisasmString(script) + if err != nil { + b.Fatalf("failed to disasm script: %v", err) + } + } +} -- 2.45.2 From ce08988514564f3cb06d64a04ccb8b41f58ed3d6 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:05 -0500 Subject: [PATCH 216/459] txscript: Optimize script disasm. This converts the DisasmString function to make use of the new zero-allocation script tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. In order to facilitate this, the opcode disassembly functionality is split into a separate function called disasmOpcode that accepts the opcode struct and data independently as opposed to requiring a parsed opcode. The new function also accepts a pointer to a string builder so the disassembly can be more efficiently be built. While here, the comment is modified to explicitly call out the script version semantics. The following is a before and after comparison of a large script: benchmark old ns/op new ns/op delta BenchmarkDisasmString-8 102902 40124 -61.01% benchmark old allocs new allocs delta BenchmarkDisasmString-8 46 51 +10.87% benchmark old bytes new bytes delta BenchmarkDisasmString-8 389324 130552 -66.47% --- txscript/opcode.go | 65 +++++++++++++++++++++++++++++----------------- txscript/script.go | 30 ++++++++++++++------- 2 files changed, 61 insertions(+), 34 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index a878a966..7383f881 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -9,8 +9,10 @@ import ( "crypto/sha1" "crypto/sha256" "encoding/binary" + "encoding/hex" "fmt" "hash" + "strings" "golang.org/x/crypto/ripemd160" @@ -815,45 +817,60 @@ func (pop *parsedOpcode) checkMinimalDataPush() error { return nil } -// print returns a human-readable string representation of the opcode for use -// in script disassembly. -func (pop *parsedOpcode) print(oneline bool) string { - // The reference implementation one-line disassembly replaces opcodes - // which represent values (e.g. OP_0 through OP_16 and OP_1NEGATE) - // with the raw value. However, when not doing a one-line dissassembly, - // we prefer to show the actual opcode names. Thus, only replace the - // opcodes in question when the oneline flag is set. - opcodeName := pop.opcode.name - if oneline { +// disasmOpcode writes a human-readable disassembly of the provided opcode and +// data into the provided buffer. The compact flag indicates the disassembly +// should print a more compact representation of data-carrying and small integer +// opcodes. For example, OP_0 through OP_16 are replaced with the numeric value +// and data pushes are printed as only the hex representation of the data as +// opposed to including the opcode that specifies the amount of data to push as +// well. +func disasmOpcode(buf *strings.Builder, op *opcode, data []byte, compact bool) { + // Replace opcode which represent values (e.g. OP_0 through OP_16 and + // OP_1NEGATE) with the raw value when performing a compact disassembly. + opcodeName := op.name + if compact { if replName, ok := opcodeOnelineRepls[opcodeName]; ok { opcodeName = replName } - // Nothing more to do for non-data push opcodes. - if pop.opcode.length == 1 { - return opcodeName + // Either write the human-readable opcode or the parsed data in hex for + // data-carrying opcodes. + switch { + case op.length == 1: + buf.WriteString(opcodeName) + + default: + buf.WriteString(hex.EncodeToString(data)) } - return fmt.Sprintf("%x", pop.data) + return } - // Nothing more to do for non-data push opcodes. - if pop.opcode.length == 1 { - return opcodeName - } + buf.WriteString(opcodeName) + + switch op.length { + // Only write the opcode name for non-data push opcodes. + case 1: + return // Add length for the OP_PUSHDATA# opcodes. - retString := opcodeName - switch pop.opcode.length { case -1: - retString += fmt.Sprintf(" 0x%02x", len(pop.data)) + buf.WriteString(fmt.Sprintf(" 0x%02x", len(data))) case -2: - retString += fmt.Sprintf(" 0x%04x", len(pop.data)) + buf.WriteString(fmt.Sprintf(" 0x%04x", len(data))) case -4: - retString += fmt.Sprintf(" 0x%08x", len(pop.data)) + buf.WriteString(fmt.Sprintf(" 0x%08x", len(data))) } - return fmt.Sprintf("%s 0x%02x", retString, pop.data) + buf.WriteString(fmt.Sprintf(" 0x%02x", data)) +} + +// print returns a human-readable string representation of the opcode for use +// in script disassembly. +func (pop *parsedOpcode) print(compact bool) string { + var buf strings.Builder + disasmOpcode(&buf, pop.opcode, pop.data, compact) + return buf.String() } // bytes returns any data associated with the opcode encoded as it would be in diff --git a/txscript/script.go b/txscript/script.go index 92a50e37..b7c2ef96 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/binary" "fmt" + "strings" "time" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -275,20 +276,29 @@ func unparseScript(pops []parsedOpcode) ([]byte, error) { // script up to the point the failure occurred along with the string '[error]' // appended. In addition, the reason the script failed to parse is returned // if the caller wants more information about the failure. -func DisasmString(buf []byte) (string, error) { - var disbuf bytes.Buffer - opcodes, err := parseScript(buf) - for _, pop := range opcodes { - disbuf.WriteString(pop.print(true)) +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func DisasmString(script []byte) (string, error) { + const scriptVersion = 0 + + var disbuf strings.Builder + tokenizer := MakeScriptTokenizer(scriptVersion, script) + if tokenizer.Next() { + disasmOpcode(&disbuf, tokenizer.op, tokenizer.Data(), true) + } + for tokenizer.Next() { disbuf.WriteByte(' ') + disasmOpcode(&disbuf, tokenizer.op, tokenizer.Data(), true) } - if disbuf.Len() > 0 { - disbuf.Truncate(disbuf.Len() - 1) - } - if err != nil { + if tokenizer.Err() != nil { + if tokenizer.ByteIndex() != 0 { + disbuf.WriteByte(' ') + } disbuf.WriteString("[error]") } - return disbuf.String(), err + return disbuf.String(), tokenizer.Err() } // removeOpcode will remove any opcode matching ``opcode'' from the opcode -- 2.45.2 From 07c1a9343dcec2b8f2b8c98050710fc4ed0588c6 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 18 Apr 2019 20:11:36 -0700 Subject: [PATCH 217/459] txscript: Introduce raw script sighash calc func. This introduces a new function named calcSignatureHashRaw which accepts the raw script bytes to calculate the script hash versus requiring the parsed opcode only to unparse them later in order to make it more flexible for working with raw scripts. Since there are several places in the rest of the code that currently only have access to the parsed opcodes, this modifies the existing calcSignatureHash to first unparse the script before calling the new function. Backport of decred/dcrd:f306a72a16eaabfb7054a26f9d9f850b87b00279 --- txscript/opcode.go | 10 ++++++++-- txscript/reference_test.go | 7 ++++++- txscript/script.go | 41 ++++++++++++++++++++++++++++---------- txscript/sign.go | 5 ++++- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 7383f881..893bebdf 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -2198,7 +2198,10 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { // to sign itself. subScript = removeOpcodeByData(subScript, fullSigBytes) - hash = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx) + hash, err = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx) + if err != nil { + return err + } } pubKey, err := btcec.ParsePubKey(pkBytes, btcec.S256()) @@ -2467,7 +2470,10 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { return err } } else { - hash = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx) + hash, err = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx) + if err != nil { + return err + } } var valid bool diff --git a/txscript/reference_test.go b/txscript/reference_test.go index 5015960b..6ac9b68f 100644 --- a/txscript/reference_test.go +++ b/txscript/reference_test.go @@ -863,8 +863,13 @@ func TestCalcSignatureHash(t *testing.T) { } hashType := SigHashType(testVecF64ToUint32(test[3].(float64))) - hash := calcSignatureHash(parsedScript, hashType, &tx, + hash, err := calcSignatureHash(parsedScript, hashType, &tx, int(test[2].(float64))) + if err != nil { + t.Errorf("TestCalcSignatureHash failed test #%d: "+ + "Failed to compute sighash: %v", i, err) + continue + } expectedHash, _ := chainhash.NewHashFromStr(test[4].(string)) if !bytes.Equal(hash, expectedHash[:]) { diff --git a/txscript/script.go b/txscript/script.go index b7c2ef96..52bb5b6b 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -572,13 +572,12 @@ func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx if err != nil { return nil, fmt.Errorf("cannot parse output script: %v", err) } - return calcSignatureHash(parsedScript, hashType, tx, idx), nil + return calcSignatureHash(parsedScript, hashType, tx, idx) } -// calcSignatureHash will, given a script and hash type for the current script -// engine instance, calculate the signature hash to be used for signing and -// verification. -func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.MsgTx, idx int) []byte { +// calcSignatureHashRaw computes the signature hash for the specified input of +// the target transaction observing the desired signature hash type. +func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx, idx int) []byte { // The SigHashSingle signature type signs only the corresponding input // and output (the output with the same index number as the input). // @@ -606,17 +605,24 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg } // Remove all instances of OP_CODESEPARATOR from the script. - script = removeOpcode(script, OP_CODESEPARATOR) + filteredScript := make([]byte, 0, len(sigScript)) + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, sigScript) + var prevOffset int32 + for tokenizer.Next() { + if tokenizer.Opcode() != OP_CODESEPARATOR { + filteredScript = append(filteredScript, + sigScript[prevOffset:tokenizer.ByteIndex()]...) + } + prevOffset = tokenizer.ByteIndex() + } // Make a shallow copy of the transaction, zeroing out the script for // all inputs that are not currently being processed. txCopy := shallowCopyTx(tx) for i := range txCopy.TxIn { if i == idx { - // UnparseScript cannot fail here because removeOpcode - // above only returns a valid script. - sigScript, _ := unparseScript(script) - txCopy.TxIn[idx].SignatureScript = sigScript + txCopy.TxIn[idx].SignatureScript = filteredScript } else { txCopy.TxIn[i].SignatureScript = nil } @@ -670,6 +676,21 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg return chainhash.DoubleHashB(wbuf.Bytes()) } +// calcSignatureHash computes the signature hash for the specified input of the +// target transaction observing the desired signature hash type. +// +// DEPRECATED: Use calcSignatureHashRaw instead +func calcSignatureHash(prevOutScript []parsedOpcode, hashType SigHashType, + tx *wire.MsgTx, idx int) ([]byte, error) { + + sigScript, err := unparseScript(prevOutScript) + if err != nil { + return nil, err + } + + return calcSignatureHashRaw(sigScript, hashType, tx, idx), nil +} + // asSmallInt returns the passed opcode, which must be true according to // isSmallInt(), as an integer. func asSmallInt(op *opcode) int { diff --git a/txscript/sign.go b/txscript/sign.go index 42af9686..b9f8b2db 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -345,7 +345,10 @@ sigLoop: // however, assume no sigs etc are in the script since that // would make the transaction nonstandard and thus not // MultiSigTy, so we just need to hash the full thing. - hash := calcSignatureHash(pkPops, hashType, tx, idx) + hash, err := calcSignatureHash(pkPops, hashType, tx, idx) + if err != nil { + panic(fmt.Sprintf("cannot compute sighash: %v", err)) + } for _, addr := range addresses { // All multisig addresses should be pubkey addresses -- 2.45.2 From 18aa1a59df38c2fb0d1a507bc3d7deb883ebdff9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:07 -0500 Subject: [PATCH 218/459] txscript: Optimize CalcSignatureHash. This modifies the CalcSignatureHash function to make use of the new signature hash calculation function that accepts raw scripts without needing to first parse them. Consequently, it also doubles as a slight optimization to the execution time and a significant reduction in the number of allocations. In order to convert the CalcScriptHash function and keep the same semantics, a new function named checkScriptParses is introduced which will quickly determine if a script can be fully parsed without failure and return the parse failure in the case it can't. The following is a before and after comparison of analyzing a large multiple input transaction: benchmark old ns/op new ns/op delta BenchmarkCalcSigHash-8 3627895 3619477 -0.23% benchmark old allocs new allocs delta BenchmarkCalcSigHash-8 1335 801 -40.00% benchmark old bytes new bytes delta BenchmarkCalcSigHash-8 1373812 1293354 -5.86% --- txscript/script.go | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 52bb5b6b..112c24ac 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -567,12 +567,17 @@ func shallowCopyTx(tx *wire.MsgTx) wire.MsgTx { // CalcSignatureHash will, given a script and hash type for the current script // engine instance, calculate the signature hash to be used for signing and // verification. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx int) ([]byte, error) { - parsedScript, err := parseScript(script) - if err != nil { - return nil, fmt.Errorf("cannot parse output script: %v", err) + const scriptVersion = 0 + if err := checkScriptParses(scriptVersion, script); err != nil { + return nil, err } - return calcSignatureHash(parsedScript, hashType, tx, idx) + + return calcSignatureHashRaw(script, hashType, tx, idx), nil } // calcSignatureHashRaw computes the signature hash for the specified input of @@ -850,6 +855,15 @@ func getWitnessSigOps(pkScript []byte, witness wire.TxWitness) int { return 0 } +// checkScriptParses returns an error if the provided script fails to parse. +func checkScriptParses(scriptVersion uint16, script []byte) error { + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + // Nothing to do. + } + return tokenizer.Err() +} + // IsUnspendable returns whether the passed public key script is unspendable, or // guaranteed to fail at execution. This allows inputs to be pruned instantly // when entering the UTXO set. -- 2.45.2 From a02b71bcf95fdbf9b3487b19367d1b3a57892c77 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 18 Apr 2019 21:12:34 -0700 Subject: [PATCH 219/459] txscript/reference_test: Convert sighash calc test This converts the tests for calculating signature hashes to use the exported function which handles the raw script versus the now deprecated variant requiring parsed opcodes. Backport of 06f769ef72e6042e7f2b5ff1c512ef1371d615e5 --- txscript/reference_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/txscript/reference_test.go b/txscript/reference_test.go index 6ac9b68f..9d9c8f39 100644 --- a/txscript/reference_test.go +++ b/txscript/reference_test.go @@ -836,6 +836,7 @@ func TestCalcSignatureHash(t *testing.T) { err) } + const scriptVersion = 0 for i, test := range tests { if i == 0 { // Skip first line -- contains comments only. @@ -855,15 +856,14 @@ func TestCalcSignatureHash(t *testing.T) { } subScript, _ := hex.DecodeString(test[1].(string)) - parsedScript, err := parseScript(subScript) - if err != nil { + if err := checkScriptParses(scriptVersion, subScript); err != nil { t.Errorf("TestCalcSignatureHash failed test #%d: "+ "Failed to parse sub-script: %v", i, err) continue } hashType := SigHashType(testVecF64ToUint32(test[3].(float64))) - hash, err := calcSignatureHash(parsedScript, hashType, &tx, + hash, err := CalcSignatureHash(subScript, hashType, &tx, int(test[2].(float64))) if err != nil { t.Errorf("TestCalcSignatureHash failed test #%d: "+ -- 2.45.2 From 45de22d45736daccf195c6a4a431b3e182934ea5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:09 -0500 Subject: [PATCH 220/459] txscript: Make isSmallInt accept raw opcode. This converts the isSmallInt function to accept an opcode as a byte instead of the internal opcode data struct in order to make it more flexible for raw script analysis. The comment is modified to explicitly call out the script version semantics. Finally, it updates all callers accordingly. --- txscript/script.go | 14 ++++++++------ txscript/standard.go | 10 +++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 112c24ac..58b8e69f 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -1,4 +1,5 @@ // Copyright (c) 2013-2017 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -45,11 +46,12 @@ const ( // isSmallInt returns whether or not the opcode is considered a small integer, // which is an OP_0, or OP_1 through OP_16. -func isSmallInt(op *opcode) bool { - if op.value == OP_0 || (op.value >= OP_1 && op.value <= OP_16) { - return true - } - return false +// +// NOTE: This function is only valid for version 0 opcodes. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func isSmallInt(op byte) bool { + return op == OP_0 || (op >= OP_1 && op <= OP_16) } // isScriptHash returns true if the script passed is a pay-to-script-hash @@ -136,7 +138,7 @@ func IsWitnessProgram(script []byte) bool { // bytes. func isWitnessProgram(pops []parsedOpcode) bool { return len(pops) == 2 && - isSmallInt(pops[0].opcode) && + isSmallInt(pops[0].opcode.value) && canonicalPush(pops[1]) && (len(pops[1].data) >= 2 && len(pops[1].data) <= 40) } diff --git a/txscript/standard.go b/txscript/standard.go index 2cad218e..a447303d 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -115,10 +115,10 @@ func isMultiSig(pops []parsedOpcode) bool { if l < 4 { return false } - if !isSmallInt(pops[0].opcode) { + if !isSmallInt(pops[0].opcode.value) { return false } - if !isSmallInt(pops[l-2].opcode) { + if !isSmallInt(pops[l-2].opcode.value) { return false } if pops[l-1].opcode.value != OP_CHECKMULTISIG { @@ -153,7 +153,7 @@ func isNullData(pops []parsedOpcode) bool { return l == 2 && pops[0].opcode.value == OP_RETURN && - (isSmallInt(pops[1].opcode) || pops[1].opcode.value <= + (isSmallInt(pops[1].opcode.value) || pops[1].opcode.value <= OP_PUSHDATA4) && len(pops[1].data) <= MaxDataCarrierSize } @@ -705,7 +705,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa return nil, nil } pushes.SecretSize = int64(locktime) - } else if op := pops[2].opcode; isSmallInt(op) { + } else if op := pops[2].opcode; isSmallInt(op.value) { pushes.SecretSize = int64(asSmallInt(op)) } else { return nil, nil @@ -716,7 +716,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa return nil, nil } pushes.LockTime = int64(locktime) - } else if op := pops[11].opcode; isSmallInt(op) { + } else if op := pops[11].opcode; isSmallInt(op.value) { pushes.LockTime = int64(asSmallInt(op)) } else { return nil, nil -- 2.45.2 From 8c68575331fcabdc6a00f907660294d4bf0ca9ac Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:11 -0500 Subject: [PATCH 221/459] txscript: Make asSmallInt accept raw opcode. This converts the asSmallInt function to accept an opcode as a byte instead of the internal opcode data struct in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/script.go | 10 +++++----- txscript/standard.go | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 58b8e69f..3dfd82e1 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -159,7 +159,7 @@ func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { "unable to extract version or witness program") } - witnessVersion := asSmallInt(pops[0].opcode) + witnessVersion := asSmallInt(pops[0].opcode.value) witnessProgram := pops[1].data return witnessVersion, witnessProgram, nil @@ -700,12 +700,12 @@ func calcSignatureHash(prevOutScript []parsedOpcode, hashType SigHashType, // asSmallInt returns the passed opcode, which must be true according to // isSmallInt(), as an integer. -func asSmallInt(op *opcode) int { - if op.value == OP_0 { +func asSmallInt(op byte) int { + if op == OP_0 { return 0 } - return int(op.value - (OP_1 - 1)) + return int(op - (OP_1 - 1)) } // getSigOpCount is the implementation function for counting the number of @@ -730,7 +730,7 @@ func getSigOpCount(pops []parsedOpcode, precise bool) int { if precise && i > 0 && pops[i-1].opcode.value >= OP_1 && pops[i-1].opcode.value <= OP_16 { - nSigs += asSmallInt(pops[i-1].opcode) + nSigs += asSmallInt(pops[i-1].opcode.value) } else { nSigs += MaxPubKeysPerMultiSig } diff --git a/txscript/standard.go b/txscript/standard.go index a447303d..94b3cce5 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -127,7 +127,7 @@ func isMultiSig(pops []parsedOpcode) bool { // Verify the number of pubkeys specified matches the actual number // of pubkeys provided. - if l-2-1 != asSmallInt(pops[l-2].opcode) { + if l-2-1 != asSmallInt(pops[l-2].opcode.value) { return false } @@ -238,7 +238,7 @@ func expectedInputs(pops []parsedOpcode, class ScriptClass) int { // the original bitcoind bug where OP_CHECKMULTISIG pops an // additional item from the stack, add an extra expected input // for the extra push that is required to compensate. - return asSmallInt(pops[0].opcode) + 1 + return asSmallInt(pops[0].opcode.value) + 1 case NullDataTy: fallthrough @@ -395,8 +395,8 @@ func CalcMultiSigStats(script []byte) (int, int, error) { return 0, 0, scriptError(ErrNotMultisigScript, str) } - numSigs := asSmallInt(pops[0].opcode) - numPubKeys := asSmallInt(pops[len(pops)-2].opcode) + numSigs := asSmallInt(pops[0].opcode.value) + numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value) return numPubKeys, numSigs, nil } @@ -617,8 +617,8 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script // Therefore the number of required signatures is the 1st item // on the stack and the number of public keys is the 2nd to last // item on the stack. - requiredSigs = asSmallInt(pops[0].opcode) - numPubKeys := asSmallInt(pops[len(pops)-2].opcode) + requiredSigs = asSmallInt(pops[0].opcode.value) + numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value) // Extract the public keys while skipping any that are invalid. addrs = make([]btcutil.Address, 0, numPubKeys) @@ -706,7 +706,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa } pushes.SecretSize = int64(locktime) } else if op := pops[2].opcode; isSmallInt(op.value) { - pushes.SecretSize = int64(asSmallInt(op)) + pushes.SecretSize = int64(asSmallInt(op.value)) } else { return nil, nil } @@ -717,7 +717,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa } pushes.LockTime = int64(locktime) } else if op := pops[11].opcode; isSmallInt(op.value) { - pushes.LockTime = int64(asSmallInt(op)) + pushes.LockTime = int64(asSmallInt(op.value)) } else { return nil, nil } -- 2.45.2 From 28eaf3492d465582b77fa06dfafeb77a32b6e445 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:38 -0500 Subject: [PATCH 222/459] txscript: Add benchmark for IsPayToPubKey --- txscript/bench_test.go | 15 +++++++++++++++ txscript/script.go | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 3b1ed40d..6415c595 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -129,3 +129,18 @@ func BenchmarkDisasmString(b *testing.B) { } } } + +// BenchmarkIsPubKeyScript benchmarks how long it takes to analyze a very large +// script to determine if it is a standard pay-to-pubkey script. +func BenchmarkIsPubKeyScript(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToPubKey(script) + } +} diff --git a/txscript/script.go b/txscript/script.go index 3dfd82e1..c642069c 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -63,6 +63,16 @@ func isScriptHash(pops []parsedOpcode) bool { pops[2].opcode.value == OP_EQUAL } +// IsPayToPubKey returns true if the script is in the standard pay-to-pubkey +// (P2PK) format, false otherwise. +func IsPayToPubKey(script []byte) bool { + pops, err := parseScript(script) + if err != nil { + return false + } + return isPubkey(pops) +} + // IsPayToScriptHash returns true if the script is in the standard // pay-to-script-hash (P2SH) format, false otherwise. func IsPayToScriptHash(script []byte) bool { -- 2.45.2 From 5d18558bc6142c08b50fa5ab1b6bfbda5bc2b7c3 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:06:56 -0800 Subject: [PATCH 223/459] txscript: Optimize IsPayToPubKey This converts the IsPayToScriptHash function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimizing the function. In order to accomplish this, it introduces four new functions: extractCompressedPubKey, extractUncompressedPubKey, extractPubKey, and isPubKeyScript. The extractPubKey function makes use of extractCompressedPubKey and extractUncompressedPubKey to combine their functionality as a convenience and isPubKeyScript is defined in terms of extractPubKey. The extractCompressedPubKey works with the raw script bytes to simultaneously determine if the script is a pay-to-compressed-pubkey script, and in the case it is, extract and return the raw compressed pubkey bytes. Similarly, the extractUncompressedPubKey works in the same way except it determines if the script is a pay-to-uncompressed-pubkey script and returns the raw uncompressed pubkey bytes in the case it is. The extract function approach was chosen because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result so long as the extraction does not require allocations. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsPubKeyScript-8 62323 2.97 -100.00% benchmark old allocs new allocs delta BenchmarkIsPubKeyScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPubKeyScript-8 311299 0 -100.00% --- txscript/script.go | 6 +---- txscript/standard.go | 58 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index c642069c..00df5216 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -66,11 +66,7 @@ func isScriptHash(pops []parsedOpcode) bool { // IsPayToPubKey returns true if the script is in the standard pay-to-pubkey // (P2PK) format, false otherwise. func IsPayToPubKey(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isPubkey(pops) + return isPubKeyScript(script) } // IsPayToScriptHash returns true if the script is in the standard diff --git a/txscript/standard.go b/txscript/standard.go index 94b3cce5..0a835dbb 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -85,6 +85,64 @@ func (t ScriptClass) String() string { return scriptClassToName[t] } +// extractCompressedPubKey extracts a compressed public key from the passed +// script if it is a standard pay-to-compressed-secp256k1-pubkey script. It +// will return nil otherwise. +func extractCompressedPubKey(script []byte) []byte { + // A pay-to-compressed-pubkey script is of the form: + // OP_DATA_33 <33-byte compressed pubkey> OP_CHECKSIG + + // All compressed secp256k1 public keys must start with 0x02 or 0x03. + if len(script) == 35 && + script[34] == OP_CHECKSIG && + script[0] == OP_DATA_33 && + (script[1] == 0x02 || script[1] == 0x03) { + + return script[1:34] + } + + return nil +} + +// extractUncompressedPubKey extracts an uncompressed public key from the +// passed script if it is a standard pay-to-uncompressed-secp256k1-pubkey +// script. It will return nil otherwise. +func extractUncompressedPubKey(script []byte) []byte { + // A pay-to-uncompressed-pubkey script is of the form: + // OP_DATA_65 <65-byte uncompressed pubkey> OP_CHECKSIG + // + // All non-hybrid uncompressed secp256k1 public keys must start with 0x04. + // Hybrid uncompressed secp256k1 public keys start with 0x06 or 0x07: + // - 0x06 => hybrid format for even Y coords + // - 0x07 => hybrid format for odd Y coords + if len(script) == 67 && + script[66] == OP_CHECKSIG && + script[0] == OP_DATA_65 && + (script[1] == 0x04 || script[1] == 0x06 || script[1] == 0x07) { + + return script[1:66] + } + return nil +} + +// extractPubKey extracts either compressed or uncompressed public key from the +// passed script if it is a either a standard pay-to-compressed-secp256k1-pubkey +// or pay-to-uncompressed-secp256k1-pubkey script, respectively. It will return +// nil otherwise. +func extractPubKey(script []byte) []byte { + if pubKey := extractCompressedPubKey(script); pubKey != nil { + return pubKey + } + return extractUncompressedPubKey(script) +} + +// isPubKeyScript returns whether or not the passed script is either a standard +// pay-to-compressed-secp256k1-pubkey or pay-to-uncompressed-secp256k1-pubkey +// script. +func isPubKeyScript(script []byte) bool { + return extractPubKey(script) != nil +} + // isPubkey returns true if the script passed is a pay-to-pubkey transaction, // false otherwise. func isPubkey(pops []parsedOpcode) bool { -- 2.45.2 From c4da180d4f70f542afdb245d3c87423460971abb Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:52:11 -0800 Subject: [PATCH 224/459] txscript: Add benchmark for IsPayToPubKeyHash --- txscript/bench_test.go | 15 +++++++++++++++ txscript/script.go | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 6415c595..401b9683 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -144,3 +144,18 @@ func BenchmarkIsPubKeyScript(b *testing.B) { _ = IsPayToPubKey(script) } } + +// BenchmarkIsPubKeyHashScript benchmarks how long it takes to analyze a very +// large script to determine if it is a standard pay-to-pubkey-hash script. +func BenchmarkIsPubKeyHashScript(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToPubKeyHash(script) + } +} diff --git a/txscript/script.go b/txscript/script.go index 00df5216..fb4fc8bc 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -69,6 +69,16 @@ func IsPayToPubKey(script []byte) bool { return isPubKeyScript(script) } +// IsPayToPubKeyHash returns true if the script is in the standard +// pay-to-pubkey-hash (P2PKH) format, false otherwise. +func IsPayToPubKeyHash(script []byte) bool { + pops, err := parseScript(script) + if err != nil { + return false + } + return isPubkeyHash(pops) +} + // IsPayToScriptHash returns true if the script is in the standard // pay-to-script-hash (P2SH) format, false otherwise. func IsPayToScriptHash(script []byte) bool { -- 2.45.2 From eb03d84098811f1711489297389fda011a6091d2 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:09:28 -0800 Subject: [PATCH 225/459] txscript: Optimize IsPayToPubKeyHash This converts the IsPayToPubKeyHash function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimization the function. In order to accomplish this, it introduces two new functions. The first one is named extractPubKeyHash and works with the raw script bytes to simultaneously determine if the script is a pay-to-pubkey-hash script, and in the case it is, extract and return the hash. The second new function is named isPubKeyHashScript and is defined in terms of the former. The extract function approach was chosen because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result so long as the extraction does not require allocations. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsPubKeyHashScript-8 62228 0.45 -100.00% benchmark old allocs new allocs delta BenchmarkIsPubKeyHashScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPubKeyHashScript-8 311299 0 -100.00% --- txscript/script.go | 6 +----- txscript/standard.go | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index fb4fc8bc..b154c110 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -72,11 +72,7 @@ func IsPayToPubKey(script []byte) bool { // IsPayToPubKeyHash returns true if the script is in the standard // pay-to-pubkey-hash (P2PKH) format, false otherwise. func IsPayToPubKeyHash(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isPubkeyHash(pops) + return isPubKeyHashScript(script) } // IsPayToScriptHash returns true if the script is in the standard diff --git a/txscript/standard.go b/txscript/standard.go index 0a835dbb..f7948f79 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -143,6 +143,30 @@ func isPubKeyScript(script []byte) bool { return extractPubKey(script) != nil } +// extractPubKeyHash extracts the public key hash from the passed script if it +// is a standard pay-to-pubkey-hash script. It will return nil otherwise. +func extractPubKeyHash(script []byte) []byte { + // A pay-to-pubkey-hash script is of the form: + // OP_DUP OP_HASH160 <20-byte hash> OP_EQUALVERIFY OP_CHECKSIG + if len(script) == 25 && + script[0] == OP_DUP && + script[1] == OP_HASH160 && + script[2] == OP_DATA_20 && + script[23] == OP_EQUALVERIFY && + script[24] == OP_CHECKSIG { + + return script[3:23] + } + + return nil +} + +// isPubKeyHashScript returns whether or not the passed script is a standard +// pay-to-pubkey-hash script. +func isPubKeyHashScript(script []byte) bool { + return extractPubKeyHash(script) != nil +} + // isPubkey returns true if the script passed is a pay-to-pubkey transaction, // false otherwise. func isPubkey(pops []parsedOpcode) bool { -- 2.45.2 From e7228a2e5f51bdc5063c1fd5faa5146d1dc91742 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:13 -0500 Subject: [PATCH 226/459] txscript: Add benchmark for IsPayToScriptHash. --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 401b9683..e47cf21f 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -159,3 +159,18 @@ func BenchmarkIsPubKeyHashScript(b *testing.B) { _ = IsPayToPubKeyHash(script) } } + +// BenchmarkIsPayToScriptHash benchmarks how long it takes IsPayToScriptHash to +// analyze a very large script. +func BenchmarkIsPayToScriptHash(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToScriptHash(script) + } +} -- 2.45.2 From 69aefa65e69e9b5052b443917ea5db0291e6c6d8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:14 -0500 Subject: [PATCH 227/459] txscript: Optimize IsPayToScriptHash. This converts the IsPayToScriptHash function to analyze the raw script instead of using the far less efficient parseScript thereby significantly optimizing the function. In order to accomplish this, it introduces two new functions. The first one is named extractScriptHash and works with the raw script bytes to simultaneously determine if the script is a p2sh script, and in the case it is, extract and return the hash. The second new function is named isScriptHashScript and is defined in terms of the former. The extract function approach was chosen because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result so long as the extraction does not require allocations. Finally, this also deprecates the isScriptHash function that requires opcodes in favor of the new functions and modifies the comment on IsPayToScriptHash to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script that is not a p2sh script: benchmark old ns/op new ns/op delta BenchmarkIsPayToScriptHash-8 62393 0.60 -100.00% benchmark old allocs new allocs delta BenchmarkIsPayToScriptHash-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPayToScriptHash-8 311299 0 -100.00% --- txscript/script.go | 14 +++++++++----- txscript/standard.go | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index b154c110..a8cfd166 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -56,6 +56,8 @@ func isSmallInt(op byte) bool { // isScriptHash returns true if the script passed is a pay-to-script-hash // transaction, false otherwise. +// +// DEPRECATED. Use isScriptHashScript or extractScriptHash instead. func isScriptHash(pops []parsedOpcode) bool { return len(pops) == 3 && pops[0].opcode.value == OP_HASH160 && @@ -77,12 +79,14 @@ func IsPayToPubKeyHash(script []byte) bool { // IsPayToScriptHash returns true if the script is in the standard // pay-to-script-hash (P2SH) format, false otherwise. +// +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before determining if the script is a P2SH which means nodes +// on existing rules will analyze new version scripts as if they were version 0. func IsPayToScriptHash(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isScriptHash(pops) + return isScriptHashScript(script) } // isWitnessScriptHash returns true if the passed script is a diff --git a/txscript/standard.go b/txscript/standard.go index f7948f79..a02f8723 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -167,6 +167,32 @@ func isPubKeyHashScript(script []byte) bool { return extractPubKeyHash(script) != nil } +// extractScriptHash extracts the script hash from the passed script if it is a +// standard pay-to-script-hash script. It will return nil otherwise. +// +// NOTE: This function is only valid for version 0 opcodes. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func extractScriptHash(script []byte) []byte { + // A pay-to-script-hash script is of the form: + // OP_HASH160 <20-byte scripthash> OP_EQUAL + if len(script) == 23 && + script[0] == OP_HASH160 && + script[1] == OP_DATA_20 && + script[22] == OP_EQUAL { + + return script[2:22] + } + + return nil +} + +// isScriptHashScript returns whether or not the passed script is a standard +// pay-to-script-hash script. +func isScriptHashScript(script []byte) bool { + return extractScriptHash(script) != nil +} + // isPubkey returns true if the script passed is a pay-to-pubkey transaction, // false otherwise. func isPubkey(pops []parsedOpcode) bool { -- 2.45.2 From a6244b516d0ff3c2944c2502eabb9198c5f9a694 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:15 -0500 Subject: [PATCH 228/459] txscript: Add benchmarks for IsMutlsigScript. --- txscript/bench_test.go | 45 ++++++++++++++++++++++++++++++++++++++++++ txscript/standard.go | 21 ++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index e47cf21f..49be4958 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -174,3 +174,48 @@ func BenchmarkIsPayToScriptHash(b *testing.B) { _ = IsPayToScriptHash(script) } } + +// BenchmarkIsMultisigScriptLarge benchmarks how long it takes IsMultisigScript +// to analyze a very large script. +func BenchmarkIsMultisigScriptLarge(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + isMultisig, err := IsMultisigScript(script) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + if isMultisig { + b.Fatalf("script should NOT be reported as mutisig script") + } + } +} + +// BenchmarkIsMultisigScript benchmarks how long it takes IsMultisigScript to +// analyze a 1-of-2 multisig public key script. +func BenchmarkIsMultisigScript(b *testing.B) { + multisigShortForm := "1 " + + "DATA_33 " + + "0x030478aaaa2be30772f1e69e581610f1840b3cf2fe7228ee0281cd599e5746f81e " + + "DATA_33 " + + "0x0284f4d078b236a9ff91661f8ffbe012737cd3507566f30fd97d25f2b23539f3cd " + + "2 CHECKMULTISIG" + pkScript := mustParseShortForm(multisigShortForm) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + isMultisig, err := IsMultisigScript(pkScript) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + if !isMultisig { + b.Fatalf("script should be reported as a mutisig script") + } + } +} diff --git a/txscript/standard.go b/txscript/standard.go index a02f8723..25483aeb 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -248,6 +248,27 @@ func isMultiSig(pops []parsedOpcode) bool { return true } +// IsMultisigScript returns whether or not the passed script is a standard +// multisignature script. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +// +// The error is DEPRECATED and will be removed in the major version bump. +func IsMultisigScript(script []byte) (bool, error) { + if len(script) == 0 || script == nil { + return false, nil + } + + pops, err := parseScript(script) + if err != nil { + return false, err + } + + return isMultiSig(pops), nil +} + // isNullData returns true if the passed script is a null data transaction, // false otherwise. func isNullData(pops []parsedOpcode) bool { -- 2.45.2 From 67e2cbe3748b2f2964de540b3fdc7d4dfbc7f86d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:16 -0500 Subject: [PATCH 229/459] txscript: Optimize IsMultisigScript. This converts the IsMultisigScript function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. In order to accomplish this, it introduces two new functions. The first one is named extractMultisigScriptDetails and works with the raw script bytes to simultaneously determine if the script is a multisignature script, and in the case it is, extract and return the relevant details. The second new function is named isMultisigScript and is defined in terms of the former. The extract function accepts the script version, raw script bytes, and a flag to determine whether or not the public keys should also be extracted. The flag is provided because extracting pubkeys results in an allocation that the caller might wish to avoid. The extract function approach was chosen because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result so long as the extraction does not require allocations. It is important to note that this new implementation intentionally has a semantic difference from the existing implementation in that it will now correctly identify a multisig script with zero pubkeys whereas previously it incorrectly required at least one pubkey. This change is acceptable because the function only deals with standardness rather than consensus rules. Finally, this also deprecates the isMultiSig function that requires opcodes in favor of the new functions and deprecates the error return on the export IsMultisigScript function since it really does not make sense given the purpose of the function. The following is a before and after comparison of analyzing both a large script that is not a multisig script and a 1-of-2 multisig public key script: benchmark old ns/op new ns/op delta BenchmarkIsMultisigScriptLarge-8 64166 5.52 -99.99% BenchmarkIsMultisigScript-8 630 59.4 -90.57% benchmark old allocs new allocs delta BenchmarkIsMultisigScriptLarge-8 1 0 -100.00% BenchmarkIsMultisigScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsMultisigScriptLarge-8 311299 0 -100.00% BenchmarkIsMultisigScript-8 2304 0 -100.00% --- txscript/engine.go | 21 ++++++++ txscript/standard.go | 116 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 127 insertions(+), 10 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index f2d7b303..3c76b747 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -580,6 +580,27 @@ func (vm *Engine) checkHashTypeEncoding(hashType SigHashType) error { return nil } +// isStrictPubKeyEncoding returns whether or not the passed public key adheres +// to the strict encoding requirements. +func isStrictPubKeyEncoding(pubKey []byte) bool { + if len(pubKey) == 33 && (pubKey[0] == 0x02 || pubKey[0] == 0x03) { + // Compressed + return true + } + if len(pubKey) == 65 { + switch pubKey[0] { + case 0x04: + // Uncompressed + return true + + case 0x06, 0x07: + // Hybrid + return true + } + } + return false +} + // checkPubKeyEncoding returns whether or not the passed public key adheres to // the strict encoding requirements if enabled. func (vm *Engine) checkPubKeyEncoding(pubKey []byte) error { diff --git a/txscript/standard.go b/txscript/standard.go index 25483aeb..096de4e5 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -216,6 +216,8 @@ func isPubkeyHash(pops []parsedOpcode) bool { // isMultiSig returns true if the passed script is a multisig transaction, false // otherwise. +// +// DEPECATED. Use isMultisigScript or extractMultisigScriptDetails instead. func isMultiSig(pops []parsedOpcode) bool { // The absolute minimum is 1 pubkey: // OP_0/OP_1-16 OP_1 OP_CHECKMULTISIG @@ -248,6 +250,108 @@ func isMultiSig(pops []parsedOpcode) bool { return true } +// multiSigDetails houses details extracted from a standard multisig script. +type multiSigDetails struct { + requiredSigs int + numPubKeys int + pubKeys [][]byte + valid bool +} + +// extractMultisigScriptDetails attempts to extract details from the passed +// script if it is a standard multisig script. The returned details struct will +// have the valid flag set to false otherwise. +// +// The extract pubkeys flag indicates whether or not the pubkeys themselves +// should also be extracted and is provided because extracting them results in +// an allocation that the caller might wish to avoid. The pubKeys member of +// the returned details struct will be nil when the flag is false. +// +// NOTE: This function is only valid for version 0 scripts. The returned +// details struct will always be empty and have the valid flag set to false for +// other script versions. +func extractMultisigScriptDetails(scriptVersion uint16, script []byte, extractPubKeys bool) multiSigDetails { + // The only currently supported script version is 0. + if scriptVersion != 0 { + return multiSigDetails{} + } + + // A multi-signature script is of the form: + // NUM_SIGS PUBKEY PUBKEY PUBKEY ... NUM_PUBKEYS OP_CHECKMULTISIG + + // The script can't possibly be a multisig script if it doesn't end with + // OP_CHECKMULTISIG or have at least two small integer pushes preceding it. + // Fail fast to avoid more work below. + if len(script) < 3 || script[len(script)-1] != OP_CHECKMULTISIG { + return multiSigDetails{} + } + + // The first opcode must be a small integer specifying the number of + // signatures required. + tokenizer := MakeScriptTokenizer(scriptVersion, script) + if !tokenizer.Next() || !isSmallInt(tokenizer.Opcode()) { + return multiSigDetails{} + } + requiredSigs := asSmallInt(tokenizer.Opcode()) + + // The next series of opcodes must either push public keys or be a small + // integer specifying the number of public keys. + var numPubKeys int + var pubKeys [][]byte + if extractPubKeys { + pubKeys = make([][]byte, 0, MaxPubKeysPerMultiSig) + } + for tokenizer.Next() { + if isSmallInt(tokenizer.Opcode()) { + break + } + + data := tokenizer.Data() + numPubKeys++ + if !isStrictPubKeyEncoding(data) { + continue + } + if extractPubKeys { + pubKeys = append(pubKeys, data) + } + } + if tokenizer.Done() { + return multiSigDetails{} + } + + // The next opcode must be a small integer specifying the number of public + // keys required. + op := tokenizer.Opcode() + if !isSmallInt(op) || asSmallInt(op) != numPubKeys { + return multiSigDetails{} + } + + // There must only be a single opcode left unparsed which will be + // OP_CHECKMULTISIG per the check above. + if int32(len(tokenizer.Script()))-tokenizer.ByteIndex() != 1 { + return multiSigDetails{} + } + + return multiSigDetails{ + requiredSigs: requiredSigs, + numPubKeys: numPubKeys, + pubKeys: pubKeys, + valid: true, + } +} + +// isMultisigScript returns whether or not the passed script is a standard +// multisig script. +// +// NOTE: This function is only valid for version 0 scripts. It will always +// return false for other script versions. +func isMultisigScript(scriptVersion uint16, script []byte) bool { + // Since this is only checking the form of the script, don't extract the + // public keys to avoid the allocation. + details := extractMultisigScriptDetails(scriptVersion, script, false) + return details.valid +} + // IsMultisigScript returns whether or not the passed script is a standard // multisignature script. // @@ -257,16 +361,8 @@ func isMultiSig(pops []parsedOpcode) bool { // // The error is DEPRECATED and will be removed in the major version bump. func IsMultisigScript(script []byte) (bool, error) { - if len(script) == 0 || script == nil { - return false, nil - } - - pops, err := parseScript(script) - if err != nil { - return false, err - } - - return isMultiSig(pops), nil + const scriptVersion = 0 + return isMultisigScript(scriptVersion, script), nil } // isNullData returns true if the passed script is a null data transaction, -- 2.45.2 From 3bdeaa46bf23ce225b8f283b4196d85c20995014 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:17 -0500 Subject: [PATCH 230/459] txscript: Add benchmarks for IsMutlsigSigScript. --- txscript/bench_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++ txscript/standard.go | 18 ++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 49be4958..41d79ccb 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -219,3 +219,51 @@ func BenchmarkIsMultisigScript(b *testing.B) { } } } + +// BenchmarkIsMultisigSigScript benchmarks how long it takes IsMultisigSigScript +// to analyze a very large script. +func BenchmarkIsMultisigSigScriptLarge(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if IsMultisigSigScript(script) { + b.Fatalf("script should NOT be reported as mutisig sig script") + } + } +} + +// BenchmarkIsMultisigSigScript benchmarks how long it takes IsMultisigSigScript +// to analyze both a 1-of-2 multisig public key script (which should be false) +// and a signature script comprised of a pay-to-script-hash 1-of-2 multisig +// redeem script (which should be true). +func BenchmarkIsMultisigSigScript(b *testing.B) { + multisigShortForm := "1 " + + "DATA_33 " + + "0x030478aaaa2be30772f1e69e581610f1840b3cf2fe7228ee0281cd599e5746f81e " + + "DATA_33 " + + "0x0284f4d078b236a9ff91661f8ffbe012737cd3507566f30fd97d25f2b23539f3cd " + + "2 CHECKMULTISIG" + pkScript := mustParseShortForm(multisigShortForm) + + sigHex := "0x304402205795c3ab6ba11331eeac757bf1fc9c34bef0c7e1a9c8bd5eebb8" + + "82f3b79c5838022001e0ab7b4c7662e4522dc5fa479e4b4133fa88c6a53d895dc1d5" + + "2eddc7bbcf2801 " + sigScript := mustParseShortForm("DATA_71 " + sigHex + "DATA_71 " + + multisigShortForm) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if IsMultisigSigScript(pkScript) { + b.Fatalf("script should NOT be reported as mutisig sig script") + } + if !IsMultisigSigScript(sigScript) { + b.Fatalf("script should be reported as a mutisig sig script") + } + } +} diff --git a/txscript/standard.go b/txscript/standard.go index 096de4e5..51dcbfb9 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -365,6 +365,24 @@ func IsMultisigScript(script []byte) (bool, error) { return isMultisigScript(scriptVersion, script), nil } +// IsMultisigSigScript takes a script, parses it, then returns whether or +// not it is a multisignature script. +func IsMultisigSigScript(script []byte) bool { + if len(script) == 0 || script == nil { + return false + } + pops, err := parseScript(script) + if err != nil { + return false + } + subPops, err := parseScript(pops[len(pops)-1].data) + if err != nil { + return false + } + + return isMultiSig(subPops) +} + // isNullData returns true if the passed script is a null data transaction, // false otherwise. func isNullData(pops []parsedOpcode) bool { -- 2.45.2 From 6be04a8e4374c79c46f250a9f73257056182db05 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:18 -0500 Subject: [PATCH 231/459] txscript: Optimize IsMultisigSigScript. This converts the IsMultisigSigScript function to analyze the raw script and make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. In order to accomplish this, it first rejects scripts that can't possibly fit the bill due to the final byte of what would be the redeem script not being the appropriate opcode or the overall script not having enough bytes. Then, it uses a new function that is introduced named finalOpcodeData that uses the tokenizer to return any data associated with the final opcode in the signature script (which will be nil for non-push opcodes or if the script fails to parse) and analyzes it as if it were a redeem script when it is non nil. It is also worth noting that this new implementation intentionally has the same semantic difference from the existing implementation as the updated IsMultisigScript function in regards to allowing zero pubkeys whereas previously it incorrectly required at least one pubkey. Finally, the comment is modified to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script that is not a multisig script and both a 1-of-2 multisig public key script (which should be false) and a signature script comprised of a pay-to-script-hash 1-of-2 multisig redeem script (which should be true): benchmark old ns/op new ns/op delta BenchmarkIsMultisigSigScriptLarge-8 69328 2.93 -100.00% BenchmarkIsMultisigSigScript-8 2375 146 -93.85% benchmark old allocs new allocs delta BenchmarkIsMultisigSigScriptLarge-8 5 0 -100.00% BenchmarkIsMultisigSigScript-8 3 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsMultisigSigScriptLarge-8 330035 0 -100.00% BenchmarkIsMultisigSigScript-8 9472 0 -100.00% --- txscript/script.go | 19 +++++++++++++++++++ txscript/standard.go | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index a8cfd166..eb5be8b7 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -769,6 +769,25 @@ func GetSigOpCount(script []byte) int { return getSigOpCount(pops, false) } +// finalOpcodeData returns the data associated with the final opcode in the +// script. It will return nil if the script fails to parse. +func finalOpcodeData(scriptVersion uint16, script []byte) []byte { + // Avoid unnecessary work. + if len(script) == 0 { + return nil + } + + var data []byte + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + data = tokenizer.Data() + } + if tokenizer.Err() != nil { + return nil + } + return data +} + // GetPreciseSigOpCount returns the number of signature operations in // scriptPubKey. If bip16 is true then scriptSig may be searched for the // Pay-To-Script-Hash script in order to find the precise number of signature diff --git a/txscript/standard.go b/txscript/standard.go index 51dcbfb9..272b42b8 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -365,22 +365,39 @@ func IsMultisigScript(script []byte) (bool, error) { return isMultisigScript(scriptVersion, script), nil } -// IsMultisigSigScript takes a script, parses it, then returns whether or -// not it is a multisignature script. +// IsMultisigSigScript returns whether or not the passed script appears to be a +// signature script which consists of a pay-to-script-hash multi-signature +// redeem script. Determining if a signature script is actually a redemption of +// pay-to-script-hash requires the associated public key script which is often +// expensive to obtain. Therefore, this makes a fast best effort guess that has +// a high probability of being correct by checking if the signature script ends +// with a data push and treating that data push as if it were a p2sh redeem +// script +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func IsMultisigSigScript(script []byte) bool { - if len(script) == 0 || script == nil { - return false - } - pops, err := parseScript(script) - if err != nil { - return false - } - subPops, err := parseScript(pops[len(pops)-1].data) - if err != nil { + const scriptVersion = 0 + + // The script can't possibly be a multisig signature script if it doesn't + // end with OP_CHECKMULTISIG in the redeem script or have at least two small + // integers preceding it, and the redeem script itself must be preceded by + // at least a data push opcode. Fail fast to avoid more work below. + if len(script) < 4 || script[len(script)-1] != OP_CHECKMULTISIG { return false } - return isMultiSig(subPops) + // Parse through the script to find the last opcode and any data it might + // push and treat it as a p2sh redeem script even though it might not + // actually be one. + possibleRedeemScript := finalOpcodeData(scriptVersion, script) + if possibleRedeemScript == nil { + return false + } + + // Finally, return if that possible redeem script is a multisig script. + return isMultisigScript(scriptVersion, possibleRedeemScript) } // isNullData returns true if the passed script is a null data transaction, -- 2.45.2 From 2b5edd2b5e32a3375f971fb0cce10f21ed7e7201 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:25 -0500 Subject: [PATCH 232/459] txscript: Add benchmark for IsPushOnlyScript. --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 41d79ccb..ca64267a 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -267,3 +267,18 @@ func BenchmarkIsMultisigSigScript(b *testing.B) { } } } + +// BenchmarkIsPushOnlyScript benchmarks how long it takes IsPushOnlyScript to +// analyze a very large script. +func BenchmarkIsPushOnlyScript(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPushOnlyScript(script) + } +} -- 2.45.2 From 02ddaf29fd107ce1845fcf942f390b9805bef936 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:26 -0500 Subject: [PATCH 233/459] txscript: Optimize IsPushOnlyScript. This converts the IsPushOnlyScript function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. It also deprecates the isPushOnly function that requires opcodes in favor of the new function and modifies the comment on IsPushOnlyScript to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsPushOnlyScript-8 62412 622 -99.00% benchmark old allocs new allocs delta BenchmarkIsPushOnlyScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPushOnlyScript-8 311299 0 -100.00% --- txscript/script.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index eb5be8b7..43048e95 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -182,6 +182,8 @@ func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { } // isPushOnly returns true if the script only pushes data, false otherwise. +// +// DEPRECATED. Use IsPushOnlyScript instead. func isPushOnly(pops []parsedOpcode) bool { // NOTE: This function does NOT verify opcodes directly since it is // internal and is only called with parsed opcodes for scripts that did @@ -199,15 +201,27 @@ func isPushOnly(pops []parsedOpcode) bool { return true } -// IsPushOnlyScript returns whether or not the passed script only pushes data. +// IsPushOnlyScript returns whether or not the passed script only pushes data +// according to the consensus definition of pushing data. // -// False will be returned when the script does not parse. +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before checking if it is a push only script which means nodes +// on existing rules will treat new version scripts as if they were version 0. func IsPushOnlyScript(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + // All opcodes up to OP_16 are data push instructions. + // NOTE: This does consider OP_RESERVED to be a data push instruction, + // but execution of OP_RESERVED will fail anyway and matches the + // behavior required by consensus. + if tokenizer.Opcode() > OP_16 { + return false + } } - return isPushOnly(pops) + return tokenizer.Err() == nil } // parseScriptTemplate is the same as parseScript but allows the passing of the -- 2.45.2 From 38ade2c48f95d97497601463457b797dbd0792a2 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 01:43:18 -0700 Subject: [PATCH 234/459] txscript: Add benchmark IsPayToWitnessPubkeyHash --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index ca64267a..de6636d9 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -282,3 +282,18 @@ func BenchmarkIsPushOnlyScript(b *testing.B) { _ = IsPushOnlyScript(script) } } + +// BenchmarkIsWitnessPubKeyHash benchmarks how long it takes to analyze a very +// large script to determine if it is a standard witness pubkey hash script. +func BenchmarkIsWitnessPubKeyHash(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToWitnessPubKeyHash(script) + } +} -- 2.45.2 From 4d8edfe6d9457ff8578f8ea2381fb47f049a32a1 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 13:22:40 -0800 Subject: [PATCH 235/459] txscript: Optimize IsPayToWitnessPubKeyHash This converts the IsPayToWitnessPubKeyHash function to analyze the raw script instead of the far less efficient parseScript, thereby significantly optimizing the function. In order to accomplish this, it introduces two new functions. The first one is named extractWitnessPubKeyHash and works with the raw script bytes to simultaneously deteremine if the script is a p2wkh, and in case it is, extract and return the hash. The second new function is name isWitnessPubKeyHashScript which is defined in terms of the former. The extract function is approach was chosen because it is common for callers to want to only extract relevant details from the script if the script is of the specific type. Extracting those details requires the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two and define the type determination in terms of the result so long as the extraction does not require allocations. Finally, this deprecates the isWitnessPubKeyHash function that requires opcodes in favor of the new functions and modifies the comment on IsPayToWitnessPubKeyHash to explicitly call out the script version semantics. The following is a before and after comparison of executing IsPayToWitnessPubKeyHash on a large script: benchmark old ns/op new ns/op delta BenchmarkIsWitnessPubKeyHash-8 68927 0.53 -100.00% benchmark old allocs new allocs delta BenchmarkIsWitnessPubKeyHash-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsWitnessPubKeyHash-8 311299 0 -100.00% --- txscript/script.go | 6 +----- txscript/standard.go | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 43048e95..59dc2e27 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -110,11 +110,7 @@ func IsPayToWitnessScriptHash(script []byte) bool { // IsPayToWitnessPubKeyHash returns true if the is in the standard // pay-to-witness-pubkey-hash (P2WKH) format, false otherwise. func IsPayToWitnessPubKeyHash(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isWitnessPubKeyHash(pops) + return isWitnessPubKeyHashScript(script) } // isWitnessPubKeyHash returns true if the passed script is a diff --git a/txscript/standard.go b/txscript/standard.go index 272b42b8..513c9ce1 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -400,6 +400,27 @@ func IsMultisigSigScript(script []byte) bool { return isMultisigScript(scriptVersion, possibleRedeemScript) } +// extractWitnessPubKeyHash extracts the witness public key hash from the passed +// script if it is a standard pay-to-witness-pubkey-hash script. It will return +// nil otherwise. +func extractWitnessPubKeyHash(script []byte) []byte { + // A pay-to-witness-pubkey-hash script is of the form: + // OP_0 OP_DATA_20 <20-byte-hash> + if len(script) == 22 && + script[0] == OP_0 && + script[1] == OP_DATA_20 { + + return script[2:22] + } + return nil +} + +// isWitnessPubKeyHashScript returns whether or not the passed script is a +// standard pay-to-witness-pubkey-hash script. +func isWitnessPubKeyHashScript(script []byte) bool { + return extractWitnessPubKeyHash(script) != nil +} + // isNullData returns true if the passed script is a null data transaction, // false otherwise. func isNullData(pops []parsedOpcode) bool { -- 2.45.2 From b3dd941a77bca945ed705860f36d7a77e8ed714f Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 01:57:31 -0700 Subject: [PATCH 236/459] txscript: Add benchmark for IsPayToWitnessScriptHash --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index de6636d9..529d32f7 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -297,3 +297,18 @@ func BenchmarkIsWitnessPubKeyHash(b *testing.B) { _ = IsPayToWitnessPubKeyHash(script) } } + +// BenchmarkIsWitnessScriptHash benchmarks how long it takes to analyze a very +// large script to determine if it is a standard witness script hash script. +func BenchmarkIsWitnessScriptHash(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsPayToWitnessScriptHash(script) + } +} -- 2.45.2 From 44c6be3d4e105f5e14119aa931d31dc5cdd37280 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 13:39:10 -0800 Subject: [PATCH 237/459] txscript: Optimize IsPayToWitnessScriptHash This converts the IsPayToWitnessScriptHash function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimizing the function. In order to accomplish this, it introduces two new functions. The first one is named extractWitnessScriptHash and works with the raw script byte to simultaneously deteremine if the script is a p2wsh script, and in the case that is is, extract and return the hash. The second new function is named isWitnessScriptHashScript and is defined in terms of the former. The extract function approach was chosed because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result, so long as the extraction does not require allocations. Finally, this also deprecates the isWitnessScriptHash function that requires opcodes in favor of the new functions and modifies the comment on IsPayToWitnessScriptHash to call out the script version semantics. The following is a before and after comparison of executing IsPayToWitnessScriptHash on a large script: benchmark old ns/op new ns/op delta BenchmarkIsWitnessScriptHash-8 62774 0.63 -100.00% benchmark old allocs new allocs delta BenchmarkIsWitnessScriptHash-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsWitnessScriptHash-8 311299 0 -100.00% --- txscript/script.go | 6 +----- txscript/standard.go | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 59dc2e27..5968cec7 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -100,11 +100,7 @@ func isWitnessScriptHash(pops []parsedOpcode) bool { // IsPayToWitnessScriptHash returns true if the is in the standard // pay-to-witness-script-hash (P2WSH) format, false otherwise. func IsPayToWitnessScriptHash(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isWitnessScriptHash(pops) + return isWitnessScriptHashScript(script) } // IsPayToWitnessPubKeyHash returns true if the is in the standard diff --git a/txscript/standard.go b/txscript/standard.go index 513c9ce1..a53180f1 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -421,6 +421,28 @@ func isWitnessPubKeyHashScript(script []byte) bool { return extractWitnessPubKeyHash(script) != nil } +// extractWitnessScriptHash extracts the witness script hash from the passed +// script if it is standard pay-to-witness-script-hash script. It will return +// nil otherwise. +func extractWitnessScriptHash(script []byte) []byte { + // A pay-to-witness-script-hash script is of the form: + // OP_0 OP_DATA_32 <32-byte-hash> + if len(script) == 34 && + script[0] == OP_0 && + script[1] == OP_DATA_32 { + + return script[2:34] + } + + return nil +} + +// isWitnessScriptHashScript returns whether or not the passed script is a +// standard pay-to-witness-script-hash script. +func isWitnessScriptHashScript(script []byte) bool { + return extractWitnessScriptHash(script) != nil +} + // isNullData returns true if the passed script is a null data transaction, // false otherwise. func isNullData(pops []parsedOpcode) bool { -- 2.45.2 From 4878db49cfabd2c83a94ac035fa29353624168f1 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:49 -0500 Subject: [PATCH 238/459] txscript: Add benchmark for IsNullData --- txscript/bench_test.go | 15 +++++++++++++++ txscript/script.go | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 529d32f7..fda83771 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -312,3 +312,18 @@ func BenchmarkIsWitnessScriptHash(b *testing.B) { _ = IsPayToWitnessScriptHash(script) } } + +// BenchmarkIsNullDataScript benchmarks how long it takes to analyze a very +// large script to determine if it is a standard nulldata script. +func BenchmarkIsNullDataScript(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsNullData(script) + } +} diff --git a/txscript/script.go b/txscript/script.go index 5968cec7..7f812207 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -151,6 +151,16 @@ func isWitnessProgram(pops []parsedOpcode) bool { (len(pops[1].data) >= 2 && len(pops[1].data) <= 40) } +// IsNullData returns true if the passed script is a null data script, false +// otherwise. +func IsNullData(script []byte) bool { + pops, err := parseScript(script) + if err != nil { + return false + } + return isNullData(pops) +} + // ExtractWitnessProgramInfo attempts to extract the witness program version, // as well as the witness program itself from the passed script. func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { -- 2.45.2 From b4f144ad8c318bc9889eaa90a03404fc96c3363c Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 15:15:34 -0800 Subject: [PATCH 239/459] txscript: Optimize IsNullData This converts the IsNullData function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimizing the function. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsNullDataScript-8 62495 2.65 -100.00% benchmark old allocs new allocs delta BenchmarkIsNullDataScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsNullDataScript-8 311299 0 -100.00% --- txscript/script.go | 7 ++----- txscript/standard.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 7f812207..691e31cc 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -154,11 +154,8 @@ func isWitnessProgram(pops []parsedOpcode) bool { // IsNullData returns true if the passed script is a null data script, false // otherwise. func IsNullData(script []byte) bool { - pops, err := parseScript(script) - if err != nil { - return false - } - return isNullData(pops) + const scriptVersion = 0 + return isNullDataScript(scriptVersion, script) } // ExtractWitnessProgramInfo attempts to extract the witness program version, diff --git a/txscript/standard.go b/txscript/standard.go index a53180f1..9825f61b 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -461,6 +461,41 @@ func isNullData(pops []parsedOpcode) bool { len(pops[1].data) <= MaxDataCarrierSize } +// isNullDataScript returns whether or not the passed script is a standard +// null data script. +// +// NOTE: This function is only valid for version 0 scripts. It will always +// return false for other script versions. +func isNullDataScript(scriptVersion uint16, script []byte) bool { + // The only currently supported script version is 0. + if scriptVersion != 0 { + return false + } + + // A null script is of the form: + // OP_RETURN + // + // Thus, it can either be a single OP_RETURN or an OP_RETURN followed by a + // data push up to MaxDataCarrierSize bytes. + + // The script can't possibly be a a null data script if it doesn't start + // with OP_RETURN. Fail fast to avoid more work below. + if len(script) < 1 || script[0] != OP_RETURN { + return false + } + + // Single OP_RETURN. + if len(script) == 1 { + return true + } + + // OP_RETURN followed by data push up to MaxDataCarrierSize bytes. + tokenizer := MakeScriptTokenizer(scriptVersion, script[1:]) + return tokenizer.Next() && tokenizer.Done() && + (isSmallInt(tokenizer.Opcode()) || tokenizer.Opcode() <= OP_PUSHDATA4) && + len(tokenizer.Data()) <= MaxDataCarrierSize +} + // scriptType returns the type of the script being inspected from the known // standard types. func typeOfScript(pops []parsedOpcode) ScriptClass { -- 2.45.2 From 90e7a42585ff69fd4acbbc8a8120d60048a18147 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:20 -0500 Subject: [PATCH 240/459] txscript: Add benchmark for IsUnspendable. --- txscript/bench_test.go | 14 ++++++++++++++ txscript/script_test.go | 13 ------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index fda83771..c8f7d0f7 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -327,3 +327,17 @@ func BenchmarkIsNullDataScript(b *testing.B) { _ = IsNullData(script) } } + +// BenchmarkIsUnspendable benchmarks how long it takes IsUnspendable to analyze +// a very large script. +func BenchmarkIsUnspendable(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = IsUnspendable(script) + } +} diff --git a/txscript/script_test.go b/txscript/script_test.go index 34c8ef97..665d9ef6 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -4334,16 +4334,3 @@ func TestIsUnspendable(t *testing.T) { } } } - -// BenchmarkIsUnspendable adds a benchmark to compare the time and allocations -// necessary for the IsUnspendable function. -func BenchmarkIsUnspendable(b *testing.B) { - pkScriptToUse := []byte{0xa9, 0x14, 0x82, 0x1d, 0xba, 0x94, 0xbc, 0xfb, 0xa2, 0x57, 0x36, 0xa3, 0x9e, 0x5d, 0x14, 0x5d, 0x69, 0x75, 0xba, 0x8c, 0x0b, 0x42, 0x87} - var res bool = false - for i := 0; i < b.N; i++ { - res = IsUnspendable(pkScriptToUse) - } - if res { - b.Fatalf("Benchmark should never have res be %t\n", res) - } -} -- 2.45.2 From 814f0bae891da288f1207ea178b5296dceb1ead8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:21 -0500 Subject: [PATCH 241/459] txscript: Optimize IsUnspendable. This converts the IsUnspendable function to make use of a combination of raw script analysis and the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. It is important to note that this new implementation intentionally has a semantic difference from the existing implementation in that it will now report scripts that are larger than the max allowed script size are unspendable as well. Finally, the comment is modified to explicitly call out the script version semantics. Note: this function was recently optimized in master, so the gains here are less noticable than other optimizations. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsUnspendable-8 656 584 -10.98% benchmark old allocs new allocs delta BenchmarkIsUnspendable-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsUnspendable-8 1 0 -100.00% --- txscript/script.go | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 691e31cc..e933167d 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -917,15 +917,22 @@ func checkScriptParses(scriptVersion uint16, script []byte) error { // IsUnspendable returns whether the passed public key script is unspendable, or // guaranteed to fail at execution. This allows inputs to be pruned instantly // when entering the UTXO set. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func IsUnspendable(pkScript []byte) bool { - // Not provably unspendable - if len(pkScript) == 0 { - return false - } - firstOpcode, err := checkScriptTemplateParseable(pkScript, &opcodeArray) - if err != nil { + // The script is unspendable if starts with OP_RETURN or is guaranteed + // to fail at execution due to being larger than the max allowed script + // size. + switch { + case len(pkScript) > 0 && pkScript[0] == OP_RETURN: + return true + case len(pkScript) > MaxScriptSize: return true } - return firstOpcode != nil && *firstOpcode == OP_RETURN + // The script is unspendable if it is guaranteed to fail at execution. + const scriptVersion = 0 + return checkScriptParses(scriptVersion, pkScript) != nil } -- 2.45.2 From 1814b48565616c291adc394a5ae3cb1ad2066f56 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 00:35:28 -0700 Subject: [PATCH 242/459] txscript/engine: Optimize new engine push only script This modifies the check for whether or not a pay-to-script-hash signature script is a push only script to make use of the new and more efficient raw script function. Also, since the script will have already been checked further above when the ScriptVerifySigPushOnly flags is set, avoid checking it again in that case. Backport of af67951b9a66df3aac1bf3d6376af0730287bbf2 --- txscript/engine.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/txscript/engine.go b/txscript/engine.go index 3c76b747..06f454d3 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -946,7 +946,11 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags if vm.hasFlag(ScriptBip16) && isScriptHash(vm.scripts[1]) { // Only accept input scripts that push data for P2SH. - if !isPushOnly(vm.scripts[0]) { + // Notice that the push only checks have already been done when + // the flag to verify signature scripts are push only is set + // above, so avoid checking again. + alreadyChecked := vm.hasFlag(ScriptVerifySigPushOnly) + if !alreadyChecked && !isPushOnly(vm.scripts[0]) { return nil, scriptError(ErrNotPushOnly, "pay to script hash is not push only") } -- 2.45.2 From c0b2b10241f7cd3afe6d117856f992f5e6be2972 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 00:43:38 -0700 Subject: [PATCH 243/459] txscript/engine: Use optimized IsPushOnlyScript --- txscript/engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/txscript/engine.go b/txscript/engine.go index 06f454d3..f0a94851 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -950,7 +950,7 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags // the flag to verify signature scripts are push only is set // above, so avoid checking again. alreadyChecked := vm.hasFlag(ScriptVerifySigPushOnly) - if !alreadyChecked && !isPushOnly(vm.scripts[0]) { + if !alreadyChecked && !IsPushOnlyScript(scriptSig) { return nil, scriptError(ErrNotPushOnly, "pay to script hash is not push only") } -- 2.45.2 From 2674b2926b5299fedcbe874168a822ea6166be0f Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 00:49:23 -0700 Subject: [PATCH 244/459] txscript/engine: Use optimized isScriptHashScript --- txscript/engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/txscript/engine.go b/txscript/engine.go index f0a94851..703baef7 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -944,7 +944,7 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags vm.scriptIdx++ } - if vm.hasFlag(ScriptBip16) && isScriptHash(vm.scripts[1]) { + if vm.hasFlag(ScriptBip16) && isScriptHashScript(scriptPubKey) { // Only accept input scripts that push data for P2SH. // Notice that the push only checks have already been done when // the flag to verify signature scripts are push only is set -- 2.45.2 From f1ab6cc7cb0805beba1496a4cece263ab41dc217 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 00:50:54 -0700 Subject: [PATCH 245/459] txscript/engine: Check ps2h push before parsing script This moves the check for non push-only pay-to-script-hash signature scripts before the script parsing logic when creating a new engine instance to avoid the extra overhead in the error case. --- txscript/engine.go | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 703baef7..576adc71 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -918,6 +918,21 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags "signature script is not push only") } + // The signature script must only contain data pushes for PS2H which is + // determined based on the form of the public key script. + if vm.hasFlag(ScriptBip16) && isScriptHashScript(scriptPubKey) { + // Only accept input scripts that push data for P2SH. + // Notice that the push only checks have already been done when + // the flag to verify signature scripts are push only is set + // above, so avoid checking again. + alreadyChecked := vm.hasFlag(ScriptVerifySigPushOnly) + if !alreadyChecked && !IsPushOnlyScript(scriptSig) { + return nil, scriptError(ErrNotPushOnly, + "pay to script hash is not push only") + } + vm.bip16 = true + } + // The engine stores the scripts in parsed form using a slice. This // allows multiple scripts to be executed in sequence. For example, // with a pay-to-script-hash transaction, there will be ultimately be @@ -943,19 +958,6 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags if len(scripts[0]) == 0 { vm.scriptIdx++ } - - if vm.hasFlag(ScriptBip16) && isScriptHashScript(scriptPubKey) { - // Only accept input scripts that push data for P2SH. - // Notice that the push only checks have already been done when - // the flag to verify signature scripts are push only is set - // above, so avoid checking again. - alreadyChecked := vm.hasFlag(ScriptVerifySigPushOnly) - if !alreadyChecked && !IsPushOnlyScript(scriptSig) { - return nil, scriptError(ErrNotPushOnly, - "pay to script hash is not push only") - } - vm.bip16 = true - } if vm.hasFlag(ScriptVerifyMinimalData) { vm.dstack.verifyMinimalData = true vm.astack.verifyMinimalData = true -- 2.45.2 From c7218b26229dba81cd6a3be6852aceb7c7c65a79 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:19 -0500 Subject: [PATCH 246/459] txscript: Add benchmark for GetSigOpCount. --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index c8f7d0f7..7d0b90c4 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -341,3 +341,18 @@ func BenchmarkIsUnspendable(b *testing.B) { _ = IsUnspendable(script) } } + +// BenchmarkGetSigOpCount benchmarks how long it takes to count the signature +// operations of a very large script. +func BenchmarkGetSigOpCount(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetSigOpCount(script) + } +} -- 2.45.2 From 873339c5bc416811793747b90c4f7c2149f08a96 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:20 -0500 Subject: [PATCH 247/459] txscript: Optimize GetSigOpCount. This converts the GetSigOpCount function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. A new function named countSigOpsV0 which accepts the raw script is introduced to perform the bulk of the work so it can be reused for precise signature operation counting as well in a later commit. It retains the same semantics in terms of counting the number of signature operations either up to the first parse error or the end of the script in the case it parses successfully as required by consensus. Finally, this also deprecates the getSigOpCount function that requires opcodes in favor of the new function and modifies the comment on GetSigOpCount to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkGetSigOpCount-8 61051 677 -98.89% benchmark old allocs new allocs delta BenchmarkGetSigOpCount-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkGetSigOpCount-8 311299 0 -100.00% --- txscript/script.go | 66 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index e933167d..32654f78 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -741,6 +741,8 @@ func asSmallInt(op byte) int { // signature operations in the script provided by pops. If precise mode is // requested then we attempt to count the number of operations for a multisig // op. Otherwise we use the maximum. +// +// DEPRECATED. Use countSigOpsV0 instead. func getSigOpCount(pops []parsedOpcode, precise bool) int { nSigs := 0 for i, pop := range pops { @@ -771,15 +773,71 @@ func getSigOpCount(pops []parsedOpcode, precise bool) int { return nSigs } +// countSigOpsV0 returns the number of signature operations in the provided +// script up to the point of the first parse failure or the entire script when +// there are no parse failures. The precise flag attempts to accurately count +// the number of operations for a multisig operation versus using the maximum +// allowed. +// +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before counting their signature operations which means nodes +// on existing rules will count new version scripts as if they were version 0. +func countSigOpsV0(script []byte, precise bool) int { + const scriptVersion = 0 + + numSigOps := 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + prevOp := byte(OP_INVALIDOPCODE) + for tokenizer.Next() { + switch tokenizer.Opcode() { + case OP_CHECKSIG, OP_CHECKSIGVERIFY: + numSigOps++ + + case OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY: + // Note that OP_0 is treated as the max number of sigops here in + // precise mode despite it being a valid small integer in order to + // highly discourage multisigs with zero pubkeys. + // + // Also, even though this is referred to as "precise" counting, it's + // not really precise at all due to the small int opcodes only + // covering 1 through 16 pubkeys, which means this will count any + // more than that value (e.g. 17, 18 19) as the maximum number of + // allowed pubkeys. This is, unfortunately, now part of + // the Bitcion consensus rules, due to historical + // reasons. This could be made more correct with a new + // script version, however, ideally all multisignaure + // operations in new script versions should move to + // aggregated schemes such as Schnorr instead. + if precise && prevOp >= OP_1 && prevOp <= OP_16 { + numSigOps += asSmallInt(prevOp) + } else { + numSigOps += MaxPubKeysPerMultiSig + } + + default: + // Not a sigop. + } + + prevOp = tokenizer.Opcode() + } + + return numSigOps +} + // GetSigOpCount provides a quick count of the number of signature operations // in a script. a CHECKSIG operations counts for 1, and a CHECK_MULTISIG for 20. // If the script fails to parse, then the count up to the point of failure is // returned. +// +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before counting their signature operations which means nodes +// on existing rules will count new version scripts as if they were version 0. func GetSigOpCount(script []byte) int { - // Don't check error since parseScript returns the parsed-up-to-error - // list of pops. - pops, _ := parseScript(script) - return getSigOpCount(pops, false) + return countSigOpsV0(script, false) } // finalOpcodeData returns the data associated with the final opcode in the -- 2.45.2 From 8de1bc3ecc4ff6f56179fa068a0e40ee46a1c9d7 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:30 -0500 Subject: [PATCH 248/459] txscript: Add benchmark for GetPreciseSigOpCount. --- txscript/bench_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 7d0b90c4..817eb98f 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -356,3 +356,29 @@ func BenchmarkGetSigOpCount(b *testing.B) { _ = GetSigOpCount(script) } } + +// BenchmarkGetPreciseSigOpCount benchmarks how long it takes to count the +// signature operations of a very large script using the more precise counting +// method. +func BenchmarkGetPreciseSigOpCount(b *testing.B) { + redeemScript, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + // Create a fake pay-to-script-hash to pass the necessary checks and create + // the signature script accordingly by pushing the generated "redeem" script + // as the final data push so the benchmark will cover the p2sh path. + scriptHash := "0x0000000000000000000000000000000000000001" + pkScript := mustParseShortForm("HASH160 DATA_20 " + scriptHash + " EQUAL") + sigScript, err := NewScriptBuilder().AddFullData(redeemScript).Script() + if err != nil { + b.Fatalf("failed to create signature script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetPreciseSigOpCount(sigScript, pkScript, true) + } +} -- 2.45.2 From b607be085224992af092510b69ab747b9aab18db Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:31 -0500 Subject: [PATCH 249/459] txscript: Optimize GetPreciseSigOpCount. This converts the GetPreciseSigOpCount function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. In particular it uses the recently converted isScriptHashScript, IsPushOnlyScript, and countSigOpsV0 functions along with the recently added finalOpcodeData functions. It also modifies the comment to explicitly call out the script version semantics. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkGetPreciseSigOpCount-8 130223 742 -99.43% benchmark old allocs new allocs delta BenchmarkGetPreciseSigOpCount-8 3 0 -100.00% benchmark old bytes new bytes delta BenchmarkGetPreciseSigOpCount-8 623367 0 -100.00% --- txscript/script.go | 48 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 32654f78..aee1aaac 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -864,44 +864,44 @@ func finalOpcodeData(scriptVersion uint16, script []byte) []byte { // Pay-To-Script-Hash script in order to find the precise number of signature // operations in the transaction. If the script fails to parse, then the count // up to the point of failure is returned. -func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, bip16 bool) int { - // Don't check error since parseScript returns the parsed-up-to-error - // list of pops. - pops, _ := parseScript(scriptPubKey) +// +// WARNING: This function always treats the passed script as version 0. Great +// care must be taken if introducing a new script version because it is used in +// consensus which, unfortunately as of the time of this writing, does not check +// script versions before counting their signature operations which means nodes +// on existing rules will count new version scripts as if they were version 0. +// +// The third parameter is DEPRECATED and is unused. +func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, _ bool) int { + const scriptVersion = 0 - // Treat non P2SH transactions as normal. - if !(bip16 && isScriptHash(pops)) { - return getSigOpCount(pops, true) - } - - // The public key script is a pay-to-script-hash, so parse the signature - // script to get the final item. Scripts that fail to fully parse count - // as 0 signature operations. - sigPops, err := parseScript(scriptSig) - if err != nil { - return 0 + // Treat non P2SH transactions as normal. Note that signature operation + // counting includes all operations up to the first parse failure. + if !isScriptHashScript(scriptPubKey) { + return countSigOpsV0(scriptPubKey, true) } // The signature script must only push data to the stack for P2SH to be // a valid pair, so the signature operation count is 0 when that is not // the case. - if !isPushOnly(sigPops) || len(sigPops) == 0 { + if len(scriptSig) == 0 || !IsPushOnlyScript(scriptSig) { return 0 } // The P2SH script is the last item the signature script pushes to the // stack. When the script is empty, there are no signature operations. - shScript := sigPops[len(sigPops)-1].data - if len(shScript) == 0 { + // + // Notice that signature scripts that fail to fully parse count as 0 + // signature operations unlike public key and redeem scripts. + redeemScript := finalOpcodeData(scriptVersion, scriptSig) + if len(redeemScript) == 0 { return 0 } - // Parse the P2SH script and don't check the error since parseScript - // returns the parsed-up-to-error list of pops and the consensus rules - // dictate signature operations are counted up to the first parse - // failure. - shPops, _ := parseScript(shScript) - return getSigOpCount(shPops, true) + // Return the more precise sigops count for the redeem script. Note that + // signature operation counting includes all operations up to the first + // parse failure. + return countSigOpsV0(redeemScript, true) } // GetWitnessSigOpCount returns the number of signature operations generated by -- 2.45.2 From 83442d60bf18866181df43fb44695b14a3a4224e Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 12:58:03 -0800 Subject: [PATCH 250/459] txscript: add GetWitnessSigOpCountBenchmarks --- txscript/bench_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 817eb98f..52965dca 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -382,3 +382,44 @@ func BenchmarkGetPreciseSigOpCount(b *testing.B) { _ = GetPreciseSigOpCount(sigScript, pkScript, true) } } + +// BenchmarkGetWitnessSigOpCount benchmarks how long it takes to count the +// witness signature operations of a very large script. +func BenchmarkGetWitnessSigOpCountP2WKH(b *testing.B) { + pkScript := mustParseShortForm("OP_0 DATA_20 0x0000000000000000000000000000000000000000") + redeemScript, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + witness := wire.TxWitness{ + redeemScript, + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetWitnessSigOpCount(nil, pkScript, witness) + } +} + +// BenchmarkGetWitnessSigOpCount benchmarks how long it takes to count the +// witness signature operations of a very large script. +func BenchmarkGetWitnessSigOpCountNested(b *testing.B) { + pkScript := mustParseShortForm("HASH160 DATA_20 0x0000000000000000000000000000000000000000 OP_EQUAL") + sigScript := mustParseShortForm("DATA_22 0x001600000000000000000000000000000000000000000000") + redeemScript, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + witness := wire.TxWitness{ + redeemScript, + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetWitnessSigOpCount(sigScript, pkScript, witness) + } +} -- 2.45.2 From 43e2a2acb2f82ff5877b97e8daac0afdbcf4f5a2 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:14:53 -0800 Subject: [PATCH 251/459] txscript: Optimize GetWitnessSigOpCount This converts the GetWitnessSigOpCount function to use a combination of raw script analysis and the new tokenizer instead of the far less efficeint parseScript, thereby significantly optimizing the funciton. In particular, it use the recently added countSigOpsv0 in precise mode to avoid calling paseScript. --- txscript/script.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index aee1aaac..b69c915a 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -955,8 +955,7 @@ func getWitnessSigOps(pkScript []byte, witness wire.TxWitness) int { len(witness) > 0: witnessScript := witness[len(witness)-1] - pops, _ := parseScript(witnessScript) - return getSigOpCount(pops, true) + return countSigOpsV0(witnessScript, true) } } -- 2.45.2 From aa5a1d1648095fe068cea09d3affac585812f34e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:32 -0500 Subject: [PATCH 252/459] txscript: Add benchmark for GetScriptClass. --- txscript/bench_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 52965dca..aba3d123 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -423,3 +423,18 @@ func BenchmarkGetWitnessSigOpCountNested(b *testing.B) { _ = GetWitnessSigOpCount(sigScript, pkScript, witness) } } + +// BenchmarkGetScriptClass benchmarks how long it takes GetScriptClass to +// analyze a very large script. +func BenchmarkGetScriptClass(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = GetScriptClass(script) + } +} -- 2.45.2 From 9ac8abd5199f23db0db271474e4e909fc933799e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:33 -0500 Subject: [PATCH 253/459] txscript: Make typeOfScript accept raw script. This converts the typeOfScript function to accept a script version and raw script instead of an array of internal parsed opcodes in order to make it more flexible for raw script analysis. Also, this adds a comment to CalcScriptInfo to call out the specific version semantics and deprecates the function since nothing currently uses it, and the relevant information can now be obtained by callers more directly through the use of the new script tokenizer. All other callers are updated accordingly. --- txscript/standard.go | 46 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 9825f61b..54c04318 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -498,7 +498,19 @@ func isNullDataScript(scriptVersion uint16, script []byte) bool { // scriptType returns the type of the script being inspected from the known // standard types. -func typeOfScript(pops []parsedOpcode) ScriptClass { +// +// NOTE: All scripts that are not version 0 are currently considered non +// standard. +func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { + if scriptVersion != 0 { + return NonStandardTy + } + + pops, err := parseScript(script) + if err != nil { + return NonStandardTy + } + if isPubkey(pops) { return PubKeyTy } else if isPubkeyHash(pops) { @@ -521,11 +533,8 @@ func typeOfScript(pops []parsedOpcode) ScriptClass { // // NonStandardTy will be returned when the script does not parse. func GetScriptClass(script []byte) ScriptClass { - pops, err := parseScript(script) - if err != nil { - return NonStandardTy - } - return typeOfScript(pops) + const scriptVersion = 0 + return typeOfScript(scriptVersion, script) } // NewScriptClass returns the ScriptClass corresponding to the string name @@ -608,9 +617,17 @@ type ScriptInfo struct { // pair. It will error if the pair is in someway invalid such that they can not // be analysed, i.e. if they do not parse or the pkScript is not a push-only // script +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +// +// DEPRECATED. This will be removed in the next major version bump. func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, bip16, segwit bool) (*ScriptInfo, error) { + const scriptVersion = 0 + sigPops, err := parseScript(sigScript) if err != nil { return nil, err @@ -621,9 +638,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, return nil, err } - // Push only sigScript makes little sense. si := new(ScriptInfo) - si.PkScriptClass = typeOfScript(pkPops) + si.PkScriptClass = typeOfScript(scriptVersion, pkScript) // Can't have a signature script that doesn't just push data. if !isPushOnly(sigPops) { @@ -644,7 +660,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, return nil, err } - shInputs := expectedInputs(shPops, typeOfScript(shPops)) + redeemClass := typeOfScript(scriptVersion, script) + shInputs := expectedInputs(shPops, redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -671,7 +688,9 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, // Extract the pushed witness program from the sigScript so we // can determine the number of expected inputs. pkPops, _ := parseScript(sigScript[1:]) - shInputs := expectedInputs(pkPops, typeOfScript(pkPops)) + + redeemClass := typeOfScript(scriptVersion, sigScript[1:]) + shInputs := expectedInputs(pkPops, redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -691,7 +710,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, witnessScript := witness[len(witness)-1] pops, _ := parseScript(witnessScript) - shInputs := expectedInputs(pops, typeOfScript(pops)) + redeemClass := typeOfScript(scriptVersion, witnessScript) + shInputs := expectedInputs(pops, redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -888,7 +908,9 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return NonStandardTy, nil, 0, err } - scriptClass := typeOfScript(pops) + const scriptVersion = 0 + scriptClass := typeOfScript(scriptVersion, pkScript) + switch scriptClass { case PubKeyHashTy: // A pay-to-pubkey-hash script is of the form: -- 2.45.2 From 603c2e3b2bcda11539c01ad94f98513d28dd6f1d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:34 -0500 Subject: [PATCH 254/459] txscript: Optimize typeOfScript pay-to-script-hash. This begins the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes with the intent of significantly optimizing the function. In order to ease the review process, each script type will be converted in a separate commit and the typeOfScript function will be updated such that the script is only parsed as a fallback for the cases that are not already converted to more efficient raw script variants. In particular, for this commit, since the ability to detect pay-to-script-hash via raw script analysis is now available, the function is simply updated to make use of it. --- txscript/standard.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 54c04318..fb3bb982 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -506,6 +506,11 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return NonStandardTy } + switch { + case isScriptHashScript(script): + return ScriptHashTy + } + pops, err := parseScript(script) if err != nil { return NonStandardTy @@ -517,8 +522,6 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return PubKeyHashTy } else if isWitnessPubKeyHash(pops) { return WitnessV0PubKeyHashTy - } else if isScriptHash(pops) { - return ScriptHashTy } else if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy } else if isMultiSig(pops) { -- 2.45.2 From c85458bc7c300f20ed86a11d055df44e52872889 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:35 -0500 Subject: [PATCH 255/459] txscript: Remove unused isScriptHash function. --- txscript/script.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index b69c915a..ca6520c8 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -54,17 +54,6 @@ func isSmallInt(op byte) bool { return op == OP_0 || (op >= OP_1 && op <= OP_16) } -// isScriptHash returns true if the script passed is a pay-to-script-hash -// transaction, false otherwise. -// -// DEPRECATED. Use isScriptHashScript or extractScriptHash instead. -func isScriptHash(pops []parsedOpcode) bool { - return len(pops) == 3 && - pops[0].opcode.value == OP_HASH160 && - pops[1].opcode.value == OP_DATA_20 && - pops[2].opcode.value == OP_EQUAL -} - // IsPayToPubKey returns true if the script is in the standard pay-to-pubkey // (P2PK) format, false otherwise. func IsPayToPubKey(script []byte) bool { -- 2.45.2 From cfb6bc93993495d3a9f972a149f3e0c42efe0831 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:36 -0500 Subject: [PATCH 256/459] txscript: Optimize typeOfScript multisig. This continues the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes. In particular, for this commit, since the ability to detect multisig scripts via the new tokenizer is now available, the function is simply updated to make use of it. --- txscript/standard.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index fb3bb982..dcd75214 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -509,6 +509,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { switch { case isScriptHashScript(script): return ScriptHashTy + case isMultisigScript(scriptVersion, script): + return MultiSigTy } pops, err := parseScript(script) @@ -524,8 +526,6 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return WitnessV0PubKeyHashTy } else if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy - } else if isMultiSig(pops) { - return MultiSigTy } else if isNullData(pops) { return NullDataTy } -- 2.45.2 From 1f2592117246ce6b23da8f109e07554d955ef0f2 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:37 -0500 Subject: [PATCH 257/459] txscript: Remove unused isMultiSig function. --- txscript/standard.go | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index dcd75214..2722bc41 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -214,42 +214,6 @@ func isPubkeyHash(pops []parsedOpcode) bool { } -// isMultiSig returns true if the passed script is a multisig transaction, false -// otherwise. -// -// DEPECATED. Use isMultisigScript or extractMultisigScriptDetails instead. -func isMultiSig(pops []parsedOpcode) bool { - // The absolute minimum is 1 pubkey: - // OP_0/OP_1-16 OP_1 OP_CHECKMULTISIG - l := len(pops) - if l < 4 { - return false - } - if !isSmallInt(pops[0].opcode.value) { - return false - } - if !isSmallInt(pops[l-2].opcode.value) { - return false - } - if pops[l-1].opcode.value != OP_CHECKMULTISIG { - return false - } - - // Verify the number of pubkeys specified matches the actual number - // of pubkeys provided. - if l-2-1 != asSmallInt(pops[l-2].opcode.value) { - return false - } - - for _, pop := range pops[1 : l-2] { - // Valid pubkeys are either 33 or 65 bytes. - if len(pop.data) != 33 && len(pop.data) != 65 { - return false - } - } - return true -} - // multiSigDetails houses details extracted from a standard multisig script. type multiSigDetails struct { requiredSigs int -- 2.45.2 From b1544cd4a9bf26be68f5c522190700705bca8931 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 14:07:19 -0800 Subject: [PATCH 258/459] txscript: Optimze typeOfScript pay-to-pubkey This continues the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the face less efficient parsed opcodes, with the intent of significantly optimizing the function. In particular, it converts the detection of pay-to-pubkey scripts to use raw script analysis. --- txscript/standard.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 2722bc41..52a37478 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -471,6 +471,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { } switch { + case isPubKeyScript(script): + return PubKeyTy case isScriptHashScript(script): return ScriptHashTy case isMultisigScript(scriptVersion, script): @@ -482,9 +484,7 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return NonStandardTy } - if isPubkey(pops) { - return PubKeyTy - } else if isPubkeyHash(pops) { + if isPubkeyHash(pops) { return PubKeyHashTy } else if isWitnessPubKeyHash(pops) { return WitnessV0PubKeyHashTy -- 2.45.2 From cb4018a1d4d601612dea0aa825920e5744b8b334 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:40 -0500 Subject: [PATCH 259/459] txscript: Remove unused isPubkey function. --- txscript/standard.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 52a37478..d2aa0e99 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -193,15 +193,6 @@ func isScriptHashScript(script []byte) bool { return extractScriptHash(script) != nil } -// isPubkey returns true if the script passed is a pay-to-pubkey transaction, -// false otherwise. -func isPubkey(pops []parsedOpcode) bool { - // Valid pubkeys are either 33 or 65 bytes. - return len(pops) == 2 && - (len(pops[0].data) == 33 || len(pops[0].data) == 65) && - pops[1].opcode.value == OP_CHECKSIG -} - // isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash // transaction, false otherwise. func isPubkeyHash(pops []parsedOpcode) bool { -- 2.45.2 From c52f41a5af956d1f6ed51da15c070b28ecf38036 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:45 -0500 Subject: [PATCH 260/459] txscript: Optimize typeOfScript pay-to-pubkey-hash. This continues the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes. In particular, it converts the detection of pay-to-pubkey-hash scripts to use raw script analysis. --- txscript/standard.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index d2aa0e99..08c6054e 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -464,6 +464,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { switch { case isPubKeyScript(script): return PubKeyTy + case isPubKeyHashScript(script): + return PubKeyHashTy case isScriptHashScript(script): return ScriptHashTy case isMultisigScript(scriptVersion, script): @@ -475,9 +477,7 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return NonStandardTy } - if isPubkeyHash(pops) { - return PubKeyHashTy - } else if isWitnessPubKeyHash(pops) { + if isWitnessPubKeyHash(pops) { return WitnessV0PubKeyHashTy } else if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy -- 2.45.2 From 461335437acaca96ad330ff9e496f0c33ea8ccab Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:46 -0500 Subject: [PATCH 261/459] txscript: Remove unused isPubkeyHash function. --- txscript/standard.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 08c6054e..ff382537 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -193,18 +193,6 @@ func isScriptHashScript(script []byte) bool { return extractScriptHash(script) != nil } -// isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash -// transaction, false otherwise. -func isPubkeyHash(pops []parsedOpcode) bool { - return len(pops) == 5 && - pops[0].opcode.value == OP_DUP && - pops[1].opcode.value == OP_HASH160 && - pops[2].opcode.value == OP_DATA_20 && - pops[3].opcode.value == OP_EQUALVERIFY && - pops[4].opcode.value == OP_CHECKSIG - -} - // multiSigDetails houses details extracted from a standard multisig script. type multiSigDetails struct { requiredSigs int -- 2.45.2 From b5e58f4a8d6db3dc72e1a44db1c483c9c516feeb Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Thu, 4 Feb 2021 15:15:45 -0800 Subject: [PATCH 262/459] txscript: Optimize typeOfScript for null data scripts This continues the process of converting the typeOfScript function to use a combination of raw script analysize and the tokenizer instead of parsed opcode, with the intent of significanty optimizing the function. In particular, it converts the detection of null data scripts to use raw script analysis. --- txscript/standard.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index ff382537..bae2b0c5 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -458,6 +458,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return ScriptHashTy case isMultisigScript(scriptVersion, script): return MultiSigTy + case isNullDataScript(scriptVersion, script): + return NullDataTy } pops, err := parseScript(script) @@ -469,9 +471,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return WitnessV0PubKeyHashTy } else if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy - } else if isNullData(pops) { - return NullDataTy } + return NonStandardTy } -- 2.45.2 From 9cfaf490246159a1221f2d185b5214be504ad5d4 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:11:51 -0500 Subject: [PATCH 263/459] txscript: Remove unused isNullData function. --- txscript/standard.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index bae2b0c5..85b28582 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -386,24 +386,6 @@ func isWitnessScriptHashScript(script []byte) bool { return extractWitnessScriptHash(script) != nil } -// isNullData returns true if the passed script is a null data transaction, -// false otherwise. -func isNullData(pops []parsedOpcode) bool { - // A nulldata transaction is either a single OP_RETURN or an - // OP_RETURN SMALLDATA (where SMALLDATA is a data push up to - // MaxDataCarrierSize bytes). - l := len(pops) - if l == 1 && pops[0].opcode.value == OP_RETURN { - return true - } - - return l == 2 && - pops[0].opcode.value == OP_RETURN && - (isSmallInt(pops[1].opcode.value) || pops[1].opcode.value <= - OP_PUSHDATA4) && - len(pops[1].data) <= MaxDataCarrierSize -} - // isNullDataScript returns whether or not the passed script is a standard // null data script. // -- 2.45.2 From 918278a2514361dcf173b855b5ae6d227ac3d3b3 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 01:46:52 -0700 Subject: [PATCH 264/459] txscript: Optimize typeOfScript witness-pubkey-hash This continues the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes. In particular, it converts the detection of witness pubkey hash scripts to use raw script analysis and the new tokenizer. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsWitnessPubKeyHash-8 61688 62839 +1.87% benchmark old allocs new allocs delta BenchmarkIsWitnessPubKeyHash-8 1 1 +0.00% benchmark old bytes new bytes delta BenchmarkIsWitnessPubKeyHash-8 311299 311299 +0.00% --- txscript/standard.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 85b28582..5d5c6687 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -355,6 +355,7 @@ func extractWitnessPubKeyHash(script []byte) []byte { return script[2:22] } + return nil } @@ -438,6 +439,8 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return PubKeyHashTy case isScriptHashScript(script): return ScriptHashTy + case isWitnessPubKeyHashScript(script): + return WitnessV0PubKeyHashTy case isMultisigScript(scriptVersion, script): return MultiSigTy case isNullDataScript(scriptVersion, script): @@ -449,9 +452,7 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return NonStandardTy } - if isWitnessPubKeyHash(pops) { - return WitnessV0PubKeyHashTy - } else if isWitnessScriptHash(pops) { + if isWitnessScriptHash(pops) { return WitnessV0ScriptHashTy } -- 2.45.2 From 6e0abb61bd0e028508a73566338af2aa17889459 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 02:04:01 -0700 Subject: [PATCH 265/459] txscript: Optimize typeOfScript for witness-script-hash This concludes the process of converting the typeOfScript function to use a combination of raw script analysis and the new tokenizer instead of the far less efficient parsed opcodes. In particular, it converts the detection of witness script hash scripts to use raw script analysis and the new tokenizer. With all of the limbs now useing optimized variants, the following is a before an after comparison of calling GetScriptClass on a large script: benchmark old ns/op new ns/op delta BenchmarkGetScriptClass-8 61515 15.3 -99.98% benchmark old allocs new allocs delta BenchmarkGetScriptClass-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkGetScriptClass-8 311299 0 -100.00% --- txscript/standard.go | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 5d5c6687..dd751cbe 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -441,22 +441,15 @@ func typeOfScript(scriptVersion uint16, script []byte) ScriptClass { return ScriptHashTy case isWitnessPubKeyHashScript(script): return WitnessV0PubKeyHashTy + case isWitnessScriptHashScript(script): + return WitnessV0ScriptHashTy case isMultisigScript(scriptVersion, script): return MultiSigTy case isNullDataScript(scriptVersion, script): return NullDataTy - } - - pops, err := parseScript(script) - if err != nil { + default: return NonStandardTy } - - if isWitnessScriptHash(pops) { - return WitnessV0ScriptHashTy - } - - return NonStandardTy } // GetScriptClass returns the class of the script passed. -- 2.45.2 From 0edfee87d65cbad01c6774558156288d475630ef Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 02:05:04 -0700 Subject: [PATCH 266/459] txscript: Remove unused isWitnessScriptHash --- txscript/script.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index ca6520c8..0d041a8b 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -78,14 +78,6 @@ func IsPayToScriptHash(script []byte) bool { return isScriptHashScript(script) } -// isWitnessScriptHash returns true if the passed script is a -// pay-to-witness-script-hash transaction, false otherwise. -func isWitnessScriptHash(pops []parsedOpcode) bool { - return len(pops) == 2 && - pops[0].opcode.value == OP_0 && - pops[1].opcode.value == OP_DATA_32 -} - // IsPayToWitnessScriptHash returns true if the is in the standard // pay-to-witness-script-hash (P2WSH) format, false otherwise. func IsPayToWitnessScriptHash(script []byte) bool { -- 2.45.2 From ded9b8c5067d4db6dac35e8cdbd7cf59ec32b527 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:09 -0500 Subject: [PATCH 267/459] txscript: Convert CalcScriptInfo. This converts CalcScriptInfo and dependent expectedInputs to make use of the new script tokenizer as well as several of the other recently added raw script analysis functions in order to remove the reliance on parsed opcodes as a step towards utlimately removing them altogether. It is worth noting that this has the side effect of significantly optimizing the function as well, however, since it is deprecated, no benchmarks are provided. --- txscript/standard.go | 76 +++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index dd751cbe..fea6799f 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -481,7 +481,11 @@ func NewScriptClass(name string) (*ScriptClass, error) { // then -1 is returned. We are an internal function and thus assume that class // is the real class of pops (and we can thus assume things that were determined // while finding out the type). -func expectedInputs(pops []parsedOpcode, class ScriptClass) int { +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func expectedInputs(script []byte, class ScriptClass) int { switch class { case PubKeyTy: return 1 @@ -508,7 +512,7 @@ func expectedInputs(pops []parsedOpcode, class ScriptClass) int { // the original bitcoind bug where OP_CHECKMULTISIG pops an // additional item from the stack, add an extra expected input // for the extra push that is required to compensate. - return asSmallInt(pops[0].opcode.value) + 1 + return asSmallInt(script[0]) + 1 case NullDataTy: fallthrough @@ -549,52 +553,52 @@ type ScriptInfo struct { func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, bip16, segwit bool) (*ScriptInfo, error) { + // Count the number of opcodes in the signature script while also ensuring + // that successfully parses. Since there is a check below to ensure the + // script is push only, this equates to the number of inputs to the public + // key script. const scriptVersion = 0 - - sigPops, err := parseScript(sigScript) - if err != nil { + var numInputs int + tokenizer := MakeScriptTokenizer(scriptVersion, sigScript) + for tokenizer.Next() { + numInputs++ + } + if err := tokenizer.Err(); err != nil { return nil, err } - pkPops, err := parseScript(pkScript) - if err != nil { + if err := checkScriptParses(scriptVersion, pkScript); err != nil { return nil, err } + // Can't have a signature script that doesn't just push data. + if !IsPushOnlyScript(sigScript) { + return nil, scriptError(ErrNotPushOnly, + "signature script is not push only") + } + si := new(ScriptInfo) si.PkScriptClass = typeOfScript(scriptVersion, pkScript) - // Can't have a signature script that doesn't just push data. - if !isPushOnly(sigPops) { - return nil, scriptError(ErrNotPushOnly, - "signature script is not push only") - } - - si.ExpectedInputs = expectedInputs(pkPops, si.PkScriptClass) + si.ExpectedInputs = expectedInputs(pkScript, si.PkScriptClass) switch { // Count sigops taking into account pay-to-script-hash. case si.PkScriptClass == ScriptHashTy && bip16 && !segwit: - // The pay-to-hash-script is the final data push of the - // signature script. - script := sigPops[len(sigPops)-1].data - shPops, err := parseScript(script) - if err != nil { - return nil, err - } - - redeemClass := typeOfScript(scriptVersion, script) - shInputs := expectedInputs(shPops, redeemClass) - if shInputs == -1 { + // The redeem script is the final data push of the signature script. + redeemScript := finalOpcodeData(scriptVersion, sigScript) + reedeemClass := typeOfScript(scriptVersion, redeemScript) + rsInputs := expectedInputs(redeemScript, reedeemClass) + if rsInputs == -1 { si.ExpectedInputs = -1 } else { - si.ExpectedInputs += shInputs + si.ExpectedInputs += rsInputs } - si.SigOps = getSigOpCount(shPops, true) + si.SigOps = countSigOpsV0(redeemScript, true) // All entries pushed to stack (or are OP_RESERVED and exec // will fail). - si.NumInputs = len(sigPops) + si.NumInputs = numInputs // If segwit is active, and this is a regular p2wkh output, then we'll // treat the script as a p2pkh output in essence. @@ -610,10 +614,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, // Extract the pushed witness program from the sigScript so we // can determine the number of expected inputs. - pkPops, _ := parseScript(sigScript[1:]) - redeemClass := typeOfScript(scriptVersion, sigScript[1:]) - shInputs := expectedInputs(pkPops, redeemClass) + shInputs := expectedInputs(sigScript[1:], redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -623,18 +625,14 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, si.SigOps = GetWitnessSigOpCount(sigScript, pkScript, witness) si.NumInputs = len(witness) - si.NumInputs += len(sigPops) + si.NumInputs += numInputs // If segwit is active, and this is a p2wsh output, then we'll need to // examine the witness script to generate accurate script info. case si.PkScriptClass == WitnessV0ScriptHashTy && segwit: - // The witness script is the final element of the witness - // stack. witnessScript := witness[len(witness)-1] - pops, _ := parseScript(witnessScript) - redeemClass := typeOfScript(scriptVersion, witnessScript) - shInputs := expectedInputs(pops, redeemClass) + shInputs := expectedInputs(witnessScript, redeemClass) if shInputs == -1 { si.ExpectedInputs = -1 } else { @@ -645,11 +643,11 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, si.NumInputs = len(witness) default: - si.SigOps = getSigOpCount(pkPops, true) + si.SigOps = countSigOpsV0(pkScript, true) // All entries pushed to stack (or are OP_RESERVED and exec // will fail). - si.NumInputs = len(sigPops) + si.NumInputs = numInputs } return si, nil -- 2.45.2 From e9a777d84e90a969087f6ee0aef1645b3fcf24ff Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:10 -0500 Subject: [PATCH 268/459] txscript: Remove unused isPushOnly function. --- txscript/script.go | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 0d041a8b..7e0e3669 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -161,26 +161,6 @@ func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { return witnessVersion, witnessProgram, nil } -// isPushOnly returns true if the script only pushes data, false otherwise. -// -// DEPRECATED. Use IsPushOnlyScript instead. -func isPushOnly(pops []parsedOpcode) bool { - // NOTE: This function does NOT verify opcodes directly since it is - // internal and is only called with parsed opcodes for scripts that did - // not have any parse errors. Thus, consensus is properly maintained. - - for _, pop := range pops { - // All opcodes up to OP_16 are data push instructions. - // NOTE: This does consider OP_RESERVED to be a data push - // instruction, but execution of OP_RESERVED will fail anyways - // and matches the behavior required by consensus. - if pop.opcode.value > OP_16 { - return false - } - } - return true -} - // IsPushOnlyScript returns whether or not the passed script only pushes data // according to the consensus definition of pushing data. // @@ -901,11 +881,7 @@ func GetWitnessSigOpCount(sigScript, pkScript []byte, witness wire.TxWitness) in // Next, we'll check the sigScript to see if this is a nested p2sh // witness program. This is a case wherein the sigScript is actually a // datapush of a p2wsh witness program. - sigPops, err := parseScript(sigScript) - if err != nil { - return 0 - } - if IsPayToScriptHash(pkScript) && isPushOnly(sigPops) && + if IsPayToScriptHash(pkScript) && IsPushOnlyScript(sigScript) && IsWitnessProgram(sigScript[1:]) { return getWitnessSigOps(sigScript[1:], witness) } -- 2.45.2 From ea7b0e381671422a9a95729679063b3b3e043b2d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:11 -0500 Subject: [PATCH 269/459] txscript: Remove unused getSigOpCount function. --- txscript/script.go | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 7e0e3669..10ff4315 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -698,42 +698,6 @@ func asSmallInt(op byte) int { return int(op - (OP_1 - 1)) } -// getSigOpCount is the implementation function for counting the number of -// signature operations in the script provided by pops. If precise mode is -// requested then we attempt to count the number of operations for a multisig -// op. Otherwise we use the maximum. -// -// DEPRECATED. Use countSigOpsV0 instead. -func getSigOpCount(pops []parsedOpcode, precise bool) int { - nSigs := 0 - for i, pop := range pops { - switch pop.opcode.value { - case OP_CHECKSIG: - fallthrough - case OP_CHECKSIGVERIFY: - nSigs++ - case OP_CHECKMULTISIG: - fallthrough - case OP_CHECKMULTISIGVERIFY: - // If we are being precise then look for familiar - // patterns for multisig, for now all we recognize is - // OP_1 - OP_16 to signify the number of pubkeys. - // Otherwise, we use the max of 20. - if precise && i > 0 && - pops[i-1].opcode.value >= OP_1 && - pops[i-1].opcode.value <= OP_16 { - nSigs += asSmallInt(pops[i-1].opcode.value) - } else { - nSigs += MaxPubKeysPerMultiSig - } - default: - // Not a sigop. - } - } - - return nSigs -} - // countSigOpsV0 returns the number of signature operations in the provided // script up to the point of the first parse failure or the entire script when // there are no parse failures. The precise flag attempts to accurately count -- 2.45.2 From e0cafeb4ca2adbe3a9cda15c98c78123437fdfd0 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:13 -0500 Subject: [PATCH 270/459] txscript: Optimize CalcMultiSigStats. This converts the CalcMultiSigStats function to make use of the new extractMultisigScriptDetails function instead of the far less efficient parseScript thereby significantly optimizing the function. The tests are also updated accordingly. The following is a before and after comparison of analyzing a standard multisig script: benchmark old ns/op new ns/op delta --------------------------------------------------------------- BenchmarkCalcMultiSigStats 972 79.5 -91.82% benchmark old allocs new allocs delta --------------------------------------------------------------- BenchmarkCalcMultiSigStats 1 0 -100.00% benchmark old bytes new bytes delta --------------------------------------------------------------- BenchmarkCalcMultiSigStats 2304 0 -100.00% --- txscript/standard.go | 26 ++++++++++---------------- txscript/standard_test.go | 8 ++------ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index fea6799f..3bb12b9a 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -656,27 +656,21 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, // CalcMultiSigStats returns the number of public keys and signatures from // a multi-signature transaction script. The passed script MUST already be // known to be a multi-signature script. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func CalcMultiSigStats(script []byte) (int, int, error) { - pops, err := parseScript(script) - if err != nil { - return 0, 0, err - } - - // A multi-signature script is of the pattern: - // NUM_SIGS PUBKEY PUBKEY PUBKEY... NUM_PUBKEYS OP_CHECKMULTISIG - // Therefore the number of signatures is the oldest item on the stack - // and the number of pubkeys is the 2nd to last. Also, the absolute - // minimum for a multi-signature script is 1 pubkey, so at least 4 - // items must be on the stack per: - // OP_1 PUBKEY OP_1 OP_CHECKMULTISIG - if len(pops) < 4 { + // The public keys are not needed here, so pass false to avoid the extra + // allocation. + const scriptVersion = 0 + details := extractMultisigScriptDetails(scriptVersion, script, false) + if !details.valid { str := fmt.Sprintf("script %x is not a multisig script", script) return 0, 0, scriptError(ErrNotMultisigScript, str) } - numSigs := asSmallInt(pops[0].opcode.value) - numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value) - return numPubKeys, numSigs, nil + return details.numPubKeys, details.requiredSigs, nil } // payToPubKeyHashScript creates a new script to pay a transaction diff --git a/txscript/standard_test.go b/txscript/standard_test.go index 37dd8f8a..582d30ee 100644 --- a/txscript/standard_test.go +++ b/txscript/standard_test.go @@ -832,7 +832,7 @@ func TestCalcMultiSigStats(t *testing.T) { name: "short script", script: "0x046708afdb0fe5548271967f1a67130b7105cd6a828" + "e03909a67962e0ea1f61d", - err: scriptError(ErrMalformedPush, ""), + err: scriptError(ErrNotMultisigScript, ""), }, { name: "stack underflow", @@ -843,11 +843,7 @@ func TestCalcMultiSigStats(t *testing.T) { }, { name: "multisig script", - script: "0 DATA_72 0x30450220106a3e4ef0b51b764a2887226" + - "2ffef55846514dacbdcbbdd652c849d395b4384022100" + - "e03ae554c3cbb40600d31dd46fc33f25e47bf8525b1fe" + - "07282e3b6ecb5f3bb2801 CODESEPARATOR 1 DATA_33 " + - "0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" + + script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" + "0357b3a7886211ab414d55a 1 CHECKMULTISIG", err: nil, }, -- 2.45.2 From e063742295d1071330d3cdea0e76c14e33c459cc Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:18 -0500 Subject: [PATCH 271/459] txscript: Add benchmark for PushedData. --- txscript/bench_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index aba3d123..26b7c9fe 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -438,3 +438,21 @@ func BenchmarkGetScriptClass(b *testing.B) { _ = GetScriptClass(script) } } + +// BenchmarkPushedData benchmarks how long it takes to extract the pushed data +// from a very large script. +func BenchmarkPushedData(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, err := PushedData(script) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} -- 2.45.2 From afb68c4ea2c5bbd208b8dd21fa81ba2b21537848 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:19 -0500 Subject: [PATCH 272/459] txscript: Optimize PushedData. This converts the PushedData function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. Also, the comment is modified to explicitly call out the script version semantics. The following is a before and after comparison of extracting the data from a very large script: benchmark old ns/op new ns/op delta BenchmarkPushedData-8 64837 1790 -97.24% benchmark old allocs new allocs delta BenchmarkPushedData-8 7 6 -14.29% benchmark old bytes new bytes delta BenchmarkPushedData-8 312816 1520 -99.51% --- txscript/standard.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 3bb12b9a..0607b305 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -791,20 +791,25 @@ func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, er // PushedData returns an array of byte slices containing any pushed data found // in the passed script. This includes OP_0, but not OP_1 - OP_16. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func PushedData(script []byte) ([][]byte, error) { - pops, err := parseScript(script) - if err != nil { - return nil, err - } + const scriptVersion = 0 var data [][]byte - for _, pop := range pops { - if pop.data != nil { - data = append(data, pop.data) - } else if pop.opcode.value == OP_0 { + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if tokenizer.Data() != nil { + data = append(data, tokenizer.Data()) + } else if tokenizer.Opcode() == OP_0 { data = append(data, nil) } } + if err := tokenizer.Err(); err != nil { + return nil, err + } return data, nil } -- 2.45.2 From ef4e5611195f0b913d02a592928a66d4829d2cac Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:22 -0500 Subject: [PATCH 273/459] txscript: Make canonicalPush accept raw opcode. This renames the canonicalPush function to isCanonicalPush and converts it to accept an opcode as a byte and the associate data as a byte slice instead of the internal parse opcode data struct in order to make it more flexible for raw script analysis. It also updates all callers and tests accordingly. --- txscript/engine.go | 5 +++- txscript/script.go | 23 ++++++++------ txscript/script_test.go | 66 ++++++++++++++++++----------------------- txscript/standard.go | 4 +-- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 576adc71..ef7ad33e 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -875,6 +875,7 @@ func (vm *Engine) SetAltStack(data [][]byte) { // engine according to the description provided by each flag. func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags, sigCache *SigCache, hashCache *TxSigHashes, inputAmount int64) (*Engine, error) { + const scriptVersion = 0 // The provided transaction input index must refer to a valid input. if txIdx < 0 || txIdx >= len(tx.TxIn) { @@ -994,7 +995,9 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags // data push of the witness program, otherwise we // reintroduce malleability. sigPops := vm.scripts[0] - if len(sigPops) == 1 && canonicalPush(sigPops[0]) && + if len(sigPops) == 1 && + isCanonicalPush(sigPops[0].opcode.value, + sigPops[0].data) && IsWitnessProgram(sigPops[0].data) { witProgram = sigPops[0].data diff --git a/txscript/script.go b/txscript/script.go index 10ff4315..52bedf26 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -128,7 +128,7 @@ func IsWitnessProgram(script []byte) bool { func isWitnessProgram(pops []parsedOpcode) bool { return len(pops) == 2 && isSmallInt(pops[0].opcode.value) && - canonicalPush(pops[1]) && + isCanonicalPush(pops[1].opcode.value, pops[1].data) && (len(pops[1].data) >= 2 && len(pops[1].data) <= 40) } @@ -305,13 +305,16 @@ func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode { return retScript } -// canonicalPush returns true if the object is either not a push instruction -// or the push instruction contained wherein is matches the canonical form -// or using the smallest instruction to do the job. False otherwise. -func canonicalPush(pop parsedOpcode) bool { - opcode := pop.opcode.value - data := pop.data - dataLen := len(pop.data) +// isCanonicalPush returns true if the opcode is either not a push instruction +// or the data associated with the push instruction uses the smallest +// instruction to do the job. False otherwise. +// +// For example, it is possible to push a value of 1 to the stack as "OP_1", +// "OP_DATA_1 0x01", "OP_PUSHDATA1 0x01 0x01", and others, however, the first +// only takes a single byte, while the rest take more. Only the first is +// considered canonical. +func isCanonicalPush(opcode byte, data []byte) bool { + dataLen := len(data) if opcode > OP_16 { return true } @@ -336,7 +339,9 @@ func canonicalPush(pop parsedOpcode) bool { func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode { retScript := make([]parsedOpcode, 0, len(pkscript)) for _, pop := range pkscript { - if !canonicalPush(pop) || !bytes.Contains(pop.data, data) { + if !isCanonicalPush(pop.opcode.value, pop.data) || + !bytes.Contains(pop.data, data) { + retScript = append(retScript, pop) } } diff --git a/txscript/script_test.go b/txscript/script_test.go index 665d9ef6..62c51e41 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -3740,31 +3740,25 @@ func TestPushedData(t *testing.T) { } } -// TestHasCanonicalPush ensures the canonicalPush function works as expected. +// TestHasCanonicalPush ensures the isCanonicalPush function works as expected. func TestHasCanonicalPush(t *testing.T) { t.Parallel() + const scriptVersion = 0 for i := 0; i < 65535; i++ { script, err := NewScriptBuilder().AddInt64(int64(i)).Script() if err != nil { - t.Errorf("Script: test #%d unexpected error: %v\n", i, - err) + t.Errorf("Script: test #%d unexpected error: %v\n", i, err) continue } - if result := IsPushOnlyScript(script); !result { - t.Errorf("IsPushOnlyScript: test #%d failed: %x\n", i, - script) + if !IsPushOnlyScript(script) { + t.Errorf("IsPushOnlyScript: test #%d failed: %x\n", i, script) continue } - pops, err := parseScript(script) - if err != nil { - t.Errorf("parseScript: #%d failed: %v", i, err) - continue - } - for _, pop := range pops { - if result := canonicalPush(pop); !result { - t.Errorf("canonicalPush: test #%d failed: %x\n", - i, script) + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { + t.Errorf("isCanonicalPush: test #%d failed: %x\n", i, script) break } } @@ -3774,21 +3768,17 @@ func TestHasCanonicalPush(t *testing.T) { builder.AddData(bytes.Repeat([]byte{0x49}, i)) script, err := builder.Script() if err != nil { - t.Errorf("StandardPushesTests test #%d unexpected error: %v\n", i, err) + t.Errorf("Script: test #%d unexpected error: %v\n", i, err) continue } - if result := IsPushOnlyScript(script); !result { - t.Errorf("StandardPushesTests IsPushOnlyScript test #%d failed: %x\n", i, script) + if !IsPushOnlyScript(script) { + t.Errorf("IsPushOnlyScript: test #%d failed: %x\n", i, script) continue } - pops, err := parseScript(script) - if err != nil { - t.Errorf("StandardPushesTests #%d failed to TstParseScript: %v", i, err) - continue - } - for _, pop := range pops { - if result := canonicalPush(pop); !result { - t.Errorf("StandardPushesTests TstHasCanonicalPushes test #%d failed: %x\n", i, script) + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { + t.Errorf("isCanonicalPush: test #%d failed: %x\n", i, script) break } } @@ -4213,11 +4203,13 @@ func TestIsPayToWitnessPubKeyHash(t *testing.T) { } } -// TestHasCanonicalPushes ensures the canonicalPush function properly determines -// what is considered a canonical push for the purposes of removeOpcodeByData. +// TestHasCanonicalPushes ensures the isCanonicalPush function properly +// determines what is considered a canonical push for the purposes of +// removeOpcodeByData. func TestHasCanonicalPushes(t *testing.T) { t.Parallel() + const scriptVersion = 0 tests := []struct { name string script string @@ -4236,20 +4228,20 @@ func TestHasCanonicalPushes(t *testing.T) { }, } - for i, test := range tests { + for _, test := range tests { script := mustParseShortForm(test.script) - pops, err := parseScript(script) - if err != nil { + if err := checkScriptParses(scriptVersion, script); err != nil { if test.expected { - t.Errorf("TstParseScript #%d failed: %v", i, err) + t.Errorf("%q: script parse failed: %v", test.name, err) } continue } - for _, pop := range pops { - if canonicalPush(pop) != test.expected { - t.Errorf("canonicalPush: #%d (%s) wrong result"+ - "\ngot: %v\nwant: %v", i, test.name, - true, test.expected) + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + result := isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) + if result != test.expected { + t.Errorf("%q: isCanonicalPush wrong result\ngot: %v\nwant: %v", + test.name, result, test.expected) break } } diff --git a/txscript/standard.go b/txscript/standard.go index 0607b305..d97072f1 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -953,7 +953,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa } isAtomicSwap := pops[0].opcode.value == OP_IF && pops[1].opcode.value == OP_SIZE && - canonicalPush(pops[2]) && + isCanonicalPush(pops[2].opcode.value, pops[2].data) && pops[3].opcode.value == OP_EQUALVERIFY && pops[4].opcode.value == OP_SHA256 && pops[5].opcode.value == OP_DATA_32 && @@ -962,7 +962,7 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa pops[8].opcode.value == OP_HASH160 && pops[9].opcode.value == OP_DATA_20 && pops[10].opcode.value == OP_ELSE && - canonicalPush(pops[11]) && + isCanonicalPush(pops[11].opcode.value, pops[11].data) && pops[12].opcode.value == OP_CHECKLOCKTIMEVERIFY && pops[13].opcode.value == OP_DROP && pops[14].opcode.value == OP_DUP && -- 2.45.2 From 76fcfbaa1f8e47c34f2a35ac9134c55c31d2d969 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:24 -0500 Subject: [PATCH 274/459] txscript: Add ExtractAtomicSwapDataPushes benches. --- txscript/bench_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 26b7c9fe..456db25d 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -456,3 +456,44 @@ func BenchmarkPushedData(b *testing.B) { } } } + +// BenchmarkExtractAtomicSwapDataPushesLarge benchmarks how long it takes +// ExtractAtomicSwapDataPushes to analyze a very large script. +func BenchmarkExtractAtomicSwapDataPushesLarge(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + const scriptVersion = 0 + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, err := ExtractAtomicSwapDataPushes(scriptVersion, script) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} + +// BenchmarkExtractAtomicSwapDataPushesLarge benchmarks how long it takes +// ExtractAtomicSwapDataPushes to analyze a standard atomic swap script. +func BenchmarkExtractAtomicSwapDataPushes(b *testing.B) { + secret := "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" + recipient := "0000000000000000000000000000000000000001" + refund := "0000000000000000000000000000000000000002" + script := mustParseShortForm(fmt.Sprintf("IF SIZE 32 EQUALVERIFY SHA256 "+ + "DATA_32 0x%s EQUALVERIFY DUP HASH160 DATA_20 0x%s ELSE 300000 "+ + "CHECKLOCKTIMEVERIFY DROP DUP HASH160 DATA_20 0x%s ENDIF "+ + "EQUALVERIFY CHECKSIG", secret, recipient, refund)) + + const scriptVersion = 0 + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, err := ExtractAtomicSwapDataPushes(scriptVersion, script) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} -- 2.45.2 From 767dae7adfda959d904e68dbfd619d39c91a9157 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 03:05:55 -0700 Subject: [PATCH 275/459] txscript/scriptnum: add maxscriptnum and maxcltvlength --- txscript/scriptnum.go | 20 ++++-- txscript/scriptnum_test.go | 126 ++++++++++++++++++------------------- txscript/stack.go | 4 +- 3 files changed, 81 insertions(+), 69 deletions(-) diff --git a/txscript/scriptnum.go b/txscript/scriptnum.go index a89d5f39..81f26361 100644 --- a/txscript/scriptnum.go +++ b/txscript/scriptnum.go @@ -12,9 +12,21 @@ const ( maxInt32 = 1<<31 - 1 minInt32 = -1 << 31 - // defaultScriptNumLen is the default number of bytes - // data being interpreted as an integer may be. - defaultScriptNumLen = 4 + // maxScriptNumLen is the maximum number of bytes data being interpreted + // as an integer may be for the majority of op codes. + maxScriptNumLen = 4 + + // cltvMaxScriptNumLen is the maximum number of bytes data being interpreted + // as an integer may be for by-time and by-height locks as interpreted by + // CHECKLOCKTIMEVERIFY. + // + // The value comes from the fact that the current transaction locktime + // is a uint32 resulting in a maximum locktime of 2^32-1 (the year + // 2106). However, scriptNums are signed and therefore a standard + // 4-byte scriptNum would only support up to a maximum of 2^31-1 (the + // year 2038). Thus, a 5-byte scriptNum is needed since it will support + // up to 2^39-1 which allows dates beyond the current locktime limit. + cltvMaxScriptNumLen = 5 ) // scriptNum represents a numeric value used in the scripting engine with @@ -178,7 +190,7 @@ func (n scriptNum) Int32() int32 { // before an ErrStackNumberTooBig is returned. This effectively limits the // range of allowed values. // WARNING: Great care should be taken if passing a value larger than -// defaultScriptNumLen, which could lead to addition and multiplication +// maxScriptNumLen, which could lead to addition and multiplication // overflows. // // See the Bytes function documentation for example encodings. diff --git a/txscript/scriptnum_test.go b/txscript/scriptnum_test.go index e32862b7..668f912f 100644 --- a/txscript/scriptnum_test.go +++ b/txscript/scriptnum_test.go @@ -104,35 +104,35 @@ func TestMakeScriptNum(t *testing.T) { err error }{ // Minimal encoding must reject negative 0. - {hexToBytes("80"), 0, defaultScriptNumLen, true, errMinimalData}, + {hexToBytes("80"), 0, maxScriptNumLen, true, errMinimalData}, // Minimally encoded valid values with minimal encoding flag. // Should not error and return expected integral number. - {nil, 0, defaultScriptNumLen, true, nil}, - {hexToBytes("01"), 1, defaultScriptNumLen, true, nil}, - {hexToBytes("81"), -1, defaultScriptNumLen, true, nil}, - {hexToBytes("7f"), 127, defaultScriptNumLen, true, nil}, - {hexToBytes("ff"), -127, defaultScriptNumLen, true, nil}, - {hexToBytes("8000"), 128, defaultScriptNumLen, true, nil}, - {hexToBytes("8080"), -128, defaultScriptNumLen, true, nil}, - {hexToBytes("8100"), 129, defaultScriptNumLen, true, nil}, - {hexToBytes("8180"), -129, defaultScriptNumLen, true, nil}, - {hexToBytes("0001"), 256, defaultScriptNumLen, true, nil}, - {hexToBytes("0081"), -256, defaultScriptNumLen, true, nil}, - {hexToBytes("ff7f"), 32767, defaultScriptNumLen, true, nil}, - {hexToBytes("ffff"), -32767, defaultScriptNumLen, true, nil}, - {hexToBytes("008000"), 32768, defaultScriptNumLen, true, nil}, - {hexToBytes("008080"), -32768, defaultScriptNumLen, true, nil}, - {hexToBytes("ffff00"), 65535, defaultScriptNumLen, true, nil}, - {hexToBytes("ffff80"), -65535, defaultScriptNumLen, true, nil}, - {hexToBytes("000008"), 524288, defaultScriptNumLen, true, nil}, - {hexToBytes("000088"), -524288, defaultScriptNumLen, true, nil}, - {hexToBytes("000070"), 7340032, defaultScriptNumLen, true, nil}, - {hexToBytes("0000f0"), -7340032, defaultScriptNumLen, true, nil}, - {hexToBytes("00008000"), 8388608, defaultScriptNumLen, true, nil}, - {hexToBytes("00008080"), -8388608, defaultScriptNumLen, true, nil}, - {hexToBytes("ffffff7f"), 2147483647, defaultScriptNumLen, true, nil}, - {hexToBytes("ffffffff"), -2147483647, defaultScriptNumLen, true, nil}, + {nil, 0, maxScriptNumLen, true, nil}, + {hexToBytes("01"), 1, maxScriptNumLen, true, nil}, + {hexToBytes("81"), -1, maxScriptNumLen, true, nil}, + {hexToBytes("7f"), 127, maxScriptNumLen, true, nil}, + {hexToBytes("ff"), -127, maxScriptNumLen, true, nil}, + {hexToBytes("8000"), 128, maxScriptNumLen, true, nil}, + {hexToBytes("8080"), -128, maxScriptNumLen, true, nil}, + {hexToBytes("8100"), 129, maxScriptNumLen, true, nil}, + {hexToBytes("8180"), -129, maxScriptNumLen, true, nil}, + {hexToBytes("0001"), 256, maxScriptNumLen, true, nil}, + {hexToBytes("0081"), -256, maxScriptNumLen, true, nil}, + {hexToBytes("ff7f"), 32767, maxScriptNumLen, true, nil}, + {hexToBytes("ffff"), -32767, maxScriptNumLen, true, nil}, + {hexToBytes("008000"), 32768, maxScriptNumLen, true, nil}, + {hexToBytes("008080"), -32768, maxScriptNumLen, true, nil}, + {hexToBytes("ffff00"), 65535, maxScriptNumLen, true, nil}, + {hexToBytes("ffff80"), -65535, maxScriptNumLen, true, nil}, + {hexToBytes("000008"), 524288, maxScriptNumLen, true, nil}, + {hexToBytes("000088"), -524288, maxScriptNumLen, true, nil}, + {hexToBytes("000070"), 7340032, maxScriptNumLen, true, nil}, + {hexToBytes("0000f0"), -7340032, maxScriptNumLen, true, nil}, + {hexToBytes("00008000"), 8388608, maxScriptNumLen, true, nil}, + {hexToBytes("00008080"), -8388608, maxScriptNumLen, true, nil}, + {hexToBytes("ffffff7f"), 2147483647, maxScriptNumLen, true, nil}, + {hexToBytes("ffffffff"), -2147483647, maxScriptNumLen, true, nil}, {hexToBytes("ffffffff7f"), 549755813887, 5, true, nil}, {hexToBytes("ffffffffff"), -549755813887, 5, true, nil}, {hexToBytes("ffffffffffffff7f"), 9223372036854775807, 8, true, nil}, @@ -145,50 +145,50 @@ func TestMakeScriptNum(t *testing.T) { // Minimally encoded values that are out of range for data that // is interpreted as script numbers with the minimal encoding // flag set. Should error and return 0. - {hexToBytes("0000008000"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000008080"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000009000"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000009080"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffff00"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffff80"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000000001"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("0000000081"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffff00"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffff80"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffffff00"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffffff80"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffffff7f"), 0, defaultScriptNumLen, true, errNumTooBig}, - {hexToBytes("ffffffffffffffff"), 0, defaultScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000008000"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000008080"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000009000"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000009080"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffff00"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffff80"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000000001"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("0000000081"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffff00"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffff80"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffffff00"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffffff80"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffffff7f"), 0, maxScriptNumLen, true, errNumTooBig}, + {hexToBytes("ffffffffffffffff"), 0, maxScriptNumLen, true, errNumTooBig}, // Non-minimally encoded, but otherwise valid values with // minimal encoding flag. Should error and return 0. - {hexToBytes("00"), 0, defaultScriptNumLen, true, errMinimalData}, // 0 - {hexToBytes("0100"), 0, defaultScriptNumLen, true, errMinimalData}, // 1 - {hexToBytes("7f00"), 0, defaultScriptNumLen, true, errMinimalData}, // 127 - {hexToBytes("800000"), 0, defaultScriptNumLen, true, errMinimalData}, // 128 - {hexToBytes("810000"), 0, defaultScriptNumLen, true, errMinimalData}, // 129 - {hexToBytes("000100"), 0, defaultScriptNumLen, true, errMinimalData}, // 256 - {hexToBytes("ff7f00"), 0, defaultScriptNumLen, true, errMinimalData}, // 32767 - {hexToBytes("00800000"), 0, defaultScriptNumLen, true, errMinimalData}, // 32768 - {hexToBytes("ffff0000"), 0, defaultScriptNumLen, true, errMinimalData}, // 65535 - {hexToBytes("00000800"), 0, defaultScriptNumLen, true, errMinimalData}, // 524288 - {hexToBytes("00007000"), 0, defaultScriptNumLen, true, errMinimalData}, // 7340032 - {hexToBytes("0009000100"), 0, 5, true, errMinimalData}, // 16779520 + {hexToBytes("00"), 0, maxScriptNumLen, true, errMinimalData}, // 0 + {hexToBytes("0100"), 0, maxScriptNumLen, true, errMinimalData}, // 1 + {hexToBytes("7f00"), 0, maxScriptNumLen, true, errMinimalData}, // 127 + {hexToBytes("800000"), 0, maxScriptNumLen, true, errMinimalData}, // 128 + {hexToBytes("810000"), 0, maxScriptNumLen, true, errMinimalData}, // 129 + {hexToBytes("000100"), 0, maxScriptNumLen, true, errMinimalData}, // 256 + {hexToBytes("ff7f00"), 0, maxScriptNumLen, true, errMinimalData}, // 32767 + {hexToBytes("00800000"), 0, maxScriptNumLen, true, errMinimalData}, // 32768 + {hexToBytes("ffff0000"), 0, maxScriptNumLen, true, errMinimalData}, // 65535 + {hexToBytes("00000800"), 0, maxScriptNumLen, true, errMinimalData}, // 524288 + {hexToBytes("00007000"), 0, maxScriptNumLen, true, errMinimalData}, // 7340032 + {hexToBytes("0009000100"), 0, 5, true, errMinimalData}, // 16779520 // Non-minimally encoded, but otherwise valid values without // minimal encoding flag. Should not error and return expected // integral number. - {hexToBytes("00"), 0, defaultScriptNumLen, false, nil}, - {hexToBytes("0100"), 1, defaultScriptNumLen, false, nil}, - {hexToBytes("7f00"), 127, defaultScriptNumLen, false, nil}, - {hexToBytes("800000"), 128, defaultScriptNumLen, false, nil}, - {hexToBytes("810000"), 129, defaultScriptNumLen, false, nil}, - {hexToBytes("000100"), 256, defaultScriptNumLen, false, nil}, - {hexToBytes("ff7f00"), 32767, defaultScriptNumLen, false, nil}, - {hexToBytes("00800000"), 32768, defaultScriptNumLen, false, nil}, - {hexToBytes("ffff0000"), 65535, defaultScriptNumLen, false, nil}, - {hexToBytes("00000800"), 524288, defaultScriptNumLen, false, nil}, - {hexToBytes("00007000"), 7340032, defaultScriptNumLen, false, nil}, + {hexToBytes("00"), 0, maxScriptNumLen, false, nil}, + {hexToBytes("0100"), 1, maxScriptNumLen, false, nil}, + {hexToBytes("7f00"), 127, maxScriptNumLen, false, nil}, + {hexToBytes("800000"), 128, maxScriptNumLen, false, nil}, + {hexToBytes("810000"), 129, maxScriptNumLen, false, nil}, + {hexToBytes("000100"), 256, maxScriptNumLen, false, nil}, + {hexToBytes("ff7f00"), 32767, maxScriptNumLen, false, nil}, + {hexToBytes("00800000"), 32768, maxScriptNumLen, false, nil}, + {hexToBytes("ffff0000"), 65535, maxScriptNumLen, false, nil}, + {hexToBytes("00000800"), 524288, maxScriptNumLen, false, nil}, + {hexToBytes("00007000"), 7340032, maxScriptNumLen, false, nil}, {hexToBytes("0009000100"), 16779520, 5, false, nil}, } diff --git a/txscript/stack.go b/txscript/stack.go index eb1d8cfd..923047d9 100644 --- a/txscript/stack.go +++ b/txscript/stack.go @@ -86,7 +86,7 @@ func (s *stack) PopInt() (scriptNum, error) { return 0, err } - return makeScriptNum(so, s.verifyMinimalData, defaultScriptNumLen) + return makeScriptNum(so, s.verifyMinimalData, maxScriptNumLen) } // PopBool pops the value off the top of the stack, converts it into a bool, and @@ -123,7 +123,7 @@ func (s *stack) PeekInt(idx int32) (scriptNum, error) { return 0, err } - return makeScriptNum(so, s.verifyMinimalData, defaultScriptNumLen) + return makeScriptNum(so, s.verifyMinimalData, maxScriptNumLen) } // PeekBool returns the Nth item on the stack as a bool without removing it. -- 2.45.2 From 96c8bc1e93f93bc357aa8c7ce040bf392ca9103b Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:25 -0500 Subject: [PATCH 276/459] txscript: Optimize ExtractAtomicSwapDataPushes. This converts the ExtractAtomicSwapDataPushes function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. The new implementation is designed such that it should be fairly easy to move the function into the atomic swap tools where it more naturally belongs now that the tokenizer makes it possible to analyze scripts outside of the txscript module. Consequently, this also deprecates the function. The following is a before and after comparison of attempting to extract from both a typical atomic swap script and a very large non-atomic swap script: benchmark old ns/op new ns/op delta BenchmarkExtractAtomicSwapDataPushesLarge-8 61332 44.4 -99.93% BenchmarkExtractAtomicSwapDataPushes-8 990 260 -73.74% benchmark old allocs new allocs delta BenchmarkExtractAtomicSwapDataPushesLarge-8 1 0 -100.00% BenchmarkExtractAtomicSwapDataPushes-8 2 1 -50.00% benchmark old bytes new bytes delta BenchmarkExtractAtomicSwapDataPushesLarge-8 311299 0 -100.00% BenchmarkExtractAtomicSwapDataPushes-8 3168 96 -96.97% --- txscript/standard.go | 144 +++++++++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 53 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index d97072f1..041516e2 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -942,64 +942,102 @@ type AtomicSwapDataPushes struct { // // This function is only defined in the txscript package due to API limitations // which prevent callers using txscript to parse nonstandard scripts. +// +// DEPRECATED. This will be removed in the next major version bump. The error +// should also likely be removed if the code is reimplemented by any callers +// since any errors result in a nil result anyway. func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDataPushes, error) { - pops, err := parseScript(pkScript) - if err != nil { + // An atomic swap is of the form: + // IF + // SIZE EQUALVERIFY SHA256 <32-byte secret> EQUALVERIFY DUP + // HASH160 <20-byte recipient hash> + // ELSE + // CHECKLOCKTIMEVERIFY DROP DUP HASH160 <20-byte refund hash> + // ENDIF + // EQUALVERIFY CHECKSIG + type templateMatch struct { + expectCanonicalInt bool + maxIntBytes int + opcode byte + extractedInt int64 + extractedData []byte + } + var template = [20]templateMatch{ + {opcode: OP_IF}, + {opcode: OP_SIZE}, + {expectCanonicalInt: true, maxIntBytes: maxScriptNumLen}, + {opcode: OP_EQUALVERIFY}, + {opcode: OP_SHA256}, + {opcode: OP_DATA_32}, + {opcode: OP_EQUALVERIFY}, + {opcode: OP_DUP}, + {opcode: OP_HASH160}, + {opcode: OP_DATA_20}, + {opcode: OP_ELSE}, + {expectCanonicalInt: true, maxIntBytes: cltvMaxScriptNumLen}, + {opcode: OP_CHECKLOCKTIMEVERIFY}, + {opcode: OP_DROP}, + {opcode: OP_DUP}, + {opcode: OP_HASH160}, + {opcode: OP_DATA_20}, + {opcode: OP_ENDIF}, + {opcode: OP_EQUALVERIFY}, + {opcode: OP_CHECKSIG}, + } + + var templateOffset int + tokenizer := MakeScriptTokenizer(version, pkScript) + for tokenizer.Next() { + // Not an atomic swap script if it has more opcodes than expected in the + // template. + if templateOffset >= len(template) { + return nil, nil + } + + op := tokenizer.Opcode() + data := tokenizer.Data() + tplEntry := &template[templateOffset] + if tplEntry.expectCanonicalInt { + switch { + case data != nil: + val, err := makeScriptNum(data, true, tplEntry.maxIntBytes) + if err != nil { + return nil, err + } + tplEntry.extractedInt = int64(val) + + case isSmallInt(op): + tplEntry.extractedInt = int64(asSmallInt(op)) + + // Not an atomic swap script if the opcode does not push an int. + default: + return nil, nil + } + } else { + if op != tplEntry.opcode { + return nil, nil + } + + tplEntry.extractedData = data + } + + templateOffset++ + } + if err := tokenizer.Err(); err != nil { return nil, err } - - if len(pops) != 20 { - return nil, nil - } - isAtomicSwap := pops[0].opcode.value == OP_IF && - pops[1].opcode.value == OP_SIZE && - isCanonicalPush(pops[2].opcode.value, pops[2].data) && - pops[3].opcode.value == OP_EQUALVERIFY && - pops[4].opcode.value == OP_SHA256 && - pops[5].opcode.value == OP_DATA_32 && - pops[6].opcode.value == OP_EQUALVERIFY && - pops[7].opcode.value == OP_DUP && - pops[8].opcode.value == OP_HASH160 && - pops[9].opcode.value == OP_DATA_20 && - pops[10].opcode.value == OP_ELSE && - isCanonicalPush(pops[11].opcode.value, pops[11].data) && - pops[12].opcode.value == OP_CHECKLOCKTIMEVERIFY && - pops[13].opcode.value == OP_DROP && - pops[14].opcode.value == OP_DUP && - pops[15].opcode.value == OP_HASH160 && - pops[16].opcode.value == OP_DATA_20 && - pops[17].opcode.value == OP_ENDIF && - pops[18].opcode.value == OP_EQUALVERIFY && - pops[19].opcode.value == OP_CHECKSIG - if !isAtomicSwap { + if !tokenizer.Done() || templateOffset != len(template) { return nil, nil } - pushes := new(AtomicSwapDataPushes) - copy(pushes.SecretHash[:], pops[5].data) - copy(pushes.RecipientHash160[:], pops[9].data) - copy(pushes.RefundHash160[:], pops[16].data) - if pops[2].data != nil { - locktime, err := makeScriptNum(pops[2].data, true, 5) - if err != nil { - return nil, nil - } - pushes.SecretSize = int64(locktime) - } else if op := pops[2].opcode; isSmallInt(op.value) { - pushes.SecretSize = int64(asSmallInt(op.value)) - } else { - return nil, nil + // At this point, the script appears to be an atomic swap, so populate and + // return the extacted data. + pushes := AtomicSwapDataPushes{ + SecretSize: template[2].extractedInt, + LockTime: template[11].extractedInt, } - if pops[11].data != nil { - locktime, err := makeScriptNum(pops[11].data, true, 5) - if err != nil { - return nil, nil - } - pushes.LockTime = int64(locktime) - } else if op := pops[11].opcode; isSmallInt(op.value) { - pushes.LockTime = int64(asSmallInt(op.value)) - } else { - return nil, nil - } - return pushes, nil + copy(pushes.SecretHash[:], template[5].extractedData) + copy(pushes.RecipientHash160[:], template[9].extractedData) + copy(pushes.RefundHash160[:], template[16].extractedData) + return &pushes, nil } -- 2.45.2 From e4c9d283b56cf07bd0c521fe11a82b674bdebcc7 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:26 -0500 Subject: [PATCH 277/459] txscript: Add ExtractPkScriptAddrs benchmarks. --- txscript/bench_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/txscript/bench_test.go b/txscript/bench_test.go index 456db25d..cac29202 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -10,6 +10,7 @@ import ( "io/ioutil" "testing" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" ) @@ -497,3 +498,40 @@ func BenchmarkExtractAtomicSwapDataPushes(b *testing.B) { } } } + +// BenchmarkExtractPkScriptAddrsLarge benchmarks how long it takes to analyze +// and potentially extract addresses from a very large non-standard script. +func BenchmarkExtractPkScriptAddrsLarge(b *testing.B) { + script, err := genComplexScript() + if err != nil { + b.Fatalf("failed to create benchmark script: %v", err) + } + + params := &chaincfg.MainNetParams + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, _, _, err := ExtractPkScriptAddrs(script, params) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} + +// BenchmarkExtractPkScriptAddrs benchmarks how long it takes to analyze and +// potentially extract addresses from a typical script. +func BenchmarkExtractPkScriptAddrs(b *testing.B) { + script := mustParseShortForm("OP_DUP HASH160 " + + "DATA_20 0x0102030405060708090a0b0c0d0e0f1011121314 " + + "EQUAL") + + params := &chaincfg.MainNetParams + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, _, _, err := ExtractPkScriptAddrs(script, params) + if err != nil { + b.Fatalf("unexpected err: %v", err) + } + } +} -- 2.45.2 From 9dec01adf44dd468a9172d6cbad3ebf813f2428a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:27 -0500 Subject: [PATCH 278/459] txscript: Optimize ExtractPkScriptAddrs scripthash. This begins the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In order to ease the review process, the detection of each script type will be converted in a separate commit such that the script is only parsed as a fallback for the cases that are not already converted to more efficient variants. In particular, this converts the detection for pay-to-script-hash scripts. --- txscript/standard.go | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 041516e2..f55cbf98 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -813,11 +813,36 @@ func PushedData(script []byte) ([][]byte, error) { return data, nil } +// scriptHashToAddrs is a convenience function to attempt to convert the passed +// hash to a pay-to-script-hash address housed within an address slice. It is +// used to consolidate common code. +func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address { + // Skip the hash if it's invalid for some reason. + var addrs []btcutil.Address + addr, err := btcutil.NewAddressScriptHashFromHash(hash, params) + if err == nil { + addrs = append(addrs, addr) + } + return addrs +} + // ExtractPkScriptAddrs returns the type of script, addresses and required // signatures associated with the passed PkScript. Note that it only works for // 'standard' transaction script types. Any data such as public keys which are // invalid are omitted from the results. func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, error) { + + // Avoid parsing the script for the cases that already have the able to + // work with raw scripts. + + // Check for pay-to-script-hash. + if hash := extractScriptHash(pkScript); hash != nil { + return ScriptHashTy, scriptHashToAddrs(hash, chainParams), 1, nil + } + + // Fall back to slow path. Ultimately these are intended to be replaced by + // faster variants based on the unparsed raw scripts. + var addrs []btcutil.Address var requiredSigs int @@ -867,18 +892,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script addrs = append(addrs, addr) } - case ScriptHashTy: - // A pay-to-script-hash script is of the form: - // OP_HASH160 OP_EQUAL - // Therefore the script hash is the 2nd item on the stack. - // Skip the script hash if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressScriptHashFromHash(pops[1].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case WitnessV0ScriptHashTy: // A pay-to-witness-script-hash script is of the form: // OP_0 <32-byte hash> -- 2.45.2 From 9b541ad169401d9208ab362c0a5fec04792fa546 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:28 -0500 Subject: [PATCH 279/459] txscript: Optimize ExtractPkScriptAddrs pubkeyhash. This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the detection for pay-to-pubkey-hash scripts. --- txscript/standard.go | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index f55cbf98..af506606 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -813,6 +813,19 @@ func PushedData(script []byte) ([][]byte, error) { return data, nil } +// pubKeyHashToAddrs is a convenience function to attempt to convert the +// passed hash to a pay-to-pubkey-hash address housed within an address +// slice. It is used to consolidate common code. +func pubKeyHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address { + // Skip the pubkey hash if it's invalid for some reason. + var addrs []btcutil.Address + addr, err := btcutil.NewAddressPubKeyHash(hash, params) + if err == nil { + addrs = append(addrs, addr) + } + return addrs +} + // scriptHashToAddrs is a convenience function to attempt to convert the passed // hash to a pay-to-script-hash address housed within an address slice. It is // used to consolidate common code. @@ -835,6 +848,11 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script // Avoid parsing the script for the cases that already have the able to // work with raw scripts. + // Check for pay-to-pubkey-hash script. + if hash := extractPubKeyHash(pkScript); hash != nil { + return PubKeyHashTy, pubKeyHashToAddrs(hash, chainParams), 1, nil + } + // Check for pay-to-script-hash. if hash := extractScriptHash(pkScript); hash != nil { return ScriptHashTy, scriptHashToAddrs(hash, chainParams), 1, nil @@ -857,18 +875,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script scriptClass := typeOfScript(scriptVersion, pkScript) switch scriptClass { - case PubKeyHashTy: - // A pay-to-pubkey-hash script is of the form: - // OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG - // Therefore the pubkey hash is the 3rd item on the stack. - // Skip the pubkey hash if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressPubKeyHash(pops[2].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case WitnessV0PubKeyHashTy: // A pay-to-witness-pubkey-hash script is of thw form: // OP_0 <20-byte hash> -- 2.45.2 From dcbff6a50766e8641cbd2e4ae2376d00796adbf7 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:31 -0500 Subject: [PATCH 280/459] txscript: Optimize ExtractPkScriptAddrs pubkey. This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the detection for pay-to-pubkey scripts. --- txscript/standard.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index af506606..6377598c 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -858,6 +858,16 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return ScriptHashTy, scriptHashToAddrs(hash, chainParams), 1, nil } + // Check for pay-to-pubkey script. + if data := extractPubKey(pkScript); data != nil { + var addrs []btcutil.Address + addr, err := btcutil.NewAddressPubKey(data, chainParams) + if err == nil { + addrs = append(addrs, addr) + } + return PubKeyTy, addrs, 1, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. @@ -887,17 +897,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script addrs = append(addrs, addr) } - case PubKeyTy: - // A pay-to-pubkey script is of the form: - // OP_CHECKSIG - // Therefore the pubkey is the first item on the stack. - // Skip the pubkey if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressPubKey(pops[0].data, chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case WitnessV0ScriptHashTy: // A pay-to-witness-script-hash script is of the form: // OP_0 <32-byte hash> -- 2.45.2 From 8a4da7690d5cbe9a35918cc685ec747b86a9cfb8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:33 -0500 Subject: [PATCH 281/459] txscript: Optimize ExtractPkScriptAddrs multisig. This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the detection for multisig scripts. Also, since the remaining slow path cases are all recursive calls, the parsed opcodes are no longer used, so parsing is removed. --- txscript/standard.go | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 6377598c..b187ac01 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -868,11 +868,27 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return PubKeyTy, addrs, 1, nil } + // Check for multi-signature script. + const scriptVersion = 0 + details := extractMultisigScriptDetails(scriptVersion, pkScript, true) + if details.valid { + // Convert the public keys while skipping any that are invalid. + addrs := make([]btcutil.Address, 0, len(details.pubKeys)) + for _, pubkey := range details.pubKeys { + addr, err := btcutil.NewAddressPubKey(pubkey, chainParams) + if err == nil { + addrs = append(addrs, addr) + } + } + return MultiSigTy, addrs, details.requiredSigs, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. var addrs []btcutil.Address var requiredSigs int + var err error // No valid addresses or required signatures if the script doesn't // parse. @@ -881,7 +897,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return NonStandardTy, nil, 0, err } - const scriptVersion = 0 scriptClass := typeOfScript(scriptVersion, pkScript) switch scriptClass { @@ -909,25 +924,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script addrs = append(addrs, addr) } - case MultiSigTy: - // A multi-signature script is of the form: - // ... OP_CHECKMULTISIG - // Therefore the number of required signatures is the 1st item - // on the stack and the number of public keys is the 2nd to last - // item on the stack. - requiredSigs = asSmallInt(pops[0].opcode.value) - numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value) - - // Extract the public keys while skipping any that are invalid. - addrs = make([]btcutil.Address, 0, numPubKeys) - for i := 0; i < numPubKeys; i++ { - addr, err := btcutil.NewAddressPubKey(pops[i+1].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - } - case NullDataTy: // Null data transactions have no addresses or required // signatures. -- 2.45.2 From 45bdd26ac3d4061f2df2c1f9a9f07b382d961f4f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:38 -0500 Subject: [PATCH 282/459] txscript: Optimize ExtractPkScriptAddrs nulldata. This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the detection for nulldata scripts, removes the slow path fallback code since it is the final case, and modifies the comment to call out the script version semantics. The following is a before and after comparison of analyzing both a typical standard script and a very large non-standard script: benchmark old ns/op new ns/op delta ----------------------------------------------------------------------- BenchmarkExtractPkScriptAddrsLarge 132400 44.4 -99.97% BenchmarkExtractPkScriptAddrs 1265 231 -81.74% benchmark old allocs new allocs delta ----------------------------------------------------------------------- BenchmarkExtractPkScriptAddrsLarge 1 0 -100.00% BenchmarkExtractPkScriptAddrs 5 2 -60.00% benchmark old bytes new bytes delta ----------------------------------------------------------------------- BenchmarkExtractPkScriptAddrsLarge 466944 0 -100.00% BenchmarkExtractPkScriptAddrs 1600 48 -97.00% --- txscript/standard.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index b187ac01..89c21966 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -843,11 +843,12 @@ func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address { // signatures associated with the passed PkScript. Note that it only works for // 'standard' transaction script types. Any data such as public keys which are // invalid are omitted from the results. +// +// NOTE: This function only attempts to identify version 0 scripts. The return +// value will indicate a nonstandard script type for other script versions along +// with an invalid script version error. func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, error) { - // Avoid parsing the script for the cases that already have the able to - // work with raw scripts. - // Check for pay-to-pubkey-hash script. if hash := extractPubKeyHash(pkScript); hash != nil { return PubKeyHashTy, pubKeyHashToAddrs(hash, chainParams), 1, nil @@ -883,6 +884,12 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return MultiSigTy, addrs, details.requiredSigs, nil } + // Check for null data script. + if isNullDataScript(scriptVersion, pkScript) { + // Null data transactions have no addresses or required signatures. + return NullDataTy, nil, 0, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. @@ -924,15 +931,13 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script addrs = append(addrs, addr) } - case NullDataTy: - // Null data transactions have no addresses or required - // signatures. - case NonStandardTy: // Don't attempt to extract addresses or required signatures for // nonstandard transactions. } + // Don't attempt to extract addresses or required signatures for nonstandard + // transactions. return scriptClass, addrs, requiredSigs, nil } -- 2.45.2 From a3c39034b8f70f5fc347b4015b198274698cde87 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:18:51 -0700 Subject: [PATCH 283/459] txscript: Optimize ExtractPkScriptAddrs witness pubkey hash This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the extraction for witness-pubkey-hash scripts. --- txscript/standard.go | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 89c21966..c0178250 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -890,6 +890,15 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return NullDataTy, nil, 0, nil } + if hash := extractWitnessPubKeyHash(pkScript); hash != nil { + var addrs []btcutil.Address + addr, err := btcutil.NewAddressWitnessPubKeyHash(hash, chainParams) + if err == nil { + addrs = append(addrs, addr) + } + return WitnessV0PubKeyHashTy, addrs, 1, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. @@ -907,18 +916,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script scriptClass := typeOfScript(scriptVersion, pkScript) switch scriptClass { - case WitnessV0PubKeyHashTy: - // A pay-to-witness-pubkey-hash script is of thw form: - // OP_0 <20-byte hash> - // Therefore, the pubkey hash is the second item on the stack. - // Skip the pubkey hash if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressWitnessPubKeyHash(pops[1].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case WitnessV0ScriptHashTy: // A pay-to-witness-script-hash script is of the form: // OP_0 <32-byte hash> -- 2.45.2 From 37f9cdd1155ffee17b389129a09340a2479f480a Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:22:52 -0700 Subject: [PATCH 284/459] txscript: Optimize ExtractPkScriptAddrs witness script hash This continues the process of converting the ExtractPkScriptAddrs function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this converts the extract of witness-pay-to-script-hash scripts. --- txscript/standard.go | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index c0178250..d9f8a9a3 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -899,35 +899,24 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return WitnessV0PubKeyHashTy, addrs, 1, nil } + if hash := extractWitnessScriptHash(pkScript); hash != nil { + var addrs []btcutil.Address + addr, err := btcutil.NewAddressWitnessScriptHash(hash, chainParams) + if err == nil { + addrs = append(addrs, addr) + } + return WitnessV0ScriptHashTy, addrs, 1, nil + } + // Fall back to slow path. Ultimately these are intended to be replaced by // faster variants based on the unparsed raw scripts. var addrs []btcutil.Address var requiredSigs int - var err error - - // No valid addresses or required signatures if the script doesn't - // parse. - pops, err := parseScript(pkScript) - if err != nil { - return NonStandardTy, nil, 0, err - } scriptClass := typeOfScript(scriptVersion, pkScript) switch scriptClass { - case WitnessV0ScriptHashTy: - // A pay-to-witness-script-hash script is of the form: - // OP_0 <32-byte hash> - // Therefore, the script hash is the second item on the stack. - // Skip the script hash if it's invalid for some reason. - requiredSigs = 1 - addr, err := btcutil.NewAddressWitnessScriptHash(pops[1].data, - chainParams) - if err == nil { - addrs = append(addrs, addr) - } - case NonStandardTy: // Don't attempt to extract addresses or required signatures for // nonstandard transactions. -- 2.45.2 From 67168099d3dd9a5fdcbe45bcba38821f9f2744f3 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:32:37 -0700 Subject: [PATCH 285/459] txscript: Optimize ExtractPkScriptAddr assume non-standard if no success This completes the process of converting the ExtractPkScriptAddr function to use the optimized extraction functions recently introduced as part of the typeOfScript conversion. In particular, this cleans up the final remaining case for non-standard transactions. The method now returns NonStandardTy direclty if no other branch was taken. The following is a before and after comparison of attempting to extract pkscript addrs from a very large, non-standard script. benchmark old ns/op new ns/op delta BenchmarkExtractPkScriptAddrsLarge-8 60713 17.0 -99.97% BenchmarkExtractPkScriptAddrs-8 289 17.0 -94.12% benchmark old allocs new allocs delta BenchmarkExtractPkScriptAddrsLarge-8 1 0 -100.00% BenchmarkExtractPkScriptAddrs-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkExtractPkScriptAddrsLarge-8 311299 0 -100.00% BenchmarkExtractPkScriptAddrs-8 768 0 -100.00% --- txscript/standard.go | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index d9f8a9a3..326d14d8 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -908,23 +908,8 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script return WitnessV0ScriptHashTy, addrs, 1, nil } - // Fall back to slow path. Ultimately these are intended to be replaced by - // faster variants based on the unparsed raw scripts. - - var addrs []btcutil.Address - var requiredSigs int - - scriptClass := typeOfScript(scriptVersion, pkScript) - - switch scriptClass { - case NonStandardTy: - // Don't attempt to extract addresses or required signatures for - // nonstandard transactions. - } - - // Don't attempt to extract addresses or required signatures for nonstandard - // transactions. - return scriptClass, addrs, requiredSigs, nil + // If none of the above passed, then the address must be non-standard. + return NonStandardTy, nil, 0, nil } // AtomicSwapDataPushes houses the data pushes found in atomic swap contracts. -- 2.45.2 From 1936f28d3376bfb3988ff5251026afa3d5221275 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 18:58:28 -0700 Subject: [PATCH 286/459] txscript: Optimize IsWitnessProgram --- txscript/script.go | 17 +++-------------- txscript/standard.go | 45 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 52bedf26..1ca953de 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -103,20 +103,7 @@ func isWitnessPubKeyHash(pops []parsedOpcode) bool { // witness program must be a small integer (from 0-16), followed by 2-40 bytes // of pushed data. func IsWitnessProgram(script []byte) bool { - // The length of the script must be between 4 and 42 bytes. The - // smallest program is the witness version, followed by a data push of - // 2 bytes. The largest allowed witness program has a data push of - // 40-bytes. - if len(script) < 4 || len(script) > 42 { - return false - } - - pops, err := parseScript(script) - if err != nil { - return false - } - - return isWitnessProgram(pops) + return isWitnessProgramScript(script) } // isWitnessProgram returns true if the passed script is a witness program, and @@ -125,6 +112,8 @@ func IsWitnessProgram(script []byte) bool { // first opcode MUST be a small integer (0-16), the push data MUST be // canonical, and finally the size of the push data must be between 2 and 40 // bytes. +// +// DEPRECATED: Use isWitnessProgramScript instead. func isWitnessProgram(pops []parsedOpcode) bool { return len(pops) == 2 && isSmallInt(pops[0].opcode.value) && diff --git a/txscript/standard.go b/txscript/standard.go index 326d14d8..4b7d9be5 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -387,6 +387,51 @@ func isWitnessScriptHashScript(script []byte) bool { return extractWitnessScriptHash(script) != nil } +// isWitnessProgramScript returns true if the passed script is a witness +// program, and false otherwise. A witness program MUST adhere to the following +// constraints: there must be exactly two pops (program version and the program +// itself), the first opcode MUST be a small integer (0-16), the push data MUST +// be canonical, and finally the size of the push data must be between 2 and 40 +// bytes. +// +// The length of the script must be between 4 and 42 bytes. The +// smallest program is the witness version, followed by a data push of +// 2 bytes. The largest allowed witness program has a data push of +// 40-bytes. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func isWitnessProgramScript(script []byte) bool { + // Skip parsing if we know the program is invalid based on size. + if len(script) < 4 || len(script) > 42 { + return false + } + + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + + // The first opcode must be a small int. + if !tokenizer.Next() || + !isSmallInt(tokenizer.Opcode()) { + + return false + } + + // The second opcode must be a canonical data push, the length of the + // data push is bounded to 40 by the initial check on overall script + // length. + if !tokenizer.Next() || + !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { + + return false + } + + // The witness program is valid if there are no more opcodes, and we + // terminated without a parsing error. + return tokenizer.Done() && tokenizer.Err() == nil +} + // isNullDataScript returns whether or not the passed script is a standard // null data script. // -- 2.45.2 From 76131529f2dea1af284d4e9687f7fb35f0585309 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:39:28 -0700 Subject: [PATCH 287/459] txscript: Return witness version and program in one pass --- txscript/standard.go | 66 ++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 4b7d9be5..e3cf7707 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -387,6 +387,43 @@ func isWitnessScriptHashScript(script []byte) bool { return extractWitnessScriptHash(script) != nil } +// extractWitnessProgramInfo returns the version and program if the passed +// script constitutes a valid witness program. The alst return value indicates +// whether or not the script is a valid witness program. +func extractWitnessProgramInfo(script []byte) (int, []byte, bool) { + // Skip parsing if we know the program is invalid based on size. + if len(script) < 4 || len(script) > 42 { + return 0, nil, false + } + + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + + // The first opcode must be a small int. + if !tokenizer.Next() || + !isSmallInt(tokenizer.Opcode()) { + + return 0, nil, false + } + version := asSmallInt(tokenizer.Opcode()) + + // The second opcode must be a canonical data push, the length of the + // data push is bounded to 40 by the initial check on overall script + // length. + if !tokenizer.Next() || + !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { + + return 0, nil, false + } + program := tokenizer.Data() + + // The witness program is valid if there are no more opcodes, and we + // terminated without a parsing error. + valid := tokenizer.Done() && tokenizer.Err() == nil + + return version, program, valid +} + // isWitnessProgramScript returns true if the passed script is a witness // program, and false otherwise. A witness program MUST adhere to the following // constraints: there must be exactly two pops (program version and the program @@ -403,33 +440,8 @@ func isWitnessScriptHashScript(script []byte) bool { // does not accept a script version, the results are undefined for other script // versions. func isWitnessProgramScript(script []byte) bool { - // Skip parsing if we know the program is invalid based on size. - if len(script) < 4 || len(script) > 42 { - return false - } - - const scriptVersion = 0 - tokenizer := MakeScriptTokenizer(scriptVersion, script) - - // The first opcode must be a small int. - if !tokenizer.Next() || - !isSmallInt(tokenizer.Opcode()) { - - return false - } - - // The second opcode must be a canonical data push, the length of the - // data push is bounded to 40 by the initial check on overall script - // length. - if !tokenizer.Next() || - !isCanonicalPush(tokenizer.Opcode(), tokenizer.Data()) { - - return false - } - - // The witness program is valid if there are no more opcodes, and we - // terminated without a parsing error. - return tokenizer.Done() && tokenizer.Err() == nil + _, _, valid := extractWitnessProgramInfo(script) + return valid } // isNullDataScript returns whether or not the passed script is a standard -- 2.45.2 From ad01d080d93a90b7517eff27cb3f39bdfe7875b7 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 5 Feb 2021 01:58:59 -0800 Subject: [PATCH 288/459] txscript: Use internal analysis methods for GetWitnessSigOpCount --- txscript/script.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 1ca953de..57c7b9be 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -832,15 +832,15 @@ func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, _ bool) int { func GetWitnessSigOpCount(sigScript, pkScript []byte, witness wire.TxWitness) int { // If this is a regular witness program, then we can proceed directly // to counting its signature operations without any further processing. - if IsWitnessProgram(pkScript) { + if isWitnessProgramScript(pkScript) { return getWitnessSigOps(pkScript, witness) } // Next, we'll check the sigScript to see if this is a nested p2sh // witness program. This is a case wherein the sigScript is actually a // datapush of a p2wsh witness program. - if IsPayToScriptHash(pkScript) && IsPushOnlyScript(sigScript) && - IsWitnessProgram(sigScript[1:]) { + if isScriptHashScript(pkScript) && IsPushOnlyScript(sigScript) && + len(sigScript) > 0 && isWitnessProgramScript(sigScript[1:]) { return getWitnessSigOps(sigScript[1:], witness) } -- 2.45.2 From a3166c8d9b0b2ff66a33fa63406a13d1351851b1 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:43:43 -0700 Subject: [PATCH 289/459] txscript: Optimize ExtractWitnessProgramInfo --- txscript/script.go | 13 +++---------- txscript/standard.go | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 57c7b9be..9d7de56c 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -131,23 +131,16 @@ func IsNullData(script []byte) bool { // ExtractWitnessProgramInfo attempts to extract the witness program version, // as well as the witness program itself from the passed script. func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { - pops, err := parseScript(script) - if err != nil { - return 0, nil, err - } - // If at this point, the scripts doesn't resemble a witness program, // then we'll exit early as there isn't a valid version or program to // extract. - if !isWitnessProgram(pops) { + version, program, valid := extractWitnessProgramInfo(script) + if !valid { return 0, nil, fmt.Errorf("script is not a witness program, " + "unable to extract version or witness program") } - witnessVersion := asSmallInt(pops[0].opcode.value) - witnessProgram := pops[1].data - - return witnessVersion, witnessProgram, nil + return version, program, nil } // IsPushOnlyScript returns whether or not the passed script only pushes data diff --git a/txscript/standard.go b/txscript/standard.go index e3cf7707..44902971 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -388,7 +388,7 @@ func isWitnessScriptHashScript(script []byte) bool { } // extractWitnessProgramInfo returns the version and program if the passed -// script constitutes a valid witness program. The alst return value indicates +// script constitutes a valid witness program. The last return value indicates // whether or not the script is a valid witness program. func extractWitnessProgramInfo(script []byte) (int, []byte, bool) { // Skip parsing if we know the program is invalid based on size. -- 2.45.2 From f8978f58041563558e9c02822414061daac227f4 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:46 -0500 Subject: [PATCH 290/459] txscript: mergeMultiSig function def order cleanup. This moves the function definition for mergeMultiSig so it is more consistent with the preferred order used through the codebase. In particular, the functions are defined before they're first used and generally as close as possible to the first use when they're defined in the same file. --- txscript/sign.go | 135 ++++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 67 deletions(-) diff --git a/txscript/sign.go b/txscript/sign.go index b9f8b2db..58791064 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -212,73 +212,6 @@ func sign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, } } -// mergeScripts merges sigScript and prevScript assuming they are both -// partial solutions for pkScript spending output idx of tx. class, addresses -// and nrequired are the result of extracting the addresses from pkscript. -// The return value is the best effort merging of the two scripts. Calling this -// function with addresses, class and nrequired that do not match pkScript is -// an error and results in undefined behaviour. -func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, - pkScript []byte, class ScriptClass, addresses []btcutil.Address, - nRequired int, sigScript, prevScript []byte) []byte { - - // TODO: the scripthash and multisig paths here are overly - // inefficient in that they will recompute already known data. - // some internal refactoring could probably make this avoid needless - // extra calculations. - switch class { - case ScriptHashTy: - // Remove the last push in the script and then recurse. - // this could be a lot less inefficient. - sigPops, err := parseScript(sigScript) - if err != nil || len(sigPops) == 0 { - return prevScript - } - prevPops, err := parseScript(prevScript) - if err != nil || len(prevPops) == 0 { - return sigScript - } - - // assume that script in sigPops is the correct one, we just - // made it. - script := sigPops[len(sigPops)-1].data - - // We already know this information somewhere up the stack. - class, addresses, nrequired, _ := - ExtractPkScriptAddrs(script, chainParams) - - // regenerate scripts. - sigScript, _ := unparseScript(sigPops) - prevScript, _ := unparseScript(prevPops) - - // Merge - mergedScript := mergeScripts(chainParams, tx, idx, script, - class, addresses, nrequired, sigScript, prevScript) - - // Reappend the script and return the result. - builder := NewScriptBuilder() - builder.AddOps(mergedScript) - builder.AddData(script) - finalScript, _ := builder.Script() - return finalScript - case MultiSigTy: - return mergeMultiSig(tx, idx, addresses, nRequired, pkScript, - sigScript, prevScript) - - // It doesn't actually make sense to merge anything other than multiig - // and scripthash (because it could contain multisig). Everything else - // has either zero signature, can't be spent, or has a single signature - // which is either present or not. The other two cases are handled - // above. In the conflict case here we just assume the longest is - // correct (this matches behaviour of the reference implementation). - default: - if len(sigScript) > len(prevScript) { - return sigScript - } - return prevScript - } -} - // mergeMultiSig combines the two signature scripts sigScript and prevScript // that both provide signatures for pkScript in output idx of tx. addresses // and nRequired should be the results from extracting the addresses from @@ -397,6 +330,74 @@ sigLoop: return script } +// mergeScripts merges sigScript and prevScript assuming they are both +// partial solutions for pkScript spending output idx of tx. class, addresses +// and nrequired are the result of extracting the addresses from pkscript. +// The return value is the best effort merging of the two scripts. Calling this +// function with addresses, class and nrequired that do not match pkScript is +// an error and results in undefined behaviour. +func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, + pkScript []byte, class ScriptClass, addresses []btcutil.Address, + nRequired int, sigScript, prevScript []byte) []byte { + + // TODO(oga) the scripthash and multisig paths here are overly + // inefficient in that they will recompute already known data. + // some internal refactoring could probably make this avoid needless + // extra calculations. + switch class { + case ScriptHashTy: + // Remove the last push in the script and then recurse. + // this could be a lot less inefficient. + sigPops, err := parseScript(sigScript) + if err != nil || len(sigPops) == 0 { + return prevScript + } + prevPops, err := parseScript(prevScript) + if err != nil || len(prevPops) == 0 { + return sigScript + } + + // assume that script in sigPops is the correct one, we just + // made it. + script := sigPops[len(sigPops)-1].data + + // We already know this information somewhere up the stack, + // therefore the error is ignored. + class, addresses, nrequired, _ := + ExtractPkScriptAddrs(script, chainParams) + + // regenerate scripts. + sigScript, _ := unparseScript(sigPops) + prevScript, _ := unparseScript(prevPops) + + // Merge + mergedScript := mergeScripts(chainParams, tx, idx, script, + class, addresses, nrequired, sigScript, prevScript) + + // Reappend the script and return the result. + builder := NewScriptBuilder() + builder.AddOps(mergedScript) + builder.AddData(script) + finalScript, _ := builder.Script() + return finalScript + case MultiSigTy: + return mergeMultiSig(tx, idx, addresses, nRequired, pkScript, + sigScript, prevScript) + + // It doesn't actually make sense to merge anything other than multiig + // and scripthash (because it could contain multisig). Everything else + // has either zero signature, can't be spent, or has a single signature + // which is either present or not. The other two cases are handled + // above. In the conflict case here we just assume the longest is + // correct (this matches behaviour of the reference implementation). + default: + if len(sigScript) > len(prevScript) { + return sigScript + } + return prevScript + } +} + // KeyDB is an interface type provided to SignTxOutput, it encapsulates // any user state required to get the private keys for an address. type KeyDB interface { -- 2.45.2 From 13dbfa3d873d8c1c6f98a48d6fb3c328aeba11d7 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 15:25:18 -0700 Subject: [PATCH 291/459] txscript: Introduce calcWitnessSignatureHashRaw --- txscript/script.go | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 9d7de56c..46517985 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -385,7 +385,7 @@ func calcHashOutputs(tx *wire.MsgTx) chainhash.Hash { return chainhash.DoubleHashH(b.Bytes()) } -// calcWitnessSignatureHash computes the sighash digest of a transaction's +// calcWitnessSignatureHashRaw computes the sighash digest of a transaction's // segwit input using the new, optimized digest calculation algorithm defined // in BIP0143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki. // This function makes use of pre-calculated sighash fragments stored within @@ -396,7 +396,7 @@ func calcHashOutputs(tx *wire.MsgTx) chainhash.Hash { // being spent, in addition to the final transaction fee. In the case the // wallet if fed an invalid input amount, the real sighash will differ causing // the produced signature to be invalid. -func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, +func calcWitnessSignatureHashRaw(scriptSig []byte, sigHashes *TxSigHashes, hashType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { // As a sanity check, ensure the passed input index for the transaction @@ -446,7 +446,7 @@ func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, binary.LittleEndian.PutUint32(bIndex[:], txIn.PreviousOutPoint.Index) sigHash.Write(bIndex[:]) - if isWitnessPubKeyHash(subScript) { + if isWitnessPubKeyHashScript(scriptSig) { // The script code for a p2wkh is a length prefix varint for // the next 25 bytes, followed by a re-creation of the original // p2pkh pk script. @@ -454,15 +454,14 @@ func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, sigHash.Write([]byte{OP_DUP}) sigHash.Write([]byte{OP_HASH160}) sigHash.Write([]byte{OP_DATA_20}) - sigHash.Write(subScript[1].data) + sigHash.Write(extractWitnessPubKeyHash(scriptSig)) sigHash.Write([]byte{OP_EQUALVERIFY}) sigHash.Write([]byte{OP_CHECKSIG}) } else { // For p2wsh outputs, and future outputs, the script code is // the original script, with all code separators removed, // serialized with a var int length prefix. - rawScript, _ := unparseScript(subScript) - wire.WriteVarBytes(&sigHash, 0, rawScript) + wire.WriteVarBytes(&sigHash, 0, scriptSig) } // Next, add the input amount, and sequence number of the input being @@ -501,6 +500,30 @@ func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, return chainhash.DoubleHashB(sigHash.Bytes()), nil } +// calcWitnessSignatureHash computes the sighash digest of a transaction's +// segwit input using the new, optimized digest calculation algorithm defined +// in BIP0143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki. +// This function makes use of pre-calculated sighash fragments stored within +// the passed HashCache to eliminate duplicate hashing computations when +// calculating the final digest, reducing the complexity from O(N^2) to O(N). +// Additionally, signatures now cover the input value of the referenced unspent +// output. This allows offline, or hardware wallets to compute the exact amount +// being spent, in addition to the final transaction fee. In the case the +// wallet if fed an invalid input amount, the real sighash will differ causing +// the produced signature to be invalid. +// +// DEPRECATED: Use calcWitnessSignatureHashRaw instead. +func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, + hashType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { + + script, err := unparseScript(subScript) + if err != nil { + return nil, err + } + + return calcWitnessSignatureHashRaw(script, sigHashes, hashType, tx, idx, amt) +} + // CalcWitnessSigHash computes the sighash digest for the specified input of // the target transaction observing the desired sig hash type. func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType SigHashType, -- 2.45.2 From 21ed801540b8efe3004bf2914db50cc5723992c2 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 20:09:07 -0700 Subject: [PATCH 292/459] txscript: Remove unused isWitnessPubKeyHash --- txscript/script.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 46517985..10e0a1ca 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -90,14 +90,6 @@ func IsPayToWitnessPubKeyHash(script []byte) bool { return isWitnessPubKeyHashScript(script) } -// isWitnessPubKeyHash returns true if the passed script is a -// pay-to-witness-pubkey-hash, and false otherwise. -func isWitnessPubKeyHash(pops []parsedOpcode) bool { - return len(pops) == 2 && - pops[0].opcode.value == OP_0 && - pops[1].opcode.value == OP_DATA_20 -} - // IsWitnessProgram returns true if the passed script is a valid witness // program which is encoded according to the passed witness program version. A // witness program must be a small integer (from 0-16), followed by 2-40 bytes -- 2.45.2 From b8e25c397c85094a57bc5a002aa3dc7df4e2d43d Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 15:26:10 -0700 Subject: [PATCH 293/459] txscript: Use optimized calcWitnessSignatureHashRaw w/o parsing --- txscript/script.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 10e0a1ca..6798be1c 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -521,13 +521,12 @@ func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { - parsedScript, err := parseScript(script) - if err != nil { - return nil, fmt.Errorf("cannot parse output script: %v", err) + const scriptVersion = 0 + if err := checkScriptParses(scriptVersion, script); err != nil { + return nil, err } - return calcWitnessSignatureHash(parsedScript, sigHashes, hType, tx, idx, - amt) + return calcWitnessSignatureHashRaw(script, sigHashes, hType, tx, idx, amt) } // shallowCopyTx creates a shallow copy of the transaction for use when -- 2.45.2 From 5283e30bfcb40eaaec9d9c6c3dce5adabc997657 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:50 -0500 Subject: [PATCH 294/459] txscript: Use raw scripts in SignTxOutput. This converts SignTxOutput and supporting funcs, namely sign, mergeScripts and mergeMultiSig, to make use of the new tokenizer as well as some recently added funcs that deal with raw scripts in order to remove the reliance on parsed opcodes as a step towards utlimately removing them altogether and updates the comments to explicitly call out the script version semantics. It is worth noting that this has the side effect of optimizing the function as well, however, since this change is not focused on the optimization aspects, no benchmarks are provided. --- txscript/sign.go | 88 ++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/txscript/sign.go b/txscript/sign.go index 58791064..4d63a9b2 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -218,37 +218,44 @@ func sign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, // pkScript. Since this function is internal only we assume that the arguments // have come from other functions internally and thus are all consistent with // each other, behaviour is undefined if this contract is broken. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func mergeMultiSig(tx *wire.MsgTx, idx int, addresses []btcutil.Address, nRequired int, pkScript, sigScript, prevScript []byte) []byte { - // This is an internal only function and we already parsed this script - // as ok for multisig (this is how we got here), so if this fails then - // all assumptions are broken and who knows which way is up? - pkPops, _ := parseScript(pkScript) - - sigPops, err := parseScript(sigScript) - if err != nil || len(sigPops) == 0 { + // Nothing to merge if either the new or previous signature scripts are + // empty. + if len(sigScript) == 0 { return prevScript } - - prevPops, err := parseScript(prevScript) - if err != nil || len(prevPops) == 0 { + if len(prevScript) == 0 { return sigScript } // Convenience function to avoid duplication. - extractSigs := func(pops []parsedOpcode, sigs [][]byte) [][]byte { - for _, pop := range pops { - if len(pop.data) != 0 { - sigs = append(sigs, pop.data) + var possibleSigs [][]byte + extractSigs := func(script []byte) error { + const scriptVersion = 0 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if data := tokenizer.Data(); len(data) != 0 { + possibleSigs = append(possibleSigs, data) } } - return sigs + return tokenizer.Err() } - possibleSigs := make([][]byte, 0, len(sigPops)+len(prevPops)) - possibleSigs = extractSigs(sigPops, possibleSigs) - possibleSigs = extractSigs(prevPops, possibleSigs) + // Attempt to extract signatures from the two scripts. Return the other + // script that is intended to be merged in the case signature extraction + // fails for some reason. + if err := extractSigs(sigScript); err != nil { + return prevScript + } + if err := extractSigs(prevScript); err != nil { + return sigScript + } // Now we need to match the signatures to pubkeys, the only real way to // do that is to try to verify them all and match it to the pubkey @@ -278,10 +285,7 @@ sigLoop: // however, assume no sigs etc are in the script since that // would make the transaction nonstandard and thus not // MultiSigTy, so we just need to hash the full thing. - hash, err := calcSignatureHash(pkPops, hashType, tx, idx) - if err != nil { - panic(fmt.Sprintf("cannot compute sighash: %v", err)) - } + hash := calcSignatureHashRaw(pkScript, hashType, tx, idx) for _, addr := range addresses { // All multisig addresses should be pubkey addresses @@ -336,6 +340,10 @@ sigLoop: // The return value is the best effort merging of the two scripts. Calling this // function with addresses, class and nrequired that do not match pkScript is // an error and results in undefined behaviour. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, pkScript []byte, class ScriptClass, addresses []btcutil.Address, nRequired int, sigScript, prevScript []byte) []byte { @@ -344,32 +352,34 @@ func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, // inefficient in that they will recompute already known data. // some internal refactoring could probably make this avoid needless // extra calculations. + const scriptVersion = 0 switch class { case ScriptHashTy: - // Remove the last push in the script and then recurse. - // this could be a lot less inefficient. - sigPops, err := parseScript(sigScript) - if err != nil || len(sigPops) == 0 { + // Nothing to merge if either the new or previous signature + // scripts are empty or fail to parse. + if len(sigScript) == 0 || + checkScriptParses(scriptVersion, sigScript) != nil { + return prevScript } - prevPops, err := parseScript(prevScript) - if err != nil || len(prevPops) == 0 { + if len(prevScript) == 0 || + checkScriptParses(scriptVersion, prevScript) != nil { + return sigScript } - // assume that script in sigPops is the correct one, we just - // made it. - script := sigPops[len(sigPops)-1].data + // Remove the last push in the script and then recurse. + // this could be a lot less inefficient. + // + // Assume that final script is the correct one since it was just + // made and it is a pay-to-script-hash. + script := finalOpcodeData(scriptVersion, sigScript) // We already know this information somewhere up the stack, // therefore the error is ignored. class, addresses, nrequired, _ := ExtractPkScriptAddrs(script, chainParams) - // regenerate scripts. - sigScript, _ := unparseScript(sigPops) - prevScript, _ := unparseScript(prevPops) - // Merge mergedScript := mergeScripts(chainParams, tx, idx, script, class, addresses, nrequired, sigScript, prevScript) @@ -380,6 +390,7 @@ func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, builder.AddData(script) finalScript, _ := builder.Script() return finalScript + case MultiSigTy: return mergeMultiSig(tx, idx, addresses, nRequired, pkScript, sigScript, prevScript) @@ -408,8 +419,7 @@ type KeyDB interface { type KeyClosure func(btcutil.Address) (*btcec.PrivateKey, bool, error) // GetKey implements KeyDB by returning the result of calling the closure. -func (kc KeyClosure) GetKey(address btcutil.Address) (*btcec.PrivateKey, - bool, error) { +func (kc KeyClosure) GetKey(address btcutil.Address) (*btcec.PrivateKey, bool, error) { return kc(address) } @@ -434,6 +444,10 @@ func (sc ScriptClosure) GetScript(address btcutil.Address) ([]byte, error) { // getScript. If previousScript is provided then the results in previousScript // will be merged in a type-dependent manner with the newly generated. // signature script. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. func SignTxOutput(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, pkScript []byte, hashType SigHashType, kdb KeyDB, sdb ScriptDB, previousScript []byte) ([]byte, error) { -- 2.45.2 From f5d78e8b1009ac575363e9f0dee6d8004de12244 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:51 -0500 Subject: [PATCH 295/459] txscript: Implement efficient opcode data removal. This introduces a new function named removeOpcodeByDataRaw which accepts the raw scripts and data to remove versus requiring the parsed opcodes to both significantly optimize it as well as make it more flexible for working with raw scripts. There are several places in the rest of the code that currently only have access to the parsed opcodes, so this only introduces the function for use in the future and deprecates the existing one. Note that, in practice, the script will never actually contain the data that is intended to be removed since the function is only used during signature verification to remove the signature itself which would require some incredibly non-standard code to create. Thus, as an optimization, it avoids allocating a new script unless there is actually a match that needs to be removed. Finally, it updates the tests to use the new function. --- txscript/script.go | 55 +++++++++++++++++++++++++++++++++++++++++ txscript/script_test.go | 13 +++++----- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 6798be1c..336a2c8b 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -310,6 +310,8 @@ func isCanonicalPush(opcode byte, data []byte) bool { // removeOpcodeByData will return the script minus any opcodes that would push // the passed data to the stack. +// +// DEPRECATED. Use removeOpcodeByDataRaw instead. func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode { retScript := make([]parsedOpcode, 0, len(pkscript)) for _, pop := range pkscript { @@ -323,6 +325,59 @@ func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode { } +// removeOpcodeByDataRaw will return the script minus any opcodes that perform a +// canonical push of data that contains the passed data to remove. This +// function assumes it is provided a version 0 script as any future version of +// script should avoid this functionality since it is unncessary due to the +// signature scripts not being part of the witness-free transaction hash. +// +// WARNING: This will return the passed script unmodified unless a modification +// is necessary in which case the modified script is returned. This implies +// callers may NOT rely on being able to safely mutate either the passed or +// returned script without potentially modifying the same data. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func removeOpcodeByDataRaw(script []byte, dataToRemove []byte) []byte { + // Avoid work when possible. + if len(script) == 0 || len(dataToRemove) == 0 { + return script + } + + // Parse through the script looking for a canonical data push that contains + // the data to remove. + const scriptVersion = 0 + var result []byte + var prevOffset int32 + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + // In practice, the script will basically never actually contain the + // data since this function is only used during signature verification + // to remove the signature itself which would require some incredibly + // non-standard code to create. + // + // Thus, as an optimization, avoid allocating a new script unless there + // is actually a match that needs to be removed. + op, data := tokenizer.Opcode(), tokenizer.Data() + if isCanonicalPush(op, data) && bytes.Contains(data, dataToRemove) { + if result == nil { + fullPushLen := tokenizer.ByteIndex() - prevOffset + result = make([]byte, 0, int32(len(script))-fullPushLen) + result = append(result, script[0:prevOffset]...) + } + } else if result != nil { + result = append(result, script[prevOffset:tokenizer.ByteIndex()]...) + } + + prevOffset = tokenizer.ByteIndex() + } + if result == nil { + result = script + } + return result +} + // calcHashPrevOuts calculates a single hash of all the previous outputs // (txid:index) referenced within the passed transaction. This calculated hash // can be re-used when validating all inputs spending segwit outputs, with a diff --git a/txscript/script_test.go b/txscript/script_test.go index 62c51e41..9a64865e 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -4129,16 +4129,15 @@ func TestRemoveOpcodeByData(t *testing.T) { }, } - // tstRemoveOpcodeByData is a convenience function to parse the provided - // raw script, remove the passed data, then unparse the result back - // into a raw script. + // tstRemoveOpcodeByData is a convenience function to ensure the provided + // script parses before attempting to remove the passed data. + const scriptVersion = 0 tstRemoveOpcodeByData := func(script []byte, data []byte) ([]byte, error) { - pops, err := parseScript(script) - if err != nil { + if err := checkScriptParses(scriptVersion, script); err != nil { return nil, err } - pops = removeOpcodeByData(pops, data) - return unparseScript(pops) + + return removeOpcodeByDataRaw(script, data), nil } for _, test := range tests { -- 2.45.2 From 90b8c2cb51da85252d3a2f686080cd273154ad06 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 16:26:22 -0700 Subject: [PATCH 296/459] txscript: Optimize removeOpcodeRaw --- txscript/script.go | 39 +++++++++++++++++++++++++++++++++++++++ txscript/script_test.go | 7 +++---- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 336a2c8b..7bfe44b3 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -269,6 +269,8 @@ func DisasmString(script []byte) (string, error) { // removeOpcode will remove any opcode matching ``opcode'' from the opcode // stream in pkscript +// +// DEPRECATED. Use removeOpcodeRaw instead. func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode { retScript := make([]parsedOpcode, 0, len(pkscript)) for _, pop := range pkscript { @@ -279,6 +281,43 @@ func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode { return retScript } +// removeOpcodeRaw will return the script after removing any opcodes that match +// `opcode`. If the opcode does not appear in script, the original script will +// be returned unmodified. Otherwise, a new script will be allocated to contain +// the filtered script. This metehod assumes that the script parses +// successfully. +// +// NOTE: This function is only valid for version 0 scripts. Since the function +// does not accept a script version, the results are undefined for other script +// versions. +func removeOpcodeRaw(script []byte, opcode byte) []byte { + // Avoid work when possible. + if len(script) == 0 { + return script + } + + const scriptVersion = 0 + var result []byte + var prevOffset int32 + + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if tokenizer.Opcode() == opcode { + if result == nil { + result = make([]byte, 0, len(script)) + result = append(result, script[:prevOffset]...) + } + } else if result != nil { + result = append(result, script[prevOffset:tokenizer.ByteIndex()]...) + } + prevOffset = tokenizer.ByteIndex() + } + if result == nil { + return script + } + return result +} + // isCanonicalPush returns true if the opcode is either not a push instruction // or the data associated with the push instruction uses the smallest // instruction to do the job. False otherwise. diff --git a/txscript/script_test.go b/txscript/script_test.go index 9a64865e..02c364ce 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -3981,13 +3981,12 @@ func TestRemoveOpcodes(t *testing.T) { // tstRemoveOpcode is a convenience function to parse the provided // raw script, remove the passed opcode, then unparse the result back // into a raw script. + const scriptVersion = 0 tstRemoveOpcode := func(script []byte, opcode byte) ([]byte, error) { - pops, err := parseScript(script) - if err != nil { + if err := checkScriptParses(scriptVersion, script); err != nil { return nil, err } - pops = removeOpcode(pops, opcode) - return unparseScript(pops) + return removeOpcodeRaw(script, opcode), nil } for _, test := range tests { -- 2.45.2 From 1e3b85cd602108ee4391257a0ec92581a00eeb39 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 20:11:34 -0700 Subject: [PATCH 297/459] txscript: Remove unused removeOpcode --- txscript/script.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 7bfe44b3..7c8423bb 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -267,20 +267,6 @@ func DisasmString(script []byte) (string, error) { return disbuf.String(), tokenizer.Err() } -// removeOpcode will remove any opcode matching ``opcode'' from the opcode -// stream in pkscript -// -// DEPRECATED. Use removeOpcodeRaw instead. -func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode { - retScript := make([]parsedOpcode, 0, len(pkscript)) - for _, pop := range pkscript { - if pop.opcode.value != opcode { - retScript = append(retScript, pop) - } - } - return retScript -} - // removeOpcodeRaw will return the script after removing any opcodes that match // `opcode`. If the opcode does not appear in script, the original script will // be returned unmodified. Otherwise, a new script will be allocated to contain -- 2.45.2 From 25206b9565d592e4352e50a37b32415dac5084d3 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 16:28:26 -0700 Subject: [PATCH 298/459] txscript: Use removeOpcodeRaw for CODESEP in calcSigHash --- txscript/script.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 7c8423bb..0be0a7b8 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -683,24 +683,14 @@ func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx } // Remove all instances of OP_CODESEPARATOR from the script. - filteredScript := make([]byte, 0, len(sigScript)) - const scriptVersion = 0 - tokenizer := MakeScriptTokenizer(scriptVersion, sigScript) - var prevOffset int32 - for tokenizer.Next() { - if tokenizer.Opcode() != OP_CODESEPARATOR { - filteredScript = append(filteredScript, - sigScript[prevOffset:tokenizer.ByteIndex()]...) - } - prevOffset = tokenizer.ByteIndex() - } + sigScript = removeOpcodeRaw(sigScript, OP_CODESEPARATOR) // Make a shallow copy of the transaction, zeroing out the script for // all inputs that are not currently being processed. txCopy := shallowCopyTx(tx) for i := range txCopy.TxIn { if i == idx { - txCopy.TxIn[idx].SignatureScript = filteredScript + txCopy.TxIn[idx].SignatureScript = sigScript } else { txCopy.TxIn[i].SignatureScript = nil } -- 2.45.2 From e928eeb5cedaff81621f55cd9e0ce6998bacdd7e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:52 -0500 Subject: [PATCH 299/459] txscript: Make isDisabled accept raw opcode. This converts the isDisabled function defined on a parsed opcode to a standalone function which accepts an opcode as a byte instead in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/engine.go | 42 +++++++++++++++++++++++++++++++++++++++++- txscript/opcode.go | 39 --------------------------------------- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index ef7ad33e..00973a03 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -154,12 +154,52 @@ func (vm *Engine) isBranchExecuting() bool { return vm.condStack[len(vm.condStack)-1] == OpCondTrue } +// isOpcodeDisabled returns whether or not the opcode is disabled and thus is +// always bad to see in the instruction stream (even if turned off by a +// conditional). +func isOpcodeDisabled(opcode byte) bool { + switch opcode { + case OP_CAT: + return true + case OP_SUBSTR: + return true + case OP_LEFT: + return true + case OP_RIGHT: + return true + case OP_INVERT: + return true + case OP_AND: + return true + case OP_OR: + return true + case OP_XOR: + return true + case OP_2MUL: + return true + case OP_2DIV: + return true + case OP_MUL: + return true + case OP_DIV: + return true + case OP_MOD: + return true + case OP_LSHIFT: + return true + case OP_RSHIFT: + return true + default: + return false + } +} + // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. func (vm *Engine) executeOpcode(pop *parsedOpcode) error { // Disabled opcodes are fail on program counter. - if pop.isDisabled() { + if isOpcodeDisabled(pop.opcode.value) { str := fmt.Sprintf("attempt to execute disabled opcode %s", pop.opcode.name) return scriptError(ErrDisabledOpcode, str) diff --git a/txscript/opcode.go b/txscript/opcode.go index 893bebdf..62c6649d 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -619,45 +619,6 @@ type parsedOpcode struct { data []byte } -// isDisabled returns whether or not the opcode is disabled and thus is always -// bad to see in the instruction stream (even if turned off by a conditional). -func (pop *parsedOpcode) isDisabled() bool { - switch pop.opcode.value { - case OP_CAT: - return true - case OP_SUBSTR: - return true - case OP_LEFT: - return true - case OP_RIGHT: - return true - case OP_INVERT: - return true - case OP_AND: - return true - case OP_OR: - return true - case OP_XOR: - return true - case OP_2MUL: - return true - case OP_2DIV: - return true - case OP_MUL: - return true - case OP_DIV: - return true - case OP_MOD: - return true - case OP_LSHIFT: - return true - case OP_RSHIFT: - return true - default: - return false - } -} - // checkParseableInScript checks whether or not the current opcode is able to be // parsed at a certain position in a script. // This returns the position of the next opcode to be parsed in the script. -- 2.45.2 From 804327d22c05abce112c5df6890bfafcf7783256 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:53 -0500 Subject: [PATCH 300/459] txscript: Make alwaysIllegal accept raw opcode. This converts the alwaysIllegal function defined on a parsed opcode to a standalone function named isOpcodeAlwaysIllegal which accepts an opcode as a byte instead in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/engine.go | 16 +++++++++++++++- txscript/opcode.go | 14 -------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 00973a03..1c6a124b 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -194,6 +194,20 @@ func isOpcodeDisabled(opcode byte) bool { } } +// isOpcodeAlwaysIllegal returns whether or not the opcode is always illegal +// when passed over by the program counter even if in a non-executed branch (it +// isn't a coincidence that they are conditionals). +func isOpcodeAlwaysIllegal(opcode byte) bool { + switch opcode { + case OP_VERIF: + return true + case OP_VERNOTIF: + return true + default: + return false + } +} + // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. @@ -206,7 +220,7 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { } // Always-illegal opcodes are fail on program counter. - if pop.alwaysIllegal() { + if isOpcodeAlwaysIllegal(pop.opcode.value) { str := fmt.Sprintf("attempt to execute reserved opcode %s", pop.opcode.name) return scriptError(ErrReservedOpcode, str) diff --git a/txscript/opcode.go b/txscript/opcode.go index 62c6649d..dc4ec50e 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -692,20 +692,6 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (i return scriptPos, nil } -// alwaysIllegal returns whether or not the opcode is always illegal when passed -// over by the program counter even if in a non-executed branch (it isn't a -// coincidence that they are conditionals). -func (pop *parsedOpcode) alwaysIllegal() bool { - switch pop.opcode.value { - case OP_VERIF: - return true - case OP_VERNOTIF: - return true - default: - return false - } -} - // isConditional returns whether or not the opcode is a conditional opcode which // changes the conditional execution stack when executed. func (pop *parsedOpcode) isConditional() bool { -- 2.45.2 From e610deb203e737c9ae16a3864ab09c99a8af26c9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:54 -0500 Subject: [PATCH 301/459] txscript: Make isConditional accept raw opcode. This converts the isConditional function defined on a parsed opcode to a standalone function named isOpcodeConditional which accepts an opcode as a byte instead in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/engine.go | 19 ++++++++++++++++++- txscript/opcode.go | 17 ----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 1c6a124b..ddb26de5 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -208,6 +208,23 @@ func isOpcodeAlwaysIllegal(opcode byte) bool { } } +// isOpcodeConditional returns whether or not the opcode is a conditional opcode +// which changes the conditional execution stack when executed. +func isOpcodeConditional(opcode byte) bool { + switch opcode { + case OP_IF: + return true + case OP_NOTIF: + return true + case OP_ELSE: + return true + case OP_ENDIF: + return true + default: + return false + } +} + // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. @@ -243,7 +260,7 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { // Nothing left to do when this is not a conditional opcode and it is // not in an executing branch. - if !vm.isBranchExecuting() && !pop.isConditional() { + if !vm.isBranchExecuting() && !isOpcodeConditional(pop.opcode.value) { return nil } diff --git a/txscript/opcode.go b/txscript/opcode.go index dc4ec50e..7705f59b 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -692,23 +692,6 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (i return scriptPos, nil } -// isConditional returns whether or not the opcode is a conditional opcode which -// changes the conditional execution stack when executed. -func (pop *parsedOpcode) isConditional() bool { - switch pop.opcode.value { - case OP_IF: - return true - case OP_NOTIF: - return true - case OP_ELSE: - return true - case OP_ENDIF: - return true - default: - return false - } -} - // checkMinimalDataPush returns whether or not the current data push uses the // smallest possible opcode to represent it. For example, the value 15 could // be pushed with OP_DATA_1 15 (among other variations); however, OP_15 is a -- 2.45.2 From 07e13698393719c4ab7e5bf7fbe23ae1d158e9d6 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:55 -0500 Subject: [PATCH 302/459] txscript: Make min push accept raw opcode and data. This converts the checkMinimalDataPush function defined on a parsed opcode to a standalone function which accepts an opcode and data slice instead in order to make it more flexible for raw script analysis. It also updates all callers accordingly. --- txscript/engine.go | 51 +++++++++++++++++++++++++++++++++++++++++- txscript/opcode.go | 55 ---------------------------------------------- 2 files changed, 50 insertions(+), 56 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index ddb26de5..a2dfad4c 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -225,6 +225,55 @@ func isOpcodeConditional(opcode byte) bool { } } +// checkMinimalDataPush returns whether or not the provided opcode is the +// smallest possible way to represent the given data. For example, the value 15 +// could be pushed with OP_DATA_1 15 (among other variations); however, OP_15 is +// a single opcode that represents the same value and is only a single byte +// versus two bytes. +func checkMinimalDataPush(op *opcode, data []byte) error { + opcodeVal := op.value + dataLen := len(data) + switch { + case dataLen == 0 && opcodeVal != OP_0: + str := fmt.Sprintf("zero length data push is encoded with opcode %s "+ + "instead of OP_0", op.name) + return scriptError(ErrMinimalData, str) + case dataLen == 1 && data[0] >= 1 && data[0] <= 16: + if opcodeVal != OP_1+data[0]-1 { + // Should have used OP_1 .. OP_16 + str := fmt.Sprintf("data push of the value %d encoded with opcode "+ + "%s instead of OP_%d", data[0], op.name, data[0]) + return scriptError(ErrMinimalData, str) + } + case dataLen == 1 && data[0] == 0x81: + if opcodeVal != OP_1NEGATE { + str := fmt.Sprintf("data push of the value -1 encoded with opcode "+ + "%s instead of OP_1NEGATE", op.name) + return scriptError(ErrMinimalData, str) + } + case dataLen <= 75: + if int(opcodeVal) != dataLen { + // Should have used a direct push + str := fmt.Sprintf("data push of %d bytes encoded with opcode %s "+ + "instead of OP_DATA_%d", dataLen, op.name, dataLen) + return scriptError(ErrMinimalData, str) + } + case dataLen <= 255: + if opcodeVal != OP_PUSHDATA1 { + str := fmt.Sprintf("data push of %d bytes encoded with opcode %s "+ + "instead of OP_PUSHDATA1", dataLen, op.name) + return scriptError(ErrMinimalData, str) + } + case dataLen <= 65535: + if opcodeVal != OP_PUSHDATA2 { + str := fmt.Sprintf("data push of %d bytes encoded with opcode %s "+ + "instead of OP_PUSHDATA2", dataLen, op.name) + return scriptError(ErrMinimalData, str) + } + } + return nil +} + // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. @@ -269,7 +318,7 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { if vm.dstack.verifyMinimalData && vm.isBranchExecuting() && pop.opcode.value >= 0 && pop.opcode.value <= OP_PUSHDATA4 { - if err := pop.checkMinimalDataPush(); err != nil { + if err := checkMinimalDataPush(pop.opcode, pop.data); err != nil { return err } } diff --git a/txscript/opcode.go b/txscript/opcode.go index 7705f59b..95b47580 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -692,61 +692,6 @@ func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (i return scriptPos, nil } -// checkMinimalDataPush returns whether or not the current data push uses the -// smallest possible opcode to represent it. For example, the value 15 could -// be pushed with OP_DATA_1 15 (among other variations); however, OP_15 is a -// single opcode that represents the same value and is only a single byte versus -// two bytes. -func (pop *parsedOpcode) checkMinimalDataPush() error { - data := pop.data - dataLen := len(data) - opcode := pop.opcode.value - - if dataLen == 0 && opcode != OP_0 { - str := fmt.Sprintf("zero length data push is encoded with "+ - "opcode %s instead of OP_0", pop.opcode.name) - return scriptError(ErrMinimalData, str) - } else if dataLen == 1 && data[0] >= 1 && data[0] <= 16 { - if opcode != OP_1+data[0]-1 { - // Should have used OP_1 .. OP_16 - str := fmt.Sprintf("data push of the value %d encoded "+ - "with opcode %s instead of OP_%d", data[0], - pop.opcode.name, data[0]) - return scriptError(ErrMinimalData, str) - } - } else if dataLen == 1 && data[0] == 0x81 { - if opcode != OP_1NEGATE { - str := fmt.Sprintf("data push of the value -1 encoded "+ - "with opcode %s instead of OP_1NEGATE", - pop.opcode.name) - return scriptError(ErrMinimalData, str) - } - } else if dataLen <= 75 { - if int(opcode) != dataLen { - // Should have used a direct push - str := fmt.Sprintf("data push of %d bytes encoded "+ - "with opcode %s instead of OP_DATA_%d", dataLen, - pop.opcode.name, dataLen) - return scriptError(ErrMinimalData, str) - } - } else if dataLen <= 255 { - if opcode != OP_PUSHDATA1 { - str := fmt.Sprintf("data push of %d bytes encoded "+ - "with opcode %s instead of OP_PUSHDATA1", - dataLen, pop.opcode.name) - return scriptError(ErrMinimalData, str) - } - } else if dataLen <= 65535 { - if opcode != OP_PUSHDATA2 { - str := fmt.Sprintf("data push of %d bytes encoded "+ - "with opcode %s instead of OP_PUSHDATA2", - dataLen, pop.opcode.name) - return scriptError(ErrMinimalData, str) - } - } - return nil -} - // disasmOpcode writes a human-readable disassembly of the provided opcode and // data into the provided buffer. The compact flag indicates the disassembly // should print a more compact representation of data-carrying and small integer -- 2.45.2 From 6198f453078624ccae46595411b6c2794b3d0027 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:56 -0500 Subject: [PATCH 303/459] txscript: Convert to use non-parsed opcode disasm. This converts the engine's current program counter disasembly to make use of the standalone disassembly function to remove the dependency on the parsed opcode struct. It also updates the tests accordingly. --- txscript/engine.go | 7 +++++-- txscript/opcode.go | 8 -------- txscript/opcode_test.go | 10 ++++++---- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index a2dfad4c..191de29f 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -10,6 +10,7 @@ import ( "crypto/sha256" "fmt" "math/big" + "strings" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/wire" @@ -331,8 +332,10 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { // provided position in the script. It does no error checking and leaves that // to the caller to provide a valid offset. func (vm *Engine) disasm(scriptIdx int, scriptOff int) string { - return fmt.Sprintf("%02x:%04x: %s", scriptIdx, scriptOff, - vm.scripts[scriptIdx][scriptOff].print(false)) + var buf strings.Builder + pop := vm.scripts[scriptIdx][scriptOff] + disasmOpcode(&buf, pop.opcode, pop.data, false) + return fmt.Sprintf("%02x:%04x: %s", scriptIdx, scriptOff, buf.String()) } // validPC returns an error if the current script position is valid for diff --git a/txscript/opcode.go b/txscript/opcode.go index 95b47580..a0d05052 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -740,14 +740,6 @@ func disasmOpcode(buf *strings.Builder, op *opcode, data []byte, compact bool) { buf.WriteString(fmt.Sprintf(" 0x%02x", data)) } -// print returns a human-readable string representation of the opcode for use -// in script disassembly. -func (pop *parsedOpcode) print(compact bool) string { - var buf strings.Builder - disasmOpcode(&buf, pop.opcode, pop.data, compact) - return buf.String() -} - // bytes returns any data associated with the opcode encoded as it would be in // a script. This is used for unparsing scripts from parsed opcodes. func (pop *parsedOpcode) bytes() ([]byte, error) { diff --git a/txscript/opcode_test.go b/txscript/opcode_test.go index 1487dde5..3c5abf9d 100644 --- a/txscript/opcode_test.go +++ b/txscript/opcode_test.go @@ -127,8 +127,9 @@ func TestOpcodeDisasm(t *testing.T) { expectedStr = "OP_UNKNOWN" + strconv.Itoa(opcodeVal) } - pop := parsedOpcode{opcode: &opcodeArray[opcodeVal], data: data} - gotStr := pop.print(true) + var buf strings.Builder + disasmOpcode(&buf, &opcodeArray[opcodeVal], data, true) + gotStr := buf.String() if gotStr != expectedStr { t.Errorf("pop.print (opcode %x): Unexpected disasm "+ "string - got %v, want %v", opcodeVal, gotStr, @@ -193,8 +194,9 @@ func TestOpcodeDisasm(t *testing.T) { expectedStr = "OP_UNKNOWN" + strconv.Itoa(opcodeVal) } - pop := parsedOpcode{opcode: &opcodeArray[opcodeVal], data: data} - gotStr := pop.print(false) + var buf strings.Builder + disasmOpcode(&buf, &opcodeArray[opcodeVal], data, false) + gotStr := buf.String() if gotStr != expectedStr { t.Errorf("pop.print (opcode %x): Unexpected disasm "+ "string - got %v, want %v", opcodeVal, gotStr, -- 2.45.2 From b871286f9864f70b84474dec85ce49b68c76b30c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:58 -0500 Subject: [PATCH 304/459] txscript: Refactor engine to use raw scripts. This refactors the script engine to store and step through raw scripts by making using of the new zero-allocation script tokenizer as opposed to the less efficient method of storing and stepping through parsed opcodes. It also improves several aspects while refactoring such as optimizing the disassembly trace, showing all scripts in the trace in the case of execution failure, and providing additional comments describing the purpose of each field in the engine. It should be noted that this is a step towards removing the parsed opcode struct and associated supporting code altogether, however, in order to ease the review process, this retains the struct and all function signatures for opcode execution which make use of an individual parsed opcode. Those will be updated in future commits. The following is an overview of the changes: - Modify internal engine scripts slice to use raw scripts instead of parsed opcodes - Introduce a tokenizer to the engine to track the current script - Remove no longer needed script offset parameter from the engine since that is tracked by the tokenizer - Add an opcode index counter for disassembly purposes to the engine - Update check for valid program counter to only consider the script index - Update tests for bad program counter accordingly - Rework the NewEngine function - Store the raw scripts - Setup the initial tokenizer - Explicitly check against version 0 instead of DefaultScriptVersion which would break consensus if changed - Check the scripts parse according to version 0 semantics to retain current consensus rules - Improve comments throughout - Rework the Step function - Use the tokenizer and raw scripts - Create a parsed opcode on the fly for now to retain existing opcode execution function signatures - Improve comments throughout - Update the Execute function - Explicitly check against version 0 instead of DefaultScriptVersion which would break consensus if changed - Improve the disassembly tracing in the case of error - Update the CheckErrorCondition function - Modify clean stack error message to make sense in all cases - Improve the comments - Update the DisasmPC and DisasmScript functions on the engine - Use the tokenizer - Optimize construction via the use of strings.Builder - Modify the subScript function to return the raw script bytes since the parsed opcodes are no longer stored - Update the various signature checking opcodes to use the raw opcode data removal and signature hash calculation functions since the subscript is now a raw script - opcodeCheckSig - opcodeCheckMultiSig - opcodeCheckSigAlt --- txscript/engine.go | 373 +++++++++++++++++++++++++++------------- txscript/engine_test.go | 19 +- txscript/opcode.go | 20 +-- 3 files changed, 266 insertions(+), 146 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 191de29f..1afb8324 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -119,21 +119,84 @@ var halfOrder = new(big.Int).Rsh(btcec.S256().N, 1) // Engine is the virtual machine that executes scripts. type Engine struct { - scripts [][]parsedOpcode + // The following fields are set when the engine is created and must not be + // changed afterwards. The entries of the signature cache are mutated + // during execution, however, the cache pointer itself is not changed. + // + // flags specifies the additional flags which modify the execution behavior + // of the engine. + // + // tx identifies the transaction that contains the input which in turn + // contains the signature script being executed. + // + // txIdx identifies the input index within the transaction that contains + // the signature script being executed. + // + // version specifies the version of the public key script to execute. Since + // signature scripts redeem public keys scripts, this means the same version + // also extends to signature scripts and redeem scripts in the case of + // pay-to-script-hash. + // + // bip16 specifies that the public key script is of a special form that + // indicates it is a BIP16 pay-to-script-hash and therefore the + // execution must be treated as such. + // + // sigCache caches the results of signature verifications. This is useful + // since transaction scripts are often executed more than once from various + // contexts (e.g. new block templates, when transactions are first seen + // prior to being mined, part of full block verification, etc). + flags ScriptFlags + tx wire.MsgTx + txIdx int + version uint16 + bip16 bool + sigCache *SigCache + hashCache *TxSigHashes + + // The following fields handle keeping track of the current execution state + // of the engine. + // + // scripts houses the raw scripts that are executed by the engine. This + // includes the signature script as well as the public key script. It also + // includes the redeem script in the case of pay-to-script-hash. + // + // scriptIdx tracks the index into the scripts array for the current program + // counter. + // + // opcodeIdx tracks the number of the opcode within the current script for + // the current program counter. Note that it differs from the actual byte + // index into the script and is really only used for disassembly purposes. + // + // lastCodeSep specifies the position within the current script of the last + // OP_CODESEPARATOR. + // + // tokenizer provides the token stream of the current script being executed + // and doubles as state tracking for the program counter within the script. + // + // savedFirstStack keeps a copy of the stack from the first script when + // performing pay-to-script-hash execution. + // + // dstack is the primary data stack the various opcodes push and pop data + // to and from during execution. + // + // astack is the alternate data stack the various opcodes push and pop data + // to and from during execution. + // + // condStack tracks the conditional execution state with support for + // multiple nested conditional execution opcodes. + // + // numOps tracks the total number of non-push operations in a script and is + // primarily used to enforce maximum limits. + scripts [][]byte scriptIdx int - scriptOff int + opcodeIdx int lastCodeSep int - dstack stack // data stack - astack stack // alt stack - tx wire.MsgTx - txIdx int + tokenizer ScriptTokenizer + savedFirstStack [][]byte + dstack stack + astack stack condStack []int numOps int - flags ScriptFlags - sigCache *SigCache - hashCache *TxSigHashes - bip16 bool // treat execution as pay-to-script-hash - savedFirstStack [][]byte // stack from first script for bip16 scripts witnessVersion int witnessProgram []byte inputAmount int64 @@ -327,44 +390,17 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { return pop.opcode.opfunc(pop, vm) } -// disasm is a helper function to produce the output for DisasmPC and -// DisasmScript. It produces the opcode prefixed by the program counter at the -// provided position in the script. It does no error checking and leaves that -// to the caller to provide a valid offset. -func (vm *Engine) disasm(scriptIdx int, scriptOff int) string { - var buf strings.Builder - pop := vm.scripts[scriptIdx][scriptOff] - disasmOpcode(&buf, pop.opcode, pop.data, false) - return fmt.Sprintf("%02x:%04x: %s", scriptIdx, scriptOff, buf.String()) -} - -// validPC returns an error if the current script position is valid for -// execution, nil otherwise. -func (vm *Engine) validPC() error { +// checkValidPC returns an error if the current script position is not valid for +// execution. +func (vm *Engine) checkValidPC() error { if vm.scriptIdx >= len(vm.scripts) { - str := fmt.Sprintf("past input scripts %v:%v %v:xxxx", - vm.scriptIdx, vm.scriptOff, len(vm.scripts)) - return scriptError(ErrInvalidProgramCounter, str) - } - if vm.scriptOff >= len(vm.scripts[vm.scriptIdx]) { - str := fmt.Sprintf("past input scripts %v:%v %v:%04d", - vm.scriptIdx, vm.scriptOff, vm.scriptIdx, - len(vm.scripts[vm.scriptIdx])) + str := fmt.Sprintf("script index %d beyond total scripts %d", + vm.scriptIdx, len(vm.scripts)) return scriptError(ErrInvalidProgramCounter, str) } return nil } -// curPC returns either the current script and offset, or an error if the -// position isn't valid. -func (vm *Engine) curPC() (script int, off int, err error) { - err = vm.validPC() - if err != nil { - return 0, 0, err - } - return vm.scriptIdx, vm.scriptOff, nil -} - // isWitnessVersionActive returns true if a witness program was extracted // during the initialization of the Engine, and the program's version matches // the specified version. @@ -392,7 +428,9 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { if err != nil { return err } - pops, err := parseScript(pkScript) + + const scriptVersion = 0 + err = checkScriptParses(vm.version, pkScript) if err != nil { return err } @@ -400,7 +438,7 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { // Set the stack to the provided witness stack, then // append the pkScript generated above as the next // script to execute. - vm.scripts = append(vm.scripts, pops) + vm.scripts = append(vm.scripts, pkScript) vm.SetStack(witness) case payToWitnessScriptHashDataSize: // P2WSH @@ -430,10 +468,10 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { "witness program hash mismatch") } - // With all the validity checks passed, parse the - // script into individual op-codes so w can execute it - // as the next script. - pops, err := parseScript(witnessScript) + // With all the validity checks passed, assert that the + // script parses without failure. + const scriptVersion = 0 + err := checkScriptParses(vm.version, witnessScript) if err != nil { return err } @@ -441,7 +479,7 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { // The hash matched successfully, so use the witness as // the stack, and set the witnessScript to be the next // script executed. - vm.scripts = append(vm.scripts, pops) + vm.scripts = append(vm.scripts, witnessScript) vm.SetStack(witness[:len(witness)-1]) default: @@ -482,18 +520,50 @@ func (vm *Engine) verifyWitnessProgram(witness [][]byte) error { } // DisasmPC returns the string for the disassembly of the opcode that will be -// next to execute when Step() is called. +// next to execute when Step is called. func (vm *Engine) DisasmPC() (string, error) { - scriptIdx, scriptOff, err := vm.curPC() - if err != nil { + if err := vm.checkValidPC(); err != nil { return "", err } - return vm.disasm(scriptIdx, scriptOff), nil + + // Create a copy of the current tokenizer and parse the next opcode in the + // copy to avoid mutating the current one. + peekTokenizer := vm.tokenizer + if !peekTokenizer.Next() { + // Note that due to the fact that all scripts are checked for parse + // failures before this code ever runs, there should never be an error + // here, but check again to be safe in case a refactor breaks that + // assumption or new script versions are introduced with different + // semantics. + if err := peekTokenizer.Err(); err != nil { + return "", err + } + + // Note that this should be impossible to hit in practice because the + // only way it could happen would be for the final opcode of a script to + // already be parsed without the script index having been updated, which + // is not the case since stepping the script always increments the + // script index when parsing and executing the final opcode of a script. + // + // However, check again to be safe in case a refactor breaks that + // assumption or new script versions are introduced with different + // semantics. + str := fmt.Sprintf("program counter beyond script index %d (bytes %x)", + vm.scriptIdx, vm.scripts[vm.scriptIdx]) + return "", scriptError(ErrInvalidProgramCounter, str) + } + + var buf strings.Builder + disasmOpcode(&buf, peekTokenizer.op, peekTokenizer.Data(), false) + return fmt.Sprintf("%02x:%04x: %s", vm.scriptIdx, vm.opcodeIdx, + buf.String()), nil } // DisasmScript returns the disassembly string for the script at the requested // offset index. Index 0 is the signature script and 1 is the public key -// script. +// script. In the case of pay-to-script-hash, index 2 is the redeem script once +// the execution has progressed far enough to have successfully verified script +// hash and thus add the script to the scripts to execute. func (vm *Engine) DisasmScript(idx int) (string, error) { if idx >= len(vm.scripts) { str := fmt.Sprintf("script index %d >= total scripts %d", idx, @@ -501,19 +571,25 @@ func (vm *Engine) DisasmScript(idx int) (string, error) { return "", scriptError(ErrInvalidIndex, str) } - var disstr string - for i := range vm.scripts[idx] { - disstr = disstr + vm.disasm(idx, i) + "\n" + var disbuf strings.Builder + script := vm.scripts[idx] + tokenizer := MakeScriptTokenizer(vm.version, script) + var opcodeIdx int + for tokenizer.Next() { + disbuf.WriteString(fmt.Sprintf("%02x:%04x: ", idx, opcodeIdx)) + disasmOpcode(&disbuf, tokenizer.op, tokenizer.Data(), false) + disbuf.WriteByte('\n') + opcodeIdx++ } - return disstr, nil + return disbuf.String(), tokenizer.Err() } // CheckErrorCondition returns nil if the running script has ended and was // successful, leaving a a true boolean on the stack. An error otherwise, // including if the script has not finished. func (vm *Engine) CheckErrorCondition(finalScript bool) error { - // Check execution is actually done. When pc is past the end of script - // array there are no more scripts to run. + // Check execution is actually done by ensuring the script index is after + // the final script in the array script. if vm.scriptIdx < len(vm.scripts) { return scriptError(ErrScriptUnfinished, "error check when script unfinished") @@ -527,11 +603,14 @@ func (vm *Engine) CheckErrorCondition(finalScript bool) error { "have clean stack") } + // The final script must end with exactly one data stack item when the + // verify clean stack flag is set. Otherwise, there must be at least one + // data stack item in order to interpret it as a boolean. if finalScript && vm.hasFlag(ScriptVerifyCleanStack) && vm.dstack.Depth() != 1 { - str := fmt.Sprintf("stack contains %d unexpected items", - vm.dstack.Depth()-1) + str := fmt.Sprintf("stack must contain exactly one item (contains %d)", + vm.dstack.Depth()) return scriptError(ErrCleanStack, str) } else if vm.dstack.Depth() < 1 { return scriptError(ErrEmptyStack, @@ -545,10 +624,14 @@ func (vm *Engine) CheckErrorCondition(finalScript bool) error { if !v { // Log interesting data. log.Tracef("%v", newLogClosure(func() string { - dis0, _ := vm.DisasmScript(0) - dis1, _ := vm.DisasmScript(1) - return fmt.Sprintf("scripts failed: script0: %s\n"+ - "script1: %s", dis0, dis1) + var buf strings.Builder + buf.WriteString("scripts failed:\n") + for i := range vm.scripts { + dis, _ := vm.DisasmScript(i) + buf.WriteString(fmt.Sprintf("script%d:\n", i)) + buf.WriteString(dis) + } + return buf.String() })) return scriptError(ErrEvalFalse, "false stack entry at end of script execution") @@ -556,25 +639,39 @@ func (vm *Engine) CheckErrorCondition(finalScript bool) error { return nil } -// Step will execute the next instruction and move the program counter to the -// next opcode in the script, or the next script if the current has ended. Step -// will return true in the case that the last opcode was successfully executed. +// Step executes the next instruction and moves the program counter to the next +// opcode in the script, or the next script if the current has ended. Step will +// return true in the case that the last opcode was successfully executed. // // The result of calling Step or any other method is undefined if an error is // returned. func (vm *Engine) Step() (done bool, err error) { - // Verify that it is pointing to a valid script address. - err = vm.validPC() - if err != nil { + // Verify the engine is pointing to a valid program counter. + if err := vm.checkValidPC(); err != nil { return true, err } - opcode := &vm.scripts[vm.scriptIdx][vm.scriptOff] - vm.scriptOff++ + + // Attempt to parse the next opcode from the current script. + if !vm.tokenizer.Next() { + // Note that due to the fact that all scripts are checked for parse + // failures before this code ever runs, there should never be an error + // here, but check again to be safe in case a refactor breaks that + // assumption or new script versions are introduced with different + // semantics. + if err := vm.tokenizer.Err(); err != nil { + return false, err + } + + str := fmt.Sprintf("attempt to step beyond script index %d (bytes %x)", + vm.scriptIdx, vm.scripts[vm.scriptIdx]) + return true, scriptError(ErrInvalidProgramCounter, str) + } // Execute the opcode while taking into account several things such as - // disabled opcodes, illegal opcodes, maximum allowed operations per - // script, maximum script element sizes, and conditionals. - err = vm.executeOpcode(opcode) + // disabled opcodes, illegal opcodes, maximum allowed operations per script, + // maximum script element sizes, and conditionals. + pop := parsedOpcode{opcode: vm.tokenizer.op, data: vm.tokenizer.Data()} + err = vm.executeOpcode(&pop) if err != nil { return true, err } @@ -589,43 +686,53 @@ func (vm *Engine) Step() (done bool, err error) { } // Prepare for next instruction. - if vm.scriptOff >= len(vm.scripts[vm.scriptIdx]) { - // Illegal to have an `if' that straddles two scripts. - if err == nil && len(vm.condStack) != 0 { + vm.opcodeIdx++ + if vm.tokenizer.Done() { + // Illegal to have a conditional that straddles two scripts. + if len(vm.condStack) != 0 { return false, scriptError(ErrUnbalancedConditional, "end of script reached in conditional execution") } - // Alt stack doesn't persist. + // Alt stack doesn't persist between scripts. _ = vm.astack.DropN(vm.astack.Depth()) - vm.numOps = 0 // number of ops is per script. - vm.scriptOff = 0 - if vm.scriptIdx == 0 && vm.bip16 { + // The number of operations is per script. + vm.numOps = 0 + + // Reset the opcode index for the next script. + vm.opcodeIdx = 0 + + // Advance to the next script as needed. + switch { + case vm.scriptIdx == 0 && vm.bip16: vm.scriptIdx++ vm.savedFirstStack = vm.GetStack() - } else if vm.scriptIdx == 1 && vm.bip16 { + + case vm.scriptIdx == 1 && vm.bip16: // Put us past the end for CheckErrorCondition() vm.scriptIdx++ - // Check script ran successfully and pull the script - // out of the first stack and execute that. + + // Check script ran successfully. err := vm.CheckErrorCondition(false) if err != nil { return false, err } + // Obtain the redeem script from the first stack and ensure it + // parses. script := vm.savedFirstStack[len(vm.savedFirstStack)-1] - pops, err := parseScript(script) - if err != nil { + if err := checkScriptParses(vm.version, script); err != nil { return false, err } - vm.scripts = append(vm.scripts, pops) + vm.scripts = append(vm.scripts, script) - // Set stack to be the stack from first script minus the + // Set stack to be the stack from first script minus the redeem // script itself vm.SetStack(vm.savedFirstStack[:len(vm.savedFirstStack)-1]) - } else if (vm.scriptIdx == 1 && vm.witnessProgram != nil) || - (vm.scriptIdx == 2 && vm.witnessProgram != nil && vm.bip16) { // Nested P2SH. + + case vm.scriptIdx == 1 && vm.witnessProgram != nil, + vm.scriptIdx == 2 && vm.witnessProgram != nil && vm.bip16: // np2sh vm.scriptIdx++ @@ -633,30 +740,46 @@ func (vm *Engine) Step() (done bool, err error) { if err := vm.verifyWitnessProgram(witness); err != nil { return false, err } - } else { + + default: vm.scriptIdx++ } - // there are zero length scripts in the wild - if vm.scriptIdx < len(vm.scripts) && vm.scriptOff >= len(vm.scripts[vm.scriptIdx]) { + + // Skip empty scripts. + if vm.scriptIdx < len(vm.scripts) && len(vm.scripts[vm.scriptIdx]) == 0 { vm.scriptIdx++ } + vm.lastCodeSep = 0 if vm.scriptIdx >= len(vm.scripts) { return true, nil } + + // Finally, update the current tokenizer used to parse through scripts + // one opcode at a time to start from the beginning of the new script + // associated with the program counter. + vm.tokenizer = MakeScriptTokenizer(vm.version, vm.scripts[vm.scriptIdx]) } + return false, nil } // Execute will execute all scripts in the script engine and return either nil // for successful validation or an error if one occurred. func (vm *Engine) Execute() (err error) { + // All script versions other than 0 currently execute without issue, + // making all outputs to them anyone can pay. In the future this + // will allow for the addition of new scripting languages. + if vm.version != 0 { + return nil + } + done := false for !done { log.Tracef("%v", newLogClosure(func() string { dis, err := vm.DisasmPC() if err != nil { - return fmt.Sprintf("stepping (%v)", err) + return fmt.Sprintf("stepping - failed to disasm pc: %v", err) } return fmt.Sprintf("stepping %v", dis) })) @@ -668,7 +791,7 @@ func (vm *Engine) Execute() (err error) { log.Tracef("%v", newLogClosure(func() string { var dstr, astr string - // if we're tracing, dump the stacks. + // Log the non-empty stacks when tracing. if vm.dstack.Depth() != 0 { dstr = "Stack:\n" + vm.dstack.String() } @@ -684,7 +807,7 @@ func (vm *Engine) Execute() (err error) { } // subScript returns the script since the last OP_CODESEPARATOR. -func (vm *Engine) subScript() []parsedOpcode { +func (vm *Engine) subScript() []byte { return vm.scripts[vm.scriptIdx][vm.lastCodeSep:] } @@ -1008,10 +1131,10 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags } scriptSig := tx.TxIn[txIdx].SignatureScript - // When both the signature script and public key script are empty the - // result is necessarily an error since the stack would end up being - // empty which is equivalent to a false top element. Thus, just return - // the relevant error now as an optimization. + // When both the signature script and public key script are empty the result + // is necessarily an error since the stack would end up being empty which is + // equivalent to a false top element. Thus, just return the relevant error + // now as an optimization. if len(scriptSig) == 0 && len(scriptPubKey) == 0 { return nil, scriptError(ErrEvalFalse, "false stack entry at end of script execution") @@ -1057,29 +1180,28 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags vm.bip16 = true } - // The engine stores the scripts in parsed form using a slice. This - // allows multiple scripts to be executed in sequence. For example, - // with a pay-to-script-hash transaction, there will be ultimately be - // a third script to execute. + // The engine stores the scripts using a slice. This allows multiple + // scripts to be executed in sequence. For example, with a + // pay-to-script-hash transaction, there will be ultimately be a third + // script to execute. scripts := [][]byte{scriptSig, scriptPubKey} - vm.scripts = make([][]parsedOpcode, len(scripts)) - for i, scr := range scripts { + for _, scr := range scripts { if len(scr) > MaxScriptSize { - str := fmt.Sprintf("script size %d is larger than max "+ - "allowed size %d", len(scr), MaxScriptSize) + str := fmt.Sprintf("script size %d is larger than max allowed "+ + "size %d", len(scr), MaxScriptSize) return nil, scriptError(ErrScriptTooBig, str) } - var err error - vm.scripts[i], err = parseScript(scr) - if err != nil { + + const scriptVersion = 0 + if err := checkScriptParses(scriptVersion, scr); err != nil { return nil, err } } + vm.scripts = scripts // Advance the program counter to the public key script if the signature - // script is empty since there is nothing to execute for it in that - // case. - if len(scripts[0]) == 0 { + // script is empty since there is nothing to execute for it in that case. + if len(scriptSig) == 0 { vm.scriptIdx++ } if vm.hasFlag(ScriptVerifyMinimalData) { @@ -1103,7 +1225,7 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags var witProgram []byte switch { - case isWitnessProgram(vm.scripts[1]): + case IsWitnessProgram(vm.scripts[1]): // The scriptSig must be *empty* for all native witness // programs, otherwise we introduce malleability. if len(scriptSig) != 0 { @@ -1118,12 +1240,11 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags // data push of the witness program, otherwise we // reintroduce malleability. sigPops := vm.scripts[0] - if len(sigPops) == 1 && - isCanonicalPush(sigPops[0].opcode.value, - sigPops[0].data) && - IsWitnessProgram(sigPops[0].data) { + if len(sigPops) > 2 && + isCanonicalPush(sigPops[0], sigPops[1:]) && + IsWitnessProgram(sigPops[1:]) { - witProgram = sigPops[0].data + witProgram = sigPops[1:] } else { errStr := "signature script for witness " + "nested p2sh is not canonical" @@ -1150,6 +1271,10 @@ func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags } + // Setup the current tokenizer used to parse through the script one opcode + // at a time with the script associated with the program counter. + vm.tokenizer = MakeScriptTokenizer(scriptVersion, scripts[vm.scriptIdx]) + vm.tx = *tx vm.txIdx = txIdx diff --git a/txscript/engine_test.go b/txscript/engine_test.go index 2e8c522c..5818080d 100644 --- a/txscript/engine_test.go +++ b/txscript/engine_test.go @@ -1,4 +1,5 @@ // Copyright (c) 2013-2017 The btcsuite developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -11,16 +12,16 @@ import ( "github.com/btcsuite/btcd/wire" ) -// TestBadPC sets the pc to a deliberately bad result then confirms that Step() +// TestBadPC sets the pc to a deliberately bad result then confirms that Step // and Disasm fail correctly. func TestBadPC(t *testing.T) { t.Parallel() tests := []struct { - script, off int + scriptIdx int }{ - {script: 2, off: 0}, - {script: 0, off: 2}, + {scriptIdx: 2}, + {scriptIdx: 3}, } // tx with almost empty scripts. @@ -59,20 +60,20 @@ func TestBadPC(t *testing.T) { t.Errorf("Failed to create script: %v", err) } - // set to after all scripts - vm.scriptIdx = test.script - vm.scriptOff = test.off + // Set to after all scripts. + vm.scriptIdx = test.scriptIdx + // Ensure attempting to step fails. _, err = vm.Step() if err == nil { t.Errorf("Step with invalid pc (%v) succeeds!", test) continue } + // Ensure attempting to disassemble the current program counter fails. _, err = vm.DisasmPC() if err == nil { - t.Errorf("DisasmPC with invalid pc (%v) succeeds!", - test) + t.Errorf("DisasmPC with invalid pc (%v) succeeds!", test) } } } diff --git a/txscript/opcode.go b/txscript/opcode.go index a0d05052..950121c6 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -1981,7 +1981,7 @@ func opcodeHash256(op *parsedOpcode, vm *Engine) error { // // This opcode does not change the contents of the data stack. func opcodeCodeSeparator(op *parsedOpcode, vm *Engine) error { - vm.lastCodeSep = vm.scriptOff + vm.lastCodeSep = int(vm.tokenizer.ByteIndex()) return nil } @@ -2055,7 +2055,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { sigHashes = NewTxSigHashes(&vm.tx) } - hash, err = calcWitnessSignatureHash(subScript, sigHashes, hashType, + hash, err = calcWitnessSignatureHashRaw(subScript, sigHashes, hashType, &vm.tx, vm.txIdx, vm.inputAmount) if err != nil { return err @@ -2063,12 +2063,9 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { } else { // Remove the signature since there is no way for a signature // to sign itself. - subScript = removeOpcodeByData(subScript, fullSigBytes) + subScript = removeOpcodeByDataRaw(subScript, fullSigBytes) - hash, err = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx) - if err != nil { - return err - } + hash = calcSignatureHashRaw(subScript, hashType, &vm.tx, vm.txIdx) } pubKey, err := btcec.ParsePubKey(pkBytes, btcec.S256()) @@ -2239,7 +2236,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { // no way for a signature to sign itself. if !vm.isWitnessVersionActive(0) { for _, sigInfo := range signatures { - script = removeOpcodeByData(script, sigInfo.signature) + script = removeOpcodeByDataRaw(script, sigInfo.signature) } } @@ -2331,16 +2328,13 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { sigHashes = NewTxSigHashes(&vm.tx) } - hash, err = calcWitnessSignatureHash(script, sigHashes, hashType, + hash, err = calcWitnessSignatureHashRaw(script, sigHashes, hashType, &vm.tx, vm.txIdx, vm.inputAmount) if err != nil { return err } } else { - hash, err = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx) - if err != nil { - return err - } + hash = calcSignatureHashRaw(script, hashType, &vm.tx, vm.txIdx) } var valid bool -- 2.45.2 From bd07a2580e895aae9418134cf0d6ce59bb59b902 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:05:20 -0700 Subject: [PATCH 305/459] txscript: Remove unused calcSignatureHash --- txscript/script.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 0be0a7b8..8ff39e20 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -744,21 +744,6 @@ func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx return chainhash.DoubleHashB(wbuf.Bytes()) } -// calcSignatureHash computes the signature hash for the specified input of the -// target transaction observing the desired signature hash type. -// -// DEPRECATED: Use calcSignatureHashRaw instead -func calcSignatureHash(prevOutScript []parsedOpcode, hashType SigHashType, - tx *wire.MsgTx, idx int) ([]byte, error) { - - sigScript, err := unparseScript(prevOutScript) - if err != nil { - return nil, err - } - - return calcSignatureHashRaw(sigScript, hashType, tx, idx), nil -} - // asSmallInt returns the passed opcode, which must be true according to // isSmallInt(), as an integer. func asSmallInt(op byte) int { -- 2.45.2 From aa1014c87bbf801d03c7b31d4bd2195985c1cca5 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 20:09:59 -0700 Subject: [PATCH 306/459] txscript: Remove unused isWitnessProgram --- txscript/script.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 8ff39e20..6557c64d 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -98,21 +98,6 @@ func IsWitnessProgram(script []byte) bool { return isWitnessProgramScript(script) } -// isWitnessProgram returns true if the passed script is a witness program, and -// false otherwise. A witness program MUST adhere to the following constraints: -// there must be exactly two pops (program version and the program itself), the -// first opcode MUST be a small integer (0-16), the push data MUST be -// canonical, and finally the size of the push data must be between 2 and 40 -// bytes. -// -// DEPRECATED: Use isWitnessProgramScript instead. -func isWitnessProgram(pops []parsedOpcode) bool { - return len(pops) == 2 && - isSmallInt(pops[0].opcode.value) && - isCanonicalPush(pops[1].opcode.value, pops[1].data) && - (len(pops[1].data) >= 2 && len(pops[1].data) <= 40) -} - // IsNullData returns true if the passed script is a null data script, false // otherwise. func IsNullData(script []byte) bool { -- 2.45.2 From 64aeab7882e8907422555d64faa933bfdd4d1313 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:59 -0500 Subject: [PATCH 307/459] txscript: Remove unused removeOpcodeByData func. --- txscript/script.go | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 6557c64d..242fc2d8 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -318,23 +318,6 @@ func isCanonicalPush(opcode byte, data []byte) bool { return true } -// removeOpcodeByData will return the script minus any opcodes that would push -// the passed data to the stack. -// -// DEPRECATED. Use removeOpcodeByDataRaw instead. -func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode { - retScript := make([]parsedOpcode, 0, len(pkscript)) - for _, pop := range pkscript { - if !isCanonicalPush(pop.opcode.value, pop.data) || - !bytes.Contains(pop.data, data) { - - retScript = append(retScript, pop) - } - } - return retScript - -} - // removeOpcodeByDataRaw will return the script minus any opcodes that perform a // canonical push of data that contains the passed data to remove. This // function assumes it is provided a version 0 script as any future version of -- 2.45.2 From 9d1d6d59a6fbf90c62b45f7dd2019a7ad7e09e5c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:00 -0500 Subject: [PATCH 308/459] txscript: Rename removeOpcodeByDataRaw func. This renames the removeOpcodeByDataRaw to removeOpcodeByData now that the old version has been removed. --- txscript/opcode.go | 4 ++-- txscript/script.go | 4 ++-- txscript/script_test.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 950121c6..1d8ee25e 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -2063,7 +2063,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { } else { // Remove the signature since there is no way for a signature // to sign itself. - subScript = removeOpcodeByDataRaw(subScript, fullSigBytes) + subScript = removeOpcodeByData(subScript, fullSigBytes) hash = calcSignatureHashRaw(subScript, hashType, &vm.tx, vm.txIdx) } @@ -2236,7 +2236,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { // no way for a signature to sign itself. if !vm.isWitnessVersionActive(0) { for _, sigInfo := range signatures { - script = removeOpcodeByDataRaw(script, sigInfo.signature) + script = removeOpcodeByData(script, sigInfo.signature) } } diff --git a/txscript/script.go b/txscript/script.go index 242fc2d8..266c36dd 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -318,7 +318,7 @@ func isCanonicalPush(opcode byte, data []byte) bool { return true } -// removeOpcodeByDataRaw will return the script minus any opcodes that perform a +// removeOpcodeByData will return the script minus any opcodes that perform a // canonical push of data that contains the passed data to remove. This // function assumes it is provided a version 0 script as any future version of // script should avoid this functionality since it is unncessary due to the @@ -332,7 +332,7 @@ func isCanonicalPush(opcode byte, data []byte) bool { // NOTE: This function is only valid for version 0 scripts. Since the function // does not accept a script version, the results are undefined for other script // versions. -func removeOpcodeByDataRaw(script []byte, dataToRemove []byte) []byte { +func removeOpcodeByData(script []byte, dataToRemove []byte) []byte { // Avoid work when possible. if len(script) == 0 || len(dataToRemove) == 0 { return script diff --git a/txscript/script_test.go b/txscript/script_test.go index 02c364ce..7db065de 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -4136,7 +4136,7 @@ func TestRemoveOpcodeByData(t *testing.T) { return nil, err } - return removeOpcodeByDataRaw(script, data), nil + return removeOpcodeByData(script, data), nil } for _, test := range tests { -- 2.45.2 From b40859ff00128c80b29d9164588047dcfe5b8fc6 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:07:18 -0700 Subject: [PATCH 309/459] txscript: Rename calcSignatureHashRaw --- txscript/opcode.go | 4 ++-- txscript/script.go | 8 ++++---- txscript/sign.go | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 1d8ee25e..9e0320ae 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -2065,7 +2065,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { // to sign itself. subScript = removeOpcodeByData(subScript, fullSigBytes) - hash = calcSignatureHashRaw(subScript, hashType, &vm.tx, vm.txIdx) + hash = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx) } pubKey, err := btcec.ParsePubKey(pkBytes, btcec.S256()) @@ -2334,7 +2334,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { return err } } else { - hash = calcSignatureHashRaw(script, hashType, &vm.tx, vm.txIdx) + hash = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx) } var valid bool diff --git a/txscript/script.go b/txscript/script.go index 266c36dd..2e3431d0 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -618,12 +618,12 @@ func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx return nil, err } - return calcSignatureHashRaw(script, hashType, tx, idx), nil + return calcSignatureHash(script, hashType, tx, idx), nil } -// calcSignatureHashRaw computes the signature hash for the specified input of -// the target transaction observing the desired signature hash type. -func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx, idx int) []byte { +// calcSignatureHash computes the signature hash for the specified input of the +// target transaction observing the desired signature hash type. +func calcSignatureHash(sigScript []byte, hashType SigHashType, tx *wire.MsgTx, idx int) []byte { // The SigHashSingle signature type signs only the corresponding input // and output (the output with the same index number as the input). // diff --git a/txscript/sign.go b/txscript/sign.go index 4d63a9b2..51c69103 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -285,7 +285,7 @@ sigLoop: // however, assume no sigs etc are in the script since that // would make the transaction nonstandard and thus not // MultiSigTy, so we just need to hash the full thing. - hash := calcSignatureHashRaw(pkScript, hashType, tx, idx) + hash := calcSignatureHash(pkScript, hashType, tx, idx) for _, addr := range addresses { // All multisig addresses should be pubkey addresses -- 2.45.2 From e84398d21e091b8b28c8723583b7cf3d4f10c677 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:10:48 -0700 Subject: [PATCH 310/459] txscript/sign: Use calcWitnessSigHashRaw for witness sigs --- txscript/sign.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/txscript/sign.go b/txscript/sign.go index 51c69103..138e31cd 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -22,12 +22,7 @@ func RawTxInWitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int, amt int64, subScript []byte, hashType SigHashType, key *btcec.PrivateKey) ([]byte, error) { - parsedScript, err := parseScript(subScript) - if err != nil { - return nil, fmt.Errorf("cannot parse output script: %v", err) - } - - hash, err := calcWitnessSignatureHash(parsedScript, sigHashes, hashType, tx, + hash, err := calcWitnessSignatureHashRaw(subScript, sigHashes, hashType, tx, idx, amt) if err != nil { return nil, err -- 2.45.2 From 8588536586cf2e350bf190a96400ce1bd5f09de1 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:31:33 -0700 Subject: [PATCH 311/459] txscript/pkscript: Use finalOpcodeData to extract redeem script --- txscript/pkscript.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/txscript/pkscript.go b/txscript/pkscript.go index 0703ef5d..f5b11e6d 100644 --- a/txscript/pkscript.go +++ b/txscript/pkscript.go @@ -211,11 +211,12 @@ func computeNonWitnessPkScript(sigScript []byte) (PkScript, error) { // The redeem script will always be the last data push of the // signature script, so we'll parse the script into opcodes to // obtain it. - parsedOpcodes, err := parseScript(sigScript) + const scriptVersion = 0 + err := checkScriptParses(scriptVersion, sigScript) if err != nil { return PkScript{}, err } - redeemScript := parsedOpcodes[len(parsedOpcodes)-1].data + redeemScript := finalOpcodeData(scriptVersion, sigScript) scriptHash := hash160(redeemScript) script, err := payToScriptHashScript(scriptHash) -- 2.45.2 From 08a53b25fb5d36cfb2c7f2845a791232a54ef91f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:03 -0500 Subject: [PATCH 312/459] txscript: Remove unused parseScript func. --- txscript/script.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 2e3431d0..1a8890b9 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -202,12 +202,6 @@ func checkScriptTemplateParseable(script []byte, opcodes *[256]opcode) (*byte, e return &firstOpcode, nil } -// parseScript preparses the script in bytes into a list of parsedOpcodes while -// applying a number of sanity checks. -func parseScript(script []byte) ([]parsedOpcode, error) { - return parseScriptTemplate(script, &opcodeArray) -} - // unparseScript reversed the action of parseScript and returns the // parsedOpcodes as a list of bytes func unparseScript(pops []parsedOpcode) ([]byte, error) { -- 2.45.2 From 82e02951dc664c6dc245f078d8a16695ddb195ac Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Fri, 19 Apr 2019 19:48:25 -0700 Subject: [PATCH 313/459] txscript: Remove unused calcWitnessSignatureHash --- txscript/script.go | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 1a8890b9..97c2f401 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -534,30 +534,6 @@ func calcWitnessSignatureHashRaw(scriptSig []byte, sigHashes *TxSigHashes, return chainhash.DoubleHashB(sigHash.Bytes()), nil } -// calcWitnessSignatureHash computes the sighash digest of a transaction's -// segwit input using the new, optimized digest calculation algorithm defined -// in BIP0143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki. -// This function makes use of pre-calculated sighash fragments stored within -// the passed HashCache to eliminate duplicate hashing computations when -// calculating the final digest, reducing the complexity from O(N^2) to O(N). -// Additionally, signatures now cover the input value of the referenced unspent -// output. This allows offline, or hardware wallets to compute the exact amount -// being spent, in addition to the final transaction fee. In the case the -// wallet if fed an invalid input amount, the real sighash will differ causing -// the produced signature to be invalid. -// -// DEPRECATED: Use calcWitnessSignatureHashRaw instead. -func calcWitnessSignatureHash(subScript []parsedOpcode, sigHashes *TxSigHashes, - hashType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { - - script, err := unparseScript(subScript) - if err != nil { - return nil, err - } - - return calcWitnessSignatureHashRaw(script, sigHashes, hashType, tx, idx, amt) -} - // CalcWitnessSigHash computes the sighash digest for the specified input of // the target transaction observing the desired sig hash type. func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType SigHashType, -- 2.45.2 From 849873675f5fca000e431228838e4db397f6300c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:04 -0500 Subject: [PATCH 314/459] txscript: Remove unused unparseScript func. Also remove tests associated with unparsing opcodes accordingly. --- txscript/script.go | 14 - txscript/script_test.go | 3651 --------------------------------------- 2 files changed, 3665 deletions(-) diff --git a/txscript/script.go b/txscript/script.go index 97c2f401..0dbe4683 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -202,20 +202,6 @@ func checkScriptTemplateParseable(script []byte, opcodes *[256]opcode) (*byte, e return &firstOpcode, nil } -// unparseScript reversed the action of parseScript and returns the -// parsedOpcodes as a list of bytes -func unparseScript(pops []parsedOpcode) ([]byte, error) { - script := make([]byte, 0, len(pops)) - for _, pop := range pops { - b, err := pop.bytes() - if err != nil { - return nil, err - } - script = append(script, b...) - } - return script, nil -} - // DisasmString formats a disassembled script for one line printing. When the // script fails to parse, the returned string will contain the disassembled // script up to the point the failure occurred along with the string '[error]' diff --git a/txscript/script_test.go b/txscript/script_test.go index 7db065de..b6e7ff42 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -28,3657 +28,6 @@ func TestParseOpcode(t *testing.T) { } } -// TestUnparsingInvalidOpcodes tests for errors when unparsing invalid parsed -// opcodes. -func TestUnparsingInvalidOpcodes(t *testing.T) { - tests := []struct { - name string - pop *parsedOpcode - expectedErr error - }{ - { - name: "OP_FALSE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_FALSE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_FALSE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_FALSE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_1 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_1], - data: nil, - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_1], - data: make([]byte, 1), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_1 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_1], - data: make([]byte, 2), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_2 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_2], - data: make([]byte, 2), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_2], - data: make([]byte, 3), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_3 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_3], - data: make([]byte, 2), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_3", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_3], - data: make([]byte, 3), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_3 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_3], - data: make([]byte, 4), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_4 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_4], - data: make([]byte, 3), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_4", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_4], - data: make([]byte, 4), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_4 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_4], - data: make([]byte, 5), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_5 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_5], - data: make([]byte, 4), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_5", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_5], - data: make([]byte, 5), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_5 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_5], - data: make([]byte, 6), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_6 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_6], - data: make([]byte, 5), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_6", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_6], - data: make([]byte, 6), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_6 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_6], - data: make([]byte, 7), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_7 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_7], - data: make([]byte, 6), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_7", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_7], - data: make([]byte, 7), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_7 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_7], - data: make([]byte, 8), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_8 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_8], - data: make([]byte, 7), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_8", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_8], - data: make([]byte, 8), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_8 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_8], - data: make([]byte, 9), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_9 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_9], - data: make([]byte, 8), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_9", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_9], - data: make([]byte, 9), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_9 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_9], - data: make([]byte, 10), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_10 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_10], - data: make([]byte, 9), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_10", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_10], - data: make([]byte, 10), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_10 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_10], - data: make([]byte, 11), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_11 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_11], - data: make([]byte, 10), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_11", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_11], - data: make([]byte, 11), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_11 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_11], - data: make([]byte, 12), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_12 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_12], - data: make([]byte, 11), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_12", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_12], - data: make([]byte, 12), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_12 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_12], - data: make([]byte, 13), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_13 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_13], - data: make([]byte, 12), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_13", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_13], - data: make([]byte, 13), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_13 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_13], - data: make([]byte, 14), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_14 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_14], - data: make([]byte, 13), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_14", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_14], - data: make([]byte, 14), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_14 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_14], - data: make([]byte, 15), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_15 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_15], - data: make([]byte, 14), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_15", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_15], - data: make([]byte, 15), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_15 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_15], - data: make([]byte, 16), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_16 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_16], - data: make([]byte, 15), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_16", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_16], - data: make([]byte, 16), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_16 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_16], - data: make([]byte, 17), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_17 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_17], - data: make([]byte, 16), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_17", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_17], - data: make([]byte, 17), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_17 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_17], - data: make([]byte, 18), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_18 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_18], - data: make([]byte, 17), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_18", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_18], - data: make([]byte, 18), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_18 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_18], - data: make([]byte, 19), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_19 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_19], - data: make([]byte, 18), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_19", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_19], - data: make([]byte, 19), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_19 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_19], - data: make([]byte, 20), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_20 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_20], - data: make([]byte, 19), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_20", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_20], - data: make([]byte, 20), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_20 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_20], - data: make([]byte, 21), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_21 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_21], - data: make([]byte, 20), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_21", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_21], - data: make([]byte, 21), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_21 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_21], - data: make([]byte, 22), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_22 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_22], - data: make([]byte, 21), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_22", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_22], - data: make([]byte, 22), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_22 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_22], - data: make([]byte, 23), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_23 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_23], - data: make([]byte, 22), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_23", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_23], - data: make([]byte, 23), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_23 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_23], - data: make([]byte, 24), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_24 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_24], - data: make([]byte, 23), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_24", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_24], - data: make([]byte, 24), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_24 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_24], - data: make([]byte, 25), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_25 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_25], - data: make([]byte, 24), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_25", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_25], - data: make([]byte, 25), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_25 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_25], - data: make([]byte, 26), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_26 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_26], - data: make([]byte, 25), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_26", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_26], - data: make([]byte, 26), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_26 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_26], - data: make([]byte, 27), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_27 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_27], - data: make([]byte, 26), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_27", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_27], - data: make([]byte, 27), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_27 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_27], - data: make([]byte, 28), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_28 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_28], - data: make([]byte, 27), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_28", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_28], - data: make([]byte, 28), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_28 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_28], - data: make([]byte, 29), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_29 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_29], - data: make([]byte, 28), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_29", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_29], - data: make([]byte, 29), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_29 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_29], - data: make([]byte, 30), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_30 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_30], - data: make([]byte, 29), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_30", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_30], - data: make([]byte, 30), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_30 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_30], - data: make([]byte, 31), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_31 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_31], - data: make([]byte, 30), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_31", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_31], - data: make([]byte, 31), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_31 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_31], - data: make([]byte, 32), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_32 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_32], - data: make([]byte, 31), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_32", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_32], - data: make([]byte, 32), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_32 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_32], - data: make([]byte, 33), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_33 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_33], - data: make([]byte, 32), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_33", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_33], - data: make([]byte, 33), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_33 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_33], - data: make([]byte, 34), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_34 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_34], - data: make([]byte, 33), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_34", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_34], - data: make([]byte, 34), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_34 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_34], - data: make([]byte, 35), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_35 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_35], - data: make([]byte, 34), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_35", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_35], - data: make([]byte, 35), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_35 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_35], - data: make([]byte, 36), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_36 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_36], - data: make([]byte, 35), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_36", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_36], - data: make([]byte, 36), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_36 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_36], - data: make([]byte, 37), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_37 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_37], - data: make([]byte, 36), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_37", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_37], - data: make([]byte, 37), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_37 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_37], - data: make([]byte, 38), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_38 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_38], - data: make([]byte, 37), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_38", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_38], - data: make([]byte, 38), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_38 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_38], - data: make([]byte, 39), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_39 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_39], - data: make([]byte, 38), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_39", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_39], - data: make([]byte, 39), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_39 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_39], - data: make([]byte, 40), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_40 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_40], - data: make([]byte, 39), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_40", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_40], - data: make([]byte, 40), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_40 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_40], - data: make([]byte, 41), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_41 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_41], - data: make([]byte, 40), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_41", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_41], - data: make([]byte, 41), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_41 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_41], - data: make([]byte, 42), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_42 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_42], - data: make([]byte, 41), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_42", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_42], - data: make([]byte, 42), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_42 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_42], - data: make([]byte, 43), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_43 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_43], - data: make([]byte, 42), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_43", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_43], - data: make([]byte, 43), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_43 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_43], - data: make([]byte, 44), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_44 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_44], - data: make([]byte, 43), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_44", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_44], - data: make([]byte, 44), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_44 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_44], - data: make([]byte, 45), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_45 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_45], - data: make([]byte, 44), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_45", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_45], - data: make([]byte, 45), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_45 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_45], - data: make([]byte, 46), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_46 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_46], - data: make([]byte, 45), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_46", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_46], - data: make([]byte, 46), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_46 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_46], - data: make([]byte, 47), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_47 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_47], - data: make([]byte, 46), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_47", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_47], - data: make([]byte, 47), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_47 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_47], - data: make([]byte, 48), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_48 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_48], - data: make([]byte, 47), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_48", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_48], - data: make([]byte, 48), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_48 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_48], - data: make([]byte, 49), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_49 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_49], - data: make([]byte, 48), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_49", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_49], - data: make([]byte, 49), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_49 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_49], - data: make([]byte, 50), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_50 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_50], - data: make([]byte, 49), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_50", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_50], - data: make([]byte, 50), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_50 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_50], - data: make([]byte, 51), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_51 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_51], - data: make([]byte, 50), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_51", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_51], - data: make([]byte, 51), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_51 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_51], - data: make([]byte, 52), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_52 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_52], - data: make([]byte, 51), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_52", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_52], - data: make([]byte, 52), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_52 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_52], - data: make([]byte, 53), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_53 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_53], - data: make([]byte, 52), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_53", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_53], - data: make([]byte, 53), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_53 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_53], - data: make([]byte, 54), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_54 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_54], - data: make([]byte, 53), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_54", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_54], - data: make([]byte, 54), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_54 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_54], - data: make([]byte, 55), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_55 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_55], - data: make([]byte, 54), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_55", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_55], - data: make([]byte, 55), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_55 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_55], - data: make([]byte, 56), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_56 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_56], - data: make([]byte, 55), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_56", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_56], - data: make([]byte, 56), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_56 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_56], - data: make([]byte, 57), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_57 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_57], - data: make([]byte, 56), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_57", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_57], - data: make([]byte, 57), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_57 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_57], - data: make([]byte, 58), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_58 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_58], - data: make([]byte, 57), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_58", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_58], - data: make([]byte, 58), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_58 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_58], - data: make([]byte, 59), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_59 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_59], - data: make([]byte, 58), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_59", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_59], - data: make([]byte, 59), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_59 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_59], - data: make([]byte, 60), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_60 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_60], - data: make([]byte, 59), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_60", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_60], - data: make([]byte, 60), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_60 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_60], - data: make([]byte, 61), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_61 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_61], - data: make([]byte, 60), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_61", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_61], - data: make([]byte, 61), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_61 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_61], - data: make([]byte, 62), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_62 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_62], - data: make([]byte, 61), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_62", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_62], - data: make([]byte, 62), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_62 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_62], - data: make([]byte, 63), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_63 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_63], - data: make([]byte, 62), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_63", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_63], - data: make([]byte, 63), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_63 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_63], - data: make([]byte, 64), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_64 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_64], - data: make([]byte, 63), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_64", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_64], - data: make([]byte, 64), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_64 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_64], - data: make([]byte, 65), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_65 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_65], - data: make([]byte, 64), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_65", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_65], - data: make([]byte, 65), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_65 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_65], - data: make([]byte, 66), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_66 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_66], - data: make([]byte, 65), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_66", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_66], - data: make([]byte, 66), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_66 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_66], - data: make([]byte, 67), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_67 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_67], - data: make([]byte, 66), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_67", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_67], - data: make([]byte, 67), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_67 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_67], - data: make([]byte, 68), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_68 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_68], - data: make([]byte, 67), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_68", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_68], - data: make([]byte, 68), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_68 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_68], - data: make([]byte, 69), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_69 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_69], - data: make([]byte, 68), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_69", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_69], - data: make([]byte, 69), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_69 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_69], - data: make([]byte, 70), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_70 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_70], - data: make([]byte, 69), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_70", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_70], - data: make([]byte, 70), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_70 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_70], - data: make([]byte, 71), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_71 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_71], - data: make([]byte, 70), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_71", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_71], - data: make([]byte, 71), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_71 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_71], - data: make([]byte, 72), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_72 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_72], - data: make([]byte, 71), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_72", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_72], - data: make([]byte, 72), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_72 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_72], - data: make([]byte, 73), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_73 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_73], - data: make([]byte, 72), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_73", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_73], - data: make([]byte, 73), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_73 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_73], - data: make([]byte, 74), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_74 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_74], - data: make([]byte, 73), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_74", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_74], - data: make([]byte, 74), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_74 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_74], - data: make([]byte, 75), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_75 short", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_75], - data: make([]byte, 74), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DATA_75", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_75], - data: make([]byte, 75), - }, - expectedErr: nil, - }, - { - name: "OP_DATA_75 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DATA_75], - data: make([]byte, 76), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_PUSHDATA1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUSHDATA1], - data: []byte{0, 1, 2, 3, 4}, - }, - expectedErr: nil, - }, - { - name: "OP_PUSHDATA2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUSHDATA2], - data: []byte{0, 1, 2, 3, 4}, - }, - expectedErr: nil, - }, - { - name: "OP_PUSHDATA4", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUSHDATA1], - data: []byte{0, 1, 2, 3, 4}, - }, - expectedErr: nil, - }, - { - name: "OP_1NEGATE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1NEGATE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_1NEGATE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1NEGATE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RESERVED", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RESERVED long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_TRUE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TRUE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_TRUE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TRUE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_3", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_3], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_3 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_3], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_4", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_4], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_4 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_4], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_5", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_5], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_5 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_5], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_6", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_6], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_6 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_6], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_7", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_7], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_7 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_7], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_8", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_8], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_8 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_8], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_9", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_9], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_9 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_9], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_10", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_10], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_10 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_10], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_11", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_11], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_11 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_11], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_12", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_12], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_12 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_12], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_13", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_13], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_13 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_13], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_14", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_14], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_14 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_14], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_15", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_15], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_15 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_15], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_16", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_16], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_16 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_16], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_VER", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VER], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_VER long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VER], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_IF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_IF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_IF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_IF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOTIF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOTIF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOTIF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOTIF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_VERIF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERIF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_VERIF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERIF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_VERNOTIF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERNOTIF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_VERNOTIF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERNOTIF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ELSE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ELSE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ELSE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ELSE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ENDIF", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ENDIF], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ENDIF long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ENDIF], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_VERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_VERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_VERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RETURN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RETURN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RETURN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RETURN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_TOALTSTACK", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TOALTSTACK], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_TOALTSTACK long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TOALTSTACK], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_FROMALTSTACK", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_FROMALTSTACK], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_FROMALTSTACK long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_FROMALTSTACK], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2DROP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DROP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2DROP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DROP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2DUP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DUP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2DUP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DUP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_3DUP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_3DUP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_3DUP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_3DUP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2OVER", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2OVER], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2OVER long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2OVER], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2ROT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2ROT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2ROT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2ROT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2SWAP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2SWAP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2SWAP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2SWAP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_IFDUP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_IFDUP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_IFDUP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_IFDUP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DEPTH", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DEPTH], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_DEPTH long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DEPTH], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DROP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DROP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_DROP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DROP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DUP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DUP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_DUP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DUP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NIP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NIP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NIP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NIP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_OVER", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_OVER], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_OVER long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_OVER], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_PICK", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PICK], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_PICK long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PICK], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ROLL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ROLL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ROLL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ROLL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ROT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ROT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ROT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ROT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SWAP", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SWAP], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SWAP long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SWAP], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_TUCK", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TUCK], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_TUCK long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_TUCK], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CAT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CAT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CAT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CAT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SUBSTR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SUBSTR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SUBSTR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SUBSTR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LEFT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LEFT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LEFT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LEFT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LEFT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LEFT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LEFT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LEFT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RIGHT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RIGHT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RIGHT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RIGHT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SIZE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SIZE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SIZE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SIZE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_INVERT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_INVERT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_INVERT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_INVERT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_AND", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_AND], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_AND long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_AND], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_OR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_OR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_OR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_OR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_XOR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_XOR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_XOR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_XOR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_EQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_EQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_EQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_EQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_EQUALVERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_EQUALVERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_EQUALVERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_EQUALVERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RESERVED1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED1], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RESERVED1 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED1], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RESERVED2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED2], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RESERVED2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RESERVED2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_1ADD", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1ADD], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_1ADD long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1ADD], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_1SUB", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1SUB], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_1SUB long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_1SUB], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2MUL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2MUL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2MUL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2MUL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_2DIV", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DIV], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_2DIV long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_2DIV], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NEGATE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NEGATE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NEGATE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NEGATE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ABS", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ABS], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ABS long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ABS], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_0NOTEQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_0NOTEQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_0NOTEQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_0NOTEQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_ADD", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ADD], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_ADD long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_ADD], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SUB", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SUB], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SUB long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SUB], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_MUL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MUL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_MUL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MUL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_DIV", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DIV], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_DIV long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_DIV], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_MOD", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MOD], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_MOD long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MOD], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LSHIFT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LSHIFT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LSHIFT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LSHIFT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RSHIFT", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RSHIFT], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RSHIFT long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RSHIFT], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_BOOLAND", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_BOOLAND], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_BOOLAND long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_BOOLAND], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_BOOLOR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_BOOLOR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_BOOLOR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_BOOLOR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NUMEQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMEQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NUMEQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMEQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NUMEQUALVERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMEQUALVERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NUMEQUALVERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMEQUALVERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NUMNOTEQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMNOTEQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NUMNOTEQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NUMNOTEQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LESSTHAN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LESSTHAN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LESSTHAN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LESSTHAN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_GREATERTHAN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_GREATERTHAN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_GREATERTHAN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_GREATERTHAN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_LESSTHANOREQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LESSTHANOREQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_LESSTHANOREQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_LESSTHANOREQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_GREATERTHANOREQUAL", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_GREATERTHANOREQUAL], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_GREATERTHANOREQUAL long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_GREATERTHANOREQUAL], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_MIN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MIN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_MIN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MIN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_MAX", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MAX], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_MAX long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_MAX], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_WITHIN", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_WITHIN], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_WITHIN long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_WITHIN], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_RIPEMD160", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RIPEMD160], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_RIPEMD160 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_RIPEMD160], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SHA1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SHA1], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SHA1 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SHA1], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_SHA256", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SHA256], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_SHA256 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_SHA256], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_HASH160", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_HASH160], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_HASH160 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_HASH160], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_HASH256", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_HASH256], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_HASH256 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_HASH256], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CODESAPERATOR", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CODESEPARATOR], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CODESEPARATOR long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CODESEPARATOR], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CHECKSIG", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKSIG], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CHECKSIG long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKSIG], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CHECKSIGVERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKSIGVERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CHECKSIGVERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKSIGVERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CHECKMULTISIG", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKMULTISIG], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CHECKMULTISIG long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKMULTISIG], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_CHECKMULTISIGVERIFY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKMULTISIGVERIFY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_CHECKMULTISIGVERIFY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_CHECKMULTISIGVERIFY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP1", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP1], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP1 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP1], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP2", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP2], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP2 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP2], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP3", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP3], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP3 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP3], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP4", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP4], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP4 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP4], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP5", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP5], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP5 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP5], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP6", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP6], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP6 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP6], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP7", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP7], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP7 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP7], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP8", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP8], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP8 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP8], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP9", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP9], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP9 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP9], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_NOP10", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP10], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_NOP10 long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_NOP10], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_PUBKEYHASH", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUBKEYHASH], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_PUBKEYHASH long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUBKEYHASH], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_PUBKEY", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUBKEY], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_PUBKEY long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_PUBKEY], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - { - name: "OP_INVALIDOPCODE", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_INVALIDOPCODE], - data: nil, - }, - expectedErr: nil, - }, - { - name: "OP_INVALIDOPCODE long", - pop: &parsedOpcode{ - opcode: &opcodeArray[OP_INVALIDOPCODE], - data: make([]byte, 1), - }, - expectedErr: scriptError(ErrInternal, ""), - }, - } - - for _, test := range tests { - _, err := test.pop.bytes() - if e := tstCheckScriptError(err, test.expectedErr); e != nil { - t.Errorf("Parsed opcode test '%s': %v", test.name, e) - continue - } - } -} - // TestPushedData ensured the PushedData function extracts the expected data out // of various scripts. func TestPushedData(t *testing.T) { -- 2.45.2 From 4bbfd2413c99ed6bcaecc68e18326e0489faebf9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:05 -0500 Subject: [PATCH 315/459] txscript: Remove unused parsedOpcode.bytes func. --- txscript/opcode.go | 57 ---------------------------------------------- 1 file changed, 57 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 9e0320ae..515e1cf2 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -8,7 +8,6 @@ import ( "bytes" "crypto/sha1" "crypto/sha256" - "encoding/binary" "encoding/hex" "fmt" "hash" @@ -740,62 +739,6 @@ func disasmOpcode(buf *strings.Builder, op *opcode, data []byte, compact bool) { buf.WriteString(fmt.Sprintf(" 0x%02x", data)) } -// bytes returns any data associated with the opcode encoded as it would be in -// a script. This is used for unparsing scripts from parsed opcodes. -func (pop *parsedOpcode) bytes() ([]byte, error) { - var retbytes []byte - if pop.opcode.length > 0 { - retbytes = make([]byte, 1, pop.opcode.length) - } else { - retbytes = make([]byte, 1, 1+len(pop.data)- - pop.opcode.length) - } - - retbytes[0] = pop.opcode.value - if pop.opcode.length == 1 { - if len(pop.data) != 0 { - str := fmt.Sprintf("internal consistency error - "+ - "parsed opcode %s has data length %d when %d "+ - "was expected", pop.opcode.name, len(pop.data), - 0) - return nil, scriptError(ErrInternal, str) - } - return retbytes, nil - } - nbytes := pop.opcode.length - if pop.opcode.length < 0 { - l := len(pop.data) - // tempting just to hardcode to avoid the complexity here. - switch pop.opcode.length { - case -1: - retbytes = append(retbytes, byte(l)) - nbytes = int(retbytes[1]) + len(retbytes) - case -2: - retbytes = append(retbytes, byte(l&0xff), - byte(l>>8&0xff)) - nbytes = int(binary.LittleEndian.Uint16(retbytes[1:])) + - len(retbytes) - case -4: - retbytes = append(retbytes, byte(l&0xff), - byte((l>>8)&0xff), byte((l>>16)&0xff), - byte((l>>24)&0xff)) - nbytes = int(binary.LittleEndian.Uint32(retbytes[1:])) + - len(retbytes) - } - } - - retbytes = append(retbytes, pop.data...) - - if len(retbytes) != nbytes { - str := fmt.Sprintf("internal consistency error - "+ - "parsed opcode %s has data length %d when %d was "+ - "expected", pop.opcode.name, len(retbytes), nbytes) - return nil, scriptError(ErrInternal, str) - } - - return retbytes, nil -} - // ******************************************* // Opcode implementation functions start here. // ******************************************* -- 2.45.2 From 6f3f4c1b8c45d215bbd8d0bd934d0d1d83290a75 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:06 -0500 Subject: [PATCH 316/459] txscript: Remove unused parseScriptTemplate func. Also remove tests associated with the func accordingly. --- txscript/opcode.go | 73 ----------------------------------------- txscript/script.go | 59 --------------------------------- txscript/script_test.go | 16 --------- 3 files changed, 148 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 515e1cf2..d6fc494c 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -618,79 +618,6 @@ type parsedOpcode struct { data []byte } -// checkParseableInScript checks whether or not the current opcode is able to be -// parsed at a certain position in a script. -// This returns the position of the next opcode to be parsed in the script. -func (pop *parsedOpcode) checkParseableInScript(script []byte, scriptPos int) (int, error) { - // Parse data out of instruction. - switch { - // No additional data. Note that some of the opcodes, notably - // OP_1NEGATE, OP_0, and OP_[1-16] represent the data - // themselves. - case pop.opcode.length == 1: - scriptPos++ - - // Data pushes of specific lengths -- OP_DATA_[1-75]. - case pop.opcode.length > 1: - if len(script[scriptPos:]) < pop.opcode.length { - str := fmt.Sprintf("opcode %s requires %d "+ - "bytes, but script only has %d remaining", - pop.opcode.name, pop.opcode.length, len(script[scriptPos:])) - return 0, scriptError(ErrMalformedPush, str) - } - - // Slice out the data. - pop.data = script[scriptPos+1 : scriptPos+pop.opcode.length] - scriptPos += pop.opcode.length - - // Data pushes with parsed lengths -- OP_PUSHDATAP{1,2,4}. - case pop.opcode.length < 0: - var l uint - off := scriptPos + 1 - - if len(script[off:]) < -pop.opcode.length { - str := fmt.Sprintf("opcode %s requires %d "+ - "bytes, but script only has %d remaining", - pop.opcode.name, -pop.opcode.length, len(script[off:])) - return 0, scriptError(ErrMalformedPush, str) - } - - // Next -length bytes are little endian length of data. - switch pop.opcode.length { - case -1: - l = uint(script[off]) - case -2: - l = ((uint(script[off+1]) << 8) | - uint(script[off])) - case -4: - l = ((uint(script[off+3]) << 24) | - (uint(script[off+2]) << 16) | - (uint(script[off+1]) << 8) | - uint(script[off])) - default: - str := fmt.Sprintf("invalid opcode length %d", - pop.opcode.length) - return 0, scriptError(ErrMalformedPush, str) - } - - // Move offset to beginning of the data. - off += -pop.opcode.length - - // Disallow entries that do not fit script or were - // sign extended. - if int(l) > len(script[off:]) || int(l) < 0 { - str := fmt.Sprintf("opcode %s pushes %d bytes, "+ - "but script only has %d remaining", - pop.opcode.name, int(l), len(script[off:])) - return 0, scriptError(ErrMalformedPush, str) - } - - pop.data = script[off : off+int(l)] - scriptPos += 1 - pop.opcode.length + int(l) - } - return scriptPos, nil -} - // disasmOpcode writes a human-readable disassembly of the provided opcode and // data into the provided buffer. The compact flag indicates the disassembly // should print a more compact representation of data-carrying and small integer diff --git a/txscript/script.go b/txscript/script.go index 0dbe4683..696bfe2d 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -143,65 +143,6 @@ func IsPushOnlyScript(script []byte) bool { return tokenizer.Err() == nil } -// parseScriptTemplate is the same as parseScript but allows the passing of the -// template list for testing purposes. When there are parse errors, it returns -// the list of parsed opcodes up to the point of failure along with the error. -func parseScriptTemplate(script []byte, opcodes *[256]opcode) ([]parsedOpcode, error) { - retScript := make([]parsedOpcode, 0, len(script)) - var err error - for i := 0; i < len(script); { - instr := script[i] - op := &opcodes[instr] - pop := parsedOpcode{opcode: op} - i, err = pop.checkParseableInScript(script, i) - if err != nil { - return retScript, err - } - - retScript = append(retScript, pop) - } - - return retScript, nil -} - -// checkScriptTemplateParseable is the same as parseScriptTemplate but does not -// return the list of opcodes up until the point of failure so that this can be -// used in functions which do not necessarily have a need for the failed list of -// opcodes, such as IsUnspendable. -// -// This function returns a pointer to a byte. This byte is nil if the parsing -// has an error, or if the script length is zero. If the script length is not -// zero and parsing succeeds, then the first opcode parsed will be returned. -// -// Not returning the full opcode list up until failure also has the benefit of -// reducing GC pressure, as the list would get immediately thrown away. -func checkScriptTemplateParseable(script []byte, opcodes *[256]opcode) (*byte, error) { - var err error - - // A script of length zero is an unspendable script but it is parseable. - var firstOpcode byte - var numParsedInstr uint = 0 - - for i := 0; i < len(script); { - instr := script[i] - op := &opcodes[instr] - pop := parsedOpcode{opcode: op} - i, err = pop.checkParseableInScript(script, i) - if err != nil { - return nil, err - } - - // if this is a op_return then it is unspendable so we set the first - // parsed instruction in case it's an op_return - if numParsedInstr == 0 { - firstOpcode = pop.opcode.value - } - numParsedInstr++ - } - - return &firstOpcode, nil -} - // DisasmString formats a disassembled script for one line printing. When the // script fails to parse, the returned string will contain the disassembled // script up to the point the failure occurred along with the string '[error]' diff --git a/txscript/script_test.go b/txscript/script_test.go index b6e7ff42..86f94d84 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -12,22 +12,6 @@ import ( "github.com/btcsuite/btcd/wire" ) -// TestParseOpcode tests for opcode parsing with bad data templates. -func TestParseOpcode(t *testing.T) { - // Deep copy the array and make one of the opcodes invalid by setting it - // to the wrong length. - fakeArray := opcodeArray - fakeArray[OP_PUSHDATA4] = opcode{value: OP_PUSHDATA4, - name: "OP_PUSHDATA4", length: -8, opfunc: opcodePushData} - - // This script would be fine if -8 was a valid length. - _, err := parseScriptTemplate([]byte{OP_PUSHDATA4, 0x1, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}, &fakeArray) - if err == nil { - t.Errorf("no error with dodgy opcode array!") - } -} - // TestPushedData ensured the PushedData function extracts the expected data out // of various scripts. func TestPushedData(t *testing.T) { -- 2.45.2 From 7358671e83beafb60e5c10d3072d8acedd633d7a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:07 -0500 Subject: [PATCH 317/459] txscript: Make executeOpcode take opcode and data. This converts the executeOpcode function defined on the engine to accept an opcode and data slice instead of a parsed opcode as a step towards removing the parsed opcode struct and associated supporting code altogether. It also updates all callers accordingly. --- txscript/engine.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index 1afb8324..a91dc961 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -341,23 +341,21 @@ func checkMinimalDataPush(op *opcode, data []byte) error { // executeOpcode peforms execution on the passed opcode. It takes into account // whether or not it is hidden by conditionals, but some rules still must be // tested in this case. -func (vm *Engine) executeOpcode(pop *parsedOpcode) error { +func (vm *Engine) executeOpcode(op *opcode, data []byte) error { // Disabled opcodes are fail on program counter. - if isOpcodeDisabled(pop.opcode.value) { - str := fmt.Sprintf("attempt to execute disabled opcode %s", - pop.opcode.name) + if isOpcodeDisabled(op.value) { + str := fmt.Sprintf("attempt to execute disabled opcode %s", op.name) return scriptError(ErrDisabledOpcode, str) } // Always-illegal opcodes are fail on program counter. - if isOpcodeAlwaysIllegal(pop.opcode.value) { - str := fmt.Sprintf("attempt to execute reserved opcode %s", - pop.opcode.name) + if isOpcodeAlwaysIllegal(op.value) { + str := fmt.Sprintf("attempt to execute reserved opcode %s", op.name) return scriptError(ErrReservedOpcode, str) } // Note that this includes OP_RESERVED which counts as a push operation. - if pop.opcode.value > OP_16 { + if op.value > OP_16 { vm.numOps++ if vm.numOps > MaxOpsPerScript { str := fmt.Sprintf("exceeded max operation limit of %d", @@ -365,29 +363,30 @@ func (vm *Engine) executeOpcode(pop *parsedOpcode) error { return scriptError(ErrTooManyOperations, str) } - } else if len(pop.data) > MaxScriptElementSize { + } else if len(data) > MaxScriptElementSize { str := fmt.Sprintf("element size %d exceeds max allowed size %d", - len(pop.data), MaxScriptElementSize) + len(data), MaxScriptElementSize) return scriptError(ErrElementTooBig, str) } // Nothing left to do when this is not a conditional opcode and it is // not in an executing branch. - if !vm.isBranchExecuting() && !isOpcodeConditional(pop.opcode.value) { + if !vm.isBranchExecuting() && !isOpcodeConditional(op.value) { return nil } // Ensure all executed data push opcodes use the minimal encoding when // the minimal data verification flag is set. if vm.dstack.verifyMinimalData && vm.isBranchExecuting() && - pop.opcode.value >= 0 && pop.opcode.value <= OP_PUSHDATA4 { + op.value >= 0 && op.value <= OP_PUSHDATA4 { - if err := checkMinimalDataPush(pop.opcode, pop.data); err != nil { + if err := checkMinimalDataPush(op, data); err != nil { return err } } - return pop.opcode.opfunc(pop, vm) + pop := parsedOpcode{opcode: op, data: data} + return op.opfunc(&pop, vm) } // checkValidPC returns an error if the current script position is not valid for @@ -670,8 +669,7 @@ func (vm *Engine) Step() (done bool, err error) { // Execute the opcode while taking into account several things such as // disabled opcodes, illegal opcodes, maximum allowed operations per script, // maximum script element sizes, and conditionals. - pop := parsedOpcode{opcode: vm.tokenizer.op, data: vm.tokenizer.Data()} - err = vm.executeOpcode(&pop) + err = vm.executeOpcode(vm.tokenizer.op, vm.tokenizer.Data()) if err != nil { return true, err } -- 2.45.2 From 42310f69484b5fed0694d3c78965eff52b7febca Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:13:08 -0500 Subject: [PATCH 318/459] txscript: Make op callbacks take opcode and data. This converts the callback function defined on the internal opcode struct to accept the opcode and data slice instead of a parsed opcode as the final step towards removing the parsed opcode struct and associated supporting code altogether. It also updates all of the callbacks and tests accordingly and finally removes the now unused parsedOpcode struct. The final results for the raw script analysis and tokenizer optimizations are as follows: benchmark old ns/op new ns/op delta BenchmarkIsPayToScriptHash-8 62393 0.51 -100.00% BenchmarkIsPubKeyHashScript-8 62228 0.56 -100.00% BenchmarkGetSigOpCount-8 61051 658 -98.92% BenchmarkExtractPkScriptAddrsLarge-8 60713 17.2 -99.97% BenchmarkExtractPkScriptAddrs-8 289 17.9 -93.81% BenchmarkIsWitnessPubKeyHash-8 61688 0.42 -100.00% BenchmarkIsUnspendable-8 656 520 -20.73% BenchmarkExtractAtomicSwapDataPushesLarge-8 61332 44.0 -99.93% BenchmarkExtractAtomicSwapDataPushes-8 990 260 -73.74% BenchmarkDisasmString-8 102902 39754 -61.37% BenchmarkGetPreciseSigOpCount-8 130223 715 -99.45% BenchmarkScriptParsing-8 63464 681 -98.93% BenchmarkIsMultisigScriptLarge-8 64166 5.83 -99.99% BenchmarkIsMultisigScript-8 630 58.5 -90.71% BenchmarkPushedData-8 64837 1779 -97.26% BenchmarkCalcSigHash-8 3627895 3605459 -0.62% BenchmarkIsPubKeyScript-8 62323 2.83 -100.00% BenchmarkIsPushOnlyScript-8 62412 569 -99.09% BenchmarkIsWitnessScriptHash-8 61243 0.56 -100.00% BenchmarkGetScriptClass-8 61515 16.4 -99.97% BenchmarkIsNullDataScript-8 62495 2.53 -100.00% BenchmarkIsMultisigSigScriptLarge-8 69328 2.52 -100.00% BenchmarkIsMultisigSigScript-8 2375 141 -94.06% BenchmarkGetWitnessSigOpCountP2WKH-8 504 72.0 -85.71% BenchmarkGetWitnessSigOpCountNested-8 1158 136 -88.26% BenchmarkIsWitnessPubKeyHash-8 68927 0.53 -100.00% BenchmarkIsWitnessScriptHash-8 62774 0.63 -100.00% benchmark old allocs new allocs delta BenchmarkIsPayToScriptHash-8 1 0 -100.00% BenchmarkIsPubKeyHashScript-8 1 0 -100.00% BenchmarkGetSigOpCount-8 1 0 -100.00% BenchmarkExtractPkScriptAddrsLarge-8 1 0 -100.00% BenchmarkExtractPkScriptAddrs-8 1 0 -100.00% BenchmarkIsWitnessPubKeyHash-8 1 0 -100.00% BenchmarkIsUnspendable-8 1 0 -100.00% BenchmarkExtractAtomicSwapDataPushesLarge-8 1 0 -100.00% BenchmarkExtractAtomicSwapDataPushes-8 2 1 -50.00% BenchmarkDisasmString-8 46 51 +10.87% BenchmarkGetPreciseSigOpCount-8 3 0 -100.00% BenchmarkScriptParsing-8 1 0 -100.00% BenchmarkIsMultisigScriptLarge-8 1 0 -100.00% BenchmarkIsMultisigScript-8 1 0 -100.00% BenchmarkPushedData-8 7 6 -14.29% BenchmarkCalcSigHash-8 1335 712 -46.67% BenchmarkIsPubKeyScript-8 1 0 -100.00% BenchmarkIsPushOnlyScript-8 1 0 -100.00% BenchmarkIsWitnessScriptHash-8 1 0 -100.00% BenchmarkGetScriptClass-8 1 0 -100.00% BenchmarkIsNullDataScript-8 1 0 -100.00% BenchmarkIsMultisigSigScriptLarge-8 5 0 -100.00% BenchmarkIsMultisigSigScript-8 3 0 -100.00% BenchmarkGetWitnessSigOpCountP2WKH-8 2 0 -100.00% BenchmarkGetWitnessSigOpCountNested-8 4 0 -100.00% BenchmarkIsWitnessPubKeyHash-8 1 0 -100.00% BenchmarkIsWitnessScriptHash-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPayToScriptHash-8 311299 0 -100.00% BenchmarkIsPubKeyHashScript-8 311299 0 -100.00% BenchmarkGetSigOpCount-8 311299 0 -100.00% BenchmarkExtractPkScriptAddrsLarge-8 311299 0 -100.00% BenchmarkExtractPkScriptAddrs-8 768 0 -100.00% BenchmarkIsWitnessPubKeyHash-8 311299 0 -100.00% BenchmarkIsUnspendable-8 1 0 -100.00% BenchmarkExtractAtomicSwapDataPushesLarge-8 311299 0 -100.00% BenchmarkExtractAtomicSwapDataPushes-8 3168 96 -96.97% BenchmarkDisasmString-8 389324 130552 -66.47% BenchmarkGetPreciseSigOpCount-8 623367 0 -100.00% BenchmarkScriptParsing-8 311299 0 -100.00% BenchmarkIsMultisigScriptLarge-8 311299 0 -100.00% BenchmarkIsMultisigScript-8 2304 0 -100.00% BenchmarkPushedData-8 312816 1520 -99.51% BenchmarkCalcSigHash-8 1373812 1290507 -6.06% BenchmarkIsPubKeyScript-8 311299 0 -100.00% BenchmarkIsPushOnlyScript-8 311299 0 -100.00% BenchmarkIsWitnessScriptHash-8 311299 0 -100.00% BenchmarkGetScriptClass-8 311299 0 -100.00% BenchmarkIsNullDataScript-8 311299 0 -100.00% BenchmarkIsMultisigSigScriptLarge-8 330035 0 -100.00% BenchmarkIsMultisigSigScript-8 9472 0 -100.00% BenchmarkGetWitnessSigOpCountP2WKH-8 1408 0 -100.00% BenchmarkGetWitnessSigOpCountNested-8 3200 0 -100.00% BenchmarkIsWitnessPubKeyHash-8 311299 0 -100.00% BenchmarkIsWitnessScriptHash-8 311299 0 -100.00% --- txscript/engine.go | 3 +- txscript/opcode.go | 183 +++++++++++++++++++--------------------- txscript/opcode_test.go | 4 +- 3 files changed, 90 insertions(+), 100 deletions(-) diff --git a/txscript/engine.go b/txscript/engine.go index a91dc961..0814e7eb 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -385,8 +385,7 @@ func (vm *Engine) executeOpcode(op *opcode, data []byte) error { } } - pop := parsedOpcode{opcode: op, data: data} - return op.opfunc(&pop, vm) + return op.opfunc(op, data, vm) } // checkValidPC returns an error if the current script position is not valid for diff --git a/txscript/opcode.go b/txscript/opcode.go index d6fc494c..4c31be3f 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -28,7 +28,7 @@ type opcode struct { value byte name string length int - opfunc func(*parsedOpcode, *Engine) error + opfunc func(*opcode, []byte, *Engine) error } // These constants are the values of the official opcodes used on the btc wiki, @@ -611,13 +611,6 @@ var opcodeOnelineRepls = map[string]string{ "OP_16": "16", } -// parsedOpcode represents an opcode that has been parsed and includes any -// potential data associated with it. -type parsedOpcode struct { - opcode *opcode - data []byte -} - // disasmOpcode writes a human-readable disassembly of the provided opcode and // data into the provided buffer. The compact flag indicates the disassembly // should print a more compact representation of data-carrying and small integer @@ -676,45 +669,42 @@ func disasmOpcode(buf *strings.Builder, op *opcode, data []byte, compact bool) { // opcodes before executing in an initial parse step, the consensus rules // dictate the script doesn't fail until the program counter passes over a // disabled opcode (even when they appear in a branch that is not executed). -func opcodeDisabled(op *parsedOpcode, vm *Engine) error { - str := fmt.Sprintf("attempt to execute disabled opcode %s", - op.opcode.name) +func opcodeDisabled(op *opcode, data []byte, vm *Engine) error { + str := fmt.Sprintf("attempt to execute disabled opcode %s", op.name) return scriptError(ErrDisabledOpcode, str) } // opcodeReserved is a common handler for all reserved opcodes. It returns an // appropriate error indicating the opcode is reserved. -func opcodeReserved(op *parsedOpcode, vm *Engine) error { - str := fmt.Sprintf("attempt to execute reserved opcode %s", - op.opcode.name) +func opcodeReserved(op *opcode, data []byte, vm *Engine) error { + str := fmt.Sprintf("attempt to execute reserved opcode %s", op.name) return scriptError(ErrReservedOpcode, str) } // opcodeInvalid is a common handler for all invalid opcodes. It returns an // appropriate error indicating the opcode is invalid. -func opcodeInvalid(op *parsedOpcode, vm *Engine) error { - str := fmt.Sprintf("attempt to execute invalid opcode %s", - op.opcode.name) +func opcodeInvalid(op *opcode, data []byte, vm *Engine) error { + str := fmt.Sprintf("attempt to execute invalid opcode %s", op.name) return scriptError(ErrReservedOpcode, str) } // opcodeFalse pushes an empty array to the data stack to represent false. Note // that 0, when encoded as a number according to the numeric encoding consensus // rules, is an empty array. -func opcodeFalse(op *parsedOpcode, vm *Engine) error { +func opcodeFalse(op *opcode, data []byte, vm *Engine) error { vm.dstack.PushByteArray(nil) return nil } // opcodePushData is a common handler for the vast majority of opcodes that push // raw data (bytes) to the data stack. -func opcodePushData(op *parsedOpcode, vm *Engine) error { - vm.dstack.PushByteArray(op.data) +func opcodePushData(op *opcode, data []byte, vm *Engine) error { + vm.dstack.PushByteArray(data) return nil } // opcode1Negate pushes -1, encoded as a number, to the data stack. -func opcode1Negate(op *parsedOpcode, vm *Engine) error { +func opcode1Negate(op *opcode, data []byte, vm *Engine) error { vm.dstack.PushInt(scriptNum(-1)) return nil } @@ -722,23 +712,24 @@ func opcode1Negate(op *parsedOpcode, vm *Engine) error { // opcodeN is a common handler for the small integer data push opcodes. It // pushes the numeric value the opcode represents (which will be from 1 to 16) // onto the data stack. -func opcodeN(op *parsedOpcode, vm *Engine) error { +func opcodeN(op *opcode, data []byte, vm *Engine) error { // The opcodes are all defined consecutively, so the numeric value is // the difference. - vm.dstack.PushInt(scriptNum((op.opcode.value - (OP_1 - 1)))) + vm.dstack.PushInt(scriptNum((op.value - (OP_1 - 1)))) return nil } // opcodeNop is a common handler for the NOP family of opcodes. As the name // implies it generally does nothing, however, it will return an error when // the flag to discourage use of NOPs is set for select opcodes. -func opcodeNop(op *parsedOpcode, vm *Engine) error { - switch op.opcode.value { +func opcodeNop(op *opcode, data []byte, vm *Engine) error { + switch op.value { case OP_NOP1, OP_NOP4, OP_NOP5, OP_NOP6, OP_NOP7, OP_NOP8, OP_NOP9, OP_NOP10: + if vm.hasFlag(ScriptDiscourageUpgradableNops) { - str := fmt.Sprintf("OP_NOP%d reserved for soft-fork "+ - "upgrades", op.opcode.value-(OP_NOP1-1)) + str := fmt.Sprintf("%v reserved for soft-fork "+ + "upgrades", op.name) return scriptError(ErrDiscourageUpgradableNOPs, str) } } @@ -801,7 +792,7 @@ func popIfBool(vm *Engine) (bool, error) { // // Data stack transformation: [... bool] -> [...] // Conditional stack transformation: [...] -> [... OpCondValue] -func opcodeIf(op *parsedOpcode, vm *Engine) error { +func opcodeIf(op *opcode, data []byte, vm *Engine) error { condVal := OpCondFalse if vm.isBranchExecuting() { ok, err := popIfBool(vm) @@ -835,7 +826,7 @@ func opcodeIf(op *parsedOpcode, vm *Engine) error { // // Data stack transformation: [... bool] -> [...] // Conditional stack transformation: [...] -> [... OpCondValue] -func opcodeNotIf(op *parsedOpcode, vm *Engine) error { +func opcodeNotIf(op *opcode, data []byte, vm *Engine) error { condVal := OpCondFalse if vm.isBranchExecuting() { ok, err := popIfBool(vm) @@ -858,10 +849,10 @@ func opcodeNotIf(op *parsedOpcode, vm *Engine) error { // An error is returned if there has not already been a matching OP_IF. // // Conditional stack transformation: [... OpCondValue] -> [... !OpCondValue] -func opcodeElse(op *parsedOpcode, vm *Engine) error { +func opcodeElse(op *opcode, data []byte, vm *Engine) error { if len(vm.condStack) == 0 { str := fmt.Sprintf("encountered opcode %s with no matching "+ - "opcode to begin conditional execution", op.opcode.name) + "opcode to begin conditional execution", op.name) return scriptError(ErrUnbalancedConditional, str) } @@ -884,10 +875,10 @@ func opcodeElse(op *parsedOpcode, vm *Engine) error { // An error is returned if there has not already been a matching OP_IF. // // Conditional stack transformation: [... OpCondValue] -> [...] -func opcodeEndif(op *parsedOpcode, vm *Engine) error { +func opcodeEndif(op *opcode, data []byte, vm *Engine) error { if len(vm.condStack) == 0 { str := fmt.Sprintf("encountered opcode %s with no matching "+ - "opcode to begin conditional execution", op.opcode.name) + "opcode to begin conditional execution", op.name) return scriptError(ErrUnbalancedConditional, str) } @@ -900,14 +891,14 @@ func opcodeEndif(op *parsedOpcode, vm *Engine) error { // item on the stack or when that item evaluates to false. In the latter case // where the verification fails specifically due to the top item evaluating // to false, the returned error will use the passed error code. -func abstractVerify(op *parsedOpcode, vm *Engine, c ErrorCode) error { +func abstractVerify(op *opcode, vm *Engine, c ErrorCode) error { verified, err := vm.dstack.PopBool() if err != nil { return err } if !verified { - str := fmt.Sprintf("%s failed", op.opcode.name) + str := fmt.Sprintf("%s failed", op.name) return scriptError(c, str) } return nil @@ -915,13 +906,13 @@ func abstractVerify(op *parsedOpcode, vm *Engine, c ErrorCode) error { // opcodeVerify examines the top item on the data stack as a boolean value and // verifies it evaluates to true. An error is returned if it does not. -func opcodeVerify(op *parsedOpcode, vm *Engine) error { +func opcodeVerify(op *opcode, data []byte, vm *Engine) error { return abstractVerify(op, vm, ErrVerify) } // opcodeReturn returns an appropriate error since it is always an error to // return early from a script. -func opcodeReturn(op *parsedOpcode, vm *Engine) error { +func opcodeReturn(op *opcode, data []byte, vm *Engine) error { return scriptError(ErrEarlyReturn, "script returned early") } @@ -951,7 +942,7 @@ func verifyLockTime(txLockTime, threshold, lockTime int64) error { // validating if the transaction outputs are spendable yet. If flag // ScriptVerifyCheckLockTimeVerify is not set, the code continues as if OP_NOP2 // were executed. -func opcodeCheckLockTimeVerify(op *parsedOpcode, vm *Engine) error { +func opcodeCheckLockTimeVerify(op *opcode, data []byte, vm *Engine) error { // If the ScriptVerifyCheckLockTimeVerify script flag is not set, treat // opcode as OP_NOP2 instead. if !vm.hasFlag(ScriptVerifyCheckLockTimeVerify) { @@ -1025,7 +1016,7 @@ func opcodeCheckLockTimeVerify(op *parsedOpcode, vm *Engine) error { // validating if the transaction outputs are spendable yet. If flag // ScriptVerifyCheckSequenceVerify is not set, the code continues as if OP_NOP3 // were executed. -func opcodeCheckSequenceVerify(op *parsedOpcode, vm *Engine) error { +func opcodeCheckSequenceVerify(op *opcode, data []byte, vm *Engine) error { // If the ScriptVerifyCheckSequenceVerify script flag is not set, treat // opcode as OP_NOP3 instead. if !vm.hasFlag(ScriptVerifyCheckSequenceVerify) { @@ -1102,7 +1093,7 @@ func opcodeCheckSequenceVerify(op *parsedOpcode, vm *Engine) error { // // Main data stack transformation: [... x1 x2 x3] -> [... x1 x2] // Alt data stack transformation: [... y1 y2 y3] -> [... y1 y2 y3 x3] -func opcodeToAltStack(op *parsedOpcode, vm *Engine) error { +func opcodeToAltStack(op *opcode, data []byte, vm *Engine) error { so, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1117,7 +1108,7 @@ func opcodeToAltStack(op *parsedOpcode, vm *Engine) error { // // Main data stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 y3] // Alt data stack transformation: [... y1 y2 y3] -> [... y1 y2] -func opcodeFromAltStack(op *parsedOpcode, vm *Engine) error { +func opcodeFromAltStack(op *opcode, data []byte, vm *Engine) error { so, err := vm.astack.PopByteArray() if err != nil { return err @@ -1130,35 +1121,35 @@ func opcodeFromAltStack(op *parsedOpcode, vm *Engine) error { // opcode2Drop removes the top 2 items from the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1] -func opcode2Drop(op *parsedOpcode, vm *Engine) error { +func opcode2Drop(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DropN(2) } // opcode2Dup duplicates the top 2 items on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 x2 x3] -func opcode2Dup(op *parsedOpcode, vm *Engine) error { +func opcode2Dup(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DupN(2) } // opcode3Dup duplicates the top 3 items on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 x1 x2 x3] -func opcode3Dup(op *parsedOpcode, vm *Engine) error { +func opcode3Dup(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DupN(3) } // opcode2Over duplicates the 2 items before the top 2 items on the data stack. // // Stack transformation: [... x1 x2 x3 x4] -> [... x1 x2 x3 x4 x1 x2] -func opcode2Over(op *parsedOpcode, vm *Engine) error { +func opcode2Over(op *opcode, data []byte, vm *Engine) error { return vm.dstack.OverN(2) } // opcode2Rot rotates the top 6 items on the data stack to the left twice. // // Stack transformation: [... x1 x2 x3 x4 x5 x6] -> [... x3 x4 x5 x6 x1 x2] -func opcode2Rot(op *parsedOpcode, vm *Engine) error { +func opcode2Rot(op *opcode, data []byte, vm *Engine) error { return vm.dstack.RotN(2) } @@ -1166,7 +1157,7 @@ func opcode2Rot(op *parsedOpcode, vm *Engine) error { // before them. // // Stack transformation: [... x1 x2 x3 x4] -> [... x3 x4 x1 x2] -func opcode2Swap(op *parsedOpcode, vm *Engine) error { +func opcode2Swap(op *opcode, data []byte, vm *Engine) error { return vm.dstack.SwapN(2) } @@ -1174,7 +1165,7 @@ func opcode2Swap(op *parsedOpcode, vm *Engine) error { // // Stack transformation (x1==0): [... x1] -> [... x1] // Stack transformation (x1!=0): [... x1] -> [... x1 x1] -func opcodeIfDup(op *parsedOpcode, vm *Engine) error { +func opcodeIfDup(op *opcode, data []byte, vm *Engine) error { so, err := vm.dstack.PeekByteArray(0) if err != nil { return err @@ -1194,7 +1185,7 @@ func opcodeIfDup(op *parsedOpcode, vm *Engine) error { // Stack transformation: [...] -> [... ] // Example with 2 items: [x1 x2] -> [x1 x2 2] // Example with 3 items: [x1 x2 x3] -> [x1 x2 x3 3] -func opcodeDepth(op *parsedOpcode, vm *Engine) error { +func opcodeDepth(op *opcode, data []byte, vm *Engine) error { vm.dstack.PushInt(scriptNum(vm.dstack.Depth())) return nil } @@ -1202,28 +1193,28 @@ func opcodeDepth(op *parsedOpcode, vm *Engine) error { // opcodeDrop removes the top item from the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2] -func opcodeDrop(op *parsedOpcode, vm *Engine) error { +func opcodeDrop(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DropN(1) } // opcodeDup duplicates the top item on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 x3] -func opcodeDup(op *parsedOpcode, vm *Engine) error { +func opcodeDup(op *opcode, data []byte, vm *Engine) error { return vm.dstack.DupN(1) } // opcodeNip removes the item before the top item on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x3] -func opcodeNip(op *parsedOpcode, vm *Engine) error { +func opcodeNip(op *opcode, data []byte, vm *Engine) error { return vm.dstack.NipN(1) } // opcodeOver duplicates the item before the top item on the data stack. // // Stack transformation: [... x1 x2 x3] -> [... x1 x2 x3 x2] -func opcodeOver(op *parsedOpcode, vm *Engine) error { +func opcodeOver(op *opcode, data []byte, vm *Engine) error { return vm.dstack.OverN(1) } @@ -1233,7 +1224,7 @@ func opcodeOver(op *parsedOpcode, vm *Engine) error { // Stack transformation: [xn ... x2 x1 x0 n] -> [xn ... x2 x1 x0 xn] // Example with n=1: [x2 x1 x0 1] -> [x2 x1 x0 x1] // Example with n=2: [x2 x1 x0 2] -> [x2 x1 x0 x2] -func opcodePick(op *parsedOpcode, vm *Engine) error { +func opcodePick(op *opcode, data []byte, vm *Engine) error { val, err := vm.dstack.PopInt() if err != nil { return err @@ -1248,7 +1239,7 @@ func opcodePick(op *parsedOpcode, vm *Engine) error { // Stack transformation: [xn ... x2 x1 x0 n] -> [... x2 x1 x0 xn] // Example with n=1: [x2 x1 x0 1] -> [x2 x0 x1] // Example with n=2: [x2 x1 x0 2] -> [x1 x0 x2] -func opcodeRoll(op *parsedOpcode, vm *Engine) error { +func opcodeRoll(op *opcode, data []byte, vm *Engine) error { val, err := vm.dstack.PopInt() if err != nil { return err @@ -1260,14 +1251,14 @@ func opcodeRoll(op *parsedOpcode, vm *Engine) error { // opcodeRot rotates the top 3 items on the data stack to the left. // // Stack transformation: [... x1 x2 x3] -> [... x2 x3 x1] -func opcodeRot(op *parsedOpcode, vm *Engine) error { +func opcodeRot(op *opcode, data []byte, vm *Engine) error { return vm.dstack.RotN(1) } // opcodeSwap swaps the top two items on the stack. // // Stack transformation: [... x1 x2] -> [... x2 x1] -func opcodeSwap(op *parsedOpcode, vm *Engine) error { +func opcodeSwap(op *opcode, data []byte, vm *Engine) error { return vm.dstack.SwapN(1) } @@ -1275,7 +1266,7 @@ func opcodeSwap(op *parsedOpcode, vm *Engine) error { // second-to-top item. // // Stack transformation: [... x1 x2] -> [... x2 x1 x2] -func opcodeTuck(op *parsedOpcode, vm *Engine) error { +func opcodeTuck(op *opcode, data []byte, vm *Engine) error { return vm.dstack.Tuck() } @@ -1283,7 +1274,7 @@ func opcodeTuck(op *parsedOpcode, vm *Engine) error { // stack. // // Stack transformation: [... x1] -> [... x1 len(x1)] -func opcodeSize(op *parsedOpcode, vm *Engine) error { +func opcodeSize(op *opcode, data []byte, vm *Engine) error { so, err := vm.dstack.PeekByteArray(0) if err != nil { return err @@ -1297,7 +1288,7 @@ func opcodeSize(op *parsedOpcode, vm *Engine) error { // bytes, and pushes the result, encoded as a boolean, back to the stack. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeEqual(op *parsedOpcode, vm *Engine) error { +func opcodeEqual(op *opcode, data []byte, vm *Engine) error { a, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1318,8 +1309,8 @@ func opcodeEqual(op *parsedOpcode, vm *Engine) error { // evaluates to true. An error is returned if it does not. // // Stack transformation: [... x1 x2] -> [... bool] -> [...] -func opcodeEqualVerify(op *parsedOpcode, vm *Engine) error { - err := opcodeEqual(op, vm) +func opcodeEqualVerify(op *opcode, data []byte, vm *Engine) error { + err := opcodeEqual(op, data, vm) if err == nil { err = abstractVerify(op, vm, ErrEqualVerify) } @@ -1330,7 +1321,7 @@ func opcodeEqualVerify(op *parsedOpcode, vm *Engine) error { // it with its incremented value (plus 1). // // Stack transformation: [... x1 x2] -> [... x1 x2+1] -func opcode1Add(op *parsedOpcode, vm *Engine) error { +func opcode1Add(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1344,7 +1335,7 @@ func opcode1Add(op *parsedOpcode, vm *Engine) error { // it with its decremented value (minus 1). // // Stack transformation: [... x1 x2] -> [... x1 x2-1] -func opcode1Sub(op *parsedOpcode, vm *Engine) error { +func opcode1Sub(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1358,7 +1349,7 @@ func opcode1Sub(op *parsedOpcode, vm *Engine) error { // it with its negation. // // Stack transformation: [... x1 x2] -> [... x1 -x2] -func opcodeNegate(op *parsedOpcode, vm *Engine) error { +func opcodeNegate(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1372,7 +1363,7 @@ func opcodeNegate(op *parsedOpcode, vm *Engine) error { // it with its absolute value. // // Stack transformation: [... x1 x2] -> [... x1 abs(x2)] -func opcodeAbs(op *parsedOpcode, vm *Engine) error { +func opcodeAbs(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1397,7 +1388,7 @@ func opcodeAbs(op *parsedOpcode, vm *Engine) error { // Stack transformation (x2==0): [... x1 0] -> [... x1 1] // Stack transformation (x2!=0): [... x1 1] -> [... x1 0] // Stack transformation (x2!=0): [... x1 17] -> [... x1 0] -func opcodeNot(op *parsedOpcode, vm *Engine) error { +func opcodeNot(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1417,7 +1408,7 @@ func opcodeNot(op *parsedOpcode, vm *Engine) error { // Stack transformation (x2==0): [... x1 0] -> [... x1 0] // Stack transformation (x2!=0): [... x1 1] -> [... x1 1] // Stack transformation (x2!=0): [... x1 17] -> [... x1 1] -func opcode0NotEqual(op *parsedOpcode, vm *Engine) error { +func opcode0NotEqual(op *opcode, data []byte, vm *Engine) error { m, err := vm.dstack.PopInt() if err != nil { return err @@ -1434,7 +1425,7 @@ func opcode0NotEqual(op *parsedOpcode, vm *Engine) error { // them with their sum. // // Stack transformation: [... x1 x2] -> [... x1+x2] -func opcodeAdd(op *parsedOpcode, vm *Engine) error { +func opcodeAdd(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1454,7 +1445,7 @@ func opcodeAdd(op *parsedOpcode, vm *Engine) error { // entry. // // Stack transformation: [... x1 x2] -> [... x1-x2] -func opcodeSub(op *parsedOpcode, vm *Engine) error { +func opcodeSub(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1476,7 +1467,7 @@ func opcodeSub(op *parsedOpcode, vm *Engine) error { // Stack transformation (x1!=0, x2==0): [... 5 0] -> [... 0] // Stack transformation (x1==0, x2!=0): [... 0 7] -> [... 0] // Stack transformation (x1!=0, x2!=0): [... 4 8] -> [... 1] -func opcodeBoolAnd(op *parsedOpcode, vm *Engine) error { +func opcodeBoolAnd(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1503,7 +1494,7 @@ func opcodeBoolAnd(op *parsedOpcode, vm *Engine) error { // Stack transformation (x1!=0, x2==0): [... 5 0] -> [... 1] // Stack transformation (x1==0, x2!=0): [... 0 7] -> [... 1] // Stack transformation (x1!=0, x2!=0): [... 4 8] -> [... 1] -func opcodeBoolOr(op *parsedOpcode, vm *Engine) error { +func opcodeBoolOr(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1528,7 +1519,7 @@ func opcodeBoolOr(op *parsedOpcode, vm *Engine) error { // // Stack transformation (x1==x2): [... 5 5] -> [... 1] // Stack transformation (x1!=x2): [... 5 7] -> [... 0] -func opcodeNumEqual(op *parsedOpcode, vm *Engine) error { +func opcodeNumEqual(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1556,8 +1547,8 @@ func opcodeNumEqual(op *parsedOpcode, vm *Engine) error { // to true. An error is returned if it does not. // // Stack transformation: [... x1 x2] -> [... bool] -> [...] -func opcodeNumEqualVerify(op *parsedOpcode, vm *Engine) error { - err := opcodeNumEqual(op, vm) +func opcodeNumEqualVerify(op *opcode, data []byte, vm *Engine) error { + err := opcodeNumEqual(op, data, vm) if err == nil { err = abstractVerify(op, vm, ErrNumEqualVerify) } @@ -1569,7 +1560,7 @@ func opcodeNumEqualVerify(op *parsedOpcode, vm *Engine) error { // // Stack transformation (x1==x2): [... 5 5] -> [... 0] // Stack transformation (x1!=x2): [... 5 7] -> [... 1] -func opcodeNumNotEqual(op *parsedOpcode, vm *Engine) error { +func opcodeNumNotEqual(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1594,7 +1585,7 @@ func opcodeNumNotEqual(op *parsedOpcode, vm *Engine) error { // otherwise a 0. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeLessThan(op *parsedOpcode, vm *Engine) error { +func opcodeLessThan(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1619,7 +1610,7 @@ func opcodeLessThan(op *parsedOpcode, vm *Engine) error { // with a 1, otherwise a 0. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeGreaterThan(op *parsedOpcode, vm *Engine) error { +func opcodeGreaterThan(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1643,7 +1634,7 @@ func opcodeGreaterThan(op *parsedOpcode, vm *Engine) error { // replaced with a 1, otherwise a 0. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeLessThanOrEqual(op *parsedOpcode, vm *Engine) error { +func opcodeLessThanOrEqual(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1667,7 +1658,7 @@ func opcodeLessThanOrEqual(op *parsedOpcode, vm *Engine) error { // item, they are replaced with a 1, otherwise a 0. // // Stack transformation: [... x1 x2] -> [... bool] -func opcodeGreaterThanOrEqual(op *parsedOpcode, vm *Engine) error { +func opcodeGreaterThanOrEqual(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1691,7 +1682,7 @@ func opcodeGreaterThanOrEqual(op *parsedOpcode, vm *Engine) error { // them with the minimum of the two. // // Stack transformation: [... x1 x2] -> [... min(x1, x2)] -func opcodeMin(op *parsedOpcode, vm *Engine) error { +func opcodeMin(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1715,7 +1706,7 @@ func opcodeMin(op *parsedOpcode, vm *Engine) error { // them with the maximum of the two. // // Stack transformation: [... x1 x2] -> [... max(x1, x2)] -func opcodeMax(op *parsedOpcode, vm *Engine) error { +func opcodeMax(op *opcode, data []byte, vm *Engine) error { v0, err := vm.dstack.PopInt() if err != nil { return err @@ -1743,7 +1734,7 @@ func opcodeMax(op *parsedOpcode, vm *Engine) error { // the third-to-top item is the value to test. // // Stack transformation: [... x1 min max] -> [... bool] -func opcodeWithin(op *parsedOpcode, vm *Engine) error { +func opcodeWithin(op *opcode, data []byte, vm *Engine) error { maxVal, err := vm.dstack.PopInt() if err != nil { return err @@ -1777,7 +1768,7 @@ func calcHash(buf []byte, hasher hash.Hash) []byte { // replaces it with ripemd160(data). // // Stack transformation: [... x1] -> [... ripemd160(x1)] -func opcodeRipemd160(op *parsedOpcode, vm *Engine) error { +func opcodeRipemd160(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1791,7 +1782,7 @@ func opcodeRipemd160(op *parsedOpcode, vm *Engine) error { // with sha1(data). // // Stack transformation: [... x1] -> [... sha1(x1)] -func opcodeSha1(op *parsedOpcode, vm *Engine) error { +func opcodeSha1(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1806,7 +1797,7 @@ func opcodeSha1(op *parsedOpcode, vm *Engine) error { // it with sha256(data). // // Stack transformation: [... x1] -> [... sha256(x1)] -func opcodeSha256(op *parsedOpcode, vm *Engine) error { +func opcodeSha256(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1821,7 +1812,7 @@ func opcodeSha256(op *parsedOpcode, vm *Engine) error { // it with ripemd160(sha256(data)). // // Stack transformation: [... x1] -> [... ripemd160(sha256(x1))] -func opcodeHash160(op *parsedOpcode, vm *Engine) error { +func opcodeHash160(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1836,7 +1827,7 @@ func opcodeHash160(op *parsedOpcode, vm *Engine) error { // it with sha256(sha256(data)). // // Stack transformation: [... x1] -> [... sha256(sha256(x1))] -func opcodeHash256(op *parsedOpcode, vm *Engine) error { +func opcodeHash256(op *opcode, data []byte, vm *Engine) error { buf, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1850,7 +1841,7 @@ func opcodeHash256(op *parsedOpcode, vm *Engine) error { // seen OP_CODESEPARATOR which is used during signature checking. // // This opcode does not change the contents of the data stack. -func opcodeCodeSeparator(op *parsedOpcode, vm *Engine) error { +func opcodeCodeSeparator(op *opcode, data []byte, vm *Engine) error { vm.lastCodeSep = int(vm.tokenizer.ByteIndex()) return nil } @@ -1869,7 +1860,7 @@ func opcodeCodeSeparator(op *parsedOpcode, vm *Engine) error { // cryptographic methods against the provided public key. // // Stack transformation: [... signature pubkey] -> [... bool] -func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { +func opcodeCheckSig(op *opcode, data []byte, vm *Engine) error { pkBytes, err := vm.dstack.PopByteArray() if err != nil { return err @@ -1984,9 +1975,9 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error { // The opcodeCheckSig function is invoked followed by opcodeVerify. See the // documentation for each of those opcodes for more details. // -// Stack transformation: signature pubkey] -> [... bool] -> [...] -func opcodeCheckSigVerify(op *parsedOpcode, vm *Engine) error { - err := opcodeCheckSig(op, vm) +// Stack transformation: [... signature pubkey] -> [... bool] -> [...] +func opcodeCheckSigVerify(op *opcode, data []byte, vm *Engine) error { + err := opcodeCheckSig(op, data, vm) if err == nil { err = abstractVerify(op, vm, ErrCheckSigVerify) } @@ -2021,7 +2012,7 @@ type parsedSigInfo struct { // // Stack transformation: // [... dummy [sig ...] numsigs [pubkey ...] numpubkeys] -> [... bool] -func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { +func opcodeCheckMultiSig(op *opcode, data []byte, vm *Engine) error { numKeys, err := vm.dstack.PopInt() if err != nil { return err @@ -2247,8 +2238,8 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error { // // Stack transformation: // [... dummy [sig ...] numsigs [pubkey ...] numpubkeys] -> [... bool] -> [...] -func opcodeCheckMultiSigVerify(op *parsedOpcode, vm *Engine) error { - err := opcodeCheckMultiSig(op, vm) +func opcodeCheckMultiSigVerify(op *opcode, data []byte, vm *Engine) error { + err := opcodeCheckMultiSig(op, data, vm) if err == nil { err = abstractVerify(op, vm, ErrCheckMultiSigVerify) } diff --git a/txscript/opcode_test.go b/txscript/opcode_test.go index 3c5abf9d..91263c21 100644 --- a/txscript/opcode_test.go +++ b/txscript/opcode_test.go @@ -23,8 +23,8 @@ func TestOpcodeDisabled(t *testing.T) { OP_LSHIFT, OP_RSHIFT, } for _, opcodeVal := range tests { - pop := parsedOpcode{opcode: &opcodeArray[opcodeVal], data: nil} - err := opcodeDisabled(&pop, nil) + op := &opcodeArray[opcodeVal] + err := opcodeDisabled(op, nil, nil) if !IsErrorCode(err, ErrDisabledOpcode) { t.Errorf("opcodeDisabled: unexpected error - got %v, "+ "want %v", err, ErrDisabledOpcode) -- 2.45.2 From 40dab558f69fd0e562e933e7e44344dd613fe713 Mon Sep 17 00:00:00 2001 From: Calvin Kim Date: Wed, 17 Nov 2021 12:46:12 +0900 Subject: [PATCH 319/459] go.mod, go.sum: Update goleveldb Goleveldb recently had a PR in where memory allocation was reduced drastically (github.com/syndtr/goleveldb/pull/367). Update goleveldb to use that PR. --- go.mod | 3 ++- go.sum | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7722564f..767c2740 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,8 @@ require ( github.com/decred/dcrd/lru v1.0.0 github.com/jessevdk/go-flags v1.4.0 github.com/jrick/logrotate v1.0.0 - golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 ) go 1.16 diff --git a/go.sum b/go.sum index 4c5a352a..e9ee276d 100644 --- a/go.sum +++ b/go.sum @@ -25,7 +25,18 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -35,28 +46,56 @@ github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -64,3 +103,5 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -- 2.45.2 From a8ad25766070deafd72cadc5c7d9685d6b684660 Mon Sep 17 00:00:00 2001 From: Tomasz Ziolkowski Date: Fri, 15 Oct 2021 16:56:27 +0200 Subject: [PATCH 320/459] reduce redundant memory allocatio - resolves btcsuite/btcd#1699 Signed-off-by: Tomasz Ziolkowski --- connmgr/tor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connmgr/tor.go b/connmgr/tor.go index 2b22ae51..a2e512db 100644 --- a/connmgr/tor.go +++ b/connmgr/tor.go @@ -76,7 +76,7 @@ func TorLookupIP(host, proxy string) ([]net.IP, error) { return nil, ErrTorUnrecognizedAuthMethod } - buf = make([]byte, 7+len(host)) + buf = make([]byte, 6+len(host)) buf[0] = 5 // protocol version buf[1] = '\xF0' // Tor Resolve buf[2] = 0 // reserved -- 2.45.2 From 2c3c4db1982e5d536ff92deb04b84029d580d2ba Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 6 Jul 2021 19:36:21 -0700 Subject: [PATCH 321/459] [lbry] wire: optimize binaryFreeList handling --- wire/common.go | 56 ++++++++------------------------------------------ 1 file changed, 9 insertions(+), 47 deletions(-) diff --git a/wire/common.go b/wire/common.go index 42c1797b..8d61bdb6 100644 --- a/wire/common.go +++ b/wire/common.go @@ -18,10 +18,6 @@ import ( const ( // MaxVarIntPayload is the maximum payload size for a variable length integer. MaxVarIntPayload = 9 - - // binaryFreeListMaxItems is the number of buffers to keep in the free - // list to use for binary serialization and deserialization. - binaryFreeListMaxItems = 1024 ) var ( @@ -47,38 +43,14 @@ var ( // io.Writer, and return the buffer to the free list. type binaryFreeList chan []byte -// Borrow returns a byte slice from the free list with a length of 8. A new -// buffer is allocated if there are not any available on the free list. -func (l binaryFreeList) Borrow() []byte { - var buf []byte - select { - case buf = <-l: - default: - buf = make([]byte, 8) - } - return buf[:8] -} - -// Return puts the provided byte slice back on the free list. The buffer MUST -// have been obtained via the Borrow function and therefore have a cap of 8. -func (l binaryFreeList) Return(buf []byte) { - select { - case l <- buf: - default: - // Let it go to the garbage collector. - } -} - // Uint8 reads a single byte from the provided reader using a buffer from the // free list and returns it as a uint8. func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) { - buf := l.Borrow()[:1] + buf := make([]byte, 1) // should be allocated on the stack if _, err := io.ReadFull(r, buf); err != nil { - l.Return(buf) return 0, err } rv := buf[0] - l.Return(buf) return rv, nil } @@ -86,13 +58,11 @@ func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) { // free list, converts it to a number using the provided byte order, and returns // the resulting uint16. func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16, error) { - buf := l.Borrow()[:2] + buf := make([]byte, 2) // should be allocated on the stack if _, err := io.ReadFull(r, buf); err != nil { - l.Return(buf) return 0, err } rv := byteOrder.Uint16(buf) - l.Return(buf) return rv, nil } @@ -100,13 +70,11 @@ func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16, // free list, converts it to a number using the provided byte order, and returns // the resulting uint32. func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder) (uint32, error) { - buf := l.Borrow()[:4] + buf := make([]byte, 4) // should be allocated on the stack if _, err := io.ReadFull(r, buf); err != nil { - l.Return(buf) return 0, err } rv := byteOrder.Uint32(buf) - l.Return(buf) return rv, nil } @@ -114,23 +82,20 @@ func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder) (uint32, // free list, converts it to a number using the provided byte order, and returns // the resulting uint64. func (l binaryFreeList) Uint64(r io.Reader, byteOrder binary.ByteOrder) (uint64, error) { - buf := l.Borrow()[:8] + buf := make([]byte, 8) // should be allocated on the stack if _, err := io.ReadFull(r, buf); err != nil { - l.Return(buf) return 0, err } rv := byteOrder.Uint64(buf) - l.Return(buf) return rv, nil } // PutUint8 copies the provided uint8 into a buffer from the free list and // writes the resulting byte to the given writer. func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error { - buf := l.Borrow()[:1] + buf := make([]byte, 1) // should be allocated on the stack buf[0] = val _, err := w.Write(buf) - l.Return(buf) return err } @@ -138,10 +103,9 @@ func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error { // buffer from the free list and writes the resulting two bytes to the given // writer. func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOrder, val uint16) error { - buf := l.Borrow()[:2] + buf := make([]byte, 2) // should be allocated on the stack byteOrder.PutUint16(buf, val) _, err := w.Write(buf) - l.Return(buf) return err } @@ -149,10 +113,9 @@ func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOrder, val u // buffer from the free list and writes the resulting four bytes to the given // writer. func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOrder, val uint32) error { - buf := l.Borrow()[:4] + buf := make([]byte, 4) // should be allocated on the stack byteOrder.PutUint32(buf, val) _, err := w.Write(buf) - l.Return(buf) return err } @@ -160,16 +123,15 @@ func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOrder, val u // buffer from the free list and writes the resulting eight bytes to the given // writer. func (l binaryFreeList) PutUint64(w io.Writer, byteOrder binary.ByteOrder, val uint64) error { - buf := l.Borrow()[:8] + buf := make([]byte, 8) // should be allocated on the stack byteOrder.PutUint64(buf, val) _, err := w.Write(buf) - l.Return(buf) return err } // binarySerializer provides a free list of buffers to use for serializing and // deserializing primitive integer values to and from io.Readers and io.Writers. -var binarySerializer binaryFreeList = make(chan []byte, binaryFreeListMaxItems) +var binarySerializer binaryFreeList = make(chan []byte) // errNonCanonicalVarInt is the common format string used for non-canonically // encoded variable length integer errors. -- 2.45.2 From abe121ea6e875b346b63984dc1d6eb8927d7aa7f Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 21:05:31 -0700 Subject: [PATCH 322/459] [lbry] wire: update protocol NetIDs --- wire/protocol.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wire/protocol.go b/wire/protocol.go index 8cc9838a..cade06b7 100644 --- a/wire/protocol.go +++ b/wire/protocol.go @@ -147,13 +147,13 @@ type BitcoinNet uint32 // better idea to simply disconnect clients that are misbehaving over TCP. const ( // MainNet represents the main bitcoin network. - MainNet BitcoinNet = 0xd9b4bef9 + MainNet BitcoinNet = 0xf1aae4fa // TestNet represents the regression test network. - TestNet BitcoinNet = 0xdab5bffa + TestNet BitcoinNet = 0xd1aae4fa // TestNet3 represents the test network (version 3). - TestNet3 BitcoinNet = 0x0709110b + TestNet3 BitcoinNet = 0xe1aae4fa // SimNet represents the simulation test network. SimNet BitcoinNet = 0x12141c16 -- 2.45.2 From 31d3d9debc7f6d85e3b4aff0868a24efc93f600e Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 3 Feb 2022 22:43:34 -0800 Subject: [PATCH 323/459] [lbry] wire: increase wire.MaxBlockPayload to 8MB --- wire/msgblock.go | 4 ++-- wire/msgblock_test.go | 2 +- wire/msgmerkleblock_test.go | 2 +- wire/msgtx_test.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wire/msgblock.go b/wire/msgblock.go index 4172949d..a5a25a1c 100644 --- a/wire/msgblock.go +++ b/wire/msgblock.go @@ -23,8 +23,8 @@ const defaultTransactionAlloc = 2048 const MaxBlocksPerMsg = 500 // MaxBlockPayload is the maximum bytes a block message can be in bytes. -// After Segregated Witness, the max block payload has been raised to 4MB. -const MaxBlockPayload = 4000000 +// After Segregated Witness, the max block payload has been raised to 8MB. +const MaxBlockPayload = 8000000 // maxTxPerBlock is the maximum number of transactions that could // possibly fit into a block. diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index 2a861b20..12a6afcb 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -36,7 +36,7 @@ func TestBlock(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num addresses (varInt) + max allowed addresses. - wantPayload := uint32(4000000) + wantPayload := uint32(8000000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ diff --git a/wire/msgmerkleblock_test.go b/wire/msgmerkleblock_test.go index 9837f8a9..b74f7183 100644 --- a/wire/msgmerkleblock_test.go +++ b/wire/msgmerkleblock_test.go @@ -38,7 +38,7 @@ func TestMerkleBlock(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num addresses (varInt) + max allowed addresses. - wantPayload := uint32(4000000) + wantPayload := uint32(8000000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index 66965043..ae508f7f 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -35,7 +35,7 @@ func TestTx(t *testing.T) { } // Ensure max payload is expected value for latest protocol version. - wantPayload := uint32(1000 * 4000) + wantPayload := uint32(1000 * 8000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ -- 2.45.2 From dba1eb7261fca0816818028603913c024fca1a41 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 6 Jul 2021 19:42:57 -0700 Subject: [PATCH 324/459] [lbry] profile: support fgprof (flame graph) --- btcd.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/btcd.go b/btcd.go index 3ace182c..b93851ba 100644 --- a/btcd.go +++ b/btcd.go @@ -18,6 +18,8 @@ import ( "github.com/btcsuite/btcd/blockchain/indexers" "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcd/limits" + + "github.com/felixge/fgprof" ) const ( @@ -65,6 +67,7 @@ func btcdMain(serverChan chan<- *server) error { // Enable http profiling server if requested. if cfg.Profile != "" { + http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler()) go func() { listenAddr := net.JoinHostPort("", cfg.Profile) btcdLog.Infof("Profile server listening on %s", listenAddr) -- 2.45.2 From 21ad6495b6529ed9303cf6b3b86b78a31543f6ba Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 19:46:51 -0700 Subject: [PATCH 325/459] [lbry] chaincfg: implement LBRY PoW Hash --- chaincfg/chainhash/hashfuncs.go | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/chaincfg/chainhash/hashfuncs.go b/chaincfg/chainhash/hashfuncs.go index bf74f73c..194c60e3 100644 --- a/chaincfg/chainhash/hashfuncs.go +++ b/chaincfg/chainhash/hashfuncs.go @@ -5,7 +5,12 @@ package chainhash -import "crypto/sha256" +import ( + "crypto/sha256" + "crypto/sha512" + + "golang.org/x/crypto/ripemd160" +) // HashB calculates hash(b) and returns the resulting bytes. func HashB(b []byte) []byte { @@ -31,3 +36,26 @@ func DoubleHashH(b []byte) Hash { first := sha256.Sum256(b) return Hash(sha256.Sum256(first[:])) } + +// LbryPoWHashH calculates returns the PoW Hash. +// +// doubled := SHA256(SHA256(b)) +// expanded := SHA512(doubled) +// left := RIPEMD160(expanded[0:32]) +// right := RIPEMD160(expanded[32:64]) +// result := SHA256(SHA256(left||right)) +func LbryPoWHashH(b []byte) Hash { + doubled := DoubleHashB(b) + expanded := sha512.Sum512(doubled) + + r := ripemd160.New() + r.Reset() + r.Write(expanded[:sha256.Size]) + left := r.Sum(nil) + + r.Reset() + r.Write(expanded[sha256.Size:]) + + combined := r.Sum(left) + return DoubleHashH(combined) +} -- 2.45.2 From ba3ca3b77ecbd24c4f425206308bdc5d9bd4aa76 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 21:03:41 -0700 Subject: [PATCH 326/459] [lbry] chaincfg: setup genisis blocks --- chaincfg/genesis.go | 87 +++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/chaincfg/genesis.go b/chaincfg/genesis.go index 73d28610..2c2a043e 100644 --- a/chaincfg/genesis.go +++ b/chaincfg/genesis.go @@ -22,33 +22,22 @@ var genesisCoinbaseTx = wire.MsgTx{ Index: 0xffffffff, }, SignatureScript: []byte{ - 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */ - 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */ - 0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */ - 0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */ - 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */ - 0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */ - 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/ - 0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */ - 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/ - 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */ + 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x17, + 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, }, Sequence: 0xffffffff, }, }, TxOut: []*wire.TxOut{ { - Value: 0x12a05f200, + Value: 0x8e1bc9bf040000, // 400000000 * COIN PkScript: []byte{ - 0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */ - 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */ - 0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */ - 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */ - 0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */ - 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */ - 0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */ - 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */ - 0x1d, 0x5f, 0xac, /* |._.| */ + 0x76, 0xa9, 0x14, 0x34, 0x59, 0x91, 0xdb, 0xf5, + 0x7b, 0xfb, 0x01, 0x4b, 0x87, 0x00, 0x6a, 0xcd, + 0xfa, 0xfb, 0xfc, 0x5f, 0xe8, 0x29, 0x2f, 0x88, + 0xac, }, }, }, @@ -58,19 +47,28 @@ var genesisCoinbaseTx = wire.MsgTx{ // genesisHash is the hash of the first block in the block chain for the main // network (genesis block). var genesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, - 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, - 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x63, 0xf4, 0x34, 0x6a, 0x4d, 0xb3, 0x4f, 0xdf, + 0xce, 0x29, 0xa7, 0x0f, 0x5e, 0x8d, 0x11, 0xf0, + 0x65, 0xf6, 0xb9, 0x16, 0x02, 0xb7, 0x03, 0x6c, + 0x7f, 0x22, 0xf3, 0xa0, 0x3b, 0x28, 0x89, 0x9c, }) // genesisMerkleRoot is the hash of the first transaction in the genesis block // for the main network. var genesisMerkleRoot = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, - 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, - 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, - 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, + 0xcc, 0x59, 0xe5, 0x9f, 0xf9, 0x7a, 0xc0, 0x92, + 0xb5, 0x5e, 0x42, 0x3a, 0xa5, 0x49, 0x51, 0x51, + 0xed, 0x6f, 0xb8, 0x05, 0x70, 0xa5, 0xbb, 0x78, + 0xcd, 0x5b, 0xd1, 0xc3, 0x82, 0x1c, 0x21, 0xb8, +}) + +// genesisClaimTrie is the hash of the first transaction in the genesis block +// for the main network. +var genesisClaimTrie = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }) // genesisBlock defines the genesis block of the block chain which serves as the @@ -79,10 +77,11 @@ var genesisBlock = wire.MsgBlock{ Header: wire.BlockHeader{ Version: 1, PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000 - MerkleRoot: genesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b - Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 18:15:05 +0000 UTC - Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000] - Nonce: 0x7c2bac1d, // 2083236893 + MerkleRoot: genesisMerkleRoot, // b8211c82c3d15bcd78bba57005b86fed515149a53a425eb592c07af99fe559cc + ClaimTrie: genesisClaimTrie, // 0000000000000000000000000000000000000000000000000000000000000001 + Timestamp: time.Unix(1446058291, 0), // 28 Oct 2015 18:51:31 +0000 UTC + Bits: 0x1f00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000] + Nonce: 0x00000507, // 1287 }, Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } @@ -90,10 +89,10 @@ var genesisBlock = wire.MsgBlock{ // regTestGenesisHash is the hash of the first block in the block chain for the // regression test network (genesis block). var regTestGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, - 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, - 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, - 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, + 0x56, 0x75, 0x68, 0x69, 0x76, 0x67, 0x4f, 0x50, + 0xa0, 0xa1, 0x95, 0x3d, 0x17, 0x2e, 0x9e, 0xcf, + 0x4a, 0x4a, 0x62, 0x1d, 0xc9, 0xa4, 0xc3, 0x79, + 0x5d, 0xec, 0xd4, 0x99, 0x12, 0xcf, 0x3f, 0x6e, }) // regTestGenesisMerkleRoot is the hash of the first transaction in the genesis @@ -107,10 +106,11 @@ var regTestGenesisBlock = wire.MsgBlock{ Header: wire.BlockHeader{ Version: 1, PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000 - MerkleRoot: regTestGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b - Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC + MerkleRoot: regTestGenesisMerkleRoot, // b8211c82c3d15bcd78bba57005b86fed515149a53a425eb592c07af99fe559cc + ClaimTrie: genesisClaimTrie, // 0000000000000000000000000000000000000000000000000000000000000001 + Timestamp: time.Unix(1446058291, 0), // 28 Oct 2015 18:51:31 +0000 UTC Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000] - Nonce: 2, + Nonce: 1, }, Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } @@ -135,10 +135,11 @@ var testNet3GenesisBlock = wire.MsgBlock{ Header: wire.BlockHeader{ Version: 1, PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000 - MerkleRoot: testNet3GenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b - Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC - Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000] - Nonce: 0x18aea41a, // 414098458 + MerkleRoot: testNet3GenesisMerkleRoot, // b8211c82c3d15bcd78bba57005b86fed515149a53a425eb592c07af99fe559cc + ClaimTrie: genesisClaimTrie, // 0000000000000000000000000000000000000000000000000000000000000001 + Timestamp: time.Unix(1446058291, 0), // 28 Oct 2015 18:51:31 +0000 UTC + Bits: 0x1f00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000] + Nonce: 0x00000507, // 1287 }, Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -- 2.45.2 From cbac056756465efa259906b6b425c4608beaad4d Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 21:04:41 -0700 Subject: [PATCH 327/459] [lbry] chaincfg: update chainparams for LBRY chain Co-authored-by: Brannon King Co-authored-by: Alex Grintsvayg --- chaincfg/params.go | 263 +++++++++++++++++++++------------------------ 1 file changed, 121 insertions(+), 142 deletions(-) diff --git a/chaincfg/params.go b/chaincfg/params.go index a6d8d3e5..68c362d5 100644 --- a/chaincfg/params.go +++ b/chaincfg/params.go @@ -25,8 +25,8 @@ var ( bigOne = big.NewInt(1) // mainPowLimit is the highest proof of work value a Bitcoin block can - // have for the main network. It is the value 2^224 - 1. - mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) + // have for the main network. It is the value 2^240 - 1. + mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 240), bigOne) // regressionPowLimit is the highest proof of work value a Bitcoin block // can have for the regression test network. It is the value 2^255 - 1. @@ -34,8 +34,8 @@ var ( // testNet3PowLimit is the highest proof of work value a Bitcoin block // can have for the test network (version 3). It is the value - // 2^224 - 1. - testNet3PowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) + // 2^240 - 1. + testNet3PowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 240), bigOne) // simNetPowLimit is the highest proof of work value a Bitcoin block // can have for the simulation test network. It is the value 2^255 - 1. @@ -102,6 +102,9 @@ type ConsensusDeployment struct { // ExpireTime is the median block time after which the attempted // deployment expires. ExpireTime uint64 + + // ForceActiveAt is added by LBRY to bypass consensus. Features are activated via hard-fork instead. + ForceActiveAt int32 } // Constants that define the deployment offset in the deployments field of the @@ -237,11 +240,9 @@ type Params struct { Bech32HRPSegwit string // Address encoding magics - PubKeyHashAddrID byte // First byte of a P2PKH address - ScriptHashAddrID byte // First byte of a P2SH address - PrivateKeyID byte // First byte of a WIF private key - WitnessPubKeyHashAddrID byte // First byte of a P2WPKH address - WitnessScriptHashAddrID byte // First byte of a P2WSH address + PubKeyHashAddrID byte // First byte of a P2PKH address + ScriptHashAddrID byte // First byte of a P2SH address + PrivateKeyID byte // First byte of a WIF private key // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID [4]byte @@ -256,60 +257,58 @@ type Params struct { var MainNetParams = Params{ Name: "mainnet", Net: wire.MainNet, - DefaultPort: "8333", + DefaultPort: "9246", DNSSeeds: []DNSSeed{ - {"seed.bitcoin.sipa.be", true}, - {"dnsseed.bluematt.me", true}, - {"dnsseed.bitcoin.dashjr.org", false}, - {"seed.bitcoinstats.com", true}, - {"seed.bitnodes.io", false}, - {"seed.bitcoin.jonasschnelli.ch", true}, + {"dnsseed1.lbry.com", true}, + {"dnsseed2.lbry.com", true}, + {"dnsseed3.lbry.com", true}, + {"seed.lbry.grin.io", true}, + {"seed.allaboutlbc.com", true}, }, // Chain parameters GenesisBlock: &genesisBlock, GenesisHash: &genesisHash, PowLimit: mainPowLimit, - PowLimitBits: 0x1d00ffff, - BIP0034Height: 227931, // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8 - BIP0065Height: 388381, // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 - BIP0066Height: 363725, // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 + PowLimitBits: 0x1f00ffff, + BIP0034Height: 1, + BIP0065Height: 200000, + BIP0066Height: 200000, CoinbaseMaturity: 100, - SubsidyReductionInterval: 210000, - TargetTimespan: time.Hour * 24 * 14, // 14 days - TargetTimePerBlock: time.Minute * 10, // 10 minutes - RetargetAdjustmentFactor: 4, // 25% less, 400% more + SubsidyReductionInterval: 1 << 5, + TargetTimespan: time.Second * 150, // retarget every block + TargetTimePerBlock: time.Second * 150, // 150 seconds + RetargetAdjustmentFactor: 4, // 25% less, 400% more ReduceMinDifficulty: false, MinDiffReductionTime: 0, GenerateSupported: false, // Checkpoints ordered from oldest to newest. Checkpoints: []Checkpoint{ - {11111, newHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")}, - {33333, newHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")}, - {74000, newHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")}, - {105000, newHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")}, - {134444, newHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")}, - {168000, newHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")}, - {193000, newHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")}, - {210000, newHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")}, - {216116, newHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, - {225430, newHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, - {250000, newHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, - {267300, newHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")}, - {279000, newHashFromStr("0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")}, - {300255, newHashFromStr("0000000000000000162804527c6e9b9f0563a280525f9d08c12041def0a0f3b2")}, - {319400, newHashFromStr("000000000000000021c6052e9becade189495d1c539aa37c58917305fd15f13b")}, - {343185, newHashFromStr("0000000000000000072b8bf361d01a6ba7d445dd024203fafc78768ed4368554")}, - {352940, newHashFromStr("000000000000000010755df42dba556bb72be6a32f3ce0b6941ce4430152c9ff")}, - {382320, newHashFromStr("00000000000000000a8dc6ed5b133d0eb2fd6af56203e4159789b092defd8ab2")}, - {400000, newHashFromStr("000000000000000004ec466ce4732fe6f1ed1cddc2ed4b328fff5224276e3f6f")}, - {430000, newHashFromStr("000000000000000001868b2bb3a285f3cc6b33ea234eb70facf4dcdf22186b87")}, - {460000, newHashFromStr("000000000000000000ef751bbce8e744ad303c47ece06c8d863e4d417efc258c")}, - {490000, newHashFromStr("000000000000000000de069137b17b8d5a3dfbd5b145b2dcfb203f15d0c4de90")}, - {520000, newHashFromStr("0000000000000000000d26984c0229c9f6962dc74db0a6d525f2f1640396f69c")}, - {550000, newHashFromStr("000000000000000000223b7a2298fb1c6c75fb0efc28a4c56853ff4112ec6bc9")}, - {560000, newHashFromStr("0000000000000000002c7b276daf6efb2b6aa68e2ce3be67ef925b3264ae7122")}, + {40000, newHashFromStr("4c55584b068108b15c0066a010d11971aa92f46b0a73d479f1b7fa57df8b05f4")}, + {80000, newHashFromStr("6e9facdfb87ba8394a46c61a7c093f7f00b1397a2dabc6a04f2911e0efdcf50a")}, + {120000, newHashFromStr("6a9dba420ec544b927769765dccec8b29e214e6ca9f82b54a52bf20ca517b75a")}, + {160000, newHashFromStr("87b2913a509d857401f7587903c90214db7847af1a1ad63a3b6f245936e3ae9d")}, + {200000, newHashFromStr("0fe8ed6019a83028006435e47be4e37a0d3ed48019cde1dc7ede6562e5829839")}, + {240000, newHashFromStr("cb3c2342afbe7291012f2288403a9d105f46987f78b279d516db2deb4d35b0b7")}, + {280000, newHashFromStr("9835d03eb527ea4ce45c217350c68042926d497c21fb31413b2f7824ff6fc6c3")}, + {320000, newHashFromStr("ad80c7cb91ca1d9c9b7bf68ca1b6d4ba217fe25ca5ded6a7e8acbaba663b143f")}, + {360000, newHashFromStr("f9fd013252439663c1e729a8afb27187a8b9cc63a253336060f867e3cfbe4dcb")}, + {400000, newHashFromStr("f0e56e70782af63ccb49c76e852540688755869ba59ec68cac9c04a6b4d9f5ca")}, + {440000, newHashFromStr("52760e00c369b40781a2ced32836711fab82a720fafb121118c815bb46afd996")}, + {480000, newHashFromStr("cecacaf4d1a8d1ef60da39343540781115abb91f5f0c976bb08afc4d4e3218ac")}, + {520000, newHashFromStr("fa5e9d6dcf9ad57ba60d8ba26fb05585741098d10f42ed9d5e6b5e90ebc278d6")}, + {560000, newHashFromStr("95c6229bd9b40f03a8426b2fec740026b3f06b1628cfb87527b0cbd0da328c0c")}, + {600000, newHashFromStr("532657a97d480feb2d0423bb736cbfd7400b3ac8311e81ac749a2f29103a6c6b")}, + {640000, newHashFromStr("68b69e3e8765e1ddbac63cbfbbf12e1a920da994d242a26fd07624f067743080")}, + {680000, newHashFromStr("7b9f30c959405b5b96d0b0c2ba8fc7c5586cd0ce40df51427de4b8a217859c45")}, + {720000, newHashFromStr("42084d5f88c71c0ae09b8677070969df9c3ef875c5f434133f552d863204f0cb")}, + {760000, newHashFromStr("1887cd8b50375a9ac0dc9686c98fa8ac69bca618eab6254310647057f6fe4fc9")}, + {800000, newHashFromStr("d34bb871b21e6fda4bd9d9e530ebf12e044814004007f088415035c651ecf322")}, + {840000, newHashFromStr("d0e73c5ce3ad5d6fdb4483aa450f0b1cf7e4570987ee3a3806ace4ad2f7cc9af")}, + {880000, newHashFromStr("806a95f26bab603f1d9132b5d4ea72aab9d1198ad55ae18dac1e149f6cb70ce4")}, + {920000, newHashFromStr("83bc84555105436c51728ab200e8da4d9b3a365fd3d1d47a60048ad0f977c55b")}, + {960000, newHashFromStr("60e37b1c2d1f8771290b7f84865cbadf22b5b89d3ce1201d454b09f0775b42c2")}, }, // Consensus rule change deployments. @@ -325,14 +324,16 @@ var MainNetParams = Params{ ExpireTime: 1230767999, // December 31, 2008 UTC }, DeploymentCSV: { - BitNumber: 0, - StartTime: 1462060800, // May 1st, 2016 - ExpireTime: 1493596800, // May 1st, 2017 + BitNumber: 0, + StartTime: 1462060800, // May 1st, 2016 + ExpireTime: 1493596800, // May 1st, 2017 + ForceActiveAt: 200000, }, DeploymentSegwit: { - BitNumber: 1, - StartTime: 1479168000, // November 15, 2016 UTC - ExpireTime: 1510704000, // November 15, 2017 UTC. + BitNumber: 1, + StartTime: 1547942400, // Jan 20, 2019 + ExpireTime: 1548288000, // Jan 24, 2019 + ForceActiveAt: 680770, }, }, @@ -341,18 +342,16 @@ var MainNetParams = Params{ // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "bc", // always bc for main net + Bech32HRPSegwit: "lbc", // Address encoding magics - PubKeyHashAddrID: 0x00, // starts with 1 - ScriptHashAddrID: 0x05, // starts with 3 - PrivateKeyID: 0x80, // starts with 5 (uncompressed) or K (compressed) - WitnessPubKeyHashAddrID: 0x06, // starts with p2 - WitnessScriptHashAddrID: 0x0A, // starts with 7Xh + PubKeyHashAddrID: 0x55, + ScriptHashAddrID: 0x7a, + PrivateKeyID: 0x1c, // BIP32 hierarchical deterministic extended key magics - HDPrivateKeyID: [4]byte{0x04, 0x88, 0xad, 0xe4}, // starts with xprv - HDPublicKeyID: [4]byte{0x04, 0x88, 0xb2, 0x1e}, // starts with xpub + HDPrivateKeyID: [4]byte{0x04, 0x88, 0xad, 0xe4}, + HDPublicKeyID: [4]byte{0x04, 0x88, 0xb2, 0x1e}, // BIP44 coin type used in the hierarchical deterministic path for // address generation. @@ -365,7 +364,7 @@ var MainNetParams = Params{ var RegressionNetParams = Params{ Name: "regtest", Net: wire.TestNet, - DefaultPort: "18444", + DefaultPort: "29246", DNSSeeds: []DNSSeed{}, // Chain parameters @@ -374,15 +373,15 @@ var RegressionNetParams = Params{ PowLimit: regressionPowLimit, PowLimitBits: 0x207fffff, CoinbaseMaturity: 100, - BIP0034Height: 100000000, // Not active - Permit ver 1 blocks - BIP0065Height: 1351, // Used by regression tests - BIP0066Height: 1251, // Used by regression tests - SubsidyReductionInterval: 150, - TargetTimespan: time.Hour * 24 * 14, // 14 days - TargetTimePerBlock: time.Minute * 10, // 10 minutes - RetargetAdjustmentFactor: 4, // 25% less, 400% more - ReduceMinDifficulty: true, - MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 + BIP0034Height: 1000, + BIP0065Height: 1351, // Used by regression tests + BIP0066Height: 1251, // Used by regression tests + SubsidyReductionInterval: 1 << 5, + TargetTimespan: time.Second, + TargetTimePerBlock: time.Second, + RetargetAdjustmentFactor: 4, // 25% less, 400% more + ReduceMinDifficulty: false, + MinDiffReductionTime: 0, GenerateSupported: true, // Checkpoints ordered from oldest to newest. @@ -401,14 +400,16 @@ var RegressionNetParams = Params{ ExpireTime: math.MaxInt64, // Never expires }, DeploymentCSV: { - BitNumber: 0, - StartTime: 0, // Always available for vote - ExpireTime: math.MaxInt64, // Never expires + BitNumber: 0, + StartTime: 0, // Always available for vote + ExpireTime: math.MaxInt64, // Never expires + ForceActiveAt: 1, }, DeploymentSegwit: { - BitNumber: 1, - StartTime: 0, // Always available for vote - ExpireTime: math.MaxInt64, // Never expires. + BitNumber: 1, + StartTime: 0, + ExpireTime: math.MaxInt64, + ForceActiveAt: 150, }, }, @@ -417,12 +418,12 @@ var RegressionNetParams = Params{ // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "bcrt", // always bcrt for reg test net + Bech32HRPSegwit: "rlbc", // Address encoding magics - PubKeyHashAddrID: 0x6f, // starts with m or n - ScriptHashAddrID: 0xc4, // starts with 2 - PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) + PubKeyHashAddrID: 111, // starts with m or n + ScriptHashAddrID: 196, // starts with 2 + PrivateKeyID: 239, // starts with 9 (uncompressed) or c (compressed) // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv @@ -439,48 +440,31 @@ var RegressionNetParams = Params{ var TestNet3Params = Params{ Name: "testnet3", Net: wire.TestNet3, - DefaultPort: "18333", + DefaultPort: "19246", DNSSeeds: []DNSSeed{ - {"testnet-seed.bitcoin.jonasschnelli.ch", true}, - {"testnet-seed.bitcoin.schildbach.de", false}, - {"seed.tbtc.petertodd.org", true}, - {"testnet-seed.bluematt.me", false}, + {"testdnsseed1.lbry.com", true}, + {"testdnsseed2.lbry.com", true}, }, // Chain parameters GenesisBlock: &testNet3GenesisBlock, GenesisHash: &testNet3GenesisHash, PowLimit: testNet3PowLimit, - PowLimitBits: 0x1d00ffff, - BIP0034Height: 21111, // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8 - BIP0065Height: 581885, // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 - BIP0066Height: 330776, // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 + PowLimitBits: 0x1f00ffff, + BIP0034Height: 21111, // 0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8 + BIP0065Height: 1200000, + BIP0066Height: 1200000, CoinbaseMaturity: 100, - SubsidyReductionInterval: 210000, - TargetTimespan: time.Hour * 24 * 14, // 14 days - TargetTimePerBlock: time.Minute * 10, // 10 minutes - RetargetAdjustmentFactor: 4, // 25% less, 400% more - ReduceMinDifficulty: true, - MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 - GenerateSupported: false, + SubsidyReductionInterval: 1 << 5, + TargetTimespan: time.Second * 150, // retarget every block + TargetTimePerBlock: time.Second * 150, // 150 seconds + RetargetAdjustmentFactor: 4, // 25% less, 400% more + ReduceMinDifficulty: false, + MinDiffReductionTime: 0, + GenerateSupported: true, // Checkpoints ordered from oldest to newest. - Checkpoints: []Checkpoint{ - {546, newHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, - {100000, newHashFromStr("00000000009e2958c15ff9290d571bf9459e93b19765c6801ddeccadbb160a1e")}, - {200000, newHashFromStr("0000000000287bffd321963ef05feab753ebe274e1d78b2fd4e2bfe9ad3aa6f2")}, - {300001, newHashFromStr("0000000000004829474748f3d1bc8fcf893c88be255e6d7f571c548aff57abf4")}, - {400002, newHashFromStr("0000000005e2c73b8ecb82ae2dbc2e8274614ebad7172b53528aba7501f5a089")}, - {500011, newHashFromStr("00000000000929f63977fbac92ff570a9bd9e7715401ee96f2848f7b07750b02")}, - {600002, newHashFromStr("000000000001f471389afd6ee94dcace5ccc44adc18e8bff402443f034b07240")}, - {700000, newHashFromStr("000000000000406178b12a4dea3b27e13b3c4fe4510994fd667d7c1e6a3f4dc1")}, - {800010, newHashFromStr("000000000017ed35296433190b6829db01e657d80631d43f5983fa403bfdb4c1")}, - {900000, newHashFromStr("0000000000356f8d8924556e765b7a94aaebc6b5c8685dcfa2b1ee8b41acd89b")}, - {1000007, newHashFromStr("00000000001ccb893d8a1f25b70ad173ce955e5f50124261bbbc50379a612ddf")}, - {1100007, newHashFromStr("00000000000abc7b2cd18768ab3dee20857326a818d1946ed6796f42d66dd1e8")}, - {1200007, newHashFromStr("00000000000004f2dc41845771909db57e04191714ed8c963f7e56713a7b6cea")}, - {1300007, newHashFromStr("0000000072eab69d54df75107c052b26b0395b44f77578184293bf1bb1dbd9fa")}, - }, + Checkpoints: []Checkpoint{}, // Consensus rule change deployments. // @@ -500,9 +484,10 @@ var TestNet3Params = Params{ ExpireTime: 1493596800, // May 1st, 2017 }, DeploymentSegwit: { - BitNumber: 1, - StartTime: 1462060800, // May 1, 2016 UTC - ExpireTime: 1493596800, // May 1, 2017 UTC. + BitNumber: 1, + StartTime: 1462060800, // May 1st 2016 + ExpireTime: 1493596800, // May 1st 2017 + ForceActiveAt: 1198600, }, }, @@ -511,14 +496,12 @@ var TestNet3Params = Params{ // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "tb", // always tb for test net + Bech32HRPSegwit: "tlbc", // Address encoding magics - PubKeyHashAddrID: 0x6f, // starts with m or n - ScriptHashAddrID: 0xc4, // starts with 2 - WitnessPubKeyHashAddrID: 0x03, // starts with QW - WitnessScriptHashAddrID: 0x28, // starts with T7n - PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) + PubKeyHashAddrID: 111, + ScriptHashAddrID: 196, + PrivateKeyID: 239, // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv @@ -552,11 +535,11 @@ var SimNetParams = Params{ BIP0066Height: 0, // Always active on simnet CoinbaseMaturity: 100, SubsidyReductionInterval: 210000, - TargetTimespan: time.Hour * 24 * 14, // 14 days - TargetTimePerBlock: time.Minute * 10, // 10 minutes - RetargetAdjustmentFactor: 4, // 25% less, 400% more + TargetTimespan: time.Second * 150, + TargetTimePerBlock: time.Second * 150, + RetargetAdjustmentFactor: 4, // 25% less, 400% more ReduceMinDifficulty: true, - MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 + MinDiffReductionTime: 0, GenerateSupported: true, // Checkpoints ordered from oldest to newest. @@ -581,8 +564,8 @@ var SimNetParams = Params{ }, DeploymentSegwit: { BitNumber: 1, - StartTime: 0, // Always available for vote - ExpireTime: math.MaxInt64, // Never expires. + StartTime: 0, + ExpireTime: math.MaxInt64, }, }, @@ -591,14 +574,12 @@ var SimNetParams = Params{ // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "sb", // always sb for sim net + Bech32HRPSegwit: "slbc", // Address encoding magics - PubKeyHashAddrID: 0x3f, // starts with S - ScriptHashAddrID: 0x7b, // starts with s - PrivateKeyID: 0x64, // starts with 4 (uncompressed) or F (compressed) - WitnessPubKeyHashAddrID: 0x19, // starts with Gg - WitnessScriptHashAddrID: 0x28, // starts with ? + PubKeyHashAddrID: 111, + ScriptHashAddrID: 196, + PrivateKeyID: 239, // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID: [4]byte{0x04, 0x20, 0xb9, 0x00}, // starts with sprv @@ -691,14 +672,12 @@ func CustomSignetParams(challenge []byte, dnsSeeds []DNSSeed) Params { // Human-readable part for Bech32 encoded segwit addresses, as defined in // BIP 173. - Bech32HRPSegwit: "tb", // always tb for test net + Bech32HRPSegwit: "slbc", // Address encoding magics - PubKeyHashAddrID: 0x6f, // starts with m or n - ScriptHashAddrID: 0xc4, // starts with 2 - WitnessPubKeyHashAddrID: 0x03, // starts with QW - WitnessScriptHashAddrID: 0x28, // starts with T7n - PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) + PubKeyHashAddrID: 0x6f, // starts with m or n + ScriptHashAddrID: 0xc4, // starts with 2 + PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed) // BIP32 hierarchical deterministic extended key magics HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv -- 2.45.2 From 3dc91f12953ddf60bb6df48406b730374aeee780 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 24 May 2018 14:44:18 -0700 Subject: [PATCH 328/459] [lbry] blockchain, wire: add ClaimTrie to Block Header --- blockchain/blockindex.go | 3 +++ blockchain/error.go | 5 +++++ btcjson/chainsvrresults.go | 2 ++ wire/blockheader.go | 12 ++++++++---- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/blockchain/blockindex.go b/blockchain/blockindex.go index 2ff2fa27..1531e6b1 100644 --- a/blockchain/blockindex.go +++ b/blockchain/blockindex.go @@ -93,6 +93,7 @@ type blockNode struct { nonce uint32 timestamp int64 merkleRoot chainhash.Hash + claimTrie chainhash.Hash // status is a bitfield representing the validation state of the block. The // status field, unlike the other fields, may be written to and so should @@ -114,6 +115,7 @@ func initBlockNode(node *blockNode, blockHeader *wire.BlockHeader, parent *block nonce: blockHeader.Nonce, timestamp: blockHeader.Timestamp.Unix(), merkleRoot: blockHeader.MerkleRoot, + claimTrie: blockHeader.ClaimTrie, } if parent != nil { node.parent = parent @@ -144,6 +146,7 @@ func (node *blockNode) Header() wire.BlockHeader { Version: node.version, PrevBlock: *prevHash, MerkleRoot: node.merkleRoot, + ClaimTrie: node.claimTrie, Timestamp: time.Unix(node.timestamp, 0), Bits: node.bits, Nonce: node.nonce, diff --git a/blockchain/error.go b/blockchain/error.go index 1e7c879b..f18648f3 100644 --- a/blockchain/error.go +++ b/blockchain/error.go @@ -220,6 +220,10 @@ const ( // current chain tip. This is not a block validation rule, but is required // for block proposals submitted via getblocktemplate RPC. ErrPrevBlockNotBest + + // ErrBadClaimTrie indicates the calculated ClaimTrie root does not match + // the expected value. + ErrBadClaimTrie ) // Map of ErrorCode values back to their constant names for pretty printing. @@ -267,6 +271,7 @@ var errorCodeStrings = map[ErrorCode]string{ ErrPreviousBlockUnknown: "ErrPreviousBlockUnknown", ErrInvalidAncestorBlock: "ErrInvalidAncestorBlock", ErrPrevBlockNotBest: "ErrPrevBlockNotBest", + ErrBadClaimTrie: "ErrBadClaimTrie", } // String returns the ErrorCode as a human-readable name. diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 59f18c74..405fd867 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -25,6 +25,7 @@ type GetBlockHeaderVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` + ClaimTrie string `json:"claimtrie"` Time int64 `json:"time"` Nonce uint64 `json:"nonce"` Bits string `json:"bits"` @@ -81,6 +82,7 @@ type GetBlockVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` + ClaimTrie string `json:"claimTrie"` Tx []string `json:"tx,omitempty"` RawTx []TxRawResult `json:"rawtx,omitempty"` // Note: this field is always empty when verbose != 2. Time int64 `json:"time"` diff --git a/wire/blockheader.go b/wire/blockheader.go index 9c9c2237..b4d0531e 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -15,7 +15,7 @@ import ( // MaxBlockHeaderPayload is the maximum number of bytes a block header can be. // Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes + // PrevBlock and MerkleRoot hashes. -const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 2) +const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 3) // BlockHeader defines information about a block and is used in the bitcoin // block (MsgBlock) and headers (MsgHeaders) messages. @@ -29,6 +29,9 @@ type BlockHeader struct { // Merkle tree reference to hash of all transactions for the block. MerkleRoot chainhash.Hash + // ClaimTrie reference to hash of ClaimTrie. + ClaimTrie chainhash.Hash + // Time the block was created. This is, unfortunately, encoded as a // uint32 on the wire and therefore is limited to 2106. Timestamp time.Time @@ -96,7 +99,7 @@ func (h *BlockHeader) Serialize(w io.Writer) error { // block hash, merkle root hash, difficulty bits, and nonce used to generate the // block with defaults for the remaining fields. func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, - bits uint32, nonce uint32) *BlockHeader { + claimTrieHash *chainhash.Hash, bits uint32, nonce uint32) *BlockHeader { // Limit the timestamp to one second precision since the protocol // doesn't support better. @@ -104,6 +107,7 @@ func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, Version: version, PrevBlock: *prevHash, MerkleRoot: *merkleRootHash, + ClaimTrie: *claimTrieHash, Timestamp: time.Unix(time.Now().Unix(), 0), Bits: bits, Nonce: nonce, @@ -115,7 +119,7 @@ func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, // decoding from the wire. func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { return readElements(r, &bh.Version, &bh.PrevBlock, &bh.MerkleRoot, - (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) + &bh.ClaimTrie, (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) } // writeBlockHeader writes a bitcoin block header to w. See Serialize for @@ -124,5 +128,5 @@ func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error { sec := uint32(bh.Timestamp.Unix()) return writeElements(w, bh.Version, &bh.PrevBlock, &bh.MerkleRoot, - sec, bh.Bits, bh.Nonce) + &bh.ClaimTrie, sec, bh.Bits, bh.Nonce) } -- 2.45.2 From 9f479837c1fc2755bb6c752cd996ae10a8bda9ca Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 24 May 2018 00:00:35 -0700 Subject: [PATCH 329/459] [lbry] blockchain: change max block size to 2,000,000 --- blockchain/fullblocktests/generate.go | 2 +- blockchain/weight.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index 82d3a036..aee67810 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -31,7 +31,7 @@ const ( // Intentionally defined here rather than using constants from codebase // to ensure consensus changes are detected. maxBlockSigOps = 20000 - maxBlockSize = 1000000 + maxBlockSize = 2000000 minCoinbaseScriptLen = 2 maxCoinbaseScriptLen = 100 medianTimeBlocks = 11 diff --git a/blockchain/weight.go b/blockchain/weight.go index 6f6292a1..e23dd87d 100644 --- a/blockchain/weight.go +++ b/blockchain/weight.go @@ -24,7 +24,7 @@ const ( // MaxBlockBaseSize is the maximum number of bytes within a block // which can be allocated to non-witness data. - MaxBlockBaseSize = 1000000 + MaxBlockBaseSize = 2000000 // MaxBlockSigOpsCost is the maximum number of signature operations // allowed for a block. It is calculated via a weighted algorithm which -- 2.45.2 From 03989a91d9a4346b4408c0b8574fdaaf750fc819 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 28 May 2018 21:06:46 -0700 Subject: [PATCH 330/459] [lbry] blockchain, wire: verify blockheaders using LBRY PoW --- blockchain/validate.go | 2 +- wire/blockheader.go | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index f41d54e6..f7831469 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -324,7 +324,7 @@ func checkProofOfWork(header *wire.BlockHeader, powLimit *big.Int, flags Behavio // to avoid proof of work checks is set. if flags&BFNoPoWCheck != BFNoPoWCheck { // The block hash must be less than the claimed target. - hash := header.BlockHash() + hash := header.BlockPoWHash() hashNum := HashToBig(&hash) if hashNum.Cmp(target) > 0 { str := fmt.Sprintf("block hash of %064x is higher than "+ diff --git a/wire/blockheader.go b/wire/blockheader.go index b4d0531e..ee45ec3b 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -59,6 +59,18 @@ func (h *BlockHeader) BlockHash() chainhash.Hash { return chainhash.DoubleHashH(buf.Bytes()) } +// BlockPoWHash computes the block identifier hash for the given block header. +func (h *BlockHeader) BlockPoWHash() chainhash.Hash { + // Encode the header and double sha256 everything prior to the number of + // transactions. Ignore the error returns since there is no way the + // encode could fail except being out of memory which would cause a + // run-time panic. + buf := bytes.NewBuffer(make([]byte, 0, MaxBlockHeaderPayload)) + _ = writeBlockHeader(buf, 0, h) + + return chainhash.LbryPoWHashH(buf.Bytes()) +} + // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. // See Deserialize for decoding block headers stored to disk, such as in a -- 2.45.2 From b2d0ae301eb9ab84271f55185949a6590239c49b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 5 Jun 2018 10:31:39 -0700 Subject: [PATCH 331/459] [lbry] blockchain, txscript: change maxScriptElementSize from 520 t0 20,000 bytes --- blockchain/fullblocktests/generate.go | 4 ++-- txscript/script.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index aee67810..592a14de 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -35,7 +35,7 @@ const ( minCoinbaseScriptLen = 2 maxCoinbaseScriptLen = 100 medianTimeBlocks = 11 - maxScriptElementSize = 520 + maxScriptElementSize = 20000 // numLargeReorgBlocks is the number of blocks to use in the large block // reorg test (when enabled). This is the equivalent of 1 week's worth @@ -1875,7 +1875,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { // // Comment assumptions: // maxBlockSigOps = 20000 - // maxScriptElementSize = 520 + // maxScriptElementSize = 20000 // // [0-19999] : OP_CHECKSIG // [20000] : OP_PUSHDATA4 diff --git a/txscript/script.go b/txscript/script.go index 696bfe2d..1b3a60bd 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -39,9 +39,9 @@ const ( // These are the constants specified for maximums in individual scripts. const ( - MaxOpsPerScript = 201 // Max number of non-push operations. - MaxPubKeysPerMultiSig = 20 // Multisig can't have more sigs than this. - MaxScriptElementSize = 520 // Max bytes pushable to the stack. + MaxOpsPerScript = 201 // Max number of non-push operations. + MaxPubKeysPerMultiSig = 20 // Multisig can't have more sigs than this. + MaxScriptElementSize = 20000 // Max bytes pushable to the stack. ) // isSmallInt returns whether or not the opcode is considered a small integer, -- 2.45.2 From 4bfd69e23dcad2d143c3f956a8a510d41462ec5c Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 6 Jun 2018 13:22:50 -0700 Subject: [PATCH 332/459] [lbry] blockchain: make UTXO in Genesis block spendable --- blockchain/chain.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/blockchain/chain.go b/blockchain/chain.go index eea603ce..1a95a00b 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1764,6 +1764,20 @@ func New(config *Config) (*BlockChain, error) { return nil, err } + // Helper function to insert the output in genesis block in to the + // transaction database. + fn := func(dbTx database.Tx) error { + genesisBlock := btcutil.NewBlock(b.chainParams.GenesisBlock) + view := NewUtxoViewpoint() + if err := view.connectTransactions(genesisBlock, nil); err != nil { + return err + } + return dbPutUtxoView(dbTx, view) + } + if err := b.db.Update(fn); err != nil { + return nil, err + } + // Perform any upgrades to the various chain-specific buckets as needed. if err := b.maybeUpgradeDbBuckets(config.Interrupt); err != nil { return nil, err -- 2.45.2 From e63ede0311134a9fa57c36b2815d46843fc201cb Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 12 Jun 2018 17:27:22 -0700 Subject: [PATCH 333/459] [lbry] blockchain: change the difficulty adjustment algorithm. adjusted := target + (actual - target) / 8 max := target + (target / 2) min := target - (target / 8) if adjusted > max { adjusted = max } else if adj < min { adjusted = min } diffculty := lastDifficulty * adjusted / target --- blockchain/chain.go | 5 ++-- blockchain/difficulty.go | 56 +++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index 1a95a00b..b4a871b9 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1736,7 +1736,6 @@ func New(config *Config) (*BlockChain, error) { params := config.ChainParams targetTimespan := int64(params.TargetTimespan / time.Second) targetTimePerBlock := int64(params.TargetTimePerBlock / time.Second) - adjustmentFactor := params.RetargetAdjustmentFactor b := BlockChain{ checkpoints: config.Checkpoints, checkpointsByHeight: checkpointsByHeight, @@ -1745,8 +1744,8 @@ func New(config *Config) (*BlockChain, error) { timeSource: config.TimeSource, sigCache: config.SigCache, indexManager: config.IndexManager, - minRetargetTimespan: targetTimespan / adjustmentFactor, - maxRetargetTimespan: targetTimespan * adjustmentFactor, + minRetargetTimespan: targetTimespan - (targetTimespan / 8), + maxRetargetTimespan: targetTimespan + (targetTimespan / 2), blocksPerRetarget: int32(targetTimespan / targetTimePerBlock), index: newBlockIndex(config.DB, params), hashCache: config.HashCache, diff --git a/blockchain/difficulty.go b/blockchain/difficulty.go index 05f78a3e..3eae3844 100644 --- a/blockchain/difficulty.go +++ b/blockchain/difficulty.go @@ -159,7 +159,6 @@ func CalcWork(bits uint32) *big.Int { func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 { // Convert types used in the calculations below. durationVal := int64(duration / time.Second) - adjustmentFactor := big.NewInt(b.chainParams.RetargetAdjustmentFactor) // The test network rules allow minimum difficulty blocks after more // than twice the desired amount of time needed to generate a block has @@ -178,7 +177,8 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) // multiplied by the max adjustment factor. newTarget := CompactToBig(bits) for durationVal > 0 && newTarget.Cmp(b.chainParams.PowLimit) < 0 { - newTarget.Mul(newTarget, adjustmentFactor) + adj := new(big.Int).Div(newTarget, big.NewInt(2)) + newTarget.Add(newTarget, adj) durationVal -= b.maxRetargetTimespan } @@ -224,47 +224,44 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim return b.chainParams.PowLimitBits, nil } - // Return the previous block's difficulty requirements if this block - // is not at a difficulty retarget interval. - if (lastNode.height+1)%b.blocksPerRetarget != 0 { - // For networks that support it, allow special reduction of the - // required difficulty once too much time has elapsed without - // mining a block. - if b.chainParams.ReduceMinDifficulty { - // Return minimum difficulty when more than the desired - // amount of time has elapsed without mining a block. - reductionTime := int64(b.chainParams.MinDiffReductionTime / - time.Second) - allowMinTime := lastNode.timestamp + reductionTime - if newBlockTime.Unix() > allowMinTime { - return b.chainParams.PowLimitBits, nil - } - - // The block was mined within the desired timeframe, so - // return the difficulty for the last block which did - // not have the special minimum difficulty rule applied. - return b.findPrevTestNetDifficulty(lastNode), nil + // For networks that support it, allow special reduction of the + // required difficulty once too much time has elapsed without + // mining a block. + if b.chainParams.ReduceMinDifficulty { + // Return minimum difficulty when more than the desired + // amount of time has elapsed without mining a block. + reductionTime := int64(b.chainParams.MinDiffReductionTime / + time.Second) + allowMinTime := lastNode.timestamp + reductionTime + if newBlockTime.Unix() > allowMinTime { + return b.chainParams.PowLimitBits, nil } - // For the main network (or any unrecognized networks), simply - // return the previous block's difficulty requirements. - return lastNode.bits, nil + // The block was mined within the desired timeframe, so + // return the difficulty for the last block which did + // not have the special minimum difficulty rule applied. + return b.findPrevTestNetDifficulty(lastNode), nil } // Get the block node at the previous retarget (targetTimespan days // worth of blocks). - firstNode := lastNode.RelativeAncestor(b.blocksPerRetarget - 1) + firstNode := lastNode.RelativeAncestor(b.blocksPerRetarget) + if lastNode.height == 0 { + firstNode = lastNode + } if firstNode == nil { return 0, AssertError("unable to obtain previous retarget block") } + targetTimeSpan := int64(b.chainParams.TargetTimespan / time.Second) + // Limit the amount of adjustment that can occur to the previous // difficulty. actualTimespan := lastNode.timestamp - firstNode.timestamp - adjustedTimespan := actualTimespan - if actualTimespan < b.minRetargetTimespan { + adjustedTimespan := targetTimeSpan + (actualTimespan-targetTimeSpan)/8 + if adjustedTimespan < b.minRetargetTimespan { adjustedTimespan = b.minRetargetTimespan - } else if actualTimespan > b.maxRetargetTimespan { + } else if adjustedTimespan > b.maxRetargetTimespan { adjustedTimespan = b.maxRetargetTimespan } @@ -275,7 +272,6 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim // result. oldTarget := CompactToBig(lastNode.bits) newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan)) - targetTimeSpan := int64(b.chainParams.TargetTimespan / time.Second) newTarget.Div(newTarget, big.NewInt(targetTimeSpan)) // Limit new value to the proof of work limit. -- 2.45.2 From 767a3758165e7e4546608979b26016ed7a18dd4b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 12 Jun 2018 21:11:42 -0700 Subject: [PATCH 334/459] [lbry] blockchain: change Block Subsidy algorithm --- blockchain/validate.go | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index f7831469..2fd5d7fd 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -40,7 +40,7 @@ const ( // baseSubsidy is the starting subsidy amount for mined blocks. This // value is halved every SubsidyHalvingInterval blocks. - baseSubsidy = 50 * btcutil.SatoshiPerBitcoin + baseSubsidy = 500 * btcutil.SatoshiPerBitcoin ) var ( @@ -192,12 +192,42 @@ func isBIP0030Node(node *blockNode) bool { // At the target block generation rate for the main network, this is // approximately every 4 years. func CalcBlockSubsidy(height int32, chainParams *chaincfg.Params) int64 { - if chainParams.SubsidyReductionInterval == 0 { - return baseSubsidy + h := int64(height) + if h == 0 { + return btcutil.SatoshiPerBitcoin * 4e8 + } + if h <= 5100 { + return btcutil.SatoshiPerBitcoin + } + if h <= 55000 { + return btcutil.SatoshiPerBitcoin * (1 + (h-5001)/100) } - // Equivalent to: baseSubsidy / 2^(height/subsidyHalvingInterval) - return baseSubsidy >> uint(height/chainParams.SubsidyReductionInterval) + lv := (h - 55001) / int64(chainParams.SubsidyReductionInterval) + reduction := (int64(math.Sqrt((float64(8*lv))+1)) - 1) / 2 + for !withinLevelBounds(reduction, lv) { + if ((reduction*reduction + reduction) >> 1) > lv { + reduction-- + } else { + reduction++ + } + } + subsidyReduction := btcutil.SatoshiPerBitcoin * reduction + if subsidyReduction >= baseSubsidy { + return 0 + } + return baseSubsidy - subsidyReduction +} + +func withinLevelBounds(reduction int64, lv int64) bool { + if ((reduction*reduction + reduction) >> 1) > lv { + return false + } + reduction++ + if ((reduction*reduction + reduction) >> 1) <= lv { + return false + } + return true } // CheckTransactionSanity performs some preliminary checks on a transaction to -- 2.45.2 From 4a987b068d66ac37a86b9af4888855e627517092 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 15 Jun 2018 13:06:26 -0700 Subject: [PATCH 335/459] [lbry] blockchain, mempool: validate txscripts Co-authored-by: Brannon King --- blockchain/validate.go | 11 ++++++++--- mempool/mempool.go | 2 +- mempool/policy.go | 7 ++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index 2fd5d7fd..ef2c283b 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -231,8 +231,8 @@ func withinLevelBounds(reduction int64, lv int64) bool { } // CheckTransactionSanity performs some preliminary checks on a transaction to -// ensure it is sane. These checks are context free. -func CheckTransactionSanity(tx *btcutil.Tx) error { +// ensure it is sane. +func CheckTransactionSanity(tx *btcutil.Tx, enforceSoftFork bool) error { // A transaction must have at least one input. msgTx := tx.MsgTx() if len(msgTx.TxIn) == 0 { @@ -291,6 +291,11 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { btcutil.MaxSatoshi) return ruleError(ErrBadTxOutValue, str) } + + err := txscript.AllClaimsAreSane(txOut.PkScript, enforceSoftFork) + if err != nil { + return ruleError(ErrBadTxOutValue, err.Error()) + } } // Check for duplicate transaction inputs. @@ -545,7 +550,7 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource Median // Do some preliminary checks on each transaction to ensure they are // sane before continuing. for _, tx := range transactions { - err := CheckTransactionSanity(tx) + err := CheckTransactionSanity(tx, false) if err != nil { return err } diff --git a/mempool/mempool.go b/mempool/mempool.go index b54856c8..0aecff7e 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -963,7 +963,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit, rejec // Perform preliminary sanity checks on the transaction. This makes // use of blockchain which contains the invariant rules for what // transactions are allowed into blocks. - err := blockchain.CheckTransactionSanity(tx) + err := blockchain.CheckTransactionSanity(tx, true) if err != nil { if cerr, ok := err.(blockchain.RuleError); ok { return nil, nil, chainRuleError(cerr) diff --git a/mempool/policy.go b/mempool/policy.go index 1fe85079..c18b0d7d 100644 --- a/mempool/policy.go +++ b/mempool/policy.go @@ -99,7 +99,7 @@ func checkInputsStandard(tx *btcutil.Tx, utxoView *blockchain.UtxoViewpoint) err // they have already been checked prior to calling this // function. entry := utxoView.LookupEntry(txIn.PreviousOutPoint) - originPkScript := entry.PkScript() + originPkScript := txscript.StripClaimScriptPrefix(entry.PkScript()) switch txscript.GetScriptClass(originPkScript) { case txscript.ScriptHashTy: numSigOps := txscript.GetPreciseSigOpCount( @@ -339,8 +339,9 @@ func checkTransactionStandard(tx *btcutil.Tx, height int32, // be "dust" (except when the script is a null data script). numNullDataOutputs := 0 for i, txOut := range msgTx.TxOut { - scriptClass := txscript.GetScriptClass(txOut.PkScript) - err := checkPkScriptStandard(txOut.PkScript, scriptClass) + pkScript := txscript.StripClaimScriptPrefix(txOut.PkScript) + scriptClass := txscript.GetScriptClass(pkScript) + err := checkPkScriptStandard(pkScript, scriptClass) if err != nil { // Attempt to extract a reject code from the error so // it can be retained. When not possible, fall back to -- 2.45.2 From 8ff0f3787e9de0e7c9522161d80aa50ce12db217 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 29 Jul 2021 17:21:51 -0400 Subject: [PATCH 336/459] [lbry] blockchain: support force active fork deployment --- blockchain/thresholdstate.go | 6 ++++++ blockchain/versionbits.go | 6 ++++++ rpcserver.go | 1 + 3 files changed, 13 insertions(+) diff --git a/blockchain/thresholdstate.go b/blockchain/thresholdstate.go index 5da74a95..8a79f968 100644 --- a/blockchain/thresholdstate.go +++ b/blockchain/thresholdstate.go @@ -302,6 +302,12 @@ func (b *BlockChain) deploymentState(prevNode *blockNode, deploymentID uint32) ( } deployment := &b.chainParams.Deployments[deploymentID] + + // added to mimic LBRYcrd: + if deployment.ForceActiveAt > 0 && prevNode != nil && prevNode.height+1 >= deployment.ForceActiveAt { + return ThresholdActive, nil + } + checker := deploymentChecker{deployment: deployment, chain: b} cache := &b.deploymentCaches[deploymentID] diff --git a/blockchain/versionbits.go b/blockchain/versionbits.go index 28fcde7b..acdbf144 100644 --- a/blockchain/versionbits.go +++ b/blockchain/versionbits.go @@ -195,6 +195,12 @@ func (b *BlockChain) calcNextBlockVersion(prevNode *blockNode) (int32, error) { expectedVersion := uint32(vbTopBits) for id := 0; id < len(b.chainParams.Deployments); id++ { deployment := &b.chainParams.Deployments[id] + + // added to mimic LBRYcrd: + if deployment.ForceActiveAt > 0 && prevNode != nil && prevNode.height+1 >= deployment.ForceActiveAt { + continue + } + cache := &b.deploymentCaches[id] checker := deploymentChecker{deployment: deployment, chain: b} state, err := b.thresholdState(prevNode, checker, cache) diff --git a/rpcserver.go b/rpcserver.go index d1840729..4502a4cd 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1294,6 +1294,7 @@ func handleGetBlockChainInfo(s *rpcServer, cmd interface{}, closeChan <-chan str Bit: deploymentDetails.BitNumber, StartTime2: int64(deploymentDetails.StartTime), Timeout: int64(deploymentDetails.ExpireTime), + Since: deploymentDetails.ForceActiveAt, } } -- 2.45.2 From 4eb4dfa67096e41664081964bb340c825d288026 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 15:24:20 -0700 Subject: [PATCH 337/459] [lbry] blockchain: Consider a block with timestamp less 6 hours 'current' --- blockchain/chain.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index b4a871b9..79bb3d74 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1208,7 +1208,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla // factors are used to guess, but the key factors that allow the chain to // believe it is current are: // - Latest block height is after the latest checkpoint (if enabled) -// - Latest block has a timestamp newer than 24 hours ago +// - Latest block has a timestamp newer than ~6 hours ago (as LBRY block time is one fourth of bitcoin) // // This function MUST be called with the chain state lock held (for reads). func (b *BlockChain) isCurrent() bool { @@ -1219,13 +1219,13 @@ func (b *BlockChain) isCurrent() bool { return false } - // Not current if the latest best block has a timestamp before 24 hours + // Not current if the latest best block has a timestamp before 7 hours // ago. // // The chain appears to be current if none of the checks reported // otherwise. - minus24Hours := b.timeSource.AdjustedTime().Add(-24 * time.Hour).Unix() - return b.bestChain.Tip().timestamp >= minus24Hours + hours := b.timeSource.AdjustedTime().Add(-7 * time.Hour).Unix() + return b.bestChain.Tip().timestamp >= hours } // IsCurrent returns whether or not the chain believes it is current. Several -- 2.45.2 From 93481d7f3aada82ce9942d0a65aaddd704752883 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Jun 2018 20:20:44 -0700 Subject: [PATCH 338/459] [lbry] server: update client version to /btcwire:0.5.0/LBRY.GO:0.12.2/ TODO: double check if lbryd bumps the version. --- server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.go b/server.go index 746c48dd..6506c95d 100644 --- a/server.go +++ b/server.go @@ -62,7 +62,7 @@ const ( var ( // userAgentName is the user agent name and is used to help identify // ourselves to other bitcoin peers. - userAgentName = "btcd" + userAgentName = "LBRY.GO" // userAgentVersion is the user agent version and is used to help // identify ourselves to other bitcoin peers. -- 2.45.2 From 44dd82a9f5f29243ff1ee79f4a86386c339c3a71 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 14 Oct 2021 17:43:23 -0400 Subject: [PATCH 339/459] [lbry] server: don't ban peers on tx-not-in-block behavior --- server.go | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/server.go b/server.go index 6506c95d..c5fc4aff 100644 --- a/server.go +++ b/server.go @@ -387,11 +387,13 @@ func (sp *serverPeer) addBanScore(persistent, transient uint32, reason string) b } score := sp.banScore.Increase(persistent, transient) if score > warnThreshold { - peerLog.Warnf("Misbehaving peer %s: %s -- ban score increased to %d", - sp, reason, score) + peerLog.Warnf("Misbehaving peer %s: %s -- ban score increased to %d", sp, reason, score) if score > cfg.BanThreshold { - peerLog.Warnf("Misbehaving peer %s -- banning and disconnecting", - sp) + if sp.server.ConnectedCount() <= 1 { + peerLog.Warnf("Refusing to ban peer %s as it is the only peer", sp) + return false + } + peerLog.Warnf("Misbehaving peer %s -- banning and disconnecting", sp) sp.server.BanPeer(sp) sp.Disconnect() return true @@ -1328,24 +1330,28 @@ func (sp *serverPeer) OnNotFound(p *peer.Peer, msg *wire.MsgNotFound) { case wire.InvTypeWitnessTx: numTxns++ default: - peerLog.Debugf("Invalid inv type '%d' in notfound message from %s", - inv.Type, sp) + peerLog.Infof("Invalid inv type '%d' in NotFound message from %s. Disconnecting...", inv.Type, sp) sp.Disconnect() return } } if numBlocks > 0 { blockStr := pickNoun(uint64(numBlocks), "block", "blocks") - reason := fmt.Sprintf("%d %v not found", numBlocks, blockStr) - if sp.addBanScore(20*numBlocks, 0, reason) { - return + reason := fmt.Sprintf("%d %v not found on %s", numBlocks, blockStr, sp) + if sp.addBanScore(20, 0, reason) { + return // once they fail to return us five block requests they're gone for good } } if numTxns > 0 { - txStr := pickNoun(uint64(numTxns), "transaction", "transactions") - reason := fmt.Sprintf("%d %v not found", numBlocks, txStr) - if sp.addBanScore(0, 10*numTxns, reason) { - return + // This is an expected situation if transactions in the mempool make it into a block before + // this node knows about said block. We don't want to ban them for that alone + peerLog.Debugf("%d transactions not found on %s", numTxns, sp) + if numBlocks+numTxns < wire.MaxInvPerMsg { // if our message is full then it is likely followed by another one that isn't + txStr := pickNoun(uint64(numTxns), "transaction", "transactions") + reason := fmt.Sprintf("%d %v not found on %s", numTxns, txStr, sp) + if sp.addBanScore(0, 20, reason) { + return // if they fail us five times in one minute, they're gone -- hitting them at new-block should be rare + } } } -- 2.45.2 From 33328a3e9367105d36de30effad8b941b11a5921 Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Fri, 29 Oct 2021 16:21:54 -0400 Subject: [PATCH 340/459] [lbry] server: make uptime rpc return a real uptime --- server.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/server.go b/server.go index c5fc4aff..f5ec3705 100644 --- a/server.go +++ b/server.go @@ -203,7 +203,6 @@ type server struct { started int32 shutdown int32 shutdownSched int32 - startupTime int64 chainParams *chaincfg.Params addrManager *addrmgr.AddrManager @@ -2371,9 +2370,6 @@ func (s *server) Start() { srvrLog.Trace("Starting server") - // Server startup time. Used for the uptime command for uptime calculation. - s.startupTime = time.Now().Unix() - // Start the peer handler which in turn starts the address and block // managers. s.wg.Add(1) @@ -2631,6 +2627,8 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, db database.DB, chainParams *chaincfg.Params, interrupt <-chan struct{}) (*server, error) { + startupTime := time.Now() + services := defaultServices if cfg.NoPeerBloomFilters { services &^= wire.SFNodeBloom @@ -2937,7 +2935,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, s.rpcServer, err = newRPCServer(&rpcserverConfig{ Listeners: rpcListeners, - StartupTime: s.startupTime, + StartupTime: startupTime.Unix(), ConnMgr: &rpcConnManager{&s}, SyncMgr: &rpcSyncMgr{&s, s.syncManager}, TimeSource: s.timeSource, -- 2.45.2 From 7657419b2208e06a1ffa144b10b2b388871d4928 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 5 Jun 2018 10:32:45 -0700 Subject: [PATCH 341/459] [lbry] txscript: change MaxScriptSize from 10,000 to 20,005 --- txscript/engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/txscript/engine.go b/txscript/engine.go index 0814e7eb..40ba0eef 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -103,7 +103,7 @@ const ( MaxStackSize = 1000 // MaxScriptSize is the maximum allowed length of a raw script. - MaxScriptSize = 10000 + MaxScriptSize = 20005 // payToWitnessPubKeyHashDataSize is the size of the witness program's // data push for a pay-to-witness-pub-key-hash output. -- 2.45.2 From 2b28dfa528e38a75b0bd1f53ca7578163f27a9ac Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Jun 2018 19:13:08 -0700 Subject: [PATCH 342/459] [lbry] txscript: introduce claim script Co-authored-by: Brannon King --- txscript/claimscript.go | 216 +++++++++++++++++++++++++++++++++++ txscript/claimscript_test.go | 80 +++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 txscript/claimscript.go create mode 100644 txscript/claimscript_test.go diff --git a/txscript/claimscript.go b/txscript/claimscript.go new file mode 100644 index 00000000..1737ff60 --- /dev/null +++ b/txscript/claimscript.go @@ -0,0 +1,216 @@ +package txscript + +import ( + "bytes" + "fmt" + "unicode/utf8" +) + +const ( + // MaxClaimScriptSize is the max claim script size in bytes, not including the script pubkey part of the script. + MaxClaimScriptSize = 8192 + + // MaxClaimNameSize is the max claim name size in bytes, for all claim trie transactions. + MaxClaimNameSize = 255 + + ClaimIDLength = 160 / 8 + + claimScriptVersion = 0 +) + +// These constants are used to identify a specific claim script Error. +// The error code starts from 200, which leaves enough room between the rest +// of script error codes (numErrorCodes) +const ( + // ErrNotClaimScript is returned when the script does not have a ClaimScript Opcode. + ErrNotClaimScript ErrorCode = iota + 200 + + // ErrInvalidClaimNameScript is returned a claim name script does not conform to the format. + ErrInvalidClaimNameScript + + // ErrInvalidClaimSupportScript is returned a claim support script does not conform to the format. + ErrInvalidClaimSupportScript + + // ErrInvalidClaimUpdateScript is returned a claim update script does not conform to the format. + ErrInvalidClaimUpdateScript +) + +func claimScriptError(c ErrorCode, desc string) Error { + return Error{ErrorCode: c, Description: desc} +} + +// ClaimNameScript creates a claim name script. +func ClaimNameScript(name string, value string) ([]byte, error) { + return NewScriptBuilder().AddOp(OP_CLAIMNAME).AddData([]byte(name)).AddData([]byte(value)). + AddOp(OP_2DROP).AddOp(OP_DROP).AddOp(OP_TRUE).Script() +} + +// ClaimSupportScript creates a support claim script. +func ClaimSupportScript(name string, claimID []byte, value []byte) ([]byte, error) { + builder := NewScriptBuilder().AddOp(OP_SUPPORTCLAIM).AddData([]byte(name)).AddData(claimID) + if len(value) > 0 { + return builder.addData(value).AddOp(OP_2DROP).AddOp(OP_2DROP).AddOp(OP_TRUE).Script() + } + return builder.AddOp(OP_2DROP).AddOp(OP_DROP).AddOp(OP_TRUE).Script() +} + +// ClaimUpdateScript creates an update claim script. +func ClaimUpdateScript(name string, claimID []byte, value string) ([]byte, error) { + return NewScriptBuilder().AddOp(OP_UPDATECLAIM).AddData([]byte(name)).AddData(claimID).AddData([]byte(value)). + AddOp(OP_2DROP).AddOp(OP_2DROP).AddOp(OP_TRUE).Script() +} + +// ClaimScript represents of one of the ClaimNameScript, ClaimSupportScript, and ClaimUpdateScript. +type ClaimScript struct { + Opcode byte + Name []byte + ClaimID []byte + Value []byte + Size int +} + +// ExtractClaimScript exctracts the claim script from the script if it has one. +// The returned ClaimScript is invalidated if the given script is modified. +func ExtractClaimScript(script []byte) (*ClaimScript, error) { + + var cs ClaimScript + + tokenizer := MakeScriptTokenizer(claimScriptVersion, script) + if !tokenizer.Next() { + return nil, claimScriptError(ErrNotClaimScript, "not a claim script opcode") + } + + cs.Opcode = tokenizer.Opcode() + + switch tokenizer.Opcode() { + case OP_CLAIMNAME: + // OP_CLAIMNAME OP_2DROP OP_DROP + if !tokenizer.Next() || len(tokenizer.Data()) > MaxClaimNameSize { + str := fmt.Sprintf("name size %d exceeds limit %d", len(tokenizer.data), MaxClaimNameSize) + return nil, claimScriptError(ErrInvalidClaimNameScript, str) + } + cs.Name = tokenizer.data + + if !tokenizer.Next() { + return nil, claimScriptError(ErrInvalidClaimNameScript, "expect value") + } + cs.Value = tokenizer.Data() + + if !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP || + !tokenizer.Next() || tokenizer.Opcode() != OP_DROP { + str := fmt.Sprintf("expect OP_2DROP OP_DROP") + return nil, claimScriptError(ErrInvalidClaimNameScript, str) + } + + cs.Size = int(tokenizer.ByteIndex()) + return &cs, nil + + case OP_SUPPORTCLAIM: + // OP_SUPPORTCLAIM OP_2DROP OP_DROP + // OP_SUPPORTCLAIM OP_2DROP OP_2DROP + if !tokenizer.Next() || len(tokenizer.Data()) > MaxClaimNameSize { + str := fmt.Sprintf("name size %d exceeds limit %d", len(tokenizer.data), MaxClaimNameSize) + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + cs.Name = tokenizer.data + + if !tokenizer.Next() || len(tokenizer.Data()) != ClaimIDLength { + str := fmt.Sprintf("expect claim id length %d, instead of %d", ClaimIDLength, len(tokenizer.data)) + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + cs.ClaimID = tokenizer.Data() + + if !tokenizer.Next() { + return nil, claimScriptError(ErrInvalidClaimSupportScript, "incomplete script") + } + + switch { + case tokenizer.Opcode() == OP_2DROP: + // Case 1: OP_SUPPORTCLAIM OP_2DROP OP_DROP + if !tokenizer.Next() || tokenizer.Opcode() != OP_DROP { + str := fmt.Sprintf("expect OP_2DROP OP_DROP") + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + + case len(tokenizer.Data()) != 0: + // Case 2: OP_SUPPORTCLAIM OP_2DROP OP_2DROP + // (old bug: non-length size dummy value?) + cs.Value = tokenizer.Data() + if !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP || + !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP { + str := fmt.Sprintf("expect OP_2DROP OP_2DROP") + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + default: + str := fmt.Sprintf("expect OP_2DROP OP_DROP") + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + + cs.Size = int(tokenizer.ByteIndex()) + return &cs, nil + + case OP_UPDATECLAIM: + + // OP_UPDATECLAIM OP_2DROP OP_2DROP + if !tokenizer.Next() || len(tokenizer.Data()) > MaxClaimNameSize { + str := fmt.Sprintf("name size %d exceeds limit %d", len(tokenizer.data), MaxClaimNameSize) + return nil, claimScriptError(ErrInvalidClaimUpdateScript, str) + } + cs.Name = tokenizer.data + + if !tokenizer.Next() || len(tokenizer.Data()) != ClaimIDLength { + str := fmt.Sprintf("expect claim id length %d, instead of %d", ClaimIDLength, len(tokenizer.data)) + return nil, claimScriptError(ErrInvalidClaimUpdateScript, str) + } + cs.ClaimID = tokenizer.Data() + + if !tokenizer.Next() { + str := fmt.Sprintf("expect value") + return nil, claimScriptError(ErrInvalidClaimUpdateScript, str) + } + cs.Value = tokenizer.Data() + + if !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP || + !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP { + str := fmt.Sprintf("expect OP_2DROP OP_2DROP") + return nil, claimScriptError(ErrInvalidClaimUpdateScript, str) + } + + cs.Size = int(tokenizer.ByteIndex()) + return &cs, nil + + default: + return nil, claimScriptError(ErrNotClaimScript, "") + } +} + +// StripClaimScriptPrefix strips prefixed claim script, if any. +func StripClaimScriptPrefix(script []byte) []byte { + cs, err := ExtractClaimScript(script) + if err != nil { + return script + } + return script[cs.Size:] +} + +const illegalChars = "=&#:*$%?/;\\\b\n\t\r\x00" + +func AllClaimsAreSane(script []byte, enforceSoftFork bool) error { + cs, err := ExtractClaimScript(script) + if IsErrorCode(err, ErrNotClaimScript) { + return nil + } + if err != nil { + return err + } + if enforceSoftFork { + if !utf8.Valid(cs.Name) { + return fmt.Errorf("claim name is not valid UTF-8") + } + if bytes.ContainsAny(cs.Name, illegalChars) { + return fmt.Errorf("claim name has illegal chars; it should not contain any of these: %s", illegalChars) + } + } + + return nil +} diff --git a/txscript/claimscript_test.go b/txscript/claimscript_test.go new file mode 100644 index 00000000..ef2d2b02 --- /dev/null +++ b/txscript/claimscript_test.go @@ -0,0 +1,80 @@ +package txscript + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCreationParseLoopClaim(t *testing.T) { + + r := require.New(t) + + // OP_CLAIMNAME OP_2DROP OP_DROP + script, err := ClaimNameScript("tester", "value") + r.NoError(err) + cs, err := ExtractClaimScript(script) + r.NoError(err) + r.Equal(byte(OP_CLAIMNAME), cs.Opcode) + r.Equal([]byte("tester"), cs.Name) + r.Equal([]byte("value"), cs.Value) +} + +func TestCreationParseLoopUpdate(t *testing.T) { + + r := require.New(t) + + claimID := []byte("12345123451234512345") + claim, err := ClaimUpdateScript("tester", claimID, "value") + r.NoError(err) + cs, err := ExtractClaimScript(claim) + r.NoError(err) + r.Equal(byte(OP_UPDATECLAIM), cs.Opcode) + r.Equal([]byte("tester"), cs.Name) + r.Equal(claimID, cs.ClaimID) + r.Equal([]byte("value"), cs.Value) +} + +func TestCreationParseLoopSupport(t *testing.T) { + + r := require.New(t) + + claimID := []byte("12345123451234512345") + + // case 1: OP_SUPPORTCLAIM OP_2DROP OP_DROP + script, err := ClaimSupportScript("tester", claimID, nil) + r.NoError(err) + cs, err := ExtractClaimScript(script) + r.NoError(err) + + r.Equal(byte(OP_SUPPORTCLAIM), cs.Opcode) + r.Equal([]byte("tester"), cs.Name) + r.Equal(claimID, cs.ClaimID) + r.Nil(cs.Value) + + // case 2: OP_SUPPORTCLAIM OP_2DROP OP_2DROP + script, err = ClaimSupportScript("tester", claimID, []byte("value")) + r.NoError(err) + cs, err = ExtractClaimScript(script) + r.NoError(err) + + r.Equal(byte(OP_SUPPORTCLAIM), cs.Opcode) + r.Equal([]byte("tester"), cs.Name) + r.Equal(claimID, cs.ClaimID) + r.Equal([]byte("value"), cs.Value) + +} + +func TestInvalidChars(t *testing.T) { + r := require.New(t) + + script, err := ClaimNameScript("tester", "value") + r.NoError(err) + r.NoError(AllClaimsAreSane(script, true)) + + for i := range []byte(illegalChars) { + script, err := ClaimNameScript("a"+illegalChars[i:i+1], "value") + r.NoError(err) + r.Error(AllClaimsAreSane(script, true)) + } +} -- 2.45.2 From 61a18152e91fe02e0e03bc299adb78a53eae26db Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Jun 2018 19:12:43 -0700 Subject: [PATCH 343/459] [lbry] txscript: recognize LBRY claim script OPCODES --- txscript/opcode.go | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/txscript/opcode.go b/txscript/opcode.go index 4c31be3f..4c00f353 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -220,9 +220,9 @@ const ( OP_CHECKSEQUENCEVERIFY = 0xb2 // 178 - AKA OP_NOP3 OP_NOP4 = 0xb3 // 179 OP_NOP5 = 0xb4 // 180 - OP_NOP6 = 0xb5 // 181 - OP_NOP7 = 0xb6 // 182 - OP_NOP8 = 0xb7 // 183 + OP_CLAIMNAME = 0xb5 // 181 - AKA OP_NOP6 + OP_SUPPORTCLAIM = 0xb6 // 182 - AKA OP_NOP7 + OP_UPDATECLAIM = 0xb7 // 183 - AKA OP_NOP8 OP_NOP9 = 0xb8 // 184 OP_NOP10 = 0xb9 // 185 OP_UNKNOWN186 = 0xba // 186 @@ -501,14 +501,14 @@ var opcodeArray = [256]opcode{ OP_CHECKMULTISIGVERIFY: {OP_CHECKMULTISIGVERIFY, "OP_CHECKMULTISIGVERIFY", 1, opcodeCheckMultiSigVerify}, // Reserved opcodes. - OP_NOP1: {OP_NOP1, "OP_NOP1", 1, opcodeNop}, - OP_NOP4: {OP_NOP4, "OP_NOP4", 1, opcodeNop}, - OP_NOP5: {OP_NOP5, "OP_NOP5", 1, opcodeNop}, - OP_NOP6: {OP_NOP6, "OP_NOP6", 1, opcodeNop}, - OP_NOP7: {OP_NOP7, "OP_NOP7", 1, opcodeNop}, - OP_NOP8: {OP_NOP8, "OP_NOP8", 1, opcodeNop}, - OP_NOP9: {OP_NOP9, "OP_NOP9", 1, opcodeNop}, - OP_NOP10: {OP_NOP10, "OP_NOP10", 1, opcodeNop}, + OP_NOP1: {OP_NOP1, "OP_NOP1", 1, opcodeNop}, + OP_NOP4: {OP_NOP4, "OP_NOP4", 1, opcodeNop}, + OP_NOP5: {OP_NOP5, "OP_NOP5", 1, opcodeNop}, + OP_CLAIMNAME: {OP_CLAIMNAME, "OP_CLAIMNAME", 1, opcodeClaimScript}, + OP_SUPPORTCLAIM: {OP_SUPPORTCLAIM, "OP_SUPPORTCLAIM", 1, opcodeClaimScript}, + OP_UPDATECLAIM: {OP_UPDATECLAIM, "OP_UPDATECLAIM", 1, opcodeClaimScript}, + OP_NOP9: {OP_NOP9, "OP_NOP9", 1, opcodeNop}, + OP_NOP10: {OP_NOP10, "OP_NOP10", 1, opcodeNop}, // Undefined opcodes. OP_UNKNOWN186: {OP_UNKNOWN186, "OP_UNKNOWN186", 1, opcodeInvalid}, @@ -725,8 +725,7 @@ func opcodeN(op *opcode, data []byte, vm *Engine) error { func opcodeNop(op *opcode, data []byte, vm *Engine) error { switch op.value { case OP_NOP1, OP_NOP4, OP_NOP5, - OP_NOP6, OP_NOP7, OP_NOP8, OP_NOP9, OP_NOP10: - + OP_NOP9, OP_NOP10: if vm.hasFlag(ScriptDiscourageUpgradableNops) { str := fmt.Sprintf("%v reserved for soft-fork "+ "upgrades", op.name) @@ -736,6 +735,11 @@ func opcodeNop(op *opcode, data []byte, vm *Engine) error { return nil } +func opcodeClaimScript(op *opcode, data []byte, vm *Engine) error { + vm.dstack.PushByteArray([]byte{0}) + return nil +} + // popIfBool enforces the "minimal if" policy during script execution if the // particular flag is set. If so, in order to eliminate an additional source // of nuisance malleability, post-segwit for version 0 witness programs, we now -- 2.45.2 From 78d780263b0bbe43bfa26b60af7bff9dc6a0d2ef Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 23 Jul 2021 12:13:31 -0400 Subject: [PATCH 344/459] [lbry] txscript: remove claim prefix for addr calculation --- txscript/standard.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/txscript/standard.go b/txscript/standard.go index 44902971..2437b3cc 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -906,6 +906,8 @@ func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address { // with an invalid script version error. func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, error) { + pkScript = StripClaimScriptPrefix(pkScript) + // Check for pay-to-pubkey-hash script. if hash := extractPubKeyHash(pkScript); hash != nil { return PubKeyHashTy, pubKeyHashToAddrs(hash, chainParams), 1, nil -- 2.45.2 From ba22414cc1460694d19a3c4b4bb3f7e467af97a4 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 6 Jul 2021 19:38:44 -0700 Subject: [PATCH 345/459] [lbry] log: support claimtrie entries --- log.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/log.go b/log.go index 71accc7c..a69509cd 100644 --- a/log.go +++ b/log.go @@ -13,6 +13,7 @@ import ( "github.com/btcsuite/btcd/addrmgr" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/blockchain/indexers" + "github.com/btcsuite/btcd/claimtrie/node" "github.com/btcsuite/btcd/connmgr" "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcd/mempool" @@ -58,8 +59,9 @@ var ( amgrLog = backendLog.Logger("AMGR") cmgrLog = backendLog.Logger("CMGR") bcdbLog = backendLog.Logger("BCDB") - btcdLog = backendLog.Logger("BTCD") + btcdLog = backendLog.Logger("MAIN") chanLog = backendLog.Logger("CHAN") + lbryLog = backendLog.Logger("LBRY") discLog = backendLog.Logger("DISC") indxLog = backendLog.Logger("INDX") minrLog = backendLog.Logger("MINR") @@ -77,6 +79,7 @@ func init() { connmgr.UseLogger(cmgrLog) database.UseLogger(bcdbLog) blockchain.UseLogger(chanLog) + node.UseLogger(lbryLog) indexers.UseLogger(indxLog) mining.UseLogger(minrLog) cpuminer.UseLogger(minrLog) @@ -92,8 +95,9 @@ var subsystemLoggers = map[string]btclog.Logger{ "AMGR": amgrLog, "CMGR": cmgrLog, "BCDB": bcdbLog, - "BTCD": btcdLog, + "MAIN": btcdLog, "CHAN": chanLog, + "LBRY": lbryLog, "DISC": discLog, "INDX": indxLog, "MINR": minrLog, @@ -115,7 +119,7 @@ func initLogRotator(logFile string) { fmt.Fprintf(os.Stderr, "failed to create log directory: %v\n", err) os.Exit(1) } - r, err := rotator.New(logFile, 10*1024, false, 3) + r, err := rotator.New(logFile, 40*1024, false, 3) if err != nil { fmt.Fprintf(os.Stderr, "failed to create file rotator: %v\n", err) os.Exit(1) -- 2.45.2 From aae5b24bb0dcd6d204d2f9b2ca9367416c56c597 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 5 Aug 2018 13:59:25 -0700 Subject: [PATCH 346/459] [lbry] blockchain: connect to ClaimTrie Co-authored-by: Brannon King --- blockchain/chain.go | 97 ++++++++++++++++++++- blockchain/claimtrie.go | 183 ++++++++++++++++++++++++++++++++++++++++ btcd.go | 7 ++ server.go | 15 +++- 4 files changed, 300 insertions(+), 2 deletions(-) create mode 100644 blockchain/claimtrie.go diff --git a/blockchain/chain.go b/blockchain/chain.go index 79bb3d74..e0ea9fa9 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -17,6 +17,8 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" + + "github.com/btcsuite/btcd/claimtrie" ) const ( @@ -180,6 +182,8 @@ type BlockChain struct { // certain blockchain events. notificationsLock sync.RWMutex notifications []NotificationCallback + + claimTrie *claimtrie.ClaimTrie } // HaveBlock returns whether or not the chain instance has the block represented @@ -571,7 +575,8 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, } // No warnings about unknown rules until the chain is current. - if b.isCurrent() { + current := b.isCurrent() + if current { // Warn if any unknown new rules are either about to activate or // have already been activated. if err := b.warnUnknownRuleActivations(node); err != nil { @@ -579,6 +584,14 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, } } + // Handle LBRY Claim Scripts + if b.claimTrie != nil { + shouldFlush := current && b.chainParams.Net != wire.TestNet + if err := b.ParseClaimScripts(block, node, view, shouldFlush); err != nil { + return ruleError(ErrBadClaimTrie, err.Error()) + } + } + // Write any block status changes to DB before updating best state. err := b.index.flushToDB() if err != nil { @@ -761,6 +774,12 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view return err } + if b.claimTrie != nil { + if err = b.claimTrie.ResetHeight(node.parent.height); err != nil { + return err + } + } + // Prune fully spent entries and mark all entries in the view unmodified // now that the modifications have been committed to the database. view.commit() @@ -1614,6 +1633,11 @@ func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Has return headers } +// ClaimTrie returns the claimTrie associated wit hthe chain. +func (b *BlockChain) ClaimTrie() *claimtrie.ClaimTrie { + return b.claimTrie +} + // IndexManager provides a generic interface that the is called when blocks are // connected and disconnected to and from the tip of the main chain for the // purpose of supporting optional indexes. @@ -1700,6 +1724,8 @@ type Config struct { // This field can be nil if the caller is not interested in using a // signature cache. HashCache *txscript.HashCache + + ClaimTrie *claimtrie.ClaimTrie } // New returns a BlockChain instance using the provided configuration details. @@ -1754,6 +1780,7 @@ func New(config *Config) (*BlockChain, error) { prevOrphans: make(map[chainhash.Hash][]*orphanBlock), warningCaches: newThresholdCaches(vbNumBits), deploymentCaches: newThresholdCaches(chaincfg.DefinedDeployments), + claimTrie: config.ClaimTrie, } // Initialize the chain state from the passed database. When the db @@ -1796,6 +1823,14 @@ func New(config *Config) (*BlockChain, error) { return nil, err } + if b.claimTrie != nil { + err := rebuildMissingClaimTrieData(&b, config.Interrupt) + if err != nil { + b.claimTrie.Close() + return nil, err + } + } + bestNode := b.bestChain.Tip() log.Infof("Chain state (height %d, hash %v, totaltx %d, work %v)", bestNode.height, bestNode.hash, b.stateSnapshot.TotalTxns, @@ -1803,3 +1838,63 @@ func New(config *Config) (*BlockChain, error) { return &b, nil } + +func rebuildMissingClaimTrieData(b *BlockChain, done <-chan struct{}) error { + target := b.bestChain.Height() + if b.claimTrie.Height() == target { + return nil + } + if b.claimTrie.Height() > target { + return b.claimTrie.ResetHeight(target) + } + + start := time.Now() + lastReport := time.Now() + // TODO: move this view inside the loop (or recreate it every 5 sec.) + // as accumulating all inputs has potential to use a huge amount of RAM + // but we need to get the spent inputs working for that to be possible + view := NewUtxoViewpoint() + for h := int32(0); h < target; h++ { + select { + case <-done: + return fmt.Errorf("rebuild unfinished at height %d", b.claimTrie.Height()) + default: + } + + n := b.bestChain.NodeByHeight(h + 1) + + var block *btcutil.Block + err := b.db.View(func(dbTx database.Tx) error { + var err error + block, err = dbFetchBlockByNode(dbTx, n) + return err + }) + if err != nil { + return err + } + + err = view.fetchInputUtxos(b.db, block) + if err != nil { + return err + } + + err = view.connectTransactions(block, nil) + if err != nil { + return err + } + + if h >= b.claimTrie.Height() { + err = b.ParseClaimScripts(block, n, view, false) + if err != nil { + return err + } + } + if time.Since(lastReport) > time.Second*5 { + lastReport = time.Now() + log.Infof("Rebuilding claim trie data to %d. At: %d", target, h) + } + } + log.Infof("Completed rebuilding claim trie data to %d. Took %s ", + b.claimTrie.Height(), time.Since(start)) + return nil +} diff --git a/blockchain/claimtrie.go b/blockchain/claimtrie.go new file mode 100644 index 00000000..5d544e4c --- /dev/null +++ b/blockchain/claimtrie.go @@ -0,0 +1,183 @@ +package blockchain + +import ( + "bytes" + "fmt" + + "github.com/pkg/errors" + + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" + + "github.com/btcsuite/btcd/claimtrie" + "github.com/btcsuite/btcd/claimtrie/change" + "github.com/btcsuite/btcd/claimtrie/node" + "github.com/btcsuite/btcd/claimtrie/normalization" +) + +func (b *BlockChain) SetClaimtrieHeader(block *btcutil.Block, view *UtxoViewpoint) error { + b.chainLock.Lock() + defer b.chainLock.Unlock() + + err := b.ParseClaimScripts(block, nil, view, false) + if err != nil { + return errors.Wrapf(err, "in parse claim scripts") + } + + block.MsgBlock().Header.ClaimTrie = *b.claimTrie.MerkleHash() + err = b.claimTrie.ResetHeight(b.claimTrie.Height() - 1) + + return errors.Wrapf(err, "in reset height") +} + +func (b *BlockChain) ParseClaimScripts(block *btcutil.Block, bn *blockNode, view *UtxoViewpoint, shouldFlush bool) error { + ht := block.Height() + + for _, tx := range block.Transactions() { + h := handler{ht, tx, view, map[string][]byte{}} + if err := h.handleTxIns(b.claimTrie); err != nil { + return err + } + if err := h.handleTxOuts(b.claimTrie); err != nil { + return err + } + } + + err := b.claimTrie.AppendBlock(bn == nil) + if err != nil { + return errors.Wrapf(err, "in append block") + } + + if shouldFlush { + b.claimTrie.FlushToDisk() + } + + hash := b.claimTrie.MerkleHash() + if bn != nil && bn.claimTrie != *hash { + // undo our AppendBlock call as we've decided that our interpretation of the block data is incorrect, + // or that the person who made the block assembled the pieces incorrectly. + _ = b.claimTrie.ResetHeight(b.claimTrie.Height() - 1) + return errors.Errorf("height: %d, computed hash: %s != header's ClaimTrie: %s", ht, *hash, bn.claimTrie) + } + return nil +} + +type handler struct { + ht int32 + tx *btcutil.Tx + view *UtxoViewpoint + spent map[string][]byte +} + +func (h *handler) handleTxIns(ct *claimtrie.ClaimTrie) error { + if IsCoinBase(h.tx) { + return nil + } + for _, txIn := range h.tx.MsgTx().TxIn { + op := txIn.PreviousOutPoint + e := h.view.LookupEntry(op) + if e == nil { + return errors.Errorf("missing input in view for %s", op.String()) + } + cs, err := txscript.ExtractClaimScript(e.pkScript) + if txscript.IsErrorCode(err, txscript.ErrNotClaimScript) { + continue + } + if err != nil { + return err + } + + var id change.ClaimID + name := cs.Name // name of the previous one (that we're now spending) + + switch cs.Opcode { + case txscript.OP_CLAIMNAME: // OP code from previous transaction + id = change.NewClaimID(op) // claimID of the previous item now being spent + h.spent[id.Key()] = normalization.NormalizeIfNecessary(name, ct.Height()) + err = ct.SpendClaim(name, op, id) + case txscript.OP_UPDATECLAIM: + copy(id[:], cs.ClaimID) + h.spent[id.Key()] = normalization.NormalizeIfNecessary(name, ct.Height()) + err = ct.SpendClaim(name, op, id) + case txscript.OP_SUPPORTCLAIM: + copy(id[:], cs.ClaimID) + err = ct.SpendSupport(name, op, id) + } + if err != nil { + return errors.Wrapf(err, "handleTxIns") + } + } + return nil +} + +func (h *handler) handleTxOuts(ct *claimtrie.ClaimTrie) error { + for i, txOut := range h.tx.MsgTx().TxOut { + op := *wire.NewOutPoint(h.tx.Hash(), uint32(i)) + cs, err := txscript.ExtractClaimScript(txOut.PkScript) + if txscript.IsErrorCode(err, txscript.ErrNotClaimScript) { + continue + } + if err != nil { + return err + } + + var id change.ClaimID + name := cs.Name + amt := txOut.Value + + switch cs.Opcode { + case txscript.OP_CLAIMNAME: + id = change.NewClaimID(op) + err = ct.AddClaim(name, op, id, amt) + case txscript.OP_SUPPORTCLAIM: + copy(id[:], cs.ClaimID) + err = ct.AddSupport(name, op, amt, id) + case txscript.OP_UPDATECLAIM: + // old code wouldn't run the update if name or claimID didn't match existing data + // that was a safety feature, but it should have rejected the transaction instead + // TODO: reject transactions with invalid update commands + copy(id[:], cs.ClaimID) + normName := normalization.NormalizeIfNecessary(name, ct.Height()) + if !bytes.Equal(h.spent[id.Key()], normName) { + node.LogOnce(fmt.Sprintf("Invalid update operation: name or ID mismatch at %d for: %s, %s", + ct.Height(), normName, id.String())) + continue + } + + delete(h.spent, id.Key()) + err = ct.UpdateClaim(name, op, amt, id) + } + if err != nil { + return errors.Wrapf(err, "handleTxOuts") + } + } + return nil +} + +func (b *BlockChain) GetNamesChangedInBlock(height int32) ([]string, error) { + b.chainLock.RLock() + defer b.chainLock.RUnlock() + + return b.claimTrie.NamesChangedInBlock(height) +} + +func (b *BlockChain) GetClaimsForName(height int32, name string) (string, *node.Node, error) { + + normalizedName := normalization.NormalizeIfNecessary([]byte(name), height) + + b.chainLock.RLock() + defer b.chainLock.RUnlock() + + n, err := b.claimTrie.NodeAt(height, normalizedName) + if err != nil { + return string(normalizedName), nil, err + } + + if n == nil { + return string(normalizedName), nil, fmt.Errorf("name does not exist at height %d: %s", height, name) + } + + n.SortClaimsByBid() + return string(normalizedName), n, nil +} diff --git a/btcd.go b/btcd.go index b93851ba..4f04657b 100644 --- a/btcd.go +++ b/btcd.go @@ -16,6 +16,7 @@ import ( "runtime/pprof" "github.com/btcsuite/btcd/blockchain/indexers" + "github.com/btcsuite/btcd/claimtrie/param" "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcd/limits" @@ -147,6 +148,8 @@ func btcdMain(serverChan chan<- *server) error { return nil } + param.SetNetwork(activeNetParams.Params.Net) // prep the claimtrie params + // Create server and start it. server, err := newServer(cfg.Listeners, cfg.AgentBlacklist, cfg.AgentWhitelist, db, activeNetParams.Params, interrupt) @@ -161,6 +164,10 @@ func btcdMain(serverChan chan<- *server) error { server.Stop() server.WaitForShutdown() srvrLog.Infof("Server shutdown complete") + // TODO: tie into the sync manager for shutdown instead + if ct := server.chain.ClaimTrie(); ct != nil { + ct.Close() + } }() server.Start() if serverChan != nil { diff --git a/server.go b/server.go index f5ec3705..a38df175 100644 --- a/server.go +++ b/server.go @@ -27,6 +27,8 @@ import ( "github.com/btcsuite/btcd/blockchain/indexers" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/claimtrie" + claimtrieconfig "github.com/btcsuite/btcd/claimtrie/config" "github.com/btcsuite/btcd/connmgr" "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcd/mempool" @@ -2726,8 +2728,18 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, checkpoints = mergeCheckpoints(s.chainParams.Checkpoints, cfg.addCheckpoints) } - // Create a new block chain instance with the appropriate configuration. var err error + + claimTrieCfg := claimtrieconfig.DefaultConfig + claimTrieCfg.DataDir = cfg.DataDir + claimTrieCfg.Interrupt = interrupt + + ct, err := claimtrie.New(claimTrieCfg) + if err != nil { + return nil, err + } + + // Create a new block chain instance with the appropriate configuration. s.chain, err = blockchain.New(&blockchain.Config{ DB: s.db, Interrupt: interrupt, @@ -2737,6 +2749,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, SigCache: s.sigCache, IndexManager: indexManager, HashCache: s.hashCache, + ClaimTrie: ct, }) if err != nil { return nil, err -- 2.45.2 From 45627c7a6a4dcf5f1255de18691f453cba8d84aa Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Oct 2021 22:45:32 -0700 Subject: [PATCH 347/459] [lbry] rename btcd to lbcd Co-authored-by: Brannon King --- addrmgr/addrmanager.go | 4 +- addrmgr/addrmanager_internal_test.go | 2 +- addrmgr/addrmanager_test.go | 4 +- addrmgr/internal_test.go | 2 +- addrmgr/knownaddress.go | 2 +- addrmgr/knownaddress_test.go | 4 +- addrmgr/network.go | 2 +- addrmgr/network_test.go | 4 +- blockchain/accept.go | 4 +- blockchain/blockindex.go | 8 ++-- blockchain/chain.go | 14 +++---- blockchain/chain_test.go | 8 ++-- blockchain/chainio.go | 8 ++-- blockchain/chainio_test.go | 4 +- blockchain/chainview_test.go | 2 +- blockchain/checkpoints.go | 8 ++-- blockchain/claimtrie.go | 14 +++---- blockchain/common_test.go | 14 +++---- blockchain/compress.go | 4 +- blockchain/difficulty.go | 2 +- blockchain/example_test.go | 10 ++--- blockchain/fullblocks_test.go | 18 ++++----- blockchain/fullblocktests/generate.go | 14 +++---- blockchain/fullblocktests/params.go | 6 +-- blockchain/indexers/addrindex.go | 14 +++---- blockchain/indexers/addrindex_test.go | 2 +- blockchain/indexers/blocklogger.go | 2 +- blockchain/indexers/cfindex.go | 16 ++++---- blockchain/indexers/common.go | 6 +-- blockchain/indexers/manager.go | 10 ++--- blockchain/indexers/txindex.go | 10 ++--- blockchain/mediantime.go | 2 +- blockchain/merkle.go | 6 +-- blockchain/process.go | 6 +-- blockchain/scriptval.go | 6 +-- blockchain/scriptval_test.go | 2 +- blockchain/thresholdstate.go | 2 +- blockchain/thresholdstate_test.go | 2 +- blockchain/upgrade.go | 6 +-- blockchain/utxoviewpoint.go | 10 ++--- blockchain/validate.go | 10 ++--- blockchain/validate_test.go | 9 +++-- blockchain/versionbits.go | 2 +- blockchain/weight.go | 6 +-- btcec/example_test.go | 4 +- btcec/genprecomps.go | 2 +- btcjson/btcdextcmds_test.go | 2 +- btcjson/btcdextresults_test.go | 2 +- btcjson/btcwalletextcmds_test.go | 2 +- btcjson/chainsvrcmds.go | 2 +- btcjson/chainsvrcmds_test.go | 4 +- btcjson/chainsvrresults.go | 6 +-- btcjson/chainsvrresults_test.go | 6 +-- btcjson/chainsvrwscmds_test.go | 2 +- btcjson/chainsvrwsntfns_test.go | 2 +- btcjson/chainsvrwsresults_test.go | 2 +- btcjson/cmdinfo_test.go | 2 +- btcjson/cmdparse_test.go | 2 +- btcjson/error_test.go | 2 +- btcjson/example_test.go | 2 +- btcjson/help_test.go | 2 +- btcjson/helpers_test.go | 2 +- btcjson/jsonrpc_test.go | 2 +- btcjson/register_test.go | 2 +- btcjson/walletsvrcmds.go | 2 +- btcjson/walletsvrcmds_test.go | 4 +- btcjson/walletsvrresults.go | 2 +- btcjson/walletsvrresults_test.go | 2 +- btcjson/walletsvrwscmds_test.go | 2 +- btcjson/walletsvrwsntfns_test.go | 2 +- chaincfg/doc.go | 4 +- chaincfg/genesis.go | 4 +- chaincfg/params.go | 4 +- chaincfg/register_test.go | 2 +- cmd/addblock/addblock.go | 8 ++-- cmd/addblock/config.go | 16 ++++---- cmd/addblock/import.go | 12 +++--- cmd/findcheckpoint/config.go | 16 ++++---- cmd/findcheckpoint/findcheckpoint.go | 8 ++-- cmd/gencerts/gencerts.go | 2 +- cmd/{btcctl => lbcctl}/config.go | 20 +++++----- cmd/{btcctl => lbcctl}/httpclient.go | 2 +- cmd/{btcctl/btcctl.go => lbcctl/lbcctl.go} | 2 +- cmd/{btcctl => lbcctl}/version.go | 2 +- config.go | 38 +++++++++---------- config_test.go | 8 ++-- connmgr/seed.go | 4 +- database/cmd/dbtool/fetchblock.go | 4 +- database/cmd/dbtool/fetchblockregion.go | 4 +- database/cmd/dbtool/globalconfig.go | 16 ++++---- database/cmd/dbtool/insecureimport.go | 8 ++-- database/cmd/dbtool/loadheaders.go | 4 +- database/cmd/dbtool/main.go | 2 +- database/driver_test.go | 4 +- database/error_test.go | 2 +- database/example_test.go | 24 ++++++------ database/ffldb/bench_test.go | 6 +-- database/ffldb/blockio.go | 6 +-- database/ffldb/db.go | 10 ++--- database/ffldb/dbcache.go | 2 +- database/ffldb/doc.go | 2 +- database/ffldb/driver.go | 4 +- database/ffldb/driver_test.go | 8 ++-- database/ffldb/export_test.go | 2 +- database/ffldb/interface_test.go | 9 ++--- database/ffldb/ldbtreapiter.go | 2 +- database/ffldb/reconcile.go | 2 +- database/ffldb/whitebox_test.go | 7 ++-- database/interface.go | 4 +- doc.go | 10 ++--- docs/conf.py | 10 +++-- integration/bip0009_test.go | 8 ++-- integration/csv_fork_test.go | 16 ++++---- integration/rpcserver_test.go | 8 ++-- integration/rpctest/blockgen.go | 14 +++---- integration/rpctest/btcd.go | 6 +-- integration/rpctest/memwallet.go | 18 ++++----- integration/rpctest/node.go | 6 +-- integration/rpctest/rpc_harness.go | 12 +++--- integration/rpctest/rpc_harness_test.go | 10 ++--- integration/rpctest/utils.go | 4 +- btcd.go => lbcd.go | 8 ++-- log.go | 24 ++++++------ mempool/error.go | 4 +- mempool/estimatefee.go | 6 +-- mempool/estimatefee_test.go | 8 ++-- mempool/mempool.go | 18 ++++----- mempool/mempool_test.go | 14 +++---- mempool/policy.go | 9 +++-- mempool/policy_test.go | 12 +++--- mining/cpuminer/cpuminer.go | 12 +++--- mining/mining.go | 14 +++---- mining/mining_test.go | 2 +- mining/policy.go | 6 +-- mining/policy_test.go | 8 ++-- netsync/blocklogger.go | 2 +- netsync/interface.go | 14 +++---- netsync/manager.go | 16 ++++---- params.go | 4 +- peer/doc.go | 2 +- peer/example_test.go | 6 +-- peer/log.go | 6 +-- peer/peer.go | 8 ++-- peer/peer_test.go | 8 ++-- rpcadapters.go | 14 +++---- rpcclient/chain.go | 6 +-- rpcclient/doc.go | 2 +- rpcclient/example_test.go | 3 +- rpcclient/examples/bitcoincorehttp/main.go | 2 +- .../examples/bitcoincorehttpbulk/main.go | 2 +- rpcclient/examples/btcdwebsockets/main.go | 8 ++-- .../examples/btcwalletwebsockets/main.go | 8 ++-- rpcclient/extensions.go | 8 ++-- rpcclient/infrastructure.go | 16 ++++---- rpcclient/mining.go | 6 +-- rpcclient/net.go | 2 +- rpcclient/notify.go | 10 ++--- rpcclient/rawrequest.go | 2 +- rpcclient/rawtransactions.go | 8 ++-- rpcclient/wallet.go | 10 ++--- rpcserverhelp.go | 28 +++++++------- rpcwebsocket.go | 16 ++++---- server.go | 38 +++++++++---------- txscript/bench_test.go | 4 +- txscript/engine.go | 4 +- txscript/engine_test.go | 4 +- txscript/example_test.go | 12 +++--- txscript/hashcache.go | 4 +- txscript/hashcache_test.go | 2 +- txscript/opcode.go | 6 +-- txscript/pkscript.go | 8 ++-- txscript/pkscript_test.go | 2 +- txscript/reference_test.go | 6 +-- txscript/script.go | 4 +- txscript/script_test.go | 2 +- txscript/sigcache.go | 4 +- txscript/sigcache_test.go | 4 +- txscript/sign.go | 8 ++-- txscript/sign_test.go | 10 ++--- txscript/standard.go | 6 +-- txscript/standard_test.go | 6 +-- upgrade.go | 10 ++--- wire/bench_test.go | 2 +- wire/blockheader.go | 4 +- wire/common.go | 2 +- wire/common_test.go | 2 +- wire/invvect.go | 2 +- wire/invvect_test.go | 2 +- wire/message.go | 2 +- wire/message_test.go | 2 +- wire/msgblock.go | 2 +- wire/msgblock_test.go | 2 +- wire/msgcfcheckpt.go | 2 +- wire/msgcfheaders.go | 2 +- wire/msgcfilter.go | 2 +- wire/msggetblocks.go | 2 +- wire/msggetblocks_test.go | 2 +- wire/msggetcfcheckpt.go | 2 +- wire/msggetcfheaders.go | 2 +- wire/msggetcfilters.go | 2 +- wire/msggetdata_test.go | 2 +- wire/msggetheaders.go | 2 +- wire/msggetheaders_test.go | 2 +- wire/msginv_test.go | 2 +- wire/msgmerkleblock.go | 2 +- wire/msgmerkleblock_test.go | 2 +- wire/msgnotfound_test.go | 2 +- wire/msgreject.go | 2 +- wire/msgtx.go | 2 +- wire/msgtx_test.go | 2 +- 210 files changed, 666 insertions(+), 661 deletions(-) rename cmd/{btcctl => lbcctl}/config.go (95%) rename cmd/{btcctl => lbcctl}/httpclient.go (98%) rename cmd/{btcctl/btcctl.go => lbcctl/lbcctl.go} (99%) rename cmd/{btcctl => lbcctl}/version.go (99%) rename btcd.go => lbcd.go (98%) diff --git a/addrmgr/addrmanager.go b/addrmgr/addrmanager.go index 4c737b93..b7730671 100644 --- a/addrmgr/addrmanager.go +++ b/addrmgr/addrmanager.go @@ -23,8 +23,8 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // AddrManager provides a concurrency safe address manager for caching potential diff --git a/addrmgr/addrmanager_internal_test.go b/addrmgr/addrmanager_internal_test.go index 1c19dceb..b2f5f3d1 100644 --- a/addrmgr/addrmanager_internal_test.go +++ b/addrmgr/addrmanager_internal_test.go @@ -7,7 +7,7 @@ import ( "os" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // randAddr generates a *wire.NetAddress backed by a random IPv4/IPv6 address. diff --git a/addrmgr/addrmanager_test.go b/addrmgr/addrmanager_test.go index 676913e2..d623479c 100644 --- a/addrmgr/addrmanager_test.go +++ b/addrmgr/addrmanager_test.go @@ -12,8 +12,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/wire" ) // naTest is used to describe a test to be performed against the NetAddressKey diff --git a/addrmgr/internal_test.go b/addrmgr/internal_test.go index e50e923c..b7c650c7 100644 --- a/addrmgr/internal_test.go +++ b/addrmgr/internal_test.go @@ -7,7 +7,7 @@ package addrmgr import ( "time" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) func TstKnownAddressIsBad(ka *KnownAddress) bool { diff --git a/addrmgr/knownaddress.go b/addrmgr/knownaddress.go index 5a7674f4..59db5584 100644 --- a/addrmgr/knownaddress.go +++ b/addrmgr/knownaddress.go @@ -8,7 +8,7 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // KnownAddress tracks information about a known network address that is used diff --git a/addrmgr/knownaddress_test.go b/addrmgr/knownaddress_test.go index a289d5a3..fc882667 100644 --- a/addrmgr/knownaddress_test.go +++ b/addrmgr/knownaddress_test.go @@ -9,8 +9,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/wire" ) func TestChance(t *testing.T) { diff --git a/addrmgr/network.go b/addrmgr/network.go index 51bfa3ed..878bc2b1 100644 --- a/addrmgr/network.go +++ b/addrmgr/network.go @@ -8,7 +8,7 @@ import ( "fmt" "net" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) var ( diff --git a/addrmgr/network_test.go b/addrmgr/network_test.go index 8af3369f..6f2565fe 100644 --- a/addrmgr/network_test.go +++ b/addrmgr/network_test.go @@ -8,8 +8,8 @@ import ( "net" "testing" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/wire" ) // TestIPTypes ensures the various functions which determine the type of an IP diff --git a/blockchain/accept.go b/blockchain/accept.go index f85d6558..6acba30d 100644 --- a/blockchain/accept.go +++ b/blockchain/accept.go @@ -7,8 +7,8 @@ package blockchain import ( "fmt" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/database" + btcutil "github.com/lbryio/lbcutil" ) // maybeAcceptBlock potentially accepts a block into the block chain and, if diff --git a/blockchain/blockindex.go b/blockchain/blockindex.go index 1531e6b1..eb7c01a7 100644 --- a/blockchain/blockindex.go +++ b/blockchain/blockindex.go @@ -10,10 +10,10 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) // blockStatus is a bit field representing the validation state of the block. diff --git a/blockchain/chain.go b/blockchain/chain.go index e0ea9fa9..45496fca 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -11,14 +11,14 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" - "github.com/btcsuite/btcd/claimtrie" + "github.com/lbryio/lbcd/claimtrie" ) const ( diff --git a/blockchain/chain_test.go b/blockchain/chain_test.go index 7de323bc..b2a155bc 100644 --- a/blockchain/chain_test.go +++ b/blockchain/chain_test.go @@ -9,10 +9,10 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // TestHaveBlock tests the HaveBlock API to ensure proper functionality. diff --git a/blockchain/chainio.go b/blockchain/chainio.go index f40ba465..ae83dc64 100644 --- a/blockchain/chainio.go +++ b/blockchain/chainio.go @@ -12,10 +12,10 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/chainio_test.go b/blockchain/chainio_test.go index 630af14e..76881a33 100644 --- a/blockchain/chainio_test.go +++ b/blockchain/chainio_test.go @@ -11,8 +11,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) // TestErrNotInMainChain ensures the functions related to errNotInMainChain work diff --git a/blockchain/chainview_test.go b/blockchain/chainview_test.go index c59004fd..746bf1bd 100644 --- a/blockchain/chainview_test.go +++ b/blockchain/chainview_test.go @@ -10,7 +10,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // testNoncePrng provides a deterministic prng for the nonce in generated fake diff --git a/blockchain/checkpoints.go b/blockchain/checkpoints.go index af3b6d92..a82d70dd 100644 --- a/blockchain/checkpoints.go +++ b/blockchain/checkpoints.go @@ -8,10 +8,10 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + btcutil "github.com/lbryio/lbcutil" ) // CheckpointConfirmations is the number of blocks before the end of the current diff --git a/blockchain/claimtrie.go b/blockchain/claimtrie.go index 5d544e4c..f821537a 100644 --- a/blockchain/claimtrie.go +++ b/blockchain/claimtrie.go @@ -6,14 +6,14 @@ import ( "github.com/pkg/errors" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" - "github.com/btcsuite/btcd/claimtrie" - "github.com/btcsuite/btcd/claimtrie/change" - "github.com/btcsuite/btcd/claimtrie/node" - "github.com/btcsuite/btcd/claimtrie/normalization" + "github.com/lbryio/lbcd/claimtrie" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/claimtrie/normalization" ) func (b *BlockChain) SetClaimtrieHeader(block *btcutil.Block, view *UtxoViewpoint) error { diff --git a/blockchain/common_test.go b/blockchain/common_test.go index dd392a66..16ad6756 100644 --- a/blockchain/common_test.go +++ b/blockchain/common_test.go @@ -14,13 +14,13 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/compress.go b/blockchain/compress.go index 611b9f09..70aab39b 100644 --- a/blockchain/compress.go +++ b/blockchain/compress.go @@ -5,8 +5,8 @@ package blockchain import ( - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/txscript" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/txscript" ) // ----------------------------------------------------------------------------- diff --git a/blockchain/difficulty.go b/blockchain/difficulty.go index 3eae3844..2f16e2e5 100644 --- a/blockchain/difficulty.go +++ b/blockchain/difficulty.go @@ -8,7 +8,7 @@ import ( "math/big" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) var ( diff --git a/blockchain/example_test.go b/blockchain/example_test.go index 691d0927..da0cce79 100644 --- a/blockchain/example_test.go +++ b/blockchain/example_test.go @@ -10,11 +10,11 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + btcutil "github.com/lbryio/lbcutil" ) // This example demonstrates how to create a new chain instance and use diff --git a/blockchain/fullblocks_test.go b/blockchain/fullblocks_test.go index 3ae0d0eb..4c45c099 100644 --- a/blockchain/fullblocks_test.go +++ b/blockchain/fullblocks_test.go @@ -12,15 +12,15 @@ import ( "path/filepath" "testing" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/fullblocktests" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/fullblocktests" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index 592a14de..dc182a90 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -18,13 +18,13 @@ import ( "runtime" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/fullblocktests/params.go b/blockchain/fullblocktests/params.go index 4679036f..fa23e841 100644 --- a/blockchain/fullblocktests/params.go +++ b/blockchain/fullblocktests/params.go @@ -9,9 +9,9 @@ import ( "math/big" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // newHashFromStr converts the passed big-endian hex string into a diff --git a/blockchain/indexers/addrindex.go b/blockchain/indexers/addrindex.go index 4a9bf4ec..3ac3924a 100644 --- a/blockchain/indexers/addrindex.go +++ b/blockchain/indexers/addrindex.go @@ -9,13 +9,13 @@ import ( "fmt" "sync" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/indexers/addrindex_test.go b/blockchain/indexers/addrindex_test.go index e545887f..584ed1cc 100644 --- a/blockchain/indexers/addrindex_test.go +++ b/blockchain/indexers/addrindex_test.go @@ -9,7 +9,7 @@ import ( "fmt" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // addrIndexBucket provides a mock address index database bucket by implementing diff --git a/blockchain/indexers/blocklogger.go b/blockchain/indexers/blocklogger.go index 88d6f269..845618e7 100644 --- a/blockchain/indexers/blocklogger.go +++ b/blockchain/indexers/blocklogger.go @@ -9,7 +9,7 @@ import ( "time" "github.com/btcsuite/btclog" - "github.com/btcsuite/btcutil" + btcutil "github.com/lbryio/lbcutil" ) // blockProgressLogger provides periodic logging for other services in order diff --git a/blockchain/indexers/cfindex.go b/blockchain/indexers/cfindex.go index 8ea14728..881d3a30 100644 --- a/blockchain/indexers/cfindex.go +++ b/blockchain/indexers/cfindex.go @@ -7,14 +7,14 @@ package indexers import ( "errors" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" - "github.com/btcsuite/btcutil/gcs" - "github.com/btcsuite/btcutil/gcs/builder" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" + "github.com/lbryio/lbcutil/gcs" + "github.com/lbryio/lbcutil/gcs/builder" ) const ( diff --git a/blockchain/indexers/common.go b/blockchain/indexers/common.go index a912bb4c..57971d8b 100644 --- a/blockchain/indexers/common.go +++ b/blockchain/indexers/common.go @@ -11,9 +11,9 @@ import ( "encoding/binary" "errors" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/database" + btcutil "github.com/lbryio/lbcutil" ) var ( diff --git a/blockchain/indexers/manager.go b/blockchain/indexers/manager.go index bc0804f8..7c0bb0e1 100644 --- a/blockchain/indexers/manager.go +++ b/blockchain/indexers/manager.go @@ -8,11 +8,11 @@ import ( "bytes" "fmt" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( diff --git a/blockchain/indexers/txindex.go b/blockchain/indexers/txindex.go index 00cfd006..96b3edcb 100644 --- a/blockchain/indexers/txindex.go +++ b/blockchain/indexers/txindex.go @@ -8,11 +8,11 @@ import ( "errors" "fmt" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/mediantime.go b/blockchain/mediantime.go index f9c15a23..bb85b646 100644 --- a/blockchain/mediantime.go +++ b/blockchain/mediantime.go @@ -183,7 +183,7 @@ func (m *medianTime) AddTimeSample(sourceID string, timeVal time.Time) { // Warn if none of the time samples are close. if !remoteHasCloseTime { log.Warnf("Please check your date and time " + - "are correct! btcd will not work " + + "are correct! lbcd will not work " + "properly with an invalid time") } } diff --git a/blockchain/merkle.go b/blockchain/merkle.go index 8f3f6b97..29479c1d 100644 --- a/blockchain/merkle.go +++ b/blockchain/merkle.go @@ -9,9 +9,9 @@ import ( "fmt" "math" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/process.go b/blockchain/process.go index 6d2161bb..a48b6e50 100644 --- a/blockchain/process.go +++ b/blockchain/process.go @@ -8,9 +8,9 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + btcutil "github.com/lbryio/lbcutil" ) // BehaviorFlags is a bitmask defining tweaks to the normal behavior when diff --git a/blockchain/scriptval.go b/blockchain/scriptval.go index 8ba59a42..97bf0ece 100644 --- a/blockchain/scriptval.go +++ b/blockchain/scriptval.go @@ -10,9 +10,9 @@ import ( "runtime" "time" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // txValidateItem holds a transaction along with which input to validate. diff --git a/blockchain/scriptval_test.go b/blockchain/scriptval_test.go index 031f0480..62d97362 100644 --- a/blockchain/scriptval_test.go +++ b/blockchain/scriptval_test.go @@ -8,7 +8,7 @@ import ( "fmt" "testing" - "github.com/btcsuite/btcd/txscript" + "github.com/lbryio/lbcd/txscript" ) // TestCheckBlockScripts ensures that validating the all of the scripts in a diff --git a/blockchain/thresholdstate.go b/blockchain/thresholdstate.go index 8a79f968..ac652eff 100644 --- a/blockchain/thresholdstate.go +++ b/blockchain/thresholdstate.go @@ -7,7 +7,7 @@ package blockchain import ( "fmt" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // ThresholdState define the various threshold states used when voting on diff --git a/blockchain/thresholdstate_test.go b/blockchain/thresholdstate_test.go index c65f5a44..5eecc61e 100644 --- a/blockchain/thresholdstate_test.go +++ b/blockchain/thresholdstate_test.go @@ -7,7 +7,7 @@ package blockchain import ( "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestThresholdStateStringer tests the stringized output for the diff --git a/blockchain/upgrade.go b/blockchain/upgrade.go index 253ca62e..a899cb4e 100644 --- a/blockchain/upgrade.go +++ b/blockchain/upgrade.go @@ -11,9 +11,9 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/blockchain/utxoviewpoint.go b/blockchain/utxoviewpoint.go index b8576581..60d48df0 100644 --- a/blockchain/utxoviewpoint.go +++ b/blockchain/utxoviewpoint.go @@ -7,11 +7,11 @@ package blockchain import ( "fmt" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // txoFlags is a bitmask defining additional information and state for a diff --git a/blockchain/validate.go b/blockchain/validate.go index ef2c283b..19183aa9 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -11,11 +11,11 @@ import ( "math/big" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/blockchain/validate_test.go b/blockchain/validate_test.go index 9bf2ff42..6298ad06 100644 --- a/blockchain/validate_test.go +++ b/blockchain/validate_test.go @@ -5,15 +5,16 @@ package blockchain import ( + "encoding/hex" "math" "reflect" "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // TestSequenceLocksActive tests the SequenceLockActive function to ensure it diff --git a/blockchain/versionbits.go b/blockchain/versionbits.go index acdbf144..ddf1cace 100644 --- a/blockchain/versionbits.go +++ b/blockchain/versionbits.go @@ -7,7 +7,7 @@ package blockchain import ( "math" - "github.com/btcsuite/btcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg" ) const ( diff --git a/blockchain/weight.go b/blockchain/weight.go index e23dd87d..9a3a10b3 100644 --- a/blockchain/weight.go +++ b/blockchain/weight.go @@ -7,9 +7,9 @@ package blockchain import ( "fmt" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/btcec/example_test.go b/btcec/example_test.go index ca51ee87..cea8d771 100644 --- a/btcec/example_test.go +++ b/btcec/example_test.go @@ -8,8 +8,8 @@ import ( "encoding/hex" "fmt" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // This example demonstrates signing a message with a secp256k1 private key that diff --git a/btcec/genprecomps.go b/btcec/genprecomps.go index d4a9c1b8..f09ab311 100644 --- a/btcec/genprecomps.go +++ b/btcec/genprecomps.go @@ -17,7 +17,7 @@ import ( "log" "os" - "github.com/btcsuite/btcd/btcec" + "github.com/lbryio/lbcd/btcec" ) func main() { diff --git a/btcjson/btcdextcmds_test.go b/btcjson/btcdextcmds_test.go index aaa44144..8aadb0af 100644 --- a/btcjson/btcdextcmds_test.go +++ b/btcjson/btcdextcmds_test.go @@ -12,7 +12,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestBtcdExtCmds tests all of the btcd extended commands marshal and unmarshal diff --git a/btcjson/btcdextresults_test.go b/btcjson/btcdextresults_test.go index 478f088c..55327dce 100644 --- a/btcjson/btcdextresults_test.go +++ b/btcjson/btcdextresults_test.go @@ -9,7 +9,7 @@ import ( "encoding/json" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestBtcdExtCustomResults ensures any results that have custom marshalling diff --git a/btcjson/btcwalletextcmds_test.go b/btcjson/btcwalletextcmds_test.go index dea1c614..fe3b54c0 100644 --- a/btcjson/btcwalletextcmds_test.go +++ b/btcjson/btcwalletextcmds_test.go @@ -11,7 +11,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestBtcWalletExtCmds tests all of the btcwallet extended commands marshal and diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index aa1d4415..0cfb2e17 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -13,7 +13,7 @@ import ( "fmt" "reflect" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // AddNodeSubCmd defines the type used in the addnode JSON-RPC command for the diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index 7d3a68dc..fa8305c2 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -12,8 +12,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/wire" ) // TestChainSvrCmds tests all of the chain server commands marshal and unmarshal diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 405fd867..e658cccf 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -9,10 +9,10 @@ import ( "encoding/hex" "encoding/json" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // GetBlockHeaderVerboseResult models the data from the getblockheader command when diff --git a/btcjson/chainsvrresults_test.go b/btcjson/chainsvrresults_test.go index 72dcd8d7..bb04a003 100644 --- a/btcjson/chainsvrresults_test.go +++ b/btcjson/chainsvrresults_test.go @@ -9,10 +9,10 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcutil" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + btcutil "github.com/lbryio/lbcutil" ) // TestChainSvrCustomResults ensures any results that have custom marshalling diff --git a/btcjson/chainsvrwscmds_test.go b/btcjson/chainsvrwscmds_test.go index 03fb22c8..688c3900 100644 --- a/btcjson/chainsvrwscmds_test.go +++ b/btcjson/chainsvrwscmds_test.go @@ -12,7 +12,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestChainSvrWsCmds tests all of the chain server websocket-specific commands diff --git a/btcjson/chainsvrwsntfns_test.go b/btcjson/chainsvrwsntfns_test.go index e2b234c2..ed6902dc 100644 --- a/btcjson/chainsvrwsntfns_test.go +++ b/btcjson/chainsvrwsntfns_test.go @@ -12,7 +12,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestChainSvrWsNtfns tests all of the chain server websocket-specific diff --git a/btcjson/chainsvrwsresults_test.go b/btcjson/chainsvrwsresults_test.go index b1e17450..21e1f2ff 100644 --- a/btcjson/chainsvrwsresults_test.go +++ b/btcjson/chainsvrwsresults_test.go @@ -9,7 +9,7 @@ import ( "encoding/json" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestChainSvrWsResults ensures any results that have custom marshalling diff --git a/btcjson/cmdinfo_test.go b/btcjson/cmdinfo_test.go index 61a693e4..2d7e7ec4 100644 --- a/btcjson/cmdinfo_test.go +++ b/btcjson/cmdinfo_test.go @@ -8,7 +8,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestCmdMethod tests the CmdMethod function to ensure it retunrs the expected diff --git a/btcjson/cmdparse_test.go b/btcjson/cmdparse_test.go index f2585edf..c1414c64 100644 --- a/btcjson/cmdparse_test.go +++ b/btcjson/cmdparse_test.go @@ -10,7 +10,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestAssignField tests the assignField function handles supported combinations diff --git a/btcjson/error_test.go b/btcjson/error_test.go index 8eb93c75..d1f5cb98 100644 --- a/btcjson/error_test.go +++ b/btcjson/error_test.go @@ -7,7 +7,7 @@ package btcjson_test import ( "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestErrorCodeStringer tests the stringized output for the ErrorCode type. diff --git a/btcjson/example_test.go b/btcjson/example_test.go index 74478e74..7974ba0e 100644 --- a/btcjson/example_test.go +++ b/btcjson/example_test.go @@ -8,7 +8,7 @@ import ( "encoding/json" "fmt" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // This example demonstrates how to create and marshal a command into a JSON-RPC diff --git a/btcjson/help_test.go b/btcjson/help_test.go index 918aa144..87ad7f7e 100644 --- a/btcjson/help_test.go +++ b/btcjson/help_test.go @@ -8,7 +8,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestHelpReflectInternals ensures the various help functions which deal with diff --git a/btcjson/helpers_test.go b/btcjson/helpers_test.go index 7bcaf4bc..9023c2e4 100644 --- a/btcjson/helpers_test.go +++ b/btcjson/helpers_test.go @@ -8,7 +8,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestHelpers tests the various helper functions which create pointers to diff --git a/btcjson/jsonrpc_test.go b/btcjson/jsonrpc_test.go index 13d98e89..b7229d35 100644 --- a/btcjson/jsonrpc_test.go +++ b/btcjson/jsonrpc_test.go @@ -9,7 +9,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestIsValidIDType ensures the IsValidIDType function behaves as expected. diff --git a/btcjson/register_test.go b/btcjson/register_test.go index 2d3ab10f..45e7238c 100644 --- a/btcjson/register_test.go +++ b/btcjson/register_test.go @@ -9,7 +9,7 @@ import ( "sort" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestUsageFlagStringer tests the stringized output for the UsageFlag type. diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index e8ed6237..e4d676ff 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -12,7 +12,7 @@ import ( "encoding/json" "fmt" - "github.com/btcsuite/btcutil" + btcutil "github.com/lbryio/lbcutil" ) // AddMultisigAddressCmd defines the addmutisigaddress JSON-RPC command. diff --git a/btcjson/walletsvrcmds_test.go b/btcjson/walletsvrcmds_test.go index 9c68d260..d33888d4 100644 --- a/btcjson/walletsvrcmds_test.go +++ b/btcjson/walletsvrcmds_test.go @@ -11,8 +11,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + btcutil "github.com/lbryio/lbcutil" ) // TestWalletSvrCmds tests all of the wallet server commands marshal and diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index 78a6e647..16df09bb 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -8,7 +8,7 @@ import ( "encoding/json" "fmt" - "github.com/btcsuite/btcd/txscript" + "github.com/lbryio/lbcd/txscript" ) // CreateWalletResult models the result of the createwallet command. diff --git a/btcjson/walletsvrresults_test.go b/btcjson/walletsvrresults_test.go index fd44b066..510c367c 100644 --- a/btcjson/walletsvrresults_test.go +++ b/btcjson/walletsvrresults_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/txscript" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/txscript" ) // TestGetAddressInfoResult ensures that custom unmarshalling of diff --git a/btcjson/walletsvrwscmds_test.go b/btcjson/walletsvrwscmds_test.go index 110a893b..3c9751fc 100644 --- a/btcjson/walletsvrwscmds_test.go +++ b/btcjson/walletsvrwscmds_test.go @@ -11,7 +11,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestWalletSvrWsCmds tests all of the wallet server websocket-specific diff --git a/btcjson/walletsvrwsntfns_test.go b/btcjson/walletsvrwsntfns_test.go index 11191662..51839c68 100644 --- a/btcjson/walletsvrwsntfns_test.go +++ b/btcjson/walletsvrwsntfns_test.go @@ -11,7 +11,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // TestWalletSvrWsNtfns tests all of the chain server websocket-specific diff --git a/chaincfg/doc.go b/chaincfg/doc.go index 3659adbf..fb5fa677 100644 --- a/chaincfg/doc.go +++ b/chaincfg/doc.go @@ -25,8 +25,8 @@ // "fmt" // "log" // -// "github.com/btcsuite/btcutil" -// "github.com/btcsuite/btcd/chaincfg" +// btcutil "github.com/lbryio/lbcutil" +// "github.com/lbryio/lbcd/chaincfg" // ) // // var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network") diff --git a/chaincfg/genesis.go b/chaincfg/genesis.go index 2c2a043e..a4df289d 100644 --- a/chaincfg/genesis.go +++ b/chaincfg/genesis.go @@ -7,8 +7,8 @@ package chaincfg import ( "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // genesisCoinbaseTx is the coinbase transaction for the genesis blocks for diff --git a/chaincfg/params.go b/chaincfg/params.go index 68c362d5..b2144963 100644 --- a/chaincfg/params.go +++ b/chaincfg/params.go @@ -13,8 +13,8 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // These variables are the chain proof-of-work limit parameters for each default diff --git a/chaincfg/register_test.go b/chaincfg/register_test.go index bcb5b3c6..700a63ff 100644 --- a/chaincfg/register_test.go +++ b/chaincfg/register_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - . "github.com/btcsuite/btcd/chaincfg" + . "github.com/lbryio/lbcd/chaincfg" ) // Define some of the required parameters for a user-registered diff --git a/cmd/addblock/addblock.go b/cmd/addblock/addblock.go index 8b44f307..b601779b 100644 --- a/cmd/addblock/addblock.go +++ b/cmd/addblock/addblock.go @@ -8,11 +8,11 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/limits" "github.com/btcsuite/btclog" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/limits" ) const ( diff --git a/cmd/addblock/config.go b/cmd/addblock/config.go index 90620c8f..d2c9dc0d 100644 --- a/cmd/addblock/config.go +++ b/cmd/addblock/config.go @@ -9,12 +9,12 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -24,7 +24,7 @@ const ( ) var ( - btcdHomeDir = btcutil.AppDataDir("btcd", false) + btcdHomeDir = btcutil.AppDataDir("lbcd", false) defaultDataDir = filepath.Join(btcdHomeDir, "data") knownDbTypes = database.SupportedDrivers() activeNetParams = &chaincfg.MainNetParams @@ -35,7 +35,7 @@ var ( // See loadConfig for details on the configuration load process. type config struct { AddrIndex bool `long:"addrindex" description:"Build a full address-based transaction index which makes the searchrawtransactions RPC available"` - DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` + DataDir string `short:"b" long:"datadir" description:"Location of the lbcd data directory"` DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` InFile string `short:"i" long:"infile" description:"File containing the block(s)"` Progress int `short:"p" long:"progress" description:"Show a progress message each time this number of seconds have passed -- Use 0 to disable progress announcements"` @@ -67,7 +67,7 @@ func validDbType(dbType string) bool { } // netName returns the name used when referring to a bitcoin network. At the -// time of writing, btcd currently places blocks for testnet version 3 in the +// time of writing, lbcd currently places blocks for testnet version 3 in the // data and log directory "testnet", which does not match the Name field of the // chaincfg parameters. This function can be used to override this directory name // as "testnet" when the passed active network matches wire.TestNet3. diff --git a/cmd/addblock/import.go b/cmd/addblock/import.go index b7a30369..34117ecd 100644 --- a/cmd/addblock/import.go +++ b/cmd/addblock/import.go @@ -11,12 +11,12 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var zeroHash = chainhash.Hash{} diff --git a/cmd/findcheckpoint/config.go b/cmd/findcheckpoint/config.go index 87f04cec..7a16069a 100644 --- a/cmd/findcheckpoint/config.go +++ b/cmd/findcheckpoint/config.go @@ -9,12 +9,12 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -25,7 +25,7 @@ const ( ) var ( - btcdHomeDir = btcutil.AppDataDir("btcd", false) + btcdHomeDir = btcutil.AppDataDir("lbcd", false) defaultDataDir = filepath.Join(btcdHomeDir, "data") knownDbTypes = database.SupportedDrivers() activeNetParams = &chaincfg.MainNetParams @@ -35,7 +35,7 @@ var ( // // See loadConfig for details on the configuration load process. type config struct { - DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` + DataDir string `short:"b" long:"datadir" description:"Location of the lbcd data directory"` DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` UseGoOutput bool `short:"g" long:"gooutput" description:"Display the candidates using Go syntax that is ready to insert into the btcchain checkpoint list"` NumCandidates int `short:"n" long:"numcandidates" description:"Max num of checkpoint candidates to show {1-20}"` @@ -56,7 +56,7 @@ func validDbType(dbType string) bool { } // netName returns the name used when referring to a bitcoin network. At the -// time of writing, btcd currently places blocks for testnet version 3 in the +// time of writing, lbcd currently places blocks for testnet version 3 in the // data and log directory "testnet", which does not match the Name field of the // chaincfg parameters. This function can be used to override this directory name // as "testnet" when the passed active network matches wire.TestNet3. diff --git a/cmd/findcheckpoint/findcheckpoint.go b/cmd/findcheckpoint/findcheckpoint.go index ec4a4b30..ae307148 100644 --- a/cmd/findcheckpoint/findcheckpoint.go +++ b/cmd/findcheckpoint/findcheckpoint.go @@ -9,10 +9,10 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" ) const blockDbNamePrefix = "blocks" diff --git a/cmd/gencerts/gencerts.go b/cmd/gencerts/gencerts.go index 27d1073e..3bce5d17 100644 --- a/cmd/gencerts/gencerts.go +++ b/cmd/gencerts/gencerts.go @@ -12,8 +12,8 @@ import ( "strings" "time" - "github.com/btcsuite/btcutil" flags "github.com/jessevdk/go-flags" + btcutil "github.com/lbryio/lbcutil" ) type config struct { diff --git a/cmd/btcctl/config.go b/cmd/lbcctl/config.go similarity index 95% rename from cmd/btcctl/config.go rename to cmd/lbcctl/config.go index 1cc2a260..e00cac77 100644 --- a/cmd/btcctl/config.go +++ b/cmd/lbcctl/config.go @@ -13,10 +13,10 @@ import ( "regexp" "strings" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcutil" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -27,10 +27,10 @@ const ( ) var ( - btcdHomeDir = btcutil.AppDataDir("btcd", false) - btcctlHomeDir = btcutil.AppDataDir("btcctl", false) - btcwalletHomeDir = btcutil.AppDataDir("btcwallet", false) - defaultConfigFile = filepath.Join(btcctlHomeDir, "btcctl.conf") + btcdHomeDir = btcutil.AppDataDir("lbcd", false) + btcctlHomeDir = btcutil.AppDataDir("lbcctl", false) + btcwalletHomeDir = btcutil.AppDataDir("lbcwallet", false) + defaultConfigFile = filepath.Join(btcctlHomeDir, "lbcctl.conf") defaultRPCServer = "localhost" defaultRPCCertFile = filepath.Join(btcdHomeDir, "rpc.cert") defaultWalletCertFile = filepath.Join(btcwalletHomeDir, "rpc.cert") @@ -137,7 +137,7 @@ func normalizeAddress(addr string, chain *chaincfg.Params, useWallet bool) (stri paramErr := fmt.Errorf("cannot use -wallet with -regtest, btcwallet not yet compatible with regtest") return "", paramErr } else { - defaultPort = "18334" + defaultPort = "29245" } case &chaincfg.SigNetParams: if useWallet { @@ -231,9 +231,9 @@ func loadConfig() (*config, []string, error) { // Use config file for RPC server to create default btcctl config var serverConfigPath string if preCfg.Wallet { - serverConfigPath = filepath.Join(btcwalletHomeDir, "btcwallet.conf") + serverConfigPath = filepath.Join(btcwalletHomeDir, "lbcwallet.conf") } else { - serverConfigPath = filepath.Join(btcdHomeDir, "btcd.conf") + serverConfigPath = filepath.Join(btcdHomeDir, "lbcd.conf") } err := createDefaultConfigFile(preCfg.ConfigFile, serverConfigPath) diff --git a/cmd/btcctl/httpclient.go b/cmd/lbcctl/httpclient.go similarity index 98% rename from cmd/btcctl/httpclient.go rename to cmd/lbcctl/httpclient.go index 2a0f6dff..e7ffd205 100644 --- a/cmd/btcctl/httpclient.go +++ b/cmd/lbcctl/httpclient.go @@ -10,8 +10,8 @@ import ( "net" "net/http" - "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/go-socks/socks" + "github.com/lbryio/lbcd/btcjson" ) // newHTTPClient returns a new HTTP client that is configured according to the diff --git a/cmd/btcctl/btcctl.go b/cmd/lbcctl/lbcctl.go similarity index 99% rename from cmd/btcctl/btcctl.go rename to cmd/lbcctl/lbcctl.go index 771d5f7e..79349186 100644 --- a/cmd/btcctl/btcctl.go +++ b/cmd/lbcctl/lbcctl.go @@ -10,7 +10,7 @@ import ( "path/filepath" "strings" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) const ( diff --git a/cmd/btcctl/version.go b/cmd/lbcctl/version.go similarity index 99% rename from cmd/btcctl/version.go rename to cmd/lbcctl/version.go index edb42dbe..fcd70ce4 100644 --- a/cmd/btcctl/version.go +++ b/cmd/lbcctl/version.go @@ -18,7 +18,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr const ( appMajor uint = 0 appMinor uint = 22 - appPatch uint = 0 + appPatch uint = 100 // appPreRelease MUST only contain characters from semanticAlphabet // per the semantic versioning spec. diff --git a/config.go b/config.go index 156084bc..748a626d 100644 --- a/config.go +++ b/config.go @@ -21,26 +21,26 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/connmgr" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/go-socks/socks" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/connmgr" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( - defaultConfigFilename = "btcd.conf" + defaultConfigFilename = "lbcd.conf" defaultDataDirname = "data" defaultLogLevel = "info" defaultLogDirname = "logs" - defaultLogFilename = "btcd.log" + defaultLogFilename = "lbcd.log" defaultMaxPeers = 125 defaultBanDuration = time.Hour * 24 defaultBanThreshold = 100 @@ -63,13 +63,13 @@ const ( defaultMaxOrphanTransactions = 100 defaultMaxOrphanTxSize = 100000 defaultSigCacheMaxSize = 100000 - sampleConfigFilename = "sample-btcd.conf" + sampleConfigFilename = "sample-lbcd.conf" defaultTxIndex = false defaultAddrIndex = false ) var ( - defaultHomeDir = btcutil.AppDataDir("btcd", false) + defaultHomeDir = btcutil.AppDataDir("lbcd", false) defaultConfigFile = filepath.Join(defaultHomeDir, defaultConfigFilename) defaultDataDir = filepath.Join(defaultHomeDir, defaultDataDirname) knownDbTypes = database.SupportedDrivers() @@ -98,8 +98,8 @@ type config struct { AddCheckpoints []string `long:"addcheckpoint" description:"Add a custom checkpoint. Format: ':'"` AddPeers []string `short:"a" long:"addpeer" description:"Add a peer to connect with at startup"` AddrIndex bool `long:"addrindex" description:"Maintain a full address-based transaction index which makes the searchrawtransactions RPC available"` - AgentBlacklist []string `long:"agentblacklist" description:"A comma separated list of user-agent substrings which will cause btcd to reject any peers whose user-agent contains any of the blacklisted substrings."` - AgentWhitelist []string `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause btcd to require all peers' user-agents to contain one of the whitelisted substrings. The blacklist is applied before the blacklist, and an empty whitelist will allow all agents that do not fail the blacklist."` + AgentBlacklist []string `long:"agentblacklist" description:"A comma separated list of user-agent substrings which will cause lbcd to reject any peers whose user-agent contains any of the blacklisted substrings."` + AgentWhitelist []string `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause lbcd to require all peers' user-agents to contain one of the whitelisted substrings. The blacklist is applied before the blacklist, and an empty whitelist will allow all agents that do not fail the blacklist."` BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"` BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."` BlockMaxSize uint32 `long:"blockmaxsize" description:"Maximum block size in bytes to be used when creating a block"` @@ -125,7 +125,7 @@ type config struct { MaxOrphanTxs int `long:"maxorphantx" description:"Max number of orphan transactions to keep in memory"` MaxPeers int `long:"maxpeers" description:"Max number of inbound and outbound peers"` MiningAddrs []string `long:"miningaddr" description:"Add the specified payment address to the list of addresses to use for generated blocks -- At least one address is required if the generate option is set"` - MinRelayTxFee float64 `long:"minrelaytxfee" description:"The minimum transaction fee in BTC/kB to be considered a non-zero fee."` + MinRelayTxFee float64 `long:"minrelaytxfee" description:"The minimum transaction fee in LBC/kB to be considered a non-zero fee."` DisableBanning bool `long:"nobanning" description:"Disable banning of misbehaving peers"` NoCFilters bool `long:"nocfilters" description:"Disable committed filtering (CF) support"` DisableCheckpoints bool `long:"nocheckpoints" description:"Disable built-in checkpoints. Don't do this unless you know what you're doing."` @@ -407,7 +407,7 @@ func newConfigParser(cfg *config, so *serviceOptions, options flags.Options) *fl // 3) Load configuration file overwriting defaults with any specified options // 4) Parse CLI options and overwrite/add any specified options // -// The above results in btcd functioning properly without any config settings +// The above results in lbcd functioning properly without any config settings // while still allowing the user to override settings with config files and // command line options. Command line options always take precedence. func loadConfig() (*config, []string, error) { @@ -1146,7 +1146,7 @@ func loadConfig() (*config, []string, error) { return &cfg, remainingArgs, nil } -// createDefaultConfig copies the file sample-btcd.conf to the given destination path, +// createDefaultConfig copies the file sample-lbcd.conf to the given destination path, // and populates it with some randomly generated RPC username and password. func createDefaultConfigFile(destinationPath string) error { // Create the destination directory if it does not exists diff --git a/config_test.go b/config_test.go index e54a9f5f..84e7d444 100644 --- a/config_test.go +++ b/config_test.go @@ -20,16 +20,16 @@ func TestCreateDefaultConfigFile(t *testing.T) { if !ok { t.Fatalf("Failed finding config file path") } - sampleConfigFile := filepath.Join(filepath.Dir(path), "sample-btcd.conf") + sampleConfigFile := filepath.Join(filepath.Dir(path), "sample-lbcd.conf") // Setup a temporary directory - tmpDir, err := ioutil.TempDir("", "btcd") + tmpDir, err := ioutil.TempDir("", "lbcd") if err != nil { t.Fatalf("Failed creating a temporary directory: %v", err) } testpath := filepath.Join(tmpDir, "test.conf") - // copy config file to location of btcd binary + // copy config file to location of lbcd binary data, err := ioutil.ReadFile(sampleConfigFile) if err != nil { t.Fatalf("Failed reading sample config file: %v", err) @@ -38,7 +38,7 @@ func TestCreateDefaultConfigFile(t *testing.T) { if err != nil { t.Fatalf("Failed obtaining app path: %v", err) } - tmpConfigFile := filepath.Join(appPath, "sample-btcd.conf") + tmpConfigFile := filepath.Join(appPath, "sample-lbcd.conf") err = ioutil.WriteFile(tmpConfigFile, data, 0644) if err != nil { t.Fatalf("Failed copying sample config file: %v", err) diff --git a/connmgr/seed.go b/connmgr/seed.go index 063b546a..b35d2a1a 100644 --- a/connmgr/seed.go +++ b/connmgr/seed.go @@ -11,8 +11,8 @@ import ( "strconv" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/database/cmd/dbtool/fetchblock.go b/database/cmd/dbtool/fetchblock.go index 75a3e31a..b2ac4893 100644 --- a/database/cmd/dbtool/fetchblock.go +++ b/database/cmd/dbtool/fetchblock.go @@ -9,8 +9,8 @@ import ( "errors" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" ) // fetchBlockCmd defines the configuration options for the fetchblock command. diff --git a/database/cmd/dbtool/fetchblockregion.go b/database/cmd/dbtool/fetchblockregion.go index 9d63ed17..0204c36b 100644 --- a/database/cmd/dbtool/fetchblockregion.go +++ b/database/cmd/dbtool/fetchblockregion.go @@ -10,8 +10,8 @@ import ( "strconv" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" ) // blockRegionCmd defines the configuration options for the fetchblockregion diff --git a/database/cmd/dbtool/globalconfig.go b/database/cmd/dbtool/globalconfig.go index aa1e0e04..8d19c2b1 100644 --- a/database/cmd/dbtool/globalconfig.go +++ b/database/cmd/dbtool/globalconfig.go @@ -10,15 +10,15 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( - btcdHomeDir = btcutil.AppDataDir("btcd", false) + btcdHomeDir = btcutil.AppDataDir("lbcd", false) knownDbTypes = database.SupportedDrivers() activeNetParams = &chaincfg.MainNetParams @@ -31,7 +31,7 @@ var ( // config defines the global configuration options. type config struct { - DataDir string `short:"b" long:"datadir" description:"Location of the btcd data directory"` + DataDir string `short:"b" long:"datadir" description:"Location of the lbcd data directory"` DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` RegressionTest bool `long:"regtest" description:"Use the regression test network"` SimNet bool `long:"simnet" description:"Use the simulation test network"` @@ -60,7 +60,7 @@ func validDbType(dbType string) bool { } // netName returns the name used when referring to a bitcoin network. At the -// time of writing, btcd currently places blocks for testnet version 3 in the +// time of writing, lbcd currently places blocks for testnet version 3 in the // data and log directory "testnet", which does not match the Name field of the // chaincfg parameters. This function can be used to override this directory name // as "testnet" when the passed active network matches wire.TestNet3. diff --git a/database/cmd/dbtool/insecureimport.go b/database/cmd/dbtool/insecureimport.go index 7564eb68..442873c9 100644 --- a/database/cmd/dbtool/insecureimport.go +++ b/database/cmd/dbtool/insecureimport.go @@ -12,10 +12,10 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // importCmd defines the configuration options for the insecureimport command. diff --git a/database/cmd/dbtool/loadheaders.go b/database/cmd/dbtool/loadheaders.go index a3ee8c73..00bb5411 100644 --- a/database/cmd/dbtool/loadheaders.go +++ b/database/cmd/dbtool/loadheaders.go @@ -7,8 +7,8 @@ package main import ( "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" ) // headersCmd defines the configuration options for the loadheaders command. diff --git a/database/cmd/dbtool/main.go b/database/cmd/dbtool/main.go index 73c59a6e..c7fb6a45 100644 --- a/database/cmd/dbtool/main.go +++ b/database/cmd/dbtool/main.go @@ -9,9 +9,9 @@ import ( "path/filepath" "strings" - "github.com/btcsuite/btcd/database" "github.com/btcsuite/btclog" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/database" ) const ( diff --git a/database/driver_test.go b/database/driver_test.go index 3bb48de1..6d0b00a6 100644 --- a/database/driver_test.go +++ b/database/driver_test.go @@ -8,8 +8,8 @@ import ( "fmt" "testing" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" ) var ( diff --git a/database/error_test.go b/database/error_test.go index 759d26e1..4d053d4b 100644 --- a/database/error_test.go +++ b/database/error_test.go @@ -8,7 +8,7 @@ import ( "errors" "testing" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/database" ) // TestErrorCodeStringer tests the stringized output for the ErrorCode type. diff --git a/database/example_test.go b/database/example_test.go index 8b6fe7bc..daf475cd 100644 --- a/database/example_test.go +++ b/database/example_test.go @@ -10,11 +10,11 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - _ "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // This example demonstrates creating a new database. @@ -22,8 +22,8 @@ func ExampleCreate() { // This example assumes the ffldb driver is imported. // // import ( - // "github.com/btcsuite/btcd/database" - // _ "github.com/btcsuite/btcd/database/ffldb" + // "github.com/lbryio/lbcd/database" + // _ "github.com/lbryio/lbcd/database/ffldb" // ) // Create a database and schedule it to be closed and removed on exit. @@ -48,8 +48,8 @@ func Example_basicUsage() { // This example assumes the ffldb driver is imported. // // import ( - // "github.com/btcsuite/btcd/database" - // _ "github.com/btcsuite/btcd/database/ffldb" + // "github.com/lbryio/lbcd/database" + // _ "github.com/lbryio/lbcd/database/ffldb" // ) // Create a database and schedule it to be closed and removed on exit. @@ -114,8 +114,8 @@ func Example_blockStorageAndRetrieval() { // This example assumes the ffldb driver is imported. // // import ( - // "github.com/btcsuite/btcd/database" - // _ "github.com/btcsuite/btcd/database/ffldb" + // "github.com/lbryio/lbcd/database" + // _ "github.com/lbryio/lbcd/database/ffldb" // ) // Create a database and schedule it to be closed and removed on exit. @@ -173,5 +173,5 @@ func Example_blockStorageAndRetrieval() { fmt.Printf("Serialized block size: %d bytes\n", len(loadedBlockBytes)) // Output: - // Serialized block size: 285 bytes + // Serialized block size: 229 bytes } diff --git a/database/ffldb/bench_test.go b/database/ffldb/bench_test.go index 8d020313..7ea0d126 100644 --- a/database/ffldb/bench_test.go +++ b/database/ffldb/bench_test.go @@ -9,9 +9,9 @@ import ( "path/filepath" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + btcutil "github.com/lbryio/lbcutil" ) // BenchmarkBlockHeader benchmarks how long it takes to load the mainnet genesis diff --git a/database/ffldb/blockio.go b/database/ffldb/blockio.go index 8fb27ab2..ae71a891 100644 --- a/database/ffldb/blockio.go +++ b/database/ffldb/blockio.go @@ -17,9 +17,9 @@ import ( "path/filepath" "sync" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/database/ffldb/db.go b/database/ffldb/db.go index b4994421..0d6acd51 100644 --- a/database/ffldb/db.go +++ b/database/ffldb/db.go @@ -14,11 +14,6 @@ import ( "sort" "sync" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/database/internal/treap" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/goleveldb/leveldb" "github.com/btcsuite/goleveldb/leveldb/comparer" ldberrors "github.com/btcsuite/goleveldb/leveldb/errors" @@ -26,6 +21,11 @@ import ( "github.com/btcsuite/goleveldb/leveldb/iterator" "github.com/btcsuite/goleveldb/leveldb/opt" "github.com/btcsuite/goleveldb/leveldb/util" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/database/internal/treap" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/database/ffldb/dbcache.go b/database/ffldb/dbcache.go index a2346b58..15c554a7 100644 --- a/database/ffldb/dbcache.go +++ b/database/ffldb/dbcache.go @@ -10,10 +10,10 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/database/internal/treap" "github.com/btcsuite/goleveldb/leveldb" "github.com/btcsuite/goleveldb/leveldb/iterator" "github.com/btcsuite/goleveldb/leveldb/util" + "github.com/lbryio/lbcd/database/internal/treap" ) const ( diff --git a/database/ffldb/doc.go b/database/ffldb/doc.go index 96a2992c..cca5ebc5 100644 --- a/database/ffldb/doc.go +++ b/database/ffldb/doc.go @@ -6,7 +6,7 @@ Package ffldb implements a driver for the database package that uses leveldb for the backing metadata and flat files for block storage. -This driver is the recommended driver for use with btcd. It makes use leveldb +This driver is the recommended driver for use with lbcd. It makes use leveldb for the metadata, flat files for block storage, and checksums in key areas to ensure data integrity. diff --git a/database/ffldb/driver.go b/database/ffldb/driver.go index 28ab8277..39a1e02b 100644 --- a/database/ffldb/driver.go +++ b/database/ffldb/driver.go @@ -7,9 +7,9 @@ package ffldb import ( "fmt" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btclog" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" ) var log = btclog.Disabled diff --git a/database/ffldb/driver_test.go b/database/ffldb/driver_test.go index f3db909d..ff53acd0 100644 --- a/database/ffldb/driver_test.go +++ b/database/ffldb/driver_test.go @@ -11,10 +11,10 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/database/ffldb" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/database/ffldb" + btcutil "github.com/lbryio/lbcutil" ) // dbType is the database type name for this driver. diff --git a/database/ffldb/export_test.go b/database/ffldb/export_test.go index 2d8e4d2a..bcad41af 100644 --- a/database/ffldb/export_test.go +++ b/database/ffldb/export_test.go @@ -11,7 +11,7 @@ The functions are only exported while the tests are being run. package ffldb -import "github.com/btcsuite/btcd/database" +import "github.com/lbryio/lbcd/database" // TstRunWithMaxBlockFileSize runs the passed function with the maximum allowed // file size for the database set to the provided value. The value will be set diff --git a/database/ffldb/interface_test.go b/database/ffldb/interface_test.go index 1ce991cc..b1b4cac7 100644 --- a/database/ffldb/interface_test.go +++ b/database/ffldb/interface_test.go @@ -25,11 +25,10 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( diff --git a/database/ffldb/ldbtreapiter.go b/database/ffldb/ldbtreapiter.go index b3d6b6bd..0a552633 100644 --- a/database/ffldb/ldbtreapiter.go +++ b/database/ffldb/ldbtreapiter.go @@ -5,9 +5,9 @@ package ffldb import ( - "github.com/btcsuite/btcd/database/internal/treap" "github.com/btcsuite/goleveldb/leveldb/iterator" "github.com/btcsuite/goleveldb/leveldb/util" + "github.com/lbryio/lbcd/database/internal/treap" ) // ldbTreapIter wraps a treap iterator to provide the additional functionality diff --git a/database/ffldb/reconcile.go b/database/ffldb/reconcile.go index e2c4d6bb..60456c26 100644 --- a/database/ffldb/reconcile.go +++ b/database/ffldb/reconcile.go @@ -8,7 +8,7 @@ import ( "fmt" "hash/crc32" - "github.com/btcsuite/btcd/database" + "github.com/lbryio/lbcd/database" ) // The serialized write cursor location format is: diff --git a/database/ffldb/whitebox_test.go b/database/ffldb/whitebox_test.go index 161d866d..4314c69f 100644 --- a/database/ffldb/whitebox_test.go +++ b/database/ffldb/whitebox_test.go @@ -17,12 +17,11 @@ import ( "path/filepath" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/goleveldb/leveldb" ldberrors "github.com/btcsuite/goleveldb/leveldb/errors" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( diff --git a/database/interface.go b/database/interface.go index 435a8ff5..5b566f11 100644 --- a/database/interface.go +++ b/database/interface.go @@ -8,8 +8,8 @@ package database import ( - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + btcutil "github.com/lbryio/lbcutil" ) // Cursor represents a cursor over key/value pairs and nested buckets of a diff --git a/doc.go b/doc.go index 70d0d9e4..ce62a7cc 100644 --- a/doc.go +++ b/doc.go @@ -3,22 +3,22 @@ // license that can be found in the LICENSE file. /* -btcd is a full-node bitcoin implementation written in Go. +lbcd is a full-node bitcoin implementation written in Go. -The default options are sane for most users. This means btcd will work 'out of +The default options are sane for most users. This means lbcd will work 'out of the box' for most users. However, there are also a wide variety of flags that can be used to control it. The following section provides a usage overview which enumerates the flags. An interesting point to note is that the long form of all of these options (except -C) can be specified in a configuration file that is automatically -parsed when btcd starts up. By default, the configuration file is located at -~/.btcd/btcd.conf on POSIX-style operating systems and %LOCALAPPDATA%\btcd\btcd.conf +parsed when lbcd starts up. By default, the configuration file is located at +~/.lbcd/lbcd.conf on POSIX-style operating systems and %LOCALAPPDATA%\lbcd\lbcd.conf on Windows. The -C (--configfile) flag, as shown below, can be used to override this location. Usage: - btcd [OPTIONS] + lbcd [OPTIONS] Application Options: --addcheckpoint= Add a custom checkpoint. Format: diff --git a/docs/conf.py b/docs/conf.py index 3db16305..145c0ac5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,9 +18,9 @@ from recommonmark.transform import AutoStructify # -- Project information ----------------------------------------------------- -project = 'btcd' -copyright = '2020, btcd' -author = 'btcsuite developers' +project = 'lbcd' +copyright = '2021, lbcd' +author = 'LBRY developers' # The full version, including alpha/beta/rc tags release = 'beta' @@ -65,9 +65,11 @@ html_theme = 'sphinx_rtd_theme' html_static_path = ['_static'] # app setup hook + + def setup(app): app.add_config_value('recommonmark_config', { - #'url_resolver': lambda url: github_doc_root + url, + # 'url_resolver': lambda url: github_doc_root + url, 'auto_toc_tree_section': 'Contents', 'enable_math': False, 'enable_inline_math': False, diff --git a/integration/bip0009_test.go b/integration/bip0009_test.go index 9bdec34f..fa94d2d0 100644 --- a/integration/bip0009_test.go +++ b/integration/bip0009_test.go @@ -13,10 +13,10 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/integration/rpctest" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/integration/rpctest" ) const ( diff --git a/integration/csv_fork_test.go b/integration/csv_fork_test.go index 31466349..1b4ae02b 100644 --- a/integration/csv_fork_test.go +++ b/integration/csv_fork_test.go @@ -14,14 +14,14 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/integration/rpctest" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/integration/rpctest" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/integration/rpcserver_test.go b/integration/rpcserver_test.go index 5875b353..9fbddc6b 100644 --- a/integration/rpcserver_test.go +++ b/integration/rpcserver_test.go @@ -14,10 +14,10 @@ import ( "runtime/debug" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/integration/rpctest" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/integration/rpctest" + "github.com/lbryio/lbcd/rpcclient" ) func testGetBestBlock(r *rpctest.Harness, t *testing.T) { diff --git a/integration/rpctest/blockgen.go b/integration/rpctest/blockgen.go index 0d802f5a..dae3b7fd 100644 --- a/integration/rpctest/blockgen.go +++ b/integration/rpctest/blockgen.go @@ -11,13 +11,13 @@ import ( "runtime" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // solveBlock attempts to find a nonce which makes the passed block header hash diff --git a/integration/rpctest/btcd.go b/integration/rpctest/btcd.go index 29642c84..e3bd4178 100644 --- a/integration/rpctest/btcd.go +++ b/integration/rpctest/btcd.go @@ -44,16 +44,16 @@ func btcdExecutablePath() (string, error) { } // Build btcd and output an executable in a static temp path. - outputPath := filepath.Join(testDir, "btcd") + outputPath := filepath.Join(testDir, "lbcd") if runtime.GOOS == "windows" { outputPath += ".exe" } cmd := exec.Command( - "go", "build", "-o", outputPath, "github.com/btcsuite/btcd", + "go", "build", "-o", outputPath, "github.com/lbryio/lbcd", ) err = cmd.Run() if err != nil { - return "", fmt.Errorf("Failed to build btcd: %v", err) + return "", fmt.Errorf("Failed to build lbcd: %v", err) } // Save executable path so future calls do not recompile. diff --git a/integration/rpctest/memwallet.go b/integration/rpctest/memwallet.go index 59b0ef4c..c1374ef3 100644 --- a/integration/rpctest/memwallet.go +++ b/integration/rpctest/memwallet.go @@ -10,15 +10,15 @@ import ( "fmt" "sync" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" - "github.com/btcsuite/btcutil/hdkeychain" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" + "github.com/lbryio/lbcutil/hdkeychain" ) var ( diff --git a/integration/rpctest/node.go b/integration/rpctest/node.go index 73dc15fc..2c7644b8 100644 --- a/integration/rpctest/node.go +++ b/integration/rpctest/node.go @@ -14,8 +14,8 @@ import ( "runtime" "time" - rpc "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" + rpc "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) // nodeConfig contains all the args, and data required to launch a btcd process @@ -51,7 +51,7 @@ func newConfig(prefix, certFile, keyFile string, extra []string, var err error btcdPath, err = btcdExecutablePath() if err != nil { - btcdPath = "btcd" + btcdPath = "lbcd" } } diff --git a/integration/rpctest/rpc_harness.go b/integration/rpctest/rpc_harness.go index 679ae4e4..1d1eaefa 100644 --- a/integration/rpctest/rpc_harness.go +++ b/integration/rpctest/rpc_harness.go @@ -16,11 +16,11 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -531,7 +531,7 @@ func generateListeningAddresses() (string, string) { // baseDir is the directory path of the temp directory for all rpctest files. func baseDir() (string, error) { - dirPath := filepath.Join(os.TempDir(), "btcd", "rpctest") + dirPath := filepath.Join(os.TempDir(), "lbcd", "rpctest") err := os.MkdirAll(dirPath, 0755) return dirPath, err } diff --git a/integration/rpctest/rpc_harness_test.go b/integration/rpctest/rpc_harness_test.go index df753e31..de9db318 100644 --- a/integration/rpctest/rpc_harness_test.go +++ b/integration/rpctest/rpc_harness_test.go @@ -13,11 +13,11 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) func testSendOutputs(r *Harness, t *testing.T) { diff --git a/integration/rpctest/utils.go b/integration/rpctest/utils.go index d4d76f2e..3273ae3c 100644 --- a/integration/rpctest/utils.go +++ b/integration/rpctest/utils.go @@ -8,8 +8,8 @@ import ( "reflect" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" ) // JoinType is an enum representing a particular type of "node join". A node diff --git a/btcd.go b/lbcd.go similarity index 98% rename from btcd.go rename to lbcd.go index 4f04657b..1b2ad72d 100644 --- a/btcd.go +++ b/lbcd.go @@ -15,10 +15,10 @@ import ( "runtime/debug" "runtime/pprof" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/claimtrie/param" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/limits" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/claimtrie/param" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/limits" "github.com/felixge/fgprof" ) diff --git a/log.go b/log.go index a69509cd..cc845475 100644 --- a/log.go +++ b/log.go @@ -10,18 +10,18 @@ import ( "os" "path/filepath" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/claimtrie/node" - "github.com/btcsuite/btcd/connmgr" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/mining/cpuminer" - "github.com/btcsuite/btcd/netsync" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/txscript" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/connmgr" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/mining/cpuminer" + "github.com/lbryio/lbcd/netsync" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/txscript" "github.com/btcsuite/btclog" "github.com/jrick/logrotate/rotator" diff --git a/mempool/error.go b/mempool/error.go index b0d42be4..7d107ae3 100644 --- a/mempool/error.go +++ b/mempool/error.go @@ -5,8 +5,8 @@ package mempool import ( - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/wire" ) // RuleError identifies a rule violation. It is used to indicate that diff --git a/mempool/estimatefee.go b/mempool/estimatefee.go index 55fe4810..719c42e2 100644 --- a/mempool/estimatefee.go +++ b/mempool/estimatefee.go @@ -16,9 +16,9 @@ import ( "strings" "sync" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + btcutil "github.com/lbryio/lbcutil" ) // TODO incorporate Alex Morcos' modifications to Gavin's initial model diff --git a/mempool/estimatefee_test.go b/mempool/estimatefee_test.go index 16dcfadc..6f86d035 100644 --- a/mempool/estimatefee_test.go +++ b/mempool/estimatefee_test.go @@ -9,10 +9,10 @@ import ( "math/rand" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // newTestFeeEstimator creates a feeEstimator with some different parameters diff --git a/mempool/mempool.go b/mempool/mempool.go index 0aecff7e..de3b8028 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -12,15 +12,15 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 96d50544..b24045ba 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -12,13 +12,13 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // fakeChain is used by the pool harness to provide generated test utxos and diff --git a/mempool/policy.go b/mempool/policy.go index c18b0d7d..21899b0f 100644 --- a/mempool/policy.go +++ b/mempool/policy.go @@ -6,12 +6,13 @@ package mempool import ( "fmt" + "math" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/mempool/policy_test.go b/mempool/policy_test.go index b9cdbac4..b677ab82 100644 --- a/mempool/policy_test.go +++ b/mempool/policy_test.go @@ -9,12 +9,12 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // TestCalcMinRequiredTxRelayFee tests the calcMinRequiredTxRelayFee API. diff --git a/mining/cpuminer/cpuminer.go b/mining/cpuminer/cpuminer.go index 3d5b3b19..b9d1d222 100644 --- a/mining/cpuminer/cpuminer.go +++ b/mining/cpuminer/cpuminer.go @@ -12,12 +12,12 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/mining/mining.go b/mining/mining.go index e918328d..4daad1a6 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -10,12 +10,12 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( @@ -30,7 +30,7 @@ const ( // CoinbaseFlags is added to the coinbase script of a generated block // and is used to monitor BIP16 support as well as blocks that are // generated via btcd. - CoinbaseFlags = "/P2SH/btcd/" + CoinbaseFlags = "/P2SH/lbcd/" ) // TxDesc is a descriptor about a transaction in a transaction source along with diff --git a/mining/mining_test.go b/mining/mining_test.go index 362253e5..f2a65419 100644 --- a/mining/mining_test.go +++ b/mining/mining_test.go @@ -9,7 +9,7 @@ import ( "math/rand" "testing" - "github.com/btcsuite/btcutil" + btcutil "github.com/lbryio/lbcutil" ) // TestTxFeePrioHeap ensures the priority queue for transaction fees and diff --git a/mining/policy.go b/mining/policy.go index c3f059c5..040095f9 100644 --- a/mining/policy.go +++ b/mining/policy.go @@ -5,9 +5,9 @@ package mining import ( - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/mining/policy_test.go b/mining/policy_test.go index f66a9c8d..e7ababfa 100644 --- a/mining/policy_test.go +++ b/mining/policy_test.go @@ -8,10 +8,10 @@ import ( "encoding/hex" "testing" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // newHashFromStr converts the passed big-endian hex string into a diff --git a/netsync/blocklogger.go b/netsync/blocklogger.go index 18480e78..34a549a1 100644 --- a/netsync/blocklogger.go +++ b/netsync/blocklogger.go @@ -9,7 +9,7 @@ import ( "time" "github.com/btcsuite/btclog" - "github.com/btcsuite/btcutil" + btcutil "github.com/lbryio/lbcutil" ) // blockProgressLogger provides periodic logging for other services in order diff --git a/netsync/interface.go b/netsync/interface.go index 3e6ca1c1..9361bfbc 100644 --- a/netsync/interface.go +++ b/netsync/interface.go @@ -5,13 +5,13 @@ package netsync import ( - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // PeerNotifier exposes methods to notify peers of status changes to diff --git a/netsync/manager.go b/netsync/manager.go index 2b6c0411..2e3f05b0 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -12,14 +12,14 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/mempool" - peerpkg "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/mempool" + peerpkg "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/params.go b/params.go index b4d1453d..664a7e6a 100644 --- a/params.go +++ b/params.go @@ -5,8 +5,8 @@ package main import ( - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" ) // activeNetParams is a pointer to the parameters specific to the diff --git a/peer/doc.go b/peer/doc.go index 88fae8e8..1bb8cf32 100644 --- a/peer/doc.go +++ b/peer/doc.go @@ -145,6 +145,6 @@ raw message bytes using a format similar to hexdump -C. Bitcoin Improvement Proposals This package supports all BIPS supported by the wire package. -(https://pkg.go.dev/github.com/btcsuite/btcd/wire#hdr-Bitcoin_Improvement_Proposals) +(https://pkg.go.dev/github.com/lbryio/lbcd/wire#hdr-Bitcoin_Improvement_Proposals) */ package peer diff --git a/peer/example_test.go b/peer/example_test.go index d4662a2b..268ed1ea 100644 --- a/peer/example_test.go +++ b/peer/example_test.go @@ -10,9 +10,9 @@ import ( "net" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" ) // mockRemotePeer creates a basic inbound peer listening on the simnet port for diff --git a/peer/log.go b/peer/log.go index 71bebd0d..a96b8e50 100644 --- a/peer/log.go +++ b/peer/log.go @@ -9,10 +9,10 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btclog" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/peer/peer.go b/peer/peer.go index a7b92580..ab8add08 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -18,13 +18,13 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" "github.com/btcsuite/go-socks/socks" "github.com/davecgh/go-spew/spew" "github.com/decred/dcrd/lru" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) const ( diff --git a/peer/peer_test.go b/peer/peer_test.go index dd7f36aa..0cb9c66c 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -13,11 +13,11 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" "github.com/btcsuite/go-socks/socks" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" ) // conn mocks a network connection by implementing the net.Conn interface. It diff --git a/rpcadapters.go b/rpcadapters.go index ddcdf79b..2a1af72f 100644 --- a/rpcadapters.go +++ b/rpcadapters.go @@ -7,13 +7,13 @@ package main import ( "sync/atomic" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/netsync" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/netsync" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // rpcPeer provides a peer for use with the RPC server and implements the diff --git a/rpcclient/chain.go b/rpcclient/chain.go index a97543fd..b3735cee 100644 --- a/rpcclient/chain.go +++ b/rpcclient/chain.go @@ -10,9 +10,9 @@ import ( "encoding/hex" "encoding/json" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // FutureGetBestBlockHashResult is a future promise to deliver the result of a diff --git a/rpcclient/doc.go b/rpcclient/doc.go index b682ba10..d82a40a1 100644 --- a/rpcclient/doc.go +++ b/rpcclient/doc.go @@ -9,7 +9,7 @@ Overview This client provides a robust and easy to use client for interfacing with a Bitcoin RPC server that uses a btcd/bitcoin core compatible Bitcoin JSON-RPC -API. This client has been tested with btcd (https://github.com/btcsuite/btcd), +API. This client has been tested with btcd (https://github.com/lbryio/lbcd), btcwallet (https://github.com/btcsuite/btcwallet), and bitcoin core (https://github.com/bitcoin). diff --git a/rpcclient/example_test.go b/rpcclient/example_test.go index 9ba9adad..f044e9f1 100644 --- a/rpcclient/example_test.go +++ b/rpcclient/example_test.go @@ -6,7 +6,8 @@ package rpcclient import ( "fmt" - "github.com/btcsuite/btcd/btcjson" + + "github.com/lbryio/lbcd/btcjson" ) var connCfg = &ConnConfig{ diff --git a/rpcclient/examples/bitcoincorehttp/main.go b/rpcclient/examples/bitcoincorehttp/main.go index 489770a2..54e727de 100644 --- a/rpcclient/examples/bitcoincorehttp/main.go +++ b/rpcclient/examples/bitcoincorehttp/main.go @@ -7,7 +7,7 @@ package main import ( "log" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/rpcclient" ) func main() { diff --git a/rpcclient/examples/bitcoincorehttpbulk/main.go b/rpcclient/examples/bitcoincorehttpbulk/main.go index 3dce058d..fd21ede4 100644 --- a/rpcclient/examples/bitcoincorehttpbulk/main.go +++ b/rpcclient/examples/bitcoincorehttpbulk/main.go @@ -8,7 +8,7 @@ import ( "fmt" "log" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/rpcclient" ) func main() { diff --git a/rpcclient/examples/btcdwebsockets/main.go b/rpcclient/examples/btcdwebsockets/main.go index 56d12d82..30bb4188 100644 --- a/rpcclient/examples/btcdwebsockets/main.go +++ b/rpcclient/examples/btcdwebsockets/main.go @@ -10,9 +10,9 @@ import ( "path/filepath" "time" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) func main() { @@ -32,7 +32,7 @@ func main() { } // Connect to local btcd RPC server using websockets. - btcdHomeDir := btcutil.AppDataDir("btcd", false) + btcdHomeDir := btcutil.AppDataDir("lbcd", false) certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) diff --git a/rpcclient/examples/btcwalletwebsockets/main.go b/rpcclient/examples/btcwalletwebsockets/main.go index e803138d..b0bc6f83 100644 --- a/rpcclient/examples/btcwalletwebsockets/main.go +++ b/rpcclient/examples/btcwalletwebsockets/main.go @@ -10,9 +10,9 @@ import ( "path/filepath" "time" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) func main() { @@ -27,8 +27,8 @@ func main() { }, } - // Connect to local btcwallet RPC server using websockets. - certHomeDir := btcutil.AppDataDir("btcwallet", false) + // Connect to local lbcwallet RPC server using websockets. + certHomeDir := btcutil.AppDataDir("lbcwallet", false) certs, err := ioutil.ReadFile(filepath.Join(certHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) diff --git a/rpcclient/extensions.go b/rpcclient/extensions.go index c8615293..da44e91f 100644 --- a/rpcclient/extensions.go +++ b/rpcclient/extensions.go @@ -12,10 +12,10 @@ import ( "encoding/json" "fmt" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // FutureDebugLevelResult is a future promise to deliver the result of a diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index 63874c1b..730f8bcb 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -25,10 +25,10 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/go-socks/socks" "github.com/btcsuite/websocket" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" ) var ( @@ -114,8 +114,8 @@ const ( // 0.19.0. BitcoindPost19 - // Btcd represents a catch-all btcd version. - Btcd + // Lbcd represents a catch-all lbcd version. + Lbcd ) // Client represents a Bitcoin RPC client which allows easy access to the @@ -1587,8 +1587,8 @@ func (c *Client) BackendVersion() (BackendVersion, error) { switch err := err.(type) { // Parse the btcd version and cache it. case nil: - log.Debugf("Detected btcd version: %v", info.Version) - version := Btcd + log.Debugf("Detected lbcd version: %v", info.Version) + version := Lbcd c.backendVersion = &version return *c.backendVersion, nil @@ -1596,12 +1596,12 @@ func (c *Client) BackendVersion() (BackendVersion, error) { // we actually ran into an error. case *btcjson.RPCError: if err.Code != btcjson.ErrRPCMethodNotFound.Code { - return 0, fmt.Errorf("unable to detect btcd version: "+ + return 0, fmt.Errorf("unable to detect lbcd version: "+ "%v", err) } default: - return 0, fmt.Errorf("unable to detect btcd version: %v", err) + return 0, fmt.Errorf("unable to detect lbcd version: %v", err) } // Since the GetInfo method was not found, we assume the client is diff --git a/rpcclient/mining.go b/rpcclient/mining.go index 15473e24..ead35213 100644 --- a/rpcclient/mining.go +++ b/rpcclient/mining.go @@ -9,9 +9,9 @@ import ( "encoding/json" "errors" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + btcutil "github.com/lbryio/lbcutil" ) // FutureGenerateResult is a future promise to deliver the result of a diff --git a/rpcclient/net.go b/rpcclient/net.go index da2006c2..2d268235 100644 --- a/rpcclient/net.go +++ b/rpcclient/net.go @@ -7,7 +7,7 @@ package rpcclient import ( "encoding/json" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // AddNodeCommand enumerates the available commands that the AddNode function diff --git a/rpcclient/notify.go b/rpcclient/notify.go index 6879099a..dff3b416 100644 --- a/rpcclient/notify.go +++ b/rpcclient/notify.go @@ -13,10 +13,10 @@ import ( "fmt" "time" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) var ( @@ -419,7 +419,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { connected, err := parseBtcdConnectedNtfnParams(ntfn.Params) if err != nil { - log.Warnf("Received invalid btcd connected "+ + log.Warnf("Received invalid lbcd connected "+ "notification: %v", err) return } diff --git a/rpcclient/rawrequest.go b/rpcclient/rawrequest.go index f446b008..7c3bddf9 100644 --- a/rpcclient/rawrequest.go +++ b/rpcclient/rawrequest.go @@ -8,7 +8,7 @@ import ( "encoding/json" "errors" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // FutureRawResult is a future promise to deliver the result of a RawRequest RPC diff --git a/rpcclient/rawtransactions.go b/rpcclient/rawtransactions.go index cfc322c7..d0f28c8a 100644 --- a/rpcclient/rawtransactions.go +++ b/rpcclient/rawtransactions.go @@ -9,10 +9,10 @@ import ( "encoding/hex" "encoding/json" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index 71435d99..df928969 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -8,11 +8,11 @@ import ( "encoding/json" "strconv" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // ***************************** diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 570b5b05..e8f7a640 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - "github.com/btcsuite/btcd/btcjson" + "github.com/lbryio/lbcd/btcjson" ) // helpDescsEnUS defines the English descriptions used for the help strings. @@ -21,7 +21,7 @@ var helpDescsEnUS = map[string]string{ "The levelspec can either a debug level or of the form:\n" + "=,=,...\n" + "The valid debug levels are trace, debug, info, warn, error, and critical.\n" + - "The valid subsystems are AMGR, ADXR, BCDB, BMGR, BTCD, CHAN, DISC, PEER, RPCS, SCRP, SRVR, and TXMP.\n" + + "The valid subsystems are AMGR, ADXR, BCDB, BMGR, MAIN, LBRY, CHAN, DISC, PEER, RPCS, SCRP, SRVR, and TXMP.\n" + "Finally the keyword 'show' will return a list of the available subsystems.", "debuglevel-levelspec": "The debug level(s) to use or the keyword 'show'", "debuglevel--condition0": "levelspec!=show", @@ -52,7 +52,7 @@ var helpDescsEnUS = map[string]string{ "createrawtransaction-amounts": "JSON object with the destination addresses as keys and amounts as values", "createrawtransaction-amounts--key": "address", "createrawtransaction-amounts--value": "n.nnn", - "createrawtransaction-amounts--desc": "The destination address as the key and the amount in BTC as the value", + "createrawtransaction-amounts--desc": "The destination address as the key and the amount in LBC as the value", "createrawtransaction-locktime": "Locktime value; a non-zero value will also locktime-activate the inputs", "createrawtransaction--result0": "Hex-encoded bytes of the serialized transaction", @@ -87,9 +87,11 @@ var helpDescsEnUS = map[string]string{ "scriptpubkeyresult-reqSigs": "The number of required signatures", "scriptpubkeyresult-type": "The type of the script (e.g. 'pubkeyhash')", "scriptpubkeyresult-addresses": "The bitcoin addresses associated with this script", + "scriptpubkeyresult-issupport": "Creates a support", + "scriptpubkeyresult-isclaim": "Creates or updates a claim", // Vout help. - "vout-value": "The amount in BTC", + "vout-value": "The amount in LBC", "vout-n": "The index of this transaction output", "vout-scriptPubKey": "The public key script used to pay coins as a JSON object", @@ -388,7 +390,7 @@ var helpDescsEnUS = map[string]string{ "infochainresult-proxy": "The proxy used by the server", "infochainresult-difficulty": "The current target difficulty", "infochainresult-testnet": "Whether or not server is using testnet", - "infochainresult-relayfee": "The minimum relay fee for non-free transactions in BTC/KB", + "infochainresult-relayfee": "The minimum relay fee for non-free transactions in LBC/KB", "infochainresult-errors": "Any current errors", // InfoWalletResult help. @@ -405,8 +407,8 @@ var helpDescsEnUS = map[string]string{ "infowalletresult-keypoololdest": "Seconds since 1 Jan 1970 GMT of the oldest pre-generated key in the key pool", "infowalletresult-keypoolsize": "The number of new keys that are pre-generated", "infowalletresult-unlocked_until": "The timestamp in seconds since 1 Jan 1970 GMT that the wallet is unlocked for transfers, or 0 if the wallet is locked", - "infowalletresult-paytxfee": "The transaction fee set in BTC/KB", - "infowalletresult-relayfee": "The minimum relay fee for non-free transactions in BTC/KB", + "infowalletresult-paytxfee": "The transaction fee set in LBC/KB", + "infowalletresult-relayfee": "The minimum relay fee for non-free transactions in LBC/KB", "infowalletresult-errors": "Any current errors", // GetHeadersCmd help. @@ -522,7 +524,7 @@ var helpDescsEnUS = map[string]string{ // GetTxOutResult help. "gettxoutresult-bestblock": "The block hash that contains the transaction output", "gettxoutresult-confirmations": "The number of confirmations", - "gettxoutresult-value": "The transaction amount in BTC", + "gettxoutresult-value": "The transaction amount in LBC", "gettxoutresult-scriptPubKey": "The public key script used to pay coins as a JSON object", "gettxoutresult-version": "The transaction version", "gettxoutresult-coinbase": "Whether or not the transaction is a coinbase", @@ -565,7 +567,7 @@ var helpDescsEnUS = map[string]string{ // SendRawTransactionCmd help. "sendrawtransaction--synopsis": "Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.", "sendrawtransaction-hextx": "Serialized, hex-encoded signed transaction", - "sendrawtransaction-feesetting": "Whether or not to allow insanely high fees in bitcoind < v0.19.0 or the max fee rate for bitcoind v0.19.0 and later (btcd does not yet implement this parameter, so it has no effect)", + "sendrawtransaction-feesetting": "Whether or not to allow insanely high fees in bitcoind < v0.19.0 or the max fee rate for bitcoind v0.19.0 and later (lbcd does not yet implement this parameter, so it has no effect)", "sendrawtransaction--result0": "The hash of the transaction", "allowhighfeesormaxfeerate-value": "Either the boolean value for the allowhighfees parameter in bitcoind < v0.19.0 or the numerical value for the maxfeerate field in bitcoind v0.19.0 and later", @@ -581,8 +583,8 @@ var helpDescsEnUS = map[string]string{ "signmessagewithprivkey--result0": "The signature of the message encoded in base 64", // StopCmd help. - "stop--synopsis": "Shutdown btcd.", - "stop--result0": "The string 'btcd stopping.'", + "stop--synopsis": "Shutdown lbcd.", + "stop--result0": "The string 'lbcd stopping.'", // SubmitBlockOptions help. "submitblockoptions-workid": "This parameter is currently ignored", @@ -610,7 +612,7 @@ var helpDescsEnUS = map[string]string{ // VerifyChainCmd help. "verifychain--synopsis": "Verifies the block chain database.\n" + "The actual checks performed by the checklevel parameter are implementation specific.\n" + - "For btcd this is:\n" + + "For lbcd this is:\n" + "checklevel=0 - Look up each block and ensure it can be loaded from the database.\n" + "checklevel=1 - Perform basic context-free sanity checks on each block.", "verifychain-checklevel": "How thorough the block verification is", @@ -657,7 +659,7 @@ var helpDescsEnUS = map[string]string{ "outpoint-index": "The index of the outpoint", // NotifySpentCmd help. - "notifyspent--synopsis": "Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this btcd instance) and when such a transaction first appears in a newly-attached block.", + "notifyspent--synopsis": "Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this lbcd instance) and when such a transaction first appears in a newly-attached block.", "notifyspent-outpoints": "List of transaction outpoints to monitor.", // StopNotifySpentCmd help. diff --git a/rpcwebsocket.go b/rpcwebsocket.go index 356a8974..dd18686a 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -20,15 +20,15 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/websocket" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" "golang.org/x/crypto/ripemd160" ) diff --git a/server.go b/server.go index a38df175..6f6050c6 100644 --- a/server.go +++ b/server.go @@ -22,24 +22,24 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/addrmgr" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/claimtrie" - claimtrieconfig "github.com/btcsuite/btcd/claimtrie/config" - "github.com/btcsuite/btcd/connmgr" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/mining/cpuminer" - "github.com/btcsuite/btcd/netsync" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" - "github.com/btcsuite/btcutil/bloom" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie" + claimtrieconfig "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/connmgr" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/mining/cpuminer" + "github.com/lbryio/lbcd/netsync" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" + "github.com/lbryio/lbcutil/bloom" ) const ( @@ -2535,7 +2535,7 @@ out: // listen port? // XXX this assumes timeout is in seconds. listenPort, err := s.nat.AddPortMapping("tcp", int(lport), int(lport), - "btcd listen port", 20*60) + "lbcd listen port", 20*60) if err != nil { srvrLog.Warnf("can't add UPnP port mapping: %v", err) } diff --git a/txscript/bench_test.go b/txscript/bench_test.go index cac29202..e568b7fc 100644 --- a/txscript/bench_test.go +++ b/txscript/bench_test.go @@ -10,8 +10,8 @@ import ( "io/ioutil" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" ) var ( diff --git a/txscript/engine.go b/txscript/engine.go index 40ba0eef..66ead036 100644 --- a/txscript/engine.go +++ b/txscript/engine.go @@ -12,8 +12,8 @@ import ( "math/big" "strings" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/wire" ) // ScriptFlags is a bitmask defining additional operations or tests that will be diff --git a/txscript/engine_test.go b/txscript/engine_test.go index 5818080d..09f945c9 100644 --- a/txscript/engine_test.go +++ b/txscript/engine_test.go @@ -8,8 +8,8 @@ package txscript import ( "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // TestBadPC sets the pc to a deliberately bad result then confirms that Step diff --git a/txscript/example_test.go b/txscript/example_test.go index 6e17341c..82a11799 100644 --- a/txscript/example_test.go +++ b/txscript/example_test.go @@ -9,12 +9,12 @@ import ( "encoding/hex" "fmt" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // This example demonstrates creating a script which pays to a bitcoin address. diff --git a/txscript/hashcache.go b/txscript/hashcache.go index f9c2caf7..ab5d9d1b 100644 --- a/txscript/hashcache.go +++ b/txscript/hashcache.go @@ -7,8 +7,8 @@ package txscript import ( "sync" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // TxSigHashes houses the partial set of sighashes introduced within BIP0143. diff --git a/txscript/hashcache_test.go b/txscript/hashcache_test.go index cee59b99..c1373497 100644 --- a/txscript/hashcache_test.go +++ b/txscript/hashcache_test.go @@ -9,8 +9,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/wire" ) func init() { diff --git a/txscript/opcode.go b/txscript/opcode.go index 4c00f353..7df52d7a 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -15,9 +15,9 @@ import ( "golang.org/x/crypto/ripemd160" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // An opcode defines the information related to a txscript opcode. opfunc, if diff --git a/txscript/pkscript.go b/txscript/pkscript.go index f5b11e6d..999ce212 100644 --- a/txscript/pkscript.go +++ b/txscript/pkscript.go @@ -5,10 +5,10 @@ import ( "errors" "fmt" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" "golang.org/x/crypto/ripemd160" ) diff --git a/txscript/pkscript_test.go b/txscript/pkscript_test.go index 49e2db8a..1e95a49f 100644 --- a/txscript/pkscript_test.go +++ b/txscript/pkscript_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // TestParsePkScript ensures that the supported script types can be parsed diff --git a/txscript/reference_test.go b/txscript/reference_test.go index 9d9c8f39..9642e424 100644 --- a/txscript/reference_test.go +++ b/txscript/reference_test.go @@ -15,9 +15,9 @@ import ( "strings" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // scriptTestName returns a descriptive test name for the given reference script diff --git a/txscript/script.go b/txscript/script.go index 1b3a60bd..6354a92b 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -12,8 +12,8 @@ import ( "strings" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" ) // Bip16Activation is the timestamp where BIP0016 is valid to use in the diff --git a/txscript/script_test.go b/txscript/script_test.go index 86f94d84..dd61c4a6 100644 --- a/txscript/script_test.go +++ b/txscript/script_test.go @@ -9,7 +9,7 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/wire" + "github.com/lbryio/lbcd/wire" ) // TestPushedData ensured the PushedData function extracts the expected data out diff --git a/txscript/sigcache.go b/txscript/sigcache.go index d9e4fa6c..56db61b5 100644 --- a/txscript/sigcache.go +++ b/txscript/sigcache.go @@ -7,8 +7,8 @@ package txscript import ( "sync" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // sigCacheEntry represents an entry in the SigCache. Entries within the diff --git a/txscript/sigcache_test.go b/txscript/sigcache_test.go index 5413ea3b..40958cfb 100644 --- a/txscript/sigcache_test.go +++ b/txscript/sigcache_test.go @@ -8,8 +8,8 @@ import ( "crypto/rand" "testing" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // genRandomSig returns a random message, a signature of the message under the diff --git a/txscript/sign.go b/txscript/sign.go index 138e31cd..7562ca34 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -8,10 +8,10 @@ import ( "errors" "fmt" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // RawTxInWitnessSignature returns the serialized ECDA signature for the input diff --git a/txscript/sign_test.go b/txscript/sign_test.go index b97a8a64..abed8c36 100644 --- a/txscript/sign_test.go +++ b/txscript/sign_test.go @@ -9,11 +9,11 @@ import ( "fmt" "testing" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) type addressToKey struct { diff --git a/txscript/standard.go b/txscript/standard.go index 2437b3cc..a45bfc6f 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -7,9 +7,9 @@ package txscript import ( "fmt" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) const ( diff --git a/txscript/standard_test.go b/txscript/standard_test.go index 582d30ee..d58154e7 100644 --- a/txscript/standard_test.go +++ b/txscript/standard_test.go @@ -11,9 +11,9 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // mustParseShortForm parses the passed short form script and returns the diff --git a/upgrade.go b/upgrade.go index 5dec8d4c..9b5461da 100644 --- a/upgrade.go +++ b/upgrade.go @@ -35,13 +35,13 @@ func oldBtcdHomeDir() string { // Search for Windows APPDATA first. This won't exist on POSIX OSes. appData := os.Getenv("APPDATA") if appData != "" { - return filepath.Join(appData, "btcd") + return filepath.Join(appData, "lbcd") } // Fall back to standard HOME directory that works for most POSIX OSes. home := os.Getenv("HOME") if home != "" { - return filepath.Join(home, ".btcd") + return filepath.Join(home, ".lbcd") } // In the worst case, use the current directory. @@ -96,9 +96,9 @@ func upgradeDBPaths() error { // respective networks. Check for the old database and update it to the // new path introduced with version 0.2.0 accordingly. oldDbRoot := filepath.Join(oldBtcdHomeDir(), "db") - upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd.db"), "mainnet") - upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd_testnet.db"), "testnet") - upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd_regtest.db"), "regtest") + upgradeDBPathNet(filepath.Join(oldDbRoot, "lbcd.db"), "mainnet") + upgradeDBPathNet(filepath.Join(oldDbRoot, "lbcd_testnet.db"), "testnet") + upgradeDBPathNet(filepath.Join(oldDbRoot, "lbcd_regtest.db"), "regtest") // Remove the old db directory. return os.RemoveAll(oldDbRoot) diff --git a/wire/bench_test.go b/wire/bench_test.go index f6637d42..1eb6c413 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -13,7 +13,7 @@ import ( "os" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // genesisCoinbaseTx is the coinbase transaction for the genesis blocks for diff --git a/wire/blockheader.go b/wire/blockheader.go index ee45ec3b..372b7b46 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -9,12 +9,12 @@ import ( "io" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MaxBlockHeaderPayload is the maximum number of bytes a block header can be. // Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes + -// PrevBlock and MerkleRoot hashes. +// PrevBlock, ClaimTrie, and MerkleRoot hashes. const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 3) // BlockHeader defines information about a block and is used in the bitcoin diff --git a/wire/common.go b/wire/common.go index 8d61bdb6..134e0547 100644 --- a/wire/common.go +++ b/wire/common.go @@ -12,7 +12,7 @@ import ( "math" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/common_test.go b/wire/common_test.go index 46e3fa66..d71cc9c9 100644 --- a/wire/common_test.go +++ b/wire/common_test.go @@ -12,8 +12,8 @@ import ( "strings" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // mainNetGenesisHash is the hash of the first block in the block chain for the diff --git a/wire/invvect.go b/wire/invvect.go index 1e706642..d84b52bf 100644 --- a/wire/invvect.go +++ b/wire/invvect.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/invvect_test.go b/wire/invvect_test.go index 1d02c098..1be745c3 100644 --- a/wire/invvect_test.go +++ b/wire/invvect_test.go @@ -9,8 +9,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestInvVectStringer tests the stringized output for inventory vector types. diff --git a/wire/message.go b/wire/message.go index 6d3147a8..23cc2e05 100644 --- a/wire/message.go +++ b/wire/message.go @@ -10,7 +10,7 @@ import ( "io" "unicode/utf8" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MessageHeaderSize is the number of bytes in a bitcoin message header. diff --git a/wire/message_test.go b/wire/message_test.go index 3a422e66..b2ae3f63 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -13,8 +13,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // makeHeader is a convenience function to make a message header in the form of diff --git a/wire/msgblock.go b/wire/msgblock.go index a5a25a1c..b66db374 100644 --- a/wire/msgblock.go +++ b/wire/msgblock.go @@ -9,7 +9,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // defaultTransactionAlloc is the default size used for the backing array diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index 12a6afcb..b76220b3 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -11,8 +11,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestBlock tests the MsgBlock API. diff --git a/wire/msgcfcheckpt.go b/wire/msgcfcheckpt.go index fc3fd532..91e20de5 100644 --- a/wire/msgcfcheckpt.go +++ b/wire/msgcfcheckpt.go @@ -9,7 +9,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/msgcfheaders.go b/wire/msgcfheaders.go index 40d30f9b..0581581f 100644 --- a/wire/msgcfheaders.go +++ b/wire/msgcfheaders.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/msgcfilter.go b/wire/msgcfilter.go index 097590b2..838b0f55 100644 --- a/wire/msgcfilter.go +++ b/wire/msgcfilter.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // FilterType is used to represent a filter type. diff --git a/wire/msggetblocks.go b/wire/msggetblocks.go index caf4400c..1f94245d 100644 --- a/wire/msggetblocks.go +++ b/wire/msggetblocks.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MaxBlockLocatorsPerMsg is the maximum number of block locator hashes allowed diff --git a/wire/msggetblocks_test.go b/wire/msggetblocks_test.go index 376f7338..0893cc17 100644 --- a/wire/msggetblocks_test.go +++ b/wire/msggetblocks_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestGetBlocks tests the MsgGetBlocks API. diff --git a/wire/msggetcfcheckpt.go b/wire/msggetcfcheckpt.go index c30a86ce..4f7fde47 100644 --- a/wire/msggetcfcheckpt.go +++ b/wire/msggetcfcheckpt.go @@ -7,7 +7,7 @@ package wire import ( "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MsgGetCFCheckpt is a request for filter headers at evenly spaced intervals diff --git a/wire/msggetcfheaders.go b/wire/msggetcfheaders.go index 03a1caf7..46f6aa5f 100644 --- a/wire/msggetcfheaders.go +++ b/wire/msggetcfheaders.go @@ -7,7 +7,7 @@ package wire import ( "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MsgGetCFHeaders is a message similar to MsgGetHeaders, but for committed diff --git a/wire/msggetcfilters.go b/wire/msggetcfilters.go index 80024138..759950fd 100644 --- a/wire/msggetcfilters.go +++ b/wire/msggetcfilters.go @@ -7,7 +7,7 @@ package wire import ( "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MaxGetCFiltersReqRange the maximum number of filters that may be requested in diff --git a/wire/msggetdata_test.go b/wire/msggetdata_test.go index a2dd4651..9e34f296 100644 --- a/wire/msggetdata_test.go +++ b/wire/msggetdata_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestGetData tests the MsgGetData API. diff --git a/wire/msggetheaders.go b/wire/msggetheaders.go index 0bbe42cb..aa5cc3f2 100644 --- a/wire/msggetheaders.go +++ b/wire/msggetheaders.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // MsgGetHeaders implements the Message interface and represents a bitcoin diff --git a/wire/msggetheaders_test.go b/wire/msggetheaders_test.go index 34a24ae3..a9ee7ad9 100644 --- a/wire/msggetheaders_test.go +++ b/wire/msggetheaders_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestGetHeaders tests the MsgGetHeader API. diff --git a/wire/msginv_test.go b/wire/msginv_test.go index b7c7c6ae..09aa6732 100644 --- a/wire/msginv_test.go +++ b/wire/msginv_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestInv tests the MsgInv API. diff --git a/wire/msgmerkleblock.go b/wire/msgmerkleblock.go index d2ee4721..075f3d56 100644 --- a/wire/msgmerkleblock.go +++ b/wire/msgmerkleblock.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // maxFlagsPerMerkleBlock is the maximum number of flag bytes that could diff --git a/wire/msgmerkleblock_test.go b/wire/msgmerkleblock_test.go index b74f7183..eb7b3601 100644 --- a/wire/msgmerkleblock_test.go +++ b/wire/msgmerkleblock_test.go @@ -12,8 +12,8 @@ import ( "testing" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestMerkleBlock tests the MsgMerkleBlock API. diff --git a/wire/msgnotfound_test.go b/wire/msgnotfound_test.go index 69b9d07a..7cb6cf7b 100644 --- a/wire/msgnotfound_test.go +++ b/wire/msgnotfound_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestNotFound tests the MsgNotFound API. diff --git a/wire/msgreject.go b/wire/msgreject.go index a00eeff6..ee64c747 100644 --- a/wire/msgreject.go +++ b/wire/msgreject.go @@ -8,7 +8,7 @@ import ( "fmt" "io" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // RejectCode represents a numeric value by which a remote peer indicates diff --git a/wire/msgtx.go b/wire/msgtx.go index 1e2f69fa..34bdeaed 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -10,7 +10,7 @@ import ( "io" "strconv" - "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) const ( diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index ae508f7f..66288882 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -11,8 +11,8 @@ import ( "reflect" "testing" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" + "github.com/lbryio/lbcd/chaincfg/chainhash" ) // TestTx tests the MsgTx API. -- 2.45.2 From 6828cf5e363fadfd80d57b0119195d53b24ebbe1 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 6 Jul 2021 18:39:56 -0700 Subject: [PATCH 348/459] [lbry] claimtrie: import current snapshot Sync to tip Co-authored-by: Brannon King --- claimtrie/block/blockrepo/pebble.go | 87 + claimtrie/block/repo.go | 15 + claimtrie/chain/chainrepo/pebble.go | 77 + claimtrie/chain/repo.go | 10 + claimtrie/change/change.go | 112 + claimtrie/change/claimid.go | 54 + claimtrie/claimtrie.go | 487 + claimtrie/claimtrie_test.go | 1027 + claimtrie/cmd/cmd/block.go | 98 + claimtrie/cmd/cmd/chain.go | 441 + claimtrie/cmd/cmd/helper.go | 62 + claimtrie/cmd/cmd/merkletrie.go | 105 + claimtrie/cmd/cmd/node.go | 194 + claimtrie/cmd/cmd/root.go | 61 + claimtrie/cmd/cmd/temporal.go | 60 + claimtrie/cmd/cmd/ui.go | 76 + claimtrie/cmd/main.go | 9 + claimtrie/config/config.go | 49 + claimtrie/merkletrie/collapsedtrie.go | 235 + claimtrie/merkletrie/collapsedtrie_test.go | 113 + claimtrie/merkletrie/merkletrie.go | 255 + claimtrie/merkletrie/merkletrie_test.go | 25 + claimtrie/merkletrie/merkletrierepo/pebble.go | 67 + claimtrie/merkletrie/ramtrie.go | 139 + claimtrie/merkletrie/repo.go | 13 + claimtrie/merkletrie/vertex.go | 43 + claimtrie/node/claim.go | 82 + claimtrie/node/claim_list.go | 33 + claimtrie/node/hashfork_manager.go | 39 + claimtrie/node/hashfunc.go | 57 + claimtrie/node/log.go | 47 + claimtrie/node/manager.go | 401 + claimtrie/node/manager_test.go | 299 + claimtrie/node/node.go | 342 + claimtrie/node/noderepo/noderepo_test.go | 188 + claimtrie/node/noderepo/pebble.go | 177 + claimtrie/node/normalizing_manager.go | 114 + claimtrie/node/repo.go | 31 + claimtrie/normalization/CaseFolding_v11.txt | 1574 ++ claimtrie/normalization/NFC_v11.txt | 2431 ++ .../normalization/NormalizationTest_v11.txt | 18847 ++++++++++++++++ claimtrie/normalization/case_folder.go | 61 + claimtrie/normalization/char_decomposer.go | 177 + claimtrie/normalization/normalizer.go | 22 + claimtrie/normalization/normalizer_icu.go | 77 + .../normalization/normalizer_icu_test.go | 74 + claimtrie/normalization/normalizer_test.go | 89 + claimtrie/param/delays.go | 285 + claimtrie/param/general.go | 74 + claimtrie/param/takeovers.go | 451 + claimtrie/temporal/repo.go | 9 + claimtrie/temporal/temporalrepo/memory.go | 45 + claimtrie/temporal/temporalrepo/pebble.go | 87 + .../temporalrepo/temporalrepo_test.go | 80 + 54 files changed, 30107 insertions(+) create mode 100644 claimtrie/block/blockrepo/pebble.go create mode 100644 claimtrie/block/repo.go create mode 100644 claimtrie/chain/chainrepo/pebble.go create mode 100644 claimtrie/chain/repo.go create mode 100644 claimtrie/change/change.go create mode 100644 claimtrie/change/claimid.go create mode 100644 claimtrie/claimtrie.go create mode 100644 claimtrie/claimtrie_test.go create mode 100644 claimtrie/cmd/cmd/block.go create mode 100644 claimtrie/cmd/cmd/chain.go create mode 100644 claimtrie/cmd/cmd/helper.go create mode 100644 claimtrie/cmd/cmd/merkletrie.go create mode 100644 claimtrie/cmd/cmd/node.go create mode 100644 claimtrie/cmd/cmd/root.go create mode 100644 claimtrie/cmd/cmd/temporal.go create mode 100644 claimtrie/cmd/cmd/ui.go create mode 100644 claimtrie/cmd/main.go create mode 100644 claimtrie/config/config.go create mode 100644 claimtrie/merkletrie/collapsedtrie.go create mode 100644 claimtrie/merkletrie/collapsedtrie_test.go create mode 100644 claimtrie/merkletrie/merkletrie.go create mode 100644 claimtrie/merkletrie/merkletrie_test.go create mode 100644 claimtrie/merkletrie/merkletrierepo/pebble.go create mode 100644 claimtrie/merkletrie/ramtrie.go create mode 100644 claimtrie/merkletrie/repo.go create mode 100644 claimtrie/merkletrie/vertex.go create mode 100644 claimtrie/node/claim.go create mode 100644 claimtrie/node/claim_list.go create mode 100644 claimtrie/node/hashfork_manager.go create mode 100644 claimtrie/node/hashfunc.go create mode 100644 claimtrie/node/log.go create mode 100644 claimtrie/node/manager.go create mode 100644 claimtrie/node/manager_test.go create mode 100644 claimtrie/node/node.go create mode 100644 claimtrie/node/noderepo/noderepo_test.go create mode 100644 claimtrie/node/noderepo/pebble.go create mode 100644 claimtrie/node/normalizing_manager.go create mode 100644 claimtrie/node/repo.go create mode 100644 claimtrie/normalization/CaseFolding_v11.txt create mode 100644 claimtrie/normalization/NFC_v11.txt create mode 100644 claimtrie/normalization/NormalizationTest_v11.txt create mode 100644 claimtrie/normalization/case_folder.go create mode 100644 claimtrie/normalization/char_decomposer.go create mode 100644 claimtrie/normalization/normalizer.go create mode 100644 claimtrie/normalization/normalizer_icu.go create mode 100644 claimtrie/normalization/normalizer_icu_test.go create mode 100644 claimtrie/normalization/normalizer_test.go create mode 100644 claimtrie/param/delays.go create mode 100644 claimtrie/param/general.go create mode 100644 claimtrie/param/takeovers.go create mode 100644 claimtrie/temporal/repo.go create mode 100644 claimtrie/temporal/temporalrepo/memory.go create mode 100644 claimtrie/temporal/temporalrepo/pebble.go create mode 100644 claimtrie/temporal/temporalrepo/temporalrepo_test.go diff --git a/claimtrie/block/blockrepo/pebble.go b/claimtrie/block/blockrepo/pebble.go new file mode 100644 index 00000000..b2df6afd --- /dev/null +++ b/claimtrie/block/blockrepo/pebble.go @@ -0,0 +1,87 @@ +package blockrepo + +import ( + "encoding/binary" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + + "github.com/cockroachdb/pebble" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + db, err := pebble.Open(path, &pebble.Options{MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "unable to open %s", path) +} + +func (repo *Pebble) Load() (int32, error) { + + iter := repo.db.NewIter(nil) + if !iter.Last() { + err := iter.Close() + return 0, errors.Wrap(err, "closing iterator with no last") + } + + height := int32(binary.BigEndian.Uint32(iter.Key())) + err := iter.Close() + return height, errors.Wrap(err, "closing iterator") +} + +func (repo *Pebble) Get(height int32) (*chainhash.Hash, error) { + + key := make([]byte, 4) + binary.BigEndian.PutUint32(key, uint32(height)) + + b, closer, err := repo.db.Get(key) + if closer != nil { + defer closer.Close() + } + if err != nil { + return nil, errors.Wrap(err, "in get") + } + hash, err := chainhash.NewHash(b) + return hash, errors.Wrap(err, "creating hash") +} + +func (repo *Pebble) Set(height int32, hash *chainhash.Hash) error { + + key := make([]byte, 4) + binary.BigEndian.PutUint32(key, uint32(height)) + + return errors.WithStack(repo.db.Set(key, hash[:], pebble.NoSync)) +} + +func (repo *Pebble) Delete(heightMin, heightMax int32) error { + lower := make([]byte, 4) + binary.BigEndian.PutUint32(lower, uint32(heightMin)) + + upper := make([]byte, 4) + binary.BigEndian.PutUint32(upper, uint32(heightMax)+1) + + return errors.Wrap(repo.db.DeleteRange(lower, upper, pebble.NoSync), "on range delete") +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/block/repo.go b/claimtrie/block/repo.go new file mode 100644 index 00000000..17907ff2 --- /dev/null +++ b/claimtrie/block/repo.go @@ -0,0 +1,15 @@ +package block + +import ( + "github.com/lbryio/lbcd/chaincfg/chainhash" +) + +// Repo defines APIs for Block to access persistence layer. +type Repo interface { + Load() (int32, error) + Set(height int32, hash *chainhash.Hash) error + Get(height int32) (*chainhash.Hash, error) + Close() error + Flush() error + Delete(heightMin, heightMax int32) error +} diff --git a/claimtrie/chain/chainrepo/pebble.go b/claimtrie/chain/chainrepo/pebble.go new file mode 100644 index 00000000..4100d6ac --- /dev/null +++ b/claimtrie/chain/chainrepo/pebble.go @@ -0,0 +1,77 @@ +package chainrepo + +import ( + "encoding/binary" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/vmihailenco/msgpack/v5" + + "github.com/cockroachdb/pebble" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + db, err := pebble.Open(path, &pebble.Options{BytesPerSync: 64 << 20, MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "open %s", path) +} + +func (repo *Pebble) Save(height int32, changes []change.Change) error { + + if len(changes) == 0 { + return nil + } + + var key [4]byte + binary.BigEndian.PutUint32(key[:], uint32(height)) + + value, err := msgpack.Marshal(changes) + if err != nil { + return errors.Wrap(err, "in marshaller") + } + + err = repo.db.Set(key[:], value, pebble.NoSync) + return errors.Wrap(err, "in set") +} + +func (repo *Pebble) Load(height int32) ([]change.Change, error) { + + var key [4]byte + binary.BigEndian.PutUint32(key[:], uint32(height)) + + b, closer, err := repo.db.Get(key[:]) + if closer != nil { + defer closer.Close() + } + if err != nil { + return nil, errors.Wrap(err, "in get") + } + + var changes []change.Change + err = msgpack.Unmarshal(b, &changes) + return changes, errors.Wrap(err, "in unmarshaller") +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/chain/repo.go b/claimtrie/chain/repo.go new file mode 100644 index 00000000..7d3aa978 --- /dev/null +++ b/claimtrie/chain/repo.go @@ -0,0 +1,10 @@ +package chain + +import "github.com/lbryio/lbcd/claimtrie/change" + +type Repo interface { + Save(height int32, changes []change.Change) error + Load(height int32) ([]change.Change, error) + Close() error + Flush() error +} diff --git a/claimtrie/change/change.go b/claimtrie/change/change.go new file mode 100644 index 00000000..aac349c6 --- /dev/null +++ b/claimtrie/change/change.go @@ -0,0 +1,112 @@ +package change + +import ( + "bytes" + "encoding/binary" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" +) + +type ChangeType uint32 + +const ( + AddClaim ChangeType = iota + SpendClaim + UpdateClaim + AddSupport + SpendSupport +) + +type Change struct { + Type ChangeType + Height int32 + + Name []byte + ClaimID ClaimID + OutPoint wire.OutPoint + Amount int64 + + ActiveHeight int32 + VisibleHeight int32 // aka, CreatedAt; used for normalization fork + + SpentChildren map[string]bool +} + +func NewChange(typ ChangeType) Change { + return Change{Type: typ} +} + +func (c Change) SetHeight(height int32) Change { + c.Height = height + return c +} + +func (c Change) SetName(name []byte) Change { + c.Name = name // need to clone it? + return c +} + +func (c Change) SetOutPoint(op *wire.OutPoint) Change { + c.OutPoint = *op + return c +} + +func (c Change) SetAmount(amt int64) Change { + c.Amount = amt + return c +} + +func (c *Change) Marshal(enc *bytes.Buffer) error { + enc.Write(c.ClaimID[:]) + enc.Write(c.OutPoint.Hash[:]) + var temp [8]byte + binary.BigEndian.PutUint32(temp[:4], c.OutPoint.Index) + enc.Write(temp[:4]) + binary.BigEndian.PutUint32(temp[:4], uint32(c.Type)) + enc.Write(temp[:4]) + binary.BigEndian.PutUint32(temp[:4], uint32(c.Height)) + enc.Write(temp[:4]) + binary.BigEndian.PutUint32(temp[:4], uint32(c.ActiveHeight)) + enc.Write(temp[:4]) + binary.BigEndian.PutUint32(temp[:4], uint32(c.VisibleHeight)) + enc.Write(temp[:4]) + binary.BigEndian.PutUint64(temp[:], uint64(c.Amount)) + enc.Write(temp[:]) + + if c.SpentChildren != nil { + binary.BigEndian.PutUint32(temp[:4], uint32(len(c.SpentChildren))) + enc.Write(temp[:4]) + for key := range c.SpentChildren { + binary.BigEndian.PutUint16(temp[:2], uint16(len(key))) // technically limited to 255; not sure we trust it + enc.Write(temp[:2]) + enc.WriteString(key) + } + } else { + binary.BigEndian.PutUint32(temp[:4], 0) + enc.Write(temp[:4]) + } + return nil +} + +func (c *Change) Unmarshal(dec *bytes.Buffer) error { + copy(c.ClaimID[:], dec.Next(ClaimIDSize)) + copy(c.OutPoint.Hash[:], dec.Next(chainhash.HashSize)) + c.OutPoint.Index = binary.BigEndian.Uint32(dec.Next(4)) + c.Type = ChangeType(binary.BigEndian.Uint32(dec.Next(4))) + c.Height = int32(binary.BigEndian.Uint32(dec.Next(4))) + c.ActiveHeight = int32(binary.BigEndian.Uint32(dec.Next(4))) + c.VisibleHeight = int32(binary.BigEndian.Uint32(dec.Next(4))) + c.Amount = int64(binary.BigEndian.Uint64(dec.Next(8))) + keys := binary.BigEndian.Uint32(dec.Next(4)) + if keys > 0 { + c.SpentChildren = map[string]bool{} + } + for keys > 0 { + keys-- + keySize := int(binary.BigEndian.Uint16(dec.Next(2))) + key := string(dec.Next(keySize)) + c.SpentChildren[key] = true + } + return nil +} diff --git a/claimtrie/change/claimid.go b/claimtrie/change/claimid.go new file mode 100644 index 00000000..e7a92565 --- /dev/null +++ b/claimtrie/change/claimid.go @@ -0,0 +1,54 @@ +package change + +import ( + "encoding/binary" + "encoding/hex" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" +) + +// ClaimID represents a Claim's ClaimID. +const ClaimIDSize = 20 + +type ClaimID [ClaimIDSize]byte + +// NewClaimID returns a Claim ID calculated from Ripemd160(Sha256(OUTPOINT). +func NewClaimID(op wire.OutPoint) (id ClaimID) { + + var buffer [chainhash.HashSize + 4]byte // hoping for stack alloc + copy(buffer[:], op.Hash[:]) + binary.BigEndian.PutUint32(buffer[chainhash.HashSize:], op.Index) + copy(id[:], btcutil.Hash160(buffer[:])) + return id +} + +// NewIDFromString returns a Claim ID from a string. +func NewIDFromString(s string) (id ClaimID, err error) { + + if len(s) == 40 { + _, err = hex.Decode(id[:], []byte(s)) + } else { + copy(id[:], s) + } + for i, j := 0, len(id)-1; i < j; i, j = i+1, j-1 { + id[i], id[j] = id[j], id[i] + } + return id, err +} + +// Key is for in-memory maps +func (id ClaimID) Key() string { + return string(id[:]) +} + +// String is for anything written to a DB +func (id ClaimID) String() string { + + for i, j := 0, len(id)-1; i < j; i, j = i+1, j-1 { + id[i], id[j] = id[j], id[i] + } + + return hex.EncodeToString(id[:]) +} diff --git a/claimtrie/claimtrie.go b/claimtrie/claimtrie.go new file mode 100644 index 00000000..68ef6488 --- /dev/null +++ b/claimtrie/claimtrie.go @@ -0,0 +1,487 @@ +package claimtrie + +import ( + "bytes" + "fmt" + "path/filepath" + "runtime" + "sort" + "sync" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/claimtrie/block" + "github.com/lbryio/lbcd/claimtrie/block/blockrepo" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/claimtrie/merkletrie" + "github.com/lbryio/lbcd/claimtrie/merkletrie/merkletrierepo" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/claimtrie/node/noderepo" + "github.com/lbryio/lbcd/claimtrie/normalization" + "github.com/lbryio/lbcd/claimtrie/param" + "github.com/lbryio/lbcd/claimtrie/temporal" + "github.com/lbryio/lbcd/claimtrie/temporal/temporalrepo" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" +) + +// ClaimTrie implements a Merkle Trie supporting linear history of commits. +type ClaimTrie struct { + + // Repository for calculated block hashes. + blockRepo block.Repo + + // Repository for storing temporal information of nodes at each block height. + // For example, which nodes (by name) should be refreshed at each block height + // due to stake expiration or delayed activation. + temporalRepo temporal.Repo + + // Cache layer of Nodes. + nodeManager node.Manager + + // Prefix tree (trie) that manages merkle hash of each node. + merkleTrie merkletrie.MerkleTrie + + // Current block height, which is increased by one when AppendBlock() is called. + height int32 + + // Registrered cleanup functions which are invoked in the Close() in reverse order. + cleanups []func() error +} + +func New(cfg config.Config) (*ClaimTrie, error) { + + var cleanups []func() error + + // The passed in cfg.DataDir has been prepended with netname. + dataDir := filepath.Join(cfg.DataDir, "claim_dbs") + + dbPath := filepath.Join(dataDir, cfg.BlockRepoPebble.Path) + blockRepo, err := blockrepo.NewPebble(dbPath) + if err != nil { + return nil, errors.Wrap(err, "creating block repo") + } + cleanups = append(cleanups, blockRepo.Close) + err = blockRepo.Set(0, merkletrie.EmptyTrieHash) + if err != nil { + return nil, errors.Wrap(err, "setting block repo genesis") + } + + dbPath = filepath.Join(dataDir, cfg.TemporalRepoPebble.Path) + temporalRepo, err := temporalrepo.NewPebble(dbPath) + if err != nil { + return nil, errors.Wrap(err, "creating temporal repo") + } + cleanups = append(cleanups, temporalRepo.Close) + + // Initialize repository for changes to nodes. + // The cleanup is delegated to the Node Manager. + dbPath = filepath.Join(dataDir, cfg.NodeRepoPebble.Path) + nodeRepo, err := noderepo.NewPebble(dbPath) + if err != nil { + return nil, errors.Wrap(err, "creating node repo") + } + + baseManager, err := node.NewBaseManager(nodeRepo) + if err != nil { + return nil, errors.Wrap(err, "creating node base manager") + } + normalizingManager := node.NewNormalizingManager(baseManager) + nodeManager := &node.HashV2Manager{Manager: normalizingManager} + cleanups = append(cleanups, nodeManager.Close) + + var trie merkletrie.MerkleTrie + if cfg.RamTrie { + trie = merkletrie.NewRamTrie() + } else { + + // Initialize repository for MerkleTrie. The cleanup is delegated to MerkleTrie. + dbPath = filepath.Join(dataDir, cfg.MerkleTrieRepoPebble.Path) + trieRepo, err := merkletrierepo.NewPebble(dbPath) + if err != nil { + return nil, errors.Wrap(err, "creating trie repo") + } + + persistentTrie := merkletrie.NewPersistentTrie(trieRepo) + cleanups = append(cleanups, persistentTrie.Close) + trie = persistentTrie + } + + // Restore the last height. + previousHeight, err := blockRepo.Load() + if err != nil { + return nil, errors.Wrap(err, "load block tip") + } + + ct := &ClaimTrie{ + blockRepo: blockRepo, + temporalRepo: temporalRepo, + + nodeManager: nodeManager, + merkleTrie: trie, + + height: previousHeight, + } + + ct.cleanups = cleanups + + if previousHeight > 0 { + hash, err := blockRepo.Get(previousHeight) + if err != nil { + ct.Close() // TODO: the cleanups aren't run when we exit with an err above here (but should be) + return nil, errors.Wrap(err, "block repo get") + } + _, err = nodeManager.IncrementHeightTo(previousHeight, false) + if err != nil { + ct.Close() + return nil, errors.Wrap(err, "increment height to") + } + err = trie.SetRoot(hash) // keep this after IncrementHeightTo + if err == merkletrie.ErrFullRebuildRequired { + ct.runFullTrieRebuild(nil, cfg.Interrupt) + } + + if interruptRequested(cfg.Interrupt) || !ct.MerkleHash().IsEqual(hash) { + ct.Close() + return nil, errors.Errorf("unable to restore the claim hash to %s at height %d", hash.String(), previousHeight) + } + } + + return ct, nil +} + +// AddClaim adds a Claim to the ClaimTrie. +func (ct *ClaimTrie) AddClaim(name []byte, op wire.OutPoint, id change.ClaimID, amt int64) error { + + chg := change.Change{ + Type: change.AddClaim, + Name: name, + OutPoint: op, + Amount: amt, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// UpdateClaim updates a Claim in the ClaimTrie. +func (ct *ClaimTrie) UpdateClaim(name []byte, op wire.OutPoint, amt int64, id change.ClaimID) error { + + chg := change.Change{ + Type: change.UpdateClaim, + Name: name, + OutPoint: op, + Amount: amt, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// SpendClaim spends a Claim in the ClaimTrie. +func (ct *ClaimTrie) SpendClaim(name []byte, op wire.OutPoint, id change.ClaimID) error { + + chg := change.Change{ + Type: change.SpendClaim, + Name: name, + OutPoint: op, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// AddSupport adds a Support to the ClaimTrie. +func (ct *ClaimTrie) AddSupport(name []byte, op wire.OutPoint, amt int64, id change.ClaimID) error { + + chg := change.Change{ + Type: change.AddSupport, + Name: name, + OutPoint: op, + Amount: amt, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// SpendSupport spends a Support in the ClaimTrie. +func (ct *ClaimTrie) SpendSupport(name []byte, op wire.OutPoint, id change.ClaimID) error { + + chg := change.Change{ + Type: change.SpendSupport, + Name: name, + OutPoint: op, + ClaimID: id, + } + + return ct.forwardNodeChange(chg) +} + +// AppendBlock increases block by one. +func (ct *ClaimTrie) AppendBlock(temporary bool) error { + + ct.height++ + + names, err := ct.nodeManager.IncrementHeightTo(ct.height, temporary) + if err != nil { + return errors.Wrap(err, "node manager increment") + } + + expirations, err := ct.temporalRepo.NodesAt(ct.height) + if err != nil { + return errors.Wrap(err, "temporal repo get") + } + + names = removeDuplicates(names) // comes out sorted + + updateNames := make([][]byte, 0, len(names)+len(expirations)) + updateHeights := make([]int32, 0, len(names)+len(expirations)) + updateNames = append(updateNames, names...) + for range names { // log to the db that we updated a name at this height for rollback purposes + updateHeights = append(updateHeights, ct.height) + } + names = append(names, expirations...) + names = removeDuplicates(names) + + nhns := ct.makeNameHashNext(names, false, nil) + for nhn := range nhns { + + ct.merkleTrie.Update(nhn.Name, nhn.Hash, true) + if nhn.Next <= 0 { + continue + } + + newName := normalization.NormalizeIfNecessary(nhn.Name, nhn.Next) + updateNames = append(updateNames, newName) + updateHeights = append(updateHeights, nhn.Next) + } + if !temporary && len(updateNames) > 0 { + err = ct.temporalRepo.SetNodesAt(updateNames, updateHeights) + if err != nil { + return errors.Wrap(err, "temporal repo set") + } + } + + hitFork := ct.updateTrieForHashForkIfNecessary() + h := ct.MerkleHash() + + if !temporary { + ct.blockRepo.Set(ct.height, h) + } + + if hitFork { + err = ct.merkleTrie.SetRoot(h) // for clearing the memory entirely + } + + return errors.Wrap(err, "merkle trie clear memory") +} + +func (ct *ClaimTrie) updateTrieForHashForkIfNecessary() bool { + if ct.height != param.ActiveParams.AllClaimsInMerkleForkHeight { + return false + } + + node.LogOnce(fmt.Sprintf("Rebuilding all trie nodes for the hash fork at %d...", ct.height)) + ct.runFullTrieRebuild(nil, nil) // I don't think it's safe to allow interrupt during fork + return true +} + +func removeDuplicates(names [][]byte) [][]byte { // this might be too expensive; we'll have to profile it + sort.Slice(names, func(i, j int) bool { // put names in order so we can skip duplicates + return bytes.Compare(names[i], names[j]) < 0 + }) + + for i := len(names) - 2; i >= 0; i-- { + if bytes.Equal(names[i], names[i+1]) { + names = append(names[:i], names[i+1:]...) + } + } + return names +} + +// ResetHeight resets the ClaimTrie to a previous known height.. +func (ct *ClaimTrie) ResetHeight(height int32) error { + + names := make([][]byte, 0) + for h := height + 1; h <= ct.height; h++ { + results, err := ct.temporalRepo.NodesAt(h) + if err != nil { + return err + } + names = append(names, results...) + } + names, err := ct.nodeManager.DecrementHeightTo(names, height) + if err != nil { + return err + } + + passedHashFork := ct.height >= param.ActiveParams.AllClaimsInMerkleForkHeight && height < param.ActiveParams.AllClaimsInMerkleForkHeight + hash, err := ct.blockRepo.Get(height) + if err != nil { + return err + } + + oldHeight := ct.height + ct.height = height // keep this before the rebuild + + if passedHashFork { + names = nil // force them to reconsider all names + } + err = ct.merkleTrie.SetRoot(hash) + if err == merkletrie.ErrFullRebuildRequired { + ct.runFullTrieRebuild(names, nil) + } + + if !ct.MerkleHash().IsEqual(hash) { + return errors.Errorf("unable to restore the hash at height %d", height) + } + + return errors.WithStack(ct.blockRepo.Delete(height+1, oldHeight)) +} + +func (ct *ClaimTrie) runFullTrieRebuild(names [][]byte, interrupt <-chan struct{}) { + var nhns chan NameHashNext + if names == nil { + node.LogOnce("Building the entire claim trie in RAM...") + + nhns = ct.makeNameHashNext(nil, true, interrupt) + } else { + nhns = ct.makeNameHashNext(names, false, interrupt) + } + + for nhn := range nhns { + ct.merkleTrie.Update(nhn.Name, nhn.Hash, false) + } +} + +// MerkleHash returns the Merkle Hash of the claimTrie. +func (ct *ClaimTrie) MerkleHash() *chainhash.Hash { + if ct.height >= param.ActiveParams.AllClaimsInMerkleForkHeight { + return ct.merkleTrie.MerkleHashAllClaims() + } + return ct.merkleTrie.MerkleHash() +} + +// Height returns the current block height. +func (ct *ClaimTrie) Height() int32 { + return ct.height +} + +// Close persists states. +// Any calls to the ClaimTrie after Close() being called results undefined behaviour. +func (ct *ClaimTrie) Close() { + + for i := len(ct.cleanups) - 1; i >= 0; i-- { + cleanup := ct.cleanups[i] + err := cleanup() + if err != nil { // it would be better to cleanup what we can than exit early + node.LogOnce("On cleanup: " + err.Error()) + } + } + ct.cleanups = nil +} + +func (ct *ClaimTrie) forwardNodeChange(chg change.Change) error { + + chg.Height = ct.Height() + 1 + ct.nodeManager.AppendChange(chg) + return nil +} + +func (ct *ClaimTrie) NodeAt(height int32, name []byte) (*node.Node, error) { + return ct.nodeManager.NodeAt(height, name) +} + +func (ct *ClaimTrie) NamesChangedInBlock(height int32) ([]string, error) { + hits, err := ct.temporalRepo.NodesAt(height) + r := make([]string, len(hits)) + for i := range hits { + r[i] = string(hits[i]) + } + return r, err +} + +func (ct *ClaimTrie) FlushToDisk() { + // maybe the user can fix the file lock shown in the warning before they shut down + if err := ct.nodeManager.Flush(); err != nil { + node.Warn("During nodeManager flush: " + err.Error()) + } + if err := ct.temporalRepo.Flush(); err != nil { + node.Warn("During temporalRepo flush: " + err.Error()) + } + if err := ct.merkleTrie.Flush(); err != nil { + node.Warn("During merkleTrie flush: " + err.Error()) + } + if err := ct.blockRepo.Flush(); err != nil { + node.Warn("During blockRepo flush: " + err.Error()) + } +} + +type NameHashNext struct { + Name []byte + Hash *chainhash.Hash + Next int32 +} + +func interruptRequested(interrupted <-chan struct{}) bool { + select { + case <-interrupted: // should never block on nil + return true + default: + } + + return false +} + +func (ct *ClaimTrie) makeNameHashNext(names [][]byte, all bool, interrupt <-chan struct{}) chan NameHashNext { + inputs := make(chan []byte, 512) + outputs := make(chan NameHashNext, 512) + + var wg sync.WaitGroup + hashComputationWorker := func() { + for name := range inputs { + hash, next := ct.nodeManager.Hash(name) + outputs <- NameHashNext{name, hash, next} + } + wg.Done() + } + + threads := int(0.8 * float32(runtime.NumCPU())) + if threads < 1 { + threads = 1 + } + for threads > 0 { + threads-- + wg.Add(1) + go hashComputationWorker() + } + go func() { + if all { + ct.nodeManager.IterateNames(func(name []byte) bool { + if interruptRequested(interrupt) { + return false + } + clone := make([]byte, len(name)) + copy(clone, name) // iteration name buffer is reused on future loops + inputs <- clone + return true + }) + } else { + for _, name := range names { + if interruptRequested(interrupt) { + break + } + inputs <- name + } + } + close(inputs) + }() + go func() { + wg.Wait() + close(outputs) + }() + return outputs +} diff --git a/claimtrie/claimtrie_test.go b/claimtrie/claimtrie_test.go new file mode 100644 index 00000000..61194f1a --- /dev/null +++ b/claimtrie/claimtrie_test.go @@ -0,0 +1,1027 @@ +package claimtrie + +import ( + "math/rand" + "testing" + "time" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/claimtrie/merkletrie" + "github.com/lbryio/lbcd/claimtrie/param" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" + + "github.com/stretchr/testify/require" +) + +var cfg = config.DefaultConfig + +func setup(t *testing.T) { + param.SetNetwork(wire.TestNet) + cfg.DataDir = t.TempDir() +} + +func b(s string) []byte { + return []byte(s) +} + +func buildTx(hash chainhash.Hash) *wire.MsgTx { + tx := wire.NewMsgTx(1) + txIn := wire.NewTxIn(wire.NewOutPoint(&hash, 0), nil, nil) + tx.AddTxIn(txIn) + tx.AddTxOut(wire.NewTxOut(0, nil)) + return tx +} + +func TestFixedHashes(t *testing.T) { + + r := require.New(t) + + setup(t) + ct, err := New(cfg) + r.NoError(err) + defer ct.Close() + + r.Equal(merkletrie.EmptyTrieHash[:], ct.MerkleHash()[:]) + + tx1 := buildTx(*merkletrie.EmptyTrieHash) + tx2 := buildTx(tx1.TxHash()) + tx3 := buildTx(tx2.TxHash()) + tx4 := buildTx(tx3.TxHash()) + + err = ct.AddClaim(b("test"), tx1.TxIn[0].PreviousOutPoint, change.NewClaimID(tx1.TxIn[0].PreviousOutPoint), 50) + r.NoError(err) + + err = ct.AddClaim(b("test2"), tx2.TxIn[0].PreviousOutPoint, change.NewClaimID(tx2.TxIn[0].PreviousOutPoint), 50) + r.NoError(err) + + err = ct.AddClaim(b("test"), tx3.TxIn[0].PreviousOutPoint, change.NewClaimID(tx3.TxIn[0].PreviousOutPoint), 50) + r.NoError(err) + + err = ct.AddClaim(b("tes"), tx4.TxIn[0].PreviousOutPoint, change.NewClaimID(tx4.TxIn[0].PreviousOutPoint), 50) + r.NoError(err) + + incrementBlock(r, ct, 1) + + expected, err := chainhash.NewHashFromStr("938fb93364bf8184e0b649c799ae27274e8db5221f1723c99fb2acd3386cfb00") + r.NoError(err) + r.Equal(expected[:], ct.MerkleHash()[:]) +} + +func TestEmptyHashFork(t *testing.T) { + r := require.New(t) + + setup(t) + param.ActiveParams.AllClaimsInMerkleForkHeight = 2 + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + for i := 0; i < 5; i++ { + err := ct.AppendBlock(false) + r.NoError(err) + } +} + +func TestNormalizationFork(t *testing.T) { + r := require.New(t) + + setup(t) + param.ActiveParams.NormalizedNameForkHeight = 2 + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("AÑEJO"), o1, change.NewClaimID(o1), 10) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("AÑejo"), o2, change.NewClaimID(o2), 5) + r.NoError(err) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddClaim([]byte("あてはまる"), o3, change.NewClaimID(o3), 5) + r.NoError(err) + + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddClaim([]byte("Aḿlie"), o4, change.NewClaimID(o4), 5) + r.NoError(err) + + o5 := wire.OutPoint{Hash: hash, Index: 5} + err = ct.AddClaim([]byte("TEST"), o5, change.NewClaimID(o5), 5) + r.NoError(err) + + o6 := wire.OutPoint{Hash: hash, Index: 6} + err = ct.AddClaim([]byte("test"), o6, change.NewClaimID(o6), 7) + r.NoError(err) + + o7 := wire.OutPoint{Hash: hash, Index: 7} + err = ct.AddSupport([]byte("test"), o7, 11, change.NewClaimID(o6)) + r.NoError(err) + + incrementBlock(r, ct, 1) + r.NotEqual(merkletrie.EmptyTrieHash[:], ct.MerkleHash()[:]) + + n, err := ct.nodeManager.NodeAt(ct.nodeManager.Height(), []byte("AÑEJO")) + r.NoError(err) + r.NotNil(n.BestClaim) + r.Equal(int32(1), n.TakenOverAt) + + o8 := wire.OutPoint{Hash: hash, Index: 8} + err = ct.AddClaim([]byte("aÑEJO"), o8, change.NewClaimID(o8), 8) + r.NoError(err) + + incrementBlock(r, ct, 1) + r.NotEqual(merkletrie.EmptyTrieHash[:], ct.MerkleHash()[:]) + + n, err = ct.nodeManager.NodeAt(ct.nodeManager.Height(), []byte("añejo")) + r.NoError(err) + r.Equal(3, len(n.Claims)) + r.Equal(uint32(1), n.BestClaim.OutPoint.Index) + r.Equal(int32(2), n.TakenOverAt) + + n, err = ct.nodeManager.NodeAt(ct.nodeManager.Height(), []byte("test")) + r.NoError(err) + r.Equal(int64(18), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) +} + +func TestActivationsOnNormalizationFork(t *testing.T) { + + r := require.New(t) + + setup(t) + param.ActiveParams.NormalizedNameForkHeight = 4 + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + + o7 := wire.OutPoint{Hash: hash, Index: 7} + err = ct.AddClaim([]byte("A"), o7, change.NewClaimID(o7), 1) + r.NoError(err) + incrementBlock(r, ct, 3) + verifyBestIndex(t, ct, "A", 7, 1) + + o8 := wire.OutPoint{Hash: hash, Index: 8} + err = ct.AddClaim([]byte("A"), o8, change.NewClaimID(o8), 2) + r.NoError(err) + incrementBlock(r, ct, 1) + verifyBestIndex(t, ct, "a", 8, 2) + + incrementBlock(r, ct, 2) + verifyBestIndex(t, ct, "a", 8, 2) + + err = ct.ResetHeight(3) + r.NoError(err) + verifyBestIndex(t, ct, "A", 7, 1) +} + +func TestNormalizationSortOrder(t *testing.T) { + + r := require.New(t) + // this was an unfortunate bug; the normalization fork should not have activated anything + // alas, it's now part of our history; we hereby test it to keep it that way + setup(t) + param.ActiveParams.NormalizedNameForkHeight = 2 + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("A"), o1, change.NewClaimID(o1), 1) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("A"), o2, change.NewClaimID(o2), 2) + r.NoError(err) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddClaim([]byte("a"), o3, change.NewClaimID(o3), 3) + r.NoError(err) + + incrementBlock(r, ct, 1) + verifyBestIndex(t, ct, "A", 2, 2) + verifyBestIndex(t, ct, "a", 3, 1) + + incrementBlock(r, ct, 1) + verifyBestIndex(t, ct, "a", 3, 3) +} + +func verifyBestIndex(t *testing.T, ct *ClaimTrie, name string, idx uint32, claims int) { + + r := require.New(t) + + n, err := ct.nodeManager.NodeAt(ct.nodeManager.Height(), []byte(name)) + r.NoError(err) + r.Equal(claims, len(n.Claims)) + if claims > 0 { + r.Equal(idx, n.BestClaim.OutPoint.Index) + } +} + +func TestRebuild(t *testing.T) { + r := require.New(t) + setup(t) + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test1"), o1, change.NewClaimID(o1), 1) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test2"), o2, change.NewClaimID(o2), 2) + r.NoError(err) + + incrementBlock(r, ct, 1) + + m := ct.MerkleHash() + r.NotNil(m) + r.NotEqual(*merkletrie.EmptyTrieHash, *m) + + ct.merkleTrie = merkletrie.NewRamTrie() + ct.runFullTrieRebuild(nil, nil) + + m2 := ct.MerkleHash() + r.NotNil(m2) + r.Equal(*m, *m2) +} + +func BenchmarkClaimTrie_AppendBlock256(b *testing.B) { + + addUpdateRemoveRandoms(b, 256) +} + +func BenchmarkClaimTrie_AppendBlock4(b *testing.B) { + + addUpdateRemoveRandoms(b, 4) +} + +func addUpdateRemoveRandoms(b *testing.B, inBlock int) { + rand.Seed(42) + names := make([][]byte, 0, b.N) + + for i := 0; i < b.N; i++ { + names = append(names, randomName()) + } + + var hashes []*chainhash.Hash + + param.SetNetwork(wire.TestNet) + param.ActiveParams.OriginalClaimExpirationTime = 1000000 + param.ActiveParams.ExtendedClaimExpirationTime = 1000000 + cfg.DataDir = b.TempDir() + + r := require.New(b) + ct, err := New(cfg) + r.NoError(err) + defer ct.Close() + h1 := chainhash.Hash{100, 200} + + start := time.Now() + b.ResetTimer() + + c := 0 + for i := 0; i < b.N; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + err = ct.AddClaim(names[i], op, id, 500) + r.NoError(err) + if c++; c%inBlock == inBlock-1 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + + for i := 0; i < b.N; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + op.Hash[0] = 1 + err = ct.UpdateClaim(names[i], op, 400, id) + r.NoError(err) + if c++; c%inBlock == inBlock-1 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + + for i := 0; i < b.N; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + op.Hash[0] = 2 + err = ct.UpdateClaim(names[i], op, 300, id) + r.NoError(err) + if c++; c%inBlock == inBlock-1 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + + for i := 0; i < b.N; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + op.Hash[0] = 3 + err = ct.SpendClaim(names[i], op, id) + r.NoError(err) + if c++; c%inBlock == inBlock-1 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + + b.StopTimer() + ht := ct.height + h1 = *ct.MerkleHash() + b.Logf("Running AppendBlock bench with %d names in %f sec. Height: %d, Hash: %s", + b.N, time.Since(start).Seconds(), ht, h1.String()) + + // a very important test of the functionality: + for ct.height > 0 { + r.True(hashes[ct.height-1].IsEqual(ct.MerkleHash())) + err = ct.ResetHeight(ct.height - 1) + r.NoError(err) + } +} + +func randomName() []byte { + name := make([]byte, rand.Intn(30)+10) + rand.Read(name) + for i := range name { + name[i] %= 56 + name[i] += 65 + } + return name +} + +func incrementBlock(r *require.Assertions, ct *ClaimTrie, c int32) { + h := ct.height + c + if c < 0 { + err := ct.ResetHeight(ct.height + c) + r.NoError(err) + } else { + for ; c > 0; c-- { + err := ct.AppendBlock(false) + r.NoError(err) + } + } + r.Equal(h, ct.height) +} + +func TestNormalizationRollback(t *testing.T) { + param.SetNetwork(wire.TestNet) + param.ActiveParams.OriginalClaimExpirationTime = 1000000 + param.ActiveParams.ExtendedClaimExpirationTime = 1000000 + cfg.DataDir = t.TempDir() + + r := require.New(t) + ct, err := New(cfg) + r.NoError(err) + defer ct.Close() + + r.Equal(int32(250), param.ActiveParams.NormalizedNameForkHeight) + incrementBlock(r, ct, 247) + + h1 := chainhash.Hash{100, 200} + op := wire.OutPoint{Hash: h1, Index: 1} + id := change.NewClaimID(op) + err = ct.AddClaim([]byte("TEST"), op, id, 1000) + r.NoError(err) + + incrementBlock(r, ct, 5) + incrementBlock(r, ct, -4) + err = ct.SpendClaim([]byte("TEST"), op, id) + r.NoError(err) + incrementBlock(r, ct, 1) + h := ct.MerkleHash() + r.True(h.IsEqual(merkletrie.EmptyTrieHash)) + incrementBlock(r, ct, 3) + h2 := ct.MerkleHash() + r.True(h.IsEqual(h2)) +} + +func TestNormalizationRollbackFuzz(t *testing.T) { + rand.Seed(42) + var hashes []*chainhash.Hash + + param.SetNetwork(wire.TestNet) + param.ActiveParams.OriginalClaimExpirationTime = 1000000 + param.ActiveParams.ExtendedClaimExpirationTime = 1000000 + cfg.DataDir = t.TempDir() + + r := require.New(t) + ct, err := New(cfg) + r.NoError(err) + defer ct.Close() + h1 := chainhash.Hash{100, 200} + + r.Equal(int32(250), param.ActiveParams.NormalizedNameForkHeight) + incrementBlock(r, ct, 240) + + for j := 0; j < 10; j++ { + c := 0 + for i := 0; i < 200; i++ { + op := wire.OutPoint{Hash: h1, Index: uint32(i)} + id := change.NewClaimID(op) + err = ct.AddClaim(randomName(), op, id, 500) + r.NoError(err) + if c++; c%10 == 9 { + incrementBlock(r, ct, 1) + hashes = append(hashes, ct.MerkleHash()) + } + } + if j > 7 { + ct.runFullTrieRebuild(nil, nil) + h := ct.MerkleHash() + r.True(h.IsEqual(hashes[len(hashes)-1])) + } + for ct.height > 240 { + r.True(hashes[ct.height-1-240].IsEqual(ct.MerkleHash())) + err = ct.ResetHeight(ct.height - 1) + r.NoError(err) + } + hashes = hashes[:0] + } +} + +func TestClaimReplace(t *testing.T) { + r := require.New(t) + setup(t) + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("bass"), o1, change.NewClaimID(o1), 8) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("basso"), o2, change.NewClaimID(o2), 10) + r.NoError(err) + + incrementBlock(r, ct, 1) + n, err := ct.NodeAt(ct.height, []byte("bass")) + r.Equal(o1.String(), n.BestClaim.OutPoint.String()) + + err = ct.SpendClaim([]byte("bass"), o1, n.BestClaim.ClaimID) + r.NoError(err) + + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddClaim([]byte("bassfisher"), o4, change.NewClaimID(o4), 12) + r.NoError(err) + + incrementBlock(r, ct, 1) + n, err = ct.NodeAt(ct.height, []byte("bass")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) + n, err = ct.NodeAt(ct.height, []byte("bassfisher")) + r.Equal(o4.String(), n.BestClaim.OutPoint.String()) +} + +func TestGeneralClaim(t *testing.T) { + r := require.New(t) + setup(t) + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8) + r.NoError(err) + + incrementBlock(r, ct, 1) + err = ct.ResetHeight(ct.height - 1) + r.NoError(err) + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8) + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8) + r.NoError(err) + + incrementBlock(r, ct, 1) + incrementBlock(r, ct, -1) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8) + r.NoError(err) + incrementBlock(r, ct, 1) + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8) + r.NoError(err) + incrementBlock(r, ct, 1) + + incrementBlock(r, ct, -2) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) +} + +func TestClaimTakeover(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8) + r.NoError(err) + + incrementBlock(r, ct, 10) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 18) + r.NoError(err) + + incrementBlock(r, ct, 10) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o1.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, -1) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o1.String(), n.BestClaim.OutPoint.String()) +} + +func TestSpendClaim(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8) + r.NoError(err) + + incrementBlock(r, ct, 1) + + err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, -1) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddClaim([]byte("test"), o3, change.NewClaimID(o3), 22) + r.NoError(err) + + incrementBlock(r, ct, 10) + + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddClaim([]byte("test"), o4, change.NewClaimID(o4), 28) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o3.String(), n.BestClaim.OutPoint.String()) + + err = ct.SpendClaim([]byte("test"), o3, n.BestClaim.ClaimID) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o4.String(), n.BestClaim.OutPoint.String()) + + err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1)) + r.NoError(err) + err = ct.SpendClaim([]byte("test"), o2, change.NewClaimID(o2)) + r.NoError(err) + err = ct.SpendClaim([]byte("test"), o3, change.NewClaimID(o3)) + r.NoError(err) + err = ct.SpendClaim([]byte("test"), o4, change.NewClaimID(o4)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) + + h := ct.MerkleHash() + r.Equal(merkletrie.EmptyTrieHash.String(), h.String()) +} + +func TestSupportDelay(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8) + r.NoError(err) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddSupport([]byte("test"), o3, 18, change.NewClaimID(o3)) // using bad ClaimID on purpose + r.NoError(err) + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddSupport([]byte("test"), o4, 18, change.NewClaimID(o2)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, 10) + + o5 := wire.OutPoint{Hash: hash, Index: 5} + err = ct.AddSupport([]byte("test"), o5, 18, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, 11) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o1.String(), n.BestClaim.OutPoint.String()) + + incrementBlock(r, ct, -1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o2.String(), n.BestClaim.OutPoint.String()) +} + +func TestSupportSpending(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + + incrementBlock(r, ct, 1) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.AddSupport([]byte("test"), o3, 18, change.NewClaimID(o1)) + r.NoError(err) + + err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.True(n == nil || !n.HasActiveBestClaim()) +} + +func TestSupportOnUpdate(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + + err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1)) + r.NoError(err) + + o2 := wire.OutPoint{Hash: hash, Index: 2} + err = ct.UpdateClaim([]byte("test"), o2, 28, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(28), n.BestClaim.Amount) + + incrementBlock(r, ct, 1) + + err = ct.SpendClaim([]byte("test"), o2, change.NewClaimID(o1)) + r.NoError(err) + + o3 := wire.OutPoint{Hash: hash, Index: 3} + err = ct.UpdateClaim([]byte("test"), o3, 38, change.NewClaimID(o1)) + r.NoError(err) + + o4 := wire.OutPoint{Hash: hash, Index: 4} + err = ct.AddSupport([]byte("test"), o4, 2, change.NewClaimID(o1)) + r.NoError(err) + + o5 := wire.OutPoint{Hash: hash, Index: 5} + err = ct.AddClaim([]byte("test"), o5, change.NewClaimID(o5), 39) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(40), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) + + err = ct.SpendSupport([]byte("test"), o4, n.BestClaim.ClaimID) + r.NoError(err) + + incrementBlock(r, ct, 1) + + // NOTE: LBRYcrd did not test that supports can trigger a takeover correctly (and it doesn't work here): + // n, err = ct.NodeAt(ct.height, []byte("test")) + // r.NoError(err) + // r.Equal(int64(39), n.BestClaim.Amount + n.SupportSums[n.BestClaim.ClaimID.Key()]) +} + +func TestSupportPreservation(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + o2 := wire.OutPoint{Hash: hash, Index: 2} + o3 := wire.OutPoint{Hash: hash, Index: 3} + o4 := wire.OutPoint{Hash: hash, Index: 4} + o5 := wire.OutPoint{Hash: hash, Index: 5} + + err = ct.AddSupport([]byte("test"), o2, 10, change.NewClaimID(o1)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18) + r.NoError(err) + + err = ct.AddClaim([]byte("test"), o3, change.NewClaimID(o3), 7) + r.NoError(err) + + incrementBlock(r, ct, 10) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(28), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) + + err = ct.AddSupport([]byte("test"), o4, 10, change.NewClaimID(o1)) + r.NoError(err) + err = ct.AddSupport([]byte("test"), o5, 100, change.NewClaimID(o3)) + r.NoError(err) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(38), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) + + incrementBlock(r, ct, 10) + + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(int64(107), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) +} + +func TestInvalidClaimID(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + incrementBlock(r, ct, 1) + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + o2 := wire.OutPoint{Hash: hash, Index: 2} + o3 := wire.OutPoint{Hash: hash, Index: 3} + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 10) + r.NoError(err) + + incrementBlock(r, ct, 1) + + err = ct.SpendClaim([]byte("test"), o3, change.NewClaimID(o1)) + r.NoError(err) + + err = ct.UpdateClaim([]byte("test"), o2, 18, change.NewClaimID(o3)) + r.NoError(err) + + incrementBlock(r, ct, 12) + + n, err := ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Len(n.Claims, 1) + r.Len(n.Supports, 0) + r.Equal(int64(10), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()]) +} + +func TestStableTrieHash(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + param.ActiveParams.AllClaimsInMerkleForkHeight = 8 // changes on this one + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + hash := chainhash.HashH([]byte{1, 2, 3}) + o1 := wire.OutPoint{Hash: hash, Index: 1} + + err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 1) + r.NoError(err) + + incrementBlock(r, ct, 1) + + h := ct.MerkleHash() + r.NotEqual(merkletrie.EmptyTrieHash.String(), h.String()) + + for i := 0; i < 6; i++ { + incrementBlock(r, ct, 1) + r.Equal(h.String(), ct.MerkleHash().String()) + } + + incrementBlock(r, ct, 1) + + r.NotEqual(h.String(), ct.MerkleHash()) + h = ct.MerkleHash() + + for i := 0; i < 16; i++ { + incrementBlock(r, ct, 1) + r.Equal(h.String(), ct.MerkleHash().String()) + } +} + +func TestBlock884431(t *testing.T) { + r := require.New(t) + setup(t) + param.ActiveParams.ActiveDelayFactor = 1 + param.ActiveParams.MaxRemovalWorkaroundHeight = 0 + param.ActiveParams.AllClaimsInMerkleForkHeight = 0 + + ct, err := New(cfg) + r.NoError(err) + r.NotNil(ct) + defer ct.Close() + + // in this block we have a scenario where we update all the child names + // which, in the old code, caused a trie vertex to be removed + // which, in turn, would trigger a premature takeover + + c := byte(10) + + add := func(s string, amt int64) wire.OutPoint { + h := chainhash.HashH([]byte{c}) + c++ + o := wire.OutPoint{Hash: h, Index: 1} + err := ct.AddClaim([]byte(s), o, change.NewClaimID(o), amt) + r.NoError(err) + return o + } + + update := func(s string, o wire.OutPoint, amt int64) wire.OutPoint { + err = ct.SpendClaim([]byte(s), o, change.NewClaimID(o)) + r.NoError(err) + + h := chainhash.HashH([]byte{c}) + c++ + o2 := wire.OutPoint{Hash: h, Index: 2} + + err = ct.UpdateClaim([]byte(s), o2, amt, change.NewClaimID(o)) + r.NoError(err) + return o2 + } + + o1a := add("go", 10) + o1b := add("go", 20) + o2 := add("goop", 10) + o3 := add("gog", 20) + + o4a := add("test", 10) + o4b := add("test", 20) + o5 := add("tester", 10) + o6 := add("testing", 20) + + for i := 0; i < 10; i++ { + err = ct.AppendBlock(false) + r.NoError(err) + } + n, err := ct.NodeAt(ct.height, []byte("go")) + r.NoError(err) + r.Equal(o1b.String(), n.BestClaim.OutPoint.String()) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o4b.String(), n.BestClaim.OutPoint.String()) + + update("go", o1b, 30) + o10 := update("go", o1a, 40) + update("gog", o3, 30) + update("goop", o2, 30) + + update("testing", o6, 30) + o11 := update("test", o4b, 30) + update("test", o4a, 40) + update("tester", o5, 30) + + incrementBlock(r, ct, 1) + + n, err = ct.NodeAt(ct.height, []byte("go")) + r.NoError(err) + r.Equal(o10.String(), n.BestClaim.OutPoint.String()) + n, err = ct.NodeAt(ct.height, []byte("test")) + r.NoError(err) + r.Equal(o11.String(), n.BestClaim.OutPoint.String()) +} diff --git a/claimtrie/cmd/cmd/block.go b/claimtrie/cmd/cmd/block.go new file mode 100644 index 00000000..d0ee7719 --- /dev/null +++ b/claimtrie/cmd/cmd/block.go @@ -0,0 +1,98 @@ +package cmd + +import ( + "fmt" + + "github.com/cockroachdb/errors" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewBlocCommands()) +} + +func NewBlocCommands() *cobra.Command { + + cmd := &cobra.Command{ + Use: "block", + Short: "Block related commands", + } + + cmd.AddCommand(NewBlockBestCommand()) + cmd.AddCommand(NewBlockListCommand()) + + return cmd +} + +func NewBlockBestCommand() *cobra.Command { + + cmd := &cobra.Command{ + Use: "best", + Short: "Show the height and hash of the best block", + RunE: func(cmd *cobra.Command, args []string) error { + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load blocks database") + } + defer db.Close() + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load chain") + } + + state := chain.BestSnapshot() + fmt.Printf("Block %7d: %s\n", state.Height, state.Hash.String()) + + return nil + }, + } + + return cmd +} + +func NewBlockListCommand() *cobra.Command { + + var fromHeight int32 + var toHeight int32 + + cmd := &cobra.Command{ + Use: "list", + Short: "List merkle hash of blocks between ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load blocks database") + } + defer db.Close() + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load chain") + } + + if toHeight > chain.BestSnapshot().Height { + toHeight = chain.BestSnapshot().Height + } + + for ht := fromHeight; ht <= toHeight; ht++ { + hash, err := chain.BlockHashByHeight(ht) + if err != nil { + return errors.Wrapf(err, "load hash for %d", ht) + } + fmt.Printf("Block %7d: %s\n", ht, hash.String()) + } + + return nil + }, + } + + cmd.Flags().Int32Var(&fromHeight, "from", 0, "From height (inclusive)") + cmd.Flags().Int32Var(&toHeight, "to", 0, "To height (inclusive)") + cmd.Flags().SortFlags = false + + return cmd +} diff --git a/claimtrie/cmd/cmd/chain.go b/claimtrie/cmd/cmd/chain.go new file mode 100644 index 00000000..b16ec599 --- /dev/null +++ b/claimtrie/cmd/cmd/chain.go @@ -0,0 +1,441 @@ +package cmd + +import ( + "os" + "path/filepath" + "sync" + "time" + + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/claimtrie" + "github.com/lbryio/lbcd/claimtrie/chain" + "github.com/lbryio/lbcd/claimtrie/chain/chainrepo" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/database" + _ "github.com/lbryio/lbcd/database/ffldb" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" + + "github.com/cockroachdb/errors" + "github.com/cockroachdb/pebble" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewChainCommands()) +} + +func NewChainCommands() *cobra.Command { + + cmd := &cobra.Command{ + Use: "chain", + Short: "chain related command", + } + + cmd.AddCommand(NewChainDumpCommand()) + cmd.AddCommand(NewChainReplayCommand()) + cmd.AddCommand(NewChainConvertCommand()) + + return cmd +} + +func NewChainDumpCommand() *cobra.Command { + + var chainRepoPath string + var fromHeight int32 + var toHeight int32 + + cmd := &cobra.Command{ + Use: "dump", + Short: "Dump the chain changes between and ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := chainRepoPath + log.Debugf("Open chain repo: %q", dbPath) + chainRepo, err := chainrepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open chain repo") + } + + for height := fromHeight; height <= toHeight; height++ { + changes, err := chainRepo.Load(height) + if errors.Is(err, pebble.ErrNotFound) { + continue + } + if err != nil { + return errors.Wrapf(err, "load charnges for height: %d") + } + for _, chg := range changes { + showChange(chg) + } + } + + return nil + }, + } + + cmd.Flags().StringVar(&chainRepoPath, "chaindb", "chain_db", "Claim operation database") + cmd.Flags().Int32Var(&fromHeight, "from", 0, "From height (inclusive)") + cmd.Flags().Int32Var(&toHeight, "to", 0, "To height (inclusive)") + cmd.Flags().SortFlags = false + + return cmd +} + +func NewChainReplayCommand() *cobra.Command { + + var chainRepoPath string + var fromHeight int32 + var toHeight int32 + + cmd := &cobra.Command{ + Use: "replay", + Short: "Replay the chain changes between and ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + for _, dbName := range []string{ + cfg.BlockRepoPebble.Path, + cfg.NodeRepoPebble.Path, + cfg.MerkleTrieRepoPebble.Path, + cfg.TemporalRepoPebble.Path, + } { + dbPath := filepath.Join(dataDir, netName, "claim_dbs", dbName) + log.Debugf("Delete repo: %q", dbPath) + err := os.RemoveAll(dbPath) + if err != nil { + return errors.Wrapf(err, "delete repo: %q", dbPath) + } + } + + log.Debugf("Open chain repo: %q", chainRepoPath) + chainRepo, err := chainrepo.NewPebble(chainRepoPath) + if err != nil { + return errors.Wrapf(err, "open chain repo") + } + + cfg := config.DefaultConfig + cfg.RamTrie = true + cfg.DataDir = filepath.Join(dataDir, netName) + + ct, err := claimtrie.New(cfg) + if err != nil { + return errors.Wrapf(err, "create claimtrie") + } + defer ct.Close() + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load blocks database") + } + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load chain") + } + + startTime := time.Now() + for ht := fromHeight; ht < toHeight; ht++ { + + changes, err := chainRepo.Load(ht + 1) + if errors.Is(err, pebble.ErrNotFound) { + // do nothing. + } else if err != nil { + return errors.Wrapf(err, "load changes for block %d", ht) + } + + for _, chg := range changes { + + switch chg.Type { + case change.AddClaim: + err = ct.AddClaim(chg.Name, chg.OutPoint, chg.ClaimID, chg.Amount) + case change.UpdateClaim: + err = ct.UpdateClaim(chg.Name, chg.OutPoint, chg.Amount, chg.ClaimID) + case change.SpendClaim: + err = ct.SpendClaim(chg.Name, chg.OutPoint, chg.ClaimID) + case change.AddSupport: + err = ct.AddSupport(chg.Name, chg.OutPoint, chg.Amount, chg.ClaimID) + case change.SpendSupport: + err = ct.SpendSupport(chg.Name, chg.OutPoint, chg.ClaimID) + default: + err = errors.Errorf("invalid change type: %v", chg) + } + + if err != nil { + return errors.Wrapf(err, "execute change %v", chg) + } + } + err = appendBlock(ct, chain) + if err != nil { + return errors.Wrapf(err, "appendBlock") + } + + if time.Since(startTime) > 5*time.Second { + log.Infof("Block: %d", ct.Height()) + startTime = time.Now() + } + } + + return nil + }, + } + + cmd.Flags().StringVar(&chainRepoPath, "chaindb", "chain_db", "Claim operation database") + cmd.Flags().Int32Var(&fromHeight, "from", 0, "From height") + cmd.Flags().Int32Var(&toHeight, "to", 0, "To height") + cmd.Flags().SortFlags = false + + return cmd +} + +func appendBlock(ct *claimtrie.ClaimTrie, chain *blockchain.BlockChain) error { + + err := ct.AppendBlock(false) + if err != nil { + return errors.Wrapf(err, "append block: %w") + } + + blockHash, err := chain.BlockHashByHeight(ct.Height()) + if err != nil { + return errors.Wrapf(err, "load from block repo: %w") + } + + header, err := chain.HeaderByHash(blockHash) + + if err != nil { + return errors.Wrapf(err, "load from block repo: %w") + } + + if *ct.MerkleHash() != header.ClaimTrie { + return errors.Errorf("hash mismatched at height %5d: exp: %s, got: %s", + ct.Height(), header.ClaimTrie, ct.MerkleHash()) + } + + return nil +} + +func NewChainConvertCommand() *cobra.Command { + + var chainRepoPath string + var toHeight int32 + + cmd := &cobra.Command{ + Use: "convert", + Short: "convert changes from 0 to ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load block db") + } + defer db.Close() + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load block db") + } + + if toHeight > chain.BestSnapshot().Height { + toHeight = chain.BestSnapshot().Height + } + + chainRepo, err := chainrepo.NewPebble(chainRepoPath) + if err != nil { + return errors.Wrapf(err, "open chain repo: %v") + } + defer chainRepo.Close() + + converter := chainConverter{ + db: db, + chain: chain, + chainRepo: chainRepo, + toHeight: toHeight, + blockChan: make(chan *btcutil.Block, 1000), + changesChan: make(chan []change.Change, 1000), + wg: &sync.WaitGroup{}, + stat: &stat{}, + } + + startTime := time.Now() + err = converter.start() + if err != nil { + return errors.Wrapf(err, "start Converter") + } + + converter.wait() + log.Infof("Convert chain: took %s", time.Since(startTime)) + + return nil + }, + } + + cmd.Flags().StringVar(&chainRepoPath, "chaindb", "chain_db", "Claim operation database") + cmd.Flags().Int32Var(&toHeight, "to", 0, "toHeight") + cmd.Flags().SortFlags = false + return cmd +} + +type stat struct { + blocksFetched int + blocksProcessed int + changesSaved int +} + +type chainConverter struct { + db database.DB + chain *blockchain.BlockChain + chainRepo chain.Repo + toHeight int32 + + blockChan chan *btcutil.Block + changesChan chan []change.Change + + wg *sync.WaitGroup + + stat *stat +} + +func (cc *chainConverter) wait() { + cc.wg.Wait() +} + +func (cb *chainConverter) start() error { + + go cb.reportStats() + + cb.wg.Add(3) + go cb.getBlock() + go cb.processBlock() + go cb.saveChanges() + + return nil +} + +func (cb *chainConverter) getBlock() { + defer cb.wg.Done() + defer close(cb.blockChan) + + for ht := int32(0); ht < cb.toHeight; ht++ { + block, err := cb.chain.BlockByHeight(ht) + if err != nil { + if errors.Cause(err).Error() == "too many open files" { + err = errors.WithHintf(err, "try ulimit -n 2048") + } + log.Errorf("load changes at %d: %s", ht, err) + return + } + cb.stat.blocksFetched++ + cb.blockChan <- block + } +} + +func (cb *chainConverter) processBlock() { + defer cb.wg.Done() + defer close(cb.changesChan) + + utxoPubScripts := map[wire.OutPoint][]byte{} + for block := range cb.blockChan { + var changes []change.Change + for _, tx := range block.Transactions() { + + if blockchain.IsCoinBase(tx) { + continue + } + + for _, txIn := range tx.MsgTx().TxIn { + prevOutpoint := txIn.PreviousOutPoint + pkScript := utxoPubScripts[prevOutpoint] + cs, err := txscript.ExtractClaimScript(pkScript) + if txscript.IsErrorCode(err, txscript.ErrNotClaimScript) { + continue + } + if err != nil { + log.Criticalf("Can't parse claim script: %s", err) + } + + chg := change.Change{ + Height: block.Height(), + Name: cs.Name, + OutPoint: txIn.PreviousOutPoint, + } + delete(utxoPubScripts, prevOutpoint) + + switch cs.Opcode { + case txscript.OP_CLAIMNAME: + chg.Type = change.SpendClaim + chg.ClaimID = change.NewClaimID(chg.OutPoint) + case txscript.OP_UPDATECLAIM: + chg.Type = change.SpendClaim + copy(chg.ClaimID[:], cs.ClaimID) + case txscript.OP_SUPPORTCLAIM: + chg.Type = change.SpendSupport + copy(chg.ClaimID[:], cs.ClaimID) + } + + changes = append(changes, chg) + } + + op := *wire.NewOutPoint(tx.Hash(), 0) + for i, txOut := range tx.MsgTx().TxOut { + cs, err := txscript.ExtractClaimScript(txOut.PkScript) + if txscript.IsErrorCode(err, txscript.ErrNotClaimScript) { + continue + } + + op.Index = uint32(i) + chg := change.Change{ + Height: block.Height(), + Name: cs.Name, + OutPoint: op, + Amount: txOut.Value, + } + utxoPubScripts[op] = txOut.PkScript + + switch cs.Opcode { + case txscript.OP_CLAIMNAME: + chg.Type = change.AddClaim + chg.ClaimID = change.NewClaimID(op) + case txscript.OP_SUPPORTCLAIM: + chg.Type = change.AddSupport + copy(chg.ClaimID[:], cs.ClaimID) + case txscript.OP_UPDATECLAIM: + chg.Type = change.UpdateClaim + copy(chg.ClaimID[:], cs.ClaimID) + } + changes = append(changes, chg) + } + } + cb.stat.blocksProcessed++ + + if len(changes) != 0 { + cb.changesChan <- changes + } + } +} + +func (cb *chainConverter) saveChanges() { + defer cb.wg.Done() + + for changes := range cb.changesChan { + err := cb.chainRepo.Save(changes[0].Height, changes) + if err != nil { + log.Errorf("save to chain repo: %s", err) + return + } + cb.stat.changesSaved++ + } +} + +func (cb *chainConverter) reportStats() { + stat := cb.stat + tick := time.NewTicker(5 * time.Second) + for range tick.C { + log.Infof("block : %7d / %7d, changes saved: %d", + stat.blocksFetched, stat.blocksProcessed, stat.changesSaved) + + } +} diff --git a/claimtrie/cmd/cmd/helper.go b/claimtrie/cmd/cmd/helper.go new file mode 100644 index 00000000..e75da402 --- /dev/null +++ b/claimtrie/cmd/cmd/helper.go @@ -0,0 +1,62 @@ +package cmd + +import ( + "path/filepath" + "time" + + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + + "github.com/cockroachdb/errors" +) + +func loadBlocksDB() (database.DB, error) { + + dbPath := filepath.Join(dataDir, netName, "blocks_ffldb") + log.Infof("Loading blocks database: %s", dbPath) + db, err := database.Open("ffldb", dbPath, chainPramas().Net) + if err != nil { + return nil, errors.Wrapf(err, "open blocks database") + } + + return db, nil +} + +func loadChain(db database.DB) (*blockchain.BlockChain, error) { + paramsCopy := chaincfg.MainNetParams + + log.Infof("Loading chain from database") + + startTime := time.Now() + chain, err := blockchain.New(&blockchain.Config{ + DB: db, + ChainParams: ¶msCopy, + TimeSource: blockchain.NewMedianTime(), + SigCache: txscript.NewSigCache(1000), + }) + if err != nil { + return nil, errors.Wrapf(err, "create blockchain") + } + + log.Infof("Loaded chain from database (%s)", time.Since(startTime)) + + return chain, err + +} + +func chainPramas() chaincfg.Params { + + // Make a copy so the user won't modify the global instance. + params := chaincfg.MainNetParams + switch netName { + case "mainnet": + params = chaincfg.MainNetParams + case "testnet": + params = chaincfg.TestNet3Params + case "regtest": + params = chaincfg.RegressionNetParams + } + return params +} diff --git a/claimtrie/cmd/cmd/merkletrie.go b/claimtrie/cmd/cmd/merkletrie.go new file mode 100644 index 00000000..66694c98 --- /dev/null +++ b/claimtrie/cmd/cmd/merkletrie.go @@ -0,0 +1,105 @@ +package cmd + +import ( + "fmt" + "path/filepath" + + "github.com/lbryio/lbcd/claimtrie/merkletrie" + "github.com/lbryio/lbcd/claimtrie/merkletrie/merkletrierepo" + "github.com/lbryio/lbcd/claimtrie/temporal/temporalrepo" + + "github.com/cockroachdb/errors" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewTrieCommands()) +} + +func NewTrieCommands() *cobra.Command { + + cmd := &cobra.Command{ + Use: "trie", + Short: "MerkleTrie related commands", + } + + cmd.AddCommand(NewTrieNameCommand()) + + return cmd +} + +func NewTrieNameCommand() *cobra.Command { + + var height int32 + var name string + + cmd := &cobra.Command{ + Use: "name", + Short: "List the claim and child hashes at vertex name of block at height", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + db, err := loadBlocksDB() + if err != nil { + return errors.Wrapf(err, "load blocks database") + } + defer db.Close() + + chain, err := loadChain(db) + if err != nil { + return errors.Wrapf(err, "load chain") + } + + state := chain.BestSnapshot() + fmt.Printf("Block %7d: %s\n", state.Height, state.Hash.String()) + + if height > state.Height { + return errors.New("requested height is unavailable") + } + + hash := state.Hash + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.MerkleTrieRepoPebble.Path) + log.Debugf("Open merkletrie repo: %q", dbPath) + trieRepo, err := merkletrierepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open merkle trie repo") + } + + trie := merkletrie.NewPersistentTrie(trieRepo) + defer trie.Close() + + trie.SetRoot(&hash) + + if len(name) > 1 { + trie.Dump(name) + return nil + } + + dbPath = filepath.Join(dataDir, netName, "claim_dbs", cfg.TemporalRepoPebble.Path) + log.Debugf("Open temporal repo: %q", dbPath) + tmpRepo, err := temporalrepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open temporal repo") + } + + nodes, err := tmpRepo.NodesAt(height) + if err != nil { + return errors.Wrapf(err, "read temporal repo at %d", height) + } + + for _, name := range nodes { + fmt.Printf("Name: %s, ", string(name)) + trie.Dump(string(name)) + } + + return nil + }, + } + + cmd.Flags().Int32Var(&height, "height", 0, "Height") + cmd.Flags().StringVar(&name, "name", "", "Name") + cmd.Flags().SortFlags = false + + return cmd +} diff --git a/claimtrie/cmd/cmd/node.go b/claimtrie/cmd/cmd/node.go new file mode 100644 index 00000000..08112e94 --- /dev/null +++ b/claimtrie/cmd/cmd/node.go @@ -0,0 +1,194 @@ +package cmd + +import ( + "encoding/hex" + "fmt" + "math" + "path/filepath" + + "github.com/cockroachdb/errors" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/claimtrie/node/noderepo" + + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewNodeCommands()) +} + +func NewNodeCommands() *cobra.Command { + + cmd := &cobra.Command{ + Use: "node", + Short: "Replay the application of changes on a node up to certain height", + } + + cmd.AddCommand(NewNodeDumpCommand()) + cmd.AddCommand(NewNodeReplayCommand()) + cmd.AddCommand(NewNodeChildrenCommand()) + cmd.AddCommand(NewNodeStatsCommand()) + + return cmd +} + +func NewNodeDumpCommand() *cobra.Command { + + var name string + var height int32 + + cmd := &cobra.Command{ + Use: "dump", + Short: "Replay the application of changes on a node up to certain height", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.NodeRepoPebble.Path) + log.Debugf("Open node repo: %q", dbPath) + repo, err := noderepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open node repo") + } + defer repo.Close() + + changes, err := repo.LoadChanges([]byte(name)) + if err != nil { + return errors.Wrapf(err, "load commands") + } + + for _, chg := range changes { + if chg.Height > height { + break + } + showChange(chg) + } + + return nil + }, + } + + cmd.Flags().StringVar(&name, "name", "", "Name") + cmd.MarkFlagRequired("name") + cmd.Flags().Int32Var(&height, "height", math.MaxInt32, "Height") + + return cmd +} + +func NewNodeReplayCommand() *cobra.Command { + + var name string + var height int32 + + cmd := &cobra.Command{ + Use: "replay", + Short: "Replay the changes of up to ", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.NodeRepoPebble.Path) + log.Debugf("Open node repo: %q", dbPath) + repo, err := noderepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open node repo") + } + + bm, err := node.NewBaseManager(repo) + if err != nil { + return errors.Wrapf(err, "create node manager") + } + defer bm.Close() + + nm := node.NewNormalizingManager(bm) + + n, err := nm.NodeAt(height, []byte(name)) + if err != nil || n == nil { + return errors.Wrapf(err, "get node: %s", name) + } + + showNode(n) + return nil + }, + } + + cmd.Flags().StringVar(&name, "name", "", "Name") + cmd.MarkFlagRequired("name") + cmd.Flags().Int32Var(&height, "height", 0, "Height (inclusive)") + cmd.Flags().SortFlags = false + + return cmd +} + +func NewNodeChildrenCommand() *cobra.Command { + + var name string + + cmd := &cobra.Command{ + Use: "children", + Short: "Show all the children names of a given node name", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.NodeRepoPebble.Path) + log.Debugf("Open node repo: %q", dbPath) + repo, err := noderepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open node repo") + } + defer repo.Close() + + fn := func(changes []change.Change) bool { + fmt.Printf("Name: %s, Height: %d, %d\n", changes[0].Name, changes[0].Height, + changes[len(changes)-1].Height) + return true + } + + err = repo.IterateChildren([]byte(name), fn) + if err != nil { + return errors.Wrapf(err, "iterate children: %s", name) + } + + return nil + }, + } + + cmd.Flags().StringVar(&name, "name", "", "Name") + cmd.MarkFlagRequired("name") + + return cmd +} + +func NewNodeStatsCommand() *cobra.Command { + + cmd := &cobra.Command{ + Use: "stat", + Short: "Determine the number of unique names, average changes per name, etc.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.NodeRepoPebble.Path) + log.Debugf("Open node repo: %q", dbPath) + repo, err := noderepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open node repo") + } + defer repo.Close() + + n := 0 + c := 0 + err = repo.IterateChildren([]byte{}, func(changes []change.Change) bool { + c += len(changes) + n++ + if len(changes) > 5000 { + fmt.Printf("Name: %s, Hex: %s, Changes: %d\n", string(changes[0].Name), + hex.EncodeToString(changes[0].Name), len(changes)) + } + return true + }) + fmt.Printf("\nNames: %d, Average changes: %.2f\n", n, float64(c)/float64(n)) + return errors.Wrapf(err, "iterate node repo") + }, + } + + return cmd +} diff --git a/claimtrie/cmd/cmd/root.go b/claimtrie/cmd/cmd/root.go new file mode 100644 index 00000000..8b2fb75f --- /dev/null +++ b/claimtrie/cmd/cmd/root.go @@ -0,0 +1,61 @@ +package cmd + +import ( + "os" + + "github.com/btcsuite/btclog" + "github.com/lbryio/lbcd/claimtrie/config" + "github.com/lbryio/lbcd/claimtrie/param" + "github.com/lbryio/lbcd/limits" + "github.com/lbryio/lbcd/wire" + + "github.com/spf13/cobra" +) + +var ( + log btclog.Logger + cfg = config.DefaultConfig + netName string + dataDir string +) + +var rootCmd = NewRootCommand() + +func NewRootCommand() *cobra.Command { + + cmd := &cobra.Command{ + Use: "claimtrie", + Short: "ClaimTrie Command Line Interface", + SilenceUsage: true, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + switch netName { + case "mainnet": + param.SetNetwork(wire.MainNet) + case "testnet": + param.SetNetwork(wire.TestNet3) + case "regtest": + param.SetNetwork(wire.TestNet) + } + }, + } + + cmd.PersistentFlags().StringVar(&netName, "netname", "mainnet", "Net name") + cmd.PersistentFlags().StringVarP(&dataDir, "datadir", "b", cfg.DataDir, "Data dir") + + return cmd +} + +func Execute() { + + backendLogger := btclog.NewBackend(os.Stdout) + defer os.Stdout.Sync() + log = backendLogger.Logger("CMDL") + log.SetLevel(btclog.LevelDebug) + + // Up some limits. + if err := limits.SetLimits(); err != nil { + log.Errorf("failed to set limits: %v\n", err) + } + + rootCmd.Execute() // nolint : errchk +} diff --git a/claimtrie/cmd/cmd/temporal.go b/claimtrie/cmd/cmd/temporal.go new file mode 100644 index 00000000..67d3397c --- /dev/null +++ b/claimtrie/cmd/cmd/temporal.go @@ -0,0 +1,60 @@ +package cmd + +import ( + "path/filepath" + + "github.com/lbryio/lbcd/claimtrie/temporal/temporalrepo" + + "github.com/cockroachdb/errors" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(NewTemporalCommand()) +} + +func NewTemporalCommand() *cobra.Command { + + var fromHeight int32 + var toHeight int32 + + cmd := &cobra.Command{ + Use: "temporal", + Short: "List which nodes are update in a range of heights", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + + dbPath := filepath.Join(dataDir, netName, "claim_dbs", cfg.TemporalRepoPebble.Path) + log.Debugf("Open temporal repo: %s", dbPath) + repo, err := temporalrepo.NewPebble(dbPath) + if err != nil { + return errors.Wrapf(err, "open temporal repo") + } + + if toHeight <= 0 { + toHeight = fromHeight + } + + for ht := fromHeight; ht <= toHeight; ht++ { + names, err := repo.NodesAt(ht) + if err != nil { + return errors.Wrapf(err, "get node names from temporal") + } + + if len(names) == 0 { + continue + } + + showTemporalNames(ht, names) + } + + return nil + }, + } + + cmd.Flags().Int32Var(&fromHeight, "from", 0, "From height (inclusive)") + cmd.Flags().Int32Var(&toHeight, "to", 0, "To height (inclusive)") + cmd.Flags().SortFlags = false + + return cmd +} diff --git a/claimtrie/cmd/cmd/ui.go b/claimtrie/cmd/cmd/ui.go new file mode 100644 index 00000000..9882b474 --- /dev/null +++ b/claimtrie/cmd/cmd/ui.go @@ -0,0 +1,76 @@ +package cmd + +import ( + "fmt" + "strings" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node" +) + +var status = map[node.Status]string{ + node.Accepted: "Accepted", + node.Activated: "Activated", + node.Deactivated: "Deactivated", +} + +func changeType(c change.ChangeType) string { + switch c { + case change.AddClaim: + return "AddClaim" + case change.SpendClaim: + return "SpendClaim" + case change.UpdateClaim: + return "UpdateClaim" + case change.AddSupport: + return "AddSupport" + case change.SpendSupport: + return "SpendSupport" + } + return "Unknown" +} + +func showChange(chg change.Change) { + fmt.Printf(">>> Height: %6d: %s for %04s, %15d, %s - %s\n", + chg.Height, changeType(chg.Type), chg.ClaimID, chg.Amount, chg.OutPoint, chg.Name) +} + +func showClaim(c *node.Claim, n *node.Node) { + mark := " " + if c == n.BestClaim { + mark = "*" + } + + fmt.Printf("%s C ID: %s, TXO: %s\n %5d/%-5d, Status: %9s, Amount: %15d, Support Amount: %15d\n", + mark, c.ClaimID, c.OutPoint, c.AcceptedAt, c.ActiveAt, status[c.Status], c.Amount, n.SupportSums[c.ClaimID.Key()]) +} + +func showSupport(c *node.Claim) { + fmt.Printf(" S id: %s, op: %s, %5d/%-5d, %9s, amt: %15d\n", + c.ClaimID, c.OutPoint, c.AcceptedAt, c.ActiveAt, status[c.Status], c.Amount) +} + +func showNode(n *node.Node) { + + fmt.Printf("%s\n", strings.Repeat("-", 200)) + fmt.Printf("Last Node Takeover: %d\n\n", n.TakenOverAt) + n.SortClaimsByBid() + for _, c := range n.Claims { + showClaim(c, n) + for _, s := range n.Supports { + if s.ClaimID != c.ClaimID { + continue + } + showSupport(s) + } + } + fmt.Printf("\n\n") +} + +func showTemporalNames(height int32, names [][]byte) { + fmt.Printf("%7d: %q", height, names[0]) + for _, name := range names[1:] { + fmt.Printf(", %q ", name) + } + fmt.Printf("\n") +} diff --git a/claimtrie/cmd/main.go b/claimtrie/cmd/main.go new file mode 100644 index 00000000..b87adc7d --- /dev/null +++ b/claimtrie/cmd/main.go @@ -0,0 +1,9 @@ +package main + +import ( + "github.com/lbryio/lbcd/claimtrie/cmd/cmd" +) + +func main() { + cmd.Execute() +} diff --git a/claimtrie/config/config.go b/claimtrie/config/config.go new file mode 100644 index 00000000..4920ca17 --- /dev/null +++ b/claimtrie/config/config.go @@ -0,0 +1,49 @@ +package config + +import ( + "path/filepath" + + "github.com/lbryio/lbcd/claimtrie/param" + btcutil "github.com/lbryio/lbcutil" +) + +var DefaultConfig = Config{ + Params: param.MainNet, + + RamTrie: true, // as it stands the other trie uses more RAM, more time, and 40GB+ of disk space + + DataDir: filepath.Join(btcutil.AppDataDir("chain", false), "data"), + + BlockRepoPebble: pebbleConfig{ + Path: "blocks_pebble_db", + }, + NodeRepoPebble: pebbleConfig{ + Path: "node_change_pebble_db", + }, + TemporalRepoPebble: pebbleConfig{ + Path: "temporal_pebble_db", + }, + MerkleTrieRepoPebble: pebbleConfig{ + Path: "merkletrie_pebble_db", + }, +} + +// Config is the container of all configurations. +type Config struct { + Params param.ClaimTrieParams + + RamTrie bool + + DataDir string + + BlockRepoPebble pebbleConfig + NodeRepoPebble pebbleConfig + TemporalRepoPebble pebbleConfig + MerkleTrieRepoPebble pebbleConfig + + Interrupt <-chan struct{} +} + +type pebbleConfig struct { + Path string +} diff --git a/claimtrie/merkletrie/collapsedtrie.go b/claimtrie/merkletrie/collapsedtrie.go new file mode 100644 index 00000000..18af30a0 --- /dev/null +++ b/claimtrie/merkletrie/collapsedtrie.go @@ -0,0 +1,235 @@ +package merkletrie + +import ( + "github.com/lbryio/lbcd/chaincfg/chainhash" +) + +type KeyType []byte + +type collapsedVertex struct { + children []*collapsedVertex + key KeyType + merkleHash *chainhash.Hash + claimHash *chainhash.Hash +} + +// insertAt inserts v into s at index i and returns the new slice. +// https://stackoverflow.com/questions/42746972/golang-insert-to-a-sorted-slice +func insertAt(data []*collapsedVertex, i int, v *collapsedVertex) []*collapsedVertex { + if i == len(data) { + // Insert at end is the easy case. + return append(data, v) + } + + // Make space for the inserted element by shifting + // values at the insertion index up one index. The call + // to append does not allocate memory when cap(data) is + // greater than len(data). + data = append(data[:i+1], data[i:]...) + data[i] = v + return data +} + +func (ptn *collapsedVertex) Insert(value *collapsedVertex) *collapsedVertex { + // keep it sorted (and sort.Sort is too slow) + index := sortSearch(ptn.children, value.key[0]) + ptn.children = insertAt(ptn.children, index, value) + + return value +} + +// this sort.Search is stolen shamelessly from search.go, +// and modified for performance to not need a closure +func sortSearch(nodes []*collapsedVertex, b byte) int { + i, j := 0, len(nodes) + for i < j { + h := int(uint(i+j) >> 1) // avoid overflow when computing h + // i ≤ h < j + if nodes[h].key[0] < b { + i = h + 1 // preserves f(i-1) == false + } else { + j = h // preserves f(j) == true + } + } + // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. + return i +} + +func (ptn *collapsedVertex) findNearest(key KeyType) (int, *collapsedVertex) { + // none of the children overlap on the first char or we would have a parent node with that char + index := sortSearch(ptn.children, key[0]) + hits := ptn.children[index:] + if len(hits) > 0 { + return index, hits[0] + } + return -1, nil +} + +type collapsedTrie struct { + Root *collapsedVertex + Nodes int +} + +func NewCollapsedTrie() *collapsedTrie { + // we never delete the Root node + return &collapsedTrie{Root: &collapsedVertex{key: make(KeyType, 0)}, Nodes: 1} +} + +func (pt *collapsedTrie) NodeCount() int { + return pt.Nodes +} + +func matchLength(a, b KeyType) int { + minLen := len(a) + if len(b) < minLen { + minLen = len(b) + } + for i := 0; i < minLen; i++ { + if a[i] != b[i] { + return i + } + } + return minLen +} + +func (pt *collapsedTrie) insert(value KeyType, node *collapsedVertex) (bool, *collapsedVertex) { + index, child := node.findNearest(value) + match := 0 + if index >= 0 { // if we found a child + child.merkleHash = nil + match = matchLength(value, child.key) + if len(value) == match && len(child.key) == match { + return false, child + } + } + if match <= 0 { + pt.Nodes++ + return true, node.Insert(&collapsedVertex{key: value}) + } + if match < len(child.key) { + grandChild := collapsedVertex{key: child.key[match:], children: child.children, + claimHash: child.claimHash, merkleHash: child.merkleHash} + newChild := collapsedVertex{key: child.key[0:match], children: []*collapsedVertex{&grandChild}} + child = &newChild + node.children[index] = child + pt.Nodes++ + if len(value) == match { + return true, child + } + } + return pt.insert(value[match:], child) +} + +func (pt *collapsedTrie) InsertOrFind(value KeyType) (bool, *collapsedVertex) { + pt.Root.merkleHash = nil + if len(value) <= 0 { + return false, pt.Root + } + + // we store the name so we need to make our own copy of it + // this avoids errors where this function is called via the DB iterator + v2 := make([]byte, len(value)) + copy(v2, value) + return pt.insert(v2, pt.Root) +} + +func find(value KeyType, node *collapsedVertex, pathIndexes *[]int, path *[]*collapsedVertex) *collapsedVertex { + index, child := node.findNearest(value) + if index < 0 { + return nil + } + match := matchLength(value, child.key) + if len(value) == match && len(child.key) == match { + if pathIndexes != nil { + *pathIndexes = append(*pathIndexes, index) + } + if path != nil { + *path = append(*path, child) + } + return child + } + if match < len(child.key) || match == len(value) { + return nil + } + if pathIndexes != nil { + *pathIndexes = append(*pathIndexes, index) + } + if path != nil { + *path = append(*path, child) + } + return find(value[match:], child, pathIndexes, path) +} + +func (pt *collapsedTrie) Find(value KeyType) *collapsedVertex { + if len(value) <= 0 { + return pt.Root + } + return find(value, pt.Root, nil, nil) +} + +func (pt *collapsedTrie) FindPath(value KeyType) ([]int, []*collapsedVertex) { + pathIndexes := []int{-1} + path := []*collapsedVertex{pt.Root} + if len(value) > 0 { + result := find(value, pt.Root, &pathIndexes, &path) + if result == nil { // not sure I want this line + return nil, nil + } + } + return pathIndexes, path +} + +// IterateFrom can be used to find a value and run a function on that value. +// If the handler returns true it continues to iterate through the children of value. +func (pt *collapsedTrie) IterateFrom(start KeyType, handler func(name KeyType, value *collapsedVertex) bool) { + node := find(start, pt.Root, nil, nil) + if node == nil { + return + } + iterateFrom(start, node, handler) +} + +func iterateFrom(name KeyType, node *collapsedVertex, handler func(name KeyType, value *collapsedVertex) bool) { + for handler(name, node) { + for _, child := range node.children { + iterateFrom(append(name, child.key...), child, handler) + } + } +} + +func (pt *collapsedTrie) Erase(value KeyType) bool { + indexes, path := pt.FindPath(value) + if path == nil || len(path) <= 1 { + if len(path) == 1 { + path[0].merkleHash = nil + path[0].claimHash = nil + } + return false + } + nodes := pt.Nodes + i := len(path) - 1 + path[i].claimHash = nil // this is the thing we are erasing; the rest is book-keeping + for ; i > 0; i-- { + childCount := len(path[i].children) + noClaimData := path[i].claimHash == nil + path[i].merkleHash = nil + if childCount == 1 && noClaimData { + path[i].key = append(path[i].key, path[i].children[0].key...) + path[i].claimHash = path[i].children[0].claimHash + path[i].children = path[i].children[0].children + pt.Nodes-- + continue + } + if childCount == 0 && noClaimData { + index := indexes[i] + path[i-1].children = append(path[i-1].children[:index], path[i-1].children[index+1:]...) + pt.Nodes-- + continue + } + break + } + for ; i >= 0; i-- { + path[i].merkleHash = nil + } + return nodes > pt.Nodes +} diff --git a/claimtrie/merkletrie/collapsedtrie_test.go b/claimtrie/merkletrie/collapsedtrie_test.go new file mode 100644 index 00000000..ce41c35f --- /dev/null +++ b/claimtrie/merkletrie/collapsedtrie_test.go @@ -0,0 +1,113 @@ +package merkletrie + +import ( + "bytes" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func b(value string) []byte { return []byte(value) } +func eq(x []byte, y string) bool { return bytes.Equal(x, b(y)) } + +func TestInsertAndErase(t *testing.T) { + trie := NewCollapsedTrie() + assert.True(t, trie.NodeCount() == 1) + inserted, node := trie.InsertOrFind(b("abc")) + assert.True(t, inserted) + assert.NotNil(t, node) + assert.Equal(t, 2, trie.NodeCount()) + inserted, node = trie.InsertOrFind(b("abd")) + assert.True(t, inserted) + assert.Equal(t, 4, trie.NodeCount()) + assert.NotNil(t, node) + hit := trie.Find(b("ab")) + assert.True(t, eq(hit.key, "ab")) + assert.Equal(t, 2, len(hit.children)) + hit = trie.Find(b("abc")) + assert.True(t, eq(hit.key, "c")) + hit = trie.Find(b("abd")) + assert.True(t, eq(hit.key, "d")) + hit = trie.Find(b("a")) + assert.Nil(t, hit) + indexes, path := trie.FindPath(b("abd")) + assert.Equal(t, 3, len(indexes)) + assert.True(t, eq(path[1].key, "ab")) + erased := trie.Erase(b("ab")) + assert.False(t, erased) + assert.Equal(t, 4, trie.NodeCount()) + erased = trie.Erase(b("abc")) + assert.True(t, erased) + assert.Equal(t, 2, trie.NodeCount()) + erased = trie.Erase(b("abd")) + assert.True(t, erased) + assert.Equal(t, 1, trie.NodeCount()) +} + +func TestNilNameHandling(t *testing.T) { + trie := NewCollapsedTrie() + inserted, n := trie.InsertOrFind([]byte("test")) + assert.True(t, inserted) + n.claimHash = EmptyTrieHash + inserted, n = trie.InsertOrFind(nil) + assert.False(t, inserted) + n.claimHash = EmptyTrieHash + n.merkleHash = EmptyTrieHash + inserted, n = trie.InsertOrFind(nil) + assert.False(t, inserted) + assert.NotNil(t, n.claimHash) + assert.Nil(t, n.merkleHash) + nodeRemoved := trie.Erase(nil) + assert.False(t, nodeRemoved) + inserted, n = trie.InsertOrFind(nil) + assert.False(t, inserted) + assert.Nil(t, n.claimHash) +} + +func TestCollapsedTriePerformance(t *testing.T) { + inserts := 100000 // increase this to 1M for more interesting results + data := make([][]byte, inserts) + rand.Seed(42) + for i := 0; i < inserts; i++ { + size := rand.Intn(70) + 4 + data[i] = make([]byte, size) + rand.Read(data[i]) + for j := 0; j < size; j++ { + data[i][j] %= byte(62) // shrink the range to match the old test + } + } + + trie := NewCollapsedTrie() + // doing my own timing because I couldn't get the B.Run method to work: + start := time.Now() + for i := 0; i < inserts; i++ { + _, node := trie.InsertOrFind(data[i]) + assert.NotNil(t, node, "Failure at %d of %d", i, inserts) + } + t.Logf("Insertion in %f sec.", time.Since(start).Seconds()) + + start = time.Now() + for i := 0; i < inserts; i++ { + node := trie.Find(data[i]) + assert.True(t, bytes.HasSuffix(data[i], node.key), "Failure on %d of %d", i, inserts) + } + t.Logf("Lookup in %f sec. on %d nodes.", time.Since(start).Seconds(), trie.NodeCount()) + + start = time.Now() + for i := 0; i < inserts; i++ { + indexes, path := trie.FindPath(data[i]) + assert.True(t, len(indexes) == len(path)) + assert.True(t, len(path) > 1) + assert.True(t, bytes.HasSuffix(data[i], path[len(path)-1].key)) + } + t.Logf("Parents in %f sec.", time.Since(start).Seconds()) + + start = time.Now() + for i := 0; i < inserts; i++ { + trie.Erase(data[i]) + } + t.Logf("Deletion in %f sec.", time.Since(start).Seconds()) + assert.Equal(t, 1, trie.NodeCount()) +} diff --git a/claimtrie/merkletrie/merkletrie.go b/claimtrie/merkletrie/merkletrie.go new file mode 100644 index 00000000..3bc525fe --- /dev/null +++ b/claimtrie/merkletrie/merkletrie.go @@ -0,0 +1,255 @@ +package merkletrie + +import ( + "bytes" + "fmt" + "runtime" + "sort" + "sync" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/node" +) + +var ( + // EmptyTrieHash represents the Merkle Hash of an empty PersistentTrie. + // "0000000000000000000000000000000000000000000000000000000000000001" + EmptyTrieHash = &chainhash.Hash{1} + NoChildrenHash = &chainhash.Hash{2} + NoClaimsHash = &chainhash.Hash{3} +) + +// PersistentTrie implements a 256-way prefix tree. +type PersistentTrie struct { + repo Repo + + root *vertex + bufs *sync.Pool +} + +// NewPersistentTrie returns a PersistentTrie. +func NewPersistentTrie(repo Repo) *PersistentTrie { + + tr := &PersistentTrie{ + repo: repo, + bufs: &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + }, + root: newVertex(EmptyTrieHash), + } + + return tr +} + +// SetRoot drops all resolved nodes in the PersistentTrie, and set the Root with specified hash. +func (t *PersistentTrie) SetRoot(h *chainhash.Hash) error { + t.root = newVertex(h) + runtime.GC() + return nil +} + +// Update updates the nodes along the path to the key. +// Each node is resolved or created with their Hash cleared. +func (t *PersistentTrie) Update(name []byte, hash *chainhash.Hash, restoreChildren bool) { + + n := t.root + for i, ch := range name { + if restoreChildren && len(n.childLinks) == 0 { + t.resolveChildLinks(n, name[:i]) + } + if n.childLinks[ch] == nil { + n.childLinks[ch] = newVertex(nil) + } + n.merkleHash = nil + n = n.childLinks[ch] + } + + if restoreChildren && len(n.childLinks) == 0 { + t.resolveChildLinks(n, name) + } + n.merkleHash = nil + n.claimsHash = hash +} + +// resolveChildLinks updates the links on n +func (t *PersistentTrie) resolveChildLinks(n *vertex, key []byte) { + + if n.merkleHash == nil { + return + } + + b := t.bufs.Get().(*bytes.Buffer) + defer t.bufs.Put(b) + b.Reset() + b.Write(key) + b.Write(n.merkleHash[:]) + + result, closer, err := t.repo.Get(b.Bytes()) + if result == nil { + return + } else if err != nil { + panic(err) + } + defer closer.Close() + + nb := nbuf(result) + _, n.claimsHash = nb.hasValue() + for i := 0; i < nb.entries(); i++ { + p, h := nb.entry(i) + n.childLinks[p] = newVertex(h) + } +} + +// MerkleHash returns the Merkle Hash of the PersistentTrie. +// All nodes must have been resolved before calling this function. +func (t *PersistentTrie) MerkleHash() *chainhash.Hash { + buf := make([]byte, 0, 256) + if h := t.merkle(buf, t.root); h == nil { + return EmptyTrieHash + } + return t.root.merkleHash +} + +// merkle recursively resolves the hashes of the node. +// All nodes must have been resolved before calling this function. +func (t *PersistentTrie) merkle(prefix []byte, v *vertex) *chainhash.Hash { + if v.merkleHash != nil { + return v.merkleHash + } + + b := t.bufs.Get().(*bytes.Buffer) + defer t.bufs.Put(b) + b.Reset() + + keys := keysInOrder(v) + + for _, ch := range keys { + child := v.childLinks[ch] + if child == nil { + continue + } + p := append(prefix, ch) + h := t.merkle(p, child) + if h != nil { + b.WriteByte(ch) // nolint : errchk + b.Write(h[:]) // nolint : errchk + } + if h == nil || len(prefix) > 4 { // TODO: determine the right number here + delete(v.childLinks, ch) // keep the RAM down (they get recreated on Update) + } + } + + if v.claimsHash != nil { + b.Write(v.claimsHash[:]) + } + + if b.Len() > 0 { + h := chainhash.DoubleHashH(b.Bytes()) + v.merkleHash = &h + t.repo.Set(append(prefix, h[:]...), b.Bytes()) + } + + return v.merkleHash +} + +func keysInOrder(v *vertex) []byte { + keys := make([]byte, 0, len(v.childLinks)) + for key := range v.childLinks { + keys = append(keys, key) + } + sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] }) + return keys +} + +func (t *PersistentTrie) MerkleHashAllClaims() *chainhash.Hash { + buf := make([]byte, 0, 256) + if h := t.merkleAllClaims(buf, t.root); h == nil { + return EmptyTrieHash + } + return t.root.merkleHash +} + +func (t *PersistentTrie) merkleAllClaims(prefix []byte, v *vertex) *chainhash.Hash { + if v.merkleHash != nil { + return v.merkleHash + } + b := t.bufs.Get().(*bytes.Buffer) + defer t.bufs.Put(b) + b.Reset() + + keys := keysInOrder(v) + childHashes := make([]*chainhash.Hash, 0, len(keys)) + for _, ch := range keys { + n := v.childLinks[ch] + if n == nil { + continue + } + p := append(prefix, ch) + h := t.merkleAllClaims(p, n) + if h != nil { + childHashes = append(childHashes, h) + b.WriteByte(ch) // nolint : errchk + b.Write(h[:]) // nolint : errchk + } + if h == nil || len(prefix) > 4 { // TODO: determine the right number here + delete(v.childLinks, ch) // keep the RAM down (they get recreated on Update) + } + } + + if len(childHashes) > 1 || v.claimsHash != nil { // yeah, about that 1 there -- old code used the condensed trie + left := NoChildrenHash + if len(childHashes) > 0 { + left = node.ComputeMerkleRoot(childHashes) + } + right := NoClaimsHash + if v.claimsHash != nil { + b.Write(v.claimsHash[:]) // for Has Value, nolint : errchk + right = v.claimsHash + } + + h := node.HashMerkleBranches(left, right) + v.merkleHash = h + t.repo.Set(append(prefix, h[:]...), b.Bytes()) + } else if len(childHashes) == 1 { + v.merkleHash = childHashes[0] // pass it up the tree + t.repo.Set(append(prefix, v.merkleHash[:]...), b.Bytes()) + } + + return v.merkleHash +} + +func (t *PersistentTrie) Close() error { + return errors.WithStack(t.repo.Close()) +} + +func (t *PersistentTrie) Dump(s string) { + // TODO: this function is in the wrong spot; either it goes with its caller or it needs to be a generic iterator + // we don't want fmt used in here either way + + v := t.root + + for i := 0; i < len(s); i++ { + t.resolveChildLinks(v, []byte(s[:i])) + ch := s[i] + v = v.childLinks[ch] + if v == nil { + fmt.Printf("Missing child at %s\n", s[:i+1]) + return + } + } + t.resolveChildLinks(v, []byte(s)) + + fmt.Printf("Node hash: %s, has value: %t\n", v.merkleHash.String(), v.claimsHash != nil) + + for key, value := range v.childLinks { + fmt.Printf(" Child %s hash: %s\n", string(key), value.merkleHash.String()) + } +} + +func (t *PersistentTrie) Flush() error { + return t.repo.Flush() +} diff --git a/claimtrie/merkletrie/merkletrie_test.go b/claimtrie/merkletrie/merkletrie_test.go new file mode 100644 index 00000000..fc95a7b4 --- /dev/null +++ b/claimtrie/merkletrie/merkletrie_test.go @@ -0,0 +1,25 @@ +package merkletrie + +import ( + "testing" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/node" + + "github.com/stretchr/testify/require" +) + +func TestName(t *testing.T) { + + r := require.New(t) + + target, _ := chainhash.NewHashFromStr("e9ffb584c62449f157c8be88257bd1eebb2d8ef824f5c86b43c4f8fd9e800d6a") + + data := []*chainhash.Hash{EmptyTrieHash} + root := node.ComputeMerkleRoot(data) + r.True(EmptyTrieHash.IsEqual(root)) + + data = append(data, NoChildrenHash, NoClaimsHash) + root = node.ComputeMerkleRoot(data) + r.True(target.IsEqual(root)) +} diff --git a/claimtrie/merkletrie/merkletrierepo/pebble.go b/claimtrie/merkletrie/merkletrierepo/pebble.go new file mode 100644 index 00000000..c903794e --- /dev/null +++ b/claimtrie/merkletrie/merkletrierepo/pebble.go @@ -0,0 +1,67 @@ +package merkletrierepo + +import ( + "io" + + "github.com/cockroachdb/pebble" + "github.com/pkg/errors" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + cache := pebble.NewCache(512 << 20) + //defer cache.Unref() + // + //go func() { + // tick := time.NewTicker(60 * time.Second) + // for range tick.C { + // + // m := cache.Metrics() + // fmt.Printf("cnt: %s, objs: %s, hits: %s, miss: %s, hitrate: %.2f\n", + // humanize.Bytes(uint64(m.Size)), + // humanize.Comma(m.Count), + // humanize.Comma(m.Hits), + // humanize.Comma(m.Misses), + // float64(m.Hits)/float64(m.Hits+m.Misses)) + // + // } + //}() + + db, err := pebble.Open(path, &pebble.Options{Cache: cache, BytesPerSync: 32 << 20, MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "unable to open %s", path) +} + +func (repo *Pebble) Get(key []byte) ([]byte, io.Closer, error) { + d, c, e := repo.db.Get(key) + if e == pebble.ErrNotFound { + return nil, c, nil + } + return d, c, e +} + +func (repo *Pebble) Set(key, value []byte) error { + return repo.db.Set(key, value, pebble.NoSync) +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/merkletrie/ramtrie.go b/claimtrie/merkletrie/ramtrie.go new file mode 100644 index 00000000..7b426655 --- /dev/null +++ b/claimtrie/merkletrie/ramtrie.go @@ -0,0 +1,139 @@ +package merkletrie + +import ( + "bytes" + "errors" + "runtime" + "sync" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/node" +) + +type MerkleTrie interface { + SetRoot(h *chainhash.Hash) error + Update(name []byte, h *chainhash.Hash, restoreChildren bool) + MerkleHash() *chainhash.Hash + MerkleHashAllClaims() *chainhash.Hash + Flush() error +} + +type RamTrie struct { + collapsedTrie + bufs *sync.Pool +} + +func NewRamTrie() *RamTrie { + return &RamTrie{ + bufs: &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + }, + collapsedTrie: collapsedTrie{Root: &collapsedVertex{merkleHash: EmptyTrieHash}}, + } +} + +var ErrFullRebuildRequired = errors.New("a full rebuild is required") + +func (rt *RamTrie) SetRoot(h *chainhash.Hash) error { + if rt.Root.merkleHash.IsEqual(h) { + runtime.GC() + return nil + } + + // should technically clear the old trie first, but this is abused for partial rebuilds so don't + return ErrFullRebuildRequired +} + +func (rt *RamTrie) Update(name []byte, h *chainhash.Hash, _ bool) { + if h == nil { + rt.Erase(name) + } else { + _, n := rt.InsertOrFind(name) + n.claimHash = h + } +} + +func (rt *RamTrie) MerkleHash() *chainhash.Hash { + if h := rt.merkleHash(rt.Root); h == nil { + return EmptyTrieHash + } + return rt.Root.merkleHash +} + +func (rt *RamTrie) merkleHash(v *collapsedVertex) *chainhash.Hash { + if v.merkleHash != nil { + return v.merkleHash + } + + b := rt.bufs.Get().(*bytes.Buffer) + defer rt.bufs.Put(b) + b.Reset() + + for _, ch := range v.children { + h := rt.merkleHash(ch) // h is a pointer; don't destroy its data + b.WriteByte(ch.key[0]) // nolint : errchk + b.Write(rt.completeHash(h, ch.key)) // nolint : errchk + } + + if v.claimHash != nil { + b.Write(v.claimHash[:]) + } + + if b.Len() > 0 { + h := chainhash.DoubleHashH(b.Bytes()) + v.merkleHash = &h + } + + return v.merkleHash +} + +func (rt *RamTrie) completeHash(h *chainhash.Hash, childKey KeyType) []byte { + var data [chainhash.HashSize + 1]byte + copy(data[1:], h[:]) + for i := len(childKey) - 1; i > 0; i-- { + data[0] = childKey[i] + copy(data[1:], chainhash.DoubleHashB(data[:])) + } + return data[1:] +} + +func (rt *RamTrie) MerkleHashAllClaims() *chainhash.Hash { + if h := rt.merkleHashAllClaims(rt.Root); h == nil { + return EmptyTrieHash + } + return rt.Root.merkleHash +} + +func (rt *RamTrie) merkleHashAllClaims(v *collapsedVertex) *chainhash.Hash { + if v.merkleHash != nil { + return v.merkleHash + } + + childHashes := make([]*chainhash.Hash, 0, len(v.children)) + for _, ch := range v.children { + h := rt.merkleHashAllClaims(ch) + childHashes = append(childHashes, h) + } + + claimHash := NoClaimsHash + if v.claimHash != nil { + claimHash = v.claimHash + } else if len(childHashes) == 0 { + return nil + } + + childHash := NoChildrenHash + if len(childHashes) > 0 { + // this shouldn't be referencing node; where else can we put this merkle root func? + childHash = node.ComputeMerkleRoot(childHashes) + } + + v.merkleHash = node.HashMerkleBranches(childHash, claimHash) + return v.merkleHash +} + +func (rt *RamTrie) Flush() error { + return nil +} diff --git a/claimtrie/merkletrie/repo.go b/claimtrie/merkletrie/repo.go new file mode 100644 index 00000000..68b6c8d6 --- /dev/null +++ b/claimtrie/merkletrie/repo.go @@ -0,0 +1,13 @@ +package merkletrie + +import ( + "io" +) + +// Repo defines APIs for PersistentTrie to access persistence layer. +type Repo interface { + Get(key []byte) ([]byte, io.Closer, error) + Set(key, value []byte) error + Close() error + Flush() error +} diff --git a/claimtrie/merkletrie/vertex.go b/claimtrie/merkletrie/vertex.go new file mode 100644 index 00000000..77f1f04a --- /dev/null +++ b/claimtrie/merkletrie/vertex.go @@ -0,0 +1,43 @@ +package merkletrie + +import ( + "github.com/lbryio/lbcd/chaincfg/chainhash" +) + +type vertex struct { + merkleHash *chainhash.Hash + claimsHash *chainhash.Hash + childLinks map[byte]*vertex +} + +func newVertex(hash *chainhash.Hash) *vertex { + return &vertex{childLinks: map[byte]*vertex{}, merkleHash: hash} +} + +// TODO: more professional to use msgpack here? + +// nbuf decodes the on-disk format of a node, which has the following form: +// ch(1B) hash(32B) +// ... +// ch(1B) hash(32B) +// vhash(32B) +type nbuf []byte + +func (nb nbuf) entries() int { + return len(nb) / 33 +} + +func (nb nbuf) entry(i int) (byte, *chainhash.Hash) { + h := chainhash.Hash{} + copy(h[:], nb[33*i+1:]) + return nb[33*i], &h +} + +func (nb nbuf) hasValue() (bool, *chainhash.Hash) { + if len(nb)%33 == 0 { + return false, nil + } + h := chainhash.Hash{} + copy(h[:], nb[len(nb)-32:]) + return true, &h +} diff --git a/claimtrie/node/claim.go b/claimtrie/node/claim.go new file mode 100644 index 00000000..09a7ed08 --- /dev/null +++ b/claimtrie/node/claim.go @@ -0,0 +1,82 @@ +package node + +import ( + "bytes" + "strconv" + "strings" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/wire" +) + +type Status int + +const ( + Accepted Status = iota + Activated + Deactivated +) + +// Claim defines a structure of stake, which could be a Claim or Support. +type Claim struct { + OutPoint wire.OutPoint + ClaimID change.ClaimID + Amount int64 + // CreatedAt int32 // the very first block, unused at present + AcceptedAt int32 // the latest update height + ActiveAt int32 // AcceptedAt + actual delay + VisibleAt int32 + + Status Status `msgpack:",omitempty"` + Sequence int32 `msgpack:",omitempty"` +} + +func (c *Claim) setOutPoint(op wire.OutPoint) *Claim { + c.OutPoint = op + return c +} + +func (c *Claim) SetAmt(amt int64) *Claim { + c.Amount = amt + return c +} + +func (c *Claim) setAccepted(height int32) *Claim { + c.AcceptedAt = height + return c +} + +func (c *Claim) setActiveAt(height int32) *Claim { + c.ActiveAt = height + return c +} + +func (c *Claim) setStatus(status Status) *Claim { + c.Status = status + return c +} + +func OutPointLess(a, b wire.OutPoint) bool { + + switch cmp := bytes.Compare(a.Hash[:], b.Hash[:]); { + case cmp < 0: + return true + case cmp > 0: + return false + default: + return a.Index < b.Index + } +} + +func NewOutPointFromString(str string) *wire.OutPoint { + + f := strings.Split(str, ":") + if len(f) != 2 { + return nil + } + hash, _ := chainhash.NewHashFromStr(f[0]) + idx, _ := strconv.Atoi(f[1]) + + return wire.NewOutPoint(hash, uint32(idx)) +} diff --git a/claimtrie/node/claim_list.go b/claimtrie/node/claim_list.go new file mode 100644 index 00000000..007a1b6b --- /dev/null +++ b/claimtrie/node/claim_list.go @@ -0,0 +1,33 @@ +package node + +import ( + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/wire" +) + +type ClaimList []*Claim + +type comparator func(c *Claim) bool + +func byID(id change.ClaimID) comparator { + return func(c *Claim) bool { + return c.ClaimID == id + } +} + +func byOut(out wire.OutPoint) comparator { + return func(c *Claim) bool { + return c.OutPoint == out // assuming value comparison + } +} + +func (l ClaimList) find(cmp comparator) *Claim { + + for i := range l { + if cmp(l[i]) { + return l[i] + } + } + + return nil +} diff --git a/claimtrie/node/hashfork_manager.go b/claimtrie/node/hashfork_manager.go new file mode 100644 index 00000000..bbd814ee --- /dev/null +++ b/claimtrie/node/hashfork_manager.go @@ -0,0 +1,39 @@ +package node + +import ( + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/param" +) + +type HashV2Manager struct { + Manager +} + +func (nm *HashV2Manager) computeClaimHashes(name []byte) (*chainhash.Hash, int32) { + + n, err := nm.NodeAt(nm.Height(), name) + if err != nil || n == nil { + return nil, 0 + } + + n.SortClaimsByBid() + claimHashes := make([]*chainhash.Hash, 0, len(n.Claims)) + for _, c := range n.Claims { + if c.Status == Activated { // TODO: unit test this line + claimHashes = append(claimHashes, calculateNodeHash(c.OutPoint, n.TakenOverAt)) + } + } + if len(claimHashes) > 0 { + return ComputeMerkleRoot(claimHashes), n.NextUpdate() + } + return nil, n.NextUpdate() +} + +func (nm *HashV2Manager) Hash(name []byte) (*chainhash.Hash, int32) { + + if nm.Height() >= param.ActiveParams.AllClaimsInMerkleForkHeight { + return nm.computeClaimHashes(name) + } + + return nm.Manager.Hash(name) +} diff --git a/claimtrie/node/hashfunc.go b/claimtrie/node/hashfunc.go new file mode 100644 index 00000000..deec78bb --- /dev/null +++ b/claimtrie/node/hashfunc.go @@ -0,0 +1,57 @@ +package node + +import ( + "crypto/sha256" + "encoding/binary" + "strconv" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/wire" +) + +func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash { + // Concatenate the left and right nodes. + var hash [chainhash.HashSize * 2]byte + copy(hash[:chainhash.HashSize], left[:]) + copy(hash[chainhash.HashSize:], right[:]) + + newHash := chainhash.DoubleHashH(hash[:]) + return &newHash +} + +func ComputeMerkleRoot(hashes []*chainhash.Hash) *chainhash.Hash { + if len(hashes) <= 0 { + return nil + } + for len(hashes) > 1 { + if (len(hashes) & 1) > 0 { // odd count + hashes = append(hashes, hashes[len(hashes)-1]) + } + for i := 0; i < len(hashes); i += 2 { // TODO: parallelize this loop (or use a lib that does it) + hashes[i>>1] = HashMerkleBranches(hashes[i], hashes[i+1]) + } + hashes = hashes[:len(hashes)>>1] + } + return hashes[0] +} + +func calculateNodeHash(op wire.OutPoint, takeover int32) *chainhash.Hash { + + txHash := chainhash.DoubleHashH(op.Hash[:]) + + nOut := []byte(strconv.Itoa(int(op.Index))) + nOutHash := chainhash.DoubleHashH(nOut) + + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, uint64(takeover)) + heightHash := chainhash.DoubleHashH(buf) + + h := make([]byte, 0, sha256.Size*3) + h = append(h, txHash[:]...) + h = append(h, nOutHash[:]...) + h = append(h, heightHash[:]...) + + hh := chainhash.DoubleHashH(h) + + return &hh +} diff --git a/claimtrie/node/log.go b/claimtrie/node/log.go new file mode 100644 index 00000000..86293b58 --- /dev/null +++ b/claimtrie/node/log.go @@ -0,0 +1,47 @@ +package node + +import ( + "sync" + + "github.com/btcsuite/btclog" +) + +// log is a logger that is initialized with no output filters. This +// means the package will not perform any logging by default until the caller +// requests it. +var log btclog.Logger + +// The default amount of logging is none. +func init() { + DisableLog() +} + +// DisableLog disables all library log output. Logging output is disabled +// by default until either UseLogger or SetLogWriter are called. +func DisableLog() { + log = btclog.Disabled +} + +// UseLogger uses a specified Logger to output package logging info. +// This should be used in preference to SetLogWriter if the caller is also +// using btclog. +func UseLogger(logger btclog.Logger) { + log = logger +} + +var loggedStrings = map[string]bool{} // is this gonna get too large? +var loggedStringsMutex sync.Mutex + +func LogOnce(s string) { + loggedStringsMutex.Lock() + defer loggedStringsMutex.Unlock() + if loggedStrings[s] { + return + } + loggedStrings[s] = true + log.Info(s) +} + +func Warn(s string) { + log.Warn(s) +} diff --git a/claimtrie/node/manager.go b/claimtrie/node/manager.go new file mode 100644 index 00000000..814bfc80 --- /dev/null +++ b/claimtrie/node/manager.go @@ -0,0 +1,401 @@ +package node + +import ( + "fmt" + "sort" + + "github.com/pkg/errors" + + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/param" +) + +type Manager interface { + AppendChange(chg change.Change) + IncrementHeightTo(height int32, temporary bool) ([][]byte, error) + DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) + Height() int32 + Close() error + NodeAt(height int32, name []byte) (*Node, error) + IterateNames(predicate func(name []byte) bool) + Hash(name []byte) (*chainhash.Hash, int32) + Flush() error +} + +type BaseManager struct { + repo Repo + + height int32 + changes []change.Change + + tempChanges map[string][]change.Change +} + +func NewBaseManager(repo Repo) (*BaseManager, error) { + + nm := &BaseManager{ + repo: repo, + } + + return nm, nil +} + +func (nm *BaseManager) NodeAt(height int32, name []byte) (*Node, error) { + + changes, err := nm.repo.LoadChanges(name) + if err != nil { + return nil, errors.Wrap(err, "in load changes") + } + + if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block + changes = append(changes, nm.tempChanges[string(name)]...) + } + + n, err := nm.newNodeFromChanges(changes, height) + if err != nil { + return nil, errors.Wrap(err, "in new node") + } + + return n, nil +} + +// Node returns a node at the current height. +// The returned node may have pending changes. +func (nm *BaseManager) node(name []byte) (*Node, error) { + return nm.NodeAt(nm.height, name) +} + +// newNodeFromChanges returns a new Node constructed from the changes. +// The changes must preserve their order received. +func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) { + + if len(changes) == 0 { + return nil, nil + } + + n := New() + previous := changes[0].Height + count := len(changes) + + for i, chg := range changes { + if chg.Height < previous { + panic("expected the changes to be in order by height") + } + if chg.Height > height { + count = i + break + } + + if previous < chg.Height { + n.AdjustTo(previous, chg.Height-1, chg.Name) // update bids and activation + previous = chg.Height + } + + delay := nm.getDelayForName(n, chg) + err := n.ApplyChange(chg, delay) + if err != nil { + return nil, errors.Wrap(err, "in apply change") + } + } + + if count <= 0 { + return nil, nil + } + lastChange := changes[count-1] + return n.AdjustTo(lastChange.Height, height, lastChange.Name), nil +} + +func (nm *BaseManager) AppendChange(chg change.Change) { + + nm.changes = append(nm.changes, chg) + + // worth putting in this kind of thing pre-emptively? + // log.Debugf("CHG: %d, %s, %v, %s, %d", chg.Height, chg.Name, chg.Type, chg.ClaimID, chg.Amount) +} + +func collectChildNames(changes []change.Change) { + // we need to determine which children (names that start with the same name) go with which change + // if we have the names in order then we can avoid iterating through all names in the change list + // and we can possibly reuse the previous list. + + // what would happen in the old code: + // spending a claim (which happens before every update) could remove a node from the cached trie + // in which case we would fall back on the data from the previous block (where it obviously wasn't spent). + // It would only delete the node if it had no children, but have even some rare situations + // Where all of the children happen to be deleted first. That's what we must detect here. + + // Algorithm: + // For each non-spend change + // Loop through all the spends before you and add them to your child list if they are your child + + type pair struct { + name string + order int + } + + spends := make([]pair, 0, len(changes)) + for i := range changes { + t := changes[i].Type + if t != change.SpendClaim { + continue + } + spends = append(spends, pair{string(changes[i].Name), i}) + } + sort.Slice(spends, func(i, j int) bool { + return spends[i].name < spends[j].name + }) + + for i := range changes { + t := changes[i].Type + if t == change.SpendClaim || t == change.SpendSupport { + continue + } + a := string(changes[i].Name) + sc := map[string]bool{} + idx := sort.Search(len(spends), func(k int) bool { + return spends[k].name > a + }) + for idx < len(spends) { + b := spends[idx].name + if len(b) <= len(a) || a != b[:len(a)] { + break // since they're ordered alphabetically, we should be able to break out once we're past matches + } + if spends[idx].order < i { + sc[b] = true + } + idx++ + } + changes[i].SpentChildren = sc + } +} + +// to understand the above function, it may be helpful to refer to the slower implementation: +//func collectChildNamesSlow(changes []change.Change) { +// for i := range changes { +// t := changes[i].Type +// if t == change.SpendClaim || t == change.SpendSupport { +// continue +// } +// a := changes[i].Name +// sc := map[string]bool{} +// for j := 0; j < i; j++ { +// t = changes[j].Type +// if t != change.SpendClaim { +// continue +// } +// b := changes[j].Name +// if len(b) >= len(a) && bytes.Equal(a, b[:len(a)]) { +// sc[string(b)] = true +// } +// } +// changes[i].SpentChildren = sc +// } +//} + +func (nm *BaseManager) IncrementHeightTo(height int32, temporary bool) ([][]byte, error) { + + if height <= nm.height { + panic("invalid height") + } + + if height >= param.ActiveParams.MaxRemovalWorkaroundHeight { + // not technically needed until block 884430, but to be true to the arbitrary rollback length... + collectChildNames(nm.changes) + } + + if temporary { + if nm.tempChanges != nil { + return nil, errors.Errorf("expected nil temporary changes") + } + nm.tempChanges = map[string][]change.Change{} + } + names := make([][]byte, 0, len(nm.changes)) + for i := range nm.changes { + names = append(names, nm.changes[i].Name) + if temporary { + name := string(nm.changes[i].Name) + nm.tempChanges[name] = append(nm.tempChanges[name], nm.changes[i]) + } + } + + if !temporary { + if err := nm.repo.AppendChanges(nm.changes); err != nil { // destroys names + return nil, errors.Wrap(err, "in append changes") + } + } + + // Truncate the buffer size to zero. + if len(nm.changes) > 1000 { // TODO: determine a good number here + nm.changes = nil // release the RAM + } else { + nm.changes = nm.changes[:0] + } + nm.height = height + + return names, nil +} + +func (nm *BaseManager) DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) { + if height >= nm.height { + return affectedNames, errors.Errorf("invalid height of %d for %d", height, nm.height) + } + + if nm.tempChanges != nil { + if height != nm.height-1 { + return affectedNames, errors.Errorf("invalid temporary rollback at %d to %d", height, nm.height) + } + for key := range nm.tempChanges { + affectedNames = append(affectedNames, []byte(key)) + } + nm.tempChanges = nil + } else { + for _, name := range affectedNames { + if err := nm.repo.DropChanges(name, height); err != nil { + return affectedNames, errors.Wrap(err, "in drop changes") + } + } + } + nm.height = height + + return affectedNames, nil +} + +func (nm *BaseManager) getDelayForName(n *Node, chg change.Change) int32 { + // Note: we don't consider the active status of BestClaim here on purpose. + // That's because we deactivate and reactivate as part of claim updates. + // However, the final status will be accounted for when we compute the takeover heights; + // claims may get activated early at that point. + + hasBest := n.BestClaim != nil + if hasBest && n.BestClaim.ClaimID == chg.ClaimID { + return 0 + } + if chg.ActiveHeight >= chg.Height { // ActiveHeight is usually unset (aka, zero) + return chg.ActiveHeight - chg.Height + } + if !hasBest { + return 0 + } + + delay := calculateDelay(chg.Height, n.TakenOverAt) + if delay > 0 && nm.aWorkaroundIsNeeded(n, chg) { + if chg.Height >= nm.height { + LogOnce(fmt.Sprintf("Delay workaround applies to %s at %d, ClaimID: %s", + chg.Name, chg.Height, chg.ClaimID)) + } + return 0 + } + return delay +} + +func hasZeroActiveClaims(n *Node) bool { + // this isn't quite the same as having an active best (since that is only updated after all changes are processed) + for _, c := range n.Claims { + if c.Status == Activated { + return false + } + } + return true +} + +// aWorkaroundIsNeeded handles bugs that existed in previous versions +func (nm *BaseManager) aWorkaroundIsNeeded(n *Node, chg change.Change) bool { + + if chg.Type == change.SpendClaim || chg.Type == change.SpendSupport { + return false + } + + if chg.Height >= param.ActiveParams.MaxRemovalWorkaroundHeight { + // TODO: hard fork this out; it's a bug from previous versions: + + // old 17.3 C++ code we're trying to mimic (where empty means no active claims): + // auto it = nodesToAddOrUpdate.find(name); // nodesToAddOrUpdate is the working changes, base is previous block + // auto answer = (it || (it = base->find(name))) && !it->empty() ? nNextHeight - it->nHeightOfLastTakeover : 0; + + return hasZeroActiveClaims(n) && nm.hasChildren(chg.Name, chg.Height, chg.SpentChildren, 2) + } else if len(n.Claims) > 0 { + // NOTE: old code had a bug in it where nodes with no claims but with children would get left in the cache after removal. + // This would cause the getNumBlocksOfContinuousOwnership to return zero (causing incorrect takeover height calc). + w, ok := param.DelayWorkarounds[string(chg.Name)] + if ok { + for _, h := range w { + if chg.Height == h { + return true + } + } + } + } + return false +} + +func calculateDelay(curr, tookOver int32) int32 { + + delay := (curr - tookOver) / param.ActiveParams.ActiveDelayFactor + if delay > param.ActiveParams.MaxActiveDelay { + return param.ActiveParams.MaxActiveDelay + } + + return delay +} + +func (nm *BaseManager) Height() int32 { + return nm.height +} + +func (nm *BaseManager) Close() error { + return errors.WithStack(nm.repo.Close()) +} + +func (nm *BaseManager) hasChildren(name []byte, height int32, spentChildren map[string]bool, required int) bool { + c := map[byte]bool{} + if spentChildren == nil { + spentChildren = map[string]bool{} + } + + err := nm.repo.IterateChildren(name, func(changes []change.Change) bool { + // if the key is unseen, generate a node for it to height + // if that node is active then increase the count + if len(changes) == 0 { + return true + } + if c[changes[0].Name[len(name)]] { // assuming all names here are longer than starter name + return true // we already checked a similar name + } + if spentChildren[string(changes[0].Name)] { + return true // children that are spent in the same block cannot count as active children + } + n, _ := nm.newNodeFromChanges(changes, height) + if n != nil && n.HasActiveBestClaim() { + c[changes[0].Name[len(name)]] = true + if len(c) >= required { + return false + } + } + return true + }) + return err == nil && len(c) >= required +} + +func (nm *BaseManager) IterateNames(predicate func(name []byte) bool) { + nm.repo.IterateAll(predicate) +} + +func (nm *BaseManager) Hash(name []byte) (*chainhash.Hash, int32) { + + n, err := nm.node(name) + if err != nil || n == nil { + return nil, 0 + } + if len(n.Claims) > 0 { + if n.BestClaim != nil && n.BestClaim.Status == Activated { + h := calculateNodeHash(n.BestClaim.OutPoint, n.TakenOverAt) + return h, n.NextUpdate() + } + } + return nil, n.NextUpdate() +} + +func (nm *BaseManager) Flush() error { + return nm.repo.Flush() +} diff --git a/claimtrie/node/manager_test.go b/claimtrie/node/manager_test.go new file mode 100644 index 00000000..c907bb4c --- /dev/null +++ b/claimtrie/node/manager_test.go @@ -0,0 +1,299 @@ +package node + +import ( + "fmt" + "testing" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node/noderepo" + "github.com/lbryio/lbcd/claimtrie/param" + "github.com/lbryio/lbcd/wire" + + "github.com/stretchr/testify/require" +) + +var ( + out1 = NewOutPointFromString("0000000000000000000000000000000000000000000000000000000000000000:1") + out2 = NewOutPointFromString("0000000000000000000000000000000000000000000000000000000000000000:2") + out3 = NewOutPointFromString("0100000000000000000000000000000000000000000000000000000000000000:1") + out4 = NewOutPointFromString("0100000000000000000000000000000000000000000000000000000000000000:2") + name1 = []byte("name1") + name2 = []byte("name2") +) + +// verify that we can round-trip bytes to strings +func TestStringRoundTrip(t *testing.T) { + + r := require.New(t) + + data := [][]byte{ + {97, 98, 99, 0, 100, 255}, + {0xc3, 0x28}, + {0xa0, 0xa1}, + {0xe2, 0x28, 0xa1}, + {0xf0, 0x28, 0x8c, 0x28}, + } + for _, d := range data { + s := string(d) + r.Equal(s, fmt.Sprintf("%s", d)) // nolint + d2 := []byte(s) + r.Equal(len(d), len(s)) + r.Equal(d, d2) + } +} + +func TestSimpleAddClaim(t *testing.T) { + + r := require.New(t) + + param.SetNetwork(wire.TestNet) + repo, err := noderepo.NewPebble(t.TempDir()) + r.NoError(err) + + m, err := NewBaseManager(repo) + r.NoError(err) + defer m.Close() + + _, err = m.IncrementHeightTo(10, false) + r.NoError(err) + + chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(11, false) + r.NoError(err) + + chg = chg.SetName(name2).SetOutPoint(out2).SetHeight(12) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(12, false) + r.NoError(err) + + n1, err := m.node(name1) + r.NoError(err) + r.Equal(1, len(n1.Claims)) + r.NotNil(n1.Claims.find(byOut(*out1))) + + n2, err := m.node(name2) + r.NoError(err) + r.Equal(1, len(n2.Claims)) + r.NotNil(n2.Claims.find(byOut(*out2))) + + _, err = m.DecrementHeightTo([][]byte{name2}, 11) + r.NoError(err) + n2, err = m.node(name2) + r.NoError(err) + r.Nil(n2) + + _, err = m.DecrementHeightTo([][]byte{name1}, 1) + r.NoError(err) + n2, err = m.node(name1) + r.NoError(err) + r.Nil(n2) +} + +func TestSupportAmounts(t *testing.T) { + + r := require.New(t) + + param.SetNetwork(wire.TestNet) + repo, err := noderepo.NewPebble(t.TempDir()) + r.NoError(err) + + m, err := NewBaseManager(repo) + r.NoError(err) + defer m.Close() + + _, err = m.IncrementHeightTo(10, false) + r.NoError(err) + + chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11).SetAmount(3) + chg.ClaimID = change.NewClaimID(*out1) + m.AppendChange(chg) + + chg = change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out2).SetHeight(11).SetAmount(4) + chg.ClaimID = change.NewClaimID(*out2) + m.AppendChange(chg) + + _, err = m.IncrementHeightTo(11, false) + r.NoError(err) + + chg = change.NewChange(change.AddSupport).SetName(name1).SetOutPoint(out3).SetHeight(12).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out1) + m.AppendChange(chg) + + chg = change.NewChange(change.AddSupport).SetName(name1).SetOutPoint(out4).SetHeight(12).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out2) + m.AppendChange(chg) + + chg = change.NewChange(change.SpendSupport).SetName(name1).SetOutPoint(out4).SetHeight(12).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out2) + m.AppendChange(chg) + + _, err = m.IncrementHeightTo(20, false) + r.NoError(err) + + n1, err := m.node(name1) + r.NoError(err) + r.Equal(2, len(n1.Claims)) + r.Equal(int64(5), n1.BestClaim.Amount+n1.SupportSums[n1.BestClaim.ClaimID.Key()]) +} + +func TestNodeSort(t *testing.T) { + + r := require.New(t) + + param.ActiveParams.ExtendedClaimExpirationTime = 1000 + + r.True(OutPointLess(*out1, *out2)) + r.True(OutPointLess(*out1, *out3)) + + n := New() + n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{1}}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out2, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{2}}) + n.handleExpiredAndActivated(3) + n.updateTakeoverHeight(3, []byte{}, true) + + r.Equal(n.Claims.find(byOut(*out1)).OutPoint.String(), n.BestClaim.OutPoint.String()) + + n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{3}}) + n.handleExpiredAndActivated(3) + n.updateTakeoverHeight(3, []byte{}, true) + r.Equal(n.Claims.find(byOut(*out1)).OutPoint.String(), n.BestClaim.OutPoint.String()) +} + +func TestClaimSort(t *testing.T) { + + r := require.New(t) + + param.ActiveParams.ExtendedClaimExpirationTime = 1000 + + n := New() + n.Claims = append(n.Claims, &Claim{OutPoint: *out2, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{2}, Status: Activated}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 3, Amount: 2, ClaimID: change.ClaimID{3}, Status: Activated}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 4, Amount: 2, ClaimID: change.ClaimID{4}, Status: Activated}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 3, Amount: 4, ClaimID: change.ClaimID{1}, Status: Activated}) + n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 1, Amount: 9, ClaimID: change.ClaimID{5}, Status: Accepted}) + n.SortClaimsByBid() + + r.Equal(int64(4), n.Claims[0].Amount) + r.Equal(int64(3), n.Claims[1].Amount) + r.Equal(int64(2), n.Claims[2].Amount) + r.Equal(int32(4), n.Claims[3].AcceptedAt) +} + +func TestHasChildren(t *testing.T) { + r := require.New(t) + + param.SetNetwork(wire.TestNet) + repo, err := noderepo.NewPebble(t.TempDir()) + r.NoError(err) + + m, err := NewBaseManager(repo) + r.NoError(err) + defer m.Close() + + chg := change.NewChange(change.AddClaim).SetName([]byte("a")).SetOutPoint(out1).SetHeight(1).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out1) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(1, false) + r.NoError(err) + r.False(m.hasChildren([]byte("a"), 1, nil, 1)) + + chg = change.NewChange(change.AddClaim).SetName([]byte("ab")).SetOutPoint(out2).SetHeight(2).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out2) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(2, false) + r.NoError(err) + r.False(m.hasChildren([]byte("a"), 2, nil, 2)) + r.True(m.hasChildren([]byte("a"), 2, nil, 1)) + + chg = change.NewChange(change.AddClaim).SetName([]byte("abc")).SetOutPoint(out3).SetHeight(3).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out3) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(3, false) + r.NoError(err) + r.False(m.hasChildren([]byte("a"), 3, nil, 2)) + + chg = change.NewChange(change.AddClaim).SetName([]byte("ac")).SetOutPoint(out1).SetHeight(4).SetAmount(2) + chg.ClaimID = change.NewClaimID(*out4) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(4, false) + r.NoError(err) + r.True(m.hasChildren([]byte("a"), 4, nil, 2)) +} + +func TestCollectChildren(t *testing.T) { + r := require.New(t) + + c1 := change.Change{Name: []byte("ba"), Type: change.SpendClaim} + c2 := change.Change{Name: []byte("ba"), Type: change.UpdateClaim} + c3 := change.Change{Name: []byte("ac"), Type: change.SpendClaim} + c4 := change.Change{Name: []byte("ac"), Type: change.UpdateClaim} + c5 := change.Change{Name: []byte("a"), Type: change.SpendClaim} + c6 := change.Change{Name: []byte("a"), Type: change.UpdateClaim} + c7 := change.Change{Name: []byte("ab"), Type: change.SpendClaim} + c8 := change.Change{Name: []byte("ab"), Type: change.UpdateClaim} + c := []change.Change{c1, c2, c3, c4, c5, c6, c7, c8} + + collectChildNames(c) + + r.Empty(c[0].SpentChildren) + r.Empty(c[2].SpentChildren) + r.Empty(c[4].SpentChildren) + r.Empty(c[6].SpentChildren) + + r.Len(c[1].SpentChildren, 0) + r.Len(c[3].SpentChildren, 0) + r.Len(c[5].SpentChildren, 1) + r.True(c[5].SpentChildren["ac"]) + + r.Len(c[7].SpentChildren, 0) +} + +func TestTemporaryAddClaim(t *testing.T) { + + r := require.New(t) + + param.SetNetwork(wire.TestNet) + repo, err := noderepo.NewPebble(t.TempDir()) + r.NoError(err) + + m, err := NewBaseManager(repo) + r.NoError(err) + defer m.Close() + + _, err = m.IncrementHeightTo(10, false) + r.NoError(err) + + chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(11, false) + r.NoError(err) + + chg = chg.SetName(name2).SetOutPoint(out2).SetHeight(12) + m.AppendChange(chg) + _, err = m.IncrementHeightTo(12, true) + r.NoError(err) + + n1, err := m.node(name1) + r.NoError(err) + r.Equal(1, len(n1.Claims)) + r.NotNil(n1.Claims.find(byOut(*out1))) + + n2, err := m.node(name2) + r.NoError(err) + r.Equal(1, len(n2.Claims)) + r.NotNil(n2.Claims.find(byOut(*out2))) + + names, err := m.DecrementHeightTo([][]byte{name2}, 11) + r.Equal(names[0], name2) + r.NoError(err) + n2, err = m.node(name2) + r.NoError(err) + r.Nil(n2) + + _, err = m.DecrementHeightTo([][]byte{name1}, 1) + r.NoError(err) + n2, err = m.node(name1) + r.NoError(err) + r.Nil(n2) +} diff --git a/claimtrie/node/node.go b/claimtrie/node/node.go new file mode 100644 index 00000000..fe6db947 --- /dev/null +++ b/claimtrie/node/node.go @@ -0,0 +1,342 @@ +package node + +import ( + "fmt" + "math" + "sort" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/param" +) + +type Node struct { + BestClaim *Claim // The claim that has most effective amount at the current height. + TakenOverAt int32 // The height at when the current BestClaim took over. + Claims ClaimList // List of all Claims. + Supports ClaimList // List of all Supports, including orphaned ones. + SupportSums map[string]int64 +} + +// New returns a new node. +func New() *Node { + return &Node{SupportSums: map[string]int64{}} +} + +func (n *Node) HasActiveBestClaim() bool { + return n.BestClaim != nil && n.BestClaim.Status == Activated +} + +func (n *Node) ApplyChange(chg change.Change, delay int32) error { + + visibleAt := chg.VisibleHeight + if visibleAt <= 0 { + visibleAt = chg.Height + } + + switch chg.Type { + case change.AddClaim: + c := &Claim{ + OutPoint: chg.OutPoint, + Amount: chg.Amount, + ClaimID: chg.ClaimID, + // CreatedAt: chg.Height, + AcceptedAt: chg.Height, + ActiveAt: chg.Height + delay, + VisibleAt: visibleAt, + Sequence: int32(len(n.Claims)), + } + // old := n.Claims.find(byOut(chg.OutPoint)) // TODO: remove this after proving ResetHeight works + // if old != nil { + // return errors.Errorf("CONFLICT WITH EXISTING TXO! Name: %s, Height: %d", chg.Name, chg.Height) + // } + n.Claims = append(n.Claims, c) + + case change.SpendClaim: + c := n.Claims.find(byOut(chg.OutPoint)) + if c != nil { + c.setStatus(Deactivated) + } else { + LogOnce(fmt.Sprintf("Spending claim but missing existing claim with TXO %s, "+ + "Name: %s, ID: %s", chg.OutPoint, chg.Name, chg.ClaimID)) + } + // apparently it's legit to be absent in the map: + // 'two' at 481100, 36a719a156a1df178531f3c712b8b37f8e7cc3b36eea532df961229d936272a1:0 + + case change.UpdateClaim: + // Find and remove the claim, which has just been spent. + c := n.Claims.find(byID(chg.ClaimID)) + if c != nil && c.Status == Deactivated { + + // Keep its ID, which was generated from the spent claim. + // And update the rest of properties. + c.setOutPoint(chg.OutPoint).SetAmt(chg.Amount) + c.setStatus(Accepted) // it was Deactivated in the spend (but we only activate at the end of the block) + // that's because the old code would put all insertions into the "queue" that was processed at block's end + + // This forces us to be newer, which may in an unintentional takeover if there's an older one. + // TODO: reconsider these updates in future hard forks. + c.setAccepted(chg.Height) + c.setActiveAt(chg.Height + delay) + + } else { + LogOnce(fmt.Sprintf("Updating claim but missing existing claim with ID %s", chg.ClaimID)) + } + case change.AddSupport: + n.Supports = append(n.Supports, &Claim{ + OutPoint: chg.OutPoint, + Amount: chg.Amount, + ClaimID: chg.ClaimID, + AcceptedAt: chg.Height, + ActiveAt: chg.Height + delay, + VisibleAt: visibleAt, + }) + + case change.SpendSupport: + s := n.Supports.find(byOut(chg.OutPoint)) + if s != nil { + if s.Status == Activated { + n.SupportSums[s.ClaimID.Key()] -= s.Amount + } + // TODO: we could do without this Deactivated flag if we set expiration instead + // That would eliminate the above Sum update. + // We would also need to track the update situation, though, but that could be done locally. + s.setStatus(Deactivated) + } else { + LogOnce(fmt.Sprintf("Spending support but missing existing claim with TXO %s, "+ + "Name: %s, ID: %s", chg.OutPoint, chg.Name, chg.ClaimID)) + } + } + return nil +} + +// AdjustTo activates claims and computes takeovers until it reaches the specified height. +func (n *Node) AdjustTo(height, maxHeight int32, name []byte) *Node { + changed := n.handleExpiredAndActivated(height) > 0 + n.updateTakeoverHeight(height, name, changed) + if maxHeight > height { + for h := n.NextUpdate(); h <= maxHeight; h = n.NextUpdate() { + changed = n.handleExpiredAndActivated(h) > 0 + n.updateTakeoverHeight(h, name, changed) + height = h + } + } + return n +} + +func (n *Node) updateTakeoverHeight(height int32, name []byte, refindBest bool) { + + candidate := n.BestClaim + if refindBest { + candidate = n.findBestClaim() // so expensive... + } + + hasCandidate := candidate != nil + hasCurrentWinner := n.HasActiveBestClaim() + + takeoverHappening := !hasCandidate || !hasCurrentWinner || candidate.ClaimID != n.BestClaim.ClaimID + + if takeoverHappening { + if n.activateAllClaims(height) > 0 { + candidate = n.findBestClaim() + } + } + + if !takeoverHappening && height < param.ActiveParams.MaxRemovalWorkaroundHeight { + // This is a super ugly hack to work around bug in old code. + // The bug: un/support a name then update it. This will cause its takeover height to be reset to current. + // This is because the old code would add to the cache without setting block originals when dealing in supports. + _, takeoverHappening = param.TakeoverWorkarounds[fmt.Sprintf("%d_%s", height, name)] // TODO: ditch the fmt call + } + + if takeoverHappening { + n.TakenOverAt = height + n.BestClaim = candidate + } +} + +func (n *Node) handleExpiredAndActivated(height int32) int { + + ot := param.ActiveParams.OriginalClaimExpirationTime + et := param.ActiveParams.ExtendedClaimExpirationTime + fk := param.ActiveParams.ExtendedClaimExpirationForkHeight + expiresAt := func(c *Claim) int32 { + if c.AcceptedAt+ot > fk { + return c.AcceptedAt + et + } + return c.AcceptedAt + ot + } + + changes := 0 + update := func(items ClaimList, sums map[string]int64) ClaimList { + for i := 0; i < len(items); i++ { + c := items[i] + if c.Status == Accepted && c.ActiveAt <= height && c.VisibleAt <= height { + c.setStatus(Activated) + changes++ + if sums != nil { + sums[c.ClaimID.Key()] += c.Amount + } + } + if c.Status == Deactivated || expiresAt(c) <= height { + if i < len(items)-1 { + items[i] = items[len(items)-1] + i-- + } + items = items[:len(items)-1] + changes++ + if sums != nil && c.Status != Deactivated { + sums[c.ClaimID.Key()] -= c.Amount + } + } + } + return items + } + n.Claims = update(n.Claims, nil) + n.Supports = update(n.Supports, n.SupportSums) + return changes +} + +// NextUpdate returns the nearest height in the future that the node should +// be refreshed due to changes of claims or supports. +func (n Node) NextUpdate() int32 { + + ot := param.ActiveParams.OriginalClaimExpirationTime + et := param.ActiveParams.ExtendedClaimExpirationTime + fk := param.ActiveParams.ExtendedClaimExpirationForkHeight + expiresAt := func(c *Claim) int32 { + if c.AcceptedAt+ot > fk { + return c.AcceptedAt + et + } + return c.AcceptedAt + ot + } + + next := int32(math.MaxInt32) + + for _, c := range n.Claims { + ea := expiresAt(c) + if ea < next { + next = ea + } + // if we're not active, we need to go to activeAt unless we're still invisible there + if c.Status == Accepted { + min := c.ActiveAt + if c.VisibleAt > min { + min = c.VisibleAt + } + if min < next { + next = min + } + } + } + + for _, s := range n.Supports { + es := expiresAt(s) + if es < next { + next = es + } + if s.Status == Accepted { + min := s.ActiveAt + if s.VisibleAt > min { + min = s.VisibleAt + } + if min < next { + next = min + } + } + } + + return next +} + +func (n Node) findBestClaim() *Claim { + + // WARNING: this method is called billions of times. + // if we just had some easy way to know that our best claim was the first one in the list... + // or it may be faster to cache effective amount in the db at some point. + + var best *Claim + var bestAmount int64 + for _, candidate := range n.Claims { + + // not using switch here for performance reasons + if candidate.Status != Activated { + continue + } + + if best == nil { + best = candidate + continue + } + + candidateAmount := candidate.Amount + n.SupportSums[candidate.ClaimID.Key()] + if bestAmount <= 0 { + bestAmount = best.Amount + n.SupportSums[best.ClaimID.Key()] + } + + switch { + case candidateAmount > bestAmount: + best = candidate + bestAmount = candidateAmount + case candidateAmount < bestAmount: + continue + case candidate.AcceptedAt < best.AcceptedAt: + best = candidate + bestAmount = candidateAmount + case candidate.AcceptedAt > best.AcceptedAt: + continue + case OutPointLess(candidate.OutPoint, best.OutPoint): + best = candidate + bestAmount = candidateAmount + } + } + + return best +} + +func (n *Node) activateAllClaims(height int32) int { + count := 0 + for _, c := range n.Claims { + if c.Status == Accepted && c.ActiveAt > height && c.VisibleAt <= height { + c.setActiveAt(height) // don't necessarily need to change this number? + c.setStatus(Activated) + count++ + } + } + + for _, s := range n.Supports { + if s.Status == Accepted && s.ActiveAt > height && s.VisibleAt <= height { + s.setActiveAt(height) // don't necessarily need to change this number? + s.setStatus(Activated) + count++ + n.SupportSums[s.ClaimID.Key()] += s.Amount + } + } + return count +} + +func (n *Node) SortClaimsByBid() { + + // purposefully sorting by descent via func parameter order: + sort.Slice(n.Claims, func(j, i int) bool { + // SupportSums only include active values; do the same for amount. No active claim will have a zero amount + iAmount := n.SupportSums[n.Claims[i].ClaimID.Key()] + if n.Claims[i].Status == Activated { + iAmount += n.Claims[i].Amount + } + jAmount := n.SupportSums[n.Claims[j].ClaimID.Key()] + if n.Claims[j].Status == Activated { + jAmount += n.Claims[j].Amount + } + switch { + case iAmount < jAmount: + return true + case iAmount > jAmount: + return false + case n.Claims[i].AcceptedAt > n.Claims[j].AcceptedAt: + return true + case n.Claims[i].AcceptedAt < n.Claims[j].AcceptedAt: + return false + } + return OutPointLess(n.Claims[j].OutPoint, n.Claims[i].OutPoint) + }) +} diff --git a/claimtrie/node/noderepo/noderepo_test.go b/claimtrie/node/noderepo/noderepo_test.go new file mode 100644 index 00000000..fb0a9764 --- /dev/null +++ b/claimtrie/node/noderepo/noderepo_test.go @@ -0,0 +1,188 @@ +package noderepo + +import ( + "testing" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/node" + + "github.com/stretchr/testify/require" +) + +var ( + out1 = node.NewOutPointFromString("0000000000000000000000000000000000000000000000000000000000000000:1") + testNodeName1 = []byte("name1") +) + +func TestPebble(t *testing.T) { + + r := require.New(t) + + repo, err := NewPebble(t.TempDir()) + r.NoError(err) + defer func() { + err := repo.Close() + r.NoError(err) + }() + + cleanup := func() { + lowerBound := testNodeName1 + upperBound := append(testNodeName1, byte(0)) + err := repo.db.DeleteRange(lowerBound, upperBound, nil) + r.NoError(err) + } + + testNodeRepo(t, repo, func() {}, cleanup) +} + +func testNodeRepo(t *testing.T, repo node.Repo, setup, cleanup func()) { + + r := require.New(t) + + chg := change.NewChange(change.AddClaim).SetName(testNodeName1).SetOutPoint(out1) + + testcases := []struct { + name string + height int32 + changes []change.Change + expected []change.Change + }{ + { + "test 1", + 1, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1)}, + }, + { + "test 2", + 2, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1)}, + }, + { + "test 3", + 3, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1), chg.SetHeight(3)}, + }, + { + "test 4", + 4, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1), chg.SetHeight(3)}, + }, + { + "test 5", + 5, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + }, + { + "test 6", + 6, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + []change.Change{chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + }, + } + + for _, tt := range testcases { + + setup() + + err := repo.AppendChanges(tt.changes) + r.NoError(err) + + changes, err := repo.LoadChanges(testNodeName1) + r.NoError(err) + r.Equalf(tt.expected, changes[:len(tt.expected)], tt.name) + + cleanup() + } + + testcases2 := []struct { + name string + height int32 + changes [][]change.Change + expected []change.Change + }{ + { + "Save in 2 batches, and load up to 1", + 1, + [][]change.Change{ + {chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + {chg.SetHeight(6), chg.SetHeight(8), chg.SetHeight(9)}, + }, + []change.Change{chg.SetHeight(1)}, + }, + { + "Save in 2 batches, and load up to 9", + 9, + [][]change.Change{ + {chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5)}, + {chg.SetHeight(6), chg.SetHeight(8), chg.SetHeight(9)}, + }, + []change.Change{ + chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5), + chg.SetHeight(6), chg.SetHeight(8), chg.SetHeight(9), + }, + }, + { + "Save in 3 batches, and load up to 8", + 8, + [][]change.Change{ + {chg.SetHeight(1), chg.SetHeight(3)}, + {chg.SetHeight(5)}, + {chg.SetHeight(6), chg.SetHeight(8), chg.SetHeight(9)}, + }, + []change.Change{ + chg.SetHeight(1), chg.SetHeight(3), chg.SetHeight(5), + chg.SetHeight(6), chg.SetHeight(8), + }, + }, + } + + for _, tt := range testcases2 { + + setup() + + for _, changes := range tt.changes { + err := repo.AppendChanges(changes) + r.NoError(err) + } + + changes, err := repo.LoadChanges(testNodeName1) + r.NoError(err) + r.Equalf(tt.expected, changes[:len(tt.expected)], tt.name) + + cleanup() + } +} + +func TestIterator(t *testing.T) { + + r := require.New(t) + + repo, err := NewPebble(t.TempDir()) + r.NoError(err) + defer func() { + err := repo.Close() + r.NoError(err) + }() + + creation := []change.Change{ + {Name: []byte("test\x00"), Height: 5}, + {Name: []byte("test\x00\x00"), Height: 5}, + {Name: []byte("test\x00b"), Height: 5}, + {Name: []byte("test\x00\xFF"), Height: 5}, + {Name: []byte("testa"), Height: 5}, + } + err = repo.AppendChanges(creation) + r.NoError(err) + + i := 0 + repo.IterateChildren([]byte{}, func(changes []change.Change) bool { + r.Equal(creation[i], changes[0]) + i++ + return true + }) +} diff --git a/claimtrie/node/noderepo/pebble.go b/claimtrie/node/noderepo/pebble.go new file mode 100644 index 00000000..cb5d25e4 --- /dev/null +++ b/claimtrie/node/noderepo/pebble.go @@ -0,0 +1,177 @@ +package noderepo + +import ( + "bytes" + "sort" + + "github.com/cockroachdb/pebble" + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/pkg/errors" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + db, err := pebble.Open(path, &pebble.Options{Cache: pebble.NewCache(64 << 20), BytesPerSync: 8 << 20, MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "unable to open %s", path) +} + +func (repo *Pebble) AppendChanges(changes []change.Change) error { + + batch := repo.db.NewBatch() + defer batch.Close() + + buffer := bytes.NewBuffer(nil) + + for _, chg := range changes { + buffer.Reset() + err := chg.Marshal(buffer) + if err != nil { + return errors.Wrap(err, "in marshaller") + } + + err = batch.Merge(chg.Name, buffer.Bytes(), pebble.NoSync) + if err != nil { + return errors.Wrap(err, "in merge") + } + } + return errors.Wrap(batch.Commit(pebble.NoSync), "in commit") +} + +func (repo *Pebble) LoadChanges(name []byte) ([]change.Change, error) { + + data, closer, err := repo.db.Get(name) + if err != nil && err != pebble.ErrNotFound { + return nil, errors.Wrapf(err, "in get %s", name) // does returning a name in an error expose too much? + } + if closer != nil { + defer closer.Close() + } + + return unmarshalChanges(name, data) +} + +func unmarshalChanges(name, data []byte) ([]change.Change, error) { + // data is 84bytes+ per change + changes := make([]change.Change, 0, len(data)/84+1) // average is 5.1 changes + + buffer := bytes.NewBuffer(data) + sortNeeded := false + for buffer.Len() > 0 { + var chg change.Change + err := chg.Unmarshal(buffer) + if err != nil { + return nil, errors.Wrap(err, "in decode") + } + chg.Name = name + if len(changes) > 0 && chg.Height < changes[len(changes)-1].Height { + sortNeeded = true // alternately: sortNeeded || chg.Height != chg.VisibleHeight + } + changes = append(changes, chg) + } + + if sortNeeded { + // this was required for the normalization stuff: + sort.SliceStable(changes, func(i, j int) bool { + return changes[i].Height < changes[j].Height + }) + } + return changes, nil +} + +func (repo *Pebble) DropChanges(name []byte, finalHeight int32) error { + changes, err := repo.LoadChanges(name) + if err != nil { + return errors.Wrapf(err, "in load changes for %s", name) + } + buffer := bytes.NewBuffer(nil) + for i := 0; i < len(changes); i++ { // assuming changes are ordered by height + if changes[i].Height > finalHeight { + break + } + if changes[i].VisibleHeight > finalHeight { // created after this height has to be skipped + continue + } + // having to sort the changes really messes up performance here. It would be better to not remarshal + err := changes[i].Marshal(buffer) + if err != nil { + return errors.Wrap(err, "in marshaller") + } + } + + // making a performance assumption that DropChanges won't happen often: + err = repo.db.Set(name, buffer.Bytes(), pebble.NoSync) + return errors.Wrapf(err, "in set at %s", name) +} + +func (repo *Pebble) IterateChildren(name []byte, f func(changes []change.Change) bool) error { + start := make([]byte, len(name)+1) // zeros that last byte; need a constant len for stack alloc? + copy(start, name) + + end := make([]byte, len(name)) // max name length is 255 + copy(end, name) + validEnd := false + for i := len(name) - 1; i >= 0; i-- { + end[i]++ + if end[i] != 0 { + validEnd = true + break + } + } + if !validEnd { + end = nil // uh, we think this means run to the end of the table + } + + prefixIterOptions := &pebble.IterOptions{ + LowerBound: start, + UpperBound: end, + } + + iter := repo.db.NewIter(prefixIterOptions) + defer iter.Close() + + for iter.First(); iter.Valid(); iter.Next() { + // NOTE! iter.Key() is ephemeral! + changes, err := unmarshalChanges(iter.Key(), iter.Value()) + if err != nil { + return errors.Wrapf(err, "from unmarshaller at %s", iter.Key()) + } + if !f(changes) { + break + } + } + return nil +} + +func (repo *Pebble) IterateAll(predicate func(name []byte) bool) { + iter := repo.db.NewIter(nil) + defer iter.Close() + + for iter.First(); iter.Valid(); iter.Next() { + if !predicate(iter.Key()) { + break + } + } +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/node/normalizing_manager.go b/claimtrie/node/normalizing_manager.go new file mode 100644 index 00000000..2f6c4cfe --- /dev/null +++ b/claimtrie/node/normalizing_manager.go @@ -0,0 +1,114 @@ +package node + +import ( + "bytes" + + "github.com/lbryio/lbcd/claimtrie/change" + "github.com/lbryio/lbcd/claimtrie/normalization" + "github.com/lbryio/lbcd/claimtrie/param" +) + +type NormalizingManager struct { // implements Manager + Manager + normalizedAt int32 +} + +func NewNormalizingManager(baseManager Manager) Manager { + log.Info(normalization.NormalizeTitle) + return &NormalizingManager{ + Manager: baseManager, + normalizedAt: -1, + } +} + +func (nm *NormalizingManager) AppendChange(chg change.Change) { + chg.Name = normalization.NormalizeIfNecessary(chg.Name, chg.Height) + nm.Manager.AppendChange(chg) +} + +func (nm *NormalizingManager) IncrementHeightTo(height int32, temporary bool) ([][]byte, error) { + nm.addNormalizationForkChangesIfNecessary(height) + return nm.Manager.IncrementHeightTo(height, temporary) +} + +func (nm *NormalizingManager) DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) { + if nm.normalizedAt > height { + nm.normalizedAt = -1 + } + return nm.Manager.DecrementHeightTo(affectedNames, height) +} + +func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int32) { + + if nm.Manager.Height()+1 != height { + // initialization phase + if height >= param.ActiveParams.NormalizedNameForkHeight { + nm.normalizedAt = param.ActiveParams.NormalizedNameForkHeight // eh, we don't really know that it happened there + } + } + + if nm.normalizedAt >= 0 || height != param.ActiveParams.NormalizedNameForkHeight { + return + } + nm.normalizedAt = height + log.Info("Generating necessary changes for the normalization fork...") + + // the original code had an unfortunate bug where many unnecessary takeovers + // were triggered at the normalization fork + predicate := func(name []byte) bool { + norm := normalization.Normalize(name) + eq := bytes.Equal(name, norm) + if eq { + return true + } + + clone := make([]byte, len(name)) + copy(clone, name) // iteration name buffer is reused on future loops + + // by loading changes for norm here, you can determine if there will be a conflict + + n, err := nm.Manager.NodeAt(nm.Manager.Height(), clone) + if err != nil || n == nil { + return true + } + for _, c := range n.Claims { + nm.Manager.AppendChange(change.Change{ + Type: change.AddClaim, + Name: norm, + Height: c.AcceptedAt, + OutPoint: c.OutPoint, + ClaimID: c.ClaimID, + Amount: c.Amount, + ActiveHeight: c.ActiveAt, // necessary to match the old hash + VisibleHeight: height, // necessary to match the old hash; it would have been much better without + }) + nm.Manager.AppendChange(change.Change{ + Type: change.SpendClaim, + Name: clone, + Height: height, + OutPoint: c.OutPoint, + }) + } + for _, c := range n.Supports { + nm.Manager.AppendChange(change.Change{ + Type: change.AddSupport, + Name: norm, + Height: c.AcceptedAt, + OutPoint: c.OutPoint, + ClaimID: c.ClaimID, + Amount: c.Amount, + ActiveHeight: c.ActiveAt, + VisibleHeight: height, + }) + nm.Manager.AppendChange(change.Change{ + Type: change.SpendSupport, + Name: clone, + Height: height, + OutPoint: c.OutPoint, + }) + } + + return true + } + nm.Manager.IterateNames(predicate) +} diff --git a/claimtrie/node/repo.go b/claimtrie/node/repo.go new file mode 100644 index 00000000..4aaa65e8 --- /dev/null +++ b/claimtrie/node/repo.go @@ -0,0 +1,31 @@ +package node + +import ( + "github.com/lbryio/lbcd/claimtrie/change" +) + +// Repo defines APIs for Node to access persistence layer. +type Repo interface { + // AppendChanges saves changes into the repo. + // The changes can belong to different nodes, but the chronological + // order must be preserved for the same node. + AppendChanges(changes []change.Change) error + + // LoadChanges loads changes of a node up to (includes) the specified height. + // If no changes found, both returned slice and error will be nil. + LoadChanges(name []byte) ([]change.Change, error) + + DropChanges(name []byte, finalHeight int32) error + + // Close closes the repo. + Close() error + + // IterateChildren returns change sets for each of name.+ + // Return false on f to stop the iteration. + IterateChildren(name []byte, f func(changes []change.Change) bool) error + + // IterateAll iterates keys until the predicate function returns false + IterateAll(predicate func(name []byte) bool) + + Flush() error +} diff --git a/claimtrie/normalization/CaseFolding_v11.txt b/claimtrie/normalization/CaseFolding_v11.txt new file mode 100644 index 00000000..cce350f4 --- /dev/null +++ b/claimtrie/normalization/CaseFolding_v11.txt @@ -0,0 +1,1574 @@ +# CaseFolding-11.0.0.txt +# Date: 2018-01-31, 08:20:09 GMT +# © 2018 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Case Folding Properties +# +# This file is a supplement to the UnicodeData file. +# It provides a case folding mapping generated from the Unicode Character Database. +# If all characters are mapped according to the full mapping below, then +# case differences (according to UnicodeData.txt and SpecialCasing.txt) +# are eliminated. +# +# The data supports both implementations that require simple case foldings +# (where string lengths don't change), and implementations that allow full case folding +# (where string lengths may grow). Note that where they can be supported, the +# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match. +# +# All code points not listed in this file map to themselves. +# +# NOTE: case folding does not preserve normalization formats! +# +# For information on case folding, including how to have case folding +# preserve normalization formats, see Section 3.13 Default Case Algorithms in +# The Unicode Standard. +# +# ================================================================================ +# Format +# ================================================================================ +# The entries in this file are in the following machine-readable format: +# +# ; ; ; # +# +# The status field is: +# C: common case folding, common mappings shared by both simple and full mappings. +# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces. +# S: simple case folding, mappings to single characters where different from F. +# T: special case for uppercase I and dotted uppercase I +# - For non-Turkic languages, this mapping is normally not used. +# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters. +# Note that the Turkic mappings do not maintain canonical equivalence without additional processing. +# See the discussions of case mapping in the Unicode Standard for more information. +# +# Usage: +# A. To do a simple case folding, use the mappings with status C + S. +# B. To do a full case folding, use the mappings with status C + F. +# +# The mappings with status T can be used or omitted depending on the desired case-folding +# behavior. (The default option is to exclude them.) +# +# ================================================================= + +# Property: Case_Folding + +# All code points not explicitly listed for Case_Folding +# have the value C for the status field, and the code point itself for the mapping field. + +# ================================================================= +0041; C; 0061; # LATIN CAPITAL LETTER A +0042; C; 0062; # LATIN CAPITAL LETTER B +0043; C; 0063; # LATIN CAPITAL LETTER C +0044; C; 0064; # LATIN CAPITAL LETTER D +0045; C; 0065; # LATIN CAPITAL LETTER E +0046; C; 0066; # LATIN CAPITAL LETTER F +0047; C; 0067; # LATIN CAPITAL LETTER G +0048; C; 0068; # LATIN CAPITAL LETTER H +0049; C; 0069; # LATIN CAPITAL LETTER I +0049; T; 0131; # LATIN CAPITAL LETTER I +004A; C; 006A; # LATIN CAPITAL LETTER J +004B; C; 006B; # LATIN CAPITAL LETTER K +004C; C; 006C; # LATIN CAPITAL LETTER L +004D; C; 006D; # LATIN CAPITAL LETTER M +004E; C; 006E; # LATIN CAPITAL LETTER N +004F; C; 006F; # LATIN CAPITAL LETTER O +0050; C; 0070; # LATIN CAPITAL LETTER P +0051; C; 0071; # LATIN CAPITAL LETTER Q +0052; C; 0072; # LATIN CAPITAL LETTER R +0053; C; 0073; # LATIN CAPITAL LETTER S +0054; C; 0074; # LATIN CAPITAL LETTER T +0055; C; 0075; # LATIN CAPITAL LETTER U +0056; C; 0076; # LATIN CAPITAL LETTER V +0057; C; 0077; # LATIN CAPITAL LETTER W +0058; C; 0078; # LATIN CAPITAL LETTER X +0059; C; 0079; # LATIN CAPITAL LETTER Y +005A; C; 007A; # LATIN CAPITAL LETTER Z +00B5; C; 03BC; # MICRO SIGN +00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE +00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE +00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE +00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS +00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE +00C6; C; 00E6; # LATIN CAPITAL LETTER AE +00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA +00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE +00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE +00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS +00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE +00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE +00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS +00D0; C; 00F0; # LATIN CAPITAL LETTER ETH +00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE +00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE +00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE +00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE +00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS +00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE +00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE +00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE +00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS +00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE +00DE; C; 00FE; # LATIN CAPITAL LETTER THORN +00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S +0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON +0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE +0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK +0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE +0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE +010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON +010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON +0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE +0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON +0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE +0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE +0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK +011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON +011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE +0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE +0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA +0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE +0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE +012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON +012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE +012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK +0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0132; C; 0133; # LATIN CAPITAL LIGATURE IJ +0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA +0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE +013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA +013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON +013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT +0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE +0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE +0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA +0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON +0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +014A; C; 014B; # LATIN CAPITAL LETTER ENG +014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON +014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE +0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0152; C; 0153; # LATIN CAPITAL LIGATURE OE +0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE +0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA +0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON +015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE +015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA +0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON +0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA +0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON +0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE +0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE +016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON +016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE +016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE +0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK +0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS +0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE +017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE +017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON +017F; C; 0073; # LATIN SMALL LETTER LONG S +0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK +0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR +0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX +0186; C; 0254; # LATIN CAPITAL LETTER OPEN O +0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK +0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D +018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK +018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR +018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E +018F; C; 0259; # LATIN CAPITAL LETTER SCHWA +0190; C; 025B; # LATIN CAPITAL LETTER OPEN E +0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK +0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK +0194; C; 0263; # LATIN CAPITAL LETTER GAMMA +0196; C; 0269; # LATIN CAPITAL LETTER IOTA +0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE +0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK +019C; C; 026F; # LATIN CAPITAL LETTER TURNED M +019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK +019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE +01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN +01A2; C; 01A3; # LATIN CAPITAL LETTER OI +01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK +01A6; C; 0280; # LATIN LETTER YR +01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO +01A9; C; 0283; # LATIN CAPITAL LETTER ESH +01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK +01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK +01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN +01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON +01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK +01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK +01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE +01B7; C; 0292; # LATIN CAPITAL LETTER EZH +01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED +01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE +01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON +01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON +01C7; C; 01C9; # LATIN CAPITAL LETTER LJ +01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J +01CA; C; 01CC; # LATIN CAPITAL LETTER NJ +01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J +01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON +01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON +01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON +01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON +01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON +01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON +01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON +01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE +01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON +01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON +01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK +01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON +01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON +01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON +01F1; C; 01F3; # LATIN CAPITAL LETTER DZ +01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z +01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE +01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR +01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN +01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE +01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE +01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE +0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE +0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE +0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE +0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE +020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE +020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE +020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE +0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE +0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE +0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE +0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE +0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW +021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW +021C; C; 021D; # LATIN CAPITAL LETTER YOGH +021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON +0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG +0222; C; 0223; # LATIN CAPITAL LETTER OU +0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK +0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE +0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA +022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON +022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON +022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE +0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON +0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON +023A; C; 2C65; # LATIN CAPITAL LETTER A WITH STROKE +023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE +023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR +023E; C; 2C66; # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE +0241; C; 0242; # LATIN CAPITAL LETTER GLOTTAL STOP +0243; C; 0180; # LATIN CAPITAL LETTER B WITH STROKE +0244; C; 0289; # LATIN CAPITAL LETTER U BAR +0245; C; 028C; # LATIN CAPITAL LETTER TURNED V +0246; C; 0247; # LATIN CAPITAL LETTER E WITH STROKE +0248; C; 0249; # LATIN CAPITAL LETTER J WITH STROKE +024A; C; 024B; # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL +024C; C; 024D; # LATIN CAPITAL LETTER R WITH STROKE +024E; C; 024F; # LATIN CAPITAL LETTER Y WITH STROKE +0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI +0370; C; 0371; # GREEK CAPITAL LETTER HETA +0372; C; 0373; # GREEK CAPITAL LETTER ARCHAIC SAMPI +0376; C; 0377; # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA +037F; C; 03F3; # GREEK CAPITAL LETTER YOT +0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS +0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS +0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS +038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS +038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS +038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS +038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS +0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA +0392; C; 03B2; # GREEK CAPITAL LETTER BETA +0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA +0394; C; 03B4; # GREEK CAPITAL LETTER DELTA +0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON +0396; C; 03B6; # GREEK CAPITAL LETTER ZETA +0397; C; 03B7; # GREEK CAPITAL LETTER ETA +0398; C; 03B8; # GREEK CAPITAL LETTER THETA +0399; C; 03B9; # GREEK CAPITAL LETTER IOTA +039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA +039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA +039C; C; 03BC; # GREEK CAPITAL LETTER MU +039D; C; 03BD; # GREEK CAPITAL LETTER NU +039E; C; 03BE; # GREEK CAPITAL LETTER XI +039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON +03A0; C; 03C0; # GREEK CAPITAL LETTER PI +03A1; C; 03C1; # GREEK CAPITAL LETTER RHO +03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA +03A4; C; 03C4; # GREEK CAPITAL LETTER TAU +03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON +03A6; C; 03C6; # GREEK CAPITAL LETTER PHI +03A7; C; 03C7; # GREEK CAPITAL LETTER CHI +03A8; C; 03C8; # GREEK CAPITAL LETTER PSI +03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA +03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA +03CF; C; 03D7; # GREEK CAPITAL KAI SYMBOL +03D0; C; 03B2; # GREEK BETA SYMBOL +03D1; C; 03B8; # GREEK THETA SYMBOL +03D5; C; 03C6; # GREEK PHI SYMBOL +03D6; C; 03C0; # GREEK PI SYMBOL +03D8; C; 03D9; # GREEK LETTER ARCHAIC KOPPA +03DA; C; 03DB; # GREEK LETTER STIGMA +03DC; C; 03DD; # GREEK LETTER DIGAMMA +03DE; C; 03DF; # GREEK LETTER KOPPA +03E0; C; 03E1; # GREEK LETTER SAMPI +03E2; C; 03E3; # COPTIC CAPITAL LETTER SHEI +03E4; C; 03E5; # COPTIC CAPITAL LETTER FEI +03E6; C; 03E7; # COPTIC CAPITAL LETTER KHEI +03E8; C; 03E9; # COPTIC CAPITAL LETTER HORI +03EA; C; 03EB; # COPTIC CAPITAL LETTER GANGIA +03EC; C; 03ED; # COPTIC CAPITAL LETTER SHIMA +03EE; C; 03EF; # COPTIC CAPITAL LETTER DEI +03F0; C; 03BA; # GREEK KAPPA SYMBOL +03F1; C; 03C1; # GREEK RHO SYMBOL +03F4; C; 03B8; # GREEK CAPITAL THETA SYMBOL +03F5; C; 03B5; # GREEK LUNATE EPSILON SYMBOL +03F7; C; 03F8; # GREEK CAPITAL LETTER SHO +03F9; C; 03F2; # GREEK CAPITAL LUNATE SIGMA SYMBOL +03FA; C; 03FB; # GREEK CAPITAL LETTER SAN +03FD; C; 037B; # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL +03FE; C; 037C; # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL +03FF; C; 037D; # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL +0400; C; 0450; # CYRILLIC CAPITAL LETTER IE WITH GRAVE +0401; C; 0451; # CYRILLIC CAPITAL LETTER IO +0402; C; 0452; # CYRILLIC CAPITAL LETTER DJE +0403; C; 0453; # CYRILLIC CAPITAL LETTER GJE +0404; C; 0454; # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0405; C; 0455; # CYRILLIC CAPITAL LETTER DZE +0406; C; 0456; # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0407; C; 0457; # CYRILLIC CAPITAL LETTER YI +0408; C; 0458; # CYRILLIC CAPITAL LETTER JE +0409; C; 0459; # CYRILLIC CAPITAL LETTER LJE +040A; C; 045A; # CYRILLIC CAPITAL LETTER NJE +040B; C; 045B; # CYRILLIC CAPITAL LETTER TSHE +040C; C; 045C; # CYRILLIC CAPITAL LETTER KJE +040D; C; 045D; # CYRILLIC CAPITAL LETTER I WITH GRAVE +040E; C; 045E; # CYRILLIC CAPITAL LETTER SHORT U +040F; C; 045F; # CYRILLIC CAPITAL LETTER DZHE +0410; C; 0430; # CYRILLIC CAPITAL LETTER A +0411; C; 0431; # CYRILLIC CAPITAL LETTER BE +0412; C; 0432; # CYRILLIC CAPITAL LETTER VE +0413; C; 0433; # CYRILLIC CAPITAL LETTER GHE +0414; C; 0434; # CYRILLIC CAPITAL LETTER DE +0415; C; 0435; # CYRILLIC CAPITAL LETTER IE +0416; C; 0436; # CYRILLIC CAPITAL LETTER ZHE +0417; C; 0437; # CYRILLIC CAPITAL LETTER ZE +0418; C; 0438; # CYRILLIC CAPITAL LETTER I +0419; C; 0439; # CYRILLIC CAPITAL LETTER SHORT I +041A; C; 043A; # CYRILLIC CAPITAL LETTER KA +041B; C; 043B; # CYRILLIC CAPITAL LETTER EL +041C; C; 043C; # CYRILLIC CAPITAL LETTER EM +041D; C; 043D; # CYRILLIC CAPITAL LETTER EN +041E; C; 043E; # CYRILLIC CAPITAL LETTER O +041F; C; 043F; # CYRILLIC CAPITAL LETTER PE +0420; C; 0440; # CYRILLIC CAPITAL LETTER ER +0421; C; 0441; # CYRILLIC CAPITAL LETTER ES +0422; C; 0442; # CYRILLIC CAPITAL LETTER TE +0423; C; 0443; # CYRILLIC CAPITAL LETTER U +0424; C; 0444; # CYRILLIC CAPITAL LETTER EF +0425; C; 0445; # CYRILLIC CAPITAL LETTER HA +0426; C; 0446; # CYRILLIC CAPITAL LETTER TSE +0427; C; 0447; # CYRILLIC CAPITAL LETTER CHE +0428; C; 0448; # CYRILLIC CAPITAL LETTER SHA +0429; C; 0449; # CYRILLIC CAPITAL LETTER SHCHA +042A; C; 044A; # CYRILLIC CAPITAL LETTER HARD SIGN +042B; C; 044B; # CYRILLIC CAPITAL LETTER YERU +042C; C; 044C; # CYRILLIC CAPITAL LETTER SOFT SIGN +042D; C; 044D; # CYRILLIC CAPITAL LETTER E +042E; C; 044E; # CYRILLIC CAPITAL LETTER YU +042F; C; 044F; # CYRILLIC CAPITAL LETTER YA +0460; C; 0461; # CYRILLIC CAPITAL LETTER OMEGA +0462; C; 0463; # CYRILLIC CAPITAL LETTER YAT +0464; C; 0465; # CYRILLIC CAPITAL LETTER IOTIFIED E +0466; C; 0467; # CYRILLIC CAPITAL LETTER LITTLE YUS +0468; C; 0469; # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS +046A; C; 046B; # CYRILLIC CAPITAL LETTER BIG YUS +046C; C; 046D; # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS +046E; C; 046F; # CYRILLIC CAPITAL LETTER KSI +0470; C; 0471; # CYRILLIC CAPITAL LETTER PSI +0472; C; 0473; # CYRILLIC CAPITAL LETTER FITA +0474; C; 0475; # CYRILLIC CAPITAL LETTER IZHITSA +0476; C; 0477; # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0478; C; 0479; # CYRILLIC CAPITAL LETTER UK +047A; C; 047B; # CYRILLIC CAPITAL LETTER ROUND OMEGA +047C; C; 047D; # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO +047E; C; 047F; # CYRILLIC CAPITAL LETTER OT +0480; C; 0481; # CYRILLIC CAPITAL LETTER KOPPA +048A; C; 048B; # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL +048C; C; 048D; # CYRILLIC CAPITAL LETTER SEMISOFT SIGN +048E; C; 048F; # CYRILLIC CAPITAL LETTER ER WITH TICK +0490; C; 0491; # CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0492; C; 0493; # CYRILLIC CAPITAL LETTER GHE WITH STROKE +0494; C; 0495; # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK +0496; C; 0497; # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER +0498; C; 0499; # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER +049A; C; 049B; # CYRILLIC CAPITAL LETTER KA WITH DESCENDER +049C; C; 049D; # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE +049E; C; 049F; # CYRILLIC CAPITAL LETTER KA WITH STROKE +04A0; C; 04A1; # CYRILLIC CAPITAL LETTER BASHKIR KA +04A2; C; 04A3; # CYRILLIC CAPITAL LETTER EN WITH DESCENDER +04A4; C; 04A5; # CYRILLIC CAPITAL LIGATURE EN GHE +04A6; C; 04A7; # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK +04A8; C; 04A9; # CYRILLIC CAPITAL LETTER ABKHASIAN HA +04AA; C; 04AB; # CYRILLIC CAPITAL LETTER ES WITH DESCENDER +04AC; C; 04AD; # CYRILLIC CAPITAL LETTER TE WITH DESCENDER +04AE; C; 04AF; # CYRILLIC CAPITAL LETTER STRAIGHT U +04B0; C; 04B1; # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE +04B2; C; 04B3; # CYRILLIC CAPITAL LETTER HA WITH DESCENDER +04B4; C; 04B5; # CYRILLIC CAPITAL LIGATURE TE TSE +04B6; C; 04B7; # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER +04B8; C; 04B9; # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE +04BA; C; 04BB; # CYRILLIC CAPITAL LETTER SHHA +04BC; C; 04BD; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE +04BE; C; 04BF; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER +04C0; C; 04CF; # CYRILLIC LETTER PALOCHKA +04C1; C; 04C2; # CYRILLIC CAPITAL LETTER ZHE WITH BREVE +04C3; C; 04C4; # CYRILLIC CAPITAL LETTER KA WITH HOOK +04C5; C; 04C6; # CYRILLIC CAPITAL LETTER EL WITH TAIL +04C7; C; 04C8; # CYRILLIC CAPITAL LETTER EN WITH HOOK +04C9; C; 04CA; # CYRILLIC CAPITAL LETTER EN WITH TAIL +04CB; C; 04CC; # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE +04CD; C; 04CE; # CYRILLIC CAPITAL LETTER EM WITH TAIL +04D0; C; 04D1; # CYRILLIC CAPITAL LETTER A WITH BREVE +04D2; C; 04D3; # CYRILLIC CAPITAL LETTER A WITH DIAERESIS +04D4; C; 04D5; # CYRILLIC CAPITAL LIGATURE A IE +04D6; C; 04D7; # CYRILLIC CAPITAL LETTER IE WITH BREVE +04D8; C; 04D9; # CYRILLIC CAPITAL LETTER SCHWA +04DA; C; 04DB; # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS +04DC; C; 04DD; # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS +04DE; C; 04DF; # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS +04E0; C; 04E1; # CYRILLIC CAPITAL LETTER ABKHASIAN DZE +04E2; C; 04E3; # CYRILLIC CAPITAL LETTER I WITH MACRON +04E4; C; 04E5; # CYRILLIC CAPITAL LETTER I WITH DIAERESIS +04E6; C; 04E7; # CYRILLIC CAPITAL LETTER O WITH DIAERESIS +04E8; C; 04E9; # CYRILLIC CAPITAL LETTER BARRED O +04EA; C; 04EB; # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS +04EC; C; 04ED; # CYRILLIC CAPITAL LETTER E WITH DIAERESIS +04EE; C; 04EF; # CYRILLIC CAPITAL LETTER U WITH MACRON +04F0; C; 04F1; # CYRILLIC CAPITAL LETTER U WITH DIAERESIS +04F2; C; 04F3; # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE +04F4; C; 04F5; # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS +04F6; C; 04F7; # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER +04F8; C; 04F9; # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS +04FA; C; 04FB; # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK +04FC; C; 04FD; # CYRILLIC CAPITAL LETTER HA WITH HOOK +04FE; C; 04FF; # CYRILLIC CAPITAL LETTER HA WITH STROKE +0500; C; 0501; # CYRILLIC CAPITAL LETTER KOMI DE +0502; C; 0503; # CYRILLIC CAPITAL LETTER KOMI DJE +0504; C; 0505; # CYRILLIC CAPITAL LETTER KOMI ZJE +0506; C; 0507; # CYRILLIC CAPITAL LETTER KOMI DZJE +0508; C; 0509; # CYRILLIC CAPITAL LETTER KOMI LJE +050A; C; 050B; # CYRILLIC CAPITAL LETTER KOMI NJE +050C; C; 050D; # CYRILLIC CAPITAL LETTER KOMI SJE +050E; C; 050F; # CYRILLIC CAPITAL LETTER KOMI TJE +0510; C; 0511; # CYRILLIC CAPITAL LETTER REVERSED ZE +0512; C; 0513; # CYRILLIC CAPITAL LETTER EL WITH HOOK +0514; C; 0515; # CYRILLIC CAPITAL LETTER LHA +0516; C; 0517; # CYRILLIC CAPITAL LETTER RHA +0518; C; 0519; # CYRILLIC CAPITAL LETTER YAE +051A; C; 051B; # CYRILLIC CAPITAL LETTER QA +051C; C; 051D; # CYRILLIC CAPITAL LETTER WE +051E; C; 051F; # CYRILLIC CAPITAL LETTER ALEUT KA +0520; C; 0521; # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK +0522; C; 0523; # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK +0524; C; 0525; # CYRILLIC CAPITAL LETTER PE WITH DESCENDER +0526; C; 0527; # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER +0528; C; 0529; # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK +052A; C; 052B; # CYRILLIC CAPITAL LETTER DZZHE +052C; C; 052D; # CYRILLIC CAPITAL LETTER DCHE +052E; C; 052F; # CYRILLIC CAPITAL LETTER EL WITH DESCENDER +0531; C; 0561; # ARMENIAN CAPITAL LETTER AYB +0532; C; 0562; # ARMENIAN CAPITAL LETTER BEN +0533; C; 0563; # ARMENIAN CAPITAL LETTER GIM +0534; C; 0564; # ARMENIAN CAPITAL LETTER DA +0535; C; 0565; # ARMENIAN CAPITAL LETTER ECH +0536; C; 0566; # ARMENIAN CAPITAL LETTER ZA +0537; C; 0567; # ARMENIAN CAPITAL LETTER EH +0538; C; 0568; # ARMENIAN CAPITAL LETTER ET +0539; C; 0569; # ARMENIAN CAPITAL LETTER TO +053A; C; 056A; # ARMENIAN CAPITAL LETTER ZHE +053B; C; 056B; # ARMENIAN CAPITAL LETTER INI +053C; C; 056C; # ARMENIAN CAPITAL LETTER LIWN +053D; C; 056D; # ARMENIAN CAPITAL LETTER XEH +053E; C; 056E; # ARMENIAN CAPITAL LETTER CA +053F; C; 056F; # ARMENIAN CAPITAL LETTER KEN +0540; C; 0570; # ARMENIAN CAPITAL LETTER HO +0541; C; 0571; # ARMENIAN CAPITAL LETTER JA +0542; C; 0572; # ARMENIAN CAPITAL LETTER GHAD +0543; C; 0573; # ARMENIAN CAPITAL LETTER CHEH +0544; C; 0574; # ARMENIAN CAPITAL LETTER MEN +0545; C; 0575; # ARMENIAN CAPITAL LETTER YI +0546; C; 0576; # ARMENIAN CAPITAL LETTER NOW +0547; C; 0577; # ARMENIAN CAPITAL LETTER SHA +0548; C; 0578; # ARMENIAN CAPITAL LETTER VO +0549; C; 0579; # ARMENIAN CAPITAL LETTER CHA +054A; C; 057A; # ARMENIAN CAPITAL LETTER PEH +054B; C; 057B; # ARMENIAN CAPITAL LETTER JHEH +054C; C; 057C; # ARMENIAN CAPITAL LETTER RA +054D; C; 057D; # ARMENIAN CAPITAL LETTER SEH +054E; C; 057E; # ARMENIAN CAPITAL LETTER VEW +054F; C; 057F; # ARMENIAN CAPITAL LETTER TIWN +0550; C; 0580; # ARMENIAN CAPITAL LETTER REH +0551; C; 0581; # ARMENIAN CAPITAL LETTER CO +0552; C; 0582; # ARMENIAN CAPITAL LETTER YIWN +0553; C; 0583; # ARMENIAN CAPITAL LETTER PIWR +0554; C; 0584; # ARMENIAN CAPITAL LETTER KEH +0555; C; 0585; # ARMENIAN CAPITAL LETTER OH +0556; C; 0586; # ARMENIAN CAPITAL LETTER FEH +0587; F; 0565 0582; # ARMENIAN SMALL LIGATURE ECH YIWN +10A0; C; 2D00; # GEORGIAN CAPITAL LETTER AN +10A1; C; 2D01; # GEORGIAN CAPITAL LETTER BAN +10A2; C; 2D02; # GEORGIAN CAPITAL LETTER GAN +10A3; C; 2D03; # GEORGIAN CAPITAL LETTER DON +10A4; C; 2D04; # GEORGIAN CAPITAL LETTER EN +10A5; C; 2D05; # GEORGIAN CAPITAL LETTER VIN +10A6; C; 2D06; # GEORGIAN CAPITAL LETTER ZEN +10A7; C; 2D07; # GEORGIAN CAPITAL LETTER TAN +10A8; C; 2D08; # GEORGIAN CAPITAL LETTER IN +10A9; C; 2D09; # GEORGIAN CAPITAL LETTER KAN +10AA; C; 2D0A; # GEORGIAN CAPITAL LETTER LAS +10AB; C; 2D0B; # GEORGIAN CAPITAL LETTER MAN +10AC; C; 2D0C; # GEORGIAN CAPITAL LETTER NAR +10AD; C; 2D0D; # GEORGIAN CAPITAL LETTER ON +10AE; C; 2D0E; # GEORGIAN CAPITAL LETTER PAR +10AF; C; 2D0F; # GEORGIAN CAPITAL LETTER ZHAR +10B0; C; 2D10; # GEORGIAN CAPITAL LETTER RAE +10B1; C; 2D11; # GEORGIAN CAPITAL LETTER SAN +10B2; C; 2D12; # GEORGIAN CAPITAL LETTER TAR +10B3; C; 2D13; # GEORGIAN CAPITAL LETTER UN +10B4; C; 2D14; # GEORGIAN CAPITAL LETTER PHAR +10B5; C; 2D15; # GEORGIAN CAPITAL LETTER KHAR +10B6; C; 2D16; # GEORGIAN CAPITAL LETTER GHAN +10B7; C; 2D17; # GEORGIAN CAPITAL LETTER QAR +10B8; C; 2D18; # GEORGIAN CAPITAL LETTER SHIN +10B9; C; 2D19; # GEORGIAN CAPITAL LETTER CHIN +10BA; C; 2D1A; # GEORGIAN CAPITAL LETTER CAN +10BB; C; 2D1B; # GEORGIAN CAPITAL LETTER JIL +10BC; C; 2D1C; # GEORGIAN CAPITAL LETTER CIL +10BD; C; 2D1D; # GEORGIAN CAPITAL LETTER CHAR +10BE; C; 2D1E; # GEORGIAN CAPITAL LETTER XAN +10BF; C; 2D1F; # GEORGIAN CAPITAL LETTER JHAN +10C0; C; 2D20; # GEORGIAN CAPITAL LETTER HAE +10C1; C; 2D21; # GEORGIAN CAPITAL LETTER HE +10C2; C; 2D22; # GEORGIAN CAPITAL LETTER HIE +10C3; C; 2D23; # GEORGIAN CAPITAL LETTER WE +10C4; C; 2D24; # GEORGIAN CAPITAL LETTER HAR +10C5; C; 2D25; # GEORGIAN CAPITAL LETTER HOE +10C7; C; 2D27; # GEORGIAN CAPITAL LETTER YN +10CD; C; 2D2D; # GEORGIAN CAPITAL LETTER AEN +13F8; C; 13F0; # CHEROKEE SMALL LETTER YE +13F9; C; 13F1; # CHEROKEE SMALL LETTER YI +13FA; C; 13F2; # CHEROKEE SMALL LETTER YO +13FB; C; 13F3; # CHEROKEE SMALL LETTER YU +13FC; C; 13F4; # CHEROKEE SMALL LETTER YV +13FD; C; 13F5; # CHEROKEE SMALL LETTER MV +1C80; C; 0432; # CYRILLIC SMALL LETTER ROUNDED VE +1C81; C; 0434; # CYRILLIC SMALL LETTER LONG-LEGGED DE +1C82; C; 043E; # CYRILLIC SMALL LETTER NARROW O +1C83; C; 0441; # CYRILLIC SMALL LETTER WIDE ES +1C84; C; 0442; # CYRILLIC SMALL LETTER TALL TE +1C85; C; 0442; # CYRILLIC SMALL LETTER THREE-LEGGED TE +1C86; C; 044A; # CYRILLIC SMALL LETTER TALL HARD SIGN +1C87; C; 0463; # CYRILLIC SMALL LETTER TALL YAT +1C88; C; A64B; # CYRILLIC SMALL LETTER UNBLENDED UK +1C90; C; 10D0; # GEORGIAN MTAVRULI CAPITAL LETTER AN +1C91; C; 10D1; # GEORGIAN MTAVRULI CAPITAL LETTER BAN +1C92; C; 10D2; # GEORGIAN MTAVRULI CAPITAL LETTER GAN +1C93; C; 10D3; # GEORGIAN MTAVRULI CAPITAL LETTER DON +1C94; C; 10D4; # GEORGIAN MTAVRULI CAPITAL LETTER EN +1C95; C; 10D5; # GEORGIAN MTAVRULI CAPITAL LETTER VIN +1C96; C; 10D6; # GEORGIAN MTAVRULI CAPITAL LETTER ZEN +1C97; C; 10D7; # GEORGIAN MTAVRULI CAPITAL LETTER TAN +1C98; C; 10D8; # GEORGIAN MTAVRULI CAPITAL LETTER IN +1C99; C; 10D9; # GEORGIAN MTAVRULI CAPITAL LETTER KAN +1C9A; C; 10DA; # GEORGIAN MTAVRULI CAPITAL LETTER LAS +1C9B; C; 10DB; # GEORGIAN MTAVRULI CAPITAL LETTER MAN +1C9C; C; 10DC; # GEORGIAN MTAVRULI CAPITAL LETTER NAR +1C9D; C; 10DD; # GEORGIAN MTAVRULI CAPITAL LETTER ON +1C9E; C; 10DE; # GEORGIAN MTAVRULI CAPITAL LETTER PAR +1C9F; C; 10DF; # GEORGIAN MTAVRULI CAPITAL LETTER ZHAR +1CA0; C; 10E0; # GEORGIAN MTAVRULI CAPITAL LETTER RAE +1CA1; C; 10E1; # GEORGIAN MTAVRULI CAPITAL LETTER SAN +1CA2; C; 10E2; # GEORGIAN MTAVRULI CAPITAL LETTER TAR +1CA3; C; 10E3; # GEORGIAN MTAVRULI CAPITAL LETTER UN +1CA4; C; 10E4; # GEORGIAN MTAVRULI CAPITAL LETTER PHAR +1CA5; C; 10E5; # GEORGIAN MTAVRULI CAPITAL LETTER KHAR +1CA6; C; 10E6; # GEORGIAN MTAVRULI CAPITAL LETTER GHAN +1CA7; C; 10E7; # GEORGIAN MTAVRULI CAPITAL LETTER QAR +1CA8; C; 10E8; # GEORGIAN MTAVRULI CAPITAL LETTER SHIN +1CA9; C; 10E9; # GEORGIAN MTAVRULI CAPITAL LETTER CHIN +1CAA; C; 10EA; # GEORGIAN MTAVRULI CAPITAL LETTER CAN +1CAB; C; 10EB; # GEORGIAN MTAVRULI CAPITAL LETTER JIL +1CAC; C; 10EC; # GEORGIAN MTAVRULI CAPITAL LETTER CIL +1CAD; C; 10ED; # GEORGIAN MTAVRULI CAPITAL LETTER CHAR +1CAE; C; 10EE; # GEORGIAN MTAVRULI CAPITAL LETTER XAN +1CAF; C; 10EF; # GEORGIAN MTAVRULI CAPITAL LETTER JHAN +1CB0; C; 10F0; # GEORGIAN MTAVRULI CAPITAL LETTER HAE +1CB1; C; 10F1; # GEORGIAN MTAVRULI CAPITAL LETTER HE +1CB2; C; 10F2; # GEORGIAN MTAVRULI CAPITAL LETTER HIE +1CB3; C; 10F3; # GEORGIAN MTAVRULI CAPITAL LETTER WE +1CB4; C; 10F4; # GEORGIAN MTAVRULI CAPITAL LETTER HAR +1CB5; C; 10F5; # GEORGIAN MTAVRULI CAPITAL LETTER HOE +1CB6; C; 10F6; # GEORGIAN MTAVRULI CAPITAL LETTER FI +1CB7; C; 10F7; # GEORGIAN MTAVRULI CAPITAL LETTER YN +1CB8; C; 10F8; # GEORGIAN MTAVRULI CAPITAL LETTER ELIFI +1CB9; C; 10F9; # GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN +1CBA; C; 10FA; # GEORGIAN MTAVRULI CAPITAL LETTER AIN +1CBD; C; 10FD; # GEORGIAN MTAVRULI CAPITAL LETTER AEN +1CBE; C; 10FE; # GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN +1CBF; C; 10FF; # GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN +1E00; C; 1E01; # LATIN CAPITAL LETTER A WITH RING BELOW +1E02; C; 1E03; # LATIN CAPITAL LETTER B WITH DOT ABOVE +1E04; C; 1E05; # LATIN CAPITAL LETTER B WITH DOT BELOW +1E06; C; 1E07; # LATIN CAPITAL LETTER B WITH LINE BELOW +1E08; C; 1E09; # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE +1E0A; C; 1E0B; # LATIN CAPITAL LETTER D WITH DOT ABOVE +1E0C; C; 1E0D; # LATIN CAPITAL LETTER D WITH DOT BELOW +1E0E; C; 1E0F; # LATIN CAPITAL LETTER D WITH LINE BELOW +1E10; C; 1E11; # LATIN CAPITAL LETTER D WITH CEDILLA +1E12; C; 1E13; # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW +1E14; C; 1E15; # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE +1E16; C; 1E17; # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE +1E18; C; 1E19; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW +1E1A; C; 1E1B; # LATIN CAPITAL LETTER E WITH TILDE BELOW +1E1C; C; 1E1D; # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE +1E1E; C; 1E1F; # LATIN CAPITAL LETTER F WITH DOT ABOVE +1E20; C; 1E21; # LATIN CAPITAL LETTER G WITH MACRON +1E22; C; 1E23; # LATIN CAPITAL LETTER H WITH DOT ABOVE +1E24; C; 1E25; # LATIN CAPITAL LETTER H WITH DOT BELOW +1E26; C; 1E27; # LATIN CAPITAL LETTER H WITH DIAERESIS +1E28; C; 1E29; # LATIN CAPITAL LETTER H WITH CEDILLA +1E2A; C; 1E2B; # LATIN CAPITAL LETTER H WITH BREVE BELOW +1E2C; C; 1E2D; # LATIN CAPITAL LETTER I WITH TILDE BELOW +1E2E; C; 1E2F; # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE +1E30; C; 1E31; # LATIN CAPITAL LETTER K WITH ACUTE +1E32; C; 1E33; # LATIN CAPITAL LETTER K WITH DOT BELOW +1E34; C; 1E35; # LATIN CAPITAL LETTER K WITH LINE BELOW +1E36; C; 1E37; # LATIN CAPITAL LETTER L WITH DOT BELOW +1E38; C; 1E39; # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON +1E3A; C; 1E3B; # LATIN CAPITAL LETTER L WITH LINE BELOW +1E3C; C; 1E3D; # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW +1E3E; C; 1E3F; # LATIN CAPITAL LETTER M WITH ACUTE +1E40; C; 1E41; # LATIN CAPITAL LETTER M WITH DOT ABOVE +1E42; C; 1E43; # LATIN CAPITAL LETTER M WITH DOT BELOW +1E44; C; 1E45; # LATIN CAPITAL LETTER N WITH DOT ABOVE +1E46; C; 1E47; # LATIN CAPITAL LETTER N WITH DOT BELOW +1E48; C; 1E49; # LATIN CAPITAL LETTER N WITH LINE BELOW +1E4A; C; 1E4B; # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW +1E4C; C; 1E4D; # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE +1E4E; C; 1E4F; # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS +1E50; C; 1E51; # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE +1E52; C; 1E53; # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE +1E54; C; 1E55; # LATIN CAPITAL LETTER P WITH ACUTE +1E56; C; 1E57; # LATIN CAPITAL LETTER P WITH DOT ABOVE +1E58; C; 1E59; # LATIN CAPITAL LETTER R WITH DOT ABOVE +1E5A; C; 1E5B; # LATIN CAPITAL LETTER R WITH DOT BELOW +1E5C; C; 1E5D; # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON +1E5E; C; 1E5F; # LATIN CAPITAL LETTER R WITH LINE BELOW +1E60; C; 1E61; # LATIN CAPITAL LETTER S WITH DOT ABOVE +1E62; C; 1E63; # LATIN CAPITAL LETTER S WITH DOT BELOW +1E64; C; 1E65; # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE +1E66; C; 1E67; # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE +1E68; C; 1E69; # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE +1E6A; C; 1E6B; # LATIN CAPITAL LETTER T WITH DOT ABOVE +1E6C; C; 1E6D; # LATIN CAPITAL LETTER T WITH DOT BELOW +1E6E; C; 1E6F; # LATIN CAPITAL LETTER T WITH LINE BELOW +1E70; C; 1E71; # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW +1E72; C; 1E73; # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW +1E74; C; 1E75; # LATIN CAPITAL LETTER U WITH TILDE BELOW +1E76; C; 1E77; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW +1E78; C; 1E79; # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE +1E7A; C; 1E7B; # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS +1E7C; C; 1E7D; # LATIN CAPITAL LETTER V WITH TILDE +1E7E; C; 1E7F; # LATIN CAPITAL LETTER V WITH DOT BELOW +1E80; C; 1E81; # LATIN CAPITAL LETTER W WITH GRAVE +1E82; C; 1E83; # LATIN CAPITAL LETTER W WITH ACUTE +1E84; C; 1E85; # LATIN CAPITAL LETTER W WITH DIAERESIS +1E86; C; 1E87; # LATIN CAPITAL LETTER W WITH DOT ABOVE +1E88; C; 1E89; # LATIN CAPITAL LETTER W WITH DOT BELOW +1E8A; C; 1E8B; # LATIN CAPITAL LETTER X WITH DOT ABOVE +1E8C; C; 1E8D; # LATIN CAPITAL LETTER X WITH DIAERESIS +1E8E; C; 1E8F; # LATIN CAPITAL LETTER Y WITH DOT ABOVE +1E90; C; 1E91; # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX +1E92; C; 1E93; # LATIN CAPITAL LETTER Z WITH DOT BELOW +1E94; C; 1E95; # LATIN CAPITAL LETTER Z WITH LINE BELOW +1E96; F; 0068 0331; # LATIN SMALL LETTER H WITH LINE BELOW +1E97; F; 0074 0308; # LATIN SMALL LETTER T WITH DIAERESIS +1E98; F; 0077 030A; # LATIN SMALL LETTER W WITH RING ABOVE +1E99; F; 0079 030A; # LATIN SMALL LETTER Y WITH RING ABOVE +1E9A; F; 0061 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING +1E9B; C; 1E61; # LATIN SMALL LETTER LONG S WITH DOT ABOVE +1E9E; F; 0073 0073; # LATIN CAPITAL LETTER SHARP S +1E9E; S; 00DF; # LATIN CAPITAL LETTER SHARP S +1EA0; C; 1EA1; # LATIN CAPITAL LETTER A WITH DOT BELOW +1EA2; C; 1EA3; # LATIN CAPITAL LETTER A WITH HOOK ABOVE +1EA4; C; 1EA5; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA6; C; 1EA7; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE +1EA8; C; 1EA9; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +1EAA; C; 1EAB; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE +1EAC; C; 1EAD; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1EAE; C; 1EAF; # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE +1EB0; C; 1EB1; # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE +1EB2; C; 1EB3; # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE +1EB4; C; 1EB5; # LATIN CAPITAL LETTER A WITH BREVE AND TILDE +1EB6; C; 1EB7; # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW +1EB8; C; 1EB9; # LATIN CAPITAL LETTER E WITH DOT BELOW +1EBA; C; 1EBB; # LATIN CAPITAL LETTER E WITH HOOK ABOVE +1EBC; C; 1EBD; # LATIN CAPITAL LETTER E WITH TILDE +1EBE; C; 1EBF; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +1EC0; C; 1EC1; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC2; C; 1EC3; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +1EC4; C; 1EC5; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE +1EC6; C; 1EC7; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1EC8; C; 1EC9; # LATIN CAPITAL LETTER I WITH HOOK ABOVE +1ECA; C; 1ECB; # LATIN CAPITAL LETTER I WITH DOT BELOW +1ECC; C; 1ECD; # LATIN CAPITAL LETTER O WITH DOT BELOW +1ECE; C; 1ECF; # LATIN CAPITAL LETTER O WITH HOOK ABOVE +1ED0; C; 1ED1; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED2; C; 1ED3; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED4; C; 1ED5; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +1ED6; C; 1ED7; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE +1ED8; C; 1ED9; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW +1EDA; C; 1EDB; # LATIN CAPITAL LETTER O WITH HORN AND ACUTE +1EDC; C; 1EDD; # LATIN CAPITAL LETTER O WITH HORN AND GRAVE +1EDE; C; 1EDF; # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE +1EE0; C; 1EE1; # LATIN CAPITAL LETTER O WITH HORN AND TILDE +1EE2; C; 1EE3; # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW +1EE4; C; 1EE5; # LATIN CAPITAL LETTER U WITH DOT BELOW +1EE6; C; 1EE7; # LATIN CAPITAL LETTER U WITH HOOK ABOVE +1EE8; C; 1EE9; # LATIN CAPITAL LETTER U WITH HORN AND ACUTE +1EEA; C; 1EEB; # LATIN CAPITAL LETTER U WITH HORN AND GRAVE +1EEC; C; 1EED; # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE +1EEE; C; 1EEF; # LATIN CAPITAL LETTER U WITH HORN AND TILDE +1EF0; C; 1EF1; # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW +1EF2; C; 1EF3; # LATIN CAPITAL LETTER Y WITH GRAVE +1EF4; C; 1EF5; # LATIN CAPITAL LETTER Y WITH DOT BELOW +1EF6; C; 1EF7; # LATIN CAPITAL LETTER Y WITH HOOK ABOVE +1EF8; C; 1EF9; # LATIN CAPITAL LETTER Y WITH TILDE +1EFA; C; 1EFB; # LATIN CAPITAL LETTER MIDDLE-WELSH LL +1EFC; C; 1EFD; # LATIN CAPITAL LETTER MIDDLE-WELSH V +1EFE; C; 1EFF; # LATIN CAPITAL LETTER Y WITH LOOP +1F08; C; 1F00; # GREEK CAPITAL LETTER ALPHA WITH PSILI +1F09; C; 1F01; # GREEK CAPITAL LETTER ALPHA WITH DASIA +1F0A; C; 1F02; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA +1F0B; C; 1F03; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA +1F0C; C; 1F04; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA +1F0D; C; 1F05; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA +1F0E; C; 1F06; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI +1F0F; C; 1F07; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F18; C; 1F10; # GREEK CAPITAL LETTER EPSILON WITH PSILI +1F19; C; 1F11; # GREEK CAPITAL LETTER EPSILON WITH DASIA +1F1A; C; 1F12; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA +1F1B; C; 1F13; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA +1F1C; C; 1F14; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA +1F1D; C; 1F15; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +1F28; C; 1F20; # GREEK CAPITAL LETTER ETA WITH PSILI +1F29; C; 1F21; # GREEK CAPITAL LETTER ETA WITH DASIA +1F2A; C; 1F22; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA +1F2B; C; 1F23; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA +1F2C; C; 1F24; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA +1F2D; C; 1F25; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA +1F2E; C; 1F26; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI +1F2F; C; 1F27; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI +1F38; C; 1F30; # GREEK CAPITAL LETTER IOTA WITH PSILI +1F39; C; 1F31; # GREEK CAPITAL LETTER IOTA WITH DASIA +1F3A; C; 1F32; # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA +1F3B; C; 1F33; # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA +1F3C; C; 1F34; # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA +1F3D; C; 1F35; # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA +1F3E; C; 1F36; # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI +1F3F; C; 1F37; # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI +1F48; C; 1F40; # GREEK CAPITAL LETTER OMICRON WITH PSILI +1F49; C; 1F41; # GREEK CAPITAL LETTER OMICRON WITH DASIA +1F4A; C; 1F42; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA +1F4B; C; 1F43; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA +1F4C; C; 1F44; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA +1F4D; C; 1F45; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +1F50; F; 03C5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI +1F52; F; 03C5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA +1F54; F; 03C5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA +1F56; F; 03C5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI +1F59; C; 1F51; # GREEK CAPITAL LETTER UPSILON WITH DASIA +1F5B; C; 1F53; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +1F5D; C; 1F55; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +1F5F; C; 1F57; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F68; C; 1F60; # GREEK CAPITAL LETTER OMEGA WITH PSILI +1F69; C; 1F61; # GREEK CAPITAL LETTER OMEGA WITH DASIA +1F6A; C; 1F62; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA +1F6B; C; 1F63; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA +1F6C; C; 1F64; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA +1F6D; C; 1F65; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA +1F6E; C; 1F66; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI +1F6F; C; 1F67; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI +1F80; F; 1F00 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI +1F81; F; 1F01 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI +1F82; F; 1F02 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F83; F; 1F03 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F84; F; 1F04 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F85; F; 1F05 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F86; F; 1F06 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F87; F; 1F07 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F88; F; 1F00 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +1F88; S; 1F80; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +1F89; F; 1F01 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +1F89; S; 1F81; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +1F8A; F; 1F02 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F8A; S; 1F82; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F8B; F; 1F03 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F8B; S; 1F83; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F8C; F; 1F04 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F8C; S; 1F84; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F8D; F; 1F05 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F8D; S; 1F85; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F8E; F; 1F06 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F8E; S; 1F86; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F8F; F; 1F07 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F8F; S; 1F87; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F90; F; 1F20 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI +1F91; F; 1F21 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI +1F92; F; 1F22 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F93; F; 1F23 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F94; F; 1F24 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F95; F; 1F25 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F96; F; 1F26 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F97; F; 1F27 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F98; F; 1F20 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +1F98; S; 1F90; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +1F99; F; 1F21 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +1F99; S; 1F91; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +1F9A; F; 1F22 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F9A; S; 1F92; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F9B; F; 1F23 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F9B; S; 1F93; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F9C; F; 1F24 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F9C; S; 1F94; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F9D; F; 1F25 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F9D; S; 1F95; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F9E; F; 1F26 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F9E; S; 1F96; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F9F; F; 1F27 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F9F; S; 1F97; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FA0; F; 1F60 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI +1FA1; F; 1F61 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI +1FA2; F; 1F62 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1FA3; F; 1F63 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1FA4; F; 1F64 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1FA5; F; 1F65 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1FA6; F; 1F66 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1FA7; F; 1F67 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1FA8; F; 1F60 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +1FA8; S; 1FA0; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +1FA9; F; 1F61 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +1FA9; S; 1FA1; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +1FAA; F; 1F62 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1FAA; S; 1FA2; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1FAB; F; 1F63 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1FAB; S; 1FA3; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1FAC; F; 1F64 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1FAC; S; 1FA4; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1FAD; F; 1F65 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1FAD; S; 1FA5; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1FAE; F; 1F66 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1FAE; S; 1FA6; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1FAF; F; 1F67 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FAF; S; 1FA7; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FB2; F; 1F70 03B9; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI +1FB3; F; 03B1 03B9; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI +1FB4; F; 03AC 03B9; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1FB6; F; 03B1 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI +1FB7; F; 03B1 0342 03B9; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI +1FB8; C; 1FB0; # GREEK CAPITAL LETTER ALPHA WITH VRACHY +1FB9; C; 1FB1; # GREEK CAPITAL LETTER ALPHA WITH MACRON +1FBA; C; 1F70; # GREEK CAPITAL LETTER ALPHA WITH VARIA +1FBB; C; 1F71; # GREEK CAPITAL LETTER ALPHA WITH OXIA +1FBC; F; 03B1 03B9; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBC; S; 1FB3; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBE; C; 03B9; # GREEK PROSGEGRAMMENI +1FC2; F; 1F74 03B9; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI +1FC3; F; 03B7 03B9; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI +1FC4; F; 03AE 03B9; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1FC6; F; 03B7 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI +1FC7; F; 03B7 0342 03B9; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI +1FC8; C; 1F72; # GREEK CAPITAL LETTER EPSILON WITH VARIA +1FC9; C; 1F73; # GREEK CAPITAL LETTER EPSILON WITH OXIA +1FCA; C; 1F74; # GREEK CAPITAL LETTER ETA WITH VARIA +1FCB; C; 1F75; # GREEK CAPITAL LETTER ETA WITH OXIA +1FCC; F; 03B7 03B9; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FCC; S; 1FC3; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FD2; F; 03B9 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA +1FD3; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD6; F; 03B9 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI +1FD7; F; 03B9 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI +1FD8; C; 1FD0; # GREEK CAPITAL LETTER IOTA WITH VRACHY +1FD9; C; 1FD1; # GREEK CAPITAL LETTER IOTA WITH MACRON +1FDA; C; 1F76; # GREEK CAPITAL LETTER IOTA WITH VARIA +1FDB; C; 1F77; # GREEK CAPITAL LETTER IOTA WITH OXIA +1FE2; F; 03C5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA +1FE3; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA +1FE4; F; 03C1 0313; # GREEK SMALL LETTER RHO WITH PSILI +1FE6; F; 03C5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI +1FE7; F; 03C5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI +1FE8; C; 1FE0; # GREEK CAPITAL LETTER UPSILON WITH VRACHY +1FE9; C; 1FE1; # GREEK CAPITAL LETTER UPSILON WITH MACRON +1FEA; C; 1F7A; # GREEK CAPITAL LETTER UPSILON WITH VARIA +1FEB; C; 1F7B; # GREEK CAPITAL LETTER UPSILON WITH OXIA +1FEC; C; 1FE5; # GREEK CAPITAL LETTER RHO WITH DASIA +1FF2; F; 1F7C 03B9; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI +1FF3; F; 03C9 03B9; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI +1FF4; F; 03CE 03B9; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1FF6; F; 03C9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI +1FF7; F; 03C9 0342 03B9; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI +1FF8; C; 1F78; # GREEK CAPITAL LETTER OMICRON WITH VARIA +1FF9; C; 1F79; # GREEK CAPITAL LETTER OMICRON WITH OXIA +1FFA; C; 1F7C; # GREEK CAPITAL LETTER OMEGA WITH VARIA +1FFB; C; 1F7D; # GREEK CAPITAL LETTER OMEGA WITH OXIA +1FFC; F; 03C9 03B9; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +1FFC; S; 1FF3; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +2126; C; 03C9; # OHM SIGN +212A; C; 006B; # KELVIN SIGN +212B; C; 00E5; # ANGSTROM SIGN +2132; C; 214E; # TURNED CAPITAL F +2160; C; 2170; # ROMAN NUMERAL ONE +2161; C; 2171; # ROMAN NUMERAL TWO +2162; C; 2172; # ROMAN NUMERAL THREE +2163; C; 2173; # ROMAN NUMERAL FOUR +2164; C; 2174; # ROMAN NUMERAL FIVE +2165; C; 2175; # ROMAN NUMERAL SIX +2166; C; 2176; # ROMAN NUMERAL SEVEN +2167; C; 2177; # ROMAN NUMERAL EIGHT +2168; C; 2178; # ROMAN NUMERAL NINE +2169; C; 2179; # ROMAN NUMERAL TEN +216A; C; 217A; # ROMAN NUMERAL ELEVEN +216B; C; 217B; # ROMAN NUMERAL TWELVE +216C; C; 217C; # ROMAN NUMERAL FIFTY +216D; C; 217D; # ROMAN NUMERAL ONE HUNDRED +216E; C; 217E; # ROMAN NUMERAL FIVE HUNDRED +216F; C; 217F; # ROMAN NUMERAL ONE THOUSAND +2183; C; 2184; # ROMAN NUMERAL REVERSED ONE HUNDRED +24B6; C; 24D0; # CIRCLED LATIN CAPITAL LETTER A +24B7; C; 24D1; # CIRCLED LATIN CAPITAL LETTER B +24B8; C; 24D2; # CIRCLED LATIN CAPITAL LETTER C +24B9; C; 24D3; # CIRCLED LATIN CAPITAL LETTER D +24BA; C; 24D4; # CIRCLED LATIN CAPITAL LETTER E +24BB; C; 24D5; # CIRCLED LATIN CAPITAL LETTER F +24BC; C; 24D6; # CIRCLED LATIN CAPITAL LETTER G +24BD; C; 24D7; # CIRCLED LATIN CAPITAL LETTER H +24BE; C; 24D8; # CIRCLED LATIN CAPITAL LETTER I +24BF; C; 24D9; # CIRCLED LATIN CAPITAL LETTER J +24C0; C; 24DA; # CIRCLED LATIN CAPITAL LETTER K +24C1; C; 24DB; # CIRCLED LATIN CAPITAL LETTER L +24C2; C; 24DC; # CIRCLED LATIN CAPITAL LETTER M +24C3; C; 24DD; # CIRCLED LATIN CAPITAL LETTER N +24C4; C; 24DE; # CIRCLED LATIN CAPITAL LETTER O +24C5; C; 24DF; # CIRCLED LATIN CAPITAL LETTER P +24C6; C; 24E0; # CIRCLED LATIN CAPITAL LETTER Q +24C7; C; 24E1; # CIRCLED LATIN CAPITAL LETTER R +24C8; C; 24E2; # CIRCLED LATIN CAPITAL LETTER S +24C9; C; 24E3; # CIRCLED LATIN CAPITAL LETTER T +24CA; C; 24E4; # CIRCLED LATIN CAPITAL LETTER U +24CB; C; 24E5; # CIRCLED LATIN CAPITAL LETTER V +24CC; C; 24E6; # CIRCLED LATIN CAPITAL LETTER W +24CD; C; 24E7; # CIRCLED LATIN CAPITAL LETTER X +24CE; C; 24E8; # CIRCLED LATIN CAPITAL LETTER Y +24CF; C; 24E9; # CIRCLED LATIN CAPITAL LETTER Z +2C00; C; 2C30; # GLAGOLITIC CAPITAL LETTER AZU +2C01; C; 2C31; # GLAGOLITIC CAPITAL LETTER BUKY +2C02; C; 2C32; # GLAGOLITIC CAPITAL LETTER VEDE +2C03; C; 2C33; # GLAGOLITIC CAPITAL LETTER GLAGOLI +2C04; C; 2C34; # GLAGOLITIC CAPITAL LETTER DOBRO +2C05; C; 2C35; # GLAGOLITIC CAPITAL LETTER YESTU +2C06; C; 2C36; # GLAGOLITIC CAPITAL LETTER ZHIVETE +2C07; C; 2C37; # GLAGOLITIC CAPITAL LETTER DZELO +2C08; C; 2C38; # GLAGOLITIC CAPITAL LETTER ZEMLJA +2C09; C; 2C39; # GLAGOLITIC CAPITAL LETTER IZHE +2C0A; C; 2C3A; # GLAGOLITIC CAPITAL LETTER INITIAL IZHE +2C0B; C; 2C3B; # GLAGOLITIC CAPITAL LETTER I +2C0C; C; 2C3C; # GLAGOLITIC CAPITAL LETTER DJERVI +2C0D; C; 2C3D; # GLAGOLITIC CAPITAL LETTER KAKO +2C0E; C; 2C3E; # GLAGOLITIC CAPITAL LETTER LJUDIJE +2C0F; C; 2C3F; # GLAGOLITIC CAPITAL LETTER MYSLITE +2C10; C; 2C40; # GLAGOLITIC CAPITAL LETTER NASHI +2C11; C; 2C41; # GLAGOLITIC CAPITAL LETTER ONU +2C12; C; 2C42; # GLAGOLITIC CAPITAL LETTER POKOJI +2C13; C; 2C43; # GLAGOLITIC CAPITAL LETTER RITSI +2C14; C; 2C44; # GLAGOLITIC CAPITAL LETTER SLOVO +2C15; C; 2C45; # GLAGOLITIC CAPITAL LETTER TVRIDO +2C16; C; 2C46; # GLAGOLITIC CAPITAL LETTER UKU +2C17; C; 2C47; # GLAGOLITIC CAPITAL LETTER FRITU +2C18; C; 2C48; # GLAGOLITIC CAPITAL LETTER HERU +2C19; C; 2C49; # GLAGOLITIC CAPITAL LETTER OTU +2C1A; C; 2C4A; # GLAGOLITIC CAPITAL LETTER PE +2C1B; C; 2C4B; # GLAGOLITIC CAPITAL LETTER SHTA +2C1C; C; 2C4C; # GLAGOLITIC CAPITAL LETTER TSI +2C1D; C; 2C4D; # GLAGOLITIC CAPITAL LETTER CHRIVI +2C1E; C; 2C4E; # GLAGOLITIC CAPITAL LETTER SHA +2C1F; C; 2C4F; # GLAGOLITIC CAPITAL LETTER YERU +2C20; C; 2C50; # GLAGOLITIC CAPITAL LETTER YERI +2C21; C; 2C51; # GLAGOLITIC CAPITAL LETTER YATI +2C22; C; 2C52; # GLAGOLITIC CAPITAL LETTER SPIDERY HA +2C23; C; 2C53; # GLAGOLITIC CAPITAL LETTER YU +2C24; C; 2C54; # GLAGOLITIC CAPITAL LETTER SMALL YUS +2C25; C; 2C55; # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL +2C26; C; 2C56; # GLAGOLITIC CAPITAL LETTER YO +2C27; C; 2C57; # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS +2C28; C; 2C58; # GLAGOLITIC CAPITAL LETTER BIG YUS +2C29; C; 2C59; # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS +2C2A; C; 2C5A; # GLAGOLITIC CAPITAL LETTER FITA +2C2B; C; 2C5B; # GLAGOLITIC CAPITAL LETTER IZHITSA +2C2C; C; 2C5C; # GLAGOLITIC CAPITAL LETTER SHTAPIC +2C2D; C; 2C5D; # GLAGOLITIC CAPITAL LETTER TROKUTASTI A +2C2E; C; 2C5E; # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C60; C; 2C61; # LATIN CAPITAL LETTER L WITH DOUBLE BAR +2C62; C; 026B; # LATIN CAPITAL LETTER L WITH MIDDLE TILDE +2C63; C; 1D7D; # LATIN CAPITAL LETTER P WITH STROKE +2C64; C; 027D; # LATIN CAPITAL LETTER R WITH TAIL +2C67; C; 2C68; # LATIN CAPITAL LETTER H WITH DESCENDER +2C69; C; 2C6A; # LATIN CAPITAL LETTER K WITH DESCENDER +2C6B; C; 2C6C; # LATIN CAPITAL LETTER Z WITH DESCENDER +2C6D; C; 0251; # LATIN CAPITAL LETTER ALPHA +2C6E; C; 0271; # LATIN CAPITAL LETTER M WITH HOOK +2C6F; C; 0250; # LATIN CAPITAL LETTER TURNED A +2C70; C; 0252; # LATIN CAPITAL LETTER TURNED ALPHA +2C72; C; 2C73; # LATIN CAPITAL LETTER W WITH HOOK +2C75; C; 2C76; # LATIN CAPITAL LETTER HALF H +2C7E; C; 023F; # LATIN CAPITAL LETTER S WITH SWASH TAIL +2C7F; C; 0240; # LATIN CAPITAL LETTER Z WITH SWASH TAIL +2C80; C; 2C81; # COPTIC CAPITAL LETTER ALFA +2C82; C; 2C83; # COPTIC CAPITAL LETTER VIDA +2C84; C; 2C85; # COPTIC CAPITAL LETTER GAMMA +2C86; C; 2C87; # COPTIC CAPITAL LETTER DALDA +2C88; C; 2C89; # COPTIC CAPITAL LETTER EIE +2C8A; C; 2C8B; # COPTIC CAPITAL LETTER SOU +2C8C; C; 2C8D; # COPTIC CAPITAL LETTER ZATA +2C8E; C; 2C8F; # COPTIC CAPITAL LETTER HATE +2C90; C; 2C91; # COPTIC CAPITAL LETTER THETHE +2C92; C; 2C93; # COPTIC CAPITAL LETTER IAUDA +2C94; C; 2C95; # COPTIC CAPITAL LETTER KAPA +2C96; C; 2C97; # COPTIC CAPITAL LETTER LAULA +2C98; C; 2C99; # COPTIC CAPITAL LETTER MI +2C9A; C; 2C9B; # COPTIC CAPITAL LETTER NI +2C9C; C; 2C9D; # COPTIC CAPITAL LETTER KSI +2C9E; C; 2C9F; # COPTIC CAPITAL LETTER O +2CA0; C; 2CA1; # COPTIC CAPITAL LETTER PI +2CA2; C; 2CA3; # COPTIC CAPITAL LETTER RO +2CA4; C; 2CA5; # COPTIC CAPITAL LETTER SIMA +2CA6; C; 2CA7; # COPTIC CAPITAL LETTER TAU +2CA8; C; 2CA9; # COPTIC CAPITAL LETTER UA +2CAA; C; 2CAB; # COPTIC CAPITAL LETTER FI +2CAC; C; 2CAD; # COPTIC CAPITAL LETTER KHI +2CAE; C; 2CAF; # COPTIC CAPITAL LETTER PSI +2CB0; C; 2CB1; # COPTIC CAPITAL LETTER OOU +2CB2; C; 2CB3; # COPTIC CAPITAL LETTER DIALECT-P ALEF +2CB4; C; 2CB5; # COPTIC CAPITAL LETTER OLD COPTIC AIN +2CB6; C; 2CB7; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE +2CB8; C; 2CB9; # COPTIC CAPITAL LETTER DIALECT-P KAPA +2CBA; C; 2CBB; # COPTIC CAPITAL LETTER DIALECT-P NI +2CBC; C; 2CBD; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI +2CBE; C; 2CBF; # COPTIC CAPITAL LETTER OLD COPTIC OOU +2CC0; C; 2CC1; # COPTIC CAPITAL LETTER SAMPI +2CC2; C; 2CC3; # COPTIC CAPITAL LETTER CROSSED SHEI +2CC4; C; 2CC5; # COPTIC CAPITAL LETTER OLD COPTIC SHEI +2CC6; C; 2CC7; # COPTIC CAPITAL LETTER OLD COPTIC ESH +2CC8; C; 2CC9; # COPTIC CAPITAL LETTER AKHMIMIC KHEI +2CCA; C; 2CCB; # COPTIC CAPITAL LETTER DIALECT-P HORI +2CCC; C; 2CCD; # COPTIC CAPITAL LETTER OLD COPTIC HORI +2CCE; C; 2CCF; # COPTIC CAPITAL LETTER OLD COPTIC HA +2CD0; C; 2CD1; # COPTIC CAPITAL LETTER L-SHAPED HA +2CD2; C; 2CD3; # COPTIC CAPITAL LETTER OLD COPTIC HEI +2CD4; C; 2CD5; # COPTIC CAPITAL LETTER OLD COPTIC HAT +2CD6; C; 2CD7; # COPTIC CAPITAL LETTER OLD COPTIC GANGIA +2CD8; C; 2CD9; # COPTIC CAPITAL LETTER OLD COPTIC DJA +2CDA; C; 2CDB; # COPTIC CAPITAL LETTER OLD COPTIC SHIMA +2CDC; C; 2CDD; # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA +2CDE; C; 2CDF; # COPTIC CAPITAL LETTER OLD NUBIAN NGI +2CE0; C; 2CE1; # COPTIC CAPITAL LETTER OLD NUBIAN NYI +2CE2; C; 2CE3; # COPTIC CAPITAL LETTER OLD NUBIAN WAU +2CEB; C; 2CEC; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI +2CED; C; 2CEE; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA +2CF2; C; 2CF3; # COPTIC CAPITAL LETTER BOHAIRIC KHEI +A640; C; A641; # CYRILLIC CAPITAL LETTER ZEMLYA +A642; C; A643; # CYRILLIC CAPITAL LETTER DZELO +A644; C; A645; # CYRILLIC CAPITAL LETTER REVERSED DZE +A646; C; A647; # CYRILLIC CAPITAL LETTER IOTA +A648; C; A649; # CYRILLIC CAPITAL LETTER DJERV +A64A; C; A64B; # CYRILLIC CAPITAL LETTER MONOGRAPH UK +A64C; C; A64D; # CYRILLIC CAPITAL LETTER BROAD OMEGA +A64E; C; A64F; # CYRILLIC CAPITAL LETTER NEUTRAL YER +A650; C; A651; # CYRILLIC CAPITAL LETTER YERU WITH BACK YER +A652; C; A653; # CYRILLIC CAPITAL LETTER IOTIFIED YAT +A654; C; A655; # CYRILLIC CAPITAL LETTER REVERSED YU +A656; C; A657; # CYRILLIC CAPITAL LETTER IOTIFIED A +A658; C; A659; # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS +A65A; C; A65B; # CYRILLIC CAPITAL LETTER BLENDED YUS +A65C; C; A65D; # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS +A65E; C; A65F; # CYRILLIC CAPITAL LETTER YN +A660; C; A661; # CYRILLIC CAPITAL LETTER REVERSED TSE +A662; C; A663; # CYRILLIC CAPITAL LETTER SOFT DE +A664; C; A665; # CYRILLIC CAPITAL LETTER SOFT EL +A666; C; A667; # CYRILLIC CAPITAL LETTER SOFT EM +A668; C; A669; # CYRILLIC CAPITAL LETTER MONOCULAR O +A66A; C; A66B; # CYRILLIC CAPITAL LETTER BINOCULAR O +A66C; C; A66D; # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O +A680; C; A681; # CYRILLIC CAPITAL LETTER DWE +A682; C; A683; # CYRILLIC CAPITAL LETTER DZWE +A684; C; A685; # CYRILLIC CAPITAL LETTER ZHWE +A686; C; A687; # CYRILLIC CAPITAL LETTER CCHE +A688; C; A689; # CYRILLIC CAPITAL LETTER DZZE +A68A; C; A68B; # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK +A68C; C; A68D; # CYRILLIC CAPITAL LETTER TWE +A68E; C; A68F; # CYRILLIC CAPITAL LETTER TSWE +A690; C; A691; # CYRILLIC CAPITAL LETTER TSSE +A692; C; A693; # CYRILLIC CAPITAL LETTER TCHE +A694; C; A695; # CYRILLIC CAPITAL LETTER HWE +A696; C; A697; # CYRILLIC CAPITAL LETTER SHWE +A698; C; A699; # CYRILLIC CAPITAL LETTER DOUBLE O +A69A; C; A69B; # CYRILLIC CAPITAL LETTER CROSSED O +A722; C; A723; # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF +A724; C; A725; # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN +A726; C; A727; # LATIN CAPITAL LETTER HENG +A728; C; A729; # LATIN CAPITAL LETTER TZ +A72A; C; A72B; # LATIN CAPITAL LETTER TRESILLO +A72C; C; A72D; # LATIN CAPITAL LETTER CUATRILLO +A72E; C; A72F; # LATIN CAPITAL LETTER CUATRILLO WITH COMMA +A732; C; A733; # LATIN CAPITAL LETTER AA +A734; C; A735; # LATIN CAPITAL LETTER AO +A736; C; A737; # LATIN CAPITAL LETTER AU +A738; C; A739; # LATIN CAPITAL LETTER AV +A73A; C; A73B; # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR +A73C; C; A73D; # LATIN CAPITAL LETTER AY +A73E; C; A73F; # LATIN CAPITAL LETTER REVERSED C WITH DOT +A740; C; A741; # LATIN CAPITAL LETTER K WITH STROKE +A742; C; A743; # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE +A744; C; A745; # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE +A746; C; A747; # LATIN CAPITAL LETTER BROKEN L +A748; C; A749; # LATIN CAPITAL LETTER L WITH HIGH STROKE +A74A; C; A74B; # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY +A74C; C; A74D; # LATIN CAPITAL LETTER O WITH LOOP +A74E; C; A74F; # LATIN CAPITAL LETTER OO +A750; C; A751; # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER +A752; C; A753; # LATIN CAPITAL LETTER P WITH FLOURISH +A754; C; A755; # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL +A756; C; A757; # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER +A758; C; A759; # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE +A75A; C; A75B; # LATIN CAPITAL LETTER R ROTUNDA +A75C; C; A75D; # LATIN CAPITAL LETTER RUM ROTUNDA +A75E; C; A75F; # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE +A760; C; A761; # LATIN CAPITAL LETTER VY +A762; C; A763; # LATIN CAPITAL LETTER VISIGOTHIC Z +A764; C; A765; # LATIN CAPITAL LETTER THORN WITH STROKE +A766; C; A767; # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER +A768; C; A769; # LATIN CAPITAL LETTER VEND +A76A; C; A76B; # LATIN CAPITAL LETTER ET +A76C; C; A76D; # LATIN CAPITAL LETTER IS +A76E; C; A76F; # LATIN CAPITAL LETTER CON +A779; C; A77A; # LATIN CAPITAL LETTER INSULAR D +A77B; C; A77C; # LATIN CAPITAL LETTER INSULAR F +A77D; C; 1D79; # LATIN CAPITAL LETTER INSULAR G +A77E; C; A77F; # LATIN CAPITAL LETTER TURNED INSULAR G +A780; C; A781; # LATIN CAPITAL LETTER TURNED L +A782; C; A783; # LATIN CAPITAL LETTER INSULAR R +A784; C; A785; # LATIN CAPITAL LETTER INSULAR S +A786; C; A787; # LATIN CAPITAL LETTER INSULAR T +A78B; C; A78C; # LATIN CAPITAL LETTER SALTILLO +A78D; C; 0265; # LATIN CAPITAL LETTER TURNED H +A790; C; A791; # LATIN CAPITAL LETTER N WITH DESCENDER +A792; C; A793; # LATIN CAPITAL LETTER C WITH BAR +A796; C; A797; # LATIN CAPITAL LETTER B WITH FLOURISH +A798; C; A799; # LATIN CAPITAL LETTER F WITH STROKE +A79A; C; A79B; # LATIN CAPITAL LETTER VOLAPUK AE +A79C; C; A79D; # LATIN CAPITAL LETTER VOLAPUK OE +A79E; C; A79F; # LATIN CAPITAL LETTER VOLAPUK UE +A7A0; C; A7A1; # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE +A7A2; C; A7A3; # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE +A7A4; C; A7A5; # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE +A7A6; C; A7A7; # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE +A7A8; C; A7A9; # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE +A7AA; C; 0266; # LATIN CAPITAL LETTER H WITH HOOK +A7AB; C; 025C; # LATIN CAPITAL LETTER REVERSED OPEN E +A7AC; C; 0261; # LATIN CAPITAL LETTER SCRIPT G +A7AD; C; 026C; # LATIN CAPITAL LETTER L WITH BELT +A7AE; C; 026A; # LATIN CAPITAL LETTER SMALL CAPITAL I +A7B0; C; 029E; # LATIN CAPITAL LETTER TURNED K +A7B1; C; 0287; # LATIN CAPITAL LETTER TURNED T +A7B2; C; 029D; # LATIN CAPITAL LETTER J WITH CROSSED-TAIL +A7B3; C; AB53; # LATIN CAPITAL LETTER CHI +A7B4; C; A7B5; # LATIN CAPITAL LETTER BETA +A7B6; C; A7B7; # LATIN CAPITAL LETTER OMEGA +A7B8; C; A7B9; # LATIN CAPITAL LETTER U WITH STROKE +AB70; C; 13A0; # CHEROKEE SMALL LETTER A +AB71; C; 13A1; # CHEROKEE SMALL LETTER E +AB72; C; 13A2; # CHEROKEE SMALL LETTER I +AB73; C; 13A3; # CHEROKEE SMALL LETTER O +AB74; C; 13A4; # CHEROKEE SMALL LETTER U +AB75; C; 13A5; # CHEROKEE SMALL LETTER V +AB76; C; 13A6; # CHEROKEE SMALL LETTER GA +AB77; C; 13A7; # CHEROKEE SMALL LETTER KA +AB78; C; 13A8; # CHEROKEE SMALL LETTER GE +AB79; C; 13A9; # CHEROKEE SMALL LETTER GI +AB7A; C; 13AA; # CHEROKEE SMALL LETTER GO +AB7B; C; 13AB; # CHEROKEE SMALL LETTER GU +AB7C; C; 13AC; # CHEROKEE SMALL LETTER GV +AB7D; C; 13AD; # CHEROKEE SMALL LETTER HA +AB7E; C; 13AE; # CHEROKEE SMALL LETTER HE +AB7F; C; 13AF; # CHEROKEE SMALL LETTER HI +AB80; C; 13B0; # CHEROKEE SMALL LETTER HO +AB81; C; 13B1; # CHEROKEE SMALL LETTER HU +AB82; C; 13B2; # CHEROKEE SMALL LETTER HV +AB83; C; 13B3; # CHEROKEE SMALL LETTER LA +AB84; C; 13B4; # CHEROKEE SMALL LETTER LE +AB85; C; 13B5; # CHEROKEE SMALL LETTER LI +AB86; C; 13B6; # CHEROKEE SMALL LETTER LO +AB87; C; 13B7; # CHEROKEE SMALL LETTER LU +AB88; C; 13B8; # CHEROKEE SMALL LETTER LV +AB89; C; 13B9; # CHEROKEE SMALL LETTER MA +AB8A; C; 13BA; # CHEROKEE SMALL LETTER ME +AB8B; C; 13BB; # CHEROKEE SMALL LETTER MI +AB8C; C; 13BC; # CHEROKEE SMALL LETTER MO +AB8D; C; 13BD; # CHEROKEE SMALL LETTER MU +AB8E; C; 13BE; # CHEROKEE SMALL LETTER NA +AB8F; C; 13BF; # CHEROKEE SMALL LETTER HNA +AB90; C; 13C0; # CHEROKEE SMALL LETTER NAH +AB91; C; 13C1; # CHEROKEE SMALL LETTER NE +AB92; C; 13C2; # CHEROKEE SMALL LETTER NI +AB93; C; 13C3; # CHEROKEE SMALL LETTER NO +AB94; C; 13C4; # CHEROKEE SMALL LETTER NU +AB95; C; 13C5; # CHEROKEE SMALL LETTER NV +AB96; C; 13C6; # CHEROKEE SMALL LETTER QUA +AB97; C; 13C7; # CHEROKEE SMALL LETTER QUE +AB98; C; 13C8; # CHEROKEE SMALL LETTER QUI +AB99; C; 13C9; # CHEROKEE SMALL LETTER QUO +AB9A; C; 13CA; # CHEROKEE SMALL LETTER QUU +AB9B; C; 13CB; # CHEROKEE SMALL LETTER QUV +AB9C; C; 13CC; # CHEROKEE SMALL LETTER SA +AB9D; C; 13CD; # CHEROKEE SMALL LETTER S +AB9E; C; 13CE; # CHEROKEE SMALL LETTER SE +AB9F; C; 13CF; # CHEROKEE SMALL LETTER SI +ABA0; C; 13D0; # CHEROKEE SMALL LETTER SO +ABA1; C; 13D1; # CHEROKEE SMALL LETTER SU +ABA2; C; 13D2; # CHEROKEE SMALL LETTER SV +ABA3; C; 13D3; # CHEROKEE SMALL LETTER DA +ABA4; C; 13D4; # CHEROKEE SMALL LETTER TA +ABA5; C; 13D5; # CHEROKEE SMALL LETTER DE +ABA6; C; 13D6; # CHEROKEE SMALL LETTER TE +ABA7; C; 13D7; # CHEROKEE SMALL LETTER DI +ABA8; C; 13D8; # CHEROKEE SMALL LETTER TI +ABA9; C; 13D9; # CHEROKEE SMALL LETTER DO +ABAA; C; 13DA; # CHEROKEE SMALL LETTER DU +ABAB; C; 13DB; # CHEROKEE SMALL LETTER DV +ABAC; C; 13DC; # CHEROKEE SMALL LETTER DLA +ABAD; C; 13DD; # CHEROKEE SMALL LETTER TLA +ABAE; C; 13DE; # CHEROKEE SMALL LETTER TLE +ABAF; C; 13DF; # CHEROKEE SMALL LETTER TLI +ABB0; C; 13E0; # CHEROKEE SMALL LETTER TLO +ABB1; C; 13E1; # CHEROKEE SMALL LETTER TLU +ABB2; C; 13E2; # CHEROKEE SMALL LETTER TLV +ABB3; C; 13E3; # CHEROKEE SMALL LETTER TSA +ABB4; C; 13E4; # CHEROKEE SMALL LETTER TSE +ABB5; C; 13E5; # CHEROKEE SMALL LETTER TSI +ABB6; C; 13E6; # CHEROKEE SMALL LETTER TSO +ABB7; C; 13E7; # CHEROKEE SMALL LETTER TSU +ABB8; C; 13E8; # CHEROKEE SMALL LETTER TSV +ABB9; C; 13E9; # CHEROKEE SMALL LETTER WA +ABBA; C; 13EA; # CHEROKEE SMALL LETTER WE +ABBB; C; 13EB; # CHEROKEE SMALL LETTER WI +ABBC; C; 13EC; # CHEROKEE SMALL LETTER WO +ABBD; C; 13ED; # CHEROKEE SMALL LETTER WU +ABBE; C; 13EE; # CHEROKEE SMALL LETTER WV +ABBF; C; 13EF; # CHEROKEE SMALL LETTER YA +FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF +FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI +FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL +FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI +FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL +FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T +FB06; F; 0073 0074; # LATIN SMALL LIGATURE ST +FB13; F; 0574 0576; # ARMENIAN SMALL LIGATURE MEN NOW +FB14; F; 0574 0565; # ARMENIAN SMALL LIGATURE MEN ECH +FB15; F; 0574 056B; # ARMENIAN SMALL LIGATURE MEN INI +FB16; F; 057E 0576; # ARMENIAN SMALL LIGATURE VEW NOW +FB17; F; 0574 056D; # ARMENIAN SMALL LIGATURE MEN XEH +FF21; C; FF41; # FULLWIDTH LATIN CAPITAL LETTER A +FF22; C; FF42; # FULLWIDTH LATIN CAPITAL LETTER B +FF23; C; FF43; # FULLWIDTH LATIN CAPITAL LETTER C +FF24; C; FF44; # FULLWIDTH LATIN CAPITAL LETTER D +FF25; C; FF45; # FULLWIDTH LATIN CAPITAL LETTER E +FF26; C; FF46; # FULLWIDTH LATIN CAPITAL LETTER F +FF27; C; FF47; # FULLWIDTH LATIN CAPITAL LETTER G +FF28; C; FF48; # FULLWIDTH LATIN CAPITAL LETTER H +FF29; C; FF49; # FULLWIDTH LATIN CAPITAL LETTER I +FF2A; C; FF4A; # FULLWIDTH LATIN CAPITAL LETTER J +FF2B; C; FF4B; # FULLWIDTH LATIN CAPITAL LETTER K +FF2C; C; FF4C; # FULLWIDTH LATIN CAPITAL LETTER L +FF2D; C; FF4D; # FULLWIDTH LATIN CAPITAL LETTER M +FF2E; C; FF4E; # FULLWIDTH LATIN CAPITAL LETTER N +FF2F; C; FF4F; # FULLWIDTH LATIN CAPITAL LETTER O +FF30; C; FF50; # FULLWIDTH LATIN CAPITAL LETTER P +FF31; C; FF51; # FULLWIDTH LATIN CAPITAL LETTER Q +FF32; C; FF52; # FULLWIDTH LATIN CAPITAL LETTER R +FF33; C; FF53; # FULLWIDTH LATIN CAPITAL LETTER S +FF34; C; FF54; # FULLWIDTH LATIN CAPITAL LETTER T +FF35; C; FF55; # FULLWIDTH LATIN CAPITAL LETTER U +FF36; C; FF56; # FULLWIDTH LATIN CAPITAL LETTER V +FF37; C; FF57; # FULLWIDTH LATIN CAPITAL LETTER W +FF38; C; FF58; # FULLWIDTH LATIN CAPITAL LETTER X +FF39; C; FF59; # FULLWIDTH LATIN CAPITAL LETTER Y +FF3A; C; FF5A; # FULLWIDTH LATIN CAPITAL LETTER Z +10400; C; 10428; # DESERET CAPITAL LETTER LONG I +10401; C; 10429; # DESERET CAPITAL LETTER LONG E +10402; C; 1042A; # DESERET CAPITAL LETTER LONG A +10403; C; 1042B; # DESERET CAPITAL LETTER LONG AH +10404; C; 1042C; # DESERET CAPITAL LETTER LONG O +10405; C; 1042D; # DESERET CAPITAL LETTER LONG OO +10406; C; 1042E; # DESERET CAPITAL LETTER SHORT I +10407; C; 1042F; # DESERET CAPITAL LETTER SHORT E +10408; C; 10430; # DESERET CAPITAL LETTER SHORT A +10409; C; 10431; # DESERET CAPITAL LETTER SHORT AH +1040A; C; 10432; # DESERET CAPITAL LETTER SHORT O +1040B; C; 10433; # DESERET CAPITAL LETTER SHORT OO +1040C; C; 10434; # DESERET CAPITAL LETTER AY +1040D; C; 10435; # DESERET CAPITAL LETTER OW +1040E; C; 10436; # DESERET CAPITAL LETTER WU +1040F; C; 10437; # DESERET CAPITAL LETTER YEE +10410; C; 10438; # DESERET CAPITAL LETTER H +10411; C; 10439; # DESERET CAPITAL LETTER PEE +10412; C; 1043A; # DESERET CAPITAL LETTER BEE +10413; C; 1043B; # DESERET CAPITAL LETTER TEE +10414; C; 1043C; # DESERET CAPITAL LETTER DEE +10415; C; 1043D; # DESERET CAPITAL LETTER CHEE +10416; C; 1043E; # DESERET CAPITAL LETTER JEE +10417; C; 1043F; # DESERET CAPITAL LETTER KAY +10418; C; 10440; # DESERET CAPITAL LETTER GAY +10419; C; 10441; # DESERET CAPITAL LETTER EF +1041A; C; 10442; # DESERET CAPITAL LETTER VEE +1041B; C; 10443; # DESERET CAPITAL LETTER ETH +1041C; C; 10444; # DESERET CAPITAL LETTER THEE +1041D; C; 10445; # DESERET CAPITAL LETTER ES +1041E; C; 10446; # DESERET CAPITAL LETTER ZEE +1041F; C; 10447; # DESERET CAPITAL LETTER ESH +10420; C; 10448; # DESERET CAPITAL LETTER ZHEE +10421; C; 10449; # DESERET CAPITAL LETTER ER +10422; C; 1044A; # DESERET CAPITAL LETTER EL +10423; C; 1044B; # DESERET CAPITAL LETTER EM +10424; C; 1044C; # DESERET CAPITAL LETTER EN +10425; C; 1044D; # DESERET CAPITAL LETTER ENG +10426; C; 1044E; # DESERET CAPITAL LETTER OI +10427; C; 1044F; # DESERET CAPITAL LETTER EW +104B0; C; 104D8; # OSAGE CAPITAL LETTER A +104B1; C; 104D9; # OSAGE CAPITAL LETTER AI +104B2; C; 104DA; # OSAGE CAPITAL LETTER AIN +104B3; C; 104DB; # OSAGE CAPITAL LETTER AH +104B4; C; 104DC; # OSAGE CAPITAL LETTER BRA +104B5; C; 104DD; # OSAGE CAPITAL LETTER CHA +104B6; C; 104DE; # OSAGE CAPITAL LETTER EHCHA +104B7; C; 104DF; # OSAGE CAPITAL LETTER E +104B8; C; 104E0; # OSAGE CAPITAL LETTER EIN +104B9; C; 104E1; # OSAGE CAPITAL LETTER HA +104BA; C; 104E2; # OSAGE CAPITAL LETTER HYA +104BB; C; 104E3; # OSAGE CAPITAL LETTER I +104BC; C; 104E4; # OSAGE CAPITAL LETTER KA +104BD; C; 104E5; # OSAGE CAPITAL LETTER EHKA +104BE; C; 104E6; # OSAGE CAPITAL LETTER KYA +104BF; C; 104E7; # OSAGE CAPITAL LETTER LA +104C0; C; 104E8; # OSAGE CAPITAL LETTER MA +104C1; C; 104E9; # OSAGE CAPITAL LETTER NA +104C2; C; 104EA; # OSAGE CAPITAL LETTER O +104C3; C; 104EB; # OSAGE CAPITAL LETTER OIN +104C4; C; 104EC; # OSAGE CAPITAL LETTER PA +104C5; C; 104ED; # OSAGE CAPITAL LETTER EHPA +104C6; C; 104EE; # OSAGE CAPITAL LETTER SA +104C7; C; 104EF; # OSAGE CAPITAL LETTER SHA +104C8; C; 104F0; # OSAGE CAPITAL LETTER TA +104C9; C; 104F1; # OSAGE CAPITAL LETTER EHTA +104CA; C; 104F2; # OSAGE CAPITAL LETTER TSA +104CB; C; 104F3; # OSAGE CAPITAL LETTER EHTSA +104CC; C; 104F4; # OSAGE CAPITAL LETTER TSHA +104CD; C; 104F5; # OSAGE CAPITAL LETTER DHA +104CE; C; 104F6; # OSAGE CAPITAL LETTER U +104CF; C; 104F7; # OSAGE CAPITAL LETTER WA +104D0; C; 104F8; # OSAGE CAPITAL LETTER KHA +104D1; C; 104F9; # OSAGE CAPITAL LETTER GHA +104D2; C; 104FA; # OSAGE CAPITAL LETTER ZA +104D3; C; 104FB; # OSAGE CAPITAL LETTER ZHA +10C80; C; 10CC0; # OLD HUNGARIAN CAPITAL LETTER A +10C81; C; 10CC1; # OLD HUNGARIAN CAPITAL LETTER AA +10C82; C; 10CC2; # OLD HUNGARIAN CAPITAL LETTER EB +10C83; C; 10CC3; # OLD HUNGARIAN CAPITAL LETTER AMB +10C84; C; 10CC4; # OLD HUNGARIAN CAPITAL LETTER EC +10C85; C; 10CC5; # OLD HUNGARIAN CAPITAL LETTER ENC +10C86; C; 10CC6; # OLD HUNGARIAN CAPITAL LETTER ECS +10C87; C; 10CC7; # OLD HUNGARIAN CAPITAL LETTER ED +10C88; C; 10CC8; # OLD HUNGARIAN CAPITAL LETTER AND +10C89; C; 10CC9; # OLD HUNGARIAN CAPITAL LETTER E +10C8A; C; 10CCA; # OLD HUNGARIAN CAPITAL LETTER CLOSE E +10C8B; C; 10CCB; # OLD HUNGARIAN CAPITAL LETTER EE +10C8C; C; 10CCC; # OLD HUNGARIAN CAPITAL LETTER EF +10C8D; C; 10CCD; # OLD HUNGARIAN CAPITAL LETTER EG +10C8E; C; 10CCE; # OLD HUNGARIAN CAPITAL LETTER EGY +10C8F; C; 10CCF; # OLD HUNGARIAN CAPITAL LETTER EH +10C90; C; 10CD0; # OLD HUNGARIAN CAPITAL LETTER I +10C91; C; 10CD1; # OLD HUNGARIAN CAPITAL LETTER II +10C92; C; 10CD2; # OLD HUNGARIAN CAPITAL LETTER EJ +10C93; C; 10CD3; # OLD HUNGARIAN CAPITAL LETTER EK +10C94; C; 10CD4; # OLD HUNGARIAN CAPITAL LETTER AK +10C95; C; 10CD5; # OLD HUNGARIAN CAPITAL LETTER UNK +10C96; C; 10CD6; # OLD HUNGARIAN CAPITAL LETTER EL +10C97; C; 10CD7; # OLD HUNGARIAN CAPITAL LETTER ELY +10C98; C; 10CD8; # OLD HUNGARIAN CAPITAL LETTER EM +10C99; C; 10CD9; # OLD HUNGARIAN CAPITAL LETTER EN +10C9A; C; 10CDA; # OLD HUNGARIAN CAPITAL LETTER ENY +10C9B; C; 10CDB; # OLD HUNGARIAN CAPITAL LETTER O +10C9C; C; 10CDC; # OLD HUNGARIAN CAPITAL LETTER OO +10C9D; C; 10CDD; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE +10C9E; C; 10CDE; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE +10C9F; C; 10CDF; # OLD HUNGARIAN CAPITAL LETTER OEE +10CA0; C; 10CE0; # OLD HUNGARIAN CAPITAL LETTER EP +10CA1; C; 10CE1; # OLD HUNGARIAN CAPITAL LETTER EMP +10CA2; C; 10CE2; # OLD HUNGARIAN CAPITAL LETTER ER +10CA3; C; 10CE3; # OLD HUNGARIAN CAPITAL LETTER SHORT ER +10CA4; C; 10CE4; # OLD HUNGARIAN CAPITAL LETTER ES +10CA5; C; 10CE5; # OLD HUNGARIAN CAPITAL LETTER ESZ +10CA6; C; 10CE6; # OLD HUNGARIAN CAPITAL LETTER ET +10CA7; C; 10CE7; # OLD HUNGARIAN CAPITAL LETTER ENT +10CA8; C; 10CE8; # OLD HUNGARIAN CAPITAL LETTER ETY +10CA9; C; 10CE9; # OLD HUNGARIAN CAPITAL LETTER ECH +10CAA; C; 10CEA; # OLD HUNGARIAN CAPITAL LETTER U +10CAB; C; 10CEB; # OLD HUNGARIAN CAPITAL LETTER UU +10CAC; C; 10CEC; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE +10CAD; C; 10CED; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE +10CAE; C; 10CEE; # OLD HUNGARIAN CAPITAL LETTER EV +10CAF; C; 10CEF; # OLD HUNGARIAN CAPITAL LETTER EZ +10CB0; C; 10CF0; # OLD HUNGARIAN CAPITAL LETTER EZS +10CB1; C; 10CF1; # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN +10CB2; C; 10CF2; # OLD HUNGARIAN CAPITAL LETTER US +118A0; C; 118C0; # WARANG CITI CAPITAL LETTER NGAA +118A1; C; 118C1; # WARANG CITI CAPITAL LETTER A +118A2; C; 118C2; # WARANG CITI CAPITAL LETTER WI +118A3; C; 118C3; # WARANG CITI CAPITAL LETTER YU +118A4; C; 118C4; # WARANG CITI CAPITAL LETTER YA +118A5; C; 118C5; # WARANG CITI CAPITAL LETTER YO +118A6; C; 118C6; # WARANG CITI CAPITAL LETTER II +118A7; C; 118C7; # WARANG CITI CAPITAL LETTER UU +118A8; C; 118C8; # WARANG CITI CAPITAL LETTER E +118A9; C; 118C9; # WARANG CITI CAPITAL LETTER O +118AA; C; 118CA; # WARANG CITI CAPITAL LETTER ANG +118AB; C; 118CB; # WARANG CITI CAPITAL LETTER GA +118AC; C; 118CC; # WARANG CITI CAPITAL LETTER KO +118AD; C; 118CD; # WARANG CITI CAPITAL LETTER ENY +118AE; C; 118CE; # WARANG CITI CAPITAL LETTER YUJ +118AF; C; 118CF; # WARANG CITI CAPITAL LETTER UC +118B0; C; 118D0; # WARANG CITI CAPITAL LETTER ENN +118B1; C; 118D1; # WARANG CITI CAPITAL LETTER ODD +118B2; C; 118D2; # WARANG CITI CAPITAL LETTER TTE +118B3; C; 118D3; # WARANG CITI CAPITAL LETTER NUNG +118B4; C; 118D4; # WARANG CITI CAPITAL LETTER DA +118B5; C; 118D5; # WARANG CITI CAPITAL LETTER AT +118B6; C; 118D6; # WARANG CITI CAPITAL LETTER AM +118B7; C; 118D7; # WARANG CITI CAPITAL LETTER BU +118B8; C; 118D8; # WARANG CITI CAPITAL LETTER PU +118B9; C; 118D9; # WARANG CITI CAPITAL LETTER HIYO +118BA; C; 118DA; # WARANG CITI CAPITAL LETTER HOLO +118BB; C; 118DB; # WARANG CITI CAPITAL LETTER HORR +118BC; C; 118DC; # WARANG CITI CAPITAL LETTER HAR +118BD; C; 118DD; # WARANG CITI CAPITAL LETTER SSUU +118BE; C; 118DE; # WARANG CITI CAPITAL LETTER SII +118BF; C; 118DF; # WARANG CITI CAPITAL LETTER VIYO +16E40; C; 16E60; # MEDEFAIDRIN CAPITAL LETTER M +16E41; C; 16E61; # MEDEFAIDRIN CAPITAL LETTER S +16E42; C; 16E62; # MEDEFAIDRIN CAPITAL LETTER V +16E43; C; 16E63; # MEDEFAIDRIN CAPITAL LETTER W +16E44; C; 16E64; # MEDEFAIDRIN CAPITAL LETTER ATIU +16E45; C; 16E65; # MEDEFAIDRIN CAPITAL LETTER Z +16E46; C; 16E66; # MEDEFAIDRIN CAPITAL LETTER KP +16E47; C; 16E67; # MEDEFAIDRIN CAPITAL LETTER P +16E48; C; 16E68; # MEDEFAIDRIN CAPITAL LETTER T +16E49; C; 16E69; # MEDEFAIDRIN CAPITAL LETTER G +16E4A; C; 16E6A; # MEDEFAIDRIN CAPITAL LETTER F +16E4B; C; 16E6B; # MEDEFAIDRIN CAPITAL LETTER I +16E4C; C; 16E6C; # MEDEFAIDRIN CAPITAL LETTER K +16E4D; C; 16E6D; # MEDEFAIDRIN CAPITAL LETTER A +16E4E; C; 16E6E; # MEDEFAIDRIN CAPITAL LETTER J +16E4F; C; 16E6F; # MEDEFAIDRIN CAPITAL LETTER E +16E50; C; 16E70; # MEDEFAIDRIN CAPITAL LETTER B +16E51; C; 16E71; # MEDEFAIDRIN CAPITAL LETTER C +16E52; C; 16E72; # MEDEFAIDRIN CAPITAL LETTER U +16E53; C; 16E73; # MEDEFAIDRIN CAPITAL LETTER YU +16E54; C; 16E74; # MEDEFAIDRIN CAPITAL LETTER L +16E55; C; 16E75; # MEDEFAIDRIN CAPITAL LETTER Q +16E56; C; 16E76; # MEDEFAIDRIN CAPITAL LETTER HP +16E57; C; 16E77; # MEDEFAIDRIN CAPITAL LETTER NY +16E58; C; 16E78; # MEDEFAIDRIN CAPITAL LETTER X +16E59; C; 16E79; # MEDEFAIDRIN CAPITAL LETTER D +16E5A; C; 16E7A; # MEDEFAIDRIN CAPITAL LETTER OE +16E5B; C; 16E7B; # MEDEFAIDRIN CAPITAL LETTER N +16E5C; C; 16E7C; # MEDEFAIDRIN CAPITAL LETTER R +16E5D; C; 16E7D; # MEDEFAIDRIN CAPITAL LETTER O +16E5E; C; 16E7E; # MEDEFAIDRIN CAPITAL LETTER AI +16E5F; C; 16E7F; # MEDEFAIDRIN CAPITAL LETTER Y +1E900; C; 1E922; # ADLAM CAPITAL LETTER ALIF +1E901; C; 1E923; # ADLAM CAPITAL LETTER DAALI +1E902; C; 1E924; # ADLAM CAPITAL LETTER LAAM +1E903; C; 1E925; # ADLAM CAPITAL LETTER MIIM +1E904; C; 1E926; # ADLAM CAPITAL LETTER BA +1E905; C; 1E927; # ADLAM CAPITAL LETTER SINNYIIYHE +1E906; C; 1E928; # ADLAM CAPITAL LETTER PE +1E907; C; 1E929; # ADLAM CAPITAL LETTER BHE +1E908; C; 1E92A; # ADLAM CAPITAL LETTER RA +1E909; C; 1E92B; # ADLAM CAPITAL LETTER E +1E90A; C; 1E92C; # ADLAM CAPITAL LETTER FA +1E90B; C; 1E92D; # ADLAM CAPITAL LETTER I +1E90C; C; 1E92E; # ADLAM CAPITAL LETTER O +1E90D; C; 1E92F; # ADLAM CAPITAL LETTER DHA +1E90E; C; 1E930; # ADLAM CAPITAL LETTER YHE +1E90F; C; 1E931; # ADLAM CAPITAL LETTER WAW +1E910; C; 1E932; # ADLAM CAPITAL LETTER NUN +1E911; C; 1E933; # ADLAM CAPITAL LETTER KAF +1E912; C; 1E934; # ADLAM CAPITAL LETTER YA +1E913; C; 1E935; # ADLAM CAPITAL LETTER U +1E914; C; 1E936; # ADLAM CAPITAL LETTER JIIM +1E915; C; 1E937; # ADLAM CAPITAL LETTER CHI +1E916; C; 1E938; # ADLAM CAPITAL LETTER HA +1E917; C; 1E939; # ADLAM CAPITAL LETTER QAAF +1E918; C; 1E93A; # ADLAM CAPITAL LETTER GA +1E919; C; 1E93B; # ADLAM CAPITAL LETTER NYA +1E91A; C; 1E93C; # ADLAM CAPITAL LETTER TU +1E91B; C; 1E93D; # ADLAM CAPITAL LETTER NHA +1E91C; C; 1E93E; # ADLAM CAPITAL LETTER VA +1E91D; C; 1E93F; # ADLAM CAPITAL LETTER KHA +1E91E; C; 1E940; # ADLAM CAPITAL LETTER GBE +1E91F; C; 1E941; # ADLAM CAPITAL LETTER ZAL +1E920; C; 1E942; # ADLAM CAPITAL LETTER KPO +1E921; C; 1E943; # ADLAM CAPITAL LETTER SHA +# +# EOF diff --git a/claimtrie/normalization/NFC_v11.txt b/claimtrie/normalization/NFC_v11.txt new file mode 100644 index 00000000..de6bdd91 --- /dev/null +++ b/claimtrie/normalization/NFC_v11.txt @@ -0,0 +1,2431 @@ +# Copyright (C) 2016 and later: Unicode, Inc. and others. +# License & terms of use: http://www.unicode.org/copyright.html +# Copyright (C) 1999-2016, International Business Machines +# Corporation and others. All Rights Reserved. +# +# file name: nfc.txt +# +# machine-generated by ICU preparseucd.py +# +# Complete data for Unicode NFC normalization. + +* Unicode 11.0.0 + +# Canonical_Combining_Class (ccc) values +0300..0314:230 +0315:232 +0316..0319:220 +031A:232 +031B:216 +031C..0320:220 +0321..0322:202 +0323..0326:220 +0327..0328:202 +0329..0333:220 +0334..0338:1 +0339..033C:220 +033D..0344:230 +0345:240 +0346:230 +0347..0349:220 +034A..034C:230 +034D..034E:220 +0350..0352:230 +0353..0356:220 +0357:230 +0358:232 +0359..035A:220 +035B:230 +035C:233 +035D..035E:234 +035F:233 +0360..0361:234 +0362:233 +0363..036F:230 +0483..0487:230 +0591:220 +0592..0595:230 +0596:220 +0597..0599:230 +059A:222 +059B:220 +059C..05A1:230 +05A2..05A7:220 +05A8..05A9:230 +05AA:220 +05AB..05AC:230 +05AD:222 +05AE:228 +05AF:230 +05B0:10 +05B1:11 +05B2:12 +05B3:13 +05B4:14 +05B5:15 +05B6:16 +05B7:17 +05B8:18 +05B9..05BA:19 +05BB:20 +05BC:21 +05BD:22 +05BF:23 +05C1:24 +05C2:25 +05C4:230 +05C5:220 +05C7:18 +0610..0617:230 +0618:30 +0619:31 +061A:32 +064B:27 +064C:28 +064D:29 +064E:30 +064F:31 +0650:32 +0651:33 +0652:34 +0653..0654:230 +0655..0656:220 +0657..065B:230 +065C:220 +065D..065E:230 +065F:220 +0670:35 +06D6..06DC:230 +06DF..06E2:230 +06E3:220 +06E4:230 +06E7..06E8:230 +06EA:220 +06EB..06EC:230 +06ED:220 +0711:36 +0730:230 +0731:220 +0732..0733:230 +0734:220 +0735..0736:230 +0737..0739:220 +073A:230 +073B..073C:220 +073D:230 +073E:220 +073F..0741:230 +0742:220 +0743:230 +0744:220 +0745:230 +0746:220 +0747:230 +0748:220 +0749..074A:230 +07EB..07F1:230 +07F2:220 +07F3:230 +07FD:220 +0816..0819:230 +081B..0823:230 +0825..0827:230 +0829..082D:230 +0859..085B:220 +08D3:220 +08D4..08E1:230 +08E3:220 +08E4..08E5:230 +08E6:220 +08E7..08E8:230 +08E9:220 +08EA..08EC:230 +08ED..08EF:220 +08F0:27 +08F1:28 +08F2:29 +08F3..08F5:230 +08F6:220 +08F7..08F8:230 +08F9..08FA:220 +08FB..08FF:230 +093C:7 +094D:9 +0951:230 +0952:220 +0953..0954:230 +09BC:7 +09CD:9 +09FE:230 +0A3C:7 +0A4D:9 +0ABC:7 +0ACD:9 +0B3C:7 +0B4D:9 +0BCD:9 +0C4D:9 +0C55:84 +0C56:91 +0CBC:7 +0CCD:9 +0D3B..0D3C:9 +0D4D:9 +0DCA:9 +0E38..0E39:103 +0E3A:9 +0E48..0E4B:107 +0EB8..0EB9:118 +0EC8..0ECB:122 +0F18..0F19:220 +0F35:220 +0F37:220 +0F39:216 +0F71:129 +0F72:130 +0F74:132 +0F7A..0F7D:130 +0F80:130 +0F82..0F83:230 +0F84:9 +0F86..0F87:230 +0FC6:220 +1037:7 +1039..103A:9 +108D:220 +135D..135F:230 +1714:9 +1734:9 +17D2:9 +17DD:230 +18A9:228 +1939:222 +193A:230 +193B:220 +1A17:230 +1A18:220 +1A60:9 +1A75..1A7C:230 +1A7F:220 +1AB0..1AB4:230 +1AB5..1ABA:220 +1ABB..1ABC:230 +1ABD:220 +1B34:7 +1B44:9 +1B6B:230 +1B6C:220 +1B6D..1B73:230 +1BAA..1BAB:9 +1BE6:7 +1BF2..1BF3:9 +1C37:7 +1CD0..1CD2:230 +1CD4:1 +1CD5..1CD9:220 +1CDA..1CDB:230 +1CDC..1CDF:220 +1CE0:230 +1CE2..1CE8:1 +1CED:220 +1CF4:230 +1CF8..1CF9:230 +1DC0..1DC1:230 +1DC2:220 +1DC3..1DC9:230 +1DCA:220 +1DCB..1DCC:230 +1DCD:234 +1DCE:214 +1DCF:220 +1DD0:202 +1DD1..1DF5:230 +1DF6:232 +1DF7..1DF8:228 +1DF9:220 +1DFB:230 +1DFC:233 +1DFD:220 +1DFE:230 +1DFF:220 +20D0..20D1:230 +20D2..20D3:1 +20D4..20D7:230 +20D8..20DA:1 +20DB..20DC:230 +20E1:230 +20E5..20E6:1 +20E7:230 +20E8:220 +20E9:230 +20EA..20EB:1 +20EC..20EF:220 +20F0:230 +2CEF..2CF1:230 +2D7F:9 +2DE0..2DFF:230 +302A:218 +302B:228 +302C:232 +302D:222 +302E..302F:224 +3099..309A:8 +A66F:230 +A674..A67D:230 +A69E..A69F:230 +A6F0..A6F1:230 +A806:9 +A8C4:9 +A8E0..A8F1:230 +A92B..A92D:220 +A953:9 +A9B3:7 +A9C0:9 +AAB0:230 +AAB2..AAB3:230 +AAB4:220 +AAB7..AAB8:230 +AABE..AABF:230 +AAC1:230 +AAF6:9 +ABED:9 +FB1E:26 +FE20..FE26:230 +FE27..FE2D:220 +FE2E..FE2F:230 +101FD:220 +102E0:220 +10376..1037A:230 +10A0D:220 +10A0F:230 +10A38:230 +10A39:1 +10A3A:220 +10A3F:9 +10AE5:230 +10AE6:220 +10D24..10D27:230 +10F46..10F47:220 +10F48..10F4A:230 +10F4B:220 +10F4C:230 +10F4D..10F50:220 +11046:9 +1107F:9 +110B9:9 +110BA:7 +11100..11102:230 +11133..11134:9 +11173:7 +111C0:9 +111CA:7 +11235:9 +11236:7 +112E9:7 +112EA:9 +1133B..1133C:7 +1134D:9 +11366..1136C:230 +11370..11374:230 +11442:9 +11446:7 +1145E:230 +114C2:9 +114C3:7 +115BF:9 +115C0:7 +1163F:9 +116B6:9 +116B7:7 +1172B:9 +11839:9 +1183A:7 +11A34:9 +11A47:9 +11A99:9 +11C3F:9 +11D42:7 +11D44..11D45:9 +11D97:9 +16AF0..16AF4:1 +16B30..16B36:230 +1BC9E:1 +1D165..1D166:216 +1D167..1D169:1 +1D16D:226 +1D16E..1D172:216 +1D17B..1D182:220 +1D185..1D189:230 +1D18A..1D18B:220 +1D1AA..1D1AD:230 +1D242..1D244:230 +1E000..1E006:230 +1E008..1E018:230 +1E01B..1E021:230 +1E023..1E024:230 +1E026..1E02A:230 +1E8D0..1E8D6:220 +1E944..1E949:230 +1E94A:7 + +# Canonical decomposition mappings +00C0=0041 0300 +00C1=0041 0301 +00C2=0041 0302 +00C3=0041 0303 +00C4=0041 0308 +00C5=0041 030A +00C7=0043 0327 +00C8=0045 0300 +00C9=0045 0301 +00CA=0045 0302 +00CB=0045 0308 +00CC=0049 0300 +00CD=0049 0301 +00CE=0049 0302 +00CF=0049 0308 +00D1=004E 0303 +00D2=004F 0300 +00D3=004F 0301 +00D4=004F 0302 +00D5=004F 0303 +00D6=004F 0308 +00D9=0055 0300 +00DA=0055 0301 +00DB=0055 0302 +00DC=0055 0308 +00DD=0059 0301 +00E0=0061 0300 +00E1=0061 0301 +00E2=0061 0302 +00E3=0061 0303 +00E4=0061 0308 +00E5=0061 030A +00E7=0063 0327 +00E8=0065 0300 +00E9=0065 0301 +00EA=0065 0302 +00EB=0065 0308 +00EC=0069 0300 +00ED=0069 0301 +00EE=0069 0302 +00EF=0069 0308 +00F1=006E 0303 +00F2=006F 0300 +00F3=006F 0301 +00F4=006F 0302 +00F5=006F 0303 +00F6=006F 0308 +00F9=0075 0300 +00FA=0075 0301 +00FB=0075 0302 +00FC=0075 0308 +00FD=0079 0301 +00FF=0079 0308 +0100=0041 0304 +0101=0061 0304 +0102=0041 0306 +0103=0061 0306 +0104=0041 0328 +0105=0061 0328 +0106=0043 0301 +0107=0063 0301 +0108=0043 0302 +0109=0063 0302 +010A=0043 0307 +010B=0063 0307 +010C=0043 030C +010D=0063 030C +010E=0044 030C +010F=0064 030C +0112=0045 0304 +0113=0065 0304 +0114=0045 0306 +0115=0065 0306 +0116=0045 0307 +0117=0065 0307 +0118=0045 0328 +0119=0065 0328 +011A=0045 030C +011B=0065 030C +011C=0047 0302 +011D=0067 0302 +011E=0047 0306 +011F=0067 0306 +0120=0047 0307 +0121=0067 0307 +0122=0047 0327 +0123=0067 0327 +0124=0048 0302 +0125=0068 0302 +0128=0049 0303 +0129=0069 0303 +012A=0049 0304 +012B=0069 0304 +012C=0049 0306 +012D=0069 0306 +012E=0049 0328 +012F=0069 0328 +0130=0049 0307 +0134=004A 0302 +0135=006A 0302 +0136=004B 0327 +0137=006B 0327 +0139=004C 0301 +013A=006C 0301 +013B=004C 0327 +013C=006C 0327 +013D=004C 030C +013E=006C 030C +0143=004E 0301 +0144=006E 0301 +0145=004E 0327 +0146=006E 0327 +0147=004E 030C +0148=006E 030C +014C=004F 0304 +014D=006F 0304 +014E=004F 0306 +014F=006F 0306 +0150=004F 030B +0151=006F 030B +0154=0052 0301 +0155=0072 0301 +0156=0052 0327 +0157=0072 0327 +0158=0052 030C +0159=0072 030C +015A=0053 0301 +015B=0073 0301 +015C=0053 0302 +015D=0073 0302 +015E=0053 0327 +015F=0073 0327 +0160=0053 030C +0161=0073 030C +0162=0054 0327 +0163=0074 0327 +0164=0054 030C +0165=0074 030C +0168=0055 0303 +0169=0075 0303 +016A=0055 0304 +016B=0075 0304 +016C=0055 0306 +016D=0075 0306 +016E=0055 030A +016F=0075 030A +0170=0055 030B +0171=0075 030B +0172=0055 0328 +0173=0075 0328 +0174=0057 0302 +0175=0077 0302 +0176=0059 0302 +0177=0079 0302 +0178=0059 0308 +0179=005A 0301 +017A=007A 0301 +017B=005A 0307 +017C=007A 0307 +017D=005A 030C +017E=007A 030C +01A0=004F 031B +01A1=006F 031B +01AF=0055 031B +01B0=0075 031B +01CD=0041 030C +01CE=0061 030C +01CF=0049 030C +01D0=0069 030C +01D1=004F 030C +01D2=006F 030C +01D3=0055 030C +01D4=0075 030C +01D5=00DC 0304 +01D6=00FC 0304 +01D7=00DC 0301 +01D8=00FC 0301 +01D9=00DC 030C +01DA=00FC 030C +01DB=00DC 0300 +01DC=00FC 0300 +01DE=00C4 0304 +01DF=00E4 0304 +01E0=0226 0304 +01E1=0227 0304 +01E2=00C6 0304 +01E3=00E6 0304 +01E6=0047 030C +01E7=0067 030C +01E8=004B 030C +01E9=006B 030C +01EA=004F 0328 +01EB=006F 0328 +01EC=01EA 0304 +01ED=01EB 0304 +01EE=01B7 030C +01EF=0292 030C +01F0=006A 030C +01F4=0047 0301 +01F5=0067 0301 +01F8=004E 0300 +01F9=006E 0300 +01FA=00C5 0301 +01FB=00E5 0301 +01FC=00C6 0301 +01FD=00E6 0301 +01FE=00D8 0301 +01FF=00F8 0301 +0200=0041 030F +0201=0061 030F +0202=0041 0311 +0203=0061 0311 +0204=0045 030F +0205=0065 030F +0206=0045 0311 +0207=0065 0311 +0208=0049 030F +0209=0069 030F +020A=0049 0311 +020B=0069 0311 +020C=004F 030F +020D=006F 030F +020E=004F 0311 +020F=006F 0311 +0210=0052 030F +0211=0072 030F +0212=0052 0311 +0213=0072 0311 +0214=0055 030F +0215=0075 030F +0216=0055 0311 +0217=0075 0311 +0218=0053 0326 +0219=0073 0326 +021A=0054 0326 +021B=0074 0326 +021E=0048 030C +021F=0068 030C +0226=0041 0307 +0227=0061 0307 +0228=0045 0327 +0229=0065 0327 +022A=00D6 0304 +022B=00F6 0304 +022C=00D5 0304 +022D=00F5 0304 +022E=004F 0307 +022F=006F 0307 +0230=022E 0304 +0231=022F 0304 +0232=0059 0304 +0233=0079 0304 +0340>0300 +0341>0301 +0343>0313 +0344>0308 0301 +0374>02B9 +037E>003B +0385=00A8 0301 +0386=0391 0301 +0387>00B7 +0388=0395 0301 +0389=0397 0301 +038A=0399 0301 +038C=039F 0301 +038E=03A5 0301 +038F=03A9 0301 +0390=03CA 0301 +03AA=0399 0308 +03AB=03A5 0308 +03AC=03B1 0301 +03AD=03B5 0301 +03AE=03B7 0301 +03AF=03B9 0301 +03B0=03CB 0301 +03CA=03B9 0308 +03CB=03C5 0308 +03CC=03BF 0301 +03CD=03C5 0301 +03CE=03C9 0301 +03D3=03D2 0301 +03D4=03D2 0308 +0400=0415 0300 +0401=0415 0308 +0403=0413 0301 +0407=0406 0308 +040C=041A 0301 +040D=0418 0300 +040E=0423 0306 +0419=0418 0306 +0439=0438 0306 +0450=0435 0300 +0451=0435 0308 +0453=0433 0301 +0457=0456 0308 +045C=043A 0301 +045D=0438 0300 +045E=0443 0306 +0476=0474 030F +0477=0475 030F +04C1=0416 0306 +04C2=0436 0306 +04D0=0410 0306 +04D1=0430 0306 +04D2=0410 0308 +04D3=0430 0308 +04D6=0415 0306 +04D7=0435 0306 +04DA=04D8 0308 +04DB=04D9 0308 +04DC=0416 0308 +04DD=0436 0308 +04DE=0417 0308 +04DF=0437 0308 +04E2=0418 0304 +04E3=0438 0304 +04E4=0418 0308 +04E5=0438 0308 +04E6=041E 0308 +04E7=043E 0308 +04EA=04E8 0308 +04EB=04E9 0308 +04EC=042D 0308 +04ED=044D 0308 +04EE=0423 0304 +04EF=0443 0304 +04F0=0423 0308 +04F1=0443 0308 +04F2=0423 030B +04F3=0443 030B +04F4=0427 0308 +04F5=0447 0308 +04F8=042B 0308 +04F9=044B 0308 +0622=0627 0653 +0623=0627 0654 +0624=0648 0654 +0625=0627 0655 +0626=064A 0654 +06C0=06D5 0654 +06C2=06C1 0654 +06D3=06D2 0654 +0929=0928 093C +0931=0930 093C +0934=0933 093C +0958>0915 093C +0959>0916 093C +095A>0917 093C +095B>091C 093C +095C>0921 093C +095D>0922 093C +095E>092B 093C +095F>092F 093C +09CB=09C7 09BE +09CC=09C7 09D7 +09DC>09A1 09BC +09DD>09A2 09BC +09DF>09AF 09BC +0A33>0A32 0A3C +0A36>0A38 0A3C +0A59>0A16 0A3C +0A5A>0A17 0A3C +0A5B>0A1C 0A3C +0A5E>0A2B 0A3C +0B48=0B47 0B56 +0B4B=0B47 0B3E +0B4C=0B47 0B57 +0B5C>0B21 0B3C +0B5D>0B22 0B3C +0B94=0B92 0BD7 +0BCA=0BC6 0BBE +0BCB=0BC7 0BBE +0BCC=0BC6 0BD7 +0C48=0C46 0C56 +0CC0=0CBF 0CD5 +0CC7=0CC6 0CD5 +0CC8=0CC6 0CD6 +0CCA=0CC6 0CC2 +0CCB=0CCA 0CD5 +0D4A=0D46 0D3E +0D4B=0D47 0D3E +0D4C=0D46 0D57 +0DDA=0DD9 0DCA +0DDC=0DD9 0DCF +0DDD=0DDC 0DCA +0DDE=0DD9 0DDF +0F43>0F42 0FB7 +0F4D>0F4C 0FB7 +0F52>0F51 0FB7 +0F57>0F56 0FB7 +0F5C>0F5B 0FB7 +0F69>0F40 0FB5 +0F73>0F71 0F72 +0F75>0F71 0F74 +0F76>0FB2 0F80 +0F78>0FB3 0F80 +0F81>0F71 0F80 +0F93>0F92 0FB7 +0F9D>0F9C 0FB7 +0FA2>0FA1 0FB7 +0FA7>0FA6 0FB7 +0FAC>0FAB 0FB7 +0FB9>0F90 0FB5 +1026=1025 102E +1B06=1B05 1B35 +1B08=1B07 1B35 +1B0A=1B09 1B35 +1B0C=1B0B 1B35 +1B0E=1B0D 1B35 +1B12=1B11 1B35 +1B3B=1B3A 1B35 +1B3D=1B3C 1B35 +1B40=1B3E 1B35 +1B41=1B3F 1B35 +1B43=1B42 1B35 +1E00=0041 0325 +1E01=0061 0325 +1E02=0042 0307 +1E03=0062 0307 +1E04=0042 0323 +1E05=0062 0323 +1E06=0042 0331 +1E07=0062 0331 +1E08=00C7 0301 +1E09=00E7 0301 +1E0A=0044 0307 +1E0B=0064 0307 +1E0C=0044 0323 +1E0D=0064 0323 +1E0E=0044 0331 +1E0F=0064 0331 +1E10=0044 0327 +1E11=0064 0327 +1E12=0044 032D +1E13=0064 032D +1E14=0112 0300 +1E15=0113 0300 +1E16=0112 0301 +1E17=0113 0301 +1E18=0045 032D +1E19=0065 032D +1E1A=0045 0330 +1E1B=0065 0330 +1E1C=0228 0306 +1E1D=0229 0306 +1E1E=0046 0307 +1E1F=0066 0307 +1E20=0047 0304 +1E21=0067 0304 +1E22=0048 0307 +1E23=0068 0307 +1E24=0048 0323 +1E25=0068 0323 +1E26=0048 0308 +1E27=0068 0308 +1E28=0048 0327 +1E29=0068 0327 +1E2A=0048 032E +1E2B=0068 032E +1E2C=0049 0330 +1E2D=0069 0330 +1E2E=00CF 0301 +1E2F=00EF 0301 +1E30=004B 0301 +1E31=006B 0301 +1E32=004B 0323 +1E33=006B 0323 +1E34=004B 0331 +1E35=006B 0331 +1E36=004C 0323 +1E37=006C 0323 +1E38=1E36 0304 +1E39=1E37 0304 +1E3A=004C 0331 +1E3B=006C 0331 +1E3C=004C 032D +1E3D=006C 032D +1E3E=004D 0301 +1E3F=006D 0301 +1E40=004D 0307 +1E41=006D 0307 +1E42=004D 0323 +1E43=006D 0323 +1E44=004E 0307 +1E45=006E 0307 +1E46=004E 0323 +1E47=006E 0323 +1E48=004E 0331 +1E49=006E 0331 +1E4A=004E 032D +1E4B=006E 032D +1E4C=00D5 0301 +1E4D=00F5 0301 +1E4E=00D5 0308 +1E4F=00F5 0308 +1E50=014C 0300 +1E51=014D 0300 +1E52=014C 0301 +1E53=014D 0301 +1E54=0050 0301 +1E55=0070 0301 +1E56=0050 0307 +1E57=0070 0307 +1E58=0052 0307 +1E59=0072 0307 +1E5A=0052 0323 +1E5B=0072 0323 +1E5C=1E5A 0304 +1E5D=1E5B 0304 +1E5E=0052 0331 +1E5F=0072 0331 +1E60=0053 0307 +1E61=0073 0307 +1E62=0053 0323 +1E63=0073 0323 +1E64=015A 0307 +1E65=015B 0307 +1E66=0160 0307 +1E67=0161 0307 +1E68=1E62 0307 +1E69=1E63 0307 +1E6A=0054 0307 +1E6B=0074 0307 +1E6C=0054 0323 +1E6D=0074 0323 +1E6E=0054 0331 +1E6F=0074 0331 +1E70=0054 032D +1E71=0074 032D +1E72=0055 0324 +1E73=0075 0324 +1E74=0055 0330 +1E75=0075 0330 +1E76=0055 032D +1E77=0075 032D +1E78=0168 0301 +1E79=0169 0301 +1E7A=016A 0308 +1E7B=016B 0308 +1E7C=0056 0303 +1E7D=0076 0303 +1E7E=0056 0323 +1E7F=0076 0323 +1E80=0057 0300 +1E81=0077 0300 +1E82=0057 0301 +1E83=0077 0301 +1E84=0057 0308 +1E85=0077 0308 +1E86=0057 0307 +1E87=0077 0307 +1E88=0057 0323 +1E89=0077 0323 +1E8A=0058 0307 +1E8B=0078 0307 +1E8C=0058 0308 +1E8D=0078 0308 +1E8E=0059 0307 +1E8F=0079 0307 +1E90=005A 0302 +1E91=007A 0302 +1E92=005A 0323 +1E93=007A 0323 +1E94=005A 0331 +1E95=007A 0331 +1E96=0068 0331 +1E97=0074 0308 +1E98=0077 030A +1E99=0079 030A +1E9B=017F 0307 +1EA0=0041 0323 +1EA1=0061 0323 +1EA2=0041 0309 +1EA3=0061 0309 +1EA4=00C2 0301 +1EA5=00E2 0301 +1EA6=00C2 0300 +1EA7=00E2 0300 +1EA8=00C2 0309 +1EA9=00E2 0309 +1EAA=00C2 0303 +1EAB=00E2 0303 +1EAC=1EA0 0302 +1EAD=1EA1 0302 +1EAE=0102 0301 +1EAF=0103 0301 +1EB0=0102 0300 +1EB1=0103 0300 +1EB2=0102 0309 +1EB3=0103 0309 +1EB4=0102 0303 +1EB5=0103 0303 +1EB6=1EA0 0306 +1EB7=1EA1 0306 +1EB8=0045 0323 +1EB9=0065 0323 +1EBA=0045 0309 +1EBB=0065 0309 +1EBC=0045 0303 +1EBD=0065 0303 +1EBE=00CA 0301 +1EBF=00EA 0301 +1EC0=00CA 0300 +1EC1=00EA 0300 +1EC2=00CA 0309 +1EC3=00EA 0309 +1EC4=00CA 0303 +1EC5=00EA 0303 +1EC6=1EB8 0302 +1EC7=1EB9 0302 +1EC8=0049 0309 +1EC9=0069 0309 +1ECA=0049 0323 +1ECB=0069 0323 +1ECC=004F 0323 +1ECD=006F 0323 +1ECE=004F 0309 +1ECF=006F 0309 +1ED0=00D4 0301 +1ED1=00F4 0301 +1ED2=00D4 0300 +1ED3=00F4 0300 +1ED4=00D4 0309 +1ED5=00F4 0309 +1ED6=00D4 0303 +1ED7=00F4 0303 +1ED8=1ECC 0302 +1ED9=1ECD 0302 +1EDA=01A0 0301 +1EDB=01A1 0301 +1EDC=01A0 0300 +1EDD=01A1 0300 +1EDE=01A0 0309 +1EDF=01A1 0309 +1EE0=01A0 0303 +1EE1=01A1 0303 +1EE2=01A0 0323 +1EE3=01A1 0323 +1EE4=0055 0323 +1EE5=0075 0323 +1EE6=0055 0309 +1EE7=0075 0309 +1EE8=01AF 0301 +1EE9=01B0 0301 +1EEA=01AF 0300 +1EEB=01B0 0300 +1EEC=01AF 0309 +1EED=01B0 0309 +1EEE=01AF 0303 +1EEF=01B0 0303 +1EF0=01AF 0323 +1EF1=01B0 0323 +1EF2=0059 0300 +1EF3=0079 0300 +1EF4=0059 0323 +1EF5=0079 0323 +1EF6=0059 0309 +1EF7=0079 0309 +1EF8=0059 0303 +1EF9=0079 0303 +1F00=03B1 0313 +1F01=03B1 0314 +1F02=1F00 0300 +1F03=1F01 0300 +1F04=1F00 0301 +1F05=1F01 0301 +1F06=1F00 0342 +1F07=1F01 0342 +1F08=0391 0313 +1F09=0391 0314 +1F0A=1F08 0300 +1F0B=1F09 0300 +1F0C=1F08 0301 +1F0D=1F09 0301 +1F0E=1F08 0342 +1F0F=1F09 0342 +1F10=03B5 0313 +1F11=03B5 0314 +1F12=1F10 0300 +1F13=1F11 0300 +1F14=1F10 0301 +1F15=1F11 0301 +1F18=0395 0313 +1F19=0395 0314 +1F1A=1F18 0300 +1F1B=1F19 0300 +1F1C=1F18 0301 +1F1D=1F19 0301 +1F20=03B7 0313 +1F21=03B7 0314 +1F22=1F20 0300 +1F23=1F21 0300 +1F24=1F20 0301 +1F25=1F21 0301 +1F26=1F20 0342 +1F27=1F21 0342 +1F28=0397 0313 +1F29=0397 0314 +1F2A=1F28 0300 +1F2B=1F29 0300 +1F2C=1F28 0301 +1F2D=1F29 0301 +1F2E=1F28 0342 +1F2F=1F29 0342 +1F30=03B9 0313 +1F31=03B9 0314 +1F32=1F30 0300 +1F33=1F31 0300 +1F34=1F30 0301 +1F35=1F31 0301 +1F36=1F30 0342 +1F37=1F31 0342 +1F38=0399 0313 +1F39=0399 0314 +1F3A=1F38 0300 +1F3B=1F39 0300 +1F3C=1F38 0301 +1F3D=1F39 0301 +1F3E=1F38 0342 +1F3F=1F39 0342 +1F40=03BF 0313 +1F41=03BF 0314 +1F42=1F40 0300 +1F43=1F41 0300 +1F44=1F40 0301 +1F45=1F41 0301 +1F48=039F 0313 +1F49=039F 0314 +1F4A=1F48 0300 +1F4B=1F49 0300 +1F4C=1F48 0301 +1F4D=1F49 0301 +1F50=03C5 0313 +1F51=03C5 0314 +1F52=1F50 0300 +1F53=1F51 0300 +1F54=1F50 0301 +1F55=1F51 0301 +1F56=1F50 0342 +1F57=1F51 0342 +1F59=03A5 0314 +1F5B=1F59 0300 +1F5D=1F59 0301 +1F5F=1F59 0342 +1F60=03C9 0313 +1F61=03C9 0314 +1F62=1F60 0300 +1F63=1F61 0300 +1F64=1F60 0301 +1F65=1F61 0301 +1F66=1F60 0342 +1F67=1F61 0342 +1F68=03A9 0313 +1F69=03A9 0314 +1F6A=1F68 0300 +1F6B=1F69 0300 +1F6C=1F68 0301 +1F6D=1F69 0301 +1F6E=1F68 0342 +1F6F=1F69 0342 +1F70=03B1 0300 +1F71>03AC +1F72=03B5 0300 +1F73>03AD +1F74=03B7 0300 +1F75>03AE +1F76=03B9 0300 +1F77>03AF +1F78=03BF 0300 +1F79>03CC +1F7A=03C5 0300 +1F7B>03CD +1F7C=03C9 0300 +1F7D>03CE +1F80=1F00 0345 +1F81=1F01 0345 +1F82=1F02 0345 +1F83=1F03 0345 +1F84=1F04 0345 +1F85=1F05 0345 +1F86=1F06 0345 +1F87=1F07 0345 +1F88=1F08 0345 +1F89=1F09 0345 +1F8A=1F0A 0345 +1F8B=1F0B 0345 +1F8C=1F0C 0345 +1F8D=1F0D 0345 +1F8E=1F0E 0345 +1F8F=1F0F 0345 +1F90=1F20 0345 +1F91=1F21 0345 +1F92=1F22 0345 +1F93=1F23 0345 +1F94=1F24 0345 +1F95=1F25 0345 +1F96=1F26 0345 +1F97=1F27 0345 +1F98=1F28 0345 +1F99=1F29 0345 +1F9A=1F2A 0345 +1F9B=1F2B 0345 +1F9C=1F2C 0345 +1F9D=1F2D 0345 +1F9E=1F2E 0345 +1F9F=1F2F 0345 +1FA0=1F60 0345 +1FA1=1F61 0345 +1FA2=1F62 0345 +1FA3=1F63 0345 +1FA4=1F64 0345 +1FA5=1F65 0345 +1FA6=1F66 0345 +1FA7=1F67 0345 +1FA8=1F68 0345 +1FA9=1F69 0345 +1FAA=1F6A 0345 +1FAB=1F6B 0345 +1FAC=1F6C 0345 +1FAD=1F6D 0345 +1FAE=1F6E 0345 +1FAF=1F6F 0345 +1FB0=03B1 0306 +1FB1=03B1 0304 +1FB2=1F70 0345 +1FB3=03B1 0345 +1FB4=03AC 0345 +1FB6=03B1 0342 +1FB7=1FB6 0345 +1FB8=0391 0306 +1FB9=0391 0304 +1FBA=0391 0300 +1FBB>0386 +1FBC=0391 0345 +1FBE>03B9 +1FC1=00A8 0342 +1FC2=1F74 0345 +1FC3=03B7 0345 +1FC4=03AE 0345 +1FC6=03B7 0342 +1FC7=1FC6 0345 +1FC8=0395 0300 +1FC9>0388 +1FCA=0397 0300 +1FCB>0389 +1FCC=0397 0345 +1FCD=1FBF 0300 +1FCE=1FBF 0301 +1FCF=1FBF 0342 +1FD0=03B9 0306 +1FD1=03B9 0304 +1FD2=03CA 0300 +1FD3>0390 +1FD6=03B9 0342 +1FD7=03CA 0342 +1FD8=0399 0306 +1FD9=0399 0304 +1FDA=0399 0300 +1FDB>038A +1FDD=1FFE 0300 +1FDE=1FFE 0301 +1FDF=1FFE 0342 +1FE0=03C5 0306 +1FE1=03C5 0304 +1FE2=03CB 0300 +1FE3>03B0 +1FE4=03C1 0313 +1FE5=03C1 0314 +1FE6=03C5 0342 +1FE7=03CB 0342 +1FE8=03A5 0306 +1FE9=03A5 0304 +1FEA=03A5 0300 +1FEB>038E +1FEC=03A1 0314 +1FED=00A8 0300 +1FEE>0385 +1FEF>0060 +1FF2=1F7C 0345 +1FF3=03C9 0345 +1FF4=03CE 0345 +1FF6=03C9 0342 +1FF7=1FF6 0345 +1FF8=039F 0300 +1FF9>038C +1FFA=03A9 0300 +1FFB>038F +1FFC=03A9 0345 +1FFD>00B4 +2000>2002 +2001>2003 +2126>03A9 +212A>004B +212B>00C5 +219A=2190 0338 +219B=2192 0338 +21AE=2194 0338 +21CD=21D0 0338 +21CE=21D4 0338 +21CF=21D2 0338 +2204=2203 0338 +2209=2208 0338 +220C=220B 0338 +2224=2223 0338 +2226=2225 0338 +2241=223C 0338 +2244=2243 0338 +2247=2245 0338 +2249=2248 0338 +2260=003D 0338 +2262=2261 0338 +226D=224D 0338 +226E=003C 0338 +226F=003E 0338 +2270=2264 0338 +2271=2265 0338 +2274=2272 0338 +2275=2273 0338 +2278=2276 0338 +2279=2277 0338 +2280=227A 0338 +2281=227B 0338 +2284=2282 0338 +2285=2283 0338 +2288=2286 0338 +2289=2287 0338 +22AC=22A2 0338 +22AD=22A8 0338 +22AE=22A9 0338 +22AF=22AB 0338 +22E0=227C 0338 +22E1=227D 0338 +22E2=2291 0338 +22E3=2292 0338 +22EA=22B2 0338 +22EB=22B3 0338 +22EC=22B4 0338 +22ED=22B5 0338 +2329>3008 +232A>3009 +2ADC>2ADD 0338 +304C=304B 3099 +304E=304D 3099 +3050=304F 3099 +3052=3051 3099 +3054=3053 3099 +3056=3055 3099 +3058=3057 3099 +305A=3059 3099 +305C=305B 3099 +305E=305D 3099 +3060=305F 3099 +3062=3061 3099 +3065=3064 3099 +3067=3066 3099 +3069=3068 3099 +3070=306F 3099 +3071=306F 309A +3073=3072 3099 +3074=3072 309A +3076=3075 3099 +3077=3075 309A +3079=3078 3099 +307A=3078 309A +307C=307B 3099 +307D=307B 309A +3094=3046 3099 +309E=309D 3099 +30AC=30AB 3099 +30AE=30AD 3099 +30B0=30AF 3099 +30B2=30B1 3099 +30B4=30B3 3099 +30B6=30B5 3099 +30B8=30B7 3099 +30BA=30B9 3099 +30BC=30BB 3099 +30BE=30BD 3099 +30C0=30BF 3099 +30C2=30C1 3099 +30C5=30C4 3099 +30C7=30C6 3099 +30C9=30C8 3099 +30D0=30CF 3099 +30D1=30CF 309A +30D3=30D2 3099 +30D4=30D2 309A +30D6=30D5 3099 +30D7=30D5 309A +30D9=30D8 3099 +30DA=30D8 309A +30DC=30DB 3099 +30DD=30DB 309A +30F4=30A6 3099 +30F7=30EF 3099 +30F8=30F0 3099 +30F9=30F1 3099 +30FA=30F2 3099 +30FE=30FD 3099 +F900>8C48 +F901>66F4 +F902>8ECA +F903>8CC8 +F904>6ED1 +F905>4E32 +F906>53E5 +F907>9F9C +F908>9F9C +F909>5951 +F90A>91D1 +F90B>5587 +F90C>5948 +F90D>61F6 +F90E>7669 +F90F>7F85 +F910>863F +F911>87BA +F912>88F8 +F913>908F +F914>6A02 +F915>6D1B +F916>70D9 +F917>73DE +F918>843D +F919>916A +F91A>99F1 +F91B>4E82 +F91C>5375 +F91D>6B04 +F91E>721B +F91F>862D +F920>9E1E +F921>5D50 +F922>6FEB +F923>85CD +F924>8964 +F925>62C9 +F926>81D8 +F927>881F +F928>5ECA +F929>6717 +F92A>6D6A +F92B>72FC +F92C>90CE +F92D>4F86 +F92E>51B7 +F92F>52DE +F930>64C4 +F931>6AD3 +F932>7210 +F933>76E7 +F934>8001 +F935>8606 +F936>865C +F937>8DEF +F938>9732 +F939>9B6F +F93A>9DFA +F93B>788C +F93C>797F +F93D>7DA0 +F93E>83C9 +F93F>9304 +F940>9E7F +F941>8AD6 +F942>58DF +F943>5F04 +F944>7C60 +F945>807E +F946>7262 +F947>78CA +F948>8CC2 +F949>96F7 +F94A>58D8 +F94B>5C62 +F94C>6A13 +F94D>6DDA +F94E>6F0F +F94F>7D2F +F950>7E37 +F951>964B +F952>52D2 +F953>808B +F954>51DC +F955>51CC +F956>7A1C +F957>7DBE +F958>83F1 +F959>9675 +F95A>8B80 +F95B>62CF +F95C>6A02 +F95D>8AFE +F95E>4E39 +F95F>5BE7 +F960>6012 +F961>7387 +F962>7570 +F963>5317 +F964>78FB +F965>4FBF +F966>5FA9 +F967>4E0D +F968>6CCC +F969>6578 +F96A>7D22 +F96B>53C3 +F96C>585E +F96D>7701 +F96E>8449 +F96F>8AAA +F970>6BBA +F971>8FB0 +F972>6C88 +F973>62FE +F974>82E5 +F975>63A0 +F976>7565 +F977>4EAE +F978>5169 +F979>51C9 +F97A>6881 +F97B>7CE7 +F97C>826F +F97D>8AD2 +F97E>91CF +F97F>52F5 +F980>5442 +F981>5973 +F982>5EEC +F983>65C5 +F984>6FFE +F985>792A +F986>95AD +F987>9A6A +F988>9E97 +F989>9ECE +F98A>529B +F98B>66C6 +F98C>6B77 +F98D>8F62 +F98E>5E74 +F98F>6190 +F990>6200 +F991>649A +F992>6F23 +F993>7149 +F994>7489 +F995>79CA +F996>7DF4 +F997>806F +F998>8F26 +F999>84EE +F99A>9023 +F99B>934A +F99C>5217 +F99D>52A3 +F99E>54BD +F99F>70C8 +F9A0>88C2 +F9A1>8AAA +F9A2>5EC9 +F9A3>5FF5 +F9A4>637B +F9A5>6BAE +F9A6>7C3E +F9A7>7375 +F9A8>4EE4 +F9A9>56F9 +F9AA>5BE7 +F9AB>5DBA +F9AC>601C +F9AD>73B2 +F9AE>7469 +F9AF>7F9A +F9B0>8046 +F9B1>9234 +F9B2>96F6 +F9B3>9748 +F9B4>9818 +F9B5>4F8B +F9B6>79AE +F9B7>91B4 +F9B8>96B8 +F9B9>60E1 +F9BA>4E86 +F9BB>50DA +F9BC>5BEE +F9BD>5C3F +F9BE>6599 +F9BF>6A02 +F9C0>71CE +F9C1>7642 +F9C2>84FC +F9C3>907C +F9C4>9F8D +F9C5>6688 +F9C6>962E +F9C7>5289 +F9C8>677B +F9C9>67F3 +F9CA>6D41 +F9CB>6E9C +F9CC>7409 +F9CD>7559 +F9CE>786B +F9CF>7D10 +F9D0>985E +F9D1>516D +F9D2>622E +F9D3>9678 +F9D4>502B +F9D5>5D19 +F9D6>6DEA +F9D7>8F2A +F9D8>5F8B +F9D9>6144 +F9DA>6817 +F9DB>7387 +F9DC>9686 +F9DD>5229 +F9DE>540F +F9DF>5C65 +F9E0>6613 +F9E1>674E +F9E2>68A8 +F9E3>6CE5 +F9E4>7406 +F9E5>75E2 +F9E6>7F79 +F9E7>88CF +F9E8>88E1 +F9E9>91CC +F9EA>96E2 +F9EB>533F +F9EC>6EBA +F9ED>541D +F9EE>71D0 +F9EF>7498 +F9F0>85FA +F9F1>96A3 +F9F2>9C57 +F9F3>9E9F +F9F4>6797 +F9F5>6DCB +F9F6>81E8 +F9F7>7ACB +F9F8>7B20 +F9F9>7C92 +F9FA>72C0 +F9FB>7099 +F9FC>8B58 +F9FD>4EC0 +F9FE>8336 +F9FF>523A +FA00>5207 +FA01>5EA6 +FA02>62D3 +FA03>7CD6 +FA04>5B85 +FA05>6D1E +FA06>66B4 +FA07>8F3B +FA08>884C +FA09>964D +FA0A>898B +FA0B>5ED3 +FA0C>5140 +FA0D>55C0 +FA10>585A +FA12>6674 +FA15>51DE +FA16>732A +FA17>76CA +FA18>793C +FA19>795E +FA1A>7965 +FA1B>798F +FA1C>9756 +FA1D>7CBE +FA1E>7FBD +FA20>8612 +FA22>8AF8 +FA25>9038 +FA26>90FD +FA2A>98EF +FA2B>98FC +FA2C>9928 +FA2D>9DB4 +FA2E>90DE +FA2F>96B7 +FA30>4FAE +FA31>50E7 +FA32>514D +FA33>52C9 +FA34>52E4 +FA35>5351 +FA36>559D +FA37>5606 +FA38>5668 +FA39>5840 +FA3A>58A8 +FA3B>5C64 +FA3C>5C6E +FA3D>6094 +FA3E>6168 +FA3F>618E +FA40>61F2 +FA41>654F +FA42>65E2 +FA43>6691 +FA44>6885 +FA45>6D77 +FA46>6E1A +FA47>6F22 +FA48>716E +FA49>722B +FA4A>7422 +FA4B>7891 +FA4C>793E +FA4D>7949 +FA4E>7948 +FA4F>7950 +FA50>7956 +FA51>795D +FA52>798D +FA53>798E +FA54>7A40 +FA55>7A81 +FA56>7BC0 +FA57>7DF4 +FA58>7E09 +FA59>7E41 +FA5A>7F72 +FA5B>8005 +FA5C>81ED +FA5D>8279 +FA5E>8279 +FA5F>8457 +FA60>8910 +FA61>8996 +FA62>8B01 +FA63>8B39 +FA64>8CD3 +FA65>8D08 +FA66>8FB6 +FA67>9038 +FA68>96E3 +FA69>97FF +FA6A>983B +FA6B>6075 +FA6C>242EE +FA6D>8218 +FA70>4E26 +FA71>51B5 +FA72>5168 +FA73>4F80 +FA74>5145 +FA75>5180 +FA76>52C7 +FA77>52FA +FA78>559D +FA79>5555 +FA7A>5599 +FA7B>55E2 +FA7C>585A +FA7D>58B3 +FA7E>5944 +FA7F>5954 +FA80>5A62 +FA81>5B28 +FA82>5ED2 +FA83>5ED9 +FA84>5F69 +FA85>5FAD +FA86>60D8 +FA87>614E +FA88>6108 +FA89>618E +FA8A>6160 +FA8B>61F2 +FA8C>6234 +FA8D>63C4 +FA8E>641C +FA8F>6452 +FA90>6556 +FA91>6674 +FA92>6717 +FA93>671B +FA94>6756 +FA95>6B79 +FA96>6BBA +FA97>6D41 +FA98>6EDB +FA99>6ECB +FA9A>6F22 +FA9B>701E +FA9C>716E +FA9D>77A7 +FA9E>7235 +FA9F>72AF +FAA0>732A +FAA1>7471 +FAA2>7506 +FAA3>753B +FAA4>761D +FAA5>761F +FAA6>76CA +FAA7>76DB +FAA8>76F4 +FAA9>774A +FAAA>7740 +FAAB>78CC +FAAC>7AB1 +FAAD>7BC0 +FAAE>7C7B +FAAF>7D5B +FAB0>7DF4 +FAB1>7F3E +FAB2>8005 +FAB3>8352 +FAB4>83EF +FAB5>8779 +FAB6>8941 +FAB7>8986 +FAB8>8996 +FAB9>8ABF +FABA>8AF8 +FABB>8ACB +FABC>8B01 +FABD>8AFE +FABE>8AED +FABF>8B39 +FAC0>8B8A +FAC1>8D08 +FAC2>8F38 +FAC3>9072 +FAC4>9199 +FAC5>9276 +FAC6>967C +FAC7>96E3 +FAC8>9756 +FAC9>97DB +FACA>97FF +FACB>980B +FACC>983B +FACD>9B12 +FACE>9F9C +FACF>2284A +FAD0>22844 +FAD1>233D5 +FAD2>3B9D +FAD3>4018 +FAD4>4039 +FAD5>25249 +FAD6>25CD0 +FAD7>27ED3 +FAD8>9F43 +FAD9>9F8E +FB1D>05D9 05B4 +FB1F>05F2 05B7 +FB2A>05E9 05C1 +FB2B>05E9 05C2 +FB2C>FB49 05C1 +FB2D>FB49 05C2 +FB2E>05D0 05B7 +FB2F>05D0 05B8 +FB30>05D0 05BC +FB31>05D1 05BC +FB32>05D2 05BC +FB33>05D3 05BC +FB34>05D4 05BC +FB35>05D5 05BC +FB36>05D6 05BC +FB38>05D8 05BC +FB39>05D9 05BC +FB3A>05DA 05BC +FB3B>05DB 05BC +FB3C>05DC 05BC +FB3E>05DE 05BC +FB40>05E0 05BC +FB41>05E1 05BC +FB43>05E3 05BC +FB44>05E4 05BC +FB46>05E6 05BC +FB47>05E7 05BC +FB48>05E8 05BC +FB49>05E9 05BC +FB4A>05EA 05BC +FB4B>05D5 05B9 +FB4C>05D1 05BF +FB4D>05DB 05BF +FB4E>05E4 05BF +1109A=11099 110BA +1109C=1109B 110BA +110AB=110A5 110BA +1112E=11131 11127 +1112F=11132 11127 +1134B=11347 1133E +1134C=11347 11357 +114BB=114B9 114BA +114BC=114B9 114B0 +114BE=114B9 114BD +115BA=115B8 115AF +115BB=115B9 115AF +1D15E>1D157 1D165 +1D15F>1D158 1D165 +1D160>1D15F 1D16E +1D161>1D15F 1D16F +1D162>1D15F 1D170 +1D163>1D15F 1D171 +1D164>1D15F 1D172 +1D1BB>1D1B9 1D165 +1D1BC>1D1BA 1D165 +1D1BD>1D1BB 1D16E +1D1BE>1D1BC 1D16E +1D1BF>1D1BB 1D16F +1D1C0>1D1BC 1D16F +2F800>4E3D +2F801>4E38 +2F802>4E41 +2F803>20122 +2F804>4F60 +2F805>4FAE +2F806>4FBB +2F807>5002 +2F808>507A +2F809>5099 +2F80A>50E7 +2F80B>50CF +2F80C>349E +2F80D>2063A +2F80E>514D +2F80F>5154 +2F810>5164 +2F811>5177 +2F812>2051C +2F813>34B9 +2F814>5167 +2F815>518D +2F816>2054B +2F817>5197 +2F818>51A4 +2F819>4ECC +2F81A>51AC +2F81B>51B5 +2F81C>291DF +2F81D>51F5 +2F81E>5203 +2F81F>34DF +2F820>523B +2F821>5246 +2F822>5272 +2F823>5277 +2F824>3515 +2F825>52C7 +2F826>52C9 +2F827>52E4 +2F828>52FA +2F829>5305 +2F82A>5306 +2F82B>5317 +2F82C>5349 +2F82D>5351 +2F82E>535A +2F82F>5373 +2F830>537D +2F831>537F +2F832>537F +2F833>537F +2F834>20A2C +2F835>7070 +2F836>53CA +2F837>53DF +2F838>20B63 +2F839>53EB +2F83A>53F1 +2F83B>5406 +2F83C>549E +2F83D>5438 +2F83E>5448 +2F83F>5468 +2F840>54A2 +2F841>54F6 +2F842>5510 +2F843>5553 +2F844>5563 +2F845>5584 +2F846>5584 +2F847>5599 +2F848>55AB +2F849>55B3 +2F84A>55C2 +2F84B>5716 +2F84C>5606 +2F84D>5717 +2F84E>5651 +2F84F>5674 +2F850>5207 +2F851>58EE +2F852>57CE +2F853>57F4 +2F854>580D +2F855>578B +2F856>5832 +2F857>5831 +2F858>58AC +2F859>214E4 +2F85A>58F2 +2F85B>58F7 +2F85C>5906 +2F85D>591A +2F85E>5922 +2F85F>5962 +2F860>216A8 +2F861>216EA +2F862>59EC +2F863>5A1B +2F864>5A27 +2F865>59D8 +2F866>5A66 +2F867>36EE +2F868>36FC +2F869>5B08 +2F86A>5B3E +2F86B>5B3E +2F86C>219C8 +2F86D>5BC3 +2F86E>5BD8 +2F86F>5BE7 +2F870>5BF3 +2F871>21B18 +2F872>5BFF +2F873>5C06 +2F874>5F53 +2F875>5C22 +2F876>3781 +2F877>5C60 +2F878>5C6E +2F879>5CC0 +2F87A>5C8D +2F87B>21DE4 +2F87C>5D43 +2F87D>21DE6 +2F87E>5D6E +2F87F>5D6B +2F880>5D7C +2F881>5DE1 +2F882>5DE2 +2F883>382F +2F884>5DFD +2F885>5E28 +2F886>5E3D +2F887>5E69 +2F888>3862 +2F889>22183 +2F88A>387C +2F88B>5EB0 +2F88C>5EB3 +2F88D>5EB6 +2F88E>5ECA +2F88F>2A392 +2F890>5EFE +2F891>22331 +2F892>22331 +2F893>8201 +2F894>5F22 +2F895>5F22 +2F896>38C7 +2F897>232B8 +2F898>261DA +2F899>5F62 +2F89A>5F6B +2F89B>38E3 +2F89C>5F9A +2F89D>5FCD +2F89E>5FD7 +2F89F>5FF9 +2F8A0>6081 +2F8A1>393A +2F8A2>391C +2F8A3>6094 +2F8A4>226D4 +2F8A5>60C7 +2F8A6>6148 +2F8A7>614C +2F8A8>614E +2F8A9>614C +2F8AA>617A +2F8AB>618E +2F8AC>61B2 +2F8AD>61A4 +2F8AE>61AF +2F8AF>61DE +2F8B0>61F2 +2F8B1>61F6 +2F8B2>6210 +2F8B3>621B +2F8B4>625D +2F8B5>62B1 +2F8B6>62D4 +2F8B7>6350 +2F8B8>22B0C +2F8B9>633D +2F8BA>62FC +2F8BB>6368 +2F8BC>6383 +2F8BD>63E4 +2F8BE>22BF1 +2F8BF>6422 +2F8C0>63C5 +2F8C1>63A9 +2F8C2>3A2E +2F8C3>6469 +2F8C4>647E +2F8C5>649D +2F8C6>6477 +2F8C7>3A6C +2F8C8>654F +2F8C9>656C +2F8CA>2300A +2F8CB>65E3 +2F8CC>66F8 +2F8CD>6649 +2F8CE>3B19 +2F8CF>6691 +2F8D0>3B08 +2F8D1>3AE4 +2F8D2>5192 +2F8D3>5195 +2F8D4>6700 +2F8D5>669C +2F8D6>80AD +2F8D7>43D9 +2F8D8>6717 +2F8D9>671B +2F8DA>6721 +2F8DB>675E +2F8DC>6753 +2F8DD>233C3 +2F8DE>3B49 +2F8DF>67FA +2F8E0>6785 +2F8E1>6852 +2F8E2>6885 +2F8E3>2346D +2F8E4>688E +2F8E5>681F +2F8E6>6914 +2F8E7>3B9D +2F8E8>6942 +2F8E9>69A3 +2F8EA>69EA +2F8EB>6AA8 +2F8EC>236A3 +2F8ED>6ADB +2F8EE>3C18 +2F8EF>6B21 +2F8F0>238A7 +2F8F1>6B54 +2F8F2>3C4E +2F8F3>6B72 +2F8F4>6B9F +2F8F5>6BBA +2F8F6>6BBB +2F8F7>23A8D +2F8F8>21D0B +2F8F9>23AFA +2F8FA>6C4E +2F8FB>23CBC +2F8FC>6CBF +2F8FD>6CCD +2F8FE>6C67 +2F8FF>6D16 +2F900>6D3E +2F901>6D77 +2F902>6D41 +2F903>6D69 +2F904>6D78 +2F905>6D85 +2F906>23D1E +2F907>6D34 +2F908>6E2F +2F909>6E6E +2F90A>3D33 +2F90B>6ECB +2F90C>6EC7 +2F90D>23ED1 +2F90E>6DF9 +2F90F>6F6E +2F910>23F5E +2F911>23F8E +2F912>6FC6 +2F913>7039 +2F914>701E +2F915>701B +2F916>3D96 +2F917>704A +2F918>707D +2F919>7077 +2F91A>70AD +2F91B>20525 +2F91C>7145 +2F91D>24263 +2F91E>719C +2F91F>243AB +2F920>7228 +2F921>7235 +2F922>7250 +2F923>24608 +2F924>7280 +2F925>7295 +2F926>24735 +2F927>24814 +2F928>737A +2F929>738B +2F92A>3EAC +2F92B>73A5 +2F92C>3EB8 +2F92D>3EB8 +2F92E>7447 +2F92F>745C +2F930>7471 +2F931>7485 +2F932>74CA +2F933>3F1B +2F934>7524 +2F935>24C36 +2F936>753E +2F937>24C92 +2F938>7570 +2F939>2219F +2F93A>7610 +2F93B>24FA1 +2F93C>24FB8 +2F93D>25044 +2F93E>3FFC +2F93F>4008 +2F940>76F4 +2F941>250F3 +2F942>250F2 +2F943>25119 +2F944>25133 +2F945>771E +2F946>771F +2F947>771F +2F948>774A +2F949>4039 +2F94A>778B +2F94B>4046 +2F94C>4096 +2F94D>2541D +2F94E>784E +2F94F>788C +2F950>78CC +2F951>40E3 +2F952>25626 +2F953>7956 +2F954>2569A +2F955>256C5 +2F956>798F +2F957>79EB +2F958>412F +2F959>7A40 +2F95A>7A4A +2F95B>7A4F +2F95C>2597C +2F95D>25AA7 +2F95E>25AA7 +2F95F>7AEE +2F960>4202 +2F961>25BAB +2F962>7BC6 +2F963>7BC9 +2F964>4227 +2F965>25C80 +2F966>7CD2 +2F967>42A0 +2F968>7CE8 +2F969>7CE3 +2F96A>7D00 +2F96B>25F86 +2F96C>7D63 +2F96D>4301 +2F96E>7DC7 +2F96F>7E02 +2F970>7E45 +2F971>4334 +2F972>26228 +2F973>26247 +2F974>4359 +2F975>262D9 +2F976>7F7A +2F977>2633E +2F978>7F95 +2F979>7FFA +2F97A>8005 +2F97B>264DA +2F97C>26523 +2F97D>8060 +2F97E>265A8 +2F97F>8070 +2F980>2335F +2F981>43D5 +2F982>80B2 +2F983>8103 +2F984>440B +2F985>813E +2F986>5AB5 +2F987>267A7 +2F988>267B5 +2F989>23393 +2F98A>2339C +2F98B>8201 +2F98C>8204 +2F98D>8F9E +2F98E>446B +2F98F>8291 +2F990>828B +2F991>829D +2F992>52B3 +2F993>82B1 +2F994>82B3 +2F995>82BD +2F996>82E6 +2F997>26B3C +2F998>82E5 +2F999>831D +2F99A>8363 +2F99B>83AD +2F99C>8323 +2F99D>83BD +2F99E>83E7 +2F99F>8457 +2F9A0>8353 +2F9A1>83CA +2F9A2>83CC +2F9A3>83DC +2F9A4>26C36 +2F9A5>26D6B +2F9A6>26CD5 +2F9A7>452B +2F9A8>84F1 +2F9A9>84F3 +2F9AA>8516 +2F9AB>273CA +2F9AC>8564 +2F9AD>26F2C +2F9AE>455D +2F9AF>4561 +2F9B0>26FB1 +2F9B1>270D2 +2F9B2>456B +2F9B3>8650 +2F9B4>865C +2F9B5>8667 +2F9B6>8669 +2F9B7>86A9 +2F9B8>8688 +2F9B9>870E +2F9BA>86E2 +2F9BB>8779 +2F9BC>8728 +2F9BD>876B +2F9BE>8786 +2F9BF>45D7 +2F9C0>87E1 +2F9C1>8801 +2F9C2>45F9 +2F9C3>8860 +2F9C4>8863 +2F9C5>27667 +2F9C6>88D7 +2F9C7>88DE +2F9C8>4635 +2F9C9>88FA +2F9CA>34BB +2F9CB>278AE +2F9CC>27966 +2F9CD>46BE +2F9CE>46C7 +2F9CF>8AA0 +2F9D0>8AED +2F9D1>8B8A +2F9D2>8C55 +2F9D3>27CA8 +2F9D4>8CAB +2F9D5>8CC1 +2F9D6>8D1B +2F9D7>8D77 +2F9D8>27F2F +2F9D9>20804 +2F9DA>8DCB +2F9DB>8DBC +2F9DC>8DF0 +2F9DD>208DE +2F9DE>8ED4 +2F9DF>8F38 +2F9E0>285D2 +2F9E1>285ED +2F9E2>9094 +2F9E3>90F1 +2F9E4>9111 +2F9E5>2872E +2F9E6>911B +2F9E7>9238 +2F9E8>92D7 +2F9E9>92D8 +2F9EA>927C +2F9EB>93F9 +2F9EC>9415 +2F9ED>28BFA +2F9EE>958B +2F9EF>4995 +2F9F0>95B7 +2F9F1>28D77 +2F9F2>49E6 +2F9F3>96C3 +2F9F4>5DB2 +2F9F5>9723 +2F9F6>29145 +2F9F7>2921A +2F9F8>4A6E +2F9F9>4A76 +2F9FA>97E0 +2F9FB>2940A +2F9FC>4AB2 +2F9FD>29496 +2F9FE>980B +2F9FF>980B +2FA00>9829 +2FA01>295B6 +2FA02>98E2 +2FA03>4B33 +2FA04>9929 +2FA05>99A7 +2FA06>99C2 +2FA07>99FE +2FA08>4BCE +2FA09>29B30 +2FA0A>9B12 +2FA0B>9C40 +2FA0C>9CFD +2FA0D>4CCE +2FA0E>4CED +2FA0F>9D67 +2FA10>2A0CE +2FA11>4CF8 +2FA12>2A105 +2FA13>2A20E +2FA14>2A291 +2FA15>9EBB +2FA16>4D56 +2FA17>9EF9 +2FA18>9EFE +2FA19>9F05 +2FA1A>9F0F +2FA1B>9F16 +2FA1C>9F3B +2FA1D>2A600 \ No newline at end of file diff --git a/claimtrie/normalization/NormalizationTest_v11.txt b/claimtrie/normalization/NormalizationTest_v11.txt new file mode 100644 index 00000000..cb72a0cb --- /dev/null +++ b/claimtrie/normalization/NormalizationTest_v11.txt @@ -0,0 +1,18847 @@ +# NormalizationTest-11.0.0.txt +# Date: 2018-02-19, 18:33:08 GMT +# © 2018 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Normalization Test Suite +# Format: +# +# Columns (c1, c2,...) are separated by semicolons +# They have the following meaning: +# source; NFC; NFD; NFKC; NFKD +# Comments are indicated with hash marks +# Each of the columns may have one or more code points. +# +# CONFORMANCE: +# 1. The following invariants must be true for all conformant implementations +# +# NFC +# c2 == toNFC(c1) == toNFC(c2) == toNFC(c3) +# c4 == toNFC(c4) == toNFC(c5) +# +# NFD +# c3 == toNFD(c1) == toNFD(c2) == toNFD(c3) +# c5 == toNFD(c4) == toNFD(c5) +# +# NFKC +# c4 == toNFKC(c1) == toNFKC(c2) == toNFKC(c3) == toNFKC(c4) == toNFKC(c5) +# +# NFKD +# c5 == toNFKD(c1) == toNFKD(c2) == toNFKD(c3) == toNFKD(c4) == toNFKD(c5) +# +# 2. For every code point X assigned in this version of Unicode that is not specifically +# listed in Part 1, the following invariants must be true for all conformant +# implementations: +# +# X == toNFC(X) == toNFD(X) == toNFKC(X) == toNFKD(X) +# +@Part0 # Specific cases +# +1E0A;1E0A;0044 0307;1E0A;0044 0307; +1E0C;1E0C;0044 0323;1E0C;0044 0323; +1E0A 0323;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; +1E0C 0307;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; +0044 0307 0323;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; +0044 0323 0307;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; +1E0A 031B;1E0A 031B;0044 031B 0307;1E0A 031B;0044 031B 0307; +1E0C 031B;1E0C 031B;0044 031B 0323;1E0C 031B;0044 031B 0323; +1E0A 031B 0323;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; +1E0C 031B 0307;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; +0044 031B 0307 0323;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; +0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; +00C8;00C8;0045 0300;00C8;0045 0300; +0112;0112;0045 0304;0112;0045 0304; +0045 0300;00C8;0045 0300;00C8;0045 0300; +0045 0304;0112;0045 0304;0112;0045 0304; +1E14;1E14;0045 0304 0300;1E14;0045 0304 0300; +0112 0300;1E14;0045 0304 0300;1E14;0045 0304 0300; +1E14 0304;1E14 0304;0045 0304 0300 0304;1E14 0304;0045 0304 0300 0304; +0045 0304 0300;1E14;0045 0304 0300;1E14;0045 0304 0300; +0045 0300 0304;00C8 0304;0045 0300 0304;00C8 0304;0045 0300 0304; +05B8 05B9 05B1 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F; +0592 05B7 05BC 05A5 05B0 05C0 05C4 05AD;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4; +1100 AC00 11A8;1100 AC01;1100 1100 1161 11A8;1100 AC01;1100 1100 1161 11A8; +1100 AC00 11A8 11A8;1100 AC01 11A8;1100 1100 1161 11A8 11A8;1100 AC01 11A8;1100 1100 1161 11A8 11A8; +# +@Part1 # Character by character test +# All characters not explicitly occurring in c1 of Part 1 have identical NFC, D, KC, KD forms. +# +00A0;00A0;00A0;0020;0020; +00A8;00A8;00A8;0020 0308;0020 0308; +00AA;00AA;00AA;0061;0061; +00AF;00AF;00AF;0020 0304;0020 0304; +00B2;00B2;00B2;0032;0032; +00B3;00B3;00B3;0033;0033; +00B4;00B4;00B4;0020 0301;0020 0301; +00B5;00B5;00B5;03BC;03BC; +00B8;00B8;00B8;0020 0327;0020 0327; +00B9;00B9;00B9;0031;0031; +00BA;00BA;00BA;006F;006F; +00BC;00BC;00BC;0031 2044 0034;0031 2044 0034; +00BD;00BD;00BD;0031 2044 0032;0031 2044 0032; +00BE;00BE;00BE;0033 2044 0034;0033 2044 0034; +00C0;00C0;0041 0300;00C0;0041 0300; +00C1;00C1;0041 0301;00C1;0041 0301; +00C2;00C2;0041 0302;00C2;0041 0302; +00C3;00C3;0041 0303;00C3;0041 0303; +00C4;00C4;0041 0308;00C4;0041 0308; +00C5;00C5;0041 030A;00C5;0041 030A; +00C7;00C7;0043 0327;00C7;0043 0327; +00C8;00C8;0045 0300;00C8;0045 0300; +00C9;00C9;0045 0301;00C9;0045 0301; +00CA;00CA;0045 0302;00CA;0045 0302; +00CB;00CB;0045 0308;00CB;0045 0308; +00CC;00CC;0049 0300;00CC;0049 0300; +00CD;00CD;0049 0301;00CD;0049 0301; +00CE;00CE;0049 0302;00CE;0049 0302; +00CF;00CF;0049 0308;00CF;0049 0308; +00D1;00D1;004E 0303;00D1;004E 0303; +00D2;00D2;004F 0300;00D2;004F 0300; +00D3;00D3;004F 0301;00D3;004F 0301; +00D4;00D4;004F 0302;00D4;004F 0302; +00D5;00D5;004F 0303;00D5;004F 0303; +00D6;00D6;004F 0308;00D6;004F 0308; +00D9;00D9;0055 0300;00D9;0055 0300; +00DA;00DA;0055 0301;00DA;0055 0301; +00DB;00DB;0055 0302;00DB;0055 0302; +00DC;00DC;0055 0308;00DC;0055 0308; +00DD;00DD;0059 0301;00DD;0059 0301; +00E0;00E0;0061 0300;00E0;0061 0300; +00E1;00E1;0061 0301;00E1;0061 0301; +00E2;00E2;0061 0302;00E2;0061 0302; +00E3;00E3;0061 0303;00E3;0061 0303; +00E4;00E4;0061 0308;00E4;0061 0308; +00E5;00E5;0061 030A;00E5;0061 030A; +00E7;00E7;0063 0327;00E7;0063 0327; +00E8;00E8;0065 0300;00E8;0065 0300; +00E9;00E9;0065 0301;00E9;0065 0301; +00EA;00EA;0065 0302;00EA;0065 0302; +00EB;00EB;0065 0308;00EB;0065 0308; +00EC;00EC;0069 0300;00EC;0069 0300; +00ED;00ED;0069 0301;00ED;0069 0301; +00EE;00EE;0069 0302;00EE;0069 0302; +00EF;00EF;0069 0308;00EF;0069 0308; +00F1;00F1;006E 0303;00F1;006E 0303; +00F2;00F2;006F 0300;00F2;006F 0300; +00F3;00F3;006F 0301;00F3;006F 0301; +00F4;00F4;006F 0302;00F4;006F 0302; +00F5;00F5;006F 0303;00F5;006F 0303; +00F6;00F6;006F 0308;00F6;006F 0308; +00F9;00F9;0075 0300;00F9;0075 0300; +00FA;00FA;0075 0301;00FA;0075 0301; +00FB;00FB;0075 0302;00FB;0075 0302; +00FC;00FC;0075 0308;00FC;0075 0308; +00FD;00FD;0079 0301;00FD;0079 0301; +00FF;00FF;0079 0308;00FF;0079 0308; +0100;0100;0041 0304;0100;0041 0304; +0101;0101;0061 0304;0101;0061 0304; +0102;0102;0041 0306;0102;0041 0306; +0103;0103;0061 0306;0103;0061 0306; +0104;0104;0041 0328;0104;0041 0328; +0105;0105;0061 0328;0105;0061 0328; +0106;0106;0043 0301;0106;0043 0301; +0107;0107;0063 0301;0107;0063 0301; +0108;0108;0043 0302;0108;0043 0302; +0109;0109;0063 0302;0109;0063 0302; +010A;010A;0043 0307;010A;0043 0307; +010B;010B;0063 0307;010B;0063 0307; +010C;010C;0043 030C;010C;0043 030C; +010D;010D;0063 030C;010D;0063 030C; +010E;010E;0044 030C;010E;0044 030C; +010F;010F;0064 030C;010F;0064 030C; +0112;0112;0045 0304;0112;0045 0304; +0113;0113;0065 0304;0113;0065 0304; +0114;0114;0045 0306;0114;0045 0306; +0115;0115;0065 0306;0115;0065 0306; +0116;0116;0045 0307;0116;0045 0307; +0117;0117;0065 0307;0117;0065 0307; +0118;0118;0045 0328;0118;0045 0328; +0119;0119;0065 0328;0119;0065 0328; +011A;011A;0045 030C;011A;0045 030C; +011B;011B;0065 030C;011B;0065 030C; +011C;011C;0047 0302;011C;0047 0302; +011D;011D;0067 0302;011D;0067 0302; +011E;011E;0047 0306;011E;0047 0306; +011F;011F;0067 0306;011F;0067 0306; +0120;0120;0047 0307;0120;0047 0307; +0121;0121;0067 0307;0121;0067 0307; +0122;0122;0047 0327;0122;0047 0327; +0123;0123;0067 0327;0123;0067 0327; +0124;0124;0048 0302;0124;0048 0302; +0125;0125;0068 0302;0125;0068 0302; +0128;0128;0049 0303;0128;0049 0303; +0129;0129;0069 0303;0129;0069 0303; +012A;012A;0049 0304;012A;0049 0304; +012B;012B;0069 0304;012B;0069 0304; +012C;012C;0049 0306;012C;0049 0306; +012D;012D;0069 0306;012D;0069 0306; +012E;012E;0049 0328;012E;0049 0328; +012F;012F;0069 0328;012F;0069 0328; +0130;0130;0049 0307;0130;0049 0307; +0132;0132;0132;0049 004A;0049 004A; +0133;0133;0133;0069 006A;0069 006A; +0134;0134;004A 0302;0134;004A 0302; +0135;0135;006A 0302;0135;006A 0302; +0136;0136;004B 0327;0136;004B 0327; +0137;0137;006B 0327;0137;006B 0327; +0139;0139;004C 0301;0139;004C 0301; +013A;013A;006C 0301;013A;006C 0301; +013B;013B;004C 0327;013B;004C 0327; +013C;013C;006C 0327;013C;006C 0327; +013D;013D;004C 030C;013D;004C 030C; +013E;013E;006C 030C;013E;006C 030C; +013F;013F;013F;004C 00B7;004C 00B7; +0140;0140;0140;006C 00B7;006C 00B7; +0143;0143;004E 0301;0143;004E 0301; +0144;0144;006E 0301;0144;006E 0301; +0145;0145;004E 0327;0145;004E 0327; +0146;0146;006E 0327;0146;006E 0327; +0147;0147;004E 030C;0147;004E 030C; +0148;0148;006E 030C;0148;006E 030C; +0149;0149;0149;02BC 006E;02BC 006E; +014C;014C;004F 0304;014C;004F 0304; +014D;014D;006F 0304;014D;006F 0304; +014E;014E;004F 0306;014E;004F 0306; +014F;014F;006F 0306;014F;006F 0306; +0150;0150;004F 030B;0150;004F 030B; +0151;0151;006F 030B;0151;006F 030B; +0154;0154;0052 0301;0154;0052 0301; +0155;0155;0072 0301;0155;0072 0301; +0156;0156;0052 0327;0156;0052 0327; +0157;0157;0072 0327;0157;0072 0327; +0158;0158;0052 030C;0158;0052 030C; +0159;0159;0072 030C;0159;0072 030C; +015A;015A;0053 0301;015A;0053 0301; +015B;015B;0073 0301;015B;0073 0301; +015C;015C;0053 0302;015C;0053 0302; +015D;015D;0073 0302;015D;0073 0302; +015E;015E;0053 0327;015E;0053 0327; +015F;015F;0073 0327;015F;0073 0327; +0160;0160;0053 030C;0160;0053 030C; +0161;0161;0073 030C;0161;0073 030C; +0162;0162;0054 0327;0162;0054 0327; +0163;0163;0074 0327;0163;0074 0327; +0164;0164;0054 030C;0164;0054 030C; +0165;0165;0074 030C;0165;0074 030C; +0168;0168;0055 0303;0168;0055 0303; +0169;0169;0075 0303;0169;0075 0303; +016A;016A;0055 0304;016A;0055 0304; +016B;016B;0075 0304;016B;0075 0304; +016C;016C;0055 0306;016C;0055 0306; +016D;016D;0075 0306;016D;0075 0306; +016E;016E;0055 030A;016E;0055 030A; +016F;016F;0075 030A;016F;0075 030A; +0170;0170;0055 030B;0170;0055 030B; +0171;0171;0075 030B;0171;0075 030B; +0172;0172;0055 0328;0172;0055 0328; +0173;0173;0075 0328;0173;0075 0328; +0174;0174;0057 0302;0174;0057 0302; +0175;0175;0077 0302;0175;0077 0302; +0176;0176;0059 0302;0176;0059 0302; +0177;0177;0079 0302;0177;0079 0302; +0178;0178;0059 0308;0178;0059 0308; +0179;0179;005A 0301;0179;005A 0301; +017A;017A;007A 0301;017A;007A 0301; +017B;017B;005A 0307;017B;005A 0307; +017C;017C;007A 0307;017C;007A 0307; +017D;017D;005A 030C;017D;005A 030C; +017E;017E;007A 030C;017E;007A 030C; +017F;017F;017F;0073;0073; +01A0;01A0;004F 031B;01A0;004F 031B; +01A1;01A1;006F 031B;01A1;006F 031B; +01AF;01AF;0055 031B;01AF;0055 031B; +01B0;01B0;0075 031B;01B0;0075 031B; +01C4;01C4;01C4;0044 017D;0044 005A 030C; +01C5;01C5;01C5;0044 017E;0044 007A 030C; +01C6;01C6;01C6;0064 017E;0064 007A 030C; +01C7;01C7;01C7;004C 004A;004C 004A; +01C8;01C8;01C8;004C 006A;004C 006A; +01C9;01C9;01C9;006C 006A;006C 006A; +01CA;01CA;01CA;004E 004A;004E 004A; +01CB;01CB;01CB;004E 006A;004E 006A; +01CC;01CC;01CC;006E 006A;006E 006A; +01CD;01CD;0041 030C;01CD;0041 030C; +01CE;01CE;0061 030C;01CE;0061 030C; +01CF;01CF;0049 030C;01CF;0049 030C; +01D0;01D0;0069 030C;01D0;0069 030C; +01D1;01D1;004F 030C;01D1;004F 030C; +01D2;01D2;006F 030C;01D2;006F 030C; +01D3;01D3;0055 030C;01D3;0055 030C; +01D4;01D4;0075 030C;01D4;0075 030C; +01D5;01D5;0055 0308 0304;01D5;0055 0308 0304; +01D6;01D6;0075 0308 0304;01D6;0075 0308 0304; +01D7;01D7;0055 0308 0301;01D7;0055 0308 0301; +01D8;01D8;0075 0308 0301;01D8;0075 0308 0301; +01D9;01D9;0055 0308 030C;01D9;0055 0308 030C; +01DA;01DA;0075 0308 030C;01DA;0075 0308 030C; +01DB;01DB;0055 0308 0300;01DB;0055 0308 0300; +01DC;01DC;0075 0308 0300;01DC;0075 0308 0300; +01DE;01DE;0041 0308 0304;01DE;0041 0308 0304; +01DF;01DF;0061 0308 0304;01DF;0061 0308 0304; +01E0;01E0;0041 0307 0304;01E0;0041 0307 0304; +01E1;01E1;0061 0307 0304;01E1;0061 0307 0304; +01E2;01E2;00C6 0304;01E2;00C6 0304; +01E3;01E3;00E6 0304;01E3;00E6 0304; +01E6;01E6;0047 030C;01E6;0047 030C; +01E7;01E7;0067 030C;01E7;0067 030C; +01E8;01E8;004B 030C;01E8;004B 030C; +01E9;01E9;006B 030C;01E9;006B 030C; +01EA;01EA;004F 0328;01EA;004F 0328; +01EB;01EB;006F 0328;01EB;006F 0328; +01EC;01EC;004F 0328 0304;01EC;004F 0328 0304; +01ED;01ED;006F 0328 0304;01ED;006F 0328 0304; +01EE;01EE;01B7 030C;01EE;01B7 030C; +01EF;01EF;0292 030C;01EF;0292 030C; +01F0;01F0;006A 030C;01F0;006A 030C; +01F1;01F1;01F1;0044 005A;0044 005A; +01F2;01F2;01F2;0044 007A;0044 007A; +01F3;01F3;01F3;0064 007A;0064 007A; +01F4;01F4;0047 0301;01F4;0047 0301; +01F5;01F5;0067 0301;01F5;0067 0301; +01F8;01F8;004E 0300;01F8;004E 0300; +01F9;01F9;006E 0300;01F9;006E 0300; +01FA;01FA;0041 030A 0301;01FA;0041 030A 0301; +01FB;01FB;0061 030A 0301;01FB;0061 030A 0301; +01FC;01FC;00C6 0301;01FC;00C6 0301; +01FD;01FD;00E6 0301;01FD;00E6 0301; +01FE;01FE;00D8 0301;01FE;00D8 0301; +01FF;01FF;00F8 0301;01FF;00F8 0301; +0200;0200;0041 030F;0200;0041 030F; +0201;0201;0061 030F;0201;0061 030F; +0202;0202;0041 0311;0202;0041 0311; +0203;0203;0061 0311;0203;0061 0311; +0204;0204;0045 030F;0204;0045 030F; +0205;0205;0065 030F;0205;0065 030F; +0206;0206;0045 0311;0206;0045 0311; +0207;0207;0065 0311;0207;0065 0311; +0208;0208;0049 030F;0208;0049 030F; +0209;0209;0069 030F;0209;0069 030F; +020A;020A;0049 0311;020A;0049 0311; +020B;020B;0069 0311;020B;0069 0311; +020C;020C;004F 030F;020C;004F 030F; +020D;020D;006F 030F;020D;006F 030F; +020E;020E;004F 0311;020E;004F 0311; +020F;020F;006F 0311;020F;006F 0311; +0210;0210;0052 030F;0210;0052 030F; +0211;0211;0072 030F;0211;0072 030F; +0212;0212;0052 0311;0212;0052 0311; +0213;0213;0072 0311;0213;0072 0311; +0214;0214;0055 030F;0214;0055 030F; +0215;0215;0075 030F;0215;0075 030F; +0216;0216;0055 0311;0216;0055 0311; +0217;0217;0075 0311;0217;0075 0311; +0218;0218;0053 0326;0218;0053 0326; +0219;0219;0073 0326;0219;0073 0326; +021A;021A;0054 0326;021A;0054 0326; +021B;021B;0074 0326;021B;0074 0326; +021E;021E;0048 030C;021E;0048 030C; +021F;021F;0068 030C;021F;0068 030C; +0226;0226;0041 0307;0226;0041 0307; +0227;0227;0061 0307;0227;0061 0307; +0228;0228;0045 0327;0228;0045 0327; +0229;0229;0065 0327;0229;0065 0327; +022A;022A;004F 0308 0304;022A;004F 0308 0304; +022B;022B;006F 0308 0304;022B;006F 0308 0304; +022C;022C;004F 0303 0304;022C;004F 0303 0304; +022D;022D;006F 0303 0304;022D;006F 0303 0304; +022E;022E;004F 0307;022E;004F 0307; +022F;022F;006F 0307;022F;006F 0307; +0230;0230;004F 0307 0304;0230;004F 0307 0304; +0231;0231;006F 0307 0304;0231;006F 0307 0304; +0232;0232;0059 0304;0232;0059 0304; +0233;0233;0079 0304;0233;0079 0304; +02B0;02B0;02B0;0068;0068; +02B1;02B1;02B1;0266;0266; +02B2;02B2;02B2;006A;006A; +02B3;02B3;02B3;0072;0072; +02B4;02B4;02B4;0279;0279; +02B5;02B5;02B5;027B;027B; +02B6;02B6;02B6;0281;0281; +02B7;02B7;02B7;0077;0077; +02B8;02B8;02B8;0079;0079; +02D8;02D8;02D8;0020 0306;0020 0306; +02D9;02D9;02D9;0020 0307;0020 0307; +02DA;02DA;02DA;0020 030A;0020 030A; +02DB;02DB;02DB;0020 0328;0020 0328; +02DC;02DC;02DC;0020 0303;0020 0303; +02DD;02DD;02DD;0020 030B;0020 030B; +02E0;02E0;02E0;0263;0263; +02E1;02E1;02E1;006C;006C; +02E2;02E2;02E2;0073;0073; +02E3;02E3;02E3;0078;0078; +02E4;02E4;02E4;0295;0295; +0340;0300;0300;0300;0300; +0341;0301;0301;0301;0301; +0343;0313;0313;0313;0313; +0344;0308 0301;0308 0301;0308 0301;0308 0301; +0374;02B9;02B9;02B9;02B9; +037A;037A;037A;0020 0345;0020 0345; +037E;003B;003B;003B;003B; +0384;0384;0384;0020 0301;0020 0301; +0385;0385;00A8 0301;0020 0308 0301;0020 0308 0301; +0386;0386;0391 0301;0386;0391 0301; +0387;00B7;00B7;00B7;00B7; +0388;0388;0395 0301;0388;0395 0301; +0389;0389;0397 0301;0389;0397 0301; +038A;038A;0399 0301;038A;0399 0301; +038C;038C;039F 0301;038C;039F 0301; +038E;038E;03A5 0301;038E;03A5 0301; +038F;038F;03A9 0301;038F;03A9 0301; +0390;0390;03B9 0308 0301;0390;03B9 0308 0301; +03AA;03AA;0399 0308;03AA;0399 0308; +03AB;03AB;03A5 0308;03AB;03A5 0308; +03AC;03AC;03B1 0301;03AC;03B1 0301; +03AD;03AD;03B5 0301;03AD;03B5 0301; +03AE;03AE;03B7 0301;03AE;03B7 0301; +03AF;03AF;03B9 0301;03AF;03B9 0301; +03B0;03B0;03C5 0308 0301;03B0;03C5 0308 0301; +03CA;03CA;03B9 0308;03CA;03B9 0308; +03CB;03CB;03C5 0308;03CB;03C5 0308; +03CC;03CC;03BF 0301;03CC;03BF 0301; +03CD;03CD;03C5 0301;03CD;03C5 0301; +03CE;03CE;03C9 0301;03CE;03C9 0301; +03D0;03D0;03D0;03B2;03B2; +03D1;03D1;03D1;03B8;03B8; +03D2;03D2;03D2;03A5;03A5; +03D3;03D3;03D2 0301;038E;03A5 0301; +03D4;03D4;03D2 0308;03AB;03A5 0308; +03D5;03D5;03D5;03C6;03C6; +03D6;03D6;03D6;03C0;03C0; +03F0;03F0;03F0;03BA;03BA; +03F1;03F1;03F1;03C1;03C1; +03F2;03F2;03F2;03C2;03C2; +03F4;03F4;03F4;0398;0398; +03F5;03F5;03F5;03B5;03B5; +03F9;03F9;03F9;03A3;03A3; +0400;0400;0415 0300;0400;0415 0300; +0401;0401;0415 0308;0401;0415 0308; +0403;0403;0413 0301;0403;0413 0301; +0407;0407;0406 0308;0407;0406 0308; +040C;040C;041A 0301;040C;041A 0301; +040D;040D;0418 0300;040D;0418 0300; +040E;040E;0423 0306;040E;0423 0306; +0419;0419;0418 0306;0419;0418 0306; +0439;0439;0438 0306;0439;0438 0306; +0450;0450;0435 0300;0450;0435 0300; +0451;0451;0435 0308;0451;0435 0308; +0453;0453;0433 0301;0453;0433 0301; +0457;0457;0456 0308;0457;0456 0308; +045C;045C;043A 0301;045C;043A 0301; +045D;045D;0438 0300;045D;0438 0300; +045E;045E;0443 0306;045E;0443 0306; +0476;0476;0474 030F;0476;0474 030F; +0477;0477;0475 030F;0477;0475 030F; +04C1;04C1;0416 0306;04C1;0416 0306; +04C2;04C2;0436 0306;04C2;0436 0306; +04D0;04D0;0410 0306;04D0;0410 0306; +04D1;04D1;0430 0306;04D1;0430 0306; +04D2;04D2;0410 0308;04D2;0410 0308; +04D3;04D3;0430 0308;04D3;0430 0308; +04D6;04D6;0415 0306;04D6;0415 0306; +04D7;04D7;0435 0306;04D7;0435 0306; +04DA;04DA;04D8 0308;04DA;04D8 0308; +04DB;04DB;04D9 0308;04DB;04D9 0308; +04DC;04DC;0416 0308;04DC;0416 0308; +04DD;04DD;0436 0308;04DD;0436 0308; +04DE;04DE;0417 0308;04DE;0417 0308; +04DF;04DF;0437 0308;04DF;0437 0308; +04E2;04E2;0418 0304;04E2;0418 0304; +04E3;04E3;0438 0304;04E3;0438 0304; +04E4;04E4;0418 0308;04E4;0418 0308; +04E5;04E5;0438 0308;04E5;0438 0308; +04E6;04E6;041E 0308;04E6;041E 0308; +04E7;04E7;043E 0308;04E7;043E 0308; +04EA;04EA;04E8 0308;04EA;04E8 0308; +04EB;04EB;04E9 0308;04EB;04E9 0308; +04EC;04EC;042D 0308;04EC;042D 0308; +04ED;04ED;044D 0308;04ED;044D 0308; +04EE;04EE;0423 0304;04EE;0423 0304; +04EF;04EF;0443 0304;04EF;0443 0304; +04F0;04F0;0423 0308;04F0;0423 0308; +04F1;04F1;0443 0308;04F1;0443 0308; +04F2;04F2;0423 030B;04F2;0423 030B; +04F3;04F3;0443 030B;04F3;0443 030B; +04F4;04F4;0427 0308;04F4;0427 0308; +04F5;04F5;0447 0308;04F5;0447 0308; +04F8;04F8;042B 0308;04F8;042B 0308; +04F9;04F9;044B 0308;04F9;044B 0308; +0587;0587;0587;0565 0582;0565 0582; +0622;0622;0627 0653;0622;0627 0653; +0623;0623;0627 0654;0623;0627 0654; +0624;0624;0648 0654;0624;0648 0654; +0625;0625;0627 0655;0625;0627 0655; +0626;0626;064A 0654;0626;064A 0654; +0675;0675;0675;0627 0674;0627 0674; +0676;0676;0676;0648 0674;0648 0674; +0677;0677;0677;06C7 0674;06C7 0674; +0678;0678;0678;064A 0674;064A 0674; +06C0;06C0;06D5 0654;06C0;06D5 0654; +06C2;06C2;06C1 0654;06C2;06C1 0654; +06D3;06D3;06D2 0654;06D3;06D2 0654; +0929;0929;0928 093C;0929;0928 093C; +0931;0931;0930 093C;0931;0930 093C; +0934;0934;0933 093C;0934;0933 093C; +0958;0915 093C;0915 093C;0915 093C;0915 093C; +0959;0916 093C;0916 093C;0916 093C;0916 093C; +095A;0917 093C;0917 093C;0917 093C;0917 093C; +095B;091C 093C;091C 093C;091C 093C;091C 093C; +095C;0921 093C;0921 093C;0921 093C;0921 093C; +095D;0922 093C;0922 093C;0922 093C;0922 093C; +095E;092B 093C;092B 093C;092B 093C;092B 093C; +095F;092F 093C;092F 093C;092F 093C;092F 093C; +09CB;09CB;09C7 09BE;09CB;09C7 09BE; +09CC;09CC;09C7 09D7;09CC;09C7 09D7; +09DC;09A1 09BC;09A1 09BC;09A1 09BC;09A1 09BC; +09DD;09A2 09BC;09A2 09BC;09A2 09BC;09A2 09BC; +09DF;09AF 09BC;09AF 09BC;09AF 09BC;09AF 09BC; +0A33;0A32 0A3C;0A32 0A3C;0A32 0A3C;0A32 0A3C; +0A36;0A38 0A3C;0A38 0A3C;0A38 0A3C;0A38 0A3C; +0A59;0A16 0A3C;0A16 0A3C;0A16 0A3C;0A16 0A3C; +0A5A;0A17 0A3C;0A17 0A3C;0A17 0A3C;0A17 0A3C; +0A5B;0A1C 0A3C;0A1C 0A3C;0A1C 0A3C;0A1C 0A3C; +0A5E;0A2B 0A3C;0A2B 0A3C;0A2B 0A3C;0A2B 0A3C; +0B48;0B48;0B47 0B56;0B48;0B47 0B56; +0B4B;0B4B;0B47 0B3E;0B4B;0B47 0B3E; +0B4C;0B4C;0B47 0B57;0B4C;0B47 0B57; +0B5C;0B21 0B3C;0B21 0B3C;0B21 0B3C;0B21 0B3C; +0B5D;0B22 0B3C;0B22 0B3C;0B22 0B3C;0B22 0B3C; +0B94;0B94;0B92 0BD7;0B94;0B92 0BD7; +0BCA;0BCA;0BC6 0BBE;0BCA;0BC6 0BBE; +0BCB;0BCB;0BC7 0BBE;0BCB;0BC7 0BBE; +0BCC;0BCC;0BC6 0BD7;0BCC;0BC6 0BD7; +0C48;0C48;0C46 0C56;0C48;0C46 0C56; +0CC0;0CC0;0CBF 0CD5;0CC0;0CBF 0CD5; +0CC7;0CC7;0CC6 0CD5;0CC7;0CC6 0CD5; +0CC8;0CC8;0CC6 0CD6;0CC8;0CC6 0CD6; +0CCA;0CCA;0CC6 0CC2;0CCA;0CC6 0CC2; +0CCB;0CCB;0CC6 0CC2 0CD5;0CCB;0CC6 0CC2 0CD5; +0D4A;0D4A;0D46 0D3E;0D4A;0D46 0D3E; +0D4B;0D4B;0D47 0D3E;0D4B;0D47 0D3E; +0D4C;0D4C;0D46 0D57;0D4C;0D46 0D57; +0DDA;0DDA;0DD9 0DCA;0DDA;0DD9 0DCA; +0DDC;0DDC;0DD9 0DCF;0DDC;0DD9 0DCF; +0DDD;0DDD;0DD9 0DCF 0DCA;0DDD;0DD9 0DCF 0DCA; +0DDE;0DDE;0DD9 0DDF;0DDE;0DD9 0DDF; +0E33;0E33;0E33;0E4D 0E32;0E4D 0E32; +0EB3;0EB3;0EB3;0ECD 0EB2;0ECD 0EB2; +0EDC;0EDC;0EDC;0EAB 0E99;0EAB 0E99; +0EDD;0EDD;0EDD;0EAB 0EA1;0EAB 0EA1; +0F0C;0F0C;0F0C;0F0B;0F0B; +0F43;0F42 0FB7;0F42 0FB7;0F42 0FB7;0F42 0FB7; +0F4D;0F4C 0FB7;0F4C 0FB7;0F4C 0FB7;0F4C 0FB7; +0F52;0F51 0FB7;0F51 0FB7;0F51 0FB7;0F51 0FB7; +0F57;0F56 0FB7;0F56 0FB7;0F56 0FB7;0F56 0FB7; +0F5C;0F5B 0FB7;0F5B 0FB7;0F5B 0FB7;0F5B 0FB7; +0F69;0F40 0FB5;0F40 0FB5;0F40 0FB5;0F40 0FB5; +0F73;0F71 0F72;0F71 0F72;0F71 0F72;0F71 0F72; +0F75;0F71 0F74;0F71 0F74;0F71 0F74;0F71 0F74; +0F76;0FB2 0F80;0FB2 0F80;0FB2 0F80;0FB2 0F80; +0F77;0F77;0F77;0FB2 0F71 0F80;0FB2 0F71 0F80; +0F78;0FB3 0F80;0FB3 0F80;0FB3 0F80;0FB3 0F80; +0F79;0F79;0F79;0FB3 0F71 0F80;0FB3 0F71 0F80; +0F81;0F71 0F80;0F71 0F80;0F71 0F80;0F71 0F80; +0F93;0F92 0FB7;0F92 0FB7;0F92 0FB7;0F92 0FB7; +0F9D;0F9C 0FB7;0F9C 0FB7;0F9C 0FB7;0F9C 0FB7; +0FA2;0FA1 0FB7;0FA1 0FB7;0FA1 0FB7;0FA1 0FB7; +0FA7;0FA6 0FB7;0FA6 0FB7;0FA6 0FB7;0FA6 0FB7; +0FAC;0FAB 0FB7;0FAB 0FB7;0FAB 0FB7;0FAB 0FB7; +0FB9;0F90 0FB5;0F90 0FB5;0F90 0FB5;0F90 0FB5; +1026;1026;1025 102E;1026;1025 102E; +10FC;10FC;10FC;10DC;10DC; +1B06;1B06;1B05 1B35;1B06;1B05 1B35; +1B08;1B08;1B07 1B35;1B08;1B07 1B35; +1B0A;1B0A;1B09 1B35;1B0A;1B09 1B35; +1B0C;1B0C;1B0B 1B35;1B0C;1B0B 1B35; +1B0E;1B0E;1B0D 1B35;1B0E;1B0D 1B35; +1B12;1B12;1B11 1B35;1B12;1B11 1B35; +1B3B;1B3B;1B3A 1B35;1B3B;1B3A 1B35; +1B3D;1B3D;1B3C 1B35;1B3D;1B3C 1B35; +1B40;1B40;1B3E 1B35;1B40;1B3E 1B35; +1B41;1B41;1B3F 1B35;1B41;1B3F 1B35; +1B43;1B43;1B42 1B35;1B43;1B42 1B35; +1D2C;1D2C;1D2C;0041;0041; +1D2D;1D2D;1D2D;00C6;00C6; +1D2E;1D2E;1D2E;0042;0042; +1D30;1D30;1D30;0044;0044; +1D31;1D31;1D31;0045;0045; +1D32;1D32;1D32;018E;018E; +1D33;1D33;1D33;0047;0047; +1D34;1D34;1D34;0048;0048; +1D35;1D35;1D35;0049;0049; +1D36;1D36;1D36;004A;004A; +1D37;1D37;1D37;004B;004B; +1D38;1D38;1D38;004C;004C; +1D39;1D39;1D39;004D;004D; +1D3A;1D3A;1D3A;004E;004E; +1D3C;1D3C;1D3C;004F;004F; +1D3D;1D3D;1D3D;0222;0222; +1D3E;1D3E;1D3E;0050;0050; +1D3F;1D3F;1D3F;0052;0052; +1D40;1D40;1D40;0054;0054; +1D41;1D41;1D41;0055;0055; +1D42;1D42;1D42;0057;0057; +1D43;1D43;1D43;0061;0061; +1D44;1D44;1D44;0250;0250; +1D45;1D45;1D45;0251;0251; +1D46;1D46;1D46;1D02;1D02; +1D47;1D47;1D47;0062;0062; +1D48;1D48;1D48;0064;0064; +1D49;1D49;1D49;0065;0065; +1D4A;1D4A;1D4A;0259;0259; +1D4B;1D4B;1D4B;025B;025B; +1D4C;1D4C;1D4C;025C;025C; +1D4D;1D4D;1D4D;0067;0067; +1D4F;1D4F;1D4F;006B;006B; +1D50;1D50;1D50;006D;006D; +1D51;1D51;1D51;014B;014B; +1D52;1D52;1D52;006F;006F; +1D53;1D53;1D53;0254;0254; +1D54;1D54;1D54;1D16;1D16; +1D55;1D55;1D55;1D17;1D17; +1D56;1D56;1D56;0070;0070; +1D57;1D57;1D57;0074;0074; +1D58;1D58;1D58;0075;0075; +1D59;1D59;1D59;1D1D;1D1D; +1D5A;1D5A;1D5A;026F;026F; +1D5B;1D5B;1D5B;0076;0076; +1D5C;1D5C;1D5C;1D25;1D25; +1D5D;1D5D;1D5D;03B2;03B2; +1D5E;1D5E;1D5E;03B3;03B3; +1D5F;1D5F;1D5F;03B4;03B4; +1D60;1D60;1D60;03C6;03C6; +1D61;1D61;1D61;03C7;03C7; +1D62;1D62;1D62;0069;0069; +1D63;1D63;1D63;0072;0072; +1D64;1D64;1D64;0075;0075; +1D65;1D65;1D65;0076;0076; +1D66;1D66;1D66;03B2;03B2; +1D67;1D67;1D67;03B3;03B3; +1D68;1D68;1D68;03C1;03C1; +1D69;1D69;1D69;03C6;03C6; +1D6A;1D6A;1D6A;03C7;03C7; +1D78;1D78;1D78;043D;043D; +1D9B;1D9B;1D9B;0252;0252; +1D9C;1D9C;1D9C;0063;0063; +1D9D;1D9D;1D9D;0255;0255; +1D9E;1D9E;1D9E;00F0;00F0; +1D9F;1D9F;1D9F;025C;025C; +1DA0;1DA0;1DA0;0066;0066; +1DA1;1DA1;1DA1;025F;025F; +1DA2;1DA2;1DA2;0261;0261; +1DA3;1DA3;1DA3;0265;0265; +1DA4;1DA4;1DA4;0268;0268; +1DA5;1DA5;1DA5;0269;0269; +1DA6;1DA6;1DA6;026A;026A; +1DA7;1DA7;1DA7;1D7B;1D7B; +1DA8;1DA8;1DA8;029D;029D; +1DA9;1DA9;1DA9;026D;026D; +1DAA;1DAA;1DAA;1D85;1D85; +1DAB;1DAB;1DAB;029F;029F; +1DAC;1DAC;1DAC;0271;0271; +1DAD;1DAD;1DAD;0270;0270; +1DAE;1DAE;1DAE;0272;0272; +1DAF;1DAF;1DAF;0273;0273; +1DB0;1DB0;1DB0;0274;0274; +1DB1;1DB1;1DB1;0275;0275; +1DB2;1DB2;1DB2;0278;0278; +1DB3;1DB3;1DB3;0282;0282; +1DB4;1DB4;1DB4;0283;0283; +1DB5;1DB5;1DB5;01AB;01AB; +1DB6;1DB6;1DB6;0289;0289; +1DB7;1DB7;1DB7;028A;028A; +1DB8;1DB8;1DB8;1D1C;1D1C; +1DB9;1DB9;1DB9;028B;028B; +1DBA;1DBA;1DBA;028C;028C; +1DBB;1DBB;1DBB;007A;007A; +1DBC;1DBC;1DBC;0290;0290; +1DBD;1DBD;1DBD;0291;0291; +1DBE;1DBE;1DBE;0292;0292; +1DBF;1DBF;1DBF;03B8;03B8; +1E00;1E00;0041 0325;1E00;0041 0325; +1E01;1E01;0061 0325;1E01;0061 0325; +1E02;1E02;0042 0307;1E02;0042 0307; +1E03;1E03;0062 0307;1E03;0062 0307; +1E04;1E04;0042 0323;1E04;0042 0323; +1E05;1E05;0062 0323;1E05;0062 0323; +1E06;1E06;0042 0331;1E06;0042 0331; +1E07;1E07;0062 0331;1E07;0062 0331; +1E08;1E08;0043 0327 0301;1E08;0043 0327 0301; +1E09;1E09;0063 0327 0301;1E09;0063 0327 0301; +1E0A;1E0A;0044 0307;1E0A;0044 0307; +1E0B;1E0B;0064 0307;1E0B;0064 0307; +1E0C;1E0C;0044 0323;1E0C;0044 0323; +1E0D;1E0D;0064 0323;1E0D;0064 0323; +1E0E;1E0E;0044 0331;1E0E;0044 0331; +1E0F;1E0F;0064 0331;1E0F;0064 0331; +1E10;1E10;0044 0327;1E10;0044 0327; +1E11;1E11;0064 0327;1E11;0064 0327; +1E12;1E12;0044 032D;1E12;0044 032D; +1E13;1E13;0064 032D;1E13;0064 032D; +1E14;1E14;0045 0304 0300;1E14;0045 0304 0300; +1E15;1E15;0065 0304 0300;1E15;0065 0304 0300; +1E16;1E16;0045 0304 0301;1E16;0045 0304 0301; +1E17;1E17;0065 0304 0301;1E17;0065 0304 0301; +1E18;1E18;0045 032D;1E18;0045 032D; +1E19;1E19;0065 032D;1E19;0065 032D; +1E1A;1E1A;0045 0330;1E1A;0045 0330; +1E1B;1E1B;0065 0330;1E1B;0065 0330; +1E1C;1E1C;0045 0327 0306;1E1C;0045 0327 0306; +1E1D;1E1D;0065 0327 0306;1E1D;0065 0327 0306; +1E1E;1E1E;0046 0307;1E1E;0046 0307; +1E1F;1E1F;0066 0307;1E1F;0066 0307; +1E20;1E20;0047 0304;1E20;0047 0304; +1E21;1E21;0067 0304;1E21;0067 0304; +1E22;1E22;0048 0307;1E22;0048 0307; +1E23;1E23;0068 0307;1E23;0068 0307; +1E24;1E24;0048 0323;1E24;0048 0323; +1E25;1E25;0068 0323;1E25;0068 0323; +1E26;1E26;0048 0308;1E26;0048 0308; +1E27;1E27;0068 0308;1E27;0068 0308; +1E28;1E28;0048 0327;1E28;0048 0327; +1E29;1E29;0068 0327;1E29;0068 0327; +1E2A;1E2A;0048 032E;1E2A;0048 032E; +1E2B;1E2B;0068 032E;1E2B;0068 032E; +1E2C;1E2C;0049 0330;1E2C;0049 0330; +1E2D;1E2D;0069 0330;1E2D;0069 0330; +1E2E;1E2E;0049 0308 0301;1E2E;0049 0308 0301; +1E2F;1E2F;0069 0308 0301;1E2F;0069 0308 0301; +1E30;1E30;004B 0301;1E30;004B 0301; +1E31;1E31;006B 0301;1E31;006B 0301; +1E32;1E32;004B 0323;1E32;004B 0323; +1E33;1E33;006B 0323;1E33;006B 0323; +1E34;1E34;004B 0331;1E34;004B 0331; +1E35;1E35;006B 0331;1E35;006B 0331; +1E36;1E36;004C 0323;1E36;004C 0323; +1E37;1E37;006C 0323;1E37;006C 0323; +1E38;1E38;004C 0323 0304;1E38;004C 0323 0304; +1E39;1E39;006C 0323 0304;1E39;006C 0323 0304; +1E3A;1E3A;004C 0331;1E3A;004C 0331; +1E3B;1E3B;006C 0331;1E3B;006C 0331; +1E3C;1E3C;004C 032D;1E3C;004C 032D; +1E3D;1E3D;006C 032D;1E3D;006C 032D; +1E3E;1E3E;004D 0301;1E3E;004D 0301; +1E3F;1E3F;006D 0301;1E3F;006D 0301; +1E40;1E40;004D 0307;1E40;004D 0307; +1E41;1E41;006D 0307;1E41;006D 0307; +1E42;1E42;004D 0323;1E42;004D 0323; +1E43;1E43;006D 0323;1E43;006D 0323; +1E44;1E44;004E 0307;1E44;004E 0307; +1E45;1E45;006E 0307;1E45;006E 0307; +1E46;1E46;004E 0323;1E46;004E 0323; +1E47;1E47;006E 0323;1E47;006E 0323; +1E48;1E48;004E 0331;1E48;004E 0331; +1E49;1E49;006E 0331;1E49;006E 0331; +1E4A;1E4A;004E 032D;1E4A;004E 032D; +1E4B;1E4B;006E 032D;1E4B;006E 032D; +1E4C;1E4C;004F 0303 0301;1E4C;004F 0303 0301; +1E4D;1E4D;006F 0303 0301;1E4D;006F 0303 0301; +1E4E;1E4E;004F 0303 0308;1E4E;004F 0303 0308; +1E4F;1E4F;006F 0303 0308;1E4F;006F 0303 0308; +1E50;1E50;004F 0304 0300;1E50;004F 0304 0300; +1E51;1E51;006F 0304 0300;1E51;006F 0304 0300; +1E52;1E52;004F 0304 0301;1E52;004F 0304 0301; +1E53;1E53;006F 0304 0301;1E53;006F 0304 0301; +1E54;1E54;0050 0301;1E54;0050 0301; +1E55;1E55;0070 0301;1E55;0070 0301; +1E56;1E56;0050 0307;1E56;0050 0307; +1E57;1E57;0070 0307;1E57;0070 0307; +1E58;1E58;0052 0307;1E58;0052 0307; +1E59;1E59;0072 0307;1E59;0072 0307; +1E5A;1E5A;0052 0323;1E5A;0052 0323; +1E5B;1E5B;0072 0323;1E5B;0072 0323; +1E5C;1E5C;0052 0323 0304;1E5C;0052 0323 0304; +1E5D;1E5D;0072 0323 0304;1E5D;0072 0323 0304; +1E5E;1E5E;0052 0331;1E5E;0052 0331; +1E5F;1E5F;0072 0331;1E5F;0072 0331; +1E60;1E60;0053 0307;1E60;0053 0307; +1E61;1E61;0073 0307;1E61;0073 0307; +1E62;1E62;0053 0323;1E62;0053 0323; +1E63;1E63;0073 0323;1E63;0073 0323; +1E64;1E64;0053 0301 0307;1E64;0053 0301 0307; +1E65;1E65;0073 0301 0307;1E65;0073 0301 0307; +1E66;1E66;0053 030C 0307;1E66;0053 030C 0307; +1E67;1E67;0073 030C 0307;1E67;0073 030C 0307; +1E68;1E68;0053 0323 0307;1E68;0053 0323 0307; +1E69;1E69;0073 0323 0307;1E69;0073 0323 0307; +1E6A;1E6A;0054 0307;1E6A;0054 0307; +1E6B;1E6B;0074 0307;1E6B;0074 0307; +1E6C;1E6C;0054 0323;1E6C;0054 0323; +1E6D;1E6D;0074 0323;1E6D;0074 0323; +1E6E;1E6E;0054 0331;1E6E;0054 0331; +1E6F;1E6F;0074 0331;1E6F;0074 0331; +1E70;1E70;0054 032D;1E70;0054 032D; +1E71;1E71;0074 032D;1E71;0074 032D; +1E72;1E72;0055 0324;1E72;0055 0324; +1E73;1E73;0075 0324;1E73;0075 0324; +1E74;1E74;0055 0330;1E74;0055 0330; +1E75;1E75;0075 0330;1E75;0075 0330; +1E76;1E76;0055 032D;1E76;0055 032D; +1E77;1E77;0075 032D;1E77;0075 032D; +1E78;1E78;0055 0303 0301;1E78;0055 0303 0301; +1E79;1E79;0075 0303 0301;1E79;0075 0303 0301; +1E7A;1E7A;0055 0304 0308;1E7A;0055 0304 0308; +1E7B;1E7B;0075 0304 0308;1E7B;0075 0304 0308; +1E7C;1E7C;0056 0303;1E7C;0056 0303; +1E7D;1E7D;0076 0303;1E7D;0076 0303; +1E7E;1E7E;0056 0323;1E7E;0056 0323; +1E7F;1E7F;0076 0323;1E7F;0076 0323; +1E80;1E80;0057 0300;1E80;0057 0300; +1E81;1E81;0077 0300;1E81;0077 0300; +1E82;1E82;0057 0301;1E82;0057 0301; +1E83;1E83;0077 0301;1E83;0077 0301; +1E84;1E84;0057 0308;1E84;0057 0308; +1E85;1E85;0077 0308;1E85;0077 0308; +1E86;1E86;0057 0307;1E86;0057 0307; +1E87;1E87;0077 0307;1E87;0077 0307; +1E88;1E88;0057 0323;1E88;0057 0323; +1E89;1E89;0077 0323;1E89;0077 0323; +1E8A;1E8A;0058 0307;1E8A;0058 0307; +1E8B;1E8B;0078 0307;1E8B;0078 0307; +1E8C;1E8C;0058 0308;1E8C;0058 0308; +1E8D;1E8D;0078 0308;1E8D;0078 0308; +1E8E;1E8E;0059 0307;1E8E;0059 0307; +1E8F;1E8F;0079 0307;1E8F;0079 0307; +1E90;1E90;005A 0302;1E90;005A 0302; +1E91;1E91;007A 0302;1E91;007A 0302; +1E92;1E92;005A 0323;1E92;005A 0323; +1E93;1E93;007A 0323;1E93;007A 0323; +1E94;1E94;005A 0331;1E94;005A 0331; +1E95;1E95;007A 0331;1E95;007A 0331; +1E96;1E96;0068 0331;1E96;0068 0331; +1E97;1E97;0074 0308;1E97;0074 0308; +1E98;1E98;0077 030A;1E98;0077 030A; +1E99;1E99;0079 030A;1E99;0079 030A; +1E9A;1E9A;1E9A;0061 02BE;0061 02BE; +1E9B;1E9B;017F 0307;1E61;0073 0307; +1EA0;1EA0;0041 0323;1EA0;0041 0323; +1EA1;1EA1;0061 0323;1EA1;0061 0323; +1EA2;1EA2;0041 0309;1EA2;0041 0309; +1EA3;1EA3;0061 0309;1EA3;0061 0309; +1EA4;1EA4;0041 0302 0301;1EA4;0041 0302 0301; +1EA5;1EA5;0061 0302 0301;1EA5;0061 0302 0301; +1EA6;1EA6;0041 0302 0300;1EA6;0041 0302 0300; +1EA7;1EA7;0061 0302 0300;1EA7;0061 0302 0300; +1EA8;1EA8;0041 0302 0309;1EA8;0041 0302 0309; +1EA9;1EA9;0061 0302 0309;1EA9;0061 0302 0309; +1EAA;1EAA;0041 0302 0303;1EAA;0041 0302 0303; +1EAB;1EAB;0061 0302 0303;1EAB;0061 0302 0303; +1EAC;1EAC;0041 0323 0302;1EAC;0041 0323 0302; +1EAD;1EAD;0061 0323 0302;1EAD;0061 0323 0302; +1EAE;1EAE;0041 0306 0301;1EAE;0041 0306 0301; +1EAF;1EAF;0061 0306 0301;1EAF;0061 0306 0301; +1EB0;1EB0;0041 0306 0300;1EB0;0041 0306 0300; +1EB1;1EB1;0061 0306 0300;1EB1;0061 0306 0300; +1EB2;1EB2;0041 0306 0309;1EB2;0041 0306 0309; +1EB3;1EB3;0061 0306 0309;1EB3;0061 0306 0309; +1EB4;1EB4;0041 0306 0303;1EB4;0041 0306 0303; +1EB5;1EB5;0061 0306 0303;1EB5;0061 0306 0303; +1EB6;1EB6;0041 0323 0306;1EB6;0041 0323 0306; +1EB7;1EB7;0061 0323 0306;1EB7;0061 0323 0306; +1EB8;1EB8;0045 0323;1EB8;0045 0323; +1EB9;1EB9;0065 0323;1EB9;0065 0323; +1EBA;1EBA;0045 0309;1EBA;0045 0309; +1EBB;1EBB;0065 0309;1EBB;0065 0309; +1EBC;1EBC;0045 0303;1EBC;0045 0303; +1EBD;1EBD;0065 0303;1EBD;0065 0303; +1EBE;1EBE;0045 0302 0301;1EBE;0045 0302 0301; +1EBF;1EBF;0065 0302 0301;1EBF;0065 0302 0301; +1EC0;1EC0;0045 0302 0300;1EC0;0045 0302 0300; +1EC1;1EC1;0065 0302 0300;1EC1;0065 0302 0300; +1EC2;1EC2;0045 0302 0309;1EC2;0045 0302 0309; +1EC3;1EC3;0065 0302 0309;1EC3;0065 0302 0309; +1EC4;1EC4;0045 0302 0303;1EC4;0045 0302 0303; +1EC5;1EC5;0065 0302 0303;1EC5;0065 0302 0303; +1EC6;1EC6;0045 0323 0302;1EC6;0045 0323 0302; +1EC7;1EC7;0065 0323 0302;1EC7;0065 0323 0302; +1EC8;1EC8;0049 0309;1EC8;0049 0309; +1EC9;1EC9;0069 0309;1EC9;0069 0309; +1ECA;1ECA;0049 0323;1ECA;0049 0323; +1ECB;1ECB;0069 0323;1ECB;0069 0323; +1ECC;1ECC;004F 0323;1ECC;004F 0323; +1ECD;1ECD;006F 0323;1ECD;006F 0323; +1ECE;1ECE;004F 0309;1ECE;004F 0309; +1ECF;1ECF;006F 0309;1ECF;006F 0309; +1ED0;1ED0;004F 0302 0301;1ED0;004F 0302 0301; +1ED1;1ED1;006F 0302 0301;1ED1;006F 0302 0301; +1ED2;1ED2;004F 0302 0300;1ED2;004F 0302 0300; +1ED3;1ED3;006F 0302 0300;1ED3;006F 0302 0300; +1ED4;1ED4;004F 0302 0309;1ED4;004F 0302 0309; +1ED5;1ED5;006F 0302 0309;1ED5;006F 0302 0309; +1ED6;1ED6;004F 0302 0303;1ED6;004F 0302 0303; +1ED7;1ED7;006F 0302 0303;1ED7;006F 0302 0303; +1ED8;1ED8;004F 0323 0302;1ED8;004F 0323 0302; +1ED9;1ED9;006F 0323 0302;1ED9;006F 0323 0302; +1EDA;1EDA;004F 031B 0301;1EDA;004F 031B 0301; +1EDB;1EDB;006F 031B 0301;1EDB;006F 031B 0301; +1EDC;1EDC;004F 031B 0300;1EDC;004F 031B 0300; +1EDD;1EDD;006F 031B 0300;1EDD;006F 031B 0300; +1EDE;1EDE;004F 031B 0309;1EDE;004F 031B 0309; +1EDF;1EDF;006F 031B 0309;1EDF;006F 031B 0309; +1EE0;1EE0;004F 031B 0303;1EE0;004F 031B 0303; +1EE1;1EE1;006F 031B 0303;1EE1;006F 031B 0303; +1EE2;1EE2;004F 031B 0323;1EE2;004F 031B 0323; +1EE3;1EE3;006F 031B 0323;1EE3;006F 031B 0323; +1EE4;1EE4;0055 0323;1EE4;0055 0323; +1EE5;1EE5;0075 0323;1EE5;0075 0323; +1EE6;1EE6;0055 0309;1EE6;0055 0309; +1EE7;1EE7;0075 0309;1EE7;0075 0309; +1EE8;1EE8;0055 031B 0301;1EE8;0055 031B 0301; +1EE9;1EE9;0075 031B 0301;1EE9;0075 031B 0301; +1EEA;1EEA;0055 031B 0300;1EEA;0055 031B 0300; +1EEB;1EEB;0075 031B 0300;1EEB;0075 031B 0300; +1EEC;1EEC;0055 031B 0309;1EEC;0055 031B 0309; +1EED;1EED;0075 031B 0309;1EED;0075 031B 0309; +1EEE;1EEE;0055 031B 0303;1EEE;0055 031B 0303; +1EEF;1EEF;0075 031B 0303;1EEF;0075 031B 0303; +1EF0;1EF0;0055 031B 0323;1EF0;0055 031B 0323; +1EF1;1EF1;0075 031B 0323;1EF1;0075 031B 0323; +1EF2;1EF2;0059 0300;1EF2;0059 0300; +1EF3;1EF3;0079 0300;1EF3;0079 0300; +1EF4;1EF4;0059 0323;1EF4;0059 0323; +1EF5;1EF5;0079 0323;1EF5;0079 0323; +1EF6;1EF6;0059 0309;1EF6;0059 0309; +1EF7;1EF7;0079 0309;1EF7;0079 0309; +1EF8;1EF8;0059 0303;1EF8;0059 0303; +1EF9;1EF9;0079 0303;1EF9;0079 0303; +1F00;1F00;03B1 0313;1F00;03B1 0313; +1F01;1F01;03B1 0314;1F01;03B1 0314; +1F02;1F02;03B1 0313 0300;1F02;03B1 0313 0300; +1F03;1F03;03B1 0314 0300;1F03;03B1 0314 0300; +1F04;1F04;03B1 0313 0301;1F04;03B1 0313 0301; +1F05;1F05;03B1 0314 0301;1F05;03B1 0314 0301; +1F06;1F06;03B1 0313 0342;1F06;03B1 0313 0342; +1F07;1F07;03B1 0314 0342;1F07;03B1 0314 0342; +1F08;1F08;0391 0313;1F08;0391 0313; +1F09;1F09;0391 0314;1F09;0391 0314; +1F0A;1F0A;0391 0313 0300;1F0A;0391 0313 0300; +1F0B;1F0B;0391 0314 0300;1F0B;0391 0314 0300; +1F0C;1F0C;0391 0313 0301;1F0C;0391 0313 0301; +1F0D;1F0D;0391 0314 0301;1F0D;0391 0314 0301; +1F0E;1F0E;0391 0313 0342;1F0E;0391 0313 0342; +1F0F;1F0F;0391 0314 0342;1F0F;0391 0314 0342; +1F10;1F10;03B5 0313;1F10;03B5 0313; +1F11;1F11;03B5 0314;1F11;03B5 0314; +1F12;1F12;03B5 0313 0300;1F12;03B5 0313 0300; +1F13;1F13;03B5 0314 0300;1F13;03B5 0314 0300; +1F14;1F14;03B5 0313 0301;1F14;03B5 0313 0301; +1F15;1F15;03B5 0314 0301;1F15;03B5 0314 0301; +1F18;1F18;0395 0313;1F18;0395 0313; +1F19;1F19;0395 0314;1F19;0395 0314; +1F1A;1F1A;0395 0313 0300;1F1A;0395 0313 0300; +1F1B;1F1B;0395 0314 0300;1F1B;0395 0314 0300; +1F1C;1F1C;0395 0313 0301;1F1C;0395 0313 0301; +1F1D;1F1D;0395 0314 0301;1F1D;0395 0314 0301; +1F20;1F20;03B7 0313;1F20;03B7 0313; +1F21;1F21;03B7 0314;1F21;03B7 0314; +1F22;1F22;03B7 0313 0300;1F22;03B7 0313 0300; +1F23;1F23;03B7 0314 0300;1F23;03B7 0314 0300; +1F24;1F24;03B7 0313 0301;1F24;03B7 0313 0301; +1F25;1F25;03B7 0314 0301;1F25;03B7 0314 0301; +1F26;1F26;03B7 0313 0342;1F26;03B7 0313 0342; +1F27;1F27;03B7 0314 0342;1F27;03B7 0314 0342; +1F28;1F28;0397 0313;1F28;0397 0313; +1F29;1F29;0397 0314;1F29;0397 0314; +1F2A;1F2A;0397 0313 0300;1F2A;0397 0313 0300; +1F2B;1F2B;0397 0314 0300;1F2B;0397 0314 0300; +1F2C;1F2C;0397 0313 0301;1F2C;0397 0313 0301; +1F2D;1F2D;0397 0314 0301;1F2D;0397 0314 0301; +1F2E;1F2E;0397 0313 0342;1F2E;0397 0313 0342; +1F2F;1F2F;0397 0314 0342;1F2F;0397 0314 0342; +1F30;1F30;03B9 0313;1F30;03B9 0313; +1F31;1F31;03B9 0314;1F31;03B9 0314; +1F32;1F32;03B9 0313 0300;1F32;03B9 0313 0300; +1F33;1F33;03B9 0314 0300;1F33;03B9 0314 0300; +1F34;1F34;03B9 0313 0301;1F34;03B9 0313 0301; +1F35;1F35;03B9 0314 0301;1F35;03B9 0314 0301; +1F36;1F36;03B9 0313 0342;1F36;03B9 0313 0342; +1F37;1F37;03B9 0314 0342;1F37;03B9 0314 0342; +1F38;1F38;0399 0313;1F38;0399 0313; +1F39;1F39;0399 0314;1F39;0399 0314; +1F3A;1F3A;0399 0313 0300;1F3A;0399 0313 0300; +1F3B;1F3B;0399 0314 0300;1F3B;0399 0314 0300; +1F3C;1F3C;0399 0313 0301;1F3C;0399 0313 0301; +1F3D;1F3D;0399 0314 0301;1F3D;0399 0314 0301; +1F3E;1F3E;0399 0313 0342;1F3E;0399 0313 0342; +1F3F;1F3F;0399 0314 0342;1F3F;0399 0314 0342; +1F40;1F40;03BF 0313;1F40;03BF 0313; +1F41;1F41;03BF 0314;1F41;03BF 0314; +1F42;1F42;03BF 0313 0300;1F42;03BF 0313 0300; +1F43;1F43;03BF 0314 0300;1F43;03BF 0314 0300; +1F44;1F44;03BF 0313 0301;1F44;03BF 0313 0301; +1F45;1F45;03BF 0314 0301;1F45;03BF 0314 0301; +1F48;1F48;039F 0313;1F48;039F 0313; +1F49;1F49;039F 0314;1F49;039F 0314; +1F4A;1F4A;039F 0313 0300;1F4A;039F 0313 0300; +1F4B;1F4B;039F 0314 0300;1F4B;039F 0314 0300; +1F4C;1F4C;039F 0313 0301;1F4C;039F 0313 0301; +1F4D;1F4D;039F 0314 0301;1F4D;039F 0314 0301; +1F50;1F50;03C5 0313;1F50;03C5 0313; +1F51;1F51;03C5 0314;1F51;03C5 0314; +1F52;1F52;03C5 0313 0300;1F52;03C5 0313 0300; +1F53;1F53;03C5 0314 0300;1F53;03C5 0314 0300; +1F54;1F54;03C5 0313 0301;1F54;03C5 0313 0301; +1F55;1F55;03C5 0314 0301;1F55;03C5 0314 0301; +1F56;1F56;03C5 0313 0342;1F56;03C5 0313 0342; +1F57;1F57;03C5 0314 0342;1F57;03C5 0314 0342; +1F59;1F59;03A5 0314;1F59;03A5 0314; +1F5B;1F5B;03A5 0314 0300;1F5B;03A5 0314 0300; +1F5D;1F5D;03A5 0314 0301;1F5D;03A5 0314 0301; +1F5F;1F5F;03A5 0314 0342;1F5F;03A5 0314 0342; +1F60;1F60;03C9 0313;1F60;03C9 0313; +1F61;1F61;03C9 0314;1F61;03C9 0314; +1F62;1F62;03C9 0313 0300;1F62;03C9 0313 0300; +1F63;1F63;03C9 0314 0300;1F63;03C9 0314 0300; +1F64;1F64;03C9 0313 0301;1F64;03C9 0313 0301; +1F65;1F65;03C9 0314 0301;1F65;03C9 0314 0301; +1F66;1F66;03C9 0313 0342;1F66;03C9 0313 0342; +1F67;1F67;03C9 0314 0342;1F67;03C9 0314 0342; +1F68;1F68;03A9 0313;1F68;03A9 0313; +1F69;1F69;03A9 0314;1F69;03A9 0314; +1F6A;1F6A;03A9 0313 0300;1F6A;03A9 0313 0300; +1F6B;1F6B;03A9 0314 0300;1F6B;03A9 0314 0300; +1F6C;1F6C;03A9 0313 0301;1F6C;03A9 0313 0301; +1F6D;1F6D;03A9 0314 0301;1F6D;03A9 0314 0301; +1F6E;1F6E;03A9 0313 0342;1F6E;03A9 0313 0342; +1F6F;1F6F;03A9 0314 0342;1F6F;03A9 0314 0342; +1F70;1F70;03B1 0300;1F70;03B1 0300; +1F71;03AC;03B1 0301;03AC;03B1 0301; +1F72;1F72;03B5 0300;1F72;03B5 0300; +1F73;03AD;03B5 0301;03AD;03B5 0301; +1F74;1F74;03B7 0300;1F74;03B7 0300; +1F75;03AE;03B7 0301;03AE;03B7 0301; +1F76;1F76;03B9 0300;1F76;03B9 0300; +1F77;03AF;03B9 0301;03AF;03B9 0301; +1F78;1F78;03BF 0300;1F78;03BF 0300; +1F79;03CC;03BF 0301;03CC;03BF 0301; +1F7A;1F7A;03C5 0300;1F7A;03C5 0300; +1F7B;03CD;03C5 0301;03CD;03C5 0301; +1F7C;1F7C;03C9 0300;1F7C;03C9 0300; +1F7D;03CE;03C9 0301;03CE;03C9 0301; +1F80;1F80;03B1 0313 0345;1F80;03B1 0313 0345; +1F81;1F81;03B1 0314 0345;1F81;03B1 0314 0345; +1F82;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; +1F83;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; +1F84;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; +1F85;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; +1F86;1F86;03B1 0313 0342 0345;1F86;03B1 0313 0342 0345; +1F87;1F87;03B1 0314 0342 0345;1F87;03B1 0314 0342 0345; +1F88;1F88;0391 0313 0345;1F88;0391 0313 0345; +1F89;1F89;0391 0314 0345;1F89;0391 0314 0345; +1F8A;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; +1F8B;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; +1F8C;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; +1F8D;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; +1F8E;1F8E;0391 0313 0342 0345;1F8E;0391 0313 0342 0345; +1F8F;1F8F;0391 0314 0342 0345;1F8F;0391 0314 0342 0345; +1F90;1F90;03B7 0313 0345;1F90;03B7 0313 0345; +1F91;1F91;03B7 0314 0345;1F91;03B7 0314 0345; +1F92;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; +1F93;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; +1F94;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; +1F95;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; +1F96;1F96;03B7 0313 0342 0345;1F96;03B7 0313 0342 0345; +1F97;1F97;03B7 0314 0342 0345;1F97;03B7 0314 0342 0345; +1F98;1F98;0397 0313 0345;1F98;0397 0313 0345; +1F99;1F99;0397 0314 0345;1F99;0397 0314 0345; +1F9A;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; +1F9B;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; +1F9C;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; +1F9D;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; +1F9E;1F9E;0397 0313 0342 0345;1F9E;0397 0313 0342 0345; +1F9F;1F9F;0397 0314 0342 0345;1F9F;0397 0314 0342 0345; +1FA0;1FA0;03C9 0313 0345;1FA0;03C9 0313 0345; +1FA1;1FA1;03C9 0314 0345;1FA1;03C9 0314 0345; +1FA2;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; +1FA3;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; +1FA4;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; +1FA5;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; +1FA6;1FA6;03C9 0313 0342 0345;1FA6;03C9 0313 0342 0345; +1FA7;1FA7;03C9 0314 0342 0345;1FA7;03C9 0314 0342 0345; +1FA8;1FA8;03A9 0313 0345;1FA8;03A9 0313 0345; +1FA9;1FA9;03A9 0314 0345;1FA9;03A9 0314 0345; +1FAA;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; +1FAB;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; +1FAC;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; +1FAD;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; +1FAE;1FAE;03A9 0313 0342 0345;1FAE;03A9 0313 0342 0345; +1FAF;1FAF;03A9 0314 0342 0345;1FAF;03A9 0314 0342 0345; +1FB0;1FB0;03B1 0306;1FB0;03B1 0306; +1FB1;1FB1;03B1 0304;1FB1;03B1 0304; +1FB2;1FB2;03B1 0300 0345;1FB2;03B1 0300 0345; +1FB3;1FB3;03B1 0345;1FB3;03B1 0345; +1FB4;1FB4;03B1 0301 0345;1FB4;03B1 0301 0345; +1FB6;1FB6;03B1 0342;1FB6;03B1 0342; +1FB7;1FB7;03B1 0342 0345;1FB7;03B1 0342 0345; +1FB8;1FB8;0391 0306;1FB8;0391 0306; +1FB9;1FB9;0391 0304;1FB9;0391 0304; +1FBA;1FBA;0391 0300;1FBA;0391 0300; +1FBB;0386;0391 0301;0386;0391 0301; +1FBC;1FBC;0391 0345;1FBC;0391 0345; +1FBD;1FBD;1FBD;0020 0313;0020 0313; +1FBE;03B9;03B9;03B9;03B9; +1FBF;1FBF;1FBF;0020 0313;0020 0313; +1FC0;1FC0;1FC0;0020 0342;0020 0342; +1FC1;1FC1;00A8 0342;0020 0308 0342;0020 0308 0342; +1FC2;1FC2;03B7 0300 0345;1FC2;03B7 0300 0345; +1FC3;1FC3;03B7 0345;1FC3;03B7 0345; +1FC4;1FC4;03B7 0301 0345;1FC4;03B7 0301 0345; +1FC6;1FC6;03B7 0342;1FC6;03B7 0342; +1FC7;1FC7;03B7 0342 0345;1FC7;03B7 0342 0345; +1FC8;1FC8;0395 0300;1FC8;0395 0300; +1FC9;0388;0395 0301;0388;0395 0301; +1FCA;1FCA;0397 0300;1FCA;0397 0300; +1FCB;0389;0397 0301;0389;0397 0301; +1FCC;1FCC;0397 0345;1FCC;0397 0345; +1FCD;1FCD;1FBF 0300;0020 0313 0300;0020 0313 0300; +1FCE;1FCE;1FBF 0301;0020 0313 0301;0020 0313 0301; +1FCF;1FCF;1FBF 0342;0020 0313 0342;0020 0313 0342; +1FD0;1FD0;03B9 0306;1FD0;03B9 0306; +1FD1;1FD1;03B9 0304;1FD1;03B9 0304; +1FD2;1FD2;03B9 0308 0300;1FD2;03B9 0308 0300; +1FD3;0390;03B9 0308 0301;0390;03B9 0308 0301; +1FD6;1FD6;03B9 0342;1FD6;03B9 0342; +1FD7;1FD7;03B9 0308 0342;1FD7;03B9 0308 0342; +1FD8;1FD8;0399 0306;1FD8;0399 0306; +1FD9;1FD9;0399 0304;1FD9;0399 0304; +1FDA;1FDA;0399 0300;1FDA;0399 0300; +1FDB;038A;0399 0301;038A;0399 0301; +1FDD;1FDD;1FFE 0300;0020 0314 0300;0020 0314 0300; +1FDE;1FDE;1FFE 0301;0020 0314 0301;0020 0314 0301; +1FDF;1FDF;1FFE 0342;0020 0314 0342;0020 0314 0342; +1FE0;1FE0;03C5 0306;1FE0;03C5 0306; +1FE1;1FE1;03C5 0304;1FE1;03C5 0304; +1FE2;1FE2;03C5 0308 0300;1FE2;03C5 0308 0300; +1FE3;03B0;03C5 0308 0301;03B0;03C5 0308 0301; +1FE4;1FE4;03C1 0313;1FE4;03C1 0313; +1FE5;1FE5;03C1 0314;1FE5;03C1 0314; +1FE6;1FE6;03C5 0342;1FE6;03C5 0342; +1FE7;1FE7;03C5 0308 0342;1FE7;03C5 0308 0342; +1FE8;1FE8;03A5 0306;1FE8;03A5 0306; +1FE9;1FE9;03A5 0304;1FE9;03A5 0304; +1FEA;1FEA;03A5 0300;1FEA;03A5 0300; +1FEB;038E;03A5 0301;038E;03A5 0301; +1FEC;1FEC;03A1 0314;1FEC;03A1 0314; +1FED;1FED;00A8 0300;0020 0308 0300;0020 0308 0300; +1FEE;0385;00A8 0301;0020 0308 0301;0020 0308 0301; +1FEF;0060;0060;0060;0060; +1FF2;1FF2;03C9 0300 0345;1FF2;03C9 0300 0345; +1FF3;1FF3;03C9 0345;1FF3;03C9 0345; +1FF4;1FF4;03C9 0301 0345;1FF4;03C9 0301 0345; +1FF6;1FF6;03C9 0342;1FF6;03C9 0342; +1FF7;1FF7;03C9 0342 0345;1FF7;03C9 0342 0345; +1FF8;1FF8;039F 0300;1FF8;039F 0300; +1FF9;038C;039F 0301;038C;039F 0301; +1FFA;1FFA;03A9 0300;1FFA;03A9 0300; +1FFB;038F;03A9 0301;038F;03A9 0301; +1FFC;1FFC;03A9 0345;1FFC;03A9 0345; +1FFD;00B4;00B4;0020 0301;0020 0301; +1FFE;1FFE;1FFE;0020 0314;0020 0314; +2000;2002;2002;0020;0020; +2001;2003;2003;0020;0020; +2002;2002;2002;0020;0020; +2003;2003;2003;0020;0020; +2004;2004;2004;0020;0020; +2005;2005;2005;0020;0020; +2006;2006;2006;0020;0020; +2007;2007;2007;0020;0020; +2008;2008;2008;0020;0020; +2009;2009;2009;0020;0020; +200A;200A;200A;0020;0020; +2011;2011;2011;2010;2010; +2017;2017;2017;0020 0333;0020 0333; +2024;2024;2024;002E;002E; +2025;2025;2025;002E 002E;002E 002E; +2026;2026;2026;002E 002E 002E;002E 002E 002E; +202F;202F;202F;0020;0020; +2033;2033;2033;2032 2032;2032 2032; +2034;2034;2034;2032 2032 2032;2032 2032 2032; +2036;2036;2036;2035 2035;2035 2035; +2037;2037;2037;2035 2035 2035;2035 2035 2035; +203C;203C;203C;0021 0021;0021 0021; +203E;203E;203E;0020 0305;0020 0305; +2047;2047;2047;003F 003F;003F 003F; +2048;2048;2048;003F 0021;003F 0021; +2049;2049;2049;0021 003F;0021 003F; +2057;2057;2057;2032 2032 2032 2032;2032 2032 2032 2032; +205F;205F;205F;0020;0020; +2070;2070;2070;0030;0030; +2071;2071;2071;0069;0069; +2074;2074;2074;0034;0034; +2075;2075;2075;0035;0035; +2076;2076;2076;0036;0036; +2077;2077;2077;0037;0037; +2078;2078;2078;0038;0038; +2079;2079;2079;0039;0039; +207A;207A;207A;002B;002B; +207B;207B;207B;2212;2212; +207C;207C;207C;003D;003D; +207D;207D;207D;0028;0028; +207E;207E;207E;0029;0029; +207F;207F;207F;006E;006E; +2080;2080;2080;0030;0030; +2081;2081;2081;0031;0031; +2082;2082;2082;0032;0032; +2083;2083;2083;0033;0033; +2084;2084;2084;0034;0034; +2085;2085;2085;0035;0035; +2086;2086;2086;0036;0036; +2087;2087;2087;0037;0037; +2088;2088;2088;0038;0038; +2089;2089;2089;0039;0039; +208A;208A;208A;002B;002B; +208B;208B;208B;2212;2212; +208C;208C;208C;003D;003D; +208D;208D;208D;0028;0028; +208E;208E;208E;0029;0029; +2090;2090;2090;0061;0061; +2091;2091;2091;0065;0065; +2092;2092;2092;006F;006F; +2093;2093;2093;0078;0078; +2094;2094;2094;0259;0259; +2095;2095;2095;0068;0068; +2096;2096;2096;006B;006B; +2097;2097;2097;006C;006C; +2098;2098;2098;006D;006D; +2099;2099;2099;006E;006E; +209A;209A;209A;0070;0070; +209B;209B;209B;0073;0073; +209C;209C;209C;0074;0074; +20A8;20A8;20A8;0052 0073;0052 0073; +2100;2100;2100;0061 002F 0063;0061 002F 0063; +2101;2101;2101;0061 002F 0073;0061 002F 0073; +2102;2102;2102;0043;0043; +2103;2103;2103;00B0 0043;00B0 0043; +2105;2105;2105;0063 002F 006F;0063 002F 006F; +2106;2106;2106;0063 002F 0075;0063 002F 0075; +2107;2107;2107;0190;0190; +2109;2109;2109;00B0 0046;00B0 0046; +210A;210A;210A;0067;0067; +210B;210B;210B;0048;0048; +210C;210C;210C;0048;0048; +210D;210D;210D;0048;0048; +210E;210E;210E;0068;0068; +210F;210F;210F;0127;0127; +2110;2110;2110;0049;0049; +2111;2111;2111;0049;0049; +2112;2112;2112;004C;004C; +2113;2113;2113;006C;006C; +2115;2115;2115;004E;004E; +2116;2116;2116;004E 006F;004E 006F; +2119;2119;2119;0050;0050; +211A;211A;211A;0051;0051; +211B;211B;211B;0052;0052; +211C;211C;211C;0052;0052; +211D;211D;211D;0052;0052; +2120;2120;2120;0053 004D;0053 004D; +2121;2121;2121;0054 0045 004C;0054 0045 004C; +2122;2122;2122;0054 004D;0054 004D; +2124;2124;2124;005A;005A; +2126;03A9;03A9;03A9;03A9; +2128;2128;2128;005A;005A; +212A;004B;004B;004B;004B; +212B;00C5;0041 030A;00C5;0041 030A; +212C;212C;212C;0042;0042; +212D;212D;212D;0043;0043; +212F;212F;212F;0065;0065; +2130;2130;2130;0045;0045; +2131;2131;2131;0046;0046; +2133;2133;2133;004D;004D; +2134;2134;2134;006F;006F; +2135;2135;2135;05D0;05D0; +2136;2136;2136;05D1;05D1; +2137;2137;2137;05D2;05D2; +2138;2138;2138;05D3;05D3; +2139;2139;2139;0069;0069; +213B;213B;213B;0046 0041 0058;0046 0041 0058; +213C;213C;213C;03C0;03C0; +213D;213D;213D;03B3;03B3; +213E;213E;213E;0393;0393; +213F;213F;213F;03A0;03A0; +2140;2140;2140;2211;2211; +2145;2145;2145;0044;0044; +2146;2146;2146;0064;0064; +2147;2147;2147;0065;0065; +2148;2148;2148;0069;0069; +2149;2149;2149;006A;006A; +2150;2150;2150;0031 2044 0037;0031 2044 0037; +2151;2151;2151;0031 2044 0039;0031 2044 0039; +2152;2152;2152;0031 2044 0031 0030;0031 2044 0031 0030; +2153;2153;2153;0031 2044 0033;0031 2044 0033; +2154;2154;2154;0032 2044 0033;0032 2044 0033; +2155;2155;2155;0031 2044 0035;0031 2044 0035; +2156;2156;2156;0032 2044 0035;0032 2044 0035; +2157;2157;2157;0033 2044 0035;0033 2044 0035; +2158;2158;2158;0034 2044 0035;0034 2044 0035; +2159;2159;2159;0031 2044 0036;0031 2044 0036; +215A;215A;215A;0035 2044 0036;0035 2044 0036; +215B;215B;215B;0031 2044 0038;0031 2044 0038; +215C;215C;215C;0033 2044 0038;0033 2044 0038; +215D;215D;215D;0035 2044 0038;0035 2044 0038; +215E;215E;215E;0037 2044 0038;0037 2044 0038; +215F;215F;215F;0031 2044;0031 2044; +2160;2160;2160;0049;0049; +2161;2161;2161;0049 0049;0049 0049; +2162;2162;2162;0049 0049 0049;0049 0049 0049; +2163;2163;2163;0049 0056;0049 0056; +2164;2164;2164;0056;0056; +2165;2165;2165;0056 0049;0056 0049; +2166;2166;2166;0056 0049 0049;0056 0049 0049; +2167;2167;2167;0056 0049 0049 0049;0056 0049 0049 0049; +2168;2168;2168;0049 0058;0049 0058; +2169;2169;2169;0058;0058; +216A;216A;216A;0058 0049;0058 0049; +216B;216B;216B;0058 0049 0049;0058 0049 0049; +216C;216C;216C;004C;004C; +216D;216D;216D;0043;0043; +216E;216E;216E;0044;0044; +216F;216F;216F;004D;004D; +2170;2170;2170;0069;0069; +2171;2171;2171;0069 0069;0069 0069; +2172;2172;2172;0069 0069 0069;0069 0069 0069; +2173;2173;2173;0069 0076;0069 0076; +2174;2174;2174;0076;0076; +2175;2175;2175;0076 0069;0076 0069; +2176;2176;2176;0076 0069 0069;0076 0069 0069; +2177;2177;2177;0076 0069 0069 0069;0076 0069 0069 0069; +2178;2178;2178;0069 0078;0069 0078; +2179;2179;2179;0078;0078; +217A;217A;217A;0078 0069;0078 0069; +217B;217B;217B;0078 0069 0069;0078 0069 0069; +217C;217C;217C;006C;006C; +217D;217D;217D;0063;0063; +217E;217E;217E;0064;0064; +217F;217F;217F;006D;006D; +2189;2189;2189;0030 2044 0033;0030 2044 0033; +219A;219A;2190 0338;219A;2190 0338; +219B;219B;2192 0338;219B;2192 0338; +21AE;21AE;2194 0338;21AE;2194 0338; +21CD;21CD;21D0 0338;21CD;21D0 0338; +21CE;21CE;21D4 0338;21CE;21D4 0338; +21CF;21CF;21D2 0338;21CF;21D2 0338; +2204;2204;2203 0338;2204;2203 0338; +2209;2209;2208 0338;2209;2208 0338; +220C;220C;220B 0338;220C;220B 0338; +2224;2224;2223 0338;2224;2223 0338; +2226;2226;2225 0338;2226;2225 0338; +222C;222C;222C;222B 222B;222B 222B; +222D;222D;222D;222B 222B 222B;222B 222B 222B; +222F;222F;222F;222E 222E;222E 222E; +2230;2230;2230;222E 222E 222E;222E 222E 222E; +2241;2241;223C 0338;2241;223C 0338; +2244;2244;2243 0338;2244;2243 0338; +2247;2247;2245 0338;2247;2245 0338; +2249;2249;2248 0338;2249;2248 0338; +2260;2260;003D 0338;2260;003D 0338; +2262;2262;2261 0338;2262;2261 0338; +226D;226D;224D 0338;226D;224D 0338; +226E;226E;003C 0338;226E;003C 0338; +226F;226F;003E 0338;226F;003E 0338; +2270;2270;2264 0338;2270;2264 0338; +2271;2271;2265 0338;2271;2265 0338; +2274;2274;2272 0338;2274;2272 0338; +2275;2275;2273 0338;2275;2273 0338; +2278;2278;2276 0338;2278;2276 0338; +2279;2279;2277 0338;2279;2277 0338; +2280;2280;227A 0338;2280;227A 0338; +2281;2281;227B 0338;2281;227B 0338; +2284;2284;2282 0338;2284;2282 0338; +2285;2285;2283 0338;2285;2283 0338; +2288;2288;2286 0338;2288;2286 0338; +2289;2289;2287 0338;2289;2287 0338; +22AC;22AC;22A2 0338;22AC;22A2 0338; +22AD;22AD;22A8 0338;22AD;22A8 0338; +22AE;22AE;22A9 0338;22AE;22A9 0338; +22AF;22AF;22AB 0338;22AF;22AB 0338; +22E0;22E0;227C 0338;22E0;227C 0338; +22E1;22E1;227D 0338;22E1;227D 0338; +22E2;22E2;2291 0338;22E2;2291 0338; +22E3;22E3;2292 0338;22E3;2292 0338; +22EA;22EA;22B2 0338;22EA;22B2 0338; +22EB;22EB;22B3 0338;22EB;22B3 0338; +22EC;22EC;22B4 0338;22EC;22B4 0338; +22ED;22ED;22B5 0338;22ED;22B5 0338; +2329;3008;3008;3008;3008; +232A;3009;3009;3009;3009; +2460;2460;2460;0031;0031; +2461;2461;2461;0032;0032; +2462;2462;2462;0033;0033; +2463;2463;2463;0034;0034; +2464;2464;2464;0035;0035; +2465;2465;2465;0036;0036; +2466;2466;2466;0037;0037; +2467;2467;2467;0038;0038; +2468;2468;2468;0039;0039; +2469;2469;2469;0031 0030;0031 0030; +246A;246A;246A;0031 0031;0031 0031; +246B;246B;246B;0031 0032;0031 0032; +246C;246C;246C;0031 0033;0031 0033; +246D;246D;246D;0031 0034;0031 0034; +246E;246E;246E;0031 0035;0031 0035; +246F;246F;246F;0031 0036;0031 0036; +2470;2470;2470;0031 0037;0031 0037; +2471;2471;2471;0031 0038;0031 0038; +2472;2472;2472;0031 0039;0031 0039; +2473;2473;2473;0032 0030;0032 0030; +2474;2474;2474;0028 0031 0029;0028 0031 0029; +2475;2475;2475;0028 0032 0029;0028 0032 0029; +2476;2476;2476;0028 0033 0029;0028 0033 0029; +2477;2477;2477;0028 0034 0029;0028 0034 0029; +2478;2478;2478;0028 0035 0029;0028 0035 0029; +2479;2479;2479;0028 0036 0029;0028 0036 0029; +247A;247A;247A;0028 0037 0029;0028 0037 0029; +247B;247B;247B;0028 0038 0029;0028 0038 0029; +247C;247C;247C;0028 0039 0029;0028 0039 0029; +247D;247D;247D;0028 0031 0030 0029;0028 0031 0030 0029; +247E;247E;247E;0028 0031 0031 0029;0028 0031 0031 0029; +247F;247F;247F;0028 0031 0032 0029;0028 0031 0032 0029; +2480;2480;2480;0028 0031 0033 0029;0028 0031 0033 0029; +2481;2481;2481;0028 0031 0034 0029;0028 0031 0034 0029; +2482;2482;2482;0028 0031 0035 0029;0028 0031 0035 0029; +2483;2483;2483;0028 0031 0036 0029;0028 0031 0036 0029; +2484;2484;2484;0028 0031 0037 0029;0028 0031 0037 0029; +2485;2485;2485;0028 0031 0038 0029;0028 0031 0038 0029; +2486;2486;2486;0028 0031 0039 0029;0028 0031 0039 0029; +2487;2487;2487;0028 0032 0030 0029;0028 0032 0030 0029; +2488;2488;2488;0031 002E;0031 002E; +2489;2489;2489;0032 002E;0032 002E; +248A;248A;248A;0033 002E;0033 002E; +248B;248B;248B;0034 002E;0034 002E; +248C;248C;248C;0035 002E;0035 002E; +248D;248D;248D;0036 002E;0036 002E; +248E;248E;248E;0037 002E;0037 002E; +248F;248F;248F;0038 002E;0038 002E; +2490;2490;2490;0039 002E;0039 002E; +2491;2491;2491;0031 0030 002E;0031 0030 002E; +2492;2492;2492;0031 0031 002E;0031 0031 002E; +2493;2493;2493;0031 0032 002E;0031 0032 002E; +2494;2494;2494;0031 0033 002E;0031 0033 002E; +2495;2495;2495;0031 0034 002E;0031 0034 002E; +2496;2496;2496;0031 0035 002E;0031 0035 002E; +2497;2497;2497;0031 0036 002E;0031 0036 002E; +2498;2498;2498;0031 0037 002E;0031 0037 002E; +2499;2499;2499;0031 0038 002E;0031 0038 002E; +249A;249A;249A;0031 0039 002E;0031 0039 002E; +249B;249B;249B;0032 0030 002E;0032 0030 002E; +249C;249C;249C;0028 0061 0029;0028 0061 0029; +249D;249D;249D;0028 0062 0029;0028 0062 0029; +249E;249E;249E;0028 0063 0029;0028 0063 0029; +249F;249F;249F;0028 0064 0029;0028 0064 0029; +24A0;24A0;24A0;0028 0065 0029;0028 0065 0029; +24A1;24A1;24A1;0028 0066 0029;0028 0066 0029; +24A2;24A2;24A2;0028 0067 0029;0028 0067 0029; +24A3;24A3;24A3;0028 0068 0029;0028 0068 0029; +24A4;24A4;24A4;0028 0069 0029;0028 0069 0029; +24A5;24A5;24A5;0028 006A 0029;0028 006A 0029; +24A6;24A6;24A6;0028 006B 0029;0028 006B 0029; +24A7;24A7;24A7;0028 006C 0029;0028 006C 0029; +24A8;24A8;24A8;0028 006D 0029;0028 006D 0029; +24A9;24A9;24A9;0028 006E 0029;0028 006E 0029; +24AA;24AA;24AA;0028 006F 0029;0028 006F 0029; +24AB;24AB;24AB;0028 0070 0029;0028 0070 0029; +24AC;24AC;24AC;0028 0071 0029;0028 0071 0029; +24AD;24AD;24AD;0028 0072 0029;0028 0072 0029; +24AE;24AE;24AE;0028 0073 0029;0028 0073 0029; +24AF;24AF;24AF;0028 0074 0029;0028 0074 0029; +24B0;24B0;24B0;0028 0075 0029;0028 0075 0029; +24B1;24B1;24B1;0028 0076 0029;0028 0076 0029; +24B2;24B2;24B2;0028 0077 0029;0028 0077 0029; +24B3;24B3;24B3;0028 0078 0029;0028 0078 0029; +24B4;24B4;24B4;0028 0079 0029;0028 0079 0029; +24B5;24B5;24B5;0028 007A 0029;0028 007A 0029; +24B6;24B6;24B6;0041;0041; +24B7;24B7;24B7;0042;0042; +24B8;24B8;24B8;0043;0043; +24B9;24B9;24B9;0044;0044; +24BA;24BA;24BA;0045;0045; +24BB;24BB;24BB;0046;0046; +24BC;24BC;24BC;0047;0047; +24BD;24BD;24BD;0048;0048; +24BE;24BE;24BE;0049;0049; +24BF;24BF;24BF;004A;004A; +24C0;24C0;24C0;004B;004B; +24C1;24C1;24C1;004C;004C; +24C2;24C2;24C2;004D;004D; +24C3;24C3;24C3;004E;004E; +24C4;24C4;24C4;004F;004F; +24C5;24C5;24C5;0050;0050; +24C6;24C6;24C6;0051;0051; +24C7;24C7;24C7;0052;0052; +24C8;24C8;24C8;0053;0053; +24C9;24C9;24C9;0054;0054; +24CA;24CA;24CA;0055;0055; +24CB;24CB;24CB;0056;0056; +24CC;24CC;24CC;0057;0057; +24CD;24CD;24CD;0058;0058; +24CE;24CE;24CE;0059;0059; +24CF;24CF;24CF;005A;005A; +24D0;24D0;24D0;0061;0061; +24D1;24D1;24D1;0062;0062; +24D2;24D2;24D2;0063;0063; +24D3;24D3;24D3;0064;0064; +24D4;24D4;24D4;0065;0065; +24D5;24D5;24D5;0066;0066; +24D6;24D6;24D6;0067;0067; +24D7;24D7;24D7;0068;0068; +24D8;24D8;24D8;0069;0069; +24D9;24D9;24D9;006A;006A; +24DA;24DA;24DA;006B;006B; +24DB;24DB;24DB;006C;006C; +24DC;24DC;24DC;006D;006D; +24DD;24DD;24DD;006E;006E; +24DE;24DE;24DE;006F;006F; +24DF;24DF;24DF;0070;0070; +24E0;24E0;24E0;0071;0071; +24E1;24E1;24E1;0072;0072; +24E2;24E2;24E2;0073;0073; +24E3;24E3;24E3;0074;0074; +24E4;24E4;24E4;0075;0075; +24E5;24E5;24E5;0076;0076; +24E6;24E6;24E6;0077;0077; +24E7;24E7;24E7;0078;0078; +24E8;24E8;24E8;0079;0079; +24E9;24E9;24E9;007A;007A; +24EA;24EA;24EA;0030;0030; +2A0C;2A0C;2A0C;222B 222B 222B 222B;222B 222B 222B 222B; +2A74;2A74;2A74;003A 003A 003D;003A 003A 003D; +2A75;2A75;2A75;003D 003D;003D 003D; +2A76;2A76;2A76;003D 003D 003D;003D 003D 003D; +2ADC;2ADD 0338;2ADD 0338;2ADD 0338;2ADD 0338; +2C7C;2C7C;2C7C;006A;006A; +2C7D;2C7D;2C7D;0056;0056; +2D6F;2D6F;2D6F;2D61;2D61; +2E9F;2E9F;2E9F;6BCD;6BCD; +2EF3;2EF3;2EF3;9F9F;9F9F; +2F00;2F00;2F00;4E00;4E00; +2F01;2F01;2F01;4E28;4E28; +2F02;2F02;2F02;4E36;4E36; +2F03;2F03;2F03;4E3F;4E3F; +2F04;2F04;2F04;4E59;4E59; +2F05;2F05;2F05;4E85;4E85; +2F06;2F06;2F06;4E8C;4E8C; +2F07;2F07;2F07;4EA0;4EA0; +2F08;2F08;2F08;4EBA;4EBA; +2F09;2F09;2F09;513F;513F; +2F0A;2F0A;2F0A;5165;5165; +2F0B;2F0B;2F0B;516B;516B; +2F0C;2F0C;2F0C;5182;5182; +2F0D;2F0D;2F0D;5196;5196; +2F0E;2F0E;2F0E;51AB;51AB; +2F0F;2F0F;2F0F;51E0;51E0; +2F10;2F10;2F10;51F5;51F5; +2F11;2F11;2F11;5200;5200; +2F12;2F12;2F12;529B;529B; +2F13;2F13;2F13;52F9;52F9; +2F14;2F14;2F14;5315;5315; +2F15;2F15;2F15;531A;531A; +2F16;2F16;2F16;5338;5338; +2F17;2F17;2F17;5341;5341; +2F18;2F18;2F18;535C;535C; +2F19;2F19;2F19;5369;5369; +2F1A;2F1A;2F1A;5382;5382; +2F1B;2F1B;2F1B;53B6;53B6; +2F1C;2F1C;2F1C;53C8;53C8; +2F1D;2F1D;2F1D;53E3;53E3; +2F1E;2F1E;2F1E;56D7;56D7; +2F1F;2F1F;2F1F;571F;571F; +2F20;2F20;2F20;58EB;58EB; +2F21;2F21;2F21;5902;5902; +2F22;2F22;2F22;590A;590A; +2F23;2F23;2F23;5915;5915; +2F24;2F24;2F24;5927;5927; +2F25;2F25;2F25;5973;5973; +2F26;2F26;2F26;5B50;5B50; +2F27;2F27;2F27;5B80;5B80; +2F28;2F28;2F28;5BF8;5BF8; +2F29;2F29;2F29;5C0F;5C0F; +2F2A;2F2A;2F2A;5C22;5C22; +2F2B;2F2B;2F2B;5C38;5C38; +2F2C;2F2C;2F2C;5C6E;5C6E; +2F2D;2F2D;2F2D;5C71;5C71; +2F2E;2F2E;2F2E;5DDB;5DDB; +2F2F;2F2F;2F2F;5DE5;5DE5; +2F30;2F30;2F30;5DF1;5DF1; +2F31;2F31;2F31;5DFE;5DFE; +2F32;2F32;2F32;5E72;5E72; +2F33;2F33;2F33;5E7A;5E7A; +2F34;2F34;2F34;5E7F;5E7F; +2F35;2F35;2F35;5EF4;5EF4; +2F36;2F36;2F36;5EFE;5EFE; +2F37;2F37;2F37;5F0B;5F0B; +2F38;2F38;2F38;5F13;5F13; +2F39;2F39;2F39;5F50;5F50; +2F3A;2F3A;2F3A;5F61;5F61; +2F3B;2F3B;2F3B;5F73;5F73; +2F3C;2F3C;2F3C;5FC3;5FC3; +2F3D;2F3D;2F3D;6208;6208; +2F3E;2F3E;2F3E;6236;6236; +2F3F;2F3F;2F3F;624B;624B; +2F40;2F40;2F40;652F;652F; +2F41;2F41;2F41;6534;6534; +2F42;2F42;2F42;6587;6587; +2F43;2F43;2F43;6597;6597; +2F44;2F44;2F44;65A4;65A4; +2F45;2F45;2F45;65B9;65B9; +2F46;2F46;2F46;65E0;65E0; +2F47;2F47;2F47;65E5;65E5; +2F48;2F48;2F48;66F0;66F0; +2F49;2F49;2F49;6708;6708; +2F4A;2F4A;2F4A;6728;6728; +2F4B;2F4B;2F4B;6B20;6B20; +2F4C;2F4C;2F4C;6B62;6B62; +2F4D;2F4D;2F4D;6B79;6B79; +2F4E;2F4E;2F4E;6BB3;6BB3; +2F4F;2F4F;2F4F;6BCB;6BCB; +2F50;2F50;2F50;6BD4;6BD4; +2F51;2F51;2F51;6BDB;6BDB; +2F52;2F52;2F52;6C0F;6C0F; +2F53;2F53;2F53;6C14;6C14; +2F54;2F54;2F54;6C34;6C34; +2F55;2F55;2F55;706B;706B; +2F56;2F56;2F56;722A;722A; +2F57;2F57;2F57;7236;7236; +2F58;2F58;2F58;723B;723B; +2F59;2F59;2F59;723F;723F; +2F5A;2F5A;2F5A;7247;7247; +2F5B;2F5B;2F5B;7259;7259; +2F5C;2F5C;2F5C;725B;725B; +2F5D;2F5D;2F5D;72AC;72AC; +2F5E;2F5E;2F5E;7384;7384; +2F5F;2F5F;2F5F;7389;7389; +2F60;2F60;2F60;74DC;74DC; +2F61;2F61;2F61;74E6;74E6; +2F62;2F62;2F62;7518;7518; +2F63;2F63;2F63;751F;751F; +2F64;2F64;2F64;7528;7528; +2F65;2F65;2F65;7530;7530; +2F66;2F66;2F66;758B;758B; +2F67;2F67;2F67;7592;7592; +2F68;2F68;2F68;7676;7676; +2F69;2F69;2F69;767D;767D; +2F6A;2F6A;2F6A;76AE;76AE; +2F6B;2F6B;2F6B;76BF;76BF; +2F6C;2F6C;2F6C;76EE;76EE; +2F6D;2F6D;2F6D;77DB;77DB; +2F6E;2F6E;2F6E;77E2;77E2; +2F6F;2F6F;2F6F;77F3;77F3; +2F70;2F70;2F70;793A;793A; +2F71;2F71;2F71;79B8;79B8; +2F72;2F72;2F72;79BE;79BE; +2F73;2F73;2F73;7A74;7A74; +2F74;2F74;2F74;7ACB;7ACB; +2F75;2F75;2F75;7AF9;7AF9; +2F76;2F76;2F76;7C73;7C73; +2F77;2F77;2F77;7CF8;7CF8; +2F78;2F78;2F78;7F36;7F36; +2F79;2F79;2F79;7F51;7F51; +2F7A;2F7A;2F7A;7F8A;7F8A; +2F7B;2F7B;2F7B;7FBD;7FBD; +2F7C;2F7C;2F7C;8001;8001; +2F7D;2F7D;2F7D;800C;800C; +2F7E;2F7E;2F7E;8012;8012; +2F7F;2F7F;2F7F;8033;8033; +2F80;2F80;2F80;807F;807F; +2F81;2F81;2F81;8089;8089; +2F82;2F82;2F82;81E3;81E3; +2F83;2F83;2F83;81EA;81EA; +2F84;2F84;2F84;81F3;81F3; +2F85;2F85;2F85;81FC;81FC; +2F86;2F86;2F86;820C;820C; +2F87;2F87;2F87;821B;821B; +2F88;2F88;2F88;821F;821F; +2F89;2F89;2F89;826E;826E; +2F8A;2F8A;2F8A;8272;8272; +2F8B;2F8B;2F8B;8278;8278; +2F8C;2F8C;2F8C;864D;864D; +2F8D;2F8D;2F8D;866B;866B; +2F8E;2F8E;2F8E;8840;8840; +2F8F;2F8F;2F8F;884C;884C; +2F90;2F90;2F90;8863;8863; +2F91;2F91;2F91;897E;897E; +2F92;2F92;2F92;898B;898B; +2F93;2F93;2F93;89D2;89D2; +2F94;2F94;2F94;8A00;8A00; +2F95;2F95;2F95;8C37;8C37; +2F96;2F96;2F96;8C46;8C46; +2F97;2F97;2F97;8C55;8C55; +2F98;2F98;2F98;8C78;8C78; +2F99;2F99;2F99;8C9D;8C9D; +2F9A;2F9A;2F9A;8D64;8D64; +2F9B;2F9B;2F9B;8D70;8D70; +2F9C;2F9C;2F9C;8DB3;8DB3; +2F9D;2F9D;2F9D;8EAB;8EAB; +2F9E;2F9E;2F9E;8ECA;8ECA; +2F9F;2F9F;2F9F;8F9B;8F9B; +2FA0;2FA0;2FA0;8FB0;8FB0; +2FA1;2FA1;2FA1;8FB5;8FB5; +2FA2;2FA2;2FA2;9091;9091; +2FA3;2FA3;2FA3;9149;9149; +2FA4;2FA4;2FA4;91C6;91C6; +2FA5;2FA5;2FA5;91CC;91CC; +2FA6;2FA6;2FA6;91D1;91D1; +2FA7;2FA7;2FA7;9577;9577; +2FA8;2FA8;2FA8;9580;9580; +2FA9;2FA9;2FA9;961C;961C; +2FAA;2FAA;2FAA;96B6;96B6; +2FAB;2FAB;2FAB;96B9;96B9; +2FAC;2FAC;2FAC;96E8;96E8; +2FAD;2FAD;2FAD;9751;9751; +2FAE;2FAE;2FAE;975E;975E; +2FAF;2FAF;2FAF;9762;9762; +2FB0;2FB0;2FB0;9769;9769; +2FB1;2FB1;2FB1;97CB;97CB; +2FB2;2FB2;2FB2;97ED;97ED; +2FB3;2FB3;2FB3;97F3;97F3; +2FB4;2FB4;2FB4;9801;9801; +2FB5;2FB5;2FB5;98A8;98A8; +2FB6;2FB6;2FB6;98DB;98DB; +2FB7;2FB7;2FB7;98DF;98DF; +2FB8;2FB8;2FB8;9996;9996; +2FB9;2FB9;2FB9;9999;9999; +2FBA;2FBA;2FBA;99AC;99AC; +2FBB;2FBB;2FBB;9AA8;9AA8; +2FBC;2FBC;2FBC;9AD8;9AD8; +2FBD;2FBD;2FBD;9ADF;9ADF; +2FBE;2FBE;2FBE;9B25;9B25; +2FBF;2FBF;2FBF;9B2F;9B2F; +2FC0;2FC0;2FC0;9B32;9B32; +2FC1;2FC1;2FC1;9B3C;9B3C; +2FC2;2FC2;2FC2;9B5A;9B5A; +2FC3;2FC3;2FC3;9CE5;9CE5; +2FC4;2FC4;2FC4;9E75;9E75; +2FC5;2FC5;2FC5;9E7F;9E7F; +2FC6;2FC6;2FC6;9EA5;9EA5; +2FC7;2FC7;2FC7;9EBB;9EBB; +2FC8;2FC8;2FC8;9EC3;9EC3; +2FC9;2FC9;2FC9;9ECD;9ECD; +2FCA;2FCA;2FCA;9ED1;9ED1; +2FCB;2FCB;2FCB;9EF9;9EF9; +2FCC;2FCC;2FCC;9EFD;9EFD; +2FCD;2FCD;2FCD;9F0E;9F0E; +2FCE;2FCE;2FCE;9F13;9F13; +2FCF;2FCF;2FCF;9F20;9F20; +2FD0;2FD0;2FD0;9F3B;9F3B; +2FD1;2FD1;2FD1;9F4A;9F4A; +2FD2;2FD2;2FD2;9F52;9F52; +2FD3;2FD3;2FD3;9F8D;9F8D; +2FD4;2FD4;2FD4;9F9C;9F9C; +2FD5;2FD5;2FD5;9FA0;9FA0; +3000;3000;3000;0020;0020; +3036;3036;3036;3012;3012; +3038;3038;3038;5341;5341; +3039;3039;3039;5344;5344; +303A;303A;303A;5345;5345; +304C;304C;304B 3099;304C;304B 3099; +304E;304E;304D 3099;304E;304D 3099; +3050;3050;304F 3099;3050;304F 3099; +3052;3052;3051 3099;3052;3051 3099; +3054;3054;3053 3099;3054;3053 3099; +3056;3056;3055 3099;3056;3055 3099; +3058;3058;3057 3099;3058;3057 3099; +305A;305A;3059 3099;305A;3059 3099; +305C;305C;305B 3099;305C;305B 3099; +305E;305E;305D 3099;305E;305D 3099; +3060;3060;305F 3099;3060;305F 3099; +3062;3062;3061 3099;3062;3061 3099; +3065;3065;3064 3099;3065;3064 3099; +3067;3067;3066 3099;3067;3066 3099; +3069;3069;3068 3099;3069;3068 3099; +3070;3070;306F 3099;3070;306F 3099; +3071;3071;306F 309A;3071;306F 309A; +3073;3073;3072 3099;3073;3072 3099; +3074;3074;3072 309A;3074;3072 309A; +3076;3076;3075 3099;3076;3075 3099; +3077;3077;3075 309A;3077;3075 309A; +3079;3079;3078 3099;3079;3078 3099; +307A;307A;3078 309A;307A;3078 309A; +307C;307C;307B 3099;307C;307B 3099; +307D;307D;307B 309A;307D;307B 309A; +3094;3094;3046 3099;3094;3046 3099; +309B;309B;309B;0020 3099;0020 3099; +309C;309C;309C;0020 309A;0020 309A; +309E;309E;309D 3099;309E;309D 3099; +309F;309F;309F;3088 308A;3088 308A; +30AC;30AC;30AB 3099;30AC;30AB 3099; +30AE;30AE;30AD 3099;30AE;30AD 3099; +30B0;30B0;30AF 3099;30B0;30AF 3099; +30B2;30B2;30B1 3099;30B2;30B1 3099; +30B4;30B4;30B3 3099;30B4;30B3 3099; +30B6;30B6;30B5 3099;30B6;30B5 3099; +30B8;30B8;30B7 3099;30B8;30B7 3099; +30BA;30BA;30B9 3099;30BA;30B9 3099; +30BC;30BC;30BB 3099;30BC;30BB 3099; +30BE;30BE;30BD 3099;30BE;30BD 3099; +30C0;30C0;30BF 3099;30C0;30BF 3099; +30C2;30C2;30C1 3099;30C2;30C1 3099; +30C5;30C5;30C4 3099;30C5;30C4 3099; +30C7;30C7;30C6 3099;30C7;30C6 3099; +30C9;30C9;30C8 3099;30C9;30C8 3099; +30D0;30D0;30CF 3099;30D0;30CF 3099; +30D1;30D1;30CF 309A;30D1;30CF 309A; +30D3;30D3;30D2 3099;30D3;30D2 3099; +30D4;30D4;30D2 309A;30D4;30D2 309A; +30D6;30D6;30D5 3099;30D6;30D5 3099; +30D7;30D7;30D5 309A;30D7;30D5 309A; +30D9;30D9;30D8 3099;30D9;30D8 3099; +30DA;30DA;30D8 309A;30DA;30D8 309A; +30DC;30DC;30DB 3099;30DC;30DB 3099; +30DD;30DD;30DB 309A;30DD;30DB 309A; +30F4;30F4;30A6 3099;30F4;30A6 3099; +30F7;30F7;30EF 3099;30F7;30EF 3099; +30F8;30F8;30F0 3099;30F8;30F0 3099; +30F9;30F9;30F1 3099;30F9;30F1 3099; +30FA;30FA;30F2 3099;30FA;30F2 3099; +30FE;30FE;30FD 3099;30FE;30FD 3099; +30FF;30FF;30FF;30B3 30C8;30B3 30C8; +3131;3131;3131;1100;1100; +3132;3132;3132;1101;1101; +3133;3133;3133;11AA;11AA; +3134;3134;3134;1102;1102; +3135;3135;3135;11AC;11AC; +3136;3136;3136;11AD;11AD; +3137;3137;3137;1103;1103; +3138;3138;3138;1104;1104; +3139;3139;3139;1105;1105; +313A;313A;313A;11B0;11B0; +313B;313B;313B;11B1;11B1; +313C;313C;313C;11B2;11B2; +313D;313D;313D;11B3;11B3; +313E;313E;313E;11B4;11B4; +313F;313F;313F;11B5;11B5; +3140;3140;3140;111A;111A; +3141;3141;3141;1106;1106; +3142;3142;3142;1107;1107; +3143;3143;3143;1108;1108; +3144;3144;3144;1121;1121; +3145;3145;3145;1109;1109; +3146;3146;3146;110A;110A; +3147;3147;3147;110B;110B; +3148;3148;3148;110C;110C; +3149;3149;3149;110D;110D; +314A;314A;314A;110E;110E; +314B;314B;314B;110F;110F; +314C;314C;314C;1110;1110; +314D;314D;314D;1111;1111; +314E;314E;314E;1112;1112; +314F;314F;314F;1161;1161; +3150;3150;3150;1162;1162; +3151;3151;3151;1163;1163; +3152;3152;3152;1164;1164; +3153;3153;3153;1165;1165; +3154;3154;3154;1166;1166; +3155;3155;3155;1167;1167; +3156;3156;3156;1168;1168; +3157;3157;3157;1169;1169; +3158;3158;3158;116A;116A; +3159;3159;3159;116B;116B; +315A;315A;315A;116C;116C; +315B;315B;315B;116D;116D; +315C;315C;315C;116E;116E; +315D;315D;315D;116F;116F; +315E;315E;315E;1170;1170; +315F;315F;315F;1171;1171; +3160;3160;3160;1172;1172; +3161;3161;3161;1173;1173; +3162;3162;3162;1174;1174; +3163;3163;3163;1175;1175; +3164;3164;3164;1160;1160; +3165;3165;3165;1114;1114; +3166;3166;3166;1115;1115; +3167;3167;3167;11C7;11C7; +3168;3168;3168;11C8;11C8; +3169;3169;3169;11CC;11CC; +316A;316A;316A;11CE;11CE; +316B;316B;316B;11D3;11D3; +316C;316C;316C;11D7;11D7; +316D;316D;316D;11D9;11D9; +316E;316E;316E;111C;111C; +316F;316F;316F;11DD;11DD; +3170;3170;3170;11DF;11DF; +3171;3171;3171;111D;111D; +3172;3172;3172;111E;111E; +3173;3173;3173;1120;1120; +3174;3174;3174;1122;1122; +3175;3175;3175;1123;1123; +3176;3176;3176;1127;1127; +3177;3177;3177;1129;1129; +3178;3178;3178;112B;112B; +3179;3179;3179;112C;112C; +317A;317A;317A;112D;112D; +317B;317B;317B;112E;112E; +317C;317C;317C;112F;112F; +317D;317D;317D;1132;1132; +317E;317E;317E;1136;1136; +317F;317F;317F;1140;1140; +3180;3180;3180;1147;1147; +3181;3181;3181;114C;114C; +3182;3182;3182;11F1;11F1; +3183;3183;3183;11F2;11F2; +3184;3184;3184;1157;1157; +3185;3185;3185;1158;1158; +3186;3186;3186;1159;1159; +3187;3187;3187;1184;1184; +3188;3188;3188;1185;1185; +3189;3189;3189;1188;1188; +318A;318A;318A;1191;1191; +318B;318B;318B;1192;1192; +318C;318C;318C;1194;1194; +318D;318D;318D;119E;119E; +318E;318E;318E;11A1;11A1; +3192;3192;3192;4E00;4E00; +3193;3193;3193;4E8C;4E8C; +3194;3194;3194;4E09;4E09; +3195;3195;3195;56DB;56DB; +3196;3196;3196;4E0A;4E0A; +3197;3197;3197;4E2D;4E2D; +3198;3198;3198;4E0B;4E0B; +3199;3199;3199;7532;7532; +319A;319A;319A;4E59;4E59; +319B;319B;319B;4E19;4E19; +319C;319C;319C;4E01;4E01; +319D;319D;319D;5929;5929; +319E;319E;319E;5730;5730; +319F;319F;319F;4EBA;4EBA; +3200;3200;3200;0028 1100 0029;0028 1100 0029; +3201;3201;3201;0028 1102 0029;0028 1102 0029; +3202;3202;3202;0028 1103 0029;0028 1103 0029; +3203;3203;3203;0028 1105 0029;0028 1105 0029; +3204;3204;3204;0028 1106 0029;0028 1106 0029; +3205;3205;3205;0028 1107 0029;0028 1107 0029; +3206;3206;3206;0028 1109 0029;0028 1109 0029; +3207;3207;3207;0028 110B 0029;0028 110B 0029; +3208;3208;3208;0028 110C 0029;0028 110C 0029; +3209;3209;3209;0028 110E 0029;0028 110E 0029; +320A;320A;320A;0028 110F 0029;0028 110F 0029; +320B;320B;320B;0028 1110 0029;0028 1110 0029; +320C;320C;320C;0028 1111 0029;0028 1111 0029; +320D;320D;320D;0028 1112 0029;0028 1112 0029; +320E;320E;320E;0028 AC00 0029;0028 1100 1161 0029; +320F;320F;320F;0028 B098 0029;0028 1102 1161 0029; +3210;3210;3210;0028 B2E4 0029;0028 1103 1161 0029; +3211;3211;3211;0028 B77C 0029;0028 1105 1161 0029; +3212;3212;3212;0028 B9C8 0029;0028 1106 1161 0029; +3213;3213;3213;0028 BC14 0029;0028 1107 1161 0029; +3214;3214;3214;0028 C0AC 0029;0028 1109 1161 0029; +3215;3215;3215;0028 C544 0029;0028 110B 1161 0029; +3216;3216;3216;0028 C790 0029;0028 110C 1161 0029; +3217;3217;3217;0028 CC28 0029;0028 110E 1161 0029; +3218;3218;3218;0028 CE74 0029;0028 110F 1161 0029; +3219;3219;3219;0028 D0C0 0029;0028 1110 1161 0029; +321A;321A;321A;0028 D30C 0029;0028 1111 1161 0029; +321B;321B;321B;0028 D558 0029;0028 1112 1161 0029; +321C;321C;321C;0028 C8FC 0029;0028 110C 116E 0029; +321D;321D;321D;0028 C624 C804 0029;0028 110B 1169 110C 1165 11AB 0029; +321E;321E;321E;0028 C624 D6C4 0029;0028 110B 1169 1112 116E 0029; +3220;3220;3220;0028 4E00 0029;0028 4E00 0029; +3221;3221;3221;0028 4E8C 0029;0028 4E8C 0029; +3222;3222;3222;0028 4E09 0029;0028 4E09 0029; +3223;3223;3223;0028 56DB 0029;0028 56DB 0029; +3224;3224;3224;0028 4E94 0029;0028 4E94 0029; +3225;3225;3225;0028 516D 0029;0028 516D 0029; +3226;3226;3226;0028 4E03 0029;0028 4E03 0029; +3227;3227;3227;0028 516B 0029;0028 516B 0029; +3228;3228;3228;0028 4E5D 0029;0028 4E5D 0029; +3229;3229;3229;0028 5341 0029;0028 5341 0029; +322A;322A;322A;0028 6708 0029;0028 6708 0029; +322B;322B;322B;0028 706B 0029;0028 706B 0029; +322C;322C;322C;0028 6C34 0029;0028 6C34 0029; +322D;322D;322D;0028 6728 0029;0028 6728 0029; +322E;322E;322E;0028 91D1 0029;0028 91D1 0029; +322F;322F;322F;0028 571F 0029;0028 571F 0029; +3230;3230;3230;0028 65E5 0029;0028 65E5 0029; +3231;3231;3231;0028 682A 0029;0028 682A 0029; +3232;3232;3232;0028 6709 0029;0028 6709 0029; +3233;3233;3233;0028 793E 0029;0028 793E 0029; +3234;3234;3234;0028 540D 0029;0028 540D 0029; +3235;3235;3235;0028 7279 0029;0028 7279 0029; +3236;3236;3236;0028 8CA1 0029;0028 8CA1 0029; +3237;3237;3237;0028 795D 0029;0028 795D 0029; +3238;3238;3238;0028 52B4 0029;0028 52B4 0029; +3239;3239;3239;0028 4EE3 0029;0028 4EE3 0029; +323A;323A;323A;0028 547C 0029;0028 547C 0029; +323B;323B;323B;0028 5B66 0029;0028 5B66 0029; +323C;323C;323C;0028 76E3 0029;0028 76E3 0029; +323D;323D;323D;0028 4F01 0029;0028 4F01 0029; +323E;323E;323E;0028 8CC7 0029;0028 8CC7 0029; +323F;323F;323F;0028 5354 0029;0028 5354 0029; +3240;3240;3240;0028 796D 0029;0028 796D 0029; +3241;3241;3241;0028 4F11 0029;0028 4F11 0029; +3242;3242;3242;0028 81EA 0029;0028 81EA 0029; +3243;3243;3243;0028 81F3 0029;0028 81F3 0029; +3244;3244;3244;554F;554F; +3245;3245;3245;5E7C;5E7C; +3246;3246;3246;6587;6587; +3247;3247;3247;7B8F;7B8F; +3250;3250;3250;0050 0054 0045;0050 0054 0045; +3251;3251;3251;0032 0031;0032 0031; +3252;3252;3252;0032 0032;0032 0032; +3253;3253;3253;0032 0033;0032 0033; +3254;3254;3254;0032 0034;0032 0034; +3255;3255;3255;0032 0035;0032 0035; +3256;3256;3256;0032 0036;0032 0036; +3257;3257;3257;0032 0037;0032 0037; +3258;3258;3258;0032 0038;0032 0038; +3259;3259;3259;0032 0039;0032 0039; +325A;325A;325A;0033 0030;0033 0030; +325B;325B;325B;0033 0031;0033 0031; +325C;325C;325C;0033 0032;0033 0032; +325D;325D;325D;0033 0033;0033 0033; +325E;325E;325E;0033 0034;0033 0034; +325F;325F;325F;0033 0035;0033 0035; +3260;3260;3260;1100;1100; +3261;3261;3261;1102;1102; +3262;3262;3262;1103;1103; +3263;3263;3263;1105;1105; +3264;3264;3264;1106;1106; +3265;3265;3265;1107;1107; +3266;3266;3266;1109;1109; +3267;3267;3267;110B;110B; +3268;3268;3268;110C;110C; +3269;3269;3269;110E;110E; +326A;326A;326A;110F;110F; +326B;326B;326B;1110;1110; +326C;326C;326C;1111;1111; +326D;326D;326D;1112;1112; +326E;326E;326E;AC00;1100 1161; +326F;326F;326F;B098;1102 1161; +3270;3270;3270;B2E4;1103 1161; +3271;3271;3271;B77C;1105 1161; +3272;3272;3272;B9C8;1106 1161; +3273;3273;3273;BC14;1107 1161; +3274;3274;3274;C0AC;1109 1161; +3275;3275;3275;C544;110B 1161; +3276;3276;3276;C790;110C 1161; +3277;3277;3277;CC28;110E 1161; +3278;3278;3278;CE74;110F 1161; +3279;3279;3279;D0C0;1110 1161; +327A;327A;327A;D30C;1111 1161; +327B;327B;327B;D558;1112 1161; +327C;327C;327C;CC38 ACE0;110E 1161 11B7 1100 1169; +327D;327D;327D;C8FC C758;110C 116E 110B 1174; +327E;327E;327E;C6B0;110B 116E; +3280;3280;3280;4E00;4E00; +3281;3281;3281;4E8C;4E8C; +3282;3282;3282;4E09;4E09; +3283;3283;3283;56DB;56DB; +3284;3284;3284;4E94;4E94; +3285;3285;3285;516D;516D; +3286;3286;3286;4E03;4E03; +3287;3287;3287;516B;516B; +3288;3288;3288;4E5D;4E5D; +3289;3289;3289;5341;5341; +328A;328A;328A;6708;6708; +328B;328B;328B;706B;706B; +328C;328C;328C;6C34;6C34; +328D;328D;328D;6728;6728; +328E;328E;328E;91D1;91D1; +328F;328F;328F;571F;571F; +3290;3290;3290;65E5;65E5; +3291;3291;3291;682A;682A; +3292;3292;3292;6709;6709; +3293;3293;3293;793E;793E; +3294;3294;3294;540D;540D; +3295;3295;3295;7279;7279; +3296;3296;3296;8CA1;8CA1; +3297;3297;3297;795D;795D; +3298;3298;3298;52B4;52B4; +3299;3299;3299;79D8;79D8; +329A;329A;329A;7537;7537; +329B;329B;329B;5973;5973; +329C;329C;329C;9069;9069; +329D;329D;329D;512A;512A; +329E;329E;329E;5370;5370; +329F;329F;329F;6CE8;6CE8; +32A0;32A0;32A0;9805;9805; +32A1;32A1;32A1;4F11;4F11; +32A2;32A2;32A2;5199;5199; +32A3;32A3;32A3;6B63;6B63; +32A4;32A4;32A4;4E0A;4E0A; +32A5;32A5;32A5;4E2D;4E2D; +32A6;32A6;32A6;4E0B;4E0B; +32A7;32A7;32A7;5DE6;5DE6; +32A8;32A8;32A8;53F3;53F3; +32A9;32A9;32A9;533B;533B; +32AA;32AA;32AA;5B97;5B97; +32AB;32AB;32AB;5B66;5B66; +32AC;32AC;32AC;76E3;76E3; +32AD;32AD;32AD;4F01;4F01; +32AE;32AE;32AE;8CC7;8CC7; +32AF;32AF;32AF;5354;5354; +32B0;32B0;32B0;591C;591C; +32B1;32B1;32B1;0033 0036;0033 0036; +32B2;32B2;32B2;0033 0037;0033 0037; +32B3;32B3;32B3;0033 0038;0033 0038; +32B4;32B4;32B4;0033 0039;0033 0039; +32B5;32B5;32B5;0034 0030;0034 0030; +32B6;32B6;32B6;0034 0031;0034 0031; +32B7;32B7;32B7;0034 0032;0034 0032; +32B8;32B8;32B8;0034 0033;0034 0033; +32B9;32B9;32B9;0034 0034;0034 0034; +32BA;32BA;32BA;0034 0035;0034 0035; +32BB;32BB;32BB;0034 0036;0034 0036; +32BC;32BC;32BC;0034 0037;0034 0037; +32BD;32BD;32BD;0034 0038;0034 0038; +32BE;32BE;32BE;0034 0039;0034 0039; +32BF;32BF;32BF;0035 0030;0035 0030; +32C0;32C0;32C0;0031 6708;0031 6708; +32C1;32C1;32C1;0032 6708;0032 6708; +32C2;32C2;32C2;0033 6708;0033 6708; +32C3;32C3;32C3;0034 6708;0034 6708; +32C4;32C4;32C4;0035 6708;0035 6708; +32C5;32C5;32C5;0036 6708;0036 6708; +32C6;32C6;32C6;0037 6708;0037 6708; +32C7;32C7;32C7;0038 6708;0038 6708; +32C8;32C8;32C8;0039 6708;0039 6708; +32C9;32C9;32C9;0031 0030 6708;0031 0030 6708; +32CA;32CA;32CA;0031 0031 6708;0031 0031 6708; +32CB;32CB;32CB;0031 0032 6708;0031 0032 6708; +32CC;32CC;32CC;0048 0067;0048 0067; +32CD;32CD;32CD;0065 0072 0067;0065 0072 0067; +32CE;32CE;32CE;0065 0056;0065 0056; +32CF;32CF;32CF;004C 0054 0044;004C 0054 0044; +32D0;32D0;32D0;30A2;30A2; +32D1;32D1;32D1;30A4;30A4; +32D2;32D2;32D2;30A6;30A6; +32D3;32D3;32D3;30A8;30A8; +32D4;32D4;32D4;30AA;30AA; +32D5;32D5;32D5;30AB;30AB; +32D6;32D6;32D6;30AD;30AD; +32D7;32D7;32D7;30AF;30AF; +32D8;32D8;32D8;30B1;30B1; +32D9;32D9;32D9;30B3;30B3; +32DA;32DA;32DA;30B5;30B5; +32DB;32DB;32DB;30B7;30B7; +32DC;32DC;32DC;30B9;30B9; +32DD;32DD;32DD;30BB;30BB; +32DE;32DE;32DE;30BD;30BD; +32DF;32DF;32DF;30BF;30BF; +32E0;32E0;32E0;30C1;30C1; +32E1;32E1;32E1;30C4;30C4; +32E2;32E2;32E2;30C6;30C6; +32E3;32E3;32E3;30C8;30C8; +32E4;32E4;32E4;30CA;30CA; +32E5;32E5;32E5;30CB;30CB; +32E6;32E6;32E6;30CC;30CC; +32E7;32E7;32E7;30CD;30CD; +32E8;32E8;32E8;30CE;30CE; +32E9;32E9;32E9;30CF;30CF; +32EA;32EA;32EA;30D2;30D2; +32EB;32EB;32EB;30D5;30D5; +32EC;32EC;32EC;30D8;30D8; +32ED;32ED;32ED;30DB;30DB; +32EE;32EE;32EE;30DE;30DE; +32EF;32EF;32EF;30DF;30DF; +32F0;32F0;32F0;30E0;30E0; +32F1;32F1;32F1;30E1;30E1; +32F2;32F2;32F2;30E2;30E2; +32F3;32F3;32F3;30E4;30E4; +32F4;32F4;32F4;30E6;30E6; +32F5;32F5;32F5;30E8;30E8; +32F6;32F6;32F6;30E9;30E9; +32F7;32F7;32F7;30EA;30EA; +32F8;32F8;32F8;30EB;30EB; +32F9;32F9;32F9;30EC;30EC; +32FA;32FA;32FA;30ED;30ED; +32FB;32FB;32FB;30EF;30EF; +32FC;32FC;32FC;30F0;30F0; +32FD;32FD;32FD;30F1;30F1; +32FE;32FE;32FE;30F2;30F2; +3300;3300;3300;30A2 30D1 30FC 30C8;30A2 30CF 309A 30FC 30C8; +3301;3301;3301;30A2 30EB 30D5 30A1;30A2 30EB 30D5 30A1; +3302;3302;3302;30A2 30F3 30DA 30A2;30A2 30F3 30D8 309A 30A2; +3303;3303;3303;30A2 30FC 30EB;30A2 30FC 30EB; +3304;3304;3304;30A4 30CB 30F3 30B0;30A4 30CB 30F3 30AF 3099; +3305;3305;3305;30A4 30F3 30C1;30A4 30F3 30C1; +3306;3306;3306;30A6 30A9 30F3;30A6 30A9 30F3; +3307;3307;3307;30A8 30B9 30AF 30FC 30C9;30A8 30B9 30AF 30FC 30C8 3099; +3308;3308;3308;30A8 30FC 30AB 30FC;30A8 30FC 30AB 30FC; +3309;3309;3309;30AA 30F3 30B9;30AA 30F3 30B9; +330A;330A;330A;30AA 30FC 30E0;30AA 30FC 30E0; +330B;330B;330B;30AB 30A4 30EA;30AB 30A4 30EA; +330C;330C;330C;30AB 30E9 30C3 30C8;30AB 30E9 30C3 30C8; +330D;330D;330D;30AB 30ED 30EA 30FC;30AB 30ED 30EA 30FC; +330E;330E;330E;30AC 30ED 30F3;30AB 3099 30ED 30F3; +330F;330F;330F;30AC 30F3 30DE;30AB 3099 30F3 30DE; +3310;3310;3310;30AE 30AC;30AD 3099 30AB 3099; +3311;3311;3311;30AE 30CB 30FC;30AD 3099 30CB 30FC; +3312;3312;3312;30AD 30E5 30EA 30FC;30AD 30E5 30EA 30FC; +3313;3313;3313;30AE 30EB 30C0 30FC;30AD 3099 30EB 30BF 3099 30FC; +3314;3314;3314;30AD 30ED;30AD 30ED; +3315;3315;3315;30AD 30ED 30B0 30E9 30E0;30AD 30ED 30AF 3099 30E9 30E0; +3316;3316;3316;30AD 30ED 30E1 30FC 30C8 30EB;30AD 30ED 30E1 30FC 30C8 30EB; +3317;3317;3317;30AD 30ED 30EF 30C3 30C8;30AD 30ED 30EF 30C3 30C8; +3318;3318;3318;30B0 30E9 30E0;30AF 3099 30E9 30E0; +3319;3319;3319;30B0 30E9 30E0 30C8 30F3;30AF 3099 30E9 30E0 30C8 30F3; +331A;331A;331A;30AF 30EB 30BC 30A4 30ED;30AF 30EB 30BB 3099 30A4 30ED; +331B;331B;331B;30AF 30ED 30FC 30CD;30AF 30ED 30FC 30CD; +331C;331C;331C;30B1 30FC 30B9;30B1 30FC 30B9; +331D;331D;331D;30B3 30EB 30CA;30B3 30EB 30CA; +331E;331E;331E;30B3 30FC 30DD;30B3 30FC 30DB 309A; +331F;331F;331F;30B5 30A4 30AF 30EB;30B5 30A4 30AF 30EB; +3320;3320;3320;30B5 30F3 30C1 30FC 30E0;30B5 30F3 30C1 30FC 30E0; +3321;3321;3321;30B7 30EA 30F3 30B0;30B7 30EA 30F3 30AF 3099; +3322;3322;3322;30BB 30F3 30C1;30BB 30F3 30C1; +3323;3323;3323;30BB 30F3 30C8;30BB 30F3 30C8; +3324;3324;3324;30C0 30FC 30B9;30BF 3099 30FC 30B9; +3325;3325;3325;30C7 30B7;30C6 3099 30B7; +3326;3326;3326;30C9 30EB;30C8 3099 30EB; +3327;3327;3327;30C8 30F3;30C8 30F3; +3328;3328;3328;30CA 30CE;30CA 30CE; +3329;3329;3329;30CE 30C3 30C8;30CE 30C3 30C8; +332A;332A;332A;30CF 30A4 30C4;30CF 30A4 30C4; +332B;332B;332B;30D1 30FC 30BB 30F3 30C8;30CF 309A 30FC 30BB 30F3 30C8; +332C;332C;332C;30D1 30FC 30C4;30CF 309A 30FC 30C4; +332D;332D;332D;30D0 30FC 30EC 30EB;30CF 3099 30FC 30EC 30EB; +332E;332E;332E;30D4 30A2 30B9 30C8 30EB;30D2 309A 30A2 30B9 30C8 30EB; +332F;332F;332F;30D4 30AF 30EB;30D2 309A 30AF 30EB; +3330;3330;3330;30D4 30B3;30D2 309A 30B3; +3331;3331;3331;30D3 30EB;30D2 3099 30EB; +3332;3332;3332;30D5 30A1 30E9 30C3 30C9;30D5 30A1 30E9 30C3 30C8 3099; +3333;3333;3333;30D5 30A3 30FC 30C8;30D5 30A3 30FC 30C8; +3334;3334;3334;30D6 30C3 30B7 30A7 30EB;30D5 3099 30C3 30B7 30A7 30EB; +3335;3335;3335;30D5 30E9 30F3;30D5 30E9 30F3; +3336;3336;3336;30D8 30AF 30BF 30FC 30EB;30D8 30AF 30BF 30FC 30EB; +3337;3337;3337;30DA 30BD;30D8 309A 30BD; +3338;3338;3338;30DA 30CB 30D2;30D8 309A 30CB 30D2; +3339;3339;3339;30D8 30EB 30C4;30D8 30EB 30C4; +333A;333A;333A;30DA 30F3 30B9;30D8 309A 30F3 30B9; +333B;333B;333B;30DA 30FC 30B8;30D8 309A 30FC 30B7 3099; +333C;333C;333C;30D9 30FC 30BF;30D8 3099 30FC 30BF; +333D;333D;333D;30DD 30A4 30F3 30C8;30DB 309A 30A4 30F3 30C8; +333E;333E;333E;30DC 30EB 30C8;30DB 3099 30EB 30C8; +333F;333F;333F;30DB 30F3;30DB 30F3; +3340;3340;3340;30DD 30F3 30C9;30DB 309A 30F3 30C8 3099; +3341;3341;3341;30DB 30FC 30EB;30DB 30FC 30EB; +3342;3342;3342;30DB 30FC 30F3;30DB 30FC 30F3; +3343;3343;3343;30DE 30A4 30AF 30ED;30DE 30A4 30AF 30ED; +3344;3344;3344;30DE 30A4 30EB;30DE 30A4 30EB; +3345;3345;3345;30DE 30C3 30CF;30DE 30C3 30CF; +3346;3346;3346;30DE 30EB 30AF;30DE 30EB 30AF; +3347;3347;3347;30DE 30F3 30B7 30E7 30F3;30DE 30F3 30B7 30E7 30F3; +3348;3348;3348;30DF 30AF 30ED 30F3;30DF 30AF 30ED 30F3; +3349;3349;3349;30DF 30EA;30DF 30EA; +334A;334A;334A;30DF 30EA 30D0 30FC 30EB;30DF 30EA 30CF 3099 30FC 30EB; +334B;334B;334B;30E1 30AC;30E1 30AB 3099; +334C;334C;334C;30E1 30AC 30C8 30F3;30E1 30AB 3099 30C8 30F3; +334D;334D;334D;30E1 30FC 30C8 30EB;30E1 30FC 30C8 30EB; +334E;334E;334E;30E4 30FC 30C9;30E4 30FC 30C8 3099; +334F;334F;334F;30E4 30FC 30EB;30E4 30FC 30EB; +3350;3350;3350;30E6 30A2 30F3;30E6 30A2 30F3; +3351;3351;3351;30EA 30C3 30C8 30EB;30EA 30C3 30C8 30EB; +3352;3352;3352;30EA 30E9;30EA 30E9; +3353;3353;3353;30EB 30D4 30FC;30EB 30D2 309A 30FC; +3354;3354;3354;30EB 30FC 30D6 30EB;30EB 30FC 30D5 3099 30EB; +3355;3355;3355;30EC 30E0;30EC 30E0; +3356;3356;3356;30EC 30F3 30C8 30B2 30F3;30EC 30F3 30C8 30B1 3099 30F3; +3357;3357;3357;30EF 30C3 30C8;30EF 30C3 30C8; +3358;3358;3358;0030 70B9;0030 70B9; +3359;3359;3359;0031 70B9;0031 70B9; +335A;335A;335A;0032 70B9;0032 70B9; +335B;335B;335B;0033 70B9;0033 70B9; +335C;335C;335C;0034 70B9;0034 70B9; +335D;335D;335D;0035 70B9;0035 70B9; +335E;335E;335E;0036 70B9;0036 70B9; +335F;335F;335F;0037 70B9;0037 70B9; +3360;3360;3360;0038 70B9;0038 70B9; +3361;3361;3361;0039 70B9;0039 70B9; +3362;3362;3362;0031 0030 70B9;0031 0030 70B9; +3363;3363;3363;0031 0031 70B9;0031 0031 70B9; +3364;3364;3364;0031 0032 70B9;0031 0032 70B9; +3365;3365;3365;0031 0033 70B9;0031 0033 70B9; +3366;3366;3366;0031 0034 70B9;0031 0034 70B9; +3367;3367;3367;0031 0035 70B9;0031 0035 70B9; +3368;3368;3368;0031 0036 70B9;0031 0036 70B9; +3369;3369;3369;0031 0037 70B9;0031 0037 70B9; +336A;336A;336A;0031 0038 70B9;0031 0038 70B9; +336B;336B;336B;0031 0039 70B9;0031 0039 70B9; +336C;336C;336C;0032 0030 70B9;0032 0030 70B9; +336D;336D;336D;0032 0031 70B9;0032 0031 70B9; +336E;336E;336E;0032 0032 70B9;0032 0032 70B9; +336F;336F;336F;0032 0033 70B9;0032 0033 70B9; +3370;3370;3370;0032 0034 70B9;0032 0034 70B9; +3371;3371;3371;0068 0050 0061;0068 0050 0061; +3372;3372;3372;0064 0061;0064 0061; +3373;3373;3373;0041 0055;0041 0055; +3374;3374;3374;0062 0061 0072;0062 0061 0072; +3375;3375;3375;006F 0056;006F 0056; +3376;3376;3376;0070 0063;0070 0063; +3377;3377;3377;0064 006D;0064 006D; +3378;3378;3378;0064 006D 0032;0064 006D 0032; +3379;3379;3379;0064 006D 0033;0064 006D 0033; +337A;337A;337A;0049 0055;0049 0055; +337B;337B;337B;5E73 6210;5E73 6210; +337C;337C;337C;662D 548C;662D 548C; +337D;337D;337D;5927 6B63;5927 6B63; +337E;337E;337E;660E 6CBB;660E 6CBB; +337F;337F;337F;682A 5F0F 4F1A 793E;682A 5F0F 4F1A 793E; +3380;3380;3380;0070 0041;0070 0041; +3381;3381;3381;006E 0041;006E 0041; +3382;3382;3382;03BC 0041;03BC 0041; +3383;3383;3383;006D 0041;006D 0041; +3384;3384;3384;006B 0041;006B 0041; +3385;3385;3385;004B 0042;004B 0042; +3386;3386;3386;004D 0042;004D 0042; +3387;3387;3387;0047 0042;0047 0042; +3388;3388;3388;0063 0061 006C;0063 0061 006C; +3389;3389;3389;006B 0063 0061 006C;006B 0063 0061 006C; +338A;338A;338A;0070 0046;0070 0046; +338B;338B;338B;006E 0046;006E 0046; +338C;338C;338C;03BC 0046;03BC 0046; +338D;338D;338D;03BC 0067;03BC 0067; +338E;338E;338E;006D 0067;006D 0067; +338F;338F;338F;006B 0067;006B 0067; +3390;3390;3390;0048 007A;0048 007A; +3391;3391;3391;006B 0048 007A;006B 0048 007A; +3392;3392;3392;004D 0048 007A;004D 0048 007A; +3393;3393;3393;0047 0048 007A;0047 0048 007A; +3394;3394;3394;0054 0048 007A;0054 0048 007A; +3395;3395;3395;03BC 006C;03BC 006C; +3396;3396;3396;006D 006C;006D 006C; +3397;3397;3397;0064 006C;0064 006C; +3398;3398;3398;006B 006C;006B 006C; +3399;3399;3399;0066 006D;0066 006D; +339A;339A;339A;006E 006D;006E 006D; +339B;339B;339B;03BC 006D;03BC 006D; +339C;339C;339C;006D 006D;006D 006D; +339D;339D;339D;0063 006D;0063 006D; +339E;339E;339E;006B 006D;006B 006D; +339F;339F;339F;006D 006D 0032;006D 006D 0032; +33A0;33A0;33A0;0063 006D 0032;0063 006D 0032; +33A1;33A1;33A1;006D 0032;006D 0032; +33A2;33A2;33A2;006B 006D 0032;006B 006D 0032; +33A3;33A3;33A3;006D 006D 0033;006D 006D 0033; +33A4;33A4;33A4;0063 006D 0033;0063 006D 0033; +33A5;33A5;33A5;006D 0033;006D 0033; +33A6;33A6;33A6;006B 006D 0033;006B 006D 0033; +33A7;33A7;33A7;006D 2215 0073;006D 2215 0073; +33A8;33A8;33A8;006D 2215 0073 0032;006D 2215 0073 0032; +33A9;33A9;33A9;0050 0061;0050 0061; +33AA;33AA;33AA;006B 0050 0061;006B 0050 0061; +33AB;33AB;33AB;004D 0050 0061;004D 0050 0061; +33AC;33AC;33AC;0047 0050 0061;0047 0050 0061; +33AD;33AD;33AD;0072 0061 0064;0072 0061 0064; +33AE;33AE;33AE;0072 0061 0064 2215 0073;0072 0061 0064 2215 0073; +33AF;33AF;33AF;0072 0061 0064 2215 0073 0032;0072 0061 0064 2215 0073 0032; +33B0;33B0;33B0;0070 0073;0070 0073; +33B1;33B1;33B1;006E 0073;006E 0073; +33B2;33B2;33B2;03BC 0073;03BC 0073; +33B3;33B3;33B3;006D 0073;006D 0073; +33B4;33B4;33B4;0070 0056;0070 0056; +33B5;33B5;33B5;006E 0056;006E 0056; +33B6;33B6;33B6;03BC 0056;03BC 0056; +33B7;33B7;33B7;006D 0056;006D 0056; +33B8;33B8;33B8;006B 0056;006B 0056; +33B9;33B9;33B9;004D 0056;004D 0056; +33BA;33BA;33BA;0070 0057;0070 0057; +33BB;33BB;33BB;006E 0057;006E 0057; +33BC;33BC;33BC;03BC 0057;03BC 0057; +33BD;33BD;33BD;006D 0057;006D 0057; +33BE;33BE;33BE;006B 0057;006B 0057; +33BF;33BF;33BF;004D 0057;004D 0057; +33C0;33C0;33C0;006B 03A9;006B 03A9; +33C1;33C1;33C1;004D 03A9;004D 03A9; +33C2;33C2;33C2;0061 002E 006D 002E;0061 002E 006D 002E; +33C3;33C3;33C3;0042 0071;0042 0071; +33C4;33C4;33C4;0063 0063;0063 0063; +33C5;33C5;33C5;0063 0064;0063 0064; +33C6;33C6;33C6;0043 2215 006B 0067;0043 2215 006B 0067; +33C7;33C7;33C7;0043 006F 002E;0043 006F 002E; +33C8;33C8;33C8;0064 0042;0064 0042; +33C9;33C9;33C9;0047 0079;0047 0079; +33CA;33CA;33CA;0068 0061;0068 0061; +33CB;33CB;33CB;0048 0050;0048 0050; +33CC;33CC;33CC;0069 006E;0069 006E; +33CD;33CD;33CD;004B 004B;004B 004B; +33CE;33CE;33CE;004B 004D;004B 004D; +33CF;33CF;33CF;006B 0074;006B 0074; +33D0;33D0;33D0;006C 006D;006C 006D; +33D1;33D1;33D1;006C 006E;006C 006E; +33D2;33D2;33D2;006C 006F 0067;006C 006F 0067; +33D3;33D3;33D3;006C 0078;006C 0078; +33D4;33D4;33D4;006D 0062;006D 0062; +33D5;33D5;33D5;006D 0069 006C;006D 0069 006C; +33D6;33D6;33D6;006D 006F 006C;006D 006F 006C; +33D7;33D7;33D7;0050 0048;0050 0048; +33D8;33D8;33D8;0070 002E 006D 002E;0070 002E 006D 002E; +33D9;33D9;33D9;0050 0050 004D;0050 0050 004D; +33DA;33DA;33DA;0050 0052;0050 0052; +33DB;33DB;33DB;0073 0072;0073 0072; +33DC;33DC;33DC;0053 0076;0053 0076; +33DD;33DD;33DD;0057 0062;0057 0062; +33DE;33DE;33DE;0056 2215 006D;0056 2215 006D; +33DF;33DF;33DF;0041 2215 006D;0041 2215 006D; +33E0;33E0;33E0;0031 65E5;0031 65E5; +33E1;33E1;33E1;0032 65E5;0032 65E5; +33E2;33E2;33E2;0033 65E5;0033 65E5; +33E3;33E3;33E3;0034 65E5;0034 65E5; +33E4;33E4;33E4;0035 65E5;0035 65E5; +33E5;33E5;33E5;0036 65E5;0036 65E5; +33E6;33E6;33E6;0037 65E5;0037 65E5; +33E7;33E7;33E7;0038 65E5;0038 65E5; +33E8;33E8;33E8;0039 65E5;0039 65E5; +33E9;33E9;33E9;0031 0030 65E5;0031 0030 65E5; +33EA;33EA;33EA;0031 0031 65E5;0031 0031 65E5; +33EB;33EB;33EB;0031 0032 65E5;0031 0032 65E5; +33EC;33EC;33EC;0031 0033 65E5;0031 0033 65E5; +33ED;33ED;33ED;0031 0034 65E5;0031 0034 65E5; +33EE;33EE;33EE;0031 0035 65E5;0031 0035 65E5; +33EF;33EF;33EF;0031 0036 65E5;0031 0036 65E5; +33F0;33F0;33F0;0031 0037 65E5;0031 0037 65E5; +33F1;33F1;33F1;0031 0038 65E5;0031 0038 65E5; +33F2;33F2;33F2;0031 0039 65E5;0031 0039 65E5; +33F3;33F3;33F3;0032 0030 65E5;0032 0030 65E5; +33F4;33F4;33F4;0032 0031 65E5;0032 0031 65E5; +33F5;33F5;33F5;0032 0032 65E5;0032 0032 65E5; +33F6;33F6;33F6;0032 0033 65E5;0032 0033 65E5; +33F7;33F7;33F7;0032 0034 65E5;0032 0034 65E5; +33F8;33F8;33F8;0032 0035 65E5;0032 0035 65E5; +33F9;33F9;33F9;0032 0036 65E5;0032 0036 65E5; +33FA;33FA;33FA;0032 0037 65E5;0032 0037 65E5; +33FB;33FB;33FB;0032 0038 65E5;0032 0038 65E5; +33FC;33FC;33FC;0032 0039 65E5;0032 0039 65E5; +33FD;33FD;33FD;0033 0030 65E5;0033 0030 65E5; +33FE;33FE;33FE;0033 0031 65E5;0033 0031 65E5; +33FF;33FF;33FF;0067 0061 006C;0067 0061 006C; +A69C;A69C;A69C;044A;044A; +A69D;A69D;A69D;044C;044C; +A770;A770;A770;A76F;A76F; +A7F8;A7F8;A7F8;0126;0126; +A7F9;A7F9;A7F9;0153;0153; +AB5C;AB5C;AB5C;A727;A727; +AB5D;AB5D;AB5D;AB37;AB37; +AB5E;AB5E;AB5E;026B;026B; +AB5F;AB5F;AB5F;AB52;AB52; +AC00;AC00;1100 1161;AC00;1100 1161; +AC01;AC01;1100 1161 11A8;AC01;1100 1161 11A8; +AC02;AC02;1100 1161 11A9;AC02;1100 1161 11A9; +AC03;AC03;1100 1161 11AA;AC03;1100 1161 11AA; +AC04;AC04;1100 1161 11AB;AC04;1100 1161 11AB; +AC05;AC05;1100 1161 11AC;AC05;1100 1161 11AC; +AC06;AC06;1100 1161 11AD;AC06;1100 1161 11AD; +AC07;AC07;1100 1161 11AE;AC07;1100 1161 11AE; +AC08;AC08;1100 1161 11AF;AC08;1100 1161 11AF; +AC09;AC09;1100 1161 11B0;AC09;1100 1161 11B0; +AC0A;AC0A;1100 1161 11B1;AC0A;1100 1161 11B1; +AC0B;AC0B;1100 1161 11B2;AC0B;1100 1161 11B2; +AC0C;AC0C;1100 1161 11B3;AC0C;1100 1161 11B3; +AC0D;AC0D;1100 1161 11B4;AC0D;1100 1161 11B4; +AC0E;AC0E;1100 1161 11B5;AC0E;1100 1161 11B5; +AC0F;AC0F;1100 1161 11B6;AC0F;1100 1161 11B6; +AC10;AC10;1100 1161 11B7;AC10;1100 1161 11B7; +AC11;AC11;1100 1161 11B8;AC11;1100 1161 11B8; +AC12;AC12;1100 1161 11B9;AC12;1100 1161 11B9; +AC13;AC13;1100 1161 11BA;AC13;1100 1161 11BA; +AC14;AC14;1100 1161 11BB;AC14;1100 1161 11BB; +AC15;AC15;1100 1161 11BC;AC15;1100 1161 11BC; +AC16;AC16;1100 1161 11BD;AC16;1100 1161 11BD; +AC17;AC17;1100 1161 11BE;AC17;1100 1161 11BE; +AC18;AC18;1100 1161 11BF;AC18;1100 1161 11BF; +AC19;AC19;1100 1161 11C0;AC19;1100 1161 11C0; +AC1A;AC1A;1100 1161 11C1;AC1A;1100 1161 11C1; +AC1B;AC1B;1100 1161 11C2;AC1B;1100 1161 11C2; +AC1C;AC1C;1100 1162;AC1C;1100 1162; +AC1D;AC1D;1100 1162 11A8;AC1D;1100 1162 11A8; +AC1E;AC1E;1100 1162 11A9;AC1E;1100 1162 11A9; +AC1F;AC1F;1100 1162 11AA;AC1F;1100 1162 11AA; +AC20;AC20;1100 1162 11AB;AC20;1100 1162 11AB; +AC21;AC21;1100 1162 11AC;AC21;1100 1162 11AC; +AC22;AC22;1100 1162 11AD;AC22;1100 1162 11AD; +AC23;AC23;1100 1162 11AE;AC23;1100 1162 11AE; +AC24;AC24;1100 1162 11AF;AC24;1100 1162 11AF; +AC25;AC25;1100 1162 11B0;AC25;1100 1162 11B0; +AC26;AC26;1100 1162 11B1;AC26;1100 1162 11B1; +AC27;AC27;1100 1162 11B2;AC27;1100 1162 11B2; +AC28;AC28;1100 1162 11B3;AC28;1100 1162 11B3; +AC29;AC29;1100 1162 11B4;AC29;1100 1162 11B4; +AC2A;AC2A;1100 1162 11B5;AC2A;1100 1162 11B5; +AC2B;AC2B;1100 1162 11B6;AC2B;1100 1162 11B6; +AC2C;AC2C;1100 1162 11B7;AC2C;1100 1162 11B7; +AC2D;AC2D;1100 1162 11B8;AC2D;1100 1162 11B8; +AC2E;AC2E;1100 1162 11B9;AC2E;1100 1162 11B9; +AC2F;AC2F;1100 1162 11BA;AC2F;1100 1162 11BA; +AC30;AC30;1100 1162 11BB;AC30;1100 1162 11BB; +AC31;AC31;1100 1162 11BC;AC31;1100 1162 11BC; +AC32;AC32;1100 1162 11BD;AC32;1100 1162 11BD; +AC33;AC33;1100 1162 11BE;AC33;1100 1162 11BE; +AC34;AC34;1100 1162 11BF;AC34;1100 1162 11BF; +AC35;AC35;1100 1162 11C0;AC35;1100 1162 11C0; +AC36;AC36;1100 1162 11C1;AC36;1100 1162 11C1; +AC37;AC37;1100 1162 11C2;AC37;1100 1162 11C2; +AC38;AC38;1100 1163;AC38;1100 1163; +AC39;AC39;1100 1163 11A8;AC39;1100 1163 11A8; +AC3A;AC3A;1100 1163 11A9;AC3A;1100 1163 11A9; +AC3B;AC3B;1100 1163 11AA;AC3B;1100 1163 11AA; +AC3C;AC3C;1100 1163 11AB;AC3C;1100 1163 11AB; +AC3D;AC3D;1100 1163 11AC;AC3D;1100 1163 11AC; +AC3E;AC3E;1100 1163 11AD;AC3E;1100 1163 11AD; +AC3F;AC3F;1100 1163 11AE;AC3F;1100 1163 11AE; +AC40;AC40;1100 1163 11AF;AC40;1100 1163 11AF; +AC41;AC41;1100 1163 11B0;AC41;1100 1163 11B0; +AC42;AC42;1100 1163 11B1;AC42;1100 1163 11B1; +AC43;AC43;1100 1163 11B2;AC43;1100 1163 11B2; +AC44;AC44;1100 1163 11B3;AC44;1100 1163 11B3; +AC45;AC45;1100 1163 11B4;AC45;1100 1163 11B4; +AC46;AC46;1100 1163 11B5;AC46;1100 1163 11B5; +AC47;AC47;1100 1163 11B6;AC47;1100 1163 11B6; +AC48;AC48;1100 1163 11B7;AC48;1100 1163 11B7; +AC49;AC49;1100 1163 11B8;AC49;1100 1163 11B8; +AC4A;AC4A;1100 1163 11B9;AC4A;1100 1163 11B9; +AC4B;AC4B;1100 1163 11BA;AC4B;1100 1163 11BA; +AC4C;AC4C;1100 1163 11BB;AC4C;1100 1163 11BB; +AC4D;AC4D;1100 1163 11BC;AC4D;1100 1163 11BC; +AC4E;AC4E;1100 1163 11BD;AC4E;1100 1163 11BD; +AC4F;AC4F;1100 1163 11BE;AC4F;1100 1163 11BE; +AC50;AC50;1100 1163 11BF;AC50;1100 1163 11BF; +AC51;AC51;1100 1163 11C0;AC51;1100 1163 11C0; +AC52;AC52;1100 1163 11C1;AC52;1100 1163 11C1; +AC53;AC53;1100 1163 11C2;AC53;1100 1163 11C2; +AC54;AC54;1100 1164;AC54;1100 1164; +AC55;AC55;1100 1164 11A8;AC55;1100 1164 11A8; +AC56;AC56;1100 1164 11A9;AC56;1100 1164 11A9; +AC57;AC57;1100 1164 11AA;AC57;1100 1164 11AA; +AC58;AC58;1100 1164 11AB;AC58;1100 1164 11AB; +AC59;AC59;1100 1164 11AC;AC59;1100 1164 11AC; +AC5A;AC5A;1100 1164 11AD;AC5A;1100 1164 11AD; +AC5B;AC5B;1100 1164 11AE;AC5B;1100 1164 11AE; +AC5C;AC5C;1100 1164 11AF;AC5C;1100 1164 11AF; +AC5D;AC5D;1100 1164 11B0;AC5D;1100 1164 11B0; +AC5E;AC5E;1100 1164 11B1;AC5E;1100 1164 11B1; +AC5F;AC5F;1100 1164 11B2;AC5F;1100 1164 11B2; +AC60;AC60;1100 1164 11B3;AC60;1100 1164 11B3; +AC61;AC61;1100 1164 11B4;AC61;1100 1164 11B4; +AC62;AC62;1100 1164 11B5;AC62;1100 1164 11B5; +AC63;AC63;1100 1164 11B6;AC63;1100 1164 11B6; +AC64;AC64;1100 1164 11B7;AC64;1100 1164 11B7; +AC65;AC65;1100 1164 11B8;AC65;1100 1164 11B8; +AC66;AC66;1100 1164 11B9;AC66;1100 1164 11B9; +AC67;AC67;1100 1164 11BA;AC67;1100 1164 11BA; +AC68;AC68;1100 1164 11BB;AC68;1100 1164 11BB; +AC69;AC69;1100 1164 11BC;AC69;1100 1164 11BC; +AC6A;AC6A;1100 1164 11BD;AC6A;1100 1164 11BD; +AC6B;AC6B;1100 1164 11BE;AC6B;1100 1164 11BE; +AC6C;AC6C;1100 1164 11BF;AC6C;1100 1164 11BF; +AC6D;AC6D;1100 1164 11C0;AC6D;1100 1164 11C0; +AC6E;AC6E;1100 1164 11C1;AC6E;1100 1164 11C1; +AC6F;AC6F;1100 1164 11C2;AC6F;1100 1164 11C2; +AC70;AC70;1100 1165;AC70;1100 1165; +AC71;AC71;1100 1165 11A8;AC71;1100 1165 11A8; +AC72;AC72;1100 1165 11A9;AC72;1100 1165 11A9; +AC73;AC73;1100 1165 11AA;AC73;1100 1165 11AA; +AC74;AC74;1100 1165 11AB;AC74;1100 1165 11AB; +AC75;AC75;1100 1165 11AC;AC75;1100 1165 11AC; +AC76;AC76;1100 1165 11AD;AC76;1100 1165 11AD; +AC77;AC77;1100 1165 11AE;AC77;1100 1165 11AE; +AC78;AC78;1100 1165 11AF;AC78;1100 1165 11AF; +AC79;AC79;1100 1165 11B0;AC79;1100 1165 11B0; +AC7A;AC7A;1100 1165 11B1;AC7A;1100 1165 11B1; +AC7B;AC7B;1100 1165 11B2;AC7B;1100 1165 11B2; +AC7C;AC7C;1100 1165 11B3;AC7C;1100 1165 11B3; +AC7D;AC7D;1100 1165 11B4;AC7D;1100 1165 11B4; +AC7E;AC7E;1100 1165 11B5;AC7E;1100 1165 11B5; +AC7F;AC7F;1100 1165 11B6;AC7F;1100 1165 11B6; +AC80;AC80;1100 1165 11B7;AC80;1100 1165 11B7; +AC81;AC81;1100 1165 11B8;AC81;1100 1165 11B8; +AC82;AC82;1100 1165 11B9;AC82;1100 1165 11B9; +AC83;AC83;1100 1165 11BA;AC83;1100 1165 11BA; +AC84;AC84;1100 1165 11BB;AC84;1100 1165 11BB; +AC85;AC85;1100 1165 11BC;AC85;1100 1165 11BC; +AC86;AC86;1100 1165 11BD;AC86;1100 1165 11BD; +AC87;AC87;1100 1165 11BE;AC87;1100 1165 11BE; +AC88;AC88;1100 1165 11BF;AC88;1100 1165 11BF; +AC89;AC89;1100 1165 11C0;AC89;1100 1165 11C0; +AC8A;AC8A;1100 1165 11C1;AC8A;1100 1165 11C1; +AC8B;AC8B;1100 1165 11C2;AC8B;1100 1165 11C2; +AC8C;AC8C;1100 1166;AC8C;1100 1166; +AC8D;AC8D;1100 1166 11A8;AC8D;1100 1166 11A8; +AC8E;AC8E;1100 1166 11A9;AC8E;1100 1166 11A9; +AC8F;AC8F;1100 1166 11AA;AC8F;1100 1166 11AA; +AC90;AC90;1100 1166 11AB;AC90;1100 1166 11AB; +AC91;AC91;1100 1166 11AC;AC91;1100 1166 11AC; +AC92;AC92;1100 1166 11AD;AC92;1100 1166 11AD; +AC93;AC93;1100 1166 11AE;AC93;1100 1166 11AE; +AC94;AC94;1100 1166 11AF;AC94;1100 1166 11AF; +AC95;AC95;1100 1166 11B0;AC95;1100 1166 11B0; +AC96;AC96;1100 1166 11B1;AC96;1100 1166 11B1; +AC97;AC97;1100 1166 11B2;AC97;1100 1166 11B2; +AC98;AC98;1100 1166 11B3;AC98;1100 1166 11B3; +AC99;AC99;1100 1166 11B4;AC99;1100 1166 11B4; +AC9A;AC9A;1100 1166 11B5;AC9A;1100 1166 11B5; +AC9B;AC9B;1100 1166 11B6;AC9B;1100 1166 11B6; +AC9C;AC9C;1100 1166 11B7;AC9C;1100 1166 11B7; +AC9D;AC9D;1100 1166 11B8;AC9D;1100 1166 11B8; +AC9E;AC9E;1100 1166 11B9;AC9E;1100 1166 11B9; +AC9F;AC9F;1100 1166 11BA;AC9F;1100 1166 11BA; +ACA0;ACA0;1100 1166 11BB;ACA0;1100 1166 11BB; +ACA1;ACA1;1100 1166 11BC;ACA1;1100 1166 11BC; +ACA2;ACA2;1100 1166 11BD;ACA2;1100 1166 11BD; +ACA3;ACA3;1100 1166 11BE;ACA3;1100 1166 11BE; +ACA4;ACA4;1100 1166 11BF;ACA4;1100 1166 11BF; +ACA5;ACA5;1100 1166 11C0;ACA5;1100 1166 11C0; +ACA6;ACA6;1100 1166 11C1;ACA6;1100 1166 11C1; +ACA7;ACA7;1100 1166 11C2;ACA7;1100 1166 11C2; +ACA8;ACA8;1100 1167;ACA8;1100 1167; +ACA9;ACA9;1100 1167 11A8;ACA9;1100 1167 11A8; +ACAA;ACAA;1100 1167 11A9;ACAA;1100 1167 11A9; +ACAB;ACAB;1100 1167 11AA;ACAB;1100 1167 11AA; +ACAC;ACAC;1100 1167 11AB;ACAC;1100 1167 11AB; +ACAD;ACAD;1100 1167 11AC;ACAD;1100 1167 11AC; +ACAE;ACAE;1100 1167 11AD;ACAE;1100 1167 11AD; +ACAF;ACAF;1100 1167 11AE;ACAF;1100 1167 11AE; +ACB0;ACB0;1100 1167 11AF;ACB0;1100 1167 11AF; +ACB1;ACB1;1100 1167 11B0;ACB1;1100 1167 11B0; +ACB2;ACB2;1100 1167 11B1;ACB2;1100 1167 11B1; +ACB3;ACB3;1100 1167 11B2;ACB3;1100 1167 11B2; +ACB4;ACB4;1100 1167 11B3;ACB4;1100 1167 11B3; +ACB5;ACB5;1100 1167 11B4;ACB5;1100 1167 11B4; +ACB6;ACB6;1100 1167 11B5;ACB6;1100 1167 11B5; +ACB7;ACB7;1100 1167 11B6;ACB7;1100 1167 11B6; +ACB8;ACB8;1100 1167 11B7;ACB8;1100 1167 11B7; +ACB9;ACB9;1100 1167 11B8;ACB9;1100 1167 11B8; +ACBA;ACBA;1100 1167 11B9;ACBA;1100 1167 11B9; +ACBB;ACBB;1100 1167 11BA;ACBB;1100 1167 11BA; +ACBC;ACBC;1100 1167 11BB;ACBC;1100 1167 11BB; +ACBD;ACBD;1100 1167 11BC;ACBD;1100 1167 11BC; +ACBE;ACBE;1100 1167 11BD;ACBE;1100 1167 11BD; +ACBF;ACBF;1100 1167 11BE;ACBF;1100 1167 11BE; +ACC0;ACC0;1100 1167 11BF;ACC0;1100 1167 11BF; +ACC1;ACC1;1100 1167 11C0;ACC1;1100 1167 11C0; +ACC2;ACC2;1100 1167 11C1;ACC2;1100 1167 11C1; +ACC3;ACC3;1100 1167 11C2;ACC3;1100 1167 11C2; +ACC4;ACC4;1100 1168;ACC4;1100 1168; +ACC5;ACC5;1100 1168 11A8;ACC5;1100 1168 11A8; +ACC6;ACC6;1100 1168 11A9;ACC6;1100 1168 11A9; +ACC7;ACC7;1100 1168 11AA;ACC7;1100 1168 11AA; +ACC8;ACC8;1100 1168 11AB;ACC8;1100 1168 11AB; +ACC9;ACC9;1100 1168 11AC;ACC9;1100 1168 11AC; +ACCA;ACCA;1100 1168 11AD;ACCA;1100 1168 11AD; +ACCB;ACCB;1100 1168 11AE;ACCB;1100 1168 11AE; +ACCC;ACCC;1100 1168 11AF;ACCC;1100 1168 11AF; +ACCD;ACCD;1100 1168 11B0;ACCD;1100 1168 11B0; +ACCE;ACCE;1100 1168 11B1;ACCE;1100 1168 11B1; +ACCF;ACCF;1100 1168 11B2;ACCF;1100 1168 11B2; +ACD0;ACD0;1100 1168 11B3;ACD0;1100 1168 11B3; +ACD1;ACD1;1100 1168 11B4;ACD1;1100 1168 11B4; +ACD2;ACD2;1100 1168 11B5;ACD2;1100 1168 11B5; +ACD3;ACD3;1100 1168 11B6;ACD3;1100 1168 11B6; +ACD4;ACD4;1100 1168 11B7;ACD4;1100 1168 11B7; +ACD5;ACD5;1100 1168 11B8;ACD5;1100 1168 11B8; +ACD6;ACD6;1100 1168 11B9;ACD6;1100 1168 11B9; +ACD7;ACD7;1100 1168 11BA;ACD7;1100 1168 11BA; +ACD8;ACD8;1100 1168 11BB;ACD8;1100 1168 11BB; +ACD9;ACD9;1100 1168 11BC;ACD9;1100 1168 11BC; +ACDA;ACDA;1100 1168 11BD;ACDA;1100 1168 11BD; +ACDB;ACDB;1100 1168 11BE;ACDB;1100 1168 11BE; +ACDC;ACDC;1100 1168 11BF;ACDC;1100 1168 11BF; +ACDD;ACDD;1100 1168 11C0;ACDD;1100 1168 11C0; +ACDE;ACDE;1100 1168 11C1;ACDE;1100 1168 11C1; +ACDF;ACDF;1100 1168 11C2;ACDF;1100 1168 11C2; +ACE0;ACE0;1100 1169;ACE0;1100 1169; +ACE1;ACE1;1100 1169 11A8;ACE1;1100 1169 11A8; +ACE2;ACE2;1100 1169 11A9;ACE2;1100 1169 11A9; +ACE3;ACE3;1100 1169 11AA;ACE3;1100 1169 11AA; +ACE4;ACE4;1100 1169 11AB;ACE4;1100 1169 11AB; +ACE5;ACE5;1100 1169 11AC;ACE5;1100 1169 11AC; +ACE6;ACE6;1100 1169 11AD;ACE6;1100 1169 11AD; +ACE7;ACE7;1100 1169 11AE;ACE7;1100 1169 11AE; +ACE8;ACE8;1100 1169 11AF;ACE8;1100 1169 11AF; +ACE9;ACE9;1100 1169 11B0;ACE9;1100 1169 11B0; +ACEA;ACEA;1100 1169 11B1;ACEA;1100 1169 11B1; +ACEB;ACEB;1100 1169 11B2;ACEB;1100 1169 11B2; +ACEC;ACEC;1100 1169 11B3;ACEC;1100 1169 11B3; +ACED;ACED;1100 1169 11B4;ACED;1100 1169 11B4; +ACEE;ACEE;1100 1169 11B5;ACEE;1100 1169 11B5; +ACEF;ACEF;1100 1169 11B6;ACEF;1100 1169 11B6; +ACF0;ACF0;1100 1169 11B7;ACF0;1100 1169 11B7; +ACF1;ACF1;1100 1169 11B8;ACF1;1100 1169 11B8; +ACF2;ACF2;1100 1169 11B9;ACF2;1100 1169 11B9; +ACF3;ACF3;1100 1169 11BA;ACF3;1100 1169 11BA; +ACF4;ACF4;1100 1169 11BB;ACF4;1100 1169 11BB; +ACF5;ACF5;1100 1169 11BC;ACF5;1100 1169 11BC; +ACF6;ACF6;1100 1169 11BD;ACF6;1100 1169 11BD; +ACF7;ACF7;1100 1169 11BE;ACF7;1100 1169 11BE; +ACF8;ACF8;1100 1169 11BF;ACF8;1100 1169 11BF; +ACF9;ACF9;1100 1169 11C0;ACF9;1100 1169 11C0; +ACFA;ACFA;1100 1169 11C1;ACFA;1100 1169 11C1; +ACFB;ACFB;1100 1169 11C2;ACFB;1100 1169 11C2; +ACFC;ACFC;1100 116A;ACFC;1100 116A; +ACFD;ACFD;1100 116A 11A8;ACFD;1100 116A 11A8; +ACFE;ACFE;1100 116A 11A9;ACFE;1100 116A 11A9; +ACFF;ACFF;1100 116A 11AA;ACFF;1100 116A 11AA; +AD00;AD00;1100 116A 11AB;AD00;1100 116A 11AB; +AD01;AD01;1100 116A 11AC;AD01;1100 116A 11AC; +AD02;AD02;1100 116A 11AD;AD02;1100 116A 11AD; +AD03;AD03;1100 116A 11AE;AD03;1100 116A 11AE; +AD04;AD04;1100 116A 11AF;AD04;1100 116A 11AF; +AD05;AD05;1100 116A 11B0;AD05;1100 116A 11B0; +AD06;AD06;1100 116A 11B1;AD06;1100 116A 11B1; +AD07;AD07;1100 116A 11B2;AD07;1100 116A 11B2; +AD08;AD08;1100 116A 11B3;AD08;1100 116A 11B3; +AD09;AD09;1100 116A 11B4;AD09;1100 116A 11B4; +AD0A;AD0A;1100 116A 11B5;AD0A;1100 116A 11B5; +AD0B;AD0B;1100 116A 11B6;AD0B;1100 116A 11B6; +AD0C;AD0C;1100 116A 11B7;AD0C;1100 116A 11B7; +AD0D;AD0D;1100 116A 11B8;AD0D;1100 116A 11B8; +AD0E;AD0E;1100 116A 11B9;AD0E;1100 116A 11B9; +AD0F;AD0F;1100 116A 11BA;AD0F;1100 116A 11BA; +AD10;AD10;1100 116A 11BB;AD10;1100 116A 11BB; +AD11;AD11;1100 116A 11BC;AD11;1100 116A 11BC; +AD12;AD12;1100 116A 11BD;AD12;1100 116A 11BD; +AD13;AD13;1100 116A 11BE;AD13;1100 116A 11BE; +AD14;AD14;1100 116A 11BF;AD14;1100 116A 11BF; +AD15;AD15;1100 116A 11C0;AD15;1100 116A 11C0; +AD16;AD16;1100 116A 11C1;AD16;1100 116A 11C1; +AD17;AD17;1100 116A 11C2;AD17;1100 116A 11C2; +AD18;AD18;1100 116B;AD18;1100 116B; +AD19;AD19;1100 116B 11A8;AD19;1100 116B 11A8; +AD1A;AD1A;1100 116B 11A9;AD1A;1100 116B 11A9; +AD1B;AD1B;1100 116B 11AA;AD1B;1100 116B 11AA; +AD1C;AD1C;1100 116B 11AB;AD1C;1100 116B 11AB; +AD1D;AD1D;1100 116B 11AC;AD1D;1100 116B 11AC; +AD1E;AD1E;1100 116B 11AD;AD1E;1100 116B 11AD; +AD1F;AD1F;1100 116B 11AE;AD1F;1100 116B 11AE; +AD20;AD20;1100 116B 11AF;AD20;1100 116B 11AF; +AD21;AD21;1100 116B 11B0;AD21;1100 116B 11B0; +AD22;AD22;1100 116B 11B1;AD22;1100 116B 11B1; +AD23;AD23;1100 116B 11B2;AD23;1100 116B 11B2; +AD24;AD24;1100 116B 11B3;AD24;1100 116B 11B3; +AD25;AD25;1100 116B 11B4;AD25;1100 116B 11B4; +AD26;AD26;1100 116B 11B5;AD26;1100 116B 11B5; +AD27;AD27;1100 116B 11B6;AD27;1100 116B 11B6; +AD28;AD28;1100 116B 11B7;AD28;1100 116B 11B7; +AD29;AD29;1100 116B 11B8;AD29;1100 116B 11B8; +AD2A;AD2A;1100 116B 11B9;AD2A;1100 116B 11B9; +AD2B;AD2B;1100 116B 11BA;AD2B;1100 116B 11BA; +AD2C;AD2C;1100 116B 11BB;AD2C;1100 116B 11BB; +AD2D;AD2D;1100 116B 11BC;AD2D;1100 116B 11BC; +AD2E;AD2E;1100 116B 11BD;AD2E;1100 116B 11BD; +AD2F;AD2F;1100 116B 11BE;AD2F;1100 116B 11BE; +AD30;AD30;1100 116B 11BF;AD30;1100 116B 11BF; +AD31;AD31;1100 116B 11C0;AD31;1100 116B 11C0; +AD32;AD32;1100 116B 11C1;AD32;1100 116B 11C1; +AD33;AD33;1100 116B 11C2;AD33;1100 116B 11C2; +AD34;AD34;1100 116C;AD34;1100 116C; +AD35;AD35;1100 116C 11A8;AD35;1100 116C 11A8; +AD36;AD36;1100 116C 11A9;AD36;1100 116C 11A9; +AD37;AD37;1100 116C 11AA;AD37;1100 116C 11AA; +AD38;AD38;1100 116C 11AB;AD38;1100 116C 11AB; +AD39;AD39;1100 116C 11AC;AD39;1100 116C 11AC; +AD3A;AD3A;1100 116C 11AD;AD3A;1100 116C 11AD; +AD3B;AD3B;1100 116C 11AE;AD3B;1100 116C 11AE; +AD3C;AD3C;1100 116C 11AF;AD3C;1100 116C 11AF; +AD3D;AD3D;1100 116C 11B0;AD3D;1100 116C 11B0; +AD3E;AD3E;1100 116C 11B1;AD3E;1100 116C 11B1; +AD3F;AD3F;1100 116C 11B2;AD3F;1100 116C 11B2; +AD40;AD40;1100 116C 11B3;AD40;1100 116C 11B3; +AD41;AD41;1100 116C 11B4;AD41;1100 116C 11B4; +AD42;AD42;1100 116C 11B5;AD42;1100 116C 11B5; +AD43;AD43;1100 116C 11B6;AD43;1100 116C 11B6; +AD44;AD44;1100 116C 11B7;AD44;1100 116C 11B7; +AD45;AD45;1100 116C 11B8;AD45;1100 116C 11B8; +AD46;AD46;1100 116C 11B9;AD46;1100 116C 11B9; +AD47;AD47;1100 116C 11BA;AD47;1100 116C 11BA; +AD48;AD48;1100 116C 11BB;AD48;1100 116C 11BB; +AD49;AD49;1100 116C 11BC;AD49;1100 116C 11BC; +AD4A;AD4A;1100 116C 11BD;AD4A;1100 116C 11BD; +AD4B;AD4B;1100 116C 11BE;AD4B;1100 116C 11BE; +AD4C;AD4C;1100 116C 11BF;AD4C;1100 116C 11BF; +AD4D;AD4D;1100 116C 11C0;AD4D;1100 116C 11C0; +AD4E;AD4E;1100 116C 11C1;AD4E;1100 116C 11C1; +AD4F;AD4F;1100 116C 11C2;AD4F;1100 116C 11C2; +AD50;AD50;1100 116D;AD50;1100 116D; +AD51;AD51;1100 116D 11A8;AD51;1100 116D 11A8; +AD52;AD52;1100 116D 11A9;AD52;1100 116D 11A9; +AD53;AD53;1100 116D 11AA;AD53;1100 116D 11AA; +AD54;AD54;1100 116D 11AB;AD54;1100 116D 11AB; +AD55;AD55;1100 116D 11AC;AD55;1100 116D 11AC; +AD56;AD56;1100 116D 11AD;AD56;1100 116D 11AD; +AD57;AD57;1100 116D 11AE;AD57;1100 116D 11AE; +AD58;AD58;1100 116D 11AF;AD58;1100 116D 11AF; +AD59;AD59;1100 116D 11B0;AD59;1100 116D 11B0; +AD5A;AD5A;1100 116D 11B1;AD5A;1100 116D 11B1; +AD5B;AD5B;1100 116D 11B2;AD5B;1100 116D 11B2; +AD5C;AD5C;1100 116D 11B3;AD5C;1100 116D 11B3; +AD5D;AD5D;1100 116D 11B4;AD5D;1100 116D 11B4; +AD5E;AD5E;1100 116D 11B5;AD5E;1100 116D 11B5; +AD5F;AD5F;1100 116D 11B6;AD5F;1100 116D 11B6; +AD60;AD60;1100 116D 11B7;AD60;1100 116D 11B7; +AD61;AD61;1100 116D 11B8;AD61;1100 116D 11B8; +AD62;AD62;1100 116D 11B9;AD62;1100 116D 11B9; +AD63;AD63;1100 116D 11BA;AD63;1100 116D 11BA; +AD64;AD64;1100 116D 11BB;AD64;1100 116D 11BB; +AD65;AD65;1100 116D 11BC;AD65;1100 116D 11BC; +AD66;AD66;1100 116D 11BD;AD66;1100 116D 11BD; +AD67;AD67;1100 116D 11BE;AD67;1100 116D 11BE; +AD68;AD68;1100 116D 11BF;AD68;1100 116D 11BF; +AD69;AD69;1100 116D 11C0;AD69;1100 116D 11C0; +AD6A;AD6A;1100 116D 11C1;AD6A;1100 116D 11C1; +AD6B;AD6B;1100 116D 11C2;AD6B;1100 116D 11C2; +AD6C;AD6C;1100 116E;AD6C;1100 116E; +AD6D;AD6D;1100 116E 11A8;AD6D;1100 116E 11A8; +AD6E;AD6E;1100 116E 11A9;AD6E;1100 116E 11A9; +AD6F;AD6F;1100 116E 11AA;AD6F;1100 116E 11AA; +AD70;AD70;1100 116E 11AB;AD70;1100 116E 11AB; +AD71;AD71;1100 116E 11AC;AD71;1100 116E 11AC; +AD72;AD72;1100 116E 11AD;AD72;1100 116E 11AD; +AD73;AD73;1100 116E 11AE;AD73;1100 116E 11AE; +AD74;AD74;1100 116E 11AF;AD74;1100 116E 11AF; +AD75;AD75;1100 116E 11B0;AD75;1100 116E 11B0; +AD76;AD76;1100 116E 11B1;AD76;1100 116E 11B1; +AD77;AD77;1100 116E 11B2;AD77;1100 116E 11B2; +AD78;AD78;1100 116E 11B3;AD78;1100 116E 11B3; +AD79;AD79;1100 116E 11B4;AD79;1100 116E 11B4; +AD7A;AD7A;1100 116E 11B5;AD7A;1100 116E 11B5; +AD7B;AD7B;1100 116E 11B6;AD7B;1100 116E 11B6; +AD7C;AD7C;1100 116E 11B7;AD7C;1100 116E 11B7; +AD7D;AD7D;1100 116E 11B8;AD7D;1100 116E 11B8; +AD7E;AD7E;1100 116E 11B9;AD7E;1100 116E 11B9; +AD7F;AD7F;1100 116E 11BA;AD7F;1100 116E 11BA; +AD80;AD80;1100 116E 11BB;AD80;1100 116E 11BB; +AD81;AD81;1100 116E 11BC;AD81;1100 116E 11BC; +AD82;AD82;1100 116E 11BD;AD82;1100 116E 11BD; +AD83;AD83;1100 116E 11BE;AD83;1100 116E 11BE; +AD84;AD84;1100 116E 11BF;AD84;1100 116E 11BF; +AD85;AD85;1100 116E 11C0;AD85;1100 116E 11C0; +AD86;AD86;1100 116E 11C1;AD86;1100 116E 11C1; +AD87;AD87;1100 116E 11C2;AD87;1100 116E 11C2; +AD88;AD88;1100 116F;AD88;1100 116F; +AD89;AD89;1100 116F 11A8;AD89;1100 116F 11A8; +AD8A;AD8A;1100 116F 11A9;AD8A;1100 116F 11A9; +AD8B;AD8B;1100 116F 11AA;AD8B;1100 116F 11AA; +AD8C;AD8C;1100 116F 11AB;AD8C;1100 116F 11AB; +AD8D;AD8D;1100 116F 11AC;AD8D;1100 116F 11AC; +AD8E;AD8E;1100 116F 11AD;AD8E;1100 116F 11AD; +AD8F;AD8F;1100 116F 11AE;AD8F;1100 116F 11AE; +AD90;AD90;1100 116F 11AF;AD90;1100 116F 11AF; +AD91;AD91;1100 116F 11B0;AD91;1100 116F 11B0; +AD92;AD92;1100 116F 11B1;AD92;1100 116F 11B1; +AD93;AD93;1100 116F 11B2;AD93;1100 116F 11B2; +AD94;AD94;1100 116F 11B3;AD94;1100 116F 11B3; +AD95;AD95;1100 116F 11B4;AD95;1100 116F 11B4; +AD96;AD96;1100 116F 11B5;AD96;1100 116F 11B5; +AD97;AD97;1100 116F 11B6;AD97;1100 116F 11B6; +AD98;AD98;1100 116F 11B7;AD98;1100 116F 11B7; +AD99;AD99;1100 116F 11B8;AD99;1100 116F 11B8; +AD9A;AD9A;1100 116F 11B9;AD9A;1100 116F 11B9; +AD9B;AD9B;1100 116F 11BA;AD9B;1100 116F 11BA; +AD9C;AD9C;1100 116F 11BB;AD9C;1100 116F 11BB; +AD9D;AD9D;1100 116F 11BC;AD9D;1100 116F 11BC; +AD9E;AD9E;1100 116F 11BD;AD9E;1100 116F 11BD; +AD9F;AD9F;1100 116F 11BE;AD9F;1100 116F 11BE; +ADA0;ADA0;1100 116F 11BF;ADA0;1100 116F 11BF; +ADA1;ADA1;1100 116F 11C0;ADA1;1100 116F 11C0; +ADA2;ADA2;1100 116F 11C1;ADA2;1100 116F 11C1; +ADA3;ADA3;1100 116F 11C2;ADA3;1100 116F 11C2; +ADA4;ADA4;1100 1170;ADA4;1100 1170; +ADA5;ADA5;1100 1170 11A8;ADA5;1100 1170 11A8; +ADA6;ADA6;1100 1170 11A9;ADA6;1100 1170 11A9; +ADA7;ADA7;1100 1170 11AA;ADA7;1100 1170 11AA; +ADA8;ADA8;1100 1170 11AB;ADA8;1100 1170 11AB; +ADA9;ADA9;1100 1170 11AC;ADA9;1100 1170 11AC; +ADAA;ADAA;1100 1170 11AD;ADAA;1100 1170 11AD; +ADAB;ADAB;1100 1170 11AE;ADAB;1100 1170 11AE; +ADAC;ADAC;1100 1170 11AF;ADAC;1100 1170 11AF; +ADAD;ADAD;1100 1170 11B0;ADAD;1100 1170 11B0; +ADAE;ADAE;1100 1170 11B1;ADAE;1100 1170 11B1; +ADAF;ADAF;1100 1170 11B2;ADAF;1100 1170 11B2; +ADB0;ADB0;1100 1170 11B3;ADB0;1100 1170 11B3; +ADB1;ADB1;1100 1170 11B4;ADB1;1100 1170 11B4; +ADB2;ADB2;1100 1170 11B5;ADB2;1100 1170 11B5; +ADB3;ADB3;1100 1170 11B6;ADB3;1100 1170 11B6; +ADB4;ADB4;1100 1170 11B7;ADB4;1100 1170 11B7; +ADB5;ADB5;1100 1170 11B8;ADB5;1100 1170 11B8; +ADB6;ADB6;1100 1170 11B9;ADB6;1100 1170 11B9; +ADB7;ADB7;1100 1170 11BA;ADB7;1100 1170 11BA; +ADB8;ADB8;1100 1170 11BB;ADB8;1100 1170 11BB; +ADB9;ADB9;1100 1170 11BC;ADB9;1100 1170 11BC; +ADBA;ADBA;1100 1170 11BD;ADBA;1100 1170 11BD; +ADBB;ADBB;1100 1170 11BE;ADBB;1100 1170 11BE; +ADBC;ADBC;1100 1170 11BF;ADBC;1100 1170 11BF; +ADBD;ADBD;1100 1170 11C0;ADBD;1100 1170 11C0; +ADBE;ADBE;1100 1170 11C1;ADBE;1100 1170 11C1; +ADBF;ADBF;1100 1170 11C2;ADBF;1100 1170 11C2; +ADC0;ADC0;1100 1171;ADC0;1100 1171; +ADC1;ADC1;1100 1171 11A8;ADC1;1100 1171 11A8; +ADC2;ADC2;1100 1171 11A9;ADC2;1100 1171 11A9; +ADC3;ADC3;1100 1171 11AA;ADC3;1100 1171 11AA; +ADC4;ADC4;1100 1171 11AB;ADC4;1100 1171 11AB; +ADC5;ADC5;1100 1171 11AC;ADC5;1100 1171 11AC; +ADC6;ADC6;1100 1171 11AD;ADC6;1100 1171 11AD; +ADC7;ADC7;1100 1171 11AE;ADC7;1100 1171 11AE; +ADC8;ADC8;1100 1171 11AF;ADC8;1100 1171 11AF; +ADC9;ADC9;1100 1171 11B0;ADC9;1100 1171 11B0; +ADCA;ADCA;1100 1171 11B1;ADCA;1100 1171 11B1; +ADCB;ADCB;1100 1171 11B2;ADCB;1100 1171 11B2; +ADCC;ADCC;1100 1171 11B3;ADCC;1100 1171 11B3; +ADCD;ADCD;1100 1171 11B4;ADCD;1100 1171 11B4; +ADCE;ADCE;1100 1171 11B5;ADCE;1100 1171 11B5; +ADCF;ADCF;1100 1171 11B6;ADCF;1100 1171 11B6; +ADD0;ADD0;1100 1171 11B7;ADD0;1100 1171 11B7; +ADD1;ADD1;1100 1171 11B8;ADD1;1100 1171 11B8; +ADD2;ADD2;1100 1171 11B9;ADD2;1100 1171 11B9; +ADD3;ADD3;1100 1171 11BA;ADD3;1100 1171 11BA; +ADD4;ADD4;1100 1171 11BB;ADD4;1100 1171 11BB; +ADD5;ADD5;1100 1171 11BC;ADD5;1100 1171 11BC; +ADD6;ADD6;1100 1171 11BD;ADD6;1100 1171 11BD; +ADD7;ADD7;1100 1171 11BE;ADD7;1100 1171 11BE; +ADD8;ADD8;1100 1171 11BF;ADD8;1100 1171 11BF; +ADD9;ADD9;1100 1171 11C0;ADD9;1100 1171 11C0; +ADDA;ADDA;1100 1171 11C1;ADDA;1100 1171 11C1; +ADDB;ADDB;1100 1171 11C2;ADDB;1100 1171 11C2; +ADDC;ADDC;1100 1172;ADDC;1100 1172; +ADDD;ADDD;1100 1172 11A8;ADDD;1100 1172 11A8; +ADDE;ADDE;1100 1172 11A9;ADDE;1100 1172 11A9; +ADDF;ADDF;1100 1172 11AA;ADDF;1100 1172 11AA; +ADE0;ADE0;1100 1172 11AB;ADE0;1100 1172 11AB; +ADE1;ADE1;1100 1172 11AC;ADE1;1100 1172 11AC; +ADE2;ADE2;1100 1172 11AD;ADE2;1100 1172 11AD; +ADE3;ADE3;1100 1172 11AE;ADE3;1100 1172 11AE; +ADE4;ADE4;1100 1172 11AF;ADE4;1100 1172 11AF; +ADE5;ADE5;1100 1172 11B0;ADE5;1100 1172 11B0; +ADE6;ADE6;1100 1172 11B1;ADE6;1100 1172 11B1; +ADE7;ADE7;1100 1172 11B2;ADE7;1100 1172 11B2; +ADE8;ADE8;1100 1172 11B3;ADE8;1100 1172 11B3; +ADE9;ADE9;1100 1172 11B4;ADE9;1100 1172 11B4; +ADEA;ADEA;1100 1172 11B5;ADEA;1100 1172 11B5; +ADEB;ADEB;1100 1172 11B6;ADEB;1100 1172 11B6; +ADEC;ADEC;1100 1172 11B7;ADEC;1100 1172 11B7; +ADED;ADED;1100 1172 11B8;ADED;1100 1172 11B8; +ADEE;ADEE;1100 1172 11B9;ADEE;1100 1172 11B9; +ADEF;ADEF;1100 1172 11BA;ADEF;1100 1172 11BA; +ADF0;ADF0;1100 1172 11BB;ADF0;1100 1172 11BB; +ADF1;ADF1;1100 1172 11BC;ADF1;1100 1172 11BC; +ADF2;ADF2;1100 1172 11BD;ADF2;1100 1172 11BD; +ADF3;ADF3;1100 1172 11BE;ADF3;1100 1172 11BE; +ADF4;ADF4;1100 1172 11BF;ADF4;1100 1172 11BF; +ADF5;ADF5;1100 1172 11C0;ADF5;1100 1172 11C0; +ADF6;ADF6;1100 1172 11C1;ADF6;1100 1172 11C1; +ADF7;ADF7;1100 1172 11C2;ADF7;1100 1172 11C2; +ADF8;ADF8;1100 1173;ADF8;1100 1173; +ADF9;ADF9;1100 1173 11A8;ADF9;1100 1173 11A8; +ADFA;ADFA;1100 1173 11A9;ADFA;1100 1173 11A9; +ADFB;ADFB;1100 1173 11AA;ADFB;1100 1173 11AA; +ADFC;ADFC;1100 1173 11AB;ADFC;1100 1173 11AB; +ADFD;ADFD;1100 1173 11AC;ADFD;1100 1173 11AC; +ADFE;ADFE;1100 1173 11AD;ADFE;1100 1173 11AD; +ADFF;ADFF;1100 1173 11AE;ADFF;1100 1173 11AE; +AE00;AE00;1100 1173 11AF;AE00;1100 1173 11AF; +AE01;AE01;1100 1173 11B0;AE01;1100 1173 11B0; +AE02;AE02;1100 1173 11B1;AE02;1100 1173 11B1; +AE03;AE03;1100 1173 11B2;AE03;1100 1173 11B2; +AE04;AE04;1100 1173 11B3;AE04;1100 1173 11B3; +AE05;AE05;1100 1173 11B4;AE05;1100 1173 11B4; +AE06;AE06;1100 1173 11B5;AE06;1100 1173 11B5; +AE07;AE07;1100 1173 11B6;AE07;1100 1173 11B6; +AE08;AE08;1100 1173 11B7;AE08;1100 1173 11B7; +AE09;AE09;1100 1173 11B8;AE09;1100 1173 11B8; +AE0A;AE0A;1100 1173 11B9;AE0A;1100 1173 11B9; +AE0B;AE0B;1100 1173 11BA;AE0B;1100 1173 11BA; +AE0C;AE0C;1100 1173 11BB;AE0C;1100 1173 11BB; +AE0D;AE0D;1100 1173 11BC;AE0D;1100 1173 11BC; +AE0E;AE0E;1100 1173 11BD;AE0E;1100 1173 11BD; +AE0F;AE0F;1100 1173 11BE;AE0F;1100 1173 11BE; +AE10;AE10;1100 1173 11BF;AE10;1100 1173 11BF; +AE11;AE11;1100 1173 11C0;AE11;1100 1173 11C0; +AE12;AE12;1100 1173 11C1;AE12;1100 1173 11C1; +AE13;AE13;1100 1173 11C2;AE13;1100 1173 11C2; +AE14;AE14;1100 1174;AE14;1100 1174; +AE15;AE15;1100 1174 11A8;AE15;1100 1174 11A8; +AE16;AE16;1100 1174 11A9;AE16;1100 1174 11A9; +AE17;AE17;1100 1174 11AA;AE17;1100 1174 11AA; +AE18;AE18;1100 1174 11AB;AE18;1100 1174 11AB; +AE19;AE19;1100 1174 11AC;AE19;1100 1174 11AC; +AE1A;AE1A;1100 1174 11AD;AE1A;1100 1174 11AD; +AE1B;AE1B;1100 1174 11AE;AE1B;1100 1174 11AE; +AE1C;AE1C;1100 1174 11AF;AE1C;1100 1174 11AF; +AE1D;AE1D;1100 1174 11B0;AE1D;1100 1174 11B0; +AE1E;AE1E;1100 1174 11B1;AE1E;1100 1174 11B1; +AE1F;AE1F;1100 1174 11B2;AE1F;1100 1174 11B2; +AE20;AE20;1100 1174 11B3;AE20;1100 1174 11B3; +AE21;AE21;1100 1174 11B4;AE21;1100 1174 11B4; +AE22;AE22;1100 1174 11B5;AE22;1100 1174 11B5; +AE23;AE23;1100 1174 11B6;AE23;1100 1174 11B6; +AE24;AE24;1100 1174 11B7;AE24;1100 1174 11B7; +AE25;AE25;1100 1174 11B8;AE25;1100 1174 11B8; +AE26;AE26;1100 1174 11B9;AE26;1100 1174 11B9; +AE27;AE27;1100 1174 11BA;AE27;1100 1174 11BA; +AE28;AE28;1100 1174 11BB;AE28;1100 1174 11BB; +AE29;AE29;1100 1174 11BC;AE29;1100 1174 11BC; +AE2A;AE2A;1100 1174 11BD;AE2A;1100 1174 11BD; +AE2B;AE2B;1100 1174 11BE;AE2B;1100 1174 11BE; +AE2C;AE2C;1100 1174 11BF;AE2C;1100 1174 11BF; +AE2D;AE2D;1100 1174 11C0;AE2D;1100 1174 11C0; +AE2E;AE2E;1100 1174 11C1;AE2E;1100 1174 11C1; +AE2F;AE2F;1100 1174 11C2;AE2F;1100 1174 11C2; +AE30;AE30;1100 1175;AE30;1100 1175; +AE31;AE31;1100 1175 11A8;AE31;1100 1175 11A8; +AE32;AE32;1100 1175 11A9;AE32;1100 1175 11A9; +AE33;AE33;1100 1175 11AA;AE33;1100 1175 11AA; +AE34;AE34;1100 1175 11AB;AE34;1100 1175 11AB; +AE35;AE35;1100 1175 11AC;AE35;1100 1175 11AC; +AE36;AE36;1100 1175 11AD;AE36;1100 1175 11AD; +AE37;AE37;1100 1175 11AE;AE37;1100 1175 11AE; +AE38;AE38;1100 1175 11AF;AE38;1100 1175 11AF; +AE39;AE39;1100 1175 11B0;AE39;1100 1175 11B0; +AE3A;AE3A;1100 1175 11B1;AE3A;1100 1175 11B1; +AE3B;AE3B;1100 1175 11B2;AE3B;1100 1175 11B2; +AE3C;AE3C;1100 1175 11B3;AE3C;1100 1175 11B3; +AE3D;AE3D;1100 1175 11B4;AE3D;1100 1175 11B4; +AE3E;AE3E;1100 1175 11B5;AE3E;1100 1175 11B5; +AE3F;AE3F;1100 1175 11B6;AE3F;1100 1175 11B6; +AE40;AE40;1100 1175 11B7;AE40;1100 1175 11B7; +AE41;AE41;1100 1175 11B8;AE41;1100 1175 11B8; +AE42;AE42;1100 1175 11B9;AE42;1100 1175 11B9; +AE43;AE43;1100 1175 11BA;AE43;1100 1175 11BA; +AE44;AE44;1100 1175 11BB;AE44;1100 1175 11BB; +AE45;AE45;1100 1175 11BC;AE45;1100 1175 11BC; +AE46;AE46;1100 1175 11BD;AE46;1100 1175 11BD; +AE47;AE47;1100 1175 11BE;AE47;1100 1175 11BE; +AE48;AE48;1100 1175 11BF;AE48;1100 1175 11BF; +AE49;AE49;1100 1175 11C0;AE49;1100 1175 11C0; +AE4A;AE4A;1100 1175 11C1;AE4A;1100 1175 11C1; +AE4B;AE4B;1100 1175 11C2;AE4B;1100 1175 11C2; +AE4C;AE4C;1101 1161;AE4C;1101 1161; +AE4D;AE4D;1101 1161 11A8;AE4D;1101 1161 11A8; +AE4E;AE4E;1101 1161 11A9;AE4E;1101 1161 11A9; +AE4F;AE4F;1101 1161 11AA;AE4F;1101 1161 11AA; +AE50;AE50;1101 1161 11AB;AE50;1101 1161 11AB; +AE51;AE51;1101 1161 11AC;AE51;1101 1161 11AC; +AE52;AE52;1101 1161 11AD;AE52;1101 1161 11AD; +AE53;AE53;1101 1161 11AE;AE53;1101 1161 11AE; +AE54;AE54;1101 1161 11AF;AE54;1101 1161 11AF; +AE55;AE55;1101 1161 11B0;AE55;1101 1161 11B0; +AE56;AE56;1101 1161 11B1;AE56;1101 1161 11B1; +AE57;AE57;1101 1161 11B2;AE57;1101 1161 11B2; +AE58;AE58;1101 1161 11B3;AE58;1101 1161 11B3; +AE59;AE59;1101 1161 11B4;AE59;1101 1161 11B4; +AE5A;AE5A;1101 1161 11B5;AE5A;1101 1161 11B5; +AE5B;AE5B;1101 1161 11B6;AE5B;1101 1161 11B6; +AE5C;AE5C;1101 1161 11B7;AE5C;1101 1161 11B7; +AE5D;AE5D;1101 1161 11B8;AE5D;1101 1161 11B8; +AE5E;AE5E;1101 1161 11B9;AE5E;1101 1161 11B9; +AE5F;AE5F;1101 1161 11BA;AE5F;1101 1161 11BA; +AE60;AE60;1101 1161 11BB;AE60;1101 1161 11BB; +AE61;AE61;1101 1161 11BC;AE61;1101 1161 11BC; +AE62;AE62;1101 1161 11BD;AE62;1101 1161 11BD; +AE63;AE63;1101 1161 11BE;AE63;1101 1161 11BE; +AE64;AE64;1101 1161 11BF;AE64;1101 1161 11BF; +AE65;AE65;1101 1161 11C0;AE65;1101 1161 11C0; +AE66;AE66;1101 1161 11C1;AE66;1101 1161 11C1; +AE67;AE67;1101 1161 11C2;AE67;1101 1161 11C2; +AE68;AE68;1101 1162;AE68;1101 1162; +AE69;AE69;1101 1162 11A8;AE69;1101 1162 11A8; +AE6A;AE6A;1101 1162 11A9;AE6A;1101 1162 11A9; +AE6B;AE6B;1101 1162 11AA;AE6B;1101 1162 11AA; +AE6C;AE6C;1101 1162 11AB;AE6C;1101 1162 11AB; +AE6D;AE6D;1101 1162 11AC;AE6D;1101 1162 11AC; +AE6E;AE6E;1101 1162 11AD;AE6E;1101 1162 11AD; +AE6F;AE6F;1101 1162 11AE;AE6F;1101 1162 11AE; +AE70;AE70;1101 1162 11AF;AE70;1101 1162 11AF; +AE71;AE71;1101 1162 11B0;AE71;1101 1162 11B0; +AE72;AE72;1101 1162 11B1;AE72;1101 1162 11B1; +AE73;AE73;1101 1162 11B2;AE73;1101 1162 11B2; +AE74;AE74;1101 1162 11B3;AE74;1101 1162 11B3; +AE75;AE75;1101 1162 11B4;AE75;1101 1162 11B4; +AE76;AE76;1101 1162 11B5;AE76;1101 1162 11B5; +AE77;AE77;1101 1162 11B6;AE77;1101 1162 11B6; +AE78;AE78;1101 1162 11B7;AE78;1101 1162 11B7; +AE79;AE79;1101 1162 11B8;AE79;1101 1162 11B8; +AE7A;AE7A;1101 1162 11B9;AE7A;1101 1162 11B9; +AE7B;AE7B;1101 1162 11BA;AE7B;1101 1162 11BA; +AE7C;AE7C;1101 1162 11BB;AE7C;1101 1162 11BB; +AE7D;AE7D;1101 1162 11BC;AE7D;1101 1162 11BC; +AE7E;AE7E;1101 1162 11BD;AE7E;1101 1162 11BD; +AE7F;AE7F;1101 1162 11BE;AE7F;1101 1162 11BE; +AE80;AE80;1101 1162 11BF;AE80;1101 1162 11BF; +AE81;AE81;1101 1162 11C0;AE81;1101 1162 11C0; +AE82;AE82;1101 1162 11C1;AE82;1101 1162 11C1; +AE83;AE83;1101 1162 11C2;AE83;1101 1162 11C2; +AE84;AE84;1101 1163;AE84;1101 1163; +AE85;AE85;1101 1163 11A8;AE85;1101 1163 11A8; +AE86;AE86;1101 1163 11A9;AE86;1101 1163 11A9; +AE87;AE87;1101 1163 11AA;AE87;1101 1163 11AA; +AE88;AE88;1101 1163 11AB;AE88;1101 1163 11AB; +AE89;AE89;1101 1163 11AC;AE89;1101 1163 11AC; +AE8A;AE8A;1101 1163 11AD;AE8A;1101 1163 11AD; +AE8B;AE8B;1101 1163 11AE;AE8B;1101 1163 11AE; +AE8C;AE8C;1101 1163 11AF;AE8C;1101 1163 11AF; +AE8D;AE8D;1101 1163 11B0;AE8D;1101 1163 11B0; +AE8E;AE8E;1101 1163 11B1;AE8E;1101 1163 11B1; +AE8F;AE8F;1101 1163 11B2;AE8F;1101 1163 11B2; +AE90;AE90;1101 1163 11B3;AE90;1101 1163 11B3; +AE91;AE91;1101 1163 11B4;AE91;1101 1163 11B4; +AE92;AE92;1101 1163 11B5;AE92;1101 1163 11B5; +AE93;AE93;1101 1163 11B6;AE93;1101 1163 11B6; +AE94;AE94;1101 1163 11B7;AE94;1101 1163 11B7; +AE95;AE95;1101 1163 11B8;AE95;1101 1163 11B8; +AE96;AE96;1101 1163 11B9;AE96;1101 1163 11B9; +AE97;AE97;1101 1163 11BA;AE97;1101 1163 11BA; +AE98;AE98;1101 1163 11BB;AE98;1101 1163 11BB; +AE99;AE99;1101 1163 11BC;AE99;1101 1163 11BC; +AE9A;AE9A;1101 1163 11BD;AE9A;1101 1163 11BD; +AE9B;AE9B;1101 1163 11BE;AE9B;1101 1163 11BE; +AE9C;AE9C;1101 1163 11BF;AE9C;1101 1163 11BF; +AE9D;AE9D;1101 1163 11C0;AE9D;1101 1163 11C0; +AE9E;AE9E;1101 1163 11C1;AE9E;1101 1163 11C1; +AE9F;AE9F;1101 1163 11C2;AE9F;1101 1163 11C2; +AEA0;AEA0;1101 1164;AEA0;1101 1164; +AEA1;AEA1;1101 1164 11A8;AEA1;1101 1164 11A8; +AEA2;AEA2;1101 1164 11A9;AEA2;1101 1164 11A9; +AEA3;AEA3;1101 1164 11AA;AEA3;1101 1164 11AA; +AEA4;AEA4;1101 1164 11AB;AEA4;1101 1164 11AB; +AEA5;AEA5;1101 1164 11AC;AEA5;1101 1164 11AC; +AEA6;AEA6;1101 1164 11AD;AEA6;1101 1164 11AD; +AEA7;AEA7;1101 1164 11AE;AEA7;1101 1164 11AE; +AEA8;AEA8;1101 1164 11AF;AEA8;1101 1164 11AF; +AEA9;AEA9;1101 1164 11B0;AEA9;1101 1164 11B0; +AEAA;AEAA;1101 1164 11B1;AEAA;1101 1164 11B1; +AEAB;AEAB;1101 1164 11B2;AEAB;1101 1164 11B2; +AEAC;AEAC;1101 1164 11B3;AEAC;1101 1164 11B3; +AEAD;AEAD;1101 1164 11B4;AEAD;1101 1164 11B4; +AEAE;AEAE;1101 1164 11B5;AEAE;1101 1164 11B5; +AEAF;AEAF;1101 1164 11B6;AEAF;1101 1164 11B6; +AEB0;AEB0;1101 1164 11B7;AEB0;1101 1164 11B7; +AEB1;AEB1;1101 1164 11B8;AEB1;1101 1164 11B8; +AEB2;AEB2;1101 1164 11B9;AEB2;1101 1164 11B9; +AEB3;AEB3;1101 1164 11BA;AEB3;1101 1164 11BA; +AEB4;AEB4;1101 1164 11BB;AEB4;1101 1164 11BB; +AEB5;AEB5;1101 1164 11BC;AEB5;1101 1164 11BC; +AEB6;AEB6;1101 1164 11BD;AEB6;1101 1164 11BD; +AEB7;AEB7;1101 1164 11BE;AEB7;1101 1164 11BE; +AEB8;AEB8;1101 1164 11BF;AEB8;1101 1164 11BF; +AEB9;AEB9;1101 1164 11C0;AEB9;1101 1164 11C0; +AEBA;AEBA;1101 1164 11C1;AEBA;1101 1164 11C1; +AEBB;AEBB;1101 1164 11C2;AEBB;1101 1164 11C2; +AEBC;AEBC;1101 1165;AEBC;1101 1165; +AEBD;AEBD;1101 1165 11A8;AEBD;1101 1165 11A8; +AEBE;AEBE;1101 1165 11A9;AEBE;1101 1165 11A9; +AEBF;AEBF;1101 1165 11AA;AEBF;1101 1165 11AA; +AEC0;AEC0;1101 1165 11AB;AEC0;1101 1165 11AB; +AEC1;AEC1;1101 1165 11AC;AEC1;1101 1165 11AC; +AEC2;AEC2;1101 1165 11AD;AEC2;1101 1165 11AD; +AEC3;AEC3;1101 1165 11AE;AEC3;1101 1165 11AE; +AEC4;AEC4;1101 1165 11AF;AEC4;1101 1165 11AF; +AEC5;AEC5;1101 1165 11B0;AEC5;1101 1165 11B0; +AEC6;AEC6;1101 1165 11B1;AEC6;1101 1165 11B1; +AEC7;AEC7;1101 1165 11B2;AEC7;1101 1165 11B2; +AEC8;AEC8;1101 1165 11B3;AEC8;1101 1165 11B3; +AEC9;AEC9;1101 1165 11B4;AEC9;1101 1165 11B4; +AECA;AECA;1101 1165 11B5;AECA;1101 1165 11B5; +AECB;AECB;1101 1165 11B6;AECB;1101 1165 11B6; +AECC;AECC;1101 1165 11B7;AECC;1101 1165 11B7; +AECD;AECD;1101 1165 11B8;AECD;1101 1165 11B8; +AECE;AECE;1101 1165 11B9;AECE;1101 1165 11B9; +AECF;AECF;1101 1165 11BA;AECF;1101 1165 11BA; +AED0;AED0;1101 1165 11BB;AED0;1101 1165 11BB; +AED1;AED1;1101 1165 11BC;AED1;1101 1165 11BC; +AED2;AED2;1101 1165 11BD;AED2;1101 1165 11BD; +AED3;AED3;1101 1165 11BE;AED3;1101 1165 11BE; +AED4;AED4;1101 1165 11BF;AED4;1101 1165 11BF; +AED5;AED5;1101 1165 11C0;AED5;1101 1165 11C0; +AED6;AED6;1101 1165 11C1;AED6;1101 1165 11C1; +AED7;AED7;1101 1165 11C2;AED7;1101 1165 11C2; +AED8;AED8;1101 1166;AED8;1101 1166; +AED9;AED9;1101 1166 11A8;AED9;1101 1166 11A8; +AEDA;AEDA;1101 1166 11A9;AEDA;1101 1166 11A9; +AEDB;AEDB;1101 1166 11AA;AEDB;1101 1166 11AA; +AEDC;AEDC;1101 1166 11AB;AEDC;1101 1166 11AB; +AEDD;AEDD;1101 1166 11AC;AEDD;1101 1166 11AC; +AEDE;AEDE;1101 1166 11AD;AEDE;1101 1166 11AD; +AEDF;AEDF;1101 1166 11AE;AEDF;1101 1166 11AE; +AEE0;AEE0;1101 1166 11AF;AEE0;1101 1166 11AF; +AEE1;AEE1;1101 1166 11B0;AEE1;1101 1166 11B0; +AEE2;AEE2;1101 1166 11B1;AEE2;1101 1166 11B1; +AEE3;AEE3;1101 1166 11B2;AEE3;1101 1166 11B2; +AEE4;AEE4;1101 1166 11B3;AEE4;1101 1166 11B3; +AEE5;AEE5;1101 1166 11B4;AEE5;1101 1166 11B4; +AEE6;AEE6;1101 1166 11B5;AEE6;1101 1166 11B5; +AEE7;AEE7;1101 1166 11B6;AEE7;1101 1166 11B6; +AEE8;AEE8;1101 1166 11B7;AEE8;1101 1166 11B7; +AEE9;AEE9;1101 1166 11B8;AEE9;1101 1166 11B8; +AEEA;AEEA;1101 1166 11B9;AEEA;1101 1166 11B9; +AEEB;AEEB;1101 1166 11BA;AEEB;1101 1166 11BA; +AEEC;AEEC;1101 1166 11BB;AEEC;1101 1166 11BB; +AEED;AEED;1101 1166 11BC;AEED;1101 1166 11BC; +AEEE;AEEE;1101 1166 11BD;AEEE;1101 1166 11BD; +AEEF;AEEF;1101 1166 11BE;AEEF;1101 1166 11BE; +AEF0;AEF0;1101 1166 11BF;AEF0;1101 1166 11BF; +AEF1;AEF1;1101 1166 11C0;AEF1;1101 1166 11C0; +AEF2;AEF2;1101 1166 11C1;AEF2;1101 1166 11C1; +AEF3;AEF3;1101 1166 11C2;AEF3;1101 1166 11C2; +AEF4;AEF4;1101 1167;AEF4;1101 1167; +AEF5;AEF5;1101 1167 11A8;AEF5;1101 1167 11A8; +AEF6;AEF6;1101 1167 11A9;AEF6;1101 1167 11A9; +AEF7;AEF7;1101 1167 11AA;AEF7;1101 1167 11AA; +AEF8;AEF8;1101 1167 11AB;AEF8;1101 1167 11AB; +AEF9;AEF9;1101 1167 11AC;AEF9;1101 1167 11AC; +AEFA;AEFA;1101 1167 11AD;AEFA;1101 1167 11AD; +AEFB;AEFB;1101 1167 11AE;AEFB;1101 1167 11AE; +AEFC;AEFC;1101 1167 11AF;AEFC;1101 1167 11AF; +AEFD;AEFD;1101 1167 11B0;AEFD;1101 1167 11B0; +AEFE;AEFE;1101 1167 11B1;AEFE;1101 1167 11B1; +AEFF;AEFF;1101 1167 11B2;AEFF;1101 1167 11B2; +AF00;AF00;1101 1167 11B3;AF00;1101 1167 11B3; +AF01;AF01;1101 1167 11B4;AF01;1101 1167 11B4; +AF02;AF02;1101 1167 11B5;AF02;1101 1167 11B5; +AF03;AF03;1101 1167 11B6;AF03;1101 1167 11B6; +AF04;AF04;1101 1167 11B7;AF04;1101 1167 11B7; +AF05;AF05;1101 1167 11B8;AF05;1101 1167 11B8; +AF06;AF06;1101 1167 11B9;AF06;1101 1167 11B9; +AF07;AF07;1101 1167 11BA;AF07;1101 1167 11BA; +AF08;AF08;1101 1167 11BB;AF08;1101 1167 11BB; +AF09;AF09;1101 1167 11BC;AF09;1101 1167 11BC; +AF0A;AF0A;1101 1167 11BD;AF0A;1101 1167 11BD; +AF0B;AF0B;1101 1167 11BE;AF0B;1101 1167 11BE; +AF0C;AF0C;1101 1167 11BF;AF0C;1101 1167 11BF; +AF0D;AF0D;1101 1167 11C0;AF0D;1101 1167 11C0; +AF0E;AF0E;1101 1167 11C1;AF0E;1101 1167 11C1; +AF0F;AF0F;1101 1167 11C2;AF0F;1101 1167 11C2; +AF10;AF10;1101 1168;AF10;1101 1168; +AF11;AF11;1101 1168 11A8;AF11;1101 1168 11A8; +AF12;AF12;1101 1168 11A9;AF12;1101 1168 11A9; +AF13;AF13;1101 1168 11AA;AF13;1101 1168 11AA; +AF14;AF14;1101 1168 11AB;AF14;1101 1168 11AB; +AF15;AF15;1101 1168 11AC;AF15;1101 1168 11AC; +AF16;AF16;1101 1168 11AD;AF16;1101 1168 11AD; +AF17;AF17;1101 1168 11AE;AF17;1101 1168 11AE; +AF18;AF18;1101 1168 11AF;AF18;1101 1168 11AF; +AF19;AF19;1101 1168 11B0;AF19;1101 1168 11B0; +AF1A;AF1A;1101 1168 11B1;AF1A;1101 1168 11B1; +AF1B;AF1B;1101 1168 11B2;AF1B;1101 1168 11B2; +AF1C;AF1C;1101 1168 11B3;AF1C;1101 1168 11B3; +AF1D;AF1D;1101 1168 11B4;AF1D;1101 1168 11B4; +AF1E;AF1E;1101 1168 11B5;AF1E;1101 1168 11B5; +AF1F;AF1F;1101 1168 11B6;AF1F;1101 1168 11B6; +AF20;AF20;1101 1168 11B7;AF20;1101 1168 11B7; +AF21;AF21;1101 1168 11B8;AF21;1101 1168 11B8; +AF22;AF22;1101 1168 11B9;AF22;1101 1168 11B9; +AF23;AF23;1101 1168 11BA;AF23;1101 1168 11BA; +AF24;AF24;1101 1168 11BB;AF24;1101 1168 11BB; +AF25;AF25;1101 1168 11BC;AF25;1101 1168 11BC; +AF26;AF26;1101 1168 11BD;AF26;1101 1168 11BD; +AF27;AF27;1101 1168 11BE;AF27;1101 1168 11BE; +AF28;AF28;1101 1168 11BF;AF28;1101 1168 11BF; +AF29;AF29;1101 1168 11C0;AF29;1101 1168 11C0; +AF2A;AF2A;1101 1168 11C1;AF2A;1101 1168 11C1; +AF2B;AF2B;1101 1168 11C2;AF2B;1101 1168 11C2; +AF2C;AF2C;1101 1169;AF2C;1101 1169; +AF2D;AF2D;1101 1169 11A8;AF2D;1101 1169 11A8; +AF2E;AF2E;1101 1169 11A9;AF2E;1101 1169 11A9; +AF2F;AF2F;1101 1169 11AA;AF2F;1101 1169 11AA; +AF30;AF30;1101 1169 11AB;AF30;1101 1169 11AB; +AF31;AF31;1101 1169 11AC;AF31;1101 1169 11AC; +AF32;AF32;1101 1169 11AD;AF32;1101 1169 11AD; +AF33;AF33;1101 1169 11AE;AF33;1101 1169 11AE; +AF34;AF34;1101 1169 11AF;AF34;1101 1169 11AF; +AF35;AF35;1101 1169 11B0;AF35;1101 1169 11B0; +AF36;AF36;1101 1169 11B1;AF36;1101 1169 11B1; +AF37;AF37;1101 1169 11B2;AF37;1101 1169 11B2; +AF38;AF38;1101 1169 11B3;AF38;1101 1169 11B3; +AF39;AF39;1101 1169 11B4;AF39;1101 1169 11B4; +AF3A;AF3A;1101 1169 11B5;AF3A;1101 1169 11B5; +AF3B;AF3B;1101 1169 11B6;AF3B;1101 1169 11B6; +AF3C;AF3C;1101 1169 11B7;AF3C;1101 1169 11B7; +AF3D;AF3D;1101 1169 11B8;AF3D;1101 1169 11B8; +AF3E;AF3E;1101 1169 11B9;AF3E;1101 1169 11B9; +AF3F;AF3F;1101 1169 11BA;AF3F;1101 1169 11BA; +AF40;AF40;1101 1169 11BB;AF40;1101 1169 11BB; +AF41;AF41;1101 1169 11BC;AF41;1101 1169 11BC; +AF42;AF42;1101 1169 11BD;AF42;1101 1169 11BD; +AF43;AF43;1101 1169 11BE;AF43;1101 1169 11BE; +AF44;AF44;1101 1169 11BF;AF44;1101 1169 11BF; +AF45;AF45;1101 1169 11C0;AF45;1101 1169 11C0; +AF46;AF46;1101 1169 11C1;AF46;1101 1169 11C1; +AF47;AF47;1101 1169 11C2;AF47;1101 1169 11C2; +AF48;AF48;1101 116A;AF48;1101 116A; +AF49;AF49;1101 116A 11A8;AF49;1101 116A 11A8; +AF4A;AF4A;1101 116A 11A9;AF4A;1101 116A 11A9; +AF4B;AF4B;1101 116A 11AA;AF4B;1101 116A 11AA; +AF4C;AF4C;1101 116A 11AB;AF4C;1101 116A 11AB; +AF4D;AF4D;1101 116A 11AC;AF4D;1101 116A 11AC; +AF4E;AF4E;1101 116A 11AD;AF4E;1101 116A 11AD; +AF4F;AF4F;1101 116A 11AE;AF4F;1101 116A 11AE; +AF50;AF50;1101 116A 11AF;AF50;1101 116A 11AF; +AF51;AF51;1101 116A 11B0;AF51;1101 116A 11B0; +AF52;AF52;1101 116A 11B1;AF52;1101 116A 11B1; +AF53;AF53;1101 116A 11B2;AF53;1101 116A 11B2; +AF54;AF54;1101 116A 11B3;AF54;1101 116A 11B3; +AF55;AF55;1101 116A 11B4;AF55;1101 116A 11B4; +AF56;AF56;1101 116A 11B5;AF56;1101 116A 11B5; +AF57;AF57;1101 116A 11B6;AF57;1101 116A 11B6; +AF58;AF58;1101 116A 11B7;AF58;1101 116A 11B7; +AF59;AF59;1101 116A 11B8;AF59;1101 116A 11B8; +AF5A;AF5A;1101 116A 11B9;AF5A;1101 116A 11B9; +AF5B;AF5B;1101 116A 11BA;AF5B;1101 116A 11BA; +AF5C;AF5C;1101 116A 11BB;AF5C;1101 116A 11BB; +AF5D;AF5D;1101 116A 11BC;AF5D;1101 116A 11BC; +AF5E;AF5E;1101 116A 11BD;AF5E;1101 116A 11BD; +AF5F;AF5F;1101 116A 11BE;AF5F;1101 116A 11BE; +AF60;AF60;1101 116A 11BF;AF60;1101 116A 11BF; +AF61;AF61;1101 116A 11C0;AF61;1101 116A 11C0; +AF62;AF62;1101 116A 11C1;AF62;1101 116A 11C1; +AF63;AF63;1101 116A 11C2;AF63;1101 116A 11C2; +AF64;AF64;1101 116B;AF64;1101 116B; +AF65;AF65;1101 116B 11A8;AF65;1101 116B 11A8; +AF66;AF66;1101 116B 11A9;AF66;1101 116B 11A9; +AF67;AF67;1101 116B 11AA;AF67;1101 116B 11AA; +AF68;AF68;1101 116B 11AB;AF68;1101 116B 11AB; +AF69;AF69;1101 116B 11AC;AF69;1101 116B 11AC; +AF6A;AF6A;1101 116B 11AD;AF6A;1101 116B 11AD; +AF6B;AF6B;1101 116B 11AE;AF6B;1101 116B 11AE; +AF6C;AF6C;1101 116B 11AF;AF6C;1101 116B 11AF; +AF6D;AF6D;1101 116B 11B0;AF6D;1101 116B 11B0; +AF6E;AF6E;1101 116B 11B1;AF6E;1101 116B 11B1; +AF6F;AF6F;1101 116B 11B2;AF6F;1101 116B 11B2; +AF70;AF70;1101 116B 11B3;AF70;1101 116B 11B3; +AF71;AF71;1101 116B 11B4;AF71;1101 116B 11B4; +AF72;AF72;1101 116B 11B5;AF72;1101 116B 11B5; +AF73;AF73;1101 116B 11B6;AF73;1101 116B 11B6; +AF74;AF74;1101 116B 11B7;AF74;1101 116B 11B7; +AF75;AF75;1101 116B 11B8;AF75;1101 116B 11B8; +AF76;AF76;1101 116B 11B9;AF76;1101 116B 11B9; +AF77;AF77;1101 116B 11BA;AF77;1101 116B 11BA; +AF78;AF78;1101 116B 11BB;AF78;1101 116B 11BB; +AF79;AF79;1101 116B 11BC;AF79;1101 116B 11BC; +AF7A;AF7A;1101 116B 11BD;AF7A;1101 116B 11BD; +AF7B;AF7B;1101 116B 11BE;AF7B;1101 116B 11BE; +AF7C;AF7C;1101 116B 11BF;AF7C;1101 116B 11BF; +AF7D;AF7D;1101 116B 11C0;AF7D;1101 116B 11C0; +AF7E;AF7E;1101 116B 11C1;AF7E;1101 116B 11C1; +AF7F;AF7F;1101 116B 11C2;AF7F;1101 116B 11C2; +AF80;AF80;1101 116C;AF80;1101 116C; +AF81;AF81;1101 116C 11A8;AF81;1101 116C 11A8; +AF82;AF82;1101 116C 11A9;AF82;1101 116C 11A9; +AF83;AF83;1101 116C 11AA;AF83;1101 116C 11AA; +AF84;AF84;1101 116C 11AB;AF84;1101 116C 11AB; +AF85;AF85;1101 116C 11AC;AF85;1101 116C 11AC; +AF86;AF86;1101 116C 11AD;AF86;1101 116C 11AD; +AF87;AF87;1101 116C 11AE;AF87;1101 116C 11AE; +AF88;AF88;1101 116C 11AF;AF88;1101 116C 11AF; +AF89;AF89;1101 116C 11B0;AF89;1101 116C 11B0; +AF8A;AF8A;1101 116C 11B1;AF8A;1101 116C 11B1; +AF8B;AF8B;1101 116C 11B2;AF8B;1101 116C 11B2; +AF8C;AF8C;1101 116C 11B3;AF8C;1101 116C 11B3; +AF8D;AF8D;1101 116C 11B4;AF8D;1101 116C 11B4; +AF8E;AF8E;1101 116C 11B5;AF8E;1101 116C 11B5; +AF8F;AF8F;1101 116C 11B6;AF8F;1101 116C 11B6; +AF90;AF90;1101 116C 11B7;AF90;1101 116C 11B7; +AF91;AF91;1101 116C 11B8;AF91;1101 116C 11B8; +AF92;AF92;1101 116C 11B9;AF92;1101 116C 11B9; +AF93;AF93;1101 116C 11BA;AF93;1101 116C 11BA; +AF94;AF94;1101 116C 11BB;AF94;1101 116C 11BB; +AF95;AF95;1101 116C 11BC;AF95;1101 116C 11BC; +AF96;AF96;1101 116C 11BD;AF96;1101 116C 11BD; +AF97;AF97;1101 116C 11BE;AF97;1101 116C 11BE; +AF98;AF98;1101 116C 11BF;AF98;1101 116C 11BF; +AF99;AF99;1101 116C 11C0;AF99;1101 116C 11C0; +AF9A;AF9A;1101 116C 11C1;AF9A;1101 116C 11C1; +AF9B;AF9B;1101 116C 11C2;AF9B;1101 116C 11C2; +AF9C;AF9C;1101 116D;AF9C;1101 116D; +AF9D;AF9D;1101 116D 11A8;AF9D;1101 116D 11A8; +AF9E;AF9E;1101 116D 11A9;AF9E;1101 116D 11A9; +AF9F;AF9F;1101 116D 11AA;AF9F;1101 116D 11AA; +AFA0;AFA0;1101 116D 11AB;AFA0;1101 116D 11AB; +AFA1;AFA1;1101 116D 11AC;AFA1;1101 116D 11AC; +AFA2;AFA2;1101 116D 11AD;AFA2;1101 116D 11AD; +AFA3;AFA3;1101 116D 11AE;AFA3;1101 116D 11AE; +AFA4;AFA4;1101 116D 11AF;AFA4;1101 116D 11AF; +AFA5;AFA5;1101 116D 11B0;AFA5;1101 116D 11B0; +AFA6;AFA6;1101 116D 11B1;AFA6;1101 116D 11B1; +AFA7;AFA7;1101 116D 11B2;AFA7;1101 116D 11B2; +AFA8;AFA8;1101 116D 11B3;AFA8;1101 116D 11B3; +AFA9;AFA9;1101 116D 11B4;AFA9;1101 116D 11B4; +AFAA;AFAA;1101 116D 11B5;AFAA;1101 116D 11B5; +AFAB;AFAB;1101 116D 11B6;AFAB;1101 116D 11B6; +AFAC;AFAC;1101 116D 11B7;AFAC;1101 116D 11B7; +AFAD;AFAD;1101 116D 11B8;AFAD;1101 116D 11B8; +AFAE;AFAE;1101 116D 11B9;AFAE;1101 116D 11B9; +AFAF;AFAF;1101 116D 11BA;AFAF;1101 116D 11BA; +AFB0;AFB0;1101 116D 11BB;AFB0;1101 116D 11BB; +AFB1;AFB1;1101 116D 11BC;AFB1;1101 116D 11BC; +AFB2;AFB2;1101 116D 11BD;AFB2;1101 116D 11BD; +AFB3;AFB3;1101 116D 11BE;AFB3;1101 116D 11BE; +AFB4;AFB4;1101 116D 11BF;AFB4;1101 116D 11BF; +AFB5;AFB5;1101 116D 11C0;AFB5;1101 116D 11C0; +AFB6;AFB6;1101 116D 11C1;AFB6;1101 116D 11C1; +AFB7;AFB7;1101 116D 11C2;AFB7;1101 116D 11C2; +AFB8;AFB8;1101 116E;AFB8;1101 116E; +AFB9;AFB9;1101 116E 11A8;AFB9;1101 116E 11A8; +AFBA;AFBA;1101 116E 11A9;AFBA;1101 116E 11A9; +AFBB;AFBB;1101 116E 11AA;AFBB;1101 116E 11AA; +AFBC;AFBC;1101 116E 11AB;AFBC;1101 116E 11AB; +AFBD;AFBD;1101 116E 11AC;AFBD;1101 116E 11AC; +AFBE;AFBE;1101 116E 11AD;AFBE;1101 116E 11AD; +AFBF;AFBF;1101 116E 11AE;AFBF;1101 116E 11AE; +AFC0;AFC0;1101 116E 11AF;AFC0;1101 116E 11AF; +AFC1;AFC1;1101 116E 11B0;AFC1;1101 116E 11B0; +AFC2;AFC2;1101 116E 11B1;AFC2;1101 116E 11B1; +AFC3;AFC3;1101 116E 11B2;AFC3;1101 116E 11B2; +AFC4;AFC4;1101 116E 11B3;AFC4;1101 116E 11B3; +AFC5;AFC5;1101 116E 11B4;AFC5;1101 116E 11B4; +AFC6;AFC6;1101 116E 11B5;AFC6;1101 116E 11B5; +AFC7;AFC7;1101 116E 11B6;AFC7;1101 116E 11B6; +AFC8;AFC8;1101 116E 11B7;AFC8;1101 116E 11B7; +AFC9;AFC9;1101 116E 11B8;AFC9;1101 116E 11B8; +AFCA;AFCA;1101 116E 11B9;AFCA;1101 116E 11B9; +AFCB;AFCB;1101 116E 11BA;AFCB;1101 116E 11BA; +AFCC;AFCC;1101 116E 11BB;AFCC;1101 116E 11BB; +AFCD;AFCD;1101 116E 11BC;AFCD;1101 116E 11BC; +AFCE;AFCE;1101 116E 11BD;AFCE;1101 116E 11BD; +AFCF;AFCF;1101 116E 11BE;AFCF;1101 116E 11BE; +AFD0;AFD0;1101 116E 11BF;AFD0;1101 116E 11BF; +AFD1;AFD1;1101 116E 11C0;AFD1;1101 116E 11C0; +AFD2;AFD2;1101 116E 11C1;AFD2;1101 116E 11C1; +AFD3;AFD3;1101 116E 11C2;AFD3;1101 116E 11C2; +AFD4;AFD4;1101 116F;AFD4;1101 116F; +AFD5;AFD5;1101 116F 11A8;AFD5;1101 116F 11A8; +AFD6;AFD6;1101 116F 11A9;AFD6;1101 116F 11A9; +AFD7;AFD7;1101 116F 11AA;AFD7;1101 116F 11AA; +AFD8;AFD8;1101 116F 11AB;AFD8;1101 116F 11AB; +AFD9;AFD9;1101 116F 11AC;AFD9;1101 116F 11AC; +AFDA;AFDA;1101 116F 11AD;AFDA;1101 116F 11AD; +AFDB;AFDB;1101 116F 11AE;AFDB;1101 116F 11AE; +AFDC;AFDC;1101 116F 11AF;AFDC;1101 116F 11AF; +AFDD;AFDD;1101 116F 11B0;AFDD;1101 116F 11B0; +AFDE;AFDE;1101 116F 11B1;AFDE;1101 116F 11B1; +AFDF;AFDF;1101 116F 11B2;AFDF;1101 116F 11B2; +AFE0;AFE0;1101 116F 11B3;AFE0;1101 116F 11B3; +AFE1;AFE1;1101 116F 11B4;AFE1;1101 116F 11B4; +AFE2;AFE2;1101 116F 11B5;AFE2;1101 116F 11B5; +AFE3;AFE3;1101 116F 11B6;AFE3;1101 116F 11B6; +AFE4;AFE4;1101 116F 11B7;AFE4;1101 116F 11B7; +AFE5;AFE5;1101 116F 11B8;AFE5;1101 116F 11B8; +AFE6;AFE6;1101 116F 11B9;AFE6;1101 116F 11B9; +AFE7;AFE7;1101 116F 11BA;AFE7;1101 116F 11BA; +AFE8;AFE8;1101 116F 11BB;AFE8;1101 116F 11BB; +AFE9;AFE9;1101 116F 11BC;AFE9;1101 116F 11BC; +AFEA;AFEA;1101 116F 11BD;AFEA;1101 116F 11BD; +AFEB;AFEB;1101 116F 11BE;AFEB;1101 116F 11BE; +AFEC;AFEC;1101 116F 11BF;AFEC;1101 116F 11BF; +AFED;AFED;1101 116F 11C0;AFED;1101 116F 11C0; +AFEE;AFEE;1101 116F 11C1;AFEE;1101 116F 11C1; +AFEF;AFEF;1101 116F 11C2;AFEF;1101 116F 11C2; +AFF0;AFF0;1101 1170;AFF0;1101 1170; +AFF1;AFF1;1101 1170 11A8;AFF1;1101 1170 11A8; +AFF2;AFF2;1101 1170 11A9;AFF2;1101 1170 11A9; +AFF3;AFF3;1101 1170 11AA;AFF3;1101 1170 11AA; +AFF4;AFF4;1101 1170 11AB;AFF4;1101 1170 11AB; +AFF5;AFF5;1101 1170 11AC;AFF5;1101 1170 11AC; +AFF6;AFF6;1101 1170 11AD;AFF6;1101 1170 11AD; +AFF7;AFF7;1101 1170 11AE;AFF7;1101 1170 11AE; +AFF8;AFF8;1101 1170 11AF;AFF8;1101 1170 11AF; +AFF9;AFF9;1101 1170 11B0;AFF9;1101 1170 11B0; +AFFA;AFFA;1101 1170 11B1;AFFA;1101 1170 11B1; +AFFB;AFFB;1101 1170 11B2;AFFB;1101 1170 11B2; +AFFC;AFFC;1101 1170 11B3;AFFC;1101 1170 11B3; +AFFD;AFFD;1101 1170 11B4;AFFD;1101 1170 11B4; +AFFE;AFFE;1101 1170 11B5;AFFE;1101 1170 11B5; +AFFF;AFFF;1101 1170 11B6;AFFF;1101 1170 11B6; +B000;B000;1101 1170 11B7;B000;1101 1170 11B7; +B001;B001;1101 1170 11B8;B001;1101 1170 11B8; +B002;B002;1101 1170 11B9;B002;1101 1170 11B9; +B003;B003;1101 1170 11BA;B003;1101 1170 11BA; +B004;B004;1101 1170 11BB;B004;1101 1170 11BB; +B005;B005;1101 1170 11BC;B005;1101 1170 11BC; +B006;B006;1101 1170 11BD;B006;1101 1170 11BD; +B007;B007;1101 1170 11BE;B007;1101 1170 11BE; +B008;B008;1101 1170 11BF;B008;1101 1170 11BF; +B009;B009;1101 1170 11C0;B009;1101 1170 11C0; +B00A;B00A;1101 1170 11C1;B00A;1101 1170 11C1; +B00B;B00B;1101 1170 11C2;B00B;1101 1170 11C2; +B00C;B00C;1101 1171;B00C;1101 1171; +B00D;B00D;1101 1171 11A8;B00D;1101 1171 11A8; +B00E;B00E;1101 1171 11A9;B00E;1101 1171 11A9; +B00F;B00F;1101 1171 11AA;B00F;1101 1171 11AA; +B010;B010;1101 1171 11AB;B010;1101 1171 11AB; +B011;B011;1101 1171 11AC;B011;1101 1171 11AC; +B012;B012;1101 1171 11AD;B012;1101 1171 11AD; +B013;B013;1101 1171 11AE;B013;1101 1171 11AE; +B014;B014;1101 1171 11AF;B014;1101 1171 11AF; +B015;B015;1101 1171 11B0;B015;1101 1171 11B0; +B016;B016;1101 1171 11B1;B016;1101 1171 11B1; +B017;B017;1101 1171 11B2;B017;1101 1171 11B2; +B018;B018;1101 1171 11B3;B018;1101 1171 11B3; +B019;B019;1101 1171 11B4;B019;1101 1171 11B4; +B01A;B01A;1101 1171 11B5;B01A;1101 1171 11B5; +B01B;B01B;1101 1171 11B6;B01B;1101 1171 11B6; +B01C;B01C;1101 1171 11B7;B01C;1101 1171 11B7; +B01D;B01D;1101 1171 11B8;B01D;1101 1171 11B8; +B01E;B01E;1101 1171 11B9;B01E;1101 1171 11B9; +B01F;B01F;1101 1171 11BA;B01F;1101 1171 11BA; +B020;B020;1101 1171 11BB;B020;1101 1171 11BB; +B021;B021;1101 1171 11BC;B021;1101 1171 11BC; +B022;B022;1101 1171 11BD;B022;1101 1171 11BD; +B023;B023;1101 1171 11BE;B023;1101 1171 11BE; +B024;B024;1101 1171 11BF;B024;1101 1171 11BF; +B025;B025;1101 1171 11C0;B025;1101 1171 11C0; +B026;B026;1101 1171 11C1;B026;1101 1171 11C1; +B027;B027;1101 1171 11C2;B027;1101 1171 11C2; +B028;B028;1101 1172;B028;1101 1172; +B029;B029;1101 1172 11A8;B029;1101 1172 11A8; +B02A;B02A;1101 1172 11A9;B02A;1101 1172 11A9; +B02B;B02B;1101 1172 11AA;B02B;1101 1172 11AA; +B02C;B02C;1101 1172 11AB;B02C;1101 1172 11AB; +B02D;B02D;1101 1172 11AC;B02D;1101 1172 11AC; +B02E;B02E;1101 1172 11AD;B02E;1101 1172 11AD; +B02F;B02F;1101 1172 11AE;B02F;1101 1172 11AE; +B030;B030;1101 1172 11AF;B030;1101 1172 11AF; +B031;B031;1101 1172 11B0;B031;1101 1172 11B0; +B032;B032;1101 1172 11B1;B032;1101 1172 11B1; +B033;B033;1101 1172 11B2;B033;1101 1172 11B2; +B034;B034;1101 1172 11B3;B034;1101 1172 11B3; +B035;B035;1101 1172 11B4;B035;1101 1172 11B4; +B036;B036;1101 1172 11B5;B036;1101 1172 11B5; +B037;B037;1101 1172 11B6;B037;1101 1172 11B6; +B038;B038;1101 1172 11B7;B038;1101 1172 11B7; +B039;B039;1101 1172 11B8;B039;1101 1172 11B8; +B03A;B03A;1101 1172 11B9;B03A;1101 1172 11B9; +B03B;B03B;1101 1172 11BA;B03B;1101 1172 11BA; +B03C;B03C;1101 1172 11BB;B03C;1101 1172 11BB; +B03D;B03D;1101 1172 11BC;B03D;1101 1172 11BC; +B03E;B03E;1101 1172 11BD;B03E;1101 1172 11BD; +B03F;B03F;1101 1172 11BE;B03F;1101 1172 11BE; +B040;B040;1101 1172 11BF;B040;1101 1172 11BF; +B041;B041;1101 1172 11C0;B041;1101 1172 11C0; +B042;B042;1101 1172 11C1;B042;1101 1172 11C1; +B043;B043;1101 1172 11C2;B043;1101 1172 11C2; +B044;B044;1101 1173;B044;1101 1173; +B045;B045;1101 1173 11A8;B045;1101 1173 11A8; +B046;B046;1101 1173 11A9;B046;1101 1173 11A9; +B047;B047;1101 1173 11AA;B047;1101 1173 11AA; +B048;B048;1101 1173 11AB;B048;1101 1173 11AB; +B049;B049;1101 1173 11AC;B049;1101 1173 11AC; +B04A;B04A;1101 1173 11AD;B04A;1101 1173 11AD; +B04B;B04B;1101 1173 11AE;B04B;1101 1173 11AE; +B04C;B04C;1101 1173 11AF;B04C;1101 1173 11AF; +B04D;B04D;1101 1173 11B0;B04D;1101 1173 11B0; +B04E;B04E;1101 1173 11B1;B04E;1101 1173 11B1; +B04F;B04F;1101 1173 11B2;B04F;1101 1173 11B2; +B050;B050;1101 1173 11B3;B050;1101 1173 11B3; +B051;B051;1101 1173 11B4;B051;1101 1173 11B4; +B052;B052;1101 1173 11B5;B052;1101 1173 11B5; +B053;B053;1101 1173 11B6;B053;1101 1173 11B6; +B054;B054;1101 1173 11B7;B054;1101 1173 11B7; +B055;B055;1101 1173 11B8;B055;1101 1173 11B8; +B056;B056;1101 1173 11B9;B056;1101 1173 11B9; +B057;B057;1101 1173 11BA;B057;1101 1173 11BA; +B058;B058;1101 1173 11BB;B058;1101 1173 11BB; +B059;B059;1101 1173 11BC;B059;1101 1173 11BC; +B05A;B05A;1101 1173 11BD;B05A;1101 1173 11BD; +B05B;B05B;1101 1173 11BE;B05B;1101 1173 11BE; +B05C;B05C;1101 1173 11BF;B05C;1101 1173 11BF; +B05D;B05D;1101 1173 11C0;B05D;1101 1173 11C0; +B05E;B05E;1101 1173 11C1;B05E;1101 1173 11C1; +B05F;B05F;1101 1173 11C2;B05F;1101 1173 11C2; +B060;B060;1101 1174;B060;1101 1174; +B061;B061;1101 1174 11A8;B061;1101 1174 11A8; +B062;B062;1101 1174 11A9;B062;1101 1174 11A9; +B063;B063;1101 1174 11AA;B063;1101 1174 11AA; +B064;B064;1101 1174 11AB;B064;1101 1174 11AB; +B065;B065;1101 1174 11AC;B065;1101 1174 11AC; +B066;B066;1101 1174 11AD;B066;1101 1174 11AD; +B067;B067;1101 1174 11AE;B067;1101 1174 11AE; +B068;B068;1101 1174 11AF;B068;1101 1174 11AF; +B069;B069;1101 1174 11B0;B069;1101 1174 11B0; +B06A;B06A;1101 1174 11B1;B06A;1101 1174 11B1; +B06B;B06B;1101 1174 11B2;B06B;1101 1174 11B2; +B06C;B06C;1101 1174 11B3;B06C;1101 1174 11B3; +B06D;B06D;1101 1174 11B4;B06D;1101 1174 11B4; +B06E;B06E;1101 1174 11B5;B06E;1101 1174 11B5; +B06F;B06F;1101 1174 11B6;B06F;1101 1174 11B6; +B070;B070;1101 1174 11B7;B070;1101 1174 11B7; +B071;B071;1101 1174 11B8;B071;1101 1174 11B8; +B072;B072;1101 1174 11B9;B072;1101 1174 11B9; +B073;B073;1101 1174 11BA;B073;1101 1174 11BA; +B074;B074;1101 1174 11BB;B074;1101 1174 11BB; +B075;B075;1101 1174 11BC;B075;1101 1174 11BC; +B076;B076;1101 1174 11BD;B076;1101 1174 11BD; +B077;B077;1101 1174 11BE;B077;1101 1174 11BE; +B078;B078;1101 1174 11BF;B078;1101 1174 11BF; +B079;B079;1101 1174 11C0;B079;1101 1174 11C0; +B07A;B07A;1101 1174 11C1;B07A;1101 1174 11C1; +B07B;B07B;1101 1174 11C2;B07B;1101 1174 11C2; +B07C;B07C;1101 1175;B07C;1101 1175; +B07D;B07D;1101 1175 11A8;B07D;1101 1175 11A8; +B07E;B07E;1101 1175 11A9;B07E;1101 1175 11A9; +B07F;B07F;1101 1175 11AA;B07F;1101 1175 11AA; +B080;B080;1101 1175 11AB;B080;1101 1175 11AB; +B081;B081;1101 1175 11AC;B081;1101 1175 11AC; +B082;B082;1101 1175 11AD;B082;1101 1175 11AD; +B083;B083;1101 1175 11AE;B083;1101 1175 11AE; +B084;B084;1101 1175 11AF;B084;1101 1175 11AF; +B085;B085;1101 1175 11B0;B085;1101 1175 11B0; +B086;B086;1101 1175 11B1;B086;1101 1175 11B1; +B087;B087;1101 1175 11B2;B087;1101 1175 11B2; +B088;B088;1101 1175 11B3;B088;1101 1175 11B3; +B089;B089;1101 1175 11B4;B089;1101 1175 11B4; +B08A;B08A;1101 1175 11B5;B08A;1101 1175 11B5; +B08B;B08B;1101 1175 11B6;B08B;1101 1175 11B6; +B08C;B08C;1101 1175 11B7;B08C;1101 1175 11B7; +B08D;B08D;1101 1175 11B8;B08D;1101 1175 11B8; +B08E;B08E;1101 1175 11B9;B08E;1101 1175 11B9; +B08F;B08F;1101 1175 11BA;B08F;1101 1175 11BA; +B090;B090;1101 1175 11BB;B090;1101 1175 11BB; +B091;B091;1101 1175 11BC;B091;1101 1175 11BC; +B092;B092;1101 1175 11BD;B092;1101 1175 11BD; +B093;B093;1101 1175 11BE;B093;1101 1175 11BE; +B094;B094;1101 1175 11BF;B094;1101 1175 11BF; +B095;B095;1101 1175 11C0;B095;1101 1175 11C0; +B096;B096;1101 1175 11C1;B096;1101 1175 11C1; +B097;B097;1101 1175 11C2;B097;1101 1175 11C2; +B098;B098;1102 1161;B098;1102 1161; +B099;B099;1102 1161 11A8;B099;1102 1161 11A8; +B09A;B09A;1102 1161 11A9;B09A;1102 1161 11A9; +B09B;B09B;1102 1161 11AA;B09B;1102 1161 11AA; +B09C;B09C;1102 1161 11AB;B09C;1102 1161 11AB; +B09D;B09D;1102 1161 11AC;B09D;1102 1161 11AC; +B09E;B09E;1102 1161 11AD;B09E;1102 1161 11AD; +B09F;B09F;1102 1161 11AE;B09F;1102 1161 11AE; +B0A0;B0A0;1102 1161 11AF;B0A0;1102 1161 11AF; +B0A1;B0A1;1102 1161 11B0;B0A1;1102 1161 11B0; +B0A2;B0A2;1102 1161 11B1;B0A2;1102 1161 11B1; +B0A3;B0A3;1102 1161 11B2;B0A3;1102 1161 11B2; +B0A4;B0A4;1102 1161 11B3;B0A4;1102 1161 11B3; +B0A5;B0A5;1102 1161 11B4;B0A5;1102 1161 11B4; +B0A6;B0A6;1102 1161 11B5;B0A6;1102 1161 11B5; +B0A7;B0A7;1102 1161 11B6;B0A7;1102 1161 11B6; +B0A8;B0A8;1102 1161 11B7;B0A8;1102 1161 11B7; +B0A9;B0A9;1102 1161 11B8;B0A9;1102 1161 11B8; +B0AA;B0AA;1102 1161 11B9;B0AA;1102 1161 11B9; +B0AB;B0AB;1102 1161 11BA;B0AB;1102 1161 11BA; +B0AC;B0AC;1102 1161 11BB;B0AC;1102 1161 11BB; +B0AD;B0AD;1102 1161 11BC;B0AD;1102 1161 11BC; +B0AE;B0AE;1102 1161 11BD;B0AE;1102 1161 11BD; +B0AF;B0AF;1102 1161 11BE;B0AF;1102 1161 11BE; +B0B0;B0B0;1102 1161 11BF;B0B0;1102 1161 11BF; +B0B1;B0B1;1102 1161 11C0;B0B1;1102 1161 11C0; +B0B2;B0B2;1102 1161 11C1;B0B2;1102 1161 11C1; +B0B3;B0B3;1102 1161 11C2;B0B3;1102 1161 11C2; +B0B4;B0B4;1102 1162;B0B4;1102 1162; +B0B5;B0B5;1102 1162 11A8;B0B5;1102 1162 11A8; +B0B6;B0B6;1102 1162 11A9;B0B6;1102 1162 11A9; +B0B7;B0B7;1102 1162 11AA;B0B7;1102 1162 11AA; +B0B8;B0B8;1102 1162 11AB;B0B8;1102 1162 11AB; +B0B9;B0B9;1102 1162 11AC;B0B9;1102 1162 11AC; +B0BA;B0BA;1102 1162 11AD;B0BA;1102 1162 11AD; +B0BB;B0BB;1102 1162 11AE;B0BB;1102 1162 11AE; +B0BC;B0BC;1102 1162 11AF;B0BC;1102 1162 11AF; +B0BD;B0BD;1102 1162 11B0;B0BD;1102 1162 11B0; +B0BE;B0BE;1102 1162 11B1;B0BE;1102 1162 11B1; +B0BF;B0BF;1102 1162 11B2;B0BF;1102 1162 11B2; +B0C0;B0C0;1102 1162 11B3;B0C0;1102 1162 11B3; +B0C1;B0C1;1102 1162 11B4;B0C1;1102 1162 11B4; +B0C2;B0C2;1102 1162 11B5;B0C2;1102 1162 11B5; +B0C3;B0C3;1102 1162 11B6;B0C3;1102 1162 11B6; +B0C4;B0C4;1102 1162 11B7;B0C4;1102 1162 11B7; +B0C5;B0C5;1102 1162 11B8;B0C5;1102 1162 11B8; +B0C6;B0C6;1102 1162 11B9;B0C6;1102 1162 11B9; +B0C7;B0C7;1102 1162 11BA;B0C7;1102 1162 11BA; +B0C8;B0C8;1102 1162 11BB;B0C8;1102 1162 11BB; +B0C9;B0C9;1102 1162 11BC;B0C9;1102 1162 11BC; +B0CA;B0CA;1102 1162 11BD;B0CA;1102 1162 11BD; +B0CB;B0CB;1102 1162 11BE;B0CB;1102 1162 11BE; +B0CC;B0CC;1102 1162 11BF;B0CC;1102 1162 11BF; +B0CD;B0CD;1102 1162 11C0;B0CD;1102 1162 11C0; +B0CE;B0CE;1102 1162 11C1;B0CE;1102 1162 11C1; +B0CF;B0CF;1102 1162 11C2;B0CF;1102 1162 11C2; +B0D0;B0D0;1102 1163;B0D0;1102 1163; +B0D1;B0D1;1102 1163 11A8;B0D1;1102 1163 11A8; +B0D2;B0D2;1102 1163 11A9;B0D2;1102 1163 11A9; +B0D3;B0D3;1102 1163 11AA;B0D3;1102 1163 11AA; +B0D4;B0D4;1102 1163 11AB;B0D4;1102 1163 11AB; +B0D5;B0D5;1102 1163 11AC;B0D5;1102 1163 11AC; +B0D6;B0D6;1102 1163 11AD;B0D6;1102 1163 11AD; +B0D7;B0D7;1102 1163 11AE;B0D7;1102 1163 11AE; +B0D8;B0D8;1102 1163 11AF;B0D8;1102 1163 11AF; +B0D9;B0D9;1102 1163 11B0;B0D9;1102 1163 11B0; +B0DA;B0DA;1102 1163 11B1;B0DA;1102 1163 11B1; +B0DB;B0DB;1102 1163 11B2;B0DB;1102 1163 11B2; +B0DC;B0DC;1102 1163 11B3;B0DC;1102 1163 11B3; +B0DD;B0DD;1102 1163 11B4;B0DD;1102 1163 11B4; +B0DE;B0DE;1102 1163 11B5;B0DE;1102 1163 11B5; +B0DF;B0DF;1102 1163 11B6;B0DF;1102 1163 11B6; +B0E0;B0E0;1102 1163 11B7;B0E0;1102 1163 11B7; +B0E1;B0E1;1102 1163 11B8;B0E1;1102 1163 11B8; +B0E2;B0E2;1102 1163 11B9;B0E2;1102 1163 11B9; +B0E3;B0E3;1102 1163 11BA;B0E3;1102 1163 11BA; +B0E4;B0E4;1102 1163 11BB;B0E4;1102 1163 11BB; +B0E5;B0E5;1102 1163 11BC;B0E5;1102 1163 11BC; +B0E6;B0E6;1102 1163 11BD;B0E6;1102 1163 11BD; +B0E7;B0E7;1102 1163 11BE;B0E7;1102 1163 11BE; +B0E8;B0E8;1102 1163 11BF;B0E8;1102 1163 11BF; +B0E9;B0E9;1102 1163 11C0;B0E9;1102 1163 11C0; +B0EA;B0EA;1102 1163 11C1;B0EA;1102 1163 11C1; +B0EB;B0EB;1102 1163 11C2;B0EB;1102 1163 11C2; +B0EC;B0EC;1102 1164;B0EC;1102 1164; +B0ED;B0ED;1102 1164 11A8;B0ED;1102 1164 11A8; +B0EE;B0EE;1102 1164 11A9;B0EE;1102 1164 11A9; +B0EF;B0EF;1102 1164 11AA;B0EF;1102 1164 11AA; +B0F0;B0F0;1102 1164 11AB;B0F0;1102 1164 11AB; +B0F1;B0F1;1102 1164 11AC;B0F1;1102 1164 11AC; +B0F2;B0F2;1102 1164 11AD;B0F2;1102 1164 11AD; +B0F3;B0F3;1102 1164 11AE;B0F3;1102 1164 11AE; +B0F4;B0F4;1102 1164 11AF;B0F4;1102 1164 11AF; +B0F5;B0F5;1102 1164 11B0;B0F5;1102 1164 11B0; +B0F6;B0F6;1102 1164 11B1;B0F6;1102 1164 11B1; +B0F7;B0F7;1102 1164 11B2;B0F7;1102 1164 11B2; +B0F8;B0F8;1102 1164 11B3;B0F8;1102 1164 11B3; +B0F9;B0F9;1102 1164 11B4;B0F9;1102 1164 11B4; +B0FA;B0FA;1102 1164 11B5;B0FA;1102 1164 11B5; +B0FB;B0FB;1102 1164 11B6;B0FB;1102 1164 11B6; +B0FC;B0FC;1102 1164 11B7;B0FC;1102 1164 11B7; +B0FD;B0FD;1102 1164 11B8;B0FD;1102 1164 11B8; +B0FE;B0FE;1102 1164 11B9;B0FE;1102 1164 11B9; +B0FF;B0FF;1102 1164 11BA;B0FF;1102 1164 11BA; +B100;B100;1102 1164 11BB;B100;1102 1164 11BB; +B101;B101;1102 1164 11BC;B101;1102 1164 11BC; +B102;B102;1102 1164 11BD;B102;1102 1164 11BD; +B103;B103;1102 1164 11BE;B103;1102 1164 11BE; +B104;B104;1102 1164 11BF;B104;1102 1164 11BF; +B105;B105;1102 1164 11C0;B105;1102 1164 11C0; +B106;B106;1102 1164 11C1;B106;1102 1164 11C1; +B107;B107;1102 1164 11C2;B107;1102 1164 11C2; +B108;B108;1102 1165;B108;1102 1165; +B109;B109;1102 1165 11A8;B109;1102 1165 11A8; +B10A;B10A;1102 1165 11A9;B10A;1102 1165 11A9; +B10B;B10B;1102 1165 11AA;B10B;1102 1165 11AA; +B10C;B10C;1102 1165 11AB;B10C;1102 1165 11AB; +B10D;B10D;1102 1165 11AC;B10D;1102 1165 11AC; +B10E;B10E;1102 1165 11AD;B10E;1102 1165 11AD; +B10F;B10F;1102 1165 11AE;B10F;1102 1165 11AE; +B110;B110;1102 1165 11AF;B110;1102 1165 11AF; +B111;B111;1102 1165 11B0;B111;1102 1165 11B0; +B112;B112;1102 1165 11B1;B112;1102 1165 11B1; +B113;B113;1102 1165 11B2;B113;1102 1165 11B2; +B114;B114;1102 1165 11B3;B114;1102 1165 11B3; +B115;B115;1102 1165 11B4;B115;1102 1165 11B4; +B116;B116;1102 1165 11B5;B116;1102 1165 11B5; +B117;B117;1102 1165 11B6;B117;1102 1165 11B6; +B118;B118;1102 1165 11B7;B118;1102 1165 11B7; +B119;B119;1102 1165 11B8;B119;1102 1165 11B8; +B11A;B11A;1102 1165 11B9;B11A;1102 1165 11B9; +B11B;B11B;1102 1165 11BA;B11B;1102 1165 11BA; +B11C;B11C;1102 1165 11BB;B11C;1102 1165 11BB; +B11D;B11D;1102 1165 11BC;B11D;1102 1165 11BC; +B11E;B11E;1102 1165 11BD;B11E;1102 1165 11BD; +B11F;B11F;1102 1165 11BE;B11F;1102 1165 11BE; +B120;B120;1102 1165 11BF;B120;1102 1165 11BF; +B121;B121;1102 1165 11C0;B121;1102 1165 11C0; +B122;B122;1102 1165 11C1;B122;1102 1165 11C1; +B123;B123;1102 1165 11C2;B123;1102 1165 11C2; +B124;B124;1102 1166;B124;1102 1166; +B125;B125;1102 1166 11A8;B125;1102 1166 11A8; +B126;B126;1102 1166 11A9;B126;1102 1166 11A9; +B127;B127;1102 1166 11AA;B127;1102 1166 11AA; +B128;B128;1102 1166 11AB;B128;1102 1166 11AB; +B129;B129;1102 1166 11AC;B129;1102 1166 11AC; +B12A;B12A;1102 1166 11AD;B12A;1102 1166 11AD; +B12B;B12B;1102 1166 11AE;B12B;1102 1166 11AE; +B12C;B12C;1102 1166 11AF;B12C;1102 1166 11AF; +B12D;B12D;1102 1166 11B0;B12D;1102 1166 11B0; +B12E;B12E;1102 1166 11B1;B12E;1102 1166 11B1; +B12F;B12F;1102 1166 11B2;B12F;1102 1166 11B2; +B130;B130;1102 1166 11B3;B130;1102 1166 11B3; +B131;B131;1102 1166 11B4;B131;1102 1166 11B4; +B132;B132;1102 1166 11B5;B132;1102 1166 11B5; +B133;B133;1102 1166 11B6;B133;1102 1166 11B6; +B134;B134;1102 1166 11B7;B134;1102 1166 11B7; +B135;B135;1102 1166 11B8;B135;1102 1166 11B8; +B136;B136;1102 1166 11B9;B136;1102 1166 11B9; +B137;B137;1102 1166 11BA;B137;1102 1166 11BA; +B138;B138;1102 1166 11BB;B138;1102 1166 11BB; +B139;B139;1102 1166 11BC;B139;1102 1166 11BC; +B13A;B13A;1102 1166 11BD;B13A;1102 1166 11BD; +B13B;B13B;1102 1166 11BE;B13B;1102 1166 11BE; +B13C;B13C;1102 1166 11BF;B13C;1102 1166 11BF; +B13D;B13D;1102 1166 11C0;B13D;1102 1166 11C0; +B13E;B13E;1102 1166 11C1;B13E;1102 1166 11C1; +B13F;B13F;1102 1166 11C2;B13F;1102 1166 11C2; +B140;B140;1102 1167;B140;1102 1167; +B141;B141;1102 1167 11A8;B141;1102 1167 11A8; +B142;B142;1102 1167 11A9;B142;1102 1167 11A9; +B143;B143;1102 1167 11AA;B143;1102 1167 11AA; +B144;B144;1102 1167 11AB;B144;1102 1167 11AB; +B145;B145;1102 1167 11AC;B145;1102 1167 11AC; +B146;B146;1102 1167 11AD;B146;1102 1167 11AD; +B147;B147;1102 1167 11AE;B147;1102 1167 11AE; +B148;B148;1102 1167 11AF;B148;1102 1167 11AF; +B149;B149;1102 1167 11B0;B149;1102 1167 11B0; +B14A;B14A;1102 1167 11B1;B14A;1102 1167 11B1; +B14B;B14B;1102 1167 11B2;B14B;1102 1167 11B2; +B14C;B14C;1102 1167 11B3;B14C;1102 1167 11B3; +B14D;B14D;1102 1167 11B4;B14D;1102 1167 11B4; +B14E;B14E;1102 1167 11B5;B14E;1102 1167 11B5; +B14F;B14F;1102 1167 11B6;B14F;1102 1167 11B6; +B150;B150;1102 1167 11B7;B150;1102 1167 11B7; +B151;B151;1102 1167 11B8;B151;1102 1167 11B8; +B152;B152;1102 1167 11B9;B152;1102 1167 11B9; +B153;B153;1102 1167 11BA;B153;1102 1167 11BA; +B154;B154;1102 1167 11BB;B154;1102 1167 11BB; +B155;B155;1102 1167 11BC;B155;1102 1167 11BC; +B156;B156;1102 1167 11BD;B156;1102 1167 11BD; +B157;B157;1102 1167 11BE;B157;1102 1167 11BE; +B158;B158;1102 1167 11BF;B158;1102 1167 11BF; +B159;B159;1102 1167 11C0;B159;1102 1167 11C0; +B15A;B15A;1102 1167 11C1;B15A;1102 1167 11C1; +B15B;B15B;1102 1167 11C2;B15B;1102 1167 11C2; +B15C;B15C;1102 1168;B15C;1102 1168; +B15D;B15D;1102 1168 11A8;B15D;1102 1168 11A8; +B15E;B15E;1102 1168 11A9;B15E;1102 1168 11A9; +B15F;B15F;1102 1168 11AA;B15F;1102 1168 11AA; +B160;B160;1102 1168 11AB;B160;1102 1168 11AB; +B161;B161;1102 1168 11AC;B161;1102 1168 11AC; +B162;B162;1102 1168 11AD;B162;1102 1168 11AD; +B163;B163;1102 1168 11AE;B163;1102 1168 11AE; +B164;B164;1102 1168 11AF;B164;1102 1168 11AF; +B165;B165;1102 1168 11B0;B165;1102 1168 11B0; +B166;B166;1102 1168 11B1;B166;1102 1168 11B1; +B167;B167;1102 1168 11B2;B167;1102 1168 11B2; +B168;B168;1102 1168 11B3;B168;1102 1168 11B3; +B169;B169;1102 1168 11B4;B169;1102 1168 11B4; +B16A;B16A;1102 1168 11B5;B16A;1102 1168 11B5; +B16B;B16B;1102 1168 11B6;B16B;1102 1168 11B6; +B16C;B16C;1102 1168 11B7;B16C;1102 1168 11B7; +B16D;B16D;1102 1168 11B8;B16D;1102 1168 11B8; +B16E;B16E;1102 1168 11B9;B16E;1102 1168 11B9; +B16F;B16F;1102 1168 11BA;B16F;1102 1168 11BA; +B170;B170;1102 1168 11BB;B170;1102 1168 11BB; +B171;B171;1102 1168 11BC;B171;1102 1168 11BC; +B172;B172;1102 1168 11BD;B172;1102 1168 11BD; +B173;B173;1102 1168 11BE;B173;1102 1168 11BE; +B174;B174;1102 1168 11BF;B174;1102 1168 11BF; +B175;B175;1102 1168 11C0;B175;1102 1168 11C0; +B176;B176;1102 1168 11C1;B176;1102 1168 11C1; +B177;B177;1102 1168 11C2;B177;1102 1168 11C2; +B178;B178;1102 1169;B178;1102 1169; +B179;B179;1102 1169 11A8;B179;1102 1169 11A8; +B17A;B17A;1102 1169 11A9;B17A;1102 1169 11A9; +B17B;B17B;1102 1169 11AA;B17B;1102 1169 11AA; +B17C;B17C;1102 1169 11AB;B17C;1102 1169 11AB; +B17D;B17D;1102 1169 11AC;B17D;1102 1169 11AC; +B17E;B17E;1102 1169 11AD;B17E;1102 1169 11AD; +B17F;B17F;1102 1169 11AE;B17F;1102 1169 11AE; +B180;B180;1102 1169 11AF;B180;1102 1169 11AF; +B181;B181;1102 1169 11B0;B181;1102 1169 11B0; +B182;B182;1102 1169 11B1;B182;1102 1169 11B1; +B183;B183;1102 1169 11B2;B183;1102 1169 11B2; +B184;B184;1102 1169 11B3;B184;1102 1169 11B3; +B185;B185;1102 1169 11B4;B185;1102 1169 11B4; +B186;B186;1102 1169 11B5;B186;1102 1169 11B5; +B187;B187;1102 1169 11B6;B187;1102 1169 11B6; +B188;B188;1102 1169 11B7;B188;1102 1169 11B7; +B189;B189;1102 1169 11B8;B189;1102 1169 11B8; +B18A;B18A;1102 1169 11B9;B18A;1102 1169 11B9; +B18B;B18B;1102 1169 11BA;B18B;1102 1169 11BA; +B18C;B18C;1102 1169 11BB;B18C;1102 1169 11BB; +B18D;B18D;1102 1169 11BC;B18D;1102 1169 11BC; +B18E;B18E;1102 1169 11BD;B18E;1102 1169 11BD; +B18F;B18F;1102 1169 11BE;B18F;1102 1169 11BE; +B190;B190;1102 1169 11BF;B190;1102 1169 11BF; +B191;B191;1102 1169 11C0;B191;1102 1169 11C0; +B192;B192;1102 1169 11C1;B192;1102 1169 11C1; +B193;B193;1102 1169 11C2;B193;1102 1169 11C2; +B194;B194;1102 116A;B194;1102 116A; +B195;B195;1102 116A 11A8;B195;1102 116A 11A8; +B196;B196;1102 116A 11A9;B196;1102 116A 11A9; +B197;B197;1102 116A 11AA;B197;1102 116A 11AA; +B198;B198;1102 116A 11AB;B198;1102 116A 11AB; +B199;B199;1102 116A 11AC;B199;1102 116A 11AC; +B19A;B19A;1102 116A 11AD;B19A;1102 116A 11AD; +B19B;B19B;1102 116A 11AE;B19B;1102 116A 11AE; +B19C;B19C;1102 116A 11AF;B19C;1102 116A 11AF; +B19D;B19D;1102 116A 11B0;B19D;1102 116A 11B0; +B19E;B19E;1102 116A 11B1;B19E;1102 116A 11B1; +B19F;B19F;1102 116A 11B2;B19F;1102 116A 11B2; +B1A0;B1A0;1102 116A 11B3;B1A0;1102 116A 11B3; +B1A1;B1A1;1102 116A 11B4;B1A1;1102 116A 11B4; +B1A2;B1A2;1102 116A 11B5;B1A2;1102 116A 11B5; +B1A3;B1A3;1102 116A 11B6;B1A3;1102 116A 11B6; +B1A4;B1A4;1102 116A 11B7;B1A4;1102 116A 11B7; +B1A5;B1A5;1102 116A 11B8;B1A5;1102 116A 11B8; +B1A6;B1A6;1102 116A 11B9;B1A6;1102 116A 11B9; +B1A7;B1A7;1102 116A 11BA;B1A7;1102 116A 11BA; +B1A8;B1A8;1102 116A 11BB;B1A8;1102 116A 11BB; +B1A9;B1A9;1102 116A 11BC;B1A9;1102 116A 11BC; +B1AA;B1AA;1102 116A 11BD;B1AA;1102 116A 11BD; +B1AB;B1AB;1102 116A 11BE;B1AB;1102 116A 11BE; +B1AC;B1AC;1102 116A 11BF;B1AC;1102 116A 11BF; +B1AD;B1AD;1102 116A 11C0;B1AD;1102 116A 11C0; +B1AE;B1AE;1102 116A 11C1;B1AE;1102 116A 11C1; +B1AF;B1AF;1102 116A 11C2;B1AF;1102 116A 11C2; +B1B0;B1B0;1102 116B;B1B0;1102 116B; +B1B1;B1B1;1102 116B 11A8;B1B1;1102 116B 11A8; +B1B2;B1B2;1102 116B 11A9;B1B2;1102 116B 11A9; +B1B3;B1B3;1102 116B 11AA;B1B3;1102 116B 11AA; +B1B4;B1B4;1102 116B 11AB;B1B4;1102 116B 11AB; +B1B5;B1B5;1102 116B 11AC;B1B5;1102 116B 11AC; +B1B6;B1B6;1102 116B 11AD;B1B6;1102 116B 11AD; +B1B7;B1B7;1102 116B 11AE;B1B7;1102 116B 11AE; +B1B8;B1B8;1102 116B 11AF;B1B8;1102 116B 11AF; +B1B9;B1B9;1102 116B 11B0;B1B9;1102 116B 11B0; +B1BA;B1BA;1102 116B 11B1;B1BA;1102 116B 11B1; +B1BB;B1BB;1102 116B 11B2;B1BB;1102 116B 11B2; +B1BC;B1BC;1102 116B 11B3;B1BC;1102 116B 11B3; +B1BD;B1BD;1102 116B 11B4;B1BD;1102 116B 11B4; +B1BE;B1BE;1102 116B 11B5;B1BE;1102 116B 11B5; +B1BF;B1BF;1102 116B 11B6;B1BF;1102 116B 11B6; +B1C0;B1C0;1102 116B 11B7;B1C0;1102 116B 11B7; +B1C1;B1C1;1102 116B 11B8;B1C1;1102 116B 11B8; +B1C2;B1C2;1102 116B 11B9;B1C2;1102 116B 11B9; +B1C3;B1C3;1102 116B 11BA;B1C3;1102 116B 11BA; +B1C4;B1C4;1102 116B 11BB;B1C4;1102 116B 11BB; +B1C5;B1C5;1102 116B 11BC;B1C5;1102 116B 11BC; +B1C6;B1C6;1102 116B 11BD;B1C6;1102 116B 11BD; +B1C7;B1C7;1102 116B 11BE;B1C7;1102 116B 11BE; +B1C8;B1C8;1102 116B 11BF;B1C8;1102 116B 11BF; +B1C9;B1C9;1102 116B 11C0;B1C9;1102 116B 11C0; +B1CA;B1CA;1102 116B 11C1;B1CA;1102 116B 11C1; +B1CB;B1CB;1102 116B 11C2;B1CB;1102 116B 11C2; +B1CC;B1CC;1102 116C;B1CC;1102 116C; +B1CD;B1CD;1102 116C 11A8;B1CD;1102 116C 11A8; +B1CE;B1CE;1102 116C 11A9;B1CE;1102 116C 11A9; +B1CF;B1CF;1102 116C 11AA;B1CF;1102 116C 11AA; +B1D0;B1D0;1102 116C 11AB;B1D0;1102 116C 11AB; +B1D1;B1D1;1102 116C 11AC;B1D1;1102 116C 11AC; +B1D2;B1D2;1102 116C 11AD;B1D2;1102 116C 11AD; +B1D3;B1D3;1102 116C 11AE;B1D3;1102 116C 11AE; +B1D4;B1D4;1102 116C 11AF;B1D4;1102 116C 11AF; +B1D5;B1D5;1102 116C 11B0;B1D5;1102 116C 11B0; +B1D6;B1D6;1102 116C 11B1;B1D6;1102 116C 11B1; +B1D7;B1D7;1102 116C 11B2;B1D7;1102 116C 11B2; +B1D8;B1D8;1102 116C 11B3;B1D8;1102 116C 11B3; +B1D9;B1D9;1102 116C 11B4;B1D9;1102 116C 11B4; +B1DA;B1DA;1102 116C 11B5;B1DA;1102 116C 11B5; +B1DB;B1DB;1102 116C 11B6;B1DB;1102 116C 11B6; +B1DC;B1DC;1102 116C 11B7;B1DC;1102 116C 11B7; +B1DD;B1DD;1102 116C 11B8;B1DD;1102 116C 11B8; +B1DE;B1DE;1102 116C 11B9;B1DE;1102 116C 11B9; +B1DF;B1DF;1102 116C 11BA;B1DF;1102 116C 11BA; +B1E0;B1E0;1102 116C 11BB;B1E0;1102 116C 11BB; +B1E1;B1E1;1102 116C 11BC;B1E1;1102 116C 11BC; +B1E2;B1E2;1102 116C 11BD;B1E2;1102 116C 11BD; +B1E3;B1E3;1102 116C 11BE;B1E3;1102 116C 11BE; +B1E4;B1E4;1102 116C 11BF;B1E4;1102 116C 11BF; +B1E5;B1E5;1102 116C 11C0;B1E5;1102 116C 11C0; +B1E6;B1E6;1102 116C 11C1;B1E6;1102 116C 11C1; +B1E7;B1E7;1102 116C 11C2;B1E7;1102 116C 11C2; +B1E8;B1E8;1102 116D;B1E8;1102 116D; +B1E9;B1E9;1102 116D 11A8;B1E9;1102 116D 11A8; +B1EA;B1EA;1102 116D 11A9;B1EA;1102 116D 11A9; +B1EB;B1EB;1102 116D 11AA;B1EB;1102 116D 11AA; +B1EC;B1EC;1102 116D 11AB;B1EC;1102 116D 11AB; +B1ED;B1ED;1102 116D 11AC;B1ED;1102 116D 11AC; +B1EE;B1EE;1102 116D 11AD;B1EE;1102 116D 11AD; +B1EF;B1EF;1102 116D 11AE;B1EF;1102 116D 11AE; +B1F0;B1F0;1102 116D 11AF;B1F0;1102 116D 11AF; +B1F1;B1F1;1102 116D 11B0;B1F1;1102 116D 11B0; +B1F2;B1F2;1102 116D 11B1;B1F2;1102 116D 11B1; +B1F3;B1F3;1102 116D 11B2;B1F3;1102 116D 11B2; +B1F4;B1F4;1102 116D 11B3;B1F4;1102 116D 11B3; +B1F5;B1F5;1102 116D 11B4;B1F5;1102 116D 11B4; +B1F6;B1F6;1102 116D 11B5;B1F6;1102 116D 11B5; +B1F7;B1F7;1102 116D 11B6;B1F7;1102 116D 11B6; +B1F8;B1F8;1102 116D 11B7;B1F8;1102 116D 11B7; +B1F9;B1F9;1102 116D 11B8;B1F9;1102 116D 11B8; +B1FA;B1FA;1102 116D 11B9;B1FA;1102 116D 11B9; +B1FB;B1FB;1102 116D 11BA;B1FB;1102 116D 11BA; +B1FC;B1FC;1102 116D 11BB;B1FC;1102 116D 11BB; +B1FD;B1FD;1102 116D 11BC;B1FD;1102 116D 11BC; +B1FE;B1FE;1102 116D 11BD;B1FE;1102 116D 11BD; +B1FF;B1FF;1102 116D 11BE;B1FF;1102 116D 11BE; +B200;B200;1102 116D 11BF;B200;1102 116D 11BF; +B201;B201;1102 116D 11C0;B201;1102 116D 11C0; +B202;B202;1102 116D 11C1;B202;1102 116D 11C1; +B203;B203;1102 116D 11C2;B203;1102 116D 11C2; +B204;B204;1102 116E;B204;1102 116E; +B205;B205;1102 116E 11A8;B205;1102 116E 11A8; +B206;B206;1102 116E 11A9;B206;1102 116E 11A9; +B207;B207;1102 116E 11AA;B207;1102 116E 11AA; +B208;B208;1102 116E 11AB;B208;1102 116E 11AB; +B209;B209;1102 116E 11AC;B209;1102 116E 11AC; +B20A;B20A;1102 116E 11AD;B20A;1102 116E 11AD; +B20B;B20B;1102 116E 11AE;B20B;1102 116E 11AE; +B20C;B20C;1102 116E 11AF;B20C;1102 116E 11AF; +B20D;B20D;1102 116E 11B0;B20D;1102 116E 11B0; +B20E;B20E;1102 116E 11B1;B20E;1102 116E 11B1; +B20F;B20F;1102 116E 11B2;B20F;1102 116E 11B2; +B210;B210;1102 116E 11B3;B210;1102 116E 11B3; +B211;B211;1102 116E 11B4;B211;1102 116E 11B4; +B212;B212;1102 116E 11B5;B212;1102 116E 11B5; +B213;B213;1102 116E 11B6;B213;1102 116E 11B6; +B214;B214;1102 116E 11B7;B214;1102 116E 11B7; +B215;B215;1102 116E 11B8;B215;1102 116E 11B8; +B216;B216;1102 116E 11B9;B216;1102 116E 11B9; +B217;B217;1102 116E 11BA;B217;1102 116E 11BA; +B218;B218;1102 116E 11BB;B218;1102 116E 11BB; +B219;B219;1102 116E 11BC;B219;1102 116E 11BC; +B21A;B21A;1102 116E 11BD;B21A;1102 116E 11BD; +B21B;B21B;1102 116E 11BE;B21B;1102 116E 11BE; +B21C;B21C;1102 116E 11BF;B21C;1102 116E 11BF; +B21D;B21D;1102 116E 11C0;B21D;1102 116E 11C0; +B21E;B21E;1102 116E 11C1;B21E;1102 116E 11C1; +B21F;B21F;1102 116E 11C2;B21F;1102 116E 11C2; +B220;B220;1102 116F;B220;1102 116F; +B221;B221;1102 116F 11A8;B221;1102 116F 11A8; +B222;B222;1102 116F 11A9;B222;1102 116F 11A9; +B223;B223;1102 116F 11AA;B223;1102 116F 11AA; +B224;B224;1102 116F 11AB;B224;1102 116F 11AB; +B225;B225;1102 116F 11AC;B225;1102 116F 11AC; +B226;B226;1102 116F 11AD;B226;1102 116F 11AD; +B227;B227;1102 116F 11AE;B227;1102 116F 11AE; +B228;B228;1102 116F 11AF;B228;1102 116F 11AF; +B229;B229;1102 116F 11B0;B229;1102 116F 11B0; +B22A;B22A;1102 116F 11B1;B22A;1102 116F 11B1; +B22B;B22B;1102 116F 11B2;B22B;1102 116F 11B2; +B22C;B22C;1102 116F 11B3;B22C;1102 116F 11B3; +B22D;B22D;1102 116F 11B4;B22D;1102 116F 11B4; +B22E;B22E;1102 116F 11B5;B22E;1102 116F 11B5; +B22F;B22F;1102 116F 11B6;B22F;1102 116F 11B6; +B230;B230;1102 116F 11B7;B230;1102 116F 11B7; +B231;B231;1102 116F 11B8;B231;1102 116F 11B8; +B232;B232;1102 116F 11B9;B232;1102 116F 11B9; +B233;B233;1102 116F 11BA;B233;1102 116F 11BA; +B234;B234;1102 116F 11BB;B234;1102 116F 11BB; +B235;B235;1102 116F 11BC;B235;1102 116F 11BC; +B236;B236;1102 116F 11BD;B236;1102 116F 11BD; +B237;B237;1102 116F 11BE;B237;1102 116F 11BE; +B238;B238;1102 116F 11BF;B238;1102 116F 11BF; +B239;B239;1102 116F 11C0;B239;1102 116F 11C0; +B23A;B23A;1102 116F 11C1;B23A;1102 116F 11C1; +B23B;B23B;1102 116F 11C2;B23B;1102 116F 11C2; +B23C;B23C;1102 1170;B23C;1102 1170; +B23D;B23D;1102 1170 11A8;B23D;1102 1170 11A8; +B23E;B23E;1102 1170 11A9;B23E;1102 1170 11A9; +B23F;B23F;1102 1170 11AA;B23F;1102 1170 11AA; +B240;B240;1102 1170 11AB;B240;1102 1170 11AB; +B241;B241;1102 1170 11AC;B241;1102 1170 11AC; +B242;B242;1102 1170 11AD;B242;1102 1170 11AD; +B243;B243;1102 1170 11AE;B243;1102 1170 11AE; +B244;B244;1102 1170 11AF;B244;1102 1170 11AF; +B245;B245;1102 1170 11B0;B245;1102 1170 11B0; +B246;B246;1102 1170 11B1;B246;1102 1170 11B1; +B247;B247;1102 1170 11B2;B247;1102 1170 11B2; +B248;B248;1102 1170 11B3;B248;1102 1170 11B3; +B249;B249;1102 1170 11B4;B249;1102 1170 11B4; +B24A;B24A;1102 1170 11B5;B24A;1102 1170 11B5; +B24B;B24B;1102 1170 11B6;B24B;1102 1170 11B6; +B24C;B24C;1102 1170 11B7;B24C;1102 1170 11B7; +B24D;B24D;1102 1170 11B8;B24D;1102 1170 11B8; +B24E;B24E;1102 1170 11B9;B24E;1102 1170 11B9; +B24F;B24F;1102 1170 11BA;B24F;1102 1170 11BA; +B250;B250;1102 1170 11BB;B250;1102 1170 11BB; +B251;B251;1102 1170 11BC;B251;1102 1170 11BC; +B252;B252;1102 1170 11BD;B252;1102 1170 11BD; +B253;B253;1102 1170 11BE;B253;1102 1170 11BE; +B254;B254;1102 1170 11BF;B254;1102 1170 11BF; +B255;B255;1102 1170 11C0;B255;1102 1170 11C0; +B256;B256;1102 1170 11C1;B256;1102 1170 11C1; +B257;B257;1102 1170 11C2;B257;1102 1170 11C2; +B258;B258;1102 1171;B258;1102 1171; +B259;B259;1102 1171 11A8;B259;1102 1171 11A8; +B25A;B25A;1102 1171 11A9;B25A;1102 1171 11A9; +B25B;B25B;1102 1171 11AA;B25B;1102 1171 11AA; +B25C;B25C;1102 1171 11AB;B25C;1102 1171 11AB; +B25D;B25D;1102 1171 11AC;B25D;1102 1171 11AC; +B25E;B25E;1102 1171 11AD;B25E;1102 1171 11AD; +B25F;B25F;1102 1171 11AE;B25F;1102 1171 11AE; +B260;B260;1102 1171 11AF;B260;1102 1171 11AF; +B261;B261;1102 1171 11B0;B261;1102 1171 11B0; +B262;B262;1102 1171 11B1;B262;1102 1171 11B1; +B263;B263;1102 1171 11B2;B263;1102 1171 11B2; +B264;B264;1102 1171 11B3;B264;1102 1171 11B3; +B265;B265;1102 1171 11B4;B265;1102 1171 11B4; +B266;B266;1102 1171 11B5;B266;1102 1171 11B5; +B267;B267;1102 1171 11B6;B267;1102 1171 11B6; +B268;B268;1102 1171 11B7;B268;1102 1171 11B7; +B269;B269;1102 1171 11B8;B269;1102 1171 11B8; +B26A;B26A;1102 1171 11B9;B26A;1102 1171 11B9; +B26B;B26B;1102 1171 11BA;B26B;1102 1171 11BA; +B26C;B26C;1102 1171 11BB;B26C;1102 1171 11BB; +B26D;B26D;1102 1171 11BC;B26D;1102 1171 11BC; +B26E;B26E;1102 1171 11BD;B26E;1102 1171 11BD; +B26F;B26F;1102 1171 11BE;B26F;1102 1171 11BE; +B270;B270;1102 1171 11BF;B270;1102 1171 11BF; +B271;B271;1102 1171 11C0;B271;1102 1171 11C0; +B272;B272;1102 1171 11C1;B272;1102 1171 11C1; +B273;B273;1102 1171 11C2;B273;1102 1171 11C2; +B274;B274;1102 1172;B274;1102 1172; +B275;B275;1102 1172 11A8;B275;1102 1172 11A8; +B276;B276;1102 1172 11A9;B276;1102 1172 11A9; +B277;B277;1102 1172 11AA;B277;1102 1172 11AA; +B278;B278;1102 1172 11AB;B278;1102 1172 11AB; +B279;B279;1102 1172 11AC;B279;1102 1172 11AC; +B27A;B27A;1102 1172 11AD;B27A;1102 1172 11AD; +B27B;B27B;1102 1172 11AE;B27B;1102 1172 11AE; +B27C;B27C;1102 1172 11AF;B27C;1102 1172 11AF; +B27D;B27D;1102 1172 11B0;B27D;1102 1172 11B0; +B27E;B27E;1102 1172 11B1;B27E;1102 1172 11B1; +B27F;B27F;1102 1172 11B2;B27F;1102 1172 11B2; +B280;B280;1102 1172 11B3;B280;1102 1172 11B3; +B281;B281;1102 1172 11B4;B281;1102 1172 11B4; +B282;B282;1102 1172 11B5;B282;1102 1172 11B5; +B283;B283;1102 1172 11B6;B283;1102 1172 11B6; +B284;B284;1102 1172 11B7;B284;1102 1172 11B7; +B285;B285;1102 1172 11B8;B285;1102 1172 11B8; +B286;B286;1102 1172 11B9;B286;1102 1172 11B9; +B287;B287;1102 1172 11BA;B287;1102 1172 11BA; +B288;B288;1102 1172 11BB;B288;1102 1172 11BB; +B289;B289;1102 1172 11BC;B289;1102 1172 11BC; +B28A;B28A;1102 1172 11BD;B28A;1102 1172 11BD; +B28B;B28B;1102 1172 11BE;B28B;1102 1172 11BE; +B28C;B28C;1102 1172 11BF;B28C;1102 1172 11BF; +B28D;B28D;1102 1172 11C0;B28D;1102 1172 11C0; +B28E;B28E;1102 1172 11C1;B28E;1102 1172 11C1; +B28F;B28F;1102 1172 11C2;B28F;1102 1172 11C2; +B290;B290;1102 1173;B290;1102 1173; +B291;B291;1102 1173 11A8;B291;1102 1173 11A8; +B292;B292;1102 1173 11A9;B292;1102 1173 11A9; +B293;B293;1102 1173 11AA;B293;1102 1173 11AA; +B294;B294;1102 1173 11AB;B294;1102 1173 11AB; +B295;B295;1102 1173 11AC;B295;1102 1173 11AC; +B296;B296;1102 1173 11AD;B296;1102 1173 11AD; +B297;B297;1102 1173 11AE;B297;1102 1173 11AE; +B298;B298;1102 1173 11AF;B298;1102 1173 11AF; +B299;B299;1102 1173 11B0;B299;1102 1173 11B0; +B29A;B29A;1102 1173 11B1;B29A;1102 1173 11B1; +B29B;B29B;1102 1173 11B2;B29B;1102 1173 11B2; +B29C;B29C;1102 1173 11B3;B29C;1102 1173 11B3; +B29D;B29D;1102 1173 11B4;B29D;1102 1173 11B4; +B29E;B29E;1102 1173 11B5;B29E;1102 1173 11B5; +B29F;B29F;1102 1173 11B6;B29F;1102 1173 11B6; +B2A0;B2A0;1102 1173 11B7;B2A0;1102 1173 11B7; +B2A1;B2A1;1102 1173 11B8;B2A1;1102 1173 11B8; +B2A2;B2A2;1102 1173 11B9;B2A2;1102 1173 11B9; +B2A3;B2A3;1102 1173 11BA;B2A3;1102 1173 11BA; +B2A4;B2A4;1102 1173 11BB;B2A4;1102 1173 11BB; +B2A5;B2A5;1102 1173 11BC;B2A5;1102 1173 11BC; +B2A6;B2A6;1102 1173 11BD;B2A6;1102 1173 11BD; +B2A7;B2A7;1102 1173 11BE;B2A7;1102 1173 11BE; +B2A8;B2A8;1102 1173 11BF;B2A8;1102 1173 11BF; +B2A9;B2A9;1102 1173 11C0;B2A9;1102 1173 11C0; +B2AA;B2AA;1102 1173 11C1;B2AA;1102 1173 11C1; +B2AB;B2AB;1102 1173 11C2;B2AB;1102 1173 11C2; +B2AC;B2AC;1102 1174;B2AC;1102 1174; +B2AD;B2AD;1102 1174 11A8;B2AD;1102 1174 11A8; +B2AE;B2AE;1102 1174 11A9;B2AE;1102 1174 11A9; +B2AF;B2AF;1102 1174 11AA;B2AF;1102 1174 11AA; +B2B0;B2B0;1102 1174 11AB;B2B0;1102 1174 11AB; +B2B1;B2B1;1102 1174 11AC;B2B1;1102 1174 11AC; +B2B2;B2B2;1102 1174 11AD;B2B2;1102 1174 11AD; +B2B3;B2B3;1102 1174 11AE;B2B3;1102 1174 11AE; +B2B4;B2B4;1102 1174 11AF;B2B4;1102 1174 11AF; +B2B5;B2B5;1102 1174 11B0;B2B5;1102 1174 11B0; +B2B6;B2B6;1102 1174 11B1;B2B6;1102 1174 11B1; +B2B7;B2B7;1102 1174 11B2;B2B7;1102 1174 11B2; +B2B8;B2B8;1102 1174 11B3;B2B8;1102 1174 11B3; +B2B9;B2B9;1102 1174 11B4;B2B9;1102 1174 11B4; +B2BA;B2BA;1102 1174 11B5;B2BA;1102 1174 11B5; +B2BB;B2BB;1102 1174 11B6;B2BB;1102 1174 11B6; +B2BC;B2BC;1102 1174 11B7;B2BC;1102 1174 11B7; +B2BD;B2BD;1102 1174 11B8;B2BD;1102 1174 11B8; +B2BE;B2BE;1102 1174 11B9;B2BE;1102 1174 11B9; +B2BF;B2BF;1102 1174 11BA;B2BF;1102 1174 11BA; +B2C0;B2C0;1102 1174 11BB;B2C0;1102 1174 11BB; +B2C1;B2C1;1102 1174 11BC;B2C1;1102 1174 11BC; +B2C2;B2C2;1102 1174 11BD;B2C2;1102 1174 11BD; +B2C3;B2C3;1102 1174 11BE;B2C3;1102 1174 11BE; +B2C4;B2C4;1102 1174 11BF;B2C4;1102 1174 11BF; +B2C5;B2C5;1102 1174 11C0;B2C5;1102 1174 11C0; +B2C6;B2C6;1102 1174 11C1;B2C6;1102 1174 11C1; +B2C7;B2C7;1102 1174 11C2;B2C7;1102 1174 11C2; +B2C8;B2C8;1102 1175;B2C8;1102 1175; +B2C9;B2C9;1102 1175 11A8;B2C9;1102 1175 11A8; +B2CA;B2CA;1102 1175 11A9;B2CA;1102 1175 11A9; +B2CB;B2CB;1102 1175 11AA;B2CB;1102 1175 11AA; +B2CC;B2CC;1102 1175 11AB;B2CC;1102 1175 11AB; +B2CD;B2CD;1102 1175 11AC;B2CD;1102 1175 11AC; +B2CE;B2CE;1102 1175 11AD;B2CE;1102 1175 11AD; +B2CF;B2CF;1102 1175 11AE;B2CF;1102 1175 11AE; +B2D0;B2D0;1102 1175 11AF;B2D0;1102 1175 11AF; +B2D1;B2D1;1102 1175 11B0;B2D1;1102 1175 11B0; +B2D2;B2D2;1102 1175 11B1;B2D2;1102 1175 11B1; +B2D3;B2D3;1102 1175 11B2;B2D3;1102 1175 11B2; +B2D4;B2D4;1102 1175 11B3;B2D4;1102 1175 11B3; +B2D5;B2D5;1102 1175 11B4;B2D5;1102 1175 11B4; +B2D6;B2D6;1102 1175 11B5;B2D6;1102 1175 11B5; +B2D7;B2D7;1102 1175 11B6;B2D7;1102 1175 11B6; +B2D8;B2D8;1102 1175 11B7;B2D8;1102 1175 11B7; +B2D9;B2D9;1102 1175 11B8;B2D9;1102 1175 11B8; +B2DA;B2DA;1102 1175 11B9;B2DA;1102 1175 11B9; +B2DB;B2DB;1102 1175 11BA;B2DB;1102 1175 11BA; +B2DC;B2DC;1102 1175 11BB;B2DC;1102 1175 11BB; +B2DD;B2DD;1102 1175 11BC;B2DD;1102 1175 11BC; +B2DE;B2DE;1102 1175 11BD;B2DE;1102 1175 11BD; +B2DF;B2DF;1102 1175 11BE;B2DF;1102 1175 11BE; +B2E0;B2E0;1102 1175 11BF;B2E0;1102 1175 11BF; +B2E1;B2E1;1102 1175 11C0;B2E1;1102 1175 11C0; +B2E2;B2E2;1102 1175 11C1;B2E2;1102 1175 11C1; +B2E3;B2E3;1102 1175 11C2;B2E3;1102 1175 11C2; +B2E4;B2E4;1103 1161;B2E4;1103 1161; +B2E5;B2E5;1103 1161 11A8;B2E5;1103 1161 11A8; +B2E6;B2E6;1103 1161 11A9;B2E6;1103 1161 11A9; +B2E7;B2E7;1103 1161 11AA;B2E7;1103 1161 11AA; +B2E8;B2E8;1103 1161 11AB;B2E8;1103 1161 11AB; +B2E9;B2E9;1103 1161 11AC;B2E9;1103 1161 11AC; +B2EA;B2EA;1103 1161 11AD;B2EA;1103 1161 11AD; +B2EB;B2EB;1103 1161 11AE;B2EB;1103 1161 11AE; +B2EC;B2EC;1103 1161 11AF;B2EC;1103 1161 11AF; +B2ED;B2ED;1103 1161 11B0;B2ED;1103 1161 11B0; +B2EE;B2EE;1103 1161 11B1;B2EE;1103 1161 11B1; +B2EF;B2EF;1103 1161 11B2;B2EF;1103 1161 11B2; +B2F0;B2F0;1103 1161 11B3;B2F0;1103 1161 11B3; +B2F1;B2F1;1103 1161 11B4;B2F1;1103 1161 11B4; +B2F2;B2F2;1103 1161 11B5;B2F2;1103 1161 11B5; +B2F3;B2F3;1103 1161 11B6;B2F3;1103 1161 11B6; +B2F4;B2F4;1103 1161 11B7;B2F4;1103 1161 11B7; +B2F5;B2F5;1103 1161 11B8;B2F5;1103 1161 11B8; +B2F6;B2F6;1103 1161 11B9;B2F6;1103 1161 11B9; +B2F7;B2F7;1103 1161 11BA;B2F7;1103 1161 11BA; +B2F8;B2F8;1103 1161 11BB;B2F8;1103 1161 11BB; +B2F9;B2F9;1103 1161 11BC;B2F9;1103 1161 11BC; +B2FA;B2FA;1103 1161 11BD;B2FA;1103 1161 11BD; +B2FB;B2FB;1103 1161 11BE;B2FB;1103 1161 11BE; +B2FC;B2FC;1103 1161 11BF;B2FC;1103 1161 11BF; +B2FD;B2FD;1103 1161 11C0;B2FD;1103 1161 11C0; +B2FE;B2FE;1103 1161 11C1;B2FE;1103 1161 11C1; +B2FF;B2FF;1103 1161 11C2;B2FF;1103 1161 11C2; +B300;B300;1103 1162;B300;1103 1162; +B301;B301;1103 1162 11A8;B301;1103 1162 11A8; +B302;B302;1103 1162 11A9;B302;1103 1162 11A9; +B303;B303;1103 1162 11AA;B303;1103 1162 11AA; +B304;B304;1103 1162 11AB;B304;1103 1162 11AB; +B305;B305;1103 1162 11AC;B305;1103 1162 11AC; +B306;B306;1103 1162 11AD;B306;1103 1162 11AD; +B307;B307;1103 1162 11AE;B307;1103 1162 11AE; +B308;B308;1103 1162 11AF;B308;1103 1162 11AF; +B309;B309;1103 1162 11B0;B309;1103 1162 11B0; +B30A;B30A;1103 1162 11B1;B30A;1103 1162 11B1; +B30B;B30B;1103 1162 11B2;B30B;1103 1162 11B2; +B30C;B30C;1103 1162 11B3;B30C;1103 1162 11B3; +B30D;B30D;1103 1162 11B4;B30D;1103 1162 11B4; +B30E;B30E;1103 1162 11B5;B30E;1103 1162 11B5; +B30F;B30F;1103 1162 11B6;B30F;1103 1162 11B6; +B310;B310;1103 1162 11B7;B310;1103 1162 11B7; +B311;B311;1103 1162 11B8;B311;1103 1162 11B8; +B312;B312;1103 1162 11B9;B312;1103 1162 11B9; +B313;B313;1103 1162 11BA;B313;1103 1162 11BA; +B314;B314;1103 1162 11BB;B314;1103 1162 11BB; +B315;B315;1103 1162 11BC;B315;1103 1162 11BC; +B316;B316;1103 1162 11BD;B316;1103 1162 11BD; +B317;B317;1103 1162 11BE;B317;1103 1162 11BE; +B318;B318;1103 1162 11BF;B318;1103 1162 11BF; +B319;B319;1103 1162 11C0;B319;1103 1162 11C0; +B31A;B31A;1103 1162 11C1;B31A;1103 1162 11C1; +B31B;B31B;1103 1162 11C2;B31B;1103 1162 11C2; +B31C;B31C;1103 1163;B31C;1103 1163; +B31D;B31D;1103 1163 11A8;B31D;1103 1163 11A8; +B31E;B31E;1103 1163 11A9;B31E;1103 1163 11A9; +B31F;B31F;1103 1163 11AA;B31F;1103 1163 11AA; +B320;B320;1103 1163 11AB;B320;1103 1163 11AB; +B321;B321;1103 1163 11AC;B321;1103 1163 11AC; +B322;B322;1103 1163 11AD;B322;1103 1163 11AD; +B323;B323;1103 1163 11AE;B323;1103 1163 11AE; +B324;B324;1103 1163 11AF;B324;1103 1163 11AF; +B325;B325;1103 1163 11B0;B325;1103 1163 11B0; +B326;B326;1103 1163 11B1;B326;1103 1163 11B1; +B327;B327;1103 1163 11B2;B327;1103 1163 11B2; +B328;B328;1103 1163 11B3;B328;1103 1163 11B3; +B329;B329;1103 1163 11B4;B329;1103 1163 11B4; +B32A;B32A;1103 1163 11B5;B32A;1103 1163 11B5; +B32B;B32B;1103 1163 11B6;B32B;1103 1163 11B6; +B32C;B32C;1103 1163 11B7;B32C;1103 1163 11B7; +B32D;B32D;1103 1163 11B8;B32D;1103 1163 11B8; +B32E;B32E;1103 1163 11B9;B32E;1103 1163 11B9; +B32F;B32F;1103 1163 11BA;B32F;1103 1163 11BA; +B330;B330;1103 1163 11BB;B330;1103 1163 11BB; +B331;B331;1103 1163 11BC;B331;1103 1163 11BC; +B332;B332;1103 1163 11BD;B332;1103 1163 11BD; +B333;B333;1103 1163 11BE;B333;1103 1163 11BE; +B334;B334;1103 1163 11BF;B334;1103 1163 11BF; +B335;B335;1103 1163 11C0;B335;1103 1163 11C0; +B336;B336;1103 1163 11C1;B336;1103 1163 11C1; +B337;B337;1103 1163 11C2;B337;1103 1163 11C2; +B338;B338;1103 1164;B338;1103 1164; +B339;B339;1103 1164 11A8;B339;1103 1164 11A8; +B33A;B33A;1103 1164 11A9;B33A;1103 1164 11A9; +B33B;B33B;1103 1164 11AA;B33B;1103 1164 11AA; +B33C;B33C;1103 1164 11AB;B33C;1103 1164 11AB; +B33D;B33D;1103 1164 11AC;B33D;1103 1164 11AC; +B33E;B33E;1103 1164 11AD;B33E;1103 1164 11AD; +B33F;B33F;1103 1164 11AE;B33F;1103 1164 11AE; +B340;B340;1103 1164 11AF;B340;1103 1164 11AF; +B341;B341;1103 1164 11B0;B341;1103 1164 11B0; +B342;B342;1103 1164 11B1;B342;1103 1164 11B1; +B343;B343;1103 1164 11B2;B343;1103 1164 11B2; +B344;B344;1103 1164 11B3;B344;1103 1164 11B3; +B345;B345;1103 1164 11B4;B345;1103 1164 11B4; +B346;B346;1103 1164 11B5;B346;1103 1164 11B5; +B347;B347;1103 1164 11B6;B347;1103 1164 11B6; +B348;B348;1103 1164 11B7;B348;1103 1164 11B7; +B349;B349;1103 1164 11B8;B349;1103 1164 11B8; +B34A;B34A;1103 1164 11B9;B34A;1103 1164 11B9; +B34B;B34B;1103 1164 11BA;B34B;1103 1164 11BA; +B34C;B34C;1103 1164 11BB;B34C;1103 1164 11BB; +B34D;B34D;1103 1164 11BC;B34D;1103 1164 11BC; +B34E;B34E;1103 1164 11BD;B34E;1103 1164 11BD; +B34F;B34F;1103 1164 11BE;B34F;1103 1164 11BE; +B350;B350;1103 1164 11BF;B350;1103 1164 11BF; +B351;B351;1103 1164 11C0;B351;1103 1164 11C0; +B352;B352;1103 1164 11C1;B352;1103 1164 11C1; +B353;B353;1103 1164 11C2;B353;1103 1164 11C2; +B354;B354;1103 1165;B354;1103 1165; +B355;B355;1103 1165 11A8;B355;1103 1165 11A8; +B356;B356;1103 1165 11A9;B356;1103 1165 11A9; +B357;B357;1103 1165 11AA;B357;1103 1165 11AA; +B358;B358;1103 1165 11AB;B358;1103 1165 11AB; +B359;B359;1103 1165 11AC;B359;1103 1165 11AC; +B35A;B35A;1103 1165 11AD;B35A;1103 1165 11AD; +B35B;B35B;1103 1165 11AE;B35B;1103 1165 11AE; +B35C;B35C;1103 1165 11AF;B35C;1103 1165 11AF; +B35D;B35D;1103 1165 11B0;B35D;1103 1165 11B0; +B35E;B35E;1103 1165 11B1;B35E;1103 1165 11B1; +B35F;B35F;1103 1165 11B2;B35F;1103 1165 11B2; +B360;B360;1103 1165 11B3;B360;1103 1165 11B3; +B361;B361;1103 1165 11B4;B361;1103 1165 11B4; +B362;B362;1103 1165 11B5;B362;1103 1165 11B5; +B363;B363;1103 1165 11B6;B363;1103 1165 11B6; +B364;B364;1103 1165 11B7;B364;1103 1165 11B7; +B365;B365;1103 1165 11B8;B365;1103 1165 11B8; +B366;B366;1103 1165 11B9;B366;1103 1165 11B9; +B367;B367;1103 1165 11BA;B367;1103 1165 11BA; +B368;B368;1103 1165 11BB;B368;1103 1165 11BB; +B369;B369;1103 1165 11BC;B369;1103 1165 11BC; +B36A;B36A;1103 1165 11BD;B36A;1103 1165 11BD; +B36B;B36B;1103 1165 11BE;B36B;1103 1165 11BE; +B36C;B36C;1103 1165 11BF;B36C;1103 1165 11BF; +B36D;B36D;1103 1165 11C0;B36D;1103 1165 11C0; +B36E;B36E;1103 1165 11C1;B36E;1103 1165 11C1; +B36F;B36F;1103 1165 11C2;B36F;1103 1165 11C2; +B370;B370;1103 1166;B370;1103 1166; +B371;B371;1103 1166 11A8;B371;1103 1166 11A8; +B372;B372;1103 1166 11A9;B372;1103 1166 11A9; +B373;B373;1103 1166 11AA;B373;1103 1166 11AA; +B374;B374;1103 1166 11AB;B374;1103 1166 11AB; +B375;B375;1103 1166 11AC;B375;1103 1166 11AC; +B376;B376;1103 1166 11AD;B376;1103 1166 11AD; +B377;B377;1103 1166 11AE;B377;1103 1166 11AE; +B378;B378;1103 1166 11AF;B378;1103 1166 11AF; +B379;B379;1103 1166 11B0;B379;1103 1166 11B0; +B37A;B37A;1103 1166 11B1;B37A;1103 1166 11B1; +B37B;B37B;1103 1166 11B2;B37B;1103 1166 11B2; +B37C;B37C;1103 1166 11B3;B37C;1103 1166 11B3; +B37D;B37D;1103 1166 11B4;B37D;1103 1166 11B4; +B37E;B37E;1103 1166 11B5;B37E;1103 1166 11B5; +B37F;B37F;1103 1166 11B6;B37F;1103 1166 11B6; +B380;B380;1103 1166 11B7;B380;1103 1166 11B7; +B381;B381;1103 1166 11B8;B381;1103 1166 11B8; +B382;B382;1103 1166 11B9;B382;1103 1166 11B9; +B383;B383;1103 1166 11BA;B383;1103 1166 11BA; +B384;B384;1103 1166 11BB;B384;1103 1166 11BB; +B385;B385;1103 1166 11BC;B385;1103 1166 11BC; +B386;B386;1103 1166 11BD;B386;1103 1166 11BD; +B387;B387;1103 1166 11BE;B387;1103 1166 11BE; +B388;B388;1103 1166 11BF;B388;1103 1166 11BF; +B389;B389;1103 1166 11C0;B389;1103 1166 11C0; +B38A;B38A;1103 1166 11C1;B38A;1103 1166 11C1; +B38B;B38B;1103 1166 11C2;B38B;1103 1166 11C2; +B38C;B38C;1103 1167;B38C;1103 1167; +B38D;B38D;1103 1167 11A8;B38D;1103 1167 11A8; +B38E;B38E;1103 1167 11A9;B38E;1103 1167 11A9; +B38F;B38F;1103 1167 11AA;B38F;1103 1167 11AA; +B390;B390;1103 1167 11AB;B390;1103 1167 11AB; +B391;B391;1103 1167 11AC;B391;1103 1167 11AC; +B392;B392;1103 1167 11AD;B392;1103 1167 11AD; +B393;B393;1103 1167 11AE;B393;1103 1167 11AE; +B394;B394;1103 1167 11AF;B394;1103 1167 11AF; +B395;B395;1103 1167 11B0;B395;1103 1167 11B0; +B396;B396;1103 1167 11B1;B396;1103 1167 11B1; +B397;B397;1103 1167 11B2;B397;1103 1167 11B2; +B398;B398;1103 1167 11B3;B398;1103 1167 11B3; +B399;B399;1103 1167 11B4;B399;1103 1167 11B4; +B39A;B39A;1103 1167 11B5;B39A;1103 1167 11B5; +B39B;B39B;1103 1167 11B6;B39B;1103 1167 11B6; +B39C;B39C;1103 1167 11B7;B39C;1103 1167 11B7; +B39D;B39D;1103 1167 11B8;B39D;1103 1167 11B8; +B39E;B39E;1103 1167 11B9;B39E;1103 1167 11B9; +B39F;B39F;1103 1167 11BA;B39F;1103 1167 11BA; +B3A0;B3A0;1103 1167 11BB;B3A0;1103 1167 11BB; +B3A1;B3A1;1103 1167 11BC;B3A1;1103 1167 11BC; +B3A2;B3A2;1103 1167 11BD;B3A2;1103 1167 11BD; +B3A3;B3A3;1103 1167 11BE;B3A3;1103 1167 11BE; +B3A4;B3A4;1103 1167 11BF;B3A4;1103 1167 11BF; +B3A5;B3A5;1103 1167 11C0;B3A5;1103 1167 11C0; +B3A6;B3A6;1103 1167 11C1;B3A6;1103 1167 11C1; +B3A7;B3A7;1103 1167 11C2;B3A7;1103 1167 11C2; +B3A8;B3A8;1103 1168;B3A8;1103 1168; +B3A9;B3A9;1103 1168 11A8;B3A9;1103 1168 11A8; +B3AA;B3AA;1103 1168 11A9;B3AA;1103 1168 11A9; +B3AB;B3AB;1103 1168 11AA;B3AB;1103 1168 11AA; +B3AC;B3AC;1103 1168 11AB;B3AC;1103 1168 11AB; +B3AD;B3AD;1103 1168 11AC;B3AD;1103 1168 11AC; +B3AE;B3AE;1103 1168 11AD;B3AE;1103 1168 11AD; +B3AF;B3AF;1103 1168 11AE;B3AF;1103 1168 11AE; +B3B0;B3B0;1103 1168 11AF;B3B0;1103 1168 11AF; +B3B1;B3B1;1103 1168 11B0;B3B1;1103 1168 11B0; +B3B2;B3B2;1103 1168 11B1;B3B2;1103 1168 11B1; +B3B3;B3B3;1103 1168 11B2;B3B3;1103 1168 11B2; +B3B4;B3B4;1103 1168 11B3;B3B4;1103 1168 11B3; +B3B5;B3B5;1103 1168 11B4;B3B5;1103 1168 11B4; +B3B6;B3B6;1103 1168 11B5;B3B6;1103 1168 11B5; +B3B7;B3B7;1103 1168 11B6;B3B7;1103 1168 11B6; +B3B8;B3B8;1103 1168 11B7;B3B8;1103 1168 11B7; +B3B9;B3B9;1103 1168 11B8;B3B9;1103 1168 11B8; +B3BA;B3BA;1103 1168 11B9;B3BA;1103 1168 11B9; +B3BB;B3BB;1103 1168 11BA;B3BB;1103 1168 11BA; +B3BC;B3BC;1103 1168 11BB;B3BC;1103 1168 11BB; +B3BD;B3BD;1103 1168 11BC;B3BD;1103 1168 11BC; +B3BE;B3BE;1103 1168 11BD;B3BE;1103 1168 11BD; +B3BF;B3BF;1103 1168 11BE;B3BF;1103 1168 11BE; +B3C0;B3C0;1103 1168 11BF;B3C0;1103 1168 11BF; +B3C1;B3C1;1103 1168 11C0;B3C1;1103 1168 11C0; +B3C2;B3C2;1103 1168 11C1;B3C2;1103 1168 11C1; +B3C3;B3C3;1103 1168 11C2;B3C3;1103 1168 11C2; +B3C4;B3C4;1103 1169;B3C4;1103 1169; +B3C5;B3C5;1103 1169 11A8;B3C5;1103 1169 11A8; +B3C6;B3C6;1103 1169 11A9;B3C6;1103 1169 11A9; +B3C7;B3C7;1103 1169 11AA;B3C7;1103 1169 11AA; +B3C8;B3C8;1103 1169 11AB;B3C8;1103 1169 11AB; +B3C9;B3C9;1103 1169 11AC;B3C9;1103 1169 11AC; +B3CA;B3CA;1103 1169 11AD;B3CA;1103 1169 11AD; +B3CB;B3CB;1103 1169 11AE;B3CB;1103 1169 11AE; +B3CC;B3CC;1103 1169 11AF;B3CC;1103 1169 11AF; +B3CD;B3CD;1103 1169 11B0;B3CD;1103 1169 11B0; +B3CE;B3CE;1103 1169 11B1;B3CE;1103 1169 11B1; +B3CF;B3CF;1103 1169 11B2;B3CF;1103 1169 11B2; +B3D0;B3D0;1103 1169 11B3;B3D0;1103 1169 11B3; +B3D1;B3D1;1103 1169 11B4;B3D1;1103 1169 11B4; +B3D2;B3D2;1103 1169 11B5;B3D2;1103 1169 11B5; +B3D3;B3D3;1103 1169 11B6;B3D3;1103 1169 11B6; +B3D4;B3D4;1103 1169 11B7;B3D4;1103 1169 11B7; +B3D5;B3D5;1103 1169 11B8;B3D5;1103 1169 11B8; +B3D6;B3D6;1103 1169 11B9;B3D6;1103 1169 11B9; +B3D7;B3D7;1103 1169 11BA;B3D7;1103 1169 11BA; +B3D8;B3D8;1103 1169 11BB;B3D8;1103 1169 11BB; +B3D9;B3D9;1103 1169 11BC;B3D9;1103 1169 11BC; +B3DA;B3DA;1103 1169 11BD;B3DA;1103 1169 11BD; +B3DB;B3DB;1103 1169 11BE;B3DB;1103 1169 11BE; +B3DC;B3DC;1103 1169 11BF;B3DC;1103 1169 11BF; +B3DD;B3DD;1103 1169 11C0;B3DD;1103 1169 11C0; +B3DE;B3DE;1103 1169 11C1;B3DE;1103 1169 11C1; +B3DF;B3DF;1103 1169 11C2;B3DF;1103 1169 11C2; +B3E0;B3E0;1103 116A;B3E0;1103 116A; +B3E1;B3E1;1103 116A 11A8;B3E1;1103 116A 11A8; +B3E2;B3E2;1103 116A 11A9;B3E2;1103 116A 11A9; +B3E3;B3E3;1103 116A 11AA;B3E3;1103 116A 11AA; +B3E4;B3E4;1103 116A 11AB;B3E4;1103 116A 11AB; +B3E5;B3E5;1103 116A 11AC;B3E5;1103 116A 11AC; +B3E6;B3E6;1103 116A 11AD;B3E6;1103 116A 11AD; +B3E7;B3E7;1103 116A 11AE;B3E7;1103 116A 11AE; +B3E8;B3E8;1103 116A 11AF;B3E8;1103 116A 11AF; +B3E9;B3E9;1103 116A 11B0;B3E9;1103 116A 11B0; +B3EA;B3EA;1103 116A 11B1;B3EA;1103 116A 11B1; +B3EB;B3EB;1103 116A 11B2;B3EB;1103 116A 11B2; +B3EC;B3EC;1103 116A 11B3;B3EC;1103 116A 11B3; +B3ED;B3ED;1103 116A 11B4;B3ED;1103 116A 11B4; +B3EE;B3EE;1103 116A 11B5;B3EE;1103 116A 11B5; +B3EF;B3EF;1103 116A 11B6;B3EF;1103 116A 11B6; +B3F0;B3F0;1103 116A 11B7;B3F0;1103 116A 11B7; +B3F1;B3F1;1103 116A 11B8;B3F1;1103 116A 11B8; +B3F2;B3F2;1103 116A 11B9;B3F2;1103 116A 11B9; +B3F3;B3F3;1103 116A 11BA;B3F3;1103 116A 11BA; +B3F4;B3F4;1103 116A 11BB;B3F4;1103 116A 11BB; +B3F5;B3F5;1103 116A 11BC;B3F5;1103 116A 11BC; +B3F6;B3F6;1103 116A 11BD;B3F6;1103 116A 11BD; +B3F7;B3F7;1103 116A 11BE;B3F7;1103 116A 11BE; +B3F8;B3F8;1103 116A 11BF;B3F8;1103 116A 11BF; +B3F9;B3F9;1103 116A 11C0;B3F9;1103 116A 11C0; +B3FA;B3FA;1103 116A 11C1;B3FA;1103 116A 11C1; +B3FB;B3FB;1103 116A 11C2;B3FB;1103 116A 11C2; +B3FC;B3FC;1103 116B;B3FC;1103 116B; +B3FD;B3FD;1103 116B 11A8;B3FD;1103 116B 11A8; +B3FE;B3FE;1103 116B 11A9;B3FE;1103 116B 11A9; +B3FF;B3FF;1103 116B 11AA;B3FF;1103 116B 11AA; +B400;B400;1103 116B 11AB;B400;1103 116B 11AB; +B401;B401;1103 116B 11AC;B401;1103 116B 11AC; +B402;B402;1103 116B 11AD;B402;1103 116B 11AD; +B403;B403;1103 116B 11AE;B403;1103 116B 11AE; +B404;B404;1103 116B 11AF;B404;1103 116B 11AF; +B405;B405;1103 116B 11B0;B405;1103 116B 11B0; +B406;B406;1103 116B 11B1;B406;1103 116B 11B1; +B407;B407;1103 116B 11B2;B407;1103 116B 11B2; +B408;B408;1103 116B 11B3;B408;1103 116B 11B3; +B409;B409;1103 116B 11B4;B409;1103 116B 11B4; +B40A;B40A;1103 116B 11B5;B40A;1103 116B 11B5; +B40B;B40B;1103 116B 11B6;B40B;1103 116B 11B6; +B40C;B40C;1103 116B 11B7;B40C;1103 116B 11B7; +B40D;B40D;1103 116B 11B8;B40D;1103 116B 11B8; +B40E;B40E;1103 116B 11B9;B40E;1103 116B 11B9; +B40F;B40F;1103 116B 11BA;B40F;1103 116B 11BA; +B410;B410;1103 116B 11BB;B410;1103 116B 11BB; +B411;B411;1103 116B 11BC;B411;1103 116B 11BC; +B412;B412;1103 116B 11BD;B412;1103 116B 11BD; +B413;B413;1103 116B 11BE;B413;1103 116B 11BE; +B414;B414;1103 116B 11BF;B414;1103 116B 11BF; +B415;B415;1103 116B 11C0;B415;1103 116B 11C0; +B416;B416;1103 116B 11C1;B416;1103 116B 11C1; +B417;B417;1103 116B 11C2;B417;1103 116B 11C2; +B418;B418;1103 116C;B418;1103 116C; +B419;B419;1103 116C 11A8;B419;1103 116C 11A8; +B41A;B41A;1103 116C 11A9;B41A;1103 116C 11A9; +B41B;B41B;1103 116C 11AA;B41B;1103 116C 11AA; +B41C;B41C;1103 116C 11AB;B41C;1103 116C 11AB; +B41D;B41D;1103 116C 11AC;B41D;1103 116C 11AC; +B41E;B41E;1103 116C 11AD;B41E;1103 116C 11AD; +B41F;B41F;1103 116C 11AE;B41F;1103 116C 11AE; +B420;B420;1103 116C 11AF;B420;1103 116C 11AF; +B421;B421;1103 116C 11B0;B421;1103 116C 11B0; +B422;B422;1103 116C 11B1;B422;1103 116C 11B1; +B423;B423;1103 116C 11B2;B423;1103 116C 11B2; +B424;B424;1103 116C 11B3;B424;1103 116C 11B3; +B425;B425;1103 116C 11B4;B425;1103 116C 11B4; +B426;B426;1103 116C 11B5;B426;1103 116C 11B5; +B427;B427;1103 116C 11B6;B427;1103 116C 11B6; +B428;B428;1103 116C 11B7;B428;1103 116C 11B7; +B429;B429;1103 116C 11B8;B429;1103 116C 11B8; +B42A;B42A;1103 116C 11B9;B42A;1103 116C 11B9; +B42B;B42B;1103 116C 11BA;B42B;1103 116C 11BA; +B42C;B42C;1103 116C 11BB;B42C;1103 116C 11BB; +B42D;B42D;1103 116C 11BC;B42D;1103 116C 11BC; +B42E;B42E;1103 116C 11BD;B42E;1103 116C 11BD; +B42F;B42F;1103 116C 11BE;B42F;1103 116C 11BE; +B430;B430;1103 116C 11BF;B430;1103 116C 11BF; +B431;B431;1103 116C 11C0;B431;1103 116C 11C0; +B432;B432;1103 116C 11C1;B432;1103 116C 11C1; +B433;B433;1103 116C 11C2;B433;1103 116C 11C2; +B434;B434;1103 116D;B434;1103 116D; +B435;B435;1103 116D 11A8;B435;1103 116D 11A8; +B436;B436;1103 116D 11A9;B436;1103 116D 11A9; +B437;B437;1103 116D 11AA;B437;1103 116D 11AA; +B438;B438;1103 116D 11AB;B438;1103 116D 11AB; +B439;B439;1103 116D 11AC;B439;1103 116D 11AC; +B43A;B43A;1103 116D 11AD;B43A;1103 116D 11AD; +B43B;B43B;1103 116D 11AE;B43B;1103 116D 11AE; +B43C;B43C;1103 116D 11AF;B43C;1103 116D 11AF; +B43D;B43D;1103 116D 11B0;B43D;1103 116D 11B0; +B43E;B43E;1103 116D 11B1;B43E;1103 116D 11B1; +B43F;B43F;1103 116D 11B2;B43F;1103 116D 11B2; +B440;B440;1103 116D 11B3;B440;1103 116D 11B3; +B441;B441;1103 116D 11B4;B441;1103 116D 11B4; +B442;B442;1103 116D 11B5;B442;1103 116D 11B5; +B443;B443;1103 116D 11B6;B443;1103 116D 11B6; +B444;B444;1103 116D 11B7;B444;1103 116D 11B7; +B445;B445;1103 116D 11B8;B445;1103 116D 11B8; +B446;B446;1103 116D 11B9;B446;1103 116D 11B9; +B447;B447;1103 116D 11BA;B447;1103 116D 11BA; +B448;B448;1103 116D 11BB;B448;1103 116D 11BB; +B449;B449;1103 116D 11BC;B449;1103 116D 11BC; +B44A;B44A;1103 116D 11BD;B44A;1103 116D 11BD; +B44B;B44B;1103 116D 11BE;B44B;1103 116D 11BE; +B44C;B44C;1103 116D 11BF;B44C;1103 116D 11BF; +B44D;B44D;1103 116D 11C0;B44D;1103 116D 11C0; +B44E;B44E;1103 116D 11C1;B44E;1103 116D 11C1; +B44F;B44F;1103 116D 11C2;B44F;1103 116D 11C2; +B450;B450;1103 116E;B450;1103 116E; +B451;B451;1103 116E 11A8;B451;1103 116E 11A8; +B452;B452;1103 116E 11A9;B452;1103 116E 11A9; +B453;B453;1103 116E 11AA;B453;1103 116E 11AA; +B454;B454;1103 116E 11AB;B454;1103 116E 11AB; +B455;B455;1103 116E 11AC;B455;1103 116E 11AC; +B456;B456;1103 116E 11AD;B456;1103 116E 11AD; +B457;B457;1103 116E 11AE;B457;1103 116E 11AE; +B458;B458;1103 116E 11AF;B458;1103 116E 11AF; +B459;B459;1103 116E 11B0;B459;1103 116E 11B0; +B45A;B45A;1103 116E 11B1;B45A;1103 116E 11B1; +B45B;B45B;1103 116E 11B2;B45B;1103 116E 11B2; +B45C;B45C;1103 116E 11B3;B45C;1103 116E 11B3; +B45D;B45D;1103 116E 11B4;B45D;1103 116E 11B4; +B45E;B45E;1103 116E 11B5;B45E;1103 116E 11B5; +B45F;B45F;1103 116E 11B6;B45F;1103 116E 11B6; +B460;B460;1103 116E 11B7;B460;1103 116E 11B7; +B461;B461;1103 116E 11B8;B461;1103 116E 11B8; +B462;B462;1103 116E 11B9;B462;1103 116E 11B9; +B463;B463;1103 116E 11BA;B463;1103 116E 11BA; +B464;B464;1103 116E 11BB;B464;1103 116E 11BB; +B465;B465;1103 116E 11BC;B465;1103 116E 11BC; +B466;B466;1103 116E 11BD;B466;1103 116E 11BD; +B467;B467;1103 116E 11BE;B467;1103 116E 11BE; +B468;B468;1103 116E 11BF;B468;1103 116E 11BF; +B469;B469;1103 116E 11C0;B469;1103 116E 11C0; +B46A;B46A;1103 116E 11C1;B46A;1103 116E 11C1; +B46B;B46B;1103 116E 11C2;B46B;1103 116E 11C2; +B46C;B46C;1103 116F;B46C;1103 116F; +B46D;B46D;1103 116F 11A8;B46D;1103 116F 11A8; +B46E;B46E;1103 116F 11A9;B46E;1103 116F 11A9; +B46F;B46F;1103 116F 11AA;B46F;1103 116F 11AA; +B470;B470;1103 116F 11AB;B470;1103 116F 11AB; +B471;B471;1103 116F 11AC;B471;1103 116F 11AC; +B472;B472;1103 116F 11AD;B472;1103 116F 11AD; +B473;B473;1103 116F 11AE;B473;1103 116F 11AE; +B474;B474;1103 116F 11AF;B474;1103 116F 11AF; +B475;B475;1103 116F 11B0;B475;1103 116F 11B0; +B476;B476;1103 116F 11B1;B476;1103 116F 11B1; +B477;B477;1103 116F 11B2;B477;1103 116F 11B2; +B478;B478;1103 116F 11B3;B478;1103 116F 11B3; +B479;B479;1103 116F 11B4;B479;1103 116F 11B4; +B47A;B47A;1103 116F 11B5;B47A;1103 116F 11B5; +B47B;B47B;1103 116F 11B6;B47B;1103 116F 11B6; +B47C;B47C;1103 116F 11B7;B47C;1103 116F 11B7; +B47D;B47D;1103 116F 11B8;B47D;1103 116F 11B8; +B47E;B47E;1103 116F 11B9;B47E;1103 116F 11B9; +B47F;B47F;1103 116F 11BA;B47F;1103 116F 11BA; +B480;B480;1103 116F 11BB;B480;1103 116F 11BB; +B481;B481;1103 116F 11BC;B481;1103 116F 11BC; +B482;B482;1103 116F 11BD;B482;1103 116F 11BD; +B483;B483;1103 116F 11BE;B483;1103 116F 11BE; +B484;B484;1103 116F 11BF;B484;1103 116F 11BF; +B485;B485;1103 116F 11C0;B485;1103 116F 11C0; +B486;B486;1103 116F 11C1;B486;1103 116F 11C1; +B487;B487;1103 116F 11C2;B487;1103 116F 11C2; +B488;B488;1103 1170;B488;1103 1170; +B489;B489;1103 1170 11A8;B489;1103 1170 11A8; +B48A;B48A;1103 1170 11A9;B48A;1103 1170 11A9; +B48B;B48B;1103 1170 11AA;B48B;1103 1170 11AA; +B48C;B48C;1103 1170 11AB;B48C;1103 1170 11AB; +B48D;B48D;1103 1170 11AC;B48D;1103 1170 11AC; +B48E;B48E;1103 1170 11AD;B48E;1103 1170 11AD; +B48F;B48F;1103 1170 11AE;B48F;1103 1170 11AE; +B490;B490;1103 1170 11AF;B490;1103 1170 11AF; +B491;B491;1103 1170 11B0;B491;1103 1170 11B0; +B492;B492;1103 1170 11B1;B492;1103 1170 11B1; +B493;B493;1103 1170 11B2;B493;1103 1170 11B2; +B494;B494;1103 1170 11B3;B494;1103 1170 11B3; +B495;B495;1103 1170 11B4;B495;1103 1170 11B4; +B496;B496;1103 1170 11B5;B496;1103 1170 11B5; +B497;B497;1103 1170 11B6;B497;1103 1170 11B6; +B498;B498;1103 1170 11B7;B498;1103 1170 11B7; +B499;B499;1103 1170 11B8;B499;1103 1170 11B8; +B49A;B49A;1103 1170 11B9;B49A;1103 1170 11B9; +B49B;B49B;1103 1170 11BA;B49B;1103 1170 11BA; +B49C;B49C;1103 1170 11BB;B49C;1103 1170 11BB; +B49D;B49D;1103 1170 11BC;B49D;1103 1170 11BC; +B49E;B49E;1103 1170 11BD;B49E;1103 1170 11BD; +B49F;B49F;1103 1170 11BE;B49F;1103 1170 11BE; +B4A0;B4A0;1103 1170 11BF;B4A0;1103 1170 11BF; +B4A1;B4A1;1103 1170 11C0;B4A1;1103 1170 11C0; +B4A2;B4A2;1103 1170 11C1;B4A2;1103 1170 11C1; +B4A3;B4A3;1103 1170 11C2;B4A3;1103 1170 11C2; +B4A4;B4A4;1103 1171;B4A4;1103 1171; +B4A5;B4A5;1103 1171 11A8;B4A5;1103 1171 11A8; +B4A6;B4A6;1103 1171 11A9;B4A6;1103 1171 11A9; +B4A7;B4A7;1103 1171 11AA;B4A7;1103 1171 11AA; +B4A8;B4A8;1103 1171 11AB;B4A8;1103 1171 11AB; +B4A9;B4A9;1103 1171 11AC;B4A9;1103 1171 11AC; +B4AA;B4AA;1103 1171 11AD;B4AA;1103 1171 11AD; +B4AB;B4AB;1103 1171 11AE;B4AB;1103 1171 11AE; +B4AC;B4AC;1103 1171 11AF;B4AC;1103 1171 11AF; +B4AD;B4AD;1103 1171 11B0;B4AD;1103 1171 11B0; +B4AE;B4AE;1103 1171 11B1;B4AE;1103 1171 11B1; +B4AF;B4AF;1103 1171 11B2;B4AF;1103 1171 11B2; +B4B0;B4B0;1103 1171 11B3;B4B0;1103 1171 11B3; +B4B1;B4B1;1103 1171 11B4;B4B1;1103 1171 11B4; +B4B2;B4B2;1103 1171 11B5;B4B2;1103 1171 11B5; +B4B3;B4B3;1103 1171 11B6;B4B3;1103 1171 11B6; +B4B4;B4B4;1103 1171 11B7;B4B4;1103 1171 11B7; +B4B5;B4B5;1103 1171 11B8;B4B5;1103 1171 11B8; +B4B6;B4B6;1103 1171 11B9;B4B6;1103 1171 11B9; +B4B7;B4B7;1103 1171 11BA;B4B7;1103 1171 11BA; +B4B8;B4B8;1103 1171 11BB;B4B8;1103 1171 11BB; +B4B9;B4B9;1103 1171 11BC;B4B9;1103 1171 11BC; +B4BA;B4BA;1103 1171 11BD;B4BA;1103 1171 11BD; +B4BB;B4BB;1103 1171 11BE;B4BB;1103 1171 11BE; +B4BC;B4BC;1103 1171 11BF;B4BC;1103 1171 11BF; +B4BD;B4BD;1103 1171 11C0;B4BD;1103 1171 11C0; +B4BE;B4BE;1103 1171 11C1;B4BE;1103 1171 11C1; +B4BF;B4BF;1103 1171 11C2;B4BF;1103 1171 11C2; +B4C0;B4C0;1103 1172;B4C0;1103 1172; +B4C1;B4C1;1103 1172 11A8;B4C1;1103 1172 11A8; +B4C2;B4C2;1103 1172 11A9;B4C2;1103 1172 11A9; +B4C3;B4C3;1103 1172 11AA;B4C3;1103 1172 11AA; +B4C4;B4C4;1103 1172 11AB;B4C4;1103 1172 11AB; +B4C5;B4C5;1103 1172 11AC;B4C5;1103 1172 11AC; +B4C6;B4C6;1103 1172 11AD;B4C6;1103 1172 11AD; +B4C7;B4C7;1103 1172 11AE;B4C7;1103 1172 11AE; +B4C8;B4C8;1103 1172 11AF;B4C8;1103 1172 11AF; +B4C9;B4C9;1103 1172 11B0;B4C9;1103 1172 11B0; +B4CA;B4CA;1103 1172 11B1;B4CA;1103 1172 11B1; +B4CB;B4CB;1103 1172 11B2;B4CB;1103 1172 11B2; +B4CC;B4CC;1103 1172 11B3;B4CC;1103 1172 11B3; +B4CD;B4CD;1103 1172 11B4;B4CD;1103 1172 11B4; +B4CE;B4CE;1103 1172 11B5;B4CE;1103 1172 11B5; +B4CF;B4CF;1103 1172 11B6;B4CF;1103 1172 11B6; +B4D0;B4D0;1103 1172 11B7;B4D0;1103 1172 11B7; +B4D1;B4D1;1103 1172 11B8;B4D1;1103 1172 11B8; +B4D2;B4D2;1103 1172 11B9;B4D2;1103 1172 11B9; +B4D3;B4D3;1103 1172 11BA;B4D3;1103 1172 11BA; +B4D4;B4D4;1103 1172 11BB;B4D4;1103 1172 11BB; +B4D5;B4D5;1103 1172 11BC;B4D5;1103 1172 11BC; +B4D6;B4D6;1103 1172 11BD;B4D6;1103 1172 11BD; +B4D7;B4D7;1103 1172 11BE;B4D7;1103 1172 11BE; +B4D8;B4D8;1103 1172 11BF;B4D8;1103 1172 11BF; +B4D9;B4D9;1103 1172 11C0;B4D9;1103 1172 11C0; +B4DA;B4DA;1103 1172 11C1;B4DA;1103 1172 11C1; +B4DB;B4DB;1103 1172 11C2;B4DB;1103 1172 11C2; +B4DC;B4DC;1103 1173;B4DC;1103 1173; +B4DD;B4DD;1103 1173 11A8;B4DD;1103 1173 11A8; +B4DE;B4DE;1103 1173 11A9;B4DE;1103 1173 11A9; +B4DF;B4DF;1103 1173 11AA;B4DF;1103 1173 11AA; +B4E0;B4E0;1103 1173 11AB;B4E0;1103 1173 11AB; +B4E1;B4E1;1103 1173 11AC;B4E1;1103 1173 11AC; +B4E2;B4E2;1103 1173 11AD;B4E2;1103 1173 11AD; +B4E3;B4E3;1103 1173 11AE;B4E3;1103 1173 11AE; +B4E4;B4E4;1103 1173 11AF;B4E4;1103 1173 11AF; +B4E5;B4E5;1103 1173 11B0;B4E5;1103 1173 11B0; +B4E6;B4E6;1103 1173 11B1;B4E6;1103 1173 11B1; +B4E7;B4E7;1103 1173 11B2;B4E7;1103 1173 11B2; +B4E8;B4E8;1103 1173 11B3;B4E8;1103 1173 11B3; +B4E9;B4E9;1103 1173 11B4;B4E9;1103 1173 11B4; +B4EA;B4EA;1103 1173 11B5;B4EA;1103 1173 11B5; +B4EB;B4EB;1103 1173 11B6;B4EB;1103 1173 11B6; +B4EC;B4EC;1103 1173 11B7;B4EC;1103 1173 11B7; +B4ED;B4ED;1103 1173 11B8;B4ED;1103 1173 11B8; +B4EE;B4EE;1103 1173 11B9;B4EE;1103 1173 11B9; +B4EF;B4EF;1103 1173 11BA;B4EF;1103 1173 11BA; +B4F0;B4F0;1103 1173 11BB;B4F0;1103 1173 11BB; +B4F1;B4F1;1103 1173 11BC;B4F1;1103 1173 11BC; +B4F2;B4F2;1103 1173 11BD;B4F2;1103 1173 11BD; +B4F3;B4F3;1103 1173 11BE;B4F3;1103 1173 11BE; +B4F4;B4F4;1103 1173 11BF;B4F4;1103 1173 11BF; +B4F5;B4F5;1103 1173 11C0;B4F5;1103 1173 11C0; +B4F6;B4F6;1103 1173 11C1;B4F6;1103 1173 11C1; +B4F7;B4F7;1103 1173 11C2;B4F7;1103 1173 11C2; +B4F8;B4F8;1103 1174;B4F8;1103 1174; +B4F9;B4F9;1103 1174 11A8;B4F9;1103 1174 11A8; +B4FA;B4FA;1103 1174 11A9;B4FA;1103 1174 11A9; +B4FB;B4FB;1103 1174 11AA;B4FB;1103 1174 11AA; +B4FC;B4FC;1103 1174 11AB;B4FC;1103 1174 11AB; +B4FD;B4FD;1103 1174 11AC;B4FD;1103 1174 11AC; +B4FE;B4FE;1103 1174 11AD;B4FE;1103 1174 11AD; +B4FF;B4FF;1103 1174 11AE;B4FF;1103 1174 11AE; +B500;B500;1103 1174 11AF;B500;1103 1174 11AF; +B501;B501;1103 1174 11B0;B501;1103 1174 11B0; +B502;B502;1103 1174 11B1;B502;1103 1174 11B1; +B503;B503;1103 1174 11B2;B503;1103 1174 11B2; +B504;B504;1103 1174 11B3;B504;1103 1174 11B3; +B505;B505;1103 1174 11B4;B505;1103 1174 11B4; +B506;B506;1103 1174 11B5;B506;1103 1174 11B5; +B507;B507;1103 1174 11B6;B507;1103 1174 11B6; +B508;B508;1103 1174 11B7;B508;1103 1174 11B7; +B509;B509;1103 1174 11B8;B509;1103 1174 11B8; +B50A;B50A;1103 1174 11B9;B50A;1103 1174 11B9; +B50B;B50B;1103 1174 11BA;B50B;1103 1174 11BA; +B50C;B50C;1103 1174 11BB;B50C;1103 1174 11BB; +B50D;B50D;1103 1174 11BC;B50D;1103 1174 11BC; +B50E;B50E;1103 1174 11BD;B50E;1103 1174 11BD; +B50F;B50F;1103 1174 11BE;B50F;1103 1174 11BE; +B510;B510;1103 1174 11BF;B510;1103 1174 11BF; +B511;B511;1103 1174 11C0;B511;1103 1174 11C0; +B512;B512;1103 1174 11C1;B512;1103 1174 11C1; +B513;B513;1103 1174 11C2;B513;1103 1174 11C2; +B514;B514;1103 1175;B514;1103 1175; +B515;B515;1103 1175 11A8;B515;1103 1175 11A8; +B516;B516;1103 1175 11A9;B516;1103 1175 11A9; +B517;B517;1103 1175 11AA;B517;1103 1175 11AA; +B518;B518;1103 1175 11AB;B518;1103 1175 11AB; +B519;B519;1103 1175 11AC;B519;1103 1175 11AC; +B51A;B51A;1103 1175 11AD;B51A;1103 1175 11AD; +B51B;B51B;1103 1175 11AE;B51B;1103 1175 11AE; +B51C;B51C;1103 1175 11AF;B51C;1103 1175 11AF; +B51D;B51D;1103 1175 11B0;B51D;1103 1175 11B0; +B51E;B51E;1103 1175 11B1;B51E;1103 1175 11B1; +B51F;B51F;1103 1175 11B2;B51F;1103 1175 11B2; +B520;B520;1103 1175 11B3;B520;1103 1175 11B3; +B521;B521;1103 1175 11B4;B521;1103 1175 11B4; +B522;B522;1103 1175 11B5;B522;1103 1175 11B5; +B523;B523;1103 1175 11B6;B523;1103 1175 11B6; +B524;B524;1103 1175 11B7;B524;1103 1175 11B7; +B525;B525;1103 1175 11B8;B525;1103 1175 11B8; +B526;B526;1103 1175 11B9;B526;1103 1175 11B9; +B527;B527;1103 1175 11BA;B527;1103 1175 11BA; +B528;B528;1103 1175 11BB;B528;1103 1175 11BB; +B529;B529;1103 1175 11BC;B529;1103 1175 11BC; +B52A;B52A;1103 1175 11BD;B52A;1103 1175 11BD; +B52B;B52B;1103 1175 11BE;B52B;1103 1175 11BE; +B52C;B52C;1103 1175 11BF;B52C;1103 1175 11BF; +B52D;B52D;1103 1175 11C0;B52D;1103 1175 11C0; +B52E;B52E;1103 1175 11C1;B52E;1103 1175 11C1; +B52F;B52F;1103 1175 11C2;B52F;1103 1175 11C2; +B530;B530;1104 1161;B530;1104 1161; +B531;B531;1104 1161 11A8;B531;1104 1161 11A8; +B532;B532;1104 1161 11A9;B532;1104 1161 11A9; +B533;B533;1104 1161 11AA;B533;1104 1161 11AA; +B534;B534;1104 1161 11AB;B534;1104 1161 11AB; +B535;B535;1104 1161 11AC;B535;1104 1161 11AC; +B536;B536;1104 1161 11AD;B536;1104 1161 11AD; +B537;B537;1104 1161 11AE;B537;1104 1161 11AE; +B538;B538;1104 1161 11AF;B538;1104 1161 11AF; +B539;B539;1104 1161 11B0;B539;1104 1161 11B0; +B53A;B53A;1104 1161 11B1;B53A;1104 1161 11B1; +B53B;B53B;1104 1161 11B2;B53B;1104 1161 11B2; +B53C;B53C;1104 1161 11B3;B53C;1104 1161 11B3; +B53D;B53D;1104 1161 11B4;B53D;1104 1161 11B4; +B53E;B53E;1104 1161 11B5;B53E;1104 1161 11B5; +B53F;B53F;1104 1161 11B6;B53F;1104 1161 11B6; +B540;B540;1104 1161 11B7;B540;1104 1161 11B7; +B541;B541;1104 1161 11B8;B541;1104 1161 11B8; +B542;B542;1104 1161 11B9;B542;1104 1161 11B9; +B543;B543;1104 1161 11BA;B543;1104 1161 11BA; +B544;B544;1104 1161 11BB;B544;1104 1161 11BB; +B545;B545;1104 1161 11BC;B545;1104 1161 11BC; +B546;B546;1104 1161 11BD;B546;1104 1161 11BD; +B547;B547;1104 1161 11BE;B547;1104 1161 11BE; +B548;B548;1104 1161 11BF;B548;1104 1161 11BF; +B549;B549;1104 1161 11C0;B549;1104 1161 11C0; +B54A;B54A;1104 1161 11C1;B54A;1104 1161 11C1; +B54B;B54B;1104 1161 11C2;B54B;1104 1161 11C2; +B54C;B54C;1104 1162;B54C;1104 1162; +B54D;B54D;1104 1162 11A8;B54D;1104 1162 11A8; +B54E;B54E;1104 1162 11A9;B54E;1104 1162 11A9; +B54F;B54F;1104 1162 11AA;B54F;1104 1162 11AA; +B550;B550;1104 1162 11AB;B550;1104 1162 11AB; +B551;B551;1104 1162 11AC;B551;1104 1162 11AC; +B552;B552;1104 1162 11AD;B552;1104 1162 11AD; +B553;B553;1104 1162 11AE;B553;1104 1162 11AE; +B554;B554;1104 1162 11AF;B554;1104 1162 11AF; +B555;B555;1104 1162 11B0;B555;1104 1162 11B0; +B556;B556;1104 1162 11B1;B556;1104 1162 11B1; +B557;B557;1104 1162 11B2;B557;1104 1162 11B2; +B558;B558;1104 1162 11B3;B558;1104 1162 11B3; +B559;B559;1104 1162 11B4;B559;1104 1162 11B4; +B55A;B55A;1104 1162 11B5;B55A;1104 1162 11B5; +B55B;B55B;1104 1162 11B6;B55B;1104 1162 11B6; +B55C;B55C;1104 1162 11B7;B55C;1104 1162 11B7; +B55D;B55D;1104 1162 11B8;B55D;1104 1162 11B8; +B55E;B55E;1104 1162 11B9;B55E;1104 1162 11B9; +B55F;B55F;1104 1162 11BA;B55F;1104 1162 11BA; +B560;B560;1104 1162 11BB;B560;1104 1162 11BB; +B561;B561;1104 1162 11BC;B561;1104 1162 11BC; +B562;B562;1104 1162 11BD;B562;1104 1162 11BD; +B563;B563;1104 1162 11BE;B563;1104 1162 11BE; +B564;B564;1104 1162 11BF;B564;1104 1162 11BF; +B565;B565;1104 1162 11C0;B565;1104 1162 11C0; +B566;B566;1104 1162 11C1;B566;1104 1162 11C1; +B567;B567;1104 1162 11C2;B567;1104 1162 11C2; +B568;B568;1104 1163;B568;1104 1163; +B569;B569;1104 1163 11A8;B569;1104 1163 11A8; +B56A;B56A;1104 1163 11A9;B56A;1104 1163 11A9; +B56B;B56B;1104 1163 11AA;B56B;1104 1163 11AA; +B56C;B56C;1104 1163 11AB;B56C;1104 1163 11AB; +B56D;B56D;1104 1163 11AC;B56D;1104 1163 11AC; +B56E;B56E;1104 1163 11AD;B56E;1104 1163 11AD; +B56F;B56F;1104 1163 11AE;B56F;1104 1163 11AE; +B570;B570;1104 1163 11AF;B570;1104 1163 11AF; +B571;B571;1104 1163 11B0;B571;1104 1163 11B0; +B572;B572;1104 1163 11B1;B572;1104 1163 11B1; +B573;B573;1104 1163 11B2;B573;1104 1163 11B2; +B574;B574;1104 1163 11B3;B574;1104 1163 11B3; +B575;B575;1104 1163 11B4;B575;1104 1163 11B4; +B576;B576;1104 1163 11B5;B576;1104 1163 11B5; +B577;B577;1104 1163 11B6;B577;1104 1163 11B6; +B578;B578;1104 1163 11B7;B578;1104 1163 11B7; +B579;B579;1104 1163 11B8;B579;1104 1163 11B8; +B57A;B57A;1104 1163 11B9;B57A;1104 1163 11B9; +B57B;B57B;1104 1163 11BA;B57B;1104 1163 11BA; +B57C;B57C;1104 1163 11BB;B57C;1104 1163 11BB; +B57D;B57D;1104 1163 11BC;B57D;1104 1163 11BC; +B57E;B57E;1104 1163 11BD;B57E;1104 1163 11BD; +B57F;B57F;1104 1163 11BE;B57F;1104 1163 11BE; +B580;B580;1104 1163 11BF;B580;1104 1163 11BF; +B581;B581;1104 1163 11C0;B581;1104 1163 11C0; +B582;B582;1104 1163 11C1;B582;1104 1163 11C1; +B583;B583;1104 1163 11C2;B583;1104 1163 11C2; +B584;B584;1104 1164;B584;1104 1164; +B585;B585;1104 1164 11A8;B585;1104 1164 11A8; +B586;B586;1104 1164 11A9;B586;1104 1164 11A9; +B587;B587;1104 1164 11AA;B587;1104 1164 11AA; +B588;B588;1104 1164 11AB;B588;1104 1164 11AB; +B589;B589;1104 1164 11AC;B589;1104 1164 11AC; +B58A;B58A;1104 1164 11AD;B58A;1104 1164 11AD; +B58B;B58B;1104 1164 11AE;B58B;1104 1164 11AE; +B58C;B58C;1104 1164 11AF;B58C;1104 1164 11AF; +B58D;B58D;1104 1164 11B0;B58D;1104 1164 11B0; +B58E;B58E;1104 1164 11B1;B58E;1104 1164 11B1; +B58F;B58F;1104 1164 11B2;B58F;1104 1164 11B2; +B590;B590;1104 1164 11B3;B590;1104 1164 11B3; +B591;B591;1104 1164 11B4;B591;1104 1164 11B4; +B592;B592;1104 1164 11B5;B592;1104 1164 11B5; +B593;B593;1104 1164 11B6;B593;1104 1164 11B6; +B594;B594;1104 1164 11B7;B594;1104 1164 11B7; +B595;B595;1104 1164 11B8;B595;1104 1164 11B8; +B596;B596;1104 1164 11B9;B596;1104 1164 11B9; +B597;B597;1104 1164 11BA;B597;1104 1164 11BA; +B598;B598;1104 1164 11BB;B598;1104 1164 11BB; +B599;B599;1104 1164 11BC;B599;1104 1164 11BC; +B59A;B59A;1104 1164 11BD;B59A;1104 1164 11BD; +B59B;B59B;1104 1164 11BE;B59B;1104 1164 11BE; +B59C;B59C;1104 1164 11BF;B59C;1104 1164 11BF; +B59D;B59D;1104 1164 11C0;B59D;1104 1164 11C0; +B59E;B59E;1104 1164 11C1;B59E;1104 1164 11C1; +B59F;B59F;1104 1164 11C2;B59F;1104 1164 11C2; +B5A0;B5A0;1104 1165;B5A0;1104 1165; +B5A1;B5A1;1104 1165 11A8;B5A1;1104 1165 11A8; +B5A2;B5A2;1104 1165 11A9;B5A2;1104 1165 11A9; +B5A3;B5A3;1104 1165 11AA;B5A3;1104 1165 11AA; +B5A4;B5A4;1104 1165 11AB;B5A4;1104 1165 11AB; +B5A5;B5A5;1104 1165 11AC;B5A5;1104 1165 11AC; +B5A6;B5A6;1104 1165 11AD;B5A6;1104 1165 11AD; +B5A7;B5A7;1104 1165 11AE;B5A7;1104 1165 11AE; +B5A8;B5A8;1104 1165 11AF;B5A8;1104 1165 11AF; +B5A9;B5A9;1104 1165 11B0;B5A9;1104 1165 11B0; +B5AA;B5AA;1104 1165 11B1;B5AA;1104 1165 11B1; +B5AB;B5AB;1104 1165 11B2;B5AB;1104 1165 11B2; +B5AC;B5AC;1104 1165 11B3;B5AC;1104 1165 11B3; +B5AD;B5AD;1104 1165 11B4;B5AD;1104 1165 11B4; +B5AE;B5AE;1104 1165 11B5;B5AE;1104 1165 11B5; +B5AF;B5AF;1104 1165 11B6;B5AF;1104 1165 11B6; +B5B0;B5B0;1104 1165 11B7;B5B0;1104 1165 11B7; +B5B1;B5B1;1104 1165 11B8;B5B1;1104 1165 11B8; +B5B2;B5B2;1104 1165 11B9;B5B2;1104 1165 11B9; +B5B3;B5B3;1104 1165 11BA;B5B3;1104 1165 11BA; +B5B4;B5B4;1104 1165 11BB;B5B4;1104 1165 11BB; +B5B5;B5B5;1104 1165 11BC;B5B5;1104 1165 11BC; +B5B6;B5B6;1104 1165 11BD;B5B6;1104 1165 11BD; +B5B7;B5B7;1104 1165 11BE;B5B7;1104 1165 11BE; +B5B8;B5B8;1104 1165 11BF;B5B8;1104 1165 11BF; +B5B9;B5B9;1104 1165 11C0;B5B9;1104 1165 11C0; +B5BA;B5BA;1104 1165 11C1;B5BA;1104 1165 11C1; +B5BB;B5BB;1104 1165 11C2;B5BB;1104 1165 11C2; +B5BC;B5BC;1104 1166;B5BC;1104 1166; +B5BD;B5BD;1104 1166 11A8;B5BD;1104 1166 11A8; +B5BE;B5BE;1104 1166 11A9;B5BE;1104 1166 11A9; +B5BF;B5BF;1104 1166 11AA;B5BF;1104 1166 11AA; +B5C0;B5C0;1104 1166 11AB;B5C0;1104 1166 11AB; +B5C1;B5C1;1104 1166 11AC;B5C1;1104 1166 11AC; +B5C2;B5C2;1104 1166 11AD;B5C2;1104 1166 11AD; +B5C3;B5C3;1104 1166 11AE;B5C3;1104 1166 11AE; +B5C4;B5C4;1104 1166 11AF;B5C4;1104 1166 11AF; +B5C5;B5C5;1104 1166 11B0;B5C5;1104 1166 11B0; +B5C6;B5C6;1104 1166 11B1;B5C6;1104 1166 11B1; +B5C7;B5C7;1104 1166 11B2;B5C7;1104 1166 11B2; +B5C8;B5C8;1104 1166 11B3;B5C8;1104 1166 11B3; +B5C9;B5C9;1104 1166 11B4;B5C9;1104 1166 11B4; +B5CA;B5CA;1104 1166 11B5;B5CA;1104 1166 11B5; +B5CB;B5CB;1104 1166 11B6;B5CB;1104 1166 11B6; +B5CC;B5CC;1104 1166 11B7;B5CC;1104 1166 11B7; +B5CD;B5CD;1104 1166 11B8;B5CD;1104 1166 11B8; +B5CE;B5CE;1104 1166 11B9;B5CE;1104 1166 11B9; +B5CF;B5CF;1104 1166 11BA;B5CF;1104 1166 11BA; +B5D0;B5D0;1104 1166 11BB;B5D0;1104 1166 11BB; +B5D1;B5D1;1104 1166 11BC;B5D1;1104 1166 11BC; +B5D2;B5D2;1104 1166 11BD;B5D2;1104 1166 11BD; +B5D3;B5D3;1104 1166 11BE;B5D3;1104 1166 11BE; +B5D4;B5D4;1104 1166 11BF;B5D4;1104 1166 11BF; +B5D5;B5D5;1104 1166 11C0;B5D5;1104 1166 11C0; +B5D6;B5D6;1104 1166 11C1;B5D6;1104 1166 11C1; +B5D7;B5D7;1104 1166 11C2;B5D7;1104 1166 11C2; +B5D8;B5D8;1104 1167;B5D8;1104 1167; +B5D9;B5D9;1104 1167 11A8;B5D9;1104 1167 11A8; +B5DA;B5DA;1104 1167 11A9;B5DA;1104 1167 11A9; +B5DB;B5DB;1104 1167 11AA;B5DB;1104 1167 11AA; +B5DC;B5DC;1104 1167 11AB;B5DC;1104 1167 11AB; +B5DD;B5DD;1104 1167 11AC;B5DD;1104 1167 11AC; +B5DE;B5DE;1104 1167 11AD;B5DE;1104 1167 11AD; +B5DF;B5DF;1104 1167 11AE;B5DF;1104 1167 11AE; +B5E0;B5E0;1104 1167 11AF;B5E0;1104 1167 11AF; +B5E1;B5E1;1104 1167 11B0;B5E1;1104 1167 11B0; +B5E2;B5E2;1104 1167 11B1;B5E2;1104 1167 11B1; +B5E3;B5E3;1104 1167 11B2;B5E3;1104 1167 11B2; +B5E4;B5E4;1104 1167 11B3;B5E4;1104 1167 11B3; +B5E5;B5E5;1104 1167 11B4;B5E5;1104 1167 11B4; +B5E6;B5E6;1104 1167 11B5;B5E6;1104 1167 11B5; +B5E7;B5E7;1104 1167 11B6;B5E7;1104 1167 11B6; +B5E8;B5E8;1104 1167 11B7;B5E8;1104 1167 11B7; +B5E9;B5E9;1104 1167 11B8;B5E9;1104 1167 11B8; +B5EA;B5EA;1104 1167 11B9;B5EA;1104 1167 11B9; +B5EB;B5EB;1104 1167 11BA;B5EB;1104 1167 11BA; +B5EC;B5EC;1104 1167 11BB;B5EC;1104 1167 11BB; +B5ED;B5ED;1104 1167 11BC;B5ED;1104 1167 11BC; +B5EE;B5EE;1104 1167 11BD;B5EE;1104 1167 11BD; +B5EF;B5EF;1104 1167 11BE;B5EF;1104 1167 11BE; +B5F0;B5F0;1104 1167 11BF;B5F0;1104 1167 11BF; +B5F1;B5F1;1104 1167 11C0;B5F1;1104 1167 11C0; +B5F2;B5F2;1104 1167 11C1;B5F2;1104 1167 11C1; +B5F3;B5F3;1104 1167 11C2;B5F3;1104 1167 11C2; +B5F4;B5F4;1104 1168;B5F4;1104 1168; +B5F5;B5F5;1104 1168 11A8;B5F5;1104 1168 11A8; +B5F6;B5F6;1104 1168 11A9;B5F6;1104 1168 11A9; +B5F7;B5F7;1104 1168 11AA;B5F7;1104 1168 11AA; +B5F8;B5F8;1104 1168 11AB;B5F8;1104 1168 11AB; +B5F9;B5F9;1104 1168 11AC;B5F9;1104 1168 11AC; +B5FA;B5FA;1104 1168 11AD;B5FA;1104 1168 11AD; +B5FB;B5FB;1104 1168 11AE;B5FB;1104 1168 11AE; +B5FC;B5FC;1104 1168 11AF;B5FC;1104 1168 11AF; +B5FD;B5FD;1104 1168 11B0;B5FD;1104 1168 11B0; +B5FE;B5FE;1104 1168 11B1;B5FE;1104 1168 11B1; +B5FF;B5FF;1104 1168 11B2;B5FF;1104 1168 11B2; +B600;B600;1104 1168 11B3;B600;1104 1168 11B3; +B601;B601;1104 1168 11B4;B601;1104 1168 11B4; +B602;B602;1104 1168 11B5;B602;1104 1168 11B5; +B603;B603;1104 1168 11B6;B603;1104 1168 11B6; +B604;B604;1104 1168 11B7;B604;1104 1168 11B7; +B605;B605;1104 1168 11B8;B605;1104 1168 11B8; +B606;B606;1104 1168 11B9;B606;1104 1168 11B9; +B607;B607;1104 1168 11BA;B607;1104 1168 11BA; +B608;B608;1104 1168 11BB;B608;1104 1168 11BB; +B609;B609;1104 1168 11BC;B609;1104 1168 11BC; +B60A;B60A;1104 1168 11BD;B60A;1104 1168 11BD; +B60B;B60B;1104 1168 11BE;B60B;1104 1168 11BE; +B60C;B60C;1104 1168 11BF;B60C;1104 1168 11BF; +B60D;B60D;1104 1168 11C0;B60D;1104 1168 11C0; +B60E;B60E;1104 1168 11C1;B60E;1104 1168 11C1; +B60F;B60F;1104 1168 11C2;B60F;1104 1168 11C2; +B610;B610;1104 1169;B610;1104 1169; +B611;B611;1104 1169 11A8;B611;1104 1169 11A8; +B612;B612;1104 1169 11A9;B612;1104 1169 11A9; +B613;B613;1104 1169 11AA;B613;1104 1169 11AA; +B614;B614;1104 1169 11AB;B614;1104 1169 11AB; +B615;B615;1104 1169 11AC;B615;1104 1169 11AC; +B616;B616;1104 1169 11AD;B616;1104 1169 11AD; +B617;B617;1104 1169 11AE;B617;1104 1169 11AE; +B618;B618;1104 1169 11AF;B618;1104 1169 11AF; +B619;B619;1104 1169 11B0;B619;1104 1169 11B0; +B61A;B61A;1104 1169 11B1;B61A;1104 1169 11B1; +B61B;B61B;1104 1169 11B2;B61B;1104 1169 11B2; +B61C;B61C;1104 1169 11B3;B61C;1104 1169 11B3; +B61D;B61D;1104 1169 11B4;B61D;1104 1169 11B4; +B61E;B61E;1104 1169 11B5;B61E;1104 1169 11B5; +B61F;B61F;1104 1169 11B6;B61F;1104 1169 11B6; +B620;B620;1104 1169 11B7;B620;1104 1169 11B7; +B621;B621;1104 1169 11B8;B621;1104 1169 11B8; +B622;B622;1104 1169 11B9;B622;1104 1169 11B9; +B623;B623;1104 1169 11BA;B623;1104 1169 11BA; +B624;B624;1104 1169 11BB;B624;1104 1169 11BB; +B625;B625;1104 1169 11BC;B625;1104 1169 11BC; +B626;B626;1104 1169 11BD;B626;1104 1169 11BD; +B627;B627;1104 1169 11BE;B627;1104 1169 11BE; +B628;B628;1104 1169 11BF;B628;1104 1169 11BF; +B629;B629;1104 1169 11C0;B629;1104 1169 11C0; +B62A;B62A;1104 1169 11C1;B62A;1104 1169 11C1; +B62B;B62B;1104 1169 11C2;B62B;1104 1169 11C2; +B62C;B62C;1104 116A;B62C;1104 116A; +B62D;B62D;1104 116A 11A8;B62D;1104 116A 11A8; +B62E;B62E;1104 116A 11A9;B62E;1104 116A 11A9; +B62F;B62F;1104 116A 11AA;B62F;1104 116A 11AA; +B630;B630;1104 116A 11AB;B630;1104 116A 11AB; +B631;B631;1104 116A 11AC;B631;1104 116A 11AC; +B632;B632;1104 116A 11AD;B632;1104 116A 11AD; +B633;B633;1104 116A 11AE;B633;1104 116A 11AE; +B634;B634;1104 116A 11AF;B634;1104 116A 11AF; +B635;B635;1104 116A 11B0;B635;1104 116A 11B0; +B636;B636;1104 116A 11B1;B636;1104 116A 11B1; +B637;B637;1104 116A 11B2;B637;1104 116A 11B2; +B638;B638;1104 116A 11B3;B638;1104 116A 11B3; +B639;B639;1104 116A 11B4;B639;1104 116A 11B4; +B63A;B63A;1104 116A 11B5;B63A;1104 116A 11B5; +B63B;B63B;1104 116A 11B6;B63B;1104 116A 11B6; +B63C;B63C;1104 116A 11B7;B63C;1104 116A 11B7; +B63D;B63D;1104 116A 11B8;B63D;1104 116A 11B8; +B63E;B63E;1104 116A 11B9;B63E;1104 116A 11B9; +B63F;B63F;1104 116A 11BA;B63F;1104 116A 11BA; +B640;B640;1104 116A 11BB;B640;1104 116A 11BB; +B641;B641;1104 116A 11BC;B641;1104 116A 11BC; +B642;B642;1104 116A 11BD;B642;1104 116A 11BD; +B643;B643;1104 116A 11BE;B643;1104 116A 11BE; +B644;B644;1104 116A 11BF;B644;1104 116A 11BF; +B645;B645;1104 116A 11C0;B645;1104 116A 11C0; +B646;B646;1104 116A 11C1;B646;1104 116A 11C1; +B647;B647;1104 116A 11C2;B647;1104 116A 11C2; +B648;B648;1104 116B;B648;1104 116B; +B649;B649;1104 116B 11A8;B649;1104 116B 11A8; +B64A;B64A;1104 116B 11A9;B64A;1104 116B 11A9; +B64B;B64B;1104 116B 11AA;B64B;1104 116B 11AA; +B64C;B64C;1104 116B 11AB;B64C;1104 116B 11AB; +B64D;B64D;1104 116B 11AC;B64D;1104 116B 11AC; +B64E;B64E;1104 116B 11AD;B64E;1104 116B 11AD; +B64F;B64F;1104 116B 11AE;B64F;1104 116B 11AE; +B650;B650;1104 116B 11AF;B650;1104 116B 11AF; +B651;B651;1104 116B 11B0;B651;1104 116B 11B0; +B652;B652;1104 116B 11B1;B652;1104 116B 11B1; +B653;B653;1104 116B 11B2;B653;1104 116B 11B2; +B654;B654;1104 116B 11B3;B654;1104 116B 11B3; +B655;B655;1104 116B 11B4;B655;1104 116B 11B4; +B656;B656;1104 116B 11B5;B656;1104 116B 11B5; +B657;B657;1104 116B 11B6;B657;1104 116B 11B6; +B658;B658;1104 116B 11B7;B658;1104 116B 11B7; +B659;B659;1104 116B 11B8;B659;1104 116B 11B8; +B65A;B65A;1104 116B 11B9;B65A;1104 116B 11B9; +B65B;B65B;1104 116B 11BA;B65B;1104 116B 11BA; +B65C;B65C;1104 116B 11BB;B65C;1104 116B 11BB; +B65D;B65D;1104 116B 11BC;B65D;1104 116B 11BC; +B65E;B65E;1104 116B 11BD;B65E;1104 116B 11BD; +B65F;B65F;1104 116B 11BE;B65F;1104 116B 11BE; +B660;B660;1104 116B 11BF;B660;1104 116B 11BF; +B661;B661;1104 116B 11C0;B661;1104 116B 11C0; +B662;B662;1104 116B 11C1;B662;1104 116B 11C1; +B663;B663;1104 116B 11C2;B663;1104 116B 11C2; +B664;B664;1104 116C;B664;1104 116C; +B665;B665;1104 116C 11A8;B665;1104 116C 11A8; +B666;B666;1104 116C 11A9;B666;1104 116C 11A9; +B667;B667;1104 116C 11AA;B667;1104 116C 11AA; +B668;B668;1104 116C 11AB;B668;1104 116C 11AB; +B669;B669;1104 116C 11AC;B669;1104 116C 11AC; +B66A;B66A;1104 116C 11AD;B66A;1104 116C 11AD; +B66B;B66B;1104 116C 11AE;B66B;1104 116C 11AE; +B66C;B66C;1104 116C 11AF;B66C;1104 116C 11AF; +B66D;B66D;1104 116C 11B0;B66D;1104 116C 11B0; +B66E;B66E;1104 116C 11B1;B66E;1104 116C 11B1; +B66F;B66F;1104 116C 11B2;B66F;1104 116C 11B2; +B670;B670;1104 116C 11B3;B670;1104 116C 11B3; +B671;B671;1104 116C 11B4;B671;1104 116C 11B4; +B672;B672;1104 116C 11B5;B672;1104 116C 11B5; +B673;B673;1104 116C 11B6;B673;1104 116C 11B6; +B674;B674;1104 116C 11B7;B674;1104 116C 11B7; +B675;B675;1104 116C 11B8;B675;1104 116C 11B8; +B676;B676;1104 116C 11B9;B676;1104 116C 11B9; +B677;B677;1104 116C 11BA;B677;1104 116C 11BA; +B678;B678;1104 116C 11BB;B678;1104 116C 11BB; +B679;B679;1104 116C 11BC;B679;1104 116C 11BC; +B67A;B67A;1104 116C 11BD;B67A;1104 116C 11BD; +B67B;B67B;1104 116C 11BE;B67B;1104 116C 11BE; +B67C;B67C;1104 116C 11BF;B67C;1104 116C 11BF; +B67D;B67D;1104 116C 11C0;B67D;1104 116C 11C0; +B67E;B67E;1104 116C 11C1;B67E;1104 116C 11C1; +B67F;B67F;1104 116C 11C2;B67F;1104 116C 11C2; +B680;B680;1104 116D;B680;1104 116D; +B681;B681;1104 116D 11A8;B681;1104 116D 11A8; +B682;B682;1104 116D 11A9;B682;1104 116D 11A9; +B683;B683;1104 116D 11AA;B683;1104 116D 11AA; +B684;B684;1104 116D 11AB;B684;1104 116D 11AB; +B685;B685;1104 116D 11AC;B685;1104 116D 11AC; +B686;B686;1104 116D 11AD;B686;1104 116D 11AD; +B687;B687;1104 116D 11AE;B687;1104 116D 11AE; +B688;B688;1104 116D 11AF;B688;1104 116D 11AF; +B689;B689;1104 116D 11B0;B689;1104 116D 11B0; +B68A;B68A;1104 116D 11B1;B68A;1104 116D 11B1; +B68B;B68B;1104 116D 11B2;B68B;1104 116D 11B2; +B68C;B68C;1104 116D 11B3;B68C;1104 116D 11B3; +B68D;B68D;1104 116D 11B4;B68D;1104 116D 11B4; +B68E;B68E;1104 116D 11B5;B68E;1104 116D 11B5; +B68F;B68F;1104 116D 11B6;B68F;1104 116D 11B6; +B690;B690;1104 116D 11B7;B690;1104 116D 11B7; +B691;B691;1104 116D 11B8;B691;1104 116D 11B8; +B692;B692;1104 116D 11B9;B692;1104 116D 11B9; +B693;B693;1104 116D 11BA;B693;1104 116D 11BA; +B694;B694;1104 116D 11BB;B694;1104 116D 11BB; +B695;B695;1104 116D 11BC;B695;1104 116D 11BC; +B696;B696;1104 116D 11BD;B696;1104 116D 11BD; +B697;B697;1104 116D 11BE;B697;1104 116D 11BE; +B698;B698;1104 116D 11BF;B698;1104 116D 11BF; +B699;B699;1104 116D 11C0;B699;1104 116D 11C0; +B69A;B69A;1104 116D 11C1;B69A;1104 116D 11C1; +B69B;B69B;1104 116D 11C2;B69B;1104 116D 11C2; +B69C;B69C;1104 116E;B69C;1104 116E; +B69D;B69D;1104 116E 11A8;B69D;1104 116E 11A8; +B69E;B69E;1104 116E 11A9;B69E;1104 116E 11A9; +B69F;B69F;1104 116E 11AA;B69F;1104 116E 11AA; +B6A0;B6A0;1104 116E 11AB;B6A0;1104 116E 11AB; +B6A1;B6A1;1104 116E 11AC;B6A1;1104 116E 11AC; +B6A2;B6A2;1104 116E 11AD;B6A2;1104 116E 11AD; +B6A3;B6A3;1104 116E 11AE;B6A3;1104 116E 11AE; +B6A4;B6A4;1104 116E 11AF;B6A4;1104 116E 11AF; +B6A5;B6A5;1104 116E 11B0;B6A5;1104 116E 11B0; +B6A6;B6A6;1104 116E 11B1;B6A6;1104 116E 11B1; +B6A7;B6A7;1104 116E 11B2;B6A7;1104 116E 11B2; +B6A8;B6A8;1104 116E 11B3;B6A8;1104 116E 11B3; +B6A9;B6A9;1104 116E 11B4;B6A9;1104 116E 11B4; +B6AA;B6AA;1104 116E 11B5;B6AA;1104 116E 11B5; +B6AB;B6AB;1104 116E 11B6;B6AB;1104 116E 11B6; +B6AC;B6AC;1104 116E 11B7;B6AC;1104 116E 11B7; +B6AD;B6AD;1104 116E 11B8;B6AD;1104 116E 11B8; +B6AE;B6AE;1104 116E 11B9;B6AE;1104 116E 11B9; +B6AF;B6AF;1104 116E 11BA;B6AF;1104 116E 11BA; +B6B0;B6B0;1104 116E 11BB;B6B0;1104 116E 11BB; +B6B1;B6B1;1104 116E 11BC;B6B1;1104 116E 11BC; +B6B2;B6B2;1104 116E 11BD;B6B2;1104 116E 11BD; +B6B3;B6B3;1104 116E 11BE;B6B3;1104 116E 11BE; +B6B4;B6B4;1104 116E 11BF;B6B4;1104 116E 11BF; +B6B5;B6B5;1104 116E 11C0;B6B5;1104 116E 11C0; +B6B6;B6B6;1104 116E 11C1;B6B6;1104 116E 11C1; +B6B7;B6B7;1104 116E 11C2;B6B7;1104 116E 11C2; +B6B8;B6B8;1104 116F;B6B8;1104 116F; +B6B9;B6B9;1104 116F 11A8;B6B9;1104 116F 11A8; +B6BA;B6BA;1104 116F 11A9;B6BA;1104 116F 11A9; +B6BB;B6BB;1104 116F 11AA;B6BB;1104 116F 11AA; +B6BC;B6BC;1104 116F 11AB;B6BC;1104 116F 11AB; +B6BD;B6BD;1104 116F 11AC;B6BD;1104 116F 11AC; +B6BE;B6BE;1104 116F 11AD;B6BE;1104 116F 11AD; +B6BF;B6BF;1104 116F 11AE;B6BF;1104 116F 11AE; +B6C0;B6C0;1104 116F 11AF;B6C0;1104 116F 11AF; +B6C1;B6C1;1104 116F 11B0;B6C1;1104 116F 11B0; +B6C2;B6C2;1104 116F 11B1;B6C2;1104 116F 11B1; +B6C3;B6C3;1104 116F 11B2;B6C3;1104 116F 11B2; +B6C4;B6C4;1104 116F 11B3;B6C4;1104 116F 11B3; +B6C5;B6C5;1104 116F 11B4;B6C5;1104 116F 11B4; +B6C6;B6C6;1104 116F 11B5;B6C6;1104 116F 11B5; +B6C7;B6C7;1104 116F 11B6;B6C7;1104 116F 11B6; +B6C8;B6C8;1104 116F 11B7;B6C8;1104 116F 11B7; +B6C9;B6C9;1104 116F 11B8;B6C9;1104 116F 11B8; +B6CA;B6CA;1104 116F 11B9;B6CA;1104 116F 11B9; +B6CB;B6CB;1104 116F 11BA;B6CB;1104 116F 11BA; +B6CC;B6CC;1104 116F 11BB;B6CC;1104 116F 11BB; +B6CD;B6CD;1104 116F 11BC;B6CD;1104 116F 11BC; +B6CE;B6CE;1104 116F 11BD;B6CE;1104 116F 11BD; +B6CF;B6CF;1104 116F 11BE;B6CF;1104 116F 11BE; +B6D0;B6D0;1104 116F 11BF;B6D0;1104 116F 11BF; +B6D1;B6D1;1104 116F 11C0;B6D1;1104 116F 11C0; +B6D2;B6D2;1104 116F 11C1;B6D2;1104 116F 11C1; +B6D3;B6D3;1104 116F 11C2;B6D3;1104 116F 11C2; +B6D4;B6D4;1104 1170;B6D4;1104 1170; +B6D5;B6D5;1104 1170 11A8;B6D5;1104 1170 11A8; +B6D6;B6D6;1104 1170 11A9;B6D6;1104 1170 11A9; +B6D7;B6D7;1104 1170 11AA;B6D7;1104 1170 11AA; +B6D8;B6D8;1104 1170 11AB;B6D8;1104 1170 11AB; +B6D9;B6D9;1104 1170 11AC;B6D9;1104 1170 11AC; +B6DA;B6DA;1104 1170 11AD;B6DA;1104 1170 11AD; +B6DB;B6DB;1104 1170 11AE;B6DB;1104 1170 11AE; +B6DC;B6DC;1104 1170 11AF;B6DC;1104 1170 11AF; +B6DD;B6DD;1104 1170 11B0;B6DD;1104 1170 11B0; +B6DE;B6DE;1104 1170 11B1;B6DE;1104 1170 11B1; +B6DF;B6DF;1104 1170 11B2;B6DF;1104 1170 11B2; +B6E0;B6E0;1104 1170 11B3;B6E0;1104 1170 11B3; +B6E1;B6E1;1104 1170 11B4;B6E1;1104 1170 11B4; +B6E2;B6E2;1104 1170 11B5;B6E2;1104 1170 11B5; +B6E3;B6E3;1104 1170 11B6;B6E3;1104 1170 11B6; +B6E4;B6E4;1104 1170 11B7;B6E4;1104 1170 11B7; +B6E5;B6E5;1104 1170 11B8;B6E5;1104 1170 11B8; +B6E6;B6E6;1104 1170 11B9;B6E6;1104 1170 11B9; +B6E7;B6E7;1104 1170 11BA;B6E7;1104 1170 11BA; +B6E8;B6E8;1104 1170 11BB;B6E8;1104 1170 11BB; +B6E9;B6E9;1104 1170 11BC;B6E9;1104 1170 11BC; +B6EA;B6EA;1104 1170 11BD;B6EA;1104 1170 11BD; +B6EB;B6EB;1104 1170 11BE;B6EB;1104 1170 11BE; +B6EC;B6EC;1104 1170 11BF;B6EC;1104 1170 11BF; +B6ED;B6ED;1104 1170 11C0;B6ED;1104 1170 11C0; +B6EE;B6EE;1104 1170 11C1;B6EE;1104 1170 11C1; +B6EF;B6EF;1104 1170 11C2;B6EF;1104 1170 11C2; +B6F0;B6F0;1104 1171;B6F0;1104 1171; +B6F1;B6F1;1104 1171 11A8;B6F1;1104 1171 11A8; +B6F2;B6F2;1104 1171 11A9;B6F2;1104 1171 11A9; +B6F3;B6F3;1104 1171 11AA;B6F3;1104 1171 11AA; +B6F4;B6F4;1104 1171 11AB;B6F4;1104 1171 11AB; +B6F5;B6F5;1104 1171 11AC;B6F5;1104 1171 11AC; +B6F6;B6F6;1104 1171 11AD;B6F6;1104 1171 11AD; +B6F7;B6F7;1104 1171 11AE;B6F7;1104 1171 11AE; +B6F8;B6F8;1104 1171 11AF;B6F8;1104 1171 11AF; +B6F9;B6F9;1104 1171 11B0;B6F9;1104 1171 11B0; +B6FA;B6FA;1104 1171 11B1;B6FA;1104 1171 11B1; +B6FB;B6FB;1104 1171 11B2;B6FB;1104 1171 11B2; +B6FC;B6FC;1104 1171 11B3;B6FC;1104 1171 11B3; +B6FD;B6FD;1104 1171 11B4;B6FD;1104 1171 11B4; +B6FE;B6FE;1104 1171 11B5;B6FE;1104 1171 11B5; +B6FF;B6FF;1104 1171 11B6;B6FF;1104 1171 11B6; +B700;B700;1104 1171 11B7;B700;1104 1171 11B7; +B701;B701;1104 1171 11B8;B701;1104 1171 11B8; +B702;B702;1104 1171 11B9;B702;1104 1171 11B9; +B703;B703;1104 1171 11BA;B703;1104 1171 11BA; +B704;B704;1104 1171 11BB;B704;1104 1171 11BB; +B705;B705;1104 1171 11BC;B705;1104 1171 11BC; +B706;B706;1104 1171 11BD;B706;1104 1171 11BD; +B707;B707;1104 1171 11BE;B707;1104 1171 11BE; +B708;B708;1104 1171 11BF;B708;1104 1171 11BF; +B709;B709;1104 1171 11C0;B709;1104 1171 11C0; +B70A;B70A;1104 1171 11C1;B70A;1104 1171 11C1; +B70B;B70B;1104 1171 11C2;B70B;1104 1171 11C2; +B70C;B70C;1104 1172;B70C;1104 1172; +B70D;B70D;1104 1172 11A8;B70D;1104 1172 11A8; +B70E;B70E;1104 1172 11A9;B70E;1104 1172 11A9; +B70F;B70F;1104 1172 11AA;B70F;1104 1172 11AA; +B710;B710;1104 1172 11AB;B710;1104 1172 11AB; +B711;B711;1104 1172 11AC;B711;1104 1172 11AC; +B712;B712;1104 1172 11AD;B712;1104 1172 11AD; +B713;B713;1104 1172 11AE;B713;1104 1172 11AE; +B714;B714;1104 1172 11AF;B714;1104 1172 11AF; +B715;B715;1104 1172 11B0;B715;1104 1172 11B0; +B716;B716;1104 1172 11B1;B716;1104 1172 11B1; +B717;B717;1104 1172 11B2;B717;1104 1172 11B2; +B718;B718;1104 1172 11B3;B718;1104 1172 11B3; +B719;B719;1104 1172 11B4;B719;1104 1172 11B4; +B71A;B71A;1104 1172 11B5;B71A;1104 1172 11B5; +B71B;B71B;1104 1172 11B6;B71B;1104 1172 11B6; +B71C;B71C;1104 1172 11B7;B71C;1104 1172 11B7; +B71D;B71D;1104 1172 11B8;B71D;1104 1172 11B8; +B71E;B71E;1104 1172 11B9;B71E;1104 1172 11B9; +B71F;B71F;1104 1172 11BA;B71F;1104 1172 11BA; +B720;B720;1104 1172 11BB;B720;1104 1172 11BB; +B721;B721;1104 1172 11BC;B721;1104 1172 11BC; +B722;B722;1104 1172 11BD;B722;1104 1172 11BD; +B723;B723;1104 1172 11BE;B723;1104 1172 11BE; +B724;B724;1104 1172 11BF;B724;1104 1172 11BF; +B725;B725;1104 1172 11C0;B725;1104 1172 11C0; +B726;B726;1104 1172 11C1;B726;1104 1172 11C1; +B727;B727;1104 1172 11C2;B727;1104 1172 11C2; +B728;B728;1104 1173;B728;1104 1173; +B729;B729;1104 1173 11A8;B729;1104 1173 11A8; +B72A;B72A;1104 1173 11A9;B72A;1104 1173 11A9; +B72B;B72B;1104 1173 11AA;B72B;1104 1173 11AA; +B72C;B72C;1104 1173 11AB;B72C;1104 1173 11AB; +B72D;B72D;1104 1173 11AC;B72D;1104 1173 11AC; +B72E;B72E;1104 1173 11AD;B72E;1104 1173 11AD; +B72F;B72F;1104 1173 11AE;B72F;1104 1173 11AE; +B730;B730;1104 1173 11AF;B730;1104 1173 11AF; +B731;B731;1104 1173 11B0;B731;1104 1173 11B0; +B732;B732;1104 1173 11B1;B732;1104 1173 11B1; +B733;B733;1104 1173 11B2;B733;1104 1173 11B2; +B734;B734;1104 1173 11B3;B734;1104 1173 11B3; +B735;B735;1104 1173 11B4;B735;1104 1173 11B4; +B736;B736;1104 1173 11B5;B736;1104 1173 11B5; +B737;B737;1104 1173 11B6;B737;1104 1173 11B6; +B738;B738;1104 1173 11B7;B738;1104 1173 11B7; +B739;B739;1104 1173 11B8;B739;1104 1173 11B8; +B73A;B73A;1104 1173 11B9;B73A;1104 1173 11B9; +B73B;B73B;1104 1173 11BA;B73B;1104 1173 11BA; +B73C;B73C;1104 1173 11BB;B73C;1104 1173 11BB; +B73D;B73D;1104 1173 11BC;B73D;1104 1173 11BC; +B73E;B73E;1104 1173 11BD;B73E;1104 1173 11BD; +B73F;B73F;1104 1173 11BE;B73F;1104 1173 11BE; +B740;B740;1104 1173 11BF;B740;1104 1173 11BF; +B741;B741;1104 1173 11C0;B741;1104 1173 11C0; +B742;B742;1104 1173 11C1;B742;1104 1173 11C1; +B743;B743;1104 1173 11C2;B743;1104 1173 11C2; +B744;B744;1104 1174;B744;1104 1174; +B745;B745;1104 1174 11A8;B745;1104 1174 11A8; +B746;B746;1104 1174 11A9;B746;1104 1174 11A9; +B747;B747;1104 1174 11AA;B747;1104 1174 11AA; +B748;B748;1104 1174 11AB;B748;1104 1174 11AB; +B749;B749;1104 1174 11AC;B749;1104 1174 11AC; +B74A;B74A;1104 1174 11AD;B74A;1104 1174 11AD; +B74B;B74B;1104 1174 11AE;B74B;1104 1174 11AE; +B74C;B74C;1104 1174 11AF;B74C;1104 1174 11AF; +B74D;B74D;1104 1174 11B0;B74D;1104 1174 11B0; +B74E;B74E;1104 1174 11B1;B74E;1104 1174 11B1; +B74F;B74F;1104 1174 11B2;B74F;1104 1174 11B2; +B750;B750;1104 1174 11B3;B750;1104 1174 11B3; +B751;B751;1104 1174 11B4;B751;1104 1174 11B4; +B752;B752;1104 1174 11B5;B752;1104 1174 11B5; +B753;B753;1104 1174 11B6;B753;1104 1174 11B6; +B754;B754;1104 1174 11B7;B754;1104 1174 11B7; +B755;B755;1104 1174 11B8;B755;1104 1174 11B8; +B756;B756;1104 1174 11B9;B756;1104 1174 11B9; +B757;B757;1104 1174 11BA;B757;1104 1174 11BA; +B758;B758;1104 1174 11BB;B758;1104 1174 11BB; +B759;B759;1104 1174 11BC;B759;1104 1174 11BC; +B75A;B75A;1104 1174 11BD;B75A;1104 1174 11BD; +B75B;B75B;1104 1174 11BE;B75B;1104 1174 11BE; +B75C;B75C;1104 1174 11BF;B75C;1104 1174 11BF; +B75D;B75D;1104 1174 11C0;B75D;1104 1174 11C0; +B75E;B75E;1104 1174 11C1;B75E;1104 1174 11C1; +B75F;B75F;1104 1174 11C2;B75F;1104 1174 11C2; +B760;B760;1104 1175;B760;1104 1175; +B761;B761;1104 1175 11A8;B761;1104 1175 11A8; +B762;B762;1104 1175 11A9;B762;1104 1175 11A9; +B763;B763;1104 1175 11AA;B763;1104 1175 11AA; +B764;B764;1104 1175 11AB;B764;1104 1175 11AB; +B765;B765;1104 1175 11AC;B765;1104 1175 11AC; +B766;B766;1104 1175 11AD;B766;1104 1175 11AD; +B767;B767;1104 1175 11AE;B767;1104 1175 11AE; +B768;B768;1104 1175 11AF;B768;1104 1175 11AF; +B769;B769;1104 1175 11B0;B769;1104 1175 11B0; +B76A;B76A;1104 1175 11B1;B76A;1104 1175 11B1; +B76B;B76B;1104 1175 11B2;B76B;1104 1175 11B2; +B76C;B76C;1104 1175 11B3;B76C;1104 1175 11B3; +B76D;B76D;1104 1175 11B4;B76D;1104 1175 11B4; +B76E;B76E;1104 1175 11B5;B76E;1104 1175 11B5; +B76F;B76F;1104 1175 11B6;B76F;1104 1175 11B6; +B770;B770;1104 1175 11B7;B770;1104 1175 11B7; +B771;B771;1104 1175 11B8;B771;1104 1175 11B8; +B772;B772;1104 1175 11B9;B772;1104 1175 11B9; +B773;B773;1104 1175 11BA;B773;1104 1175 11BA; +B774;B774;1104 1175 11BB;B774;1104 1175 11BB; +B775;B775;1104 1175 11BC;B775;1104 1175 11BC; +B776;B776;1104 1175 11BD;B776;1104 1175 11BD; +B777;B777;1104 1175 11BE;B777;1104 1175 11BE; +B778;B778;1104 1175 11BF;B778;1104 1175 11BF; +B779;B779;1104 1175 11C0;B779;1104 1175 11C0; +B77A;B77A;1104 1175 11C1;B77A;1104 1175 11C1; +B77B;B77B;1104 1175 11C2;B77B;1104 1175 11C2; +B77C;B77C;1105 1161;B77C;1105 1161; +B77D;B77D;1105 1161 11A8;B77D;1105 1161 11A8; +B77E;B77E;1105 1161 11A9;B77E;1105 1161 11A9; +B77F;B77F;1105 1161 11AA;B77F;1105 1161 11AA; +B780;B780;1105 1161 11AB;B780;1105 1161 11AB; +B781;B781;1105 1161 11AC;B781;1105 1161 11AC; +B782;B782;1105 1161 11AD;B782;1105 1161 11AD; +B783;B783;1105 1161 11AE;B783;1105 1161 11AE; +B784;B784;1105 1161 11AF;B784;1105 1161 11AF; +B785;B785;1105 1161 11B0;B785;1105 1161 11B0; +B786;B786;1105 1161 11B1;B786;1105 1161 11B1; +B787;B787;1105 1161 11B2;B787;1105 1161 11B2; +B788;B788;1105 1161 11B3;B788;1105 1161 11B3; +B789;B789;1105 1161 11B4;B789;1105 1161 11B4; +B78A;B78A;1105 1161 11B5;B78A;1105 1161 11B5; +B78B;B78B;1105 1161 11B6;B78B;1105 1161 11B6; +B78C;B78C;1105 1161 11B7;B78C;1105 1161 11B7; +B78D;B78D;1105 1161 11B8;B78D;1105 1161 11B8; +B78E;B78E;1105 1161 11B9;B78E;1105 1161 11B9; +B78F;B78F;1105 1161 11BA;B78F;1105 1161 11BA; +B790;B790;1105 1161 11BB;B790;1105 1161 11BB; +B791;B791;1105 1161 11BC;B791;1105 1161 11BC; +B792;B792;1105 1161 11BD;B792;1105 1161 11BD; +B793;B793;1105 1161 11BE;B793;1105 1161 11BE; +B794;B794;1105 1161 11BF;B794;1105 1161 11BF; +B795;B795;1105 1161 11C0;B795;1105 1161 11C0; +B796;B796;1105 1161 11C1;B796;1105 1161 11C1; +B797;B797;1105 1161 11C2;B797;1105 1161 11C2; +B798;B798;1105 1162;B798;1105 1162; +B799;B799;1105 1162 11A8;B799;1105 1162 11A8; +B79A;B79A;1105 1162 11A9;B79A;1105 1162 11A9; +B79B;B79B;1105 1162 11AA;B79B;1105 1162 11AA; +B79C;B79C;1105 1162 11AB;B79C;1105 1162 11AB; +B79D;B79D;1105 1162 11AC;B79D;1105 1162 11AC; +B79E;B79E;1105 1162 11AD;B79E;1105 1162 11AD; +B79F;B79F;1105 1162 11AE;B79F;1105 1162 11AE; +B7A0;B7A0;1105 1162 11AF;B7A0;1105 1162 11AF; +B7A1;B7A1;1105 1162 11B0;B7A1;1105 1162 11B0; +B7A2;B7A2;1105 1162 11B1;B7A2;1105 1162 11B1; +B7A3;B7A3;1105 1162 11B2;B7A3;1105 1162 11B2; +B7A4;B7A4;1105 1162 11B3;B7A4;1105 1162 11B3; +B7A5;B7A5;1105 1162 11B4;B7A5;1105 1162 11B4; +B7A6;B7A6;1105 1162 11B5;B7A6;1105 1162 11B5; +B7A7;B7A7;1105 1162 11B6;B7A7;1105 1162 11B6; +B7A8;B7A8;1105 1162 11B7;B7A8;1105 1162 11B7; +B7A9;B7A9;1105 1162 11B8;B7A9;1105 1162 11B8; +B7AA;B7AA;1105 1162 11B9;B7AA;1105 1162 11B9; +B7AB;B7AB;1105 1162 11BA;B7AB;1105 1162 11BA; +B7AC;B7AC;1105 1162 11BB;B7AC;1105 1162 11BB; +B7AD;B7AD;1105 1162 11BC;B7AD;1105 1162 11BC; +B7AE;B7AE;1105 1162 11BD;B7AE;1105 1162 11BD; +B7AF;B7AF;1105 1162 11BE;B7AF;1105 1162 11BE; +B7B0;B7B0;1105 1162 11BF;B7B0;1105 1162 11BF; +B7B1;B7B1;1105 1162 11C0;B7B1;1105 1162 11C0; +B7B2;B7B2;1105 1162 11C1;B7B2;1105 1162 11C1; +B7B3;B7B3;1105 1162 11C2;B7B3;1105 1162 11C2; +B7B4;B7B4;1105 1163;B7B4;1105 1163; +B7B5;B7B5;1105 1163 11A8;B7B5;1105 1163 11A8; +B7B6;B7B6;1105 1163 11A9;B7B6;1105 1163 11A9; +B7B7;B7B7;1105 1163 11AA;B7B7;1105 1163 11AA; +B7B8;B7B8;1105 1163 11AB;B7B8;1105 1163 11AB; +B7B9;B7B9;1105 1163 11AC;B7B9;1105 1163 11AC; +B7BA;B7BA;1105 1163 11AD;B7BA;1105 1163 11AD; +B7BB;B7BB;1105 1163 11AE;B7BB;1105 1163 11AE; +B7BC;B7BC;1105 1163 11AF;B7BC;1105 1163 11AF; +B7BD;B7BD;1105 1163 11B0;B7BD;1105 1163 11B0; +B7BE;B7BE;1105 1163 11B1;B7BE;1105 1163 11B1; +B7BF;B7BF;1105 1163 11B2;B7BF;1105 1163 11B2; +B7C0;B7C0;1105 1163 11B3;B7C0;1105 1163 11B3; +B7C1;B7C1;1105 1163 11B4;B7C1;1105 1163 11B4; +B7C2;B7C2;1105 1163 11B5;B7C2;1105 1163 11B5; +B7C3;B7C3;1105 1163 11B6;B7C3;1105 1163 11B6; +B7C4;B7C4;1105 1163 11B7;B7C4;1105 1163 11B7; +B7C5;B7C5;1105 1163 11B8;B7C5;1105 1163 11B8; +B7C6;B7C6;1105 1163 11B9;B7C6;1105 1163 11B9; +B7C7;B7C7;1105 1163 11BA;B7C7;1105 1163 11BA; +B7C8;B7C8;1105 1163 11BB;B7C8;1105 1163 11BB; +B7C9;B7C9;1105 1163 11BC;B7C9;1105 1163 11BC; +B7CA;B7CA;1105 1163 11BD;B7CA;1105 1163 11BD; +B7CB;B7CB;1105 1163 11BE;B7CB;1105 1163 11BE; +B7CC;B7CC;1105 1163 11BF;B7CC;1105 1163 11BF; +B7CD;B7CD;1105 1163 11C0;B7CD;1105 1163 11C0; +B7CE;B7CE;1105 1163 11C1;B7CE;1105 1163 11C1; +B7CF;B7CF;1105 1163 11C2;B7CF;1105 1163 11C2; +B7D0;B7D0;1105 1164;B7D0;1105 1164; +B7D1;B7D1;1105 1164 11A8;B7D1;1105 1164 11A8; +B7D2;B7D2;1105 1164 11A9;B7D2;1105 1164 11A9; +B7D3;B7D3;1105 1164 11AA;B7D3;1105 1164 11AA; +B7D4;B7D4;1105 1164 11AB;B7D4;1105 1164 11AB; +B7D5;B7D5;1105 1164 11AC;B7D5;1105 1164 11AC; +B7D6;B7D6;1105 1164 11AD;B7D6;1105 1164 11AD; +B7D7;B7D7;1105 1164 11AE;B7D7;1105 1164 11AE; +B7D8;B7D8;1105 1164 11AF;B7D8;1105 1164 11AF; +B7D9;B7D9;1105 1164 11B0;B7D9;1105 1164 11B0; +B7DA;B7DA;1105 1164 11B1;B7DA;1105 1164 11B1; +B7DB;B7DB;1105 1164 11B2;B7DB;1105 1164 11B2; +B7DC;B7DC;1105 1164 11B3;B7DC;1105 1164 11B3; +B7DD;B7DD;1105 1164 11B4;B7DD;1105 1164 11B4; +B7DE;B7DE;1105 1164 11B5;B7DE;1105 1164 11B5; +B7DF;B7DF;1105 1164 11B6;B7DF;1105 1164 11B6; +B7E0;B7E0;1105 1164 11B7;B7E0;1105 1164 11B7; +B7E1;B7E1;1105 1164 11B8;B7E1;1105 1164 11B8; +B7E2;B7E2;1105 1164 11B9;B7E2;1105 1164 11B9; +B7E3;B7E3;1105 1164 11BA;B7E3;1105 1164 11BA; +B7E4;B7E4;1105 1164 11BB;B7E4;1105 1164 11BB; +B7E5;B7E5;1105 1164 11BC;B7E5;1105 1164 11BC; +B7E6;B7E6;1105 1164 11BD;B7E6;1105 1164 11BD; +B7E7;B7E7;1105 1164 11BE;B7E7;1105 1164 11BE; +B7E8;B7E8;1105 1164 11BF;B7E8;1105 1164 11BF; +B7E9;B7E9;1105 1164 11C0;B7E9;1105 1164 11C0; +B7EA;B7EA;1105 1164 11C1;B7EA;1105 1164 11C1; +B7EB;B7EB;1105 1164 11C2;B7EB;1105 1164 11C2; +B7EC;B7EC;1105 1165;B7EC;1105 1165; +B7ED;B7ED;1105 1165 11A8;B7ED;1105 1165 11A8; +B7EE;B7EE;1105 1165 11A9;B7EE;1105 1165 11A9; +B7EF;B7EF;1105 1165 11AA;B7EF;1105 1165 11AA; +B7F0;B7F0;1105 1165 11AB;B7F0;1105 1165 11AB; +B7F1;B7F1;1105 1165 11AC;B7F1;1105 1165 11AC; +B7F2;B7F2;1105 1165 11AD;B7F2;1105 1165 11AD; +B7F3;B7F3;1105 1165 11AE;B7F3;1105 1165 11AE; +B7F4;B7F4;1105 1165 11AF;B7F4;1105 1165 11AF; +B7F5;B7F5;1105 1165 11B0;B7F5;1105 1165 11B0; +B7F6;B7F6;1105 1165 11B1;B7F6;1105 1165 11B1; +B7F7;B7F7;1105 1165 11B2;B7F7;1105 1165 11B2; +B7F8;B7F8;1105 1165 11B3;B7F8;1105 1165 11B3; +B7F9;B7F9;1105 1165 11B4;B7F9;1105 1165 11B4; +B7FA;B7FA;1105 1165 11B5;B7FA;1105 1165 11B5; +B7FB;B7FB;1105 1165 11B6;B7FB;1105 1165 11B6; +B7FC;B7FC;1105 1165 11B7;B7FC;1105 1165 11B7; +B7FD;B7FD;1105 1165 11B8;B7FD;1105 1165 11B8; +B7FE;B7FE;1105 1165 11B9;B7FE;1105 1165 11B9; +B7FF;B7FF;1105 1165 11BA;B7FF;1105 1165 11BA; +B800;B800;1105 1165 11BB;B800;1105 1165 11BB; +B801;B801;1105 1165 11BC;B801;1105 1165 11BC; +B802;B802;1105 1165 11BD;B802;1105 1165 11BD; +B803;B803;1105 1165 11BE;B803;1105 1165 11BE; +B804;B804;1105 1165 11BF;B804;1105 1165 11BF; +B805;B805;1105 1165 11C0;B805;1105 1165 11C0; +B806;B806;1105 1165 11C1;B806;1105 1165 11C1; +B807;B807;1105 1165 11C2;B807;1105 1165 11C2; +B808;B808;1105 1166;B808;1105 1166; +B809;B809;1105 1166 11A8;B809;1105 1166 11A8; +B80A;B80A;1105 1166 11A9;B80A;1105 1166 11A9; +B80B;B80B;1105 1166 11AA;B80B;1105 1166 11AA; +B80C;B80C;1105 1166 11AB;B80C;1105 1166 11AB; +B80D;B80D;1105 1166 11AC;B80D;1105 1166 11AC; +B80E;B80E;1105 1166 11AD;B80E;1105 1166 11AD; +B80F;B80F;1105 1166 11AE;B80F;1105 1166 11AE; +B810;B810;1105 1166 11AF;B810;1105 1166 11AF; +B811;B811;1105 1166 11B0;B811;1105 1166 11B0; +B812;B812;1105 1166 11B1;B812;1105 1166 11B1; +B813;B813;1105 1166 11B2;B813;1105 1166 11B2; +B814;B814;1105 1166 11B3;B814;1105 1166 11B3; +B815;B815;1105 1166 11B4;B815;1105 1166 11B4; +B816;B816;1105 1166 11B5;B816;1105 1166 11B5; +B817;B817;1105 1166 11B6;B817;1105 1166 11B6; +B818;B818;1105 1166 11B7;B818;1105 1166 11B7; +B819;B819;1105 1166 11B8;B819;1105 1166 11B8; +B81A;B81A;1105 1166 11B9;B81A;1105 1166 11B9; +B81B;B81B;1105 1166 11BA;B81B;1105 1166 11BA; +B81C;B81C;1105 1166 11BB;B81C;1105 1166 11BB; +B81D;B81D;1105 1166 11BC;B81D;1105 1166 11BC; +B81E;B81E;1105 1166 11BD;B81E;1105 1166 11BD; +B81F;B81F;1105 1166 11BE;B81F;1105 1166 11BE; +B820;B820;1105 1166 11BF;B820;1105 1166 11BF; +B821;B821;1105 1166 11C0;B821;1105 1166 11C0; +B822;B822;1105 1166 11C1;B822;1105 1166 11C1; +B823;B823;1105 1166 11C2;B823;1105 1166 11C2; +B824;B824;1105 1167;B824;1105 1167; +B825;B825;1105 1167 11A8;B825;1105 1167 11A8; +B826;B826;1105 1167 11A9;B826;1105 1167 11A9; +B827;B827;1105 1167 11AA;B827;1105 1167 11AA; +B828;B828;1105 1167 11AB;B828;1105 1167 11AB; +B829;B829;1105 1167 11AC;B829;1105 1167 11AC; +B82A;B82A;1105 1167 11AD;B82A;1105 1167 11AD; +B82B;B82B;1105 1167 11AE;B82B;1105 1167 11AE; +B82C;B82C;1105 1167 11AF;B82C;1105 1167 11AF; +B82D;B82D;1105 1167 11B0;B82D;1105 1167 11B0; +B82E;B82E;1105 1167 11B1;B82E;1105 1167 11B1; +B82F;B82F;1105 1167 11B2;B82F;1105 1167 11B2; +B830;B830;1105 1167 11B3;B830;1105 1167 11B3; +B831;B831;1105 1167 11B4;B831;1105 1167 11B4; +B832;B832;1105 1167 11B5;B832;1105 1167 11B5; +B833;B833;1105 1167 11B6;B833;1105 1167 11B6; +B834;B834;1105 1167 11B7;B834;1105 1167 11B7; +B835;B835;1105 1167 11B8;B835;1105 1167 11B8; +B836;B836;1105 1167 11B9;B836;1105 1167 11B9; +B837;B837;1105 1167 11BA;B837;1105 1167 11BA; +B838;B838;1105 1167 11BB;B838;1105 1167 11BB; +B839;B839;1105 1167 11BC;B839;1105 1167 11BC; +B83A;B83A;1105 1167 11BD;B83A;1105 1167 11BD; +B83B;B83B;1105 1167 11BE;B83B;1105 1167 11BE; +B83C;B83C;1105 1167 11BF;B83C;1105 1167 11BF; +B83D;B83D;1105 1167 11C0;B83D;1105 1167 11C0; +B83E;B83E;1105 1167 11C1;B83E;1105 1167 11C1; +B83F;B83F;1105 1167 11C2;B83F;1105 1167 11C2; +B840;B840;1105 1168;B840;1105 1168; +B841;B841;1105 1168 11A8;B841;1105 1168 11A8; +B842;B842;1105 1168 11A9;B842;1105 1168 11A9; +B843;B843;1105 1168 11AA;B843;1105 1168 11AA; +B844;B844;1105 1168 11AB;B844;1105 1168 11AB; +B845;B845;1105 1168 11AC;B845;1105 1168 11AC; +B846;B846;1105 1168 11AD;B846;1105 1168 11AD; +B847;B847;1105 1168 11AE;B847;1105 1168 11AE; +B848;B848;1105 1168 11AF;B848;1105 1168 11AF; +B849;B849;1105 1168 11B0;B849;1105 1168 11B0; +B84A;B84A;1105 1168 11B1;B84A;1105 1168 11B1; +B84B;B84B;1105 1168 11B2;B84B;1105 1168 11B2; +B84C;B84C;1105 1168 11B3;B84C;1105 1168 11B3; +B84D;B84D;1105 1168 11B4;B84D;1105 1168 11B4; +B84E;B84E;1105 1168 11B5;B84E;1105 1168 11B5; +B84F;B84F;1105 1168 11B6;B84F;1105 1168 11B6; +B850;B850;1105 1168 11B7;B850;1105 1168 11B7; +B851;B851;1105 1168 11B8;B851;1105 1168 11B8; +B852;B852;1105 1168 11B9;B852;1105 1168 11B9; +B853;B853;1105 1168 11BA;B853;1105 1168 11BA; +B854;B854;1105 1168 11BB;B854;1105 1168 11BB; +B855;B855;1105 1168 11BC;B855;1105 1168 11BC; +B856;B856;1105 1168 11BD;B856;1105 1168 11BD; +B857;B857;1105 1168 11BE;B857;1105 1168 11BE; +B858;B858;1105 1168 11BF;B858;1105 1168 11BF; +B859;B859;1105 1168 11C0;B859;1105 1168 11C0; +B85A;B85A;1105 1168 11C1;B85A;1105 1168 11C1; +B85B;B85B;1105 1168 11C2;B85B;1105 1168 11C2; +B85C;B85C;1105 1169;B85C;1105 1169; +B85D;B85D;1105 1169 11A8;B85D;1105 1169 11A8; +B85E;B85E;1105 1169 11A9;B85E;1105 1169 11A9; +B85F;B85F;1105 1169 11AA;B85F;1105 1169 11AA; +B860;B860;1105 1169 11AB;B860;1105 1169 11AB; +B861;B861;1105 1169 11AC;B861;1105 1169 11AC; +B862;B862;1105 1169 11AD;B862;1105 1169 11AD; +B863;B863;1105 1169 11AE;B863;1105 1169 11AE; +B864;B864;1105 1169 11AF;B864;1105 1169 11AF; +B865;B865;1105 1169 11B0;B865;1105 1169 11B0; +B866;B866;1105 1169 11B1;B866;1105 1169 11B1; +B867;B867;1105 1169 11B2;B867;1105 1169 11B2; +B868;B868;1105 1169 11B3;B868;1105 1169 11B3; +B869;B869;1105 1169 11B4;B869;1105 1169 11B4; +B86A;B86A;1105 1169 11B5;B86A;1105 1169 11B5; +B86B;B86B;1105 1169 11B6;B86B;1105 1169 11B6; +B86C;B86C;1105 1169 11B7;B86C;1105 1169 11B7; +B86D;B86D;1105 1169 11B8;B86D;1105 1169 11B8; +B86E;B86E;1105 1169 11B9;B86E;1105 1169 11B9; +B86F;B86F;1105 1169 11BA;B86F;1105 1169 11BA; +B870;B870;1105 1169 11BB;B870;1105 1169 11BB; +B871;B871;1105 1169 11BC;B871;1105 1169 11BC; +B872;B872;1105 1169 11BD;B872;1105 1169 11BD; +B873;B873;1105 1169 11BE;B873;1105 1169 11BE; +B874;B874;1105 1169 11BF;B874;1105 1169 11BF; +B875;B875;1105 1169 11C0;B875;1105 1169 11C0; +B876;B876;1105 1169 11C1;B876;1105 1169 11C1; +B877;B877;1105 1169 11C2;B877;1105 1169 11C2; +B878;B878;1105 116A;B878;1105 116A; +B879;B879;1105 116A 11A8;B879;1105 116A 11A8; +B87A;B87A;1105 116A 11A9;B87A;1105 116A 11A9; +B87B;B87B;1105 116A 11AA;B87B;1105 116A 11AA; +B87C;B87C;1105 116A 11AB;B87C;1105 116A 11AB; +B87D;B87D;1105 116A 11AC;B87D;1105 116A 11AC; +B87E;B87E;1105 116A 11AD;B87E;1105 116A 11AD; +B87F;B87F;1105 116A 11AE;B87F;1105 116A 11AE; +B880;B880;1105 116A 11AF;B880;1105 116A 11AF; +B881;B881;1105 116A 11B0;B881;1105 116A 11B0; +B882;B882;1105 116A 11B1;B882;1105 116A 11B1; +B883;B883;1105 116A 11B2;B883;1105 116A 11B2; +B884;B884;1105 116A 11B3;B884;1105 116A 11B3; +B885;B885;1105 116A 11B4;B885;1105 116A 11B4; +B886;B886;1105 116A 11B5;B886;1105 116A 11B5; +B887;B887;1105 116A 11B6;B887;1105 116A 11B6; +B888;B888;1105 116A 11B7;B888;1105 116A 11B7; +B889;B889;1105 116A 11B8;B889;1105 116A 11B8; +B88A;B88A;1105 116A 11B9;B88A;1105 116A 11B9; +B88B;B88B;1105 116A 11BA;B88B;1105 116A 11BA; +B88C;B88C;1105 116A 11BB;B88C;1105 116A 11BB; +B88D;B88D;1105 116A 11BC;B88D;1105 116A 11BC; +B88E;B88E;1105 116A 11BD;B88E;1105 116A 11BD; +B88F;B88F;1105 116A 11BE;B88F;1105 116A 11BE; +B890;B890;1105 116A 11BF;B890;1105 116A 11BF; +B891;B891;1105 116A 11C0;B891;1105 116A 11C0; +B892;B892;1105 116A 11C1;B892;1105 116A 11C1; +B893;B893;1105 116A 11C2;B893;1105 116A 11C2; +B894;B894;1105 116B;B894;1105 116B; +B895;B895;1105 116B 11A8;B895;1105 116B 11A8; +B896;B896;1105 116B 11A9;B896;1105 116B 11A9; +B897;B897;1105 116B 11AA;B897;1105 116B 11AA; +B898;B898;1105 116B 11AB;B898;1105 116B 11AB; +B899;B899;1105 116B 11AC;B899;1105 116B 11AC; +B89A;B89A;1105 116B 11AD;B89A;1105 116B 11AD; +B89B;B89B;1105 116B 11AE;B89B;1105 116B 11AE; +B89C;B89C;1105 116B 11AF;B89C;1105 116B 11AF; +B89D;B89D;1105 116B 11B0;B89D;1105 116B 11B0; +B89E;B89E;1105 116B 11B1;B89E;1105 116B 11B1; +B89F;B89F;1105 116B 11B2;B89F;1105 116B 11B2; +B8A0;B8A0;1105 116B 11B3;B8A0;1105 116B 11B3; +B8A1;B8A1;1105 116B 11B4;B8A1;1105 116B 11B4; +B8A2;B8A2;1105 116B 11B5;B8A2;1105 116B 11B5; +B8A3;B8A3;1105 116B 11B6;B8A3;1105 116B 11B6; +B8A4;B8A4;1105 116B 11B7;B8A4;1105 116B 11B7; +B8A5;B8A5;1105 116B 11B8;B8A5;1105 116B 11B8; +B8A6;B8A6;1105 116B 11B9;B8A6;1105 116B 11B9; +B8A7;B8A7;1105 116B 11BA;B8A7;1105 116B 11BA; +B8A8;B8A8;1105 116B 11BB;B8A8;1105 116B 11BB; +B8A9;B8A9;1105 116B 11BC;B8A9;1105 116B 11BC; +B8AA;B8AA;1105 116B 11BD;B8AA;1105 116B 11BD; +B8AB;B8AB;1105 116B 11BE;B8AB;1105 116B 11BE; +B8AC;B8AC;1105 116B 11BF;B8AC;1105 116B 11BF; +B8AD;B8AD;1105 116B 11C0;B8AD;1105 116B 11C0; +B8AE;B8AE;1105 116B 11C1;B8AE;1105 116B 11C1; +B8AF;B8AF;1105 116B 11C2;B8AF;1105 116B 11C2; +B8B0;B8B0;1105 116C;B8B0;1105 116C; +B8B1;B8B1;1105 116C 11A8;B8B1;1105 116C 11A8; +B8B2;B8B2;1105 116C 11A9;B8B2;1105 116C 11A9; +B8B3;B8B3;1105 116C 11AA;B8B3;1105 116C 11AA; +B8B4;B8B4;1105 116C 11AB;B8B4;1105 116C 11AB; +B8B5;B8B5;1105 116C 11AC;B8B5;1105 116C 11AC; +B8B6;B8B6;1105 116C 11AD;B8B6;1105 116C 11AD; +B8B7;B8B7;1105 116C 11AE;B8B7;1105 116C 11AE; +B8B8;B8B8;1105 116C 11AF;B8B8;1105 116C 11AF; +B8B9;B8B9;1105 116C 11B0;B8B9;1105 116C 11B0; +B8BA;B8BA;1105 116C 11B1;B8BA;1105 116C 11B1; +B8BB;B8BB;1105 116C 11B2;B8BB;1105 116C 11B2; +B8BC;B8BC;1105 116C 11B3;B8BC;1105 116C 11B3; +B8BD;B8BD;1105 116C 11B4;B8BD;1105 116C 11B4; +B8BE;B8BE;1105 116C 11B5;B8BE;1105 116C 11B5; +B8BF;B8BF;1105 116C 11B6;B8BF;1105 116C 11B6; +B8C0;B8C0;1105 116C 11B7;B8C0;1105 116C 11B7; +B8C1;B8C1;1105 116C 11B8;B8C1;1105 116C 11B8; +B8C2;B8C2;1105 116C 11B9;B8C2;1105 116C 11B9; +B8C3;B8C3;1105 116C 11BA;B8C3;1105 116C 11BA; +B8C4;B8C4;1105 116C 11BB;B8C4;1105 116C 11BB; +B8C5;B8C5;1105 116C 11BC;B8C5;1105 116C 11BC; +B8C6;B8C6;1105 116C 11BD;B8C6;1105 116C 11BD; +B8C7;B8C7;1105 116C 11BE;B8C7;1105 116C 11BE; +B8C8;B8C8;1105 116C 11BF;B8C8;1105 116C 11BF; +B8C9;B8C9;1105 116C 11C0;B8C9;1105 116C 11C0; +B8CA;B8CA;1105 116C 11C1;B8CA;1105 116C 11C1; +B8CB;B8CB;1105 116C 11C2;B8CB;1105 116C 11C2; +B8CC;B8CC;1105 116D;B8CC;1105 116D; +B8CD;B8CD;1105 116D 11A8;B8CD;1105 116D 11A8; +B8CE;B8CE;1105 116D 11A9;B8CE;1105 116D 11A9; +B8CF;B8CF;1105 116D 11AA;B8CF;1105 116D 11AA; +B8D0;B8D0;1105 116D 11AB;B8D0;1105 116D 11AB; +B8D1;B8D1;1105 116D 11AC;B8D1;1105 116D 11AC; +B8D2;B8D2;1105 116D 11AD;B8D2;1105 116D 11AD; +B8D3;B8D3;1105 116D 11AE;B8D3;1105 116D 11AE; +B8D4;B8D4;1105 116D 11AF;B8D4;1105 116D 11AF; +B8D5;B8D5;1105 116D 11B0;B8D5;1105 116D 11B0; +B8D6;B8D6;1105 116D 11B1;B8D6;1105 116D 11B1; +B8D7;B8D7;1105 116D 11B2;B8D7;1105 116D 11B2; +B8D8;B8D8;1105 116D 11B3;B8D8;1105 116D 11B3; +B8D9;B8D9;1105 116D 11B4;B8D9;1105 116D 11B4; +B8DA;B8DA;1105 116D 11B5;B8DA;1105 116D 11B5; +B8DB;B8DB;1105 116D 11B6;B8DB;1105 116D 11B6; +B8DC;B8DC;1105 116D 11B7;B8DC;1105 116D 11B7; +B8DD;B8DD;1105 116D 11B8;B8DD;1105 116D 11B8; +B8DE;B8DE;1105 116D 11B9;B8DE;1105 116D 11B9; +B8DF;B8DF;1105 116D 11BA;B8DF;1105 116D 11BA; +B8E0;B8E0;1105 116D 11BB;B8E0;1105 116D 11BB; +B8E1;B8E1;1105 116D 11BC;B8E1;1105 116D 11BC; +B8E2;B8E2;1105 116D 11BD;B8E2;1105 116D 11BD; +B8E3;B8E3;1105 116D 11BE;B8E3;1105 116D 11BE; +B8E4;B8E4;1105 116D 11BF;B8E4;1105 116D 11BF; +B8E5;B8E5;1105 116D 11C0;B8E5;1105 116D 11C0; +B8E6;B8E6;1105 116D 11C1;B8E6;1105 116D 11C1; +B8E7;B8E7;1105 116D 11C2;B8E7;1105 116D 11C2; +B8E8;B8E8;1105 116E;B8E8;1105 116E; +B8E9;B8E9;1105 116E 11A8;B8E9;1105 116E 11A8; +B8EA;B8EA;1105 116E 11A9;B8EA;1105 116E 11A9; +B8EB;B8EB;1105 116E 11AA;B8EB;1105 116E 11AA; +B8EC;B8EC;1105 116E 11AB;B8EC;1105 116E 11AB; +B8ED;B8ED;1105 116E 11AC;B8ED;1105 116E 11AC; +B8EE;B8EE;1105 116E 11AD;B8EE;1105 116E 11AD; +B8EF;B8EF;1105 116E 11AE;B8EF;1105 116E 11AE; +B8F0;B8F0;1105 116E 11AF;B8F0;1105 116E 11AF; +B8F1;B8F1;1105 116E 11B0;B8F1;1105 116E 11B0; +B8F2;B8F2;1105 116E 11B1;B8F2;1105 116E 11B1; +B8F3;B8F3;1105 116E 11B2;B8F3;1105 116E 11B2; +B8F4;B8F4;1105 116E 11B3;B8F4;1105 116E 11B3; +B8F5;B8F5;1105 116E 11B4;B8F5;1105 116E 11B4; +B8F6;B8F6;1105 116E 11B5;B8F6;1105 116E 11B5; +B8F7;B8F7;1105 116E 11B6;B8F7;1105 116E 11B6; +B8F8;B8F8;1105 116E 11B7;B8F8;1105 116E 11B7; +B8F9;B8F9;1105 116E 11B8;B8F9;1105 116E 11B8; +B8FA;B8FA;1105 116E 11B9;B8FA;1105 116E 11B9; +B8FB;B8FB;1105 116E 11BA;B8FB;1105 116E 11BA; +B8FC;B8FC;1105 116E 11BB;B8FC;1105 116E 11BB; +B8FD;B8FD;1105 116E 11BC;B8FD;1105 116E 11BC; +B8FE;B8FE;1105 116E 11BD;B8FE;1105 116E 11BD; +B8FF;B8FF;1105 116E 11BE;B8FF;1105 116E 11BE; +B900;B900;1105 116E 11BF;B900;1105 116E 11BF; +B901;B901;1105 116E 11C0;B901;1105 116E 11C0; +B902;B902;1105 116E 11C1;B902;1105 116E 11C1; +B903;B903;1105 116E 11C2;B903;1105 116E 11C2; +B904;B904;1105 116F;B904;1105 116F; +B905;B905;1105 116F 11A8;B905;1105 116F 11A8; +B906;B906;1105 116F 11A9;B906;1105 116F 11A9; +B907;B907;1105 116F 11AA;B907;1105 116F 11AA; +B908;B908;1105 116F 11AB;B908;1105 116F 11AB; +B909;B909;1105 116F 11AC;B909;1105 116F 11AC; +B90A;B90A;1105 116F 11AD;B90A;1105 116F 11AD; +B90B;B90B;1105 116F 11AE;B90B;1105 116F 11AE; +B90C;B90C;1105 116F 11AF;B90C;1105 116F 11AF; +B90D;B90D;1105 116F 11B0;B90D;1105 116F 11B0; +B90E;B90E;1105 116F 11B1;B90E;1105 116F 11B1; +B90F;B90F;1105 116F 11B2;B90F;1105 116F 11B2; +B910;B910;1105 116F 11B3;B910;1105 116F 11B3; +B911;B911;1105 116F 11B4;B911;1105 116F 11B4; +B912;B912;1105 116F 11B5;B912;1105 116F 11B5; +B913;B913;1105 116F 11B6;B913;1105 116F 11B6; +B914;B914;1105 116F 11B7;B914;1105 116F 11B7; +B915;B915;1105 116F 11B8;B915;1105 116F 11B8; +B916;B916;1105 116F 11B9;B916;1105 116F 11B9; +B917;B917;1105 116F 11BA;B917;1105 116F 11BA; +B918;B918;1105 116F 11BB;B918;1105 116F 11BB; +B919;B919;1105 116F 11BC;B919;1105 116F 11BC; +B91A;B91A;1105 116F 11BD;B91A;1105 116F 11BD; +B91B;B91B;1105 116F 11BE;B91B;1105 116F 11BE; +B91C;B91C;1105 116F 11BF;B91C;1105 116F 11BF; +B91D;B91D;1105 116F 11C0;B91D;1105 116F 11C0; +B91E;B91E;1105 116F 11C1;B91E;1105 116F 11C1; +B91F;B91F;1105 116F 11C2;B91F;1105 116F 11C2; +B920;B920;1105 1170;B920;1105 1170; +B921;B921;1105 1170 11A8;B921;1105 1170 11A8; +B922;B922;1105 1170 11A9;B922;1105 1170 11A9; +B923;B923;1105 1170 11AA;B923;1105 1170 11AA; +B924;B924;1105 1170 11AB;B924;1105 1170 11AB; +B925;B925;1105 1170 11AC;B925;1105 1170 11AC; +B926;B926;1105 1170 11AD;B926;1105 1170 11AD; +B927;B927;1105 1170 11AE;B927;1105 1170 11AE; +B928;B928;1105 1170 11AF;B928;1105 1170 11AF; +B929;B929;1105 1170 11B0;B929;1105 1170 11B0; +B92A;B92A;1105 1170 11B1;B92A;1105 1170 11B1; +B92B;B92B;1105 1170 11B2;B92B;1105 1170 11B2; +B92C;B92C;1105 1170 11B3;B92C;1105 1170 11B3; +B92D;B92D;1105 1170 11B4;B92D;1105 1170 11B4; +B92E;B92E;1105 1170 11B5;B92E;1105 1170 11B5; +B92F;B92F;1105 1170 11B6;B92F;1105 1170 11B6; +B930;B930;1105 1170 11B7;B930;1105 1170 11B7; +B931;B931;1105 1170 11B8;B931;1105 1170 11B8; +B932;B932;1105 1170 11B9;B932;1105 1170 11B9; +B933;B933;1105 1170 11BA;B933;1105 1170 11BA; +B934;B934;1105 1170 11BB;B934;1105 1170 11BB; +B935;B935;1105 1170 11BC;B935;1105 1170 11BC; +B936;B936;1105 1170 11BD;B936;1105 1170 11BD; +B937;B937;1105 1170 11BE;B937;1105 1170 11BE; +B938;B938;1105 1170 11BF;B938;1105 1170 11BF; +B939;B939;1105 1170 11C0;B939;1105 1170 11C0; +B93A;B93A;1105 1170 11C1;B93A;1105 1170 11C1; +B93B;B93B;1105 1170 11C2;B93B;1105 1170 11C2; +B93C;B93C;1105 1171;B93C;1105 1171; +B93D;B93D;1105 1171 11A8;B93D;1105 1171 11A8; +B93E;B93E;1105 1171 11A9;B93E;1105 1171 11A9; +B93F;B93F;1105 1171 11AA;B93F;1105 1171 11AA; +B940;B940;1105 1171 11AB;B940;1105 1171 11AB; +B941;B941;1105 1171 11AC;B941;1105 1171 11AC; +B942;B942;1105 1171 11AD;B942;1105 1171 11AD; +B943;B943;1105 1171 11AE;B943;1105 1171 11AE; +B944;B944;1105 1171 11AF;B944;1105 1171 11AF; +B945;B945;1105 1171 11B0;B945;1105 1171 11B0; +B946;B946;1105 1171 11B1;B946;1105 1171 11B1; +B947;B947;1105 1171 11B2;B947;1105 1171 11B2; +B948;B948;1105 1171 11B3;B948;1105 1171 11B3; +B949;B949;1105 1171 11B4;B949;1105 1171 11B4; +B94A;B94A;1105 1171 11B5;B94A;1105 1171 11B5; +B94B;B94B;1105 1171 11B6;B94B;1105 1171 11B6; +B94C;B94C;1105 1171 11B7;B94C;1105 1171 11B7; +B94D;B94D;1105 1171 11B8;B94D;1105 1171 11B8; +B94E;B94E;1105 1171 11B9;B94E;1105 1171 11B9; +B94F;B94F;1105 1171 11BA;B94F;1105 1171 11BA; +B950;B950;1105 1171 11BB;B950;1105 1171 11BB; +B951;B951;1105 1171 11BC;B951;1105 1171 11BC; +B952;B952;1105 1171 11BD;B952;1105 1171 11BD; +B953;B953;1105 1171 11BE;B953;1105 1171 11BE; +B954;B954;1105 1171 11BF;B954;1105 1171 11BF; +B955;B955;1105 1171 11C0;B955;1105 1171 11C0; +B956;B956;1105 1171 11C1;B956;1105 1171 11C1; +B957;B957;1105 1171 11C2;B957;1105 1171 11C2; +B958;B958;1105 1172;B958;1105 1172; +B959;B959;1105 1172 11A8;B959;1105 1172 11A8; +B95A;B95A;1105 1172 11A9;B95A;1105 1172 11A9; +B95B;B95B;1105 1172 11AA;B95B;1105 1172 11AA; +B95C;B95C;1105 1172 11AB;B95C;1105 1172 11AB; +B95D;B95D;1105 1172 11AC;B95D;1105 1172 11AC; +B95E;B95E;1105 1172 11AD;B95E;1105 1172 11AD; +B95F;B95F;1105 1172 11AE;B95F;1105 1172 11AE; +B960;B960;1105 1172 11AF;B960;1105 1172 11AF; +B961;B961;1105 1172 11B0;B961;1105 1172 11B0; +B962;B962;1105 1172 11B1;B962;1105 1172 11B1; +B963;B963;1105 1172 11B2;B963;1105 1172 11B2; +B964;B964;1105 1172 11B3;B964;1105 1172 11B3; +B965;B965;1105 1172 11B4;B965;1105 1172 11B4; +B966;B966;1105 1172 11B5;B966;1105 1172 11B5; +B967;B967;1105 1172 11B6;B967;1105 1172 11B6; +B968;B968;1105 1172 11B7;B968;1105 1172 11B7; +B969;B969;1105 1172 11B8;B969;1105 1172 11B8; +B96A;B96A;1105 1172 11B9;B96A;1105 1172 11B9; +B96B;B96B;1105 1172 11BA;B96B;1105 1172 11BA; +B96C;B96C;1105 1172 11BB;B96C;1105 1172 11BB; +B96D;B96D;1105 1172 11BC;B96D;1105 1172 11BC; +B96E;B96E;1105 1172 11BD;B96E;1105 1172 11BD; +B96F;B96F;1105 1172 11BE;B96F;1105 1172 11BE; +B970;B970;1105 1172 11BF;B970;1105 1172 11BF; +B971;B971;1105 1172 11C0;B971;1105 1172 11C0; +B972;B972;1105 1172 11C1;B972;1105 1172 11C1; +B973;B973;1105 1172 11C2;B973;1105 1172 11C2; +B974;B974;1105 1173;B974;1105 1173; +B975;B975;1105 1173 11A8;B975;1105 1173 11A8; +B976;B976;1105 1173 11A9;B976;1105 1173 11A9; +B977;B977;1105 1173 11AA;B977;1105 1173 11AA; +B978;B978;1105 1173 11AB;B978;1105 1173 11AB; +B979;B979;1105 1173 11AC;B979;1105 1173 11AC; +B97A;B97A;1105 1173 11AD;B97A;1105 1173 11AD; +B97B;B97B;1105 1173 11AE;B97B;1105 1173 11AE; +B97C;B97C;1105 1173 11AF;B97C;1105 1173 11AF; +B97D;B97D;1105 1173 11B0;B97D;1105 1173 11B0; +B97E;B97E;1105 1173 11B1;B97E;1105 1173 11B1; +B97F;B97F;1105 1173 11B2;B97F;1105 1173 11B2; +B980;B980;1105 1173 11B3;B980;1105 1173 11B3; +B981;B981;1105 1173 11B4;B981;1105 1173 11B4; +B982;B982;1105 1173 11B5;B982;1105 1173 11B5; +B983;B983;1105 1173 11B6;B983;1105 1173 11B6; +B984;B984;1105 1173 11B7;B984;1105 1173 11B7; +B985;B985;1105 1173 11B8;B985;1105 1173 11B8; +B986;B986;1105 1173 11B9;B986;1105 1173 11B9; +B987;B987;1105 1173 11BA;B987;1105 1173 11BA; +B988;B988;1105 1173 11BB;B988;1105 1173 11BB; +B989;B989;1105 1173 11BC;B989;1105 1173 11BC; +B98A;B98A;1105 1173 11BD;B98A;1105 1173 11BD; +B98B;B98B;1105 1173 11BE;B98B;1105 1173 11BE; +B98C;B98C;1105 1173 11BF;B98C;1105 1173 11BF; +B98D;B98D;1105 1173 11C0;B98D;1105 1173 11C0; +B98E;B98E;1105 1173 11C1;B98E;1105 1173 11C1; +B98F;B98F;1105 1173 11C2;B98F;1105 1173 11C2; +B990;B990;1105 1174;B990;1105 1174; +B991;B991;1105 1174 11A8;B991;1105 1174 11A8; +B992;B992;1105 1174 11A9;B992;1105 1174 11A9; +B993;B993;1105 1174 11AA;B993;1105 1174 11AA; +B994;B994;1105 1174 11AB;B994;1105 1174 11AB; +B995;B995;1105 1174 11AC;B995;1105 1174 11AC; +B996;B996;1105 1174 11AD;B996;1105 1174 11AD; +B997;B997;1105 1174 11AE;B997;1105 1174 11AE; +B998;B998;1105 1174 11AF;B998;1105 1174 11AF; +B999;B999;1105 1174 11B0;B999;1105 1174 11B0; +B99A;B99A;1105 1174 11B1;B99A;1105 1174 11B1; +B99B;B99B;1105 1174 11B2;B99B;1105 1174 11B2; +B99C;B99C;1105 1174 11B3;B99C;1105 1174 11B3; +B99D;B99D;1105 1174 11B4;B99D;1105 1174 11B4; +B99E;B99E;1105 1174 11B5;B99E;1105 1174 11B5; +B99F;B99F;1105 1174 11B6;B99F;1105 1174 11B6; +B9A0;B9A0;1105 1174 11B7;B9A0;1105 1174 11B7; +B9A1;B9A1;1105 1174 11B8;B9A1;1105 1174 11B8; +B9A2;B9A2;1105 1174 11B9;B9A2;1105 1174 11B9; +B9A3;B9A3;1105 1174 11BA;B9A3;1105 1174 11BA; +B9A4;B9A4;1105 1174 11BB;B9A4;1105 1174 11BB; +B9A5;B9A5;1105 1174 11BC;B9A5;1105 1174 11BC; +B9A6;B9A6;1105 1174 11BD;B9A6;1105 1174 11BD; +B9A7;B9A7;1105 1174 11BE;B9A7;1105 1174 11BE; +B9A8;B9A8;1105 1174 11BF;B9A8;1105 1174 11BF; +B9A9;B9A9;1105 1174 11C0;B9A9;1105 1174 11C0; +B9AA;B9AA;1105 1174 11C1;B9AA;1105 1174 11C1; +B9AB;B9AB;1105 1174 11C2;B9AB;1105 1174 11C2; +B9AC;B9AC;1105 1175;B9AC;1105 1175; +B9AD;B9AD;1105 1175 11A8;B9AD;1105 1175 11A8; +B9AE;B9AE;1105 1175 11A9;B9AE;1105 1175 11A9; +B9AF;B9AF;1105 1175 11AA;B9AF;1105 1175 11AA; +B9B0;B9B0;1105 1175 11AB;B9B0;1105 1175 11AB; +B9B1;B9B1;1105 1175 11AC;B9B1;1105 1175 11AC; +B9B2;B9B2;1105 1175 11AD;B9B2;1105 1175 11AD; +B9B3;B9B3;1105 1175 11AE;B9B3;1105 1175 11AE; +B9B4;B9B4;1105 1175 11AF;B9B4;1105 1175 11AF; +B9B5;B9B5;1105 1175 11B0;B9B5;1105 1175 11B0; +B9B6;B9B6;1105 1175 11B1;B9B6;1105 1175 11B1; +B9B7;B9B7;1105 1175 11B2;B9B7;1105 1175 11B2; +B9B8;B9B8;1105 1175 11B3;B9B8;1105 1175 11B3; +B9B9;B9B9;1105 1175 11B4;B9B9;1105 1175 11B4; +B9BA;B9BA;1105 1175 11B5;B9BA;1105 1175 11B5; +B9BB;B9BB;1105 1175 11B6;B9BB;1105 1175 11B6; +B9BC;B9BC;1105 1175 11B7;B9BC;1105 1175 11B7; +B9BD;B9BD;1105 1175 11B8;B9BD;1105 1175 11B8; +B9BE;B9BE;1105 1175 11B9;B9BE;1105 1175 11B9; +B9BF;B9BF;1105 1175 11BA;B9BF;1105 1175 11BA; +B9C0;B9C0;1105 1175 11BB;B9C0;1105 1175 11BB; +B9C1;B9C1;1105 1175 11BC;B9C1;1105 1175 11BC; +B9C2;B9C2;1105 1175 11BD;B9C2;1105 1175 11BD; +B9C3;B9C3;1105 1175 11BE;B9C3;1105 1175 11BE; +B9C4;B9C4;1105 1175 11BF;B9C4;1105 1175 11BF; +B9C5;B9C5;1105 1175 11C0;B9C5;1105 1175 11C0; +B9C6;B9C6;1105 1175 11C1;B9C6;1105 1175 11C1; +B9C7;B9C7;1105 1175 11C2;B9C7;1105 1175 11C2; +B9C8;B9C8;1106 1161;B9C8;1106 1161; +B9C9;B9C9;1106 1161 11A8;B9C9;1106 1161 11A8; +B9CA;B9CA;1106 1161 11A9;B9CA;1106 1161 11A9; +B9CB;B9CB;1106 1161 11AA;B9CB;1106 1161 11AA; +B9CC;B9CC;1106 1161 11AB;B9CC;1106 1161 11AB; +B9CD;B9CD;1106 1161 11AC;B9CD;1106 1161 11AC; +B9CE;B9CE;1106 1161 11AD;B9CE;1106 1161 11AD; +B9CF;B9CF;1106 1161 11AE;B9CF;1106 1161 11AE; +B9D0;B9D0;1106 1161 11AF;B9D0;1106 1161 11AF; +B9D1;B9D1;1106 1161 11B0;B9D1;1106 1161 11B0; +B9D2;B9D2;1106 1161 11B1;B9D2;1106 1161 11B1; +B9D3;B9D3;1106 1161 11B2;B9D3;1106 1161 11B2; +B9D4;B9D4;1106 1161 11B3;B9D4;1106 1161 11B3; +B9D5;B9D5;1106 1161 11B4;B9D5;1106 1161 11B4; +B9D6;B9D6;1106 1161 11B5;B9D6;1106 1161 11B5; +B9D7;B9D7;1106 1161 11B6;B9D7;1106 1161 11B6; +B9D8;B9D8;1106 1161 11B7;B9D8;1106 1161 11B7; +B9D9;B9D9;1106 1161 11B8;B9D9;1106 1161 11B8; +B9DA;B9DA;1106 1161 11B9;B9DA;1106 1161 11B9; +B9DB;B9DB;1106 1161 11BA;B9DB;1106 1161 11BA; +B9DC;B9DC;1106 1161 11BB;B9DC;1106 1161 11BB; +B9DD;B9DD;1106 1161 11BC;B9DD;1106 1161 11BC; +B9DE;B9DE;1106 1161 11BD;B9DE;1106 1161 11BD; +B9DF;B9DF;1106 1161 11BE;B9DF;1106 1161 11BE; +B9E0;B9E0;1106 1161 11BF;B9E0;1106 1161 11BF; +B9E1;B9E1;1106 1161 11C0;B9E1;1106 1161 11C0; +B9E2;B9E2;1106 1161 11C1;B9E2;1106 1161 11C1; +B9E3;B9E3;1106 1161 11C2;B9E3;1106 1161 11C2; +B9E4;B9E4;1106 1162;B9E4;1106 1162; +B9E5;B9E5;1106 1162 11A8;B9E5;1106 1162 11A8; +B9E6;B9E6;1106 1162 11A9;B9E6;1106 1162 11A9; +B9E7;B9E7;1106 1162 11AA;B9E7;1106 1162 11AA; +B9E8;B9E8;1106 1162 11AB;B9E8;1106 1162 11AB; +B9E9;B9E9;1106 1162 11AC;B9E9;1106 1162 11AC; +B9EA;B9EA;1106 1162 11AD;B9EA;1106 1162 11AD; +B9EB;B9EB;1106 1162 11AE;B9EB;1106 1162 11AE; +B9EC;B9EC;1106 1162 11AF;B9EC;1106 1162 11AF; +B9ED;B9ED;1106 1162 11B0;B9ED;1106 1162 11B0; +B9EE;B9EE;1106 1162 11B1;B9EE;1106 1162 11B1; +B9EF;B9EF;1106 1162 11B2;B9EF;1106 1162 11B2; +B9F0;B9F0;1106 1162 11B3;B9F0;1106 1162 11B3; +B9F1;B9F1;1106 1162 11B4;B9F1;1106 1162 11B4; +B9F2;B9F2;1106 1162 11B5;B9F2;1106 1162 11B5; +B9F3;B9F3;1106 1162 11B6;B9F3;1106 1162 11B6; +B9F4;B9F4;1106 1162 11B7;B9F4;1106 1162 11B7; +B9F5;B9F5;1106 1162 11B8;B9F5;1106 1162 11B8; +B9F6;B9F6;1106 1162 11B9;B9F6;1106 1162 11B9; +B9F7;B9F7;1106 1162 11BA;B9F7;1106 1162 11BA; +B9F8;B9F8;1106 1162 11BB;B9F8;1106 1162 11BB; +B9F9;B9F9;1106 1162 11BC;B9F9;1106 1162 11BC; +B9FA;B9FA;1106 1162 11BD;B9FA;1106 1162 11BD; +B9FB;B9FB;1106 1162 11BE;B9FB;1106 1162 11BE; +B9FC;B9FC;1106 1162 11BF;B9FC;1106 1162 11BF; +B9FD;B9FD;1106 1162 11C0;B9FD;1106 1162 11C0; +B9FE;B9FE;1106 1162 11C1;B9FE;1106 1162 11C1; +B9FF;B9FF;1106 1162 11C2;B9FF;1106 1162 11C2; +BA00;BA00;1106 1163;BA00;1106 1163; +BA01;BA01;1106 1163 11A8;BA01;1106 1163 11A8; +BA02;BA02;1106 1163 11A9;BA02;1106 1163 11A9; +BA03;BA03;1106 1163 11AA;BA03;1106 1163 11AA; +BA04;BA04;1106 1163 11AB;BA04;1106 1163 11AB; +BA05;BA05;1106 1163 11AC;BA05;1106 1163 11AC; +BA06;BA06;1106 1163 11AD;BA06;1106 1163 11AD; +BA07;BA07;1106 1163 11AE;BA07;1106 1163 11AE; +BA08;BA08;1106 1163 11AF;BA08;1106 1163 11AF; +BA09;BA09;1106 1163 11B0;BA09;1106 1163 11B0; +BA0A;BA0A;1106 1163 11B1;BA0A;1106 1163 11B1; +BA0B;BA0B;1106 1163 11B2;BA0B;1106 1163 11B2; +BA0C;BA0C;1106 1163 11B3;BA0C;1106 1163 11B3; +BA0D;BA0D;1106 1163 11B4;BA0D;1106 1163 11B4; +BA0E;BA0E;1106 1163 11B5;BA0E;1106 1163 11B5; +BA0F;BA0F;1106 1163 11B6;BA0F;1106 1163 11B6; +BA10;BA10;1106 1163 11B7;BA10;1106 1163 11B7; +BA11;BA11;1106 1163 11B8;BA11;1106 1163 11B8; +BA12;BA12;1106 1163 11B9;BA12;1106 1163 11B9; +BA13;BA13;1106 1163 11BA;BA13;1106 1163 11BA; +BA14;BA14;1106 1163 11BB;BA14;1106 1163 11BB; +BA15;BA15;1106 1163 11BC;BA15;1106 1163 11BC; +BA16;BA16;1106 1163 11BD;BA16;1106 1163 11BD; +BA17;BA17;1106 1163 11BE;BA17;1106 1163 11BE; +BA18;BA18;1106 1163 11BF;BA18;1106 1163 11BF; +BA19;BA19;1106 1163 11C0;BA19;1106 1163 11C0; +BA1A;BA1A;1106 1163 11C1;BA1A;1106 1163 11C1; +BA1B;BA1B;1106 1163 11C2;BA1B;1106 1163 11C2; +BA1C;BA1C;1106 1164;BA1C;1106 1164; +BA1D;BA1D;1106 1164 11A8;BA1D;1106 1164 11A8; +BA1E;BA1E;1106 1164 11A9;BA1E;1106 1164 11A9; +BA1F;BA1F;1106 1164 11AA;BA1F;1106 1164 11AA; +BA20;BA20;1106 1164 11AB;BA20;1106 1164 11AB; +BA21;BA21;1106 1164 11AC;BA21;1106 1164 11AC; +BA22;BA22;1106 1164 11AD;BA22;1106 1164 11AD; +BA23;BA23;1106 1164 11AE;BA23;1106 1164 11AE; +BA24;BA24;1106 1164 11AF;BA24;1106 1164 11AF; +BA25;BA25;1106 1164 11B0;BA25;1106 1164 11B0; +BA26;BA26;1106 1164 11B1;BA26;1106 1164 11B1; +BA27;BA27;1106 1164 11B2;BA27;1106 1164 11B2; +BA28;BA28;1106 1164 11B3;BA28;1106 1164 11B3; +BA29;BA29;1106 1164 11B4;BA29;1106 1164 11B4; +BA2A;BA2A;1106 1164 11B5;BA2A;1106 1164 11B5; +BA2B;BA2B;1106 1164 11B6;BA2B;1106 1164 11B6; +BA2C;BA2C;1106 1164 11B7;BA2C;1106 1164 11B7; +BA2D;BA2D;1106 1164 11B8;BA2D;1106 1164 11B8; +BA2E;BA2E;1106 1164 11B9;BA2E;1106 1164 11B9; +BA2F;BA2F;1106 1164 11BA;BA2F;1106 1164 11BA; +BA30;BA30;1106 1164 11BB;BA30;1106 1164 11BB; +BA31;BA31;1106 1164 11BC;BA31;1106 1164 11BC; +BA32;BA32;1106 1164 11BD;BA32;1106 1164 11BD; +BA33;BA33;1106 1164 11BE;BA33;1106 1164 11BE; +BA34;BA34;1106 1164 11BF;BA34;1106 1164 11BF; +BA35;BA35;1106 1164 11C0;BA35;1106 1164 11C0; +BA36;BA36;1106 1164 11C1;BA36;1106 1164 11C1; +BA37;BA37;1106 1164 11C2;BA37;1106 1164 11C2; +BA38;BA38;1106 1165;BA38;1106 1165; +BA39;BA39;1106 1165 11A8;BA39;1106 1165 11A8; +BA3A;BA3A;1106 1165 11A9;BA3A;1106 1165 11A9; +BA3B;BA3B;1106 1165 11AA;BA3B;1106 1165 11AA; +BA3C;BA3C;1106 1165 11AB;BA3C;1106 1165 11AB; +BA3D;BA3D;1106 1165 11AC;BA3D;1106 1165 11AC; +BA3E;BA3E;1106 1165 11AD;BA3E;1106 1165 11AD; +BA3F;BA3F;1106 1165 11AE;BA3F;1106 1165 11AE; +BA40;BA40;1106 1165 11AF;BA40;1106 1165 11AF; +BA41;BA41;1106 1165 11B0;BA41;1106 1165 11B0; +BA42;BA42;1106 1165 11B1;BA42;1106 1165 11B1; +BA43;BA43;1106 1165 11B2;BA43;1106 1165 11B2; +BA44;BA44;1106 1165 11B3;BA44;1106 1165 11B3; +BA45;BA45;1106 1165 11B4;BA45;1106 1165 11B4; +BA46;BA46;1106 1165 11B5;BA46;1106 1165 11B5; +BA47;BA47;1106 1165 11B6;BA47;1106 1165 11B6; +BA48;BA48;1106 1165 11B7;BA48;1106 1165 11B7; +BA49;BA49;1106 1165 11B8;BA49;1106 1165 11B8; +BA4A;BA4A;1106 1165 11B9;BA4A;1106 1165 11B9; +BA4B;BA4B;1106 1165 11BA;BA4B;1106 1165 11BA; +BA4C;BA4C;1106 1165 11BB;BA4C;1106 1165 11BB; +BA4D;BA4D;1106 1165 11BC;BA4D;1106 1165 11BC; +BA4E;BA4E;1106 1165 11BD;BA4E;1106 1165 11BD; +BA4F;BA4F;1106 1165 11BE;BA4F;1106 1165 11BE; +BA50;BA50;1106 1165 11BF;BA50;1106 1165 11BF; +BA51;BA51;1106 1165 11C0;BA51;1106 1165 11C0; +BA52;BA52;1106 1165 11C1;BA52;1106 1165 11C1; +BA53;BA53;1106 1165 11C2;BA53;1106 1165 11C2; +BA54;BA54;1106 1166;BA54;1106 1166; +BA55;BA55;1106 1166 11A8;BA55;1106 1166 11A8; +BA56;BA56;1106 1166 11A9;BA56;1106 1166 11A9; +BA57;BA57;1106 1166 11AA;BA57;1106 1166 11AA; +BA58;BA58;1106 1166 11AB;BA58;1106 1166 11AB; +BA59;BA59;1106 1166 11AC;BA59;1106 1166 11AC; +BA5A;BA5A;1106 1166 11AD;BA5A;1106 1166 11AD; +BA5B;BA5B;1106 1166 11AE;BA5B;1106 1166 11AE; +BA5C;BA5C;1106 1166 11AF;BA5C;1106 1166 11AF; +BA5D;BA5D;1106 1166 11B0;BA5D;1106 1166 11B0; +BA5E;BA5E;1106 1166 11B1;BA5E;1106 1166 11B1; +BA5F;BA5F;1106 1166 11B2;BA5F;1106 1166 11B2; +BA60;BA60;1106 1166 11B3;BA60;1106 1166 11B3; +BA61;BA61;1106 1166 11B4;BA61;1106 1166 11B4; +BA62;BA62;1106 1166 11B5;BA62;1106 1166 11B5; +BA63;BA63;1106 1166 11B6;BA63;1106 1166 11B6; +BA64;BA64;1106 1166 11B7;BA64;1106 1166 11B7; +BA65;BA65;1106 1166 11B8;BA65;1106 1166 11B8; +BA66;BA66;1106 1166 11B9;BA66;1106 1166 11B9; +BA67;BA67;1106 1166 11BA;BA67;1106 1166 11BA; +BA68;BA68;1106 1166 11BB;BA68;1106 1166 11BB; +BA69;BA69;1106 1166 11BC;BA69;1106 1166 11BC; +BA6A;BA6A;1106 1166 11BD;BA6A;1106 1166 11BD; +BA6B;BA6B;1106 1166 11BE;BA6B;1106 1166 11BE; +BA6C;BA6C;1106 1166 11BF;BA6C;1106 1166 11BF; +BA6D;BA6D;1106 1166 11C0;BA6D;1106 1166 11C0; +BA6E;BA6E;1106 1166 11C1;BA6E;1106 1166 11C1; +BA6F;BA6F;1106 1166 11C2;BA6F;1106 1166 11C2; +BA70;BA70;1106 1167;BA70;1106 1167; +BA71;BA71;1106 1167 11A8;BA71;1106 1167 11A8; +BA72;BA72;1106 1167 11A9;BA72;1106 1167 11A9; +BA73;BA73;1106 1167 11AA;BA73;1106 1167 11AA; +BA74;BA74;1106 1167 11AB;BA74;1106 1167 11AB; +BA75;BA75;1106 1167 11AC;BA75;1106 1167 11AC; +BA76;BA76;1106 1167 11AD;BA76;1106 1167 11AD; +BA77;BA77;1106 1167 11AE;BA77;1106 1167 11AE; +BA78;BA78;1106 1167 11AF;BA78;1106 1167 11AF; +BA79;BA79;1106 1167 11B0;BA79;1106 1167 11B0; +BA7A;BA7A;1106 1167 11B1;BA7A;1106 1167 11B1; +BA7B;BA7B;1106 1167 11B2;BA7B;1106 1167 11B2; +BA7C;BA7C;1106 1167 11B3;BA7C;1106 1167 11B3; +BA7D;BA7D;1106 1167 11B4;BA7D;1106 1167 11B4; +BA7E;BA7E;1106 1167 11B5;BA7E;1106 1167 11B5; +BA7F;BA7F;1106 1167 11B6;BA7F;1106 1167 11B6; +BA80;BA80;1106 1167 11B7;BA80;1106 1167 11B7; +BA81;BA81;1106 1167 11B8;BA81;1106 1167 11B8; +BA82;BA82;1106 1167 11B9;BA82;1106 1167 11B9; +BA83;BA83;1106 1167 11BA;BA83;1106 1167 11BA; +BA84;BA84;1106 1167 11BB;BA84;1106 1167 11BB; +BA85;BA85;1106 1167 11BC;BA85;1106 1167 11BC; +BA86;BA86;1106 1167 11BD;BA86;1106 1167 11BD; +BA87;BA87;1106 1167 11BE;BA87;1106 1167 11BE; +BA88;BA88;1106 1167 11BF;BA88;1106 1167 11BF; +BA89;BA89;1106 1167 11C0;BA89;1106 1167 11C0; +BA8A;BA8A;1106 1167 11C1;BA8A;1106 1167 11C1; +BA8B;BA8B;1106 1167 11C2;BA8B;1106 1167 11C2; +BA8C;BA8C;1106 1168;BA8C;1106 1168; +BA8D;BA8D;1106 1168 11A8;BA8D;1106 1168 11A8; +BA8E;BA8E;1106 1168 11A9;BA8E;1106 1168 11A9; +BA8F;BA8F;1106 1168 11AA;BA8F;1106 1168 11AA; +BA90;BA90;1106 1168 11AB;BA90;1106 1168 11AB; +BA91;BA91;1106 1168 11AC;BA91;1106 1168 11AC; +BA92;BA92;1106 1168 11AD;BA92;1106 1168 11AD; +BA93;BA93;1106 1168 11AE;BA93;1106 1168 11AE; +BA94;BA94;1106 1168 11AF;BA94;1106 1168 11AF; +BA95;BA95;1106 1168 11B0;BA95;1106 1168 11B0; +BA96;BA96;1106 1168 11B1;BA96;1106 1168 11B1; +BA97;BA97;1106 1168 11B2;BA97;1106 1168 11B2; +BA98;BA98;1106 1168 11B3;BA98;1106 1168 11B3; +BA99;BA99;1106 1168 11B4;BA99;1106 1168 11B4; +BA9A;BA9A;1106 1168 11B5;BA9A;1106 1168 11B5; +BA9B;BA9B;1106 1168 11B6;BA9B;1106 1168 11B6; +BA9C;BA9C;1106 1168 11B7;BA9C;1106 1168 11B7; +BA9D;BA9D;1106 1168 11B8;BA9D;1106 1168 11B8; +BA9E;BA9E;1106 1168 11B9;BA9E;1106 1168 11B9; +BA9F;BA9F;1106 1168 11BA;BA9F;1106 1168 11BA; +BAA0;BAA0;1106 1168 11BB;BAA0;1106 1168 11BB; +BAA1;BAA1;1106 1168 11BC;BAA1;1106 1168 11BC; +BAA2;BAA2;1106 1168 11BD;BAA2;1106 1168 11BD; +BAA3;BAA3;1106 1168 11BE;BAA3;1106 1168 11BE; +BAA4;BAA4;1106 1168 11BF;BAA4;1106 1168 11BF; +BAA5;BAA5;1106 1168 11C0;BAA5;1106 1168 11C0; +BAA6;BAA6;1106 1168 11C1;BAA6;1106 1168 11C1; +BAA7;BAA7;1106 1168 11C2;BAA7;1106 1168 11C2; +BAA8;BAA8;1106 1169;BAA8;1106 1169; +BAA9;BAA9;1106 1169 11A8;BAA9;1106 1169 11A8; +BAAA;BAAA;1106 1169 11A9;BAAA;1106 1169 11A9; +BAAB;BAAB;1106 1169 11AA;BAAB;1106 1169 11AA; +BAAC;BAAC;1106 1169 11AB;BAAC;1106 1169 11AB; +BAAD;BAAD;1106 1169 11AC;BAAD;1106 1169 11AC; +BAAE;BAAE;1106 1169 11AD;BAAE;1106 1169 11AD; +BAAF;BAAF;1106 1169 11AE;BAAF;1106 1169 11AE; +BAB0;BAB0;1106 1169 11AF;BAB0;1106 1169 11AF; +BAB1;BAB1;1106 1169 11B0;BAB1;1106 1169 11B0; +BAB2;BAB2;1106 1169 11B1;BAB2;1106 1169 11B1; +BAB3;BAB3;1106 1169 11B2;BAB3;1106 1169 11B2; +BAB4;BAB4;1106 1169 11B3;BAB4;1106 1169 11B3; +BAB5;BAB5;1106 1169 11B4;BAB5;1106 1169 11B4; +BAB6;BAB6;1106 1169 11B5;BAB6;1106 1169 11B5; +BAB7;BAB7;1106 1169 11B6;BAB7;1106 1169 11B6; +BAB8;BAB8;1106 1169 11B7;BAB8;1106 1169 11B7; +BAB9;BAB9;1106 1169 11B8;BAB9;1106 1169 11B8; +BABA;BABA;1106 1169 11B9;BABA;1106 1169 11B9; +BABB;BABB;1106 1169 11BA;BABB;1106 1169 11BA; +BABC;BABC;1106 1169 11BB;BABC;1106 1169 11BB; +BABD;BABD;1106 1169 11BC;BABD;1106 1169 11BC; +BABE;BABE;1106 1169 11BD;BABE;1106 1169 11BD; +BABF;BABF;1106 1169 11BE;BABF;1106 1169 11BE; +BAC0;BAC0;1106 1169 11BF;BAC0;1106 1169 11BF; +BAC1;BAC1;1106 1169 11C0;BAC1;1106 1169 11C0; +BAC2;BAC2;1106 1169 11C1;BAC2;1106 1169 11C1; +BAC3;BAC3;1106 1169 11C2;BAC3;1106 1169 11C2; +BAC4;BAC4;1106 116A;BAC4;1106 116A; +BAC5;BAC5;1106 116A 11A8;BAC5;1106 116A 11A8; +BAC6;BAC6;1106 116A 11A9;BAC6;1106 116A 11A9; +BAC7;BAC7;1106 116A 11AA;BAC7;1106 116A 11AA; +BAC8;BAC8;1106 116A 11AB;BAC8;1106 116A 11AB; +BAC9;BAC9;1106 116A 11AC;BAC9;1106 116A 11AC; +BACA;BACA;1106 116A 11AD;BACA;1106 116A 11AD; +BACB;BACB;1106 116A 11AE;BACB;1106 116A 11AE; +BACC;BACC;1106 116A 11AF;BACC;1106 116A 11AF; +BACD;BACD;1106 116A 11B0;BACD;1106 116A 11B0; +BACE;BACE;1106 116A 11B1;BACE;1106 116A 11B1; +BACF;BACF;1106 116A 11B2;BACF;1106 116A 11B2; +BAD0;BAD0;1106 116A 11B3;BAD0;1106 116A 11B3; +BAD1;BAD1;1106 116A 11B4;BAD1;1106 116A 11B4; +BAD2;BAD2;1106 116A 11B5;BAD2;1106 116A 11B5; +BAD3;BAD3;1106 116A 11B6;BAD3;1106 116A 11B6; +BAD4;BAD4;1106 116A 11B7;BAD4;1106 116A 11B7; +BAD5;BAD5;1106 116A 11B8;BAD5;1106 116A 11B8; +BAD6;BAD6;1106 116A 11B9;BAD6;1106 116A 11B9; +BAD7;BAD7;1106 116A 11BA;BAD7;1106 116A 11BA; +BAD8;BAD8;1106 116A 11BB;BAD8;1106 116A 11BB; +BAD9;BAD9;1106 116A 11BC;BAD9;1106 116A 11BC; +BADA;BADA;1106 116A 11BD;BADA;1106 116A 11BD; +BADB;BADB;1106 116A 11BE;BADB;1106 116A 11BE; +BADC;BADC;1106 116A 11BF;BADC;1106 116A 11BF; +BADD;BADD;1106 116A 11C0;BADD;1106 116A 11C0; +BADE;BADE;1106 116A 11C1;BADE;1106 116A 11C1; +BADF;BADF;1106 116A 11C2;BADF;1106 116A 11C2; +BAE0;BAE0;1106 116B;BAE0;1106 116B; +BAE1;BAE1;1106 116B 11A8;BAE1;1106 116B 11A8; +BAE2;BAE2;1106 116B 11A9;BAE2;1106 116B 11A9; +BAE3;BAE3;1106 116B 11AA;BAE3;1106 116B 11AA; +BAE4;BAE4;1106 116B 11AB;BAE4;1106 116B 11AB; +BAE5;BAE5;1106 116B 11AC;BAE5;1106 116B 11AC; +BAE6;BAE6;1106 116B 11AD;BAE6;1106 116B 11AD; +BAE7;BAE7;1106 116B 11AE;BAE7;1106 116B 11AE; +BAE8;BAE8;1106 116B 11AF;BAE8;1106 116B 11AF; +BAE9;BAE9;1106 116B 11B0;BAE9;1106 116B 11B0; +BAEA;BAEA;1106 116B 11B1;BAEA;1106 116B 11B1; +BAEB;BAEB;1106 116B 11B2;BAEB;1106 116B 11B2; +BAEC;BAEC;1106 116B 11B3;BAEC;1106 116B 11B3; +BAED;BAED;1106 116B 11B4;BAED;1106 116B 11B4; +BAEE;BAEE;1106 116B 11B5;BAEE;1106 116B 11B5; +BAEF;BAEF;1106 116B 11B6;BAEF;1106 116B 11B6; +BAF0;BAF0;1106 116B 11B7;BAF0;1106 116B 11B7; +BAF1;BAF1;1106 116B 11B8;BAF1;1106 116B 11B8; +BAF2;BAF2;1106 116B 11B9;BAF2;1106 116B 11B9; +BAF3;BAF3;1106 116B 11BA;BAF3;1106 116B 11BA; +BAF4;BAF4;1106 116B 11BB;BAF4;1106 116B 11BB; +BAF5;BAF5;1106 116B 11BC;BAF5;1106 116B 11BC; +BAF6;BAF6;1106 116B 11BD;BAF6;1106 116B 11BD; +BAF7;BAF7;1106 116B 11BE;BAF7;1106 116B 11BE; +BAF8;BAF8;1106 116B 11BF;BAF8;1106 116B 11BF; +BAF9;BAF9;1106 116B 11C0;BAF9;1106 116B 11C0; +BAFA;BAFA;1106 116B 11C1;BAFA;1106 116B 11C1; +BAFB;BAFB;1106 116B 11C2;BAFB;1106 116B 11C2; +BAFC;BAFC;1106 116C;BAFC;1106 116C; +BAFD;BAFD;1106 116C 11A8;BAFD;1106 116C 11A8; +BAFE;BAFE;1106 116C 11A9;BAFE;1106 116C 11A9; +BAFF;BAFF;1106 116C 11AA;BAFF;1106 116C 11AA; +BB00;BB00;1106 116C 11AB;BB00;1106 116C 11AB; +BB01;BB01;1106 116C 11AC;BB01;1106 116C 11AC; +BB02;BB02;1106 116C 11AD;BB02;1106 116C 11AD; +BB03;BB03;1106 116C 11AE;BB03;1106 116C 11AE; +BB04;BB04;1106 116C 11AF;BB04;1106 116C 11AF; +BB05;BB05;1106 116C 11B0;BB05;1106 116C 11B0; +BB06;BB06;1106 116C 11B1;BB06;1106 116C 11B1; +BB07;BB07;1106 116C 11B2;BB07;1106 116C 11B2; +BB08;BB08;1106 116C 11B3;BB08;1106 116C 11B3; +BB09;BB09;1106 116C 11B4;BB09;1106 116C 11B4; +BB0A;BB0A;1106 116C 11B5;BB0A;1106 116C 11B5; +BB0B;BB0B;1106 116C 11B6;BB0B;1106 116C 11B6; +BB0C;BB0C;1106 116C 11B7;BB0C;1106 116C 11B7; +BB0D;BB0D;1106 116C 11B8;BB0D;1106 116C 11B8; +BB0E;BB0E;1106 116C 11B9;BB0E;1106 116C 11B9; +BB0F;BB0F;1106 116C 11BA;BB0F;1106 116C 11BA; +BB10;BB10;1106 116C 11BB;BB10;1106 116C 11BB; +BB11;BB11;1106 116C 11BC;BB11;1106 116C 11BC; +BB12;BB12;1106 116C 11BD;BB12;1106 116C 11BD; +BB13;BB13;1106 116C 11BE;BB13;1106 116C 11BE; +BB14;BB14;1106 116C 11BF;BB14;1106 116C 11BF; +BB15;BB15;1106 116C 11C0;BB15;1106 116C 11C0; +BB16;BB16;1106 116C 11C1;BB16;1106 116C 11C1; +BB17;BB17;1106 116C 11C2;BB17;1106 116C 11C2; +BB18;BB18;1106 116D;BB18;1106 116D; +BB19;BB19;1106 116D 11A8;BB19;1106 116D 11A8; +BB1A;BB1A;1106 116D 11A9;BB1A;1106 116D 11A9; +BB1B;BB1B;1106 116D 11AA;BB1B;1106 116D 11AA; +BB1C;BB1C;1106 116D 11AB;BB1C;1106 116D 11AB; +BB1D;BB1D;1106 116D 11AC;BB1D;1106 116D 11AC; +BB1E;BB1E;1106 116D 11AD;BB1E;1106 116D 11AD; +BB1F;BB1F;1106 116D 11AE;BB1F;1106 116D 11AE; +BB20;BB20;1106 116D 11AF;BB20;1106 116D 11AF; +BB21;BB21;1106 116D 11B0;BB21;1106 116D 11B0; +BB22;BB22;1106 116D 11B1;BB22;1106 116D 11B1; +BB23;BB23;1106 116D 11B2;BB23;1106 116D 11B2; +BB24;BB24;1106 116D 11B3;BB24;1106 116D 11B3; +BB25;BB25;1106 116D 11B4;BB25;1106 116D 11B4; +BB26;BB26;1106 116D 11B5;BB26;1106 116D 11B5; +BB27;BB27;1106 116D 11B6;BB27;1106 116D 11B6; +BB28;BB28;1106 116D 11B7;BB28;1106 116D 11B7; +BB29;BB29;1106 116D 11B8;BB29;1106 116D 11B8; +BB2A;BB2A;1106 116D 11B9;BB2A;1106 116D 11B9; +BB2B;BB2B;1106 116D 11BA;BB2B;1106 116D 11BA; +BB2C;BB2C;1106 116D 11BB;BB2C;1106 116D 11BB; +BB2D;BB2D;1106 116D 11BC;BB2D;1106 116D 11BC; +BB2E;BB2E;1106 116D 11BD;BB2E;1106 116D 11BD; +BB2F;BB2F;1106 116D 11BE;BB2F;1106 116D 11BE; +BB30;BB30;1106 116D 11BF;BB30;1106 116D 11BF; +BB31;BB31;1106 116D 11C0;BB31;1106 116D 11C0; +BB32;BB32;1106 116D 11C1;BB32;1106 116D 11C1; +BB33;BB33;1106 116D 11C2;BB33;1106 116D 11C2; +BB34;BB34;1106 116E;BB34;1106 116E; +BB35;BB35;1106 116E 11A8;BB35;1106 116E 11A8; +BB36;BB36;1106 116E 11A9;BB36;1106 116E 11A9; +BB37;BB37;1106 116E 11AA;BB37;1106 116E 11AA; +BB38;BB38;1106 116E 11AB;BB38;1106 116E 11AB; +BB39;BB39;1106 116E 11AC;BB39;1106 116E 11AC; +BB3A;BB3A;1106 116E 11AD;BB3A;1106 116E 11AD; +BB3B;BB3B;1106 116E 11AE;BB3B;1106 116E 11AE; +BB3C;BB3C;1106 116E 11AF;BB3C;1106 116E 11AF; +BB3D;BB3D;1106 116E 11B0;BB3D;1106 116E 11B0; +BB3E;BB3E;1106 116E 11B1;BB3E;1106 116E 11B1; +BB3F;BB3F;1106 116E 11B2;BB3F;1106 116E 11B2; +BB40;BB40;1106 116E 11B3;BB40;1106 116E 11B3; +BB41;BB41;1106 116E 11B4;BB41;1106 116E 11B4; +BB42;BB42;1106 116E 11B5;BB42;1106 116E 11B5; +BB43;BB43;1106 116E 11B6;BB43;1106 116E 11B6; +BB44;BB44;1106 116E 11B7;BB44;1106 116E 11B7; +BB45;BB45;1106 116E 11B8;BB45;1106 116E 11B8; +BB46;BB46;1106 116E 11B9;BB46;1106 116E 11B9; +BB47;BB47;1106 116E 11BA;BB47;1106 116E 11BA; +BB48;BB48;1106 116E 11BB;BB48;1106 116E 11BB; +BB49;BB49;1106 116E 11BC;BB49;1106 116E 11BC; +BB4A;BB4A;1106 116E 11BD;BB4A;1106 116E 11BD; +BB4B;BB4B;1106 116E 11BE;BB4B;1106 116E 11BE; +BB4C;BB4C;1106 116E 11BF;BB4C;1106 116E 11BF; +BB4D;BB4D;1106 116E 11C0;BB4D;1106 116E 11C0; +BB4E;BB4E;1106 116E 11C1;BB4E;1106 116E 11C1; +BB4F;BB4F;1106 116E 11C2;BB4F;1106 116E 11C2; +BB50;BB50;1106 116F;BB50;1106 116F; +BB51;BB51;1106 116F 11A8;BB51;1106 116F 11A8; +BB52;BB52;1106 116F 11A9;BB52;1106 116F 11A9; +BB53;BB53;1106 116F 11AA;BB53;1106 116F 11AA; +BB54;BB54;1106 116F 11AB;BB54;1106 116F 11AB; +BB55;BB55;1106 116F 11AC;BB55;1106 116F 11AC; +BB56;BB56;1106 116F 11AD;BB56;1106 116F 11AD; +BB57;BB57;1106 116F 11AE;BB57;1106 116F 11AE; +BB58;BB58;1106 116F 11AF;BB58;1106 116F 11AF; +BB59;BB59;1106 116F 11B0;BB59;1106 116F 11B0; +BB5A;BB5A;1106 116F 11B1;BB5A;1106 116F 11B1; +BB5B;BB5B;1106 116F 11B2;BB5B;1106 116F 11B2; +BB5C;BB5C;1106 116F 11B3;BB5C;1106 116F 11B3; +BB5D;BB5D;1106 116F 11B4;BB5D;1106 116F 11B4; +BB5E;BB5E;1106 116F 11B5;BB5E;1106 116F 11B5; +BB5F;BB5F;1106 116F 11B6;BB5F;1106 116F 11B6; +BB60;BB60;1106 116F 11B7;BB60;1106 116F 11B7; +BB61;BB61;1106 116F 11B8;BB61;1106 116F 11B8; +BB62;BB62;1106 116F 11B9;BB62;1106 116F 11B9; +BB63;BB63;1106 116F 11BA;BB63;1106 116F 11BA; +BB64;BB64;1106 116F 11BB;BB64;1106 116F 11BB; +BB65;BB65;1106 116F 11BC;BB65;1106 116F 11BC; +BB66;BB66;1106 116F 11BD;BB66;1106 116F 11BD; +BB67;BB67;1106 116F 11BE;BB67;1106 116F 11BE; +BB68;BB68;1106 116F 11BF;BB68;1106 116F 11BF; +BB69;BB69;1106 116F 11C0;BB69;1106 116F 11C0; +BB6A;BB6A;1106 116F 11C1;BB6A;1106 116F 11C1; +BB6B;BB6B;1106 116F 11C2;BB6B;1106 116F 11C2; +BB6C;BB6C;1106 1170;BB6C;1106 1170; +BB6D;BB6D;1106 1170 11A8;BB6D;1106 1170 11A8; +BB6E;BB6E;1106 1170 11A9;BB6E;1106 1170 11A9; +BB6F;BB6F;1106 1170 11AA;BB6F;1106 1170 11AA; +BB70;BB70;1106 1170 11AB;BB70;1106 1170 11AB; +BB71;BB71;1106 1170 11AC;BB71;1106 1170 11AC; +BB72;BB72;1106 1170 11AD;BB72;1106 1170 11AD; +BB73;BB73;1106 1170 11AE;BB73;1106 1170 11AE; +BB74;BB74;1106 1170 11AF;BB74;1106 1170 11AF; +BB75;BB75;1106 1170 11B0;BB75;1106 1170 11B0; +BB76;BB76;1106 1170 11B1;BB76;1106 1170 11B1; +BB77;BB77;1106 1170 11B2;BB77;1106 1170 11B2; +BB78;BB78;1106 1170 11B3;BB78;1106 1170 11B3; +BB79;BB79;1106 1170 11B4;BB79;1106 1170 11B4; +BB7A;BB7A;1106 1170 11B5;BB7A;1106 1170 11B5; +BB7B;BB7B;1106 1170 11B6;BB7B;1106 1170 11B6; +BB7C;BB7C;1106 1170 11B7;BB7C;1106 1170 11B7; +BB7D;BB7D;1106 1170 11B8;BB7D;1106 1170 11B8; +BB7E;BB7E;1106 1170 11B9;BB7E;1106 1170 11B9; +BB7F;BB7F;1106 1170 11BA;BB7F;1106 1170 11BA; +BB80;BB80;1106 1170 11BB;BB80;1106 1170 11BB; +BB81;BB81;1106 1170 11BC;BB81;1106 1170 11BC; +BB82;BB82;1106 1170 11BD;BB82;1106 1170 11BD; +BB83;BB83;1106 1170 11BE;BB83;1106 1170 11BE; +BB84;BB84;1106 1170 11BF;BB84;1106 1170 11BF; +BB85;BB85;1106 1170 11C0;BB85;1106 1170 11C0; +BB86;BB86;1106 1170 11C1;BB86;1106 1170 11C1; +BB87;BB87;1106 1170 11C2;BB87;1106 1170 11C2; +BB88;BB88;1106 1171;BB88;1106 1171; +BB89;BB89;1106 1171 11A8;BB89;1106 1171 11A8; +BB8A;BB8A;1106 1171 11A9;BB8A;1106 1171 11A9; +BB8B;BB8B;1106 1171 11AA;BB8B;1106 1171 11AA; +BB8C;BB8C;1106 1171 11AB;BB8C;1106 1171 11AB; +BB8D;BB8D;1106 1171 11AC;BB8D;1106 1171 11AC; +BB8E;BB8E;1106 1171 11AD;BB8E;1106 1171 11AD; +BB8F;BB8F;1106 1171 11AE;BB8F;1106 1171 11AE; +BB90;BB90;1106 1171 11AF;BB90;1106 1171 11AF; +BB91;BB91;1106 1171 11B0;BB91;1106 1171 11B0; +BB92;BB92;1106 1171 11B1;BB92;1106 1171 11B1; +BB93;BB93;1106 1171 11B2;BB93;1106 1171 11B2; +BB94;BB94;1106 1171 11B3;BB94;1106 1171 11B3; +BB95;BB95;1106 1171 11B4;BB95;1106 1171 11B4; +BB96;BB96;1106 1171 11B5;BB96;1106 1171 11B5; +BB97;BB97;1106 1171 11B6;BB97;1106 1171 11B6; +BB98;BB98;1106 1171 11B7;BB98;1106 1171 11B7; +BB99;BB99;1106 1171 11B8;BB99;1106 1171 11B8; +BB9A;BB9A;1106 1171 11B9;BB9A;1106 1171 11B9; +BB9B;BB9B;1106 1171 11BA;BB9B;1106 1171 11BA; +BB9C;BB9C;1106 1171 11BB;BB9C;1106 1171 11BB; +BB9D;BB9D;1106 1171 11BC;BB9D;1106 1171 11BC; +BB9E;BB9E;1106 1171 11BD;BB9E;1106 1171 11BD; +BB9F;BB9F;1106 1171 11BE;BB9F;1106 1171 11BE; +BBA0;BBA0;1106 1171 11BF;BBA0;1106 1171 11BF; +BBA1;BBA1;1106 1171 11C0;BBA1;1106 1171 11C0; +BBA2;BBA2;1106 1171 11C1;BBA2;1106 1171 11C1; +BBA3;BBA3;1106 1171 11C2;BBA3;1106 1171 11C2; +BBA4;BBA4;1106 1172;BBA4;1106 1172; +BBA5;BBA5;1106 1172 11A8;BBA5;1106 1172 11A8; +BBA6;BBA6;1106 1172 11A9;BBA6;1106 1172 11A9; +BBA7;BBA7;1106 1172 11AA;BBA7;1106 1172 11AA; +BBA8;BBA8;1106 1172 11AB;BBA8;1106 1172 11AB; +BBA9;BBA9;1106 1172 11AC;BBA9;1106 1172 11AC; +BBAA;BBAA;1106 1172 11AD;BBAA;1106 1172 11AD; +BBAB;BBAB;1106 1172 11AE;BBAB;1106 1172 11AE; +BBAC;BBAC;1106 1172 11AF;BBAC;1106 1172 11AF; +BBAD;BBAD;1106 1172 11B0;BBAD;1106 1172 11B0; +BBAE;BBAE;1106 1172 11B1;BBAE;1106 1172 11B1; +BBAF;BBAF;1106 1172 11B2;BBAF;1106 1172 11B2; +BBB0;BBB0;1106 1172 11B3;BBB0;1106 1172 11B3; +BBB1;BBB1;1106 1172 11B4;BBB1;1106 1172 11B4; +BBB2;BBB2;1106 1172 11B5;BBB2;1106 1172 11B5; +BBB3;BBB3;1106 1172 11B6;BBB3;1106 1172 11B6; +BBB4;BBB4;1106 1172 11B7;BBB4;1106 1172 11B7; +BBB5;BBB5;1106 1172 11B8;BBB5;1106 1172 11B8; +BBB6;BBB6;1106 1172 11B9;BBB6;1106 1172 11B9; +BBB7;BBB7;1106 1172 11BA;BBB7;1106 1172 11BA; +BBB8;BBB8;1106 1172 11BB;BBB8;1106 1172 11BB; +BBB9;BBB9;1106 1172 11BC;BBB9;1106 1172 11BC; +BBBA;BBBA;1106 1172 11BD;BBBA;1106 1172 11BD; +BBBB;BBBB;1106 1172 11BE;BBBB;1106 1172 11BE; +BBBC;BBBC;1106 1172 11BF;BBBC;1106 1172 11BF; +BBBD;BBBD;1106 1172 11C0;BBBD;1106 1172 11C0; +BBBE;BBBE;1106 1172 11C1;BBBE;1106 1172 11C1; +BBBF;BBBF;1106 1172 11C2;BBBF;1106 1172 11C2; +BBC0;BBC0;1106 1173;BBC0;1106 1173; +BBC1;BBC1;1106 1173 11A8;BBC1;1106 1173 11A8; +BBC2;BBC2;1106 1173 11A9;BBC2;1106 1173 11A9; +BBC3;BBC3;1106 1173 11AA;BBC3;1106 1173 11AA; +BBC4;BBC4;1106 1173 11AB;BBC4;1106 1173 11AB; +BBC5;BBC5;1106 1173 11AC;BBC5;1106 1173 11AC; +BBC6;BBC6;1106 1173 11AD;BBC6;1106 1173 11AD; +BBC7;BBC7;1106 1173 11AE;BBC7;1106 1173 11AE; +BBC8;BBC8;1106 1173 11AF;BBC8;1106 1173 11AF; +BBC9;BBC9;1106 1173 11B0;BBC9;1106 1173 11B0; +BBCA;BBCA;1106 1173 11B1;BBCA;1106 1173 11B1; +BBCB;BBCB;1106 1173 11B2;BBCB;1106 1173 11B2; +BBCC;BBCC;1106 1173 11B3;BBCC;1106 1173 11B3; +BBCD;BBCD;1106 1173 11B4;BBCD;1106 1173 11B4; +BBCE;BBCE;1106 1173 11B5;BBCE;1106 1173 11B5; +BBCF;BBCF;1106 1173 11B6;BBCF;1106 1173 11B6; +BBD0;BBD0;1106 1173 11B7;BBD0;1106 1173 11B7; +BBD1;BBD1;1106 1173 11B8;BBD1;1106 1173 11B8; +BBD2;BBD2;1106 1173 11B9;BBD2;1106 1173 11B9; +BBD3;BBD3;1106 1173 11BA;BBD3;1106 1173 11BA; +BBD4;BBD4;1106 1173 11BB;BBD4;1106 1173 11BB; +BBD5;BBD5;1106 1173 11BC;BBD5;1106 1173 11BC; +BBD6;BBD6;1106 1173 11BD;BBD6;1106 1173 11BD; +BBD7;BBD7;1106 1173 11BE;BBD7;1106 1173 11BE; +BBD8;BBD8;1106 1173 11BF;BBD8;1106 1173 11BF; +BBD9;BBD9;1106 1173 11C0;BBD9;1106 1173 11C0; +BBDA;BBDA;1106 1173 11C1;BBDA;1106 1173 11C1; +BBDB;BBDB;1106 1173 11C2;BBDB;1106 1173 11C2; +BBDC;BBDC;1106 1174;BBDC;1106 1174; +BBDD;BBDD;1106 1174 11A8;BBDD;1106 1174 11A8; +BBDE;BBDE;1106 1174 11A9;BBDE;1106 1174 11A9; +BBDF;BBDF;1106 1174 11AA;BBDF;1106 1174 11AA; +BBE0;BBE0;1106 1174 11AB;BBE0;1106 1174 11AB; +BBE1;BBE1;1106 1174 11AC;BBE1;1106 1174 11AC; +BBE2;BBE2;1106 1174 11AD;BBE2;1106 1174 11AD; +BBE3;BBE3;1106 1174 11AE;BBE3;1106 1174 11AE; +BBE4;BBE4;1106 1174 11AF;BBE4;1106 1174 11AF; +BBE5;BBE5;1106 1174 11B0;BBE5;1106 1174 11B0; +BBE6;BBE6;1106 1174 11B1;BBE6;1106 1174 11B1; +BBE7;BBE7;1106 1174 11B2;BBE7;1106 1174 11B2; +BBE8;BBE8;1106 1174 11B3;BBE8;1106 1174 11B3; +BBE9;BBE9;1106 1174 11B4;BBE9;1106 1174 11B4; +BBEA;BBEA;1106 1174 11B5;BBEA;1106 1174 11B5; +BBEB;BBEB;1106 1174 11B6;BBEB;1106 1174 11B6; +BBEC;BBEC;1106 1174 11B7;BBEC;1106 1174 11B7; +BBED;BBED;1106 1174 11B8;BBED;1106 1174 11B8; +BBEE;BBEE;1106 1174 11B9;BBEE;1106 1174 11B9; +BBEF;BBEF;1106 1174 11BA;BBEF;1106 1174 11BA; +BBF0;BBF0;1106 1174 11BB;BBF0;1106 1174 11BB; +BBF1;BBF1;1106 1174 11BC;BBF1;1106 1174 11BC; +BBF2;BBF2;1106 1174 11BD;BBF2;1106 1174 11BD; +BBF3;BBF3;1106 1174 11BE;BBF3;1106 1174 11BE; +BBF4;BBF4;1106 1174 11BF;BBF4;1106 1174 11BF; +BBF5;BBF5;1106 1174 11C0;BBF5;1106 1174 11C0; +BBF6;BBF6;1106 1174 11C1;BBF6;1106 1174 11C1; +BBF7;BBF7;1106 1174 11C2;BBF7;1106 1174 11C2; +BBF8;BBF8;1106 1175;BBF8;1106 1175; +BBF9;BBF9;1106 1175 11A8;BBF9;1106 1175 11A8; +BBFA;BBFA;1106 1175 11A9;BBFA;1106 1175 11A9; +BBFB;BBFB;1106 1175 11AA;BBFB;1106 1175 11AA; +BBFC;BBFC;1106 1175 11AB;BBFC;1106 1175 11AB; +BBFD;BBFD;1106 1175 11AC;BBFD;1106 1175 11AC; +BBFE;BBFE;1106 1175 11AD;BBFE;1106 1175 11AD; +BBFF;BBFF;1106 1175 11AE;BBFF;1106 1175 11AE; +BC00;BC00;1106 1175 11AF;BC00;1106 1175 11AF; +BC01;BC01;1106 1175 11B0;BC01;1106 1175 11B0; +BC02;BC02;1106 1175 11B1;BC02;1106 1175 11B1; +BC03;BC03;1106 1175 11B2;BC03;1106 1175 11B2; +BC04;BC04;1106 1175 11B3;BC04;1106 1175 11B3; +BC05;BC05;1106 1175 11B4;BC05;1106 1175 11B4; +BC06;BC06;1106 1175 11B5;BC06;1106 1175 11B5; +BC07;BC07;1106 1175 11B6;BC07;1106 1175 11B6; +BC08;BC08;1106 1175 11B7;BC08;1106 1175 11B7; +BC09;BC09;1106 1175 11B8;BC09;1106 1175 11B8; +BC0A;BC0A;1106 1175 11B9;BC0A;1106 1175 11B9; +BC0B;BC0B;1106 1175 11BA;BC0B;1106 1175 11BA; +BC0C;BC0C;1106 1175 11BB;BC0C;1106 1175 11BB; +BC0D;BC0D;1106 1175 11BC;BC0D;1106 1175 11BC; +BC0E;BC0E;1106 1175 11BD;BC0E;1106 1175 11BD; +BC0F;BC0F;1106 1175 11BE;BC0F;1106 1175 11BE; +BC10;BC10;1106 1175 11BF;BC10;1106 1175 11BF; +BC11;BC11;1106 1175 11C0;BC11;1106 1175 11C0; +BC12;BC12;1106 1175 11C1;BC12;1106 1175 11C1; +BC13;BC13;1106 1175 11C2;BC13;1106 1175 11C2; +BC14;BC14;1107 1161;BC14;1107 1161; +BC15;BC15;1107 1161 11A8;BC15;1107 1161 11A8; +BC16;BC16;1107 1161 11A9;BC16;1107 1161 11A9; +BC17;BC17;1107 1161 11AA;BC17;1107 1161 11AA; +BC18;BC18;1107 1161 11AB;BC18;1107 1161 11AB; +BC19;BC19;1107 1161 11AC;BC19;1107 1161 11AC; +BC1A;BC1A;1107 1161 11AD;BC1A;1107 1161 11AD; +BC1B;BC1B;1107 1161 11AE;BC1B;1107 1161 11AE; +BC1C;BC1C;1107 1161 11AF;BC1C;1107 1161 11AF; +BC1D;BC1D;1107 1161 11B0;BC1D;1107 1161 11B0; +BC1E;BC1E;1107 1161 11B1;BC1E;1107 1161 11B1; +BC1F;BC1F;1107 1161 11B2;BC1F;1107 1161 11B2; +BC20;BC20;1107 1161 11B3;BC20;1107 1161 11B3; +BC21;BC21;1107 1161 11B4;BC21;1107 1161 11B4; +BC22;BC22;1107 1161 11B5;BC22;1107 1161 11B5; +BC23;BC23;1107 1161 11B6;BC23;1107 1161 11B6; +BC24;BC24;1107 1161 11B7;BC24;1107 1161 11B7; +BC25;BC25;1107 1161 11B8;BC25;1107 1161 11B8; +BC26;BC26;1107 1161 11B9;BC26;1107 1161 11B9; +BC27;BC27;1107 1161 11BA;BC27;1107 1161 11BA; +BC28;BC28;1107 1161 11BB;BC28;1107 1161 11BB; +BC29;BC29;1107 1161 11BC;BC29;1107 1161 11BC; +BC2A;BC2A;1107 1161 11BD;BC2A;1107 1161 11BD; +BC2B;BC2B;1107 1161 11BE;BC2B;1107 1161 11BE; +BC2C;BC2C;1107 1161 11BF;BC2C;1107 1161 11BF; +BC2D;BC2D;1107 1161 11C0;BC2D;1107 1161 11C0; +BC2E;BC2E;1107 1161 11C1;BC2E;1107 1161 11C1; +BC2F;BC2F;1107 1161 11C2;BC2F;1107 1161 11C2; +BC30;BC30;1107 1162;BC30;1107 1162; +BC31;BC31;1107 1162 11A8;BC31;1107 1162 11A8; +BC32;BC32;1107 1162 11A9;BC32;1107 1162 11A9; +BC33;BC33;1107 1162 11AA;BC33;1107 1162 11AA; +BC34;BC34;1107 1162 11AB;BC34;1107 1162 11AB; +BC35;BC35;1107 1162 11AC;BC35;1107 1162 11AC; +BC36;BC36;1107 1162 11AD;BC36;1107 1162 11AD; +BC37;BC37;1107 1162 11AE;BC37;1107 1162 11AE; +BC38;BC38;1107 1162 11AF;BC38;1107 1162 11AF; +BC39;BC39;1107 1162 11B0;BC39;1107 1162 11B0; +BC3A;BC3A;1107 1162 11B1;BC3A;1107 1162 11B1; +BC3B;BC3B;1107 1162 11B2;BC3B;1107 1162 11B2; +BC3C;BC3C;1107 1162 11B3;BC3C;1107 1162 11B3; +BC3D;BC3D;1107 1162 11B4;BC3D;1107 1162 11B4; +BC3E;BC3E;1107 1162 11B5;BC3E;1107 1162 11B5; +BC3F;BC3F;1107 1162 11B6;BC3F;1107 1162 11B6; +BC40;BC40;1107 1162 11B7;BC40;1107 1162 11B7; +BC41;BC41;1107 1162 11B8;BC41;1107 1162 11B8; +BC42;BC42;1107 1162 11B9;BC42;1107 1162 11B9; +BC43;BC43;1107 1162 11BA;BC43;1107 1162 11BA; +BC44;BC44;1107 1162 11BB;BC44;1107 1162 11BB; +BC45;BC45;1107 1162 11BC;BC45;1107 1162 11BC; +BC46;BC46;1107 1162 11BD;BC46;1107 1162 11BD; +BC47;BC47;1107 1162 11BE;BC47;1107 1162 11BE; +BC48;BC48;1107 1162 11BF;BC48;1107 1162 11BF; +BC49;BC49;1107 1162 11C0;BC49;1107 1162 11C0; +BC4A;BC4A;1107 1162 11C1;BC4A;1107 1162 11C1; +BC4B;BC4B;1107 1162 11C2;BC4B;1107 1162 11C2; +BC4C;BC4C;1107 1163;BC4C;1107 1163; +BC4D;BC4D;1107 1163 11A8;BC4D;1107 1163 11A8; +BC4E;BC4E;1107 1163 11A9;BC4E;1107 1163 11A9; +BC4F;BC4F;1107 1163 11AA;BC4F;1107 1163 11AA; +BC50;BC50;1107 1163 11AB;BC50;1107 1163 11AB; +BC51;BC51;1107 1163 11AC;BC51;1107 1163 11AC; +BC52;BC52;1107 1163 11AD;BC52;1107 1163 11AD; +BC53;BC53;1107 1163 11AE;BC53;1107 1163 11AE; +BC54;BC54;1107 1163 11AF;BC54;1107 1163 11AF; +BC55;BC55;1107 1163 11B0;BC55;1107 1163 11B0; +BC56;BC56;1107 1163 11B1;BC56;1107 1163 11B1; +BC57;BC57;1107 1163 11B2;BC57;1107 1163 11B2; +BC58;BC58;1107 1163 11B3;BC58;1107 1163 11B3; +BC59;BC59;1107 1163 11B4;BC59;1107 1163 11B4; +BC5A;BC5A;1107 1163 11B5;BC5A;1107 1163 11B5; +BC5B;BC5B;1107 1163 11B6;BC5B;1107 1163 11B6; +BC5C;BC5C;1107 1163 11B7;BC5C;1107 1163 11B7; +BC5D;BC5D;1107 1163 11B8;BC5D;1107 1163 11B8; +BC5E;BC5E;1107 1163 11B9;BC5E;1107 1163 11B9; +BC5F;BC5F;1107 1163 11BA;BC5F;1107 1163 11BA; +BC60;BC60;1107 1163 11BB;BC60;1107 1163 11BB; +BC61;BC61;1107 1163 11BC;BC61;1107 1163 11BC; +BC62;BC62;1107 1163 11BD;BC62;1107 1163 11BD; +BC63;BC63;1107 1163 11BE;BC63;1107 1163 11BE; +BC64;BC64;1107 1163 11BF;BC64;1107 1163 11BF; +BC65;BC65;1107 1163 11C0;BC65;1107 1163 11C0; +BC66;BC66;1107 1163 11C1;BC66;1107 1163 11C1; +BC67;BC67;1107 1163 11C2;BC67;1107 1163 11C2; +BC68;BC68;1107 1164;BC68;1107 1164; +BC69;BC69;1107 1164 11A8;BC69;1107 1164 11A8; +BC6A;BC6A;1107 1164 11A9;BC6A;1107 1164 11A9; +BC6B;BC6B;1107 1164 11AA;BC6B;1107 1164 11AA; +BC6C;BC6C;1107 1164 11AB;BC6C;1107 1164 11AB; +BC6D;BC6D;1107 1164 11AC;BC6D;1107 1164 11AC; +BC6E;BC6E;1107 1164 11AD;BC6E;1107 1164 11AD; +BC6F;BC6F;1107 1164 11AE;BC6F;1107 1164 11AE; +BC70;BC70;1107 1164 11AF;BC70;1107 1164 11AF; +BC71;BC71;1107 1164 11B0;BC71;1107 1164 11B0; +BC72;BC72;1107 1164 11B1;BC72;1107 1164 11B1; +BC73;BC73;1107 1164 11B2;BC73;1107 1164 11B2; +BC74;BC74;1107 1164 11B3;BC74;1107 1164 11B3; +BC75;BC75;1107 1164 11B4;BC75;1107 1164 11B4; +BC76;BC76;1107 1164 11B5;BC76;1107 1164 11B5; +BC77;BC77;1107 1164 11B6;BC77;1107 1164 11B6; +BC78;BC78;1107 1164 11B7;BC78;1107 1164 11B7; +BC79;BC79;1107 1164 11B8;BC79;1107 1164 11B8; +BC7A;BC7A;1107 1164 11B9;BC7A;1107 1164 11B9; +BC7B;BC7B;1107 1164 11BA;BC7B;1107 1164 11BA; +BC7C;BC7C;1107 1164 11BB;BC7C;1107 1164 11BB; +BC7D;BC7D;1107 1164 11BC;BC7D;1107 1164 11BC; +BC7E;BC7E;1107 1164 11BD;BC7E;1107 1164 11BD; +BC7F;BC7F;1107 1164 11BE;BC7F;1107 1164 11BE; +BC80;BC80;1107 1164 11BF;BC80;1107 1164 11BF; +BC81;BC81;1107 1164 11C0;BC81;1107 1164 11C0; +BC82;BC82;1107 1164 11C1;BC82;1107 1164 11C1; +BC83;BC83;1107 1164 11C2;BC83;1107 1164 11C2; +BC84;BC84;1107 1165;BC84;1107 1165; +BC85;BC85;1107 1165 11A8;BC85;1107 1165 11A8; +BC86;BC86;1107 1165 11A9;BC86;1107 1165 11A9; +BC87;BC87;1107 1165 11AA;BC87;1107 1165 11AA; +BC88;BC88;1107 1165 11AB;BC88;1107 1165 11AB; +BC89;BC89;1107 1165 11AC;BC89;1107 1165 11AC; +BC8A;BC8A;1107 1165 11AD;BC8A;1107 1165 11AD; +BC8B;BC8B;1107 1165 11AE;BC8B;1107 1165 11AE; +BC8C;BC8C;1107 1165 11AF;BC8C;1107 1165 11AF; +BC8D;BC8D;1107 1165 11B0;BC8D;1107 1165 11B0; +BC8E;BC8E;1107 1165 11B1;BC8E;1107 1165 11B1; +BC8F;BC8F;1107 1165 11B2;BC8F;1107 1165 11B2; +BC90;BC90;1107 1165 11B3;BC90;1107 1165 11B3; +BC91;BC91;1107 1165 11B4;BC91;1107 1165 11B4; +BC92;BC92;1107 1165 11B5;BC92;1107 1165 11B5; +BC93;BC93;1107 1165 11B6;BC93;1107 1165 11B6; +BC94;BC94;1107 1165 11B7;BC94;1107 1165 11B7; +BC95;BC95;1107 1165 11B8;BC95;1107 1165 11B8; +BC96;BC96;1107 1165 11B9;BC96;1107 1165 11B9; +BC97;BC97;1107 1165 11BA;BC97;1107 1165 11BA; +BC98;BC98;1107 1165 11BB;BC98;1107 1165 11BB; +BC99;BC99;1107 1165 11BC;BC99;1107 1165 11BC; +BC9A;BC9A;1107 1165 11BD;BC9A;1107 1165 11BD; +BC9B;BC9B;1107 1165 11BE;BC9B;1107 1165 11BE; +BC9C;BC9C;1107 1165 11BF;BC9C;1107 1165 11BF; +BC9D;BC9D;1107 1165 11C0;BC9D;1107 1165 11C0; +BC9E;BC9E;1107 1165 11C1;BC9E;1107 1165 11C1; +BC9F;BC9F;1107 1165 11C2;BC9F;1107 1165 11C2; +BCA0;BCA0;1107 1166;BCA0;1107 1166; +BCA1;BCA1;1107 1166 11A8;BCA1;1107 1166 11A8; +BCA2;BCA2;1107 1166 11A9;BCA2;1107 1166 11A9; +BCA3;BCA3;1107 1166 11AA;BCA3;1107 1166 11AA; +BCA4;BCA4;1107 1166 11AB;BCA4;1107 1166 11AB; +BCA5;BCA5;1107 1166 11AC;BCA5;1107 1166 11AC; +BCA6;BCA6;1107 1166 11AD;BCA6;1107 1166 11AD; +BCA7;BCA7;1107 1166 11AE;BCA7;1107 1166 11AE; +BCA8;BCA8;1107 1166 11AF;BCA8;1107 1166 11AF; +BCA9;BCA9;1107 1166 11B0;BCA9;1107 1166 11B0; +BCAA;BCAA;1107 1166 11B1;BCAA;1107 1166 11B1; +BCAB;BCAB;1107 1166 11B2;BCAB;1107 1166 11B2; +BCAC;BCAC;1107 1166 11B3;BCAC;1107 1166 11B3; +BCAD;BCAD;1107 1166 11B4;BCAD;1107 1166 11B4; +BCAE;BCAE;1107 1166 11B5;BCAE;1107 1166 11B5; +BCAF;BCAF;1107 1166 11B6;BCAF;1107 1166 11B6; +BCB0;BCB0;1107 1166 11B7;BCB0;1107 1166 11B7; +BCB1;BCB1;1107 1166 11B8;BCB1;1107 1166 11B8; +BCB2;BCB2;1107 1166 11B9;BCB2;1107 1166 11B9; +BCB3;BCB3;1107 1166 11BA;BCB3;1107 1166 11BA; +BCB4;BCB4;1107 1166 11BB;BCB4;1107 1166 11BB; +BCB5;BCB5;1107 1166 11BC;BCB5;1107 1166 11BC; +BCB6;BCB6;1107 1166 11BD;BCB6;1107 1166 11BD; +BCB7;BCB7;1107 1166 11BE;BCB7;1107 1166 11BE; +BCB8;BCB8;1107 1166 11BF;BCB8;1107 1166 11BF; +BCB9;BCB9;1107 1166 11C0;BCB9;1107 1166 11C0; +BCBA;BCBA;1107 1166 11C1;BCBA;1107 1166 11C1; +BCBB;BCBB;1107 1166 11C2;BCBB;1107 1166 11C2; +BCBC;BCBC;1107 1167;BCBC;1107 1167; +BCBD;BCBD;1107 1167 11A8;BCBD;1107 1167 11A8; +BCBE;BCBE;1107 1167 11A9;BCBE;1107 1167 11A9; +BCBF;BCBF;1107 1167 11AA;BCBF;1107 1167 11AA; +BCC0;BCC0;1107 1167 11AB;BCC0;1107 1167 11AB; +BCC1;BCC1;1107 1167 11AC;BCC1;1107 1167 11AC; +BCC2;BCC2;1107 1167 11AD;BCC2;1107 1167 11AD; +BCC3;BCC3;1107 1167 11AE;BCC3;1107 1167 11AE; +BCC4;BCC4;1107 1167 11AF;BCC4;1107 1167 11AF; +BCC5;BCC5;1107 1167 11B0;BCC5;1107 1167 11B0; +BCC6;BCC6;1107 1167 11B1;BCC6;1107 1167 11B1; +BCC7;BCC7;1107 1167 11B2;BCC7;1107 1167 11B2; +BCC8;BCC8;1107 1167 11B3;BCC8;1107 1167 11B3; +BCC9;BCC9;1107 1167 11B4;BCC9;1107 1167 11B4; +BCCA;BCCA;1107 1167 11B5;BCCA;1107 1167 11B5; +BCCB;BCCB;1107 1167 11B6;BCCB;1107 1167 11B6; +BCCC;BCCC;1107 1167 11B7;BCCC;1107 1167 11B7; +BCCD;BCCD;1107 1167 11B8;BCCD;1107 1167 11B8; +BCCE;BCCE;1107 1167 11B9;BCCE;1107 1167 11B9; +BCCF;BCCF;1107 1167 11BA;BCCF;1107 1167 11BA; +BCD0;BCD0;1107 1167 11BB;BCD0;1107 1167 11BB; +BCD1;BCD1;1107 1167 11BC;BCD1;1107 1167 11BC; +BCD2;BCD2;1107 1167 11BD;BCD2;1107 1167 11BD; +BCD3;BCD3;1107 1167 11BE;BCD3;1107 1167 11BE; +BCD4;BCD4;1107 1167 11BF;BCD4;1107 1167 11BF; +BCD5;BCD5;1107 1167 11C0;BCD5;1107 1167 11C0; +BCD6;BCD6;1107 1167 11C1;BCD6;1107 1167 11C1; +BCD7;BCD7;1107 1167 11C2;BCD7;1107 1167 11C2; +BCD8;BCD8;1107 1168;BCD8;1107 1168; +BCD9;BCD9;1107 1168 11A8;BCD9;1107 1168 11A8; +BCDA;BCDA;1107 1168 11A9;BCDA;1107 1168 11A9; +BCDB;BCDB;1107 1168 11AA;BCDB;1107 1168 11AA; +BCDC;BCDC;1107 1168 11AB;BCDC;1107 1168 11AB; +BCDD;BCDD;1107 1168 11AC;BCDD;1107 1168 11AC; +BCDE;BCDE;1107 1168 11AD;BCDE;1107 1168 11AD; +BCDF;BCDF;1107 1168 11AE;BCDF;1107 1168 11AE; +BCE0;BCE0;1107 1168 11AF;BCE0;1107 1168 11AF; +BCE1;BCE1;1107 1168 11B0;BCE1;1107 1168 11B0; +BCE2;BCE2;1107 1168 11B1;BCE2;1107 1168 11B1; +BCE3;BCE3;1107 1168 11B2;BCE3;1107 1168 11B2; +BCE4;BCE4;1107 1168 11B3;BCE4;1107 1168 11B3; +BCE5;BCE5;1107 1168 11B4;BCE5;1107 1168 11B4; +BCE6;BCE6;1107 1168 11B5;BCE6;1107 1168 11B5; +BCE7;BCE7;1107 1168 11B6;BCE7;1107 1168 11B6; +BCE8;BCE8;1107 1168 11B7;BCE8;1107 1168 11B7; +BCE9;BCE9;1107 1168 11B8;BCE9;1107 1168 11B8; +BCEA;BCEA;1107 1168 11B9;BCEA;1107 1168 11B9; +BCEB;BCEB;1107 1168 11BA;BCEB;1107 1168 11BA; +BCEC;BCEC;1107 1168 11BB;BCEC;1107 1168 11BB; +BCED;BCED;1107 1168 11BC;BCED;1107 1168 11BC; +BCEE;BCEE;1107 1168 11BD;BCEE;1107 1168 11BD; +BCEF;BCEF;1107 1168 11BE;BCEF;1107 1168 11BE; +BCF0;BCF0;1107 1168 11BF;BCF0;1107 1168 11BF; +BCF1;BCF1;1107 1168 11C0;BCF1;1107 1168 11C0; +BCF2;BCF2;1107 1168 11C1;BCF2;1107 1168 11C1; +BCF3;BCF3;1107 1168 11C2;BCF3;1107 1168 11C2; +BCF4;BCF4;1107 1169;BCF4;1107 1169; +BCF5;BCF5;1107 1169 11A8;BCF5;1107 1169 11A8; +BCF6;BCF6;1107 1169 11A9;BCF6;1107 1169 11A9; +BCF7;BCF7;1107 1169 11AA;BCF7;1107 1169 11AA; +BCF8;BCF8;1107 1169 11AB;BCF8;1107 1169 11AB; +BCF9;BCF9;1107 1169 11AC;BCF9;1107 1169 11AC; +BCFA;BCFA;1107 1169 11AD;BCFA;1107 1169 11AD; +BCFB;BCFB;1107 1169 11AE;BCFB;1107 1169 11AE; +BCFC;BCFC;1107 1169 11AF;BCFC;1107 1169 11AF; +BCFD;BCFD;1107 1169 11B0;BCFD;1107 1169 11B0; +BCFE;BCFE;1107 1169 11B1;BCFE;1107 1169 11B1; +BCFF;BCFF;1107 1169 11B2;BCFF;1107 1169 11B2; +BD00;BD00;1107 1169 11B3;BD00;1107 1169 11B3; +BD01;BD01;1107 1169 11B4;BD01;1107 1169 11B4; +BD02;BD02;1107 1169 11B5;BD02;1107 1169 11B5; +BD03;BD03;1107 1169 11B6;BD03;1107 1169 11B6; +BD04;BD04;1107 1169 11B7;BD04;1107 1169 11B7; +BD05;BD05;1107 1169 11B8;BD05;1107 1169 11B8; +BD06;BD06;1107 1169 11B9;BD06;1107 1169 11B9; +BD07;BD07;1107 1169 11BA;BD07;1107 1169 11BA; +BD08;BD08;1107 1169 11BB;BD08;1107 1169 11BB; +BD09;BD09;1107 1169 11BC;BD09;1107 1169 11BC; +BD0A;BD0A;1107 1169 11BD;BD0A;1107 1169 11BD; +BD0B;BD0B;1107 1169 11BE;BD0B;1107 1169 11BE; +BD0C;BD0C;1107 1169 11BF;BD0C;1107 1169 11BF; +BD0D;BD0D;1107 1169 11C0;BD0D;1107 1169 11C0; +BD0E;BD0E;1107 1169 11C1;BD0E;1107 1169 11C1; +BD0F;BD0F;1107 1169 11C2;BD0F;1107 1169 11C2; +BD10;BD10;1107 116A;BD10;1107 116A; +BD11;BD11;1107 116A 11A8;BD11;1107 116A 11A8; +BD12;BD12;1107 116A 11A9;BD12;1107 116A 11A9; +BD13;BD13;1107 116A 11AA;BD13;1107 116A 11AA; +BD14;BD14;1107 116A 11AB;BD14;1107 116A 11AB; +BD15;BD15;1107 116A 11AC;BD15;1107 116A 11AC; +BD16;BD16;1107 116A 11AD;BD16;1107 116A 11AD; +BD17;BD17;1107 116A 11AE;BD17;1107 116A 11AE; +BD18;BD18;1107 116A 11AF;BD18;1107 116A 11AF; +BD19;BD19;1107 116A 11B0;BD19;1107 116A 11B0; +BD1A;BD1A;1107 116A 11B1;BD1A;1107 116A 11B1; +BD1B;BD1B;1107 116A 11B2;BD1B;1107 116A 11B2; +BD1C;BD1C;1107 116A 11B3;BD1C;1107 116A 11B3; +BD1D;BD1D;1107 116A 11B4;BD1D;1107 116A 11B4; +BD1E;BD1E;1107 116A 11B5;BD1E;1107 116A 11B5; +BD1F;BD1F;1107 116A 11B6;BD1F;1107 116A 11B6; +BD20;BD20;1107 116A 11B7;BD20;1107 116A 11B7; +BD21;BD21;1107 116A 11B8;BD21;1107 116A 11B8; +BD22;BD22;1107 116A 11B9;BD22;1107 116A 11B9; +BD23;BD23;1107 116A 11BA;BD23;1107 116A 11BA; +BD24;BD24;1107 116A 11BB;BD24;1107 116A 11BB; +BD25;BD25;1107 116A 11BC;BD25;1107 116A 11BC; +BD26;BD26;1107 116A 11BD;BD26;1107 116A 11BD; +BD27;BD27;1107 116A 11BE;BD27;1107 116A 11BE; +BD28;BD28;1107 116A 11BF;BD28;1107 116A 11BF; +BD29;BD29;1107 116A 11C0;BD29;1107 116A 11C0; +BD2A;BD2A;1107 116A 11C1;BD2A;1107 116A 11C1; +BD2B;BD2B;1107 116A 11C2;BD2B;1107 116A 11C2; +BD2C;BD2C;1107 116B;BD2C;1107 116B; +BD2D;BD2D;1107 116B 11A8;BD2D;1107 116B 11A8; +BD2E;BD2E;1107 116B 11A9;BD2E;1107 116B 11A9; +BD2F;BD2F;1107 116B 11AA;BD2F;1107 116B 11AA; +BD30;BD30;1107 116B 11AB;BD30;1107 116B 11AB; +BD31;BD31;1107 116B 11AC;BD31;1107 116B 11AC; +BD32;BD32;1107 116B 11AD;BD32;1107 116B 11AD; +BD33;BD33;1107 116B 11AE;BD33;1107 116B 11AE; +BD34;BD34;1107 116B 11AF;BD34;1107 116B 11AF; +BD35;BD35;1107 116B 11B0;BD35;1107 116B 11B0; +BD36;BD36;1107 116B 11B1;BD36;1107 116B 11B1; +BD37;BD37;1107 116B 11B2;BD37;1107 116B 11B2; +BD38;BD38;1107 116B 11B3;BD38;1107 116B 11B3; +BD39;BD39;1107 116B 11B4;BD39;1107 116B 11B4; +BD3A;BD3A;1107 116B 11B5;BD3A;1107 116B 11B5; +BD3B;BD3B;1107 116B 11B6;BD3B;1107 116B 11B6; +BD3C;BD3C;1107 116B 11B7;BD3C;1107 116B 11B7; +BD3D;BD3D;1107 116B 11B8;BD3D;1107 116B 11B8; +BD3E;BD3E;1107 116B 11B9;BD3E;1107 116B 11B9; +BD3F;BD3F;1107 116B 11BA;BD3F;1107 116B 11BA; +BD40;BD40;1107 116B 11BB;BD40;1107 116B 11BB; +BD41;BD41;1107 116B 11BC;BD41;1107 116B 11BC; +BD42;BD42;1107 116B 11BD;BD42;1107 116B 11BD; +BD43;BD43;1107 116B 11BE;BD43;1107 116B 11BE; +BD44;BD44;1107 116B 11BF;BD44;1107 116B 11BF; +BD45;BD45;1107 116B 11C0;BD45;1107 116B 11C0; +BD46;BD46;1107 116B 11C1;BD46;1107 116B 11C1; +BD47;BD47;1107 116B 11C2;BD47;1107 116B 11C2; +BD48;BD48;1107 116C;BD48;1107 116C; +BD49;BD49;1107 116C 11A8;BD49;1107 116C 11A8; +BD4A;BD4A;1107 116C 11A9;BD4A;1107 116C 11A9; +BD4B;BD4B;1107 116C 11AA;BD4B;1107 116C 11AA; +BD4C;BD4C;1107 116C 11AB;BD4C;1107 116C 11AB; +BD4D;BD4D;1107 116C 11AC;BD4D;1107 116C 11AC; +BD4E;BD4E;1107 116C 11AD;BD4E;1107 116C 11AD; +BD4F;BD4F;1107 116C 11AE;BD4F;1107 116C 11AE; +BD50;BD50;1107 116C 11AF;BD50;1107 116C 11AF; +BD51;BD51;1107 116C 11B0;BD51;1107 116C 11B0; +BD52;BD52;1107 116C 11B1;BD52;1107 116C 11B1; +BD53;BD53;1107 116C 11B2;BD53;1107 116C 11B2; +BD54;BD54;1107 116C 11B3;BD54;1107 116C 11B3; +BD55;BD55;1107 116C 11B4;BD55;1107 116C 11B4; +BD56;BD56;1107 116C 11B5;BD56;1107 116C 11B5; +BD57;BD57;1107 116C 11B6;BD57;1107 116C 11B6; +BD58;BD58;1107 116C 11B7;BD58;1107 116C 11B7; +BD59;BD59;1107 116C 11B8;BD59;1107 116C 11B8; +BD5A;BD5A;1107 116C 11B9;BD5A;1107 116C 11B9; +BD5B;BD5B;1107 116C 11BA;BD5B;1107 116C 11BA; +BD5C;BD5C;1107 116C 11BB;BD5C;1107 116C 11BB; +BD5D;BD5D;1107 116C 11BC;BD5D;1107 116C 11BC; +BD5E;BD5E;1107 116C 11BD;BD5E;1107 116C 11BD; +BD5F;BD5F;1107 116C 11BE;BD5F;1107 116C 11BE; +BD60;BD60;1107 116C 11BF;BD60;1107 116C 11BF; +BD61;BD61;1107 116C 11C0;BD61;1107 116C 11C0; +BD62;BD62;1107 116C 11C1;BD62;1107 116C 11C1; +BD63;BD63;1107 116C 11C2;BD63;1107 116C 11C2; +BD64;BD64;1107 116D;BD64;1107 116D; +BD65;BD65;1107 116D 11A8;BD65;1107 116D 11A8; +BD66;BD66;1107 116D 11A9;BD66;1107 116D 11A9; +BD67;BD67;1107 116D 11AA;BD67;1107 116D 11AA; +BD68;BD68;1107 116D 11AB;BD68;1107 116D 11AB; +BD69;BD69;1107 116D 11AC;BD69;1107 116D 11AC; +BD6A;BD6A;1107 116D 11AD;BD6A;1107 116D 11AD; +BD6B;BD6B;1107 116D 11AE;BD6B;1107 116D 11AE; +BD6C;BD6C;1107 116D 11AF;BD6C;1107 116D 11AF; +BD6D;BD6D;1107 116D 11B0;BD6D;1107 116D 11B0; +BD6E;BD6E;1107 116D 11B1;BD6E;1107 116D 11B1; +BD6F;BD6F;1107 116D 11B2;BD6F;1107 116D 11B2; +BD70;BD70;1107 116D 11B3;BD70;1107 116D 11B3; +BD71;BD71;1107 116D 11B4;BD71;1107 116D 11B4; +BD72;BD72;1107 116D 11B5;BD72;1107 116D 11B5; +BD73;BD73;1107 116D 11B6;BD73;1107 116D 11B6; +BD74;BD74;1107 116D 11B7;BD74;1107 116D 11B7; +BD75;BD75;1107 116D 11B8;BD75;1107 116D 11B8; +BD76;BD76;1107 116D 11B9;BD76;1107 116D 11B9; +BD77;BD77;1107 116D 11BA;BD77;1107 116D 11BA; +BD78;BD78;1107 116D 11BB;BD78;1107 116D 11BB; +BD79;BD79;1107 116D 11BC;BD79;1107 116D 11BC; +BD7A;BD7A;1107 116D 11BD;BD7A;1107 116D 11BD; +BD7B;BD7B;1107 116D 11BE;BD7B;1107 116D 11BE; +BD7C;BD7C;1107 116D 11BF;BD7C;1107 116D 11BF; +BD7D;BD7D;1107 116D 11C0;BD7D;1107 116D 11C0; +BD7E;BD7E;1107 116D 11C1;BD7E;1107 116D 11C1; +BD7F;BD7F;1107 116D 11C2;BD7F;1107 116D 11C2; +BD80;BD80;1107 116E;BD80;1107 116E; +BD81;BD81;1107 116E 11A8;BD81;1107 116E 11A8; +BD82;BD82;1107 116E 11A9;BD82;1107 116E 11A9; +BD83;BD83;1107 116E 11AA;BD83;1107 116E 11AA; +BD84;BD84;1107 116E 11AB;BD84;1107 116E 11AB; +BD85;BD85;1107 116E 11AC;BD85;1107 116E 11AC; +BD86;BD86;1107 116E 11AD;BD86;1107 116E 11AD; +BD87;BD87;1107 116E 11AE;BD87;1107 116E 11AE; +BD88;BD88;1107 116E 11AF;BD88;1107 116E 11AF; +BD89;BD89;1107 116E 11B0;BD89;1107 116E 11B0; +BD8A;BD8A;1107 116E 11B1;BD8A;1107 116E 11B1; +BD8B;BD8B;1107 116E 11B2;BD8B;1107 116E 11B2; +BD8C;BD8C;1107 116E 11B3;BD8C;1107 116E 11B3; +BD8D;BD8D;1107 116E 11B4;BD8D;1107 116E 11B4; +BD8E;BD8E;1107 116E 11B5;BD8E;1107 116E 11B5; +BD8F;BD8F;1107 116E 11B6;BD8F;1107 116E 11B6; +BD90;BD90;1107 116E 11B7;BD90;1107 116E 11B7; +BD91;BD91;1107 116E 11B8;BD91;1107 116E 11B8; +BD92;BD92;1107 116E 11B9;BD92;1107 116E 11B9; +BD93;BD93;1107 116E 11BA;BD93;1107 116E 11BA; +BD94;BD94;1107 116E 11BB;BD94;1107 116E 11BB; +BD95;BD95;1107 116E 11BC;BD95;1107 116E 11BC; +BD96;BD96;1107 116E 11BD;BD96;1107 116E 11BD; +BD97;BD97;1107 116E 11BE;BD97;1107 116E 11BE; +BD98;BD98;1107 116E 11BF;BD98;1107 116E 11BF; +BD99;BD99;1107 116E 11C0;BD99;1107 116E 11C0; +BD9A;BD9A;1107 116E 11C1;BD9A;1107 116E 11C1; +BD9B;BD9B;1107 116E 11C2;BD9B;1107 116E 11C2; +BD9C;BD9C;1107 116F;BD9C;1107 116F; +BD9D;BD9D;1107 116F 11A8;BD9D;1107 116F 11A8; +BD9E;BD9E;1107 116F 11A9;BD9E;1107 116F 11A9; +BD9F;BD9F;1107 116F 11AA;BD9F;1107 116F 11AA; +BDA0;BDA0;1107 116F 11AB;BDA0;1107 116F 11AB; +BDA1;BDA1;1107 116F 11AC;BDA1;1107 116F 11AC; +BDA2;BDA2;1107 116F 11AD;BDA2;1107 116F 11AD; +BDA3;BDA3;1107 116F 11AE;BDA3;1107 116F 11AE; +BDA4;BDA4;1107 116F 11AF;BDA4;1107 116F 11AF; +BDA5;BDA5;1107 116F 11B0;BDA5;1107 116F 11B0; +BDA6;BDA6;1107 116F 11B1;BDA6;1107 116F 11B1; +BDA7;BDA7;1107 116F 11B2;BDA7;1107 116F 11B2; +BDA8;BDA8;1107 116F 11B3;BDA8;1107 116F 11B3; +BDA9;BDA9;1107 116F 11B4;BDA9;1107 116F 11B4; +BDAA;BDAA;1107 116F 11B5;BDAA;1107 116F 11B5; +BDAB;BDAB;1107 116F 11B6;BDAB;1107 116F 11B6; +BDAC;BDAC;1107 116F 11B7;BDAC;1107 116F 11B7; +BDAD;BDAD;1107 116F 11B8;BDAD;1107 116F 11B8; +BDAE;BDAE;1107 116F 11B9;BDAE;1107 116F 11B9; +BDAF;BDAF;1107 116F 11BA;BDAF;1107 116F 11BA; +BDB0;BDB0;1107 116F 11BB;BDB0;1107 116F 11BB; +BDB1;BDB1;1107 116F 11BC;BDB1;1107 116F 11BC; +BDB2;BDB2;1107 116F 11BD;BDB2;1107 116F 11BD; +BDB3;BDB3;1107 116F 11BE;BDB3;1107 116F 11BE; +BDB4;BDB4;1107 116F 11BF;BDB4;1107 116F 11BF; +BDB5;BDB5;1107 116F 11C0;BDB5;1107 116F 11C0; +BDB6;BDB6;1107 116F 11C1;BDB6;1107 116F 11C1; +BDB7;BDB7;1107 116F 11C2;BDB7;1107 116F 11C2; +BDB8;BDB8;1107 1170;BDB8;1107 1170; +BDB9;BDB9;1107 1170 11A8;BDB9;1107 1170 11A8; +BDBA;BDBA;1107 1170 11A9;BDBA;1107 1170 11A9; +BDBB;BDBB;1107 1170 11AA;BDBB;1107 1170 11AA; +BDBC;BDBC;1107 1170 11AB;BDBC;1107 1170 11AB; +BDBD;BDBD;1107 1170 11AC;BDBD;1107 1170 11AC; +BDBE;BDBE;1107 1170 11AD;BDBE;1107 1170 11AD; +BDBF;BDBF;1107 1170 11AE;BDBF;1107 1170 11AE; +BDC0;BDC0;1107 1170 11AF;BDC0;1107 1170 11AF; +BDC1;BDC1;1107 1170 11B0;BDC1;1107 1170 11B0; +BDC2;BDC2;1107 1170 11B1;BDC2;1107 1170 11B1; +BDC3;BDC3;1107 1170 11B2;BDC3;1107 1170 11B2; +BDC4;BDC4;1107 1170 11B3;BDC4;1107 1170 11B3; +BDC5;BDC5;1107 1170 11B4;BDC5;1107 1170 11B4; +BDC6;BDC6;1107 1170 11B5;BDC6;1107 1170 11B5; +BDC7;BDC7;1107 1170 11B6;BDC7;1107 1170 11B6; +BDC8;BDC8;1107 1170 11B7;BDC8;1107 1170 11B7; +BDC9;BDC9;1107 1170 11B8;BDC9;1107 1170 11B8; +BDCA;BDCA;1107 1170 11B9;BDCA;1107 1170 11B9; +BDCB;BDCB;1107 1170 11BA;BDCB;1107 1170 11BA; +BDCC;BDCC;1107 1170 11BB;BDCC;1107 1170 11BB; +BDCD;BDCD;1107 1170 11BC;BDCD;1107 1170 11BC; +BDCE;BDCE;1107 1170 11BD;BDCE;1107 1170 11BD; +BDCF;BDCF;1107 1170 11BE;BDCF;1107 1170 11BE; +BDD0;BDD0;1107 1170 11BF;BDD0;1107 1170 11BF; +BDD1;BDD1;1107 1170 11C0;BDD1;1107 1170 11C0; +BDD2;BDD2;1107 1170 11C1;BDD2;1107 1170 11C1; +BDD3;BDD3;1107 1170 11C2;BDD3;1107 1170 11C2; +BDD4;BDD4;1107 1171;BDD4;1107 1171; +BDD5;BDD5;1107 1171 11A8;BDD5;1107 1171 11A8; +BDD6;BDD6;1107 1171 11A9;BDD6;1107 1171 11A9; +BDD7;BDD7;1107 1171 11AA;BDD7;1107 1171 11AA; +BDD8;BDD8;1107 1171 11AB;BDD8;1107 1171 11AB; +BDD9;BDD9;1107 1171 11AC;BDD9;1107 1171 11AC; +BDDA;BDDA;1107 1171 11AD;BDDA;1107 1171 11AD; +BDDB;BDDB;1107 1171 11AE;BDDB;1107 1171 11AE; +BDDC;BDDC;1107 1171 11AF;BDDC;1107 1171 11AF; +BDDD;BDDD;1107 1171 11B0;BDDD;1107 1171 11B0; +BDDE;BDDE;1107 1171 11B1;BDDE;1107 1171 11B1; +BDDF;BDDF;1107 1171 11B2;BDDF;1107 1171 11B2; +BDE0;BDE0;1107 1171 11B3;BDE0;1107 1171 11B3; +BDE1;BDE1;1107 1171 11B4;BDE1;1107 1171 11B4; +BDE2;BDE2;1107 1171 11B5;BDE2;1107 1171 11B5; +BDE3;BDE3;1107 1171 11B6;BDE3;1107 1171 11B6; +BDE4;BDE4;1107 1171 11B7;BDE4;1107 1171 11B7; +BDE5;BDE5;1107 1171 11B8;BDE5;1107 1171 11B8; +BDE6;BDE6;1107 1171 11B9;BDE6;1107 1171 11B9; +BDE7;BDE7;1107 1171 11BA;BDE7;1107 1171 11BA; +BDE8;BDE8;1107 1171 11BB;BDE8;1107 1171 11BB; +BDE9;BDE9;1107 1171 11BC;BDE9;1107 1171 11BC; +BDEA;BDEA;1107 1171 11BD;BDEA;1107 1171 11BD; +BDEB;BDEB;1107 1171 11BE;BDEB;1107 1171 11BE; +BDEC;BDEC;1107 1171 11BF;BDEC;1107 1171 11BF; +BDED;BDED;1107 1171 11C0;BDED;1107 1171 11C0; +BDEE;BDEE;1107 1171 11C1;BDEE;1107 1171 11C1; +BDEF;BDEF;1107 1171 11C2;BDEF;1107 1171 11C2; +BDF0;BDF0;1107 1172;BDF0;1107 1172; +BDF1;BDF1;1107 1172 11A8;BDF1;1107 1172 11A8; +BDF2;BDF2;1107 1172 11A9;BDF2;1107 1172 11A9; +BDF3;BDF3;1107 1172 11AA;BDF3;1107 1172 11AA; +BDF4;BDF4;1107 1172 11AB;BDF4;1107 1172 11AB; +BDF5;BDF5;1107 1172 11AC;BDF5;1107 1172 11AC; +BDF6;BDF6;1107 1172 11AD;BDF6;1107 1172 11AD; +BDF7;BDF7;1107 1172 11AE;BDF7;1107 1172 11AE; +BDF8;BDF8;1107 1172 11AF;BDF8;1107 1172 11AF; +BDF9;BDF9;1107 1172 11B0;BDF9;1107 1172 11B0; +BDFA;BDFA;1107 1172 11B1;BDFA;1107 1172 11B1; +BDFB;BDFB;1107 1172 11B2;BDFB;1107 1172 11B2; +BDFC;BDFC;1107 1172 11B3;BDFC;1107 1172 11B3; +BDFD;BDFD;1107 1172 11B4;BDFD;1107 1172 11B4; +BDFE;BDFE;1107 1172 11B5;BDFE;1107 1172 11B5; +BDFF;BDFF;1107 1172 11B6;BDFF;1107 1172 11B6; +BE00;BE00;1107 1172 11B7;BE00;1107 1172 11B7; +BE01;BE01;1107 1172 11B8;BE01;1107 1172 11B8; +BE02;BE02;1107 1172 11B9;BE02;1107 1172 11B9; +BE03;BE03;1107 1172 11BA;BE03;1107 1172 11BA; +BE04;BE04;1107 1172 11BB;BE04;1107 1172 11BB; +BE05;BE05;1107 1172 11BC;BE05;1107 1172 11BC; +BE06;BE06;1107 1172 11BD;BE06;1107 1172 11BD; +BE07;BE07;1107 1172 11BE;BE07;1107 1172 11BE; +BE08;BE08;1107 1172 11BF;BE08;1107 1172 11BF; +BE09;BE09;1107 1172 11C0;BE09;1107 1172 11C0; +BE0A;BE0A;1107 1172 11C1;BE0A;1107 1172 11C1; +BE0B;BE0B;1107 1172 11C2;BE0B;1107 1172 11C2; +BE0C;BE0C;1107 1173;BE0C;1107 1173; +BE0D;BE0D;1107 1173 11A8;BE0D;1107 1173 11A8; +BE0E;BE0E;1107 1173 11A9;BE0E;1107 1173 11A9; +BE0F;BE0F;1107 1173 11AA;BE0F;1107 1173 11AA; +BE10;BE10;1107 1173 11AB;BE10;1107 1173 11AB; +BE11;BE11;1107 1173 11AC;BE11;1107 1173 11AC; +BE12;BE12;1107 1173 11AD;BE12;1107 1173 11AD; +BE13;BE13;1107 1173 11AE;BE13;1107 1173 11AE; +BE14;BE14;1107 1173 11AF;BE14;1107 1173 11AF; +BE15;BE15;1107 1173 11B0;BE15;1107 1173 11B0; +BE16;BE16;1107 1173 11B1;BE16;1107 1173 11B1; +BE17;BE17;1107 1173 11B2;BE17;1107 1173 11B2; +BE18;BE18;1107 1173 11B3;BE18;1107 1173 11B3; +BE19;BE19;1107 1173 11B4;BE19;1107 1173 11B4; +BE1A;BE1A;1107 1173 11B5;BE1A;1107 1173 11B5; +BE1B;BE1B;1107 1173 11B6;BE1B;1107 1173 11B6; +BE1C;BE1C;1107 1173 11B7;BE1C;1107 1173 11B7; +BE1D;BE1D;1107 1173 11B8;BE1D;1107 1173 11B8; +BE1E;BE1E;1107 1173 11B9;BE1E;1107 1173 11B9; +BE1F;BE1F;1107 1173 11BA;BE1F;1107 1173 11BA; +BE20;BE20;1107 1173 11BB;BE20;1107 1173 11BB; +BE21;BE21;1107 1173 11BC;BE21;1107 1173 11BC; +BE22;BE22;1107 1173 11BD;BE22;1107 1173 11BD; +BE23;BE23;1107 1173 11BE;BE23;1107 1173 11BE; +BE24;BE24;1107 1173 11BF;BE24;1107 1173 11BF; +BE25;BE25;1107 1173 11C0;BE25;1107 1173 11C0; +BE26;BE26;1107 1173 11C1;BE26;1107 1173 11C1; +BE27;BE27;1107 1173 11C2;BE27;1107 1173 11C2; +BE28;BE28;1107 1174;BE28;1107 1174; +BE29;BE29;1107 1174 11A8;BE29;1107 1174 11A8; +BE2A;BE2A;1107 1174 11A9;BE2A;1107 1174 11A9; +BE2B;BE2B;1107 1174 11AA;BE2B;1107 1174 11AA; +BE2C;BE2C;1107 1174 11AB;BE2C;1107 1174 11AB; +BE2D;BE2D;1107 1174 11AC;BE2D;1107 1174 11AC; +BE2E;BE2E;1107 1174 11AD;BE2E;1107 1174 11AD; +BE2F;BE2F;1107 1174 11AE;BE2F;1107 1174 11AE; +BE30;BE30;1107 1174 11AF;BE30;1107 1174 11AF; +BE31;BE31;1107 1174 11B0;BE31;1107 1174 11B0; +BE32;BE32;1107 1174 11B1;BE32;1107 1174 11B1; +BE33;BE33;1107 1174 11B2;BE33;1107 1174 11B2; +BE34;BE34;1107 1174 11B3;BE34;1107 1174 11B3; +BE35;BE35;1107 1174 11B4;BE35;1107 1174 11B4; +BE36;BE36;1107 1174 11B5;BE36;1107 1174 11B5; +BE37;BE37;1107 1174 11B6;BE37;1107 1174 11B6; +BE38;BE38;1107 1174 11B7;BE38;1107 1174 11B7; +BE39;BE39;1107 1174 11B8;BE39;1107 1174 11B8; +BE3A;BE3A;1107 1174 11B9;BE3A;1107 1174 11B9; +BE3B;BE3B;1107 1174 11BA;BE3B;1107 1174 11BA; +BE3C;BE3C;1107 1174 11BB;BE3C;1107 1174 11BB; +BE3D;BE3D;1107 1174 11BC;BE3D;1107 1174 11BC; +BE3E;BE3E;1107 1174 11BD;BE3E;1107 1174 11BD; +BE3F;BE3F;1107 1174 11BE;BE3F;1107 1174 11BE; +BE40;BE40;1107 1174 11BF;BE40;1107 1174 11BF; +BE41;BE41;1107 1174 11C0;BE41;1107 1174 11C0; +BE42;BE42;1107 1174 11C1;BE42;1107 1174 11C1; +BE43;BE43;1107 1174 11C2;BE43;1107 1174 11C2; +BE44;BE44;1107 1175;BE44;1107 1175; +BE45;BE45;1107 1175 11A8;BE45;1107 1175 11A8; +BE46;BE46;1107 1175 11A9;BE46;1107 1175 11A9; +BE47;BE47;1107 1175 11AA;BE47;1107 1175 11AA; +BE48;BE48;1107 1175 11AB;BE48;1107 1175 11AB; +BE49;BE49;1107 1175 11AC;BE49;1107 1175 11AC; +BE4A;BE4A;1107 1175 11AD;BE4A;1107 1175 11AD; +BE4B;BE4B;1107 1175 11AE;BE4B;1107 1175 11AE; +BE4C;BE4C;1107 1175 11AF;BE4C;1107 1175 11AF; +BE4D;BE4D;1107 1175 11B0;BE4D;1107 1175 11B0; +BE4E;BE4E;1107 1175 11B1;BE4E;1107 1175 11B1; +BE4F;BE4F;1107 1175 11B2;BE4F;1107 1175 11B2; +BE50;BE50;1107 1175 11B3;BE50;1107 1175 11B3; +BE51;BE51;1107 1175 11B4;BE51;1107 1175 11B4; +BE52;BE52;1107 1175 11B5;BE52;1107 1175 11B5; +BE53;BE53;1107 1175 11B6;BE53;1107 1175 11B6; +BE54;BE54;1107 1175 11B7;BE54;1107 1175 11B7; +BE55;BE55;1107 1175 11B8;BE55;1107 1175 11B8; +BE56;BE56;1107 1175 11B9;BE56;1107 1175 11B9; +BE57;BE57;1107 1175 11BA;BE57;1107 1175 11BA; +BE58;BE58;1107 1175 11BB;BE58;1107 1175 11BB; +BE59;BE59;1107 1175 11BC;BE59;1107 1175 11BC; +BE5A;BE5A;1107 1175 11BD;BE5A;1107 1175 11BD; +BE5B;BE5B;1107 1175 11BE;BE5B;1107 1175 11BE; +BE5C;BE5C;1107 1175 11BF;BE5C;1107 1175 11BF; +BE5D;BE5D;1107 1175 11C0;BE5D;1107 1175 11C0; +BE5E;BE5E;1107 1175 11C1;BE5E;1107 1175 11C1; +BE5F;BE5F;1107 1175 11C2;BE5F;1107 1175 11C2; +BE60;BE60;1108 1161;BE60;1108 1161; +BE61;BE61;1108 1161 11A8;BE61;1108 1161 11A8; +BE62;BE62;1108 1161 11A9;BE62;1108 1161 11A9; +BE63;BE63;1108 1161 11AA;BE63;1108 1161 11AA; +BE64;BE64;1108 1161 11AB;BE64;1108 1161 11AB; +BE65;BE65;1108 1161 11AC;BE65;1108 1161 11AC; +BE66;BE66;1108 1161 11AD;BE66;1108 1161 11AD; +BE67;BE67;1108 1161 11AE;BE67;1108 1161 11AE; +BE68;BE68;1108 1161 11AF;BE68;1108 1161 11AF; +BE69;BE69;1108 1161 11B0;BE69;1108 1161 11B0; +BE6A;BE6A;1108 1161 11B1;BE6A;1108 1161 11B1; +BE6B;BE6B;1108 1161 11B2;BE6B;1108 1161 11B2; +BE6C;BE6C;1108 1161 11B3;BE6C;1108 1161 11B3; +BE6D;BE6D;1108 1161 11B4;BE6D;1108 1161 11B4; +BE6E;BE6E;1108 1161 11B5;BE6E;1108 1161 11B5; +BE6F;BE6F;1108 1161 11B6;BE6F;1108 1161 11B6; +BE70;BE70;1108 1161 11B7;BE70;1108 1161 11B7; +BE71;BE71;1108 1161 11B8;BE71;1108 1161 11B8; +BE72;BE72;1108 1161 11B9;BE72;1108 1161 11B9; +BE73;BE73;1108 1161 11BA;BE73;1108 1161 11BA; +BE74;BE74;1108 1161 11BB;BE74;1108 1161 11BB; +BE75;BE75;1108 1161 11BC;BE75;1108 1161 11BC; +BE76;BE76;1108 1161 11BD;BE76;1108 1161 11BD; +BE77;BE77;1108 1161 11BE;BE77;1108 1161 11BE; +BE78;BE78;1108 1161 11BF;BE78;1108 1161 11BF; +BE79;BE79;1108 1161 11C0;BE79;1108 1161 11C0; +BE7A;BE7A;1108 1161 11C1;BE7A;1108 1161 11C1; +BE7B;BE7B;1108 1161 11C2;BE7B;1108 1161 11C2; +BE7C;BE7C;1108 1162;BE7C;1108 1162; +BE7D;BE7D;1108 1162 11A8;BE7D;1108 1162 11A8; +BE7E;BE7E;1108 1162 11A9;BE7E;1108 1162 11A9; +BE7F;BE7F;1108 1162 11AA;BE7F;1108 1162 11AA; +BE80;BE80;1108 1162 11AB;BE80;1108 1162 11AB; +BE81;BE81;1108 1162 11AC;BE81;1108 1162 11AC; +BE82;BE82;1108 1162 11AD;BE82;1108 1162 11AD; +BE83;BE83;1108 1162 11AE;BE83;1108 1162 11AE; +BE84;BE84;1108 1162 11AF;BE84;1108 1162 11AF; +BE85;BE85;1108 1162 11B0;BE85;1108 1162 11B0; +BE86;BE86;1108 1162 11B1;BE86;1108 1162 11B1; +BE87;BE87;1108 1162 11B2;BE87;1108 1162 11B2; +BE88;BE88;1108 1162 11B3;BE88;1108 1162 11B3; +BE89;BE89;1108 1162 11B4;BE89;1108 1162 11B4; +BE8A;BE8A;1108 1162 11B5;BE8A;1108 1162 11B5; +BE8B;BE8B;1108 1162 11B6;BE8B;1108 1162 11B6; +BE8C;BE8C;1108 1162 11B7;BE8C;1108 1162 11B7; +BE8D;BE8D;1108 1162 11B8;BE8D;1108 1162 11B8; +BE8E;BE8E;1108 1162 11B9;BE8E;1108 1162 11B9; +BE8F;BE8F;1108 1162 11BA;BE8F;1108 1162 11BA; +BE90;BE90;1108 1162 11BB;BE90;1108 1162 11BB; +BE91;BE91;1108 1162 11BC;BE91;1108 1162 11BC; +BE92;BE92;1108 1162 11BD;BE92;1108 1162 11BD; +BE93;BE93;1108 1162 11BE;BE93;1108 1162 11BE; +BE94;BE94;1108 1162 11BF;BE94;1108 1162 11BF; +BE95;BE95;1108 1162 11C0;BE95;1108 1162 11C0; +BE96;BE96;1108 1162 11C1;BE96;1108 1162 11C1; +BE97;BE97;1108 1162 11C2;BE97;1108 1162 11C2; +BE98;BE98;1108 1163;BE98;1108 1163; +BE99;BE99;1108 1163 11A8;BE99;1108 1163 11A8; +BE9A;BE9A;1108 1163 11A9;BE9A;1108 1163 11A9; +BE9B;BE9B;1108 1163 11AA;BE9B;1108 1163 11AA; +BE9C;BE9C;1108 1163 11AB;BE9C;1108 1163 11AB; +BE9D;BE9D;1108 1163 11AC;BE9D;1108 1163 11AC; +BE9E;BE9E;1108 1163 11AD;BE9E;1108 1163 11AD; +BE9F;BE9F;1108 1163 11AE;BE9F;1108 1163 11AE; +BEA0;BEA0;1108 1163 11AF;BEA0;1108 1163 11AF; +BEA1;BEA1;1108 1163 11B0;BEA1;1108 1163 11B0; +BEA2;BEA2;1108 1163 11B1;BEA2;1108 1163 11B1; +BEA3;BEA3;1108 1163 11B2;BEA3;1108 1163 11B2; +BEA4;BEA4;1108 1163 11B3;BEA4;1108 1163 11B3; +BEA5;BEA5;1108 1163 11B4;BEA5;1108 1163 11B4; +BEA6;BEA6;1108 1163 11B5;BEA6;1108 1163 11B5; +BEA7;BEA7;1108 1163 11B6;BEA7;1108 1163 11B6; +BEA8;BEA8;1108 1163 11B7;BEA8;1108 1163 11B7; +BEA9;BEA9;1108 1163 11B8;BEA9;1108 1163 11B8; +BEAA;BEAA;1108 1163 11B9;BEAA;1108 1163 11B9; +BEAB;BEAB;1108 1163 11BA;BEAB;1108 1163 11BA; +BEAC;BEAC;1108 1163 11BB;BEAC;1108 1163 11BB; +BEAD;BEAD;1108 1163 11BC;BEAD;1108 1163 11BC; +BEAE;BEAE;1108 1163 11BD;BEAE;1108 1163 11BD; +BEAF;BEAF;1108 1163 11BE;BEAF;1108 1163 11BE; +BEB0;BEB0;1108 1163 11BF;BEB0;1108 1163 11BF; +BEB1;BEB1;1108 1163 11C0;BEB1;1108 1163 11C0; +BEB2;BEB2;1108 1163 11C1;BEB2;1108 1163 11C1; +BEB3;BEB3;1108 1163 11C2;BEB3;1108 1163 11C2; +BEB4;BEB4;1108 1164;BEB4;1108 1164; +BEB5;BEB5;1108 1164 11A8;BEB5;1108 1164 11A8; +BEB6;BEB6;1108 1164 11A9;BEB6;1108 1164 11A9; +BEB7;BEB7;1108 1164 11AA;BEB7;1108 1164 11AA; +BEB8;BEB8;1108 1164 11AB;BEB8;1108 1164 11AB; +BEB9;BEB9;1108 1164 11AC;BEB9;1108 1164 11AC; +BEBA;BEBA;1108 1164 11AD;BEBA;1108 1164 11AD; +BEBB;BEBB;1108 1164 11AE;BEBB;1108 1164 11AE; +BEBC;BEBC;1108 1164 11AF;BEBC;1108 1164 11AF; +BEBD;BEBD;1108 1164 11B0;BEBD;1108 1164 11B0; +BEBE;BEBE;1108 1164 11B1;BEBE;1108 1164 11B1; +BEBF;BEBF;1108 1164 11B2;BEBF;1108 1164 11B2; +BEC0;BEC0;1108 1164 11B3;BEC0;1108 1164 11B3; +BEC1;BEC1;1108 1164 11B4;BEC1;1108 1164 11B4; +BEC2;BEC2;1108 1164 11B5;BEC2;1108 1164 11B5; +BEC3;BEC3;1108 1164 11B6;BEC3;1108 1164 11B6; +BEC4;BEC4;1108 1164 11B7;BEC4;1108 1164 11B7; +BEC5;BEC5;1108 1164 11B8;BEC5;1108 1164 11B8; +BEC6;BEC6;1108 1164 11B9;BEC6;1108 1164 11B9; +BEC7;BEC7;1108 1164 11BA;BEC7;1108 1164 11BA; +BEC8;BEC8;1108 1164 11BB;BEC8;1108 1164 11BB; +BEC9;BEC9;1108 1164 11BC;BEC9;1108 1164 11BC; +BECA;BECA;1108 1164 11BD;BECA;1108 1164 11BD; +BECB;BECB;1108 1164 11BE;BECB;1108 1164 11BE; +BECC;BECC;1108 1164 11BF;BECC;1108 1164 11BF; +BECD;BECD;1108 1164 11C0;BECD;1108 1164 11C0; +BECE;BECE;1108 1164 11C1;BECE;1108 1164 11C1; +BECF;BECF;1108 1164 11C2;BECF;1108 1164 11C2; +BED0;BED0;1108 1165;BED0;1108 1165; +BED1;BED1;1108 1165 11A8;BED1;1108 1165 11A8; +BED2;BED2;1108 1165 11A9;BED2;1108 1165 11A9; +BED3;BED3;1108 1165 11AA;BED3;1108 1165 11AA; +BED4;BED4;1108 1165 11AB;BED4;1108 1165 11AB; +BED5;BED5;1108 1165 11AC;BED5;1108 1165 11AC; +BED6;BED6;1108 1165 11AD;BED6;1108 1165 11AD; +BED7;BED7;1108 1165 11AE;BED7;1108 1165 11AE; +BED8;BED8;1108 1165 11AF;BED8;1108 1165 11AF; +BED9;BED9;1108 1165 11B0;BED9;1108 1165 11B0; +BEDA;BEDA;1108 1165 11B1;BEDA;1108 1165 11B1; +BEDB;BEDB;1108 1165 11B2;BEDB;1108 1165 11B2; +BEDC;BEDC;1108 1165 11B3;BEDC;1108 1165 11B3; +BEDD;BEDD;1108 1165 11B4;BEDD;1108 1165 11B4; +BEDE;BEDE;1108 1165 11B5;BEDE;1108 1165 11B5; +BEDF;BEDF;1108 1165 11B6;BEDF;1108 1165 11B6; +BEE0;BEE0;1108 1165 11B7;BEE0;1108 1165 11B7; +BEE1;BEE1;1108 1165 11B8;BEE1;1108 1165 11B8; +BEE2;BEE2;1108 1165 11B9;BEE2;1108 1165 11B9; +BEE3;BEE3;1108 1165 11BA;BEE3;1108 1165 11BA; +BEE4;BEE4;1108 1165 11BB;BEE4;1108 1165 11BB; +BEE5;BEE5;1108 1165 11BC;BEE5;1108 1165 11BC; +BEE6;BEE6;1108 1165 11BD;BEE6;1108 1165 11BD; +BEE7;BEE7;1108 1165 11BE;BEE7;1108 1165 11BE; +BEE8;BEE8;1108 1165 11BF;BEE8;1108 1165 11BF; +BEE9;BEE9;1108 1165 11C0;BEE9;1108 1165 11C0; +BEEA;BEEA;1108 1165 11C1;BEEA;1108 1165 11C1; +BEEB;BEEB;1108 1165 11C2;BEEB;1108 1165 11C2; +BEEC;BEEC;1108 1166;BEEC;1108 1166; +BEED;BEED;1108 1166 11A8;BEED;1108 1166 11A8; +BEEE;BEEE;1108 1166 11A9;BEEE;1108 1166 11A9; +BEEF;BEEF;1108 1166 11AA;BEEF;1108 1166 11AA; +BEF0;BEF0;1108 1166 11AB;BEF0;1108 1166 11AB; +BEF1;BEF1;1108 1166 11AC;BEF1;1108 1166 11AC; +BEF2;BEF2;1108 1166 11AD;BEF2;1108 1166 11AD; +BEF3;BEF3;1108 1166 11AE;BEF3;1108 1166 11AE; +BEF4;BEF4;1108 1166 11AF;BEF4;1108 1166 11AF; +BEF5;BEF5;1108 1166 11B0;BEF5;1108 1166 11B0; +BEF6;BEF6;1108 1166 11B1;BEF6;1108 1166 11B1; +BEF7;BEF7;1108 1166 11B2;BEF7;1108 1166 11B2; +BEF8;BEF8;1108 1166 11B3;BEF8;1108 1166 11B3; +BEF9;BEF9;1108 1166 11B4;BEF9;1108 1166 11B4; +BEFA;BEFA;1108 1166 11B5;BEFA;1108 1166 11B5; +BEFB;BEFB;1108 1166 11B6;BEFB;1108 1166 11B6; +BEFC;BEFC;1108 1166 11B7;BEFC;1108 1166 11B7; +BEFD;BEFD;1108 1166 11B8;BEFD;1108 1166 11B8; +BEFE;BEFE;1108 1166 11B9;BEFE;1108 1166 11B9; +BEFF;BEFF;1108 1166 11BA;BEFF;1108 1166 11BA; +BF00;BF00;1108 1166 11BB;BF00;1108 1166 11BB; +BF01;BF01;1108 1166 11BC;BF01;1108 1166 11BC; +BF02;BF02;1108 1166 11BD;BF02;1108 1166 11BD; +BF03;BF03;1108 1166 11BE;BF03;1108 1166 11BE; +BF04;BF04;1108 1166 11BF;BF04;1108 1166 11BF; +BF05;BF05;1108 1166 11C0;BF05;1108 1166 11C0; +BF06;BF06;1108 1166 11C1;BF06;1108 1166 11C1; +BF07;BF07;1108 1166 11C2;BF07;1108 1166 11C2; +BF08;BF08;1108 1167;BF08;1108 1167; +BF09;BF09;1108 1167 11A8;BF09;1108 1167 11A8; +BF0A;BF0A;1108 1167 11A9;BF0A;1108 1167 11A9; +BF0B;BF0B;1108 1167 11AA;BF0B;1108 1167 11AA; +BF0C;BF0C;1108 1167 11AB;BF0C;1108 1167 11AB; +BF0D;BF0D;1108 1167 11AC;BF0D;1108 1167 11AC; +BF0E;BF0E;1108 1167 11AD;BF0E;1108 1167 11AD; +BF0F;BF0F;1108 1167 11AE;BF0F;1108 1167 11AE; +BF10;BF10;1108 1167 11AF;BF10;1108 1167 11AF; +BF11;BF11;1108 1167 11B0;BF11;1108 1167 11B0; +BF12;BF12;1108 1167 11B1;BF12;1108 1167 11B1; +BF13;BF13;1108 1167 11B2;BF13;1108 1167 11B2; +BF14;BF14;1108 1167 11B3;BF14;1108 1167 11B3; +BF15;BF15;1108 1167 11B4;BF15;1108 1167 11B4; +BF16;BF16;1108 1167 11B5;BF16;1108 1167 11B5; +BF17;BF17;1108 1167 11B6;BF17;1108 1167 11B6; +BF18;BF18;1108 1167 11B7;BF18;1108 1167 11B7; +BF19;BF19;1108 1167 11B8;BF19;1108 1167 11B8; +BF1A;BF1A;1108 1167 11B9;BF1A;1108 1167 11B9; +BF1B;BF1B;1108 1167 11BA;BF1B;1108 1167 11BA; +BF1C;BF1C;1108 1167 11BB;BF1C;1108 1167 11BB; +BF1D;BF1D;1108 1167 11BC;BF1D;1108 1167 11BC; +BF1E;BF1E;1108 1167 11BD;BF1E;1108 1167 11BD; +BF1F;BF1F;1108 1167 11BE;BF1F;1108 1167 11BE; +BF20;BF20;1108 1167 11BF;BF20;1108 1167 11BF; +BF21;BF21;1108 1167 11C0;BF21;1108 1167 11C0; +BF22;BF22;1108 1167 11C1;BF22;1108 1167 11C1; +BF23;BF23;1108 1167 11C2;BF23;1108 1167 11C2; +BF24;BF24;1108 1168;BF24;1108 1168; +BF25;BF25;1108 1168 11A8;BF25;1108 1168 11A8; +BF26;BF26;1108 1168 11A9;BF26;1108 1168 11A9; +BF27;BF27;1108 1168 11AA;BF27;1108 1168 11AA; +BF28;BF28;1108 1168 11AB;BF28;1108 1168 11AB; +BF29;BF29;1108 1168 11AC;BF29;1108 1168 11AC; +BF2A;BF2A;1108 1168 11AD;BF2A;1108 1168 11AD; +BF2B;BF2B;1108 1168 11AE;BF2B;1108 1168 11AE; +BF2C;BF2C;1108 1168 11AF;BF2C;1108 1168 11AF; +BF2D;BF2D;1108 1168 11B0;BF2D;1108 1168 11B0; +BF2E;BF2E;1108 1168 11B1;BF2E;1108 1168 11B1; +BF2F;BF2F;1108 1168 11B2;BF2F;1108 1168 11B2; +BF30;BF30;1108 1168 11B3;BF30;1108 1168 11B3; +BF31;BF31;1108 1168 11B4;BF31;1108 1168 11B4; +BF32;BF32;1108 1168 11B5;BF32;1108 1168 11B5; +BF33;BF33;1108 1168 11B6;BF33;1108 1168 11B6; +BF34;BF34;1108 1168 11B7;BF34;1108 1168 11B7; +BF35;BF35;1108 1168 11B8;BF35;1108 1168 11B8; +BF36;BF36;1108 1168 11B9;BF36;1108 1168 11B9; +BF37;BF37;1108 1168 11BA;BF37;1108 1168 11BA; +BF38;BF38;1108 1168 11BB;BF38;1108 1168 11BB; +BF39;BF39;1108 1168 11BC;BF39;1108 1168 11BC; +BF3A;BF3A;1108 1168 11BD;BF3A;1108 1168 11BD; +BF3B;BF3B;1108 1168 11BE;BF3B;1108 1168 11BE; +BF3C;BF3C;1108 1168 11BF;BF3C;1108 1168 11BF; +BF3D;BF3D;1108 1168 11C0;BF3D;1108 1168 11C0; +BF3E;BF3E;1108 1168 11C1;BF3E;1108 1168 11C1; +BF3F;BF3F;1108 1168 11C2;BF3F;1108 1168 11C2; +BF40;BF40;1108 1169;BF40;1108 1169; +BF41;BF41;1108 1169 11A8;BF41;1108 1169 11A8; +BF42;BF42;1108 1169 11A9;BF42;1108 1169 11A9; +BF43;BF43;1108 1169 11AA;BF43;1108 1169 11AA; +BF44;BF44;1108 1169 11AB;BF44;1108 1169 11AB; +BF45;BF45;1108 1169 11AC;BF45;1108 1169 11AC; +BF46;BF46;1108 1169 11AD;BF46;1108 1169 11AD; +BF47;BF47;1108 1169 11AE;BF47;1108 1169 11AE; +BF48;BF48;1108 1169 11AF;BF48;1108 1169 11AF; +BF49;BF49;1108 1169 11B0;BF49;1108 1169 11B0; +BF4A;BF4A;1108 1169 11B1;BF4A;1108 1169 11B1; +BF4B;BF4B;1108 1169 11B2;BF4B;1108 1169 11B2; +BF4C;BF4C;1108 1169 11B3;BF4C;1108 1169 11B3; +BF4D;BF4D;1108 1169 11B4;BF4D;1108 1169 11B4; +BF4E;BF4E;1108 1169 11B5;BF4E;1108 1169 11B5; +BF4F;BF4F;1108 1169 11B6;BF4F;1108 1169 11B6; +BF50;BF50;1108 1169 11B7;BF50;1108 1169 11B7; +BF51;BF51;1108 1169 11B8;BF51;1108 1169 11B8; +BF52;BF52;1108 1169 11B9;BF52;1108 1169 11B9; +BF53;BF53;1108 1169 11BA;BF53;1108 1169 11BA; +BF54;BF54;1108 1169 11BB;BF54;1108 1169 11BB; +BF55;BF55;1108 1169 11BC;BF55;1108 1169 11BC; +BF56;BF56;1108 1169 11BD;BF56;1108 1169 11BD; +BF57;BF57;1108 1169 11BE;BF57;1108 1169 11BE; +BF58;BF58;1108 1169 11BF;BF58;1108 1169 11BF; +BF59;BF59;1108 1169 11C0;BF59;1108 1169 11C0; +BF5A;BF5A;1108 1169 11C1;BF5A;1108 1169 11C1; +BF5B;BF5B;1108 1169 11C2;BF5B;1108 1169 11C2; +BF5C;BF5C;1108 116A;BF5C;1108 116A; +BF5D;BF5D;1108 116A 11A8;BF5D;1108 116A 11A8; +BF5E;BF5E;1108 116A 11A9;BF5E;1108 116A 11A9; +BF5F;BF5F;1108 116A 11AA;BF5F;1108 116A 11AA; +BF60;BF60;1108 116A 11AB;BF60;1108 116A 11AB; +BF61;BF61;1108 116A 11AC;BF61;1108 116A 11AC; +BF62;BF62;1108 116A 11AD;BF62;1108 116A 11AD; +BF63;BF63;1108 116A 11AE;BF63;1108 116A 11AE; +BF64;BF64;1108 116A 11AF;BF64;1108 116A 11AF; +BF65;BF65;1108 116A 11B0;BF65;1108 116A 11B0; +BF66;BF66;1108 116A 11B1;BF66;1108 116A 11B1; +BF67;BF67;1108 116A 11B2;BF67;1108 116A 11B2; +BF68;BF68;1108 116A 11B3;BF68;1108 116A 11B3; +BF69;BF69;1108 116A 11B4;BF69;1108 116A 11B4; +BF6A;BF6A;1108 116A 11B5;BF6A;1108 116A 11B5; +BF6B;BF6B;1108 116A 11B6;BF6B;1108 116A 11B6; +BF6C;BF6C;1108 116A 11B7;BF6C;1108 116A 11B7; +BF6D;BF6D;1108 116A 11B8;BF6D;1108 116A 11B8; +BF6E;BF6E;1108 116A 11B9;BF6E;1108 116A 11B9; +BF6F;BF6F;1108 116A 11BA;BF6F;1108 116A 11BA; +BF70;BF70;1108 116A 11BB;BF70;1108 116A 11BB; +BF71;BF71;1108 116A 11BC;BF71;1108 116A 11BC; +BF72;BF72;1108 116A 11BD;BF72;1108 116A 11BD; +BF73;BF73;1108 116A 11BE;BF73;1108 116A 11BE; +BF74;BF74;1108 116A 11BF;BF74;1108 116A 11BF; +BF75;BF75;1108 116A 11C0;BF75;1108 116A 11C0; +BF76;BF76;1108 116A 11C1;BF76;1108 116A 11C1; +BF77;BF77;1108 116A 11C2;BF77;1108 116A 11C2; +BF78;BF78;1108 116B;BF78;1108 116B; +BF79;BF79;1108 116B 11A8;BF79;1108 116B 11A8; +BF7A;BF7A;1108 116B 11A9;BF7A;1108 116B 11A9; +BF7B;BF7B;1108 116B 11AA;BF7B;1108 116B 11AA; +BF7C;BF7C;1108 116B 11AB;BF7C;1108 116B 11AB; +BF7D;BF7D;1108 116B 11AC;BF7D;1108 116B 11AC; +BF7E;BF7E;1108 116B 11AD;BF7E;1108 116B 11AD; +BF7F;BF7F;1108 116B 11AE;BF7F;1108 116B 11AE; +BF80;BF80;1108 116B 11AF;BF80;1108 116B 11AF; +BF81;BF81;1108 116B 11B0;BF81;1108 116B 11B0; +BF82;BF82;1108 116B 11B1;BF82;1108 116B 11B1; +BF83;BF83;1108 116B 11B2;BF83;1108 116B 11B2; +BF84;BF84;1108 116B 11B3;BF84;1108 116B 11B3; +BF85;BF85;1108 116B 11B4;BF85;1108 116B 11B4; +BF86;BF86;1108 116B 11B5;BF86;1108 116B 11B5; +BF87;BF87;1108 116B 11B6;BF87;1108 116B 11B6; +BF88;BF88;1108 116B 11B7;BF88;1108 116B 11B7; +BF89;BF89;1108 116B 11B8;BF89;1108 116B 11B8; +BF8A;BF8A;1108 116B 11B9;BF8A;1108 116B 11B9; +BF8B;BF8B;1108 116B 11BA;BF8B;1108 116B 11BA; +BF8C;BF8C;1108 116B 11BB;BF8C;1108 116B 11BB; +BF8D;BF8D;1108 116B 11BC;BF8D;1108 116B 11BC; +BF8E;BF8E;1108 116B 11BD;BF8E;1108 116B 11BD; +BF8F;BF8F;1108 116B 11BE;BF8F;1108 116B 11BE; +BF90;BF90;1108 116B 11BF;BF90;1108 116B 11BF; +BF91;BF91;1108 116B 11C0;BF91;1108 116B 11C0; +BF92;BF92;1108 116B 11C1;BF92;1108 116B 11C1; +BF93;BF93;1108 116B 11C2;BF93;1108 116B 11C2; +BF94;BF94;1108 116C;BF94;1108 116C; +BF95;BF95;1108 116C 11A8;BF95;1108 116C 11A8; +BF96;BF96;1108 116C 11A9;BF96;1108 116C 11A9; +BF97;BF97;1108 116C 11AA;BF97;1108 116C 11AA; +BF98;BF98;1108 116C 11AB;BF98;1108 116C 11AB; +BF99;BF99;1108 116C 11AC;BF99;1108 116C 11AC; +BF9A;BF9A;1108 116C 11AD;BF9A;1108 116C 11AD; +BF9B;BF9B;1108 116C 11AE;BF9B;1108 116C 11AE; +BF9C;BF9C;1108 116C 11AF;BF9C;1108 116C 11AF; +BF9D;BF9D;1108 116C 11B0;BF9D;1108 116C 11B0; +BF9E;BF9E;1108 116C 11B1;BF9E;1108 116C 11B1; +BF9F;BF9F;1108 116C 11B2;BF9F;1108 116C 11B2; +BFA0;BFA0;1108 116C 11B3;BFA0;1108 116C 11B3; +BFA1;BFA1;1108 116C 11B4;BFA1;1108 116C 11B4; +BFA2;BFA2;1108 116C 11B5;BFA2;1108 116C 11B5; +BFA3;BFA3;1108 116C 11B6;BFA3;1108 116C 11B6; +BFA4;BFA4;1108 116C 11B7;BFA4;1108 116C 11B7; +BFA5;BFA5;1108 116C 11B8;BFA5;1108 116C 11B8; +BFA6;BFA6;1108 116C 11B9;BFA6;1108 116C 11B9; +BFA7;BFA7;1108 116C 11BA;BFA7;1108 116C 11BA; +BFA8;BFA8;1108 116C 11BB;BFA8;1108 116C 11BB; +BFA9;BFA9;1108 116C 11BC;BFA9;1108 116C 11BC; +BFAA;BFAA;1108 116C 11BD;BFAA;1108 116C 11BD; +BFAB;BFAB;1108 116C 11BE;BFAB;1108 116C 11BE; +BFAC;BFAC;1108 116C 11BF;BFAC;1108 116C 11BF; +BFAD;BFAD;1108 116C 11C0;BFAD;1108 116C 11C0; +BFAE;BFAE;1108 116C 11C1;BFAE;1108 116C 11C1; +BFAF;BFAF;1108 116C 11C2;BFAF;1108 116C 11C2; +BFB0;BFB0;1108 116D;BFB0;1108 116D; +BFB1;BFB1;1108 116D 11A8;BFB1;1108 116D 11A8; +BFB2;BFB2;1108 116D 11A9;BFB2;1108 116D 11A9; +BFB3;BFB3;1108 116D 11AA;BFB3;1108 116D 11AA; +BFB4;BFB4;1108 116D 11AB;BFB4;1108 116D 11AB; +BFB5;BFB5;1108 116D 11AC;BFB5;1108 116D 11AC; +BFB6;BFB6;1108 116D 11AD;BFB6;1108 116D 11AD; +BFB7;BFB7;1108 116D 11AE;BFB7;1108 116D 11AE; +BFB8;BFB8;1108 116D 11AF;BFB8;1108 116D 11AF; +BFB9;BFB9;1108 116D 11B0;BFB9;1108 116D 11B0; +BFBA;BFBA;1108 116D 11B1;BFBA;1108 116D 11B1; +BFBB;BFBB;1108 116D 11B2;BFBB;1108 116D 11B2; +BFBC;BFBC;1108 116D 11B3;BFBC;1108 116D 11B3; +BFBD;BFBD;1108 116D 11B4;BFBD;1108 116D 11B4; +BFBE;BFBE;1108 116D 11B5;BFBE;1108 116D 11B5; +BFBF;BFBF;1108 116D 11B6;BFBF;1108 116D 11B6; +BFC0;BFC0;1108 116D 11B7;BFC0;1108 116D 11B7; +BFC1;BFC1;1108 116D 11B8;BFC1;1108 116D 11B8; +BFC2;BFC2;1108 116D 11B9;BFC2;1108 116D 11B9; +BFC3;BFC3;1108 116D 11BA;BFC3;1108 116D 11BA; +BFC4;BFC4;1108 116D 11BB;BFC4;1108 116D 11BB; +BFC5;BFC5;1108 116D 11BC;BFC5;1108 116D 11BC; +BFC6;BFC6;1108 116D 11BD;BFC6;1108 116D 11BD; +BFC7;BFC7;1108 116D 11BE;BFC7;1108 116D 11BE; +BFC8;BFC8;1108 116D 11BF;BFC8;1108 116D 11BF; +BFC9;BFC9;1108 116D 11C0;BFC9;1108 116D 11C0; +BFCA;BFCA;1108 116D 11C1;BFCA;1108 116D 11C1; +BFCB;BFCB;1108 116D 11C2;BFCB;1108 116D 11C2; +BFCC;BFCC;1108 116E;BFCC;1108 116E; +BFCD;BFCD;1108 116E 11A8;BFCD;1108 116E 11A8; +BFCE;BFCE;1108 116E 11A9;BFCE;1108 116E 11A9; +BFCF;BFCF;1108 116E 11AA;BFCF;1108 116E 11AA; +BFD0;BFD0;1108 116E 11AB;BFD0;1108 116E 11AB; +BFD1;BFD1;1108 116E 11AC;BFD1;1108 116E 11AC; +BFD2;BFD2;1108 116E 11AD;BFD2;1108 116E 11AD; +BFD3;BFD3;1108 116E 11AE;BFD3;1108 116E 11AE; +BFD4;BFD4;1108 116E 11AF;BFD4;1108 116E 11AF; +BFD5;BFD5;1108 116E 11B0;BFD5;1108 116E 11B0; +BFD6;BFD6;1108 116E 11B1;BFD6;1108 116E 11B1; +BFD7;BFD7;1108 116E 11B2;BFD7;1108 116E 11B2; +BFD8;BFD8;1108 116E 11B3;BFD8;1108 116E 11B3; +BFD9;BFD9;1108 116E 11B4;BFD9;1108 116E 11B4; +BFDA;BFDA;1108 116E 11B5;BFDA;1108 116E 11B5; +BFDB;BFDB;1108 116E 11B6;BFDB;1108 116E 11B6; +BFDC;BFDC;1108 116E 11B7;BFDC;1108 116E 11B7; +BFDD;BFDD;1108 116E 11B8;BFDD;1108 116E 11B8; +BFDE;BFDE;1108 116E 11B9;BFDE;1108 116E 11B9; +BFDF;BFDF;1108 116E 11BA;BFDF;1108 116E 11BA; +BFE0;BFE0;1108 116E 11BB;BFE0;1108 116E 11BB; +BFE1;BFE1;1108 116E 11BC;BFE1;1108 116E 11BC; +BFE2;BFE2;1108 116E 11BD;BFE2;1108 116E 11BD; +BFE3;BFE3;1108 116E 11BE;BFE3;1108 116E 11BE; +BFE4;BFE4;1108 116E 11BF;BFE4;1108 116E 11BF; +BFE5;BFE5;1108 116E 11C0;BFE5;1108 116E 11C0; +BFE6;BFE6;1108 116E 11C1;BFE6;1108 116E 11C1; +BFE7;BFE7;1108 116E 11C2;BFE7;1108 116E 11C2; +BFE8;BFE8;1108 116F;BFE8;1108 116F; +BFE9;BFE9;1108 116F 11A8;BFE9;1108 116F 11A8; +BFEA;BFEA;1108 116F 11A9;BFEA;1108 116F 11A9; +BFEB;BFEB;1108 116F 11AA;BFEB;1108 116F 11AA; +BFEC;BFEC;1108 116F 11AB;BFEC;1108 116F 11AB; +BFED;BFED;1108 116F 11AC;BFED;1108 116F 11AC; +BFEE;BFEE;1108 116F 11AD;BFEE;1108 116F 11AD; +BFEF;BFEF;1108 116F 11AE;BFEF;1108 116F 11AE; +BFF0;BFF0;1108 116F 11AF;BFF0;1108 116F 11AF; +BFF1;BFF1;1108 116F 11B0;BFF1;1108 116F 11B0; +BFF2;BFF2;1108 116F 11B1;BFF2;1108 116F 11B1; +BFF3;BFF3;1108 116F 11B2;BFF3;1108 116F 11B2; +BFF4;BFF4;1108 116F 11B3;BFF4;1108 116F 11B3; +BFF5;BFF5;1108 116F 11B4;BFF5;1108 116F 11B4; +BFF6;BFF6;1108 116F 11B5;BFF6;1108 116F 11B5; +BFF7;BFF7;1108 116F 11B6;BFF7;1108 116F 11B6; +BFF8;BFF8;1108 116F 11B7;BFF8;1108 116F 11B7; +BFF9;BFF9;1108 116F 11B8;BFF9;1108 116F 11B8; +BFFA;BFFA;1108 116F 11B9;BFFA;1108 116F 11B9; +BFFB;BFFB;1108 116F 11BA;BFFB;1108 116F 11BA; +BFFC;BFFC;1108 116F 11BB;BFFC;1108 116F 11BB; +BFFD;BFFD;1108 116F 11BC;BFFD;1108 116F 11BC; +BFFE;BFFE;1108 116F 11BD;BFFE;1108 116F 11BD; +BFFF;BFFF;1108 116F 11BE;BFFF;1108 116F 11BE; +C000;C000;1108 116F 11BF;C000;1108 116F 11BF; +C001;C001;1108 116F 11C0;C001;1108 116F 11C0; +C002;C002;1108 116F 11C1;C002;1108 116F 11C1; +C003;C003;1108 116F 11C2;C003;1108 116F 11C2; +C004;C004;1108 1170;C004;1108 1170; +C005;C005;1108 1170 11A8;C005;1108 1170 11A8; +C006;C006;1108 1170 11A9;C006;1108 1170 11A9; +C007;C007;1108 1170 11AA;C007;1108 1170 11AA; +C008;C008;1108 1170 11AB;C008;1108 1170 11AB; +C009;C009;1108 1170 11AC;C009;1108 1170 11AC; +C00A;C00A;1108 1170 11AD;C00A;1108 1170 11AD; +C00B;C00B;1108 1170 11AE;C00B;1108 1170 11AE; +C00C;C00C;1108 1170 11AF;C00C;1108 1170 11AF; +C00D;C00D;1108 1170 11B0;C00D;1108 1170 11B0; +C00E;C00E;1108 1170 11B1;C00E;1108 1170 11B1; +C00F;C00F;1108 1170 11B2;C00F;1108 1170 11B2; +C010;C010;1108 1170 11B3;C010;1108 1170 11B3; +C011;C011;1108 1170 11B4;C011;1108 1170 11B4; +C012;C012;1108 1170 11B5;C012;1108 1170 11B5; +C013;C013;1108 1170 11B6;C013;1108 1170 11B6; +C014;C014;1108 1170 11B7;C014;1108 1170 11B7; +C015;C015;1108 1170 11B8;C015;1108 1170 11B8; +C016;C016;1108 1170 11B9;C016;1108 1170 11B9; +C017;C017;1108 1170 11BA;C017;1108 1170 11BA; +C018;C018;1108 1170 11BB;C018;1108 1170 11BB; +C019;C019;1108 1170 11BC;C019;1108 1170 11BC; +C01A;C01A;1108 1170 11BD;C01A;1108 1170 11BD; +C01B;C01B;1108 1170 11BE;C01B;1108 1170 11BE; +C01C;C01C;1108 1170 11BF;C01C;1108 1170 11BF; +C01D;C01D;1108 1170 11C0;C01D;1108 1170 11C0; +C01E;C01E;1108 1170 11C1;C01E;1108 1170 11C1; +C01F;C01F;1108 1170 11C2;C01F;1108 1170 11C2; +C020;C020;1108 1171;C020;1108 1171; +C021;C021;1108 1171 11A8;C021;1108 1171 11A8; +C022;C022;1108 1171 11A9;C022;1108 1171 11A9; +C023;C023;1108 1171 11AA;C023;1108 1171 11AA; +C024;C024;1108 1171 11AB;C024;1108 1171 11AB; +C025;C025;1108 1171 11AC;C025;1108 1171 11AC; +C026;C026;1108 1171 11AD;C026;1108 1171 11AD; +C027;C027;1108 1171 11AE;C027;1108 1171 11AE; +C028;C028;1108 1171 11AF;C028;1108 1171 11AF; +C029;C029;1108 1171 11B0;C029;1108 1171 11B0; +C02A;C02A;1108 1171 11B1;C02A;1108 1171 11B1; +C02B;C02B;1108 1171 11B2;C02B;1108 1171 11B2; +C02C;C02C;1108 1171 11B3;C02C;1108 1171 11B3; +C02D;C02D;1108 1171 11B4;C02D;1108 1171 11B4; +C02E;C02E;1108 1171 11B5;C02E;1108 1171 11B5; +C02F;C02F;1108 1171 11B6;C02F;1108 1171 11B6; +C030;C030;1108 1171 11B7;C030;1108 1171 11B7; +C031;C031;1108 1171 11B8;C031;1108 1171 11B8; +C032;C032;1108 1171 11B9;C032;1108 1171 11B9; +C033;C033;1108 1171 11BA;C033;1108 1171 11BA; +C034;C034;1108 1171 11BB;C034;1108 1171 11BB; +C035;C035;1108 1171 11BC;C035;1108 1171 11BC; +C036;C036;1108 1171 11BD;C036;1108 1171 11BD; +C037;C037;1108 1171 11BE;C037;1108 1171 11BE; +C038;C038;1108 1171 11BF;C038;1108 1171 11BF; +C039;C039;1108 1171 11C0;C039;1108 1171 11C0; +C03A;C03A;1108 1171 11C1;C03A;1108 1171 11C1; +C03B;C03B;1108 1171 11C2;C03B;1108 1171 11C2; +C03C;C03C;1108 1172;C03C;1108 1172; +C03D;C03D;1108 1172 11A8;C03D;1108 1172 11A8; +C03E;C03E;1108 1172 11A9;C03E;1108 1172 11A9; +C03F;C03F;1108 1172 11AA;C03F;1108 1172 11AA; +C040;C040;1108 1172 11AB;C040;1108 1172 11AB; +C041;C041;1108 1172 11AC;C041;1108 1172 11AC; +C042;C042;1108 1172 11AD;C042;1108 1172 11AD; +C043;C043;1108 1172 11AE;C043;1108 1172 11AE; +C044;C044;1108 1172 11AF;C044;1108 1172 11AF; +C045;C045;1108 1172 11B0;C045;1108 1172 11B0; +C046;C046;1108 1172 11B1;C046;1108 1172 11B1; +C047;C047;1108 1172 11B2;C047;1108 1172 11B2; +C048;C048;1108 1172 11B3;C048;1108 1172 11B3; +C049;C049;1108 1172 11B4;C049;1108 1172 11B4; +C04A;C04A;1108 1172 11B5;C04A;1108 1172 11B5; +C04B;C04B;1108 1172 11B6;C04B;1108 1172 11B6; +C04C;C04C;1108 1172 11B7;C04C;1108 1172 11B7; +C04D;C04D;1108 1172 11B8;C04D;1108 1172 11B8; +C04E;C04E;1108 1172 11B9;C04E;1108 1172 11B9; +C04F;C04F;1108 1172 11BA;C04F;1108 1172 11BA; +C050;C050;1108 1172 11BB;C050;1108 1172 11BB; +C051;C051;1108 1172 11BC;C051;1108 1172 11BC; +C052;C052;1108 1172 11BD;C052;1108 1172 11BD; +C053;C053;1108 1172 11BE;C053;1108 1172 11BE; +C054;C054;1108 1172 11BF;C054;1108 1172 11BF; +C055;C055;1108 1172 11C0;C055;1108 1172 11C0; +C056;C056;1108 1172 11C1;C056;1108 1172 11C1; +C057;C057;1108 1172 11C2;C057;1108 1172 11C2; +C058;C058;1108 1173;C058;1108 1173; +C059;C059;1108 1173 11A8;C059;1108 1173 11A8; +C05A;C05A;1108 1173 11A9;C05A;1108 1173 11A9; +C05B;C05B;1108 1173 11AA;C05B;1108 1173 11AA; +C05C;C05C;1108 1173 11AB;C05C;1108 1173 11AB; +C05D;C05D;1108 1173 11AC;C05D;1108 1173 11AC; +C05E;C05E;1108 1173 11AD;C05E;1108 1173 11AD; +C05F;C05F;1108 1173 11AE;C05F;1108 1173 11AE; +C060;C060;1108 1173 11AF;C060;1108 1173 11AF; +C061;C061;1108 1173 11B0;C061;1108 1173 11B0; +C062;C062;1108 1173 11B1;C062;1108 1173 11B1; +C063;C063;1108 1173 11B2;C063;1108 1173 11B2; +C064;C064;1108 1173 11B3;C064;1108 1173 11B3; +C065;C065;1108 1173 11B4;C065;1108 1173 11B4; +C066;C066;1108 1173 11B5;C066;1108 1173 11B5; +C067;C067;1108 1173 11B6;C067;1108 1173 11B6; +C068;C068;1108 1173 11B7;C068;1108 1173 11B7; +C069;C069;1108 1173 11B8;C069;1108 1173 11B8; +C06A;C06A;1108 1173 11B9;C06A;1108 1173 11B9; +C06B;C06B;1108 1173 11BA;C06B;1108 1173 11BA; +C06C;C06C;1108 1173 11BB;C06C;1108 1173 11BB; +C06D;C06D;1108 1173 11BC;C06D;1108 1173 11BC; +C06E;C06E;1108 1173 11BD;C06E;1108 1173 11BD; +C06F;C06F;1108 1173 11BE;C06F;1108 1173 11BE; +C070;C070;1108 1173 11BF;C070;1108 1173 11BF; +C071;C071;1108 1173 11C0;C071;1108 1173 11C0; +C072;C072;1108 1173 11C1;C072;1108 1173 11C1; +C073;C073;1108 1173 11C2;C073;1108 1173 11C2; +C074;C074;1108 1174;C074;1108 1174; +C075;C075;1108 1174 11A8;C075;1108 1174 11A8; +C076;C076;1108 1174 11A9;C076;1108 1174 11A9; +C077;C077;1108 1174 11AA;C077;1108 1174 11AA; +C078;C078;1108 1174 11AB;C078;1108 1174 11AB; +C079;C079;1108 1174 11AC;C079;1108 1174 11AC; +C07A;C07A;1108 1174 11AD;C07A;1108 1174 11AD; +C07B;C07B;1108 1174 11AE;C07B;1108 1174 11AE; +C07C;C07C;1108 1174 11AF;C07C;1108 1174 11AF; +C07D;C07D;1108 1174 11B0;C07D;1108 1174 11B0; +C07E;C07E;1108 1174 11B1;C07E;1108 1174 11B1; +C07F;C07F;1108 1174 11B2;C07F;1108 1174 11B2; +C080;C080;1108 1174 11B3;C080;1108 1174 11B3; +C081;C081;1108 1174 11B4;C081;1108 1174 11B4; +C082;C082;1108 1174 11B5;C082;1108 1174 11B5; +C083;C083;1108 1174 11B6;C083;1108 1174 11B6; +C084;C084;1108 1174 11B7;C084;1108 1174 11B7; +C085;C085;1108 1174 11B8;C085;1108 1174 11B8; +C086;C086;1108 1174 11B9;C086;1108 1174 11B9; +C087;C087;1108 1174 11BA;C087;1108 1174 11BA; +C088;C088;1108 1174 11BB;C088;1108 1174 11BB; +C089;C089;1108 1174 11BC;C089;1108 1174 11BC; +C08A;C08A;1108 1174 11BD;C08A;1108 1174 11BD; +C08B;C08B;1108 1174 11BE;C08B;1108 1174 11BE; +C08C;C08C;1108 1174 11BF;C08C;1108 1174 11BF; +C08D;C08D;1108 1174 11C0;C08D;1108 1174 11C0; +C08E;C08E;1108 1174 11C1;C08E;1108 1174 11C1; +C08F;C08F;1108 1174 11C2;C08F;1108 1174 11C2; +C090;C090;1108 1175;C090;1108 1175; +C091;C091;1108 1175 11A8;C091;1108 1175 11A8; +C092;C092;1108 1175 11A9;C092;1108 1175 11A9; +C093;C093;1108 1175 11AA;C093;1108 1175 11AA; +C094;C094;1108 1175 11AB;C094;1108 1175 11AB; +C095;C095;1108 1175 11AC;C095;1108 1175 11AC; +C096;C096;1108 1175 11AD;C096;1108 1175 11AD; +C097;C097;1108 1175 11AE;C097;1108 1175 11AE; +C098;C098;1108 1175 11AF;C098;1108 1175 11AF; +C099;C099;1108 1175 11B0;C099;1108 1175 11B0; +C09A;C09A;1108 1175 11B1;C09A;1108 1175 11B1; +C09B;C09B;1108 1175 11B2;C09B;1108 1175 11B2; +C09C;C09C;1108 1175 11B3;C09C;1108 1175 11B3; +C09D;C09D;1108 1175 11B4;C09D;1108 1175 11B4; +C09E;C09E;1108 1175 11B5;C09E;1108 1175 11B5; +C09F;C09F;1108 1175 11B6;C09F;1108 1175 11B6; +C0A0;C0A0;1108 1175 11B7;C0A0;1108 1175 11B7; +C0A1;C0A1;1108 1175 11B8;C0A1;1108 1175 11B8; +C0A2;C0A2;1108 1175 11B9;C0A2;1108 1175 11B9; +C0A3;C0A3;1108 1175 11BA;C0A3;1108 1175 11BA; +C0A4;C0A4;1108 1175 11BB;C0A4;1108 1175 11BB; +C0A5;C0A5;1108 1175 11BC;C0A5;1108 1175 11BC; +C0A6;C0A6;1108 1175 11BD;C0A6;1108 1175 11BD; +C0A7;C0A7;1108 1175 11BE;C0A7;1108 1175 11BE; +C0A8;C0A8;1108 1175 11BF;C0A8;1108 1175 11BF; +C0A9;C0A9;1108 1175 11C0;C0A9;1108 1175 11C0; +C0AA;C0AA;1108 1175 11C1;C0AA;1108 1175 11C1; +C0AB;C0AB;1108 1175 11C2;C0AB;1108 1175 11C2; +C0AC;C0AC;1109 1161;C0AC;1109 1161; +C0AD;C0AD;1109 1161 11A8;C0AD;1109 1161 11A8; +C0AE;C0AE;1109 1161 11A9;C0AE;1109 1161 11A9; +C0AF;C0AF;1109 1161 11AA;C0AF;1109 1161 11AA; +C0B0;C0B0;1109 1161 11AB;C0B0;1109 1161 11AB; +C0B1;C0B1;1109 1161 11AC;C0B1;1109 1161 11AC; +C0B2;C0B2;1109 1161 11AD;C0B2;1109 1161 11AD; +C0B3;C0B3;1109 1161 11AE;C0B3;1109 1161 11AE; +C0B4;C0B4;1109 1161 11AF;C0B4;1109 1161 11AF; +C0B5;C0B5;1109 1161 11B0;C0B5;1109 1161 11B0; +C0B6;C0B6;1109 1161 11B1;C0B6;1109 1161 11B1; +C0B7;C0B7;1109 1161 11B2;C0B7;1109 1161 11B2; +C0B8;C0B8;1109 1161 11B3;C0B8;1109 1161 11B3; +C0B9;C0B9;1109 1161 11B4;C0B9;1109 1161 11B4; +C0BA;C0BA;1109 1161 11B5;C0BA;1109 1161 11B5; +C0BB;C0BB;1109 1161 11B6;C0BB;1109 1161 11B6; +C0BC;C0BC;1109 1161 11B7;C0BC;1109 1161 11B7; +C0BD;C0BD;1109 1161 11B8;C0BD;1109 1161 11B8; +C0BE;C0BE;1109 1161 11B9;C0BE;1109 1161 11B9; +C0BF;C0BF;1109 1161 11BA;C0BF;1109 1161 11BA; +C0C0;C0C0;1109 1161 11BB;C0C0;1109 1161 11BB; +C0C1;C0C1;1109 1161 11BC;C0C1;1109 1161 11BC; +C0C2;C0C2;1109 1161 11BD;C0C2;1109 1161 11BD; +C0C3;C0C3;1109 1161 11BE;C0C3;1109 1161 11BE; +C0C4;C0C4;1109 1161 11BF;C0C4;1109 1161 11BF; +C0C5;C0C5;1109 1161 11C0;C0C5;1109 1161 11C0; +C0C6;C0C6;1109 1161 11C1;C0C6;1109 1161 11C1; +C0C7;C0C7;1109 1161 11C2;C0C7;1109 1161 11C2; +C0C8;C0C8;1109 1162;C0C8;1109 1162; +C0C9;C0C9;1109 1162 11A8;C0C9;1109 1162 11A8; +C0CA;C0CA;1109 1162 11A9;C0CA;1109 1162 11A9; +C0CB;C0CB;1109 1162 11AA;C0CB;1109 1162 11AA; +C0CC;C0CC;1109 1162 11AB;C0CC;1109 1162 11AB; +C0CD;C0CD;1109 1162 11AC;C0CD;1109 1162 11AC; +C0CE;C0CE;1109 1162 11AD;C0CE;1109 1162 11AD; +C0CF;C0CF;1109 1162 11AE;C0CF;1109 1162 11AE; +C0D0;C0D0;1109 1162 11AF;C0D0;1109 1162 11AF; +C0D1;C0D1;1109 1162 11B0;C0D1;1109 1162 11B0; +C0D2;C0D2;1109 1162 11B1;C0D2;1109 1162 11B1; +C0D3;C0D3;1109 1162 11B2;C0D3;1109 1162 11B2; +C0D4;C0D4;1109 1162 11B3;C0D4;1109 1162 11B3; +C0D5;C0D5;1109 1162 11B4;C0D5;1109 1162 11B4; +C0D6;C0D6;1109 1162 11B5;C0D6;1109 1162 11B5; +C0D7;C0D7;1109 1162 11B6;C0D7;1109 1162 11B6; +C0D8;C0D8;1109 1162 11B7;C0D8;1109 1162 11B7; +C0D9;C0D9;1109 1162 11B8;C0D9;1109 1162 11B8; +C0DA;C0DA;1109 1162 11B9;C0DA;1109 1162 11B9; +C0DB;C0DB;1109 1162 11BA;C0DB;1109 1162 11BA; +C0DC;C0DC;1109 1162 11BB;C0DC;1109 1162 11BB; +C0DD;C0DD;1109 1162 11BC;C0DD;1109 1162 11BC; +C0DE;C0DE;1109 1162 11BD;C0DE;1109 1162 11BD; +C0DF;C0DF;1109 1162 11BE;C0DF;1109 1162 11BE; +C0E0;C0E0;1109 1162 11BF;C0E0;1109 1162 11BF; +C0E1;C0E1;1109 1162 11C0;C0E1;1109 1162 11C0; +C0E2;C0E2;1109 1162 11C1;C0E2;1109 1162 11C1; +C0E3;C0E3;1109 1162 11C2;C0E3;1109 1162 11C2; +C0E4;C0E4;1109 1163;C0E4;1109 1163; +C0E5;C0E5;1109 1163 11A8;C0E5;1109 1163 11A8; +C0E6;C0E6;1109 1163 11A9;C0E6;1109 1163 11A9; +C0E7;C0E7;1109 1163 11AA;C0E7;1109 1163 11AA; +C0E8;C0E8;1109 1163 11AB;C0E8;1109 1163 11AB; +C0E9;C0E9;1109 1163 11AC;C0E9;1109 1163 11AC; +C0EA;C0EA;1109 1163 11AD;C0EA;1109 1163 11AD; +C0EB;C0EB;1109 1163 11AE;C0EB;1109 1163 11AE; +C0EC;C0EC;1109 1163 11AF;C0EC;1109 1163 11AF; +C0ED;C0ED;1109 1163 11B0;C0ED;1109 1163 11B0; +C0EE;C0EE;1109 1163 11B1;C0EE;1109 1163 11B1; +C0EF;C0EF;1109 1163 11B2;C0EF;1109 1163 11B2; +C0F0;C0F0;1109 1163 11B3;C0F0;1109 1163 11B3; +C0F1;C0F1;1109 1163 11B4;C0F1;1109 1163 11B4; +C0F2;C0F2;1109 1163 11B5;C0F2;1109 1163 11B5; +C0F3;C0F3;1109 1163 11B6;C0F3;1109 1163 11B6; +C0F4;C0F4;1109 1163 11B7;C0F4;1109 1163 11B7; +C0F5;C0F5;1109 1163 11B8;C0F5;1109 1163 11B8; +C0F6;C0F6;1109 1163 11B9;C0F6;1109 1163 11B9; +C0F7;C0F7;1109 1163 11BA;C0F7;1109 1163 11BA; +C0F8;C0F8;1109 1163 11BB;C0F8;1109 1163 11BB; +C0F9;C0F9;1109 1163 11BC;C0F9;1109 1163 11BC; +C0FA;C0FA;1109 1163 11BD;C0FA;1109 1163 11BD; +C0FB;C0FB;1109 1163 11BE;C0FB;1109 1163 11BE; +C0FC;C0FC;1109 1163 11BF;C0FC;1109 1163 11BF; +C0FD;C0FD;1109 1163 11C0;C0FD;1109 1163 11C0; +C0FE;C0FE;1109 1163 11C1;C0FE;1109 1163 11C1; +C0FF;C0FF;1109 1163 11C2;C0FF;1109 1163 11C2; +C100;C100;1109 1164;C100;1109 1164; +C101;C101;1109 1164 11A8;C101;1109 1164 11A8; +C102;C102;1109 1164 11A9;C102;1109 1164 11A9; +C103;C103;1109 1164 11AA;C103;1109 1164 11AA; +C104;C104;1109 1164 11AB;C104;1109 1164 11AB; +C105;C105;1109 1164 11AC;C105;1109 1164 11AC; +C106;C106;1109 1164 11AD;C106;1109 1164 11AD; +C107;C107;1109 1164 11AE;C107;1109 1164 11AE; +C108;C108;1109 1164 11AF;C108;1109 1164 11AF; +C109;C109;1109 1164 11B0;C109;1109 1164 11B0; +C10A;C10A;1109 1164 11B1;C10A;1109 1164 11B1; +C10B;C10B;1109 1164 11B2;C10B;1109 1164 11B2; +C10C;C10C;1109 1164 11B3;C10C;1109 1164 11B3; +C10D;C10D;1109 1164 11B4;C10D;1109 1164 11B4; +C10E;C10E;1109 1164 11B5;C10E;1109 1164 11B5; +C10F;C10F;1109 1164 11B6;C10F;1109 1164 11B6; +C110;C110;1109 1164 11B7;C110;1109 1164 11B7; +C111;C111;1109 1164 11B8;C111;1109 1164 11B8; +C112;C112;1109 1164 11B9;C112;1109 1164 11B9; +C113;C113;1109 1164 11BA;C113;1109 1164 11BA; +C114;C114;1109 1164 11BB;C114;1109 1164 11BB; +C115;C115;1109 1164 11BC;C115;1109 1164 11BC; +C116;C116;1109 1164 11BD;C116;1109 1164 11BD; +C117;C117;1109 1164 11BE;C117;1109 1164 11BE; +C118;C118;1109 1164 11BF;C118;1109 1164 11BF; +C119;C119;1109 1164 11C0;C119;1109 1164 11C0; +C11A;C11A;1109 1164 11C1;C11A;1109 1164 11C1; +C11B;C11B;1109 1164 11C2;C11B;1109 1164 11C2; +C11C;C11C;1109 1165;C11C;1109 1165; +C11D;C11D;1109 1165 11A8;C11D;1109 1165 11A8; +C11E;C11E;1109 1165 11A9;C11E;1109 1165 11A9; +C11F;C11F;1109 1165 11AA;C11F;1109 1165 11AA; +C120;C120;1109 1165 11AB;C120;1109 1165 11AB; +C121;C121;1109 1165 11AC;C121;1109 1165 11AC; +C122;C122;1109 1165 11AD;C122;1109 1165 11AD; +C123;C123;1109 1165 11AE;C123;1109 1165 11AE; +C124;C124;1109 1165 11AF;C124;1109 1165 11AF; +C125;C125;1109 1165 11B0;C125;1109 1165 11B0; +C126;C126;1109 1165 11B1;C126;1109 1165 11B1; +C127;C127;1109 1165 11B2;C127;1109 1165 11B2; +C128;C128;1109 1165 11B3;C128;1109 1165 11B3; +C129;C129;1109 1165 11B4;C129;1109 1165 11B4; +C12A;C12A;1109 1165 11B5;C12A;1109 1165 11B5; +C12B;C12B;1109 1165 11B6;C12B;1109 1165 11B6; +C12C;C12C;1109 1165 11B7;C12C;1109 1165 11B7; +C12D;C12D;1109 1165 11B8;C12D;1109 1165 11B8; +C12E;C12E;1109 1165 11B9;C12E;1109 1165 11B9; +C12F;C12F;1109 1165 11BA;C12F;1109 1165 11BA; +C130;C130;1109 1165 11BB;C130;1109 1165 11BB; +C131;C131;1109 1165 11BC;C131;1109 1165 11BC; +C132;C132;1109 1165 11BD;C132;1109 1165 11BD; +C133;C133;1109 1165 11BE;C133;1109 1165 11BE; +C134;C134;1109 1165 11BF;C134;1109 1165 11BF; +C135;C135;1109 1165 11C0;C135;1109 1165 11C0; +C136;C136;1109 1165 11C1;C136;1109 1165 11C1; +C137;C137;1109 1165 11C2;C137;1109 1165 11C2; +C138;C138;1109 1166;C138;1109 1166; +C139;C139;1109 1166 11A8;C139;1109 1166 11A8; +C13A;C13A;1109 1166 11A9;C13A;1109 1166 11A9; +C13B;C13B;1109 1166 11AA;C13B;1109 1166 11AA; +C13C;C13C;1109 1166 11AB;C13C;1109 1166 11AB; +C13D;C13D;1109 1166 11AC;C13D;1109 1166 11AC; +C13E;C13E;1109 1166 11AD;C13E;1109 1166 11AD; +C13F;C13F;1109 1166 11AE;C13F;1109 1166 11AE; +C140;C140;1109 1166 11AF;C140;1109 1166 11AF; +C141;C141;1109 1166 11B0;C141;1109 1166 11B0; +C142;C142;1109 1166 11B1;C142;1109 1166 11B1; +C143;C143;1109 1166 11B2;C143;1109 1166 11B2; +C144;C144;1109 1166 11B3;C144;1109 1166 11B3; +C145;C145;1109 1166 11B4;C145;1109 1166 11B4; +C146;C146;1109 1166 11B5;C146;1109 1166 11B5; +C147;C147;1109 1166 11B6;C147;1109 1166 11B6; +C148;C148;1109 1166 11B7;C148;1109 1166 11B7; +C149;C149;1109 1166 11B8;C149;1109 1166 11B8; +C14A;C14A;1109 1166 11B9;C14A;1109 1166 11B9; +C14B;C14B;1109 1166 11BA;C14B;1109 1166 11BA; +C14C;C14C;1109 1166 11BB;C14C;1109 1166 11BB; +C14D;C14D;1109 1166 11BC;C14D;1109 1166 11BC; +C14E;C14E;1109 1166 11BD;C14E;1109 1166 11BD; +C14F;C14F;1109 1166 11BE;C14F;1109 1166 11BE; +C150;C150;1109 1166 11BF;C150;1109 1166 11BF; +C151;C151;1109 1166 11C0;C151;1109 1166 11C0; +C152;C152;1109 1166 11C1;C152;1109 1166 11C1; +C153;C153;1109 1166 11C2;C153;1109 1166 11C2; +C154;C154;1109 1167;C154;1109 1167; +C155;C155;1109 1167 11A8;C155;1109 1167 11A8; +C156;C156;1109 1167 11A9;C156;1109 1167 11A9; +C157;C157;1109 1167 11AA;C157;1109 1167 11AA; +C158;C158;1109 1167 11AB;C158;1109 1167 11AB; +C159;C159;1109 1167 11AC;C159;1109 1167 11AC; +C15A;C15A;1109 1167 11AD;C15A;1109 1167 11AD; +C15B;C15B;1109 1167 11AE;C15B;1109 1167 11AE; +C15C;C15C;1109 1167 11AF;C15C;1109 1167 11AF; +C15D;C15D;1109 1167 11B0;C15D;1109 1167 11B0; +C15E;C15E;1109 1167 11B1;C15E;1109 1167 11B1; +C15F;C15F;1109 1167 11B2;C15F;1109 1167 11B2; +C160;C160;1109 1167 11B3;C160;1109 1167 11B3; +C161;C161;1109 1167 11B4;C161;1109 1167 11B4; +C162;C162;1109 1167 11B5;C162;1109 1167 11B5; +C163;C163;1109 1167 11B6;C163;1109 1167 11B6; +C164;C164;1109 1167 11B7;C164;1109 1167 11B7; +C165;C165;1109 1167 11B8;C165;1109 1167 11B8; +C166;C166;1109 1167 11B9;C166;1109 1167 11B9; +C167;C167;1109 1167 11BA;C167;1109 1167 11BA; +C168;C168;1109 1167 11BB;C168;1109 1167 11BB; +C169;C169;1109 1167 11BC;C169;1109 1167 11BC; +C16A;C16A;1109 1167 11BD;C16A;1109 1167 11BD; +C16B;C16B;1109 1167 11BE;C16B;1109 1167 11BE; +C16C;C16C;1109 1167 11BF;C16C;1109 1167 11BF; +C16D;C16D;1109 1167 11C0;C16D;1109 1167 11C0; +C16E;C16E;1109 1167 11C1;C16E;1109 1167 11C1; +C16F;C16F;1109 1167 11C2;C16F;1109 1167 11C2; +C170;C170;1109 1168;C170;1109 1168; +C171;C171;1109 1168 11A8;C171;1109 1168 11A8; +C172;C172;1109 1168 11A9;C172;1109 1168 11A9; +C173;C173;1109 1168 11AA;C173;1109 1168 11AA; +C174;C174;1109 1168 11AB;C174;1109 1168 11AB; +C175;C175;1109 1168 11AC;C175;1109 1168 11AC; +C176;C176;1109 1168 11AD;C176;1109 1168 11AD; +C177;C177;1109 1168 11AE;C177;1109 1168 11AE; +C178;C178;1109 1168 11AF;C178;1109 1168 11AF; +C179;C179;1109 1168 11B0;C179;1109 1168 11B0; +C17A;C17A;1109 1168 11B1;C17A;1109 1168 11B1; +C17B;C17B;1109 1168 11B2;C17B;1109 1168 11B2; +C17C;C17C;1109 1168 11B3;C17C;1109 1168 11B3; +C17D;C17D;1109 1168 11B4;C17D;1109 1168 11B4; +C17E;C17E;1109 1168 11B5;C17E;1109 1168 11B5; +C17F;C17F;1109 1168 11B6;C17F;1109 1168 11B6; +C180;C180;1109 1168 11B7;C180;1109 1168 11B7; +C181;C181;1109 1168 11B8;C181;1109 1168 11B8; +C182;C182;1109 1168 11B9;C182;1109 1168 11B9; +C183;C183;1109 1168 11BA;C183;1109 1168 11BA; +C184;C184;1109 1168 11BB;C184;1109 1168 11BB; +C185;C185;1109 1168 11BC;C185;1109 1168 11BC; +C186;C186;1109 1168 11BD;C186;1109 1168 11BD; +C187;C187;1109 1168 11BE;C187;1109 1168 11BE; +C188;C188;1109 1168 11BF;C188;1109 1168 11BF; +C189;C189;1109 1168 11C0;C189;1109 1168 11C0; +C18A;C18A;1109 1168 11C1;C18A;1109 1168 11C1; +C18B;C18B;1109 1168 11C2;C18B;1109 1168 11C2; +C18C;C18C;1109 1169;C18C;1109 1169; +C18D;C18D;1109 1169 11A8;C18D;1109 1169 11A8; +C18E;C18E;1109 1169 11A9;C18E;1109 1169 11A9; +C18F;C18F;1109 1169 11AA;C18F;1109 1169 11AA; +C190;C190;1109 1169 11AB;C190;1109 1169 11AB; +C191;C191;1109 1169 11AC;C191;1109 1169 11AC; +C192;C192;1109 1169 11AD;C192;1109 1169 11AD; +C193;C193;1109 1169 11AE;C193;1109 1169 11AE; +C194;C194;1109 1169 11AF;C194;1109 1169 11AF; +C195;C195;1109 1169 11B0;C195;1109 1169 11B0; +C196;C196;1109 1169 11B1;C196;1109 1169 11B1; +C197;C197;1109 1169 11B2;C197;1109 1169 11B2; +C198;C198;1109 1169 11B3;C198;1109 1169 11B3; +C199;C199;1109 1169 11B4;C199;1109 1169 11B4; +C19A;C19A;1109 1169 11B5;C19A;1109 1169 11B5; +C19B;C19B;1109 1169 11B6;C19B;1109 1169 11B6; +C19C;C19C;1109 1169 11B7;C19C;1109 1169 11B7; +C19D;C19D;1109 1169 11B8;C19D;1109 1169 11B8; +C19E;C19E;1109 1169 11B9;C19E;1109 1169 11B9; +C19F;C19F;1109 1169 11BA;C19F;1109 1169 11BA; +C1A0;C1A0;1109 1169 11BB;C1A0;1109 1169 11BB; +C1A1;C1A1;1109 1169 11BC;C1A1;1109 1169 11BC; +C1A2;C1A2;1109 1169 11BD;C1A2;1109 1169 11BD; +C1A3;C1A3;1109 1169 11BE;C1A3;1109 1169 11BE; +C1A4;C1A4;1109 1169 11BF;C1A4;1109 1169 11BF; +C1A5;C1A5;1109 1169 11C0;C1A5;1109 1169 11C0; +C1A6;C1A6;1109 1169 11C1;C1A6;1109 1169 11C1; +C1A7;C1A7;1109 1169 11C2;C1A7;1109 1169 11C2; +C1A8;C1A8;1109 116A;C1A8;1109 116A; +C1A9;C1A9;1109 116A 11A8;C1A9;1109 116A 11A8; +C1AA;C1AA;1109 116A 11A9;C1AA;1109 116A 11A9; +C1AB;C1AB;1109 116A 11AA;C1AB;1109 116A 11AA; +C1AC;C1AC;1109 116A 11AB;C1AC;1109 116A 11AB; +C1AD;C1AD;1109 116A 11AC;C1AD;1109 116A 11AC; +C1AE;C1AE;1109 116A 11AD;C1AE;1109 116A 11AD; +C1AF;C1AF;1109 116A 11AE;C1AF;1109 116A 11AE; +C1B0;C1B0;1109 116A 11AF;C1B0;1109 116A 11AF; +C1B1;C1B1;1109 116A 11B0;C1B1;1109 116A 11B0; +C1B2;C1B2;1109 116A 11B1;C1B2;1109 116A 11B1; +C1B3;C1B3;1109 116A 11B2;C1B3;1109 116A 11B2; +C1B4;C1B4;1109 116A 11B3;C1B4;1109 116A 11B3; +C1B5;C1B5;1109 116A 11B4;C1B5;1109 116A 11B4; +C1B6;C1B6;1109 116A 11B5;C1B6;1109 116A 11B5; +C1B7;C1B7;1109 116A 11B6;C1B7;1109 116A 11B6; +C1B8;C1B8;1109 116A 11B7;C1B8;1109 116A 11B7; +C1B9;C1B9;1109 116A 11B8;C1B9;1109 116A 11B8; +C1BA;C1BA;1109 116A 11B9;C1BA;1109 116A 11B9; +C1BB;C1BB;1109 116A 11BA;C1BB;1109 116A 11BA; +C1BC;C1BC;1109 116A 11BB;C1BC;1109 116A 11BB; +C1BD;C1BD;1109 116A 11BC;C1BD;1109 116A 11BC; +C1BE;C1BE;1109 116A 11BD;C1BE;1109 116A 11BD; +C1BF;C1BF;1109 116A 11BE;C1BF;1109 116A 11BE; +C1C0;C1C0;1109 116A 11BF;C1C0;1109 116A 11BF; +C1C1;C1C1;1109 116A 11C0;C1C1;1109 116A 11C0; +C1C2;C1C2;1109 116A 11C1;C1C2;1109 116A 11C1; +C1C3;C1C3;1109 116A 11C2;C1C3;1109 116A 11C2; +C1C4;C1C4;1109 116B;C1C4;1109 116B; +C1C5;C1C5;1109 116B 11A8;C1C5;1109 116B 11A8; +C1C6;C1C6;1109 116B 11A9;C1C6;1109 116B 11A9; +C1C7;C1C7;1109 116B 11AA;C1C7;1109 116B 11AA; +C1C8;C1C8;1109 116B 11AB;C1C8;1109 116B 11AB; +C1C9;C1C9;1109 116B 11AC;C1C9;1109 116B 11AC; +C1CA;C1CA;1109 116B 11AD;C1CA;1109 116B 11AD; +C1CB;C1CB;1109 116B 11AE;C1CB;1109 116B 11AE; +C1CC;C1CC;1109 116B 11AF;C1CC;1109 116B 11AF; +C1CD;C1CD;1109 116B 11B0;C1CD;1109 116B 11B0; +C1CE;C1CE;1109 116B 11B1;C1CE;1109 116B 11B1; +C1CF;C1CF;1109 116B 11B2;C1CF;1109 116B 11B2; +C1D0;C1D0;1109 116B 11B3;C1D0;1109 116B 11B3; +C1D1;C1D1;1109 116B 11B4;C1D1;1109 116B 11B4; +C1D2;C1D2;1109 116B 11B5;C1D2;1109 116B 11B5; +C1D3;C1D3;1109 116B 11B6;C1D3;1109 116B 11B6; +C1D4;C1D4;1109 116B 11B7;C1D4;1109 116B 11B7; +C1D5;C1D5;1109 116B 11B8;C1D5;1109 116B 11B8; +C1D6;C1D6;1109 116B 11B9;C1D6;1109 116B 11B9; +C1D7;C1D7;1109 116B 11BA;C1D7;1109 116B 11BA; +C1D8;C1D8;1109 116B 11BB;C1D8;1109 116B 11BB; +C1D9;C1D9;1109 116B 11BC;C1D9;1109 116B 11BC; +C1DA;C1DA;1109 116B 11BD;C1DA;1109 116B 11BD; +C1DB;C1DB;1109 116B 11BE;C1DB;1109 116B 11BE; +C1DC;C1DC;1109 116B 11BF;C1DC;1109 116B 11BF; +C1DD;C1DD;1109 116B 11C0;C1DD;1109 116B 11C0; +C1DE;C1DE;1109 116B 11C1;C1DE;1109 116B 11C1; +C1DF;C1DF;1109 116B 11C2;C1DF;1109 116B 11C2; +C1E0;C1E0;1109 116C;C1E0;1109 116C; +C1E1;C1E1;1109 116C 11A8;C1E1;1109 116C 11A8; +C1E2;C1E2;1109 116C 11A9;C1E2;1109 116C 11A9; +C1E3;C1E3;1109 116C 11AA;C1E3;1109 116C 11AA; +C1E4;C1E4;1109 116C 11AB;C1E4;1109 116C 11AB; +C1E5;C1E5;1109 116C 11AC;C1E5;1109 116C 11AC; +C1E6;C1E6;1109 116C 11AD;C1E6;1109 116C 11AD; +C1E7;C1E7;1109 116C 11AE;C1E7;1109 116C 11AE; +C1E8;C1E8;1109 116C 11AF;C1E8;1109 116C 11AF; +C1E9;C1E9;1109 116C 11B0;C1E9;1109 116C 11B0; +C1EA;C1EA;1109 116C 11B1;C1EA;1109 116C 11B1; +C1EB;C1EB;1109 116C 11B2;C1EB;1109 116C 11B2; +C1EC;C1EC;1109 116C 11B3;C1EC;1109 116C 11B3; +C1ED;C1ED;1109 116C 11B4;C1ED;1109 116C 11B4; +C1EE;C1EE;1109 116C 11B5;C1EE;1109 116C 11B5; +C1EF;C1EF;1109 116C 11B6;C1EF;1109 116C 11B6; +C1F0;C1F0;1109 116C 11B7;C1F0;1109 116C 11B7; +C1F1;C1F1;1109 116C 11B8;C1F1;1109 116C 11B8; +C1F2;C1F2;1109 116C 11B9;C1F2;1109 116C 11B9; +C1F3;C1F3;1109 116C 11BA;C1F3;1109 116C 11BA; +C1F4;C1F4;1109 116C 11BB;C1F4;1109 116C 11BB; +C1F5;C1F5;1109 116C 11BC;C1F5;1109 116C 11BC; +C1F6;C1F6;1109 116C 11BD;C1F6;1109 116C 11BD; +C1F7;C1F7;1109 116C 11BE;C1F7;1109 116C 11BE; +C1F8;C1F8;1109 116C 11BF;C1F8;1109 116C 11BF; +C1F9;C1F9;1109 116C 11C0;C1F9;1109 116C 11C0; +C1FA;C1FA;1109 116C 11C1;C1FA;1109 116C 11C1; +C1FB;C1FB;1109 116C 11C2;C1FB;1109 116C 11C2; +C1FC;C1FC;1109 116D;C1FC;1109 116D; +C1FD;C1FD;1109 116D 11A8;C1FD;1109 116D 11A8; +C1FE;C1FE;1109 116D 11A9;C1FE;1109 116D 11A9; +C1FF;C1FF;1109 116D 11AA;C1FF;1109 116D 11AA; +C200;C200;1109 116D 11AB;C200;1109 116D 11AB; +C201;C201;1109 116D 11AC;C201;1109 116D 11AC; +C202;C202;1109 116D 11AD;C202;1109 116D 11AD; +C203;C203;1109 116D 11AE;C203;1109 116D 11AE; +C204;C204;1109 116D 11AF;C204;1109 116D 11AF; +C205;C205;1109 116D 11B0;C205;1109 116D 11B0; +C206;C206;1109 116D 11B1;C206;1109 116D 11B1; +C207;C207;1109 116D 11B2;C207;1109 116D 11B2; +C208;C208;1109 116D 11B3;C208;1109 116D 11B3; +C209;C209;1109 116D 11B4;C209;1109 116D 11B4; +C20A;C20A;1109 116D 11B5;C20A;1109 116D 11B5; +C20B;C20B;1109 116D 11B6;C20B;1109 116D 11B6; +C20C;C20C;1109 116D 11B7;C20C;1109 116D 11B7; +C20D;C20D;1109 116D 11B8;C20D;1109 116D 11B8; +C20E;C20E;1109 116D 11B9;C20E;1109 116D 11B9; +C20F;C20F;1109 116D 11BA;C20F;1109 116D 11BA; +C210;C210;1109 116D 11BB;C210;1109 116D 11BB; +C211;C211;1109 116D 11BC;C211;1109 116D 11BC; +C212;C212;1109 116D 11BD;C212;1109 116D 11BD; +C213;C213;1109 116D 11BE;C213;1109 116D 11BE; +C214;C214;1109 116D 11BF;C214;1109 116D 11BF; +C215;C215;1109 116D 11C0;C215;1109 116D 11C0; +C216;C216;1109 116D 11C1;C216;1109 116D 11C1; +C217;C217;1109 116D 11C2;C217;1109 116D 11C2; +C218;C218;1109 116E;C218;1109 116E; +C219;C219;1109 116E 11A8;C219;1109 116E 11A8; +C21A;C21A;1109 116E 11A9;C21A;1109 116E 11A9; +C21B;C21B;1109 116E 11AA;C21B;1109 116E 11AA; +C21C;C21C;1109 116E 11AB;C21C;1109 116E 11AB; +C21D;C21D;1109 116E 11AC;C21D;1109 116E 11AC; +C21E;C21E;1109 116E 11AD;C21E;1109 116E 11AD; +C21F;C21F;1109 116E 11AE;C21F;1109 116E 11AE; +C220;C220;1109 116E 11AF;C220;1109 116E 11AF; +C221;C221;1109 116E 11B0;C221;1109 116E 11B0; +C222;C222;1109 116E 11B1;C222;1109 116E 11B1; +C223;C223;1109 116E 11B2;C223;1109 116E 11B2; +C224;C224;1109 116E 11B3;C224;1109 116E 11B3; +C225;C225;1109 116E 11B4;C225;1109 116E 11B4; +C226;C226;1109 116E 11B5;C226;1109 116E 11B5; +C227;C227;1109 116E 11B6;C227;1109 116E 11B6; +C228;C228;1109 116E 11B7;C228;1109 116E 11B7; +C229;C229;1109 116E 11B8;C229;1109 116E 11B8; +C22A;C22A;1109 116E 11B9;C22A;1109 116E 11B9; +C22B;C22B;1109 116E 11BA;C22B;1109 116E 11BA; +C22C;C22C;1109 116E 11BB;C22C;1109 116E 11BB; +C22D;C22D;1109 116E 11BC;C22D;1109 116E 11BC; +C22E;C22E;1109 116E 11BD;C22E;1109 116E 11BD; +C22F;C22F;1109 116E 11BE;C22F;1109 116E 11BE; +C230;C230;1109 116E 11BF;C230;1109 116E 11BF; +C231;C231;1109 116E 11C0;C231;1109 116E 11C0; +C232;C232;1109 116E 11C1;C232;1109 116E 11C1; +C233;C233;1109 116E 11C2;C233;1109 116E 11C2; +C234;C234;1109 116F;C234;1109 116F; +C235;C235;1109 116F 11A8;C235;1109 116F 11A8; +C236;C236;1109 116F 11A9;C236;1109 116F 11A9; +C237;C237;1109 116F 11AA;C237;1109 116F 11AA; +C238;C238;1109 116F 11AB;C238;1109 116F 11AB; +C239;C239;1109 116F 11AC;C239;1109 116F 11AC; +C23A;C23A;1109 116F 11AD;C23A;1109 116F 11AD; +C23B;C23B;1109 116F 11AE;C23B;1109 116F 11AE; +C23C;C23C;1109 116F 11AF;C23C;1109 116F 11AF; +C23D;C23D;1109 116F 11B0;C23D;1109 116F 11B0; +C23E;C23E;1109 116F 11B1;C23E;1109 116F 11B1; +C23F;C23F;1109 116F 11B2;C23F;1109 116F 11B2; +C240;C240;1109 116F 11B3;C240;1109 116F 11B3; +C241;C241;1109 116F 11B4;C241;1109 116F 11B4; +C242;C242;1109 116F 11B5;C242;1109 116F 11B5; +C243;C243;1109 116F 11B6;C243;1109 116F 11B6; +C244;C244;1109 116F 11B7;C244;1109 116F 11B7; +C245;C245;1109 116F 11B8;C245;1109 116F 11B8; +C246;C246;1109 116F 11B9;C246;1109 116F 11B9; +C247;C247;1109 116F 11BA;C247;1109 116F 11BA; +C248;C248;1109 116F 11BB;C248;1109 116F 11BB; +C249;C249;1109 116F 11BC;C249;1109 116F 11BC; +C24A;C24A;1109 116F 11BD;C24A;1109 116F 11BD; +C24B;C24B;1109 116F 11BE;C24B;1109 116F 11BE; +C24C;C24C;1109 116F 11BF;C24C;1109 116F 11BF; +C24D;C24D;1109 116F 11C0;C24D;1109 116F 11C0; +C24E;C24E;1109 116F 11C1;C24E;1109 116F 11C1; +C24F;C24F;1109 116F 11C2;C24F;1109 116F 11C2; +C250;C250;1109 1170;C250;1109 1170; +C251;C251;1109 1170 11A8;C251;1109 1170 11A8; +C252;C252;1109 1170 11A9;C252;1109 1170 11A9; +C253;C253;1109 1170 11AA;C253;1109 1170 11AA; +C254;C254;1109 1170 11AB;C254;1109 1170 11AB; +C255;C255;1109 1170 11AC;C255;1109 1170 11AC; +C256;C256;1109 1170 11AD;C256;1109 1170 11AD; +C257;C257;1109 1170 11AE;C257;1109 1170 11AE; +C258;C258;1109 1170 11AF;C258;1109 1170 11AF; +C259;C259;1109 1170 11B0;C259;1109 1170 11B0; +C25A;C25A;1109 1170 11B1;C25A;1109 1170 11B1; +C25B;C25B;1109 1170 11B2;C25B;1109 1170 11B2; +C25C;C25C;1109 1170 11B3;C25C;1109 1170 11B3; +C25D;C25D;1109 1170 11B4;C25D;1109 1170 11B4; +C25E;C25E;1109 1170 11B5;C25E;1109 1170 11B5; +C25F;C25F;1109 1170 11B6;C25F;1109 1170 11B6; +C260;C260;1109 1170 11B7;C260;1109 1170 11B7; +C261;C261;1109 1170 11B8;C261;1109 1170 11B8; +C262;C262;1109 1170 11B9;C262;1109 1170 11B9; +C263;C263;1109 1170 11BA;C263;1109 1170 11BA; +C264;C264;1109 1170 11BB;C264;1109 1170 11BB; +C265;C265;1109 1170 11BC;C265;1109 1170 11BC; +C266;C266;1109 1170 11BD;C266;1109 1170 11BD; +C267;C267;1109 1170 11BE;C267;1109 1170 11BE; +C268;C268;1109 1170 11BF;C268;1109 1170 11BF; +C269;C269;1109 1170 11C0;C269;1109 1170 11C0; +C26A;C26A;1109 1170 11C1;C26A;1109 1170 11C1; +C26B;C26B;1109 1170 11C2;C26B;1109 1170 11C2; +C26C;C26C;1109 1171;C26C;1109 1171; +C26D;C26D;1109 1171 11A8;C26D;1109 1171 11A8; +C26E;C26E;1109 1171 11A9;C26E;1109 1171 11A9; +C26F;C26F;1109 1171 11AA;C26F;1109 1171 11AA; +C270;C270;1109 1171 11AB;C270;1109 1171 11AB; +C271;C271;1109 1171 11AC;C271;1109 1171 11AC; +C272;C272;1109 1171 11AD;C272;1109 1171 11AD; +C273;C273;1109 1171 11AE;C273;1109 1171 11AE; +C274;C274;1109 1171 11AF;C274;1109 1171 11AF; +C275;C275;1109 1171 11B0;C275;1109 1171 11B0; +C276;C276;1109 1171 11B1;C276;1109 1171 11B1; +C277;C277;1109 1171 11B2;C277;1109 1171 11B2; +C278;C278;1109 1171 11B3;C278;1109 1171 11B3; +C279;C279;1109 1171 11B4;C279;1109 1171 11B4; +C27A;C27A;1109 1171 11B5;C27A;1109 1171 11B5; +C27B;C27B;1109 1171 11B6;C27B;1109 1171 11B6; +C27C;C27C;1109 1171 11B7;C27C;1109 1171 11B7; +C27D;C27D;1109 1171 11B8;C27D;1109 1171 11B8; +C27E;C27E;1109 1171 11B9;C27E;1109 1171 11B9; +C27F;C27F;1109 1171 11BA;C27F;1109 1171 11BA; +C280;C280;1109 1171 11BB;C280;1109 1171 11BB; +C281;C281;1109 1171 11BC;C281;1109 1171 11BC; +C282;C282;1109 1171 11BD;C282;1109 1171 11BD; +C283;C283;1109 1171 11BE;C283;1109 1171 11BE; +C284;C284;1109 1171 11BF;C284;1109 1171 11BF; +C285;C285;1109 1171 11C0;C285;1109 1171 11C0; +C286;C286;1109 1171 11C1;C286;1109 1171 11C1; +C287;C287;1109 1171 11C2;C287;1109 1171 11C2; +C288;C288;1109 1172;C288;1109 1172; +C289;C289;1109 1172 11A8;C289;1109 1172 11A8; +C28A;C28A;1109 1172 11A9;C28A;1109 1172 11A9; +C28B;C28B;1109 1172 11AA;C28B;1109 1172 11AA; +C28C;C28C;1109 1172 11AB;C28C;1109 1172 11AB; +C28D;C28D;1109 1172 11AC;C28D;1109 1172 11AC; +C28E;C28E;1109 1172 11AD;C28E;1109 1172 11AD; +C28F;C28F;1109 1172 11AE;C28F;1109 1172 11AE; +C290;C290;1109 1172 11AF;C290;1109 1172 11AF; +C291;C291;1109 1172 11B0;C291;1109 1172 11B0; +C292;C292;1109 1172 11B1;C292;1109 1172 11B1; +C293;C293;1109 1172 11B2;C293;1109 1172 11B2; +C294;C294;1109 1172 11B3;C294;1109 1172 11B3; +C295;C295;1109 1172 11B4;C295;1109 1172 11B4; +C296;C296;1109 1172 11B5;C296;1109 1172 11B5; +C297;C297;1109 1172 11B6;C297;1109 1172 11B6; +C298;C298;1109 1172 11B7;C298;1109 1172 11B7; +C299;C299;1109 1172 11B8;C299;1109 1172 11B8; +C29A;C29A;1109 1172 11B9;C29A;1109 1172 11B9; +C29B;C29B;1109 1172 11BA;C29B;1109 1172 11BA; +C29C;C29C;1109 1172 11BB;C29C;1109 1172 11BB; +C29D;C29D;1109 1172 11BC;C29D;1109 1172 11BC; +C29E;C29E;1109 1172 11BD;C29E;1109 1172 11BD; +C29F;C29F;1109 1172 11BE;C29F;1109 1172 11BE; +C2A0;C2A0;1109 1172 11BF;C2A0;1109 1172 11BF; +C2A1;C2A1;1109 1172 11C0;C2A1;1109 1172 11C0; +C2A2;C2A2;1109 1172 11C1;C2A2;1109 1172 11C1; +C2A3;C2A3;1109 1172 11C2;C2A3;1109 1172 11C2; +C2A4;C2A4;1109 1173;C2A4;1109 1173; +C2A5;C2A5;1109 1173 11A8;C2A5;1109 1173 11A8; +C2A6;C2A6;1109 1173 11A9;C2A6;1109 1173 11A9; +C2A7;C2A7;1109 1173 11AA;C2A7;1109 1173 11AA; +C2A8;C2A8;1109 1173 11AB;C2A8;1109 1173 11AB; +C2A9;C2A9;1109 1173 11AC;C2A9;1109 1173 11AC; +C2AA;C2AA;1109 1173 11AD;C2AA;1109 1173 11AD; +C2AB;C2AB;1109 1173 11AE;C2AB;1109 1173 11AE; +C2AC;C2AC;1109 1173 11AF;C2AC;1109 1173 11AF; +C2AD;C2AD;1109 1173 11B0;C2AD;1109 1173 11B0; +C2AE;C2AE;1109 1173 11B1;C2AE;1109 1173 11B1; +C2AF;C2AF;1109 1173 11B2;C2AF;1109 1173 11B2; +C2B0;C2B0;1109 1173 11B3;C2B0;1109 1173 11B3; +C2B1;C2B1;1109 1173 11B4;C2B1;1109 1173 11B4; +C2B2;C2B2;1109 1173 11B5;C2B2;1109 1173 11B5; +C2B3;C2B3;1109 1173 11B6;C2B3;1109 1173 11B6; +C2B4;C2B4;1109 1173 11B7;C2B4;1109 1173 11B7; +C2B5;C2B5;1109 1173 11B8;C2B5;1109 1173 11B8; +C2B6;C2B6;1109 1173 11B9;C2B6;1109 1173 11B9; +C2B7;C2B7;1109 1173 11BA;C2B7;1109 1173 11BA; +C2B8;C2B8;1109 1173 11BB;C2B8;1109 1173 11BB; +C2B9;C2B9;1109 1173 11BC;C2B9;1109 1173 11BC; +C2BA;C2BA;1109 1173 11BD;C2BA;1109 1173 11BD; +C2BB;C2BB;1109 1173 11BE;C2BB;1109 1173 11BE; +C2BC;C2BC;1109 1173 11BF;C2BC;1109 1173 11BF; +C2BD;C2BD;1109 1173 11C0;C2BD;1109 1173 11C0; +C2BE;C2BE;1109 1173 11C1;C2BE;1109 1173 11C1; +C2BF;C2BF;1109 1173 11C2;C2BF;1109 1173 11C2; +C2C0;C2C0;1109 1174;C2C0;1109 1174; +C2C1;C2C1;1109 1174 11A8;C2C1;1109 1174 11A8; +C2C2;C2C2;1109 1174 11A9;C2C2;1109 1174 11A9; +C2C3;C2C3;1109 1174 11AA;C2C3;1109 1174 11AA; +C2C4;C2C4;1109 1174 11AB;C2C4;1109 1174 11AB; +C2C5;C2C5;1109 1174 11AC;C2C5;1109 1174 11AC; +C2C6;C2C6;1109 1174 11AD;C2C6;1109 1174 11AD; +C2C7;C2C7;1109 1174 11AE;C2C7;1109 1174 11AE; +C2C8;C2C8;1109 1174 11AF;C2C8;1109 1174 11AF; +C2C9;C2C9;1109 1174 11B0;C2C9;1109 1174 11B0; +C2CA;C2CA;1109 1174 11B1;C2CA;1109 1174 11B1; +C2CB;C2CB;1109 1174 11B2;C2CB;1109 1174 11B2; +C2CC;C2CC;1109 1174 11B3;C2CC;1109 1174 11B3; +C2CD;C2CD;1109 1174 11B4;C2CD;1109 1174 11B4; +C2CE;C2CE;1109 1174 11B5;C2CE;1109 1174 11B5; +C2CF;C2CF;1109 1174 11B6;C2CF;1109 1174 11B6; +C2D0;C2D0;1109 1174 11B7;C2D0;1109 1174 11B7; +C2D1;C2D1;1109 1174 11B8;C2D1;1109 1174 11B8; +C2D2;C2D2;1109 1174 11B9;C2D2;1109 1174 11B9; +C2D3;C2D3;1109 1174 11BA;C2D3;1109 1174 11BA; +C2D4;C2D4;1109 1174 11BB;C2D4;1109 1174 11BB; +C2D5;C2D5;1109 1174 11BC;C2D5;1109 1174 11BC; +C2D6;C2D6;1109 1174 11BD;C2D6;1109 1174 11BD; +C2D7;C2D7;1109 1174 11BE;C2D7;1109 1174 11BE; +C2D8;C2D8;1109 1174 11BF;C2D8;1109 1174 11BF; +C2D9;C2D9;1109 1174 11C0;C2D9;1109 1174 11C0; +C2DA;C2DA;1109 1174 11C1;C2DA;1109 1174 11C1; +C2DB;C2DB;1109 1174 11C2;C2DB;1109 1174 11C2; +C2DC;C2DC;1109 1175;C2DC;1109 1175; +C2DD;C2DD;1109 1175 11A8;C2DD;1109 1175 11A8; +C2DE;C2DE;1109 1175 11A9;C2DE;1109 1175 11A9; +C2DF;C2DF;1109 1175 11AA;C2DF;1109 1175 11AA; +C2E0;C2E0;1109 1175 11AB;C2E0;1109 1175 11AB; +C2E1;C2E1;1109 1175 11AC;C2E1;1109 1175 11AC; +C2E2;C2E2;1109 1175 11AD;C2E2;1109 1175 11AD; +C2E3;C2E3;1109 1175 11AE;C2E3;1109 1175 11AE; +C2E4;C2E4;1109 1175 11AF;C2E4;1109 1175 11AF; +C2E5;C2E5;1109 1175 11B0;C2E5;1109 1175 11B0; +C2E6;C2E6;1109 1175 11B1;C2E6;1109 1175 11B1; +C2E7;C2E7;1109 1175 11B2;C2E7;1109 1175 11B2; +C2E8;C2E8;1109 1175 11B3;C2E8;1109 1175 11B3; +C2E9;C2E9;1109 1175 11B4;C2E9;1109 1175 11B4; +C2EA;C2EA;1109 1175 11B5;C2EA;1109 1175 11B5; +C2EB;C2EB;1109 1175 11B6;C2EB;1109 1175 11B6; +C2EC;C2EC;1109 1175 11B7;C2EC;1109 1175 11B7; +C2ED;C2ED;1109 1175 11B8;C2ED;1109 1175 11B8; +C2EE;C2EE;1109 1175 11B9;C2EE;1109 1175 11B9; +C2EF;C2EF;1109 1175 11BA;C2EF;1109 1175 11BA; +C2F0;C2F0;1109 1175 11BB;C2F0;1109 1175 11BB; +C2F1;C2F1;1109 1175 11BC;C2F1;1109 1175 11BC; +C2F2;C2F2;1109 1175 11BD;C2F2;1109 1175 11BD; +C2F3;C2F3;1109 1175 11BE;C2F3;1109 1175 11BE; +C2F4;C2F4;1109 1175 11BF;C2F4;1109 1175 11BF; +C2F5;C2F5;1109 1175 11C0;C2F5;1109 1175 11C0; +C2F6;C2F6;1109 1175 11C1;C2F6;1109 1175 11C1; +C2F7;C2F7;1109 1175 11C2;C2F7;1109 1175 11C2; +C2F8;C2F8;110A 1161;C2F8;110A 1161; +C2F9;C2F9;110A 1161 11A8;C2F9;110A 1161 11A8; +C2FA;C2FA;110A 1161 11A9;C2FA;110A 1161 11A9; +C2FB;C2FB;110A 1161 11AA;C2FB;110A 1161 11AA; +C2FC;C2FC;110A 1161 11AB;C2FC;110A 1161 11AB; +C2FD;C2FD;110A 1161 11AC;C2FD;110A 1161 11AC; +C2FE;C2FE;110A 1161 11AD;C2FE;110A 1161 11AD; +C2FF;C2FF;110A 1161 11AE;C2FF;110A 1161 11AE; +C300;C300;110A 1161 11AF;C300;110A 1161 11AF; +C301;C301;110A 1161 11B0;C301;110A 1161 11B0; +C302;C302;110A 1161 11B1;C302;110A 1161 11B1; +C303;C303;110A 1161 11B2;C303;110A 1161 11B2; +C304;C304;110A 1161 11B3;C304;110A 1161 11B3; +C305;C305;110A 1161 11B4;C305;110A 1161 11B4; +C306;C306;110A 1161 11B5;C306;110A 1161 11B5; +C307;C307;110A 1161 11B6;C307;110A 1161 11B6; +C308;C308;110A 1161 11B7;C308;110A 1161 11B7; +C309;C309;110A 1161 11B8;C309;110A 1161 11B8; +C30A;C30A;110A 1161 11B9;C30A;110A 1161 11B9; +C30B;C30B;110A 1161 11BA;C30B;110A 1161 11BA; +C30C;C30C;110A 1161 11BB;C30C;110A 1161 11BB; +C30D;C30D;110A 1161 11BC;C30D;110A 1161 11BC; +C30E;C30E;110A 1161 11BD;C30E;110A 1161 11BD; +C30F;C30F;110A 1161 11BE;C30F;110A 1161 11BE; +C310;C310;110A 1161 11BF;C310;110A 1161 11BF; +C311;C311;110A 1161 11C0;C311;110A 1161 11C0; +C312;C312;110A 1161 11C1;C312;110A 1161 11C1; +C313;C313;110A 1161 11C2;C313;110A 1161 11C2; +C314;C314;110A 1162;C314;110A 1162; +C315;C315;110A 1162 11A8;C315;110A 1162 11A8; +C316;C316;110A 1162 11A9;C316;110A 1162 11A9; +C317;C317;110A 1162 11AA;C317;110A 1162 11AA; +C318;C318;110A 1162 11AB;C318;110A 1162 11AB; +C319;C319;110A 1162 11AC;C319;110A 1162 11AC; +C31A;C31A;110A 1162 11AD;C31A;110A 1162 11AD; +C31B;C31B;110A 1162 11AE;C31B;110A 1162 11AE; +C31C;C31C;110A 1162 11AF;C31C;110A 1162 11AF; +C31D;C31D;110A 1162 11B0;C31D;110A 1162 11B0; +C31E;C31E;110A 1162 11B1;C31E;110A 1162 11B1; +C31F;C31F;110A 1162 11B2;C31F;110A 1162 11B2; +C320;C320;110A 1162 11B3;C320;110A 1162 11B3; +C321;C321;110A 1162 11B4;C321;110A 1162 11B4; +C322;C322;110A 1162 11B5;C322;110A 1162 11B5; +C323;C323;110A 1162 11B6;C323;110A 1162 11B6; +C324;C324;110A 1162 11B7;C324;110A 1162 11B7; +C325;C325;110A 1162 11B8;C325;110A 1162 11B8; +C326;C326;110A 1162 11B9;C326;110A 1162 11B9; +C327;C327;110A 1162 11BA;C327;110A 1162 11BA; +C328;C328;110A 1162 11BB;C328;110A 1162 11BB; +C329;C329;110A 1162 11BC;C329;110A 1162 11BC; +C32A;C32A;110A 1162 11BD;C32A;110A 1162 11BD; +C32B;C32B;110A 1162 11BE;C32B;110A 1162 11BE; +C32C;C32C;110A 1162 11BF;C32C;110A 1162 11BF; +C32D;C32D;110A 1162 11C0;C32D;110A 1162 11C0; +C32E;C32E;110A 1162 11C1;C32E;110A 1162 11C1; +C32F;C32F;110A 1162 11C2;C32F;110A 1162 11C2; +C330;C330;110A 1163;C330;110A 1163; +C331;C331;110A 1163 11A8;C331;110A 1163 11A8; +C332;C332;110A 1163 11A9;C332;110A 1163 11A9; +C333;C333;110A 1163 11AA;C333;110A 1163 11AA; +C334;C334;110A 1163 11AB;C334;110A 1163 11AB; +C335;C335;110A 1163 11AC;C335;110A 1163 11AC; +C336;C336;110A 1163 11AD;C336;110A 1163 11AD; +C337;C337;110A 1163 11AE;C337;110A 1163 11AE; +C338;C338;110A 1163 11AF;C338;110A 1163 11AF; +C339;C339;110A 1163 11B0;C339;110A 1163 11B0; +C33A;C33A;110A 1163 11B1;C33A;110A 1163 11B1; +C33B;C33B;110A 1163 11B2;C33B;110A 1163 11B2; +C33C;C33C;110A 1163 11B3;C33C;110A 1163 11B3; +C33D;C33D;110A 1163 11B4;C33D;110A 1163 11B4; +C33E;C33E;110A 1163 11B5;C33E;110A 1163 11B5; +C33F;C33F;110A 1163 11B6;C33F;110A 1163 11B6; +C340;C340;110A 1163 11B7;C340;110A 1163 11B7; +C341;C341;110A 1163 11B8;C341;110A 1163 11B8; +C342;C342;110A 1163 11B9;C342;110A 1163 11B9; +C343;C343;110A 1163 11BA;C343;110A 1163 11BA; +C344;C344;110A 1163 11BB;C344;110A 1163 11BB; +C345;C345;110A 1163 11BC;C345;110A 1163 11BC; +C346;C346;110A 1163 11BD;C346;110A 1163 11BD; +C347;C347;110A 1163 11BE;C347;110A 1163 11BE; +C348;C348;110A 1163 11BF;C348;110A 1163 11BF; +C349;C349;110A 1163 11C0;C349;110A 1163 11C0; +C34A;C34A;110A 1163 11C1;C34A;110A 1163 11C1; +C34B;C34B;110A 1163 11C2;C34B;110A 1163 11C2; +C34C;C34C;110A 1164;C34C;110A 1164; +C34D;C34D;110A 1164 11A8;C34D;110A 1164 11A8; +C34E;C34E;110A 1164 11A9;C34E;110A 1164 11A9; +C34F;C34F;110A 1164 11AA;C34F;110A 1164 11AA; +C350;C350;110A 1164 11AB;C350;110A 1164 11AB; +C351;C351;110A 1164 11AC;C351;110A 1164 11AC; +C352;C352;110A 1164 11AD;C352;110A 1164 11AD; +C353;C353;110A 1164 11AE;C353;110A 1164 11AE; +C354;C354;110A 1164 11AF;C354;110A 1164 11AF; +C355;C355;110A 1164 11B0;C355;110A 1164 11B0; +C356;C356;110A 1164 11B1;C356;110A 1164 11B1; +C357;C357;110A 1164 11B2;C357;110A 1164 11B2; +C358;C358;110A 1164 11B3;C358;110A 1164 11B3; +C359;C359;110A 1164 11B4;C359;110A 1164 11B4; +C35A;C35A;110A 1164 11B5;C35A;110A 1164 11B5; +C35B;C35B;110A 1164 11B6;C35B;110A 1164 11B6; +C35C;C35C;110A 1164 11B7;C35C;110A 1164 11B7; +C35D;C35D;110A 1164 11B8;C35D;110A 1164 11B8; +C35E;C35E;110A 1164 11B9;C35E;110A 1164 11B9; +C35F;C35F;110A 1164 11BA;C35F;110A 1164 11BA; +C360;C360;110A 1164 11BB;C360;110A 1164 11BB; +C361;C361;110A 1164 11BC;C361;110A 1164 11BC; +C362;C362;110A 1164 11BD;C362;110A 1164 11BD; +C363;C363;110A 1164 11BE;C363;110A 1164 11BE; +C364;C364;110A 1164 11BF;C364;110A 1164 11BF; +C365;C365;110A 1164 11C0;C365;110A 1164 11C0; +C366;C366;110A 1164 11C1;C366;110A 1164 11C1; +C367;C367;110A 1164 11C2;C367;110A 1164 11C2; +C368;C368;110A 1165;C368;110A 1165; +C369;C369;110A 1165 11A8;C369;110A 1165 11A8; +C36A;C36A;110A 1165 11A9;C36A;110A 1165 11A9; +C36B;C36B;110A 1165 11AA;C36B;110A 1165 11AA; +C36C;C36C;110A 1165 11AB;C36C;110A 1165 11AB; +C36D;C36D;110A 1165 11AC;C36D;110A 1165 11AC; +C36E;C36E;110A 1165 11AD;C36E;110A 1165 11AD; +C36F;C36F;110A 1165 11AE;C36F;110A 1165 11AE; +C370;C370;110A 1165 11AF;C370;110A 1165 11AF; +C371;C371;110A 1165 11B0;C371;110A 1165 11B0; +C372;C372;110A 1165 11B1;C372;110A 1165 11B1; +C373;C373;110A 1165 11B2;C373;110A 1165 11B2; +C374;C374;110A 1165 11B3;C374;110A 1165 11B3; +C375;C375;110A 1165 11B4;C375;110A 1165 11B4; +C376;C376;110A 1165 11B5;C376;110A 1165 11B5; +C377;C377;110A 1165 11B6;C377;110A 1165 11B6; +C378;C378;110A 1165 11B7;C378;110A 1165 11B7; +C379;C379;110A 1165 11B8;C379;110A 1165 11B8; +C37A;C37A;110A 1165 11B9;C37A;110A 1165 11B9; +C37B;C37B;110A 1165 11BA;C37B;110A 1165 11BA; +C37C;C37C;110A 1165 11BB;C37C;110A 1165 11BB; +C37D;C37D;110A 1165 11BC;C37D;110A 1165 11BC; +C37E;C37E;110A 1165 11BD;C37E;110A 1165 11BD; +C37F;C37F;110A 1165 11BE;C37F;110A 1165 11BE; +C380;C380;110A 1165 11BF;C380;110A 1165 11BF; +C381;C381;110A 1165 11C0;C381;110A 1165 11C0; +C382;C382;110A 1165 11C1;C382;110A 1165 11C1; +C383;C383;110A 1165 11C2;C383;110A 1165 11C2; +C384;C384;110A 1166;C384;110A 1166; +C385;C385;110A 1166 11A8;C385;110A 1166 11A8; +C386;C386;110A 1166 11A9;C386;110A 1166 11A9; +C387;C387;110A 1166 11AA;C387;110A 1166 11AA; +C388;C388;110A 1166 11AB;C388;110A 1166 11AB; +C389;C389;110A 1166 11AC;C389;110A 1166 11AC; +C38A;C38A;110A 1166 11AD;C38A;110A 1166 11AD; +C38B;C38B;110A 1166 11AE;C38B;110A 1166 11AE; +C38C;C38C;110A 1166 11AF;C38C;110A 1166 11AF; +C38D;C38D;110A 1166 11B0;C38D;110A 1166 11B0; +C38E;C38E;110A 1166 11B1;C38E;110A 1166 11B1; +C38F;C38F;110A 1166 11B2;C38F;110A 1166 11B2; +C390;C390;110A 1166 11B3;C390;110A 1166 11B3; +C391;C391;110A 1166 11B4;C391;110A 1166 11B4; +C392;C392;110A 1166 11B5;C392;110A 1166 11B5; +C393;C393;110A 1166 11B6;C393;110A 1166 11B6; +C394;C394;110A 1166 11B7;C394;110A 1166 11B7; +C395;C395;110A 1166 11B8;C395;110A 1166 11B8; +C396;C396;110A 1166 11B9;C396;110A 1166 11B9; +C397;C397;110A 1166 11BA;C397;110A 1166 11BA; +C398;C398;110A 1166 11BB;C398;110A 1166 11BB; +C399;C399;110A 1166 11BC;C399;110A 1166 11BC; +C39A;C39A;110A 1166 11BD;C39A;110A 1166 11BD; +C39B;C39B;110A 1166 11BE;C39B;110A 1166 11BE; +C39C;C39C;110A 1166 11BF;C39C;110A 1166 11BF; +C39D;C39D;110A 1166 11C0;C39D;110A 1166 11C0; +C39E;C39E;110A 1166 11C1;C39E;110A 1166 11C1; +C39F;C39F;110A 1166 11C2;C39F;110A 1166 11C2; +C3A0;C3A0;110A 1167;C3A0;110A 1167; +C3A1;C3A1;110A 1167 11A8;C3A1;110A 1167 11A8; +C3A2;C3A2;110A 1167 11A9;C3A2;110A 1167 11A9; +C3A3;C3A3;110A 1167 11AA;C3A3;110A 1167 11AA; +C3A4;C3A4;110A 1167 11AB;C3A4;110A 1167 11AB; +C3A5;C3A5;110A 1167 11AC;C3A5;110A 1167 11AC; +C3A6;C3A6;110A 1167 11AD;C3A6;110A 1167 11AD; +C3A7;C3A7;110A 1167 11AE;C3A7;110A 1167 11AE; +C3A8;C3A8;110A 1167 11AF;C3A8;110A 1167 11AF; +C3A9;C3A9;110A 1167 11B0;C3A9;110A 1167 11B0; +C3AA;C3AA;110A 1167 11B1;C3AA;110A 1167 11B1; +C3AB;C3AB;110A 1167 11B2;C3AB;110A 1167 11B2; +C3AC;C3AC;110A 1167 11B3;C3AC;110A 1167 11B3; +C3AD;C3AD;110A 1167 11B4;C3AD;110A 1167 11B4; +C3AE;C3AE;110A 1167 11B5;C3AE;110A 1167 11B5; +C3AF;C3AF;110A 1167 11B6;C3AF;110A 1167 11B6; +C3B0;C3B0;110A 1167 11B7;C3B0;110A 1167 11B7; +C3B1;C3B1;110A 1167 11B8;C3B1;110A 1167 11B8; +C3B2;C3B2;110A 1167 11B9;C3B2;110A 1167 11B9; +C3B3;C3B3;110A 1167 11BA;C3B3;110A 1167 11BA; +C3B4;C3B4;110A 1167 11BB;C3B4;110A 1167 11BB; +C3B5;C3B5;110A 1167 11BC;C3B5;110A 1167 11BC; +C3B6;C3B6;110A 1167 11BD;C3B6;110A 1167 11BD; +C3B7;C3B7;110A 1167 11BE;C3B7;110A 1167 11BE; +C3B8;C3B8;110A 1167 11BF;C3B8;110A 1167 11BF; +C3B9;C3B9;110A 1167 11C0;C3B9;110A 1167 11C0; +C3BA;C3BA;110A 1167 11C1;C3BA;110A 1167 11C1; +C3BB;C3BB;110A 1167 11C2;C3BB;110A 1167 11C2; +C3BC;C3BC;110A 1168;C3BC;110A 1168; +C3BD;C3BD;110A 1168 11A8;C3BD;110A 1168 11A8; +C3BE;C3BE;110A 1168 11A9;C3BE;110A 1168 11A9; +C3BF;C3BF;110A 1168 11AA;C3BF;110A 1168 11AA; +C3C0;C3C0;110A 1168 11AB;C3C0;110A 1168 11AB; +C3C1;C3C1;110A 1168 11AC;C3C1;110A 1168 11AC; +C3C2;C3C2;110A 1168 11AD;C3C2;110A 1168 11AD; +C3C3;C3C3;110A 1168 11AE;C3C3;110A 1168 11AE; +C3C4;C3C4;110A 1168 11AF;C3C4;110A 1168 11AF; +C3C5;C3C5;110A 1168 11B0;C3C5;110A 1168 11B0; +C3C6;C3C6;110A 1168 11B1;C3C6;110A 1168 11B1; +C3C7;C3C7;110A 1168 11B2;C3C7;110A 1168 11B2; +C3C8;C3C8;110A 1168 11B3;C3C8;110A 1168 11B3; +C3C9;C3C9;110A 1168 11B4;C3C9;110A 1168 11B4; +C3CA;C3CA;110A 1168 11B5;C3CA;110A 1168 11B5; +C3CB;C3CB;110A 1168 11B6;C3CB;110A 1168 11B6; +C3CC;C3CC;110A 1168 11B7;C3CC;110A 1168 11B7; +C3CD;C3CD;110A 1168 11B8;C3CD;110A 1168 11B8; +C3CE;C3CE;110A 1168 11B9;C3CE;110A 1168 11B9; +C3CF;C3CF;110A 1168 11BA;C3CF;110A 1168 11BA; +C3D0;C3D0;110A 1168 11BB;C3D0;110A 1168 11BB; +C3D1;C3D1;110A 1168 11BC;C3D1;110A 1168 11BC; +C3D2;C3D2;110A 1168 11BD;C3D2;110A 1168 11BD; +C3D3;C3D3;110A 1168 11BE;C3D3;110A 1168 11BE; +C3D4;C3D4;110A 1168 11BF;C3D4;110A 1168 11BF; +C3D5;C3D5;110A 1168 11C0;C3D5;110A 1168 11C0; +C3D6;C3D6;110A 1168 11C1;C3D6;110A 1168 11C1; +C3D7;C3D7;110A 1168 11C2;C3D7;110A 1168 11C2; +C3D8;C3D8;110A 1169;C3D8;110A 1169; +C3D9;C3D9;110A 1169 11A8;C3D9;110A 1169 11A8; +C3DA;C3DA;110A 1169 11A9;C3DA;110A 1169 11A9; +C3DB;C3DB;110A 1169 11AA;C3DB;110A 1169 11AA; +C3DC;C3DC;110A 1169 11AB;C3DC;110A 1169 11AB; +C3DD;C3DD;110A 1169 11AC;C3DD;110A 1169 11AC; +C3DE;C3DE;110A 1169 11AD;C3DE;110A 1169 11AD; +C3DF;C3DF;110A 1169 11AE;C3DF;110A 1169 11AE; +C3E0;C3E0;110A 1169 11AF;C3E0;110A 1169 11AF; +C3E1;C3E1;110A 1169 11B0;C3E1;110A 1169 11B0; +C3E2;C3E2;110A 1169 11B1;C3E2;110A 1169 11B1; +C3E3;C3E3;110A 1169 11B2;C3E3;110A 1169 11B2; +C3E4;C3E4;110A 1169 11B3;C3E4;110A 1169 11B3; +C3E5;C3E5;110A 1169 11B4;C3E5;110A 1169 11B4; +C3E6;C3E6;110A 1169 11B5;C3E6;110A 1169 11B5; +C3E7;C3E7;110A 1169 11B6;C3E7;110A 1169 11B6; +C3E8;C3E8;110A 1169 11B7;C3E8;110A 1169 11B7; +C3E9;C3E9;110A 1169 11B8;C3E9;110A 1169 11B8; +C3EA;C3EA;110A 1169 11B9;C3EA;110A 1169 11B9; +C3EB;C3EB;110A 1169 11BA;C3EB;110A 1169 11BA; +C3EC;C3EC;110A 1169 11BB;C3EC;110A 1169 11BB; +C3ED;C3ED;110A 1169 11BC;C3ED;110A 1169 11BC; +C3EE;C3EE;110A 1169 11BD;C3EE;110A 1169 11BD; +C3EF;C3EF;110A 1169 11BE;C3EF;110A 1169 11BE; +C3F0;C3F0;110A 1169 11BF;C3F0;110A 1169 11BF; +C3F1;C3F1;110A 1169 11C0;C3F1;110A 1169 11C0; +C3F2;C3F2;110A 1169 11C1;C3F2;110A 1169 11C1; +C3F3;C3F3;110A 1169 11C2;C3F3;110A 1169 11C2; +C3F4;C3F4;110A 116A;C3F4;110A 116A; +C3F5;C3F5;110A 116A 11A8;C3F5;110A 116A 11A8; +C3F6;C3F6;110A 116A 11A9;C3F6;110A 116A 11A9; +C3F7;C3F7;110A 116A 11AA;C3F7;110A 116A 11AA; +C3F8;C3F8;110A 116A 11AB;C3F8;110A 116A 11AB; +C3F9;C3F9;110A 116A 11AC;C3F9;110A 116A 11AC; +C3FA;C3FA;110A 116A 11AD;C3FA;110A 116A 11AD; +C3FB;C3FB;110A 116A 11AE;C3FB;110A 116A 11AE; +C3FC;C3FC;110A 116A 11AF;C3FC;110A 116A 11AF; +C3FD;C3FD;110A 116A 11B0;C3FD;110A 116A 11B0; +C3FE;C3FE;110A 116A 11B1;C3FE;110A 116A 11B1; +C3FF;C3FF;110A 116A 11B2;C3FF;110A 116A 11B2; +C400;C400;110A 116A 11B3;C400;110A 116A 11B3; +C401;C401;110A 116A 11B4;C401;110A 116A 11B4; +C402;C402;110A 116A 11B5;C402;110A 116A 11B5; +C403;C403;110A 116A 11B6;C403;110A 116A 11B6; +C404;C404;110A 116A 11B7;C404;110A 116A 11B7; +C405;C405;110A 116A 11B8;C405;110A 116A 11B8; +C406;C406;110A 116A 11B9;C406;110A 116A 11B9; +C407;C407;110A 116A 11BA;C407;110A 116A 11BA; +C408;C408;110A 116A 11BB;C408;110A 116A 11BB; +C409;C409;110A 116A 11BC;C409;110A 116A 11BC; +C40A;C40A;110A 116A 11BD;C40A;110A 116A 11BD; +C40B;C40B;110A 116A 11BE;C40B;110A 116A 11BE; +C40C;C40C;110A 116A 11BF;C40C;110A 116A 11BF; +C40D;C40D;110A 116A 11C0;C40D;110A 116A 11C0; +C40E;C40E;110A 116A 11C1;C40E;110A 116A 11C1; +C40F;C40F;110A 116A 11C2;C40F;110A 116A 11C2; +C410;C410;110A 116B;C410;110A 116B; +C411;C411;110A 116B 11A8;C411;110A 116B 11A8; +C412;C412;110A 116B 11A9;C412;110A 116B 11A9; +C413;C413;110A 116B 11AA;C413;110A 116B 11AA; +C414;C414;110A 116B 11AB;C414;110A 116B 11AB; +C415;C415;110A 116B 11AC;C415;110A 116B 11AC; +C416;C416;110A 116B 11AD;C416;110A 116B 11AD; +C417;C417;110A 116B 11AE;C417;110A 116B 11AE; +C418;C418;110A 116B 11AF;C418;110A 116B 11AF; +C419;C419;110A 116B 11B0;C419;110A 116B 11B0; +C41A;C41A;110A 116B 11B1;C41A;110A 116B 11B1; +C41B;C41B;110A 116B 11B2;C41B;110A 116B 11B2; +C41C;C41C;110A 116B 11B3;C41C;110A 116B 11B3; +C41D;C41D;110A 116B 11B4;C41D;110A 116B 11B4; +C41E;C41E;110A 116B 11B5;C41E;110A 116B 11B5; +C41F;C41F;110A 116B 11B6;C41F;110A 116B 11B6; +C420;C420;110A 116B 11B7;C420;110A 116B 11B7; +C421;C421;110A 116B 11B8;C421;110A 116B 11B8; +C422;C422;110A 116B 11B9;C422;110A 116B 11B9; +C423;C423;110A 116B 11BA;C423;110A 116B 11BA; +C424;C424;110A 116B 11BB;C424;110A 116B 11BB; +C425;C425;110A 116B 11BC;C425;110A 116B 11BC; +C426;C426;110A 116B 11BD;C426;110A 116B 11BD; +C427;C427;110A 116B 11BE;C427;110A 116B 11BE; +C428;C428;110A 116B 11BF;C428;110A 116B 11BF; +C429;C429;110A 116B 11C0;C429;110A 116B 11C0; +C42A;C42A;110A 116B 11C1;C42A;110A 116B 11C1; +C42B;C42B;110A 116B 11C2;C42B;110A 116B 11C2; +C42C;C42C;110A 116C;C42C;110A 116C; +C42D;C42D;110A 116C 11A8;C42D;110A 116C 11A8; +C42E;C42E;110A 116C 11A9;C42E;110A 116C 11A9; +C42F;C42F;110A 116C 11AA;C42F;110A 116C 11AA; +C430;C430;110A 116C 11AB;C430;110A 116C 11AB; +C431;C431;110A 116C 11AC;C431;110A 116C 11AC; +C432;C432;110A 116C 11AD;C432;110A 116C 11AD; +C433;C433;110A 116C 11AE;C433;110A 116C 11AE; +C434;C434;110A 116C 11AF;C434;110A 116C 11AF; +C435;C435;110A 116C 11B0;C435;110A 116C 11B0; +C436;C436;110A 116C 11B1;C436;110A 116C 11B1; +C437;C437;110A 116C 11B2;C437;110A 116C 11B2; +C438;C438;110A 116C 11B3;C438;110A 116C 11B3; +C439;C439;110A 116C 11B4;C439;110A 116C 11B4; +C43A;C43A;110A 116C 11B5;C43A;110A 116C 11B5; +C43B;C43B;110A 116C 11B6;C43B;110A 116C 11B6; +C43C;C43C;110A 116C 11B7;C43C;110A 116C 11B7; +C43D;C43D;110A 116C 11B8;C43D;110A 116C 11B8; +C43E;C43E;110A 116C 11B9;C43E;110A 116C 11B9; +C43F;C43F;110A 116C 11BA;C43F;110A 116C 11BA; +C440;C440;110A 116C 11BB;C440;110A 116C 11BB; +C441;C441;110A 116C 11BC;C441;110A 116C 11BC; +C442;C442;110A 116C 11BD;C442;110A 116C 11BD; +C443;C443;110A 116C 11BE;C443;110A 116C 11BE; +C444;C444;110A 116C 11BF;C444;110A 116C 11BF; +C445;C445;110A 116C 11C0;C445;110A 116C 11C0; +C446;C446;110A 116C 11C1;C446;110A 116C 11C1; +C447;C447;110A 116C 11C2;C447;110A 116C 11C2; +C448;C448;110A 116D;C448;110A 116D; +C449;C449;110A 116D 11A8;C449;110A 116D 11A8; +C44A;C44A;110A 116D 11A9;C44A;110A 116D 11A9; +C44B;C44B;110A 116D 11AA;C44B;110A 116D 11AA; +C44C;C44C;110A 116D 11AB;C44C;110A 116D 11AB; +C44D;C44D;110A 116D 11AC;C44D;110A 116D 11AC; +C44E;C44E;110A 116D 11AD;C44E;110A 116D 11AD; +C44F;C44F;110A 116D 11AE;C44F;110A 116D 11AE; +C450;C450;110A 116D 11AF;C450;110A 116D 11AF; +C451;C451;110A 116D 11B0;C451;110A 116D 11B0; +C452;C452;110A 116D 11B1;C452;110A 116D 11B1; +C453;C453;110A 116D 11B2;C453;110A 116D 11B2; +C454;C454;110A 116D 11B3;C454;110A 116D 11B3; +C455;C455;110A 116D 11B4;C455;110A 116D 11B4; +C456;C456;110A 116D 11B5;C456;110A 116D 11B5; +C457;C457;110A 116D 11B6;C457;110A 116D 11B6; +C458;C458;110A 116D 11B7;C458;110A 116D 11B7; +C459;C459;110A 116D 11B8;C459;110A 116D 11B8; +C45A;C45A;110A 116D 11B9;C45A;110A 116D 11B9; +C45B;C45B;110A 116D 11BA;C45B;110A 116D 11BA; +C45C;C45C;110A 116D 11BB;C45C;110A 116D 11BB; +C45D;C45D;110A 116D 11BC;C45D;110A 116D 11BC; +C45E;C45E;110A 116D 11BD;C45E;110A 116D 11BD; +C45F;C45F;110A 116D 11BE;C45F;110A 116D 11BE; +C460;C460;110A 116D 11BF;C460;110A 116D 11BF; +C461;C461;110A 116D 11C0;C461;110A 116D 11C0; +C462;C462;110A 116D 11C1;C462;110A 116D 11C1; +C463;C463;110A 116D 11C2;C463;110A 116D 11C2; +C464;C464;110A 116E;C464;110A 116E; +C465;C465;110A 116E 11A8;C465;110A 116E 11A8; +C466;C466;110A 116E 11A9;C466;110A 116E 11A9; +C467;C467;110A 116E 11AA;C467;110A 116E 11AA; +C468;C468;110A 116E 11AB;C468;110A 116E 11AB; +C469;C469;110A 116E 11AC;C469;110A 116E 11AC; +C46A;C46A;110A 116E 11AD;C46A;110A 116E 11AD; +C46B;C46B;110A 116E 11AE;C46B;110A 116E 11AE; +C46C;C46C;110A 116E 11AF;C46C;110A 116E 11AF; +C46D;C46D;110A 116E 11B0;C46D;110A 116E 11B0; +C46E;C46E;110A 116E 11B1;C46E;110A 116E 11B1; +C46F;C46F;110A 116E 11B2;C46F;110A 116E 11B2; +C470;C470;110A 116E 11B3;C470;110A 116E 11B3; +C471;C471;110A 116E 11B4;C471;110A 116E 11B4; +C472;C472;110A 116E 11B5;C472;110A 116E 11B5; +C473;C473;110A 116E 11B6;C473;110A 116E 11B6; +C474;C474;110A 116E 11B7;C474;110A 116E 11B7; +C475;C475;110A 116E 11B8;C475;110A 116E 11B8; +C476;C476;110A 116E 11B9;C476;110A 116E 11B9; +C477;C477;110A 116E 11BA;C477;110A 116E 11BA; +C478;C478;110A 116E 11BB;C478;110A 116E 11BB; +C479;C479;110A 116E 11BC;C479;110A 116E 11BC; +C47A;C47A;110A 116E 11BD;C47A;110A 116E 11BD; +C47B;C47B;110A 116E 11BE;C47B;110A 116E 11BE; +C47C;C47C;110A 116E 11BF;C47C;110A 116E 11BF; +C47D;C47D;110A 116E 11C0;C47D;110A 116E 11C0; +C47E;C47E;110A 116E 11C1;C47E;110A 116E 11C1; +C47F;C47F;110A 116E 11C2;C47F;110A 116E 11C2; +C480;C480;110A 116F;C480;110A 116F; +C481;C481;110A 116F 11A8;C481;110A 116F 11A8; +C482;C482;110A 116F 11A9;C482;110A 116F 11A9; +C483;C483;110A 116F 11AA;C483;110A 116F 11AA; +C484;C484;110A 116F 11AB;C484;110A 116F 11AB; +C485;C485;110A 116F 11AC;C485;110A 116F 11AC; +C486;C486;110A 116F 11AD;C486;110A 116F 11AD; +C487;C487;110A 116F 11AE;C487;110A 116F 11AE; +C488;C488;110A 116F 11AF;C488;110A 116F 11AF; +C489;C489;110A 116F 11B0;C489;110A 116F 11B0; +C48A;C48A;110A 116F 11B1;C48A;110A 116F 11B1; +C48B;C48B;110A 116F 11B2;C48B;110A 116F 11B2; +C48C;C48C;110A 116F 11B3;C48C;110A 116F 11B3; +C48D;C48D;110A 116F 11B4;C48D;110A 116F 11B4; +C48E;C48E;110A 116F 11B5;C48E;110A 116F 11B5; +C48F;C48F;110A 116F 11B6;C48F;110A 116F 11B6; +C490;C490;110A 116F 11B7;C490;110A 116F 11B7; +C491;C491;110A 116F 11B8;C491;110A 116F 11B8; +C492;C492;110A 116F 11B9;C492;110A 116F 11B9; +C493;C493;110A 116F 11BA;C493;110A 116F 11BA; +C494;C494;110A 116F 11BB;C494;110A 116F 11BB; +C495;C495;110A 116F 11BC;C495;110A 116F 11BC; +C496;C496;110A 116F 11BD;C496;110A 116F 11BD; +C497;C497;110A 116F 11BE;C497;110A 116F 11BE; +C498;C498;110A 116F 11BF;C498;110A 116F 11BF; +C499;C499;110A 116F 11C0;C499;110A 116F 11C0; +C49A;C49A;110A 116F 11C1;C49A;110A 116F 11C1; +C49B;C49B;110A 116F 11C2;C49B;110A 116F 11C2; +C49C;C49C;110A 1170;C49C;110A 1170; +C49D;C49D;110A 1170 11A8;C49D;110A 1170 11A8; +C49E;C49E;110A 1170 11A9;C49E;110A 1170 11A9; +C49F;C49F;110A 1170 11AA;C49F;110A 1170 11AA; +C4A0;C4A0;110A 1170 11AB;C4A0;110A 1170 11AB; +C4A1;C4A1;110A 1170 11AC;C4A1;110A 1170 11AC; +C4A2;C4A2;110A 1170 11AD;C4A2;110A 1170 11AD; +C4A3;C4A3;110A 1170 11AE;C4A3;110A 1170 11AE; +C4A4;C4A4;110A 1170 11AF;C4A4;110A 1170 11AF; +C4A5;C4A5;110A 1170 11B0;C4A5;110A 1170 11B0; +C4A6;C4A6;110A 1170 11B1;C4A6;110A 1170 11B1; +C4A7;C4A7;110A 1170 11B2;C4A7;110A 1170 11B2; +C4A8;C4A8;110A 1170 11B3;C4A8;110A 1170 11B3; +C4A9;C4A9;110A 1170 11B4;C4A9;110A 1170 11B4; +C4AA;C4AA;110A 1170 11B5;C4AA;110A 1170 11B5; +C4AB;C4AB;110A 1170 11B6;C4AB;110A 1170 11B6; +C4AC;C4AC;110A 1170 11B7;C4AC;110A 1170 11B7; +C4AD;C4AD;110A 1170 11B8;C4AD;110A 1170 11B8; +C4AE;C4AE;110A 1170 11B9;C4AE;110A 1170 11B9; +C4AF;C4AF;110A 1170 11BA;C4AF;110A 1170 11BA; +C4B0;C4B0;110A 1170 11BB;C4B0;110A 1170 11BB; +C4B1;C4B1;110A 1170 11BC;C4B1;110A 1170 11BC; +C4B2;C4B2;110A 1170 11BD;C4B2;110A 1170 11BD; +C4B3;C4B3;110A 1170 11BE;C4B3;110A 1170 11BE; +C4B4;C4B4;110A 1170 11BF;C4B4;110A 1170 11BF; +C4B5;C4B5;110A 1170 11C0;C4B5;110A 1170 11C0; +C4B6;C4B6;110A 1170 11C1;C4B6;110A 1170 11C1; +C4B7;C4B7;110A 1170 11C2;C4B7;110A 1170 11C2; +C4B8;C4B8;110A 1171;C4B8;110A 1171; +C4B9;C4B9;110A 1171 11A8;C4B9;110A 1171 11A8; +C4BA;C4BA;110A 1171 11A9;C4BA;110A 1171 11A9; +C4BB;C4BB;110A 1171 11AA;C4BB;110A 1171 11AA; +C4BC;C4BC;110A 1171 11AB;C4BC;110A 1171 11AB; +C4BD;C4BD;110A 1171 11AC;C4BD;110A 1171 11AC; +C4BE;C4BE;110A 1171 11AD;C4BE;110A 1171 11AD; +C4BF;C4BF;110A 1171 11AE;C4BF;110A 1171 11AE; +C4C0;C4C0;110A 1171 11AF;C4C0;110A 1171 11AF; +C4C1;C4C1;110A 1171 11B0;C4C1;110A 1171 11B0; +C4C2;C4C2;110A 1171 11B1;C4C2;110A 1171 11B1; +C4C3;C4C3;110A 1171 11B2;C4C3;110A 1171 11B2; +C4C4;C4C4;110A 1171 11B3;C4C4;110A 1171 11B3; +C4C5;C4C5;110A 1171 11B4;C4C5;110A 1171 11B4; +C4C6;C4C6;110A 1171 11B5;C4C6;110A 1171 11B5; +C4C7;C4C7;110A 1171 11B6;C4C7;110A 1171 11B6; +C4C8;C4C8;110A 1171 11B7;C4C8;110A 1171 11B7; +C4C9;C4C9;110A 1171 11B8;C4C9;110A 1171 11B8; +C4CA;C4CA;110A 1171 11B9;C4CA;110A 1171 11B9; +C4CB;C4CB;110A 1171 11BA;C4CB;110A 1171 11BA; +C4CC;C4CC;110A 1171 11BB;C4CC;110A 1171 11BB; +C4CD;C4CD;110A 1171 11BC;C4CD;110A 1171 11BC; +C4CE;C4CE;110A 1171 11BD;C4CE;110A 1171 11BD; +C4CF;C4CF;110A 1171 11BE;C4CF;110A 1171 11BE; +C4D0;C4D0;110A 1171 11BF;C4D0;110A 1171 11BF; +C4D1;C4D1;110A 1171 11C0;C4D1;110A 1171 11C0; +C4D2;C4D2;110A 1171 11C1;C4D2;110A 1171 11C1; +C4D3;C4D3;110A 1171 11C2;C4D3;110A 1171 11C2; +C4D4;C4D4;110A 1172;C4D4;110A 1172; +C4D5;C4D5;110A 1172 11A8;C4D5;110A 1172 11A8; +C4D6;C4D6;110A 1172 11A9;C4D6;110A 1172 11A9; +C4D7;C4D7;110A 1172 11AA;C4D7;110A 1172 11AA; +C4D8;C4D8;110A 1172 11AB;C4D8;110A 1172 11AB; +C4D9;C4D9;110A 1172 11AC;C4D9;110A 1172 11AC; +C4DA;C4DA;110A 1172 11AD;C4DA;110A 1172 11AD; +C4DB;C4DB;110A 1172 11AE;C4DB;110A 1172 11AE; +C4DC;C4DC;110A 1172 11AF;C4DC;110A 1172 11AF; +C4DD;C4DD;110A 1172 11B0;C4DD;110A 1172 11B0; +C4DE;C4DE;110A 1172 11B1;C4DE;110A 1172 11B1; +C4DF;C4DF;110A 1172 11B2;C4DF;110A 1172 11B2; +C4E0;C4E0;110A 1172 11B3;C4E0;110A 1172 11B3; +C4E1;C4E1;110A 1172 11B4;C4E1;110A 1172 11B4; +C4E2;C4E2;110A 1172 11B5;C4E2;110A 1172 11B5; +C4E3;C4E3;110A 1172 11B6;C4E3;110A 1172 11B6; +C4E4;C4E4;110A 1172 11B7;C4E4;110A 1172 11B7; +C4E5;C4E5;110A 1172 11B8;C4E5;110A 1172 11B8; +C4E6;C4E6;110A 1172 11B9;C4E6;110A 1172 11B9; +C4E7;C4E7;110A 1172 11BA;C4E7;110A 1172 11BA; +C4E8;C4E8;110A 1172 11BB;C4E8;110A 1172 11BB; +C4E9;C4E9;110A 1172 11BC;C4E9;110A 1172 11BC; +C4EA;C4EA;110A 1172 11BD;C4EA;110A 1172 11BD; +C4EB;C4EB;110A 1172 11BE;C4EB;110A 1172 11BE; +C4EC;C4EC;110A 1172 11BF;C4EC;110A 1172 11BF; +C4ED;C4ED;110A 1172 11C0;C4ED;110A 1172 11C0; +C4EE;C4EE;110A 1172 11C1;C4EE;110A 1172 11C1; +C4EF;C4EF;110A 1172 11C2;C4EF;110A 1172 11C2; +C4F0;C4F0;110A 1173;C4F0;110A 1173; +C4F1;C4F1;110A 1173 11A8;C4F1;110A 1173 11A8; +C4F2;C4F2;110A 1173 11A9;C4F2;110A 1173 11A9; +C4F3;C4F3;110A 1173 11AA;C4F3;110A 1173 11AA; +C4F4;C4F4;110A 1173 11AB;C4F4;110A 1173 11AB; +C4F5;C4F5;110A 1173 11AC;C4F5;110A 1173 11AC; +C4F6;C4F6;110A 1173 11AD;C4F6;110A 1173 11AD; +C4F7;C4F7;110A 1173 11AE;C4F7;110A 1173 11AE; +C4F8;C4F8;110A 1173 11AF;C4F8;110A 1173 11AF; +C4F9;C4F9;110A 1173 11B0;C4F9;110A 1173 11B0; +C4FA;C4FA;110A 1173 11B1;C4FA;110A 1173 11B1; +C4FB;C4FB;110A 1173 11B2;C4FB;110A 1173 11B2; +C4FC;C4FC;110A 1173 11B3;C4FC;110A 1173 11B3; +C4FD;C4FD;110A 1173 11B4;C4FD;110A 1173 11B4; +C4FE;C4FE;110A 1173 11B5;C4FE;110A 1173 11B5; +C4FF;C4FF;110A 1173 11B6;C4FF;110A 1173 11B6; +C500;C500;110A 1173 11B7;C500;110A 1173 11B7; +C501;C501;110A 1173 11B8;C501;110A 1173 11B8; +C502;C502;110A 1173 11B9;C502;110A 1173 11B9; +C503;C503;110A 1173 11BA;C503;110A 1173 11BA; +C504;C504;110A 1173 11BB;C504;110A 1173 11BB; +C505;C505;110A 1173 11BC;C505;110A 1173 11BC; +C506;C506;110A 1173 11BD;C506;110A 1173 11BD; +C507;C507;110A 1173 11BE;C507;110A 1173 11BE; +C508;C508;110A 1173 11BF;C508;110A 1173 11BF; +C509;C509;110A 1173 11C0;C509;110A 1173 11C0; +C50A;C50A;110A 1173 11C1;C50A;110A 1173 11C1; +C50B;C50B;110A 1173 11C2;C50B;110A 1173 11C2; +C50C;C50C;110A 1174;C50C;110A 1174; +C50D;C50D;110A 1174 11A8;C50D;110A 1174 11A8; +C50E;C50E;110A 1174 11A9;C50E;110A 1174 11A9; +C50F;C50F;110A 1174 11AA;C50F;110A 1174 11AA; +C510;C510;110A 1174 11AB;C510;110A 1174 11AB; +C511;C511;110A 1174 11AC;C511;110A 1174 11AC; +C512;C512;110A 1174 11AD;C512;110A 1174 11AD; +C513;C513;110A 1174 11AE;C513;110A 1174 11AE; +C514;C514;110A 1174 11AF;C514;110A 1174 11AF; +C515;C515;110A 1174 11B0;C515;110A 1174 11B0; +C516;C516;110A 1174 11B1;C516;110A 1174 11B1; +C517;C517;110A 1174 11B2;C517;110A 1174 11B2; +C518;C518;110A 1174 11B3;C518;110A 1174 11B3; +C519;C519;110A 1174 11B4;C519;110A 1174 11B4; +C51A;C51A;110A 1174 11B5;C51A;110A 1174 11B5; +C51B;C51B;110A 1174 11B6;C51B;110A 1174 11B6; +C51C;C51C;110A 1174 11B7;C51C;110A 1174 11B7; +C51D;C51D;110A 1174 11B8;C51D;110A 1174 11B8; +C51E;C51E;110A 1174 11B9;C51E;110A 1174 11B9; +C51F;C51F;110A 1174 11BA;C51F;110A 1174 11BA; +C520;C520;110A 1174 11BB;C520;110A 1174 11BB; +C521;C521;110A 1174 11BC;C521;110A 1174 11BC; +C522;C522;110A 1174 11BD;C522;110A 1174 11BD; +C523;C523;110A 1174 11BE;C523;110A 1174 11BE; +C524;C524;110A 1174 11BF;C524;110A 1174 11BF; +C525;C525;110A 1174 11C0;C525;110A 1174 11C0; +C526;C526;110A 1174 11C1;C526;110A 1174 11C1; +C527;C527;110A 1174 11C2;C527;110A 1174 11C2; +C528;C528;110A 1175;C528;110A 1175; +C529;C529;110A 1175 11A8;C529;110A 1175 11A8; +C52A;C52A;110A 1175 11A9;C52A;110A 1175 11A9; +C52B;C52B;110A 1175 11AA;C52B;110A 1175 11AA; +C52C;C52C;110A 1175 11AB;C52C;110A 1175 11AB; +C52D;C52D;110A 1175 11AC;C52D;110A 1175 11AC; +C52E;C52E;110A 1175 11AD;C52E;110A 1175 11AD; +C52F;C52F;110A 1175 11AE;C52F;110A 1175 11AE; +C530;C530;110A 1175 11AF;C530;110A 1175 11AF; +C531;C531;110A 1175 11B0;C531;110A 1175 11B0; +C532;C532;110A 1175 11B1;C532;110A 1175 11B1; +C533;C533;110A 1175 11B2;C533;110A 1175 11B2; +C534;C534;110A 1175 11B3;C534;110A 1175 11B3; +C535;C535;110A 1175 11B4;C535;110A 1175 11B4; +C536;C536;110A 1175 11B5;C536;110A 1175 11B5; +C537;C537;110A 1175 11B6;C537;110A 1175 11B6; +C538;C538;110A 1175 11B7;C538;110A 1175 11B7; +C539;C539;110A 1175 11B8;C539;110A 1175 11B8; +C53A;C53A;110A 1175 11B9;C53A;110A 1175 11B9; +C53B;C53B;110A 1175 11BA;C53B;110A 1175 11BA; +C53C;C53C;110A 1175 11BB;C53C;110A 1175 11BB; +C53D;C53D;110A 1175 11BC;C53D;110A 1175 11BC; +C53E;C53E;110A 1175 11BD;C53E;110A 1175 11BD; +C53F;C53F;110A 1175 11BE;C53F;110A 1175 11BE; +C540;C540;110A 1175 11BF;C540;110A 1175 11BF; +C541;C541;110A 1175 11C0;C541;110A 1175 11C0; +C542;C542;110A 1175 11C1;C542;110A 1175 11C1; +C543;C543;110A 1175 11C2;C543;110A 1175 11C2; +C544;C544;110B 1161;C544;110B 1161; +C545;C545;110B 1161 11A8;C545;110B 1161 11A8; +C546;C546;110B 1161 11A9;C546;110B 1161 11A9; +C547;C547;110B 1161 11AA;C547;110B 1161 11AA; +C548;C548;110B 1161 11AB;C548;110B 1161 11AB; +C549;C549;110B 1161 11AC;C549;110B 1161 11AC; +C54A;C54A;110B 1161 11AD;C54A;110B 1161 11AD; +C54B;C54B;110B 1161 11AE;C54B;110B 1161 11AE; +C54C;C54C;110B 1161 11AF;C54C;110B 1161 11AF; +C54D;C54D;110B 1161 11B0;C54D;110B 1161 11B0; +C54E;C54E;110B 1161 11B1;C54E;110B 1161 11B1; +C54F;C54F;110B 1161 11B2;C54F;110B 1161 11B2; +C550;C550;110B 1161 11B3;C550;110B 1161 11B3; +C551;C551;110B 1161 11B4;C551;110B 1161 11B4; +C552;C552;110B 1161 11B5;C552;110B 1161 11B5; +C553;C553;110B 1161 11B6;C553;110B 1161 11B6; +C554;C554;110B 1161 11B7;C554;110B 1161 11B7; +C555;C555;110B 1161 11B8;C555;110B 1161 11B8; +C556;C556;110B 1161 11B9;C556;110B 1161 11B9; +C557;C557;110B 1161 11BA;C557;110B 1161 11BA; +C558;C558;110B 1161 11BB;C558;110B 1161 11BB; +C559;C559;110B 1161 11BC;C559;110B 1161 11BC; +C55A;C55A;110B 1161 11BD;C55A;110B 1161 11BD; +C55B;C55B;110B 1161 11BE;C55B;110B 1161 11BE; +C55C;C55C;110B 1161 11BF;C55C;110B 1161 11BF; +C55D;C55D;110B 1161 11C0;C55D;110B 1161 11C0; +C55E;C55E;110B 1161 11C1;C55E;110B 1161 11C1; +C55F;C55F;110B 1161 11C2;C55F;110B 1161 11C2; +C560;C560;110B 1162;C560;110B 1162; +C561;C561;110B 1162 11A8;C561;110B 1162 11A8; +C562;C562;110B 1162 11A9;C562;110B 1162 11A9; +C563;C563;110B 1162 11AA;C563;110B 1162 11AA; +C564;C564;110B 1162 11AB;C564;110B 1162 11AB; +C565;C565;110B 1162 11AC;C565;110B 1162 11AC; +C566;C566;110B 1162 11AD;C566;110B 1162 11AD; +C567;C567;110B 1162 11AE;C567;110B 1162 11AE; +C568;C568;110B 1162 11AF;C568;110B 1162 11AF; +C569;C569;110B 1162 11B0;C569;110B 1162 11B0; +C56A;C56A;110B 1162 11B1;C56A;110B 1162 11B1; +C56B;C56B;110B 1162 11B2;C56B;110B 1162 11B2; +C56C;C56C;110B 1162 11B3;C56C;110B 1162 11B3; +C56D;C56D;110B 1162 11B4;C56D;110B 1162 11B4; +C56E;C56E;110B 1162 11B5;C56E;110B 1162 11B5; +C56F;C56F;110B 1162 11B6;C56F;110B 1162 11B6; +C570;C570;110B 1162 11B7;C570;110B 1162 11B7; +C571;C571;110B 1162 11B8;C571;110B 1162 11B8; +C572;C572;110B 1162 11B9;C572;110B 1162 11B9; +C573;C573;110B 1162 11BA;C573;110B 1162 11BA; +C574;C574;110B 1162 11BB;C574;110B 1162 11BB; +C575;C575;110B 1162 11BC;C575;110B 1162 11BC; +C576;C576;110B 1162 11BD;C576;110B 1162 11BD; +C577;C577;110B 1162 11BE;C577;110B 1162 11BE; +C578;C578;110B 1162 11BF;C578;110B 1162 11BF; +C579;C579;110B 1162 11C0;C579;110B 1162 11C0; +C57A;C57A;110B 1162 11C1;C57A;110B 1162 11C1; +C57B;C57B;110B 1162 11C2;C57B;110B 1162 11C2; +C57C;C57C;110B 1163;C57C;110B 1163; +C57D;C57D;110B 1163 11A8;C57D;110B 1163 11A8; +C57E;C57E;110B 1163 11A9;C57E;110B 1163 11A9; +C57F;C57F;110B 1163 11AA;C57F;110B 1163 11AA; +C580;C580;110B 1163 11AB;C580;110B 1163 11AB; +C581;C581;110B 1163 11AC;C581;110B 1163 11AC; +C582;C582;110B 1163 11AD;C582;110B 1163 11AD; +C583;C583;110B 1163 11AE;C583;110B 1163 11AE; +C584;C584;110B 1163 11AF;C584;110B 1163 11AF; +C585;C585;110B 1163 11B0;C585;110B 1163 11B0; +C586;C586;110B 1163 11B1;C586;110B 1163 11B1; +C587;C587;110B 1163 11B2;C587;110B 1163 11B2; +C588;C588;110B 1163 11B3;C588;110B 1163 11B3; +C589;C589;110B 1163 11B4;C589;110B 1163 11B4; +C58A;C58A;110B 1163 11B5;C58A;110B 1163 11B5; +C58B;C58B;110B 1163 11B6;C58B;110B 1163 11B6; +C58C;C58C;110B 1163 11B7;C58C;110B 1163 11B7; +C58D;C58D;110B 1163 11B8;C58D;110B 1163 11B8; +C58E;C58E;110B 1163 11B9;C58E;110B 1163 11B9; +C58F;C58F;110B 1163 11BA;C58F;110B 1163 11BA; +C590;C590;110B 1163 11BB;C590;110B 1163 11BB; +C591;C591;110B 1163 11BC;C591;110B 1163 11BC; +C592;C592;110B 1163 11BD;C592;110B 1163 11BD; +C593;C593;110B 1163 11BE;C593;110B 1163 11BE; +C594;C594;110B 1163 11BF;C594;110B 1163 11BF; +C595;C595;110B 1163 11C0;C595;110B 1163 11C0; +C596;C596;110B 1163 11C1;C596;110B 1163 11C1; +C597;C597;110B 1163 11C2;C597;110B 1163 11C2; +C598;C598;110B 1164;C598;110B 1164; +C599;C599;110B 1164 11A8;C599;110B 1164 11A8; +C59A;C59A;110B 1164 11A9;C59A;110B 1164 11A9; +C59B;C59B;110B 1164 11AA;C59B;110B 1164 11AA; +C59C;C59C;110B 1164 11AB;C59C;110B 1164 11AB; +C59D;C59D;110B 1164 11AC;C59D;110B 1164 11AC; +C59E;C59E;110B 1164 11AD;C59E;110B 1164 11AD; +C59F;C59F;110B 1164 11AE;C59F;110B 1164 11AE; +C5A0;C5A0;110B 1164 11AF;C5A0;110B 1164 11AF; +C5A1;C5A1;110B 1164 11B0;C5A1;110B 1164 11B0; +C5A2;C5A2;110B 1164 11B1;C5A2;110B 1164 11B1; +C5A3;C5A3;110B 1164 11B2;C5A3;110B 1164 11B2; +C5A4;C5A4;110B 1164 11B3;C5A4;110B 1164 11B3; +C5A5;C5A5;110B 1164 11B4;C5A5;110B 1164 11B4; +C5A6;C5A6;110B 1164 11B5;C5A6;110B 1164 11B5; +C5A7;C5A7;110B 1164 11B6;C5A7;110B 1164 11B6; +C5A8;C5A8;110B 1164 11B7;C5A8;110B 1164 11B7; +C5A9;C5A9;110B 1164 11B8;C5A9;110B 1164 11B8; +C5AA;C5AA;110B 1164 11B9;C5AA;110B 1164 11B9; +C5AB;C5AB;110B 1164 11BA;C5AB;110B 1164 11BA; +C5AC;C5AC;110B 1164 11BB;C5AC;110B 1164 11BB; +C5AD;C5AD;110B 1164 11BC;C5AD;110B 1164 11BC; +C5AE;C5AE;110B 1164 11BD;C5AE;110B 1164 11BD; +C5AF;C5AF;110B 1164 11BE;C5AF;110B 1164 11BE; +C5B0;C5B0;110B 1164 11BF;C5B0;110B 1164 11BF; +C5B1;C5B1;110B 1164 11C0;C5B1;110B 1164 11C0; +C5B2;C5B2;110B 1164 11C1;C5B2;110B 1164 11C1; +C5B3;C5B3;110B 1164 11C2;C5B3;110B 1164 11C2; +C5B4;C5B4;110B 1165;C5B4;110B 1165; +C5B5;C5B5;110B 1165 11A8;C5B5;110B 1165 11A8; +C5B6;C5B6;110B 1165 11A9;C5B6;110B 1165 11A9; +C5B7;C5B7;110B 1165 11AA;C5B7;110B 1165 11AA; +C5B8;C5B8;110B 1165 11AB;C5B8;110B 1165 11AB; +C5B9;C5B9;110B 1165 11AC;C5B9;110B 1165 11AC; +C5BA;C5BA;110B 1165 11AD;C5BA;110B 1165 11AD; +C5BB;C5BB;110B 1165 11AE;C5BB;110B 1165 11AE; +C5BC;C5BC;110B 1165 11AF;C5BC;110B 1165 11AF; +C5BD;C5BD;110B 1165 11B0;C5BD;110B 1165 11B0; +C5BE;C5BE;110B 1165 11B1;C5BE;110B 1165 11B1; +C5BF;C5BF;110B 1165 11B2;C5BF;110B 1165 11B2; +C5C0;C5C0;110B 1165 11B3;C5C0;110B 1165 11B3; +C5C1;C5C1;110B 1165 11B4;C5C1;110B 1165 11B4; +C5C2;C5C2;110B 1165 11B5;C5C2;110B 1165 11B5; +C5C3;C5C3;110B 1165 11B6;C5C3;110B 1165 11B6; +C5C4;C5C4;110B 1165 11B7;C5C4;110B 1165 11B7; +C5C5;C5C5;110B 1165 11B8;C5C5;110B 1165 11B8; +C5C6;C5C6;110B 1165 11B9;C5C6;110B 1165 11B9; +C5C7;C5C7;110B 1165 11BA;C5C7;110B 1165 11BA; +C5C8;C5C8;110B 1165 11BB;C5C8;110B 1165 11BB; +C5C9;C5C9;110B 1165 11BC;C5C9;110B 1165 11BC; +C5CA;C5CA;110B 1165 11BD;C5CA;110B 1165 11BD; +C5CB;C5CB;110B 1165 11BE;C5CB;110B 1165 11BE; +C5CC;C5CC;110B 1165 11BF;C5CC;110B 1165 11BF; +C5CD;C5CD;110B 1165 11C0;C5CD;110B 1165 11C0; +C5CE;C5CE;110B 1165 11C1;C5CE;110B 1165 11C1; +C5CF;C5CF;110B 1165 11C2;C5CF;110B 1165 11C2; +C5D0;C5D0;110B 1166;C5D0;110B 1166; +C5D1;C5D1;110B 1166 11A8;C5D1;110B 1166 11A8; +C5D2;C5D2;110B 1166 11A9;C5D2;110B 1166 11A9; +C5D3;C5D3;110B 1166 11AA;C5D3;110B 1166 11AA; +C5D4;C5D4;110B 1166 11AB;C5D4;110B 1166 11AB; +C5D5;C5D5;110B 1166 11AC;C5D5;110B 1166 11AC; +C5D6;C5D6;110B 1166 11AD;C5D6;110B 1166 11AD; +C5D7;C5D7;110B 1166 11AE;C5D7;110B 1166 11AE; +C5D8;C5D8;110B 1166 11AF;C5D8;110B 1166 11AF; +C5D9;C5D9;110B 1166 11B0;C5D9;110B 1166 11B0; +C5DA;C5DA;110B 1166 11B1;C5DA;110B 1166 11B1; +C5DB;C5DB;110B 1166 11B2;C5DB;110B 1166 11B2; +C5DC;C5DC;110B 1166 11B3;C5DC;110B 1166 11B3; +C5DD;C5DD;110B 1166 11B4;C5DD;110B 1166 11B4; +C5DE;C5DE;110B 1166 11B5;C5DE;110B 1166 11B5; +C5DF;C5DF;110B 1166 11B6;C5DF;110B 1166 11B6; +C5E0;C5E0;110B 1166 11B7;C5E0;110B 1166 11B7; +C5E1;C5E1;110B 1166 11B8;C5E1;110B 1166 11B8; +C5E2;C5E2;110B 1166 11B9;C5E2;110B 1166 11B9; +C5E3;C5E3;110B 1166 11BA;C5E3;110B 1166 11BA; +C5E4;C5E4;110B 1166 11BB;C5E4;110B 1166 11BB; +C5E5;C5E5;110B 1166 11BC;C5E5;110B 1166 11BC; +C5E6;C5E6;110B 1166 11BD;C5E6;110B 1166 11BD; +C5E7;C5E7;110B 1166 11BE;C5E7;110B 1166 11BE; +C5E8;C5E8;110B 1166 11BF;C5E8;110B 1166 11BF; +C5E9;C5E9;110B 1166 11C0;C5E9;110B 1166 11C0; +C5EA;C5EA;110B 1166 11C1;C5EA;110B 1166 11C1; +C5EB;C5EB;110B 1166 11C2;C5EB;110B 1166 11C2; +C5EC;C5EC;110B 1167;C5EC;110B 1167; +C5ED;C5ED;110B 1167 11A8;C5ED;110B 1167 11A8; +C5EE;C5EE;110B 1167 11A9;C5EE;110B 1167 11A9; +C5EF;C5EF;110B 1167 11AA;C5EF;110B 1167 11AA; +C5F0;C5F0;110B 1167 11AB;C5F0;110B 1167 11AB; +C5F1;C5F1;110B 1167 11AC;C5F1;110B 1167 11AC; +C5F2;C5F2;110B 1167 11AD;C5F2;110B 1167 11AD; +C5F3;C5F3;110B 1167 11AE;C5F3;110B 1167 11AE; +C5F4;C5F4;110B 1167 11AF;C5F4;110B 1167 11AF; +C5F5;C5F5;110B 1167 11B0;C5F5;110B 1167 11B0; +C5F6;C5F6;110B 1167 11B1;C5F6;110B 1167 11B1; +C5F7;C5F7;110B 1167 11B2;C5F7;110B 1167 11B2; +C5F8;C5F8;110B 1167 11B3;C5F8;110B 1167 11B3; +C5F9;C5F9;110B 1167 11B4;C5F9;110B 1167 11B4; +C5FA;C5FA;110B 1167 11B5;C5FA;110B 1167 11B5; +C5FB;C5FB;110B 1167 11B6;C5FB;110B 1167 11B6; +C5FC;C5FC;110B 1167 11B7;C5FC;110B 1167 11B7; +C5FD;C5FD;110B 1167 11B8;C5FD;110B 1167 11B8; +C5FE;C5FE;110B 1167 11B9;C5FE;110B 1167 11B9; +C5FF;C5FF;110B 1167 11BA;C5FF;110B 1167 11BA; +C600;C600;110B 1167 11BB;C600;110B 1167 11BB; +C601;C601;110B 1167 11BC;C601;110B 1167 11BC; +C602;C602;110B 1167 11BD;C602;110B 1167 11BD; +C603;C603;110B 1167 11BE;C603;110B 1167 11BE; +C604;C604;110B 1167 11BF;C604;110B 1167 11BF; +C605;C605;110B 1167 11C0;C605;110B 1167 11C0; +C606;C606;110B 1167 11C1;C606;110B 1167 11C1; +C607;C607;110B 1167 11C2;C607;110B 1167 11C2; +C608;C608;110B 1168;C608;110B 1168; +C609;C609;110B 1168 11A8;C609;110B 1168 11A8; +C60A;C60A;110B 1168 11A9;C60A;110B 1168 11A9; +C60B;C60B;110B 1168 11AA;C60B;110B 1168 11AA; +C60C;C60C;110B 1168 11AB;C60C;110B 1168 11AB; +C60D;C60D;110B 1168 11AC;C60D;110B 1168 11AC; +C60E;C60E;110B 1168 11AD;C60E;110B 1168 11AD; +C60F;C60F;110B 1168 11AE;C60F;110B 1168 11AE; +C610;C610;110B 1168 11AF;C610;110B 1168 11AF; +C611;C611;110B 1168 11B0;C611;110B 1168 11B0; +C612;C612;110B 1168 11B1;C612;110B 1168 11B1; +C613;C613;110B 1168 11B2;C613;110B 1168 11B2; +C614;C614;110B 1168 11B3;C614;110B 1168 11B3; +C615;C615;110B 1168 11B4;C615;110B 1168 11B4; +C616;C616;110B 1168 11B5;C616;110B 1168 11B5; +C617;C617;110B 1168 11B6;C617;110B 1168 11B6; +C618;C618;110B 1168 11B7;C618;110B 1168 11B7; +C619;C619;110B 1168 11B8;C619;110B 1168 11B8; +C61A;C61A;110B 1168 11B9;C61A;110B 1168 11B9; +C61B;C61B;110B 1168 11BA;C61B;110B 1168 11BA; +C61C;C61C;110B 1168 11BB;C61C;110B 1168 11BB; +C61D;C61D;110B 1168 11BC;C61D;110B 1168 11BC; +C61E;C61E;110B 1168 11BD;C61E;110B 1168 11BD; +C61F;C61F;110B 1168 11BE;C61F;110B 1168 11BE; +C620;C620;110B 1168 11BF;C620;110B 1168 11BF; +C621;C621;110B 1168 11C0;C621;110B 1168 11C0; +C622;C622;110B 1168 11C1;C622;110B 1168 11C1; +C623;C623;110B 1168 11C2;C623;110B 1168 11C2; +C624;C624;110B 1169;C624;110B 1169; +C625;C625;110B 1169 11A8;C625;110B 1169 11A8; +C626;C626;110B 1169 11A9;C626;110B 1169 11A9; +C627;C627;110B 1169 11AA;C627;110B 1169 11AA; +C628;C628;110B 1169 11AB;C628;110B 1169 11AB; +C629;C629;110B 1169 11AC;C629;110B 1169 11AC; +C62A;C62A;110B 1169 11AD;C62A;110B 1169 11AD; +C62B;C62B;110B 1169 11AE;C62B;110B 1169 11AE; +C62C;C62C;110B 1169 11AF;C62C;110B 1169 11AF; +C62D;C62D;110B 1169 11B0;C62D;110B 1169 11B0; +C62E;C62E;110B 1169 11B1;C62E;110B 1169 11B1; +C62F;C62F;110B 1169 11B2;C62F;110B 1169 11B2; +C630;C630;110B 1169 11B3;C630;110B 1169 11B3; +C631;C631;110B 1169 11B4;C631;110B 1169 11B4; +C632;C632;110B 1169 11B5;C632;110B 1169 11B5; +C633;C633;110B 1169 11B6;C633;110B 1169 11B6; +C634;C634;110B 1169 11B7;C634;110B 1169 11B7; +C635;C635;110B 1169 11B8;C635;110B 1169 11B8; +C636;C636;110B 1169 11B9;C636;110B 1169 11B9; +C637;C637;110B 1169 11BA;C637;110B 1169 11BA; +C638;C638;110B 1169 11BB;C638;110B 1169 11BB; +C639;C639;110B 1169 11BC;C639;110B 1169 11BC; +C63A;C63A;110B 1169 11BD;C63A;110B 1169 11BD; +C63B;C63B;110B 1169 11BE;C63B;110B 1169 11BE; +C63C;C63C;110B 1169 11BF;C63C;110B 1169 11BF; +C63D;C63D;110B 1169 11C0;C63D;110B 1169 11C0; +C63E;C63E;110B 1169 11C1;C63E;110B 1169 11C1; +C63F;C63F;110B 1169 11C2;C63F;110B 1169 11C2; +C640;C640;110B 116A;C640;110B 116A; +C641;C641;110B 116A 11A8;C641;110B 116A 11A8; +C642;C642;110B 116A 11A9;C642;110B 116A 11A9; +C643;C643;110B 116A 11AA;C643;110B 116A 11AA; +C644;C644;110B 116A 11AB;C644;110B 116A 11AB; +C645;C645;110B 116A 11AC;C645;110B 116A 11AC; +C646;C646;110B 116A 11AD;C646;110B 116A 11AD; +C647;C647;110B 116A 11AE;C647;110B 116A 11AE; +C648;C648;110B 116A 11AF;C648;110B 116A 11AF; +C649;C649;110B 116A 11B0;C649;110B 116A 11B0; +C64A;C64A;110B 116A 11B1;C64A;110B 116A 11B1; +C64B;C64B;110B 116A 11B2;C64B;110B 116A 11B2; +C64C;C64C;110B 116A 11B3;C64C;110B 116A 11B3; +C64D;C64D;110B 116A 11B4;C64D;110B 116A 11B4; +C64E;C64E;110B 116A 11B5;C64E;110B 116A 11B5; +C64F;C64F;110B 116A 11B6;C64F;110B 116A 11B6; +C650;C650;110B 116A 11B7;C650;110B 116A 11B7; +C651;C651;110B 116A 11B8;C651;110B 116A 11B8; +C652;C652;110B 116A 11B9;C652;110B 116A 11B9; +C653;C653;110B 116A 11BA;C653;110B 116A 11BA; +C654;C654;110B 116A 11BB;C654;110B 116A 11BB; +C655;C655;110B 116A 11BC;C655;110B 116A 11BC; +C656;C656;110B 116A 11BD;C656;110B 116A 11BD; +C657;C657;110B 116A 11BE;C657;110B 116A 11BE; +C658;C658;110B 116A 11BF;C658;110B 116A 11BF; +C659;C659;110B 116A 11C0;C659;110B 116A 11C0; +C65A;C65A;110B 116A 11C1;C65A;110B 116A 11C1; +C65B;C65B;110B 116A 11C2;C65B;110B 116A 11C2; +C65C;C65C;110B 116B;C65C;110B 116B; +C65D;C65D;110B 116B 11A8;C65D;110B 116B 11A8; +C65E;C65E;110B 116B 11A9;C65E;110B 116B 11A9; +C65F;C65F;110B 116B 11AA;C65F;110B 116B 11AA; +C660;C660;110B 116B 11AB;C660;110B 116B 11AB; +C661;C661;110B 116B 11AC;C661;110B 116B 11AC; +C662;C662;110B 116B 11AD;C662;110B 116B 11AD; +C663;C663;110B 116B 11AE;C663;110B 116B 11AE; +C664;C664;110B 116B 11AF;C664;110B 116B 11AF; +C665;C665;110B 116B 11B0;C665;110B 116B 11B0; +C666;C666;110B 116B 11B1;C666;110B 116B 11B1; +C667;C667;110B 116B 11B2;C667;110B 116B 11B2; +C668;C668;110B 116B 11B3;C668;110B 116B 11B3; +C669;C669;110B 116B 11B4;C669;110B 116B 11B4; +C66A;C66A;110B 116B 11B5;C66A;110B 116B 11B5; +C66B;C66B;110B 116B 11B6;C66B;110B 116B 11B6; +C66C;C66C;110B 116B 11B7;C66C;110B 116B 11B7; +C66D;C66D;110B 116B 11B8;C66D;110B 116B 11B8; +C66E;C66E;110B 116B 11B9;C66E;110B 116B 11B9; +C66F;C66F;110B 116B 11BA;C66F;110B 116B 11BA; +C670;C670;110B 116B 11BB;C670;110B 116B 11BB; +C671;C671;110B 116B 11BC;C671;110B 116B 11BC; +C672;C672;110B 116B 11BD;C672;110B 116B 11BD; +C673;C673;110B 116B 11BE;C673;110B 116B 11BE; +C674;C674;110B 116B 11BF;C674;110B 116B 11BF; +C675;C675;110B 116B 11C0;C675;110B 116B 11C0; +C676;C676;110B 116B 11C1;C676;110B 116B 11C1; +C677;C677;110B 116B 11C2;C677;110B 116B 11C2; +C678;C678;110B 116C;C678;110B 116C; +C679;C679;110B 116C 11A8;C679;110B 116C 11A8; +C67A;C67A;110B 116C 11A9;C67A;110B 116C 11A9; +C67B;C67B;110B 116C 11AA;C67B;110B 116C 11AA; +C67C;C67C;110B 116C 11AB;C67C;110B 116C 11AB; +C67D;C67D;110B 116C 11AC;C67D;110B 116C 11AC; +C67E;C67E;110B 116C 11AD;C67E;110B 116C 11AD; +C67F;C67F;110B 116C 11AE;C67F;110B 116C 11AE; +C680;C680;110B 116C 11AF;C680;110B 116C 11AF; +C681;C681;110B 116C 11B0;C681;110B 116C 11B0; +C682;C682;110B 116C 11B1;C682;110B 116C 11B1; +C683;C683;110B 116C 11B2;C683;110B 116C 11B2; +C684;C684;110B 116C 11B3;C684;110B 116C 11B3; +C685;C685;110B 116C 11B4;C685;110B 116C 11B4; +C686;C686;110B 116C 11B5;C686;110B 116C 11B5; +C687;C687;110B 116C 11B6;C687;110B 116C 11B6; +C688;C688;110B 116C 11B7;C688;110B 116C 11B7; +C689;C689;110B 116C 11B8;C689;110B 116C 11B8; +C68A;C68A;110B 116C 11B9;C68A;110B 116C 11B9; +C68B;C68B;110B 116C 11BA;C68B;110B 116C 11BA; +C68C;C68C;110B 116C 11BB;C68C;110B 116C 11BB; +C68D;C68D;110B 116C 11BC;C68D;110B 116C 11BC; +C68E;C68E;110B 116C 11BD;C68E;110B 116C 11BD; +C68F;C68F;110B 116C 11BE;C68F;110B 116C 11BE; +C690;C690;110B 116C 11BF;C690;110B 116C 11BF; +C691;C691;110B 116C 11C0;C691;110B 116C 11C0; +C692;C692;110B 116C 11C1;C692;110B 116C 11C1; +C693;C693;110B 116C 11C2;C693;110B 116C 11C2; +C694;C694;110B 116D;C694;110B 116D; +C695;C695;110B 116D 11A8;C695;110B 116D 11A8; +C696;C696;110B 116D 11A9;C696;110B 116D 11A9; +C697;C697;110B 116D 11AA;C697;110B 116D 11AA; +C698;C698;110B 116D 11AB;C698;110B 116D 11AB; +C699;C699;110B 116D 11AC;C699;110B 116D 11AC; +C69A;C69A;110B 116D 11AD;C69A;110B 116D 11AD; +C69B;C69B;110B 116D 11AE;C69B;110B 116D 11AE; +C69C;C69C;110B 116D 11AF;C69C;110B 116D 11AF; +C69D;C69D;110B 116D 11B0;C69D;110B 116D 11B0; +C69E;C69E;110B 116D 11B1;C69E;110B 116D 11B1; +C69F;C69F;110B 116D 11B2;C69F;110B 116D 11B2; +C6A0;C6A0;110B 116D 11B3;C6A0;110B 116D 11B3; +C6A1;C6A1;110B 116D 11B4;C6A1;110B 116D 11B4; +C6A2;C6A2;110B 116D 11B5;C6A2;110B 116D 11B5; +C6A3;C6A3;110B 116D 11B6;C6A3;110B 116D 11B6; +C6A4;C6A4;110B 116D 11B7;C6A4;110B 116D 11B7; +C6A5;C6A5;110B 116D 11B8;C6A5;110B 116D 11B8; +C6A6;C6A6;110B 116D 11B9;C6A6;110B 116D 11B9; +C6A7;C6A7;110B 116D 11BA;C6A7;110B 116D 11BA; +C6A8;C6A8;110B 116D 11BB;C6A8;110B 116D 11BB; +C6A9;C6A9;110B 116D 11BC;C6A9;110B 116D 11BC; +C6AA;C6AA;110B 116D 11BD;C6AA;110B 116D 11BD; +C6AB;C6AB;110B 116D 11BE;C6AB;110B 116D 11BE; +C6AC;C6AC;110B 116D 11BF;C6AC;110B 116D 11BF; +C6AD;C6AD;110B 116D 11C0;C6AD;110B 116D 11C0; +C6AE;C6AE;110B 116D 11C1;C6AE;110B 116D 11C1; +C6AF;C6AF;110B 116D 11C2;C6AF;110B 116D 11C2; +C6B0;C6B0;110B 116E;C6B0;110B 116E; +C6B1;C6B1;110B 116E 11A8;C6B1;110B 116E 11A8; +C6B2;C6B2;110B 116E 11A9;C6B2;110B 116E 11A9; +C6B3;C6B3;110B 116E 11AA;C6B3;110B 116E 11AA; +C6B4;C6B4;110B 116E 11AB;C6B4;110B 116E 11AB; +C6B5;C6B5;110B 116E 11AC;C6B5;110B 116E 11AC; +C6B6;C6B6;110B 116E 11AD;C6B6;110B 116E 11AD; +C6B7;C6B7;110B 116E 11AE;C6B7;110B 116E 11AE; +C6B8;C6B8;110B 116E 11AF;C6B8;110B 116E 11AF; +C6B9;C6B9;110B 116E 11B0;C6B9;110B 116E 11B0; +C6BA;C6BA;110B 116E 11B1;C6BA;110B 116E 11B1; +C6BB;C6BB;110B 116E 11B2;C6BB;110B 116E 11B2; +C6BC;C6BC;110B 116E 11B3;C6BC;110B 116E 11B3; +C6BD;C6BD;110B 116E 11B4;C6BD;110B 116E 11B4; +C6BE;C6BE;110B 116E 11B5;C6BE;110B 116E 11B5; +C6BF;C6BF;110B 116E 11B6;C6BF;110B 116E 11B6; +C6C0;C6C0;110B 116E 11B7;C6C0;110B 116E 11B7; +C6C1;C6C1;110B 116E 11B8;C6C1;110B 116E 11B8; +C6C2;C6C2;110B 116E 11B9;C6C2;110B 116E 11B9; +C6C3;C6C3;110B 116E 11BA;C6C3;110B 116E 11BA; +C6C4;C6C4;110B 116E 11BB;C6C4;110B 116E 11BB; +C6C5;C6C5;110B 116E 11BC;C6C5;110B 116E 11BC; +C6C6;C6C6;110B 116E 11BD;C6C6;110B 116E 11BD; +C6C7;C6C7;110B 116E 11BE;C6C7;110B 116E 11BE; +C6C8;C6C8;110B 116E 11BF;C6C8;110B 116E 11BF; +C6C9;C6C9;110B 116E 11C0;C6C9;110B 116E 11C0; +C6CA;C6CA;110B 116E 11C1;C6CA;110B 116E 11C1; +C6CB;C6CB;110B 116E 11C2;C6CB;110B 116E 11C2; +C6CC;C6CC;110B 116F;C6CC;110B 116F; +C6CD;C6CD;110B 116F 11A8;C6CD;110B 116F 11A8; +C6CE;C6CE;110B 116F 11A9;C6CE;110B 116F 11A9; +C6CF;C6CF;110B 116F 11AA;C6CF;110B 116F 11AA; +C6D0;C6D0;110B 116F 11AB;C6D0;110B 116F 11AB; +C6D1;C6D1;110B 116F 11AC;C6D1;110B 116F 11AC; +C6D2;C6D2;110B 116F 11AD;C6D2;110B 116F 11AD; +C6D3;C6D3;110B 116F 11AE;C6D3;110B 116F 11AE; +C6D4;C6D4;110B 116F 11AF;C6D4;110B 116F 11AF; +C6D5;C6D5;110B 116F 11B0;C6D5;110B 116F 11B0; +C6D6;C6D6;110B 116F 11B1;C6D6;110B 116F 11B1; +C6D7;C6D7;110B 116F 11B2;C6D7;110B 116F 11B2; +C6D8;C6D8;110B 116F 11B3;C6D8;110B 116F 11B3; +C6D9;C6D9;110B 116F 11B4;C6D9;110B 116F 11B4; +C6DA;C6DA;110B 116F 11B5;C6DA;110B 116F 11B5; +C6DB;C6DB;110B 116F 11B6;C6DB;110B 116F 11B6; +C6DC;C6DC;110B 116F 11B7;C6DC;110B 116F 11B7; +C6DD;C6DD;110B 116F 11B8;C6DD;110B 116F 11B8; +C6DE;C6DE;110B 116F 11B9;C6DE;110B 116F 11B9; +C6DF;C6DF;110B 116F 11BA;C6DF;110B 116F 11BA; +C6E0;C6E0;110B 116F 11BB;C6E0;110B 116F 11BB; +C6E1;C6E1;110B 116F 11BC;C6E1;110B 116F 11BC; +C6E2;C6E2;110B 116F 11BD;C6E2;110B 116F 11BD; +C6E3;C6E3;110B 116F 11BE;C6E3;110B 116F 11BE; +C6E4;C6E4;110B 116F 11BF;C6E4;110B 116F 11BF; +C6E5;C6E5;110B 116F 11C0;C6E5;110B 116F 11C0; +C6E6;C6E6;110B 116F 11C1;C6E6;110B 116F 11C1; +C6E7;C6E7;110B 116F 11C2;C6E7;110B 116F 11C2; +C6E8;C6E8;110B 1170;C6E8;110B 1170; +C6E9;C6E9;110B 1170 11A8;C6E9;110B 1170 11A8; +C6EA;C6EA;110B 1170 11A9;C6EA;110B 1170 11A9; +C6EB;C6EB;110B 1170 11AA;C6EB;110B 1170 11AA; +C6EC;C6EC;110B 1170 11AB;C6EC;110B 1170 11AB; +C6ED;C6ED;110B 1170 11AC;C6ED;110B 1170 11AC; +C6EE;C6EE;110B 1170 11AD;C6EE;110B 1170 11AD; +C6EF;C6EF;110B 1170 11AE;C6EF;110B 1170 11AE; +C6F0;C6F0;110B 1170 11AF;C6F0;110B 1170 11AF; +C6F1;C6F1;110B 1170 11B0;C6F1;110B 1170 11B0; +C6F2;C6F2;110B 1170 11B1;C6F2;110B 1170 11B1; +C6F3;C6F3;110B 1170 11B2;C6F3;110B 1170 11B2; +C6F4;C6F4;110B 1170 11B3;C6F4;110B 1170 11B3; +C6F5;C6F5;110B 1170 11B4;C6F5;110B 1170 11B4; +C6F6;C6F6;110B 1170 11B5;C6F6;110B 1170 11B5; +C6F7;C6F7;110B 1170 11B6;C6F7;110B 1170 11B6; +C6F8;C6F8;110B 1170 11B7;C6F8;110B 1170 11B7; +C6F9;C6F9;110B 1170 11B8;C6F9;110B 1170 11B8; +C6FA;C6FA;110B 1170 11B9;C6FA;110B 1170 11B9; +C6FB;C6FB;110B 1170 11BA;C6FB;110B 1170 11BA; +C6FC;C6FC;110B 1170 11BB;C6FC;110B 1170 11BB; +C6FD;C6FD;110B 1170 11BC;C6FD;110B 1170 11BC; +C6FE;C6FE;110B 1170 11BD;C6FE;110B 1170 11BD; +C6FF;C6FF;110B 1170 11BE;C6FF;110B 1170 11BE; +C700;C700;110B 1170 11BF;C700;110B 1170 11BF; +C701;C701;110B 1170 11C0;C701;110B 1170 11C0; +C702;C702;110B 1170 11C1;C702;110B 1170 11C1; +C703;C703;110B 1170 11C2;C703;110B 1170 11C2; +C704;C704;110B 1171;C704;110B 1171; +C705;C705;110B 1171 11A8;C705;110B 1171 11A8; +C706;C706;110B 1171 11A9;C706;110B 1171 11A9; +C707;C707;110B 1171 11AA;C707;110B 1171 11AA; +C708;C708;110B 1171 11AB;C708;110B 1171 11AB; +C709;C709;110B 1171 11AC;C709;110B 1171 11AC; +C70A;C70A;110B 1171 11AD;C70A;110B 1171 11AD; +C70B;C70B;110B 1171 11AE;C70B;110B 1171 11AE; +C70C;C70C;110B 1171 11AF;C70C;110B 1171 11AF; +C70D;C70D;110B 1171 11B0;C70D;110B 1171 11B0; +C70E;C70E;110B 1171 11B1;C70E;110B 1171 11B1; +C70F;C70F;110B 1171 11B2;C70F;110B 1171 11B2; +C710;C710;110B 1171 11B3;C710;110B 1171 11B3; +C711;C711;110B 1171 11B4;C711;110B 1171 11B4; +C712;C712;110B 1171 11B5;C712;110B 1171 11B5; +C713;C713;110B 1171 11B6;C713;110B 1171 11B6; +C714;C714;110B 1171 11B7;C714;110B 1171 11B7; +C715;C715;110B 1171 11B8;C715;110B 1171 11B8; +C716;C716;110B 1171 11B9;C716;110B 1171 11B9; +C717;C717;110B 1171 11BA;C717;110B 1171 11BA; +C718;C718;110B 1171 11BB;C718;110B 1171 11BB; +C719;C719;110B 1171 11BC;C719;110B 1171 11BC; +C71A;C71A;110B 1171 11BD;C71A;110B 1171 11BD; +C71B;C71B;110B 1171 11BE;C71B;110B 1171 11BE; +C71C;C71C;110B 1171 11BF;C71C;110B 1171 11BF; +C71D;C71D;110B 1171 11C0;C71D;110B 1171 11C0; +C71E;C71E;110B 1171 11C1;C71E;110B 1171 11C1; +C71F;C71F;110B 1171 11C2;C71F;110B 1171 11C2; +C720;C720;110B 1172;C720;110B 1172; +C721;C721;110B 1172 11A8;C721;110B 1172 11A8; +C722;C722;110B 1172 11A9;C722;110B 1172 11A9; +C723;C723;110B 1172 11AA;C723;110B 1172 11AA; +C724;C724;110B 1172 11AB;C724;110B 1172 11AB; +C725;C725;110B 1172 11AC;C725;110B 1172 11AC; +C726;C726;110B 1172 11AD;C726;110B 1172 11AD; +C727;C727;110B 1172 11AE;C727;110B 1172 11AE; +C728;C728;110B 1172 11AF;C728;110B 1172 11AF; +C729;C729;110B 1172 11B0;C729;110B 1172 11B0; +C72A;C72A;110B 1172 11B1;C72A;110B 1172 11B1; +C72B;C72B;110B 1172 11B2;C72B;110B 1172 11B2; +C72C;C72C;110B 1172 11B3;C72C;110B 1172 11B3; +C72D;C72D;110B 1172 11B4;C72D;110B 1172 11B4; +C72E;C72E;110B 1172 11B5;C72E;110B 1172 11B5; +C72F;C72F;110B 1172 11B6;C72F;110B 1172 11B6; +C730;C730;110B 1172 11B7;C730;110B 1172 11B7; +C731;C731;110B 1172 11B8;C731;110B 1172 11B8; +C732;C732;110B 1172 11B9;C732;110B 1172 11B9; +C733;C733;110B 1172 11BA;C733;110B 1172 11BA; +C734;C734;110B 1172 11BB;C734;110B 1172 11BB; +C735;C735;110B 1172 11BC;C735;110B 1172 11BC; +C736;C736;110B 1172 11BD;C736;110B 1172 11BD; +C737;C737;110B 1172 11BE;C737;110B 1172 11BE; +C738;C738;110B 1172 11BF;C738;110B 1172 11BF; +C739;C739;110B 1172 11C0;C739;110B 1172 11C0; +C73A;C73A;110B 1172 11C1;C73A;110B 1172 11C1; +C73B;C73B;110B 1172 11C2;C73B;110B 1172 11C2; +C73C;C73C;110B 1173;C73C;110B 1173; +C73D;C73D;110B 1173 11A8;C73D;110B 1173 11A8; +C73E;C73E;110B 1173 11A9;C73E;110B 1173 11A9; +C73F;C73F;110B 1173 11AA;C73F;110B 1173 11AA; +C740;C740;110B 1173 11AB;C740;110B 1173 11AB; +C741;C741;110B 1173 11AC;C741;110B 1173 11AC; +C742;C742;110B 1173 11AD;C742;110B 1173 11AD; +C743;C743;110B 1173 11AE;C743;110B 1173 11AE; +C744;C744;110B 1173 11AF;C744;110B 1173 11AF; +C745;C745;110B 1173 11B0;C745;110B 1173 11B0; +C746;C746;110B 1173 11B1;C746;110B 1173 11B1; +C747;C747;110B 1173 11B2;C747;110B 1173 11B2; +C748;C748;110B 1173 11B3;C748;110B 1173 11B3; +C749;C749;110B 1173 11B4;C749;110B 1173 11B4; +C74A;C74A;110B 1173 11B5;C74A;110B 1173 11B5; +C74B;C74B;110B 1173 11B6;C74B;110B 1173 11B6; +C74C;C74C;110B 1173 11B7;C74C;110B 1173 11B7; +C74D;C74D;110B 1173 11B8;C74D;110B 1173 11B8; +C74E;C74E;110B 1173 11B9;C74E;110B 1173 11B9; +C74F;C74F;110B 1173 11BA;C74F;110B 1173 11BA; +C750;C750;110B 1173 11BB;C750;110B 1173 11BB; +C751;C751;110B 1173 11BC;C751;110B 1173 11BC; +C752;C752;110B 1173 11BD;C752;110B 1173 11BD; +C753;C753;110B 1173 11BE;C753;110B 1173 11BE; +C754;C754;110B 1173 11BF;C754;110B 1173 11BF; +C755;C755;110B 1173 11C0;C755;110B 1173 11C0; +C756;C756;110B 1173 11C1;C756;110B 1173 11C1; +C757;C757;110B 1173 11C2;C757;110B 1173 11C2; +C758;C758;110B 1174;C758;110B 1174; +C759;C759;110B 1174 11A8;C759;110B 1174 11A8; +C75A;C75A;110B 1174 11A9;C75A;110B 1174 11A9; +C75B;C75B;110B 1174 11AA;C75B;110B 1174 11AA; +C75C;C75C;110B 1174 11AB;C75C;110B 1174 11AB; +C75D;C75D;110B 1174 11AC;C75D;110B 1174 11AC; +C75E;C75E;110B 1174 11AD;C75E;110B 1174 11AD; +C75F;C75F;110B 1174 11AE;C75F;110B 1174 11AE; +C760;C760;110B 1174 11AF;C760;110B 1174 11AF; +C761;C761;110B 1174 11B0;C761;110B 1174 11B0; +C762;C762;110B 1174 11B1;C762;110B 1174 11B1; +C763;C763;110B 1174 11B2;C763;110B 1174 11B2; +C764;C764;110B 1174 11B3;C764;110B 1174 11B3; +C765;C765;110B 1174 11B4;C765;110B 1174 11B4; +C766;C766;110B 1174 11B5;C766;110B 1174 11B5; +C767;C767;110B 1174 11B6;C767;110B 1174 11B6; +C768;C768;110B 1174 11B7;C768;110B 1174 11B7; +C769;C769;110B 1174 11B8;C769;110B 1174 11B8; +C76A;C76A;110B 1174 11B9;C76A;110B 1174 11B9; +C76B;C76B;110B 1174 11BA;C76B;110B 1174 11BA; +C76C;C76C;110B 1174 11BB;C76C;110B 1174 11BB; +C76D;C76D;110B 1174 11BC;C76D;110B 1174 11BC; +C76E;C76E;110B 1174 11BD;C76E;110B 1174 11BD; +C76F;C76F;110B 1174 11BE;C76F;110B 1174 11BE; +C770;C770;110B 1174 11BF;C770;110B 1174 11BF; +C771;C771;110B 1174 11C0;C771;110B 1174 11C0; +C772;C772;110B 1174 11C1;C772;110B 1174 11C1; +C773;C773;110B 1174 11C2;C773;110B 1174 11C2; +C774;C774;110B 1175;C774;110B 1175; +C775;C775;110B 1175 11A8;C775;110B 1175 11A8; +C776;C776;110B 1175 11A9;C776;110B 1175 11A9; +C777;C777;110B 1175 11AA;C777;110B 1175 11AA; +C778;C778;110B 1175 11AB;C778;110B 1175 11AB; +C779;C779;110B 1175 11AC;C779;110B 1175 11AC; +C77A;C77A;110B 1175 11AD;C77A;110B 1175 11AD; +C77B;C77B;110B 1175 11AE;C77B;110B 1175 11AE; +C77C;C77C;110B 1175 11AF;C77C;110B 1175 11AF; +C77D;C77D;110B 1175 11B0;C77D;110B 1175 11B0; +C77E;C77E;110B 1175 11B1;C77E;110B 1175 11B1; +C77F;C77F;110B 1175 11B2;C77F;110B 1175 11B2; +C780;C780;110B 1175 11B3;C780;110B 1175 11B3; +C781;C781;110B 1175 11B4;C781;110B 1175 11B4; +C782;C782;110B 1175 11B5;C782;110B 1175 11B5; +C783;C783;110B 1175 11B6;C783;110B 1175 11B6; +C784;C784;110B 1175 11B7;C784;110B 1175 11B7; +C785;C785;110B 1175 11B8;C785;110B 1175 11B8; +C786;C786;110B 1175 11B9;C786;110B 1175 11B9; +C787;C787;110B 1175 11BA;C787;110B 1175 11BA; +C788;C788;110B 1175 11BB;C788;110B 1175 11BB; +C789;C789;110B 1175 11BC;C789;110B 1175 11BC; +C78A;C78A;110B 1175 11BD;C78A;110B 1175 11BD; +C78B;C78B;110B 1175 11BE;C78B;110B 1175 11BE; +C78C;C78C;110B 1175 11BF;C78C;110B 1175 11BF; +C78D;C78D;110B 1175 11C0;C78D;110B 1175 11C0; +C78E;C78E;110B 1175 11C1;C78E;110B 1175 11C1; +C78F;C78F;110B 1175 11C2;C78F;110B 1175 11C2; +C790;C790;110C 1161;C790;110C 1161; +C791;C791;110C 1161 11A8;C791;110C 1161 11A8; +C792;C792;110C 1161 11A9;C792;110C 1161 11A9; +C793;C793;110C 1161 11AA;C793;110C 1161 11AA; +C794;C794;110C 1161 11AB;C794;110C 1161 11AB; +C795;C795;110C 1161 11AC;C795;110C 1161 11AC; +C796;C796;110C 1161 11AD;C796;110C 1161 11AD; +C797;C797;110C 1161 11AE;C797;110C 1161 11AE; +C798;C798;110C 1161 11AF;C798;110C 1161 11AF; +C799;C799;110C 1161 11B0;C799;110C 1161 11B0; +C79A;C79A;110C 1161 11B1;C79A;110C 1161 11B1; +C79B;C79B;110C 1161 11B2;C79B;110C 1161 11B2; +C79C;C79C;110C 1161 11B3;C79C;110C 1161 11B3; +C79D;C79D;110C 1161 11B4;C79D;110C 1161 11B4; +C79E;C79E;110C 1161 11B5;C79E;110C 1161 11B5; +C79F;C79F;110C 1161 11B6;C79F;110C 1161 11B6; +C7A0;C7A0;110C 1161 11B7;C7A0;110C 1161 11B7; +C7A1;C7A1;110C 1161 11B8;C7A1;110C 1161 11B8; +C7A2;C7A2;110C 1161 11B9;C7A2;110C 1161 11B9; +C7A3;C7A3;110C 1161 11BA;C7A3;110C 1161 11BA; +C7A4;C7A4;110C 1161 11BB;C7A4;110C 1161 11BB; +C7A5;C7A5;110C 1161 11BC;C7A5;110C 1161 11BC; +C7A6;C7A6;110C 1161 11BD;C7A6;110C 1161 11BD; +C7A7;C7A7;110C 1161 11BE;C7A7;110C 1161 11BE; +C7A8;C7A8;110C 1161 11BF;C7A8;110C 1161 11BF; +C7A9;C7A9;110C 1161 11C0;C7A9;110C 1161 11C0; +C7AA;C7AA;110C 1161 11C1;C7AA;110C 1161 11C1; +C7AB;C7AB;110C 1161 11C2;C7AB;110C 1161 11C2; +C7AC;C7AC;110C 1162;C7AC;110C 1162; +C7AD;C7AD;110C 1162 11A8;C7AD;110C 1162 11A8; +C7AE;C7AE;110C 1162 11A9;C7AE;110C 1162 11A9; +C7AF;C7AF;110C 1162 11AA;C7AF;110C 1162 11AA; +C7B0;C7B0;110C 1162 11AB;C7B0;110C 1162 11AB; +C7B1;C7B1;110C 1162 11AC;C7B1;110C 1162 11AC; +C7B2;C7B2;110C 1162 11AD;C7B2;110C 1162 11AD; +C7B3;C7B3;110C 1162 11AE;C7B3;110C 1162 11AE; +C7B4;C7B4;110C 1162 11AF;C7B4;110C 1162 11AF; +C7B5;C7B5;110C 1162 11B0;C7B5;110C 1162 11B0; +C7B6;C7B6;110C 1162 11B1;C7B6;110C 1162 11B1; +C7B7;C7B7;110C 1162 11B2;C7B7;110C 1162 11B2; +C7B8;C7B8;110C 1162 11B3;C7B8;110C 1162 11B3; +C7B9;C7B9;110C 1162 11B4;C7B9;110C 1162 11B4; +C7BA;C7BA;110C 1162 11B5;C7BA;110C 1162 11B5; +C7BB;C7BB;110C 1162 11B6;C7BB;110C 1162 11B6; +C7BC;C7BC;110C 1162 11B7;C7BC;110C 1162 11B7; +C7BD;C7BD;110C 1162 11B8;C7BD;110C 1162 11B8; +C7BE;C7BE;110C 1162 11B9;C7BE;110C 1162 11B9; +C7BF;C7BF;110C 1162 11BA;C7BF;110C 1162 11BA; +C7C0;C7C0;110C 1162 11BB;C7C0;110C 1162 11BB; +C7C1;C7C1;110C 1162 11BC;C7C1;110C 1162 11BC; +C7C2;C7C2;110C 1162 11BD;C7C2;110C 1162 11BD; +C7C3;C7C3;110C 1162 11BE;C7C3;110C 1162 11BE; +C7C4;C7C4;110C 1162 11BF;C7C4;110C 1162 11BF; +C7C5;C7C5;110C 1162 11C0;C7C5;110C 1162 11C0; +C7C6;C7C6;110C 1162 11C1;C7C6;110C 1162 11C1; +C7C7;C7C7;110C 1162 11C2;C7C7;110C 1162 11C2; +C7C8;C7C8;110C 1163;C7C8;110C 1163; +C7C9;C7C9;110C 1163 11A8;C7C9;110C 1163 11A8; +C7CA;C7CA;110C 1163 11A9;C7CA;110C 1163 11A9; +C7CB;C7CB;110C 1163 11AA;C7CB;110C 1163 11AA; +C7CC;C7CC;110C 1163 11AB;C7CC;110C 1163 11AB; +C7CD;C7CD;110C 1163 11AC;C7CD;110C 1163 11AC; +C7CE;C7CE;110C 1163 11AD;C7CE;110C 1163 11AD; +C7CF;C7CF;110C 1163 11AE;C7CF;110C 1163 11AE; +C7D0;C7D0;110C 1163 11AF;C7D0;110C 1163 11AF; +C7D1;C7D1;110C 1163 11B0;C7D1;110C 1163 11B0; +C7D2;C7D2;110C 1163 11B1;C7D2;110C 1163 11B1; +C7D3;C7D3;110C 1163 11B2;C7D3;110C 1163 11B2; +C7D4;C7D4;110C 1163 11B3;C7D4;110C 1163 11B3; +C7D5;C7D5;110C 1163 11B4;C7D5;110C 1163 11B4; +C7D6;C7D6;110C 1163 11B5;C7D6;110C 1163 11B5; +C7D7;C7D7;110C 1163 11B6;C7D7;110C 1163 11B6; +C7D8;C7D8;110C 1163 11B7;C7D8;110C 1163 11B7; +C7D9;C7D9;110C 1163 11B8;C7D9;110C 1163 11B8; +C7DA;C7DA;110C 1163 11B9;C7DA;110C 1163 11B9; +C7DB;C7DB;110C 1163 11BA;C7DB;110C 1163 11BA; +C7DC;C7DC;110C 1163 11BB;C7DC;110C 1163 11BB; +C7DD;C7DD;110C 1163 11BC;C7DD;110C 1163 11BC; +C7DE;C7DE;110C 1163 11BD;C7DE;110C 1163 11BD; +C7DF;C7DF;110C 1163 11BE;C7DF;110C 1163 11BE; +C7E0;C7E0;110C 1163 11BF;C7E0;110C 1163 11BF; +C7E1;C7E1;110C 1163 11C0;C7E1;110C 1163 11C0; +C7E2;C7E2;110C 1163 11C1;C7E2;110C 1163 11C1; +C7E3;C7E3;110C 1163 11C2;C7E3;110C 1163 11C2; +C7E4;C7E4;110C 1164;C7E4;110C 1164; +C7E5;C7E5;110C 1164 11A8;C7E5;110C 1164 11A8; +C7E6;C7E6;110C 1164 11A9;C7E6;110C 1164 11A9; +C7E7;C7E7;110C 1164 11AA;C7E7;110C 1164 11AA; +C7E8;C7E8;110C 1164 11AB;C7E8;110C 1164 11AB; +C7E9;C7E9;110C 1164 11AC;C7E9;110C 1164 11AC; +C7EA;C7EA;110C 1164 11AD;C7EA;110C 1164 11AD; +C7EB;C7EB;110C 1164 11AE;C7EB;110C 1164 11AE; +C7EC;C7EC;110C 1164 11AF;C7EC;110C 1164 11AF; +C7ED;C7ED;110C 1164 11B0;C7ED;110C 1164 11B0; +C7EE;C7EE;110C 1164 11B1;C7EE;110C 1164 11B1; +C7EF;C7EF;110C 1164 11B2;C7EF;110C 1164 11B2; +C7F0;C7F0;110C 1164 11B3;C7F0;110C 1164 11B3; +C7F1;C7F1;110C 1164 11B4;C7F1;110C 1164 11B4; +C7F2;C7F2;110C 1164 11B5;C7F2;110C 1164 11B5; +C7F3;C7F3;110C 1164 11B6;C7F3;110C 1164 11B6; +C7F4;C7F4;110C 1164 11B7;C7F4;110C 1164 11B7; +C7F5;C7F5;110C 1164 11B8;C7F5;110C 1164 11B8; +C7F6;C7F6;110C 1164 11B9;C7F6;110C 1164 11B9; +C7F7;C7F7;110C 1164 11BA;C7F7;110C 1164 11BA; +C7F8;C7F8;110C 1164 11BB;C7F8;110C 1164 11BB; +C7F9;C7F9;110C 1164 11BC;C7F9;110C 1164 11BC; +C7FA;C7FA;110C 1164 11BD;C7FA;110C 1164 11BD; +C7FB;C7FB;110C 1164 11BE;C7FB;110C 1164 11BE; +C7FC;C7FC;110C 1164 11BF;C7FC;110C 1164 11BF; +C7FD;C7FD;110C 1164 11C0;C7FD;110C 1164 11C0; +C7FE;C7FE;110C 1164 11C1;C7FE;110C 1164 11C1; +C7FF;C7FF;110C 1164 11C2;C7FF;110C 1164 11C2; +C800;C800;110C 1165;C800;110C 1165; +C801;C801;110C 1165 11A8;C801;110C 1165 11A8; +C802;C802;110C 1165 11A9;C802;110C 1165 11A9; +C803;C803;110C 1165 11AA;C803;110C 1165 11AA; +C804;C804;110C 1165 11AB;C804;110C 1165 11AB; +C805;C805;110C 1165 11AC;C805;110C 1165 11AC; +C806;C806;110C 1165 11AD;C806;110C 1165 11AD; +C807;C807;110C 1165 11AE;C807;110C 1165 11AE; +C808;C808;110C 1165 11AF;C808;110C 1165 11AF; +C809;C809;110C 1165 11B0;C809;110C 1165 11B0; +C80A;C80A;110C 1165 11B1;C80A;110C 1165 11B1; +C80B;C80B;110C 1165 11B2;C80B;110C 1165 11B2; +C80C;C80C;110C 1165 11B3;C80C;110C 1165 11B3; +C80D;C80D;110C 1165 11B4;C80D;110C 1165 11B4; +C80E;C80E;110C 1165 11B5;C80E;110C 1165 11B5; +C80F;C80F;110C 1165 11B6;C80F;110C 1165 11B6; +C810;C810;110C 1165 11B7;C810;110C 1165 11B7; +C811;C811;110C 1165 11B8;C811;110C 1165 11B8; +C812;C812;110C 1165 11B9;C812;110C 1165 11B9; +C813;C813;110C 1165 11BA;C813;110C 1165 11BA; +C814;C814;110C 1165 11BB;C814;110C 1165 11BB; +C815;C815;110C 1165 11BC;C815;110C 1165 11BC; +C816;C816;110C 1165 11BD;C816;110C 1165 11BD; +C817;C817;110C 1165 11BE;C817;110C 1165 11BE; +C818;C818;110C 1165 11BF;C818;110C 1165 11BF; +C819;C819;110C 1165 11C0;C819;110C 1165 11C0; +C81A;C81A;110C 1165 11C1;C81A;110C 1165 11C1; +C81B;C81B;110C 1165 11C2;C81B;110C 1165 11C2; +C81C;C81C;110C 1166;C81C;110C 1166; +C81D;C81D;110C 1166 11A8;C81D;110C 1166 11A8; +C81E;C81E;110C 1166 11A9;C81E;110C 1166 11A9; +C81F;C81F;110C 1166 11AA;C81F;110C 1166 11AA; +C820;C820;110C 1166 11AB;C820;110C 1166 11AB; +C821;C821;110C 1166 11AC;C821;110C 1166 11AC; +C822;C822;110C 1166 11AD;C822;110C 1166 11AD; +C823;C823;110C 1166 11AE;C823;110C 1166 11AE; +C824;C824;110C 1166 11AF;C824;110C 1166 11AF; +C825;C825;110C 1166 11B0;C825;110C 1166 11B0; +C826;C826;110C 1166 11B1;C826;110C 1166 11B1; +C827;C827;110C 1166 11B2;C827;110C 1166 11B2; +C828;C828;110C 1166 11B3;C828;110C 1166 11B3; +C829;C829;110C 1166 11B4;C829;110C 1166 11B4; +C82A;C82A;110C 1166 11B5;C82A;110C 1166 11B5; +C82B;C82B;110C 1166 11B6;C82B;110C 1166 11B6; +C82C;C82C;110C 1166 11B7;C82C;110C 1166 11B7; +C82D;C82D;110C 1166 11B8;C82D;110C 1166 11B8; +C82E;C82E;110C 1166 11B9;C82E;110C 1166 11B9; +C82F;C82F;110C 1166 11BA;C82F;110C 1166 11BA; +C830;C830;110C 1166 11BB;C830;110C 1166 11BB; +C831;C831;110C 1166 11BC;C831;110C 1166 11BC; +C832;C832;110C 1166 11BD;C832;110C 1166 11BD; +C833;C833;110C 1166 11BE;C833;110C 1166 11BE; +C834;C834;110C 1166 11BF;C834;110C 1166 11BF; +C835;C835;110C 1166 11C0;C835;110C 1166 11C0; +C836;C836;110C 1166 11C1;C836;110C 1166 11C1; +C837;C837;110C 1166 11C2;C837;110C 1166 11C2; +C838;C838;110C 1167;C838;110C 1167; +C839;C839;110C 1167 11A8;C839;110C 1167 11A8; +C83A;C83A;110C 1167 11A9;C83A;110C 1167 11A9; +C83B;C83B;110C 1167 11AA;C83B;110C 1167 11AA; +C83C;C83C;110C 1167 11AB;C83C;110C 1167 11AB; +C83D;C83D;110C 1167 11AC;C83D;110C 1167 11AC; +C83E;C83E;110C 1167 11AD;C83E;110C 1167 11AD; +C83F;C83F;110C 1167 11AE;C83F;110C 1167 11AE; +C840;C840;110C 1167 11AF;C840;110C 1167 11AF; +C841;C841;110C 1167 11B0;C841;110C 1167 11B0; +C842;C842;110C 1167 11B1;C842;110C 1167 11B1; +C843;C843;110C 1167 11B2;C843;110C 1167 11B2; +C844;C844;110C 1167 11B3;C844;110C 1167 11B3; +C845;C845;110C 1167 11B4;C845;110C 1167 11B4; +C846;C846;110C 1167 11B5;C846;110C 1167 11B5; +C847;C847;110C 1167 11B6;C847;110C 1167 11B6; +C848;C848;110C 1167 11B7;C848;110C 1167 11B7; +C849;C849;110C 1167 11B8;C849;110C 1167 11B8; +C84A;C84A;110C 1167 11B9;C84A;110C 1167 11B9; +C84B;C84B;110C 1167 11BA;C84B;110C 1167 11BA; +C84C;C84C;110C 1167 11BB;C84C;110C 1167 11BB; +C84D;C84D;110C 1167 11BC;C84D;110C 1167 11BC; +C84E;C84E;110C 1167 11BD;C84E;110C 1167 11BD; +C84F;C84F;110C 1167 11BE;C84F;110C 1167 11BE; +C850;C850;110C 1167 11BF;C850;110C 1167 11BF; +C851;C851;110C 1167 11C0;C851;110C 1167 11C0; +C852;C852;110C 1167 11C1;C852;110C 1167 11C1; +C853;C853;110C 1167 11C2;C853;110C 1167 11C2; +C854;C854;110C 1168;C854;110C 1168; +C855;C855;110C 1168 11A8;C855;110C 1168 11A8; +C856;C856;110C 1168 11A9;C856;110C 1168 11A9; +C857;C857;110C 1168 11AA;C857;110C 1168 11AA; +C858;C858;110C 1168 11AB;C858;110C 1168 11AB; +C859;C859;110C 1168 11AC;C859;110C 1168 11AC; +C85A;C85A;110C 1168 11AD;C85A;110C 1168 11AD; +C85B;C85B;110C 1168 11AE;C85B;110C 1168 11AE; +C85C;C85C;110C 1168 11AF;C85C;110C 1168 11AF; +C85D;C85D;110C 1168 11B0;C85D;110C 1168 11B0; +C85E;C85E;110C 1168 11B1;C85E;110C 1168 11B1; +C85F;C85F;110C 1168 11B2;C85F;110C 1168 11B2; +C860;C860;110C 1168 11B3;C860;110C 1168 11B3; +C861;C861;110C 1168 11B4;C861;110C 1168 11B4; +C862;C862;110C 1168 11B5;C862;110C 1168 11B5; +C863;C863;110C 1168 11B6;C863;110C 1168 11B6; +C864;C864;110C 1168 11B7;C864;110C 1168 11B7; +C865;C865;110C 1168 11B8;C865;110C 1168 11B8; +C866;C866;110C 1168 11B9;C866;110C 1168 11B9; +C867;C867;110C 1168 11BA;C867;110C 1168 11BA; +C868;C868;110C 1168 11BB;C868;110C 1168 11BB; +C869;C869;110C 1168 11BC;C869;110C 1168 11BC; +C86A;C86A;110C 1168 11BD;C86A;110C 1168 11BD; +C86B;C86B;110C 1168 11BE;C86B;110C 1168 11BE; +C86C;C86C;110C 1168 11BF;C86C;110C 1168 11BF; +C86D;C86D;110C 1168 11C0;C86D;110C 1168 11C0; +C86E;C86E;110C 1168 11C1;C86E;110C 1168 11C1; +C86F;C86F;110C 1168 11C2;C86F;110C 1168 11C2; +C870;C870;110C 1169;C870;110C 1169; +C871;C871;110C 1169 11A8;C871;110C 1169 11A8; +C872;C872;110C 1169 11A9;C872;110C 1169 11A9; +C873;C873;110C 1169 11AA;C873;110C 1169 11AA; +C874;C874;110C 1169 11AB;C874;110C 1169 11AB; +C875;C875;110C 1169 11AC;C875;110C 1169 11AC; +C876;C876;110C 1169 11AD;C876;110C 1169 11AD; +C877;C877;110C 1169 11AE;C877;110C 1169 11AE; +C878;C878;110C 1169 11AF;C878;110C 1169 11AF; +C879;C879;110C 1169 11B0;C879;110C 1169 11B0; +C87A;C87A;110C 1169 11B1;C87A;110C 1169 11B1; +C87B;C87B;110C 1169 11B2;C87B;110C 1169 11B2; +C87C;C87C;110C 1169 11B3;C87C;110C 1169 11B3; +C87D;C87D;110C 1169 11B4;C87D;110C 1169 11B4; +C87E;C87E;110C 1169 11B5;C87E;110C 1169 11B5; +C87F;C87F;110C 1169 11B6;C87F;110C 1169 11B6; +C880;C880;110C 1169 11B7;C880;110C 1169 11B7; +C881;C881;110C 1169 11B8;C881;110C 1169 11B8; +C882;C882;110C 1169 11B9;C882;110C 1169 11B9; +C883;C883;110C 1169 11BA;C883;110C 1169 11BA; +C884;C884;110C 1169 11BB;C884;110C 1169 11BB; +C885;C885;110C 1169 11BC;C885;110C 1169 11BC; +C886;C886;110C 1169 11BD;C886;110C 1169 11BD; +C887;C887;110C 1169 11BE;C887;110C 1169 11BE; +C888;C888;110C 1169 11BF;C888;110C 1169 11BF; +C889;C889;110C 1169 11C0;C889;110C 1169 11C0; +C88A;C88A;110C 1169 11C1;C88A;110C 1169 11C1; +C88B;C88B;110C 1169 11C2;C88B;110C 1169 11C2; +C88C;C88C;110C 116A;C88C;110C 116A; +C88D;C88D;110C 116A 11A8;C88D;110C 116A 11A8; +C88E;C88E;110C 116A 11A9;C88E;110C 116A 11A9; +C88F;C88F;110C 116A 11AA;C88F;110C 116A 11AA; +C890;C890;110C 116A 11AB;C890;110C 116A 11AB; +C891;C891;110C 116A 11AC;C891;110C 116A 11AC; +C892;C892;110C 116A 11AD;C892;110C 116A 11AD; +C893;C893;110C 116A 11AE;C893;110C 116A 11AE; +C894;C894;110C 116A 11AF;C894;110C 116A 11AF; +C895;C895;110C 116A 11B0;C895;110C 116A 11B0; +C896;C896;110C 116A 11B1;C896;110C 116A 11B1; +C897;C897;110C 116A 11B2;C897;110C 116A 11B2; +C898;C898;110C 116A 11B3;C898;110C 116A 11B3; +C899;C899;110C 116A 11B4;C899;110C 116A 11B4; +C89A;C89A;110C 116A 11B5;C89A;110C 116A 11B5; +C89B;C89B;110C 116A 11B6;C89B;110C 116A 11B6; +C89C;C89C;110C 116A 11B7;C89C;110C 116A 11B7; +C89D;C89D;110C 116A 11B8;C89D;110C 116A 11B8; +C89E;C89E;110C 116A 11B9;C89E;110C 116A 11B9; +C89F;C89F;110C 116A 11BA;C89F;110C 116A 11BA; +C8A0;C8A0;110C 116A 11BB;C8A0;110C 116A 11BB; +C8A1;C8A1;110C 116A 11BC;C8A1;110C 116A 11BC; +C8A2;C8A2;110C 116A 11BD;C8A2;110C 116A 11BD; +C8A3;C8A3;110C 116A 11BE;C8A3;110C 116A 11BE; +C8A4;C8A4;110C 116A 11BF;C8A4;110C 116A 11BF; +C8A5;C8A5;110C 116A 11C0;C8A5;110C 116A 11C0; +C8A6;C8A6;110C 116A 11C1;C8A6;110C 116A 11C1; +C8A7;C8A7;110C 116A 11C2;C8A7;110C 116A 11C2; +C8A8;C8A8;110C 116B;C8A8;110C 116B; +C8A9;C8A9;110C 116B 11A8;C8A9;110C 116B 11A8; +C8AA;C8AA;110C 116B 11A9;C8AA;110C 116B 11A9; +C8AB;C8AB;110C 116B 11AA;C8AB;110C 116B 11AA; +C8AC;C8AC;110C 116B 11AB;C8AC;110C 116B 11AB; +C8AD;C8AD;110C 116B 11AC;C8AD;110C 116B 11AC; +C8AE;C8AE;110C 116B 11AD;C8AE;110C 116B 11AD; +C8AF;C8AF;110C 116B 11AE;C8AF;110C 116B 11AE; +C8B0;C8B0;110C 116B 11AF;C8B0;110C 116B 11AF; +C8B1;C8B1;110C 116B 11B0;C8B1;110C 116B 11B0; +C8B2;C8B2;110C 116B 11B1;C8B2;110C 116B 11B1; +C8B3;C8B3;110C 116B 11B2;C8B3;110C 116B 11B2; +C8B4;C8B4;110C 116B 11B3;C8B4;110C 116B 11B3; +C8B5;C8B5;110C 116B 11B4;C8B5;110C 116B 11B4; +C8B6;C8B6;110C 116B 11B5;C8B6;110C 116B 11B5; +C8B7;C8B7;110C 116B 11B6;C8B7;110C 116B 11B6; +C8B8;C8B8;110C 116B 11B7;C8B8;110C 116B 11B7; +C8B9;C8B9;110C 116B 11B8;C8B9;110C 116B 11B8; +C8BA;C8BA;110C 116B 11B9;C8BA;110C 116B 11B9; +C8BB;C8BB;110C 116B 11BA;C8BB;110C 116B 11BA; +C8BC;C8BC;110C 116B 11BB;C8BC;110C 116B 11BB; +C8BD;C8BD;110C 116B 11BC;C8BD;110C 116B 11BC; +C8BE;C8BE;110C 116B 11BD;C8BE;110C 116B 11BD; +C8BF;C8BF;110C 116B 11BE;C8BF;110C 116B 11BE; +C8C0;C8C0;110C 116B 11BF;C8C0;110C 116B 11BF; +C8C1;C8C1;110C 116B 11C0;C8C1;110C 116B 11C0; +C8C2;C8C2;110C 116B 11C1;C8C2;110C 116B 11C1; +C8C3;C8C3;110C 116B 11C2;C8C3;110C 116B 11C2; +C8C4;C8C4;110C 116C;C8C4;110C 116C; +C8C5;C8C5;110C 116C 11A8;C8C5;110C 116C 11A8; +C8C6;C8C6;110C 116C 11A9;C8C6;110C 116C 11A9; +C8C7;C8C7;110C 116C 11AA;C8C7;110C 116C 11AA; +C8C8;C8C8;110C 116C 11AB;C8C8;110C 116C 11AB; +C8C9;C8C9;110C 116C 11AC;C8C9;110C 116C 11AC; +C8CA;C8CA;110C 116C 11AD;C8CA;110C 116C 11AD; +C8CB;C8CB;110C 116C 11AE;C8CB;110C 116C 11AE; +C8CC;C8CC;110C 116C 11AF;C8CC;110C 116C 11AF; +C8CD;C8CD;110C 116C 11B0;C8CD;110C 116C 11B0; +C8CE;C8CE;110C 116C 11B1;C8CE;110C 116C 11B1; +C8CF;C8CF;110C 116C 11B2;C8CF;110C 116C 11B2; +C8D0;C8D0;110C 116C 11B3;C8D0;110C 116C 11B3; +C8D1;C8D1;110C 116C 11B4;C8D1;110C 116C 11B4; +C8D2;C8D2;110C 116C 11B5;C8D2;110C 116C 11B5; +C8D3;C8D3;110C 116C 11B6;C8D3;110C 116C 11B6; +C8D4;C8D4;110C 116C 11B7;C8D4;110C 116C 11B7; +C8D5;C8D5;110C 116C 11B8;C8D5;110C 116C 11B8; +C8D6;C8D6;110C 116C 11B9;C8D6;110C 116C 11B9; +C8D7;C8D7;110C 116C 11BA;C8D7;110C 116C 11BA; +C8D8;C8D8;110C 116C 11BB;C8D8;110C 116C 11BB; +C8D9;C8D9;110C 116C 11BC;C8D9;110C 116C 11BC; +C8DA;C8DA;110C 116C 11BD;C8DA;110C 116C 11BD; +C8DB;C8DB;110C 116C 11BE;C8DB;110C 116C 11BE; +C8DC;C8DC;110C 116C 11BF;C8DC;110C 116C 11BF; +C8DD;C8DD;110C 116C 11C0;C8DD;110C 116C 11C0; +C8DE;C8DE;110C 116C 11C1;C8DE;110C 116C 11C1; +C8DF;C8DF;110C 116C 11C2;C8DF;110C 116C 11C2; +C8E0;C8E0;110C 116D;C8E0;110C 116D; +C8E1;C8E1;110C 116D 11A8;C8E1;110C 116D 11A8; +C8E2;C8E2;110C 116D 11A9;C8E2;110C 116D 11A9; +C8E3;C8E3;110C 116D 11AA;C8E3;110C 116D 11AA; +C8E4;C8E4;110C 116D 11AB;C8E4;110C 116D 11AB; +C8E5;C8E5;110C 116D 11AC;C8E5;110C 116D 11AC; +C8E6;C8E6;110C 116D 11AD;C8E6;110C 116D 11AD; +C8E7;C8E7;110C 116D 11AE;C8E7;110C 116D 11AE; +C8E8;C8E8;110C 116D 11AF;C8E8;110C 116D 11AF; +C8E9;C8E9;110C 116D 11B0;C8E9;110C 116D 11B0; +C8EA;C8EA;110C 116D 11B1;C8EA;110C 116D 11B1; +C8EB;C8EB;110C 116D 11B2;C8EB;110C 116D 11B2; +C8EC;C8EC;110C 116D 11B3;C8EC;110C 116D 11B3; +C8ED;C8ED;110C 116D 11B4;C8ED;110C 116D 11B4; +C8EE;C8EE;110C 116D 11B5;C8EE;110C 116D 11B5; +C8EF;C8EF;110C 116D 11B6;C8EF;110C 116D 11B6; +C8F0;C8F0;110C 116D 11B7;C8F0;110C 116D 11B7; +C8F1;C8F1;110C 116D 11B8;C8F1;110C 116D 11B8; +C8F2;C8F2;110C 116D 11B9;C8F2;110C 116D 11B9; +C8F3;C8F3;110C 116D 11BA;C8F3;110C 116D 11BA; +C8F4;C8F4;110C 116D 11BB;C8F4;110C 116D 11BB; +C8F5;C8F5;110C 116D 11BC;C8F5;110C 116D 11BC; +C8F6;C8F6;110C 116D 11BD;C8F6;110C 116D 11BD; +C8F7;C8F7;110C 116D 11BE;C8F7;110C 116D 11BE; +C8F8;C8F8;110C 116D 11BF;C8F8;110C 116D 11BF; +C8F9;C8F9;110C 116D 11C0;C8F9;110C 116D 11C0; +C8FA;C8FA;110C 116D 11C1;C8FA;110C 116D 11C1; +C8FB;C8FB;110C 116D 11C2;C8FB;110C 116D 11C2; +C8FC;C8FC;110C 116E;C8FC;110C 116E; +C8FD;C8FD;110C 116E 11A8;C8FD;110C 116E 11A8; +C8FE;C8FE;110C 116E 11A9;C8FE;110C 116E 11A9; +C8FF;C8FF;110C 116E 11AA;C8FF;110C 116E 11AA; +C900;C900;110C 116E 11AB;C900;110C 116E 11AB; +C901;C901;110C 116E 11AC;C901;110C 116E 11AC; +C902;C902;110C 116E 11AD;C902;110C 116E 11AD; +C903;C903;110C 116E 11AE;C903;110C 116E 11AE; +C904;C904;110C 116E 11AF;C904;110C 116E 11AF; +C905;C905;110C 116E 11B0;C905;110C 116E 11B0; +C906;C906;110C 116E 11B1;C906;110C 116E 11B1; +C907;C907;110C 116E 11B2;C907;110C 116E 11B2; +C908;C908;110C 116E 11B3;C908;110C 116E 11B3; +C909;C909;110C 116E 11B4;C909;110C 116E 11B4; +C90A;C90A;110C 116E 11B5;C90A;110C 116E 11B5; +C90B;C90B;110C 116E 11B6;C90B;110C 116E 11B6; +C90C;C90C;110C 116E 11B7;C90C;110C 116E 11B7; +C90D;C90D;110C 116E 11B8;C90D;110C 116E 11B8; +C90E;C90E;110C 116E 11B9;C90E;110C 116E 11B9; +C90F;C90F;110C 116E 11BA;C90F;110C 116E 11BA; +C910;C910;110C 116E 11BB;C910;110C 116E 11BB; +C911;C911;110C 116E 11BC;C911;110C 116E 11BC; +C912;C912;110C 116E 11BD;C912;110C 116E 11BD; +C913;C913;110C 116E 11BE;C913;110C 116E 11BE; +C914;C914;110C 116E 11BF;C914;110C 116E 11BF; +C915;C915;110C 116E 11C0;C915;110C 116E 11C0; +C916;C916;110C 116E 11C1;C916;110C 116E 11C1; +C917;C917;110C 116E 11C2;C917;110C 116E 11C2; +C918;C918;110C 116F;C918;110C 116F; +C919;C919;110C 116F 11A8;C919;110C 116F 11A8; +C91A;C91A;110C 116F 11A9;C91A;110C 116F 11A9; +C91B;C91B;110C 116F 11AA;C91B;110C 116F 11AA; +C91C;C91C;110C 116F 11AB;C91C;110C 116F 11AB; +C91D;C91D;110C 116F 11AC;C91D;110C 116F 11AC; +C91E;C91E;110C 116F 11AD;C91E;110C 116F 11AD; +C91F;C91F;110C 116F 11AE;C91F;110C 116F 11AE; +C920;C920;110C 116F 11AF;C920;110C 116F 11AF; +C921;C921;110C 116F 11B0;C921;110C 116F 11B0; +C922;C922;110C 116F 11B1;C922;110C 116F 11B1; +C923;C923;110C 116F 11B2;C923;110C 116F 11B2; +C924;C924;110C 116F 11B3;C924;110C 116F 11B3; +C925;C925;110C 116F 11B4;C925;110C 116F 11B4; +C926;C926;110C 116F 11B5;C926;110C 116F 11B5; +C927;C927;110C 116F 11B6;C927;110C 116F 11B6; +C928;C928;110C 116F 11B7;C928;110C 116F 11B7; +C929;C929;110C 116F 11B8;C929;110C 116F 11B8; +C92A;C92A;110C 116F 11B9;C92A;110C 116F 11B9; +C92B;C92B;110C 116F 11BA;C92B;110C 116F 11BA; +C92C;C92C;110C 116F 11BB;C92C;110C 116F 11BB; +C92D;C92D;110C 116F 11BC;C92D;110C 116F 11BC; +C92E;C92E;110C 116F 11BD;C92E;110C 116F 11BD; +C92F;C92F;110C 116F 11BE;C92F;110C 116F 11BE; +C930;C930;110C 116F 11BF;C930;110C 116F 11BF; +C931;C931;110C 116F 11C0;C931;110C 116F 11C0; +C932;C932;110C 116F 11C1;C932;110C 116F 11C1; +C933;C933;110C 116F 11C2;C933;110C 116F 11C2; +C934;C934;110C 1170;C934;110C 1170; +C935;C935;110C 1170 11A8;C935;110C 1170 11A8; +C936;C936;110C 1170 11A9;C936;110C 1170 11A9; +C937;C937;110C 1170 11AA;C937;110C 1170 11AA; +C938;C938;110C 1170 11AB;C938;110C 1170 11AB; +C939;C939;110C 1170 11AC;C939;110C 1170 11AC; +C93A;C93A;110C 1170 11AD;C93A;110C 1170 11AD; +C93B;C93B;110C 1170 11AE;C93B;110C 1170 11AE; +C93C;C93C;110C 1170 11AF;C93C;110C 1170 11AF; +C93D;C93D;110C 1170 11B0;C93D;110C 1170 11B0; +C93E;C93E;110C 1170 11B1;C93E;110C 1170 11B1; +C93F;C93F;110C 1170 11B2;C93F;110C 1170 11B2; +C940;C940;110C 1170 11B3;C940;110C 1170 11B3; +C941;C941;110C 1170 11B4;C941;110C 1170 11B4; +C942;C942;110C 1170 11B5;C942;110C 1170 11B5; +C943;C943;110C 1170 11B6;C943;110C 1170 11B6; +C944;C944;110C 1170 11B7;C944;110C 1170 11B7; +C945;C945;110C 1170 11B8;C945;110C 1170 11B8; +C946;C946;110C 1170 11B9;C946;110C 1170 11B9; +C947;C947;110C 1170 11BA;C947;110C 1170 11BA; +C948;C948;110C 1170 11BB;C948;110C 1170 11BB; +C949;C949;110C 1170 11BC;C949;110C 1170 11BC; +C94A;C94A;110C 1170 11BD;C94A;110C 1170 11BD; +C94B;C94B;110C 1170 11BE;C94B;110C 1170 11BE; +C94C;C94C;110C 1170 11BF;C94C;110C 1170 11BF; +C94D;C94D;110C 1170 11C0;C94D;110C 1170 11C0; +C94E;C94E;110C 1170 11C1;C94E;110C 1170 11C1; +C94F;C94F;110C 1170 11C2;C94F;110C 1170 11C2; +C950;C950;110C 1171;C950;110C 1171; +C951;C951;110C 1171 11A8;C951;110C 1171 11A8; +C952;C952;110C 1171 11A9;C952;110C 1171 11A9; +C953;C953;110C 1171 11AA;C953;110C 1171 11AA; +C954;C954;110C 1171 11AB;C954;110C 1171 11AB; +C955;C955;110C 1171 11AC;C955;110C 1171 11AC; +C956;C956;110C 1171 11AD;C956;110C 1171 11AD; +C957;C957;110C 1171 11AE;C957;110C 1171 11AE; +C958;C958;110C 1171 11AF;C958;110C 1171 11AF; +C959;C959;110C 1171 11B0;C959;110C 1171 11B0; +C95A;C95A;110C 1171 11B1;C95A;110C 1171 11B1; +C95B;C95B;110C 1171 11B2;C95B;110C 1171 11B2; +C95C;C95C;110C 1171 11B3;C95C;110C 1171 11B3; +C95D;C95D;110C 1171 11B4;C95D;110C 1171 11B4; +C95E;C95E;110C 1171 11B5;C95E;110C 1171 11B5; +C95F;C95F;110C 1171 11B6;C95F;110C 1171 11B6; +C960;C960;110C 1171 11B7;C960;110C 1171 11B7; +C961;C961;110C 1171 11B8;C961;110C 1171 11B8; +C962;C962;110C 1171 11B9;C962;110C 1171 11B9; +C963;C963;110C 1171 11BA;C963;110C 1171 11BA; +C964;C964;110C 1171 11BB;C964;110C 1171 11BB; +C965;C965;110C 1171 11BC;C965;110C 1171 11BC; +C966;C966;110C 1171 11BD;C966;110C 1171 11BD; +C967;C967;110C 1171 11BE;C967;110C 1171 11BE; +C968;C968;110C 1171 11BF;C968;110C 1171 11BF; +C969;C969;110C 1171 11C0;C969;110C 1171 11C0; +C96A;C96A;110C 1171 11C1;C96A;110C 1171 11C1; +C96B;C96B;110C 1171 11C2;C96B;110C 1171 11C2; +C96C;C96C;110C 1172;C96C;110C 1172; +C96D;C96D;110C 1172 11A8;C96D;110C 1172 11A8; +C96E;C96E;110C 1172 11A9;C96E;110C 1172 11A9; +C96F;C96F;110C 1172 11AA;C96F;110C 1172 11AA; +C970;C970;110C 1172 11AB;C970;110C 1172 11AB; +C971;C971;110C 1172 11AC;C971;110C 1172 11AC; +C972;C972;110C 1172 11AD;C972;110C 1172 11AD; +C973;C973;110C 1172 11AE;C973;110C 1172 11AE; +C974;C974;110C 1172 11AF;C974;110C 1172 11AF; +C975;C975;110C 1172 11B0;C975;110C 1172 11B0; +C976;C976;110C 1172 11B1;C976;110C 1172 11B1; +C977;C977;110C 1172 11B2;C977;110C 1172 11B2; +C978;C978;110C 1172 11B3;C978;110C 1172 11B3; +C979;C979;110C 1172 11B4;C979;110C 1172 11B4; +C97A;C97A;110C 1172 11B5;C97A;110C 1172 11B5; +C97B;C97B;110C 1172 11B6;C97B;110C 1172 11B6; +C97C;C97C;110C 1172 11B7;C97C;110C 1172 11B7; +C97D;C97D;110C 1172 11B8;C97D;110C 1172 11B8; +C97E;C97E;110C 1172 11B9;C97E;110C 1172 11B9; +C97F;C97F;110C 1172 11BA;C97F;110C 1172 11BA; +C980;C980;110C 1172 11BB;C980;110C 1172 11BB; +C981;C981;110C 1172 11BC;C981;110C 1172 11BC; +C982;C982;110C 1172 11BD;C982;110C 1172 11BD; +C983;C983;110C 1172 11BE;C983;110C 1172 11BE; +C984;C984;110C 1172 11BF;C984;110C 1172 11BF; +C985;C985;110C 1172 11C0;C985;110C 1172 11C0; +C986;C986;110C 1172 11C1;C986;110C 1172 11C1; +C987;C987;110C 1172 11C2;C987;110C 1172 11C2; +C988;C988;110C 1173;C988;110C 1173; +C989;C989;110C 1173 11A8;C989;110C 1173 11A8; +C98A;C98A;110C 1173 11A9;C98A;110C 1173 11A9; +C98B;C98B;110C 1173 11AA;C98B;110C 1173 11AA; +C98C;C98C;110C 1173 11AB;C98C;110C 1173 11AB; +C98D;C98D;110C 1173 11AC;C98D;110C 1173 11AC; +C98E;C98E;110C 1173 11AD;C98E;110C 1173 11AD; +C98F;C98F;110C 1173 11AE;C98F;110C 1173 11AE; +C990;C990;110C 1173 11AF;C990;110C 1173 11AF; +C991;C991;110C 1173 11B0;C991;110C 1173 11B0; +C992;C992;110C 1173 11B1;C992;110C 1173 11B1; +C993;C993;110C 1173 11B2;C993;110C 1173 11B2; +C994;C994;110C 1173 11B3;C994;110C 1173 11B3; +C995;C995;110C 1173 11B4;C995;110C 1173 11B4; +C996;C996;110C 1173 11B5;C996;110C 1173 11B5; +C997;C997;110C 1173 11B6;C997;110C 1173 11B6; +C998;C998;110C 1173 11B7;C998;110C 1173 11B7; +C999;C999;110C 1173 11B8;C999;110C 1173 11B8; +C99A;C99A;110C 1173 11B9;C99A;110C 1173 11B9; +C99B;C99B;110C 1173 11BA;C99B;110C 1173 11BA; +C99C;C99C;110C 1173 11BB;C99C;110C 1173 11BB; +C99D;C99D;110C 1173 11BC;C99D;110C 1173 11BC; +C99E;C99E;110C 1173 11BD;C99E;110C 1173 11BD; +C99F;C99F;110C 1173 11BE;C99F;110C 1173 11BE; +C9A0;C9A0;110C 1173 11BF;C9A0;110C 1173 11BF; +C9A1;C9A1;110C 1173 11C0;C9A1;110C 1173 11C0; +C9A2;C9A2;110C 1173 11C1;C9A2;110C 1173 11C1; +C9A3;C9A3;110C 1173 11C2;C9A3;110C 1173 11C2; +C9A4;C9A4;110C 1174;C9A4;110C 1174; +C9A5;C9A5;110C 1174 11A8;C9A5;110C 1174 11A8; +C9A6;C9A6;110C 1174 11A9;C9A6;110C 1174 11A9; +C9A7;C9A7;110C 1174 11AA;C9A7;110C 1174 11AA; +C9A8;C9A8;110C 1174 11AB;C9A8;110C 1174 11AB; +C9A9;C9A9;110C 1174 11AC;C9A9;110C 1174 11AC; +C9AA;C9AA;110C 1174 11AD;C9AA;110C 1174 11AD; +C9AB;C9AB;110C 1174 11AE;C9AB;110C 1174 11AE; +C9AC;C9AC;110C 1174 11AF;C9AC;110C 1174 11AF; +C9AD;C9AD;110C 1174 11B0;C9AD;110C 1174 11B0; +C9AE;C9AE;110C 1174 11B1;C9AE;110C 1174 11B1; +C9AF;C9AF;110C 1174 11B2;C9AF;110C 1174 11B2; +C9B0;C9B0;110C 1174 11B3;C9B0;110C 1174 11B3; +C9B1;C9B1;110C 1174 11B4;C9B1;110C 1174 11B4; +C9B2;C9B2;110C 1174 11B5;C9B2;110C 1174 11B5; +C9B3;C9B3;110C 1174 11B6;C9B3;110C 1174 11B6; +C9B4;C9B4;110C 1174 11B7;C9B4;110C 1174 11B7; +C9B5;C9B5;110C 1174 11B8;C9B5;110C 1174 11B8; +C9B6;C9B6;110C 1174 11B9;C9B6;110C 1174 11B9; +C9B7;C9B7;110C 1174 11BA;C9B7;110C 1174 11BA; +C9B8;C9B8;110C 1174 11BB;C9B8;110C 1174 11BB; +C9B9;C9B9;110C 1174 11BC;C9B9;110C 1174 11BC; +C9BA;C9BA;110C 1174 11BD;C9BA;110C 1174 11BD; +C9BB;C9BB;110C 1174 11BE;C9BB;110C 1174 11BE; +C9BC;C9BC;110C 1174 11BF;C9BC;110C 1174 11BF; +C9BD;C9BD;110C 1174 11C0;C9BD;110C 1174 11C0; +C9BE;C9BE;110C 1174 11C1;C9BE;110C 1174 11C1; +C9BF;C9BF;110C 1174 11C2;C9BF;110C 1174 11C2; +C9C0;C9C0;110C 1175;C9C0;110C 1175; +C9C1;C9C1;110C 1175 11A8;C9C1;110C 1175 11A8; +C9C2;C9C2;110C 1175 11A9;C9C2;110C 1175 11A9; +C9C3;C9C3;110C 1175 11AA;C9C3;110C 1175 11AA; +C9C4;C9C4;110C 1175 11AB;C9C4;110C 1175 11AB; +C9C5;C9C5;110C 1175 11AC;C9C5;110C 1175 11AC; +C9C6;C9C6;110C 1175 11AD;C9C6;110C 1175 11AD; +C9C7;C9C7;110C 1175 11AE;C9C7;110C 1175 11AE; +C9C8;C9C8;110C 1175 11AF;C9C8;110C 1175 11AF; +C9C9;C9C9;110C 1175 11B0;C9C9;110C 1175 11B0; +C9CA;C9CA;110C 1175 11B1;C9CA;110C 1175 11B1; +C9CB;C9CB;110C 1175 11B2;C9CB;110C 1175 11B2; +C9CC;C9CC;110C 1175 11B3;C9CC;110C 1175 11B3; +C9CD;C9CD;110C 1175 11B4;C9CD;110C 1175 11B4; +C9CE;C9CE;110C 1175 11B5;C9CE;110C 1175 11B5; +C9CF;C9CF;110C 1175 11B6;C9CF;110C 1175 11B6; +C9D0;C9D0;110C 1175 11B7;C9D0;110C 1175 11B7; +C9D1;C9D1;110C 1175 11B8;C9D1;110C 1175 11B8; +C9D2;C9D2;110C 1175 11B9;C9D2;110C 1175 11B9; +C9D3;C9D3;110C 1175 11BA;C9D3;110C 1175 11BA; +C9D4;C9D4;110C 1175 11BB;C9D4;110C 1175 11BB; +C9D5;C9D5;110C 1175 11BC;C9D5;110C 1175 11BC; +C9D6;C9D6;110C 1175 11BD;C9D6;110C 1175 11BD; +C9D7;C9D7;110C 1175 11BE;C9D7;110C 1175 11BE; +C9D8;C9D8;110C 1175 11BF;C9D8;110C 1175 11BF; +C9D9;C9D9;110C 1175 11C0;C9D9;110C 1175 11C0; +C9DA;C9DA;110C 1175 11C1;C9DA;110C 1175 11C1; +C9DB;C9DB;110C 1175 11C2;C9DB;110C 1175 11C2; +C9DC;C9DC;110D 1161;C9DC;110D 1161; +C9DD;C9DD;110D 1161 11A8;C9DD;110D 1161 11A8; +C9DE;C9DE;110D 1161 11A9;C9DE;110D 1161 11A9; +C9DF;C9DF;110D 1161 11AA;C9DF;110D 1161 11AA; +C9E0;C9E0;110D 1161 11AB;C9E0;110D 1161 11AB; +C9E1;C9E1;110D 1161 11AC;C9E1;110D 1161 11AC; +C9E2;C9E2;110D 1161 11AD;C9E2;110D 1161 11AD; +C9E3;C9E3;110D 1161 11AE;C9E3;110D 1161 11AE; +C9E4;C9E4;110D 1161 11AF;C9E4;110D 1161 11AF; +C9E5;C9E5;110D 1161 11B0;C9E5;110D 1161 11B0; +C9E6;C9E6;110D 1161 11B1;C9E6;110D 1161 11B1; +C9E7;C9E7;110D 1161 11B2;C9E7;110D 1161 11B2; +C9E8;C9E8;110D 1161 11B3;C9E8;110D 1161 11B3; +C9E9;C9E9;110D 1161 11B4;C9E9;110D 1161 11B4; +C9EA;C9EA;110D 1161 11B5;C9EA;110D 1161 11B5; +C9EB;C9EB;110D 1161 11B6;C9EB;110D 1161 11B6; +C9EC;C9EC;110D 1161 11B7;C9EC;110D 1161 11B7; +C9ED;C9ED;110D 1161 11B8;C9ED;110D 1161 11B8; +C9EE;C9EE;110D 1161 11B9;C9EE;110D 1161 11B9; +C9EF;C9EF;110D 1161 11BA;C9EF;110D 1161 11BA; +C9F0;C9F0;110D 1161 11BB;C9F0;110D 1161 11BB; +C9F1;C9F1;110D 1161 11BC;C9F1;110D 1161 11BC; +C9F2;C9F2;110D 1161 11BD;C9F2;110D 1161 11BD; +C9F3;C9F3;110D 1161 11BE;C9F3;110D 1161 11BE; +C9F4;C9F4;110D 1161 11BF;C9F4;110D 1161 11BF; +C9F5;C9F5;110D 1161 11C0;C9F5;110D 1161 11C0; +C9F6;C9F6;110D 1161 11C1;C9F6;110D 1161 11C1; +C9F7;C9F7;110D 1161 11C2;C9F7;110D 1161 11C2; +C9F8;C9F8;110D 1162;C9F8;110D 1162; +C9F9;C9F9;110D 1162 11A8;C9F9;110D 1162 11A8; +C9FA;C9FA;110D 1162 11A9;C9FA;110D 1162 11A9; +C9FB;C9FB;110D 1162 11AA;C9FB;110D 1162 11AA; +C9FC;C9FC;110D 1162 11AB;C9FC;110D 1162 11AB; +C9FD;C9FD;110D 1162 11AC;C9FD;110D 1162 11AC; +C9FE;C9FE;110D 1162 11AD;C9FE;110D 1162 11AD; +C9FF;C9FF;110D 1162 11AE;C9FF;110D 1162 11AE; +CA00;CA00;110D 1162 11AF;CA00;110D 1162 11AF; +CA01;CA01;110D 1162 11B0;CA01;110D 1162 11B0; +CA02;CA02;110D 1162 11B1;CA02;110D 1162 11B1; +CA03;CA03;110D 1162 11B2;CA03;110D 1162 11B2; +CA04;CA04;110D 1162 11B3;CA04;110D 1162 11B3; +CA05;CA05;110D 1162 11B4;CA05;110D 1162 11B4; +CA06;CA06;110D 1162 11B5;CA06;110D 1162 11B5; +CA07;CA07;110D 1162 11B6;CA07;110D 1162 11B6; +CA08;CA08;110D 1162 11B7;CA08;110D 1162 11B7; +CA09;CA09;110D 1162 11B8;CA09;110D 1162 11B8; +CA0A;CA0A;110D 1162 11B9;CA0A;110D 1162 11B9; +CA0B;CA0B;110D 1162 11BA;CA0B;110D 1162 11BA; +CA0C;CA0C;110D 1162 11BB;CA0C;110D 1162 11BB; +CA0D;CA0D;110D 1162 11BC;CA0D;110D 1162 11BC; +CA0E;CA0E;110D 1162 11BD;CA0E;110D 1162 11BD; +CA0F;CA0F;110D 1162 11BE;CA0F;110D 1162 11BE; +CA10;CA10;110D 1162 11BF;CA10;110D 1162 11BF; +CA11;CA11;110D 1162 11C0;CA11;110D 1162 11C0; +CA12;CA12;110D 1162 11C1;CA12;110D 1162 11C1; +CA13;CA13;110D 1162 11C2;CA13;110D 1162 11C2; +CA14;CA14;110D 1163;CA14;110D 1163; +CA15;CA15;110D 1163 11A8;CA15;110D 1163 11A8; +CA16;CA16;110D 1163 11A9;CA16;110D 1163 11A9; +CA17;CA17;110D 1163 11AA;CA17;110D 1163 11AA; +CA18;CA18;110D 1163 11AB;CA18;110D 1163 11AB; +CA19;CA19;110D 1163 11AC;CA19;110D 1163 11AC; +CA1A;CA1A;110D 1163 11AD;CA1A;110D 1163 11AD; +CA1B;CA1B;110D 1163 11AE;CA1B;110D 1163 11AE; +CA1C;CA1C;110D 1163 11AF;CA1C;110D 1163 11AF; +CA1D;CA1D;110D 1163 11B0;CA1D;110D 1163 11B0; +CA1E;CA1E;110D 1163 11B1;CA1E;110D 1163 11B1; +CA1F;CA1F;110D 1163 11B2;CA1F;110D 1163 11B2; +CA20;CA20;110D 1163 11B3;CA20;110D 1163 11B3; +CA21;CA21;110D 1163 11B4;CA21;110D 1163 11B4; +CA22;CA22;110D 1163 11B5;CA22;110D 1163 11B5; +CA23;CA23;110D 1163 11B6;CA23;110D 1163 11B6; +CA24;CA24;110D 1163 11B7;CA24;110D 1163 11B7; +CA25;CA25;110D 1163 11B8;CA25;110D 1163 11B8; +CA26;CA26;110D 1163 11B9;CA26;110D 1163 11B9; +CA27;CA27;110D 1163 11BA;CA27;110D 1163 11BA; +CA28;CA28;110D 1163 11BB;CA28;110D 1163 11BB; +CA29;CA29;110D 1163 11BC;CA29;110D 1163 11BC; +CA2A;CA2A;110D 1163 11BD;CA2A;110D 1163 11BD; +CA2B;CA2B;110D 1163 11BE;CA2B;110D 1163 11BE; +CA2C;CA2C;110D 1163 11BF;CA2C;110D 1163 11BF; +CA2D;CA2D;110D 1163 11C0;CA2D;110D 1163 11C0; +CA2E;CA2E;110D 1163 11C1;CA2E;110D 1163 11C1; +CA2F;CA2F;110D 1163 11C2;CA2F;110D 1163 11C2; +CA30;CA30;110D 1164;CA30;110D 1164; +CA31;CA31;110D 1164 11A8;CA31;110D 1164 11A8; +CA32;CA32;110D 1164 11A9;CA32;110D 1164 11A9; +CA33;CA33;110D 1164 11AA;CA33;110D 1164 11AA; +CA34;CA34;110D 1164 11AB;CA34;110D 1164 11AB; +CA35;CA35;110D 1164 11AC;CA35;110D 1164 11AC; +CA36;CA36;110D 1164 11AD;CA36;110D 1164 11AD; +CA37;CA37;110D 1164 11AE;CA37;110D 1164 11AE; +CA38;CA38;110D 1164 11AF;CA38;110D 1164 11AF; +CA39;CA39;110D 1164 11B0;CA39;110D 1164 11B0; +CA3A;CA3A;110D 1164 11B1;CA3A;110D 1164 11B1; +CA3B;CA3B;110D 1164 11B2;CA3B;110D 1164 11B2; +CA3C;CA3C;110D 1164 11B3;CA3C;110D 1164 11B3; +CA3D;CA3D;110D 1164 11B4;CA3D;110D 1164 11B4; +CA3E;CA3E;110D 1164 11B5;CA3E;110D 1164 11B5; +CA3F;CA3F;110D 1164 11B6;CA3F;110D 1164 11B6; +CA40;CA40;110D 1164 11B7;CA40;110D 1164 11B7; +CA41;CA41;110D 1164 11B8;CA41;110D 1164 11B8; +CA42;CA42;110D 1164 11B9;CA42;110D 1164 11B9; +CA43;CA43;110D 1164 11BA;CA43;110D 1164 11BA; +CA44;CA44;110D 1164 11BB;CA44;110D 1164 11BB; +CA45;CA45;110D 1164 11BC;CA45;110D 1164 11BC; +CA46;CA46;110D 1164 11BD;CA46;110D 1164 11BD; +CA47;CA47;110D 1164 11BE;CA47;110D 1164 11BE; +CA48;CA48;110D 1164 11BF;CA48;110D 1164 11BF; +CA49;CA49;110D 1164 11C0;CA49;110D 1164 11C0; +CA4A;CA4A;110D 1164 11C1;CA4A;110D 1164 11C1; +CA4B;CA4B;110D 1164 11C2;CA4B;110D 1164 11C2; +CA4C;CA4C;110D 1165;CA4C;110D 1165; +CA4D;CA4D;110D 1165 11A8;CA4D;110D 1165 11A8; +CA4E;CA4E;110D 1165 11A9;CA4E;110D 1165 11A9; +CA4F;CA4F;110D 1165 11AA;CA4F;110D 1165 11AA; +CA50;CA50;110D 1165 11AB;CA50;110D 1165 11AB; +CA51;CA51;110D 1165 11AC;CA51;110D 1165 11AC; +CA52;CA52;110D 1165 11AD;CA52;110D 1165 11AD; +CA53;CA53;110D 1165 11AE;CA53;110D 1165 11AE; +CA54;CA54;110D 1165 11AF;CA54;110D 1165 11AF; +CA55;CA55;110D 1165 11B0;CA55;110D 1165 11B0; +CA56;CA56;110D 1165 11B1;CA56;110D 1165 11B1; +CA57;CA57;110D 1165 11B2;CA57;110D 1165 11B2; +CA58;CA58;110D 1165 11B3;CA58;110D 1165 11B3; +CA59;CA59;110D 1165 11B4;CA59;110D 1165 11B4; +CA5A;CA5A;110D 1165 11B5;CA5A;110D 1165 11B5; +CA5B;CA5B;110D 1165 11B6;CA5B;110D 1165 11B6; +CA5C;CA5C;110D 1165 11B7;CA5C;110D 1165 11B7; +CA5D;CA5D;110D 1165 11B8;CA5D;110D 1165 11B8; +CA5E;CA5E;110D 1165 11B9;CA5E;110D 1165 11B9; +CA5F;CA5F;110D 1165 11BA;CA5F;110D 1165 11BA; +CA60;CA60;110D 1165 11BB;CA60;110D 1165 11BB; +CA61;CA61;110D 1165 11BC;CA61;110D 1165 11BC; +CA62;CA62;110D 1165 11BD;CA62;110D 1165 11BD; +CA63;CA63;110D 1165 11BE;CA63;110D 1165 11BE; +CA64;CA64;110D 1165 11BF;CA64;110D 1165 11BF; +CA65;CA65;110D 1165 11C0;CA65;110D 1165 11C0; +CA66;CA66;110D 1165 11C1;CA66;110D 1165 11C1; +CA67;CA67;110D 1165 11C2;CA67;110D 1165 11C2; +CA68;CA68;110D 1166;CA68;110D 1166; +CA69;CA69;110D 1166 11A8;CA69;110D 1166 11A8; +CA6A;CA6A;110D 1166 11A9;CA6A;110D 1166 11A9; +CA6B;CA6B;110D 1166 11AA;CA6B;110D 1166 11AA; +CA6C;CA6C;110D 1166 11AB;CA6C;110D 1166 11AB; +CA6D;CA6D;110D 1166 11AC;CA6D;110D 1166 11AC; +CA6E;CA6E;110D 1166 11AD;CA6E;110D 1166 11AD; +CA6F;CA6F;110D 1166 11AE;CA6F;110D 1166 11AE; +CA70;CA70;110D 1166 11AF;CA70;110D 1166 11AF; +CA71;CA71;110D 1166 11B0;CA71;110D 1166 11B0; +CA72;CA72;110D 1166 11B1;CA72;110D 1166 11B1; +CA73;CA73;110D 1166 11B2;CA73;110D 1166 11B2; +CA74;CA74;110D 1166 11B3;CA74;110D 1166 11B3; +CA75;CA75;110D 1166 11B4;CA75;110D 1166 11B4; +CA76;CA76;110D 1166 11B5;CA76;110D 1166 11B5; +CA77;CA77;110D 1166 11B6;CA77;110D 1166 11B6; +CA78;CA78;110D 1166 11B7;CA78;110D 1166 11B7; +CA79;CA79;110D 1166 11B8;CA79;110D 1166 11B8; +CA7A;CA7A;110D 1166 11B9;CA7A;110D 1166 11B9; +CA7B;CA7B;110D 1166 11BA;CA7B;110D 1166 11BA; +CA7C;CA7C;110D 1166 11BB;CA7C;110D 1166 11BB; +CA7D;CA7D;110D 1166 11BC;CA7D;110D 1166 11BC; +CA7E;CA7E;110D 1166 11BD;CA7E;110D 1166 11BD; +CA7F;CA7F;110D 1166 11BE;CA7F;110D 1166 11BE; +CA80;CA80;110D 1166 11BF;CA80;110D 1166 11BF; +CA81;CA81;110D 1166 11C0;CA81;110D 1166 11C0; +CA82;CA82;110D 1166 11C1;CA82;110D 1166 11C1; +CA83;CA83;110D 1166 11C2;CA83;110D 1166 11C2; +CA84;CA84;110D 1167;CA84;110D 1167; +CA85;CA85;110D 1167 11A8;CA85;110D 1167 11A8; +CA86;CA86;110D 1167 11A9;CA86;110D 1167 11A9; +CA87;CA87;110D 1167 11AA;CA87;110D 1167 11AA; +CA88;CA88;110D 1167 11AB;CA88;110D 1167 11AB; +CA89;CA89;110D 1167 11AC;CA89;110D 1167 11AC; +CA8A;CA8A;110D 1167 11AD;CA8A;110D 1167 11AD; +CA8B;CA8B;110D 1167 11AE;CA8B;110D 1167 11AE; +CA8C;CA8C;110D 1167 11AF;CA8C;110D 1167 11AF; +CA8D;CA8D;110D 1167 11B0;CA8D;110D 1167 11B0; +CA8E;CA8E;110D 1167 11B1;CA8E;110D 1167 11B1; +CA8F;CA8F;110D 1167 11B2;CA8F;110D 1167 11B2; +CA90;CA90;110D 1167 11B3;CA90;110D 1167 11B3; +CA91;CA91;110D 1167 11B4;CA91;110D 1167 11B4; +CA92;CA92;110D 1167 11B5;CA92;110D 1167 11B5; +CA93;CA93;110D 1167 11B6;CA93;110D 1167 11B6; +CA94;CA94;110D 1167 11B7;CA94;110D 1167 11B7; +CA95;CA95;110D 1167 11B8;CA95;110D 1167 11B8; +CA96;CA96;110D 1167 11B9;CA96;110D 1167 11B9; +CA97;CA97;110D 1167 11BA;CA97;110D 1167 11BA; +CA98;CA98;110D 1167 11BB;CA98;110D 1167 11BB; +CA99;CA99;110D 1167 11BC;CA99;110D 1167 11BC; +CA9A;CA9A;110D 1167 11BD;CA9A;110D 1167 11BD; +CA9B;CA9B;110D 1167 11BE;CA9B;110D 1167 11BE; +CA9C;CA9C;110D 1167 11BF;CA9C;110D 1167 11BF; +CA9D;CA9D;110D 1167 11C0;CA9D;110D 1167 11C0; +CA9E;CA9E;110D 1167 11C1;CA9E;110D 1167 11C1; +CA9F;CA9F;110D 1167 11C2;CA9F;110D 1167 11C2; +CAA0;CAA0;110D 1168;CAA0;110D 1168; +CAA1;CAA1;110D 1168 11A8;CAA1;110D 1168 11A8; +CAA2;CAA2;110D 1168 11A9;CAA2;110D 1168 11A9; +CAA3;CAA3;110D 1168 11AA;CAA3;110D 1168 11AA; +CAA4;CAA4;110D 1168 11AB;CAA4;110D 1168 11AB; +CAA5;CAA5;110D 1168 11AC;CAA5;110D 1168 11AC; +CAA6;CAA6;110D 1168 11AD;CAA6;110D 1168 11AD; +CAA7;CAA7;110D 1168 11AE;CAA7;110D 1168 11AE; +CAA8;CAA8;110D 1168 11AF;CAA8;110D 1168 11AF; +CAA9;CAA9;110D 1168 11B0;CAA9;110D 1168 11B0; +CAAA;CAAA;110D 1168 11B1;CAAA;110D 1168 11B1; +CAAB;CAAB;110D 1168 11B2;CAAB;110D 1168 11B2; +CAAC;CAAC;110D 1168 11B3;CAAC;110D 1168 11B3; +CAAD;CAAD;110D 1168 11B4;CAAD;110D 1168 11B4; +CAAE;CAAE;110D 1168 11B5;CAAE;110D 1168 11B5; +CAAF;CAAF;110D 1168 11B6;CAAF;110D 1168 11B6; +CAB0;CAB0;110D 1168 11B7;CAB0;110D 1168 11B7; +CAB1;CAB1;110D 1168 11B8;CAB1;110D 1168 11B8; +CAB2;CAB2;110D 1168 11B9;CAB2;110D 1168 11B9; +CAB3;CAB3;110D 1168 11BA;CAB3;110D 1168 11BA; +CAB4;CAB4;110D 1168 11BB;CAB4;110D 1168 11BB; +CAB5;CAB5;110D 1168 11BC;CAB5;110D 1168 11BC; +CAB6;CAB6;110D 1168 11BD;CAB6;110D 1168 11BD; +CAB7;CAB7;110D 1168 11BE;CAB7;110D 1168 11BE; +CAB8;CAB8;110D 1168 11BF;CAB8;110D 1168 11BF; +CAB9;CAB9;110D 1168 11C0;CAB9;110D 1168 11C0; +CABA;CABA;110D 1168 11C1;CABA;110D 1168 11C1; +CABB;CABB;110D 1168 11C2;CABB;110D 1168 11C2; +CABC;CABC;110D 1169;CABC;110D 1169; +CABD;CABD;110D 1169 11A8;CABD;110D 1169 11A8; +CABE;CABE;110D 1169 11A9;CABE;110D 1169 11A9; +CABF;CABF;110D 1169 11AA;CABF;110D 1169 11AA; +CAC0;CAC0;110D 1169 11AB;CAC0;110D 1169 11AB; +CAC1;CAC1;110D 1169 11AC;CAC1;110D 1169 11AC; +CAC2;CAC2;110D 1169 11AD;CAC2;110D 1169 11AD; +CAC3;CAC3;110D 1169 11AE;CAC3;110D 1169 11AE; +CAC4;CAC4;110D 1169 11AF;CAC4;110D 1169 11AF; +CAC5;CAC5;110D 1169 11B0;CAC5;110D 1169 11B0; +CAC6;CAC6;110D 1169 11B1;CAC6;110D 1169 11B1; +CAC7;CAC7;110D 1169 11B2;CAC7;110D 1169 11B2; +CAC8;CAC8;110D 1169 11B3;CAC8;110D 1169 11B3; +CAC9;CAC9;110D 1169 11B4;CAC9;110D 1169 11B4; +CACA;CACA;110D 1169 11B5;CACA;110D 1169 11B5; +CACB;CACB;110D 1169 11B6;CACB;110D 1169 11B6; +CACC;CACC;110D 1169 11B7;CACC;110D 1169 11B7; +CACD;CACD;110D 1169 11B8;CACD;110D 1169 11B8; +CACE;CACE;110D 1169 11B9;CACE;110D 1169 11B9; +CACF;CACF;110D 1169 11BA;CACF;110D 1169 11BA; +CAD0;CAD0;110D 1169 11BB;CAD0;110D 1169 11BB; +CAD1;CAD1;110D 1169 11BC;CAD1;110D 1169 11BC; +CAD2;CAD2;110D 1169 11BD;CAD2;110D 1169 11BD; +CAD3;CAD3;110D 1169 11BE;CAD3;110D 1169 11BE; +CAD4;CAD4;110D 1169 11BF;CAD4;110D 1169 11BF; +CAD5;CAD5;110D 1169 11C0;CAD5;110D 1169 11C0; +CAD6;CAD6;110D 1169 11C1;CAD6;110D 1169 11C1; +CAD7;CAD7;110D 1169 11C2;CAD7;110D 1169 11C2; +CAD8;CAD8;110D 116A;CAD8;110D 116A; +CAD9;CAD9;110D 116A 11A8;CAD9;110D 116A 11A8; +CADA;CADA;110D 116A 11A9;CADA;110D 116A 11A9; +CADB;CADB;110D 116A 11AA;CADB;110D 116A 11AA; +CADC;CADC;110D 116A 11AB;CADC;110D 116A 11AB; +CADD;CADD;110D 116A 11AC;CADD;110D 116A 11AC; +CADE;CADE;110D 116A 11AD;CADE;110D 116A 11AD; +CADF;CADF;110D 116A 11AE;CADF;110D 116A 11AE; +CAE0;CAE0;110D 116A 11AF;CAE0;110D 116A 11AF; +CAE1;CAE1;110D 116A 11B0;CAE1;110D 116A 11B0; +CAE2;CAE2;110D 116A 11B1;CAE2;110D 116A 11B1; +CAE3;CAE3;110D 116A 11B2;CAE3;110D 116A 11B2; +CAE4;CAE4;110D 116A 11B3;CAE4;110D 116A 11B3; +CAE5;CAE5;110D 116A 11B4;CAE5;110D 116A 11B4; +CAE6;CAE6;110D 116A 11B5;CAE6;110D 116A 11B5; +CAE7;CAE7;110D 116A 11B6;CAE7;110D 116A 11B6; +CAE8;CAE8;110D 116A 11B7;CAE8;110D 116A 11B7; +CAE9;CAE9;110D 116A 11B8;CAE9;110D 116A 11B8; +CAEA;CAEA;110D 116A 11B9;CAEA;110D 116A 11B9; +CAEB;CAEB;110D 116A 11BA;CAEB;110D 116A 11BA; +CAEC;CAEC;110D 116A 11BB;CAEC;110D 116A 11BB; +CAED;CAED;110D 116A 11BC;CAED;110D 116A 11BC; +CAEE;CAEE;110D 116A 11BD;CAEE;110D 116A 11BD; +CAEF;CAEF;110D 116A 11BE;CAEF;110D 116A 11BE; +CAF0;CAF0;110D 116A 11BF;CAF0;110D 116A 11BF; +CAF1;CAF1;110D 116A 11C0;CAF1;110D 116A 11C0; +CAF2;CAF2;110D 116A 11C1;CAF2;110D 116A 11C1; +CAF3;CAF3;110D 116A 11C2;CAF3;110D 116A 11C2; +CAF4;CAF4;110D 116B;CAF4;110D 116B; +CAF5;CAF5;110D 116B 11A8;CAF5;110D 116B 11A8; +CAF6;CAF6;110D 116B 11A9;CAF6;110D 116B 11A9; +CAF7;CAF7;110D 116B 11AA;CAF7;110D 116B 11AA; +CAF8;CAF8;110D 116B 11AB;CAF8;110D 116B 11AB; +CAF9;CAF9;110D 116B 11AC;CAF9;110D 116B 11AC; +CAFA;CAFA;110D 116B 11AD;CAFA;110D 116B 11AD; +CAFB;CAFB;110D 116B 11AE;CAFB;110D 116B 11AE; +CAFC;CAFC;110D 116B 11AF;CAFC;110D 116B 11AF; +CAFD;CAFD;110D 116B 11B0;CAFD;110D 116B 11B0; +CAFE;CAFE;110D 116B 11B1;CAFE;110D 116B 11B1; +CAFF;CAFF;110D 116B 11B2;CAFF;110D 116B 11B2; +CB00;CB00;110D 116B 11B3;CB00;110D 116B 11B3; +CB01;CB01;110D 116B 11B4;CB01;110D 116B 11B4; +CB02;CB02;110D 116B 11B5;CB02;110D 116B 11B5; +CB03;CB03;110D 116B 11B6;CB03;110D 116B 11B6; +CB04;CB04;110D 116B 11B7;CB04;110D 116B 11B7; +CB05;CB05;110D 116B 11B8;CB05;110D 116B 11B8; +CB06;CB06;110D 116B 11B9;CB06;110D 116B 11B9; +CB07;CB07;110D 116B 11BA;CB07;110D 116B 11BA; +CB08;CB08;110D 116B 11BB;CB08;110D 116B 11BB; +CB09;CB09;110D 116B 11BC;CB09;110D 116B 11BC; +CB0A;CB0A;110D 116B 11BD;CB0A;110D 116B 11BD; +CB0B;CB0B;110D 116B 11BE;CB0B;110D 116B 11BE; +CB0C;CB0C;110D 116B 11BF;CB0C;110D 116B 11BF; +CB0D;CB0D;110D 116B 11C0;CB0D;110D 116B 11C0; +CB0E;CB0E;110D 116B 11C1;CB0E;110D 116B 11C1; +CB0F;CB0F;110D 116B 11C2;CB0F;110D 116B 11C2; +CB10;CB10;110D 116C;CB10;110D 116C; +CB11;CB11;110D 116C 11A8;CB11;110D 116C 11A8; +CB12;CB12;110D 116C 11A9;CB12;110D 116C 11A9; +CB13;CB13;110D 116C 11AA;CB13;110D 116C 11AA; +CB14;CB14;110D 116C 11AB;CB14;110D 116C 11AB; +CB15;CB15;110D 116C 11AC;CB15;110D 116C 11AC; +CB16;CB16;110D 116C 11AD;CB16;110D 116C 11AD; +CB17;CB17;110D 116C 11AE;CB17;110D 116C 11AE; +CB18;CB18;110D 116C 11AF;CB18;110D 116C 11AF; +CB19;CB19;110D 116C 11B0;CB19;110D 116C 11B0; +CB1A;CB1A;110D 116C 11B1;CB1A;110D 116C 11B1; +CB1B;CB1B;110D 116C 11B2;CB1B;110D 116C 11B2; +CB1C;CB1C;110D 116C 11B3;CB1C;110D 116C 11B3; +CB1D;CB1D;110D 116C 11B4;CB1D;110D 116C 11B4; +CB1E;CB1E;110D 116C 11B5;CB1E;110D 116C 11B5; +CB1F;CB1F;110D 116C 11B6;CB1F;110D 116C 11B6; +CB20;CB20;110D 116C 11B7;CB20;110D 116C 11B7; +CB21;CB21;110D 116C 11B8;CB21;110D 116C 11B8; +CB22;CB22;110D 116C 11B9;CB22;110D 116C 11B9; +CB23;CB23;110D 116C 11BA;CB23;110D 116C 11BA; +CB24;CB24;110D 116C 11BB;CB24;110D 116C 11BB; +CB25;CB25;110D 116C 11BC;CB25;110D 116C 11BC; +CB26;CB26;110D 116C 11BD;CB26;110D 116C 11BD; +CB27;CB27;110D 116C 11BE;CB27;110D 116C 11BE; +CB28;CB28;110D 116C 11BF;CB28;110D 116C 11BF; +CB29;CB29;110D 116C 11C0;CB29;110D 116C 11C0; +CB2A;CB2A;110D 116C 11C1;CB2A;110D 116C 11C1; +CB2B;CB2B;110D 116C 11C2;CB2B;110D 116C 11C2; +CB2C;CB2C;110D 116D;CB2C;110D 116D; +CB2D;CB2D;110D 116D 11A8;CB2D;110D 116D 11A8; +CB2E;CB2E;110D 116D 11A9;CB2E;110D 116D 11A9; +CB2F;CB2F;110D 116D 11AA;CB2F;110D 116D 11AA; +CB30;CB30;110D 116D 11AB;CB30;110D 116D 11AB; +CB31;CB31;110D 116D 11AC;CB31;110D 116D 11AC; +CB32;CB32;110D 116D 11AD;CB32;110D 116D 11AD; +CB33;CB33;110D 116D 11AE;CB33;110D 116D 11AE; +CB34;CB34;110D 116D 11AF;CB34;110D 116D 11AF; +CB35;CB35;110D 116D 11B0;CB35;110D 116D 11B0; +CB36;CB36;110D 116D 11B1;CB36;110D 116D 11B1; +CB37;CB37;110D 116D 11B2;CB37;110D 116D 11B2; +CB38;CB38;110D 116D 11B3;CB38;110D 116D 11B3; +CB39;CB39;110D 116D 11B4;CB39;110D 116D 11B4; +CB3A;CB3A;110D 116D 11B5;CB3A;110D 116D 11B5; +CB3B;CB3B;110D 116D 11B6;CB3B;110D 116D 11B6; +CB3C;CB3C;110D 116D 11B7;CB3C;110D 116D 11B7; +CB3D;CB3D;110D 116D 11B8;CB3D;110D 116D 11B8; +CB3E;CB3E;110D 116D 11B9;CB3E;110D 116D 11B9; +CB3F;CB3F;110D 116D 11BA;CB3F;110D 116D 11BA; +CB40;CB40;110D 116D 11BB;CB40;110D 116D 11BB; +CB41;CB41;110D 116D 11BC;CB41;110D 116D 11BC; +CB42;CB42;110D 116D 11BD;CB42;110D 116D 11BD; +CB43;CB43;110D 116D 11BE;CB43;110D 116D 11BE; +CB44;CB44;110D 116D 11BF;CB44;110D 116D 11BF; +CB45;CB45;110D 116D 11C0;CB45;110D 116D 11C0; +CB46;CB46;110D 116D 11C1;CB46;110D 116D 11C1; +CB47;CB47;110D 116D 11C2;CB47;110D 116D 11C2; +CB48;CB48;110D 116E;CB48;110D 116E; +CB49;CB49;110D 116E 11A8;CB49;110D 116E 11A8; +CB4A;CB4A;110D 116E 11A9;CB4A;110D 116E 11A9; +CB4B;CB4B;110D 116E 11AA;CB4B;110D 116E 11AA; +CB4C;CB4C;110D 116E 11AB;CB4C;110D 116E 11AB; +CB4D;CB4D;110D 116E 11AC;CB4D;110D 116E 11AC; +CB4E;CB4E;110D 116E 11AD;CB4E;110D 116E 11AD; +CB4F;CB4F;110D 116E 11AE;CB4F;110D 116E 11AE; +CB50;CB50;110D 116E 11AF;CB50;110D 116E 11AF; +CB51;CB51;110D 116E 11B0;CB51;110D 116E 11B0; +CB52;CB52;110D 116E 11B1;CB52;110D 116E 11B1; +CB53;CB53;110D 116E 11B2;CB53;110D 116E 11B2; +CB54;CB54;110D 116E 11B3;CB54;110D 116E 11B3; +CB55;CB55;110D 116E 11B4;CB55;110D 116E 11B4; +CB56;CB56;110D 116E 11B5;CB56;110D 116E 11B5; +CB57;CB57;110D 116E 11B6;CB57;110D 116E 11B6; +CB58;CB58;110D 116E 11B7;CB58;110D 116E 11B7; +CB59;CB59;110D 116E 11B8;CB59;110D 116E 11B8; +CB5A;CB5A;110D 116E 11B9;CB5A;110D 116E 11B9; +CB5B;CB5B;110D 116E 11BA;CB5B;110D 116E 11BA; +CB5C;CB5C;110D 116E 11BB;CB5C;110D 116E 11BB; +CB5D;CB5D;110D 116E 11BC;CB5D;110D 116E 11BC; +CB5E;CB5E;110D 116E 11BD;CB5E;110D 116E 11BD; +CB5F;CB5F;110D 116E 11BE;CB5F;110D 116E 11BE; +CB60;CB60;110D 116E 11BF;CB60;110D 116E 11BF; +CB61;CB61;110D 116E 11C0;CB61;110D 116E 11C0; +CB62;CB62;110D 116E 11C1;CB62;110D 116E 11C1; +CB63;CB63;110D 116E 11C2;CB63;110D 116E 11C2; +CB64;CB64;110D 116F;CB64;110D 116F; +CB65;CB65;110D 116F 11A8;CB65;110D 116F 11A8; +CB66;CB66;110D 116F 11A9;CB66;110D 116F 11A9; +CB67;CB67;110D 116F 11AA;CB67;110D 116F 11AA; +CB68;CB68;110D 116F 11AB;CB68;110D 116F 11AB; +CB69;CB69;110D 116F 11AC;CB69;110D 116F 11AC; +CB6A;CB6A;110D 116F 11AD;CB6A;110D 116F 11AD; +CB6B;CB6B;110D 116F 11AE;CB6B;110D 116F 11AE; +CB6C;CB6C;110D 116F 11AF;CB6C;110D 116F 11AF; +CB6D;CB6D;110D 116F 11B0;CB6D;110D 116F 11B0; +CB6E;CB6E;110D 116F 11B1;CB6E;110D 116F 11B1; +CB6F;CB6F;110D 116F 11B2;CB6F;110D 116F 11B2; +CB70;CB70;110D 116F 11B3;CB70;110D 116F 11B3; +CB71;CB71;110D 116F 11B4;CB71;110D 116F 11B4; +CB72;CB72;110D 116F 11B5;CB72;110D 116F 11B5; +CB73;CB73;110D 116F 11B6;CB73;110D 116F 11B6; +CB74;CB74;110D 116F 11B7;CB74;110D 116F 11B7; +CB75;CB75;110D 116F 11B8;CB75;110D 116F 11B8; +CB76;CB76;110D 116F 11B9;CB76;110D 116F 11B9; +CB77;CB77;110D 116F 11BA;CB77;110D 116F 11BA; +CB78;CB78;110D 116F 11BB;CB78;110D 116F 11BB; +CB79;CB79;110D 116F 11BC;CB79;110D 116F 11BC; +CB7A;CB7A;110D 116F 11BD;CB7A;110D 116F 11BD; +CB7B;CB7B;110D 116F 11BE;CB7B;110D 116F 11BE; +CB7C;CB7C;110D 116F 11BF;CB7C;110D 116F 11BF; +CB7D;CB7D;110D 116F 11C0;CB7D;110D 116F 11C0; +CB7E;CB7E;110D 116F 11C1;CB7E;110D 116F 11C1; +CB7F;CB7F;110D 116F 11C2;CB7F;110D 116F 11C2; +CB80;CB80;110D 1170;CB80;110D 1170; +CB81;CB81;110D 1170 11A8;CB81;110D 1170 11A8; +CB82;CB82;110D 1170 11A9;CB82;110D 1170 11A9; +CB83;CB83;110D 1170 11AA;CB83;110D 1170 11AA; +CB84;CB84;110D 1170 11AB;CB84;110D 1170 11AB; +CB85;CB85;110D 1170 11AC;CB85;110D 1170 11AC; +CB86;CB86;110D 1170 11AD;CB86;110D 1170 11AD; +CB87;CB87;110D 1170 11AE;CB87;110D 1170 11AE; +CB88;CB88;110D 1170 11AF;CB88;110D 1170 11AF; +CB89;CB89;110D 1170 11B0;CB89;110D 1170 11B0; +CB8A;CB8A;110D 1170 11B1;CB8A;110D 1170 11B1; +CB8B;CB8B;110D 1170 11B2;CB8B;110D 1170 11B2; +CB8C;CB8C;110D 1170 11B3;CB8C;110D 1170 11B3; +CB8D;CB8D;110D 1170 11B4;CB8D;110D 1170 11B4; +CB8E;CB8E;110D 1170 11B5;CB8E;110D 1170 11B5; +CB8F;CB8F;110D 1170 11B6;CB8F;110D 1170 11B6; +CB90;CB90;110D 1170 11B7;CB90;110D 1170 11B7; +CB91;CB91;110D 1170 11B8;CB91;110D 1170 11B8; +CB92;CB92;110D 1170 11B9;CB92;110D 1170 11B9; +CB93;CB93;110D 1170 11BA;CB93;110D 1170 11BA; +CB94;CB94;110D 1170 11BB;CB94;110D 1170 11BB; +CB95;CB95;110D 1170 11BC;CB95;110D 1170 11BC; +CB96;CB96;110D 1170 11BD;CB96;110D 1170 11BD; +CB97;CB97;110D 1170 11BE;CB97;110D 1170 11BE; +CB98;CB98;110D 1170 11BF;CB98;110D 1170 11BF; +CB99;CB99;110D 1170 11C0;CB99;110D 1170 11C0; +CB9A;CB9A;110D 1170 11C1;CB9A;110D 1170 11C1; +CB9B;CB9B;110D 1170 11C2;CB9B;110D 1170 11C2; +CB9C;CB9C;110D 1171;CB9C;110D 1171; +CB9D;CB9D;110D 1171 11A8;CB9D;110D 1171 11A8; +CB9E;CB9E;110D 1171 11A9;CB9E;110D 1171 11A9; +CB9F;CB9F;110D 1171 11AA;CB9F;110D 1171 11AA; +CBA0;CBA0;110D 1171 11AB;CBA0;110D 1171 11AB; +CBA1;CBA1;110D 1171 11AC;CBA1;110D 1171 11AC; +CBA2;CBA2;110D 1171 11AD;CBA2;110D 1171 11AD; +CBA3;CBA3;110D 1171 11AE;CBA3;110D 1171 11AE; +CBA4;CBA4;110D 1171 11AF;CBA4;110D 1171 11AF; +CBA5;CBA5;110D 1171 11B0;CBA5;110D 1171 11B0; +CBA6;CBA6;110D 1171 11B1;CBA6;110D 1171 11B1; +CBA7;CBA7;110D 1171 11B2;CBA7;110D 1171 11B2; +CBA8;CBA8;110D 1171 11B3;CBA8;110D 1171 11B3; +CBA9;CBA9;110D 1171 11B4;CBA9;110D 1171 11B4; +CBAA;CBAA;110D 1171 11B5;CBAA;110D 1171 11B5; +CBAB;CBAB;110D 1171 11B6;CBAB;110D 1171 11B6; +CBAC;CBAC;110D 1171 11B7;CBAC;110D 1171 11B7; +CBAD;CBAD;110D 1171 11B8;CBAD;110D 1171 11B8; +CBAE;CBAE;110D 1171 11B9;CBAE;110D 1171 11B9; +CBAF;CBAF;110D 1171 11BA;CBAF;110D 1171 11BA; +CBB0;CBB0;110D 1171 11BB;CBB0;110D 1171 11BB; +CBB1;CBB1;110D 1171 11BC;CBB1;110D 1171 11BC; +CBB2;CBB2;110D 1171 11BD;CBB2;110D 1171 11BD; +CBB3;CBB3;110D 1171 11BE;CBB3;110D 1171 11BE; +CBB4;CBB4;110D 1171 11BF;CBB4;110D 1171 11BF; +CBB5;CBB5;110D 1171 11C0;CBB5;110D 1171 11C0; +CBB6;CBB6;110D 1171 11C1;CBB6;110D 1171 11C1; +CBB7;CBB7;110D 1171 11C2;CBB7;110D 1171 11C2; +CBB8;CBB8;110D 1172;CBB8;110D 1172; +CBB9;CBB9;110D 1172 11A8;CBB9;110D 1172 11A8; +CBBA;CBBA;110D 1172 11A9;CBBA;110D 1172 11A9; +CBBB;CBBB;110D 1172 11AA;CBBB;110D 1172 11AA; +CBBC;CBBC;110D 1172 11AB;CBBC;110D 1172 11AB; +CBBD;CBBD;110D 1172 11AC;CBBD;110D 1172 11AC; +CBBE;CBBE;110D 1172 11AD;CBBE;110D 1172 11AD; +CBBF;CBBF;110D 1172 11AE;CBBF;110D 1172 11AE; +CBC0;CBC0;110D 1172 11AF;CBC0;110D 1172 11AF; +CBC1;CBC1;110D 1172 11B0;CBC1;110D 1172 11B0; +CBC2;CBC2;110D 1172 11B1;CBC2;110D 1172 11B1; +CBC3;CBC3;110D 1172 11B2;CBC3;110D 1172 11B2; +CBC4;CBC4;110D 1172 11B3;CBC4;110D 1172 11B3; +CBC5;CBC5;110D 1172 11B4;CBC5;110D 1172 11B4; +CBC6;CBC6;110D 1172 11B5;CBC6;110D 1172 11B5; +CBC7;CBC7;110D 1172 11B6;CBC7;110D 1172 11B6; +CBC8;CBC8;110D 1172 11B7;CBC8;110D 1172 11B7; +CBC9;CBC9;110D 1172 11B8;CBC9;110D 1172 11B8; +CBCA;CBCA;110D 1172 11B9;CBCA;110D 1172 11B9; +CBCB;CBCB;110D 1172 11BA;CBCB;110D 1172 11BA; +CBCC;CBCC;110D 1172 11BB;CBCC;110D 1172 11BB; +CBCD;CBCD;110D 1172 11BC;CBCD;110D 1172 11BC; +CBCE;CBCE;110D 1172 11BD;CBCE;110D 1172 11BD; +CBCF;CBCF;110D 1172 11BE;CBCF;110D 1172 11BE; +CBD0;CBD0;110D 1172 11BF;CBD0;110D 1172 11BF; +CBD1;CBD1;110D 1172 11C0;CBD1;110D 1172 11C0; +CBD2;CBD2;110D 1172 11C1;CBD2;110D 1172 11C1; +CBD3;CBD3;110D 1172 11C2;CBD3;110D 1172 11C2; +CBD4;CBD4;110D 1173;CBD4;110D 1173; +CBD5;CBD5;110D 1173 11A8;CBD5;110D 1173 11A8; +CBD6;CBD6;110D 1173 11A9;CBD6;110D 1173 11A9; +CBD7;CBD7;110D 1173 11AA;CBD7;110D 1173 11AA; +CBD8;CBD8;110D 1173 11AB;CBD8;110D 1173 11AB; +CBD9;CBD9;110D 1173 11AC;CBD9;110D 1173 11AC; +CBDA;CBDA;110D 1173 11AD;CBDA;110D 1173 11AD; +CBDB;CBDB;110D 1173 11AE;CBDB;110D 1173 11AE; +CBDC;CBDC;110D 1173 11AF;CBDC;110D 1173 11AF; +CBDD;CBDD;110D 1173 11B0;CBDD;110D 1173 11B0; +CBDE;CBDE;110D 1173 11B1;CBDE;110D 1173 11B1; +CBDF;CBDF;110D 1173 11B2;CBDF;110D 1173 11B2; +CBE0;CBE0;110D 1173 11B3;CBE0;110D 1173 11B3; +CBE1;CBE1;110D 1173 11B4;CBE1;110D 1173 11B4; +CBE2;CBE2;110D 1173 11B5;CBE2;110D 1173 11B5; +CBE3;CBE3;110D 1173 11B6;CBE3;110D 1173 11B6; +CBE4;CBE4;110D 1173 11B7;CBE4;110D 1173 11B7; +CBE5;CBE5;110D 1173 11B8;CBE5;110D 1173 11B8; +CBE6;CBE6;110D 1173 11B9;CBE6;110D 1173 11B9; +CBE7;CBE7;110D 1173 11BA;CBE7;110D 1173 11BA; +CBE8;CBE8;110D 1173 11BB;CBE8;110D 1173 11BB; +CBE9;CBE9;110D 1173 11BC;CBE9;110D 1173 11BC; +CBEA;CBEA;110D 1173 11BD;CBEA;110D 1173 11BD; +CBEB;CBEB;110D 1173 11BE;CBEB;110D 1173 11BE; +CBEC;CBEC;110D 1173 11BF;CBEC;110D 1173 11BF; +CBED;CBED;110D 1173 11C0;CBED;110D 1173 11C0; +CBEE;CBEE;110D 1173 11C1;CBEE;110D 1173 11C1; +CBEF;CBEF;110D 1173 11C2;CBEF;110D 1173 11C2; +CBF0;CBF0;110D 1174;CBF0;110D 1174; +CBF1;CBF1;110D 1174 11A8;CBF1;110D 1174 11A8; +CBF2;CBF2;110D 1174 11A9;CBF2;110D 1174 11A9; +CBF3;CBF3;110D 1174 11AA;CBF3;110D 1174 11AA; +CBF4;CBF4;110D 1174 11AB;CBF4;110D 1174 11AB; +CBF5;CBF5;110D 1174 11AC;CBF5;110D 1174 11AC; +CBF6;CBF6;110D 1174 11AD;CBF6;110D 1174 11AD; +CBF7;CBF7;110D 1174 11AE;CBF7;110D 1174 11AE; +CBF8;CBF8;110D 1174 11AF;CBF8;110D 1174 11AF; +CBF9;CBF9;110D 1174 11B0;CBF9;110D 1174 11B0; +CBFA;CBFA;110D 1174 11B1;CBFA;110D 1174 11B1; +CBFB;CBFB;110D 1174 11B2;CBFB;110D 1174 11B2; +CBFC;CBFC;110D 1174 11B3;CBFC;110D 1174 11B3; +CBFD;CBFD;110D 1174 11B4;CBFD;110D 1174 11B4; +CBFE;CBFE;110D 1174 11B5;CBFE;110D 1174 11B5; +CBFF;CBFF;110D 1174 11B6;CBFF;110D 1174 11B6; +CC00;CC00;110D 1174 11B7;CC00;110D 1174 11B7; +CC01;CC01;110D 1174 11B8;CC01;110D 1174 11B8; +CC02;CC02;110D 1174 11B9;CC02;110D 1174 11B9; +CC03;CC03;110D 1174 11BA;CC03;110D 1174 11BA; +CC04;CC04;110D 1174 11BB;CC04;110D 1174 11BB; +CC05;CC05;110D 1174 11BC;CC05;110D 1174 11BC; +CC06;CC06;110D 1174 11BD;CC06;110D 1174 11BD; +CC07;CC07;110D 1174 11BE;CC07;110D 1174 11BE; +CC08;CC08;110D 1174 11BF;CC08;110D 1174 11BF; +CC09;CC09;110D 1174 11C0;CC09;110D 1174 11C0; +CC0A;CC0A;110D 1174 11C1;CC0A;110D 1174 11C1; +CC0B;CC0B;110D 1174 11C2;CC0B;110D 1174 11C2; +CC0C;CC0C;110D 1175;CC0C;110D 1175; +CC0D;CC0D;110D 1175 11A8;CC0D;110D 1175 11A8; +CC0E;CC0E;110D 1175 11A9;CC0E;110D 1175 11A9; +CC0F;CC0F;110D 1175 11AA;CC0F;110D 1175 11AA; +CC10;CC10;110D 1175 11AB;CC10;110D 1175 11AB; +CC11;CC11;110D 1175 11AC;CC11;110D 1175 11AC; +CC12;CC12;110D 1175 11AD;CC12;110D 1175 11AD; +CC13;CC13;110D 1175 11AE;CC13;110D 1175 11AE; +CC14;CC14;110D 1175 11AF;CC14;110D 1175 11AF; +CC15;CC15;110D 1175 11B0;CC15;110D 1175 11B0; +CC16;CC16;110D 1175 11B1;CC16;110D 1175 11B1; +CC17;CC17;110D 1175 11B2;CC17;110D 1175 11B2; +CC18;CC18;110D 1175 11B3;CC18;110D 1175 11B3; +CC19;CC19;110D 1175 11B4;CC19;110D 1175 11B4; +CC1A;CC1A;110D 1175 11B5;CC1A;110D 1175 11B5; +CC1B;CC1B;110D 1175 11B6;CC1B;110D 1175 11B6; +CC1C;CC1C;110D 1175 11B7;CC1C;110D 1175 11B7; +CC1D;CC1D;110D 1175 11B8;CC1D;110D 1175 11B8; +CC1E;CC1E;110D 1175 11B9;CC1E;110D 1175 11B9; +CC1F;CC1F;110D 1175 11BA;CC1F;110D 1175 11BA; +CC20;CC20;110D 1175 11BB;CC20;110D 1175 11BB; +CC21;CC21;110D 1175 11BC;CC21;110D 1175 11BC; +CC22;CC22;110D 1175 11BD;CC22;110D 1175 11BD; +CC23;CC23;110D 1175 11BE;CC23;110D 1175 11BE; +CC24;CC24;110D 1175 11BF;CC24;110D 1175 11BF; +CC25;CC25;110D 1175 11C0;CC25;110D 1175 11C0; +CC26;CC26;110D 1175 11C1;CC26;110D 1175 11C1; +CC27;CC27;110D 1175 11C2;CC27;110D 1175 11C2; +CC28;CC28;110E 1161;CC28;110E 1161; +CC29;CC29;110E 1161 11A8;CC29;110E 1161 11A8; +CC2A;CC2A;110E 1161 11A9;CC2A;110E 1161 11A9; +CC2B;CC2B;110E 1161 11AA;CC2B;110E 1161 11AA; +CC2C;CC2C;110E 1161 11AB;CC2C;110E 1161 11AB; +CC2D;CC2D;110E 1161 11AC;CC2D;110E 1161 11AC; +CC2E;CC2E;110E 1161 11AD;CC2E;110E 1161 11AD; +CC2F;CC2F;110E 1161 11AE;CC2F;110E 1161 11AE; +CC30;CC30;110E 1161 11AF;CC30;110E 1161 11AF; +CC31;CC31;110E 1161 11B0;CC31;110E 1161 11B0; +CC32;CC32;110E 1161 11B1;CC32;110E 1161 11B1; +CC33;CC33;110E 1161 11B2;CC33;110E 1161 11B2; +CC34;CC34;110E 1161 11B3;CC34;110E 1161 11B3; +CC35;CC35;110E 1161 11B4;CC35;110E 1161 11B4; +CC36;CC36;110E 1161 11B5;CC36;110E 1161 11B5; +CC37;CC37;110E 1161 11B6;CC37;110E 1161 11B6; +CC38;CC38;110E 1161 11B7;CC38;110E 1161 11B7; +CC39;CC39;110E 1161 11B8;CC39;110E 1161 11B8; +CC3A;CC3A;110E 1161 11B9;CC3A;110E 1161 11B9; +CC3B;CC3B;110E 1161 11BA;CC3B;110E 1161 11BA; +CC3C;CC3C;110E 1161 11BB;CC3C;110E 1161 11BB; +CC3D;CC3D;110E 1161 11BC;CC3D;110E 1161 11BC; +CC3E;CC3E;110E 1161 11BD;CC3E;110E 1161 11BD; +CC3F;CC3F;110E 1161 11BE;CC3F;110E 1161 11BE; +CC40;CC40;110E 1161 11BF;CC40;110E 1161 11BF; +CC41;CC41;110E 1161 11C0;CC41;110E 1161 11C0; +CC42;CC42;110E 1161 11C1;CC42;110E 1161 11C1; +CC43;CC43;110E 1161 11C2;CC43;110E 1161 11C2; +CC44;CC44;110E 1162;CC44;110E 1162; +CC45;CC45;110E 1162 11A8;CC45;110E 1162 11A8; +CC46;CC46;110E 1162 11A9;CC46;110E 1162 11A9; +CC47;CC47;110E 1162 11AA;CC47;110E 1162 11AA; +CC48;CC48;110E 1162 11AB;CC48;110E 1162 11AB; +CC49;CC49;110E 1162 11AC;CC49;110E 1162 11AC; +CC4A;CC4A;110E 1162 11AD;CC4A;110E 1162 11AD; +CC4B;CC4B;110E 1162 11AE;CC4B;110E 1162 11AE; +CC4C;CC4C;110E 1162 11AF;CC4C;110E 1162 11AF; +CC4D;CC4D;110E 1162 11B0;CC4D;110E 1162 11B0; +CC4E;CC4E;110E 1162 11B1;CC4E;110E 1162 11B1; +CC4F;CC4F;110E 1162 11B2;CC4F;110E 1162 11B2; +CC50;CC50;110E 1162 11B3;CC50;110E 1162 11B3; +CC51;CC51;110E 1162 11B4;CC51;110E 1162 11B4; +CC52;CC52;110E 1162 11B5;CC52;110E 1162 11B5; +CC53;CC53;110E 1162 11B6;CC53;110E 1162 11B6; +CC54;CC54;110E 1162 11B7;CC54;110E 1162 11B7; +CC55;CC55;110E 1162 11B8;CC55;110E 1162 11B8; +CC56;CC56;110E 1162 11B9;CC56;110E 1162 11B9; +CC57;CC57;110E 1162 11BA;CC57;110E 1162 11BA; +CC58;CC58;110E 1162 11BB;CC58;110E 1162 11BB; +CC59;CC59;110E 1162 11BC;CC59;110E 1162 11BC; +CC5A;CC5A;110E 1162 11BD;CC5A;110E 1162 11BD; +CC5B;CC5B;110E 1162 11BE;CC5B;110E 1162 11BE; +CC5C;CC5C;110E 1162 11BF;CC5C;110E 1162 11BF; +CC5D;CC5D;110E 1162 11C0;CC5D;110E 1162 11C0; +CC5E;CC5E;110E 1162 11C1;CC5E;110E 1162 11C1; +CC5F;CC5F;110E 1162 11C2;CC5F;110E 1162 11C2; +CC60;CC60;110E 1163;CC60;110E 1163; +CC61;CC61;110E 1163 11A8;CC61;110E 1163 11A8; +CC62;CC62;110E 1163 11A9;CC62;110E 1163 11A9; +CC63;CC63;110E 1163 11AA;CC63;110E 1163 11AA; +CC64;CC64;110E 1163 11AB;CC64;110E 1163 11AB; +CC65;CC65;110E 1163 11AC;CC65;110E 1163 11AC; +CC66;CC66;110E 1163 11AD;CC66;110E 1163 11AD; +CC67;CC67;110E 1163 11AE;CC67;110E 1163 11AE; +CC68;CC68;110E 1163 11AF;CC68;110E 1163 11AF; +CC69;CC69;110E 1163 11B0;CC69;110E 1163 11B0; +CC6A;CC6A;110E 1163 11B1;CC6A;110E 1163 11B1; +CC6B;CC6B;110E 1163 11B2;CC6B;110E 1163 11B2; +CC6C;CC6C;110E 1163 11B3;CC6C;110E 1163 11B3; +CC6D;CC6D;110E 1163 11B4;CC6D;110E 1163 11B4; +CC6E;CC6E;110E 1163 11B5;CC6E;110E 1163 11B5; +CC6F;CC6F;110E 1163 11B6;CC6F;110E 1163 11B6; +CC70;CC70;110E 1163 11B7;CC70;110E 1163 11B7; +CC71;CC71;110E 1163 11B8;CC71;110E 1163 11B8; +CC72;CC72;110E 1163 11B9;CC72;110E 1163 11B9; +CC73;CC73;110E 1163 11BA;CC73;110E 1163 11BA; +CC74;CC74;110E 1163 11BB;CC74;110E 1163 11BB; +CC75;CC75;110E 1163 11BC;CC75;110E 1163 11BC; +CC76;CC76;110E 1163 11BD;CC76;110E 1163 11BD; +CC77;CC77;110E 1163 11BE;CC77;110E 1163 11BE; +CC78;CC78;110E 1163 11BF;CC78;110E 1163 11BF; +CC79;CC79;110E 1163 11C0;CC79;110E 1163 11C0; +CC7A;CC7A;110E 1163 11C1;CC7A;110E 1163 11C1; +CC7B;CC7B;110E 1163 11C2;CC7B;110E 1163 11C2; +CC7C;CC7C;110E 1164;CC7C;110E 1164; +CC7D;CC7D;110E 1164 11A8;CC7D;110E 1164 11A8; +CC7E;CC7E;110E 1164 11A9;CC7E;110E 1164 11A9; +CC7F;CC7F;110E 1164 11AA;CC7F;110E 1164 11AA; +CC80;CC80;110E 1164 11AB;CC80;110E 1164 11AB; +CC81;CC81;110E 1164 11AC;CC81;110E 1164 11AC; +CC82;CC82;110E 1164 11AD;CC82;110E 1164 11AD; +CC83;CC83;110E 1164 11AE;CC83;110E 1164 11AE; +CC84;CC84;110E 1164 11AF;CC84;110E 1164 11AF; +CC85;CC85;110E 1164 11B0;CC85;110E 1164 11B0; +CC86;CC86;110E 1164 11B1;CC86;110E 1164 11B1; +CC87;CC87;110E 1164 11B2;CC87;110E 1164 11B2; +CC88;CC88;110E 1164 11B3;CC88;110E 1164 11B3; +CC89;CC89;110E 1164 11B4;CC89;110E 1164 11B4; +CC8A;CC8A;110E 1164 11B5;CC8A;110E 1164 11B5; +CC8B;CC8B;110E 1164 11B6;CC8B;110E 1164 11B6; +CC8C;CC8C;110E 1164 11B7;CC8C;110E 1164 11B7; +CC8D;CC8D;110E 1164 11B8;CC8D;110E 1164 11B8; +CC8E;CC8E;110E 1164 11B9;CC8E;110E 1164 11B9; +CC8F;CC8F;110E 1164 11BA;CC8F;110E 1164 11BA; +CC90;CC90;110E 1164 11BB;CC90;110E 1164 11BB; +CC91;CC91;110E 1164 11BC;CC91;110E 1164 11BC; +CC92;CC92;110E 1164 11BD;CC92;110E 1164 11BD; +CC93;CC93;110E 1164 11BE;CC93;110E 1164 11BE; +CC94;CC94;110E 1164 11BF;CC94;110E 1164 11BF; +CC95;CC95;110E 1164 11C0;CC95;110E 1164 11C0; +CC96;CC96;110E 1164 11C1;CC96;110E 1164 11C1; +CC97;CC97;110E 1164 11C2;CC97;110E 1164 11C2; +CC98;CC98;110E 1165;CC98;110E 1165; +CC99;CC99;110E 1165 11A8;CC99;110E 1165 11A8; +CC9A;CC9A;110E 1165 11A9;CC9A;110E 1165 11A9; +CC9B;CC9B;110E 1165 11AA;CC9B;110E 1165 11AA; +CC9C;CC9C;110E 1165 11AB;CC9C;110E 1165 11AB; +CC9D;CC9D;110E 1165 11AC;CC9D;110E 1165 11AC; +CC9E;CC9E;110E 1165 11AD;CC9E;110E 1165 11AD; +CC9F;CC9F;110E 1165 11AE;CC9F;110E 1165 11AE; +CCA0;CCA0;110E 1165 11AF;CCA0;110E 1165 11AF; +CCA1;CCA1;110E 1165 11B0;CCA1;110E 1165 11B0; +CCA2;CCA2;110E 1165 11B1;CCA2;110E 1165 11B1; +CCA3;CCA3;110E 1165 11B2;CCA3;110E 1165 11B2; +CCA4;CCA4;110E 1165 11B3;CCA4;110E 1165 11B3; +CCA5;CCA5;110E 1165 11B4;CCA5;110E 1165 11B4; +CCA6;CCA6;110E 1165 11B5;CCA6;110E 1165 11B5; +CCA7;CCA7;110E 1165 11B6;CCA7;110E 1165 11B6; +CCA8;CCA8;110E 1165 11B7;CCA8;110E 1165 11B7; +CCA9;CCA9;110E 1165 11B8;CCA9;110E 1165 11B8; +CCAA;CCAA;110E 1165 11B9;CCAA;110E 1165 11B9; +CCAB;CCAB;110E 1165 11BA;CCAB;110E 1165 11BA; +CCAC;CCAC;110E 1165 11BB;CCAC;110E 1165 11BB; +CCAD;CCAD;110E 1165 11BC;CCAD;110E 1165 11BC; +CCAE;CCAE;110E 1165 11BD;CCAE;110E 1165 11BD; +CCAF;CCAF;110E 1165 11BE;CCAF;110E 1165 11BE; +CCB0;CCB0;110E 1165 11BF;CCB0;110E 1165 11BF; +CCB1;CCB1;110E 1165 11C0;CCB1;110E 1165 11C0; +CCB2;CCB2;110E 1165 11C1;CCB2;110E 1165 11C1; +CCB3;CCB3;110E 1165 11C2;CCB3;110E 1165 11C2; +CCB4;CCB4;110E 1166;CCB4;110E 1166; +CCB5;CCB5;110E 1166 11A8;CCB5;110E 1166 11A8; +CCB6;CCB6;110E 1166 11A9;CCB6;110E 1166 11A9; +CCB7;CCB7;110E 1166 11AA;CCB7;110E 1166 11AA; +CCB8;CCB8;110E 1166 11AB;CCB8;110E 1166 11AB; +CCB9;CCB9;110E 1166 11AC;CCB9;110E 1166 11AC; +CCBA;CCBA;110E 1166 11AD;CCBA;110E 1166 11AD; +CCBB;CCBB;110E 1166 11AE;CCBB;110E 1166 11AE; +CCBC;CCBC;110E 1166 11AF;CCBC;110E 1166 11AF; +CCBD;CCBD;110E 1166 11B0;CCBD;110E 1166 11B0; +CCBE;CCBE;110E 1166 11B1;CCBE;110E 1166 11B1; +CCBF;CCBF;110E 1166 11B2;CCBF;110E 1166 11B2; +CCC0;CCC0;110E 1166 11B3;CCC0;110E 1166 11B3; +CCC1;CCC1;110E 1166 11B4;CCC1;110E 1166 11B4; +CCC2;CCC2;110E 1166 11B5;CCC2;110E 1166 11B5; +CCC3;CCC3;110E 1166 11B6;CCC3;110E 1166 11B6; +CCC4;CCC4;110E 1166 11B7;CCC4;110E 1166 11B7; +CCC5;CCC5;110E 1166 11B8;CCC5;110E 1166 11B8; +CCC6;CCC6;110E 1166 11B9;CCC6;110E 1166 11B9; +CCC7;CCC7;110E 1166 11BA;CCC7;110E 1166 11BA; +CCC8;CCC8;110E 1166 11BB;CCC8;110E 1166 11BB; +CCC9;CCC9;110E 1166 11BC;CCC9;110E 1166 11BC; +CCCA;CCCA;110E 1166 11BD;CCCA;110E 1166 11BD; +CCCB;CCCB;110E 1166 11BE;CCCB;110E 1166 11BE; +CCCC;CCCC;110E 1166 11BF;CCCC;110E 1166 11BF; +CCCD;CCCD;110E 1166 11C0;CCCD;110E 1166 11C0; +CCCE;CCCE;110E 1166 11C1;CCCE;110E 1166 11C1; +CCCF;CCCF;110E 1166 11C2;CCCF;110E 1166 11C2; +CCD0;CCD0;110E 1167;CCD0;110E 1167; +CCD1;CCD1;110E 1167 11A8;CCD1;110E 1167 11A8; +CCD2;CCD2;110E 1167 11A9;CCD2;110E 1167 11A9; +CCD3;CCD3;110E 1167 11AA;CCD3;110E 1167 11AA; +CCD4;CCD4;110E 1167 11AB;CCD4;110E 1167 11AB; +CCD5;CCD5;110E 1167 11AC;CCD5;110E 1167 11AC; +CCD6;CCD6;110E 1167 11AD;CCD6;110E 1167 11AD; +CCD7;CCD7;110E 1167 11AE;CCD7;110E 1167 11AE; +CCD8;CCD8;110E 1167 11AF;CCD8;110E 1167 11AF; +CCD9;CCD9;110E 1167 11B0;CCD9;110E 1167 11B0; +CCDA;CCDA;110E 1167 11B1;CCDA;110E 1167 11B1; +CCDB;CCDB;110E 1167 11B2;CCDB;110E 1167 11B2; +CCDC;CCDC;110E 1167 11B3;CCDC;110E 1167 11B3; +CCDD;CCDD;110E 1167 11B4;CCDD;110E 1167 11B4; +CCDE;CCDE;110E 1167 11B5;CCDE;110E 1167 11B5; +CCDF;CCDF;110E 1167 11B6;CCDF;110E 1167 11B6; +CCE0;CCE0;110E 1167 11B7;CCE0;110E 1167 11B7; +CCE1;CCE1;110E 1167 11B8;CCE1;110E 1167 11B8; +CCE2;CCE2;110E 1167 11B9;CCE2;110E 1167 11B9; +CCE3;CCE3;110E 1167 11BA;CCE3;110E 1167 11BA; +CCE4;CCE4;110E 1167 11BB;CCE4;110E 1167 11BB; +CCE5;CCE5;110E 1167 11BC;CCE5;110E 1167 11BC; +CCE6;CCE6;110E 1167 11BD;CCE6;110E 1167 11BD; +CCE7;CCE7;110E 1167 11BE;CCE7;110E 1167 11BE; +CCE8;CCE8;110E 1167 11BF;CCE8;110E 1167 11BF; +CCE9;CCE9;110E 1167 11C0;CCE9;110E 1167 11C0; +CCEA;CCEA;110E 1167 11C1;CCEA;110E 1167 11C1; +CCEB;CCEB;110E 1167 11C2;CCEB;110E 1167 11C2; +CCEC;CCEC;110E 1168;CCEC;110E 1168; +CCED;CCED;110E 1168 11A8;CCED;110E 1168 11A8; +CCEE;CCEE;110E 1168 11A9;CCEE;110E 1168 11A9; +CCEF;CCEF;110E 1168 11AA;CCEF;110E 1168 11AA; +CCF0;CCF0;110E 1168 11AB;CCF0;110E 1168 11AB; +CCF1;CCF1;110E 1168 11AC;CCF1;110E 1168 11AC; +CCF2;CCF2;110E 1168 11AD;CCF2;110E 1168 11AD; +CCF3;CCF3;110E 1168 11AE;CCF3;110E 1168 11AE; +CCF4;CCF4;110E 1168 11AF;CCF4;110E 1168 11AF; +CCF5;CCF5;110E 1168 11B0;CCF5;110E 1168 11B0; +CCF6;CCF6;110E 1168 11B1;CCF6;110E 1168 11B1; +CCF7;CCF7;110E 1168 11B2;CCF7;110E 1168 11B2; +CCF8;CCF8;110E 1168 11B3;CCF8;110E 1168 11B3; +CCF9;CCF9;110E 1168 11B4;CCF9;110E 1168 11B4; +CCFA;CCFA;110E 1168 11B5;CCFA;110E 1168 11B5; +CCFB;CCFB;110E 1168 11B6;CCFB;110E 1168 11B6; +CCFC;CCFC;110E 1168 11B7;CCFC;110E 1168 11B7; +CCFD;CCFD;110E 1168 11B8;CCFD;110E 1168 11B8; +CCFE;CCFE;110E 1168 11B9;CCFE;110E 1168 11B9; +CCFF;CCFF;110E 1168 11BA;CCFF;110E 1168 11BA; +CD00;CD00;110E 1168 11BB;CD00;110E 1168 11BB; +CD01;CD01;110E 1168 11BC;CD01;110E 1168 11BC; +CD02;CD02;110E 1168 11BD;CD02;110E 1168 11BD; +CD03;CD03;110E 1168 11BE;CD03;110E 1168 11BE; +CD04;CD04;110E 1168 11BF;CD04;110E 1168 11BF; +CD05;CD05;110E 1168 11C0;CD05;110E 1168 11C0; +CD06;CD06;110E 1168 11C1;CD06;110E 1168 11C1; +CD07;CD07;110E 1168 11C2;CD07;110E 1168 11C2; +CD08;CD08;110E 1169;CD08;110E 1169; +CD09;CD09;110E 1169 11A8;CD09;110E 1169 11A8; +CD0A;CD0A;110E 1169 11A9;CD0A;110E 1169 11A9; +CD0B;CD0B;110E 1169 11AA;CD0B;110E 1169 11AA; +CD0C;CD0C;110E 1169 11AB;CD0C;110E 1169 11AB; +CD0D;CD0D;110E 1169 11AC;CD0D;110E 1169 11AC; +CD0E;CD0E;110E 1169 11AD;CD0E;110E 1169 11AD; +CD0F;CD0F;110E 1169 11AE;CD0F;110E 1169 11AE; +CD10;CD10;110E 1169 11AF;CD10;110E 1169 11AF; +CD11;CD11;110E 1169 11B0;CD11;110E 1169 11B0; +CD12;CD12;110E 1169 11B1;CD12;110E 1169 11B1; +CD13;CD13;110E 1169 11B2;CD13;110E 1169 11B2; +CD14;CD14;110E 1169 11B3;CD14;110E 1169 11B3; +CD15;CD15;110E 1169 11B4;CD15;110E 1169 11B4; +CD16;CD16;110E 1169 11B5;CD16;110E 1169 11B5; +CD17;CD17;110E 1169 11B6;CD17;110E 1169 11B6; +CD18;CD18;110E 1169 11B7;CD18;110E 1169 11B7; +CD19;CD19;110E 1169 11B8;CD19;110E 1169 11B8; +CD1A;CD1A;110E 1169 11B9;CD1A;110E 1169 11B9; +CD1B;CD1B;110E 1169 11BA;CD1B;110E 1169 11BA; +CD1C;CD1C;110E 1169 11BB;CD1C;110E 1169 11BB; +CD1D;CD1D;110E 1169 11BC;CD1D;110E 1169 11BC; +CD1E;CD1E;110E 1169 11BD;CD1E;110E 1169 11BD; +CD1F;CD1F;110E 1169 11BE;CD1F;110E 1169 11BE; +CD20;CD20;110E 1169 11BF;CD20;110E 1169 11BF; +CD21;CD21;110E 1169 11C0;CD21;110E 1169 11C0; +CD22;CD22;110E 1169 11C1;CD22;110E 1169 11C1; +CD23;CD23;110E 1169 11C2;CD23;110E 1169 11C2; +CD24;CD24;110E 116A;CD24;110E 116A; +CD25;CD25;110E 116A 11A8;CD25;110E 116A 11A8; +CD26;CD26;110E 116A 11A9;CD26;110E 116A 11A9; +CD27;CD27;110E 116A 11AA;CD27;110E 116A 11AA; +CD28;CD28;110E 116A 11AB;CD28;110E 116A 11AB; +CD29;CD29;110E 116A 11AC;CD29;110E 116A 11AC; +CD2A;CD2A;110E 116A 11AD;CD2A;110E 116A 11AD; +CD2B;CD2B;110E 116A 11AE;CD2B;110E 116A 11AE; +CD2C;CD2C;110E 116A 11AF;CD2C;110E 116A 11AF; +CD2D;CD2D;110E 116A 11B0;CD2D;110E 116A 11B0; +CD2E;CD2E;110E 116A 11B1;CD2E;110E 116A 11B1; +CD2F;CD2F;110E 116A 11B2;CD2F;110E 116A 11B2; +CD30;CD30;110E 116A 11B3;CD30;110E 116A 11B3; +CD31;CD31;110E 116A 11B4;CD31;110E 116A 11B4; +CD32;CD32;110E 116A 11B5;CD32;110E 116A 11B5; +CD33;CD33;110E 116A 11B6;CD33;110E 116A 11B6; +CD34;CD34;110E 116A 11B7;CD34;110E 116A 11B7; +CD35;CD35;110E 116A 11B8;CD35;110E 116A 11B8; +CD36;CD36;110E 116A 11B9;CD36;110E 116A 11B9; +CD37;CD37;110E 116A 11BA;CD37;110E 116A 11BA; +CD38;CD38;110E 116A 11BB;CD38;110E 116A 11BB; +CD39;CD39;110E 116A 11BC;CD39;110E 116A 11BC; +CD3A;CD3A;110E 116A 11BD;CD3A;110E 116A 11BD; +CD3B;CD3B;110E 116A 11BE;CD3B;110E 116A 11BE; +CD3C;CD3C;110E 116A 11BF;CD3C;110E 116A 11BF; +CD3D;CD3D;110E 116A 11C0;CD3D;110E 116A 11C0; +CD3E;CD3E;110E 116A 11C1;CD3E;110E 116A 11C1; +CD3F;CD3F;110E 116A 11C2;CD3F;110E 116A 11C2; +CD40;CD40;110E 116B;CD40;110E 116B; +CD41;CD41;110E 116B 11A8;CD41;110E 116B 11A8; +CD42;CD42;110E 116B 11A9;CD42;110E 116B 11A9; +CD43;CD43;110E 116B 11AA;CD43;110E 116B 11AA; +CD44;CD44;110E 116B 11AB;CD44;110E 116B 11AB; +CD45;CD45;110E 116B 11AC;CD45;110E 116B 11AC; +CD46;CD46;110E 116B 11AD;CD46;110E 116B 11AD; +CD47;CD47;110E 116B 11AE;CD47;110E 116B 11AE; +CD48;CD48;110E 116B 11AF;CD48;110E 116B 11AF; +CD49;CD49;110E 116B 11B0;CD49;110E 116B 11B0; +CD4A;CD4A;110E 116B 11B1;CD4A;110E 116B 11B1; +CD4B;CD4B;110E 116B 11B2;CD4B;110E 116B 11B2; +CD4C;CD4C;110E 116B 11B3;CD4C;110E 116B 11B3; +CD4D;CD4D;110E 116B 11B4;CD4D;110E 116B 11B4; +CD4E;CD4E;110E 116B 11B5;CD4E;110E 116B 11B5; +CD4F;CD4F;110E 116B 11B6;CD4F;110E 116B 11B6; +CD50;CD50;110E 116B 11B7;CD50;110E 116B 11B7; +CD51;CD51;110E 116B 11B8;CD51;110E 116B 11B8; +CD52;CD52;110E 116B 11B9;CD52;110E 116B 11B9; +CD53;CD53;110E 116B 11BA;CD53;110E 116B 11BA; +CD54;CD54;110E 116B 11BB;CD54;110E 116B 11BB; +CD55;CD55;110E 116B 11BC;CD55;110E 116B 11BC; +CD56;CD56;110E 116B 11BD;CD56;110E 116B 11BD; +CD57;CD57;110E 116B 11BE;CD57;110E 116B 11BE; +CD58;CD58;110E 116B 11BF;CD58;110E 116B 11BF; +CD59;CD59;110E 116B 11C0;CD59;110E 116B 11C0; +CD5A;CD5A;110E 116B 11C1;CD5A;110E 116B 11C1; +CD5B;CD5B;110E 116B 11C2;CD5B;110E 116B 11C2; +CD5C;CD5C;110E 116C;CD5C;110E 116C; +CD5D;CD5D;110E 116C 11A8;CD5D;110E 116C 11A8; +CD5E;CD5E;110E 116C 11A9;CD5E;110E 116C 11A9; +CD5F;CD5F;110E 116C 11AA;CD5F;110E 116C 11AA; +CD60;CD60;110E 116C 11AB;CD60;110E 116C 11AB; +CD61;CD61;110E 116C 11AC;CD61;110E 116C 11AC; +CD62;CD62;110E 116C 11AD;CD62;110E 116C 11AD; +CD63;CD63;110E 116C 11AE;CD63;110E 116C 11AE; +CD64;CD64;110E 116C 11AF;CD64;110E 116C 11AF; +CD65;CD65;110E 116C 11B0;CD65;110E 116C 11B0; +CD66;CD66;110E 116C 11B1;CD66;110E 116C 11B1; +CD67;CD67;110E 116C 11B2;CD67;110E 116C 11B2; +CD68;CD68;110E 116C 11B3;CD68;110E 116C 11B3; +CD69;CD69;110E 116C 11B4;CD69;110E 116C 11B4; +CD6A;CD6A;110E 116C 11B5;CD6A;110E 116C 11B5; +CD6B;CD6B;110E 116C 11B6;CD6B;110E 116C 11B6; +CD6C;CD6C;110E 116C 11B7;CD6C;110E 116C 11B7; +CD6D;CD6D;110E 116C 11B8;CD6D;110E 116C 11B8; +CD6E;CD6E;110E 116C 11B9;CD6E;110E 116C 11B9; +CD6F;CD6F;110E 116C 11BA;CD6F;110E 116C 11BA; +CD70;CD70;110E 116C 11BB;CD70;110E 116C 11BB; +CD71;CD71;110E 116C 11BC;CD71;110E 116C 11BC; +CD72;CD72;110E 116C 11BD;CD72;110E 116C 11BD; +CD73;CD73;110E 116C 11BE;CD73;110E 116C 11BE; +CD74;CD74;110E 116C 11BF;CD74;110E 116C 11BF; +CD75;CD75;110E 116C 11C0;CD75;110E 116C 11C0; +CD76;CD76;110E 116C 11C1;CD76;110E 116C 11C1; +CD77;CD77;110E 116C 11C2;CD77;110E 116C 11C2; +CD78;CD78;110E 116D;CD78;110E 116D; +CD79;CD79;110E 116D 11A8;CD79;110E 116D 11A8; +CD7A;CD7A;110E 116D 11A9;CD7A;110E 116D 11A9; +CD7B;CD7B;110E 116D 11AA;CD7B;110E 116D 11AA; +CD7C;CD7C;110E 116D 11AB;CD7C;110E 116D 11AB; +CD7D;CD7D;110E 116D 11AC;CD7D;110E 116D 11AC; +CD7E;CD7E;110E 116D 11AD;CD7E;110E 116D 11AD; +CD7F;CD7F;110E 116D 11AE;CD7F;110E 116D 11AE; +CD80;CD80;110E 116D 11AF;CD80;110E 116D 11AF; +CD81;CD81;110E 116D 11B0;CD81;110E 116D 11B0; +CD82;CD82;110E 116D 11B1;CD82;110E 116D 11B1; +CD83;CD83;110E 116D 11B2;CD83;110E 116D 11B2; +CD84;CD84;110E 116D 11B3;CD84;110E 116D 11B3; +CD85;CD85;110E 116D 11B4;CD85;110E 116D 11B4; +CD86;CD86;110E 116D 11B5;CD86;110E 116D 11B5; +CD87;CD87;110E 116D 11B6;CD87;110E 116D 11B6; +CD88;CD88;110E 116D 11B7;CD88;110E 116D 11B7; +CD89;CD89;110E 116D 11B8;CD89;110E 116D 11B8; +CD8A;CD8A;110E 116D 11B9;CD8A;110E 116D 11B9; +CD8B;CD8B;110E 116D 11BA;CD8B;110E 116D 11BA; +CD8C;CD8C;110E 116D 11BB;CD8C;110E 116D 11BB; +CD8D;CD8D;110E 116D 11BC;CD8D;110E 116D 11BC; +CD8E;CD8E;110E 116D 11BD;CD8E;110E 116D 11BD; +CD8F;CD8F;110E 116D 11BE;CD8F;110E 116D 11BE; +CD90;CD90;110E 116D 11BF;CD90;110E 116D 11BF; +CD91;CD91;110E 116D 11C0;CD91;110E 116D 11C0; +CD92;CD92;110E 116D 11C1;CD92;110E 116D 11C1; +CD93;CD93;110E 116D 11C2;CD93;110E 116D 11C2; +CD94;CD94;110E 116E;CD94;110E 116E; +CD95;CD95;110E 116E 11A8;CD95;110E 116E 11A8; +CD96;CD96;110E 116E 11A9;CD96;110E 116E 11A9; +CD97;CD97;110E 116E 11AA;CD97;110E 116E 11AA; +CD98;CD98;110E 116E 11AB;CD98;110E 116E 11AB; +CD99;CD99;110E 116E 11AC;CD99;110E 116E 11AC; +CD9A;CD9A;110E 116E 11AD;CD9A;110E 116E 11AD; +CD9B;CD9B;110E 116E 11AE;CD9B;110E 116E 11AE; +CD9C;CD9C;110E 116E 11AF;CD9C;110E 116E 11AF; +CD9D;CD9D;110E 116E 11B0;CD9D;110E 116E 11B0; +CD9E;CD9E;110E 116E 11B1;CD9E;110E 116E 11B1; +CD9F;CD9F;110E 116E 11B2;CD9F;110E 116E 11B2; +CDA0;CDA0;110E 116E 11B3;CDA0;110E 116E 11B3; +CDA1;CDA1;110E 116E 11B4;CDA1;110E 116E 11B4; +CDA2;CDA2;110E 116E 11B5;CDA2;110E 116E 11B5; +CDA3;CDA3;110E 116E 11B6;CDA3;110E 116E 11B6; +CDA4;CDA4;110E 116E 11B7;CDA4;110E 116E 11B7; +CDA5;CDA5;110E 116E 11B8;CDA5;110E 116E 11B8; +CDA6;CDA6;110E 116E 11B9;CDA6;110E 116E 11B9; +CDA7;CDA7;110E 116E 11BA;CDA7;110E 116E 11BA; +CDA8;CDA8;110E 116E 11BB;CDA8;110E 116E 11BB; +CDA9;CDA9;110E 116E 11BC;CDA9;110E 116E 11BC; +CDAA;CDAA;110E 116E 11BD;CDAA;110E 116E 11BD; +CDAB;CDAB;110E 116E 11BE;CDAB;110E 116E 11BE; +CDAC;CDAC;110E 116E 11BF;CDAC;110E 116E 11BF; +CDAD;CDAD;110E 116E 11C0;CDAD;110E 116E 11C0; +CDAE;CDAE;110E 116E 11C1;CDAE;110E 116E 11C1; +CDAF;CDAF;110E 116E 11C2;CDAF;110E 116E 11C2; +CDB0;CDB0;110E 116F;CDB0;110E 116F; +CDB1;CDB1;110E 116F 11A8;CDB1;110E 116F 11A8; +CDB2;CDB2;110E 116F 11A9;CDB2;110E 116F 11A9; +CDB3;CDB3;110E 116F 11AA;CDB3;110E 116F 11AA; +CDB4;CDB4;110E 116F 11AB;CDB4;110E 116F 11AB; +CDB5;CDB5;110E 116F 11AC;CDB5;110E 116F 11AC; +CDB6;CDB6;110E 116F 11AD;CDB6;110E 116F 11AD; +CDB7;CDB7;110E 116F 11AE;CDB7;110E 116F 11AE; +CDB8;CDB8;110E 116F 11AF;CDB8;110E 116F 11AF; +CDB9;CDB9;110E 116F 11B0;CDB9;110E 116F 11B0; +CDBA;CDBA;110E 116F 11B1;CDBA;110E 116F 11B1; +CDBB;CDBB;110E 116F 11B2;CDBB;110E 116F 11B2; +CDBC;CDBC;110E 116F 11B3;CDBC;110E 116F 11B3; +CDBD;CDBD;110E 116F 11B4;CDBD;110E 116F 11B4; +CDBE;CDBE;110E 116F 11B5;CDBE;110E 116F 11B5; +CDBF;CDBF;110E 116F 11B6;CDBF;110E 116F 11B6; +CDC0;CDC0;110E 116F 11B7;CDC0;110E 116F 11B7; +CDC1;CDC1;110E 116F 11B8;CDC1;110E 116F 11B8; +CDC2;CDC2;110E 116F 11B9;CDC2;110E 116F 11B9; +CDC3;CDC3;110E 116F 11BA;CDC3;110E 116F 11BA; +CDC4;CDC4;110E 116F 11BB;CDC4;110E 116F 11BB; +CDC5;CDC5;110E 116F 11BC;CDC5;110E 116F 11BC; +CDC6;CDC6;110E 116F 11BD;CDC6;110E 116F 11BD; +CDC7;CDC7;110E 116F 11BE;CDC7;110E 116F 11BE; +CDC8;CDC8;110E 116F 11BF;CDC8;110E 116F 11BF; +CDC9;CDC9;110E 116F 11C0;CDC9;110E 116F 11C0; +CDCA;CDCA;110E 116F 11C1;CDCA;110E 116F 11C1; +CDCB;CDCB;110E 116F 11C2;CDCB;110E 116F 11C2; +CDCC;CDCC;110E 1170;CDCC;110E 1170; +CDCD;CDCD;110E 1170 11A8;CDCD;110E 1170 11A8; +CDCE;CDCE;110E 1170 11A9;CDCE;110E 1170 11A9; +CDCF;CDCF;110E 1170 11AA;CDCF;110E 1170 11AA; +CDD0;CDD0;110E 1170 11AB;CDD0;110E 1170 11AB; +CDD1;CDD1;110E 1170 11AC;CDD1;110E 1170 11AC; +CDD2;CDD2;110E 1170 11AD;CDD2;110E 1170 11AD; +CDD3;CDD3;110E 1170 11AE;CDD3;110E 1170 11AE; +CDD4;CDD4;110E 1170 11AF;CDD4;110E 1170 11AF; +CDD5;CDD5;110E 1170 11B0;CDD5;110E 1170 11B0; +CDD6;CDD6;110E 1170 11B1;CDD6;110E 1170 11B1; +CDD7;CDD7;110E 1170 11B2;CDD7;110E 1170 11B2; +CDD8;CDD8;110E 1170 11B3;CDD8;110E 1170 11B3; +CDD9;CDD9;110E 1170 11B4;CDD9;110E 1170 11B4; +CDDA;CDDA;110E 1170 11B5;CDDA;110E 1170 11B5; +CDDB;CDDB;110E 1170 11B6;CDDB;110E 1170 11B6; +CDDC;CDDC;110E 1170 11B7;CDDC;110E 1170 11B7; +CDDD;CDDD;110E 1170 11B8;CDDD;110E 1170 11B8; +CDDE;CDDE;110E 1170 11B9;CDDE;110E 1170 11B9; +CDDF;CDDF;110E 1170 11BA;CDDF;110E 1170 11BA; +CDE0;CDE0;110E 1170 11BB;CDE0;110E 1170 11BB; +CDE1;CDE1;110E 1170 11BC;CDE1;110E 1170 11BC; +CDE2;CDE2;110E 1170 11BD;CDE2;110E 1170 11BD; +CDE3;CDE3;110E 1170 11BE;CDE3;110E 1170 11BE; +CDE4;CDE4;110E 1170 11BF;CDE4;110E 1170 11BF; +CDE5;CDE5;110E 1170 11C0;CDE5;110E 1170 11C0; +CDE6;CDE6;110E 1170 11C1;CDE6;110E 1170 11C1; +CDE7;CDE7;110E 1170 11C2;CDE7;110E 1170 11C2; +CDE8;CDE8;110E 1171;CDE8;110E 1171; +CDE9;CDE9;110E 1171 11A8;CDE9;110E 1171 11A8; +CDEA;CDEA;110E 1171 11A9;CDEA;110E 1171 11A9; +CDEB;CDEB;110E 1171 11AA;CDEB;110E 1171 11AA; +CDEC;CDEC;110E 1171 11AB;CDEC;110E 1171 11AB; +CDED;CDED;110E 1171 11AC;CDED;110E 1171 11AC; +CDEE;CDEE;110E 1171 11AD;CDEE;110E 1171 11AD; +CDEF;CDEF;110E 1171 11AE;CDEF;110E 1171 11AE; +CDF0;CDF0;110E 1171 11AF;CDF0;110E 1171 11AF; +CDF1;CDF1;110E 1171 11B0;CDF1;110E 1171 11B0; +CDF2;CDF2;110E 1171 11B1;CDF2;110E 1171 11B1; +CDF3;CDF3;110E 1171 11B2;CDF3;110E 1171 11B2; +CDF4;CDF4;110E 1171 11B3;CDF4;110E 1171 11B3; +CDF5;CDF5;110E 1171 11B4;CDF5;110E 1171 11B4; +CDF6;CDF6;110E 1171 11B5;CDF6;110E 1171 11B5; +CDF7;CDF7;110E 1171 11B6;CDF7;110E 1171 11B6; +CDF8;CDF8;110E 1171 11B7;CDF8;110E 1171 11B7; +CDF9;CDF9;110E 1171 11B8;CDF9;110E 1171 11B8; +CDFA;CDFA;110E 1171 11B9;CDFA;110E 1171 11B9; +CDFB;CDFB;110E 1171 11BA;CDFB;110E 1171 11BA; +CDFC;CDFC;110E 1171 11BB;CDFC;110E 1171 11BB; +CDFD;CDFD;110E 1171 11BC;CDFD;110E 1171 11BC; +CDFE;CDFE;110E 1171 11BD;CDFE;110E 1171 11BD; +CDFF;CDFF;110E 1171 11BE;CDFF;110E 1171 11BE; +CE00;CE00;110E 1171 11BF;CE00;110E 1171 11BF; +CE01;CE01;110E 1171 11C0;CE01;110E 1171 11C0; +CE02;CE02;110E 1171 11C1;CE02;110E 1171 11C1; +CE03;CE03;110E 1171 11C2;CE03;110E 1171 11C2; +CE04;CE04;110E 1172;CE04;110E 1172; +CE05;CE05;110E 1172 11A8;CE05;110E 1172 11A8; +CE06;CE06;110E 1172 11A9;CE06;110E 1172 11A9; +CE07;CE07;110E 1172 11AA;CE07;110E 1172 11AA; +CE08;CE08;110E 1172 11AB;CE08;110E 1172 11AB; +CE09;CE09;110E 1172 11AC;CE09;110E 1172 11AC; +CE0A;CE0A;110E 1172 11AD;CE0A;110E 1172 11AD; +CE0B;CE0B;110E 1172 11AE;CE0B;110E 1172 11AE; +CE0C;CE0C;110E 1172 11AF;CE0C;110E 1172 11AF; +CE0D;CE0D;110E 1172 11B0;CE0D;110E 1172 11B0; +CE0E;CE0E;110E 1172 11B1;CE0E;110E 1172 11B1; +CE0F;CE0F;110E 1172 11B2;CE0F;110E 1172 11B2; +CE10;CE10;110E 1172 11B3;CE10;110E 1172 11B3; +CE11;CE11;110E 1172 11B4;CE11;110E 1172 11B4; +CE12;CE12;110E 1172 11B5;CE12;110E 1172 11B5; +CE13;CE13;110E 1172 11B6;CE13;110E 1172 11B6; +CE14;CE14;110E 1172 11B7;CE14;110E 1172 11B7; +CE15;CE15;110E 1172 11B8;CE15;110E 1172 11B8; +CE16;CE16;110E 1172 11B9;CE16;110E 1172 11B9; +CE17;CE17;110E 1172 11BA;CE17;110E 1172 11BA; +CE18;CE18;110E 1172 11BB;CE18;110E 1172 11BB; +CE19;CE19;110E 1172 11BC;CE19;110E 1172 11BC; +CE1A;CE1A;110E 1172 11BD;CE1A;110E 1172 11BD; +CE1B;CE1B;110E 1172 11BE;CE1B;110E 1172 11BE; +CE1C;CE1C;110E 1172 11BF;CE1C;110E 1172 11BF; +CE1D;CE1D;110E 1172 11C0;CE1D;110E 1172 11C0; +CE1E;CE1E;110E 1172 11C1;CE1E;110E 1172 11C1; +CE1F;CE1F;110E 1172 11C2;CE1F;110E 1172 11C2; +CE20;CE20;110E 1173;CE20;110E 1173; +CE21;CE21;110E 1173 11A8;CE21;110E 1173 11A8; +CE22;CE22;110E 1173 11A9;CE22;110E 1173 11A9; +CE23;CE23;110E 1173 11AA;CE23;110E 1173 11AA; +CE24;CE24;110E 1173 11AB;CE24;110E 1173 11AB; +CE25;CE25;110E 1173 11AC;CE25;110E 1173 11AC; +CE26;CE26;110E 1173 11AD;CE26;110E 1173 11AD; +CE27;CE27;110E 1173 11AE;CE27;110E 1173 11AE; +CE28;CE28;110E 1173 11AF;CE28;110E 1173 11AF; +CE29;CE29;110E 1173 11B0;CE29;110E 1173 11B0; +CE2A;CE2A;110E 1173 11B1;CE2A;110E 1173 11B1; +CE2B;CE2B;110E 1173 11B2;CE2B;110E 1173 11B2; +CE2C;CE2C;110E 1173 11B3;CE2C;110E 1173 11B3; +CE2D;CE2D;110E 1173 11B4;CE2D;110E 1173 11B4; +CE2E;CE2E;110E 1173 11B5;CE2E;110E 1173 11B5; +CE2F;CE2F;110E 1173 11B6;CE2F;110E 1173 11B6; +CE30;CE30;110E 1173 11B7;CE30;110E 1173 11B7; +CE31;CE31;110E 1173 11B8;CE31;110E 1173 11B8; +CE32;CE32;110E 1173 11B9;CE32;110E 1173 11B9; +CE33;CE33;110E 1173 11BA;CE33;110E 1173 11BA; +CE34;CE34;110E 1173 11BB;CE34;110E 1173 11BB; +CE35;CE35;110E 1173 11BC;CE35;110E 1173 11BC; +CE36;CE36;110E 1173 11BD;CE36;110E 1173 11BD; +CE37;CE37;110E 1173 11BE;CE37;110E 1173 11BE; +CE38;CE38;110E 1173 11BF;CE38;110E 1173 11BF; +CE39;CE39;110E 1173 11C0;CE39;110E 1173 11C0; +CE3A;CE3A;110E 1173 11C1;CE3A;110E 1173 11C1; +CE3B;CE3B;110E 1173 11C2;CE3B;110E 1173 11C2; +CE3C;CE3C;110E 1174;CE3C;110E 1174; +CE3D;CE3D;110E 1174 11A8;CE3D;110E 1174 11A8; +CE3E;CE3E;110E 1174 11A9;CE3E;110E 1174 11A9; +CE3F;CE3F;110E 1174 11AA;CE3F;110E 1174 11AA; +CE40;CE40;110E 1174 11AB;CE40;110E 1174 11AB; +CE41;CE41;110E 1174 11AC;CE41;110E 1174 11AC; +CE42;CE42;110E 1174 11AD;CE42;110E 1174 11AD; +CE43;CE43;110E 1174 11AE;CE43;110E 1174 11AE; +CE44;CE44;110E 1174 11AF;CE44;110E 1174 11AF; +CE45;CE45;110E 1174 11B0;CE45;110E 1174 11B0; +CE46;CE46;110E 1174 11B1;CE46;110E 1174 11B1; +CE47;CE47;110E 1174 11B2;CE47;110E 1174 11B2; +CE48;CE48;110E 1174 11B3;CE48;110E 1174 11B3; +CE49;CE49;110E 1174 11B4;CE49;110E 1174 11B4; +CE4A;CE4A;110E 1174 11B5;CE4A;110E 1174 11B5; +CE4B;CE4B;110E 1174 11B6;CE4B;110E 1174 11B6; +CE4C;CE4C;110E 1174 11B7;CE4C;110E 1174 11B7; +CE4D;CE4D;110E 1174 11B8;CE4D;110E 1174 11B8; +CE4E;CE4E;110E 1174 11B9;CE4E;110E 1174 11B9; +CE4F;CE4F;110E 1174 11BA;CE4F;110E 1174 11BA; +CE50;CE50;110E 1174 11BB;CE50;110E 1174 11BB; +CE51;CE51;110E 1174 11BC;CE51;110E 1174 11BC; +CE52;CE52;110E 1174 11BD;CE52;110E 1174 11BD; +CE53;CE53;110E 1174 11BE;CE53;110E 1174 11BE; +CE54;CE54;110E 1174 11BF;CE54;110E 1174 11BF; +CE55;CE55;110E 1174 11C0;CE55;110E 1174 11C0; +CE56;CE56;110E 1174 11C1;CE56;110E 1174 11C1; +CE57;CE57;110E 1174 11C2;CE57;110E 1174 11C2; +CE58;CE58;110E 1175;CE58;110E 1175; +CE59;CE59;110E 1175 11A8;CE59;110E 1175 11A8; +CE5A;CE5A;110E 1175 11A9;CE5A;110E 1175 11A9; +CE5B;CE5B;110E 1175 11AA;CE5B;110E 1175 11AA; +CE5C;CE5C;110E 1175 11AB;CE5C;110E 1175 11AB; +CE5D;CE5D;110E 1175 11AC;CE5D;110E 1175 11AC; +CE5E;CE5E;110E 1175 11AD;CE5E;110E 1175 11AD; +CE5F;CE5F;110E 1175 11AE;CE5F;110E 1175 11AE; +CE60;CE60;110E 1175 11AF;CE60;110E 1175 11AF; +CE61;CE61;110E 1175 11B0;CE61;110E 1175 11B0; +CE62;CE62;110E 1175 11B1;CE62;110E 1175 11B1; +CE63;CE63;110E 1175 11B2;CE63;110E 1175 11B2; +CE64;CE64;110E 1175 11B3;CE64;110E 1175 11B3; +CE65;CE65;110E 1175 11B4;CE65;110E 1175 11B4; +CE66;CE66;110E 1175 11B5;CE66;110E 1175 11B5; +CE67;CE67;110E 1175 11B6;CE67;110E 1175 11B6; +CE68;CE68;110E 1175 11B7;CE68;110E 1175 11B7; +CE69;CE69;110E 1175 11B8;CE69;110E 1175 11B8; +CE6A;CE6A;110E 1175 11B9;CE6A;110E 1175 11B9; +CE6B;CE6B;110E 1175 11BA;CE6B;110E 1175 11BA; +CE6C;CE6C;110E 1175 11BB;CE6C;110E 1175 11BB; +CE6D;CE6D;110E 1175 11BC;CE6D;110E 1175 11BC; +CE6E;CE6E;110E 1175 11BD;CE6E;110E 1175 11BD; +CE6F;CE6F;110E 1175 11BE;CE6F;110E 1175 11BE; +CE70;CE70;110E 1175 11BF;CE70;110E 1175 11BF; +CE71;CE71;110E 1175 11C0;CE71;110E 1175 11C0; +CE72;CE72;110E 1175 11C1;CE72;110E 1175 11C1; +CE73;CE73;110E 1175 11C2;CE73;110E 1175 11C2; +CE74;CE74;110F 1161;CE74;110F 1161; +CE75;CE75;110F 1161 11A8;CE75;110F 1161 11A8; +CE76;CE76;110F 1161 11A9;CE76;110F 1161 11A9; +CE77;CE77;110F 1161 11AA;CE77;110F 1161 11AA; +CE78;CE78;110F 1161 11AB;CE78;110F 1161 11AB; +CE79;CE79;110F 1161 11AC;CE79;110F 1161 11AC; +CE7A;CE7A;110F 1161 11AD;CE7A;110F 1161 11AD; +CE7B;CE7B;110F 1161 11AE;CE7B;110F 1161 11AE; +CE7C;CE7C;110F 1161 11AF;CE7C;110F 1161 11AF; +CE7D;CE7D;110F 1161 11B0;CE7D;110F 1161 11B0; +CE7E;CE7E;110F 1161 11B1;CE7E;110F 1161 11B1; +CE7F;CE7F;110F 1161 11B2;CE7F;110F 1161 11B2; +CE80;CE80;110F 1161 11B3;CE80;110F 1161 11B3; +CE81;CE81;110F 1161 11B4;CE81;110F 1161 11B4; +CE82;CE82;110F 1161 11B5;CE82;110F 1161 11B5; +CE83;CE83;110F 1161 11B6;CE83;110F 1161 11B6; +CE84;CE84;110F 1161 11B7;CE84;110F 1161 11B7; +CE85;CE85;110F 1161 11B8;CE85;110F 1161 11B8; +CE86;CE86;110F 1161 11B9;CE86;110F 1161 11B9; +CE87;CE87;110F 1161 11BA;CE87;110F 1161 11BA; +CE88;CE88;110F 1161 11BB;CE88;110F 1161 11BB; +CE89;CE89;110F 1161 11BC;CE89;110F 1161 11BC; +CE8A;CE8A;110F 1161 11BD;CE8A;110F 1161 11BD; +CE8B;CE8B;110F 1161 11BE;CE8B;110F 1161 11BE; +CE8C;CE8C;110F 1161 11BF;CE8C;110F 1161 11BF; +CE8D;CE8D;110F 1161 11C0;CE8D;110F 1161 11C0; +CE8E;CE8E;110F 1161 11C1;CE8E;110F 1161 11C1; +CE8F;CE8F;110F 1161 11C2;CE8F;110F 1161 11C2; +CE90;CE90;110F 1162;CE90;110F 1162; +CE91;CE91;110F 1162 11A8;CE91;110F 1162 11A8; +CE92;CE92;110F 1162 11A9;CE92;110F 1162 11A9; +CE93;CE93;110F 1162 11AA;CE93;110F 1162 11AA; +CE94;CE94;110F 1162 11AB;CE94;110F 1162 11AB; +CE95;CE95;110F 1162 11AC;CE95;110F 1162 11AC; +CE96;CE96;110F 1162 11AD;CE96;110F 1162 11AD; +CE97;CE97;110F 1162 11AE;CE97;110F 1162 11AE; +CE98;CE98;110F 1162 11AF;CE98;110F 1162 11AF; +CE99;CE99;110F 1162 11B0;CE99;110F 1162 11B0; +CE9A;CE9A;110F 1162 11B1;CE9A;110F 1162 11B1; +CE9B;CE9B;110F 1162 11B2;CE9B;110F 1162 11B2; +CE9C;CE9C;110F 1162 11B3;CE9C;110F 1162 11B3; +CE9D;CE9D;110F 1162 11B4;CE9D;110F 1162 11B4; +CE9E;CE9E;110F 1162 11B5;CE9E;110F 1162 11B5; +CE9F;CE9F;110F 1162 11B6;CE9F;110F 1162 11B6; +CEA0;CEA0;110F 1162 11B7;CEA0;110F 1162 11B7; +CEA1;CEA1;110F 1162 11B8;CEA1;110F 1162 11B8; +CEA2;CEA2;110F 1162 11B9;CEA2;110F 1162 11B9; +CEA3;CEA3;110F 1162 11BA;CEA3;110F 1162 11BA; +CEA4;CEA4;110F 1162 11BB;CEA4;110F 1162 11BB; +CEA5;CEA5;110F 1162 11BC;CEA5;110F 1162 11BC; +CEA6;CEA6;110F 1162 11BD;CEA6;110F 1162 11BD; +CEA7;CEA7;110F 1162 11BE;CEA7;110F 1162 11BE; +CEA8;CEA8;110F 1162 11BF;CEA8;110F 1162 11BF; +CEA9;CEA9;110F 1162 11C0;CEA9;110F 1162 11C0; +CEAA;CEAA;110F 1162 11C1;CEAA;110F 1162 11C1; +CEAB;CEAB;110F 1162 11C2;CEAB;110F 1162 11C2; +CEAC;CEAC;110F 1163;CEAC;110F 1163; +CEAD;CEAD;110F 1163 11A8;CEAD;110F 1163 11A8; +CEAE;CEAE;110F 1163 11A9;CEAE;110F 1163 11A9; +CEAF;CEAF;110F 1163 11AA;CEAF;110F 1163 11AA; +CEB0;CEB0;110F 1163 11AB;CEB0;110F 1163 11AB; +CEB1;CEB1;110F 1163 11AC;CEB1;110F 1163 11AC; +CEB2;CEB2;110F 1163 11AD;CEB2;110F 1163 11AD; +CEB3;CEB3;110F 1163 11AE;CEB3;110F 1163 11AE; +CEB4;CEB4;110F 1163 11AF;CEB4;110F 1163 11AF; +CEB5;CEB5;110F 1163 11B0;CEB5;110F 1163 11B0; +CEB6;CEB6;110F 1163 11B1;CEB6;110F 1163 11B1; +CEB7;CEB7;110F 1163 11B2;CEB7;110F 1163 11B2; +CEB8;CEB8;110F 1163 11B3;CEB8;110F 1163 11B3; +CEB9;CEB9;110F 1163 11B4;CEB9;110F 1163 11B4; +CEBA;CEBA;110F 1163 11B5;CEBA;110F 1163 11B5; +CEBB;CEBB;110F 1163 11B6;CEBB;110F 1163 11B6; +CEBC;CEBC;110F 1163 11B7;CEBC;110F 1163 11B7; +CEBD;CEBD;110F 1163 11B8;CEBD;110F 1163 11B8; +CEBE;CEBE;110F 1163 11B9;CEBE;110F 1163 11B9; +CEBF;CEBF;110F 1163 11BA;CEBF;110F 1163 11BA; +CEC0;CEC0;110F 1163 11BB;CEC0;110F 1163 11BB; +CEC1;CEC1;110F 1163 11BC;CEC1;110F 1163 11BC; +CEC2;CEC2;110F 1163 11BD;CEC2;110F 1163 11BD; +CEC3;CEC3;110F 1163 11BE;CEC3;110F 1163 11BE; +CEC4;CEC4;110F 1163 11BF;CEC4;110F 1163 11BF; +CEC5;CEC5;110F 1163 11C0;CEC5;110F 1163 11C0; +CEC6;CEC6;110F 1163 11C1;CEC6;110F 1163 11C1; +CEC7;CEC7;110F 1163 11C2;CEC7;110F 1163 11C2; +CEC8;CEC8;110F 1164;CEC8;110F 1164; +CEC9;CEC9;110F 1164 11A8;CEC9;110F 1164 11A8; +CECA;CECA;110F 1164 11A9;CECA;110F 1164 11A9; +CECB;CECB;110F 1164 11AA;CECB;110F 1164 11AA; +CECC;CECC;110F 1164 11AB;CECC;110F 1164 11AB; +CECD;CECD;110F 1164 11AC;CECD;110F 1164 11AC; +CECE;CECE;110F 1164 11AD;CECE;110F 1164 11AD; +CECF;CECF;110F 1164 11AE;CECF;110F 1164 11AE; +CED0;CED0;110F 1164 11AF;CED0;110F 1164 11AF; +CED1;CED1;110F 1164 11B0;CED1;110F 1164 11B0; +CED2;CED2;110F 1164 11B1;CED2;110F 1164 11B1; +CED3;CED3;110F 1164 11B2;CED3;110F 1164 11B2; +CED4;CED4;110F 1164 11B3;CED4;110F 1164 11B3; +CED5;CED5;110F 1164 11B4;CED5;110F 1164 11B4; +CED6;CED6;110F 1164 11B5;CED6;110F 1164 11B5; +CED7;CED7;110F 1164 11B6;CED7;110F 1164 11B6; +CED8;CED8;110F 1164 11B7;CED8;110F 1164 11B7; +CED9;CED9;110F 1164 11B8;CED9;110F 1164 11B8; +CEDA;CEDA;110F 1164 11B9;CEDA;110F 1164 11B9; +CEDB;CEDB;110F 1164 11BA;CEDB;110F 1164 11BA; +CEDC;CEDC;110F 1164 11BB;CEDC;110F 1164 11BB; +CEDD;CEDD;110F 1164 11BC;CEDD;110F 1164 11BC; +CEDE;CEDE;110F 1164 11BD;CEDE;110F 1164 11BD; +CEDF;CEDF;110F 1164 11BE;CEDF;110F 1164 11BE; +CEE0;CEE0;110F 1164 11BF;CEE0;110F 1164 11BF; +CEE1;CEE1;110F 1164 11C0;CEE1;110F 1164 11C0; +CEE2;CEE2;110F 1164 11C1;CEE2;110F 1164 11C1; +CEE3;CEE3;110F 1164 11C2;CEE3;110F 1164 11C2; +CEE4;CEE4;110F 1165;CEE4;110F 1165; +CEE5;CEE5;110F 1165 11A8;CEE5;110F 1165 11A8; +CEE6;CEE6;110F 1165 11A9;CEE6;110F 1165 11A9; +CEE7;CEE7;110F 1165 11AA;CEE7;110F 1165 11AA; +CEE8;CEE8;110F 1165 11AB;CEE8;110F 1165 11AB; +CEE9;CEE9;110F 1165 11AC;CEE9;110F 1165 11AC; +CEEA;CEEA;110F 1165 11AD;CEEA;110F 1165 11AD; +CEEB;CEEB;110F 1165 11AE;CEEB;110F 1165 11AE; +CEEC;CEEC;110F 1165 11AF;CEEC;110F 1165 11AF; +CEED;CEED;110F 1165 11B0;CEED;110F 1165 11B0; +CEEE;CEEE;110F 1165 11B1;CEEE;110F 1165 11B1; +CEEF;CEEF;110F 1165 11B2;CEEF;110F 1165 11B2; +CEF0;CEF0;110F 1165 11B3;CEF0;110F 1165 11B3; +CEF1;CEF1;110F 1165 11B4;CEF1;110F 1165 11B4; +CEF2;CEF2;110F 1165 11B5;CEF2;110F 1165 11B5; +CEF3;CEF3;110F 1165 11B6;CEF3;110F 1165 11B6; +CEF4;CEF4;110F 1165 11B7;CEF4;110F 1165 11B7; +CEF5;CEF5;110F 1165 11B8;CEF5;110F 1165 11B8; +CEF6;CEF6;110F 1165 11B9;CEF6;110F 1165 11B9; +CEF7;CEF7;110F 1165 11BA;CEF7;110F 1165 11BA; +CEF8;CEF8;110F 1165 11BB;CEF8;110F 1165 11BB; +CEF9;CEF9;110F 1165 11BC;CEF9;110F 1165 11BC; +CEFA;CEFA;110F 1165 11BD;CEFA;110F 1165 11BD; +CEFB;CEFB;110F 1165 11BE;CEFB;110F 1165 11BE; +CEFC;CEFC;110F 1165 11BF;CEFC;110F 1165 11BF; +CEFD;CEFD;110F 1165 11C0;CEFD;110F 1165 11C0; +CEFE;CEFE;110F 1165 11C1;CEFE;110F 1165 11C1; +CEFF;CEFF;110F 1165 11C2;CEFF;110F 1165 11C2; +CF00;CF00;110F 1166;CF00;110F 1166; +CF01;CF01;110F 1166 11A8;CF01;110F 1166 11A8; +CF02;CF02;110F 1166 11A9;CF02;110F 1166 11A9; +CF03;CF03;110F 1166 11AA;CF03;110F 1166 11AA; +CF04;CF04;110F 1166 11AB;CF04;110F 1166 11AB; +CF05;CF05;110F 1166 11AC;CF05;110F 1166 11AC; +CF06;CF06;110F 1166 11AD;CF06;110F 1166 11AD; +CF07;CF07;110F 1166 11AE;CF07;110F 1166 11AE; +CF08;CF08;110F 1166 11AF;CF08;110F 1166 11AF; +CF09;CF09;110F 1166 11B0;CF09;110F 1166 11B0; +CF0A;CF0A;110F 1166 11B1;CF0A;110F 1166 11B1; +CF0B;CF0B;110F 1166 11B2;CF0B;110F 1166 11B2; +CF0C;CF0C;110F 1166 11B3;CF0C;110F 1166 11B3; +CF0D;CF0D;110F 1166 11B4;CF0D;110F 1166 11B4; +CF0E;CF0E;110F 1166 11B5;CF0E;110F 1166 11B5; +CF0F;CF0F;110F 1166 11B6;CF0F;110F 1166 11B6; +CF10;CF10;110F 1166 11B7;CF10;110F 1166 11B7; +CF11;CF11;110F 1166 11B8;CF11;110F 1166 11B8; +CF12;CF12;110F 1166 11B9;CF12;110F 1166 11B9; +CF13;CF13;110F 1166 11BA;CF13;110F 1166 11BA; +CF14;CF14;110F 1166 11BB;CF14;110F 1166 11BB; +CF15;CF15;110F 1166 11BC;CF15;110F 1166 11BC; +CF16;CF16;110F 1166 11BD;CF16;110F 1166 11BD; +CF17;CF17;110F 1166 11BE;CF17;110F 1166 11BE; +CF18;CF18;110F 1166 11BF;CF18;110F 1166 11BF; +CF19;CF19;110F 1166 11C0;CF19;110F 1166 11C0; +CF1A;CF1A;110F 1166 11C1;CF1A;110F 1166 11C1; +CF1B;CF1B;110F 1166 11C2;CF1B;110F 1166 11C2; +CF1C;CF1C;110F 1167;CF1C;110F 1167; +CF1D;CF1D;110F 1167 11A8;CF1D;110F 1167 11A8; +CF1E;CF1E;110F 1167 11A9;CF1E;110F 1167 11A9; +CF1F;CF1F;110F 1167 11AA;CF1F;110F 1167 11AA; +CF20;CF20;110F 1167 11AB;CF20;110F 1167 11AB; +CF21;CF21;110F 1167 11AC;CF21;110F 1167 11AC; +CF22;CF22;110F 1167 11AD;CF22;110F 1167 11AD; +CF23;CF23;110F 1167 11AE;CF23;110F 1167 11AE; +CF24;CF24;110F 1167 11AF;CF24;110F 1167 11AF; +CF25;CF25;110F 1167 11B0;CF25;110F 1167 11B0; +CF26;CF26;110F 1167 11B1;CF26;110F 1167 11B1; +CF27;CF27;110F 1167 11B2;CF27;110F 1167 11B2; +CF28;CF28;110F 1167 11B3;CF28;110F 1167 11B3; +CF29;CF29;110F 1167 11B4;CF29;110F 1167 11B4; +CF2A;CF2A;110F 1167 11B5;CF2A;110F 1167 11B5; +CF2B;CF2B;110F 1167 11B6;CF2B;110F 1167 11B6; +CF2C;CF2C;110F 1167 11B7;CF2C;110F 1167 11B7; +CF2D;CF2D;110F 1167 11B8;CF2D;110F 1167 11B8; +CF2E;CF2E;110F 1167 11B9;CF2E;110F 1167 11B9; +CF2F;CF2F;110F 1167 11BA;CF2F;110F 1167 11BA; +CF30;CF30;110F 1167 11BB;CF30;110F 1167 11BB; +CF31;CF31;110F 1167 11BC;CF31;110F 1167 11BC; +CF32;CF32;110F 1167 11BD;CF32;110F 1167 11BD; +CF33;CF33;110F 1167 11BE;CF33;110F 1167 11BE; +CF34;CF34;110F 1167 11BF;CF34;110F 1167 11BF; +CF35;CF35;110F 1167 11C0;CF35;110F 1167 11C0; +CF36;CF36;110F 1167 11C1;CF36;110F 1167 11C1; +CF37;CF37;110F 1167 11C2;CF37;110F 1167 11C2; +CF38;CF38;110F 1168;CF38;110F 1168; +CF39;CF39;110F 1168 11A8;CF39;110F 1168 11A8; +CF3A;CF3A;110F 1168 11A9;CF3A;110F 1168 11A9; +CF3B;CF3B;110F 1168 11AA;CF3B;110F 1168 11AA; +CF3C;CF3C;110F 1168 11AB;CF3C;110F 1168 11AB; +CF3D;CF3D;110F 1168 11AC;CF3D;110F 1168 11AC; +CF3E;CF3E;110F 1168 11AD;CF3E;110F 1168 11AD; +CF3F;CF3F;110F 1168 11AE;CF3F;110F 1168 11AE; +CF40;CF40;110F 1168 11AF;CF40;110F 1168 11AF; +CF41;CF41;110F 1168 11B0;CF41;110F 1168 11B0; +CF42;CF42;110F 1168 11B1;CF42;110F 1168 11B1; +CF43;CF43;110F 1168 11B2;CF43;110F 1168 11B2; +CF44;CF44;110F 1168 11B3;CF44;110F 1168 11B3; +CF45;CF45;110F 1168 11B4;CF45;110F 1168 11B4; +CF46;CF46;110F 1168 11B5;CF46;110F 1168 11B5; +CF47;CF47;110F 1168 11B6;CF47;110F 1168 11B6; +CF48;CF48;110F 1168 11B7;CF48;110F 1168 11B7; +CF49;CF49;110F 1168 11B8;CF49;110F 1168 11B8; +CF4A;CF4A;110F 1168 11B9;CF4A;110F 1168 11B9; +CF4B;CF4B;110F 1168 11BA;CF4B;110F 1168 11BA; +CF4C;CF4C;110F 1168 11BB;CF4C;110F 1168 11BB; +CF4D;CF4D;110F 1168 11BC;CF4D;110F 1168 11BC; +CF4E;CF4E;110F 1168 11BD;CF4E;110F 1168 11BD; +CF4F;CF4F;110F 1168 11BE;CF4F;110F 1168 11BE; +CF50;CF50;110F 1168 11BF;CF50;110F 1168 11BF; +CF51;CF51;110F 1168 11C0;CF51;110F 1168 11C0; +CF52;CF52;110F 1168 11C1;CF52;110F 1168 11C1; +CF53;CF53;110F 1168 11C2;CF53;110F 1168 11C2; +CF54;CF54;110F 1169;CF54;110F 1169; +CF55;CF55;110F 1169 11A8;CF55;110F 1169 11A8; +CF56;CF56;110F 1169 11A9;CF56;110F 1169 11A9; +CF57;CF57;110F 1169 11AA;CF57;110F 1169 11AA; +CF58;CF58;110F 1169 11AB;CF58;110F 1169 11AB; +CF59;CF59;110F 1169 11AC;CF59;110F 1169 11AC; +CF5A;CF5A;110F 1169 11AD;CF5A;110F 1169 11AD; +CF5B;CF5B;110F 1169 11AE;CF5B;110F 1169 11AE; +CF5C;CF5C;110F 1169 11AF;CF5C;110F 1169 11AF; +CF5D;CF5D;110F 1169 11B0;CF5D;110F 1169 11B0; +CF5E;CF5E;110F 1169 11B1;CF5E;110F 1169 11B1; +CF5F;CF5F;110F 1169 11B2;CF5F;110F 1169 11B2; +CF60;CF60;110F 1169 11B3;CF60;110F 1169 11B3; +CF61;CF61;110F 1169 11B4;CF61;110F 1169 11B4; +CF62;CF62;110F 1169 11B5;CF62;110F 1169 11B5; +CF63;CF63;110F 1169 11B6;CF63;110F 1169 11B6; +CF64;CF64;110F 1169 11B7;CF64;110F 1169 11B7; +CF65;CF65;110F 1169 11B8;CF65;110F 1169 11B8; +CF66;CF66;110F 1169 11B9;CF66;110F 1169 11B9; +CF67;CF67;110F 1169 11BA;CF67;110F 1169 11BA; +CF68;CF68;110F 1169 11BB;CF68;110F 1169 11BB; +CF69;CF69;110F 1169 11BC;CF69;110F 1169 11BC; +CF6A;CF6A;110F 1169 11BD;CF6A;110F 1169 11BD; +CF6B;CF6B;110F 1169 11BE;CF6B;110F 1169 11BE; +CF6C;CF6C;110F 1169 11BF;CF6C;110F 1169 11BF; +CF6D;CF6D;110F 1169 11C0;CF6D;110F 1169 11C0; +CF6E;CF6E;110F 1169 11C1;CF6E;110F 1169 11C1; +CF6F;CF6F;110F 1169 11C2;CF6F;110F 1169 11C2; +CF70;CF70;110F 116A;CF70;110F 116A; +CF71;CF71;110F 116A 11A8;CF71;110F 116A 11A8; +CF72;CF72;110F 116A 11A9;CF72;110F 116A 11A9; +CF73;CF73;110F 116A 11AA;CF73;110F 116A 11AA; +CF74;CF74;110F 116A 11AB;CF74;110F 116A 11AB; +CF75;CF75;110F 116A 11AC;CF75;110F 116A 11AC; +CF76;CF76;110F 116A 11AD;CF76;110F 116A 11AD; +CF77;CF77;110F 116A 11AE;CF77;110F 116A 11AE; +CF78;CF78;110F 116A 11AF;CF78;110F 116A 11AF; +CF79;CF79;110F 116A 11B0;CF79;110F 116A 11B0; +CF7A;CF7A;110F 116A 11B1;CF7A;110F 116A 11B1; +CF7B;CF7B;110F 116A 11B2;CF7B;110F 116A 11B2; +CF7C;CF7C;110F 116A 11B3;CF7C;110F 116A 11B3; +CF7D;CF7D;110F 116A 11B4;CF7D;110F 116A 11B4; +CF7E;CF7E;110F 116A 11B5;CF7E;110F 116A 11B5; +CF7F;CF7F;110F 116A 11B6;CF7F;110F 116A 11B6; +CF80;CF80;110F 116A 11B7;CF80;110F 116A 11B7; +CF81;CF81;110F 116A 11B8;CF81;110F 116A 11B8; +CF82;CF82;110F 116A 11B9;CF82;110F 116A 11B9; +CF83;CF83;110F 116A 11BA;CF83;110F 116A 11BA; +CF84;CF84;110F 116A 11BB;CF84;110F 116A 11BB; +CF85;CF85;110F 116A 11BC;CF85;110F 116A 11BC; +CF86;CF86;110F 116A 11BD;CF86;110F 116A 11BD; +CF87;CF87;110F 116A 11BE;CF87;110F 116A 11BE; +CF88;CF88;110F 116A 11BF;CF88;110F 116A 11BF; +CF89;CF89;110F 116A 11C0;CF89;110F 116A 11C0; +CF8A;CF8A;110F 116A 11C1;CF8A;110F 116A 11C1; +CF8B;CF8B;110F 116A 11C2;CF8B;110F 116A 11C2; +CF8C;CF8C;110F 116B;CF8C;110F 116B; +CF8D;CF8D;110F 116B 11A8;CF8D;110F 116B 11A8; +CF8E;CF8E;110F 116B 11A9;CF8E;110F 116B 11A9; +CF8F;CF8F;110F 116B 11AA;CF8F;110F 116B 11AA; +CF90;CF90;110F 116B 11AB;CF90;110F 116B 11AB; +CF91;CF91;110F 116B 11AC;CF91;110F 116B 11AC; +CF92;CF92;110F 116B 11AD;CF92;110F 116B 11AD; +CF93;CF93;110F 116B 11AE;CF93;110F 116B 11AE; +CF94;CF94;110F 116B 11AF;CF94;110F 116B 11AF; +CF95;CF95;110F 116B 11B0;CF95;110F 116B 11B0; +CF96;CF96;110F 116B 11B1;CF96;110F 116B 11B1; +CF97;CF97;110F 116B 11B2;CF97;110F 116B 11B2; +CF98;CF98;110F 116B 11B3;CF98;110F 116B 11B3; +CF99;CF99;110F 116B 11B4;CF99;110F 116B 11B4; +CF9A;CF9A;110F 116B 11B5;CF9A;110F 116B 11B5; +CF9B;CF9B;110F 116B 11B6;CF9B;110F 116B 11B6; +CF9C;CF9C;110F 116B 11B7;CF9C;110F 116B 11B7; +CF9D;CF9D;110F 116B 11B8;CF9D;110F 116B 11B8; +CF9E;CF9E;110F 116B 11B9;CF9E;110F 116B 11B9; +CF9F;CF9F;110F 116B 11BA;CF9F;110F 116B 11BA; +CFA0;CFA0;110F 116B 11BB;CFA0;110F 116B 11BB; +CFA1;CFA1;110F 116B 11BC;CFA1;110F 116B 11BC; +CFA2;CFA2;110F 116B 11BD;CFA2;110F 116B 11BD; +CFA3;CFA3;110F 116B 11BE;CFA3;110F 116B 11BE; +CFA4;CFA4;110F 116B 11BF;CFA4;110F 116B 11BF; +CFA5;CFA5;110F 116B 11C0;CFA5;110F 116B 11C0; +CFA6;CFA6;110F 116B 11C1;CFA6;110F 116B 11C1; +CFA7;CFA7;110F 116B 11C2;CFA7;110F 116B 11C2; +CFA8;CFA8;110F 116C;CFA8;110F 116C; +CFA9;CFA9;110F 116C 11A8;CFA9;110F 116C 11A8; +CFAA;CFAA;110F 116C 11A9;CFAA;110F 116C 11A9; +CFAB;CFAB;110F 116C 11AA;CFAB;110F 116C 11AA; +CFAC;CFAC;110F 116C 11AB;CFAC;110F 116C 11AB; +CFAD;CFAD;110F 116C 11AC;CFAD;110F 116C 11AC; +CFAE;CFAE;110F 116C 11AD;CFAE;110F 116C 11AD; +CFAF;CFAF;110F 116C 11AE;CFAF;110F 116C 11AE; +CFB0;CFB0;110F 116C 11AF;CFB0;110F 116C 11AF; +CFB1;CFB1;110F 116C 11B0;CFB1;110F 116C 11B0; +CFB2;CFB2;110F 116C 11B1;CFB2;110F 116C 11B1; +CFB3;CFB3;110F 116C 11B2;CFB3;110F 116C 11B2; +CFB4;CFB4;110F 116C 11B3;CFB4;110F 116C 11B3; +CFB5;CFB5;110F 116C 11B4;CFB5;110F 116C 11B4; +CFB6;CFB6;110F 116C 11B5;CFB6;110F 116C 11B5; +CFB7;CFB7;110F 116C 11B6;CFB7;110F 116C 11B6; +CFB8;CFB8;110F 116C 11B7;CFB8;110F 116C 11B7; +CFB9;CFB9;110F 116C 11B8;CFB9;110F 116C 11B8; +CFBA;CFBA;110F 116C 11B9;CFBA;110F 116C 11B9; +CFBB;CFBB;110F 116C 11BA;CFBB;110F 116C 11BA; +CFBC;CFBC;110F 116C 11BB;CFBC;110F 116C 11BB; +CFBD;CFBD;110F 116C 11BC;CFBD;110F 116C 11BC; +CFBE;CFBE;110F 116C 11BD;CFBE;110F 116C 11BD; +CFBF;CFBF;110F 116C 11BE;CFBF;110F 116C 11BE; +CFC0;CFC0;110F 116C 11BF;CFC0;110F 116C 11BF; +CFC1;CFC1;110F 116C 11C0;CFC1;110F 116C 11C0; +CFC2;CFC2;110F 116C 11C1;CFC2;110F 116C 11C1; +CFC3;CFC3;110F 116C 11C2;CFC3;110F 116C 11C2; +CFC4;CFC4;110F 116D;CFC4;110F 116D; +CFC5;CFC5;110F 116D 11A8;CFC5;110F 116D 11A8; +CFC6;CFC6;110F 116D 11A9;CFC6;110F 116D 11A9; +CFC7;CFC7;110F 116D 11AA;CFC7;110F 116D 11AA; +CFC8;CFC8;110F 116D 11AB;CFC8;110F 116D 11AB; +CFC9;CFC9;110F 116D 11AC;CFC9;110F 116D 11AC; +CFCA;CFCA;110F 116D 11AD;CFCA;110F 116D 11AD; +CFCB;CFCB;110F 116D 11AE;CFCB;110F 116D 11AE; +CFCC;CFCC;110F 116D 11AF;CFCC;110F 116D 11AF; +CFCD;CFCD;110F 116D 11B0;CFCD;110F 116D 11B0; +CFCE;CFCE;110F 116D 11B1;CFCE;110F 116D 11B1; +CFCF;CFCF;110F 116D 11B2;CFCF;110F 116D 11B2; +CFD0;CFD0;110F 116D 11B3;CFD0;110F 116D 11B3; +CFD1;CFD1;110F 116D 11B4;CFD1;110F 116D 11B4; +CFD2;CFD2;110F 116D 11B5;CFD2;110F 116D 11B5; +CFD3;CFD3;110F 116D 11B6;CFD3;110F 116D 11B6; +CFD4;CFD4;110F 116D 11B7;CFD4;110F 116D 11B7; +CFD5;CFD5;110F 116D 11B8;CFD5;110F 116D 11B8; +CFD6;CFD6;110F 116D 11B9;CFD6;110F 116D 11B9; +CFD7;CFD7;110F 116D 11BA;CFD7;110F 116D 11BA; +CFD8;CFD8;110F 116D 11BB;CFD8;110F 116D 11BB; +CFD9;CFD9;110F 116D 11BC;CFD9;110F 116D 11BC; +CFDA;CFDA;110F 116D 11BD;CFDA;110F 116D 11BD; +CFDB;CFDB;110F 116D 11BE;CFDB;110F 116D 11BE; +CFDC;CFDC;110F 116D 11BF;CFDC;110F 116D 11BF; +CFDD;CFDD;110F 116D 11C0;CFDD;110F 116D 11C0; +CFDE;CFDE;110F 116D 11C1;CFDE;110F 116D 11C1; +CFDF;CFDF;110F 116D 11C2;CFDF;110F 116D 11C2; +CFE0;CFE0;110F 116E;CFE0;110F 116E; +CFE1;CFE1;110F 116E 11A8;CFE1;110F 116E 11A8; +CFE2;CFE2;110F 116E 11A9;CFE2;110F 116E 11A9; +CFE3;CFE3;110F 116E 11AA;CFE3;110F 116E 11AA; +CFE4;CFE4;110F 116E 11AB;CFE4;110F 116E 11AB; +CFE5;CFE5;110F 116E 11AC;CFE5;110F 116E 11AC; +CFE6;CFE6;110F 116E 11AD;CFE6;110F 116E 11AD; +CFE7;CFE7;110F 116E 11AE;CFE7;110F 116E 11AE; +CFE8;CFE8;110F 116E 11AF;CFE8;110F 116E 11AF; +CFE9;CFE9;110F 116E 11B0;CFE9;110F 116E 11B0; +CFEA;CFEA;110F 116E 11B1;CFEA;110F 116E 11B1; +CFEB;CFEB;110F 116E 11B2;CFEB;110F 116E 11B2; +CFEC;CFEC;110F 116E 11B3;CFEC;110F 116E 11B3; +CFED;CFED;110F 116E 11B4;CFED;110F 116E 11B4; +CFEE;CFEE;110F 116E 11B5;CFEE;110F 116E 11B5; +CFEF;CFEF;110F 116E 11B6;CFEF;110F 116E 11B6; +CFF0;CFF0;110F 116E 11B7;CFF0;110F 116E 11B7; +CFF1;CFF1;110F 116E 11B8;CFF1;110F 116E 11B8; +CFF2;CFF2;110F 116E 11B9;CFF2;110F 116E 11B9; +CFF3;CFF3;110F 116E 11BA;CFF3;110F 116E 11BA; +CFF4;CFF4;110F 116E 11BB;CFF4;110F 116E 11BB; +CFF5;CFF5;110F 116E 11BC;CFF5;110F 116E 11BC; +CFF6;CFF6;110F 116E 11BD;CFF6;110F 116E 11BD; +CFF7;CFF7;110F 116E 11BE;CFF7;110F 116E 11BE; +CFF8;CFF8;110F 116E 11BF;CFF8;110F 116E 11BF; +CFF9;CFF9;110F 116E 11C0;CFF9;110F 116E 11C0; +CFFA;CFFA;110F 116E 11C1;CFFA;110F 116E 11C1; +CFFB;CFFB;110F 116E 11C2;CFFB;110F 116E 11C2; +CFFC;CFFC;110F 116F;CFFC;110F 116F; +CFFD;CFFD;110F 116F 11A8;CFFD;110F 116F 11A8; +CFFE;CFFE;110F 116F 11A9;CFFE;110F 116F 11A9; +CFFF;CFFF;110F 116F 11AA;CFFF;110F 116F 11AA; +D000;D000;110F 116F 11AB;D000;110F 116F 11AB; +D001;D001;110F 116F 11AC;D001;110F 116F 11AC; +D002;D002;110F 116F 11AD;D002;110F 116F 11AD; +D003;D003;110F 116F 11AE;D003;110F 116F 11AE; +D004;D004;110F 116F 11AF;D004;110F 116F 11AF; +D005;D005;110F 116F 11B0;D005;110F 116F 11B0; +D006;D006;110F 116F 11B1;D006;110F 116F 11B1; +D007;D007;110F 116F 11B2;D007;110F 116F 11B2; +D008;D008;110F 116F 11B3;D008;110F 116F 11B3; +D009;D009;110F 116F 11B4;D009;110F 116F 11B4; +D00A;D00A;110F 116F 11B5;D00A;110F 116F 11B5; +D00B;D00B;110F 116F 11B6;D00B;110F 116F 11B6; +D00C;D00C;110F 116F 11B7;D00C;110F 116F 11B7; +D00D;D00D;110F 116F 11B8;D00D;110F 116F 11B8; +D00E;D00E;110F 116F 11B9;D00E;110F 116F 11B9; +D00F;D00F;110F 116F 11BA;D00F;110F 116F 11BA; +D010;D010;110F 116F 11BB;D010;110F 116F 11BB; +D011;D011;110F 116F 11BC;D011;110F 116F 11BC; +D012;D012;110F 116F 11BD;D012;110F 116F 11BD; +D013;D013;110F 116F 11BE;D013;110F 116F 11BE; +D014;D014;110F 116F 11BF;D014;110F 116F 11BF; +D015;D015;110F 116F 11C0;D015;110F 116F 11C0; +D016;D016;110F 116F 11C1;D016;110F 116F 11C1; +D017;D017;110F 116F 11C2;D017;110F 116F 11C2; +D018;D018;110F 1170;D018;110F 1170; +D019;D019;110F 1170 11A8;D019;110F 1170 11A8; +D01A;D01A;110F 1170 11A9;D01A;110F 1170 11A9; +D01B;D01B;110F 1170 11AA;D01B;110F 1170 11AA; +D01C;D01C;110F 1170 11AB;D01C;110F 1170 11AB; +D01D;D01D;110F 1170 11AC;D01D;110F 1170 11AC; +D01E;D01E;110F 1170 11AD;D01E;110F 1170 11AD; +D01F;D01F;110F 1170 11AE;D01F;110F 1170 11AE; +D020;D020;110F 1170 11AF;D020;110F 1170 11AF; +D021;D021;110F 1170 11B0;D021;110F 1170 11B0; +D022;D022;110F 1170 11B1;D022;110F 1170 11B1; +D023;D023;110F 1170 11B2;D023;110F 1170 11B2; +D024;D024;110F 1170 11B3;D024;110F 1170 11B3; +D025;D025;110F 1170 11B4;D025;110F 1170 11B4; +D026;D026;110F 1170 11B5;D026;110F 1170 11B5; +D027;D027;110F 1170 11B6;D027;110F 1170 11B6; +D028;D028;110F 1170 11B7;D028;110F 1170 11B7; +D029;D029;110F 1170 11B8;D029;110F 1170 11B8; +D02A;D02A;110F 1170 11B9;D02A;110F 1170 11B9; +D02B;D02B;110F 1170 11BA;D02B;110F 1170 11BA; +D02C;D02C;110F 1170 11BB;D02C;110F 1170 11BB; +D02D;D02D;110F 1170 11BC;D02D;110F 1170 11BC; +D02E;D02E;110F 1170 11BD;D02E;110F 1170 11BD; +D02F;D02F;110F 1170 11BE;D02F;110F 1170 11BE; +D030;D030;110F 1170 11BF;D030;110F 1170 11BF; +D031;D031;110F 1170 11C0;D031;110F 1170 11C0; +D032;D032;110F 1170 11C1;D032;110F 1170 11C1; +D033;D033;110F 1170 11C2;D033;110F 1170 11C2; +D034;D034;110F 1171;D034;110F 1171; +D035;D035;110F 1171 11A8;D035;110F 1171 11A8; +D036;D036;110F 1171 11A9;D036;110F 1171 11A9; +D037;D037;110F 1171 11AA;D037;110F 1171 11AA; +D038;D038;110F 1171 11AB;D038;110F 1171 11AB; +D039;D039;110F 1171 11AC;D039;110F 1171 11AC; +D03A;D03A;110F 1171 11AD;D03A;110F 1171 11AD; +D03B;D03B;110F 1171 11AE;D03B;110F 1171 11AE; +D03C;D03C;110F 1171 11AF;D03C;110F 1171 11AF; +D03D;D03D;110F 1171 11B0;D03D;110F 1171 11B0; +D03E;D03E;110F 1171 11B1;D03E;110F 1171 11B1; +D03F;D03F;110F 1171 11B2;D03F;110F 1171 11B2; +D040;D040;110F 1171 11B3;D040;110F 1171 11B3; +D041;D041;110F 1171 11B4;D041;110F 1171 11B4; +D042;D042;110F 1171 11B5;D042;110F 1171 11B5; +D043;D043;110F 1171 11B6;D043;110F 1171 11B6; +D044;D044;110F 1171 11B7;D044;110F 1171 11B7; +D045;D045;110F 1171 11B8;D045;110F 1171 11B8; +D046;D046;110F 1171 11B9;D046;110F 1171 11B9; +D047;D047;110F 1171 11BA;D047;110F 1171 11BA; +D048;D048;110F 1171 11BB;D048;110F 1171 11BB; +D049;D049;110F 1171 11BC;D049;110F 1171 11BC; +D04A;D04A;110F 1171 11BD;D04A;110F 1171 11BD; +D04B;D04B;110F 1171 11BE;D04B;110F 1171 11BE; +D04C;D04C;110F 1171 11BF;D04C;110F 1171 11BF; +D04D;D04D;110F 1171 11C0;D04D;110F 1171 11C0; +D04E;D04E;110F 1171 11C1;D04E;110F 1171 11C1; +D04F;D04F;110F 1171 11C2;D04F;110F 1171 11C2; +D050;D050;110F 1172;D050;110F 1172; +D051;D051;110F 1172 11A8;D051;110F 1172 11A8; +D052;D052;110F 1172 11A9;D052;110F 1172 11A9; +D053;D053;110F 1172 11AA;D053;110F 1172 11AA; +D054;D054;110F 1172 11AB;D054;110F 1172 11AB; +D055;D055;110F 1172 11AC;D055;110F 1172 11AC; +D056;D056;110F 1172 11AD;D056;110F 1172 11AD; +D057;D057;110F 1172 11AE;D057;110F 1172 11AE; +D058;D058;110F 1172 11AF;D058;110F 1172 11AF; +D059;D059;110F 1172 11B0;D059;110F 1172 11B0; +D05A;D05A;110F 1172 11B1;D05A;110F 1172 11B1; +D05B;D05B;110F 1172 11B2;D05B;110F 1172 11B2; +D05C;D05C;110F 1172 11B3;D05C;110F 1172 11B3; +D05D;D05D;110F 1172 11B4;D05D;110F 1172 11B4; +D05E;D05E;110F 1172 11B5;D05E;110F 1172 11B5; +D05F;D05F;110F 1172 11B6;D05F;110F 1172 11B6; +D060;D060;110F 1172 11B7;D060;110F 1172 11B7; +D061;D061;110F 1172 11B8;D061;110F 1172 11B8; +D062;D062;110F 1172 11B9;D062;110F 1172 11B9; +D063;D063;110F 1172 11BA;D063;110F 1172 11BA; +D064;D064;110F 1172 11BB;D064;110F 1172 11BB; +D065;D065;110F 1172 11BC;D065;110F 1172 11BC; +D066;D066;110F 1172 11BD;D066;110F 1172 11BD; +D067;D067;110F 1172 11BE;D067;110F 1172 11BE; +D068;D068;110F 1172 11BF;D068;110F 1172 11BF; +D069;D069;110F 1172 11C0;D069;110F 1172 11C0; +D06A;D06A;110F 1172 11C1;D06A;110F 1172 11C1; +D06B;D06B;110F 1172 11C2;D06B;110F 1172 11C2; +D06C;D06C;110F 1173;D06C;110F 1173; +D06D;D06D;110F 1173 11A8;D06D;110F 1173 11A8; +D06E;D06E;110F 1173 11A9;D06E;110F 1173 11A9; +D06F;D06F;110F 1173 11AA;D06F;110F 1173 11AA; +D070;D070;110F 1173 11AB;D070;110F 1173 11AB; +D071;D071;110F 1173 11AC;D071;110F 1173 11AC; +D072;D072;110F 1173 11AD;D072;110F 1173 11AD; +D073;D073;110F 1173 11AE;D073;110F 1173 11AE; +D074;D074;110F 1173 11AF;D074;110F 1173 11AF; +D075;D075;110F 1173 11B0;D075;110F 1173 11B0; +D076;D076;110F 1173 11B1;D076;110F 1173 11B1; +D077;D077;110F 1173 11B2;D077;110F 1173 11B2; +D078;D078;110F 1173 11B3;D078;110F 1173 11B3; +D079;D079;110F 1173 11B4;D079;110F 1173 11B4; +D07A;D07A;110F 1173 11B5;D07A;110F 1173 11B5; +D07B;D07B;110F 1173 11B6;D07B;110F 1173 11B6; +D07C;D07C;110F 1173 11B7;D07C;110F 1173 11B7; +D07D;D07D;110F 1173 11B8;D07D;110F 1173 11B8; +D07E;D07E;110F 1173 11B9;D07E;110F 1173 11B9; +D07F;D07F;110F 1173 11BA;D07F;110F 1173 11BA; +D080;D080;110F 1173 11BB;D080;110F 1173 11BB; +D081;D081;110F 1173 11BC;D081;110F 1173 11BC; +D082;D082;110F 1173 11BD;D082;110F 1173 11BD; +D083;D083;110F 1173 11BE;D083;110F 1173 11BE; +D084;D084;110F 1173 11BF;D084;110F 1173 11BF; +D085;D085;110F 1173 11C0;D085;110F 1173 11C0; +D086;D086;110F 1173 11C1;D086;110F 1173 11C1; +D087;D087;110F 1173 11C2;D087;110F 1173 11C2; +D088;D088;110F 1174;D088;110F 1174; +D089;D089;110F 1174 11A8;D089;110F 1174 11A8; +D08A;D08A;110F 1174 11A9;D08A;110F 1174 11A9; +D08B;D08B;110F 1174 11AA;D08B;110F 1174 11AA; +D08C;D08C;110F 1174 11AB;D08C;110F 1174 11AB; +D08D;D08D;110F 1174 11AC;D08D;110F 1174 11AC; +D08E;D08E;110F 1174 11AD;D08E;110F 1174 11AD; +D08F;D08F;110F 1174 11AE;D08F;110F 1174 11AE; +D090;D090;110F 1174 11AF;D090;110F 1174 11AF; +D091;D091;110F 1174 11B0;D091;110F 1174 11B0; +D092;D092;110F 1174 11B1;D092;110F 1174 11B1; +D093;D093;110F 1174 11B2;D093;110F 1174 11B2; +D094;D094;110F 1174 11B3;D094;110F 1174 11B3; +D095;D095;110F 1174 11B4;D095;110F 1174 11B4; +D096;D096;110F 1174 11B5;D096;110F 1174 11B5; +D097;D097;110F 1174 11B6;D097;110F 1174 11B6; +D098;D098;110F 1174 11B7;D098;110F 1174 11B7; +D099;D099;110F 1174 11B8;D099;110F 1174 11B8; +D09A;D09A;110F 1174 11B9;D09A;110F 1174 11B9; +D09B;D09B;110F 1174 11BA;D09B;110F 1174 11BA; +D09C;D09C;110F 1174 11BB;D09C;110F 1174 11BB; +D09D;D09D;110F 1174 11BC;D09D;110F 1174 11BC; +D09E;D09E;110F 1174 11BD;D09E;110F 1174 11BD; +D09F;D09F;110F 1174 11BE;D09F;110F 1174 11BE; +D0A0;D0A0;110F 1174 11BF;D0A0;110F 1174 11BF; +D0A1;D0A1;110F 1174 11C0;D0A1;110F 1174 11C0; +D0A2;D0A2;110F 1174 11C1;D0A2;110F 1174 11C1; +D0A3;D0A3;110F 1174 11C2;D0A3;110F 1174 11C2; +D0A4;D0A4;110F 1175;D0A4;110F 1175; +D0A5;D0A5;110F 1175 11A8;D0A5;110F 1175 11A8; +D0A6;D0A6;110F 1175 11A9;D0A6;110F 1175 11A9; +D0A7;D0A7;110F 1175 11AA;D0A7;110F 1175 11AA; +D0A8;D0A8;110F 1175 11AB;D0A8;110F 1175 11AB; +D0A9;D0A9;110F 1175 11AC;D0A9;110F 1175 11AC; +D0AA;D0AA;110F 1175 11AD;D0AA;110F 1175 11AD; +D0AB;D0AB;110F 1175 11AE;D0AB;110F 1175 11AE; +D0AC;D0AC;110F 1175 11AF;D0AC;110F 1175 11AF; +D0AD;D0AD;110F 1175 11B0;D0AD;110F 1175 11B0; +D0AE;D0AE;110F 1175 11B1;D0AE;110F 1175 11B1; +D0AF;D0AF;110F 1175 11B2;D0AF;110F 1175 11B2; +D0B0;D0B0;110F 1175 11B3;D0B0;110F 1175 11B3; +D0B1;D0B1;110F 1175 11B4;D0B1;110F 1175 11B4; +D0B2;D0B2;110F 1175 11B5;D0B2;110F 1175 11B5; +D0B3;D0B3;110F 1175 11B6;D0B3;110F 1175 11B6; +D0B4;D0B4;110F 1175 11B7;D0B4;110F 1175 11B7; +D0B5;D0B5;110F 1175 11B8;D0B5;110F 1175 11B8; +D0B6;D0B6;110F 1175 11B9;D0B6;110F 1175 11B9; +D0B7;D0B7;110F 1175 11BA;D0B7;110F 1175 11BA; +D0B8;D0B8;110F 1175 11BB;D0B8;110F 1175 11BB; +D0B9;D0B9;110F 1175 11BC;D0B9;110F 1175 11BC; +D0BA;D0BA;110F 1175 11BD;D0BA;110F 1175 11BD; +D0BB;D0BB;110F 1175 11BE;D0BB;110F 1175 11BE; +D0BC;D0BC;110F 1175 11BF;D0BC;110F 1175 11BF; +D0BD;D0BD;110F 1175 11C0;D0BD;110F 1175 11C0; +D0BE;D0BE;110F 1175 11C1;D0BE;110F 1175 11C1; +D0BF;D0BF;110F 1175 11C2;D0BF;110F 1175 11C2; +D0C0;D0C0;1110 1161;D0C0;1110 1161; +D0C1;D0C1;1110 1161 11A8;D0C1;1110 1161 11A8; +D0C2;D0C2;1110 1161 11A9;D0C2;1110 1161 11A9; +D0C3;D0C3;1110 1161 11AA;D0C3;1110 1161 11AA; +D0C4;D0C4;1110 1161 11AB;D0C4;1110 1161 11AB; +D0C5;D0C5;1110 1161 11AC;D0C5;1110 1161 11AC; +D0C6;D0C6;1110 1161 11AD;D0C6;1110 1161 11AD; +D0C7;D0C7;1110 1161 11AE;D0C7;1110 1161 11AE; +D0C8;D0C8;1110 1161 11AF;D0C8;1110 1161 11AF; +D0C9;D0C9;1110 1161 11B0;D0C9;1110 1161 11B0; +D0CA;D0CA;1110 1161 11B1;D0CA;1110 1161 11B1; +D0CB;D0CB;1110 1161 11B2;D0CB;1110 1161 11B2; +D0CC;D0CC;1110 1161 11B3;D0CC;1110 1161 11B3; +D0CD;D0CD;1110 1161 11B4;D0CD;1110 1161 11B4; +D0CE;D0CE;1110 1161 11B5;D0CE;1110 1161 11B5; +D0CF;D0CF;1110 1161 11B6;D0CF;1110 1161 11B6; +D0D0;D0D0;1110 1161 11B7;D0D0;1110 1161 11B7; +D0D1;D0D1;1110 1161 11B8;D0D1;1110 1161 11B8; +D0D2;D0D2;1110 1161 11B9;D0D2;1110 1161 11B9; +D0D3;D0D3;1110 1161 11BA;D0D3;1110 1161 11BA; +D0D4;D0D4;1110 1161 11BB;D0D4;1110 1161 11BB; +D0D5;D0D5;1110 1161 11BC;D0D5;1110 1161 11BC; +D0D6;D0D6;1110 1161 11BD;D0D6;1110 1161 11BD; +D0D7;D0D7;1110 1161 11BE;D0D7;1110 1161 11BE; +D0D8;D0D8;1110 1161 11BF;D0D8;1110 1161 11BF; +D0D9;D0D9;1110 1161 11C0;D0D9;1110 1161 11C0; +D0DA;D0DA;1110 1161 11C1;D0DA;1110 1161 11C1; +D0DB;D0DB;1110 1161 11C2;D0DB;1110 1161 11C2; +D0DC;D0DC;1110 1162;D0DC;1110 1162; +D0DD;D0DD;1110 1162 11A8;D0DD;1110 1162 11A8; +D0DE;D0DE;1110 1162 11A9;D0DE;1110 1162 11A9; +D0DF;D0DF;1110 1162 11AA;D0DF;1110 1162 11AA; +D0E0;D0E0;1110 1162 11AB;D0E0;1110 1162 11AB; +D0E1;D0E1;1110 1162 11AC;D0E1;1110 1162 11AC; +D0E2;D0E2;1110 1162 11AD;D0E2;1110 1162 11AD; +D0E3;D0E3;1110 1162 11AE;D0E3;1110 1162 11AE; +D0E4;D0E4;1110 1162 11AF;D0E4;1110 1162 11AF; +D0E5;D0E5;1110 1162 11B0;D0E5;1110 1162 11B0; +D0E6;D0E6;1110 1162 11B1;D0E6;1110 1162 11B1; +D0E7;D0E7;1110 1162 11B2;D0E7;1110 1162 11B2; +D0E8;D0E8;1110 1162 11B3;D0E8;1110 1162 11B3; +D0E9;D0E9;1110 1162 11B4;D0E9;1110 1162 11B4; +D0EA;D0EA;1110 1162 11B5;D0EA;1110 1162 11B5; +D0EB;D0EB;1110 1162 11B6;D0EB;1110 1162 11B6; +D0EC;D0EC;1110 1162 11B7;D0EC;1110 1162 11B7; +D0ED;D0ED;1110 1162 11B8;D0ED;1110 1162 11B8; +D0EE;D0EE;1110 1162 11B9;D0EE;1110 1162 11B9; +D0EF;D0EF;1110 1162 11BA;D0EF;1110 1162 11BA; +D0F0;D0F0;1110 1162 11BB;D0F0;1110 1162 11BB; +D0F1;D0F1;1110 1162 11BC;D0F1;1110 1162 11BC; +D0F2;D0F2;1110 1162 11BD;D0F2;1110 1162 11BD; +D0F3;D0F3;1110 1162 11BE;D0F3;1110 1162 11BE; +D0F4;D0F4;1110 1162 11BF;D0F4;1110 1162 11BF; +D0F5;D0F5;1110 1162 11C0;D0F5;1110 1162 11C0; +D0F6;D0F6;1110 1162 11C1;D0F6;1110 1162 11C1; +D0F7;D0F7;1110 1162 11C2;D0F7;1110 1162 11C2; +D0F8;D0F8;1110 1163;D0F8;1110 1163; +D0F9;D0F9;1110 1163 11A8;D0F9;1110 1163 11A8; +D0FA;D0FA;1110 1163 11A9;D0FA;1110 1163 11A9; +D0FB;D0FB;1110 1163 11AA;D0FB;1110 1163 11AA; +D0FC;D0FC;1110 1163 11AB;D0FC;1110 1163 11AB; +D0FD;D0FD;1110 1163 11AC;D0FD;1110 1163 11AC; +D0FE;D0FE;1110 1163 11AD;D0FE;1110 1163 11AD; +D0FF;D0FF;1110 1163 11AE;D0FF;1110 1163 11AE; +D100;D100;1110 1163 11AF;D100;1110 1163 11AF; +D101;D101;1110 1163 11B0;D101;1110 1163 11B0; +D102;D102;1110 1163 11B1;D102;1110 1163 11B1; +D103;D103;1110 1163 11B2;D103;1110 1163 11B2; +D104;D104;1110 1163 11B3;D104;1110 1163 11B3; +D105;D105;1110 1163 11B4;D105;1110 1163 11B4; +D106;D106;1110 1163 11B5;D106;1110 1163 11B5; +D107;D107;1110 1163 11B6;D107;1110 1163 11B6; +D108;D108;1110 1163 11B7;D108;1110 1163 11B7; +D109;D109;1110 1163 11B8;D109;1110 1163 11B8; +D10A;D10A;1110 1163 11B9;D10A;1110 1163 11B9; +D10B;D10B;1110 1163 11BA;D10B;1110 1163 11BA; +D10C;D10C;1110 1163 11BB;D10C;1110 1163 11BB; +D10D;D10D;1110 1163 11BC;D10D;1110 1163 11BC; +D10E;D10E;1110 1163 11BD;D10E;1110 1163 11BD; +D10F;D10F;1110 1163 11BE;D10F;1110 1163 11BE; +D110;D110;1110 1163 11BF;D110;1110 1163 11BF; +D111;D111;1110 1163 11C0;D111;1110 1163 11C0; +D112;D112;1110 1163 11C1;D112;1110 1163 11C1; +D113;D113;1110 1163 11C2;D113;1110 1163 11C2; +D114;D114;1110 1164;D114;1110 1164; +D115;D115;1110 1164 11A8;D115;1110 1164 11A8; +D116;D116;1110 1164 11A9;D116;1110 1164 11A9; +D117;D117;1110 1164 11AA;D117;1110 1164 11AA; +D118;D118;1110 1164 11AB;D118;1110 1164 11AB; +D119;D119;1110 1164 11AC;D119;1110 1164 11AC; +D11A;D11A;1110 1164 11AD;D11A;1110 1164 11AD; +D11B;D11B;1110 1164 11AE;D11B;1110 1164 11AE; +D11C;D11C;1110 1164 11AF;D11C;1110 1164 11AF; +D11D;D11D;1110 1164 11B0;D11D;1110 1164 11B0; +D11E;D11E;1110 1164 11B1;D11E;1110 1164 11B1; +D11F;D11F;1110 1164 11B2;D11F;1110 1164 11B2; +D120;D120;1110 1164 11B3;D120;1110 1164 11B3; +D121;D121;1110 1164 11B4;D121;1110 1164 11B4; +D122;D122;1110 1164 11B5;D122;1110 1164 11B5; +D123;D123;1110 1164 11B6;D123;1110 1164 11B6; +D124;D124;1110 1164 11B7;D124;1110 1164 11B7; +D125;D125;1110 1164 11B8;D125;1110 1164 11B8; +D126;D126;1110 1164 11B9;D126;1110 1164 11B9; +D127;D127;1110 1164 11BA;D127;1110 1164 11BA; +D128;D128;1110 1164 11BB;D128;1110 1164 11BB; +D129;D129;1110 1164 11BC;D129;1110 1164 11BC; +D12A;D12A;1110 1164 11BD;D12A;1110 1164 11BD; +D12B;D12B;1110 1164 11BE;D12B;1110 1164 11BE; +D12C;D12C;1110 1164 11BF;D12C;1110 1164 11BF; +D12D;D12D;1110 1164 11C0;D12D;1110 1164 11C0; +D12E;D12E;1110 1164 11C1;D12E;1110 1164 11C1; +D12F;D12F;1110 1164 11C2;D12F;1110 1164 11C2; +D130;D130;1110 1165;D130;1110 1165; +D131;D131;1110 1165 11A8;D131;1110 1165 11A8; +D132;D132;1110 1165 11A9;D132;1110 1165 11A9; +D133;D133;1110 1165 11AA;D133;1110 1165 11AA; +D134;D134;1110 1165 11AB;D134;1110 1165 11AB; +D135;D135;1110 1165 11AC;D135;1110 1165 11AC; +D136;D136;1110 1165 11AD;D136;1110 1165 11AD; +D137;D137;1110 1165 11AE;D137;1110 1165 11AE; +D138;D138;1110 1165 11AF;D138;1110 1165 11AF; +D139;D139;1110 1165 11B0;D139;1110 1165 11B0; +D13A;D13A;1110 1165 11B1;D13A;1110 1165 11B1; +D13B;D13B;1110 1165 11B2;D13B;1110 1165 11B2; +D13C;D13C;1110 1165 11B3;D13C;1110 1165 11B3; +D13D;D13D;1110 1165 11B4;D13D;1110 1165 11B4; +D13E;D13E;1110 1165 11B5;D13E;1110 1165 11B5; +D13F;D13F;1110 1165 11B6;D13F;1110 1165 11B6; +D140;D140;1110 1165 11B7;D140;1110 1165 11B7; +D141;D141;1110 1165 11B8;D141;1110 1165 11B8; +D142;D142;1110 1165 11B9;D142;1110 1165 11B9; +D143;D143;1110 1165 11BA;D143;1110 1165 11BA; +D144;D144;1110 1165 11BB;D144;1110 1165 11BB; +D145;D145;1110 1165 11BC;D145;1110 1165 11BC; +D146;D146;1110 1165 11BD;D146;1110 1165 11BD; +D147;D147;1110 1165 11BE;D147;1110 1165 11BE; +D148;D148;1110 1165 11BF;D148;1110 1165 11BF; +D149;D149;1110 1165 11C0;D149;1110 1165 11C0; +D14A;D14A;1110 1165 11C1;D14A;1110 1165 11C1; +D14B;D14B;1110 1165 11C2;D14B;1110 1165 11C2; +D14C;D14C;1110 1166;D14C;1110 1166; +D14D;D14D;1110 1166 11A8;D14D;1110 1166 11A8; +D14E;D14E;1110 1166 11A9;D14E;1110 1166 11A9; +D14F;D14F;1110 1166 11AA;D14F;1110 1166 11AA; +D150;D150;1110 1166 11AB;D150;1110 1166 11AB; +D151;D151;1110 1166 11AC;D151;1110 1166 11AC; +D152;D152;1110 1166 11AD;D152;1110 1166 11AD; +D153;D153;1110 1166 11AE;D153;1110 1166 11AE; +D154;D154;1110 1166 11AF;D154;1110 1166 11AF; +D155;D155;1110 1166 11B0;D155;1110 1166 11B0; +D156;D156;1110 1166 11B1;D156;1110 1166 11B1; +D157;D157;1110 1166 11B2;D157;1110 1166 11B2; +D158;D158;1110 1166 11B3;D158;1110 1166 11B3; +D159;D159;1110 1166 11B4;D159;1110 1166 11B4; +D15A;D15A;1110 1166 11B5;D15A;1110 1166 11B5; +D15B;D15B;1110 1166 11B6;D15B;1110 1166 11B6; +D15C;D15C;1110 1166 11B7;D15C;1110 1166 11B7; +D15D;D15D;1110 1166 11B8;D15D;1110 1166 11B8; +D15E;D15E;1110 1166 11B9;D15E;1110 1166 11B9; +D15F;D15F;1110 1166 11BA;D15F;1110 1166 11BA; +D160;D160;1110 1166 11BB;D160;1110 1166 11BB; +D161;D161;1110 1166 11BC;D161;1110 1166 11BC; +D162;D162;1110 1166 11BD;D162;1110 1166 11BD; +D163;D163;1110 1166 11BE;D163;1110 1166 11BE; +D164;D164;1110 1166 11BF;D164;1110 1166 11BF; +D165;D165;1110 1166 11C0;D165;1110 1166 11C0; +D166;D166;1110 1166 11C1;D166;1110 1166 11C1; +D167;D167;1110 1166 11C2;D167;1110 1166 11C2; +D168;D168;1110 1167;D168;1110 1167; +D169;D169;1110 1167 11A8;D169;1110 1167 11A8; +D16A;D16A;1110 1167 11A9;D16A;1110 1167 11A9; +D16B;D16B;1110 1167 11AA;D16B;1110 1167 11AA; +D16C;D16C;1110 1167 11AB;D16C;1110 1167 11AB; +D16D;D16D;1110 1167 11AC;D16D;1110 1167 11AC; +D16E;D16E;1110 1167 11AD;D16E;1110 1167 11AD; +D16F;D16F;1110 1167 11AE;D16F;1110 1167 11AE; +D170;D170;1110 1167 11AF;D170;1110 1167 11AF; +D171;D171;1110 1167 11B0;D171;1110 1167 11B0; +D172;D172;1110 1167 11B1;D172;1110 1167 11B1; +D173;D173;1110 1167 11B2;D173;1110 1167 11B2; +D174;D174;1110 1167 11B3;D174;1110 1167 11B3; +D175;D175;1110 1167 11B4;D175;1110 1167 11B4; +D176;D176;1110 1167 11B5;D176;1110 1167 11B5; +D177;D177;1110 1167 11B6;D177;1110 1167 11B6; +D178;D178;1110 1167 11B7;D178;1110 1167 11B7; +D179;D179;1110 1167 11B8;D179;1110 1167 11B8; +D17A;D17A;1110 1167 11B9;D17A;1110 1167 11B9; +D17B;D17B;1110 1167 11BA;D17B;1110 1167 11BA; +D17C;D17C;1110 1167 11BB;D17C;1110 1167 11BB; +D17D;D17D;1110 1167 11BC;D17D;1110 1167 11BC; +D17E;D17E;1110 1167 11BD;D17E;1110 1167 11BD; +D17F;D17F;1110 1167 11BE;D17F;1110 1167 11BE; +D180;D180;1110 1167 11BF;D180;1110 1167 11BF; +D181;D181;1110 1167 11C0;D181;1110 1167 11C0; +D182;D182;1110 1167 11C1;D182;1110 1167 11C1; +D183;D183;1110 1167 11C2;D183;1110 1167 11C2; +D184;D184;1110 1168;D184;1110 1168; +D185;D185;1110 1168 11A8;D185;1110 1168 11A8; +D186;D186;1110 1168 11A9;D186;1110 1168 11A9; +D187;D187;1110 1168 11AA;D187;1110 1168 11AA; +D188;D188;1110 1168 11AB;D188;1110 1168 11AB; +D189;D189;1110 1168 11AC;D189;1110 1168 11AC; +D18A;D18A;1110 1168 11AD;D18A;1110 1168 11AD; +D18B;D18B;1110 1168 11AE;D18B;1110 1168 11AE; +D18C;D18C;1110 1168 11AF;D18C;1110 1168 11AF; +D18D;D18D;1110 1168 11B0;D18D;1110 1168 11B0; +D18E;D18E;1110 1168 11B1;D18E;1110 1168 11B1; +D18F;D18F;1110 1168 11B2;D18F;1110 1168 11B2; +D190;D190;1110 1168 11B3;D190;1110 1168 11B3; +D191;D191;1110 1168 11B4;D191;1110 1168 11B4; +D192;D192;1110 1168 11B5;D192;1110 1168 11B5; +D193;D193;1110 1168 11B6;D193;1110 1168 11B6; +D194;D194;1110 1168 11B7;D194;1110 1168 11B7; +D195;D195;1110 1168 11B8;D195;1110 1168 11B8; +D196;D196;1110 1168 11B9;D196;1110 1168 11B9; +D197;D197;1110 1168 11BA;D197;1110 1168 11BA; +D198;D198;1110 1168 11BB;D198;1110 1168 11BB; +D199;D199;1110 1168 11BC;D199;1110 1168 11BC; +D19A;D19A;1110 1168 11BD;D19A;1110 1168 11BD; +D19B;D19B;1110 1168 11BE;D19B;1110 1168 11BE; +D19C;D19C;1110 1168 11BF;D19C;1110 1168 11BF; +D19D;D19D;1110 1168 11C0;D19D;1110 1168 11C0; +D19E;D19E;1110 1168 11C1;D19E;1110 1168 11C1; +D19F;D19F;1110 1168 11C2;D19F;1110 1168 11C2; +D1A0;D1A0;1110 1169;D1A0;1110 1169; +D1A1;D1A1;1110 1169 11A8;D1A1;1110 1169 11A8; +D1A2;D1A2;1110 1169 11A9;D1A2;1110 1169 11A9; +D1A3;D1A3;1110 1169 11AA;D1A3;1110 1169 11AA; +D1A4;D1A4;1110 1169 11AB;D1A4;1110 1169 11AB; +D1A5;D1A5;1110 1169 11AC;D1A5;1110 1169 11AC; +D1A6;D1A6;1110 1169 11AD;D1A6;1110 1169 11AD; +D1A7;D1A7;1110 1169 11AE;D1A7;1110 1169 11AE; +D1A8;D1A8;1110 1169 11AF;D1A8;1110 1169 11AF; +D1A9;D1A9;1110 1169 11B0;D1A9;1110 1169 11B0; +D1AA;D1AA;1110 1169 11B1;D1AA;1110 1169 11B1; +D1AB;D1AB;1110 1169 11B2;D1AB;1110 1169 11B2; +D1AC;D1AC;1110 1169 11B3;D1AC;1110 1169 11B3; +D1AD;D1AD;1110 1169 11B4;D1AD;1110 1169 11B4; +D1AE;D1AE;1110 1169 11B5;D1AE;1110 1169 11B5; +D1AF;D1AF;1110 1169 11B6;D1AF;1110 1169 11B6; +D1B0;D1B0;1110 1169 11B7;D1B0;1110 1169 11B7; +D1B1;D1B1;1110 1169 11B8;D1B1;1110 1169 11B8; +D1B2;D1B2;1110 1169 11B9;D1B2;1110 1169 11B9; +D1B3;D1B3;1110 1169 11BA;D1B3;1110 1169 11BA; +D1B4;D1B4;1110 1169 11BB;D1B4;1110 1169 11BB; +D1B5;D1B5;1110 1169 11BC;D1B5;1110 1169 11BC; +D1B6;D1B6;1110 1169 11BD;D1B6;1110 1169 11BD; +D1B7;D1B7;1110 1169 11BE;D1B7;1110 1169 11BE; +D1B8;D1B8;1110 1169 11BF;D1B8;1110 1169 11BF; +D1B9;D1B9;1110 1169 11C0;D1B9;1110 1169 11C0; +D1BA;D1BA;1110 1169 11C1;D1BA;1110 1169 11C1; +D1BB;D1BB;1110 1169 11C2;D1BB;1110 1169 11C2; +D1BC;D1BC;1110 116A;D1BC;1110 116A; +D1BD;D1BD;1110 116A 11A8;D1BD;1110 116A 11A8; +D1BE;D1BE;1110 116A 11A9;D1BE;1110 116A 11A9; +D1BF;D1BF;1110 116A 11AA;D1BF;1110 116A 11AA; +D1C0;D1C0;1110 116A 11AB;D1C0;1110 116A 11AB; +D1C1;D1C1;1110 116A 11AC;D1C1;1110 116A 11AC; +D1C2;D1C2;1110 116A 11AD;D1C2;1110 116A 11AD; +D1C3;D1C3;1110 116A 11AE;D1C3;1110 116A 11AE; +D1C4;D1C4;1110 116A 11AF;D1C4;1110 116A 11AF; +D1C5;D1C5;1110 116A 11B0;D1C5;1110 116A 11B0; +D1C6;D1C6;1110 116A 11B1;D1C6;1110 116A 11B1; +D1C7;D1C7;1110 116A 11B2;D1C7;1110 116A 11B2; +D1C8;D1C8;1110 116A 11B3;D1C8;1110 116A 11B3; +D1C9;D1C9;1110 116A 11B4;D1C9;1110 116A 11B4; +D1CA;D1CA;1110 116A 11B5;D1CA;1110 116A 11B5; +D1CB;D1CB;1110 116A 11B6;D1CB;1110 116A 11B6; +D1CC;D1CC;1110 116A 11B7;D1CC;1110 116A 11B7; +D1CD;D1CD;1110 116A 11B8;D1CD;1110 116A 11B8; +D1CE;D1CE;1110 116A 11B9;D1CE;1110 116A 11B9; +D1CF;D1CF;1110 116A 11BA;D1CF;1110 116A 11BA; +D1D0;D1D0;1110 116A 11BB;D1D0;1110 116A 11BB; +D1D1;D1D1;1110 116A 11BC;D1D1;1110 116A 11BC; +D1D2;D1D2;1110 116A 11BD;D1D2;1110 116A 11BD; +D1D3;D1D3;1110 116A 11BE;D1D3;1110 116A 11BE; +D1D4;D1D4;1110 116A 11BF;D1D4;1110 116A 11BF; +D1D5;D1D5;1110 116A 11C0;D1D5;1110 116A 11C0; +D1D6;D1D6;1110 116A 11C1;D1D6;1110 116A 11C1; +D1D7;D1D7;1110 116A 11C2;D1D7;1110 116A 11C2; +D1D8;D1D8;1110 116B;D1D8;1110 116B; +D1D9;D1D9;1110 116B 11A8;D1D9;1110 116B 11A8; +D1DA;D1DA;1110 116B 11A9;D1DA;1110 116B 11A9; +D1DB;D1DB;1110 116B 11AA;D1DB;1110 116B 11AA; +D1DC;D1DC;1110 116B 11AB;D1DC;1110 116B 11AB; +D1DD;D1DD;1110 116B 11AC;D1DD;1110 116B 11AC; +D1DE;D1DE;1110 116B 11AD;D1DE;1110 116B 11AD; +D1DF;D1DF;1110 116B 11AE;D1DF;1110 116B 11AE; +D1E0;D1E0;1110 116B 11AF;D1E0;1110 116B 11AF; +D1E1;D1E1;1110 116B 11B0;D1E1;1110 116B 11B0; +D1E2;D1E2;1110 116B 11B1;D1E2;1110 116B 11B1; +D1E3;D1E3;1110 116B 11B2;D1E3;1110 116B 11B2; +D1E4;D1E4;1110 116B 11B3;D1E4;1110 116B 11B3; +D1E5;D1E5;1110 116B 11B4;D1E5;1110 116B 11B4; +D1E6;D1E6;1110 116B 11B5;D1E6;1110 116B 11B5; +D1E7;D1E7;1110 116B 11B6;D1E7;1110 116B 11B6; +D1E8;D1E8;1110 116B 11B7;D1E8;1110 116B 11B7; +D1E9;D1E9;1110 116B 11B8;D1E9;1110 116B 11B8; +D1EA;D1EA;1110 116B 11B9;D1EA;1110 116B 11B9; +D1EB;D1EB;1110 116B 11BA;D1EB;1110 116B 11BA; +D1EC;D1EC;1110 116B 11BB;D1EC;1110 116B 11BB; +D1ED;D1ED;1110 116B 11BC;D1ED;1110 116B 11BC; +D1EE;D1EE;1110 116B 11BD;D1EE;1110 116B 11BD; +D1EF;D1EF;1110 116B 11BE;D1EF;1110 116B 11BE; +D1F0;D1F0;1110 116B 11BF;D1F0;1110 116B 11BF; +D1F1;D1F1;1110 116B 11C0;D1F1;1110 116B 11C0; +D1F2;D1F2;1110 116B 11C1;D1F2;1110 116B 11C1; +D1F3;D1F3;1110 116B 11C2;D1F3;1110 116B 11C2; +D1F4;D1F4;1110 116C;D1F4;1110 116C; +D1F5;D1F5;1110 116C 11A8;D1F5;1110 116C 11A8; +D1F6;D1F6;1110 116C 11A9;D1F6;1110 116C 11A9; +D1F7;D1F7;1110 116C 11AA;D1F7;1110 116C 11AA; +D1F8;D1F8;1110 116C 11AB;D1F8;1110 116C 11AB; +D1F9;D1F9;1110 116C 11AC;D1F9;1110 116C 11AC; +D1FA;D1FA;1110 116C 11AD;D1FA;1110 116C 11AD; +D1FB;D1FB;1110 116C 11AE;D1FB;1110 116C 11AE; +D1FC;D1FC;1110 116C 11AF;D1FC;1110 116C 11AF; +D1FD;D1FD;1110 116C 11B0;D1FD;1110 116C 11B0; +D1FE;D1FE;1110 116C 11B1;D1FE;1110 116C 11B1; +D1FF;D1FF;1110 116C 11B2;D1FF;1110 116C 11B2; +D200;D200;1110 116C 11B3;D200;1110 116C 11B3; +D201;D201;1110 116C 11B4;D201;1110 116C 11B4; +D202;D202;1110 116C 11B5;D202;1110 116C 11B5; +D203;D203;1110 116C 11B6;D203;1110 116C 11B6; +D204;D204;1110 116C 11B7;D204;1110 116C 11B7; +D205;D205;1110 116C 11B8;D205;1110 116C 11B8; +D206;D206;1110 116C 11B9;D206;1110 116C 11B9; +D207;D207;1110 116C 11BA;D207;1110 116C 11BA; +D208;D208;1110 116C 11BB;D208;1110 116C 11BB; +D209;D209;1110 116C 11BC;D209;1110 116C 11BC; +D20A;D20A;1110 116C 11BD;D20A;1110 116C 11BD; +D20B;D20B;1110 116C 11BE;D20B;1110 116C 11BE; +D20C;D20C;1110 116C 11BF;D20C;1110 116C 11BF; +D20D;D20D;1110 116C 11C0;D20D;1110 116C 11C0; +D20E;D20E;1110 116C 11C1;D20E;1110 116C 11C1; +D20F;D20F;1110 116C 11C2;D20F;1110 116C 11C2; +D210;D210;1110 116D;D210;1110 116D; +D211;D211;1110 116D 11A8;D211;1110 116D 11A8; +D212;D212;1110 116D 11A9;D212;1110 116D 11A9; +D213;D213;1110 116D 11AA;D213;1110 116D 11AA; +D214;D214;1110 116D 11AB;D214;1110 116D 11AB; +D215;D215;1110 116D 11AC;D215;1110 116D 11AC; +D216;D216;1110 116D 11AD;D216;1110 116D 11AD; +D217;D217;1110 116D 11AE;D217;1110 116D 11AE; +D218;D218;1110 116D 11AF;D218;1110 116D 11AF; +D219;D219;1110 116D 11B0;D219;1110 116D 11B0; +D21A;D21A;1110 116D 11B1;D21A;1110 116D 11B1; +D21B;D21B;1110 116D 11B2;D21B;1110 116D 11B2; +D21C;D21C;1110 116D 11B3;D21C;1110 116D 11B3; +D21D;D21D;1110 116D 11B4;D21D;1110 116D 11B4; +D21E;D21E;1110 116D 11B5;D21E;1110 116D 11B5; +D21F;D21F;1110 116D 11B6;D21F;1110 116D 11B6; +D220;D220;1110 116D 11B7;D220;1110 116D 11B7; +D221;D221;1110 116D 11B8;D221;1110 116D 11B8; +D222;D222;1110 116D 11B9;D222;1110 116D 11B9; +D223;D223;1110 116D 11BA;D223;1110 116D 11BA; +D224;D224;1110 116D 11BB;D224;1110 116D 11BB; +D225;D225;1110 116D 11BC;D225;1110 116D 11BC; +D226;D226;1110 116D 11BD;D226;1110 116D 11BD; +D227;D227;1110 116D 11BE;D227;1110 116D 11BE; +D228;D228;1110 116D 11BF;D228;1110 116D 11BF; +D229;D229;1110 116D 11C0;D229;1110 116D 11C0; +D22A;D22A;1110 116D 11C1;D22A;1110 116D 11C1; +D22B;D22B;1110 116D 11C2;D22B;1110 116D 11C2; +D22C;D22C;1110 116E;D22C;1110 116E; +D22D;D22D;1110 116E 11A8;D22D;1110 116E 11A8; +D22E;D22E;1110 116E 11A9;D22E;1110 116E 11A9; +D22F;D22F;1110 116E 11AA;D22F;1110 116E 11AA; +D230;D230;1110 116E 11AB;D230;1110 116E 11AB; +D231;D231;1110 116E 11AC;D231;1110 116E 11AC; +D232;D232;1110 116E 11AD;D232;1110 116E 11AD; +D233;D233;1110 116E 11AE;D233;1110 116E 11AE; +D234;D234;1110 116E 11AF;D234;1110 116E 11AF; +D235;D235;1110 116E 11B0;D235;1110 116E 11B0; +D236;D236;1110 116E 11B1;D236;1110 116E 11B1; +D237;D237;1110 116E 11B2;D237;1110 116E 11B2; +D238;D238;1110 116E 11B3;D238;1110 116E 11B3; +D239;D239;1110 116E 11B4;D239;1110 116E 11B4; +D23A;D23A;1110 116E 11B5;D23A;1110 116E 11B5; +D23B;D23B;1110 116E 11B6;D23B;1110 116E 11B6; +D23C;D23C;1110 116E 11B7;D23C;1110 116E 11B7; +D23D;D23D;1110 116E 11B8;D23D;1110 116E 11B8; +D23E;D23E;1110 116E 11B9;D23E;1110 116E 11B9; +D23F;D23F;1110 116E 11BA;D23F;1110 116E 11BA; +D240;D240;1110 116E 11BB;D240;1110 116E 11BB; +D241;D241;1110 116E 11BC;D241;1110 116E 11BC; +D242;D242;1110 116E 11BD;D242;1110 116E 11BD; +D243;D243;1110 116E 11BE;D243;1110 116E 11BE; +D244;D244;1110 116E 11BF;D244;1110 116E 11BF; +D245;D245;1110 116E 11C0;D245;1110 116E 11C0; +D246;D246;1110 116E 11C1;D246;1110 116E 11C1; +D247;D247;1110 116E 11C2;D247;1110 116E 11C2; +D248;D248;1110 116F;D248;1110 116F; +D249;D249;1110 116F 11A8;D249;1110 116F 11A8; +D24A;D24A;1110 116F 11A9;D24A;1110 116F 11A9; +D24B;D24B;1110 116F 11AA;D24B;1110 116F 11AA; +D24C;D24C;1110 116F 11AB;D24C;1110 116F 11AB; +D24D;D24D;1110 116F 11AC;D24D;1110 116F 11AC; +D24E;D24E;1110 116F 11AD;D24E;1110 116F 11AD; +D24F;D24F;1110 116F 11AE;D24F;1110 116F 11AE; +D250;D250;1110 116F 11AF;D250;1110 116F 11AF; +D251;D251;1110 116F 11B0;D251;1110 116F 11B0; +D252;D252;1110 116F 11B1;D252;1110 116F 11B1; +D253;D253;1110 116F 11B2;D253;1110 116F 11B2; +D254;D254;1110 116F 11B3;D254;1110 116F 11B3; +D255;D255;1110 116F 11B4;D255;1110 116F 11B4; +D256;D256;1110 116F 11B5;D256;1110 116F 11B5; +D257;D257;1110 116F 11B6;D257;1110 116F 11B6; +D258;D258;1110 116F 11B7;D258;1110 116F 11B7; +D259;D259;1110 116F 11B8;D259;1110 116F 11B8; +D25A;D25A;1110 116F 11B9;D25A;1110 116F 11B9; +D25B;D25B;1110 116F 11BA;D25B;1110 116F 11BA; +D25C;D25C;1110 116F 11BB;D25C;1110 116F 11BB; +D25D;D25D;1110 116F 11BC;D25D;1110 116F 11BC; +D25E;D25E;1110 116F 11BD;D25E;1110 116F 11BD; +D25F;D25F;1110 116F 11BE;D25F;1110 116F 11BE; +D260;D260;1110 116F 11BF;D260;1110 116F 11BF; +D261;D261;1110 116F 11C0;D261;1110 116F 11C0; +D262;D262;1110 116F 11C1;D262;1110 116F 11C1; +D263;D263;1110 116F 11C2;D263;1110 116F 11C2; +D264;D264;1110 1170;D264;1110 1170; +D265;D265;1110 1170 11A8;D265;1110 1170 11A8; +D266;D266;1110 1170 11A9;D266;1110 1170 11A9; +D267;D267;1110 1170 11AA;D267;1110 1170 11AA; +D268;D268;1110 1170 11AB;D268;1110 1170 11AB; +D269;D269;1110 1170 11AC;D269;1110 1170 11AC; +D26A;D26A;1110 1170 11AD;D26A;1110 1170 11AD; +D26B;D26B;1110 1170 11AE;D26B;1110 1170 11AE; +D26C;D26C;1110 1170 11AF;D26C;1110 1170 11AF; +D26D;D26D;1110 1170 11B0;D26D;1110 1170 11B0; +D26E;D26E;1110 1170 11B1;D26E;1110 1170 11B1; +D26F;D26F;1110 1170 11B2;D26F;1110 1170 11B2; +D270;D270;1110 1170 11B3;D270;1110 1170 11B3; +D271;D271;1110 1170 11B4;D271;1110 1170 11B4; +D272;D272;1110 1170 11B5;D272;1110 1170 11B5; +D273;D273;1110 1170 11B6;D273;1110 1170 11B6; +D274;D274;1110 1170 11B7;D274;1110 1170 11B7; +D275;D275;1110 1170 11B8;D275;1110 1170 11B8; +D276;D276;1110 1170 11B9;D276;1110 1170 11B9; +D277;D277;1110 1170 11BA;D277;1110 1170 11BA; +D278;D278;1110 1170 11BB;D278;1110 1170 11BB; +D279;D279;1110 1170 11BC;D279;1110 1170 11BC; +D27A;D27A;1110 1170 11BD;D27A;1110 1170 11BD; +D27B;D27B;1110 1170 11BE;D27B;1110 1170 11BE; +D27C;D27C;1110 1170 11BF;D27C;1110 1170 11BF; +D27D;D27D;1110 1170 11C0;D27D;1110 1170 11C0; +D27E;D27E;1110 1170 11C1;D27E;1110 1170 11C1; +D27F;D27F;1110 1170 11C2;D27F;1110 1170 11C2; +D280;D280;1110 1171;D280;1110 1171; +D281;D281;1110 1171 11A8;D281;1110 1171 11A8; +D282;D282;1110 1171 11A9;D282;1110 1171 11A9; +D283;D283;1110 1171 11AA;D283;1110 1171 11AA; +D284;D284;1110 1171 11AB;D284;1110 1171 11AB; +D285;D285;1110 1171 11AC;D285;1110 1171 11AC; +D286;D286;1110 1171 11AD;D286;1110 1171 11AD; +D287;D287;1110 1171 11AE;D287;1110 1171 11AE; +D288;D288;1110 1171 11AF;D288;1110 1171 11AF; +D289;D289;1110 1171 11B0;D289;1110 1171 11B0; +D28A;D28A;1110 1171 11B1;D28A;1110 1171 11B1; +D28B;D28B;1110 1171 11B2;D28B;1110 1171 11B2; +D28C;D28C;1110 1171 11B3;D28C;1110 1171 11B3; +D28D;D28D;1110 1171 11B4;D28D;1110 1171 11B4; +D28E;D28E;1110 1171 11B5;D28E;1110 1171 11B5; +D28F;D28F;1110 1171 11B6;D28F;1110 1171 11B6; +D290;D290;1110 1171 11B7;D290;1110 1171 11B7; +D291;D291;1110 1171 11B8;D291;1110 1171 11B8; +D292;D292;1110 1171 11B9;D292;1110 1171 11B9; +D293;D293;1110 1171 11BA;D293;1110 1171 11BA; +D294;D294;1110 1171 11BB;D294;1110 1171 11BB; +D295;D295;1110 1171 11BC;D295;1110 1171 11BC; +D296;D296;1110 1171 11BD;D296;1110 1171 11BD; +D297;D297;1110 1171 11BE;D297;1110 1171 11BE; +D298;D298;1110 1171 11BF;D298;1110 1171 11BF; +D299;D299;1110 1171 11C0;D299;1110 1171 11C0; +D29A;D29A;1110 1171 11C1;D29A;1110 1171 11C1; +D29B;D29B;1110 1171 11C2;D29B;1110 1171 11C2; +D29C;D29C;1110 1172;D29C;1110 1172; +D29D;D29D;1110 1172 11A8;D29D;1110 1172 11A8; +D29E;D29E;1110 1172 11A9;D29E;1110 1172 11A9; +D29F;D29F;1110 1172 11AA;D29F;1110 1172 11AA; +D2A0;D2A0;1110 1172 11AB;D2A0;1110 1172 11AB; +D2A1;D2A1;1110 1172 11AC;D2A1;1110 1172 11AC; +D2A2;D2A2;1110 1172 11AD;D2A2;1110 1172 11AD; +D2A3;D2A3;1110 1172 11AE;D2A3;1110 1172 11AE; +D2A4;D2A4;1110 1172 11AF;D2A4;1110 1172 11AF; +D2A5;D2A5;1110 1172 11B0;D2A5;1110 1172 11B0; +D2A6;D2A6;1110 1172 11B1;D2A6;1110 1172 11B1; +D2A7;D2A7;1110 1172 11B2;D2A7;1110 1172 11B2; +D2A8;D2A8;1110 1172 11B3;D2A8;1110 1172 11B3; +D2A9;D2A9;1110 1172 11B4;D2A9;1110 1172 11B4; +D2AA;D2AA;1110 1172 11B5;D2AA;1110 1172 11B5; +D2AB;D2AB;1110 1172 11B6;D2AB;1110 1172 11B6; +D2AC;D2AC;1110 1172 11B7;D2AC;1110 1172 11B7; +D2AD;D2AD;1110 1172 11B8;D2AD;1110 1172 11B8; +D2AE;D2AE;1110 1172 11B9;D2AE;1110 1172 11B9; +D2AF;D2AF;1110 1172 11BA;D2AF;1110 1172 11BA; +D2B0;D2B0;1110 1172 11BB;D2B0;1110 1172 11BB; +D2B1;D2B1;1110 1172 11BC;D2B1;1110 1172 11BC; +D2B2;D2B2;1110 1172 11BD;D2B2;1110 1172 11BD; +D2B3;D2B3;1110 1172 11BE;D2B3;1110 1172 11BE; +D2B4;D2B4;1110 1172 11BF;D2B4;1110 1172 11BF; +D2B5;D2B5;1110 1172 11C0;D2B5;1110 1172 11C0; +D2B6;D2B6;1110 1172 11C1;D2B6;1110 1172 11C1; +D2B7;D2B7;1110 1172 11C2;D2B7;1110 1172 11C2; +D2B8;D2B8;1110 1173;D2B8;1110 1173; +D2B9;D2B9;1110 1173 11A8;D2B9;1110 1173 11A8; +D2BA;D2BA;1110 1173 11A9;D2BA;1110 1173 11A9; +D2BB;D2BB;1110 1173 11AA;D2BB;1110 1173 11AA; +D2BC;D2BC;1110 1173 11AB;D2BC;1110 1173 11AB; +D2BD;D2BD;1110 1173 11AC;D2BD;1110 1173 11AC; +D2BE;D2BE;1110 1173 11AD;D2BE;1110 1173 11AD; +D2BF;D2BF;1110 1173 11AE;D2BF;1110 1173 11AE; +D2C0;D2C0;1110 1173 11AF;D2C0;1110 1173 11AF; +D2C1;D2C1;1110 1173 11B0;D2C1;1110 1173 11B0; +D2C2;D2C2;1110 1173 11B1;D2C2;1110 1173 11B1; +D2C3;D2C3;1110 1173 11B2;D2C3;1110 1173 11B2; +D2C4;D2C4;1110 1173 11B3;D2C4;1110 1173 11B3; +D2C5;D2C5;1110 1173 11B4;D2C5;1110 1173 11B4; +D2C6;D2C6;1110 1173 11B5;D2C6;1110 1173 11B5; +D2C7;D2C7;1110 1173 11B6;D2C7;1110 1173 11B6; +D2C8;D2C8;1110 1173 11B7;D2C8;1110 1173 11B7; +D2C9;D2C9;1110 1173 11B8;D2C9;1110 1173 11B8; +D2CA;D2CA;1110 1173 11B9;D2CA;1110 1173 11B9; +D2CB;D2CB;1110 1173 11BA;D2CB;1110 1173 11BA; +D2CC;D2CC;1110 1173 11BB;D2CC;1110 1173 11BB; +D2CD;D2CD;1110 1173 11BC;D2CD;1110 1173 11BC; +D2CE;D2CE;1110 1173 11BD;D2CE;1110 1173 11BD; +D2CF;D2CF;1110 1173 11BE;D2CF;1110 1173 11BE; +D2D0;D2D0;1110 1173 11BF;D2D0;1110 1173 11BF; +D2D1;D2D1;1110 1173 11C0;D2D1;1110 1173 11C0; +D2D2;D2D2;1110 1173 11C1;D2D2;1110 1173 11C1; +D2D3;D2D3;1110 1173 11C2;D2D3;1110 1173 11C2; +D2D4;D2D4;1110 1174;D2D4;1110 1174; +D2D5;D2D5;1110 1174 11A8;D2D5;1110 1174 11A8; +D2D6;D2D6;1110 1174 11A9;D2D6;1110 1174 11A9; +D2D7;D2D7;1110 1174 11AA;D2D7;1110 1174 11AA; +D2D8;D2D8;1110 1174 11AB;D2D8;1110 1174 11AB; +D2D9;D2D9;1110 1174 11AC;D2D9;1110 1174 11AC; +D2DA;D2DA;1110 1174 11AD;D2DA;1110 1174 11AD; +D2DB;D2DB;1110 1174 11AE;D2DB;1110 1174 11AE; +D2DC;D2DC;1110 1174 11AF;D2DC;1110 1174 11AF; +D2DD;D2DD;1110 1174 11B0;D2DD;1110 1174 11B0; +D2DE;D2DE;1110 1174 11B1;D2DE;1110 1174 11B1; +D2DF;D2DF;1110 1174 11B2;D2DF;1110 1174 11B2; +D2E0;D2E0;1110 1174 11B3;D2E0;1110 1174 11B3; +D2E1;D2E1;1110 1174 11B4;D2E1;1110 1174 11B4; +D2E2;D2E2;1110 1174 11B5;D2E2;1110 1174 11B5; +D2E3;D2E3;1110 1174 11B6;D2E3;1110 1174 11B6; +D2E4;D2E4;1110 1174 11B7;D2E4;1110 1174 11B7; +D2E5;D2E5;1110 1174 11B8;D2E5;1110 1174 11B8; +D2E6;D2E6;1110 1174 11B9;D2E6;1110 1174 11B9; +D2E7;D2E7;1110 1174 11BA;D2E7;1110 1174 11BA; +D2E8;D2E8;1110 1174 11BB;D2E8;1110 1174 11BB; +D2E9;D2E9;1110 1174 11BC;D2E9;1110 1174 11BC; +D2EA;D2EA;1110 1174 11BD;D2EA;1110 1174 11BD; +D2EB;D2EB;1110 1174 11BE;D2EB;1110 1174 11BE; +D2EC;D2EC;1110 1174 11BF;D2EC;1110 1174 11BF; +D2ED;D2ED;1110 1174 11C0;D2ED;1110 1174 11C0; +D2EE;D2EE;1110 1174 11C1;D2EE;1110 1174 11C1; +D2EF;D2EF;1110 1174 11C2;D2EF;1110 1174 11C2; +D2F0;D2F0;1110 1175;D2F0;1110 1175; +D2F1;D2F1;1110 1175 11A8;D2F1;1110 1175 11A8; +D2F2;D2F2;1110 1175 11A9;D2F2;1110 1175 11A9; +D2F3;D2F3;1110 1175 11AA;D2F3;1110 1175 11AA; +D2F4;D2F4;1110 1175 11AB;D2F4;1110 1175 11AB; +D2F5;D2F5;1110 1175 11AC;D2F5;1110 1175 11AC; +D2F6;D2F6;1110 1175 11AD;D2F6;1110 1175 11AD; +D2F7;D2F7;1110 1175 11AE;D2F7;1110 1175 11AE; +D2F8;D2F8;1110 1175 11AF;D2F8;1110 1175 11AF; +D2F9;D2F9;1110 1175 11B0;D2F9;1110 1175 11B0; +D2FA;D2FA;1110 1175 11B1;D2FA;1110 1175 11B1; +D2FB;D2FB;1110 1175 11B2;D2FB;1110 1175 11B2; +D2FC;D2FC;1110 1175 11B3;D2FC;1110 1175 11B3; +D2FD;D2FD;1110 1175 11B4;D2FD;1110 1175 11B4; +D2FE;D2FE;1110 1175 11B5;D2FE;1110 1175 11B5; +D2FF;D2FF;1110 1175 11B6;D2FF;1110 1175 11B6; +D300;D300;1110 1175 11B7;D300;1110 1175 11B7; +D301;D301;1110 1175 11B8;D301;1110 1175 11B8; +D302;D302;1110 1175 11B9;D302;1110 1175 11B9; +D303;D303;1110 1175 11BA;D303;1110 1175 11BA; +D304;D304;1110 1175 11BB;D304;1110 1175 11BB; +D305;D305;1110 1175 11BC;D305;1110 1175 11BC; +D306;D306;1110 1175 11BD;D306;1110 1175 11BD; +D307;D307;1110 1175 11BE;D307;1110 1175 11BE; +D308;D308;1110 1175 11BF;D308;1110 1175 11BF; +D309;D309;1110 1175 11C0;D309;1110 1175 11C0; +D30A;D30A;1110 1175 11C1;D30A;1110 1175 11C1; +D30B;D30B;1110 1175 11C2;D30B;1110 1175 11C2; +D30C;D30C;1111 1161;D30C;1111 1161; +D30D;D30D;1111 1161 11A8;D30D;1111 1161 11A8; +D30E;D30E;1111 1161 11A9;D30E;1111 1161 11A9; +D30F;D30F;1111 1161 11AA;D30F;1111 1161 11AA; +D310;D310;1111 1161 11AB;D310;1111 1161 11AB; +D311;D311;1111 1161 11AC;D311;1111 1161 11AC; +D312;D312;1111 1161 11AD;D312;1111 1161 11AD; +D313;D313;1111 1161 11AE;D313;1111 1161 11AE; +D314;D314;1111 1161 11AF;D314;1111 1161 11AF; +D315;D315;1111 1161 11B0;D315;1111 1161 11B0; +D316;D316;1111 1161 11B1;D316;1111 1161 11B1; +D317;D317;1111 1161 11B2;D317;1111 1161 11B2; +D318;D318;1111 1161 11B3;D318;1111 1161 11B3; +D319;D319;1111 1161 11B4;D319;1111 1161 11B4; +D31A;D31A;1111 1161 11B5;D31A;1111 1161 11B5; +D31B;D31B;1111 1161 11B6;D31B;1111 1161 11B6; +D31C;D31C;1111 1161 11B7;D31C;1111 1161 11B7; +D31D;D31D;1111 1161 11B8;D31D;1111 1161 11B8; +D31E;D31E;1111 1161 11B9;D31E;1111 1161 11B9; +D31F;D31F;1111 1161 11BA;D31F;1111 1161 11BA; +D320;D320;1111 1161 11BB;D320;1111 1161 11BB; +D321;D321;1111 1161 11BC;D321;1111 1161 11BC; +D322;D322;1111 1161 11BD;D322;1111 1161 11BD; +D323;D323;1111 1161 11BE;D323;1111 1161 11BE; +D324;D324;1111 1161 11BF;D324;1111 1161 11BF; +D325;D325;1111 1161 11C0;D325;1111 1161 11C0; +D326;D326;1111 1161 11C1;D326;1111 1161 11C1; +D327;D327;1111 1161 11C2;D327;1111 1161 11C2; +D328;D328;1111 1162;D328;1111 1162; +D329;D329;1111 1162 11A8;D329;1111 1162 11A8; +D32A;D32A;1111 1162 11A9;D32A;1111 1162 11A9; +D32B;D32B;1111 1162 11AA;D32B;1111 1162 11AA; +D32C;D32C;1111 1162 11AB;D32C;1111 1162 11AB; +D32D;D32D;1111 1162 11AC;D32D;1111 1162 11AC; +D32E;D32E;1111 1162 11AD;D32E;1111 1162 11AD; +D32F;D32F;1111 1162 11AE;D32F;1111 1162 11AE; +D330;D330;1111 1162 11AF;D330;1111 1162 11AF; +D331;D331;1111 1162 11B0;D331;1111 1162 11B0; +D332;D332;1111 1162 11B1;D332;1111 1162 11B1; +D333;D333;1111 1162 11B2;D333;1111 1162 11B2; +D334;D334;1111 1162 11B3;D334;1111 1162 11B3; +D335;D335;1111 1162 11B4;D335;1111 1162 11B4; +D336;D336;1111 1162 11B5;D336;1111 1162 11B5; +D337;D337;1111 1162 11B6;D337;1111 1162 11B6; +D338;D338;1111 1162 11B7;D338;1111 1162 11B7; +D339;D339;1111 1162 11B8;D339;1111 1162 11B8; +D33A;D33A;1111 1162 11B9;D33A;1111 1162 11B9; +D33B;D33B;1111 1162 11BA;D33B;1111 1162 11BA; +D33C;D33C;1111 1162 11BB;D33C;1111 1162 11BB; +D33D;D33D;1111 1162 11BC;D33D;1111 1162 11BC; +D33E;D33E;1111 1162 11BD;D33E;1111 1162 11BD; +D33F;D33F;1111 1162 11BE;D33F;1111 1162 11BE; +D340;D340;1111 1162 11BF;D340;1111 1162 11BF; +D341;D341;1111 1162 11C0;D341;1111 1162 11C0; +D342;D342;1111 1162 11C1;D342;1111 1162 11C1; +D343;D343;1111 1162 11C2;D343;1111 1162 11C2; +D344;D344;1111 1163;D344;1111 1163; +D345;D345;1111 1163 11A8;D345;1111 1163 11A8; +D346;D346;1111 1163 11A9;D346;1111 1163 11A9; +D347;D347;1111 1163 11AA;D347;1111 1163 11AA; +D348;D348;1111 1163 11AB;D348;1111 1163 11AB; +D349;D349;1111 1163 11AC;D349;1111 1163 11AC; +D34A;D34A;1111 1163 11AD;D34A;1111 1163 11AD; +D34B;D34B;1111 1163 11AE;D34B;1111 1163 11AE; +D34C;D34C;1111 1163 11AF;D34C;1111 1163 11AF; +D34D;D34D;1111 1163 11B0;D34D;1111 1163 11B0; +D34E;D34E;1111 1163 11B1;D34E;1111 1163 11B1; +D34F;D34F;1111 1163 11B2;D34F;1111 1163 11B2; +D350;D350;1111 1163 11B3;D350;1111 1163 11B3; +D351;D351;1111 1163 11B4;D351;1111 1163 11B4; +D352;D352;1111 1163 11B5;D352;1111 1163 11B5; +D353;D353;1111 1163 11B6;D353;1111 1163 11B6; +D354;D354;1111 1163 11B7;D354;1111 1163 11B7; +D355;D355;1111 1163 11B8;D355;1111 1163 11B8; +D356;D356;1111 1163 11B9;D356;1111 1163 11B9; +D357;D357;1111 1163 11BA;D357;1111 1163 11BA; +D358;D358;1111 1163 11BB;D358;1111 1163 11BB; +D359;D359;1111 1163 11BC;D359;1111 1163 11BC; +D35A;D35A;1111 1163 11BD;D35A;1111 1163 11BD; +D35B;D35B;1111 1163 11BE;D35B;1111 1163 11BE; +D35C;D35C;1111 1163 11BF;D35C;1111 1163 11BF; +D35D;D35D;1111 1163 11C0;D35D;1111 1163 11C0; +D35E;D35E;1111 1163 11C1;D35E;1111 1163 11C1; +D35F;D35F;1111 1163 11C2;D35F;1111 1163 11C2; +D360;D360;1111 1164;D360;1111 1164; +D361;D361;1111 1164 11A8;D361;1111 1164 11A8; +D362;D362;1111 1164 11A9;D362;1111 1164 11A9; +D363;D363;1111 1164 11AA;D363;1111 1164 11AA; +D364;D364;1111 1164 11AB;D364;1111 1164 11AB; +D365;D365;1111 1164 11AC;D365;1111 1164 11AC; +D366;D366;1111 1164 11AD;D366;1111 1164 11AD; +D367;D367;1111 1164 11AE;D367;1111 1164 11AE; +D368;D368;1111 1164 11AF;D368;1111 1164 11AF; +D369;D369;1111 1164 11B0;D369;1111 1164 11B0; +D36A;D36A;1111 1164 11B1;D36A;1111 1164 11B1; +D36B;D36B;1111 1164 11B2;D36B;1111 1164 11B2; +D36C;D36C;1111 1164 11B3;D36C;1111 1164 11B3; +D36D;D36D;1111 1164 11B4;D36D;1111 1164 11B4; +D36E;D36E;1111 1164 11B5;D36E;1111 1164 11B5; +D36F;D36F;1111 1164 11B6;D36F;1111 1164 11B6; +D370;D370;1111 1164 11B7;D370;1111 1164 11B7; +D371;D371;1111 1164 11B8;D371;1111 1164 11B8; +D372;D372;1111 1164 11B9;D372;1111 1164 11B9; +D373;D373;1111 1164 11BA;D373;1111 1164 11BA; +D374;D374;1111 1164 11BB;D374;1111 1164 11BB; +D375;D375;1111 1164 11BC;D375;1111 1164 11BC; +D376;D376;1111 1164 11BD;D376;1111 1164 11BD; +D377;D377;1111 1164 11BE;D377;1111 1164 11BE; +D378;D378;1111 1164 11BF;D378;1111 1164 11BF; +D379;D379;1111 1164 11C0;D379;1111 1164 11C0; +D37A;D37A;1111 1164 11C1;D37A;1111 1164 11C1; +D37B;D37B;1111 1164 11C2;D37B;1111 1164 11C2; +D37C;D37C;1111 1165;D37C;1111 1165; +D37D;D37D;1111 1165 11A8;D37D;1111 1165 11A8; +D37E;D37E;1111 1165 11A9;D37E;1111 1165 11A9; +D37F;D37F;1111 1165 11AA;D37F;1111 1165 11AA; +D380;D380;1111 1165 11AB;D380;1111 1165 11AB; +D381;D381;1111 1165 11AC;D381;1111 1165 11AC; +D382;D382;1111 1165 11AD;D382;1111 1165 11AD; +D383;D383;1111 1165 11AE;D383;1111 1165 11AE; +D384;D384;1111 1165 11AF;D384;1111 1165 11AF; +D385;D385;1111 1165 11B0;D385;1111 1165 11B0; +D386;D386;1111 1165 11B1;D386;1111 1165 11B1; +D387;D387;1111 1165 11B2;D387;1111 1165 11B2; +D388;D388;1111 1165 11B3;D388;1111 1165 11B3; +D389;D389;1111 1165 11B4;D389;1111 1165 11B4; +D38A;D38A;1111 1165 11B5;D38A;1111 1165 11B5; +D38B;D38B;1111 1165 11B6;D38B;1111 1165 11B6; +D38C;D38C;1111 1165 11B7;D38C;1111 1165 11B7; +D38D;D38D;1111 1165 11B8;D38D;1111 1165 11B8; +D38E;D38E;1111 1165 11B9;D38E;1111 1165 11B9; +D38F;D38F;1111 1165 11BA;D38F;1111 1165 11BA; +D390;D390;1111 1165 11BB;D390;1111 1165 11BB; +D391;D391;1111 1165 11BC;D391;1111 1165 11BC; +D392;D392;1111 1165 11BD;D392;1111 1165 11BD; +D393;D393;1111 1165 11BE;D393;1111 1165 11BE; +D394;D394;1111 1165 11BF;D394;1111 1165 11BF; +D395;D395;1111 1165 11C0;D395;1111 1165 11C0; +D396;D396;1111 1165 11C1;D396;1111 1165 11C1; +D397;D397;1111 1165 11C2;D397;1111 1165 11C2; +D398;D398;1111 1166;D398;1111 1166; +D399;D399;1111 1166 11A8;D399;1111 1166 11A8; +D39A;D39A;1111 1166 11A9;D39A;1111 1166 11A9; +D39B;D39B;1111 1166 11AA;D39B;1111 1166 11AA; +D39C;D39C;1111 1166 11AB;D39C;1111 1166 11AB; +D39D;D39D;1111 1166 11AC;D39D;1111 1166 11AC; +D39E;D39E;1111 1166 11AD;D39E;1111 1166 11AD; +D39F;D39F;1111 1166 11AE;D39F;1111 1166 11AE; +D3A0;D3A0;1111 1166 11AF;D3A0;1111 1166 11AF; +D3A1;D3A1;1111 1166 11B0;D3A1;1111 1166 11B0; +D3A2;D3A2;1111 1166 11B1;D3A2;1111 1166 11B1; +D3A3;D3A3;1111 1166 11B2;D3A3;1111 1166 11B2; +D3A4;D3A4;1111 1166 11B3;D3A4;1111 1166 11B3; +D3A5;D3A5;1111 1166 11B4;D3A5;1111 1166 11B4; +D3A6;D3A6;1111 1166 11B5;D3A6;1111 1166 11B5; +D3A7;D3A7;1111 1166 11B6;D3A7;1111 1166 11B6; +D3A8;D3A8;1111 1166 11B7;D3A8;1111 1166 11B7; +D3A9;D3A9;1111 1166 11B8;D3A9;1111 1166 11B8; +D3AA;D3AA;1111 1166 11B9;D3AA;1111 1166 11B9; +D3AB;D3AB;1111 1166 11BA;D3AB;1111 1166 11BA; +D3AC;D3AC;1111 1166 11BB;D3AC;1111 1166 11BB; +D3AD;D3AD;1111 1166 11BC;D3AD;1111 1166 11BC; +D3AE;D3AE;1111 1166 11BD;D3AE;1111 1166 11BD; +D3AF;D3AF;1111 1166 11BE;D3AF;1111 1166 11BE; +D3B0;D3B0;1111 1166 11BF;D3B0;1111 1166 11BF; +D3B1;D3B1;1111 1166 11C0;D3B1;1111 1166 11C0; +D3B2;D3B2;1111 1166 11C1;D3B2;1111 1166 11C1; +D3B3;D3B3;1111 1166 11C2;D3B3;1111 1166 11C2; +D3B4;D3B4;1111 1167;D3B4;1111 1167; +D3B5;D3B5;1111 1167 11A8;D3B5;1111 1167 11A8; +D3B6;D3B6;1111 1167 11A9;D3B6;1111 1167 11A9; +D3B7;D3B7;1111 1167 11AA;D3B7;1111 1167 11AA; +D3B8;D3B8;1111 1167 11AB;D3B8;1111 1167 11AB; +D3B9;D3B9;1111 1167 11AC;D3B9;1111 1167 11AC; +D3BA;D3BA;1111 1167 11AD;D3BA;1111 1167 11AD; +D3BB;D3BB;1111 1167 11AE;D3BB;1111 1167 11AE; +D3BC;D3BC;1111 1167 11AF;D3BC;1111 1167 11AF; +D3BD;D3BD;1111 1167 11B0;D3BD;1111 1167 11B0; +D3BE;D3BE;1111 1167 11B1;D3BE;1111 1167 11B1; +D3BF;D3BF;1111 1167 11B2;D3BF;1111 1167 11B2; +D3C0;D3C0;1111 1167 11B3;D3C0;1111 1167 11B3; +D3C1;D3C1;1111 1167 11B4;D3C1;1111 1167 11B4; +D3C2;D3C2;1111 1167 11B5;D3C2;1111 1167 11B5; +D3C3;D3C3;1111 1167 11B6;D3C3;1111 1167 11B6; +D3C4;D3C4;1111 1167 11B7;D3C4;1111 1167 11B7; +D3C5;D3C5;1111 1167 11B8;D3C5;1111 1167 11B8; +D3C6;D3C6;1111 1167 11B9;D3C6;1111 1167 11B9; +D3C7;D3C7;1111 1167 11BA;D3C7;1111 1167 11BA; +D3C8;D3C8;1111 1167 11BB;D3C8;1111 1167 11BB; +D3C9;D3C9;1111 1167 11BC;D3C9;1111 1167 11BC; +D3CA;D3CA;1111 1167 11BD;D3CA;1111 1167 11BD; +D3CB;D3CB;1111 1167 11BE;D3CB;1111 1167 11BE; +D3CC;D3CC;1111 1167 11BF;D3CC;1111 1167 11BF; +D3CD;D3CD;1111 1167 11C0;D3CD;1111 1167 11C0; +D3CE;D3CE;1111 1167 11C1;D3CE;1111 1167 11C1; +D3CF;D3CF;1111 1167 11C2;D3CF;1111 1167 11C2; +D3D0;D3D0;1111 1168;D3D0;1111 1168; +D3D1;D3D1;1111 1168 11A8;D3D1;1111 1168 11A8; +D3D2;D3D2;1111 1168 11A9;D3D2;1111 1168 11A9; +D3D3;D3D3;1111 1168 11AA;D3D3;1111 1168 11AA; +D3D4;D3D4;1111 1168 11AB;D3D4;1111 1168 11AB; +D3D5;D3D5;1111 1168 11AC;D3D5;1111 1168 11AC; +D3D6;D3D6;1111 1168 11AD;D3D6;1111 1168 11AD; +D3D7;D3D7;1111 1168 11AE;D3D7;1111 1168 11AE; +D3D8;D3D8;1111 1168 11AF;D3D8;1111 1168 11AF; +D3D9;D3D9;1111 1168 11B0;D3D9;1111 1168 11B0; +D3DA;D3DA;1111 1168 11B1;D3DA;1111 1168 11B1; +D3DB;D3DB;1111 1168 11B2;D3DB;1111 1168 11B2; +D3DC;D3DC;1111 1168 11B3;D3DC;1111 1168 11B3; +D3DD;D3DD;1111 1168 11B4;D3DD;1111 1168 11B4; +D3DE;D3DE;1111 1168 11B5;D3DE;1111 1168 11B5; +D3DF;D3DF;1111 1168 11B6;D3DF;1111 1168 11B6; +D3E0;D3E0;1111 1168 11B7;D3E0;1111 1168 11B7; +D3E1;D3E1;1111 1168 11B8;D3E1;1111 1168 11B8; +D3E2;D3E2;1111 1168 11B9;D3E2;1111 1168 11B9; +D3E3;D3E3;1111 1168 11BA;D3E3;1111 1168 11BA; +D3E4;D3E4;1111 1168 11BB;D3E4;1111 1168 11BB; +D3E5;D3E5;1111 1168 11BC;D3E5;1111 1168 11BC; +D3E6;D3E6;1111 1168 11BD;D3E6;1111 1168 11BD; +D3E7;D3E7;1111 1168 11BE;D3E7;1111 1168 11BE; +D3E8;D3E8;1111 1168 11BF;D3E8;1111 1168 11BF; +D3E9;D3E9;1111 1168 11C0;D3E9;1111 1168 11C0; +D3EA;D3EA;1111 1168 11C1;D3EA;1111 1168 11C1; +D3EB;D3EB;1111 1168 11C2;D3EB;1111 1168 11C2; +D3EC;D3EC;1111 1169;D3EC;1111 1169; +D3ED;D3ED;1111 1169 11A8;D3ED;1111 1169 11A8; +D3EE;D3EE;1111 1169 11A9;D3EE;1111 1169 11A9; +D3EF;D3EF;1111 1169 11AA;D3EF;1111 1169 11AA; +D3F0;D3F0;1111 1169 11AB;D3F0;1111 1169 11AB; +D3F1;D3F1;1111 1169 11AC;D3F1;1111 1169 11AC; +D3F2;D3F2;1111 1169 11AD;D3F2;1111 1169 11AD; +D3F3;D3F3;1111 1169 11AE;D3F3;1111 1169 11AE; +D3F4;D3F4;1111 1169 11AF;D3F4;1111 1169 11AF; +D3F5;D3F5;1111 1169 11B0;D3F5;1111 1169 11B0; +D3F6;D3F6;1111 1169 11B1;D3F6;1111 1169 11B1; +D3F7;D3F7;1111 1169 11B2;D3F7;1111 1169 11B2; +D3F8;D3F8;1111 1169 11B3;D3F8;1111 1169 11B3; +D3F9;D3F9;1111 1169 11B4;D3F9;1111 1169 11B4; +D3FA;D3FA;1111 1169 11B5;D3FA;1111 1169 11B5; +D3FB;D3FB;1111 1169 11B6;D3FB;1111 1169 11B6; +D3FC;D3FC;1111 1169 11B7;D3FC;1111 1169 11B7; +D3FD;D3FD;1111 1169 11B8;D3FD;1111 1169 11B8; +D3FE;D3FE;1111 1169 11B9;D3FE;1111 1169 11B9; +D3FF;D3FF;1111 1169 11BA;D3FF;1111 1169 11BA; +D400;D400;1111 1169 11BB;D400;1111 1169 11BB; +D401;D401;1111 1169 11BC;D401;1111 1169 11BC; +D402;D402;1111 1169 11BD;D402;1111 1169 11BD; +D403;D403;1111 1169 11BE;D403;1111 1169 11BE; +D404;D404;1111 1169 11BF;D404;1111 1169 11BF; +D405;D405;1111 1169 11C0;D405;1111 1169 11C0; +D406;D406;1111 1169 11C1;D406;1111 1169 11C1; +D407;D407;1111 1169 11C2;D407;1111 1169 11C2; +D408;D408;1111 116A;D408;1111 116A; +D409;D409;1111 116A 11A8;D409;1111 116A 11A8; +D40A;D40A;1111 116A 11A9;D40A;1111 116A 11A9; +D40B;D40B;1111 116A 11AA;D40B;1111 116A 11AA; +D40C;D40C;1111 116A 11AB;D40C;1111 116A 11AB; +D40D;D40D;1111 116A 11AC;D40D;1111 116A 11AC; +D40E;D40E;1111 116A 11AD;D40E;1111 116A 11AD; +D40F;D40F;1111 116A 11AE;D40F;1111 116A 11AE; +D410;D410;1111 116A 11AF;D410;1111 116A 11AF; +D411;D411;1111 116A 11B0;D411;1111 116A 11B0; +D412;D412;1111 116A 11B1;D412;1111 116A 11B1; +D413;D413;1111 116A 11B2;D413;1111 116A 11B2; +D414;D414;1111 116A 11B3;D414;1111 116A 11B3; +D415;D415;1111 116A 11B4;D415;1111 116A 11B4; +D416;D416;1111 116A 11B5;D416;1111 116A 11B5; +D417;D417;1111 116A 11B6;D417;1111 116A 11B6; +D418;D418;1111 116A 11B7;D418;1111 116A 11B7; +D419;D419;1111 116A 11B8;D419;1111 116A 11B8; +D41A;D41A;1111 116A 11B9;D41A;1111 116A 11B9; +D41B;D41B;1111 116A 11BA;D41B;1111 116A 11BA; +D41C;D41C;1111 116A 11BB;D41C;1111 116A 11BB; +D41D;D41D;1111 116A 11BC;D41D;1111 116A 11BC; +D41E;D41E;1111 116A 11BD;D41E;1111 116A 11BD; +D41F;D41F;1111 116A 11BE;D41F;1111 116A 11BE; +D420;D420;1111 116A 11BF;D420;1111 116A 11BF; +D421;D421;1111 116A 11C0;D421;1111 116A 11C0; +D422;D422;1111 116A 11C1;D422;1111 116A 11C1; +D423;D423;1111 116A 11C2;D423;1111 116A 11C2; +D424;D424;1111 116B;D424;1111 116B; +D425;D425;1111 116B 11A8;D425;1111 116B 11A8; +D426;D426;1111 116B 11A9;D426;1111 116B 11A9; +D427;D427;1111 116B 11AA;D427;1111 116B 11AA; +D428;D428;1111 116B 11AB;D428;1111 116B 11AB; +D429;D429;1111 116B 11AC;D429;1111 116B 11AC; +D42A;D42A;1111 116B 11AD;D42A;1111 116B 11AD; +D42B;D42B;1111 116B 11AE;D42B;1111 116B 11AE; +D42C;D42C;1111 116B 11AF;D42C;1111 116B 11AF; +D42D;D42D;1111 116B 11B0;D42D;1111 116B 11B0; +D42E;D42E;1111 116B 11B1;D42E;1111 116B 11B1; +D42F;D42F;1111 116B 11B2;D42F;1111 116B 11B2; +D430;D430;1111 116B 11B3;D430;1111 116B 11B3; +D431;D431;1111 116B 11B4;D431;1111 116B 11B4; +D432;D432;1111 116B 11B5;D432;1111 116B 11B5; +D433;D433;1111 116B 11B6;D433;1111 116B 11B6; +D434;D434;1111 116B 11B7;D434;1111 116B 11B7; +D435;D435;1111 116B 11B8;D435;1111 116B 11B8; +D436;D436;1111 116B 11B9;D436;1111 116B 11B9; +D437;D437;1111 116B 11BA;D437;1111 116B 11BA; +D438;D438;1111 116B 11BB;D438;1111 116B 11BB; +D439;D439;1111 116B 11BC;D439;1111 116B 11BC; +D43A;D43A;1111 116B 11BD;D43A;1111 116B 11BD; +D43B;D43B;1111 116B 11BE;D43B;1111 116B 11BE; +D43C;D43C;1111 116B 11BF;D43C;1111 116B 11BF; +D43D;D43D;1111 116B 11C0;D43D;1111 116B 11C0; +D43E;D43E;1111 116B 11C1;D43E;1111 116B 11C1; +D43F;D43F;1111 116B 11C2;D43F;1111 116B 11C2; +D440;D440;1111 116C;D440;1111 116C; +D441;D441;1111 116C 11A8;D441;1111 116C 11A8; +D442;D442;1111 116C 11A9;D442;1111 116C 11A9; +D443;D443;1111 116C 11AA;D443;1111 116C 11AA; +D444;D444;1111 116C 11AB;D444;1111 116C 11AB; +D445;D445;1111 116C 11AC;D445;1111 116C 11AC; +D446;D446;1111 116C 11AD;D446;1111 116C 11AD; +D447;D447;1111 116C 11AE;D447;1111 116C 11AE; +D448;D448;1111 116C 11AF;D448;1111 116C 11AF; +D449;D449;1111 116C 11B0;D449;1111 116C 11B0; +D44A;D44A;1111 116C 11B1;D44A;1111 116C 11B1; +D44B;D44B;1111 116C 11B2;D44B;1111 116C 11B2; +D44C;D44C;1111 116C 11B3;D44C;1111 116C 11B3; +D44D;D44D;1111 116C 11B4;D44D;1111 116C 11B4; +D44E;D44E;1111 116C 11B5;D44E;1111 116C 11B5; +D44F;D44F;1111 116C 11B6;D44F;1111 116C 11B6; +D450;D450;1111 116C 11B7;D450;1111 116C 11B7; +D451;D451;1111 116C 11B8;D451;1111 116C 11B8; +D452;D452;1111 116C 11B9;D452;1111 116C 11B9; +D453;D453;1111 116C 11BA;D453;1111 116C 11BA; +D454;D454;1111 116C 11BB;D454;1111 116C 11BB; +D455;D455;1111 116C 11BC;D455;1111 116C 11BC; +D456;D456;1111 116C 11BD;D456;1111 116C 11BD; +D457;D457;1111 116C 11BE;D457;1111 116C 11BE; +D458;D458;1111 116C 11BF;D458;1111 116C 11BF; +D459;D459;1111 116C 11C0;D459;1111 116C 11C0; +D45A;D45A;1111 116C 11C1;D45A;1111 116C 11C1; +D45B;D45B;1111 116C 11C2;D45B;1111 116C 11C2; +D45C;D45C;1111 116D;D45C;1111 116D; +D45D;D45D;1111 116D 11A8;D45D;1111 116D 11A8; +D45E;D45E;1111 116D 11A9;D45E;1111 116D 11A9; +D45F;D45F;1111 116D 11AA;D45F;1111 116D 11AA; +D460;D460;1111 116D 11AB;D460;1111 116D 11AB; +D461;D461;1111 116D 11AC;D461;1111 116D 11AC; +D462;D462;1111 116D 11AD;D462;1111 116D 11AD; +D463;D463;1111 116D 11AE;D463;1111 116D 11AE; +D464;D464;1111 116D 11AF;D464;1111 116D 11AF; +D465;D465;1111 116D 11B0;D465;1111 116D 11B0; +D466;D466;1111 116D 11B1;D466;1111 116D 11B1; +D467;D467;1111 116D 11B2;D467;1111 116D 11B2; +D468;D468;1111 116D 11B3;D468;1111 116D 11B3; +D469;D469;1111 116D 11B4;D469;1111 116D 11B4; +D46A;D46A;1111 116D 11B5;D46A;1111 116D 11B5; +D46B;D46B;1111 116D 11B6;D46B;1111 116D 11B6; +D46C;D46C;1111 116D 11B7;D46C;1111 116D 11B7; +D46D;D46D;1111 116D 11B8;D46D;1111 116D 11B8; +D46E;D46E;1111 116D 11B9;D46E;1111 116D 11B9; +D46F;D46F;1111 116D 11BA;D46F;1111 116D 11BA; +D470;D470;1111 116D 11BB;D470;1111 116D 11BB; +D471;D471;1111 116D 11BC;D471;1111 116D 11BC; +D472;D472;1111 116D 11BD;D472;1111 116D 11BD; +D473;D473;1111 116D 11BE;D473;1111 116D 11BE; +D474;D474;1111 116D 11BF;D474;1111 116D 11BF; +D475;D475;1111 116D 11C0;D475;1111 116D 11C0; +D476;D476;1111 116D 11C1;D476;1111 116D 11C1; +D477;D477;1111 116D 11C2;D477;1111 116D 11C2; +D478;D478;1111 116E;D478;1111 116E; +D479;D479;1111 116E 11A8;D479;1111 116E 11A8; +D47A;D47A;1111 116E 11A9;D47A;1111 116E 11A9; +D47B;D47B;1111 116E 11AA;D47B;1111 116E 11AA; +D47C;D47C;1111 116E 11AB;D47C;1111 116E 11AB; +D47D;D47D;1111 116E 11AC;D47D;1111 116E 11AC; +D47E;D47E;1111 116E 11AD;D47E;1111 116E 11AD; +D47F;D47F;1111 116E 11AE;D47F;1111 116E 11AE; +D480;D480;1111 116E 11AF;D480;1111 116E 11AF; +D481;D481;1111 116E 11B0;D481;1111 116E 11B0; +D482;D482;1111 116E 11B1;D482;1111 116E 11B1; +D483;D483;1111 116E 11B2;D483;1111 116E 11B2; +D484;D484;1111 116E 11B3;D484;1111 116E 11B3; +D485;D485;1111 116E 11B4;D485;1111 116E 11B4; +D486;D486;1111 116E 11B5;D486;1111 116E 11B5; +D487;D487;1111 116E 11B6;D487;1111 116E 11B6; +D488;D488;1111 116E 11B7;D488;1111 116E 11B7; +D489;D489;1111 116E 11B8;D489;1111 116E 11B8; +D48A;D48A;1111 116E 11B9;D48A;1111 116E 11B9; +D48B;D48B;1111 116E 11BA;D48B;1111 116E 11BA; +D48C;D48C;1111 116E 11BB;D48C;1111 116E 11BB; +D48D;D48D;1111 116E 11BC;D48D;1111 116E 11BC; +D48E;D48E;1111 116E 11BD;D48E;1111 116E 11BD; +D48F;D48F;1111 116E 11BE;D48F;1111 116E 11BE; +D490;D490;1111 116E 11BF;D490;1111 116E 11BF; +D491;D491;1111 116E 11C0;D491;1111 116E 11C0; +D492;D492;1111 116E 11C1;D492;1111 116E 11C1; +D493;D493;1111 116E 11C2;D493;1111 116E 11C2; +D494;D494;1111 116F;D494;1111 116F; +D495;D495;1111 116F 11A8;D495;1111 116F 11A8; +D496;D496;1111 116F 11A9;D496;1111 116F 11A9; +D497;D497;1111 116F 11AA;D497;1111 116F 11AA; +D498;D498;1111 116F 11AB;D498;1111 116F 11AB; +D499;D499;1111 116F 11AC;D499;1111 116F 11AC; +D49A;D49A;1111 116F 11AD;D49A;1111 116F 11AD; +D49B;D49B;1111 116F 11AE;D49B;1111 116F 11AE; +D49C;D49C;1111 116F 11AF;D49C;1111 116F 11AF; +D49D;D49D;1111 116F 11B0;D49D;1111 116F 11B0; +D49E;D49E;1111 116F 11B1;D49E;1111 116F 11B1; +D49F;D49F;1111 116F 11B2;D49F;1111 116F 11B2; +D4A0;D4A0;1111 116F 11B3;D4A0;1111 116F 11B3; +D4A1;D4A1;1111 116F 11B4;D4A1;1111 116F 11B4; +D4A2;D4A2;1111 116F 11B5;D4A2;1111 116F 11B5; +D4A3;D4A3;1111 116F 11B6;D4A3;1111 116F 11B6; +D4A4;D4A4;1111 116F 11B7;D4A4;1111 116F 11B7; +D4A5;D4A5;1111 116F 11B8;D4A5;1111 116F 11B8; +D4A6;D4A6;1111 116F 11B9;D4A6;1111 116F 11B9; +D4A7;D4A7;1111 116F 11BA;D4A7;1111 116F 11BA; +D4A8;D4A8;1111 116F 11BB;D4A8;1111 116F 11BB; +D4A9;D4A9;1111 116F 11BC;D4A9;1111 116F 11BC; +D4AA;D4AA;1111 116F 11BD;D4AA;1111 116F 11BD; +D4AB;D4AB;1111 116F 11BE;D4AB;1111 116F 11BE; +D4AC;D4AC;1111 116F 11BF;D4AC;1111 116F 11BF; +D4AD;D4AD;1111 116F 11C0;D4AD;1111 116F 11C0; +D4AE;D4AE;1111 116F 11C1;D4AE;1111 116F 11C1; +D4AF;D4AF;1111 116F 11C2;D4AF;1111 116F 11C2; +D4B0;D4B0;1111 1170;D4B0;1111 1170; +D4B1;D4B1;1111 1170 11A8;D4B1;1111 1170 11A8; +D4B2;D4B2;1111 1170 11A9;D4B2;1111 1170 11A9; +D4B3;D4B3;1111 1170 11AA;D4B3;1111 1170 11AA; +D4B4;D4B4;1111 1170 11AB;D4B4;1111 1170 11AB; +D4B5;D4B5;1111 1170 11AC;D4B5;1111 1170 11AC; +D4B6;D4B6;1111 1170 11AD;D4B6;1111 1170 11AD; +D4B7;D4B7;1111 1170 11AE;D4B7;1111 1170 11AE; +D4B8;D4B8;1111 1170 11AF;D4B8;1111 1170 11AF; +D4B9;D4B9;1111 1170 11B0;D4B9;1111 1170 11B0; +D4BA;D4BA;1111 1170 11B1;D4BA;1111 1170 11B1; +D4BB;D4BB;1111 1170 11B2;D4BB;1111 1170 11B2; +D4BC;D4BC;1111 1170 11B3;D4BC;1111 1170 11B3; +D4BD;D4BD;1111 1170 11B4;D4BD;1111 1170 11B4; +D4BE;D4BE;1111 1170 11B5;D4BE;1111 1170 11B5; +D4BF;D4BF;1111 1170 11B6;D4BF;1111 1170 11B6; +D4C0;D4C0;1111 1170 11B7;D4C0;1111 1170 11B7; +D4C1;D4C1;1111 1170 11B8;D4C1;1111 1170 11B8; +D4C2;D4C2;1111 1170 11B9;D4C2;1111 1170 11B9; +D4C3;D4C3;1111 1170 11BA;D4C3;1111 1170 11BA; +D4C4;D4C4;1111 1170 11BB;D4C4;1111 1170 11BB; +D4C5;D4C5;1111 1170 11BC;D4C5;1111 1170 11BC; +D4C6;D4C6;1111 1170 11BD;D4C6;1111 1170 11BD; +D4C7;D4C7;1111 1170 11BE;D4C7;1111 1170 11BE; +D4C8;D4C8;1111 1170 11BF;D4C8;1111 1170 11BF; +D4C9;D4C9;1111 1170 11C0;D4C9;1111 1170 11C0; +D4CA;D4CA;1111 1170 11C1;D4CA;1111 1170 11C1; +D4CB;D4CB;1111 1170 11C2;D4CB;1111 1170 11C2; +D4CC;D4CC;1111 1171;D4CC;1111 1171; +D4CD;D4CD;1111 1171 11A8;D4CD;1111 1171 11A8; +D4CE;D4CE;1111 1171 11A9;D4CE;1111 1171 11A9; +D4CF;D4CF;1111 1171 11AA;D4CF;1111 1171 11AA; +D4D0;D4D0;1111 1171 11AB;D4D0;1111 1171 11AB; +D4D1;D4D1;1111 1171 11AC;D4D1;1111 1171 11AC; +D4D2;D4D2;1111 1171 11AD;D4D2;1111 1171 11AD; +D4D3;D4D3;1111 1171 11AE;D4D3;1111 1171 11AE; +D4D4;D4D4;1111 1171 11AF;D4D4;1111 1171 11AF; +D4D5;D4D5;1111 1171 11B0;D4D5;1111 1171 11B0; +D4D6;D4D6;1111 1171 11B1;D4D6;1111 1171 11B1; +D4D7;D4D7;1111 1171 11B2;D4D7;1111 1171 11B2; +D4D8;D4D8;1111 1171 11B3;D4D8;1111 1171 11B3; +D4D9;D4D9;1111 1171 11B4;D4D9;1111 1171 11B4; +D4DA;D4DA;1111 1171 11B5;D4DA;1111 1171 11B5; +D4DB;D4DB;1111 1171 11B6;D4DB;1111 1171 11B6; +D4DC;D4DC;1111 1171 11B7;D4DC;1111 1171 11B7; +D4DD;D4DD;1111 1171 11B8;D4DD;1111 1171 11B8; +D4DE;D4DE;1111 1171 11B9;D4DE;1111 1171 11B9; +D4DF;D4DF;1111 1171 11BA;D4DF;1111 1171 11BA; +D4E0;D4E0;1111 1171 11BB;D4E0;1111 1171 11BB; +D4E1;D4E1;1111 1171 11BC;D4E1;1111 1171 11BC; +D4E2;D4E2;1111 1171 11BD;D4E2;1111 1171 11BD; +D4E3;D4E3;1111 1171 11BE;D4E3;1111 1171 11BE; +D4E4;D4E4;1111 1171 11BF;D4E4;1111 1171 11BF; +D4E5;D4E5;1111 1171 11C0;D4E5;1111 1171 11C0; +D4E6;D4E6;1111 1171 11C1;D4E6;1111 1171 11C1; +D4E7;D4E7;1111 1171 11C2;D4E7;1111 1171 11C2; +D4E8;D4E8;1111 1172;D4E8;1111 1172; +D4E9;D4E9;1111 1172 11A8;D4E9;1111 1172 11A8; +D4EA;D4EA;1111 1172 11A9;D4EA;1111 1172 11A9; +D4EB;D4EB;1111 1172 11AA;D4EB;1111 1172 11AA; +D4EC;D4EC;1111 1172 11AB;D4EC;1111 1172 11AB; +D4ED;D4ED;1111 1172 11AC;D4ED;1111 1172 11AC; +D4EE;D4EE;1111 1172 11AD;D4EE;1111 1172 11AD; +D4EF;D4EF;1111 1172 11AE;D4EF;1111 1172 11AE; +D4F0;D4F0;1111 1172 11AF;D4F0;1111 1172 11AF; +D4F1;D4F1;1111 1172 11B0;D4F1;1111 1172 11B0; +D4F2;D4F2;1111 1172 11B1;D4F2;1111 1172 11B1; +D4F3;D4F3;1111 1172 11B2;D4F3;1111 1172 11B2; +D4F4;D4F4;1111 1172 11B3;D4F4;1111 1172 11B3; +D4F5;D4F5;1111 1172 11B4;D4F5;1111 1172 11B4; +D4F6;D4F6;1111 1172 11B5;D4F6;1111 1172 11B5; +D4F7;D4F7;1111 1172 11B6;D4F7;1111 1172 11B6; +D4F8;D4F8;1111 1172 11B7;D4F8;1111 1172 11B7; +D4F9;D4F9;1111 1172 11B8;D4F9;1111 1172 11B8; +D4FA;D4FA;1111 1172 11B9;D4FA;1111 1172 11B9; +D4FB;D4FB;1111 1172 11BA;D4FB;1111 1172 11BA; +D4FC;D4FC;1111 1172 11BB;D4FC;1111 1172 11BB; +D4FD;D4FD;1111 1172 11BC;D4FD;1111 1172 11BC; +D4FE;D4FE;1111 1172 11BD;D4FE;1111 1172 11BD; +D4FF;D4FF;1111 1172 11BE;D4FF;1111 1172 11BE; +D500;D500;1111 1172 11BF;D500;1111 1172 11BF; +D501;D501;1111 1172 11C0;D501;1111 1172 11C0; +D502;D502;1111 1172 11C1;D502;1111 1172 11C1; +D503;D503;1111 1172 11C2;D503;1111 1172 11C2; +D504;D504;1111 1173;D504;1111 1173; +D505;D505;1111 1173 11A8;D505;1111 1173 11A8; +D506;D506;1111 1173 11A9;D506;1111 1173 11A9; +D507;D507;1111 1173 11AA;D507;1111 1173 11AA; +D508;D508;1111 1173 11AB;D508;1111 1173 11AB; +D509;D509;1111 1173 11AC;D509;1111 1173 11AC; +D50A;D50A;1111 1173 11AD;D50A;1111 1173 11AD; +D50B;D50B;1111 1173 11AE;D50B;1111 1173 11AE; +D50C;D50C;1111 1173 11AF;D50C;1111 1173 11AF; +D50D;D50D;1111 1173 11B0;D50D;1111 1173 11B0; +D50E;D50E;1111 1173 11B1;D50E;1111 1173 11B1; +D50F;D50F;1111 1173 11B2;D50F;1111 1173 11B2; +D510;D510;1111 1173 11B3;D510;1111 1173 11B3; +D511;D511;1111 1173 11B4;D511;1111 1173 11B4; +D512;D512;1111 1173 11B5;D512;1111 1173 11B5; +D513;D513;1111 1173 11B6;D513;1111 1173 11B6; +D514;D514;1111 1173 11B7;D514;1111 1173 11B7; +D515;D515;1111 1173 11B8;D515;1111 1173 11B8; +D516;D516;1111 1173 11B9;D516;1111 1173 11B9; +D517;D517;1111 1173 11BA;D517;1111 1173 11BA; +D518;D518;1111 1173 11BB;D518;1111 1173 11BB; +D519;D519;1111 1173 11BC;D519;1111 1173 11BC; +D51A;D51A;1111 1173 11BD;D51A;1111 1173 11BD; +D51B;D51B;1111 1173 11BE;D51B;1111 1173 11BE; +D51C;D51C;1111 1173 11BF;D51C;1111 1173 11BF; +D51D;D51D;1111 1173 11C0;D51D;1111 1173 11C0; +D51E;D51E;1111 1173 11C1;D51E;1111 1173 11C1; +D51F;D51F;1111 1173 11C2;D51F;1111 1173 11C2; +D520;D520;1111 1174;D520;1111 1174; +D521;D521;1111 1174 11A8;D521;1111 1174 11A8; +D522;D522;1111 1174 11A9;D522;1111 1174 11A9; +D523;D523;1111 1174 11AA;D523;1111 1174 11AA; +D524;D524;1111 1174 11AB;D524;1111 1174 11AB; +D525;D525;1111 1174 11AC;D525;1111 1174 11AC; +D526;D526;1111 1174 11AD;D526;1111 1174 11AD; +D527;D527;1111 1174 11AE;D527;1111 1174 11AE; +D528;D528;1111 1174 11AF;D528;1111 1174 11AF; +D529;D529;1111 1174 11B0;D529;1111 1174 11B0; +D52A;D52A;1111 1174 11B1;D52A;1111 1174 11B1; +D52B;D52B;1111 1174 11B2;D52B;1111 1174 11B2; +D52C;D52C;1111 1174 11B3;D52C;1111 1174 11B3; +D52D;D52D;1111 1174 11B4;D52D;1111 1174 11B4; +D52E;D52E;1111 1174 11B5;D52E;1111 1174 11B5; +D52F;D52F;1111 1174 11B6;D52F;1111 1174 11B6; +D530;D530;1111 1174 11B7;D530;1111 1174 11B7; +D531;D531;1111 1174 11B8;D531;1111 1174 11B8; +D532;D532;1111 1174 11B9;D532;1111 1174 11B9; +D533;D533;1111 1174 11BA;D533;1111 1174 11BA; +D534;D534;1111 1174 11BB;D534;1111 1174 11BB; +D535;D535;1111 1174 11BC;D535;1111 1174 11BC; +D536;D536;1111 1174 11BD;D536;1111 1174 11BD; +D537;D537;1111 1174 11BE;D537;1111 1174 11BE; +D538;D538;1111 1174 11BF;D538;1111 1174 11BF; +D539;D539;1111 1174 11C0;D539;1111 1174 11C0; +D53A;D53A;1111 1174 11C1;D53A;1111 1174 11C1; +D53B;D53B;1111 1174 11C2;D53B;1111 1174 11C2; +D53C;D53C;1111 1175;D53C;1111 1175; +D53D;D53D;1111 1175 11A8;D53D;1111 1175 11A8; +D53E;D53E;1111 1175 11A9;D53E;1111 1175 11A9; +D53F;D53F;1111 1175 11AA;D53F;1111 1175 11AA; +D540;D540;1111 1175 11AB;D540;1111 1175 11AB; +D541;D541;1111 1175 11AC;D541;1111 1175 11AC; +D542;D542;1111 1175 11AD;D542;1111 1175 11AD; +D543;D543;1111 1175 11AE;D543;1111 1175 11AE; +D544;D544;1111 1175 11AF;D544;1111 1175 11AF; +D545;D545;1111 1175 11B0;D545;1111 1175 11B0; +D546;D546;1111 1175 11B1;D546;1111 1175 11B1; +D547;D547;1111 1175 11B2;D547;1111 1175 11B2; +D548;D548;1111 1175 11B3;D548;1111 1175 11B3; +D549;D549;1111 1175 11B4;D549;1111 1175 11B4; +D54A;D54A;1111 1175 11B5;D54A;1111 1175 11B5; +D54B;D54B;1111 1175 11B6;D54B;1111 1175 11B6; +D54C;D54C;1111 1175 11B7;D54C;1111 1175 11B7; +D54D;D54D;1111 1175 11B8;D54D;1111 1175 11B8; +D54E;D54E;1111 1175 11B9;D54E;1111 1175 11B9; +D54F;D54F;1111 1175 11BA;D54F;1111 1175 11BA; +D550;D550;1111 1175 11BB;D550;1111 1175 11BB; +D551;D551;1111 1175 11BC;D551;1111 1175 11BC; +D552;D552;1111 1175 11BD;D552;1111 1175 11BD; +D553;D553;1111 1175 11BE;D553;1111 1175 11BE; +D554;D554;1111 1175 11BF;D554;1111 1175 11BF; +D555;D555;1111 1175 11C0;D555;1111 1175 11C0; +D556;D556;1111 1175 11C1;D556;1111 1175 11C1; +D557;D557;1111 1175 11C2;D557;1111 1175 11C2; +D558;D558;1112 1161;D558;1112 1161; +D559;D559;1112 1161 11A8;D559;1112 1161 11A8; +D55A;D55A;1112 1161 11A9;D55A;1112 1161 11A9; +D55B;D55B;1112 1161 11AA;D55B;1112 1161 11AA; +D55C;D55C;1112 1161 11AB;D55C;1112 1161 11AB; +D55D;D55D;1112 1161 11AC;D55D;1112 1161 11AC; +D55E;D55E;1112 1161 11AD;D55E;1112 1161 11AD; +D55F;D55F;1112 1161 11AE;D55F;1112 1161 11AE; +D560;D560;1112 1161 11AF;D560;1112 1161 11AF; +D561;D561;1112 1161 11B0;D561;1112 1161 11B0; +D562;D562;1112 1161 11B1;D562;1112 1161 11B1; +D563;D563;1112 1161 11B2;D563;1112 1161 11B2; +D564;D564;1112 1161 11B3;D564;1112 1161 11B3; +D565;D565;1112 1161 11B4;D565;1112 1161 11B4; +D566;D566;1112 1161 11B5;D566;1112 1161 11B5; +D567;D567;1112 1161 11B6;D567;1112 1161 11B6; +D568;D568;1112 1161 11B7;D568;1112 1161 11B7; +D569;D569;1112 1161 11B8;D569;1112 1161 11B8; +D56A;D56A;1112 1161 11B9;D56A;1112 1161 11B9; +D56B;D56B;1112 1161 11BA;D56B;1112 1161 11BA; +D56C;D56C;1112 1161 11BB;D56C;1112 1161 11BB; +D56D;D56D;1112 1161 11BC;D56D;1112 1161 11BC; +D56E;D56E;1112 1161 11BD;D56E;1112 1161 11BD; +D56F;D56F;1112 1161 11BE;D56F;1112 1161 11BE; +D570;D570;1112 1161 11BF;D570;1112 1161 11BF; +D571;D571;1112 1161 11C0;D571;1112 1161 11C0; +D572;D572;1112 1161 11C1;D572;1112 1161 11C1; +D573;D573;1112 1161 11C2;D573;1112 1161 11C2; +D574;D574;1112 1162;D574;1112 1162; +D575;D575;1112 1162 11A8;D575;1112 1162 11A8; +D576;D576;1112 1162 11A9;D576;1112 1162 11A9; +D577;D577;1112 1162 11AA;D577;1112 1162 11AA; +D578;D578;1112 1162 11AB;D578;1112 1162 11AB; +D579;D579;1112 1162 11AC;D579;1112 1162 11AC; +D57A;D57A;1112 1162 11AD;D57A;1112 1162 11AD; +D57B;D57B;1112 1162 11AE;D57B;1112 1162 11AE; +D57C;D57C;1112 1162 11AF;D57C;1112 1162 11AF; +D57D;D57D;1112 1162 11B0;D57D;1112 1162 11B0; +D57E;D57E;1112 1162 11B1;D57E;1112 1162 11B1; +D57F;D57F;1112 1162 11B2;D57F;1112 1162 11B2; +D580;D580;1112 1162 11B3;D580;1112 1162 11B3; +D581;D581;1112 1162 11B4;D581;1112 1162 11B4; +D582;D582;1112 1162 11B5;D582;1112 1162 11B5; +D583;D583;1112 1162 11B6;D583;1112 1162 11B6; +D584;D584;1112 1162 11B7;D584;1112 1162 11B7; +D585;D585;1112 1162 11B8;D585;1112 1162 11B8; +D586;D586;1112 1162 11B9;D586;1112 1162 11B9; +D587;D587;1112 1162 11BA;D587;1112 1162 11BA; +D588;D588;1112 1162 11BB;D588;1112 1162 11BB; +D589;D589;1112 1162 11BC;D589;1112 1162 11BC; +D58A;D58A;1112 1162 11BD;D58A;1112 1162 11BD; +D58B;D58B;1112 1162 11BE;D58B;1112 1162 11BE; +D58C;D58C;1112 1162 11BF;D58C;1112 1162 11BF; +D58D;D58D;1112 1162 11C0;D58D;1112 1162 11C0; +D58E;D58E;1112 1162 11C1;D58E;1112 1162 11C1; +D58F;D58F;1112 1162 11C2;D58F;1112 1162 11C2; +D590;D590;1112 1163;D590;1112 1163; +D591;D591;1112 1163 11A8;D591;1112 1163 11A8; +D592;D592;1112 1163 11A9;D592;1112 1163 11A9; +D593;D593;1112 1163 11AA;D593;1112 1163 11AA; +D594;D594;1112 1163 11AB;D594;1112 1163 11AB; +D595;D595;1112 1163 11AC;D595;1112 1163 11AC; +D596;D596;1112 1163 11AD;D596;1112 1163 11AD; +D597;D597;1112 1163 11AE;D597;1112 1163 11AE; +D598;D598;1112 1163 11AF;D598;1112 1163 11AF; +D599;D599;1112 1163 11B0;D599;1112 1163 11B0; +D59A;D59A;1112 1163 11B1;D59A;1112 1163 11B1; +D59B;D59B;1112 1163 11B2;D59B;1112 1163 11B2; +D59C;D59C;1112 1163 11B3;D59C;1112 1163 11B3; +D59D;D59D;1112 1163 11B4;D59D;1112 1163 11B4; +D59E;D59E;1112 1163 11B5;D59E;1112 1163 11B5; +D59F;D59F;1112 1163 11B6;D59F;1112 1163 11B6; +D5A0;D5A0;1112 1163 11B7;D5A0;1112 1163 11B7; +D5A1;D5A1;1112 1163 11B8;D5A1;1112 1163 11B8; +D5A2;D5A2;1112 1163 11B9;D5A2;1112 1163 11B9; +D5A3;D5A3;1112 1163 11BA;D5A3;1112 1163 11BA; +D5A4;D5A4;1112 1163 11BB;D5A4;1112 1163 11BB; +D5A5;D5A5;1112 1163 11BC;D5A5;1112 1163 11BC; +D5A6;D5A6;1112 1163 11BD;D5A6;1112 1163 11BD; +D5A7;D5A7;1112 1163 11BE;D5A7;1112 1163 11BE; +D5A8;D5A8;1112 1163 11BF;D5A8;1112 1163 11BF; +D5A9;D5A9;1112 1163 11C0;D5A9;1112 1163 11C0; +D5AA;D5AA;1112 1163 11C1;D5AA;1112 1163 11C1; +D5AB;D5AB;1112 1163 11C2;D5AB;1112 1163 11C2; +D5AC;D5AC;1112 1164;D5AC;1112 1164; +D5AD;D5AD;1112 1164 11A8;D5AD;1112 1164 11A8; +D5AE;D5AE;1112 1164 11A9;D5AE;1112 1164 11A9; +D5AF;D5AF;1112 1164 11AA;D5AF;1112 1164 11AA; +D5B0;D5B0;1112 1164 11AB;D5B0;1112 1164 11AB; +D5B1;D5B1;1112 1164 11AC;D5B1;1112 1164 11AC; +D5B2;D5B2;1112 1164 11AD;D5B2;1112 1164 11AD; +D5B3;D5B3;1112 1164 11AE;D5B3;1112 1164 11AE; +D5B4;D5B4;1112 1164 11AF;D5B4;1112 1164 11AF; +D5B5;D5B5;1112 1164 11B0;D5B5;1112 1164 11B0; +D5B6;D5B6;1112 1164 11B1;D5B6;1112 1164 11B1; +D5B7;D5B7;1112 1164 11B2;D5B7;1112 1164 11B2; +D5B8;D5B8;1112 1164 11B3;D5B8;1112 1164 11B3; +D5B9;D5B9;1112 1164 11B4;D5B9;1112 1164 11B4; +D5BA;D5BA;1112 1164 11B5;D5BA;1112 1164 11B5; +D5BB;D5BB;1112 1164 11B6;D5BB;1112 1164 11B6; +D5BC;D5BC;1112 1164 11B7;D5BC;1112 1164 11B7; +D5BD;D5BD;1112 1164 11B8;D5BD;1112 1164 11B8; +D5BE;D5BE;1112 1164 11B9;D5BE;1112 1164 11B9; +D5BF;D5BF;1112 1164 11BA;D5BF;1112 1164 11BA; +D5C0;D5C0;1112 1164 11BB;D5C0;1112 1164 11BB; +D5C1;D5C1;1112 1164 11BC;D5C1;1112 1164 11BC; +D5C2;D5C2;1112 1164 11BD;D5C2;1112 1164 11BD; +D5C3;D5C3;1112 1164 11BE;D5C3;1112 1164 11BE; +D5C4;D5C4;1112 1164 11BF;D5C4;1112 1164 11BF; +D5C5;D5C5;1112 1164 11C0;D5C5;1112 1164 11C0; +D5C6;D5C6;1112 1164 11C1;D5C6;1112 1164 11C1; +D5C7;D5C7;1112 1164 11C2;D5C7;1112 1164 11C2; +D5C8;D5C8;1112 1165;D5C8;1112 1165; +D5C9;D5C9;1112 1165 11A8;D5C9;1112 1165 11A8; +D5CA;D5CA;1112 1165 11A9;D5CA;1112 1165 11A9; +D5CB;D5CB;1112 1165 11AA;D5CB;1112 1165 11AA; +D5CC;D5CC;1112 1165 11AB;D5CC;1112 1165 11AB; +D5CD;D5CD;1112 1165 11AC;D5CD;1112 1165 11AC; +D5CE;D5CE;1112 1165 11AD;D5CE;1112 1165 11AD; +D5CF;D5CF;1112 1165 11AE;D5CF;1112 1165 11AE; +D5D0;D5D0;1112 1165 11AF;D5D0;1112 1165 11AF; +D5D1;D5D1;1112 1165 11B0;D5D1;1112 1165 11B0; +D5D2;D5D2;1112 1165 11B1;D5D2;1112 1165 11B1; +D5D3;D5D3;1112 1165 11B2;D5D3;1112 1165 11B2; +D5D4;D5D4;1112 1165 11B3;D5D4;1112 1165 11B3; +D5D5;D5D5;1112 1165 11B4;D5D5;1112 1165 11B4; +D5D6;D5D6;1112 1165 11B5;D5D6;1112 1165 11B5; +D5D7;D5D7;1112 1165 11B6;D5D7;1112 1165 11B6; +D5D8;D5D8;1112 1165 11B7;D5D8;1112 1165 11B7; +D5D9;D5D9;1112 1165 11B8;D5D9;1112 1165 11B8; +D5DA;D5DA;1112 1165 11B9;D5DA;1112 1165 11B9; +D5DB;D5DB;1112 1165 11BA;D5DB;1112 1165 11BA; +D5DC;D5DC;1112 1165 11BB;D5DC;1112 1165 11BB; +D5DD;D5DD;1112 1165 11BC;D5DD;1112 1165 11BC; +D5DE;D5DE;1112 1165 11BD;D5DE;1112 1165 11BD; +D5DF;D5DF;1112 1165 11BE;D5DF;1112 1165 11BE; +D5E0;D5E0;1112 1165 11BF;D5E0;1112 1165 11BF; +D5E1;D5E1;1112 1165 11C0;D5E1;1112 1165 11C0; +D5E2;D5E2;1112 1165 11C1;D5E2;1112 1165 11C1; +D5E3;D5E3;1112 1165 11C2;D5E3;1112 1165 11C2; +D5E4;D5E4;1112 1166;D5E4;1112 1166; +D5E5;D5E5;1112 1166 11A8;D5E5;1112 1166 11A8; +D5E6;D5E6;1112 1166 11A9;D5E6;1112 1166 11A9; +D5E7;D5E7;1112 1166 11AA;D5E7;1112 1166 11AA; +D5E8;D5E8;1112 1166 11AB;D5E8;1112 1166 11AB; +D5E9;D5E9;1112 1166 11AC;D5E9;1112 1166 11AC; +D5EA;D5EA;1112 1166 11AD;D5EA;1112 1166 11AD; +D5EB;D5EB;1112 1166 11AE;D5EB;1112 1166 11AE; +D5EC;D5EC;1112 1166 11AF;D5EC;1112 1166 11AF; +D5ED;D5ED;1112 1166 11B0;D5ED;1112 1166 11B0; +D5EE;D5EE;1112 1166 11B1;D5EE;1112 1166 11B1; +D5EF;D5EF;1112 1166 11B2;D5EF;1112 1166 11B2; +D5F0;D5F0;1112 1166 11B3;D5F0;1112 1166 11B3; +D5F1;D5F1;1112 1166 11B4;D5F1;1112 1166 11B4; +D5F2;D5F2;1112 1166 11B5;D5F2;1112 1166 11B5; +D5F3;D5F3;1112 1166 11B6;D5F3;1112 1166 11B6; +D5F4;D5F4;1112 1166 11B7;D5F4;1112 1166 11B7; +D5F5;D5F5;1112 1166 11B8;D5F5;1112 1166 11B8; +D5F6;D5F6;1112 1166 11B9;D5F6;1112 1166 11B9; +D5F7;D5F7;1112 1166 11BA;D5F7;1112 1166 11BA; +D5F8;D5F8;1112 1166 11BB;D5F8;1112 1166 11BB; +D5F9;D5F9;1112 1166 11BC;D5F9;1112 1166 11BC; +D5FA;D5FA;1112 1166 11BD;D5FA;1112 1166 11BD; +D5FB;D5FB;1112 1166 11BE;D5FB;1112 1166 11BE; +D5FC;D5FC;1112 1166 11BF;D5FC;1112 1166 11BF; +D5FD;D5FD;1112 1166 11C0;D5FD;1112 1166 11C0; +D5FE;D5FE;1112 1166 11C1;D5FE;1112 1166 11C1; +D5FF;D5FF;1112 1166 11C2;D5FF;1112 1166 11C2; +D600;D600;1112 1167;D600;1112 1167; +D601;D601;1112 1167 11A8;D601;1112 1167 11A8; +D602;D602;1112 1167 11A9;D602;1112 1167 11A9; +D603;D603;1112 1167 11AA;D603;1112 1167 11AA; +D604;D604;1112 1167 11AB;D604;1112 1167 11AB; +D605;D605;1112 1167 11AC;D605;1112 1167 11AC; +D606;D606;1112 1167 11AD;D606;1112 1167 11AD; +D607;D607;1112 1167 11AE;D607;1112 1167 11AE; +D608;D608;1112 1167 11AF;D608;1112 1167 11AF; +D609;D609;1112 1167 11B0;D609;1112 1167 11B0; +D60A;D60A;1112 1167 11B1;D60A;1112 1167 11B1; +D60B;D60B;1112 1167 11B2;D60B;1112 1167 11B2; +D60C;D60C;1112 1167 11B3;D60C;1112 1167 11B3; +D60D;D60D;1112 1167 11B4;D60D;1112 1167 11B4; +D60E;D60E;1112 1167 11B5;D60E;1112 1167 11B5; +D60F;D60F;1112 1167 11B6;D60F;1112 1167 11B6; +D610;D610;1112 1167 11B7;D610;1112 1167 11B7; +D611;D611;1112 1167 11B8;D611;1112 1167 11B8; +D612;D612;1112 1167 11B9;D612;1112 1167 11B9; +D613;D613;1112 1167 11BA;D613;1112 1167 11BA; +D614;D614;1112 1167 11BB;D614;1112 1167 11BB; +D615;D615;1112 1167 11BC;D615;1112 1167 11BC; +D616;D616;1112 1167 11BD;D616;1112 1167 11BD; +D617;D617;1112 1167 11BE;D617;1112 1167 11BE; +D618;D618;1112 1167 11BF;D618;1112 1167 11BF; +D619;D619;1112 1167 11C0;D619;1112 1167 11C0; +D61A;D61A;1112 1167 11C1;D61A;1112 1167 11C1; +D61B;D61B;1112 1167 11C2;D61B;1112 1167 11C2; +D61C;D61C;1112 1168;D61C;1112 1168; +D61D;D61D;1112 1168 11A8;D61D;1112 1168 11A8; +D61E;D61E;1112 1168 11A9;D61E;1112 1168 11A9; +D61F;D61F;1112 1168 11AA;D61F;1112 1168 11AA; +D620;D620;1112 1168 11AB;D620;1112 1168 11AB; +D621;D621;1112 1168 11AC;D621;1112 1168 11AC; +D622;D622;1112 1168 11AD;D622;1112 1168 11AD; +D623;D623;1112 1168 11AE;D623;1112 1168 11AE; +D624;D624;1112 1168 11AF;D624;1112 1168 11AF; +D625;D625;1112 1168 11B0;D625;1112 1168 11B0; +D626;D626;1112 1168 11B1;D626;1112 1168 11B1; +D627;D627;1112 1168 11B2;D627;1112 1168 11B2; +D628;D628;1112 1168 11B3;D628;1112 1168 11B3; +D629;D629;1112 1168 11B4;D629;1112 1168 11B4; +D62A;D62A;1112 1168 11B5;D62A;1112 1168 11B5; +D62B;D62B;1112 1168 11B6;D62B;1112 1168 11B6; +D62C;D62C;1112 1168 11B7;D62C;1112 1168 11B7; +D62D;D62D;1112 1168 11B8;D62D;1112 1168 11B8; +D62E;D62E;1112 1168 11B9;D62E;1112 1168 11B9; +D62F;D62F;1112 1168 11BA;D62F;1112 1168 11BA; +D630;D630;1112 1168 11BB;D630;1112 1168 11BB; +D631;D631;1112 1168 11BC;D631;1112 1168 11BC; +D632;D632;1112 1168 11BD;D632;1112 1168 11BD; +D633;D633;1112 1168 11BE;D633;1112 1168 11BE; +D634;D634;1112 1168 11BF;D634;1112 1168 11BF; +D635;D635;1112 1168 11C0;D635;1112 1168 11C0; +D636;D636;1112 1168 11C1;D636;1112 1168 11C1; +D637;D637;1112 1168 11C2;D637;1112 1168 11C2; +D638;D638;1112 1169;D638;1112 1169; +D639;D639;1112 1169 11A8;D639;1112 1169 11A8; +D63A;D63A;1112 1169 11A9;D63A;1112 1169 11A9; +D63B;D63B;1112 1169 11AA;D63B;1112 1169 11AA; +D63C;D63C;1112 1169 11AB;D63C;1112 1169 11AB; +D63D;D63D;1112 1169 11AC;D63D;1112 1169 11AC; +D63E;D63E;1112 1169 11AD;D63E;1112 1169 11AD; +D63F;D63F;1112 1169 11AE;D63F;1112 1169 11AE; +D640;D640;1112 1169 11AF;D640;1112 1169 11AF; +D641;D641;1112 1169 11B0;D641;1112 1169 11B0; +D642;D642;1112 1169 11B1;D642;1112 1169 11B1; +D643;D643;1112 1169 11B2;D643;1112 1169 11B2; +D644;D644;1112 1169 11B3;D644;1112 1169 11B3; +D645;D645;1112 1169 11B4;D645;1112 1169 11B4; +D646;D646;1112 1169 11B5;D646;1112 1169 11B5; +D647;D647;1112 1169 11B6;D647;1112 1169 11B6; +D648;D648;1112 1169 11B7;D648;1112 1169 11B7; +D649;D649;1112 1169 11B8;D649;1112 1169 11B8; +D64A;D64A;1112 1169 11B9;D64A;1112 1169 11B9; +D64B;D64B;1112 1169 11BA;D64B;1112 1169 11BA; +D64C;D64C;1112 1169 11BB;D64C;1112 1169 11BB; +D64D;D64D;1112 1169 11BC;D64D;1112 1169 11BC; +D64E;D64E;1112 1169 11BD;D64E;1112 1169 11BD; +D64F;D64F;1112 1169 11BE;D64F;1112 1169 11BE; +D650;D650;1112 1169 11BF;D650;1112 1169 11BF; +D651;D651;1112 1169 11C0;D651;1112 1169 11C0; +D652;D652;1112 1169 11C1;D652;1112 1169 11C1; +D653;D653;1112 1169 11C2;D653;1112 1169 11C2; +D654;D654;1112 116A;D654;1112 116A; +D655;D655;1112 116A 11A8;D655;1112 116A 11A8; +D656;D656;1112 116A 11A9;D656;1112 116A 11A9; +D657;D657;1112 116A 11AA;D657;1112 116A 11AA; +D658;D658;1112 116A 11AB;D658;1112 116A 11AB; +D659;D659;1112 116A 11AC;D659;1112 116A 11AC; +D65A;D65A;1112 116A 11AD;D65A;1112 116A 11AD; +D65B;D65B;1112 116A 11AE;D65B;1112 116A 11AE; +D65C;D65C;1112 116A 11AF;D65C;1112 116A 11AF; +D65D;D65D;1112 116A 11B0;D65D;1112 116A 11B0; +D65E;D65E;1112 116A 11B1;D65E;1112 116A 11B1; +D65F;D65F;1112 116A 11B2;D65F;1112 116A 11B2; +D660;D660;1112 116A 11B3;D660;1112 116A 11B3; +D661;D661;1112 116A 11B4;D661;1112 116A 11B4; +D662;D662;1112 116A 11B5;D662;1112 116A 11B5; +D663;D663;1112 116A 11B6;D663;1112 116A 11B6; +D664;D664;1112 116A 11B7;D664;1112 116A 11B7; +D665;D665;1112 116A 11B8;D665;1112 116A 11B8; +D666;D666;1112 116A 11B9;D666;1112 116A 11B9; +D667;D667;1112 116A 11BA;D667;1112 116A 11BA; +D668;D668;1112 116A 11BB;D668;1112 116A 11BB; +D669;D669;1112 116A 11BC;D669;1112 116A 11BC; +D66A;D66A;1112 116A 11BD;D66A;1112 116A 11BD; +D66B;D66B;1112 116A 11BE;D66B;1112 116A 11BE; +D66C;D66C;1112 116A 11BF;D66C;1112 116A 11BF; +D66D;D66D;1112 116A 11C0;D66D;1112 116A 11C0; +D66E;D66E;1112 116A 11C1;D66E;1112 116A 11C1; +D66F;D66F;1112 116A 11C2;D66F;1112 116A 11C2; +D670;D670;1112 116B;D670;1112 116B; +D671;D671;1112 116B 11A8;D671;1112 116B 11A8; +D672;D672;1112 116B 11A9;D672;1112 116B 11A9; +D673;D673;1112 116B 11AA;D673;1112 116B 11AA; +D674;D674;1112 116B 11AB;D674;1112 116B 11AB; +D675;D675;1112 116B 11AC;D675;1112 116B 11AC; +D676;D676;1112 116B 11AD;D676;1112 116B 11AD; +D677;D677;1112 116B 11AE;D677;1112 116B 11AE; +D678;D678;1112 116B 11AF;D678;1112 116B 11AF; +D679;D679;1112 116B 11B0;D679;1112 116B 11B0; +D67A;D67A;1112 116B 11B1;D67A;1112 116B 11B1; +D67B;D67B;1112 116B 11B2;D67B;1112 116B 11B2; +D67C;D67C;1112 116B 11B3;D67C;1112 116B 11B3; +D67D;D67D;1112 116B 11B4;D67D;1112 116B 11B4; +D67E;D67E;1112 116B 11B5;D67E;1112 116B 11B5; +D67F;D67F;1112 116B 11B6;D67F;1112 116B 11B6; +D680;D680;1112 116B 11B7;D680;1112 116B 11B7; +D681;D681;1112 116B 11B8;D681;1112 116B 11B8; +D682;D682;1112 116B 11B9;D682;1112 116B 11B9; +D683;D683;1112 116B 11BA;D683;1112 116B 11BA; +D684;D684;1112 116B 11BB;D684;1112 116B 11BB; +D685;D685;1112 116B 11BC;D685;1112 116B 11BC; +D686;D686;1112 116B 11BD;D686;1112 116B 11BD; +D687;D687;1112 116B 11BE;D687;1112 116B 11BE; +D688;D688;1112 116B 11BF;D688;1112 116B 11BF; +D689;D689;1112 116B 11C0;D689;1112 116B 11C0; +D68A;D68A;1112 116B 11C1;D68A;1112 116B 11C1; +D68B;D68B;1112 116B 11C2;D68B;1112 116B 11C2; +D68C;D68C;1112 116C;D68C;1112 116C; +D68D;D68D;1112 116C 11A8;D68D;1112 116C 11A8; +D68E;D68E;1112 116C 11A9;D68E;1112 116C 11A9; +D68F;D68F;1112 116C 11AA;D68F;1112 116C 11AA; +D690;D690;1112 116C 11AB;D690;1112 116C 11AB; +D691;D691;1112 116C 11AC;D691;1112 116C 11AC; +D692;D692;1112 116C 11AD;D692;1112 116C 11AD; +D693;D693;1112 116C 11AE;D693;1112 116C 11AE; +D694;D694;1112 116C 11AF;D694;1112 116C 11AF; +D695;D695;1112 116C 11B0;D695;1112 116C 11B0; +D696;D696;1112 116C 11B1;D696;1112 116C 11B1; +D697;D697;1112 116C 11B2;D697;1112 116C 11B2; +D698;D698;1112 116C 11B3;D698;1112 116C 11B3; +D699;D699;1112 116C 11B4;D699;1112 116C 11B4; +D69A;D69A;1112 116C 11B5;D69A;1112 116C 11B5; +D69B;D69B;1112 116C 11B6;D69B;1112 116C 11B6; +D69C;D69C;1112 116C 11B7;D69C;1112 116C 11B7; +D69D;D69D;1112 116C 11B8;D69D;1112 116C 11B8; +D69E;D69E;1112 116C 11B9;D69E;1112 116C 11B9; +D69F;D69F;1112 116C 11BA;D69F;1112 116C 11BA; +D6A0;D6A0;1112 116C 11BB;D6A0;1112 116C 11BB; +D6A1;D6A1;1112 116C 11BC;D6A1;1112 116C 11BC; +D6A2;D6A2;1112 116C 11BD;D6A2;1112 116C 11BD; +D6A3;D6A3;1112 116C 11BE;D6A3;1112 116C 11BE; +D6A4;D6A4;1112 116C 11BF;D6A4;1112 116C 11BF; +D6A5;D6A5;1112 116C 11C0;D6A5;1112 116C 11C0; +D6A6;D6A6;1112 116C 11C1;D6A6;1112 116C 11C1; +D6A7;D6A7;1112 116C 11C2;D6A7;1112 116C 11C2; +D6A8;D6A8;1112 116D;D6A8;1112 116D; +D6A9;D6A9;1112 116D 11A8;D6A9;1112 116D 11A8; +D6AA;D6AA;1112 116D 11A9;D6AA;1112 116D 11A9; +D6AB;D6AB;1112 116D 11AA;D6AB;1112 116D 11AA; +D6AC;D6AC;1112 116D 11AB;D6AC;1112 116D 11AB; +D6AD;D6AD;1112 116D 11AC;D6AD;1112 116D 11AC; +D6AE;D6AE;1112 116D 11AD;D6AE;1112 116D 11AD; +D6AF;D6AF;1112 116D 11AE;D6AF;1112 116D 11AE; +D6B0;D6B0;1112 116D 11AF;D6B0;1112 116D 11AF; +D6B1;D6B1;1112 116D 11B0;D6B1;1112 116D 11B0; +D6B2;D6B2;1112 116D 11B1;D6B2;1112 116D 11B1; +D6B3;D6B3;1112 116D 11B2;D6B3;1112 116D 11B2; +D6B4;D6B4;1112 116D 11B3;D6B4;1112 116D 11B3; +D6B5;D6B5;1112 116D 11B4;D6B5;1112 116D 11B4; +D6B6;D6B6;1112 116D 11B5;D6B6;1112 116D 11B5; +D6B7;D6B7;1112 116D 11B6;D6B7;1112 116D 11B6; +D6B8;D6B8;1112 116D 11B7;D6B8;1112 116D 11B7; +D6B9;D6B9;1112 116D 11B8;D6B9;1112 116D 11B8; +D6BA;D6BA;1112 116D 11B9;D6BA;1112 116D 11B9; +D6BB;D6BB;1112 116D 11BA;D6BB;1112 116D 11BA; +D6BC;D6BC;1112 116D 11BB;D6BC;1112 116D 11BB; +D6BD;D6BD;1112 116D 11BC;D6BD;1112 116D 11BC; +D6BE;D6BE;1112 116D 11BD;D6BE;1112 116D 11BD; +D6BF;D6BF;1112 116D 11BE;D6BF;1112 116D 11BE; +D6C0;D6C0;1112 116D 11BF;D6C0;1112 116D 11BF; +D6C1;D6C1;1112 116D 11C0;D6C1;1112 116D 11C0; +D6C2;D6C2;1112 116D 11C1;D6C2;1112 116D 11C1; +D6C3;D6C3;1112 116D 11C2;D6C3;1112 116D 11C2; +D6C4;D6C4;1112 116E;D6C4;1112 116E; +D6C5;D6C5;1112 116E 11A8;D6C5;1112 116E 11A8; +D6C6;D6C6;1112 116E 11A9;D6C6;1112 116E 11A9; +D6C7;D6C7;1112 116E 11AA;D6C7;1112 116E 11AA; +D6C8;D6C8;1112 116E 11AB;D6C8;1112 116E 11AB; +D6C9;D6C9;1112 116E 11AC;D6C9;1112 116E 11AC; +D6CA;D6CA;1112 116E 11AD;D6CA;1112 116E 11AD; +D6CB;D6CB;1112 116E 11AE;D6CB;1112 116E 11AE; +D6CC;D6CC;1112 116E 11AF;D6CC;1112 116E 11AF; +D6CD;D6CD;1112 116E 11B0;D6CD;1112 116E 11B0; +D6CE;D6CE;1112 116E 11B1;D6CE;1112 116E 11B1; +D6CF;D6CF;1112 116E 11B2;D6CF;1112 116E 11B2; +D6D0;D6D0;1112 116E 11B3;D6D0;1112 116E 11B3; +D6D1;D6D1;1112 116E 11B4;D6D1;1112 116E 11B4; +D6D2;D6D2;1112 116E 11B5;D6D2;1112 116E 11B5; +D6D3;D6D3;1112 116E 11B6;D6D3;1112 116E 11B6; +D6D4;D6D4;1112 116E 11B7;D6D4;1112 116E 11B7; +D6D5;D6D5;1112 116E 11B8;D6D5;1112 116E 11B8; +D6D6;D6D6;1112 116E 11B9;D6D6;1112 116E 11B9; +D6D7;D6D7;1112 116E 11BA;D6D7;1112 116E 11BA; +D6D8;D6D8;1112 116E 11BB;D6D8;1112 116E 11BB; +D6D9;D6D9;1112 116E 11BC;D6D9;1112 116E 11BC; +D6DA;D6DA;1112 116E 11BD;D6DA;1112 116E 11BD; +D6DB;D6DB;1112 116E 11BE;D6DB;1112 116E 11BE; +D6DC;D6DC;1112 116E 11BF;D6DC;1112 116E 11BF; +D6DD;D6DD;1112 116E 11C0;D6DD;1112 116E 11C0; +D6DE;D6DE;1112 116E 11C1;D6DE;1112 116E 11C1; +D6DF;D6DF;1112 116E 11C2;D6DF;1112 116E 11C2; +D6E0;D6E0;1112 116F;D6E0;1112 116F; +D6E1;D6E1;1112 116F 11A8;D6E1;1112 116F 11A8; +D6E2;D6E2;1112 116F 11A9;D6E2;1112 116F 11A9; +D6E3;D6E3;1112 116F 11AA;D6E3;1112 116F 11AA; +D6E4;D6E4;1112 116F 11AB;D6E4;1112 116F 11AB; +D6E5;D6E5;1112 116F 11AC;D6E5;1112 116F 11AC; +D6E6;D6E6;1112 116F 11AD;D6E6;1112 116F 11AD; +D6E7;D6E7;1112 116F 11AE;D6E7;1112 116F 11AE; +D6E8;D6E8;1112 116F 11AF;D6E8;1112 116F 11AF; +D6E9;D6E9;1112 116F 11B0;D6E9;1112 116F 11B0; +D6EA;D6EA;1112 116F 11B1;D6EA;1112 116F 11B1; +D6EB;D6EB;1112 116F 11B2;D6EB;1112 116F 11B2; +D6EC;D6EC;1112 116F 11B3;D6EC;1112 116F 11B3; +D6ED;D6ED;1112 116F 11B4;D6ED;1112 116F 11B4; +D6EE;D6EE;1112 116F 11B5;D6EE;1112 116F 11B5; +D6EF;D6EF;1112 116F 11B6;D6EF;1112 116F 11B6; +D6F0;D6F0;1112 116F 11B7;D6F0;1112 116F 11B7; +D6F1;D6F1;1112 116F 11B8;D6F1;1112 116F 11B8; +D6F2;D6F2;1112 116F 11B9;D6F2;1112 116F 11B9; +D6F3;D6F3;1112 116F 11BA;D6F3;1112 116F 11BA; +D6F4;D6F4;1112 116F 11BB;D6F4;1112 116F 11BB; +D6F5;D6F5;1112 116F 11BC;D6F5;1112 116F 11BC; +D6F6;D6F6;1112 116F 11BD;D6F6;1112 116F 11BD; +D6F7;D6F7;1112 116F 11BE;D6F7;1112 116F 11BE; +D6F8;D6F8;1112 116F 11BF;D6F8;1112 116F 11BF; +D6F9;D6F9;1112 116F 11C0;D6F9;1112 116F 11C0; +D6FA;D6FA;1112 116F 11C1;D6FA;1112 116F 11C1; +D6FB;D6FB;1112 116F 11C2;D6FB;1112 116F 11C2; +D6FC;D6FC;1112 1170;D6FC;1112 1170; +D6FD;D6FD;1112 1170 11A8;D6FD;1112 1170 11A8; +D6FE;D6FE;1112 1170 11A9;D6FE;1112 1170 11A9; +D6FF;D6FF;1112 1170 11AA;D6FF;1112 1170 11AA; +D700;D700;1112 1170 11AB;D700;1112 1170 11AB; +D701;D701;1112 1170 11AC;D701;1112 1170 11AC; +D702;D702;1112 1170 11AD;D702;1112 1170 11AD; +D703;D703;1112 1170 11AE;D703;1112 1170 11AE; +D704;D704;1112 1170 11AF;D704;1112 1170 11AF; +D705;D705;1112 1170 11B0;D705;1112 1170 11B0; +D706;D706;1112 1170 11B1;D706;1112 1170 11B1; +D707;D707;1112 1170 11B2;D707;1112 1170 11B2; +D708;D708;1112 1170 11B3;D708;1112 1170 11B3; +D709;D709;1112 1170 11B4;D709;1112 1170 11B4; +D70A;D70A;1112 1170 11B5;D70A;1112 1170 11B5; +D70B;D70B;1112 1170 11B6;D70B;1112 1170 11B6; +D70C;D70C;1112 1170 11B7;D70C;1112 1170 11B7; +D70D;D70D;1112 1170 11B8;D70D;1112 1170 11B8; +D70E;D70E;1112 1170 11B9;D70E;1112 1170 11B9; +D70F;D70F;1112 1170 11BA;D70F;1112 1170 11BA; +D710;D710;1112 1170 11BB;D710;1112 1170 11BB; +D711;D711;1112 1170 11BC;D711;1112 1170 11BC; +D712;D712;1112 1170 11BD;D712;1112 1170 11BD; +D713;D713;1112 1170 11BE;D713;1112 1170 11BE; +D714;D714;1112 1170 11BF;D714;1112 1170 11BF; +D715;D715;1112 1170 11C0;D715;1112 1170 11C0; +D716;D716;1112 1170 11C1;D716;1112 1170 11C1; +D717;D717;1112 1170 11C2;D717;1112 1170 11C2; +D718;D718;1112 1171;D718;1112 1171; +D719;D719;1112 1171 11A8;D719;1112 1171 11A8; +D71A;D71A;1112 1171 11A9;D71A;1112 1171 11A9; +D71B;D71B;1112 1171 11AA;D71B;1112 1171 11AA; +D71C;D71C;1112 1171 11AB;D71C;1112 1171 11AB; +D71D;D71D;1112 1171 11AC;D71D;1112 1171 11AC; +D71E;D71E;1112 1171 11AD;D71E;1112 1171 11AD; +D71F;D71F;1112 1171 11AE;D71F;1112 1171 11AE; +D720;D720;1112 1171 11AF;D720;1112 1171 11AF; +D721;D721;1112 1171 11B0;D721;1112 1171 11B0; +D722;D722;1112 1171 11B1;D722;1112 1171 11B1; +D723;D723;1112 1171 11B2;D723;1112 1171 11B2; +D724;D724;1112 1171 11B3;D724;1112 1171 11B3; +D725;D725;1112 1171 11B4;D725;1112 1171 11B4; +D726;D726;1112 1171 11B5;D726;1112 1171 11B5; +D727;D727;1112 1171 11B6;D727;1112 1171 11B6; +D728;D728;1112 1171 11B7;D728;1112 1171 11B7; +D729;D729;1112 1171 11B8;D729;1112 1171 11B8; +D72A;D72A;1112 1171 11B9;D72A;1112 1171 11B9; +D72B;D72B;1112 1171 11BA;D72B;1112 1171 11BA; +D72C;D72C;1112 1171 11BB;D72C;1112 1171 11BB; +D72D;D72D;1112 1171 11BC;D72D;1112 1171 11BC; +D72E;D72E;1112 1171 11BD;D72E;1112 1171 11BD; +D72F;D72F;1112 1171 11BE;D72F;1112 1171 11BE; +D730;D730;1112 1171 11BF;D730;1112 1171 11BF; +D731;D731;1112 1171 11C0;D731;1112 1171 11C0; +D732;D732;1112 1171 11C1;D732;1112 1171 11C1; +D733;D733;1112 1171 11C2;D733;1112 1171 11C2; +D734;D734;1112 1172;D734;1112 1172; +D735;D735;1112 1172 11A8;D735;1112 1172 11A8; +D736;D736;1112 1172 11A9;D736;1112 1172 11A9; +D737;D737;1112 1172 11AA;D737;1112 1172 11AA; +D738;D738;1112 1172 11AB;D738;1112 1172 11AB; +D739;D739;1112 1172 11AC;D739;1112 1172 11AC; +D73A;D73A;1112 1172 11AD;D73A;1112 1172 11AD; +D73B;D73B;1112 1172 11AE;D73B;1112 1172 11AE; +D73C;D73C;1112 1172 11AF;D73C;1112 1172 11AF; +D73D;D73D;1112 1172 11B0;D73D;1112 1172 11B0; +D73E;D73E;1112 1172 11B1;D73E;1112 1172 11B1; +D73F;D73F;1112 1172 11B2;D73F;1112 1172 11B2; +D740;D740;1112 1172 11B3;D740;1112 1172 11B3; +D741;D741;1112 1172 11B4;D741;1112 1172 11B4; +D742;D742;1112 1172 11B5;D742;1112 1172 11B5; +D743;D743;1112 1172 11B6;D743;1112 1172 11B6; +D744;D744;1112 1172 11B7;D744;1112 1172 11B7; +D745;D745;1112 1172 11B8;D745;1112 1172 11B8; +D746;D746;1112 1172 11B9;D746;1112 1172 11B9; +D747;D747;1112 1172 11BA;D747;1112 1172 11BA; +D748;D748;1112 1172 11BB;D748;1112 1172 11BB; +D749;D749;1112 1172 11BC;D749;1112 1172 11BC; +D74A;D74A;1112 1172 11BD;D74A;1112 1172 11BD; +D74B;D74B;1112 1172 11BE;D74B;1112 1172 11BE; +D74C;D74C;1112 1172 11BF;D74C;1112 1172 11BF; +D74D;D74D;1112 1172 11C0;D74D;1112 1172 11C0; +D74E;D74E;1112 1172 11C1;D74E;1112 1172 11C1; +D74F;D74F;1112 1172 11C2;D74F;1112 1172 11C2; +D750;D750;1112 1173;D750;1112 1173; +D751;D751;1112 1173 11A8;D751;1112 1173 11A8; +D752;D752;1112 1173 11A9;D752;1112 1173 11A9; +D753;D753;1112 1173 11AA;D753;1112 1173 11AA; +D754;D754;1112 1173 11AB;D754;1112 1173 11AB; +D755;D755;1112 1173 11AC;D755;1112 1173 11AC; +D756;D756;1112 1173 11AD;D756;1112 1173 11AD; +D757;D757;1112 1173 11AE;D757;1112 1173 11AE; +D758;D758;1112 1173 11AF;D758;1112 1173 11AF; +D759;D759;1112 1173 11B0;D759;1112 1173 11B0; +D75A;D75A;1112 1173 11B1;D75A;1112 1173 11B1; +D75B;D75B;1112 1173 11B2;D75B;1112 1173 11B2; +D75C;D75C;1112 1173 11B3;D75C;1112 1173 11B3; +D75D;D75D;1112 1173 11B4;D75D;1112 1173 11B4; +D75E;D75E;1112 1173 11B5;D75E;1112 1173 11B5; +D75F;D75F;1112 1173 11B6;D75F;1112 1173 11B6; +D760;D760;1112 1173 11B7;D760;1112 1173 11B7; +D761;D761;1112 1173 11B8;D761;1112 1173 11B8; +D762;D762;1112 1173 11B9;D762;1112 1173 11B9; +D763;D763;1112 1173 11BA;D763;1112 1173 11BA; +D764;D764;1112 1173 11BB;D764;1112 1173 11BB; +D765;D765;1112 1173 11BC;D765;1112 1173 11BC; +D766;D766;1112 1173 11BD;D766;1112 1173 11BD; +D767;D767;1112 1173 11BE;D767;1112 1173 11BE; +D768;D768;1112 1173 11BF;D768;1112 1173 11BF; +D769;D769;1112 1173 11C0;D769;1112 1173 11C0; +D76A;D76A;1112 1173 11C1;D76A;1112 1173 11C1; +D76B;D76B;1112 1173 11C2;D76B;1112 1173 11C2; +D76C;D76C;1112 1174;D76C;1112 1174; +D76D;D76D;1112 1174 11A8;D76D;1112 1174 11A8; +D76E;D76E;1112 1174 11A9;D76E;1112 1174 11A9; +D76F;D76F;1112 1174 11AA;D76F;1112 1174 11AA; +D770;D770;1112 1174 11AB;D770;1112 1174 11AB; +D771;D771;1112 1174 11AC;D771;1112 1174 11AC; +D772;D772;1112 1174 11AD;D772;1112 1174 11AD; +D773;D773;1112 1174 11AE;D773;1112 1174 11AE; +D774;D774;1112 1174 11AF;D774;1112 1174 11AF; +D775;D775;1112 1174 11B0;D775;1112 1174 11B0; +D776;D776;1112 1174 11B1;D776;1112 1174 11B1; +D777;D777;1112 1174 11B2;D777;1112 1174 11B2; +D778;D778;1112 1174 11B3;D778;1112 1174 11B3; +D779;D779;1112 1174 11B4;D779;1112 1174 11B4; +D77A;D77A;1112 1174 11B5;D77A;1112 1174 11B5; +D77B;D77B;1112 1174 11B6;D77B;1112 1174 11B6; +D77C;D77C;1112 1174 11B7;D77C;1112 1174 11B7; +D77D;D77D;1112 1174 11B8;D77D;1112 1174 11B8; +D77E;D77E;1112 1174 11B9;D77E;1112 1174 11B9; +D77F;D77F;1112 1174 11BA;D77F;1112 1174 11BA; +D780;D780;1112 1174 11BB;D780;1112 1174 11BB; +D781;D781;1112 1174 11BC;D781;1112 1174 11BC; +D782;D782;1112 1174 11BD;D782;1112 1174 11BD; +D783;D783;1112 1174 11BE;D783;1112 1174 11BE; +D784;D784;1112 1174 11BF;D784;1112 1174 11BF; +D785;D785;1112 1174 11C0;D785;1112 1174 11C0; +D786;D786;1112 1174 11C1;D786;1112 1174 11C1; +D787;D787;1112 1174 11C2;D787;1112 1174 11C2; +D788;D788;1112 1175;D788;1112 1175; +D789;D789;1112 1175 11A8;D789;1112 1175 11A8; +D78A;D78A;1112 1175 11A9;D78A;1112 1175 11A9; +D78B;D78B;1112 1175 11AA;D78B;1112 1175 11AA; +D78C;D78C;1112 1175 11AB;D78C;1112 1175 11AB; +D78D;D78D;1112 1175 11AC;D78D;1112 1175 11AC; +D78E;D78E;1112 1175 11AD;D78E;1112 1175 11AD; +D78F;D78F;1112 1175 11AE;D78F;1112 1175 11AE; +D790;D790;1112 1175 11AF;D790;1112 1175 11AF; +D791;D791;1112 1175 11B0;D791;1112 1175 11B0; +D792;D792;1112 1175 11B1;D792;1112 1175 11B1; +D793;D793;1112 1175 11B2;D793;1112 1175 11B2; +D794;D794;1112 1175 11B3;D794;1112 1175 11B3; +D795;D795;1112 1175 11B4;D795;1112 1175 11B4; +D796;D796;1112 1175 11B5;D796;1112 1175 11B5; +D797;D797;1112 1175 11B6;D797;1112 1175 11B6; +D798;D798;1112 1175 11B7;D798;1112 1175 11B7; +D799;D799;1112 1175 11B8;D799;1112 1175 11B8; +D79A;D79A;1112 1175 11B9;D79A;1112 1175 11B9; +D79B;D79B;1112 1175 11BA;D79B;1112 1175 11BA; +D79C;D79C;1112 1175 11BB;D79C;1112 1175 11BB; +D79D;D79D;1112 1175 11BC;D79D;1112 1175 11BC; +D79E;D79E;1112 1175 11BD;D79E;1112 1175 11BD; +D79F;D79F;1112 1175 11BE;D79F;1112 1175 11BE; +D7A0;D7A0;1112 1175 11BF;D7A0;1112 1175 11BF; +D7A1;D7A1;1112 1175 11C0;D7A1;1112 1175 11C0; +D7A2;D7A2;1112 1175 11C1;D7A2;1112 1175 11C1; +D7A3;D7A3;1112 1175 11C2;D7A3;1112 1175 11C2; +F900;8C48;8C48;8C48;8C48; +F901;66F4;66F4;66F4;66F4; +F902;8ECA;8ECA;8ECA;8ECA; +F903;8CC8;8CC8;8CC8;8CC8; +F904;6ED1;6ED1;6ED1;6ED1; +F905;4E32;4E32;4E32;4E32; +F906;53E5;53E5;53E5;53E5; +F907;9F9C;9F9C;9F9C;9F9C; +F908;9F9C;9F9C;9F9C;9F9C; +F909;5951;5951;5951;5951; +F90A;91D1;91D1;91D1;91D1; +F90B;5587;5587;5587;5587; +F90C;5948;5948;5948;5948; +F90D;61F6;61F6;61F6;61F6; +F90E;7669;7669;7669;7669; +F90F;7F85;7F85;7F85;7F85; +F910;863F;863F;863F;863F; +F911;87BA;87BA;87BA;87BA; +F912;88F8;88F8;88F8;88F8; +F913;908F;908F;908F;908F; +F914;6A02;6A02;6A02;6A02; +F915;6D1B;6D1B;6D1B;6D1B; +F916;70D9;70D9;70D9;70D9; +F917;73DE;73DE;73DE;73DE; +F918;843D;843D;843D;843D; +F919;916A;916A;916A;916A; +F91A;99F1;99F1;99F1;99F1; +F91B;4E82;4E82;4E82;4E82; +F91C;5375;5375;5375;5375; +F91D;6B04;6B04;6B04;6B04; +F91E;721B;721B;721B;721B; +F91F;862D;862D;862D;862D; +F920;9E1E;9E1E;9E1E;9E1E; +F921;5D50;5D50;5D50;5D50; +F922;6FEB;6FEB;6FEB;6FEB; +F923;85CD;85CD;85CD;85CD; +F924;8964;8964;8964;8964; +F925;62C9;62C9;62C9;62C9; +F926;81D8;81D8;81D8;81D8; +F927;881F;881F;881F;881F; +F928;5ECA;5ECA;5ECA;5ECA; +F929;6717;6717;6717;6717; +F92A;6D6A;6D6A;6D6A;6D6A; +F92B;72FC;72FC;72FC;72FC; +F92C;90CE;90CE;90CE;90CE; +F92D;4F86;4F86;4F86;4F86; +F92E;51B7;51B7;51B7;51B7; +F92F;52DE;52DE;52DE;52DE; +F930;64C4;64C4;64C4;64C4; +F931;6AD3;6AD3;6AD3;6AD3; +F932;7210;7210;7210;7210; +F933;76E7;76E7;76E7;76E7; +F934;8001;8001;8001;8001; +F935;8606;8606;8606;8606; +F936;865C;865C;865C;865C; +F937;8DEF;8DEF;8DEF;8DEF; +F938;9732;9732;9732;9732; +F939;9B6F;9B6F;9B6F;9B6F; +F93A;9DFA;9DFA;9DFA;9DFA; +F93B;788C;788C;788C;788C; +F93C;797F;797F;797F;797F; +F93D;7DA0;7DA0;7DA0;7DA0; +F93E;83C9;83C9;83C9;83C9; +F93F;9304;9304;9304;9304; +F940;9E7F;9E7F;9E7F;9E7F; +F941;8AD6;8AD6;8AD6;8AD6; +F942;58DF;58DF;58DF;58DF; +F943;5F04;5F04;5F04;5F04; +F944;7C60;7C60;7C60;7C60; +F945;807E;807E;807E;807E; +F946;7262;7262;7262;7262; +F947;78CA;78CA;78CA;78CA; +F948;8CC2;8CC2;8CC2;8CC2; +F949;96F7;96F7;96F7;96F7; +F94A;58D8;58D8;58D8;58D8; +F94B;5C62;5C62;5C62;5C62; +F94C;6A13;6A13;6A13;6A13; +F94D;6DDA;6DDA;6DDA;6DDA; +F94E;6F0F;6F0F;6F0F;6F0F; +F94F;7D2F;7D2F;7D2F;7D2F; +F950;7E37;7E37;7E37;7E37; +F951;964B;964B;964B;964B; +F952;52D2;52D2;52D2;52D2; +F953;808B;808B;808B;808B; +F954;51DC;51DC;51DC;51DC; +F955;51CC;51CC;51CC;51CC; +F956;7A1C;7A1C;7A1C;7A1C; +F957;7DBE;7DBE;7DBE;7DBE; +F958;83F1;83F1;83F1;83F1; +F959;9675;9675;9675;9675; +F95A;8B80;8B80;8B80;8B80; +F95B;62CF;62CF;62CF;62CF; +F95C;6A02;6A02;6A02;6A02; +F95D;8AFE;8AFE;8AFE;8AFE; +F95E;4E39;4E39;4E39;4E39; +F95F;5BE7;5BE7;5BE7;5BE7; +F960;6012;6012;6012;6012; +F961;7387;7387;7387;7387; +F962;7570;7570;7570;7570; +F963;5317;5317;5317;5317; +F964;78FB;78FB;78FB;78FB; +F965;4FBF;4FBF;4FBF;4FBF; +F966;5FA9;5FA9;5FA9;5FA9; +F967;4E0D;4E0D;4E0D;4E0D; +F968;6CCC;6CCC;6CCC;6CCC; +F969;6578;6578;6578;6578; +F96A;7D22;7D22;7D22;7D22; +F96B;53C3;53C3;53C3;53C3; +F96C;585E;585E;585E;585E; +F96D;7701;7701;7701;7701; +F96E;8449;8449;8449;8449; +F96F;8AAA;8AAA;8AAA;8AAA; +F970;6BBA;6BBA;6BBA;6BBA; +F971;8FB0;8FB0;8FB0;8FB0; +F972;6C88;6C88;6C88;6C88; +F973;62FE;62FE;62FE;62FE; +F974;82E5;82E5;82E5;82E5; +F975;63A0;63A0;63A0;63A0; +F976;7565;7565;7565;7565; +F977;4EAE;4EAE;4EAE;4EAE; +F978;5169;5169;5169;5169; +F979;51C9;51C9;51C9;51C9; +F97A;6881;6881;6881;6881; +F97B;7CE7;7CE7;7CE7;7CE7; +F97C;826F;826F;826F;826F; +F97D;8AD2;8AD2;8AD2;8AD2; +F97E;91CF;91CF;91CF;91CF; +F97F;52F5;52F5;52F5;52F5; +F980;5442;5442;5442;5442; +F981;5973;5973;5973;5973; +F982;5EEC;5EEC;5EEC;5EEC; +F983;65C5;65C5;65C5;65C5; +F984;6FFE;6FFE;6FFE;6FFE; +F985;792A;792A;792A;792A; +F986;95AD;95AD;95AD;95AD; +F987;9A6A;9A6A;9A6A;9A6A; +F988;9E97;9E97;9E97;9E97; +F989;9ECE;9ECE;9ECE;9ECE; +F98A;529B;529B;529B;529B; +F98B;66C6;66C6;66C6;66C6; +F98C;6B77;6B77;6B77;6B77; +F98D;8F62;8F62;8F62;8F62; +F98E;5E74;5E74;5E74;5E74; +F98F;6190;6190;6190;6190; +F990;6200;6200;6200;6200; +F991;649A;649A;649A;649A; +F992;6F23;6F23;6F23;6F23; +F993;7149;7149;7149;7149; +F994;7489;7489;7489;7489; +F995;79CA;79CA;79CA;79CA; +F996;7DF4;7DF4;7DF4;7DF4; +F997;806F;806F;806F;806F; +F998;8F26;8F26;8F26;8F26; +F999;84EE;84EE;84EE;84EE; +F99A;9023;9023;9023;9023; +F99B;934A;934A;934A;934A; +F99C;5217;5217;5217;5217; +F99D;52A3;52A3;52A3;52A3; +F99E;54BD;54BD;54BD;54BD; +F99F;70C8;70C8;70C8;70C8; +F9A0;88C2;88C2;88C2;88C2; +F9A1;8AAA;8AAA;8AAA;8AAA; +F9A2;5EC9;5EC9;5EC9;5EC9; +F9A3;5FF5;5FF5;5FF5;5FF5; +F9A4;637B;637B;637B;637B; +F9A5;6BAE;6BAE;6BAE;6BAE; +F9A6;7C3E;7C3E;7C3E;7C3E; +F9A7;7375;7375;7375;7375; +F9A8;4EE4;4EE4;4EE4;4EE4; +F9A9;56F9;56F9;56F9;56F9; +F9AA;5BE7;5BE7;5BE7;5BE7; +F9AB;5DBA;5DBA;5DBA;5DBA; +F9AC;601C;601C;601C;601C; +F9AD;73B2;73B2;73B2;73B2; +F9AE;7469;7469;7469;7469; +F9AF;7F9A;7F9A;7F9A;7F9A; +F9B0;8046;8046;8046;8046; +F9B1;9234;9234;9234;9234; +F9B2;96F6;96F6;96F6;96F6; +F9B3;9748;9748;9748;9748; +F9B4;9818;9818;9818;9818; +F9B5;4F8B;4F8B;4F8B;4F8B; +F9B6;79AE;79AE;79AE;79AE; +F9B7;91B4;91B4;91B4;91B4; +F9B8;96B8;96B8;96B8;96B8; +F9B9;60E1;60E1;60E1;60E1; +F9BA;4E86;4E86;4E86;4E86; +F9BB;50DA;50DA;50DA;50DA; +F9BC;5BEE;5BEE;5BEE;5BEE; +F9BD;5C3F;5C3F;5C3F;5C3F; +F9BE;6599;6599;6599;6599; +F9BF;6A02;6A02;6A02;6A02; +F9C0;71CE;71CE;71CE;71CE; +F9C1;7642;7642;7642;7642; +F9C2;84FC;84FC;84FC;84FC; +F9C3;907C;907C;907C;907C; +F9C4;9F8D;9F8D;9F8D;9F8D; +F9C5;6688;6688;6688;6688; +F9C6;962E;962E;962E;962E; +F9C7;5289;5289;5289;5289; +F9C8;677B;677B;677B;677B; +F9C9;67F3;67F3;67F3;67F3; +F9CA;6D41;6D41;6D41;6D41; +F9CB;6E9C;6E9C;6E9C;6E9C; +F9CC;7409;7409;7409;7409; +F9CD;7559;7559;7559;7559; +F9CE;786B;786B;786B;786B; +F9CF;7D10;7D10;7D10;7D10; +F9D0;985E;985E;985E;985E; +F9D1;516D;516D;516D;516D; +F9D2;622E;622E;622E;622E; +F9D3;9678;9678;9678;9678; +F9D4;502B;502B;502B;502B; +F9D5;5D19;5D19;5D19;5D19; +F9D6;6DEA;6DEA;6DEA;6DEA; +F9D7;8F2A;8F2A;8F2A;8F2A; +F9D8;5F8B;5F8B;5F8B;5F8B; +F9D9;6144;6144;6144;6144; +F9DA;6817;6817;6817;6817; +F9DB;7387;7387;7387;7387; +F9DC;9686;9686;9686;9686; +F9DD;5229;5229;5229;5229; +F9DE;540F;540F;540F;540F; +F9DF;5C65;5C65;5C65;5C65; +F9E0;6613;6613;6613;6613; +F9E1;674E;674E;674E;674E; +F9E2;68A8;68A8;68A8;68A8; +F9E3;6CE5;6CE5;6CE5;6CE5; +F9E4;7406;7406;7406;7406; +F9E5;75E2;75E2;75E2;75E2; +F9E6;7F79;7F79;7F79;7F79; +F9E7;88CF;88CF;88CF;88CF; +F9E8;88E1;88E1;88E1;88E1; +F9E9;91CC;91CC;91CC;91CC; +F9EA;96E2;96E2;96E2;96E2; +F9EB;533F;533F;533F;533F; +F9EC;6EBA;6EBA;6EBA;6EBA; +F9ED;541D;541D;541D;541D; +F9EE;71D0;71D0;71D0;71D0; +F9EF;7498;7498;7498;7498; +F9F0;85FA;85FA;85FA;85FA; +F9F1;96A3;96A3;96A3;96A3; +F9F2;9C57;9C57;9C57;9C57; +F9F3;9E9F;9E9F;9E9F;9E9F; +F9F4;6797;6797;6797;6797; +F9F5;6DCB;6DCB;6DCB;6DCB; +F9F6;81E8;81E8;81E8;81E8; +F9F7;7ACB;7ACB;7ACB;7ACB; +F9F8;7B20;7B20;7B20;7B20; +F9F9;7C92;7C92;7C92;7C92; +F9FA;72C0;72C0;72C0;72C0; +F9FB;7099;7099;7099;7099; +F9FC;8B58;8B58;8B58;8B58; +F9FD;4EC0;4EC0;4EC0;4EC0; +F9FE;8336;8336;8336;8336; +F9FF;523A;523A;523A;523A; +FA00;5207;5207;5207;5207; +FA01;5EA6;5EA6;5EA6;5EA6; +FA02;62D3;62D3;62D3;62D3; +FA03;7CD6;7CD6;7CD6;7CD6; +FA04;5B85;5B85;5B85;5B85; +FA05;6D1E;6D1E;6D1E;6D1E; +FA06;66B4;66B4;66B4;66B4; +FA07;8F3B;8F3B;8F3B;8F3B; +FA08;884C;884C;884C;884C; +FA09;964D;964D;964D;964D; +FA0A;898B;898B;898B;898B; +FA0B;5ED3;5ED3;5ED3;5ED3; +FA0C;5140;5140;5140;5140; +FA0D;55C0;55C0;55C0;55C0; +FA10;585A;585A;585A;585A; +FA12;6674;6674;6674;6674; +FA15;51DE;51DE;51DE;51DE; +FA16;732A;732A;732A;732A; +FA17;76CA;76CA;76CA;76CA; +FA18;793C;793C;793C;793C; +FA19;795E;795E;795E;795E; +FA1A;7965;7965;7965;7965; +FA1B;798F;798F;798F;798F; +FA1C;9756;9756;9756;9756; +FA1D;7CBE;7CBE;7CBE;7CBE; +FA1E;7FBD;7FBD;7FBD;7FBD; +FA20;8612;8612;8612;8612; +FA22;8AF8;8AF8;8AF8;8AF8; +FA25;9038;9038;9038;9038; +FA26;90FD;90FD;90FD;90FD; +FA2A;98EF;98EF;98EF;98EF; +FA2B;98FC;98FC;98FC;98FC; +FA2C;9928;9928;9928;9928; +FA2D;9DB4;9DB4;9DB4;9DB4; +FA2E;90DE;90DE;90DE;90DE; +FA2F;96B7;96B7;96B7;96B7; +FA30;4FAE;4FAE;4FAE;4FAE; +FA31;50E7;50E7;50E7;50E7; +FA32;514D;514D;514D;514D; +FA33;52C9;52C9;52C9;52C9; +FA34;52E4;52E4;52E4;52E4; +FA35;5351;5351;5351;5351; +FA36;559D;559D;559D;559D; +FA37;5606;5606;5606;5606; +FA38;5668;5668;5668;5668; +FA39;5840;5840;5840;5840; +FA3A;58A8;58A8;58A8;58A8; +FA3B;5C64;5C64;5C64;5C64; +FA3C;5C6E;5C6E;5C6E;5C6E; +FA3D;6094;6094;6094;6094; +FA3E;6168;6168;6168;6168; +FA3F;618E;618E;618E;618E; +FA40;61F2;61F2;61F2;61F2; +FA41;654F;654F;654F;654F; +FA42;65E2;65E2;65E2;65E2; +FA43;6691;6691;6691;6691; +FA44;6885;6885;6885;6885; +FA45;6D77;6D77;6D77;6D77; +FA46;6E1A;6E1A;6E1A;6E1A; +FA47;6F22;6F22;6F22;6F22; +FA48;716E;716E;716E;716E; +FA49;722B;722B;722B;722B; +FA4A;7422;7422;7422;7422; +FA4B;7891;7891;7891;7891; +FA4C;793E;793E;793E;793E; +FA4D;7949;7949;7949;7949; +FA4E;7948;7948;7948;7948; +FA4F;7950;7950;7950;7950; +FA50;7956;7956;7956;7956; +FA51;795D;795D;795D;795D; +FA52;798D;798D;798D;798D; +FA53;798E;798E;798E;798E; +FA54;7A40;7A40;7A40;7A40; +FA55;7A81;7A81;7A81;7A81; +FA56;7BC0;7BC0;7BC0;7BC0; +FA57;7DF4;7DF4;7DF4;7DF4; +FA58;7E09;7E09;7E09;7E09; +FA59;7E41;7E41;7E41;7E41; +FA5A;7F72;7F72;7F72;7F72; +FA5B;8005;8005;8005;8005; +FA5C;81ED;81ED;81ED;81ED; +FA5D;8279;8279;8279;8279; +FA5E;8279;8279;8279;8279; +FA5F;8457;8457;8457;8457; +FA60;8910;8910;8910;8910; +FA61;8996;8996;8996;8996; +FA62;8B01;8B01;8B01;8B01; +FA63;8B39;8B39;8B39;8B39; +FA64;8CD3;8CD3;8CD3;8CD3; +FA65;8D08;8D08;8D08;8D08; +FA66;8FB6;8FB6;8FB6;8FB6; +FA67;9038;9038;9038;9038; +FA68;96E3;96E3;96E3;96E3; +FA69;97FF;97FF;97FF;97FF; +FA6A;983B;983B;983B;983B; +FA6B;6075;6075;6075;6075; +FA6C;242EE;242EE;242EE;242EE; +FA6D;8218;8218;8218;8218; +FA70;4E26;4E26;4E26;4E26; +FA71;51B5;51B5;51B5;51B5; +FA72;5168;5168;5168;5168; +FA73;4F80;4F80;4F80;4F80; +FA74;5145;5145;5145;5145; +FA75;5180;5180;5180;5180; +FA76;52C7;52C7;52C7;52C7; +FA77;52FA;52FA;52FA;52FA; +FA78;559D;559D;559D;559D; +FA79;5555;5555;5555;5555; +FA7A;5599;5599;5599;5599; +FA7B;55E2;55E2;55E2;55E2; +FA7C;585A;585A;585A;585A; +FA7D;58B3;58B3;58B3;58B3; +FA7E;5944;5944;5944;5944; +FA7F;5954;5954;5954;5954; +FA80;5A62;5A62;5A62;5A62; +FA81;5B28;5B28;5B28;5B28; +FA82;5ED2;5ED2;5ED2;5ED2; +FA83;5ED9;5ED9;5ED9;5ED9; +FA84;5F69;5F69;5F69;5F69; +FA85;5FAD;5FAD;5FAD;5FAD; +FA86;60D8;60D8;60D8;60D8; +FA87;614E;614E;614E;614E; +FA88;6108;6108;6108;6108; +FA89;618E;618E;618E;618E; +FA8A;6160;6160;6160;6160; +FA8B;61F2;61F2;61F2;61F2; +FA8C;6234;6234;6234;6234; +FA8D;63C4;63C4;63C4;63C4; +FA8E;641C;641C;641C;641C; +FA8F;6452;6452;6452;6452; +FA90;6556;6556;6556;6556; +FA91;6674;6674;6674;6674; +FA92;6717;6717;6717;6717; +FA93;671B;671B;671B;671B; +FA94;6756;6756;6756;6756; +FA95;6B79;6B79;6B79;6B79; +FA96;6BBA;6BBA;6BBA;6BBA; +FA97;6D41;6D41;6D41;6D41; +FA98;6EDB;6EDB;6EDB;6EDB; +FA99;6ECB;6ECB;6ECB;6ECB; +FA9A;6F22;6F22;6F22;6F22; +FA9B;701E;701E;701E;701E; +FA9C;716E;716E;716E;716E; +FA9D;77A7;77A7;77A7;77A7; +FA9E;7235;7235;7235;7235; +FA9F;72AF;72AF;72AF;72AF; +FAA0;732A;732A;732A;732A; +FAA1;7471;7471;7471;7471; +FAA2;7506;7506;7506;7506; +FAA3;753B;753B;753B;753B; +FAA4;761D;761D;761D;761D; +FAA5;761F;761F;761F;761F; +FAA6;76CA;76CA;76CA;76CA; +FAA7;76DB;76DB;76DB;76DB; +FAA8;76F4;76F4;76F4;76F4; +FAA9;774A;774A;774A;774A; +FAAA;7740;7740;7740;7740; +FAAB;78CC;78CC;78CC;78CC; +FAAC;7AB1;7AB1;7AB1;7AB1; +FAAD;7BC0;7BC0;7BC0;7BC0; +FAAE;7C7B;7C7B;7C7B;7C7B; +FAAF;7D5B;7D5B;7D5B;7D5B; +FAB0;7DF4;7DF4;7DF4;7DF4; +FAB1;7F3E;7F3E;7F3E;7F3E; +FAB2;8005;8005;8005;8005; +FAB3;8352;8352;8352;8352; +FAB4;83EF;83EF;83EF;83EF; +FAB5;8779;8779;8779;8779; +FAB6;8941;8941;8941;8941; +FAB7;8986;8986;8986;8986; +FAB8;8996;8996;8996;8996; +FAB9;8ABF;8ABF;8ABF;8ABF; +FABA;8AF8;8AF8;8AF8;8AF8; +FABB;8ACB;8ACB;8ACB;8ACB; +FABC;8B01;8B01;8B01;8B01; +FABD;8AFE;8AFE;8AFE;8AFE; +FABE;8AED;8AED;8AED;8AED; +FABF;8B39;8B39;8B39;8B39; +FAC0;8B8A;8B8A;8B8A;8B8A; +FAC1;8D08;8D08;8D08;8D08; +FAC2;8F38;8F38;8F38;8F38; +FAC3;9072;9072;9072;9072; +FAC4;9199;9199;9199;9199; +FAC5;9276;9276;9276;9276; +FAC6;967C;967C;967C;967C; +FAC7;96E3;96E3;96E3;96E3; +FAC8;9756;9756;9756;9756; +FAC9;97DB;97DB;97DB;97DB; +FACA;97FF;97FF;97FF;97FF; +FACB;980B;980B;980B;980B; +FACC;983B;983B;983B;983B; +FACD;9B12;9B12;9B12;9B12; +FACE;9F9C;9F9C;9F9C;9F9C; +FACF;2284A;2284A;2284A;2284A; +FAD0;22844;22844;22844;22844; +FAD1;233D5;233D5;233D5;233D5; +FAD2;3B9D;3B9D;3B9D;3B9D; +FAD3;4018;4018;4018;4018; +FAD4;4039;4039;4039;4039; +FAD5;25249;25249;25249;25249; +FAD6;25CD0;25CD0;25CD0;25CD0; +FAD7;27ED3;27ED3;27ED3;27ED3; +FAD8;9F43;9F43;9F43;9F43; +FAD9;9F8E;9F8E;9F8E;9F8E; +FB00;FB00;FB00;0066 0066;0066 0066; +FB01;FB01;FB01;0066 0069;0066 0069; +FB02;FB02;FB02;0066 006C;0066 006C; +FB03;FB03;FB03;0066 0066 0069;0066 0066 0069; +FB04;FB04;FB04;0066 0066 006C;0066 0066 006C; +FB05;FB05;FB05;0073 0074;0073 0074; +FB06;FB06;FB06;0073 0074;0073 0074; +FB13;FB13;FB13;0574 0576;0574 0576; +FB14;FB14;FB14;0574 0565;0574 0565; +FB15;FB15;FB15;0574 056B;0574 056B; +FB16;FB16;FB16;057E 0576;057E 0576; +FB17;FB17;FB17;0574 056D;0574 056D; +FB1D;05D9 05B4;05D9 05B4;05D9 05B4;05D9 05B4; +FB1F;05F2 05B7;05F2 05B7;05F2 05B7;05F2 05B7; +FB20;FB20;FB20;05E2;05E2; +FB21;FB21;FB21;05D0;05D0; +FB22;FB22;FB22;05D3;05D3; +FB23;FB23;FB23;05D4;05D4; +FB24;FB24;FB24;05DB;05DB; +FB25;FB25;FB25;05DC;05DC; +FB26;FB26;FB26;05DD;05DD; +FB27;FB27;FB27;05E8;05E8; +FB28;FB28;FB28;05EA;05EA; +FB29;FB29;FB29;002B;002B; +FB2A;05E9 05C1;05E9 05C1;05E9 05C1;05E9 05C1; +FB2B;05E9 05C2;05E9 05C2;05E9 05C2;05E9 05C2; +FB2C;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1; +FB2D;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2; +FB2E;05D0 05B7;05D0 05B7;05D0 05B7;05D0 05B7; +FB2F;05D0 05B8;05D0 05B8;05D0 05B8;05D0 05B8; +FB30;05D0 05BC;05D0 05BC;05D0 05BC;05D0 05BC; +FB31;05D1 05BC;05D1 05BC;05D1 05BC;05D1 05BC; +FB32;05D2 05BC;05D2 05BC;05D2 05BC;05D2 05BC; +FB33;05D3 05BC;05D3 05BC;05D3 05BC;05D3 05BC; +FB34;05D4 05BC;05D4 05BC;05D4 05BC;05D4 05BC; +FB35;05D5 05BC;05D5 05BC;05D5 05BC;05D5 05BC; +FB36;05D6 05BC;05D6 05BC;05D6 05BC;05D6 05BC; +FB38;05D8 05BC;05D8 05BC;05D8 05BC;05D8 05BC; +FB39;05D9 05BC;05D9 05BC;05D9 05BC;05D9 05BC; +FB3A;05DA 05BC;05DA 05BC;05DA 05BC;05DA 05BC; +FB3B;05DB 05BC;05DB 05BC;05DB 05BC;05DB 05BC; +FB3C;05DC 05BC;05DC 05BC;05DC 05BC;05DC 05BC; +FB3E;05DE 05BC;05DE 05BC;05DE 05BC;05DE 05BC; +FB40;05E0 05BC;05E0 05BC;05E0 05BC;05E0 05BC; +FB41;05E1 05BC;05E1 05BC;05E1 05BC;05E1 05BC; +FB43;05E3 05BC;05E3 05BC;05E3 05BC;05E3 05BC; +FB44;05E4 05BC;05E4 05BC;05E4 05BC;05E4 05BC; +FB46;05E6 05BC;05E6 05BC;05E6 05BC;05E6 05BC; +FB47;05E7 05BC;05E7 05BC;05E7 05BC;05E7 05BC; +FB48;05E8 05BC;05E8 05BC;05E8 05BC;05E8 05BC; +FB49;05E9 05BC;05E9 05BC;05E9 05BC;05E9 05BC; +FB4A;05EA 05BC;05EA 05BC;05EA 05BC;05EA 05BC; +FB4B;05D5 05B9;05D5 05B9;05D5 05B9;05D5 05B9; +FB4C;05D1 05BF;05D1 05BF;05D1 05BF;05D1 05BF; +FB4D;05DB 05BF;05DB 05BF;05DB 05BF;05DB 05BF; +FB4E;05E4 05BF;05E4 05BF;05E4 05BF;05E4 05BF; +FB4F;FB4F;FB4F;05D0 05DC;05D0 05DC; +FB50;FB50;FB50;0671;0671; +FB51;FB51;FB51;0671;0671; +FB52;FB52;FB52;067B;067B; +FB53;FB53;FB53;067B;067B; +FB54;FB54;FB54;067B;067B; +FB55;FB55;FB55;067B;067B; +FB56;FB56;FB56;067E;067E; +FB57;FB57;FB57;067E;067E; +FB58;FB58;FB58;067E;067E; +FB59;FB59;FB59;067E;067E; +FB5A;FB5A;FB5A;0680;0680; +FB5B;FB5B;FB5B;0680;0680; +FB5C;FB5C;FB5C;0680;0680; +FB5D;FB5D;FB5D;0680;0680; +FB5E;FB5E;FB5E;067A;067A; +FB5F;FB5F;FB5F;067A;067A; +FB60;FB60;FB60;067A;067A; +FB61;FB61;FB61;067A;067A; +FB62;FB62;FB62;067F;067F; +FB63;FB63;FB63;067F;067F; +FB64;FB64;FB64;067F;067F; +FB65;FB65;FB65;067F;067F; +FB66;FB66;FB66;0679;0679; +FB67;FB67;FB67;0679;0679; +FB68;FB68;FB68;0679;0679; +FB69;FB69;FB69;0679;0679; +FB6A;FB6A;FB6A;06A4;06A4; +FB6B;FB6B;FB6B;06A4;06A4; +FB6C;FB6C;FB6C;06A4;06A4; +FB6D;FB6D;FB6D;06A4;06A4; +FB6E;FB6E;FB6E;06A6;06A6; +FB6F;FB6F;FB6F;06A6;06A6; +FB70;FB70;FB70;06A6;06A6; +FB71;FB71;FB71;06A6;06A6; +FB72;FB72;FB72;0684;0684; +FB73;FB73;FB73;0684;0684; +FB74;FB74;FB74;0684;0684; +FB75;FB75;FB75;0684;0684; +FB76;FB76;FB76;0683;0683; +FB77;FB77;FB77;0683;0683; +FB78;FB78;FB78;0683;0683; +FB79;FB79;FB79;0683;0683; +FB7A;FB7A;FB7A;0686;0686; +FB7B;FB7B;FB7B;0686;0686; +FB7C;FB7C;FB7C;0686;0686; +FB7D;FB7D;FB7D;0686;0686; +FB7E;FB7E;FB7E;0687;0687; +FB7F;FB7F;FB7F;0687;0687; +FB80;FB80;FB80;0687;0687; +FB81;FB81;FB81;0687;0687; +FB82;FB82;FB82;068D;068D; +FB83;FB83;FB83;068D;068D; +FB84;FB84;FB84;068C;068C; +FB85;FB85;FB85;068C;068C; +FB86;FB86;FB86;068E;068E; +FB87;FB87;FB87;068E;068E; +FB88;FB88;FB88;0688;0688; +FB89;FB89;FB89;0688;0688; +FB8A;FB8A;FB8A;0698;0698; +FB8B;FB8B;FB8B;0698;0698; +FB8C;FB8C;FB8C;0691;0691; +FB8D;FB8D;FB8D;0691;0691; +FB8E;FB8E;FB8E;06A9;06A9; +FB8F;FB8F;FB8F;06A9;06A9; +FB90;FB90;FB90;06A9;06A9; +FB91;FB91;FB91;06A9;06A9; +FB92;FB92;FB92;06AF;06AF; +FB93;FB93;FB93;06AF;06AF; +FB94;FB94;FB94;06AF;06AF; +FB95;FB95;FB95;06AF;06AF; +FB96;FB96;FB96;06B3;06B3; +FB97;FB97;FB97;06B3;06B3; +FB98;FB98;FB98;06B3;06B3; +FB99;FB99;FB99;06B3;06B3; +FB9A;FB9A;FB9A;06B1;06B1; +FB9B;FB9B;FB9B;06B1;06B1; +FB9C;FB9C;FB9C;06B1;06B1; +FB9D;FB9D;FB9D;06B1;06B1; +FB9E;FB9E;FB9E;06BA;06BA; +FB9F;FB9F;FB9F;06BA;06BA; +FBA0;FBA0;FBA0;06BB;06BB; +FBA1;FBA1;FBA1;06BB;06BB; +FBA2;FBA2;FBA2;06BB;06BB; +FBA3;FBA3;FBA3;06BB;06BB; +FBA4;FBA4;FBA4;06C0;06D5 0654; +FBA5;FBA5;FBA5;06C0;06D5 0654; +FBA6;FBA6;FBA6;06C1;06C1; +FBA7;FBA7;FBA7;06C1;06C1; +FBA8;FBA8;FBA8;06C1;06C1; +FBA9;FBA9;FBA9;06C1;06C1; +FBAA;FBAA;FBAA;06BE;06BE; +FBAB;FBAB;FBAB;06BE;06BE; +FBAC;FBAC;FBAC;06BE;06BE; +FBAD;FBAD;FBAD;06BE;06BE; +FBAE;FBAE;FBAE;06D2;06D2; +FBAF;FBAF;FBAF;06D2;06D2; +FBB0;FBB0;FBB0;06D3;06D2 0654; +FBB1;FBB1;FBB1;06D3;06D2 0654; +FBD3;FBD3;FBD3;06AD;06AD; +FBD4;FBD4;FBD4;06AD;06AD; +FBD5;FBD5;FBD5;06AD;06AD; +FBD6;FBD6;FBD6;06AD;06AD; +FBD7;FBD7;FBD7;06C7;06C7; +FBD8;FBD8;FBD8;06C7;06C7; +FBD9;FBD9;FBD9;06C6;06C6; +FBDA;FBDA;FBDA;06C6;06C6; +FBDB;FBDB;FBDB;06C8;06C8; +FBDC;FBDC;FBDC;06C8;06C8; +FBDD;FBDD;FBDD;06C7 0674;06C7 0674; +FBDE;FBDE;FBDE;06CB;06CB; +FBDF;FBDF;FBDF;06CB;06CB; +FBE0;FBE0;FBE0;06C5;06C5; +FBE1;FBE1;FBE1;06C5;06C5; +FBE2;FBE2;FBE2;06C9;06C9; +FBE3;FBE3;FBE3;06C9;06C9; +FBE4;FBE4;FBE4;06D0;06D0; +FBE5;FBE5;FBE5;06D0;06D0; +FBE6;FBE6;FBE6;06D0;06D0; +FBE7;FBE7;FBE7;06D0;06D0; +FBE8;FBE8;FBE8;0649;0649; +FBE9;FBE9;FBE9;0649;0649; +FBEA;FBEA;FBEA;0626 0627;064A 0654 0627; +FBEB;FBEB;FBEB;0626 0627;064A 0654 0627; +FBEC;FBEC;FBEC;0626 06D5;064A 0654 06D5; +FBED;FBED;FBED;0626 06D5;064A 0654 06D5; +FBEE;FBEE;FBEE;0626 0648;064A 0654 0648; +FBEF;FBEF;FBEF;0626 0648;064A 0654 0648; +FBF0;FBF0;FBF0;0626 06C7;064A 0654 06C7; +FBF1;FBF1;FBF1;0626 06C7;064A 0654 06C7; +FBF2;FBF2;FBF2;0626 06C6;064A 0654 06C6; +FBF3;FBF3;FBF3;0626 06C6;064A 0654 06C6; +FBF4;FBF4;FBF4;0626 06C8;064A 0654 06C8; +FBF5;FBF5;FBF5;0626 06C8;064A 0654 06C8; +FBF6;FBF6;FBF6;0626 06D0;064A 0654 06D0; +FBF7;FBF7;FBF7;0626 06D0;064A 0654 06D0; +FBF8;FBF8;FBF8;0626 06D0;064A 0654 06D0; +FBF9;FBF9;FBF9;0626 0649;064A 0654 0649; +FBFA;FBFA;FBFA;0626 0649;064A 0654 0649; +FBFB;FBFB;FBFB;0626 0649;064A 0654 0649; +FBFC;FBFC;FBFC;06CC;06CC; +FBFD;FBFD;FBFD;06CC;06CC; +FBFE;FBFE;FBFE;06CC;06CC; +FBFF;FBFF;FBFF;06CC;06CC; +FC00;FC00;FC00;0626 062C;064A 0654 062C; +FC01;FC01;FC01;0626 062D;064A 0654 062D; +FC02;FC02;FC02;0626 0645;064A 0654 0645; +FC03;FC03;FC03;0626 0649;064A 0654 0649; +FC04;FC04;FC04;0626 064A;064A 0654 064A; +FC05;FC05;FC05;0628 062C;0628 062C; +FC06;FC06;FC06;0628 062D;0628 062D; +FC07;FC07;FC07;0628 062E;0628 062E; +FC08;FC08;FC08;0628 0645;0628 0645; +FC09;FC09;FC09;0628 0649;0628 0649; +FC0A;FC0A;FC0A;0628 064A;0628 064A; +FC0B;FC0B;FC0B;062A 062C;062A 062C; +FC0C;FC0C;FC0C;062A 062D;062A 062D; +FC0D;FC0D;FC0D;062A 062E;062A 062E; +FC0E;FC0E;FC0E;062A 0645;062A 0645; +FC0F;FC0F;FC0F;062A 0649;062A 0649; +FC10;FC10;FC10;062A 064A;062A 064A; +FC11;FC11;FC11;062B 062C;062B 062C; +FC12;FC12;FC12;062B 0645;062B 0645; +FC13;FC13;FC13;062B 0649;062B 0649; +FC14;FC14;FC14;062B 064A;062B 064A; +FC15;FC15;FC15;062C 062D;062C 062D; +FC16;FC16;FC16;062C 0645;062C 0645; +FC17;FC17;FC17;062D 062C;062D 062C; +FC18;FC18;FC18;062D 0645;062D 0645; +FC19;FC19;FC19;062E 062C;062E 062C; +FC1A;FC1A;FC1A;062E 062D;062E 062D; +FC1B;FC1B;FC1B;062E 0645;062E 0645; +FC1C;FC1C;FC1C;0633 062C;0633 062C; +FC1D;FC1D;FC1D;0633 062D;0633 062D; +FC1E;FC1E;FC1E;0633 062E;0633 062E; +FC1F;FC1F;FC1F;0633 0645;0633 0645; +FC20;FC20;FC20;0635 062D;0635 062D; +FC21;FC21;FC21;0635 0645;0635 0645; +FC22;FC22;FC22;0636 062C;0636 062C; +FC23;FC23;FC23;0636 062D;0636 062D; +FC24;FC24;FC24;0636 062E;0636 062E; +FC25;FC25;FC25;0636 0645;0636 0645; +FC26;FC26;FC26;0637 062D;0637 062D; +FC27;FC27;FC27;0637 0645;0637 0645; +FC28;FC28;FC28;0638 0645;0638 0645; +FC29;FC29;FC29;0639 062C;0639 062C; +FC2A;FC2A;FC2A;0639 0645;0639 0645; +FC2B;FC2B;FC2B;063A 062C;063A 062C; +FC2C;FC2C;FC2C;063A 0645;063A 0645; +FC2D;FC2D;FC2D;0641 062C;0641 062C; +FC2E;FC2E;FC2E;0641 062D;0641 062D; +FC2F;FC2F;FC2F;0641 062E;0641 062E; +FC30;FC30;FC30;0641 0645;0641 0645; +FC31;FC31;FC31;0641 0649;0641 0649; +FC32;FC32;FC32;0641 064A;0641 064A; +FC33;FC33;FC33;0642 062D;0642 062D; +FC34;FC34;FC34;0642 0645;0642 0645; +FC35;FC35;FC35;0642 0649;0642 0649; +FC36;FC36;FC36;0642 064A;0642 064A; +FC37;FC37;FC37;0643 0627;0643 0627; +FC38;FC38;FC38;0643 062C;0643 062C; +FC39;FC39;FC39;0643 062D;0643 062D; +FC3A;FC3A;FC3A;0643 062E;0643 062E; +FC3B;FC3B;FC3B;0643 0644;0643 0644; +FC3C;FC3C;FC3C;0643 0645;0643 0645; +FC3D;FC3D;FC3D;0643 0649;0643 0649; +FC3E;FC3E;FC3E;0643 064A;0643 064A; +FC3F;FC3F;FC3F;0644 062C;0644 062C; +FC40;FC40;FC40;0644 062D;0644 062D; +FC41;FC41;FC41;0644 062E;0644 062E; +FC42;FC42;FC42;0644 0645;0644 0645; +FC43;FC43;FC43;0644 0649;0644 0649; +FC44;FC44;FC44;0644 064A;0644 064A; +FC45;FC45;FC45;0645 062C;0645 062C; +FC46;FC46;FC46;0645 062D;0645 062D; +FC47;FC47;FC47;0645 062E;0645 062E; +FC48;FC48;FC48;0645 0645;0645 0645; +FC49;FC49;FC49;0645 0649;0645 0649; +FC4A;FC4A;FC4A;0645 064A;0645 064A; +FC4B;FC4B;FC4B;0646 062C;0646 062C; +FC4C;FC4C;FC4C;0646 062D;0646 062D; +FC4D;FC4D;FC4D;0646 062E;0646 062E; +FC4E;FC4E;FC4E;0646 0645;0646 0645; +FC4F;FC4F;FC4F;0646 0649;0646 0649; +FC50;FC50;FC50;0646 064A;0646 064A; +FC51;FC51;FC51;0647 062C;0647 062C; +FC52;FC52;FC52;0647 0645;0647 0645; +FC53;FC53;FC53;0647 0649;0647 0649; +FC54;FC54;FC54;0647 064A;0647 064A; +FC55;FC55;FC55;064A 062C;064A 062C; +FC56;FC56;FC56;064A 062D;064A 062D; +FC57;FC57;FC57;064A 062E;064A 062E; +FC58;FC58;FC58;064A 0645;064A 0645; +FC59;FC59;FC59;064A 0649;064A 0649; +FC5A;FC5A;FC5A;064A 064A;064A 064A; +FC5B;FC5B;FC5B;0630 0670;0630 0670; +FC5C;FC5C;FC5C;0631 0670;0631 0670; +FC5D;FC5D;FC5D;0649 0670;0649 0670; +FC5E;FC5E;FC5E;0020 064C 0651;0020 064C 0651; +FC5F;FC5F;FC5F;0020 064D 0651;0020 064D 0651; +FC60;FC60;FC60;0020 064E 0651;0020 064E 0651; +FC61;FC61;FC61;0020 064F 0651;0020 064F 0651; +FC62;FC62;FC62;0020 0650 0651;0020 0650 0651; +FC63;FC63;FC63;0020 0651 0670;0020 0651 0670; +FC64;FC64;FC64;0626 0631;064A 0654 0631; +FC65;FC65;FC65;0626 0632;064A 0654 0632; +FC66;FC66;FC66;0626 0645;064A 0654 0645; +FC67;FC67;FC67;0626 0646;064A 0654 0646; +FC68;FC68;FC68;0626 0649;064A 0654 0649; +FC69;FC69;FC69;0626 064A;064A 0654 064A; +FC6A;FC6A;FC6A;0628 0631;0628 0631; +FC6B;FC6B;FC6B;0628 0632;0628 0632; +FC6C;FC6C;FC6C;0628 0645;0628 0645; +FC6D;FC6D;FC6D;0628 0646;0628 0646; +FC6E;FC6E;FC6E;0628 0649;0628 0649; +FC6F;FC6F;FC6F;0628 064A;0628 064A; +FC70;FC70;FC70;062A 0631;062A 0631; +FC71;FC71;FC71;062A 0632;062A 0632; +FC72;FC72;FC72;062A 0645;062A 0645; +FC73;FC73;FC73;062A 0646;062A 0646; +FC74;FC74;FC74;062A 0649;062A 0649; +FC75;FC75;FC75;062A 064A;062A 064A; +FC76;FC76;FC76;062B 0631;062B 0631; +FC77;FC77;FC77;062B 0632;062B 0632; +FC78;FC78;FC78;062B 0645;062B 0645; +FC79;FC79;FC79;062B 0646;062B 0646; +FC7A;FC7A;FC7A;062B 0649;062B 0649; +FC7B;FC7B;FC7B;062B 064A;062B 064A; +FC7C;FC7C;FC7C;0641 0649;0641 0649; +FC7D;FC7D;FC7D;0641 064A;0641 064A; +FC7E;FC7E;FC7E;0642 0649;0642 0649; +FC7F;FC7F;FC7F;0642 064A;0642 064A; +FC80;FC80;FC80;0643 0627;0643 0627; +FC81;FC81;FC81;0643 0644;0643 0644; +FC82;FC82;FC82;0643 0645;0643 0645; +FC83;FC83;FC83;0643 0649;0643 0649; +FC84;FC84;FC84;0643 064A;0643 064A; +FC85;FC85;FC85;0644 0645;0644 0645; +FC86;FC86;FC86;0644 0649;0644 0649; +FC87;FC87;FC87;0644 064A;0644 064A; +FC88;FC88;FC88;0645 0627;0645 0627; +FC89;FC89;FC89;0645 0645;0645 0645; +FC8A;FC8A;FC8A;0646 0631;0646 0631; +FC8B;FC8B;FC8B;0646 0632;0646 0632; +FC8C;FC8C;FC8C;0646 0645;0646 0645; +FC8D;FC8D;FC8D;0646 0646;0646 0646; +FC8E;FC8E;FC8E;0646 0649;0646 0649; +FC8F;FC8F;FC8F;0646 064A;0646 064A; +FC90;FC90;FC90;0649 0670;0649 0670; +FC91;FC91;FC91;064A 0631;064A 0631; +FC92;FC92;FC92;064A 0632;064A 0632; +FC93;FC93;FC93;064A 0645;064A 0645; +FC94;FC94;FC94;064A 0646;064A 0646; +FC95;FC95;FC95;064A 0649;064A 0649; +FC96;FC96;FC96;064A 064A;064A 064A; +FC97;FC97;FC97;0626 062C;064A 0654 062C; +FC98;FC98;FC98;0626 062D;064A 0654 062D; +FC99;FC99;FC99;0626 062E;064A 0654 062E; +FC9A;FC9A;FC9A;0626 0645;064A 0654 0645; +FC9B;FC9B;FC9B;0626 0647;064A 0654 0647; +FC9C;FC9C;FC9C;0628 062C;0628 062C; +FC9D;FC9D;FC9D;0628 062D;0628 062D; +FC9E;FC9E;FC9E;0628 062E;0628 062E; +FC9F;FC9F;FC9F;0628 0645;0628 0645; +FCA0;FCA0;FCA0;0628 0647;0628 0647; +FCA1;FCA1;FCA1;062A 062C;062A 062C; +FCA2;FCA2;FCA2;062A 062D;062A 062D; +FCA3;FCA3;FCA3;062A 062E;062A 062E; +FCA4;FCA4;FCA4;062A 0645;062A 0645; +FCA5;FCA5;FCA5;062A 0647;062A 0647; +FCA6;FCA6;FCA6;062B 0645;062B 0645; +FCA7;FCA7;FCA7;062C 062D;062C 062D; +FCA8;FCA8;FCA8;062C 0645;062C 0645; +FCA9;FCA9;FCA9;062D 062C;062D 062C; +FCAA;FCAA;FCAA;062D 0645;062D 0645; +FCAB;FCAB;FCAB;062E 062C;062E 062C; +FCAC;FCAC;FCAC;062E 0645;062E 0645; +FCAD;FCAD;FCAD;0633 062C;0633 062C; +FCAE;FCAE;FCAE;0633 062D;0633 062D; +FCAF;FCAF;FCAF;0633 062E;0633 062E; +FCB0;FCB0;FCB0;0633 0645;0633 0645; +FCB1;FCB1;FCB1;0635 062D;0635 062D; +FCB2;FCB2;FCB2;0635 062E;0635 062E; +FCB3;FCB3;FCB3;0635 0645;0635 0645; +FCB4;FCB4;FCB4;0636 062C;0636 062C; +FCB5;FCB5;FCB5;0636 062D;0636 062D; +FCB6;FCB6;FCB6;0636 062E;0636 062E; +FCB7;FCB7;FCB7;0636 0645;0636 0645; +FCB8;FCB8;FCB8;0637 062D;0637 062D; +FCB9;FCB9;FCB9;0638 0645;0638 0645; +FCBA;FCBA;FCBA;0639 062C;0639 062C; +FCBB;FCBB;FCBB;0639 0645;0639 0645; +FCBC;FCBC;FCBC;063A 062C;063A 062C; +FCBD;FCBD;FCBD;063A 0645;063A 0645; +FCBE;FCBE;FCBE;0641 062C;0641 062C; +FCBF;FCBF;FCBF;0641 062D;0641 062D; +FCC0;FCC0;FCC0;0641 062E;0641 062E; +FCC1;FCC1;FCC1;0641 0645;0641 0645; +FCC2;FCC2;FCC2;0642 062D;0642 062D; +FCC3;FCC3;FCC3;0642 0645;0642 0645; +FCC4;FCC4;FCC4;0643 062C;0643 062C; +FCC5;FCC5;FCC5;0643 062D;0643 062D; +FCC6;FCC6;FCC6;0643 062E;0643 062E; +FCC7;FCC7;FCC7;0643 0644;0643 0644; +FCC8;FCC8;FCC8;0643 0645;0643 0645; +FCC9;FCC9;FCC9;0644 062C;0644 062C; +FCCA;FCCA;FCCA;0644 062D;0644 062D; +FCCB;FCCB;FCCB;0644 062E;0644 062E; +FCCC;FCCC;FCCC;0644 0645;0644 0645; +FCCD;FCCD;FCCD;0644 0647;0644 0647; +FCCE;FCCE;FCCE;0645 062C;0645 062C; +FCCF;FCCF;FCCF;0645 062D;0645 062D; +FCD0;FCD0;FCD0;0645 062E;0645 062E; +FCD1;FCD1;FCD1;0645 0645;0645 0645; +FCD2;FCD2;FCD2;0646 062C;0646 062C; +FCD3;FCD3;FCD3;0646 062D;0646 062D; +FCD4;FCD4;FCD4;0646 062E;0646 062E; +FCD5;FCD5;FCD5;0646 0645;0646 0645; +FCD6;FCD6;FCD6;0646 0647;0646 0647; +FCD7;FCD7;FCD7;0647 062C;0647 062C; +FCD8;FCD8;FCD8;0647 0645;0647 0645; +FCD9;FCD9;FCD9;0647 0670;0647 0670; +FCDA;FCDA;FCDA;064A 062C;064A 062C; +FCDB;FCDB;FCDB;064A 062D;064A 062D; +FCDC;FCDC;FCDC;064A 062E;064A 062E; +FCDD;FCDD;FCDD;064A 0645;064A 0645; +FCDE;FCDE;FCDE;064A 0647;064A 0647; +FCDF;FCDF;FCDF;0626 0645;064A 0654 0645; +FCE0;FCE0;FCE0;0626 0647;064A 0654 0647; +FCE1;FCE1;FCE1;0628 0645;0628 0645; +FCE2;FCE2;FCE2;0628 0647;0628 0647; +FCE3;FCE3;FCE3;062A 0645;062A 0645; +FCE4;FCE4;FCE4;062A 0647;062A 0647; +FCE5;FCE5;FCE5;062B 0645;062B 0645; +FCE6;FCE6;FCE6;062B 0647;062B 0647; +FCE7;FCE7;FCE7;0633 0645;0633 0645; +FCE8;FCE8;FCE8;0633 0647;0633 0647; +FCE9;FCE9;FCE9;0634 0645;0634 0645; +FCEA;FCEA;FCEA;0634 0647;0634 0647; +FCEB;FCEB;FCEB;0643 0644;0643 0644; +FCEC;FCEC;FCEC;0643 0645;0643 0645; +FCED;FCED;FCED;0644 0645;0644 0645; +FCEE;FCEE;FCEE;0646 0645;0646 0645; +FCEF;FCEF;FCEF;0646 0647;0646 0647; +FCF0;FCF0;FCF0;064A 0645;064A 0645; +FCF1;FCF1;FCF1;064A 0647;064A 0647; +FCF2;FCF2;FCF2;0640 064E 0651;0640 064E 0651; +FCF3;FCF3;FCF3;0640 064F 0651;0640 064F 0651; +FCF4;FCF4;FCF4;0640 0650 0651;0640 0650 0651; +FCF5;FCF5;FCF5;0637 0649;0637 0649; +FCF6;FCF6;FCF6;0637 064A;0637 064A; +FCF7;FCF7;FCF7;0639 0649;0639 0649; +FCF8;FCF8;FCF8;0639 064A;0639 064A; +FCF9;FCF9;FCF9;063A 0649;063A 0649; +FCFA;FCFA;FCFA;063A 064A;063A 064A; +FCFB;FCFB;FCFB;0633 0649;0633 0649; +FCFC;FCFC;FCFC;0633 064A;0633 064A; +FCFD;FCFD;FCFD;0634 0649;0634 0649; +FCFE;FCFE;FCFE;0634 064A;0634 064A; +FCFF;FCFF;FCFF;062D 0649;062D 0649; +FD00;FD00;FD00;062D 064A;062D 064A; +FD01;FD01;FD01;062C 0649;062C 0649; +FD02;FD02;FD02;062C 064A;062C 064A; +FD03;FD03;FD03;062E 0649;062E 0649; +FD04;FD04;FD04;062E 064A;062E 064A; +FD05;FD05;FD05;0635 0649;0635 0649; +FD06;FD06;FD06;0635 064A;0635 064A; +FD07;FD07;FD07;0636 0649;0636 0649; +FD08;FD08;FD08;0636 064A;0636 064A; +FD09;FD09;FD09;0634 062C;0634 062C; +FD0A;FD0A;FD0A;0634 062D;0634 062D; +FD0B;FD0B;FD0B;0634 062E;0634 062E; +FD0C;FD0C;FD0C;0634 0645;0634 0645; +FD0D;FD0D;FD0D;0634 0631;0634 0631; +FD0E;FD0E;FD0E;0633 0631;0633 0631; +FD0F;FD0F;FD0F;0635 0631;0635 0631; +FD10;FD10;FD10;0636 0631;0636 0631; +FD11;FD11;FD11;0637 0649;0637 0649; +FD12;FD12;FD12;0637 064A;0637 064A; +FD13;FD13;FD13;0639 0649;0639 0649; +FD14;FD14;FD14;0639 064A;0639 064A; +FD15;FD15;FD15;063A 0649;063A 0649; +FD16;FD16;FD16;063A 064A;063A 064A; +FD17;FD17;FD17;0633 0649;0633 0649; +FD18;FD18;FD18;0633 064A;0633 064A; +FD19;FD19;FD19;0634 0649;0634 0649; +FD1A;FD1A;FD1A;0634 064A;0634 064A; +FD1B;FD1B;FD1B;062D 0649;062D 0649; +FD1C;FD1C;FD1C;062D 064A;062D 064A; +FD1D;FD1D;FD1D;062C 0649;062C 0649; +FD1E;FD1E;FD1E;062C 064A;062C 064A; +FD1F;FD1F;FD1F;062E 0649;062E 0649; +FD20;FD20;FD20;062E 064A;062E 064A; +FD21;FD21;FD21;0635 0649;0635 0649; +FD22;FD22;FD22;0635 064A;0635 064A; +FD23;FD23;FD23;0636 0649;0636 0649; +FD24;FD24;FD24;0636 064A;0636 064A; +FD25;FD25;FD25;0634 062C;0634 062C; +FD26;FD26;FD26;0634 062D;0634 062D; +FD27;FD27;FD27;0634 062E;0634 062E; +FD28;FD28;FD28;0634 0645;0634 0645; +FD29;FD29;FD29;0634 0631;0634 0631; +FD2A;FD2A;FD2A;0633 0631;0633 0631; +FD2B;FD2B;FD2B;0635 0631;0635 0631; +FD2C;FD2C;FD2C;0636 0631;0636 0631; +FD2D;FD2D;FD2D;0634 062C;0634 062C; +FD2E;FD2E;FD2E;0634 062D;0634 062D; +FD2F;FD2F;FD2F;0634 062E;0634 062E; +FD30;FD30;FD30;0634 0645;0634 0645; +FD31;FD31;FD31;0633 0647;0633 0647; +FD32;FD32;FD32;0634 0647;0634 0647; +FD33;FD33;FD33;0637 0645;0637 0645; +FD34;FD34;FD34;0633 062C;0633 062C; +FD35;FD35;FD35;0633 062D;0633 062D; +FD36;FD36;FD36;0633 062E;0633 062E; +FD37;FD37;FD37;0634 062C;0634 062C; +FD38;FD38;FD38;0634 062D;0634 062D; +FD39;FD39;FD39;0634 062E;0634 062E; +FD3A;FD3A;FD3A;0637 0645;0637 0645; +FD3B;FD3B;FD3B;0638 0645;0638 0645; +FD3C;FD3C;FD3C;0627 064B;0627 064B; +FD3D;FD3D;FD3D;0627 064B;0627 064B; +FD50;FD50;FD50;062A 062C 0645;062A 062C 0645; +FD51;FD51;FD51;062A 062D 062C;062A 062D 062C; +FD52;FD52;FD52;062A 062D 062C;062A 062D 062C; +FD53;FD53;FD53;062A 062D 0645;062A 062D 0645; +FD54;FD54;FD54;062A 062E 0645;062A 062E 0645; +FD55;FD55;FD55;062A 0645 062C;062A 0645 062C; +FD56;FD56;FD56;062A 0645 062D;062A 0645 062D; +FD57;FD57;FD57;062A 0645 062E;062A 0645 062E; +FD58;FD58;FD58;062C 0645 062D;062C 0645 062D; +FD59;FD59;FD59;062C 0645 062D;062C 0645 062D; +FD5A;FD5A;FD5A;062D 0645 064A;062D 0645 064A; +FD5B;FD5B;FD5B;062D 0645 0649;062D 0645 0649; +FD5C;FD5C;FD5C;0633 062D 062C;0633 062D 062C; +FD5D;FD5D;FD5D;0633 062C 062D;0633 062C 062D; +FD5E;FD5E;FD5E;0633 062C 0649;0633 062C 0649; +FD5F;FD5F;FD5F;0633 0645 062D;0633 0645 062D; +FD60;FD60;FD60;0633 0645 062D;0633 0645 062D; +FD61;FD61;FD61;0633 0645 062C;0633 0645 062C; +FD62;FD62;FD62;0633 0645 0645;0633 0645 0645; +FD63;FD63;FD63;0633 0645 0645;0633 0645 0645; +FD64;FD64;FD64;0635 062D 062D;0635 062D 062D; +FD65;FD65;FD65;0635 062D 062D;0635 062D 062D; +FD66;FD66;FD66;0635 0645 0645;0635 0645 0645; +FD67;FD67;FD67;0634 062D 0645;0634 062D 0645; +FD68;FD68;FD68;0634 062D 0645;0634 062D 0645; +FD69;FD69;FD69;0634 062C 064A;0634 062C 064A; +FD6A;FD6A;FD6A;0634 0645 062E;0634 0645 062E; +FD6B;FD6B;FD6B;0634 0645 062E;0634 0645 062E; +FD6C;FD6C;FD6C;0634 0645 0645;0634 0645 0645; +FD6D;FD6D;FD6D;0634 0645 0645;0634 0645 0645; +FD6E;FD6E;FD6E;0636 062D 0649;0636 062D 0649; +FD6F;FD6F;FD6F;0636 062E 0645;0636 062E 0645; +FD70;FD70;FD70;0636 062E 0645;0636 062E 0645; +FD71;FD71;FD71;0637 0645 062D;0637 0645 062D; +FD72;FD72;FD72;0637 0645 062D;0637 0645 062D; +FD73;FD73;FD73;0637 0645 0645;0637 0645 0645; +FD74;FD74;FD74;0637 0645 064A;0637 0645 064A; +FD75;FD75;FD75;0639 062C 0645;0639 062C 0645; +FD76;FD76;FD76;0639 0645 0645;0639 0645 0645; +FD77;FD77;FD77;0639 0645 0645;0639 0645 0645; +FD78;FD78;FD78;0639 0645 0649;0639 0645 0649; +FD79;FD79;FD79;063A 0645 0645;063A 0645 0645; +FD7A;FD7A;FD7A;063A 0645 064A;063A 0645 064A; +FD7B;FD7B;FD7B;063A 0645 0649;063A 0645 0649; +FD7C;FD7C;FD7C;0641 062E 0645;0641 062E 0645; +FD7D;FD7D;FD7D;0641 062E 0645;0641 062E 0645; +FD7E;FD7E;FD7E;0642 0645 062D;0642 0645 062D; +FD7F;FD7F;FD7F;0642 0645 0645;0642 0645 0645; +FD80;FD80;FD80;0644 062D 0645;0644 062D 0645; +FD81;FD81;FD81;0644 062D 064A;0644 062D 064A; +FD82;FD82;FD82;0644 062D 0649;0644 062D 0649; +FD83;FD83;FD83;0644 062C 062C;0644 062C 062C; +FD84;FD84;FD84;0644 062C 062C;0644 062C 062C; +FD85;FD85;FD85;0644 062E 0645;0644 062E 0645; +FD86;FD86;FD86;0644 062E 0645;0644 062E 0645; +FD87;FD87;FD87;0644 0645 062D;0644 0645 062D; +FD88;FD88;FD88;0644 0645 062D;0644 0645 062D; +FD89;FD89;FD89;0645 062D 062C;0645 062D 062C; +FD8A;FD8A;FD8A;0645 062D 0645;0645 062D 0645; +FD8B;FD8B;FD8B;0645 062D 064A;0645 062D 064A; +FD8C;FD8C;FD8C;0645 062C 062D;0645 062C 062D; +FD8D;FD8D;FD8D;0645 062C 0645;0645 062C 0645; +FD8E;FD8E;FD8E;0645 062E 062C;0645 062E 062C; +FD8F;FD8F;FD8F;0645 062E 0645;0645 062E 0645; +FD92;FD92;FD92;0645 062C 062E;0645 062C 062E; +FD93;FD93;FD93;0647 0645 062C;0647 0645 062C; +FD94;FD94;FD94;0647 0645 0645;0647 0645 0645; +FD95;FD95;FD95;0646 062D 0645;0646 062D 0645; +FD96;FD96;FD96;0646 062D 0649;0646 062D 0649; +FD97;FD97;FD97;0646 062C 0645;0646 062C 0645; +FD98;FD98;FD98;0646 062C 0645;0646 062C 0645; +FD99;FD99;FD99;0646 062C 0649;0646 062C 0649; +FD9A;FD9A;FD9A;0646 0645 064A;0646 0645 064A; +FD9B;FD9B;FD9B;0646 0645 0649;0646 0645 0649; +FD9C;FD9C;FD9C;064A 0645 0645;064A 0645 0645; +FD9D;FD9D;FD9D;064A 0645 0645;064A 0645 0645; +FD9E;FD9E;FD9E;0628 062E 064A;0628 062E 064A; +FD9F;FD9F;FD9F;062A 062C 064A;062A 062C 064A; +FDA0;FDA0;FDA0;062A 062C 0649;062A 062C 0649; +FDA1;FDA1;FDA1;062A 062E 064A;062A 062E 064A; +FDA2;FDA2;FDA2;062A 062E 0649;062A 062E 0649; +FDA3;FDA3;FDA3;062A 0645 064A;062A 0645 064A; +FDA4;FDA4;FDA4;062A 0645 0649;062A 0645 0649; +FDA5;FDA5;FDA5;062C 0645 064A;062C 0645 064A; +FDA6;FDA6;FDA6;062C 062D 0649;062C 062D 0649; +FDA7;FDA7;FDA7;062C 0645 0649;062C 0645 0649; +FDA8;FDA8;FDA8;0633 062E 0649;0633 062E 0649; +FDA9;FDA9;FDA9;0635 062D 064A;0635 062D 064A; +FDAA;FDAA;FDAA;0634 062D 064A;0634 062D 064A; +FDAB;FDAB;FDAB;0636 062D 064A;0636 062D 064A; +FDAC;FDAC;FDAC;0644 062C 064A;0644 062C 064A; +FDAD;FDAD;FDAD;0644 0645 064A;0644 0645 064A; +FDAE;FDAE;FDAE;064A 062D 064A;064A 062D 064A; +FDAF;FDAF;FDAF;064A 062C 064A;064A 062C 064A; +FDB0;FDB0;FDB0;064A 0645 064A;064A 0645 064A; +FDB1;FDB1;FDB1;0645 0645 064A;0645 0645 064A; +FDB2;FDB2;FDB2;0642 0645 064A;0642 0645 064A; +FDB3;FDB3;FDB3;0646 062D 064A;0646 062D 064A; +FDB4;FDB4;FDB4;0642 0645 062D;0642 0645 062D; +FDB5;FDB5;FDB5;0644 062D 0645;0644 062D 0645; +FDB6;FDB6;FDB6;0639 0645 064A;0639 0645 064A; +FDB7;FDB7;FDB7;0643 0645 064A;0643 0645 064A; +FDB8;FDB8;FDB8;0646 062C 062D;0646 062C 062D; +FDB9;FDB9;FDB9;0645 062E 064A;0645 062E 064A; +FDBA;FDBA;FDBA;0644 062C 0645;0644 062C 0645; +FDBB;FDBB;FDBB;0643 0645 0645;0643 0645 0645; +FDBC;FDBC;FDBC;0644 062C 0645;0644 062C 0645; +FDBD;FDBD;FDBD;0646 062C 062D;0646 062C 062D; +FDBE;FDBE;FDBE;062C 062D 064A;062C 062D 064A; +FDBF;FDBF;FDBF;062D 062C 064A;062D 062C 064A; +FDC0;FDC0;FDC0;0645 062C 064A;0645 062C 064A; +FDC1;FDC1;FDC1;0641 0645 064A;0641 0645 064A; +FDC2;FDC2;FDC2;0628 062D 064A;0628 062D 064A; +FDC3;FDC3;FDC3;0643 0645 0645;0643 0645 0645; +FDC4;FDC4;FDC4;0639 062C 0645;0639 062C 0645; +FDC5;FDC5;FDC5;0635 0645 0645;0635 0645 0645; +FDC6;FDC6;FDC6;0633 062E 064A;0633 062E 064A; +FDC7;FDC7;FDC7;0646 062C 064A;0646 062C 064A; +FDF0;FDF0;FDF0;0635 0644 06D2;0635 0644 06D2; +FDF1;FDF1;FDF1;0642 0644 06D2;0642 0644 06D2; +FDF2;FDF2;FDF2;0627 0644 0644 0647;0627 0644 0644 0647; +FDF3;FDF3;FDF3;0627 0643 0628 0631;0627 0643 0628 0631; +FDF4;FDF4;FDF4;0645 062D 0645 062F;0645 062D 0645 062F; +FDF5;FDF5;FDF5;0635 0644 0639 0645;0635 0644 0639 0645; +FDF6;FDF6;FDF6;0631 0633 0648 0644;0631 0633 0648 0644; +FDF7;FDF7;FDF7;0639 0644 064A 0647;0639 0644 064A 0647; +FDF8;FDF8;FDF8;0648 0633 0644 0645;0648 0633 0644 0645; +FDF9;FDF9;FDF9;0635 0644 0649;0635 0644 0649; +FDFA;FDFA;FDFA;0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645; +FDFB;FDFB;FDFB;062C 0644 0020 062C 0644 0627 0644 0647;062C 0644 0020 062C 0644 0627 0644 0647; +FDFC;FDFC;FDFC;0631 06CC 0627 0644;0631 06CC 0627 0644; +FE10;FE10;FE10;002C;002C; +FE11;FE11;FE11;3001;3001; +FE12;FE12;FE12;3002;3002; +FE13;FE13;FE13;003A;003A; +FE14;FE14;FE14;003B;003B; +FE15;FE15;FE15;0021;0021; +FE16;FE16;FE16;003F;003F; +FE17;FE17;FE17;3016;3016; +FE18;FE18;FE18;3017;3017; +FE19;FE19;FE19;002E 002E 002E;002E 002E 002E; +FE30;FE30;FE30;002E 002E;002E 002E; +FE31;FE31;FE31;2014;2014; +FE32;FE32;FE32;2013;2013; +FE33;FE33;FE33;005F;005F; +FE34;FE34;FE34;005F;005F; +FE35;FE35;FE35;0028;0028; +FE36;FE36;FE36;0029;0029; +FE37;FE37;FE37;007B;007B; +FE38;FE38;FE38;007D;007D; +FE39;FE39;FE39;3014;3014; +FE3A;FE3A;FE3A;3015;3015; +FE3B;FE3B;FE3B;3010;3010; +FE3C;FE3C;FE3C;3011;3011; +FE3D;FE3D;FE3D;300A;300A; +FE3E;FE3E;FE3E;300B;300B; +FE3F;FE3F;FE3F;3008;3008; +FE40;FE40;FE40;3009;3009; +FE41;FE41;FE41;300C;300C; +FE42;FE42;FE42;300D;300D; +FE43;FE43;FE43;300E;300E; +FE44;FE44;FE44;300F;300F; +FE47;FE47;FE47;005B;005B; +FE48;FE48;FE48;005D;005D; +FE49;FE49;FE49;0020 0305;0020 0305; +FE4A;FE4A;FE4A;0020 0305;0020 0305; +FE4B;FE4B;FE4B;0020 0305;0020 0305; +FE4C;FE4C;FE4C;0020 0305;0020 0305; +FE4D;FE4D;FE4D;005F;005F; +FE4E;FE4E;FE4E;005F;005F; +FE4F;FE4F;FE4F;005F;005F; +FE50;FE50;FE50;002C;002C; +FE51;FE51;FE51;3001;3001; +FE52;FE52;FE52;002E;002E; +FE54;FE54;FE54;003B;003B; +FE55;FE55;FE55;003A;003A; +FE56;FE56;FE56;003F;003F; +FE57;FE57;FE57;0021;0021; +FE58;FE58;FE58;2014;2014; +FE59;FE59;FE59;0028;0028; +FE5A;FE5A;FE5A;0029;0029; +FE5B;FE5B;FE5B;007B;007B; +FE5C;FE5C;FE5C;007D;007D; +FE5D;FE5D;FE5D;3014;3014; +FE5E;FE5E;FE5E;3015;3015; +FE5F;FE5F;FE5F;0023;0023; +FE60;FE60;FE60;0026;0026; +FE61;FE61;FE61;002A;002A; +FE62;FE62;FE62;002B;002B; +FE63;FE63;FE63;002D;002D; +FE64;FE64;FE64;003C;003C; +FE65;FE65;FE65;003E;003E; +FE66;FE66;FE66;003D;003D; +FE68;FE68;FE68;005C;005C; +FE69;FE69;FE69;0024;0024; +FE6A;FE6A;FE6A;0025;0025; +FE6B;FE6B;FE6B;0040;0040; +FE70;FE70;FE70;0020 064B;0020 064B; +FE71;FE71;FE71;0640 064B;0640 064B; +FE72;FE72;FE72;0020 064C;0020 064C; +FE74;FE74;FE74;0020 064D;0020 064D; +FE76;FE76;FE76;0020 064E;0020 064E; +FE77;FE77;FE77;0640 064E;0640 064E; +FE78;FE78;FE78;0020 064F;0020 064F; +FE79;FE79;FE79;0640 064F;0640 064F; +FE7A;FE7A;FE7A;0020 0650;0020 0650; +FE7B;FE7B;FE7B;0640 0650;0640 0650; +FE7C;FE7C;FE7C;0020 0651;0020 0651; +FE7D;FE7D;FE7D;0640 0651;0640 0651; +FE7E;FE7E;FE7E;0020 0652;0020 0652; +FE7F;FE7F;FE7F;0640 0652;0640 0652; +FE80;FE80;FE80;0621;0621; +FE81;FE81;FE81;0622;0627 0653; +FE82;FE82;FE82;0622;0627 0653; +FE83;FE83;FE83;0623;0627 0654; +FE84;FE84;FE84;0623;0627 0654; +FE85;FE85;FE85;0624;0648 0654; +FE86;FE86;FE86;0624;0648 0654; +FE87;FE87;FE87;0625;0627 0655; +FE88;FE88;FE88;0625;0627 0655; +FE89;FE89;FE89;0626;064A 0654; +FE8A;FE8A;FE8A;0626;064A 0654; +FE8B;FE8B;FE8B;0626;064A 0654; +FE8C;FE8C;FE8C;0626;064A 0654; +FE8D;FE8D;FE8D;0627;0627; +FE8E;FE8E;FE8E;0627;0627; +FE8F;FE8F;FE8F;0628;0628; +FE90;FE90;FE90;0628;0628; +FE91;FE91;FE91;0628;0628; +FE92;FE92;FE92;0628;0628; +FE93;FE93;FE93;0629;0629; +FE94;FE94;FE94;0629;0629; +FE95;FE95;FE95;062A;062A; +FE96;FE96;FE96;062A;062A; +FE97;FE97;FE97;062A;062A; +FE98;FE98;FE98;062A;062A; +FE99;FE99;FE99;062B;062B; +FE9A;FE9A;FE9A;062B;062B; +FE9B;FE9B;FE9B;062B;062B; +FE9C;FE9C;FE9C;062B;062B; +FE9D;FE9D;FE9D;062C;062C; +FE9E;FE9E;FE9E;062C;062C; +FE9F;FE9F;FE9F;062C;062C; +FEA0;FEA0;FEA0;062C;062C; +FEA1;FEA1;FEA1;062D;062D; +FEA2;FEA2;FEA2;062D;062D; +FEA3;FEA3;FEA3;062D;062D; +FEA4;FEA4;FEA4;062D;062D; +FEA5;FEA5;FEA5;062E;062E; +FEA6;FEA6;FEA6;062E;062E; +FEA7;FEA7;FEA7;062E;062E; +FEA8;FEA8;FEA8;062E;062E; +FEA9;FEA9;FEA9;062F;062F; +FEAA;FEAA;FEAA;062F;062F; +FEAB;FEAB;FEAB;0630;0630; +FEAC;FEAC;FEAC;0630;0630; +FEAD;FEAD;FEAD;0631;0631; +FEAE;FEAE;FEAE;0631;0631; +FEAF;FEAF;FEAF;0632;0632; +FEB0;FEB0;FEB0;0632;0632; +FEB1;FEB1;FEB1;0633;0633; +FEB2;FEB2;FEB2;0633;0633; +FEB3;FEB3;FEB3;0633;0633; +FEB4;FEB4;FEB4;0633;0633; +FEB5;FEB5;FEB5;0634;0634; +FEB6;FEB6;FEB6;0634;0634; +FEB7;FEB7;FEB7;0634;0634; +FEB8;FEB8;FEB8;0634;0634; +FEB9;FEB9;FEB9;0635;0635; +FEBA;FEBA;FEBA;0635;0635; +FEBB;FEBB;FEBB;0635;0635; +FEBC;FEBC;FEBC;0635;0635; +FEBD;FEBD;FEBD;0636;0636; +FEBE;FEBE;FEBE;0636;0636; +FEBF;FEBF;FEBF;0636;0636; +FEC0;FEC0;FEC0;0636;0636; +FEC1;FEC1;FEC1;0637;0637; +FEC2;FEC2;FEC2;0637;0637; +FEC3;FEC3;FEC3;0637;0637; +FEC4;FEC4;FEC4;0637;0637; +FEC5;FEC5;FEC5;0638;0638; +FEC6;FEC6;FEC6;0638;0638; +FEC7;FEC7;FEC7;0638;0638; +FEC8;FEC8;FEC8;0638;0638; +FEC9;FEC9;FEC9;0639;0639; +FECA;FECA;FECA;0639;0639; +FECB;FECB;FECB;0639;0639; +FECC;FECC;FECC;0639;0639; +FECD;FECD;FECD;063A;063A; +FECE;FECE;FECE;063A;063A; +FECF;FECF;FECF;063A;063A; +FED0;FED0;FED0;063A;063A; +FED1;FED1;FED1;0641;0641; +FED2;FED2;FED2;0641;0641; +FED3;FED3;FED3;0641;0641; +FED4;FED4;FED4;0641;0641; +FED5;FED5;FED5;0642;0642; +FED6;FED6;FED6;0642;0642; +FED7;FED7;FED7;0642;0642; +FED8;FED8;FED8;0642;0642; +FED9;FED9;FED9;0643;0643; +FEDA;FEDA;FEDA;0643;0643; +FEDB;FEDB;FEDB;0643;0643; +FEDC;FEDC;FEDC;0643;0643; +FEDD;FEDD;FEDD;0644;0644; +FEDE;FEDE;FEDE;0644;0644; +FEDF;FEDF;FEDF;0644;0644; +FEE0;FEE0;FEE0;0644;0644; +FEE1;FEE1;FEE1;0645;0645; +FEE2;FEE2;FEE2;0645;0645; +FEE3;FEE3;FEE3;0645;0645; +FEE4;FEE4;FEE4;0645;0645; +FEE5;FEE5;FEE5;0646;0646; +FEE6;FEE6;FEE6;0646;0646; +FEE7;FEE7;FEE7;0646;0646; +FEE8;FEE8;FEE8;0646;0646; +FEE9;FEE9;FEE9;0647;0647; +FEEA;FEEA;FEEA;0647;0647; +FEEB;FEEB;FEEB;0647;0647; +FEEC;FEEC;FEEC;0647;0647; +FEED;FEED;FEED;0648;0648; +FEEE;FEEE;FEEE;0648;0648; +FEEF;FEEF;FEEF;0649;0649; +FEF0;FEF0;FEF0;0649;0649; +FEF1;FEF1;FEF1;064A;064A; +FEF2;FEF2;FEF2;064A;064A; +FEF3;FEF3;FEF3;064A;064A; +FEF4;FEF4;FEF4;064A;064A; +FEF5;FEF5;FEF5;0644 0622;0644 0627 0653; +FEF6;FEF6;FEF6;0644 0622;0644 0627 0653; +FEF7;FEF7;FEF7;0644 0623;0644 0627 0654; +FEF8;FEF8;FEF8;0644 0623;0644 0627 0654; +FEF9;FEF9;FEF9;0644 0625;0644 0627 0655; +FEFA;FEFA;FEFA;0644 0625;0644 0627 0655; +FEFB;FEFB;FEFB;0644 0627;0644 0627; +FEFC;FEFC;FEFC;0644 0627;0644 0627; +FF01;FF01;FF01;0021;0021; +FF02;FF02;FF02;0022;0022; +FF03;FF03;FF03;0023;0023; +FF04;FF04;FF04;0024;0024; +FF05;FF05;FF05;0025;0025; +FF06;FF06;FF06;0026;0026; +FF07;FF07;FF07;0027;0027; +FF08;FF08;FF08;0028;0028; +FF09;FF09;FF09;0029;0029; +FF0A;FF0A;FF0A;002A;002A; +FF0B;FF0B;FF0B;002B;002B; +FF0C;FF0C;FF0C;002C;002C; +FF0D;FF0D;FF0D;002D;002D; +FF0E;FF0E;FF0E;002E;002E; +FF0F;FF0F;FF0F;002F;002F; +FF10;FF10;FF10;0030;0030; +FF11;FF11;FF11;0031;0031; +FF12;FF12;FF12;0032;0032; +FF13;FF13;FF13;0033;0033; +FF14;FF14;FF14;0034;0034; +FF15;FF15;FF15;0035;0035; +FF16;FF16;FF16;0036;0036; +FF17;FF17;FF17;0037;0037; +FF18;FF18;FF18;0038;0038; +FF19;FF19;FF19;0039;0039; +FF1A;FF1A;FF1A;003A;003A; +FF1B;FF1B;FF1B;003B;003B; +FF1C;FF1C;FF1C;003C;003C; +FF1D;FF1D;FF1D;003D;003D; +FF1E;FF1E;FF1E;003E;003E; +FF1F;FF1F;FF1F;003F;003F; +FF20;FF20;FF20;0040;0040; +FF21;FF21;FF21;0041;0041; +FF22;FF22;FF22;0042;0042; +FF23;FF23;FF23;0043;0043; +FF24;FF24;FF24;0044;0044; +FF25;FF25;FF25;0045;0045; +FF26;FF26;FF26;0046;0046; +FF27;FF27;FF27;0047;0047; +FF28;FF28;FF28;0048;0048; +FF29;FF29;FF29;0049;0049; +FF2A;FF2A;FF2A;004A;004A; +FF2B;FF2B;FF2B;004B;004B; +FF2C;FF2C;FF2C;004C;004C; +FF2D;FF2D;FF2D;004D;004D; +FF2E;FF2E;FF2E;004E;004E; +FF2F;FF2F;FF2F;004F;004F; +FF30;FF30;FF30;0050;0050; +FF31;FF31;FF31;0051;0051; +FF32;FF32;FF32;0052;0052; +FF33;FF33;FF33;0053;0053; +FF34;FF34;FF34;0054;0054; +FF35;FF35;FF35;0055;0055; +FF36;FF36;FF36;0056;0056; +FF37;FF37;FF37;0057;0057; +FF38;FF38;FF38;0058;0058; +FF39;FF39;FF39;0059;0059; +FF3A;FF3A;FF3A;005A;005A; +FF3B;FF3B;FF3B;005B;005B; +FF3C;FF3C;FF3C;005C;005C; +FF3D;FF3D;FF3D;005D;005D; +FF3E;FF3E;FF3E;005E;005E; +FF3F;FF3F;FF3F;005F;005F; +FF40;FF40;FF40;0060;0060; +FF41;FF41;FF41;0061;0061; +FF42;FF42;FF42;0062;0062; +FF43;FF43;FF43;0063;0063; +FF44;FF44;FF44;0064;0064; +FF45;FF45;FF45;0065;0065; +FF46;FF46;FF46;0066;0066; +FF47;FF47;FF47;0067;0067; +FF48;FF48;FF48;0068;0068; +FF49;FF49;FF49;0069;0069; +FF4A;FF4A;FF4A;006A;006A; +FF4B;FF4B;FF4B;006B;006B; +FF4C;FF4C;FF4C;006C;006C; +FF4D;FF4D;FF4D;006D;006D; +FF4E;FF4E;FF4E;006E;006E; +FF4F;FF4F;FF4F;006F;006F; +FF50;FF50;FF50;0070;0070; +FF51;FF51;FF51;0071;0071; +FF52;FF52;FF52;0072;0072; +FF53;FF53;FF53;0073;0073; +FF54;FF54;FF54;0074;0074; +FF55;FF55;FF55;0075;0075; +FF56;FF56;FF56;0076;0076; +FF57;FF57;FF57;0077;0077; +FF58;FF58;FF58;0078;0078; +FF59;FF59;FF59;0079;0079; +FF5A;FF5A;FF5A;007A;007A; +FF5B;FF5B;FF5B;007B;007B; +FF5C;FF5C;FF5C;007C;007C; +FF5D;FF5D;FF5D;007D;007D; +FF5E;FF5E;FF5E;007E;007E; +FF5F;FF5F;FF5F;2985;2985; +FF60;FF60;FF60;2986;2986; +FF61;FF61;FF61;3002;3002; +FF62;FF62;FF62;300C;300C; +FF63;FF63;FF63;300D;300D; +FF64;FF64;FF64;3001;3001; +FF65;FF65;FF65;30FB;30FB; +FF66;FF66;FF66;30F2;30F2; +FF67;FF67;FF67;30A1;30A1; +FF68;FF68;FF68;30A3;30A3; +FF69;FF69;FF69;30A5;30A5; +FF6A;FF6A;FF6A;30A7;30A7; +FF6B;FF6B;FF6B;30A9;30A9; +FF6C;FF6C;FF6C;30E3;30E3; +FF6D;FF6D;FF6D;30E5;30E5; +FF6E;FF6E;FF6E;30E7;30E7; +FF6F;FF6F;FF6F;30C3;30C3; +FF70;FF70;FF70;30FC;30FC; +FF71;FF71;FF71;30A2;30A2; +FF72;FF72;FF72;30A4;30A4; +FF73;FF73;FF73;30A6;30A6; +FF74;FF74;FF74;30A8;30A8; +FF75;FF75;FF75;30AA;30AA; +FF76;FF76;FF76;30AB;30AB; +FF77;FF77;FF77;30AD;30AD; +FF78;FF78;FF78;30AF;30AF; +FF79;FF79;FF79;30B1;30B1; +FF7A;FF7A;FF7A;30B3;30B3; +FF7B;FF7B;FF7B;30B5;30B5; +FF7C;FF7C;FF7C;30B7;30B7; +FF7D;FF7D;FF7D;30B9;30B9; +FF7E;FF7E;FF7E;30BB;30BB; +FF7F;FF7F;FF7F;30BD;30BD; +FF80;FF80;FF80;30BF;30BF; +FF81;FF81;FF81;30C1;30C1; +FF82;FF82;FF82;30C4;30C4; +FF83;FF83;FF83;30C6;30C6; +FF84;FF84;FF84;30C8;30C8; +FF85;FF85;FF85;30CA;30CA; +FF86;FF86;FF86;30CB;30CB; +FF87;FF87;FF87;30CC;30CC; +FF88;FF88;FF88;30CD;30CD; +FF89;FF89;FF89;30CE;30CE; +FF8A;FF8A;FF8A;30CF;30CF; +FF8B;FF8B;FF8B;30D2;30D2; +FF8C;FF8C;FF8C;30D5;30D5; +FF8D;FF8D;FF8D;30D8;30D8; +FF8E;FF8E;FF8E;30DB;30DB; +FF8F;FF8F;FF8F;30DE;30DE; +FF90;FF90;FF90;30DF;30DF; +FF91;FF91;FF91;30E0;30E0; +FF92;FF92;FF92;30E1;30E1; +FF93;FF93;FF93;30E2;30E2; +FF94;FF94;FF94;30E4;30E4; +FF95;FF95;FF95;30E6;30E6; +FF96;FF96;FF96;30E8;30E8; +FF97;FF97;FF97;30E9;30E9; +FF98;FF98;FF98;30EA;30EA; +FF99;FF99;FF99;30EB;30EB; +FF9A;FF9A;FF9A;30EC;30EC; +FF9B;FF9B;FF9B;30ED;30ED; +FF9C;FF9C;FF9C;30EF;30EF; +FF9D;FF9D;FF9D;30F3;30F3; +FF9E;FF9E;FF9E;3099;3099; +FF9F;FF9F;FF9F;309A;309A; +FFA0;FFA0;FFA0;1160;1160; +FFA1;FFA1;FFA1;1100;1100; +FFA2;FFA2;FFA2;1101;1101; +FFA3;FFA3;FFA3;11AA;11AA; +FFA4;FFA4;FFA4;1102;1102; +FFA5;FFA5;FFA5;11AC;11AC; +FFA6;FFA6;FFA6;11AD;11AD; +FFA7;FFA7;FFA7;1103;1103; +FFA8;FFA8;FFA8;1104;1104; +FFA9;FFA9;FFA9;1105;1105; +FFAA;FFAA;FFAA;11B0;11B0; +FFAB;FFAB;FFAB;11B1;11B1; +FFAC;FFAC;FFAC;11B2;11B2; +FFAD;FFAD;FFAD;11B3;11B3; +FFAE;FFAE;FFAE;11B4;11B4; +FFAF;FFAF;FFAF;11B5;11B5; +FFB0;FFB0;FFB0;111A;111A; +FFB1;FFB1;FFB1;1106;1106; +FFB2;FFB2;FFB2;1107;1107; +FFB3;FFB3;FFB3;1108;1108; +FFB4;FFB4;FFB4;1121;1121; +FFB5;FFB5;FFB5;1109;1109; +FFB6;FFB6;FFB6;110A;110A; +FFB7;FFB7;FFB7;110B;110B; +FFB8;FFB8;FFB8;110C;110C; +FFB9;FFB9;FFB9;110D;110D; +FFBA;FFBA;FFBA;110E;110E; +FFBB;FFBB;FFBB;110F;110F; +FFBC;FFBC;FFBC;1110;1110; +FFBD;FFBD;FFBD;1111;1111; +FFBE;FFBE;FFBE;1112;1112; +FFC2;FFC2;FFC2;1161;1161; +FFC3;FFC3;FFC3;1162;1162; +FFC4;FFC4;FFC4;1163;1163; +FFC5;FFC5;FFC5;1164;1164; +FFC6;FFC6;FFC6;1165;1165; +FFC7;FFC7;FFC7;1166;1166; +FFCA;FFCA;FFCA;1167;1167; +FFCB;FFCB;FFCB;1168;1168; +FFCC;FFCC;FFCC;1169;1169; +FFCD;FFCD;FFCD;116A;116A; +FFCE;FFCE;FFCE;116B;116B; +FFCF;FFCF;FFCF;116C;116C; +FFD2;FFD2;FFD2;116D;116D; +FFD3;FFD3;FFD3;116E;116E; +FFD4;FFD4;FFD4;116F;116F; +FFD5;FFD5;FFD5;1170;1170; +FFD6;FFD6;FFD6;1171;1171; +FFD7;FFD7;FFD7;1172;1172; +FFDA;FFDA;FFDA;1173;1173; +FFDB;FFDB;FFDB;1174;1174; +FFDC;FFDC;FFDC;1175;1175; +FFE0;FFE0;FFE0;00A2;00A2; +FFE1;FFE1;FFE1;00A3;00A3; +FFE2;FFE2;FFE2;00AC;00AC; +FFE3;FFE3;FFE3;0020 0304;0020 0304; +FFE4;FFE4;FFE4;00A6;00A6; +FFE5;FFE5;FFE5;00A5;00A5; +FFE6;FFE6;FFE6;20A9;20A9; +FFE8;FFE8;FFE8;2502;2502; +FFE9;FFE9;FFE9;2190;2190; +FFEA;FFEA;FFEA;2191;2191; +FFEB;FFEB;FFEB;2192;2192; +FFEC;FFEC;FFEC;2193;2193; +FFED;FFED;FFED;25A0;25A0; +FFEE;FFEE;FFEE;25CB;25CB; +1109A;1109A;11099 110BA;1109A;11099 110BA; +1109C;1109C;1109B 110BA;1109C;1109B 110BA; +110AB;110AB;110A5 110BA;110AB;110A5 110BA; +1112E;1112E;11131 11127;1112E;11131 11127; +1112F;1112F;11132 11127;1112F;11132 11127; +1134B;1134B;11347 1133E;1134B;11347 1133E; +1134C;1134C;11347 11357;1134C;11347 11357; +114BB;114BB;114B9 114BA;114BB;114B9 114BA; +114BC;114BC;114B9 114B0;114BC;114B9 114B0; +114BE;114BE;114B9 114BD;114BE;114B9 114BD; +115BA;115BA;115B8 115AF;115BA;115B8 115AF; +115BB;115BB;115B9 115AF;115BB;115B9 115AF; +1D15E;1D157 1D165;1D157 1D165;1D157 1D165;1D157 1D165; +1D15F;1D158 1D165;1D158 1D165;1D158 1D165;1D158 1D165; +1D160;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E; +1D161;1D158 1D165 1D16F;1D158 1D165 1D16F;1D158 1D165 1D16F;1D158 1D165 1D16F; +1D162;1D158 1D165 1D170;1D158 1D165 1D170;1D158 1D165 1D170;1D158 1D165 1D170; +1D163;1D158 1D165 1D171;1D158 1D165 1D171;1D158 1D165 1D171;1D158 1D165 1D171; +1D164;1D158 1D165 1D172;1D158 1D165 1D172;1D158 1D165 1D172;1D158 1D165 1D172; +1D1BB;1D1B9 1D165;1D1B9 1D165;1D1B9 1D165;1D1B9 1D165; +1D1BC;1D1BA 1D165;1D1BA 1D165;1D1BA 1D165;1D1BA 1D165; +1D1BD;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E; +1D1BE;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E; +1D1BF;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F; +1D1C0;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F; +1D400;1D400;1D400;0041;0041; +1D401;1D401;1D401;0042;0042; +1D402;1D402;1D402;0043;0043; +1D403;1D403;1D403;0044;0044; +1D404;1D404;1D404;0045;0045; +1D405;1D405;1D405;0046;0046; +1D406;1D406;1D406;0047;0047; +1D407;1D407;1D407;0048;0048; +1D408;1D408;1D408;0049;0049; +1D409;1D409;1D409;004A;004A; +1D40A;1D40A;1D40A;004B;004B; +1D40B;1D40B;1D40B;004C;004C; +1D40C;1D40C;1D40C;004D;004D; +1D40D;1D40D;1D40D;004E;004E; +1D40E;1D40E;1D40E;004F;004F; +1D40F;1D40F;1D40F;0050;0050; +1D410;1D410;1D410;0051;0051; +1D411;1D411;1D411;0052;0052; +1D412;1D412;1D412;0053;0053; +1D413;1D413;1D413;0054;0054; +1D414;1D414;1D414;0055;0055; +1D415;1D415;1D415;0056;0056; +1D416;1D416;1D416;0057;0057; +1D417;1D417;1D417;0058;0058; +1D418;1D418;1D418;0059;0059; +1D419;1D419;1D419;005A;005A; +1D41A;1D41A;1D41A;0061;0061; +1D41B;1D41B;1D41B;0062;0062; +1D41C;1D41C;1D41C;0063;0063; +1D41D;1D41D;1D41D;0064;0064; +1D41E;1D41E;1D41E;0065;0065; +1D41F;1D41F;1D41F;0066;0066; +1D420;1D420;1D420;0067;0067; +1D421;1D421;1D421;0068;0068; +1D422;1D422;1D422;0069;0069; +1D423;1D423;1D423;006A;006A; +1D424;1D424;1D424;006B;006B; +1D425;1D425;1D425;006C;006C; +1D426;1D426;1D426;006D;006D; +1D427;1D427;1D427;006E;006E; +1D428;1D428;1D428;006F;006F; +1D429;1D429;1D429;0070;0070; +1D42A;1D42A;1D42A;0071;0071; +1D42B;1D42B;1D42B;0072;0072; +1D42C;1D42C;1D42C;0073;0073; +1D42D;1D42D;1D42D;0074;0074; +1D42E;1D42E;1D42E;0075;0075; +1D42F;1D42F;1D42F;0076;0076; +1D430;1D430;1D430;0077;0077; +1D431;1D431;1D431;0078;0078; +1D432;1D432;1D432;0079;0079; +1D433;1D433;1D433;007A;007A; +1D434;1D434;1D434;0041;0041; +1D435;1D435;1D435;0042;0042; +1D436;1D436;1D436;0043;0043; +1D437;1D437;1D437;0044;0044; +1D438;1D438;1D438;0045;0045; +1D439;1D439;1D439;0046;0046; +1D43A;1D43A;1D43A;0047;0047; +1D43B;1D43B;1D43B;0048;0048; +1D43C;1D43C;1D43C;0049;0049; +1D43D;1D43D;1D43D;004A;004A; +1D43E;1D43E;1D43E;004B;004B; +1D43F;1D43F;1D43F;004C;004C; +1D440;1D440;1D440;004D;004D; +1D441;1D441;1D441;004E;004E; +1D442;1D442;1D442;004F;004F; +1D443;1D443;1D443;0050;0050; +1D444;1D444;1D444;0051;0051; +1D445;1D445;1D445;0052;0052; +1D446;1D446;1D446;0053;0053; +1D447;1D447;1D447;0054;0054; +1D448;1D448;1D448;0055;0055; +1D449;1D449;1D449;0056;0056; +1D44A;1D44A;1D44A;0057;0057; +1D44B;1D44B;1D44B;0058;0058; +1D44C;1D44C;1D44C;0059;0059; +1D44D;1D44D;1D44D;005A;005A; +1D44E;1D44E;1D44E;0061;0061; +1D44F;1D44F;1D44F;0062;0062; +1D450;1D450;1D450;0063;0063; +1D451;1D451;1D451;0064;0064; +1D452;1D452;1D452;0065;0065; +1D453;1D453;1D453;0066;0066; +1D454;1D454;1D454;0067;0067; +1D456;1D456;1D456;0069;0069; +1D457;1D457;1D457;006A;006A; +1D458;1D458;1D458;006B;006B; +1D459;1D459;1D459;006C;006C; +1D45A;1D45A;1D45A;006D;006D; +1D45B;1D45B;1D45B;006E;006E; +1D45C;1D45C;1D45C;006F;006F; +1D45D;1D45D;1D45D;0070;0070; +1D45E;1D45E;1D45E;0071;0071; +1D45F;1D45F;1D45F;0072;0072; +1D460;1D460;1D460;0073;0073; +1D461;1D461;1D461;0074;0074; +1D462;1D462;1D462;0075;0075; +1D463;1D463;1D463;0076;0076; +1D464;1D464;1D464;0077;0077; +1D465;1D465;1D465;0078;0078; +1D466;1D466;1D466;0079;0079; +1D467;1D467;1D467;007A;007A; +1D468;1D468;1D468;0041;0041; +1D469;1D469;1D469;0042;0042; +1D46A;1D46A;1D46A;0043;0043; +1D46B;1D46B;1D46B;0044;0044; +1D46C;1D46C;1D46C;0045;0045; +1D46D;1D46D;1D46D;0046;0046; +1D46E;1D46E;1D46E;0047;0047; +1D46F;1D46F;1D46F;0048;0048; +1D470;1D470;1D470;0049;0049; +1D471;1D471;1D471;004A;004A; +1D472;1D472;1D472;004B;004B; +1D473;1D473;1D473;004C;004C; +1D474;1D474;1D474;004D;004D; +1D475;1D475;1D475;004E;004E; +1D476;1D476;1D476;004F;004F; +1D477;1D477;1D477;0050;0050; +1D478;1D478;1D478;0051;0051; +1D479;1D479;1D479;0052;0052; +1D47A;1D47A;1D47A;0053;0053; +1D47B;1D47B;1D47B;0054;0054; +1D47C;1D47C;1D47C;0055;0055; +1D47D;1D47D;1D47D;0056;0056; +1D47E;1D47E;1D47E;0057;0057; +1D47F;1D47F;1D47F;0058;0058; +1D480;1D480;1D480;0059;0059; +1D481;1D481;1D481;005A;005A; +1D482;1D482;1D482;0061;0061; +1D483;1D483;1D483;0062;0062; +1D484;1D484;1D484;0063;0063; +1D485;1D485;1D485;0064;0064; +1D486;1D486;1D486;0065;0065; +1D487;1D487;1D487;0066;0066; +1D488;1D488;1D488;0067;0067; +1D489;1D489;1D489;0068;0068; +1D48A;1D48A;1D48A;0069;0069; +1D48B;1D48B;1D48B;006A;006A; +1D48C;1D48C;1D48C;006B;006B; +1D48D;1D48D;1D48D;006C;006C; +1D48E;1D48E;1D48E;006D;006D; +1D48F;1D48F;1D48F;006E;006E; +1D490;1D490;1D490;006F;006F; +1D491;1D491;1D491;0070;0070; +1D492;1D492;1D492;0071;0071; +1D493;1D493;1D493;0072;0072; +1D494;1D494;1D494;0073;0073; +1D495;1D495;1D495;0074;0074; +1D496;1D496;1D496;0075;0075; +1D497;1D497;1D497;0076;0076; +1D498;1D498;1D498;0077;0077; +1D499;1D499;1D499;0078;0078; +1D49A;1D49A;1D49A;0079;0079; +1D49B;1D49B;1D49B;007A;007A; +1D49C;1D49C;1D49C;0041;0041; +1D49E;1D49E;1D49E;0043;0043; +1D49F;1D49F;1D49F;0044;0044; +1D4A2;1D4A2;1D4A2;0047;0047; +1D4A5;1D4A5;1D4A5;004A;004A; +1D4A6;1D4A6;1D4A6;004B;004B; +1D4A9;1D4A9;1D4A9;004E;004E; +1D4AA;1D4AA;1D4AA;004F;004F; +1D4AB;1D4AB;1D4AB;0050;0050; +1D4AC;1D4AC;1D4AC;0051;0051; +1D4AE;1D4AE;1D4AE;0053;0053; +1D4AF;1D4AF;1D4AF;0054;0054; +1D4B0;1D4B0;1D4B0;0055;0055; +1D4B1;1D4B1;1D4B1;0056;0056; +1D4B2;1D4B2;1D4B2;0057;0057; +1D4B3;1D4B3;1D4B3;0058;0058; +1D4B4;1D4B4;1D4B4;0059;0059; +1D4B5;1D4B5;1D4B5;005A;005A; +1D4B6;1D4B6;1D4B6;0061;0061; +1D4B7;1D4B7;1D4B7;0062;0062; +1D4B8;1D4B8;1D4B8;0063;0063; +1D4B9;1D4B9;1D4B9;0064;0064; +1D4BB;1D4BB;1D4BB;0066;0066; +1D4BD;1D4BD;1D4BD;0068;0068; +1D4BE;1D4BE;1D4BE;0069;0069; +1D4BF;1D4BF;1D4BF;006A;006A; +1D4C0;1D4C0;1D4C0;006B;006B; +1D4C1;1D4C1;1D4C1;006C;006C; +1D4C2;1D4C2;1D4C2;006D;006D; +1D4C3;1D4C3;1D4C3;006E;006E; +1D4C5;1D4C5;1D4C5;0070;0070; +1D4C6;1D4C6;1D4C6;0071;0071; +1D4C7;1D4C7;1D4C7;0072;0072; +1D4C8;1D4C8;1D4C8;0073;0073; +1D4C9;1D4C9;1D4C9;0074;0074; +1D4CA;1D4CA;1D4CA;0075;0075; +1D4CB;1D4CB;1D4CB;0076;0076; +1D4CC;1D4CC;1D4CC;0077;0077; +1D4CD;1D4CD;1D4CD;0078;0078; +1D4CE;1D4CE;1D4CE;0079;0079; +1D4CF;1D4CF;1D4CF;007A;007A; +1D4D0;1D4D0;1D4D0;0041;0041; +1D4D1;1D4D1;1D4D1;0042;0042; +1D4D2;1D4D2;1D4D2;0043;0043; +1D4D3;1D4D3;1D4D3;0044;0044; +1D4D4;1D4D4;1D4D4;0045;0045; +1D4D5;1D4D5;1D4D5;0046;0046; +1D4D6;1D4D6;1D4D6;0047;0047; +1D4D7;1D4D7;1D4D7;0048;0048; +1D4D8;1D4D8;1D4D8;0049;0049; +1D4D9;1D4D9;1D4D9;004A;004A; +1D4DA;1D4DA;1D4DA;004B;004B; +1D4DB;1D4DB;1D4DB;004C;004C; +1D4DC;1D4DC;1D4DC;004D;004D; +1D4DD;1D4DD;1D4DD;004E;004E; +1D4DE;1D4DE;1D4DE;004F;004F; +1D4DF;1D4DF;1D4DF;0050;0050; +1D4E0;1D4E0;1D4E0;0051;0051; +1D4E1;1D4E1;1D4E1;0052;0052; +1D4E2;1D4E2;1D4E2;0053;0053; +1D4E3;1D4E3;1D4E3;0054;0054; +1D4E4;1D4E4;1D4E4;0055;0055; +1D4E5;1D4E5;1D4E5;0056;0056; +1D4E6;1D4E6;1D4E6;0057;0057; +1D4E7;1D4E7;1D4E7;0058;0058; +1D4E8;1D4E8;1D4E8;0059;0059; +1D4E9;1D4E9;1D4E9;005A;005A; +1D4EA;1D4EA;1D4EA;0061;0061; +1D4EB;1D4EB;1D4EB;0062;0062; +1D4EC;1D4EC;1D4EC;0063;0063; +1D4ED;1D4ED;1D4ED;0064;0064; +1D4EE;1D4EE;1D4EE;0065;0065; +1D4EF;1D4EF;1D4EF;0066;0066; +1D4F0;1D4F0;1D4F0;0067;0067; +1D4F1;1D4F1;1D4F1;0068;0068; +1D4F2;1D4F2;1D4F2;0069;0069; +1D4F3;1D4F3;1D4F3;006A;006A; +1D4F4;1D4F4;1D4F4;006B;006B; +1D4F5;1D4F5;1D4F5;006C;006C; +1D4F6;1D4F6;1D4F6;006D;006D; +1D4F7;1D4F7;1D4F7;006E;006E; +1D4F8;1D4F8;1D4F8;006F;006F; +1D4F9;1D4F9;1D4F9;0070;0070; +1D4FA;1D4FA;1D4FA;0071;0071; +1D4FB;1D4FB;1D4FB;0072;0072; +1D4FC;1D4FC;1D4FC;0073;0073; +1D4FD;1D4FD;1D4FD;0074;0074; +1D4FE;1D4FE;1D4FE;0075;0075; +1D4FF;1D4FF;1D4FF;0076;0076; +1D500;1D500;1D500;0077;0077; +1D501;1D501;1D501;0078;0078; +1D502;1D502;1D502;0079;0079; +1D503;1D503;1D503;007A;007A; +1D504;1D504;1D504;0041;0041; +1D505;1D505;1D505;0042;0042; +1D507;1D507;1D507;0044;0044; +1D508;1D508;1D508;0045;0045; +1D509;1D509;1D509;0046;0046; +1D50A;1D50A;1D50A;0047;0047; +1D50D;1D50D;1D50D;004A;004A; +1D50E;1D50E;1D50E;004B;004B; +1D50F;1D50F;1D50F;004C;004C; +1D510;1D510;1D510;004D;004D; +1D511;1D511;1D511;004E;004E; +1D512;1D512;1D512;004F;004F; +1D513;1D513;1D513;0050;0050; +1D514;1D514;1D514;0051;0051; +1D516;1D516;1D516;0053;0053; +1D517;1D517;1D517;0054;0054; +1D518;1D518;1D518;0055;0055; +1D519;1D519;1D519;0056;0056; +1D51A;1D51A;1D51A;0057;0057; +1D51B;1D51B;1D51B;0058;0058; +1D51C;1D51C;1D51C;0059;0059; +1D51E;1D51E;1D51E;0061;0061; +1D51F;1D51F;1D51F;0062;0062; +1D520;1D520;1D520;0063;0063; +1D521;1D521;1D521;0064;0064; +1D522;1D522;1D522;0065;0065; +1D523;1D523;1D523;0066;0066; +1D524;1D524;1D524;0067;0067; +1D525;1D525;1D525;0068;0068; +1D526;1D526;1D526;0069;0069; +1D527;1D527;1D527;006A;006A; +1D528;1D528;1D528;006B;006B; +1D529;1D529;1D529;006C;006C; +1D52A;1D52A;1D52A;006D;006D; +1D52B;1D52B;1D52B;006E;006E; +1D52C;1D52C;1D52C;006F;006F; +1D52D;1D52D;1D52D;0070;0070; +1D52E;1D52E;1D52E;0071;0071; +1D52F;1D52F;1D52F;0072;0072; +1D530;1D530;1D530;0073;0073; +1D531;1D531;1D531;0074;0074; +1D532;1D532;1D532;0075;0075; +1D533;1D533;1D533;0076;0076; +1D534;1D534;1D534;0077;0077; +1D535;1D535;1D535;0078;0078; +1D536;1D536;1D536;0079;0079; +1D537;1D537;1D537;007A;007A; +1D538;1D538;1D538;0041;0041; +1D539;1D539;1D539;0042;0042; +1D53B;1D53B;1D53B;0044;0044; +1D53C;1D53C;1D53C;0045;0045; +1D53D;1D53D;1D53D;0046;0046; +1D53E;1D53E;1D53E;0047;0047; +1D540;1D540;1D540;0049;0049; +1D541;1D541;1D541;004A;004A; +1D542;1D542;1D542;004B;004B; +1D543;1D543;1D543;004C;004C; +1D544;1D544;1D544;004D;004D; +1D546;1D546;1D546;004F;004F; +1D54A;1D54A;1D54A;0053;0053; +1D54B;1D54B;1D54B;0054;0054; +1D54C;1D54C;1D54C;0055;0055; +1D54D;1D54D;1D54D;0056;0056; +1D54E;1D54E;1D54E;0057;0057; +1D54F;1D54F;1D54F;0058;0058; +1D550;1D550;1D550;0059;0059; +1D552;1D552;1D552;0061;0061; +1D553;1D553;1D553;0062;0062; +1D554;1D554;1D554;0063;0063; +1D555;1D555;1D555;0064;0064; +1D556;1D556;1D556;0065;0065; +1D557;1D557;1D557;0066;0066; +1D558;1D558;1D558;0067;0067; +1D559;1D559;1D559;0068;0068; +1D55A;1D55A;1D55A;0069;0069; +1D55B;1D55B;1D55B;006A;006A; +1D55C;1D55C;1D55C;006B;006B; +1D55D;1D55D;1D55D;006C;006C; +1D55E;1D55E;1D55E;006D;006D; +1D55F;1D55F;1D55F;006E;006E; +1D560;1D560;1D560;006F;006F; +1D561;1D561;1D561;0070;0070; +1D562;1D562;1D562;0071;0071; +1D563;1D563;1D563;0072;0072; +1D564;1D564;1D564;0073;0073; +1D565;1D565;1D565;0074;0074; +1D566;1D566;1D566;0075;0075; +1D567;1D567;1D567;0076;0076; +1D568;1D568;1D568;0077;0077; +1D569;1D569;1D569;0078;0078; +1D56A;1D56A;1D56A;0079;0079; +1D56B;1D56B;1D56B;007A;007A; +1D56C;1D56C;1D56C;0041;0041; +1D56D;1D56D;1D56D;0042;0042; +1D56E;1D56E;1D56E;0043;0043; +1D56F;1D56F;1D56F;0044;0044; +1D570;1D570;1D570;0045;0045; +1D571;1D571;1D571;0046;0046; +1D572;1D572;1D572;0047;0047; +1D573;1D573;1D573;0048;0048; +1D574;1D574;1D574;0049;0049; +1D575;1D575;1D575;004A;004A; +1D576;1D576;1D576;004B;004B; +1D577;1D577;1D577;004C;004C; +1D578;1D578;1D578;004D;004D; +1D579;1D579;1D579;004E;004E; +1D57A;1D57A;1D57A;004F;004F; +1D57B;1D57B;1D57B;0050;0050; +1D57C;1D57C;1D57C;0051;0051; +1D57D;1D57D;1D57D;0052;0052; +1D57E;1D57E;1D57E;0053;0053; +1D57F;1D57F;1D57F;0054;0054; +1D580;1D580;1D580;0055;0055; +1D581;1D581;1D581;0056;0056; +1D582;1D582;1D582;0057;0057; +1D583;1D583;1D583;0058;0058; +1D584;1D584;1D584;0059;0059; +1D585;1D585;1D585;005A;005A; +1D586;1D586;1D586;0061;0061; +1D587;1D587;1D587;0062;0062; +1D588;1D588;1D588;0063;0063; +1D589;1D589;1D589;0064;0064; +1D58A;1D58A;1D58A;0065;0065; +1D58B;1D58B;1D58B;0066;0066; +1D58C;1D58C;1D58C;0067;0067; +1D58D;1D58D;1D58D;0068;0068; +1D58E;1D58E;1D58E;0069;0069; +1D58F;1D58F;1D58F;006A;006A; +1D590;1D590;1D590;006B;006B; +1D591;1D591;1D591;006C;006C; +1D592;1D592;1D592;006D;006D; +1D593;1D593;1D593;006E;006E; +1D594;1D594;1D594;006F;006F; +1D595;1D595;1D595;0070;0070; +1D596;1D596;1D596;0071;0071; +1D597;1D597;1D597;0072;0072; +1D598;1D598;1D598;0073;0073; +1D599;1D599;1D599;0074;0074; +1D59A;1D59A;1D59A;0075;0075; +1D59B;1D59B;1D59B;0076;0076; +1D59C;1D59C;1D59C;0077;0077; +1D59D;1D59D;1D59D;0078;0078; +1D59E;1D59E;1D59E;0079;0079; +1D59F;1D59F;1D59F;007A;007A; +1D5A0;1D5A0;1D5A0;0041;0041; +1D5A1;1D5A1;1D5A1;0042;0042; +1D5A2;1D5A2;1D5A2;0043;0043; +1D5A3;1D5A3;1D5A3;0044;0044; +1D5A4;1D5A4;1D5A4;0045;0045; +1D5A5;1D5A5;1D5A5;0046;0046; +1D5A6;1D5A6;1D5A6;0047;0047; +1D5A7;1D5A7;1D5A7;0048;0048; +1D5A8;1D5A8;1D5A8;0049;0049; +1D5A9;1D5A9;1D5A9;004A;004A; +1D5AA;1D5AA;1D5AA;004B;004B; +1D5AB;1D5AB;1D5AB;004C;004C; +1D5AC;1D5AC;1D5AC;004D;004D; +1D5AD;1D5AD;1D5AD;004E;004E; +1D5AE;1D5AE;1D5AE;004F;004F; +1D5AF;1D5AF;1D5AF;0050;0050; +1D5B0;1D5B0;1D5B0;0051;0051; +1D5B1;1D5B1;1D5B1;0052;0052; +1D5B2;1D5B2;1D5B2;0053;0053; +1D5B3;1D5B3;1D5B3;0054;0054; +1D5B4;1D5B4;1D5B4;0055;0055; +1D5B5;1D5B5;1D5B5;0056;0056; +1D5B6;1D5B6;1D5B6;0057;0057; +1D5B7;1D5B7;1D5B7;0058;0058; +1D5B8;1D5B8;1D5B8;0059;0059; +1D5B9;1D5B9;1D5B9;005A;005A; +1D5BA;1D5BA;1D5BA;0061;0061; +1D5BB;1D5BB;1D5BB;0062;0062; +1D5BC;1D5BC;1D5BC;0063;0063; +1D5BD;1D5BD;1D5BD;0064;0064; +1D5BE;1D5BE;1D5BE;0065;0065; +1D5BF;1D5BF;1D5BF;0066;0066; +1D5C0;1D5C0;1D5C0;0067;0067; +1D5C1;1D5C1;1D5C1;0068;0068; +1D5C2;1D5C2;1D5C2;0069;0069; +1D5C3;1D5C3;1D5C3;006A;006A; +1D5C4;1D5C4;1D5C4;006B;006B; +1D5C5;1D5C5;1D5C5;006C;006C; +1D5C6;1D5C6;1D5C6;006D;006D; +1D5C7;1D5C7;1D5C7;006E;006E; +1D5C8;1D5C8;1D5C8;006F;006F; +1D5C9;1D5C9;1D5C9;0070;0070; +1D5CA;1D5CA;1D5CA;0071;0071; +1D5CB;1D5CB;1D5CB;0072;0072; +1D5CC;1D5CC;1D5CC;0073;0073; +1D5CD;1D5CD;1D5CD;0074;0074; +1D5CE;1D5CE;1D5CE;0075;0075; +1D5CF;1D5CF;1D5CF;0076;0076; +1D5D0;1D5D0;1D5D0;0077;0077; +1D5D1;1D5D1;1D5D1;0078;0078; +1D5D2;1D5D2;1D5D2;0079;0079; +1D5D3;1D5D3;1D5D3;007A;007A; +1D5D4;1D5D4;1D5D4;0041;0041; +1D5D5;1D5D5;1D5D5;0042;0042; +1D5D6;1D5D6;1D5D6;0043;0043; +1D5D7;1D5D7;1D5D7;0044;0044; +1D5D8;1D5D8;1D5D8;0045;0045; +1D5D9;1D5D9;1D5D9;0046;0046; +1D5DA;1D5DA;1D5DA;0047;0047; +1D5DB;1D5DB;1D5DB;0048;0048; +1D5DC;1D5DC;1D5DC;0049;0049; +1D5DD;1D5DD;1D5DD;004A;004A; +1D5DE;1D5DE;1D5DE;004B;004B; +1D5DF;1D5DF;1D5DF;004C;004C; +1D5E0;1D5E0;1D5E0;004D;004D; +1D5E1;1D5E1;1D5E1;004E;004E; +1D5E2;1D5E2;1D5E2;004F;004F; +1D5E3;1D5E3;1D5E3;0050;0050; +1D5E4;1D5E4;1D5E4;0051;0051; +1D5E5;1D5E5;1D5E5;0052;0052; +1D5E6;1D5E6;1D5E6;0053;0053; +1D5E7;1D5E7;1D5E7;0054;0054; +1D5E8;1D5E8;1D5E8;0055;0055; +1D5E9;1D5E9;1D5E9;0056;0056; +1D5EA;1D5EA;1D5EA;0057;0057; +1D5EB;1D5EB;1D5EB;0058;0058; +1D5EC;1D5EC;1D5EC;0059;0059; +1D5ED;1D5ED;1D5ED;005A;005A; +1D5EE;1D5EE;1D5EE;0061;0061; +1D5EF;1D5EF;1D5EF;0062;0062; +1D5F0;1D5F0;1D5F0;0063;0063; +1D5F1;1D5F1;1D5F1;0064;0064; +1D5F2;1D5F2;1D5F2;0065;0065; +1D5F3;1D5F3;1D5F3;0066;0066; +1D5F4;1D5F4;1D5F4;0067;0067; +1D5F5;1D5F5;1D5F5;0068;0068; +1D5F6;1D5F6;1D5F6;0069;0069; +1D5F7;1D5F7;1D5F7;006A;006A; +1D5F8;1D5F8;1D5F8;006B;006B; +1D5F9;1D5F9;1D5F9;006C;006C; +1D5FA;1D5FA;1D5FA;006D;006D; +1D5FB;1D5FB;1D5FB;006E;006E; +1D5FC;1D5FC;1D5FC;006F;006F; +1D5FD;1D5FD;1D5FD;0070;0070; +1D5FE;1D5FE;1D5FE;0071;0071; +1D5FF;1D5FF;1D5FF;0072;0072; +1D600;1D600;1D600;0073;0073; +1D601;1D601;1D601;0074;0074; +1D602;1D602;1D602;0075;0075; +1D603;1D603;1D603;0076;0076; +1D604;1D604;1D604;0077;0077; +1D605;1D605;1D605;0078;0078; +1D606;1D606;1D606;0079;0079; +1D607;1D607;1D607;007A;007A; +1D608;1D608;1D608;0041;0041; +1D609;1D609;1D609;0042;0042; +1D60A;1D60A;1D60A;0043;0043; +1D60B;1D60B;1D60B;0044;0044; +1D60C;1D60C;1D60C;0045;0045; +1D60D;1D60D;1D60D;0046;0046; +1D60E;1D60E;1D60E;0047;0047; +1D60F;1D60F;1D60F;0048;0048; +1D610;1D610;1D610;0049;0049; +1D611;1D611;1D611;004A;004A; +1D612;1D612;1D612;004B;004B; +1D613;1D613;1D613;004C;004C; +1D614;1D614;1D614;004D;004D; +1D615;1D615;1D615;004E;004E; +1D616;1D616;1D616;004F;004F; +1D617;1D617;1D617;0050;0050; +1D618;1D618;1D618;0051;0051; +1D619;1D619;1D619;0052;0052; +1D61A;1D61A;1D61A;0053;0053; +1D61B;1D61B;1D61B;0054;0054; +1D61C;1D61C;1D61C;0055;0055; +1D61D;1D61D;1D61D;0056;0056; +1D61E;1D61E;1D61E;0057;0057; +1D61F;1D61F;1D61F;0058;0058; +1D620;1D620;1D620;0059;0059; +1D621;1D621;1D621;005A;005A; +1D622;1D622;1D622;0061;0061; +1D623;1D623;1D623;0062;0062; +1D624;1D624;1D624;0063;0063; +1D625;1D625;1D625;0064;0064; +1D626;1D626;1D626;0065;0065; +1D627;1D627;1D627;0066;0066; +1D628;1D628;1D628;0067;0067; +1D629;1D629;1D629;0068;0068; +1D62A;1D62A;1D62A;0069;0069; +1D62B;1D62B;1D62B;006A;006A; +1D62C;1D62C;1D62C;006B;006B; +1D62D;1D62D;1D62D;006C;006C; +1D62E;1D62E;1D62E;006D;006D; +1D62F;1D62F;1D62F;006E;006E; +1D630;1D630;1D630;006F;006F; +1D631;1D631;1D631;0070;0070; +1D632;1D632;1D632;0071;0071; +1D633;1D633;1D633;0072;0072; +1D634;1D634;1D634;0073;0073; +1D635;1D635;1D635;0074;0074; +1D636;1D636;1D636;0075;0075; +1D637;1D637;1D637;0076;0076; +1D638;1D638;1D638;0077;0077; +1D639;1D639;1D639;0078;0078; +1D63A;1D63A;1D63A;0079;0079; +1D63B;1D63B;1D63B;007A;007A; +1D63C;1D63C;1D63C;0041;0041; +1D63D;1D63D;1D63D;0042;0042; +1D63E;1D63E;1D63E;0043;0043; +1D63F;1D63F;1D63F;0044;0044; +1D640;1D640;1D640;0045;0045; +1D641;1D641;1D641;0046;0046; +1D642;1D642;1D642;0047;0047; +1D643;1D643;1D643;0048;0048; +1D644;1D644;1D644;0049;0049; +1D645;1D645;1D645;004A;004A; +1D646;1D646;1D646;004B;004B; +1D647;1D647;1D647;004C;004C; +1D648;1D648;1D648;004D;004D; +1D649;1D649;1D649;004E;004E; +1D64A;1D64A;1D64A;004F;004F; +1D64B;1D64B;1D64B;0050;0050; +1D64C;1D64C;1D64C;0051;0051; +1D64D;1D64D;1D64D;0052;0052; +1D64E;1D64E;1D64E;0053;0053; +1D64F;1D64F;1D64F;0054;0054; +1D650;1D650;1D650;0055;0055; +1D651;1D651;1D651;0056;0056; +1D652;1D652;1D652;0057;0057; +1D653;1D653;1D653;0058;0058; +1D654;1D654;1D654;0059;0059; +1D655;1D655;1D655;005A;005A; +1D656;1D656;1D656;0061;0061; +1D657;1D657;1D657;0062;0062; +1D658;1D658;1D658;0063;0063; +1D659;1D659;1D659;0064;0064; +1D65A;1D65A;1D65A;0065;0065; +1D65B;1D65B;1D65B;0066;0066; +1D65C;1D65C;1D65C;0067;0067; +1D65D;1D65D;1D65D;0068;0068; +1D65E;1D65E;1D65E;0069;0069; +1D65F;1D65F;1D65F;006A;006A; +1D660;1D660;1D660;006B;006B; +1D661;1D661;1D661;006C;006C; +1D662;1D662;1D662;006D;006D; +1D663;1D663;1D663;006E;006E; +1D664;1D664;1D664;006F;006F; +1D665;1D665;1D665;0070;0070; +1D666;1D666;1D666;0071;0071; +1D667;1D667;1D667;0072;0072; +1D668;1D668;1D668;0073;0073; +1D669;1D669;1D669;0074;0074; +1D66A;1D66A;1D66A;0075;0075; +1D66B;1D66B;1D66B;0076;0076; +1D66C;1D66C;1D66C;0077;0077; +1D66D;1D66D;1D66D;0078;0078; +1D66E;1D66E;1D66E;0079;0079; +1D66F;1D66F;1D66F;007A;007A; +1D670;1D670;1D670;0041;0041; +1D671;1D671;1D671;0042;0042; +1D672;1D672;1D672;0043;0043; +1D673;1D673;1D673;0044;0044; +1D674;1D674;1D674;0045;0045; +1D675;1D675;1D675;0046;0046; +1D676;1D676;1D676;0047;0047; +1D677;1D677;1D677;0048;0048; +1D678;1D678;1D678;0049;0049; +1D679;1D679;1D679;004A;004A; +1D67A;1D67A;1D67A;004B;004B; +1D67B;1D67B;1D67B;004C;004C; +1D67C;1D67C;1D67C;004D;004D; +1D67D;1D67D;1D67D;004E;004E; +1D67E;1D67E;1D67E;004F;004F; +1D67F;1D67F;1D67F;0050;0050; +1D680;1D680;1D680;0051;0051; +1D681;1D681;1D681;0052;0052; +1D682;1D682;1D682;0053;0053; +1D683;1D683;1D683;0054;0054; +1D684;1D684;1D684;0055;0055; +1D685;1D685;1D685;0056;0056; +1D686;1D686;1D686;0057;0057; +1D687;1D687;1D687;0058;0058; +1D688;1D688;1D688;0059;0059; +1D689;1D689;1D689;005A;005A; +1D68A;1D68A;1D68A;0061;0061; +1D68B;1D68B;1D68B;0062;0062; +1D68C;1D68C;1D68C;0063;0063; +1D68D;1D68D;1D68D;0064;0064; +1D68E;1D68E;1D68E;0065;0065; +1D68F;1D68F;1D68F;0066;0066; +1D690;1D690;1D690;0067;0067; +1D691;1D691;1D691;0068;0068; +1D692;1D692;1D692;0069;0069; +1D693;1D693;1D693;006A;006A; +1D694;1D694;1D694;006B;006B; +1D695;1D695;1D695;006C;006C; +1D696;1D696;1D696;006D;006D; +1D697;1D697;1D697;006E;006E; +1D698;1D698;1D698;006F;006F; +1D699;1D699;1D699;0070;0070; +1D69A;1D69A;1D69A;0071;0071; +1D69B;1D69B;1D69B;0072;0072; +1D69C;1D69C;1D69C;0073;0073; +1D69D;1D69D;1D69D;0074;0074; +1D69E;1D69E;1D69E;0075;0075; +1D69F;1D69F;1D69F;0076;0076; +1D6A0;1D6A0;1D6A0;0077;0077; +1D6A1;1D6A1;1D6A1;0078;0078; +1D6A2;1D6A2;1D6A2;0079;0079; +1D6A3;1D6A3;1D6A3;007A;007A; +1D6A4;1D6A4;1D6A4;0131;0131; +1D6A5;1D6A5;1D6A5;0237;0237; +1D6A8;1D6A8;1D6A8;0391;0391; +1D6A9;1D6A9;1D6A9;0392;0392; +1D6AA;1D6AA;1D6AA;0393;0393; +1D6AB;1D6AB;1D6AB;0394;0394; +1D6AC;1D6AC;1D6AC;0395;0395; +1D6AD;1D6AD;1D6AD;0396;0396; +1D6AE;1D6AE;1D6AE;0397;0397; +1D6AF;1D6AF;1D6AF;0398;0398; +1D6B0;1D6B0;1D6B0;0399;0399; +1D6B1;1D6B1;1D6B1;039A;039A; +1D6B2;1D6B2;1D6B2;039B;039B; +1D6B3;1D6B3;1D6B3;039C;039C; +1D6B4;1D6B4;1D6B4;039D;039D; +1D6B5;1D6B5;1D6B5;039E;039E; +1D6B6;1D6B6;1D6B6;039F;039F; +1D6B7;1D6B7;1D6B7;03A0;03A0; +1D6B8;1D6B8;1D6B8;03A1;03A1; +1D6B9;1D6B9;1D6B9;0398;0398; +1D6BA;1D6BA;1D6BA;03A3;03A3; +1D6BB;1D6BB;1D6BB;03A4;03A4; +1D6BC;1D6BC;1D6BC;03A5;03A5; +1D6BD;1D6BD;1D6BD;03A6;03A6; +1D6BE;1D6BE;1D6BE;03A7;03A7; +1D6BF;1D6BF;1D6BF;03A8;03A8; +1D6C0;1D6C0;1D6C0;03A9;03A9; +1D6C1;1D6C1;1D6C1;2207;2207; +1D6C2;1D6C2;1D6C2;03B1;03B1; +1D6C3;1D6C3;1D6C3;03B2;03B2; +1D6C4;1D6C4;1D6C4;03B3;03B3; +1D6C5;1D6C5;1D6C5;03B4;03B4; +1D6C6;1D6C6;1D6C6;03B5;03B5; +1D6C7;1D6C7;1D6C7;03B6;03B6; +1D6C8;1D6C8;1D6C8;03B7;03B7; +1D6C9;1D6C9;1D6C9;03B8;03B8; +1D6CA;1D6CA;1D6CA;03B9;03B9; +1D6CB;1D6CB;1D6CB;03BA;03BA; +1D6CC;1D6CC;1D6CC;03BB;03BB; +1D6CD;1D6CD;1D6CD;03BC;03BC; +1D6CE;1D6CE;1D6CE;03BD;03BD; +1D6CF;1D6CF;1D6CF;03BE;03BE; +1D6D0;1D6D0;1D6D0;03BF;03BF; +1D6D1;1D6D1;1D6D1;03C0;03C0; +1D6D2;1D6D2;1D6D2;03C1;03C1; +1D6D3;1D6D3;1D6D3;03C2;03C2; +1D6D4;1D6D4;1D6D4;03C3;03C3; +1D6D5;1D6D5;1D6D5;03C4;03C4; +1D6D6;1D6D6;1D6D6;03C5;03C5; +1D6D7;1D6D7;1D6D7;03C6;03C6; +1D6D8;1D6D8;1D6D8;03C7;03C7; +1D6D9;1D6D9;1D6D9;03C8;03C8; +1D6DA;1D6DA;1D6DA;03C9;03C9; +1D6DB;1D6DB;1D6DB;2202;2202; +1D6DC;1D6DC;1D6DC;03B5;03B5; +1D6DD;1D6DD;1D6DD;03B8;03B8; +1D6DE;1D6DE;1D6DE;03BA;03BA; +1D6DF;1D6DF;1D6DF;03C6;03C6; +1D6E0;1D6E0;1D6E0;03C1;03C1; +1D6E1;1D6E1;1D6E1;03C0;03C0; +1D6E2;1D6E2;1D6E2;0391;0391; +1D6E3;1D6E3;1D6E3;0392;0392; +1D6E4;1D6E4;1D6E4;0393;0393; +1D6E5;1D6E5;1D6E5;0394;0394; +1D6E6;1D6E6;1D6E6;0395;0395; +1D6E7;1D6E7;1D6E7;0396;0396; +1D6E8;1D6E8;1D6E8;0397;0397; +1D6E9;1D6E9;1D6E9;0398;0398; +1D6EA;1D6EA;1D6EA;0399;0399; +1D6EB;1D6EB;1D6EB;039A;039A; +1D6EC;1D6EC;1D6EC;039B;039B; +1D6ED;1D6ED;1D6ED;039C;039C; +1D6EE;1D6EE;1D6EE;039D;039D; +1D6EF;1D6EF;1D6EF;039E;039E; +1D6F0;1D6F0;1D6F0;039F;039F; +1D6F1;1D6F1;1D6F1;03A0;03A0; +1D6F2;1D6F2;1D6F2;03A1;03A1; +1D6F3;1D6F3;1D6F3;0398;0398; +1D6F4;1D6F4;1D6F4;03A3;03A3; +1D6F5;1D6F5;1D6F5;03A4;03A4; +1D6F6;1D6F6;1D6F6;03A5;03A5; +1D6F7;1D6F7;1D6F7;03A6;03A6; +1D6F8;1D6F8;1D6F8;03A7;03A7; +1D6F9;1D6F9;1D6F9;03A8;03A8; +1D6FA;1D6FA;1D6FA;03A9;03A9; +1D6FB;1D6FB;1D6FB;2207;2207; +1D6FC;1D6FC;1D6FC;03B1;03B1; +1D6FD;1D6FD;1D6FD;03B2;03B2; +1D6FE;1D6FE;1D6FE;03B3;03B3; +1D6FF;1D6FF;1D6FF;03B4;03B4; +1D700;1D700;1D700;03B5;03B5; +1D701;1D701;1D701;03B6;03B6; +1D702;1D702;1D702;03B7;03B7; +1D703;1D703;1D703;03B8;03B8; +1D704;1D704;1D704;03B9;03B9; +1D705;1D705;1D705;03BA;03BA; +1D706;1D706;1D706;03BB;03BB; +1D707;1D707;1D707;03BC;03BC; +1D708;1D708;1D708;03BD;03BD; +1D709;1D709;1D709;03BE;03BE; +1D70A;1D70A;1D70A;03BF;03BF; +1D70B;1D70B;1D70B;03C0;03C0; +1D70C;1D70C;1D70C;03C1;03C1; +1D70D;1D70D;1D70D;03C2;03C2; +1D70E;1D70E;1D70E;03C3;03C3; +1D70F;1D70F;1D70F;03C4;03C4; +1D710;1D710;1D710;03C5;03C5; +1D711;1D711;1D711;03C6;03C6; +1D712;1D712;1D712;03C7;03C7; +1D713;1D713;1D713;03C8;03C8; +1D714;1D714;1D714;03C9;03C9; +1D715;1D715;1D715;2202;2202; +1D716;1D716;1D716;03B5;03B5; +1D717;1D717;1D717;03B8;03B8; +1D718;1D718;1D718;03BA;03BA; +1D719;1D719;1D719;03C6;03C6; +1D71A;1D71A;1D71A;03C1;03C1; +1D71B;1D71B;1D71B;03C0;03C0; +1D71C;1D71C;1D71C;0391;0391; +1D71D;1D71D;1D71D;0392;0392; +1D71E;1D71E;1D71E;0393;0393; +1D71F;1D71F;1D71F;0394;0394; +1D720;1D720;1D720;0395;0395; +1D721;1D721;1D721;0396;0396; +1D722;1D722;1D722;0397;0397; +1D723;1D723;1D723;0398;0398; +1D724;1D724;1D724;0399;0399; +1D725;1D725;1D725;039A;039A; +1D726;1D726;1D726;039B;039B; +1D727;1D727;1D727;039C;039C; +1D728;1D728;1D728;039D;039D; +1D729;1D729;1D729;039E;039E; +1D72A;1D72A;1D72A;039F;039F; +1D72B;1D72B;1D72B;03A0;03A0; +1D72C;1D72C;1D72C;03A1;03A1; +1D72D;1D72D;1D72D;0398;0398; +1D72E;1D72E;1D72E;03A3;03A3; +1D72F;1D72F;1D72F;03A4;03A4; +1D730;1D730;1D730;03A5;03A5; +1D731;1D731;1D731;03A6;03A6; +1D732;1D732;1D732;03A7;03A7; +1D733;1D733;1D733;03A8;03A8; +1D734;1D734;1D734;03A9;03A9; +1D735;1D735;1D735;2207;2207; +1D736;1D736;1D736;03B1;03B1; +1D737;1D737;1D737;03B2;03B2; +1D738;1D738;1D738;03B3;03B3; +1D739;1D739;1D739;03B4;03B4; +1D73A;1D73A;1D73A;03B5;03B5; +1D73B;1D73B;1D73B;03B6;03B6; +1D73C;1D73C;1D73C;03B7;03B7; +1D73D;1D73D;1D73D;03B8;03B8; +1D73E;1D73E;1D73E;03B9;03B9; +1D73F;1D73F;1D73F;03BA;03BA; +1D740;1D740;1D740;03BB;03BB; +1D741;1D741;1D741;03BC;03BC; +1D742;1D742;1D742;03BD;03BD; +1D743;1D743;1D743;03BE;03BE; +1D744;1D744;1D744;03BF;03BF; +1D745;1D745;1D745;03C0;03C0; +1D746;1D746;1D746;03C1;03C1; +1D747;1D747;1D747;03C2;03C2; +1D748;1D748;1D748;03C3;03C3; +1D749;1D749;1D749;03C4;03C4; +1D74A;1D74A;1D74A;03C5;03C5; +1D74B;1D74B;1D74B;03C6;03C6; +1D74C;1D74C;1D74C;03C7;03C7; +1D74D;1D74D;1D74D;03C8;03C8; +1D74E;1D74E;1D74E;03C9;03C9; +1D74F;1D74F;1D74F;2202;2202; +1D750;1D750;1D750;03B5;03B5; +1D751;1D751;1D751;03B8;03B8; +1D752;1D752;1D752;03BA;03BA; +1D753;1D753;1D753;03C6;03C6; +1D754;1D754;1D754;03C1;03C1; +1D755;1D755;1D755;03C0;03C0; +1D756;1D756;1D756;0391;0391; +1D757;1D757;1D757;0392;0392; +1D758;1D758;1D758;0393;0393; +1D759;1D759;1D759;0394;0394; +1D75A;1D75A;1D75A;0395;0395; +1D75B;1D75B;1D75B;0396;0396; +1D75C;1D75C;1D75C;0397;0397; +1D75D;1D75D;1D75D;0398;0398; +1D75E;1D75E;1D75E;0399;0399; +1D75F;1D75F;1D75F;039A;039A; +1D760;1D760;1D760;039B;039B; +1D761;1D761;1D761;039C;039C; +1D762;1D762;1D762;039D;039D; +1D763;1D763;1D763;039E;039E; +1D764;1D764;1D764;039F;039F; +1D765;1D765;1D765;03A0;03A0; +1D766;1D766;1D766;03A1;03A1; +1D767;1D767;1D767;0398;0398; +1D768;1D768;1D768;03A3;03A3; +1D769;1D769;1D769;03A4;03A4; +1D76A;1D76A;1D76A;03A5;03A5; +1D76B;1D76B;1D76B;03A6;03A6; +1D76C;1D76C;1D76C;03A7;03A7; +1D76D;1D76D;1D76D;03A8;03A8; +1D76E;1D76E;1D76E;03A9;03A9; +1D76F;1D76F;1D76F;2207;2207; +1D770;1D770;1D770;03B1;03B1; +1D771;1D771;1D771;03B2;03B2; +1D772;1D772;1D772;03B3;03B3; +1D773;1D773;1D773;03B4;03B4; +1D774;1D774;1D774;03B5;03B5; +1D775;1D775;1D775;03B6;03B6; +1D776;1D776;1D776;03B7;03B7; +1D777;1D777;1D777;03B8;03B8; +1D778;1D778;1D778;03B9;03B9; +1D779;1D779;1D779;03BA;03BA; +1D77A;1D77A;1D77A;03BB;03BB; +1D77B;1D77B;1D77B;03BC;03BC; +1D77C;1D77C;1D77C;03BD;03BD; +1D77D;1D77D;1D77D;03BE;03BE; +1D77E;1D77E;1D77E;03BF;03BF; +1D77F;1D77F;1D77F;03C0;03C0; +1D780;1D780;1D780;03C1;03C1; +1D781;1D781;1D781;03C2;03C2; +1D782;1D782;1D782;03C3;03C3; +1D783;1D783;1D783;03C4;03C4; +1D784;1D784;1D784;03C5;03C5; +1D785;1D785;1D785;03C6;03C6; +1D786;1D786;1D786;03C7;03C7; +1D787;1D787;1D787;03C8;03C8; +1D788;1D788;1D788;03C9;03C9; +1D789;1D789;1D789;2202;2202; +1D78A;1D78A;1D78A;03B5;03B5; +1D78B;1D78B;1D78B;03B8;03B8; +1D78C;1D78C;1D78C;03BA;03BA; +1D78D;1D78D;1D78D;03C6;03C6; +1D78E;1D78E;1D78E;03C1;03C1; +1D78F;1D78F;1D78F;03C0;03C0; +1D790;1D790;1D790;0391;0391; +1D791;1D791;1D791;0392;0392; +1D792;1D792;1D792;0393;0393; +1D793;1D793;1D793;0394;0394; +1D794;1D794;1D794;0395;0395; +1D795;1D795;1D795;0396;0396; +1D796;1D796;1D796;0397;0397; +1D797;1D797;1D797;0398;0398; +1D798;1D798;1D798;0399;0399; +1D799;1D799;1D799;039A;039A; +1D79A;1D79A;1D79A;039B;039B; +1D79B;1D79B;1D79B;039C;039C; +1D79C;1D79C;1D79C;039D;039D; +1D79D;1D79D;1D79D;039E;039E; +1D79E;1D79E;1D79E;039F;039F; +1D79F;1D79F;1D79F;03A0;03A0; +1D7A0;1D7A0;1D7A0;03A1;03A1; +1D7A1;1D7A1;1D7A1;0398;0398; +1D7A2;1D7A2;1D7A2;03A3;03A3; +1D7A3;1D7A3;1D7A3;03A4;03A4; +1D7A4;1D7A4;1D7A4;03A5;03A5; +1D7A5;1D7A5;1D7A5;03A6;03A6; +1D7A6;1D7A6;1D7A6;03A7;03A7; +1D7A7;1D7A7;1D7A7;03A8;03A8; +1D7A8;1D7A8;1D7A8;03A9;03A9; +1D7A9;1D7A9;1D7A9;2207;2207; +1D7AA;1D7AA;1D7AA;03B1;03B1; +1D7AB;1D7AB;1D7AB;03B2;03B2; +1D7AC;1D7AC;1D7AC;03B3;03B3; +1D7AD;1D7AD;1D7AD;03B4;03B4; +1D7AE;1D7AE;1D7AE;03B5;03B5; +1D7AF;1D7AF;1D7AF;03B6;03B6; +1D7B0;1D7B0;1D7B0;03B7;03B7; +1D7B1;1D7B1;1D7B1;03B8;03B8; +1D7B2;1D7B2;1D7B2;03B9;03B9; +1D7B3;1D7B3;1D7B3;03BA;03BA; +1D7B4;1D7B4;1D7B4;03BB;03BB; +1D7B5;1D7B5;1D7B5;03BC;03BC; +1D7B6;1D7B6;1D7B6;03BD;03BD; +1D7B7;1D7B7;1D7B7;03BE;03BE; +1D7B8;1D7B8;1D7B8;03BF;03BF; +1D7B9;1D7B9;1D7B9;03C0;03C0; +1D7BA;1D7BA;1D7BA;03C1;03C1; +1D7BB;1D7BB;1D7BB;03C2;03C2; +1D7BC;1D7BC;1D7BC;03C3;03C3; +1D7BD;1D7BD;1D7BD;03C4;03C4; +1D7BE;1D7BE;1D7BE;03C5;03C5; +1D7BF;1D7BF;1D7BF;03C6;03C6; +1D7C0;1D7C0;1D7C0;03C7;03C7; +1D7C1;1D7C1;1D7C1;03C8;03C8; +1D7C2;1D7C2;1D7C2;03C9;03C9; +1D7C3;1D7C3;1D7C3;2202;2202; +1D7C4;1D7C4;1D7C4;03B5;03B5; +1D7C5;1D7C5;1D7C5;03B8;03B8; +1D7C6;1D7C6;1D7C6;03BA;03BA; +1D7C7;1D7C7;1D7C7;03C6;03C6; +1D7C8;1D7C8;1D7C8;03C1;03C1; +1D7C9;1D7C9;1D7C9;03C0;03C0; +1D7CA;1D7CA;1D7CA;03DC;03DC; +1D7CB;1D7CB;1D7CB;03DD;03DD; +1D7CE;1D7CE;1D7CE;0030;0030; +1D7CF;1D7CF;1D7CF;0031;0031; +1D7D0;1D7D0;1D7D0;0032;0032; +1D7D1;1D7D1;1D7D1;0033;0033; +1D7D2;1D7D2;1D7D2;0034;0034; +1D7D3;1D7D3;1D7D3;0035;0035; +1D7D4;1D7D4;1D7D4;0036;0036; +1D7D5;1D7D5;1D7D5;0037;0037; +1D7D6;1D7D6;1D7D6;0038;0038; +1D7D7;1D7D7;1D7D7;0039;0039; +1D7D8;1D7D8;1D7D8;0030;0030; +1D7D9;1D7D9;1D7D9;0031;0031; +1D7DA;1D7DA;1D7DA;0032;0032; +1D7DB;1D7DB;1D7DB;0033;0033; +1D7DC;1D7DC;1D7DC;0034;0034; +1D7DD;1D7DD;1D7DD;0035;0035; +1D7DE;1D7DE;1D7DE;0036;0036; +1D7DF;1D7DF;1D7DF;0037;0037; +1D7E0;1D7E0;1D7E0;0038;0038; +1D7E1;1D7E1;1D7E1;0039;0039; +1D7E2;1D7E2;1D7E2;0030;0030; +1D7E3;1D7E3;1D7E3;0031;0031; +1D7E4;1D7E4;1D7E4;0032;0032; +1D7E5;1D7E5;1D7E5;0033;0033; +1D7E6;1D7E6;1D7E6;0034;0034; +1D7E7;1D7E7;1D7E7;0035;0035; +1D7E8;1D7E8;1D7E8;0036;0036; +1D7E9;1D7E9;1D7E9;0037;0037; +1D7EA;1D7EA;1D7EA;0038;0038; +1D7EB;1D7EB;1D7EB;0039;0039; +1D7EC;1D7EC;1D7EC;0030;0030; +1D7ED;1D7ED;1D7ED;0031;0031; +1D7EE;1D7EE;1D7EE;0032;0032; +1D7EF;1D7EF;1D7EF;0033;0033; +1D7F0;1D7F0;1D7F0;0034;0034; +1D7F1;1D7F1;1D7F1;0035;0035; +1D7F2;1D7F2;1D7F2;0036;0036; +1D7F3;1D7F3;1D7F3;0037;0037; +1D7F4;1D7F4;1D7F4;0038;0038; +1D7F5;1D7F5;1D7F5;0039;0039; +1D7F6;1D7F6;1D7F6;0030;0030; +1D7F7;1D7F7;1D7F7;0031;0031; +1D7F8;1D7F8;1D7F8;0032;0032; +1D7F9;1D7F9;1D7F9;0033;0033; +1D7FA;1D7FA;1D7FA;0034;0034; +1D7FB;1D7FB;1D7FB;0035;0035; +1D7FC;1D7FC;1D7FC;0036;0036; +1D7FD;1D7FD;1D7FD;0037;0037; +1D7FE;1D7FE;1D7FE;0038;0038; +1D7FF;1D7FF;1D7FF;0039;0039; +1EE00;1EE00;1EE00;0627;0627; +1EE01;1EE01;1EE01;0628;0628; +1EE02;1EE02;1EE02;062C;062C; +1EE03;1EE03;1EE03;062F;062F; +1EE05;1EE05;1EE05;0648;0648; +1EE06;1EE06;1EE06;0632;0632; +1EE07;1EE07;1EE07;062D;062D; +1EE08;1EE08;1EE08;0637;0637; +1EE09;1EE09;1EE09;064A;064A; +1EE0A;1EE0A;1EE0A;0643;0643; +1EE0B;1EE0B;1EE0B;0644;0644; +1EE0C;1EE0C;1EE0C;0645;0645; +1EE0D;1EE0D;1EE0D;0646;0646; +1EE0E;1EE0E;1EE0E;0633;0633; +1EE0F;1EE0F;1EE0F;0639;0639; +1EE10;1EE10;1EE10;0641;0641; +1EE11;1EE11;1EE11;0635;0635; +1EE12;1EE12;1EE12;0642;0642; +1EE13;1EE13;1EE13;0631;0631; +1EE14;1EE14;1EE14;0634;0634; +1EE15;1EE15;1EE15;062A;062A; +1EE16;1EE16;1EE16;062B;062B; +1EE17;1EE17;1EE17;062E;062E; +1EE18;1EE18;1EE18;0630;0630; +1EE19;1EE19;1EE19;0636;0636; +1EE1A;1EE1A;1EE1A;0638;0638; +1EE1B;1EE1B;1EE1B;063A;063A; +1EE1C;1EE1C;1EE1C;066E;066E; +1EE1D;1EE1D;1EE1D;06BA;06BA; +1EE1E;1EE1E;1EE1E;06A1;06A1; +1EE1F;1EE1F;1EE1F;066F;066F; +1EE21;1EE21;1EE21;0628;0628; +1EE22;1EE22;1EE22;062C;062C; +1EE24;1EE24;1EE24;0647;0647; +1EE27;1EE27;1EE27;062D;062D; +1EE29;1EE29;1EE29;064A;064A; +1EE2A;1EE2A;1EE2A;0643;0643; +1EE2B;1EE2B;1EE2B;0644;0644; +1EE2C;1EE2C;1EE2C;0645;0645; +1EE2D;1EE2D;1EE2D;0646;0646; +1EE2E;1EE2E;1EE2E;0633;0633; +1EE2F;1EE2F;1EE2F;0639;0639; +1EE30;1EE30;1EE30;0641;0641; +1EE31;1EE31;1EE31;0635;0635; +1EE32;1EE32;1EE32;0642;0642; +1EE34;1EE34;1EE34;0634;0634; +1EE35;1EE35;1EE35;062A;062A; +1EE36;1EE36;1EE36;062B;062B; +1EE37;1EE37;1EE37;062E;062E; +1EE39;1EE39;1EE39;0636;0636; +1EE3B;1EE3B;1EE3B;063A;063A; +1EE42;1EE42;1EE42;062C;062C; +1EE47;1EE47;1EE47;062D;062D; +1EE49;1EE49;1EE49;064A;064A; +1EE4B;1EE4B;1EE4B;0644;0644; +1EE4D;1EE4D;1EE4D;0646;0646; +1EE4E;1EE4E;1EE4E;0633;0633; +1EE4F;1EE4F;1EE4F;0639;0639; +1EE51;1EE51;1EE51;0635;0635; +1EE52;1EE52;1EE52;0642;0642; +1EE54;1EE54;1EE54;0634;0634; +1EE57;1EE57;1EE57;062E;062E; +1EE59;1EE59;1EE59;0636;0636; +1EE5B;1EE5B;1EE5B;063A;063A; +1EE5D;1EE5D;1EE5D;06BA;06BA; +1EE5F;1EE5F;1EE5F;066F;066F; +1EE61;1EE61;1EE61;0628;0628; +1EE62;1EE62;1EE62;062C;062C; +1EE64;1EE64;1EE64;0647;0647; +1EE67;1EE67;1EE67;062D;062D; +1EE68;1EE68;1EE68;0637;0637; +1EE69;1EE69;1EE69;064A;064A; +1EE6A;1EE6A;1EE6A;0643;0643; +1EE6C;1EE6C;1EE6C;0645;0645; +1EE6D;1EE6D;1EE6D;0646;0646; +1EE6E;1EE6E;1EE6E;0633;0633; +1EE6F;1EE6F;1EE6F;0639;0639; +1EE70;1EE70;1EE70;0641;0641; +1EE71;1EE71;1EE71;0635;0635; +1EE72;1EE72;1EE72;0642;0642; +1EE74;1EE74;1EE74;0634;0634; +1EE75;1EE75;1EE75;062A;062A; +1EE76;1EE76;1EE76;062B;062B; +1EE77;1EE77;1EE77;062E;062E; +1EE79;1EE79;1EE79;0636;0636; +1EE7A;1EE7A;1EE7A;0638;0638; +1EE7B;1EE7B;1EE7B;063A;063A; +1EE7C;1EE7C;1EE7C;066E;066E; +1EE7E;1EE7E;1EE7E;06A1;06A1; +1EE80;1EE80;1EE80;0627;0627; +1EE81;1EE81;1EE81;0628;0628; +1EE82;1EE82;1EE82;062C;062C; +1EE83;1EE83;1EE83;062F;062F; +1EE84;1EE84;1EE84;0647;0647; +1EE85;1EE85;1EE85;0648;0648; +1EE86;1EE86;1EE86;0632;0632; +1EE87;1EE87;1EE87;062D;062D; +1EE88;1EE88;1EE88;0637;0637; +1EE89;1EE89;1EE89;064A;064A; +1EE8B;1EE8B;1EE8B;0644;0644; +1EE8C;1EE8C;1EE8C;0645;0645; +1EE8D;1EE8D;1EE8D;0646;0646; +1EE8E;1EE8E;1EE8E;0633;0633; +1EE8F;1EE8F;1EE8F;0639;0639; +1EE90;1EE90;1EE90;0641;0641; +1EE91;1EE91;1EE91;0635;0635; +1EE92;1EE92;1EE92;0642;0642; +1EE93;1EE93;1EE93;0631;0631; +1EE94;1EE94;1EE94;0634;0634; +1EE95;1EE95;1EE95;062A;062A; +1EE96;1EE96;1EE96;062B;062B; +1EE97;1EE97;1EE97;062E;062E; +1EE98;1EE98;1EE98;0630;0630; +1EE99;1EE99;1EE99;0636;0636; +1EE9A;1EE9A;1EE9A;0638;0638; +1EE9B;1EE9B;1EE9B;063A;063A; +1EEA1;1EEA1;1EEA1;0628;0628; +1EEA2;1EEA2;1EEA2;062C;062C; +1EEA3;1EEA3;1EEA3;062F;062F; +1EEA5;1EEA5;1EEA5;0648;0648; +1EEA6;1EEA6;1EEA6;0632;0632; +1EEA7;1EEA7;1EEA7;062D;062D; +1EEA8;1EEA8;1EEA8;0637;0637; +1EEA9;1EEA9;1EEA9;064A;064A; +1EEAB;1EEAB;1EEAB;0644;0644; +1EEAC;1EEAC;1EEAC;0645;0645; +1EEAD;1EEAD;1EEAD;0646;0646; +1EEAE;1EEAE;1EEAE;0633;0633; +1EEAF;1EEAF;1EEAF;0639;0639; +1EEB0;1EEB0;1EEB0;0641;0641; +1EEB1;1EEB1;1EEB1;0635;0635; +1EEB2;1EEB2;1EEB2;0642;0642; +1EEB3;1EEB3;1EEB3;0631;0631; +1EEB4;1EEB4;1EEB4;0634;0634; +1EEB5;1EEB5;1EEB5;062A;062A; +1EEB6;1EEB6;1EEB6;062B;062B; +1EEB7;1EEB7;1EEB7;062E;062E; +1EEB8;1EEB8;1EEB8;0630;0630; +1EEB9;1EEB9;1EEB9;0636;0636; +1EEBA;1EEBA;1EEBA;0638;0638; +1EEBB;1EEBB;1EEBB;063A;063A; +1F100;1F100;1F100;0030 002E;0030 002E; +1F101;1F101;1F101;0030 002C;0030 002C; +1F102;1F102;1F102;0031 002C;0031 002C; +1F103;1F103;1F103;0032 002C;0032 002C; +1F104;1F104;1F104;0033 002C;0033 002C; +1F105;1F105;1F105;0034 002C;0034 002C; +1F106;1F106;1F106;0035 002C;0035 002C; +1F107;1F107;1F107;0036 002C;0036 002C; +1F108;1F108;1F108;0037 002C;0037 002C; +1F109;1F109;1F109;0038 002C;0038 002C; +1F10A;1F10A;1F10A;0039 002C;0039 002C; +1F110;1F110;1F110;0028 0041 0029;0028 0041 0029; +1F111;1F111;1F111;0028 0042 0029;0028 0042 0029; +1F112;1F112;1F112;0028 0043 0029;0028 0043 0029; +1F113;1F113;1F113;0028 0044 0029;0028 0044 0029; +1F114;1F114;1F114;0028 0045 0029;0028 0045 0029; +1F115;1F115;1F115;0028 0046 0029;0028 0046 0029; +1F116;1F116;1F116;0028 0047 0029;0028 0047 0029; +1F117;1F117;1F117;0028 0048 0029;0028 0048 0029; +1F118;1F118;1F118;0028 0049 0029;0028 0049 0029; +1F119;1F119;1F119;0028 004A 0029;0028 004A 0029; +1F11A;1F11A;1F11A;0028 004B 0029;0028 004B 0029; +1F11B;1F11B;1F11B;0028 004C 0029;0028 004C 0029; +1F11C;1F11C;1F11C;0028 004D 0029;0028 004D 0029; +1F11D;1F11D;1F11D;0028 004E 0029;0028 004E 0029; +1F11E;1F11E;1F11E;0028 004F 0029;0028 004F 0029; +1F11F;1F11F;1F11F;0028 0050 0029;0028 0050 0029; +1F120;1F120;1F120;0028 0051 0029;0028 0051 0029; +1F121;1F121;1F121;0028 0052 0029;0028 0052 0029; +1F122;1F122;1F122;0028 0053 0029;0028 0053 0029; +1F123;1F123;1F123;0028 0054 0029;0028 0054 0029; +1F124;1F124;1F124;0028 0055 0029;0028 0055 0029; +1F125;1F125;1F125;0028 0056 0029;0028 0056 0029; +1F126;1F126;1F126;0028 0057 0029;0028 0057 0029; +1F127;1F127;1F127;0028 0058 0029;0028 0058 0029; +1F128;1F128;1F128;0028 0059 0029;0028 0059 0029; +1F129;1F129;1F129;0028 005A 0029;0028 005A 0029; +1F12A;1F12A;1F12A;3014 0053 3015;3014 0053 3015; +1F12B;1F12B;1F12B;0043;0043; +1F12C;1F12C;1F12C;0052;0052; +1F12D;1F12D;1F12D;0043 0044;0043 0044; +1F12E;1F12E;1F12E;0057 005A;0057 005A; +1F130;1F130;1F130;0041;0041; +1F131;1F131;1F131;0042;0042; +1F132;1F132;1F132;0043;0043; +1F133;1F133;1F133;0044;0044; +1F134;1F134;1F134;0045;0045; +1F135;1F135;1F135;0046;0046; +1F136;1F136;1F136;0047;0047; +1F137;1F137;1F137;0048;0048; +1F138;1F138;1F138;0049;0049; +1F139;1F139;1F139;004A;004A; +1F13A;1F13A;1F13A;004B;004B; +1F13B;1F13B;1F13B;004C;004C; +1F13C;1F13C;1F13C;004D;004D; +1F13D;1F13D;1F13D;004E;004E; +1F13E;1F13E;1F13E;004F;004F; +1F13F;1F13F;1F13F;0050;0050; +1F140;1F140;1F140;0051;0051; +1F141;1F141;1F141;0052;0052; +1F142;1F142;1F142;0053;0053; +1F143;1F143;1F143;0054;0054; +1F144;1F144;1F144;0055;0055; +1F145;1F145;1F145;0056;0056; +1F146;1F146;1F146;0057;0057; +1F147;1F147;1F147;0058;0058; +1F148;1F148;1F148;0059;0059; +1F149;1F149;1F149;005A;005A; +1F14A;1F14A;1F14A;0048 0056;0048 0056; +1F14B;1F14B;1F14B;004D 0056;004D 0056; +1F14C;1F14C;1F14C;0053 0044;0053 0044; +1F14D;1F14D;1F14D;0053 0053;0053 0053; +1F14E;1F14E;1F14E;0050 0050 0056;0050 0050 0056; +1F14F;1F14F;1F14F;0057 0043;0057 0043; +1F16A;1F16A;1F16A;004D 0043;004D 0043; +1F16B;1F16B;1F16B;004D 0044;004D 0044; +1F190;1F190;1F190;0044 004A;0044 004A; +1F200;1F200;1F200;307B 304B;307B 304B; +1F201;1F201;1F201;30B3 30B3;30B3 30B3; +1F202;1F202;1F202;30B5;30B5; +1F210;1F210;1F210;624B;624B; +1F211;1F211;1F211;5B57;5B57; +1F212;1F212;1F212;53CC;53CC; +1F213;1F213;1F213;30C7;30C6 3099; +1F214;1F214;1F214;4E8C;4E8C; +1F215;1F215;1F215;591A;591A; +1F216;1F216;1F216;89E3;89E3; +1F217;1F217;1F217;5929;5929; +1F218;1F218;1F218;4EA4;4EA4; +1F219;1F219;1F219;6620;6620; +1F21A;1F21A;1F21A;7121;7121; +1F21B;1F21B;1F21B;6599;6599; +1F21C;1F21C;1F21C;524D;524D; +1F21D;1F21D;1F21D;5F8C;5F8C; +1F21E;1F21E;1F21E;518D;518D; +1F21F;1F21F;1F21F;65B0;65B0; +1F220;1F220;1F220;521D;521D; +1F221;1F221;1F221;7D42;7D42; +1F222;1F222;1F222;751F;751F; +1F223;1F223;1F223;8CA9;8CA9; +1F224;1F224;1F224;58F0;58F0; +1F225;1F225;1F225;5439;5439; +1F226;1F226;1F226;6F14;6F14; +1F227;1F227;1F227;6295;6295; +1F228;1F228;1F228;6355;6355; +1F229;1F229;1F229;4E00;4E00; +1F22A;1F22A;1F22A;4E09;4E09; +1F22B;1F22B;1F22B;904A;904A; +1F22C;1F22C;1F22C;5DE6;5DE6; +1F22D;1F22D;1F22D;4E2D;4E2D; +1F22E;1F22E;1F22E;53F3;53F3; +1F22F;1F22F;1F22F;6307;6307; +1F230;1F230;1F230;8D70;8D70; +1F231;1F231;1F231;6253;6253; +1F232;1F232;1F232;7981;7981; +1F233;1F233;1F233;7A7A;7A7A; +1F234;1F234;1F234;5408;5408; +1F235;1F235;1F235;6E80;6E80; +1F236;1F236;1F236;6709;6709; +1F237;1F237;1F237;6708;6708; +1F238;1F238;1F238;7533;7533; +1F239;1F239;1F239;5272;5272; +1F23A;1F23A;1F23A;55B6;55B6; +1F23B;1F23B;1F23B;914D;914D; +1F240;1F240;1F240;3014 672C 3015;3014 672C 3015; +1F241;1F241;1F241;3014 4E09 3015;3014 4E09 3015; +1F242;1F242;1F242;3014 4E8C 3015;3014 4E8C 3015; +1F243;1F243;1F243;3014 5B89 3015;3014 5B89 3015; +1F244;1F244;1F244;3014 70B9 3015;3014 70B9 3015; +1F245;1F245;1F245;3014 6253 3015;3014 6253 3015; +1F246;1F246;1F246;3014 76D7 3015;3014 76D7 3015; +1F247;1F247;1F247;3014 52DD 3015;3014 52DD 3015; +1F248;1F248;1F248;3014 6557 3015;3014 6557 3015; +1F250;1F250;1F250;5F97;5F97; +1F251;1F251;1F251;53EF;53EF; +2F800;4E3D;4E3D;4E3D;4E3D; +2F801;4E38;4E38;4E38;4E38; +2F802;4E41;4E41;4E41;4E41; +2F803;20122;20122;20122;20122; +2F804;4F60;4F60;4F60;4F60; +2F805;4FAE;4FAE;4FAE;4FAE; +2F806;4FBB;4FBB;4FBB;4FBB; +2F807;5002;5002;5002;5002; +2F808;507A;507A;507A;507A; +2F809;5099;5099;5099;5099; +2F80A;50E7;50E7;50E7;50E7; +2F80B;50CF;50CF;50CF;50CF; +2F80C;349E;349E;349E;349E; +2F80D;2063A;2063A;2063A;2063A; +2F80E;514D;514D;514D;514D; +2F80F;5154;5154;5154;5154; +2F810;5164;5164;5164;5164; +2F811;5177;5177;5177;5177; +2F812;2051C;2051C;2051C;2051C; +2F813;34B9;34B9;34B9;34B9; +2F814;5167;5167;5167;5167; +2F815;518D;518D;518D;518D; +2F816;2054B;2054B;2054B;2054B; +2F817;5197;5197;5197;5197; +2F818;51A4;51A4;51A4;51A4; +2F819;4ECC;4ECC;4ECC;4ECC; +2F81A;51AC;51AC;51AC;51AC; +2F81B;51B5;51B5;51B5;51B5; +2F81C;291DF;291DF;291DF;291DF; +2F81D;51F5;51F5;51F5;51F5; +2F81E;5203;5203;5203;5203; +2F81F;34DF;34DF;34DF;34DF; +2F820;523B;523B;523B;523B; +2F821;5246;5246;5246;5246; +2F822;5272;5272;5272;5272; +2F823;5277;5277;5277;5277; +2F824;3515;3515;3515;3515; +2F825;52C7;52C7;52C7;52C7; +2F826;52C9;52C9;52C9;52C9; +2F827;52E4;52E4;52E4;52E4; +2F828;52FA;52FA;52FA;52FA; +2F829;5305;5305;5305;5305; +2F82A;5306;5306;5306;5306; +2F82B;5317;5317;5317;5317; +2F82C;5349;5349;5349;5349; +2F82D;5351;5351;5351;5351; +2F82E;535A;535A;535A;535A; +2F82F;5373;5373;5373;5373; +2F830;537D;537D;537D;537D; +2F831;537F;537F;537F;537F; +2F832;537F;537F;537F;537F; +2F833;537F;537F;537F;537F; +2F834;20A2C;20A2C;20A2C;20A2C; +2F835;7070;7070;7070;7070; +2F836;53CA;53CA;53CA;53CA; +2F837;53DF;53DF;53DF;53DF; +2F838;20B63;20B63;20B63;20B63; +2F839;53EB;53EB;53EB;53EB; +2F83A;53F1;53F1;53F1;53F1; +2F83B;5406;5406;5406;5406; +2F83C;549E;549E;549E;549E; +2F83D;5438;5438;5438;5438; +2F83E;5448;5448;5448;5448; +2F83F;5468;5468;5468;5468; +2F840;54A2;54A2;54A2;54A2; +2F841;54F6;54F6;54F6;54F6; +2F842;5510;5510;5510;5510; +2F843;5553;5553;5553;5553; +2F844;5563;5563;5563;5563; +2F845;5584;5584;5584;5584; +2F846;5584;5584;5584;5584; +2F847;5599;5599;5599;5599; +2F848;55AB;55AB;55AB;55AB; +2F849;55B3;55B3;55B3;55B3; +2F84A;55C2;55C2;55C2;55C2; +2F84B;5716;5716;5716;5716; +2F84C;5606;5606;5606;5606; +2F84D;5717;5717;5717;5717; +2F84E;5651;5651;5651;5651; +2F84F;5674;5674;5674;5674; +2F850;5207;5207;5207;5207; +2F851;58EE;58EE;58EE;58EE; +2F852;57CE;57CE;57CE;57CE; +2F853;57F4;57F4;57F4;57F4; +2F854;580D;580D;580D;580D; +2F855;578B;578B;578B;578B; +2F856;5832;5832;5832;5832; +2F857;5831;5831;5831;5831; +2F858;58AC;58AC;58AC;58AC; +2F859;214E4;214E4;214E4;214E4; +2F85A;58F2;58F2;58F2;58F2; +2F85B;58F7;58F7;58F7;58F7; +2F85C;5906;5906;5906;5906; +2F85D;591A;591A;591A;591A; +2F85E;5922;5922;5922;5922; +2F85F;5962;5962;5962;5962; +2F860;216A8;216A8;216A8;216A8; +2F861;216EA;216EA;216EA;216EA; +2F862;59EC;59EC;59EC;59EC; +2F863;5A1B;5A1B;5A1B;5A1B; +2F864;5A27;5A27;5A27;5A27; +2F865;59D8;59D8;59D8;59D8; +2F866;5A66;5A66;5A66;5A66; +2F867;36EE;36EE;36EE;36EE; +2F868;36FC;36FC;36FC;36FC; +2F869;5B08;5B08;5B08;5B08; +2F86A;5B3E;5B3E;5B3E;5B3E; +2F86B;5B3E;5B3E;5B3E;5B3E; +2F86C;219C8;219C8;219C8;219C8; +2F86D;5BC3;5BC3;5BC3;5BC3; +2F86E;5BD8;5BD8;5BD8;5BD8; +2F86F;5BE7;5BE7;5BE7;5BE7; +2F870;5BF3;5BF3;5BF3;5BF3; +2F871;21B18;21B18;21B18;21B18; +2F872;5BFF;5BFF;5BFF;5BFF; +2F873;5C06;5C06;5C06;5C06; +2F874;5F53;5F53;5F53;5F53; +2F875;5C22;5C22;5C22;5C22; +2F876;3781;3781;3781;3781; +2F877;5C60;5C60;5C60;5C60; +2F878;5C6E;5C6E;5C6E;5C6E; +2F879;5CC0;5CC0;5CC0;5CC0; +2F87A;5C8D;5C8D;5C8D;5C8D; +2F87B;21DE4;21DE4;21DE4;21DE4; +2F87C;5D43;5D43;5D43;5D43; +2F87D;21DE6;21DE6;21DE6;21DE6; +2F87E;5D6E;5D6E;5D6E;5D6E; +2F87F;5D6B;5D6B;5D6B;5D6B; +2F880;5D7C;5D7C;5D7C;5D7C; +2F881;5DE1;5DE1;5DE1;5DE1; +2F882;5DE2;5DE2;5DE2;5DE2; +2F883;382F;382F;382F;382F; +2F884;5DFD;5DFD;5DFD;5DFD; +2F885;5E28;5E28;5E28;5E28; +2F886;5E3D;5E3D;5E3D;5E3D; +2F887;5E69;5E69;5E69;5E69; +2F888;3862;3862;3862;3862; +2F889;22183;22183;22183;22183; +2F88A;387C;387C;387C;387C; +2F88B;5EB0;5EB0;5EB0;5EB0; +2F88C;5EB3;5EB3;5EB3;5EB3; +2F88D;5EB6;5EB6;5EB6;5EB6; +2F88E;5ECA;5ECA;5ECA;5ECA; +2F88F;2A392;2A392;2A392;2A392; +2F890;5EFE;5EFE;5EFE;5EFE; +2F891;22331;22331;22331;22331; +2F892;22331;22331;22331;22331; +2F893;8201;8201;8201;8201; +2F894;5F22;5F22;5F22;5F22; +2F895;5F22;5F22;5F22;5F22; +2F896;38C7;38C7;38C7;38C7; +2F897;232B8;232B8;232B8;232B8; +2F898;261DA;261DA;261DA;261DA; +2F899;5F62;5F62;5F62;5F62; +2F89A;5F6B;5F6B;5F6B;5F6B; +2F89B;38E3;38E3;38E3;38E3; +2F89C;5F9A;5F9A;5F9A;5F9A; +2F89D;5FCD;5FCD;5FCD;5FCD; +2F89E;5FD7;5FD7;5FD7;5FD7; +2F89F;5FF9;5FF9;5FF9;5FF9; +2F8A0;6081;6081;6081;6081; +2F8A1;393A;393A;393A;393A; +2F8A2;391C;391C;391C;391C; +2F8A3;6094;6094;6094;6094; +2F8A4;226D4;226D4;226D4;226D4; +2F8A5;60C7;60C7;60C7;60C7; +2F8A6;6148;6148;6148;6148; +2F8A7;614C;614C;614C;614C; +2F8A8;614E;614E;614E;614E; +2F8A9;614C;614C;614C;614C; +2F8AA;617A;617A;617A;617A; +2F8AB;618E;618E;618E;618E; +2F8AC;61B2;61B2;61B2;61B2; +2F8AD;61A4;61A4;61A4;61A4; +2F8AE;61AF;61AF;61AF;61AF; +2F8AF;61DE;61DE;61DE;61DE; +2F8B0;61F2;61F2;61F2;61F2; +2F8B1;61F6;61F6;61F6;61F6; +2F8B2;6210;6210;6210;6210; +2F8B3;621B;621B;621B;621B; +2F8B4;625D;625D;625D;625D; +2F8B5;62B1;62B1;62B1;62B1; +2F8B6;62D4;62D4;62D4;62D4; +2F8B7;6350;6350;6350;6350; +2F8B8;22B0C;22B0C;22B0C;22B0C; +2F8B9;633D;633D;633D;633D; +2F8BA;62FC;62FC;62FC;62FC; +2F8BB;6368;6368;6368;6368; +2F8BC;6383;6383;6383;6383; +2F8BD;63E4;63E4;63E4;63E4; +2F8BE;22BF1;22BF1;22BF1;22BF1; +2F8BF;6422;6422;6422;6422; +2F8C0;63C5;63C5;63C5;63C5; +2F8C1;63A9;63A9;63A9;63A9; +2F8C2;3A2E;3A2E;3A2E;3A2E; +2F8C3;6469;6469;6469;6469; +2F8C4;647E;647E;647E;647E; +2F8C5;649D;649D;649D;649D; +2F8C6;6477;6477;6477;6477; +2F8C7;3A6C;3A6C;3A6C;3A6C; +2F8C8;654F;654F;654F;654F; +2F8C9;656C;656C;656C;656C; +2F8CA;2300A;2300A;2300A;2300A; +2F8CB;65E3;65E3;65E3;65E3; +2F8CC;66F8;66F8;66F8;66F8; +2F8CD;6649;6649;6649;6649; +2F8CE;3B19;3B19;3B19;3B19; +2F8CF;6691;6691;6691;6691; +2F8D0;3B08;3B08;3B08;3B08; +2F8D1;3AE4;3AE4;3AE4;3AE4; +2F8D2;5192;5192;5192;5192; +2F8D3;5195;5195;5195;5195; +2F8D4;6700;6700;6700;6700; +2F8D5;669C;669C;669C;669C; +2F8D6;80AD;80AD;80AD;80AD; +2F8D7;43D9;43D9;43D9;43D9; +2F8D8;6717;6717;6717;6717; +2F8D9;671B;671B;671B;671B; +2F8DA;6721;6721;6721;6721; +2F8DB;675E;675E;675E;675E; +2F8DC;6753;6753;6753;6753; +2F8DD;233C3;233C3;233C3;233C3; +2F8DE;3B49;3B49;3B49;3B49; +2F8DF;67FA;67FA;67FA;67FA; +2F8E0;6785;6785;6785;6785; +2F8E1;6852;6852;6852;6852; +2F8E2;6885;6885;6885;6885; +2F8E3;2346D;2346D;2346D;2346D; +2F8E4;688E;688E;688E;688E; +2F8E5;681F;681F;681F;681F; +2F8E6;6914;6914;6914;6914; +2F8E7;3B9D;3B9D;3B9D;3B9D; +2F8E8;6942;6942;6942;6942; +2F8E9;69A3;69A3;69A3;69A3; +2F8EA;69EA;69EA;69EA;69EA; +2F8EB;6AA8;6AA8;6AA8;6AA8; +2F8EC;236A3;236A3;236A3;236A3; +2F8ED;6ADB;6ADB;6ADB;6ADB; +2F8EE;3C18;3C18;3C18;3C18; +2F8EF;6B21;6B21;6B21;6B21; +2F8F0;238A7;238A7;238A7;238A7; +2F8F1;6B54;6B54;6B54;6B54; +2F8F2;3C4E;3C4E;3C4E;3C4E; +2F8F3;6B72;6B72;6B72;6B72; +2F8F4;6B9F;6B9F;6B9F;6B9F; +2F8F5;6BBA;6BBA;6BBA;6BBA; +2F8F6;6BBB;6BBB;6BBB;6BBB; +2F8F7;23A8D;23A8D;23A8D;23A8D; +2F8F8;21D0B;21D0B;21D0B;21D0B; +2F8F9;23AFA;23AFA;23AFA;23AFA; +2F8FA;6C4E;6C4E;6C4E;6C4E; +2F8FB;23CBC;23CBC;23CBC;23CBC; +2F8FC;6CBF;6CBF;6CBF;6CBF; +2F8FD;6CCD;6CCD;6CCD;6CCD; +2F8FE;6C67;6C67;6C67;6C67; +2F8FF;6D16;6D16;6D16;6D16; +2F900;6D3E;6D3E;6D3E;6D3E; +2F901;6D77;6D77;6D77;6D77; +2F902;6D41;6D41;6D41;6D41; +2F903;6D69;6D69;6D69;6D69; +2F904;6D78;6D78;6D78;6D78; +2F905;6D85;6D85;6D85;6D85; +2F906;23D1E;23D1E;23D1E;23D1E; +2F907;6D34;6D34;6D34;6D34; +2F908;6E2F;6E2F;6E2F;6E2F; +2F909;6E6E;6E6E;6E6E;6E6E; +2F90A;3D33;3D33;3D33;3D33; +2F90B;6ECB;6ECB;6ECB;6ECB; +2F90C;6EC7;6EC7;6EC7;6EC7; +2F90D;23ED1;23ED1;23ED1;23ED1; +2F90E;6DF9;6DF9;6DF9;6DF9; +2F90F;6F6E;6F6E;6F6E;6F6E; +2F910;23F5E;23F5E;23F5E;23F5E; +2F911;23F8E;23F8E;23F8E;23F8E; +2F912;6FC6;6FC6;6FC6;6FC6; +2F913;7039;7039;7039;7039; +2F914;701E;701E;701E;701E; +2F915;701B;701B;701B;701B; +2F916;3D96;3D96;3D96;3D96; +2F917;704A;704A;704A;704A; +2F918;707D;707D;707D;707D; +2F919;7077;7077;7077;7077; +2F91A;70AD;70AD;70AD;70AD; +2F91B;20525;20525;20525;20525; +2F91C;7145;7145;7145;7145; +2F91D;24263;24263;24263;24263; +2F91E;719C;719C;719C;719C; +2F91F;243AB;243AB;243AB;243AB; +2F920;7228;7228;7228;7228; +2F921;7235;7235;7235;7235; +2F922;7250;7250;7250;7250; +2F923;24608;24608;24608;24608; +2F924;7280;7280;7280;7280; +2F925;7295;7295;7295;7295; +2F926;24735;24735;24735;24735; +2F927;24814;24814;24814;24814; +2F928;737A;737A;737A;737A; +2F929;738B;738B;738B;738B; +2F92A;3EAC;3EAC;3EAC;3EAC; +2F92B;73A5;73A5;73A5;73A5; +2F92C;3EB8;3EB8;3EB8;3EB8; +2F92D;3EB8;3EB8;3EB8;3EB8; +2F92E;7447;7447;7447;7447; +2F92F;745C;745C;745C;745C; +2F930;7471;7471;7471;7471; +2F931;7485;7485;7485;7485; +2F932;74CA;74CA;74CA;74CA; +2F933;3F1B;3F1B;3F1B;3F1B; +2F934;7524;7524;7524;7524; +2F935;24C36;24C36;24C36;24C36; +2F936;753E;753E;753E;753E; +2F937;24C92;24C92;24C92;24C92; +2F938;7570;7570;7570;7570; +2F939;2219F;2219F;2219F;2219F; +2F93A;7610;7610;7610;7610; +2F93B;24FA1;24FA1;24FA1;24FA1; +2F93C;24FB8;24FB8;24FB8;24FB8; +2F93D;25044;25044;25044;25044; +2F93E;3FFC;3FFC;3FFC;3FFC; +2F93F;4008;4008;4008;4008; +2F940;76F4;76F4;76F4;76F4; +2F941;250F3;250F3;250F3;250F3; +2F942;250F2;250F2;250F2;250F2; +2F943;25119;25119;25119;25119; +2F944;25133;25133;25133;25133; +2F945;771E;771E;771E;771E; +2F946;771F;771F;771F;771F; +2F947;771F;771F;771F;771F; +2F948;774A;774A;774A;774A; +2F949;4039;4039;4039;4039; +2F94A;778B;778B;778B;778B; +2F94B;4046;4046;4046;4046; +2F94C;4096;4096;4096;4096; +2F94D;2541D;2541D;2541D;2541D; +2F94E;784E;784E;784E;784E; +2F94F;788C;788C;788C;788C; +2F950;78CC;78CC;78CC;78CC; +2F951;40E3;40E3;40E3;40E3; +2F952;25626;25626;25626;25626; +2F953;7956;7956;7956;7956; +2F954;2569A;2569A;2569A;2569A; +2F955;256C5;256C5;256C5;256C5; +2F956;798F;798F;798F;798F; +2F957;79EB;79EB;79EB;79EB; +2F958;412F;412F;412F;412F; +2F959;7A40;7A40;7A40;7A40; +2F95A;7A4A;7A4A;7A4A;7A4A; +2F95B;7A4F;7A4F;7A4F;7A4F; +2F95C;2597C;2597C;2597C;2597C; +2F95D;25AA7;25AA7;25AA7;25AA7; +2F95E;25AA7;25AA7;25AA7;25AA7; +2F95F;7AEE;7AEE;7AEE;7AEE; +2F960;4202;4202;4202;4202; +2F961;25BAB;25BAB;25BAB;25BAB; +2F962;7BC6;7BC6;7BC6;7BC6; +2F963;7BC9;7BC9;7BC9;7BC9; +2F964;4227;4227;4227;4227; +2F965;25C80;25C80;25C80;25C80; +2F966;7CD2;7CD2;7CD2;7CD2; +2F967;42A0;42A0;42A0;42A0; +2F968;7CE8;7CE8;7CE8;7CE8; +2F969;7CE3;7CE3;7CE3;7CE3; +2F96A;7D00;7D00;7D00;7D00; +2F96B;25F86;25F86;25F86;25F86; +2F96C;7D63;7D63;7D63;7D63; +2F96D;4301;4301;4301;4301; +2F96E;7DC7;7DC7;7DC7;7DC7; +2F96F;7E02;7E02;7E02;7E02; +2F970;7E45;7E45;7E45;7E45; +2F971;4334;4334;4334;4334; +2F972;26228;26228;26228;26228; +2F973;26247;26247;26247;26247; +2F974;4359;4359;4359;4359; +2F975;262D9;262D9;262D9;262D9; +2F976;7F7A;7F7A;7F7A;7F7A; +2F977;2633E;2633E;2633E;2633E; +2F978;7F95;7F95;7F95;7F95; +2F979;7FFA;7FFA;7FFA;7FFA; +2F97A;8005;8005;8005;8005; +2F97B;264DA;264DA;264DA;264DA; +2F97C;26523;26523;26523;26523; +2F97D;8060;8060;8060;8060; +2F97E;265A8;265A8;265A8;265A8; +2F97F;8070;8070;8070;8070; +2F980;2335F;2335F;2335F;2335F; +2F981;43D5;43D5;43D5;43D5; +2F982;80B2;80B2;80B2;80B2; +2F983;8103;8103;8103;8103; +2F984;440B;440B;440B;440B; +2F985;813E;813E;813E;813E; +2F986;5AB5;5AB5;5AB5;5AB5; +2F987;267A7;267A7;267A7;267A7; +2F988;267B5;267B5;267B5;267B5; +2F989;23393;23393;23393;23393; +2F98A;2339C;2339C;2339C;2339C; +2F98B;8201;8201;8201;8201; +2F98C;8204;8204;8204;8204; +2F98D;8F9E;8F9E;8F9E;8F9E; +2F98E;446B;446B;446B;446B; +2F98F;8291;8291;8291;8291; +2F990;828B;828B;828B;828B; +2F991;829D;829D;829D;829D; +2F992;52B3;52B3;52B3;52B3; +2F993;82B1;82B1;82B1;82B1; +2F994;82B3;82B3;82B3;82B3; +2F995;82BD;82BD;82BD;82BD; +2F996;82E6;82E6;82E6;82E6; +2F997;26B3C;26B3C;26B3C;26B3C; +2F998;82E5;82E5;82E5;82E5; +2F999;831D;831D;831D;831D; +2F99A;8363;8363;8363;8363; +2F99B;83AD;83AD;83AD;83AD; +2F99C;8323;8323;8323;8323; +2F99D;83BD;83BD;83BD;83BD; +2F99E;83E7;83E7;83E7;83E7; +2F99F;8457;8457;8457;8457; +2F9A0;8353;8353;8353;8353; +2F9A1;83CA;83CA;83CA;83CA; +2F9A2;83CC;83CC;83CC;83CC; +2F9A3;83DC;83DC;83DC;83DC; +2F9A4;26C36;26C36;26C36;26C36; +2F9A5;26D6B;26D6B;26D6B;26D6B; +2F9A6;26CD5;26CD5;26CD5;26CD5; +2F9A7;452B;452B;452B;452B; +2F9A8;84F1;84F1;84F1;84F1; +2F9A9;84F3;84F3;84F3;84F3; +2F9AA;8516;8516;8516;8516; +2F9AB;273CA;273CA;273CA;273CA; +2F9AC;8564;8564;8564;8564; +2F9AD;26F2C;26F2C;26F2C;26F2C; +2F9AE;455D;455D;455D;455D; +2F9AF;4561;4561;4561;4561; +2F9B0;26FB1;26FB1;26FB1;26FB1; +2F9B1;270D2;270D2;270D2;270D2; +2F9B2;456B;456B;456B;456B; +2F9B3;8650;8650;8650;8650; +2F9B4;865C;865C;865C;865C; +2F9B5;8667;8667;8667;8667; +2F9B6;8669;8669;8669;8669; +2F9B7;86A9;86A9;86A9;86A9; +2F9B8;8688;8688;8688;8688; +2F9B9;870E;870E;870E;870E; +2F9BA;86E2;86E2;86E2;86E2; +2F9BB;8779;8779;8779;8779; +2F9BC;8728;8728;8728;8728; +2F9BD;876B;876B;876B;876B; +2F9BE;8786;8786;8786;8786; +2F9BF;45D7;45D7;45D7;45D7; +2F9C0;87E1;87E1;87E1;87E1; +2F9C1;8801;8801;8801;8801; +2F9C2;45F9;45F9;45F9;45F9; +2F9C3;8860;8860;8860;8860; +2F9C4;8863;8863;8863;8863; +2F9C5;27667;27667;27667;27667; +2F9C6;88D7;88D7;88D7;88D7; +2F9C7;88DE;88DE;88DE;88DE; +2F9C8;4635;4635;4635;4635; +2F9C9;88FA;88FA;88FA;88FA; +2F9CA;34BB;34BB;34BB;34BB; +2F9CB;278AE;278AE;278AE;278AE; +2F9CC;27966;27966;27966;27966; +2F9CD;46BE;46BE;46BE;46BE; +2F9CE;46C7;46C7;46C7;46C7; +2F9CF;8AA0;8AA0;8AA0;8AA0; +2F9D0;8AED;8AED;8AED;8AED; +2F9D1;8B8A;8B8A;8B8A;8B8A; +2F9D2;8C55;8C55;8C55;8C55; +2F9D3;27CA8;27CA8;27CA8;27CA8; +2F9D4;8CAB;8CAB;8CAB;8CAB; +2F9D5;8CC1;8CC1;8CC1;8CC1; +2F9D6;8D1B;8D1B;8D1B;8D1B; +2F9D7;8D77;8D77;8D77;8D77; +2F9D8;27F2F;27F2F;27F2F;27F2F; +2F9D9;20804;20804;20804;20804; +2F9DA;8DCB;8DCB;8DCB;8DCB; +2F9DB;8DBC;8DBC;8DBC;8DBC; +2F9DC;8DF0;8DF0;8DF0;8DF0; +2F9DD;208DE;208DE;208DE;208DE; +2F9DE;8ED4;8ED4;8ED4;8ED4; +2F9DF;8F38;8F38;8F38;8F38; +2F9E0;285D2;285D2;285D2;285D2; +2F9E1;285ED;285ED;285ED;285ED; +2F9E2;9094;9094;9094;9094; +2F9E3;90F1;90F1;90F1;90F1; +2F9E4;9111;9111;9111;9111; +2F9E5;2872E;2872E;2872E;2872E; +2F9E6;911B;911B;911B;911B; +2F9E7;9238;9238;9238;9238; +2F9E8;92D7;92D7;92D7;92D7; +2F9E9;92D8;92D8;92D8;92D8; +2F9EA;927C;927C;927C;927C; +2F9EB;93F9;93F9;93F9;93F9; +2F9EC;9415;9415;9415;9415; +2F9ED;28BFA;28BFA;28BFA;28BFA; +2F9EE;958B;958B;958B;958B; +2F9EF;4995;4995;4995;4995; +2F9F0;95B7;95B7;95B7;95B7; +2F9F1;28D77;28D77;28D77;28D77; +2F9F2;49E6;49E6;49E6;49E6; +2F9F3;96C3;96C3;96C3;96C3; +2F9F4;5DB2;5DB2;5DB2;5DB2; +2F9F5;9723;9723;9723;9723; +2F9F6;29145;29145;29145;29145; +2F9F7;2921A;2921A;2921A;2921A; +2F9F8;4A6E;4A6E;4A6E;4A6E; +2F9F9;4A76;4A76;4A76;4A76; +2F9FA;97E0;97E0;97E0;97E0; +2F9FB;2940A;2940A;2940A;2940A; +2F9FC;4AB2;4AB2;4AB2;4AB2; +2F9FD;29496;29496;29496;29496; +2F9FE;980B;980B;980B;980B; +2F9FF;980B;980B;980B;980B; +2FA00;9829;9829;9829;9829; +2FA01;295B6;295B6;295B6;295B6; +2FA02;98E2;98E2;98E2;98E2; +2FA03;4B33;4B33;4B33;4B33; +2FA04;9929;9929;9929;9929; +2FA05;99A7;99A7;99A7;99A7; +2FA06;99C2;99C2;99C2;99C2; +2FA07;99FE;99FE;99FE;99FE; +2FA08;4BCE;4BCE;4BCE;4BCE; +2FA09;29B30;29B30;29B30;29B30; +2FA0A;9B12;9B12;9B12;9B12; +2FA0B;9C40;9C40;9C40;9C40; +2FA0C;9CFD;9CFD;9CFD;9CFD; +2FA0D;4CCE;4CCE;4CCE;4CCE; +2FA0E;4CED;4CED;4CED;4CED; +2FA0F;9D67;9D67;9D67;9D67; +2FA10;2A0CE;2A0CE;2A0CE;2A0CE; +2FA11;4CF8;4CF8;4CF8;4CF8; +2FA12;2A105;2A105;2A105;2A105; +2FA13;2A20E;2A20E;2A20E;2A20E; +2FA14;2A291;2A291;2A291;2A291; +2FA15;9EBB;9EBB;9EBB;9EBB; +2FA16;4D56;4D56;4D56;4D56; +2FA17;9EF9;9EF9;9EF9;9EF9; +2FA18;9EFE;9EFE;9EFE;9EFE; +2FA19;9F05;9F05;9F05;9F05; +2FA1A;9F0F;9F0F;9F0F;9F0F; +2FA1B;9F16;9F16;9F16;9F16; +2FA1C;9F3B;9F3B;9F3B;9F3B; +2FA1D;2A600;2A600;2A600;2A600; +# +@Part2 # Canonical Order Test +# +0061 0315 0300 05AE 0300 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; +0061 0300 0315 0300 05AE 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; +0061 0315 0300 05AE 0301 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062; +0061 0301 0315 0300 05AE 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062; +0061 0315 0300 05AE 0302 0062;00E0 05AE 0302 0315 0062;0061 05AE 0300 0302 0315 0062;00E0 05AE 0302 0315 0062;0061 05AE 0300 0302 0315 0062; +0061 0302 0315 0300 05AE 0062;1EA7 05AE 0315 0062;0061 05AE 0302 0300 0315 0062;1EA7 05AE 0315 0062;0061 05AE 0302 0300 0315 0062; +0061 0315 0300 05AE 0303 0062;00E0 05AE 0303 0315 0062;0061 05AE 0300 0303 0315 0062;00E0 05AE 0303 0315 0062;0061 05AE 0300 0303 0315 0062; +0061 0303 0315 0300 05AE 0062;00E3 05AE 0300 0315 0062;0061 05AE 0303 0300 0315 0062;00E3 05AE 0300 0315 0062;0061 05AE 0303 0300 0315 0062; +0061 0315 0300 05AE 0304 0062;00E0 05AE 0304 0315 0062;0061 05AE 0300 0304 0315 0062;00E0 05AE 0304 0315 0062;0061 05AE 0300 0304 0315 0062; +0061 0304 0315 0300 05AE 0062;0101 05AE 0300 0315 0062;0061 05AE 0304 0300 0315 0062;0101 05AE 0300 0315 0062;0061 05AE 0304 0300 0315 0062; +0061 0315 0300 05AE 0305 0062;00E0 05AE 0305 0315 0062;0061 05AE 0300 0305 0315 0062;00E0 05AE 0305 0315 0062;0061 05AE 0300 0305 0315 0062; +0061 0305 0315 0300 05AE 0062;0061 05AE 0305 0300 0315 0062;0061 05AE 0305 0300 0315 0062;0061 05AE 0305 0300 0315 0062;0061 05AE 0305 0300 0315 0062; +0061 0315 0300 05AE 0306 0062;00E0 05AE 0306 0315 0062;0061 05AE 0300 0306 0315 0062;00E0 05AE 0306 0315 0062;0061 05AE 0300 0306 0315 0062; +0061 0306 0315 0300 05AE 0062;1EB1 05AE 0315 0062;0061 05AE 0306 0300 0315 0062;1EB1 05AE 0315 0062;0061 05AE 0306 0300 0315 0062; +0061 0315 0300 05AE 0307 0062;00E0 05AE 0307 0315 0062;0061 05AE 0300 0307 0315 0062;00E0 05AE 0307 0315 0062;0061 05AE 0300 0307 0315 0062; +0061 0307 0315 0300 05AE 0062;0227 05AE 0300 0315 0062;0061 05AE 0307 0300 0315 0062;0227 05AE 0300 0315 0062;0061 05AE 0307 0300 0315 0062; +0061 0315 0300 05AE 0308 0062;00E0 05AE 0308 0315 0062;0061 05AE 0300 0308 0315 0062;00E0 05AE 0308 0315 0062;0061 05AE 0300 0308 0315 0062; +0061 0308 0315 0300 05AE 0062;00E4 05AE 0300 0315 0062;0061 05AE 0308 0300 0315 0062;00E4 05AE 0300 0315 0062;0061 05AE 0308 0300 0315 0062; +0061 0315 0300 05AE 0309 0062;00E0 05AE 0309 0315 0062;0061 05AE 0300 0309 0315 0062;00E0 05AE 0309 0315 0062;0061 05AE 0300 0309 0315 0062; +0061 0309 0315 0300 05AE 0062;1EA3 05AE 0300 0315 0062;0061 05AE 0309 0300 0315 0062;1EA3 05AE 0300 0315 0062;0061 05AE 0309 0300 0315 0062; +0061 0315 0300 05AE 030A 0062;00E0 05AE 030A 0315 0062;0061 05AE 0300 030A 0315 0062;00E0 05AE 030A 0315 0062;0061 05AE 0300 030A 0315 0062; +0061 030A 0315 0300 05AE 0062;00E5 05AE 0300 0315 0062;0061 05AE 030A 0300 0315 0062;00E5 05AE 0300 0315 0062;0061 05AE 030A 0300 0315 0062; +0061 0315 0300 05AE 030B 0062;00E0 05AE 030B 0315 0062;0061 05AE 0300 030B 0315 0062;00E0 05AE 030B 0315 0062;0061 05AE 0300 030B 0315 0062; +0061 030B 0315 0300 05AE 0062;0061 05AE 030B 0300 0315 0062;0061 05AE 030B 0300 0315 0062;0061 05AE 030B 0300 0315 0062;0061 05AE 030B 0300 0315 0062; +0061 0315 0300 05AE 030C 0062;00E0 05AE 030C 0315 0062;0061 05AE 0300 030C 0315 0062;00E0 05AE 030C 0315 0062;0061 05AE 0300 030C 0315 0062; +0061 030C 0315 0300 05AE 0062;01CE 05AE 0300 0315 0062;0061 05AE 030C 0300 0315 0062;01CE 05AE 0300 0315 0062;0061 05AE 030C 0300 0315 0062; +0061 0315 0300 05AE 030D 0062;00E0 05AE 030D 0315 0062;0061 05AE 0300 030D 0315 0062;00E0 05AE 030D 0315 0062;0061 05AE 0300 030D 0315 0062; +0061 030D 0315 0300 05AE 0062;0061 05AE 030D 0300 0315 0062;0061 05AE 030D 0300 0315 0062;0061 05AE 030D 0300 0315 0062;0061 05AE 030D 0300 0315 0062; +0061 0315 0300 05AE 030E 0062;00E0 05AE 030E 0315 0062;0061 05AE 0300 030E 0315 0062;00E0 05AE 030E 0315 0062;0061 05AE 0300 030E 0315 0062; +0061 030E 0315 0300 05AE 0062;0061 05AE 030E 0300 0315 0062;0061 05AE 030E 0300 0315 0062;0061 05AE 030E 0300 0315 0062;0061 05AE 030E 0300 0315 0062; +0061 0315 0300 05AE 030F 0062;00E0 05AE 030F 0315 0062;0061 05AE 0300 030F 0315 0062;00E0 05AE 030F 0315 0062;0061 05AE 0300 030F 0315 0062; +0061 030F 0315 0300 05AE 0062;0201 05AE 0300 0315 0062;0061 05AE 030F 0300 0315 0062;0201 05AE 0300 0315 0062;0061 05AE 030F 0300 0315 0062; +0061 0315 0300 05AE 0310 0062;00E0 05AE 0310 0315 0062;0061 05AE 0300 0310 0315 0062;00E0 05AE 0310 0315 0062;0061 05AE 0300 0310 0315 0062; +0061 0310 0315 0300 05AE 0062;0061 05AE 0310 0300 0315 0062;0061 05AE 0310 0300 0315 0062;0061 05AE 0310 0300 0315 0062;0061 05AE 0310 0300 0315 0062; +0061 0315 0300 05AE 0311 0062;00E0 05AE 0311 0315 0062;0061 05AE 0300 0311 0315 0062;00E0 05AE 0311 0315 0062;0061 05AE 0300 0311 0315 0062; +0061 0311 0315 0300 05AE 0062;0203 05AE 0300 0315 0062;0061 05AE 0311 0300 0315 0062;0203 05AE 0300 0315 0062;0061 05AE 0311 0300 0315 0062; +0061 0315 0300 05AE 0312 0062;00E0 05AE 0312 0315 0062;0061 05AE 0300 0312 0315 0062;00E0 05AE 0312 0315 0062;0061 05AE 0300 0312 0315 0062; +0061 0312 0315 0300 05AE 0062;0061 05AE 0312 0300 0315 0062;0061 05AE 0312 0300 0315 0062;0061 05AE 0312 0300 0315 0062;0061 05AE 0312 0300 0315 0062; +0061 0315 0300 05AE 0313 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062; +0061 0313 0315 0300 05AE 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062; +0061 0315 0300 05AE 0314 0062;00E0 05AE 0314 0315 0062;0061 05AE 0300 0314 0315 0062;00E0 05AE 0314 0315 0062;0061 05AE 0300 0314 0315 0062; +0061 0314 0315 0300 05AE 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062; +0061 035C 0315 0300 0315 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062; +0061 0315 035C 0315 0300 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062; +0061 059A 0316 302A 0316 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062; +0061 0316 059A 0316 302A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062; +0061 059A 0316 302A 0317 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062; +0061 0317 059A 0316 302A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062; +0061 059A 0316 302A 0318 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062; +0061 0318 059A 0316 302A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062; +0061 059A 0316 302A 0319 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062; +0061 0319 059A 0316 302A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062; +0061 035C 0315 0300 031A 0062;00E0 0315 031A 035C 0062;0061 0300 0315 031A 035C 0062;00E0 0315 031A 035C 0062;0061 0300 0315 031A 035C 0062; +0061 031A 035C 0315 0300 0062;00E0 031A 0315 035C 0062;0061 0300 031A 0315 035C 0062;00E0 031A 0315 035C 0062;0061 0300 031A 0315 035C 0062; +0061 302A 031B 1DCE 031B 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062; +0061 031B 302A 031B 1DCE 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062; +0061 059A 0316 302A 031C 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062; +0061 031C 059A 0316 302A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062; +0061 059A 0316 302A 031D 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062; +0061 031D 059A 0316 302A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062; +0061 059A 0316 302A 031E 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062; +0061 031E 059A 0316 302A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062; +0061 059A 0316 302A 031F 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062; +0061 031F 059A 0316 302A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062; +0061 059A 0316 302A 0320 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062; +0061 0320 059A 0316 302A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062; +0061 1DCE 0321 0F74 0321 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062; +0061 0321 1DCE 0321 0F74 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062; +0061 1DCE 0321 0F74 0322 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062; +0061 0322 1DCE 0321 0F74 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062; +0061 059A 0316 302A 0323 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062; +0061 0323 059A 0316 302A 0062;1EA1 302A 0316 059A 0062;0061 302A 0323 0316 059A 0062;1EA1 302A 0316 059A 0062;0061 302A 0323 0316 059A 0062; +0061 059A 0316 302A 0324 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062; +0061 0324 059A 0316 302A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062; +0061 059A 0316 302A 0325 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062; +0061 0325 059A 0316 302A 0062;1E01 302A 0316 059A 0062;0061 302A 0325 0316 059A 0062;1E01 302A 0316 059A 0062;0061 302A 0325 0316 059A 0062; +0061 059A 0316 302A 0326 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062; +0061 0326 059A 0316 302A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062; +0061 1DCE 0321 0F74 0327 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062; +0061 0327 1DCE 0321 0F74 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062; +0061 1DCE 0321 0F74 0328 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062; +0061 0328 1DCE 0321 0F74 0062;0105 0F74 0321 1DCE 0062;0061 0F74 0328 0321 1DCE 0062;0105 0F74 0321 1DCE 0062;0061 0F74 0328 0321 1DCE 0062; +0061 059A 0316 302A 0329 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062; +0061 0329 059A 0316 302A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062; +0061 059A 0316 302A 032A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062; +0061 032A 059A 0316 302A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062; +0061 059A 0316 302A 032B 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062; +0061 032B 059A 0316 302A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062; +0061 059A 0316 302A 032C 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062; +0061 032C 059A 0316 302A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062; +0061 059A 0316 302A 032D 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062; +0061 032D 059A 0316 302A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062; +0061 059A 0316 302A 032E 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062; +0061 032E 059A 0316 302A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062; +0061 059A 0316 302A 032F 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062; +0061 032F 059A 0316 302A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062; +0061 059A 0316 302A 0330 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062; +0061 0330 059A 0316 302A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062; +0061 059A 0316 302A 0331 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062; +0061 0331 059A 0316 302A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062; +0061 059A 0316 302A 0332 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062; +0061 0332 059A 0316 302A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062; +0061 059A 0316 302A 0333 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062; +0061 0333 059A 0316 302A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062; +0061 093C 0334 0334 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062; +0061 0334 093C 0334 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062; +0061 093C 0334 0335 0062;0061 0334 0335 093C 0062;0061 0334 0335 093C 0062;0061 0334 0335 093C 0062;0061 0334 0335 093C 0062; +0061 0335 093C 0334 0062;0061 0335 0334 093C 0062;0061 0335 0334 093C 0062;0061 0335 0334 093C 0062;0061 0335 0334 093C 0062; +0061 093C 0334 0336 0062;0061 0334 0336 093C 0062;0061 0334 0336 093C 0062;0061 0334 0336 093C 0062;0061 0334 0336 093C 0062; +0061 0336 093C 0334 0062;0061 0336 0334 093C 0062;0061 0336 0334 093C 0062;0061 0336 0334 093C 0062;0061 0336 0334 093C 0062; +0061 093C 0334 0337 0062;0061 0334 0337 093C 0062;0061 0334 0337 093C 0062;0061 0334 0337 093C 0062;0061 0334 0337 093C 0062; +0061 0337 093C 0334 0062;0061 0337 0334 093C 0062;0061 0337 0334 093C 0062;0061 0337 0334 093C 0062;0061 0337 0334 093C 0062; +0061 093C 0334 0338 0062;0061 0334 0338 093C 0062;0061 0334 0338 093C 0062;0061 0334 0338 093C 0062;0061 0334 0338 093C 0062; +0061 0338 093C 0334 0062;0061 0338 0334 093C 0062;0061 0338 0334 093C 0062;0061 0338 0334 093C 0062;0061 0338 0334 093C 0062; +0061 059A 0316 302A 0339 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062; +0061 0339 059A 0316 302A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062; +0061 059A 0316 302A 033A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062; +0061 033A 059A 0316 302A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062; +0061 059A 0316 302A 033B 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062; +0061 033B 059A 0316 302A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062; +0061 059A 0316 302A 033C 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062; +0061 033C 059A 0316 302A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062; +0061 0315 0300 05AE 033D 0062;00E0 05AE 033D 0315 0062;0061 05AE 0300 033D 0315 0062;00E0 05AE 033D 0315 0062;0061 05AE 0300 033D 0315 0062; +0061 033D 0315 0300 05AE 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062; +0061 0315 0300 05AE 033E 0062;00E0 05AE 033E 0315 0062;0061 05AE 0300 033E 0315 0062;00E0 05AE 033E 0315 0062;0061 05AE 0300 033E 0315 0062; +0061 033E 0315 0300 05AE 0062;0061 05AE 033E 0300 0315 0062;0061 05AE 033E 0300 0315 0062;0061 05AE 033E 0300 0315 0062;0061 05AE 033E 0300 0315 0062; +0061 0315 0300 05AE 033F 0062;00E0 05AE 033F 0315 0062;0061 05AE 0300 033F 0315 0062;00E0 05AE 033F 0315 0062;0061 05AE 0300 033F 0315 0062; +0061 033F 0315 0300 05AE 0062;0061 05AE 033F 0300 0315 0062;0061 05AE 033F 0300 0315 0062;0061 05AE 033F 0300 0315 0062;0061 05AE 033F 0300 0315 0062; +0061 0315 0300 05AE 0340 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; +0061 0340 0315 0300 05AE 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; +0061 0315 0300 05AE 0341 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062; +0061 0341 0315 0300 05AE 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062; +0061 0315 0300 05AE 0342 0062;00E0 05AE 0342 0315 0062;0061 05AE 0300 0342 0315 0062;00E0 05AE 0342 0315 0062;0061 05AE 0300 0342 0315 0062; +0061 0342 0315 0300 05AE 0062;0061 05AE 0342 0300 0315 0062;0061 05AE 0342 0300 0315 0062;0061 05AE 0342 0300 0315 0062;0061 05AE 0342 0300 0315 0062; +0061 0315 0300 05AE 0343 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062; +0061 0343 0315 0300 05AE 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062; +0061 0315 0300 05AE 0344 0062;00E0 05AE 0308 0301 0315 0062;0061 05AE 0300 0308 0301 0315 0062;00E0 05AE 0308 0301 0315 0062;0061 05AE 0300 0308 0301 0315 0062; +0061 0344 0315 0300 05AE 0062;00E4 05AE 0301 0300 0315 0062;0061 05AE 0308 0301 0300 0315 0062;00E4 05AE 0301 0300 0315 0062;0061 05AE 0308 0301 0300 0315 0062; +0061 0345 035D 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062; +0061 0345 0345 035D 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062; +0061 0315 0300 05AE 0346 0062;00E0 05AE 0346 0315 0062;0061 05AE 0300 0346 0315 0062;00E0 05AE 0346 0315 0062;0061 05AE 0300 0346 0315 0062; +0061 0346 0315 0300 05AE 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062; +0061 059A 0316 302A 0347 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062; +0061 0347 059A 0316 302A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062; +0061 059A 0316 302A 0348 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062; +0061 0348 059A 0316 302A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062; +0061 059A 0316 302A 0349 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062; +0061 0349 059A 0316 302A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062; +0061 0315 0300 05AE 034A 0062;00E0 05AE 034A 0315 0062;0061 05AE 0300 034A 0315 0062;00E0 05AE 034A 0315 0062;0061 05AE 0300 034A 0315 0062; +0061 034A 0315 0300 05AE 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062; +0061 0315 0300 05AE 034B 0062;00E0 05AE 034B 0315 0062;0061 05AE 0300 034B 0315 0062;00E0 05AE 034B 0315 0062;0061 05AE 0300 034B 0315 0062; +0061 034B 0315 0300 05AE 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062; +0061 0315 0300 05AE 034C 0062;00E0 05AE 034C 0315 0062;0061 05AE 0300 034C 0315 0062;00E0 05AE 034C 0315 0062;0061 05AE 0300 034C 0315 0062; +0061 034C 0315 0300 05AE 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062; +0061 059A 0316 302A 034D 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062; +0061 034D 059A 0316 302A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062; +0061 059A 0316 302A 034E 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062; +0061 034E 059A 0316 302A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062; +0061 0315 0300 05AE 0350 0062;00E0 05AE 0350 0315 0062;0061 05AE 0300 0350 0315 0062;00E0 05AE 0350 0315 0062;0061 05AE 0300 0350 0315 0062; +0061 0350 0315 0300 05AE 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062; +0061 0315 0300 05AE 0351 0062;00E0 05AE 0351 0315 0062;0061 05AE 0300 0351 0315 0062;00E0 05AE 0351 0315 0062;0061 05AE 0300 0351 0315 0062; +0061 0351 0315 0300 05AE 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062; +0061 0315 0300 05AE 0352 0062;00E0 05AE 0352 0315 0062;0061 05AE 0300 0352 0315 0062;00E0 05AE 0352 0315 0062;0061 05AE 0300 0352 0315 0062; +0061 0352 0315 0300 05AE 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062; +0061 059A 0316 302A 0353 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062; +0061 0353 059A 0316 302A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062; +0061 059A 0316 302A 0354 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062; +0061 0354 059A 0316 302A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062; +0061 059A 0316 302A 0355 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062; +0061 0355 059A 0316 302A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062; +0061 059A 0316 302A 0356 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062; +0061 0356 059A 0316 302A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062; +0061 0315 0300 05AE 0357 0062;00E0 05AE 0357 0315 0062;0061 05AE 0300 0357 0315 0062;00E0 05AE 0357 0315 0062;0061 05AE 0300 0357 0315 0062; +0061 0357 0315 0300 05AE 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062; +0061 035C 0315 0300 0358 0062;00E0 0315 0358 035C 0062;0061 0300 0315 0358 035C 0062;00E0 0315 0358 035C 0062;0061 0300 0315 0358 035C 0062; +0061 0358 035C 0315 0300 0062;00E0 0358 0315 035C 0062;0061 0300 0358 0315 035C 0062;00E0 0358 0315 035C 0062;0061 0300 0358 0315 035C 0062; +0061 059A 0316 302A 0359 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062; +0061 0359 059A 0316 302A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062; +0061 059A 0316 302A 035A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062; +0061 035A 059A 0316 302A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062; +0061 0315 0300 05AE 035B 0062;00E0 05AE 035B 0315 0062;0061 05AE 0300 035B 0315 0062;00E0 05AE 035B 0315 0062;0061 05AE 0300 035B 0315 0062; +0061 035B 0315 0300 05AE 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062; +0061 035D 035C 0315 035C 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062; +0061 035C 035D 035C 0315 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062; +0061 0345 035D 035C 035D 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062; +0061 035D 0345 035D 035C 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062; +0061 0345 035D 035C 035E 0062;0061 035C 035D 035E 0345 0062;0061 035C 035D 035E 0345 0062;0061 035C 035D 035E 0345 0062;0061 035C 035D 035E 0345 0062; +0061 035E 0345 035D 035C 0062;0061 035C 035E 035D 0345 0062;0061 035C 035E 035D 0345 0062;0061 035C 035E 035D 0345 0062;0061 035C 035E 035D 0345 0062; +0061 035D 035C 0315 035F 0062;0061 0315 035C 035F 035D 0062;0061 0315 035C 035F 035D 0062;0061 0315 035C 035F 035D 0062;0061 0315 035C 035F 035D 0062; +0061 035F 035D 035C 0315 0062;0061 0315 035F 035C 035D 0062;0061 0315 035F 035C 035D 0062;0061 0315 035F 035C 035D 0062;0061 0315 035F 035C 035D 0062; +0061 0345 035D 035C 0360 0062;0061 035C 035D 0360 0345 0062;0061 035C 035D 0360 0345 0062;0061 035C 035D 0360 0345 0062;0061 035C 035D 0360 0345 0062; +0061 0360 0345 035D 035C 0062;0061 035C 0360 035D 0345 0062;0061 035C 0360 035D 0345 0062;0061 035C 0360 035D 0345 0062;0061 035C 0360 035D 0345 0062; +0061 0345 035D 035C 0361 0062;0061 035C 035D 0361 0345 0062;0061 035C 035D 0361 0345 0062;0061 035C 035D 0361 0345 0062;0061 035C 035D 0361 0345 0062; +0061 0361 0345 035D 035C 0062;0061 035C 0361 035D 0345 0062;0061 035C 0361 035D 0345 0062;0061 035C 0361 035D 0345 0062;0061 035C 0361 035D 0345 0062; +0061 035D 035C 0315 0362 0062;0061 0315 035C 0362 035D 0062;0061 0315 035C 0362 035D 0062;0061 0315 035C 0362 035D 0062;0061 0315 035C 0362 035D 0062; +0061 0362 035D 035C 0315 0062;0061 0315 0362 035C 035D 0062;0061 0315 0362 035C 035D 0062;0061 0315 0362 035C 035D 0062;0061 0315 0362 035C 035D 0062; +0061 0315 0300 05AE 0363 0062;00E0 05AE 0363 0315 0062;0061 05AE 0300 0363 0315 0062;00E0 05AE 0363 0315 0062;0061 05AE 0300 0363 0315 0062; +0061 0363 0315 0300 05AE 0062;0061 05AE 0363 0300 0315 0062;0061 05AE 0363 0300 0315 0062;0061 05AE 0363 0300 0315 0062;0061 05AE 0363 0300 0315 0062; +0061 0315 0300 05AE 0364 0062;00E0 05AE 0364 0315 0062;0061 05AE 0300 0364 0315 0062;00E0 05AE 0364 0315 0062;0061 05AE 0300 0364 0315 0062; +0061 0364 0315 0300 05AE 0062;0061 05AE 0364 0300 0315 0062;0061 05AE 0364 0300 0315 0062;0061 05AE 0364 0300 0315 0062;0061 05AE 0364 0300 0315 0062; +0061 0315 0300 05AE 0365 0062;00E0 05AE 0365 0315 0062;0061 05AE 0300 0365 0315 0062;00E0 05AE 0365 0315 0062;0061 05AE 0300 0365 0315 0062; +0061 0365 0315 0300 05AE 0062;0061 05AE 0365 0300 0315 0062;0061 05AE 0365 0300 0315 0062;0061 05AE 0365 0300 0315 0062;0061 05AE 0365 0300 0315 0062; +0061 0315 0300 05AE 0366 0062;00E0 05AE 0366 0315 0062;0061 05AE 0300 0366 0315 0062;00E0 05AE 0366 0315 0062;0061 05AE 0300 0366 0315 0062; +0061 0366 0315 0300 05AE 0062;0061 05AE 0366 0300 0315 0062;0061 05AE 0366 0300 0315 0062;0061 05AE 0366 0300 0315 0062;0061 05AE 0366 0300 0315 0062; +0061 0315 0300 05AE 0367 0062;00E0 05AE 0367 0315 0062;0061 05AE 0300 0367 0315 0062;00E0 05AE 0367 0315 0062;0061 05AE 0300 0367 0315 0062; +0061 0367 0315 0300 05AE 0062;0061 05AE 0367 0300 0315 0062;0061 05AE 0367 0300 0315 0062;0061 05AE 0367 0300 0315 0062;0061 05AE 0367 0300 0315 0062; +0061 0315 0300 05AE 0368 0062;00E0 05AE 0368 0315 0062;0061 05AE 0300 0368 0315 0062;00E0 05AE 0368 0315 0062;0061 05AE 0300 0368 0315 0062; +0061 0368 0315 0300 05AE 0062;0061 05AE 0368 0300 0315 0062;0061 05AE 0368 0300 0315 0062;0061 05AE 0368 0300 0315 0062;0061 05AE 0368 0300 0315 0062; +0061 0315 0300 05AE 0369 0062;00E0 05AE 0369 0315 0062;0061 05AE 0300 0369 0315 0062;00E0 05AE 0369 0315 0062;0061 05AE 0300 0369 0315 0062; +0061 0369 0315 0300 05AE 0062;0061 05AE 0369 0300 0315 0062;0061 05AE 0369 0300 0315 0062;0061 05AE 0369 0300 0315 0062;0061 05AE 0369 0300 0315 0062; +0061 0315 0300 05AE 036A 0062;00E0 05AE 036A 0315 0062;0061 05AE 0300 036A 0315 0062;00E0 05AE 036A 0315 0062;0061 05AE 0300 036A 0315 0062; +0061 036A 0315 0300 05AE 0062;0061 05AE 036A 0300 0315 0062;0061 05AE 036A 0300 0315 0062;0061 05AE 036A 0300 0315 0062;0061 05AE 036A 0300 0315 0062; +0061 0315 0300 05AE 036B 0062;00E0 05AE 036B 0315 0062;0061 05AE 0300 036B 0315 0062;00E0 05AE 036B 0315 0062;0061 05AE 0300 036B 0315 0062; +0061 036B 0315 0300 05AE 0062;0061 05AE 036B 0300 0315 0062;0061 05AE 036B 0300 0315 0062;0061 05AE 036B 0300 0315 0062;0061 05AE 036B 0300 0315 0062; +0061 0315 0300 05AE 036C 0062;00E0 05AE 036C 0315 0062;0061 05AE 0300 036C 0315 0062;00E0 05AE 036C 0315 0062;0061 05AE 0300 036C 0315 0062; +0061 036C 0315 0300 05AE 0062;0061 05AE 036C 0300 0315 0062;0061 05AE 036C 0300 0315 0062;0061 05AE 036C 0300 0315 0062;0061 05AE 036C 0300 0315 0062; +0061 0315 0300 05AE 036D 0062;00E0 05AE 036D 0315 0062;0061 05AE 0300 036D 0315 0062;00E0 05AE 036D 0315 0062;0061 05AE 0300 036D 0315 0062; +0061 036D 0315 0300 05AE 0062;0061 05AE 036D 0300 0315 0062;0061 05AE 036D 0300 0315 0062;0061 05AE 036D 0300 0315 0062;0061 05AE 036D 0300 0315 0062; +0061 0315 0300 05AE 036E 0062;00E0 05AE 036E 0315 0062;0061 05AE 0300 036E 0315 0062;00E0 05AE 036E 0315 0062;0061 05AE 0300 036E 0315 0062; +0061 036E 0315 0300 05AE 0062;0061 05AE 036E 0300 0315 0062;0061 05AE 036E 0300 0315 0062;0061 05AE 036E 0300 0315 0062;0061 05AE 036E 0300 0315 0062; +0061 0315 0300 05AE 036F 0062;00E0 05AE 036F 0315 0062;0061 05AE 0300 036F 0315 0062;00E0 05AE 036F 0315 0062;0061 05AE 0300 036F 0315 0062; +0061 036F 0315 0300 05AE 0062;0061 05AE 036F 0300 0315 0062;0061 05AE 036F 0300 0315 0062;0061 05AE 036F 0300 0315 0062;0061 05AE 036F 0300 0315 0062; +0061 0315 0300 05AE 0483 0062;00E0 05AE 0483 0315 0062;0061 05AE 0300 0483 0315 0062;00E0 05AE 0483 0315 0062;0061 05AE 0300 0483 0315 0062; +0061 0483 0315 0300 05AE 0062;0061 05AE 0483 0300 0315 0062;0061 05AE 0483 0300 0315 0062;0061 05AE 0483 0300 0315 0062;0061 05AE 0483 0300 0315 0062; +0061 0315 0300 05AE 0484 0062;00E0 05AE 0484 0315 0062;0061 05AE 0300 0484 0315 0062;00E0 05AE 0484 0315 0062;0061 05AE 0300 0484 0315 0062; +0061 0484 0315 0300 05AE 0062;0061 05AE 0484 0300 0315 0062;0061 05AE 0484 0300 0315 0062;0061 05AE 0484 0300 0315 0062;0061 05AE 0484 0300 0315 0062; +0061 0315 0300 05AE 0485 0062;00E0 05AE 0485 0315 0062;0061 05AE 0300 0485 0315 0062;00E0 05AE 0485 0315 0062;0061 05AE 0300 0485 0315 0062; +0061 0485 0315 0300 05AE 0062;0061 05AE 0485 0300 0315 0062;0061 05AE 0485 0300 0315 0062;0061 05AE 0485 0300 0315 0062;0061 05AE 0485 0300 0315 0062; +0061 0315 0300 05AE 0486 0062;00E0 05AE 0486 0315 0062;0061 05AE 0300 0486 0315 0062;00E0 05AE 0486 0315 0062;0061 05AE 0300 0486 0315 0062; +0061 0486 0315 0300 05AE 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062; +0061 0315 0300 05AE 0487 0062;00E0 05AE 0487 0315 0062;0061 05AE 0300 0487 0315 0062;00E0 05AE 0487 0315 0062;0061 05AE 0300 0487 0315 0062; +0061 0487 0315 0300 05AE 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062; +0061 059A 0316 302A 0591 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062; +0061 0591 059A 0316 302A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062; +0061 0315 0300 05AE 0592 0062;00E0 05AE 0592 0315 0062;0061 05AE 0300 0592 0315 0062;00E0 05AE 0592 0315 0062;0061 05AE 0300 0592 0315 0062; +0061 0592 0315 0300 05AE 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062; +0061 0315 0300 05AE 0593 0062;00E0 05AE 0593 0315 0062;0061 05AE 0300 0593 0315 0062;00E0 05AE 0593 0315 0062;0061 05AE 0300 0593 0315 0062; +0061 0593 0315 0300 05AE 0062;0061 05AE 0593 0300 0315 0062;0061 05AE 0593 0300 0315 0062;0061 05AE 0593 0300 0315 0062;0061 05AE 0593 0300 0315 0062; +0061 0315 0300 05AE 0594 0062;00E0 05AE 0594 0315 0062;0061 05AE 0300 0594 0315 0062;00E0 05AE 0594 0315 0062;0061 05AE 0300 0594 0315 0062; +0061 0594 0315 0300 05AE 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062; +0061 0315 0300 05AE 0595 0062;00E0 05AE 0595 0315 0062;0061 05AE 0300 0595 0315 0062;00E0 05AE 0595 0315 0062;0061 05AE 0300 0595 0315 0062; +0061 0595 0315 0300 05AE 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062; +0061 059A 0316 302A 0596 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062; +0061 0596 059A 0316 302A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062; +0061 0315 0300 05AE 0597 0062;00E0 05AE 0597 0315 0062;0061 05AE 0300 0597 0315 0062;00E0 05AE 0597 0315 0062;0061 05AE 0300 0597 0315 0062; +0061 0597 0315 0300 05AE 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062; +0061 0315 0300 05AE 0598 0062;00E0 05AE 0598 0315 0062;0061 05AE 0300 0598 0315 0062;00E0 05AE 0598 0315 0062;0061 05AE 0300 0598 0315 0062; +0061 0598 0315 0300 05AE 0062;0061 05AE 0598 0300 0315 0062;0061 05AE 0598 0300 0315 0062;0061 05AE 0598 0300 0315 0062;0061 05AE 0598 0300 0315 0062; +0061 0315 0300 05AE 0599 0062;00E0 05AE 0599 0315 0062;0061 05AE 0300 0599 0315 0062;00E0 05AE 0599 0315 0062;0061 05AE 0300 0599 0315 0062; +0061 0599 0315 0300 05AE 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062; +0061 302E 059A 0316 059A 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062; +0061 059A 302E 059A 0316 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062; +0061 059A 0316 302A 059B 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062; +0061 059B 059A 0316 302A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062; +0061 0315 0300 05AE 059C 0062;00E0 05AE 059C 0315 0062;0061 05AE 0300 059C 0315 0062;00E0 05AE 059C 0315 0062;0061 05AE 0300 059C 0315 0062; +0061 059C 0315 0300 05AE 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062; +0061 0315 0300 05AE 059D 0062;00E0 05AE 059D 0315 0062;0061 05AE 0300 059D 0315 0062;00E0 05AE 059D 0315 0062;0061 05AE 0300 059D 0315 0062; +0061 059D 0315 0300 05AE 0062;0061 05AE 059D 0300 0315 0062;0061 05AE 059D 0300 0315 0062;0061 05AE 059D 0300 0315 0062;0061 05AE 059D 0300 0315 0062; +0061 0315 0300 05AE 059E 0062;00E0 05AE 059E 0315 0062;0061 05AE 0300 059E 0315 0062;00E0 05AE 059E 0315 0062;0061 05AE 0300 059E 0315 0062; +0061 059E 0315 0300 05AE 0062;0061 05AE 059E 0300 0315 0062;0061 05AE 059E 0300 0315 0062;0061 05AE 059E 0300 0315 0062;0061 05AE 059E 0300 0315 0062; +0061 0315 0300 05AE 059F 0062;00E0 05AE 059F 0315 0062;0061 05AE 0300 059F 0315 0062;00E0 05AE 059F 0315 0062;0061 05AE 0300 059F 0315 0062; +0061 059F 0315 0300 05AE 0062;0061 05AE 059F 0300 0315 0062;0061 05AE 059F 0300 0315 0062;0061 05AE 059F 0300 0315 0062;0061 05AE 059F 0300 0315 0062; +0061 0315 0300 05AE 05A0 0062;00E0 05AE 05A0 0315 0062;0061 05AE 0300 05A0 0315 0062;00E0 05AE 05A0 0315 0062;0061 05AE 0300 05A0 0315 0062; +0061 05A0 0315 0300 05AE 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062; +0061 0315 0300 05AE 05A1 0062;00E0 05AE 05A1 0315 0062;0061 05AE 0300 05A1 0315 0062;00E0 05AE 05A1 0315 0062;0061 05AE 0300 05A1 0315 0062; +0061 05A1 0315 0300 05AE 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062; +0061 059A 0316 302A 05A2 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062; +0061 05A2 059A 0316 302A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062; +0061 059A 0316 302A 05A3 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062; +0061 05A3 059A 0316 302A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062; +0061 059A 0316 302A 05A4 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062; +0061 05A4 059A 0316 302A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062; +0061 059A 0316 302A 05A5 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062; +0061 05A5 059A 0316 302A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062; +0061 059A 0316 302A 05A6 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062; +0061 05A6 059A 0316 302A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062; +0061 059A 0316 302A 05A7 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062; +0061 05A7 059A 0316 302A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062; +0061 0315 0300 05AE 05A8 0062;00E0 05AE 05A8 0315 0062;0061 05AE 0300 05A8 0315 0062;00E0 05AE 05A8 0315 0062;0061 05AE 0300 05A8 0315 0062; +0061 05A8 0315 0300 05AE 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062; +0061 0315 0300 05AE 05A9 0062;00E0 05AE 05A9 0315 0062;0061 05AE 0300 05A9 0315 0062;00E0 05AE 05A9 0315 0062;0061 05AE 0300 05A9 0315 0062; +0061 05A9 0315 0300 05AE 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062; +0061 059A 0316 302A 05AA 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062; +0061 05AA 059A 0316 302A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062; +0061 0315 0300 05AE 05AB 0062;00E0 05AE 05AB 0315 0062;0061 05AE 0300 05AB 0315 0062;00E0 05AE 05AB 0315 0062;0061 05AE 0300 05AB 0315 0062; +0061 05AB 0315 0300 05AE 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062; +0061 0315 0300 05AE 05AC 0062;00E0 05AE 05AC 0315 0062;0061 05AE 0300 05AC 0315 0062;00E0 05AE 05AC 0315 0062;0061 05AE 0300 05AC 0315 0062; +0061 05AC 0315 0300 05AE 0062;0061 05AE 05AC 0300 0315 0062;0061 05AE 05AC 0300 0315 0062;0061 05AE 05AC 0300 0315 0062;0061 05AE 05AC 0300 0315 0062; +0061 302E 059A 0316 05AD 0062;0061 0316 059A 05AD 302E 0062;0061 0316 059A 05AD 302E 0062;0061 0316 059A 05AD 302E 0062;0061 0316 059A 05AD 302E 0062; +0061 05AD 302E 059A 0316 0062;0061 0316 05AD 059A 302E 0062;0061 0316 05AD 059A 302E 0062;0061 0316 05AD 059A 302E 0062;0061 0316 05AD 059A 302E 0062; +0061 0300 05AE 1D16D 05AE 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062; +0061 05AE 0300 05AE 1D16D 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062; +0061 0315 0300 05AE 05AF 0062;00E0 05AE 05AF 0315 0062;0061 05AE 0300 05AF 0315 0062;00E0 05AE 05AF 0315 0062;0061 05AE 0300 05AF 0315 0062; +0061 05AF 0315 0300 05AE 0062;0061 05AE 05AF 0300 0315 0062;0061 05AE 05AF 0300 0315 0062;0061 05AE 05AF 0300 0315 0062;0061 05AE 05AF 0300 0315 0062; +0061 05B1 05B0 094D 05B0 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062; +0061 05B0 05B1 05B0 094D 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062; +0061 05B2 05B1 05B0 05B1 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062; +0061 05B1 05B2 05B1 05B0 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062; +0061 05B3 05B2 05B1 05B2 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062; +0061 05B2 05B3 05B2 05B1 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062; +0061 05B4 05B3 05B2 05B3 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062; +0061 05B3 05B4 05B3 05B2 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062; +0061 05B5 05B4 05B3 05B4 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062; +0061 05B4 05B5 05B4 05B3 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062; +0061 05B6 05B5 05B4 05B5 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062; +0061 05B5 05B6 05B5 05B4 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062; +0061 05B7 05B6 05B5 05B6 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062; +0061 05B6 05B7 05B6 05B5 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062; +0061 05B8 05B7 05B6 05B7 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062; +0061 05B7 05B8 05B7 05B6 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062; +0061 05B9 05B8 05B7 05B8 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062; +0061 05B8 05B9 05B8 05B7 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062; +0061 05BB 05B9 05B8 05B9 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062; +0061 05B9 05BB 05B9 05B8 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062; +0061 05BB 05B9 05B8 05BA 0062;0061 05B8 05B9 05BA 05BB 0062;0061 05B8 05B9 05BA 05BB 0062;0061 05B8 05B9 05BA 05BB 0062;0061 05B8 05B9 05BA 05BB 0062; +0061 05BA 05BB 05B9 05B8 0062;0061 05B8 05BA 05B9 05BB 0062;0061 05B8 05BA 05B9 05BB 0062;0061 05B8 05BA 05B9 05BB 0062;0061 05B8 05BA 05B9 05BB 0062; +0061 05BC 05BB 05B9 05BB 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062; +0061 05BB 05BC 05BB 05B9 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062; +0061 05BD 05BC 05BB 05BC 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062; +0061 05BC 05BD 05BC 05BB 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062; +0061 05BF 05BD 05BC 05BD 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062; +0061 05BD 05BF 05BD 05BC 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062; +0061 05C1 05BF 05BD 05BF 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062; +0061 05BF 05C1 05BF 05BD 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062; +0061 05C2 05C1 05BF 05C1 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062; +0061 05C1 05C2 05C1 05BF 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062; +0061 FB1E 05C2 05C1 05C2 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062; +0061 05C2 FB1E 05C2 05C1 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062; +0061 0315 0300 05AE 05C4 0062;00E0 05AE 05C4 0315 0062;0061 05AE 0300 05C4 0315 0062;00E0 05AE 05C4 0315 0062;0061 05AE 0300 05C4 0315 0062; +0061 05C4 0315 0300 05AE 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062; +0061 059A 0316 302A 05C5 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062; +0061 05C5 059A 0316 302A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062; +0061 05B9 05B8 05B7 05C7 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062; +0061 05C7 05B9 05B8 05B7 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062; +0061 0315 0300 05AE 0610 0062;00E0 05AE 0610 0315 0062;0061 05AE 0300 0610 0315 0062;00E0 05AE 0610 0315 0062;0061 05AE 0300 0610 0315 0062; +0061 0610 0315 0300 05AE 0062;0061 05AE 0610 0300 0315 0062;0061 05AE 0610 0300 0315 0062;0061 05AE 0610 0300 0315 0062;0061 05AE 0610 0300 0315 0062; +0061 0315 0300 05AE 0611 0062;00E0 05AE 0611 0315 0062;0061 05AE 0300 0611 0315 0062;00E0 05AE 0611 0315 0062;0061 05AE 0300 0611 0315 0062; +0061 0611 0315 0300 05AE 0062;0061 05AE 0611 0300 0315 0062;0061 05AE 0611 0300 0315 0062;0061 05AE 0611 0300 0315 0062;0061 05AE 0611 0300 0315 0062; +0061 0315 0300 05AE 0612 0062;00E0 05AE 0612 0315 0062;0061 05AE 0300 0612 0315 0062;00E0 05AE 0612 0315 0062;0061 05AE 0300 0612 0315 0062; +0061 0612 0315 0300 05AE 0062;0061 05AE 0612 0300 0315 0062;0061 05AE 0612 0300 0315 0062;0061 05AE 0612 0300 0315 0062;0061 05AE 0612 0300 0315 0062; +0061 0315 0300 05AE 0613 0062;00E0 05AE 0613 0315 0062;0061 05AE 0300 0613 0315 0062;00E0 05AE 0613 0315 0062;0061 05AE 0300 0613 0315 0062; +0061 0613 0315 0300 05AE 0062;0061 05AE 0613 0300 0315 0062;0061 05AE 0613 0300 0315 0062;0061 05AE 0613 0300 0315 0062;0061 05AE 0613 0300 0315 0062; +0061 0315 0300 05AE 0614 0062;00E0 05AE 0614 0315 0062;0061 05AE 0300 0614 0315 0062;00E0 05AE 0614 0315 0062;0061 05AE 0300 0614 0315 0062; +0061 0614 0315 0300 05AE 0062;0061 05AE 0614 0300 0315 0062;0061 05AE 0614 0300 0315 0062;0061 05AE 0614 0300 0315 0062;0061 05AE 0614 0300 0315 0062; +0061 0315 0300 05AE 0615 0062;00E0 05AE 0615 0315 0062;0061 05AE 0300 0615 0315 0062;00E0 05AE 0615 0315 0062;0061 05AE 0300 0615 0315 0062; +0061 0615 0315 0300 05AE 0062;0061 05AE 0615 0300 0315 0062;0061 05AE 0615 0300 0315 0062;0061 05AE 0615 0300 0315 0062;0061 05AE 0615 0300 0315 0062; +0061 0315 0300 05AE 0616 0062;00E0 05AE 0616 0315 0062;0061 05AE 0300 0616 0315 0062;00E0 05AE 0616 0315 0062;0061 05AE 0300 0616 0315 0062; +0061 0616 0315 0300 05AE 0062;0061 05AE 0616 0300 0315 0062;0061 05AE 0616 0300 0315 0062;0061 05AE 0616 0300 0315 0062;0061 05AE 0616 0300 0315 0062; +0061 0315 0300 05AE 0617 0062;00E0 05AE 0617 0315 0062;0061 05AE 0300 0617 0315 0062;00E0 05AE 0617 0315 0062;0061 05AE 0300 0617 0315 0062; +0061 0617 0315 0300 05AE 0062;0061 05AE 0617 0300 0315 0062;0061 05AE 0617 0300 0315 0062;0061 05AE 0617 0300 0315 0062;0061 05AE 0617 0300 0315 0062; +0061 0619 0618 064D 0618 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062; +0061 0618 0619 0618 064D 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062; +0061 061A 0619 0618 0619 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062; +0061 0619 061A 0619 0618 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062; +0061 0651 061A 0619 061A 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062; +0061 061A 0651 061A 0619 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062; +0061 064C 064B FB1E 064B 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062; +0061 064B 064C 064B FB1E 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062; +0061 064D 064C 064B 064C 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062; +0061 064C 064D 064C 064B 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062; +0061 0618 064D 064C 064D 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062; +0061 064D 0618 064D 064C 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062; +0061 0619 0618 064D 064E 0062;0061 064D 0618 064E 0619 0062;0061 064D 0618 064E 0619 0062;0061 064D 0618 064E 0619 0062;0061 064D 0618 064E 0619 0062; +0061 064E 0619 0618 064D 0062;0061 064D 064E 0618 0619 0062;0061 064D 064E 0618 0619 0062;0061 064D 064E 0618 0619 0062;0061 064D 064E 0618 0619 0062; +0061 061A 0619 0618 064F 0062;0061 0618 0619 064F 061A 0062;0061 0618 0619 064F 061A 0062;0061 0618 0619 064F 061A 0062;0061 0618 0619 064F 061A 0062; +0061 064F 061A 0619 0618 0062;0061 0618 064F 0619 061A 0062;0061 0618 064F 0619 061A 0062;0061 0618 064F 0619 061A 0062;0061 0618 064F 0619 061A 0062; +0061 0651 061A 0619 0650 0062;0061 0619 061A 0650 0651 0062;0061 0619 061A 0650 0651 0062;0061 0619 061A 0650 0651 0062;0061 0619 061A 0650 0651 0062; +0061 0650 0651 061A 0619 0062;0061 0619 0650 061A 0651 0062;0061 0619 0650 061A 0651 0062;0061 0619 0650 061A 0651 0062;0061 0619 0650 061A 0651 0062; +0061 0652 0651 061A 0651 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062; +0061 0651 0652 0651 061A 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062; +0061 0670 0652 0651 0652 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062; +0061 0652 0670 0652 0651 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062; +0061 0315 0300 05AE 0653 0062;00E0 05AE 0653 0315 0062;0061 05AE 0300 0653 0315 0062;00E0 05AE 0653 0315 0062;0061 05AE 0300 0653 0315 0062; +0061 0653 0315 0300 05AE 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062; +0061 0315 0300 05AE 0654 0062;00E0 05AE 0654 0315 0062;0061 05AE 0300 0654 0315 0062;00E0 05AE 0654 0315 0062;0061 05AE 0300 0654 0315 0062; +0061 0654 0315 0300 05AE 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062; +0061 059A 0316 302A 0655 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062; +0061 0655 059A 0316 302A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062; +0061 059A 0316 302A 0656 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062; +0061 0656 059A 0316 302A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062; +0061 0315 0300 05AE 0657 0062;00E0 05AE 0657 0315 0062;0061 05AE 0300 0657 0315 0062;00E0 05AE 0657 0315 0062;0061 05AE 0300 0657 0315 0062; +0061 0657 0315 0300 05AE 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062; +0061 0315 0300 05AE 0658 0062;00E0 05AE 0658 0315 0062;0061 05AE 0300 0658 0315 0062;00E0 05AE 0658 0315 0062;0061 05AE 0300 0658 0315 0062; +0061 0658 0315 0300 05AE 0062;0061 05AE 0658 0300 0315 0062;0061 05AE 0658 0300 0315 0062;0061 05AE 0658 0300 0315 0062;0061 05AE 0658 0300 0315 0062; +0061 0315 0300 05AE 0659 0062;00E0 05AE 0659 0315 0062;0061 05AE 0300 0659 0315 0062;00E0 05AE 0659 0315 0062;0061 05AE 0300 0659 0315 0062; +0061 0659 0315 0300 05AE 0062;0061 05AE 0659 0300 0315 0062;0061 05AE 0659 0300 0315 0062;0061 05AE 0659 0300 0315 0062;0061 05AE 0659 0300 0315 0062; +0061 0315 0300 05AE 065A 0062;00E0 05AE 065A 0315 0062;0061 05AE 0300 065A 0315 0062;00E0 05AE 065A 0315 0062;0061 05AE 0300 065A 0315 0062; +0061 065A 0315 0300 05AE 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062; +0061 0315 0300 05AE 065B 0062;00E0 05AE 065B 0315 0062;0061 05AE 0300 065B 0315 0062;00E0 05AE 065B 0315 0062;0061 05AE 0300 065B 0315 0062; +0061 065B 0315 0300 05AE 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062; +0061 059A 0316 302A 065C 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062; +0061 065C 059A 0316 302A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062; +0061 0315 0300 05AE 065D 0062;00E0 05AE 065D 0315 0062;0061 05AE 0300 065D 0315 0062;00E0 05AE 065D 0315 0062;0061 05AE 0300 065D 0315 0062; +0061 065D 0315 0300 05AE 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062; +0061 0315 0300 05AE 065E 0062;00E0 05AE 065E 0315 0062;0061 05AE 0300 065E 0315 0062;00E0 05AE 065E 0315 0062;0061 05AE 0300 065E 0315 0062; +0061 065E 0315 0300 05AE 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062; +0061 059A 0316 302A 065F 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062; +0061 065F 059A 0316 302A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062; +0061 0711 0670 0652 0670 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062; +0061 0670 0711 0670 0652 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062; +0061 0315 0300 05AE 06D6 0062;00E0 05AE 06D6 0315 0062;0061 05AE 0300 06D6 0315 0062;00E0 05AE 06D6 0315 0062;0061 05AE 0300 06D6 0315 0062; +0061 06D6 0315 0300 05AE 0062;0061 05AE 06D6 0300 0315 0062;0061 05AE 06D6 0300 0315 0062;0061 05AE 06D6 0300 0315 0062;0061 05AE 06D6 0300 0315 0062; +0061 0315 0300 05AE 06D7 0062;00E0 05AE 06D7 0315 0062;0061 05AE 0300 06D7 0315 0062;00E0 05AE 06D7 0315 0062;0061 05AE 0300 06D7 0315 0062; +0061 06D7 0315 0300 05AE 0062;0061 05AE 06D7 0300 0315 0062;0061 05AE 06D7 0300 0315 0062;0061 05AE 06D7 0300 0315 0062;0061 05AE 06D7 0300 0315 0062; +0061 0315 0300 05AE 06D8 0062;00E0 05AE 06D8 0315 0062;0061 05AE 0300 06D8 0315 0062;00E0 05AE 06D8 0315 0062;0061 05AE 0300 06D8 0315 0062; +0061 06D8 0315 0300 05AE 0062;0061 05AE 06D8 0300 0315 0062;0061 05AE 06D8 0300 0315 0062;0061 05AE 06D8 0300 0315 0062;0061 05AE 06D8 0300 0315 0062; +0061 0315 0300 05AE 06D9 0062;00E0 05AE 06D9 0315 0062;0061 05AE 0300 06D9 0315 0062;00E0 05AE 06D9 0315 0062;0061 05AE 0300 06D9 0315 0062; +0061 06D9 0315 0300 05AE 0062;0061 05AE 06D9 0300 0315 0062;0061 05AE 06D9 0300 0315 0062;0061 05AE 06D9 0300 0315 0062;0061 05AE 06D9 0300 0315 0062; +0061 0315 0300 05AE 06DA 0062;00E0 05AE 06DA 0315 0062;0061 05AE 0300 06DA 0315 0062;00E0 05AE 06DA 0315 0062;0061 05AE 0300 06DA 0315 0062; +0061 06DA 0315 0300 05AE 0062;0061 05AE 06DA 0300 0315 0062;0061 05AE 06DA 0300 0315 0062;0061 05AE 06DA 0300 0315 0062;0061 05AE 06DA 0300 0315 0062; +0061 0315 0300 05AE 06DB 0062;00E0 05AE 06DB 0315 0062;0061 05AE 0300 06DB 0315 0062;00E0 05AE 06DB 0315 0062;0061 05AE 0300 06DB 0315 0062; +0061 06DB 0315 0300 05AE 0062;0061 05AE 06DB 0300 0315 0062;0061 05AE 06DB 0300 0315 0062;0061 05AE 06DB 0300 0315 0062;0061 05AE 06DB 0300 0315 0062; +0061 0315 0300 05AE 06DC 0062;00E0 05AE 06DC 0315 0062;0061 05AE 0300 06DC 0315 0062;00E0 05AE 06DC 0315 0062;0061 05AE 0300 06DC 0315 0062; +0061 06DC 0315 0300 05AE 0062;0061 05AE 06DC 0300 0315 0062;0061 05AE 06DC 0300 0315 0062;0061 05AE 06DC 0300 0315 0062;0061 05AE 06DC 0300 0315 0062; +0061 0315 0300 05AE 06DF 0062;00E0 05AE 06DF 0315 0062;0061 05AE 0300 06DF 0315 0062;00E0 05AE 06DF 0315 0062;0061 05AE 0300 06DF 0315 0062; +0061 06DF 0315 0300 05AE 0062;0061 05AE 06DF 0300 0315 0062;0061 05AE 06DF 0300 0315 0062;0061 05AE 06DF 0300 0315 0062;0061 05AE 06DF 0300 0315 0062; +0061 0315 0300 05AE 06E0 0062;00E0 05AE 06E0 0315 0062;0061 05AE 0300 06E0 0315 0062;00E0 05AE 06E0 0315 0062;0061 05AE 0300 06E0 0315 0062; +0061 06E0 0315 0300 05AE 0062;0061 05AE 06E0 0300 0315 0062;0061 05AE 06E0 0300 0315 0062;0061 05AE 06E0 0300 0315 0062;0061 05AE 06E0 0300 0315 0062; +0061 0315 0300 05AE 06E1 0062;00E0 05AE 06E1 0315 0062;0061 05AE 0300 06E1 0315 0062;00E0 05AE 06E1 0315 0062;0061 05AE 0300 06E1 0315 0062; +0061 06E1 0315 0300 05AE 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062; +0061 0315 0300 05AE 06E2 0062;00E0 05AE 06E2 0315 0062;0061 05AE 0300 06E2 0315 0062;00E0 05AE 06E2 0315 0062;0061 05AE 0300 06E2 0315 0062; +0061 06E2 0315 0300 05AE 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062; +0061 059A 0316 302A 06E3 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062; +0061 06E3 059A 0316 302A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062; +0061 0315 0300 05AE 06E4 0062;00E0 05AE 06E4 0315 0062;0061 05AE 0300 06E4 0315 0062;00E0 05AE 06E4 0315 0062;0061 05AE 0300 06E4 0315 0062; +0061 06E4 0315 0300 05AE 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062; +0061 0315 0300 05AE 06E7 0062;00E0 05AE 06E7 0315 0062;0061 05AE 0300 06E7 0315 0062;00E0 05AE 06E7 0315 0062;0061 05AE 0300 06E7 0315 0062; +0061 06E7 0315 0300 05AE 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062; +0061 0315 0300 05AE 06E8 0062;00E0 05AE 06E8 0315 0062;0061 05AE 0300 06E8 0315 0062;00E0 05AE 06E8 0315 0062;0061 05AE 0300 06E8 0315 0062; +0061 06E8 0315 0300 05AE 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062; +0061 059A 0316 302A 06EA 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062; +0061 06EA 059A 0316 302A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062; +0061 0315 0300 05AE 06EB 0062;00E0 05AE 06EB 0315 0062;0061 05AE 0300 06EB 0315 0062;00E0 05AE 06EB 0315 0062;0061 05AE 0300 06EB 0315 0062; +0061 06EB 0315 0300 05AE 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062; +0061 0315 0300 05AE 06EC 0062;00E0 05AE 06EC 0315 0062;0061 05AE 0300 06EC 0315 0062;00E0 05AE 06EC 0315 0062;0061 05AE 0300 06EC 0315 0062; +0061 06EC 0315 0300 05AE 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062; +0061 059A 0316 302A 06ED 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062; +0061 06ED 059A 0316 302A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062; +0061 0C55 0711 0670 0711 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062; +0061 0711 0C55 0711 0670 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062; +0061 0315 0300 05AE 0730 0062;00E0 05AE 0730 0315 0062;0061 05AE 0300 0730 0315 0062;00E0 05AE 0730 0315 0062;0061 05AE 0300 0730 0315 0062; +0061 0730 0315 0300 05AE 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062; +0061 059A 0316 302A 0731 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062; +0061 0731 059A 0316 302A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062; +0061 0315 0300 05AE 0732 0062;00E0 05AE 0732 0315 0062;0061 05AE 0300 0732 0315 0062;00E0 05AE 0732 0315 0062;0061 05AE 0300 0732 0315 0062; +0061 0732 0315 0300 05AE 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062; +0061 0315 0300 05AE 0733 0062;00E0 05AE 0733 0315 0062;0061 05AE 0300 0733 0315 0062;00E0 05AE 0733 0315 0062;0061 05AE 0300 0733 0315 0062; +0061 0733 0315 0300 05AE 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062; +0061 059A 0316 302A 0734 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062; +0061 0734 059A 0316 302A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062; +0061 0315 0300 05AE 0735 0062;00E0 05AE 0735 0315 0062;0061 05AE 0300 0735 0315 0062;00E0 05AE 0735 0315 0062;0061 05AE 0300 0735 0315 0062; +0061 0735 0315 0300 05AE 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062; +0061 0315 0300 05AE 0736 0062;00E0 05AE 0736 0315 0062;0061 05AE 0300 0736 0315 0062;00E0 05AE 0736 0315 0062;0061 05AE 0300 0736 0315 0062; +0061 0736 0315 0300 05AE 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062; +0061 059A 0316 302A 0737 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062; +0061 0737 059A 0316 302A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062; +0061 059A 0316 302A 0738 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062; +0061 0738 059A 0316 302A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062; +0061 059A 0316 302A 0739 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062; +0061 0739 059A 0316 302A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062; +0061 0315 0300 05AE 073A 0062;00E0 05AE 073A 0315 0062;0061 05AE 0300 073A 0315 0062;00E0 05AE 073A 0315 0062;0061 05AE 0300 073A 0315 0062; +0061 073A 0315 0300 05AE 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062; +0061 059A 0316 302A 073B 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062; +0061 073B 059A 0316 302A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062; +0061 059A 0316 302A 073C 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062; +0061 073C 059A 0316 302A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062; +0061 0315 0300 05AE 073D 0062;00E0 05AE 073D 0315 0062;0061 05AE 0300 073D 0315 0062;00E0 05AE 073D 0315 0062;0061 05AE 0300 073D 0315 0062; +0061 073D 0315 0300 05AE 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062; +0061 059A 0316 302A 073E 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062; +0061 073E 059A 0316 302A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062; +0061 0315 0300 05AE 073F 0062;00E0 05AE 073F 0315 0062;0061 05AE 0300 073F 0315 0062;00E0 05AE 073F 0315 0062;0061 05AE 0300 073F 0315 0062; +0061 073F 0315 0300 05AE 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062; +0061 0315 0300 05AE 0740 0062;00E0 05AE 0740 0315 0062;0061 05AE 0300 0740 0315 0062;00E0 05AE 0740 0315 0062;0061 05AE 0300 0740 0315 0062; +0061 0740 0315 0300 05AE 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062; +0061 0315 0300 05AE 0741 0062;00E0 05AE 0741 0315 0062;0061 05AE 0300 0741 0315 0062;00E0 05AE 0741 0315 0062;0061 05AE 0300 0741 0315 0062; +0061 0741 0315 0300 05AE 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062; +0061 059A 0316 302A 0742 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062; +0061 0742 059A 0316 302A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062; +0061 0315 0300 05AE 0743 0062;00E0 05AE 0743 0315 0062;0061 05AE 0300 0743 0315 0062;00E0 05AE 0743 0315 0062;0061 05AE 0300 0743 0315 0062; +0061 0743 0315 0300 05AE 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062; +0061 059A 0316 302A 0744 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062; +0061 0744 059A 0316 302A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062; +0061 0315 0300 05AE 0745 0062;00E0 05AE 0745 0315 0062;0061 05AE 0300 0745 0315 0062;00E0 05AE 0745 0315 0062;0061 05AE 0300 0745 0315 0062; +0061 0745 0315 0300 05AE 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062; +0061 059A 0316 302A 0746 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062; +0061 0746 059A 0316 302A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062; +0061 0315 0300 05AE 0747 0062;00E0 05AE 0747 0315 0062;0061 05AE 0300 0747 0315 0062;00E0 05AE 0747 0315 0062;0061 05AE 0300 0747 0315 0062; +0061 0747 0315 0300 05AE 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062; +0061 059A 0316 302A 0748 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062; +0061 0748 059A 0316 302A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062; +0061 0315 0300 05AE 0749 0062;00E0 05AE 0749 0315 0062;0061 05AE 0300 0749 0315 0062;00E0 05AE 0749 0315 0062;0061 05AE 0300 0749 0315 0062; +0061 0749 0315 0300 05AE 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062; +0061 0315 0300 05AE 074A 0062;00E0 05AE 074A 0315 0062;0061 05AE 0300 074A 0315 0062;00E0 05AE 074A 0315 0062;0061 05AE 0300 074A 0315 0062; +0061 074A 0315 0300 05AE 0062;0061 05AE 074A 0300 0315 0062;0061 05AE 074A 0300 0315 0062;0061 05AE 074A 0300 0315 0062;0061 05AE 074A 0300 0315 0062; +0061 0315 0300 05AE 07EB 0062;00E0 05AE 07EB 0315 0062;0061 05AE 0300 07EB 0315 0062;00E0 05AE 07EB 0315 0062;0061 05AE 0300 07EB 0315 0062; +0061 07EB 0315 0300 05AE 0062;0061 05AE 07EB 0300 0315 0062;0061 05AE 07EB 0300 0315 0062;0061 05AE 07EB 0300 0315 0062;0061 05AE 07EB 0300 0315 0062; +0061 0315 0300 05AE 07EC 0062;00E0 05AE 07EC 0315 0062;0061 05AE 0300 07EC 0315 0062;00E0 05AE 07EC 0315 0062;0061 05AE 0300 07EC 0315 0062; +0061 07EC 0315 0300 05AE 0062;0061 05AE 07EC 0300 0315 0062;0061 05AE 07EC 0300 0315 0062;0061 05AE 07EC 0300 0315 0062;0061 05AE 07EC 0300 0315 0062; +0061 0315 0300 05AE 07ED 0062;00E0 05AE 07ED 0315 0062;0061 05AE 0300 07ED 0315 0062;00E0 05AE 07ED 0315 0062;0061 05AE 0300 07ED 0315 0062; +0061 07ED 0315 0300 05AE 0062;0061 05AE 07ED 0300 0315 0062;0061 05AE 07ED 0300 0315 0062;0061 05AE 07ED 0300 0315 0062;0061 05AE 07ED 0300 0315 0062; +0061 0315 0300 05AE 07EE 0062;00E0 05AE 07EE 0315 0062;0061 05AE 0300 07EE 0315 0062;00E0 05AE 07EE 0315 0062;0061 05AE 0300 07EE 0315 0062; +0061 07EE 0315 0300 05AE 0062;0061 05AE 07EE 0300 0315 0062;0061 05AE 07EE 0300 0315 0062;0061 05AE 07EE 0300 0315 0062;0061 05AE 07EE 0300 0315 0062; +0061 0315 0300 05AE 07EF 0062;00E0 05AE 07EF 0315 0062;0061 05AE 0300 07EF 0315 0062;00E0 05AE 07EF 0315 0062;0061 05AE 0300 07EF 0315 0062; +0061 07EF 0315 0300 05AE 0062;0061 05AE 07EF 0300 0315 0062;0061 05AE 07EF 0300 0315 0062;0061 05AE 07EF 0300 0315 0062;0061 05AE 07EF 0300 0315 0062; +0061 0315 0300 05AE 07F0 0062;00E0 05AE 07F0 0315 0062;0061 05AE 0300 07F0 0315 0062;00E0 05AE 07F0 0315 0062;0061 05AE 0300 07F0 0315 0062; +0061 07F0 0315 0300 05AE 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062; +0061 0315 0300 05AE 07F1 0062;00E0 05AE 07F1 0315 0062;0061 05AE 0300 07F1 0315 0062;00E0 05AE 07F1 0315 0062;0061 05AE 0300 07F1 0315 0062; +0061 07F1 0315 0300 05AE 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062; +0061 059A 0316 302A 07F2 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062; +0061 07F2 059A 0316 302A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062; +0061 0315 0300 05AE 07F3 0062;00E0 05AE 07F3 0315 0062;0061 05AE 0300 07F3 0315 0062;00E0 05AE 07F3 0315 0062;0061 05AE 0300 07F3 0315 0062; +0061 07F3 0315 0300 05AE 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062; +0061 059A 0316 302A 07FD 0062;0061 302A 0316 07FD 059A 0062;0061 302A 0316 07FD 059A 0062;0061 302A 0316 07FD 059A 0062;0061 302A 0316 07FD 059A 0062; +0061 07FD 059A 0316 302A 0062;0061 302A 07FD 0316 059A 0062;0061 302A 07FD 0316 059A 0062;0061 302A 07FD 0316 059A 0062;0061 302A 07FD 0316 059A 0062; +0061 0315 0300 05AE 0816 0062;00E0 05AE 0816 0315 0062;0061 05AE 0300 0816 0315 0062;00E0 05AE 0816 0315 0062;0061 05AE 0300 0816 0315 0062; +0061 0816 0315 0300 05AE 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062; +0061 0315 0300 05AE 0817 0062;00E0 05AE 0817 0315 0062;0061 05AE 0300 0817 0315 0062;00E0 05AE 0817 0315 0062;0061 05AE 0300 0817 0315 0062; +0061 0817 0315 0300 05AE 0062;0061 05AE 0817 0300 0315 0062;0061 05AE 0817 0300 0315 0062;0061 05AE 0817 0300 0315 0062;0061 05AE 0817 0300 0315 0062; +0061 0315 0300 05AE 0818 0062;00E0 05AE 0818 0315 0062;0061 05AE 0300 0818 0315 0062;00E0 05AE 0818 0315 0062;0061 05AE 0300 0818 0315 0062; +0061 0818 0315 0300 05AE 0062;0061 05AE 0818 0300 0315 0062;0061 05AE 0818 0300 0315 0062;0061 05AE 0818 0300 0315 0062;0061 05AE 0818 0300 0315 0062; +0061 0315 0300 05AE 0819 0062;00E0 05AE 0819 0315 0062;0061 05AE 0300 0819 0315 0062;00E0 05AE 0819 0315 0062;0061 05AE 0300 0819 0315 0062; +0061 0819 0315 0300 05AE 0062;0061 05AE 0819 0300 0315 0062;0061 05AE 0819 0300 0315 0062;0061 05AE 0819 0300 0315 0062;0061 05AE 0819 0300 0315 0062; +0061 0315 0300 05AE 081B 0062;00E0 05AE 081B 0315 0062;0061 05AE 0300 081B 0315 0062;00E0 05AE 081B 0315 0062;0061 05AE 0300 081B 0315 0062; +0061 081B 0315 0300 05AE 0062;0061 05AE 081B 0300 0315 0062;0061 05AE 081B 0300 0315 0062;0061 05AE 081B 0300 0315 0062;0061 05AE 081B 0300 0315 0062; +0061 0315 0300 05AE 081C 0062;00E0 05AE 081C 0315 0062;0061 05AE 0300 081C 0315 0062;00E0 05AE 081C 0315 0062;0061 05AE 0300 081C 0315 0062; +0061 081C 0315 0300 05AE 0062;0061 05AE 081C 0300 0315 0062;0061 05AE 081C 0300 0315 0062;0061 05AE 081C 0300 0315 0062;0061 05AE 081C 0300 0315 0062; +0061 0315 0300 05AE 081D 0062;00E0 05AE 081D 0315 0062;0061 05AE 0300 081D 0315 0062;00E0 05AE 081D 0315 0062;0061 05AE 0300 081D 0315 0062; +0061 081D 0315 0300 05AE 0062;0061 05AE 081D 0300 0315 0062;0061 05AE 081D 0300 0315 0062;0061 05AE 081D 0300 0315 0062;0061 05AE 081D 0300 0315 0062; +0061 0315 0300 05AE 081E 0062;00E0 05AE 081E 0315 0062;0061 05AE 0300 081E 0315 0062;00E0 05AE 081E 0315 0062;0061 05AE 0300 081E 0315 0062; +0061 081E 0315 0300 05AE 0062;0061 05AE 081E 0300 0315 0062;0061 05AE 081E 0300 0315 0062;0061 05AE 081E 0300 0315 0062;0061 05AE 081E 0300 0315 0062; +0061 0315 0300 05AE 081F 0062;00E0 05AE 081F 0315 0062;0061 05AE 0300 081F 0315 0062;00E0 05AE 081F 0315 0062;0061 05AE 0300 081F 0315 0062; +0061 081F 0315 0300 05AE 0062;0061 05AE 081F 0300 0315 0062;0061 05AE 081F 0300 0315 0062;0061 05AE 081F 0300 0315 0062;0061 05AE 081F 0300 0315 0062; +0061 0315 0300 05AE 0820 0062;00E0 05AE 0820 0315 0062;0061 05AE 0300 0820 0315 0062;00E0 05AE 0820 0315 0062;0061 05AE 0300 0820 0315 0062; +0061 0820 0315 0300 05AE 0062;0061 05AE 0820 0300 0315 0062;0061 05AE 0820 0300 0315 0062;0061 05AE 0820 0300 0315 0062;0061 05AE 0820 0300 0315 0062; +0061 0315 0300 05AE 0821 0062;00E0 05AE 0821 0315 0062;0061 05AE 0300 0821 0315 0062;00E0 05AE 0821 0315 0062;0061 05AE 0300 0821 0315 0062; +0061 0821 0315 0300 05AE 0062;0061 05AE 0821 0300 0315 0062;0061 05AE 0821 0300 0315 0062;0061 05AE 0821 0300 0315 0062;0061 05AE 0821 0300 0315 0062; +0061 0315 0300 05AE 0822 0062;00E0 05AE 0822 0315 0062;0061 05AE 0300 0822 0315 0062;00E0 05AE 0822 0315 0062;0061 05AE 0300 0822 0315 0062; +0061 0822 0315 0300 05AE 0062;0061 05AE 0822 0300 0315 0062;0061 05AE 0822 0300 0315 0062;0061 05AE 0822 0300 0315 0062;0061 05AE 0822 0300 0315 0062; +0061 0315 0300 05AE 0823 0062;00E0 05AE 0823 0315 0062;0061 05AE 0300 0823 0315 0062;00E0 05AE 0823 0315 0062;0061 05AE 0300 0823 0315 0062; +0061 0823 0315 0300 05AE 0062;0061 05AE 0823 0300 0315 0062;0061 05AE 0823 0300 0315 0062;0061 05AE 0823 0300 0315 0062;0061 05AE 0823 0300 0315 0062; +0061 0315 0300 05AE 0825 0062;00E0 05AE 0825 0315 0062;0061 05AE 0300 0825 0315 0062;00E0 05AE 0825 0315 0062;0061 05AE 0300 0825 0315 0062; +0061 0825 0315 0300 05AE 0062;0061 05AE 0825 0300 0315 0062;0061 05AE 0825 0300 0315 0062;0061 05AE 0825 0300 0315 0062;0061 05AE 0825 0300 0315 0062; +0061 0315 0300 05AE 0826 0062;00E0 05AE 0826 0315 0062;0061 05AE 0300 0826 0315 0062;00E0 05AE 0826 0315 0062;0061 05AE 0300 0826 0315 0062; +0061 0826 0315 0300 05AE 0062;0061 05AE 0826 0300 0315 0062;0061 05AE 0826 0300 0315 0062;0061 05AE 0826 0300 0315 0062;0061 05AE 0826 0300 0315 0062; +0061 0315 0300 05AE 0827 0062;00E0 05AE 0827 0315 0062;0061 05AE 0300 0827 0315 0062;00E0 05AE 0827 0315 0062;0061 05AE 0300 0827 0315 0062; +0061 0827 0315 0300 05AE 0062;0061 05AE 0827 0300 0315 0062;0061 05AE 0827 0300 0315 0062;0061 05AE 0827 0300 0315 0062;0061 05AE 0827 0300 0315 0062; +0061 0315 0300 05AE 0829 0062;00E0 05AE 0829 0315 0062;0061 05AE 0300 0829 0315 0062;00E0 05AE 0829 0315 0062;0061 05AE 0300 0829 0315 0062; +0061 0829 0315 0300 05AE 0062;0061 05AE 0829 0300 0315 0062;0061 05AE 0829 0300 0315 0062;0061 05AE 0829 0300 0315 0062;0061 05AE 0829 0300 0315 0062; +0061 0315 0300 05AE 082A 0062;00E0 05AE 082A 0315 0062;0061 05AE 0300 082A 0315 0062;00E0 05AE 082A 0315 0062;0061 05AE 0300 082A 0315 0062; +0061 082A 0315 0300 05AE 0062;0061 05AE 082A 0300 0315 0062;0061 05AE 082A 0300 0315 0062;0061 05AE 082A 0300 0315 0062;0061 05AE 082A 0300 0315 0062; +0061 0315 0300 05AE 082B 0062;00E0 05AE 082B 0315 0062;0061 05AE 0300 082B 0315 0062;00E0 05AE 082B 0315 0062;0061 05AE 0300 082B 0315 0062; +0061 082B 0315 0300 05AE 0062;0061 05AE 082B 0300 0315 0062;0061 05AE 082B 0300 0315 0062;0061 05AE 082B 0300 0315 0062;0061 05AE 082B 0300 0315 0062; +0061 0315 0300 05AE 082C 0062;00E0 05AE 082C 0315 0062;0061 05AE 0300 082C 0315 0062;00E0 05AE 082C 0315 0062;0061 05AE 0300 082C 0315 0062; +0061 082C 0315 0300 05AE 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062; +0061 0315 0300 05AE 082D 0062;00E0 05AE 082D 0315 0062;0061 05AE 0300 082D 0315 0062;00E0 05AE 082D 0315 0062;0061 05AE 0300 082D 0315 0062; +0061 082D 0315 0300 05AE 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062; +0061 059A 0316 302A 0859 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062; +0061 0859 059A 0316 302A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062; +0061 059A 0316 302A 085A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062; +0061 085A 059A 0316 302A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062; +0061 059A 0316 302A 085B 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062; +0061 085B 059A 0316 302A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062; +0061 059A 0316 302A 08D3 0062;0061 302A 0316 08D3 059A 0062;0061 302A 0316 08D3 059A 0062;0061 302A 0316 08D3 059A 0062;0061 302A 0316 08D3 059A 0062; +0061 08D3 059A 0316 302A 0062;0061 302A 08D3 0316 059A 0062;0061 302A 08D3 0316 059A 0062;0061 302A 08D3 0316 059A 0062;0061 302A 08D3 0316 059A 0062; +0061 0315 0300 05AE 08D4 0062;00E0 05AE 08D4 0315 0062;0061 05AE 0300 08D4 0315 0062;00E0 05AE 08D4 0315 0062;0061 05AE 0300 08D4 0315 0062; +0061 08D4 0315 0300 05AE 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062; +0061 0315 0300 05AE 08D5 0062;00E0 05AE 08D5 0315 0062;0061 05AE 0300 08D5 0315 0062;00E0 05AE 08D5 0315 0062;0061 05AE 0300 08D5 0315 0062; +0061 08D5 0315 0300 05AE 0062;0061 05AE 08D5 0300 0315 0062;0061 05AE 08D5 0300 0315 0062;0061 05AE 08D5 0300 0315 0062;0061 05AE 08D5 0300 0315 0062; +0061 0315 0300 05AE 08D6 0062;00E0 05AE 08D6 0315 0062;0061 05AE 0300 08D6 0315 0062;00E0 05AE 08D6 0315 0062;0061 05AE 0300 08D6 0315 0062; +0061 08D6 0315 0300 05AE 0062;0061 05AE 08D6 0300 0315 0062;0061 05AE 08D6 0300 0315 0062;0061 05AE 08D6 0300 0315 0062;0061 05AE 08D6 0300 0315 0062; +0061 0315 0300 05AE 08D7 0062;00E0 05AE 08D7 0315 0062;0061 05AE 0300 08D7 0315 0062;00E0 05AE 08D7 0315 0062;0061 05AE 0300 08D7 0315 0062; +0061 08D7 0315 0300 05AE 0062;0061 05AE 08D7 0300 0315 0062;0061 05AE 08D7 0300 0315 0062;0061 05AE 08D7 0300 0315 0062;0061 05AE 08D7 0300 0315 0062; +0061 0315 0300 05AE 08D8 0062;00E0 05AE 08D8 0315 0062;0061 05AE 0300 08D8 0315 0062;00E0 05AE 08D8 0315 0062;0061 05AE 0300 08D8 0315 0062; +0061 08D8 0315 0300 05AE 0062;0061 05AE 08D8 0300 0315 0062;0061 05AE 08D8 0300 0315 0062;0061 05AE 08D8 0300 0315 0062;0061 05AE 08D8 0300 0315 0062; +0061 0315 0300 05AE 08D9 0062;00E0 05AE 08D9 0315 0062;0061 05AE 0300 08D9 0315 0062;00E0 05AE 08D9 0315 0062;0061 05AE 0300 08D9 0315 0062; +0061 08D9 0315 0300 05AE 0062;0061 05AE 08D9 0300 0315 0062;0061 05AE 08D9 0300 0315 0062;0061 05AE 08D9 0300 0315 0062;0061 05AE 08D9 0300 0315 0062; +0061 0315 0300 05AE 08DA 0062;00E0 05AE 08DA 0315 0062;0061 05AE 0300 08DA 0315 0062;00E0 05AE 08DA 0315 0062;0061 05AE 0300 08DA 0315 0062; +0061 08DA 0315 0300 05AE 0062;0061 05AE 08DA 0300 0315 0062;0061 05AE 08DA 0300 0315 0062;0061 05AE 08DA 0300 0315 0062;0061 05AE 08DA 0300 0315 0062; +0061 0315 0300 05AE 08DB 0062;00E0 05AE 08DB 0315 0062;0061 05AE 0300 08DB 0315 0062;00E0 05AE 08DB 0315 0062;0061 05AE 0300 08DB 0315 0062; +0061 08DB 0315 0300 05AE 0062;0061 05AE 08DB 0300 0315 0062;0061 05AE 08DB 0300 0315 0062;0061 05AE 08DB 0300 0315 0062;0061 05AE 08DB 0300 0315 0062; +0061 0315 0300 05AE 08DC 0062;00E0 05AE 08DC 0315 0062;0061 05AE 0300 08DC 0315 0062;00E0 05AE 08DC 0315 0062;0061 05AE 0300 08DC 0315 0062; +0061 08DC 0315 0300 05AE 0062;0061 05AE 08DC 0300 0315 0062;0061 05AE 08DC 0300 0315 0062;0061 05AE 08DC 0300 0315 0062;0061 05AE 08DC 0300 0315 0062; +0061 0315 0300 05AE 08DD 0062;00E0 05AE 08DD 0315 0062;0061 05AE 0300 08DD 0315 0062;00E0 05AE 08DD 0315 0062;0061 05AE 0300 08DD 0315 0062; +0061 08DD 0315 0300 05AE 0062;0061 05AE 08DD 0300 0315 0062;0061 05AE 08DD 0300 0315 0062;0061 05AE 08DD 0300 0315 0062;0061 05AE 08DD 0300 0315 0062; +0061 0315 0300 05AE 08DE 0062;00E0 05AE 08DE 0315 0062;0061 05AE 0300 08DE 0315 0062;00E0 05AE 08DE 0315 0062;0061 05AE 0300 08DE 0315 0062; +0061 08DE 0315 0300 05AE 0062;0061 05AE 08DE 0300 0315 0062;0061 05AE 08DE 0300 0315 0062;0061 05AE 08DE 0300 0315 0062;0061 05AE 08DE 0300 0315 0062; +0061 0315 0300 05AE 08DF 0062;00E0 05AE 08DF 0315 0062;0061 05AE 0300 08DF 0315 0062;00E0 05AE 08DF 0315 0062;0061 05AE 0300 08DF 0315 0062; +0061 08DF 0315 0300 05AE 0062;0061 05AE 08DF 0300 0315 0062;0061 05AE 08DF 0300 0315 0062;0061 05AE 08DF 0300 0315 0062;0061 05AE 08DF 0300 0315 0062; +0061 0315 0300 05AE 08E0 0062;00E0 05AE 08E0 0315 0062;0061 05AE 0300 08E0 0315 0062;00E0 05AE 08E0 0315 0062;0061 05AE 0300 08E0 0315 0062; +0061 08E0 0315 0300 05AE 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062; +0061 0315 0300 05AE 08E1 0062;00E0 05AE 08E1 0315 0062;0061 05AE 0300 08E1 0315 0062;00E0 05AE 08E1 0315 0062;0061 05AE 0300 08E1 0315 0062; +0061 08E1 0315 0300 05AE 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062; +0061 059A 0316 302A 08E3 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062; +0061 08E3 059A 0316 302A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062; +0061 0315 0300 05AE 08E4 0062;00E0 05AE 08E4 0315 0062;0061 05AE 0300 08E4 0315 0062;00E0 05AE 08E4 0315 0062;0061 05AE 0300 08E4 0315 0062; +0061 08E4 0315 0300 05AE 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062; +0061 0315 0300 05AE 08E5 0062;00E0 05AE 08E5 0315 0062;0061 05AE 0300 08E5 0315 0062;00E0 05AE 08E5 0315 0062;0061 05AE 0300 08E5 0315 0062; +0061 08E5 0315 0300 05AE 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062; +0061 059A 0316 302A 08E6 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062; +0061 08E6 059A 0316 302A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062; +0061 0315 0300 05AE 08E7 0062;00E0 05AE 08E7 0315 0062;0061 05AE 0300 08E7 0315 0062;00E0 05AE 08E7 0315 0062;0061 05AE 0300 08E7 0315 0062; +0061 08E7 0315 0300 05AE 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062; +0061 0315 0300 05AE 08E8 0062;00E0 05AE 08E8 0315 0062;0061 05AE 0300 08E8 0315 0062;00E0 05AE 08E8 0315 0062;0061 05AE 0300 08E8 0315 0062; +0061 08E8 0315 0300 05AE 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062; +0061 059A 0316 302A 08E9 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062; +0061 08E9 059A 0316 302A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062; +0061 0315 0300 05AE 08EA 0062;00E0 05AE 08EA 0315 0062;0061 05AE 0300 08EA 0315 0062;00E0 05AE 08EA 0315 0062;0061 05AE 0300 08EA 0315 0062; +0061 08EA 0315 0300 05AE 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062; +0061 0315 0300 05AE 08EB 0062;00E0 05AE 08EB 0315 0062;0061 05AE 0300 08EB 0315 0062;00E0 05AE 08EB 0315 0062;0061 05AE 0300 08EB 0315 0062; +0061 08EB 0315 0300 05AE 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062; +0061 0315 0300 05AE 08EC 0062;00E0 05AE 08EC 0315 0062;0061 05AE 0300 08EC 0315 0062;00E0 05AE 08EC 0315 0062;0061 05AE 0300 08EC 0315 0062; +0061 08EC 0315 0300 05AE 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062; +0061 059A 0316 302A 08ED 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062; +0061 08ED 059A 0316 302A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062; +0061 059A 0316 302A 08EE 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062; +0061 08EE 059A 0316 302A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062; +0061 059A 0316 302A 08EF 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062; +0061 08EF 059A 0316 302A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062; +0061 064C 064B FB1E 08F0 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062; +0061 08F0 064C 064B FB1E 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062; +0061 064D 064C 064B 08F1 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062; +0061 08F1 064D 064C 064B 0062;0061 064B 08F1 064C 064D 0062;0061 064B 08F1 064C 064D 0062;0061 064B 08F1 064C 064D 0062;0061 064B 08F1 064C 064D 0062; +0061 0618 064D 064C 08F2 0062;0061 064C 064D 08F2 0618 0062;0061 064C 064D 08F2 0618 0062;0061 064C 064D 08F2 0618 0062;0061 064C 064D 08F2 0618 0062; +0061 08F2 0618 064D 064C 0062;0061 064C 08F2 064D 0618 0062;0061 064C 08F2 064D 0618 0062;0061 064C 08F2 064D 0618 0062;0061 064C 08F2 064D 0618 0062; +0061 0315 0300 05AE 08F3 0062;00E0 05AE 08F3 0315 0062;0061 05AE 0300 08F3 0315 0062;00E0 05AE 08F3 0315 0062;0061 05AE 0300 08F3 0315 0062; +0061 08F3 0315 0300 05AE 0062;0061 05AE 08F3 0300 0315 0062;0061 05AE 08F3 0300 0315 0062;0061 05AE 08F3 0300 0315 0062;0061 05AE 08F3 0300 0315 0062; +0061 0315 0300 05AE 08F4 0062;00E0 05AE 08F4 0315 0062;0061 05AE 0300 08F4 0315 0062;00E0 05AE 08F4 0315 0062;0061 05AE 0300 08F4 0315 0062; +0061 08F4 0315 0300 05AE 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062; +0061 0315 0300 05AE 08F5 0062;00E0 05AE 08F5 0315 0062;0061 05AE 0300 08F5 0315 0062;00E0 05AE 08F5 0315 0062;0061 05AE 0300 08F5 0315 0062; +0061 08F5 0315 0300 05AE 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062; +0061 059A 0316 302A 08F6 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062; +0061 08F6 059A 0316 302A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062; +0061 0315 0300 05AE 08F7 0062;00E0 05AE 08F7 0315 0062;0061 05AE 0300 08F7 0315 0062;00E0 05AE 08F7 0315 0062;0061 05AE 0300 08F7 0315 0062; +0061 08F7 0315 0300 05AE 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062; +0061 0315 0300 05AE 08F8 0062;00E0 05AE 08F8 0315 0062;0061 05AE 0300 08F8 0315 0062;00E0 05AE 08F8 0315 0062;0061 05AE 0300 08F8 0315 0062; +0061 08F8 0315 0300 05AE 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062; +0061 059A 0316 302A 08F9 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062; +0061 08F9 059A 0316 302A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062; +0061 059A 0316 302A 08FA 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062; +0061 08FA 059A 0316 302A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062; +0061 0315 0300 05AE 08FB 0062;00E0 05AE 08FB 0315 0062;0061 05AE 0300 08FB 0315 0062;00E0 05AE 08FB 0315 0062;0061 05AE 0300 08FB 0315 0062; +0061 08FB 0315 0300 05AE 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062; +0061 0315 0300 05AE 08FC 0062;00E0 05AE 08FC 0315 0062;0061 05AE 0300 08FC 0315 0062;00E0 05AE 08FC 0315 0062;0061 05AE 0300 08FC 0315 0062; +0061 08FC 0315 0300 05AE 0062;0061 05AE 08FC 0300 0315 0062;0061 05AE 08FC 0300 0315 0062;0061 05AE 08FC 0300 0315 0062;0061 05AE 08FC 0300 0315 0062; +0061 0315 0300 05AE 08FD 0062;00E0 05AE 08FD 0315 0062;0061 05AE 0300 08FD 0315 0062;00E0 05AE 08FD 0315 0062;0061 05AE 0300 08FD 0315 0062; +0061 08FD 0315 0300 05AE 0062;0061 05AE 08FD 0300 0315 0062;0061 05AE 08FD 0300 0315 0062;0061 05AE 08FD 0300 0315 0062;0061 05AE 08FD 0300 0315 0062; +0061 0315 0300 05AE 08FE 0062;00E0 05AE 08FE 0315 0062;0061 05AE 0300 08FE 0315 0062;00E0 05AE 08FE 0315 0062;0061 05AE 0300 08FE 0315 0062; +0061 08FE 0315 0300 05AE 0062;0061 05AE 08FE 0300 0315 0062;0061 05AE 08FE 0300 0315 0062;0061 05AE 08FE 0300 0315 0062;0061 05AE 08FE 0300 0315 0062; +0061 0315 0300 05AE 08FF 0062;00E0 05AE 08FF 0315 0062;0061 05AE 0300 08FF 0315 0062;00E0 05AE 08FF 0315 0062;0061 05AE 0300 08FF 0315 0062; +0061 08FF 0315 0300 05AE 0062;0061 05AE 08FF 0300 0315 0062;0061 05AE 08FF 0300 0315 0062;0061 05AE 08FF 0300 0315 0062;0061 05AE 08FF 0300 0315 0062; +0061 3099 093C 0334 093C 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062; +0061 093C 3099 093C 0334 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062; +0061 05B0 094D 3099 094D 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062; +0061 094D 05B0 094D 3099 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062; +0061 0315 0300 05AE 0951 0062;00E0 05AE 0951 0315 0062;0061 05AE 0300 0951 0315 0062;00E0 05AE 0951 0315 0062;0061 05AE 0300 0951 0315 0062; +0061 0951 0315 0300 05AE 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062; +0061 059A 0316 302A 0952 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062; +0061 0952 059A 0316 302A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062; +0061 0315 0300 05AE 0953 0062;00E0 05AE 0953 0315 0062;0061 05AE 0300 0953 0315 0062;00E0 05AE 0953 0315 0062;0061 05AE 0300 0953 0315 0062; +0061 0953 0315 0300 05AE 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062; +0061 0315 0300 05AE 0954 0062;00E0 05AE 0954 0315 0062;0061 05AE 0300 0954 0315 0062;00E0 05AE 0954 0315 0062;0061 05AE 0300 0954 0315 0062; +0061 0954 0315 0300 05AE 0062;0061 05AE 0954 0300 0315 0062;0061 05AE 0954 0300 0315 0062;0061 05AE 0954 0300 0315 0062;0061 05AE 0954 0300 0315 0062; +0061 3099 093C 0334 09BC 0062;0061 0334 093C 09BC 3099 0062;0061 0334 093C 09BC 3099 0062;0061 0334 093C 09BC 3099 0062;0061 0334 093C 09BC 3099 0062; +0061 09BC 3099 093C 0334 0062;0061 0334 09BC 093C 3099 0062;0061 0334 09BC 093C 3099 0062;0061 0334 09BC 093C 3099 0062;0061 0334 09BC 093C 3099 0062; +0061 05B0 094D 3099 09CD 0062;0061 3099 094D 09CD 05B0 0062;0061 3099 094D 09CD 05B0 0062;0061 3099 094D 09CD 05B0 0062;0061 3099 094D 09CD 05B0 0062; +0061 09CD 05B0 094D 3099 0062;0061 3099 09CD 094D 05B0 0062;0061 3099 09CD 094D 05B0 0062;0061 3099 09CD 094D 05B0 0062;0061 3099 09CD 094D 05B0 0062; +0061 0315 0300 05AE 09FE 0062;00E0 05AE 09FE 0315 0062;0061 05AE 0300 09FE 0315 0062;00E0 05AE 09FE 0315 0062;0061 05AE 0300 09FE 0315 0062; +0061 09FE 0315 0300 05AE 0062;0061 05AE 09FE 0300 0315 0062;0061 05AE 09FE 0300 0315 0062;0061 05AE 09FE 0300 0315 0062;0061 05AE 09FE 0300 0315 0062; +0061 3099 093C 0334 0A3C 0062;0061 0334 093C 0A3C 3099 0062;0061 0334 093C 0A3C 3099 0062;0061 0334 093C 0A3C 3099 0062;0061 0334 093C 0A3C 3099 0062; +0061 0A3C 3099 093C 0334 0062;0061 0334 0A3C 093C 3099 0062;0061 0334 0A3C 093C 3099 0062;0061 0334 0A3C 093C 3099 0062;0061 0334 0A3C 093C 3099 0062; +0061 05B0 094D 3099 0A4D 0062;0061 3099 094D 0A4D 05B0 0062;0061 3099 094D 0A4D 05B0 0062;0061 3099 094D 0A4D 05B0 0062;0061 3099 094D 0A4D 05B0 0062; +0061 0A4D 05B0 094D 3099 0062;0061 3099 0A4D 094D 05B0 0062;0061 3099 0A4D 094D 05B0 0062;0061 3099 0A4D 094D 05B0 0062;0061 3099 0A4D 094D 05B0 0062; +0061 3099 093C 0334 0ABC 0062;0061 0334 093C 0ABC 3099 0062;0061 0334 093C 0ABC 3099 0062;0061 0334 093C 0ABC 3099 0062;0061 0334 093C 0ABC 3099 0062; +0061 0ABC 3099 093C 0334 0062;0061 0334 0ABC 093C 3099 0062;0061 0334 0ABC 093C 3099 0062;0061 0334 0ABC 093C 3099 0062;0061 0334 0ABC 093C 3099 0062; +0061 05B0 094D 3099 0ACD 0062;0061 3099 094D 0ACD 05B0 0062;0061 3099 094D 0ACD 05B0 0062;0061 3099 094D 0ACD 05B0 0062;0061 3099 094D 0ACD 05B0 0062; +0061 0ACD 05B0 094D 3099 0062;0061 3099 0ACD 094D 05B0 0062;0061 3099 0ACD 094D 05B0 0062;0061 3099 0ACD 094D 05B0 0062;0061 3099 0ACD 094D 05B0 0062; +0061 3099 093C 0334 0B3C 0062;0061 0334 093C 0B3C 3099 0062;0061 0334 093C 0B3C 3099 0062;0061 0334 093C 0B3C 3099 0062;0061 0334 093C 0B3C 3099 0062; +0061 0B3C 3099 093C 0334 0062;0061 0334 0B3C 093C 3099 0062;0061 0334 0B3C 093C 3099 0062;0061 0334 0B3C 093C 3099 0062;0061 0334 0B3C 093C 3099 0062; +0061 05B0 094D 3099 0B4D 0062;0061 3099 094D 0B4D 05B0 0062;0061 3099 094D 0B4D 05B0 0062;0061 3099 094D 0B4D 05B0 0062;0061 3099 094D 0B4D 05B0 0062; +0061 0B4D 05B0 094D 3099 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062; +0061 05B0 094D 3099 0BCD 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062; +0061 0BCD 05B0 094D 3099 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062; +0061 05B0 094D 3099 0C4D 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062; +0061 0C4D 05B0 094D 3099 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062; +0061 0C56 0C55 0711 0C55 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062; +0061 0C55 0C56 0C55 0711 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062; +0061 0E38 0C56 0C55 0C56 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062; +0061 0C56 0E38 0C56 0C55 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062; +0061 3099 093C 0334 0CBC 0062;0061 0334 093C 0CBC 3099 0062;0061 0334 093C 0CBC 3099 0062;0061 0334 093C 0CBC 3099 0062;0061 0334 093C 0CBC 3099 0062; +0061 0CBC 3099 093C 0334 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062; +0061 05B0 094D 3099 0CCD 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062; +0061 0CCD 05B0 094D 3099 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062; +0061 05B0 094D 3099 0D3B 0062;0061 3099 094D 0D3B 05B0 0062;0061 3099 094D 0D3B 05B0 0062;0061 3099 094D 0D3B 05B0 0062;0061 3099 094D 0D3B 05B0 0062; +0061 0D3B 05B0 094D 3099 0062;0061 3099 0D3B 094D 05B0 0062;0061 3099 0D3B 094D 05B0 0062;0061 3099 0D3B 094D 05B0 0062;0061 3099 0D3B 094D 05B0 0062; +0061 05B0 094D 3099 0D3C 0062;0061 3099 094D 0D3C 05B0 0062;0061 3099 094D 0D3C 05B0 0062;0061 3099 094D 0D3C 05B0 0062;0061 3099 094D 0D3C 05B0 0062; +0061 0D3C 05B0 094D 3099 0062;0061 3099 0D3C 094D 05B0 0062;0061 3099 0D3C 094D 05B0 0062;0061 3099 0D3C 094D 05B0 0062;0061 3099 0D3C 094D 05B0 0062; +0061 05B0 094D 3099 0D4D 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062; +0061 0D4D 05B0 094D 3099 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062; +0061 05B0 094D 3099 0DCA 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062; +0061 0DCA 05B0 094D 3099 0062;0061 3099 0DCA 094D 05B0 0062;0061 3099 0DCA 094D 05B0 0062;0061 3099 0DCA 094D 05B0 0062;0061 3099 0DCA 094D 05B0 0062; +0061 0E48 0E38 0C56 0E38 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062; +0061 0E38 0E48 0E38 0C56 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062; +0061 0E48 0E38 0C56 0E39 0062;0061 0C56 0E38 0E39 0E48 0062;0061 0C56 0E38 0E39 0E48 0062;0061 0C56 0E38 0E39 0E48 0062;0061 0C56 0E38 0E39 0E48 0062; +0061 0E39 0E48 0E38 0C56 0062;0061 0C56 0E39 0E38 0E48 0062;0061 0C56 0E39 0E38 0E48 0062;0061 0C56 0E39 0E38 0E48 0062;0061 0C56 0E39 0E38 0E48 0062; +0061 05B0 094D 3099 0E3A 0062;0061 3099 094D 0E3A 05B0 0062;0061 3099 094D 0E3A 05B0 0062;0061 3099 094D 0E3A 05B0 0062;0061 3099 094D 0E3A 05B0 0062; +0061 0E3A 05B0 094D 3099 0062;0061 3099 0E3A 094D 05B0 0062;0061 3099 0E3A 094D 05B0 0062;0061 3099 0E3A 094D 05B0 0062;0061 3099 0E3A 094D 05B0 0062; +0061 0EB8 0E48 0E38 0E48 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062; +0061 0E48 0EB8 0E48 0E38 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062; +0061 0EB8 0E48 0E38 0E49 0062;0061 0E38 0E48 0E49 0EB8 0062;0061 0E38 0E48 0E49 0EB8 0062;0061 0E38 0E48 0E49 0EB8 0062;0061 0E38 0E48 0E49 0EB8 0062; +0061 0E49 0EB8 0E48 0E38 0062;0061 0E38 0E49 0E48 0EB8 0062;0061 0E38 0E49 0E48 0EB8 0062;0061 0E38 0E49 0E48 0EB8 0062;0061 0E38 0E49 0E48 0EB8 0062; +0061 0EB8 0E48 0E38 0E4A 0062;0061 0E38 0E48 0E4A 0EB8 0062;0061 0E38 0E48 0E4A 0EB8 0062;0061 0E38 0E48 0E4A 0EB8 0062;0061 0E38 0E48 0E4A 0EB8 0062; +0061 0E4A 0EB8 0E48 0E38 0062;0061 0E38 0E4A 0E48 0EB8 0062;0061 0E38 0E4A 0E48 0EB8 0062;0061 0E38 0E4A 0E48 0EB8 0062;0061 0E38 0E4A 0E48 0EB8 0062; +0061 0EB8 0E48 0E38 0E4B 0062;0061 0E38 0E48 0E4B 0EB8 0062;0061 0E38 0E48 0E4B 0EB8 0062;0061 0E38 0E48 0E4B 0EB8 0062;0061 0E38 0E48 0E4B 0EB8 0062; +0061 0E4B 0EB8 0E48 0E38 0062;0061 0E38 0E4B 0E48 0EB8 0062;0061 0E38 0E4B 0E48 0EB8 0062;0061 0E38 0E4B 0E48 0EB8 0062;0061 0E38 0E4B 0E48 0EB8 0062; +0061 0EC8 0EB8 0E48 0EB8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062; +0061 0EB8 0EC8 0EB8 0E48 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062; +0061 0EC8 0EB8 0E48 0EB9 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062; +0061 0EB9 0EC8 0EB8 0E48 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062; +0061 0F71 0EC8 0EB8 0EC8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062; +0061 0EC8 0F71 0EC8 0EB8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062; +0061 0F71 0EC8 0EB8 0EC9 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062; +0061 0EC9 0F71 0EC8 0EB8 0062;0061 0EB8 0EC9 0EC8 0F71 0062;0061 0EB8 0EC9 0EC8 0F71 0062;0061 0EB8 0EC9 0EC8 0F71 0062;0061 0EB8 0EC9 0EC8 0F71 0062; +0061 0F71 0EC8 0EB8 0ECA 0062;0061 0EB8 0EC8 0ECA 0F71 0062;0061 0EB8 0EC8 0ECA 0F71 0062;0061 0EB8 0EC8 0ECA 0F71 0062;0061 0EB8 0EC8 0ECA 0F71 0062; +0061 0ECA 0F71 0EC8 0EB8 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062; +0061 0F71 0EC8 0EB8 0ECB 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062; +0061 0ECB 0F71 0EC8 0EB8 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062; +0061 059A 0316 302A 0F18 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062; +0061 0F18 059A 0316 302A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062; +0061 059A 0316 302A 0F19 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062; +0061 0F19 059A 0316 302A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062; +0061 059A 0316 302A 0F35 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062; +0061 0F35 059A 0316 302A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062; +0061 059A 0316 302A 0F37 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062; +0061 0F37 059A 0316 302A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062; +0061 302A 031B 1DCE 0F39 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062; +0061 0F39 302A 031B 1DCE 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062; +0061 0F72 0F71 0EC8 0F71 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062; +0061 0F71 0F72 0F71 0EC8 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062; +0061 0F74 0F72 0F71 0F72 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062; +0061 0F72 0F74 0F72 0F71 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062; +0061 0321 0F74 0F72 0F74 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062; +0061 0F74 0321 0F74 0F72 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062; +0061 0F74 0F72 0F71 0F7A 0062;0061 0F71 0F72 0F7A 0F74 0062;0061 0F71 0F72 0F7A 0F74 0062;0061 0F71 0F72 0F7A 0F74 0062;0061 0F71 0F72 0F7A 0F74 0062; +0061 0F7A 0F74 0F72 0F71 0062;0061 0F71 0F7A 0F72 0F74 0062;0061 0F71 0F7A 0F72 0F74 0062;0061 0F71 0F7A 0F72 0F74 0062;0061 0F71 0F7A 0F72 0F74 0062; +0061 0F74 0F72 0F71 0F7B 0062;0061 0F71 0F72 0F7B 0F74 0062;0061 0F71 0F72 0F7B 0F74 0062;0061 0F71 0F72 0F7B 0F74 0062;0061 0F71 0F72 0F7B 0F74 0062; +0061 0F7B 0F74 0F72 0F71 0062;0061 0F71 0F7B 0F72 0F74 0062;0061 0F71 0F7B 0F72 0F74 0062;0061 0F71 0F7B 0F72 0F74 0062;0061 0F71 0F7B 0F72 0F74 0062; +0061 0F74 0F72 0F71 0F7C 0062;0061 0F71 0F72 0F7C 0F74 0062;0061 0F71 0F72 0F7C 0F74 0062;0061 0F71 0F72 0F7C 0F74 0062;0061 0F71 0F72 0F7C 0F74 0062; +0061 0F7C 0F74 0F72 0F71 0062;0061 0F71 0F7C 0F72 0F74 0062;0061 0F71 0F7C 0F72 0F74 0062;0061 0F71 0F7C 0F72 0F74 0062;0061 0F71 0F7C 0F72 0F74 0062; +0061 0F74 0F72 0F71 0F7D 0062;0061 0F71 0F72 0F7D 0F74 0062;0061 0F71 0F72 0F7D 0F74 0062;0061 0F71 0F72 0F7D 0F74 0062;0061 0F71 0F72 0F7D 0F74 0062; +0061 0F7D 0F74 0F72 0F71 0062;0061 0F71 0F7D 0F72 0F74 0062;0061 0F71 0F7D 0F72 0F74 0062;0061 0F71 0F7D 0F72 0F74 0062;0061 0F71 0F7D 0F72 0F74 0062; +0061 0F74 0F72 0F71 0F80 0062;0061 0F71 0F72 0F80 0F74 0062;0061 0F71 0F72 0F80 0F74 0062;0061 0F71 0F72 0F80 0F74 0062;0061 0F71 0F72 0F80 0F74 0062; +0061 0F80 0F74 0F72 0F71 0062;0061 0F71 0F80 0F72 0F74 0062;0061 0F71 0F80 0F72 0F74 0062;0061 0F71 0F80 0F72 0F74 0062;0061 0F71 0F80 0F72 0F74 0062; +0061 0315 0300 05AE 0F82 0062;00E0 05AE 0F82 0315 0062;0061 05AE 0300 0F82 0315 0062;00E0 05AE 0F82 0315 0062;0061 05AE 0300 0F82 0315 0062; +0061 0F82 0315 0300 05AE 0062;0061 05AE 0F82 0300 0315 0062;0061 05AE 0F82 0300 0315 0062;0061 05AE 0F82 0300 0315 0062;0061 05AE 0F82 0300 0315 0062; +0061 0315 0300 05AE 0F83 0062;00E0 05AE 0F83 0315 0062;0061 05AE 0300 0F83 0315 0062;00E0 05AE 0F83 0315 0062;0061 05AE 0300 0F83 0315 0062; +0061 0F83 0315 0300 05AE 0062;0061 05AE 0F83 0300 0315 0062;0061 05AE 0F83 0300 0315 0062;0061 05AE 0F83 0300 0315 0062;0061 05AE 0F83 0300 0315 0062; +0061 05B0 094D 3099 0F84 0062;0061 3099 094D 0F84 05B0 0062;0061 3099 094D 0F84 05B0 0062;0061 3099 094D 0F84 05B0 0062;0061 3099 094D 0F84 05B0 0062; +0061 0F84 05B0 094D 3099 0062;0061 3099 0F84 094D 05B0 0062;0061 3099 0F84 094D 05B0 0062;0061 3099 0F84 094D 05B0 0062;0061 3099 0F84 094D 05B0 0062; +0061 0315 0300 05AE 0F86 0062;00E0 05AE 0F86 0315 0062;0061 05AE 0300 0F86 0315 0062;00E0 05AE 0F86 0315 0062;0061 05AE 0300 0F86 0315 0062; +0061 0F86 0315 0300 05AE 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062; +0061 0315 0300 05AE 0F87 0062;00E0 05AE 0F87 0315 0062;0061 05AE 0300 0F87 0315 0062;00E0 05AE 0F87 0315 0062;0061 05AE 0300 0F87 0315 0062; +0061 0F87 0315 0300 05AE 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062; +0061 059A 0316 302A 0FC6 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062; +0061 0FC6 059A 0316 302A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062; +0061 3099 093C 0334 1037 0062;0061 0334 093C 1037 3099 0062;0061 0334 093C 1037 3099 0062;0061 0334 093C 1037 3099 0062;0061 0334 093C 1037 3099 0062; +0061 1037 3099 093C 0334 0062;0061 0334 1037 093C 3099 0062;0061 0334 1037 093C 3099 0062;0061 0334 1037 093C 3099 0062;0061 0334 1037 093C 3099 0062; +0061 05B0 094D 3099 1039 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062; +0061 1039 05B0 094D 3099 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062; +0061 05B0 094D 3099 103A 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062; +0061 103A 05B0 094D 3099 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062; +0061 059A 0316 302A 108D 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062; +0061 108D 059A 0316 302A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062; +0061 0315 0300 05AE 135D 0062;00E0 05AE 135D 0315 0062;0061 05AE 0300 135D 0315 0062;00E0 05AE 135D 0315 0062;0061 05AE 0300 135D 0315 0062; +0061 135D 0315 0300 05AE 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062; +0061 0315 0300 05AE 135E 0062;00E0 05AE 135E 0315 0062;0061 05AE 0300 135E 0315 0062;00E0 05AE 135E 0315 0062;0061 05AE 0300 135E 0315 0062; +0061 135E 0315 0300 05AE 0062;0061 05AE 135E 0300 0315 0062;0061 05AE 135E 0300 0315 0062;0061 05AE 135E 0300 0315 0062;0061 05AE 135E 0300 0315 0062; +0061 0315 0300 05AE 135F 0062;00E0 05AE 135F 0315 0062;0061 05AE 0300 135F 0315 0062;00E0 05AE 135F 0315 0062;0061 05AE 0300 135F 0315 0062; +0061 135F 0315 0300 05AE 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062; +0061 05B0 094D 3099 1714 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062; +0061 1714 05B0 094D 3099 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062; +0061 05B0 094D 3099 1734 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062; +0061 1734 05B0 094D 3099 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062; +0061 05B0 094D 3099 17D2 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062; +0061 17D2 05B0 094D 3099 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062; +0061 0315 0300 05AE 17DD 0062;00E0 05AE 17DD 0315 0062;0061 05AE 0300 17DD 0315 0062;00E0 05AE 17DD 0315 0062;0061 05AE 0300 17DD 0315 0062; +0061 17DD 0315 0300 05AE 0062;0061 05AE 17DD 0300 0315 0062;0061 05AE 17DD 0300 0315 0062;0061 05AE 17DD 0300 0315 0062;0061 05AE 17DD 0300 0315 0062; +0061 0300 05AE 1D16D 18A9 0062;00E0 1D16D 05AE 18A9 0062;0061 1D16D 05AE 18A9 0300 0062;00E0 1D16D 05AE 18A9 0062;0061 1D16D 05AE 18A9 0300 0062; +0061 18A9 0300 05AE 1D16D 0062;00E0 1D16D 18A9 05AE 0062;0061 1D16D 18A9 05AE 0300 0062;00E0 1D16D 18A9 05AE 0062;0061 1D16D 18A9 05AE 0300 0062; +0061 302E 059A 0316 1939 0062;0061 0316 059A 1939 302E 0062;0061 0316 059A 1939 302E 0062;0061 0316 059A 1939 302E 0062;0061 0316 059A 1939 302E 0062; +0061 1939 302E 059A 0316 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062; +0061 0315 0300 05AE 193A 0062;00E0 05AE 193A 0315 0062;0061 05AE 0300 193A 0315 0062;00E0 05AE 193A 0315 0062;0061 05AE 0300 193A 0315 0062; +0061 193A 0315 0300 05AE 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062; +0061 059A 0316 302A 193B 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062; +0061 193B 059A 0316 302A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062; +0061 0315 0300 05AE 1A17 0062;00E0 05AE 1A17 0315 0062;0061 05AE 0300 1A17 0315 0062;00E0 05AE 1A17 0315 0062;0061 05AE 0300 1A17 0315 0062; +0061 1A17 0315 0300 05AE 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062; +0061 059A 0316 302A 1A18 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062; +0061 1A18 059A 0316 302A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062; +0061 05B0 094D 3099 1A60 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062; +0061 1A60 05B0 094D 3099 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062; +0061 0315 0300 05AE 1A75 0062;00E0 05AE 1A75 0315 0062;0061 05AE 0300 1A75 0315 0062;00E0 05AE 1A75 0315 0062;0061 05AE 0300 1A75 0315 0062; +0061 1A75 0315 0300 05AE 0062;0061 05AE 1A75 0300 0315 0062;0061 05AE 1A75 0300 0315 0062;0061 05AE 1A75 0300 0315 0062;0061 05AE 1A75 0300 0315 0062; +0061 0315 0300 05AE 1A76 0062;00E0 05AE 1A76 0315 0062;0061 05AE 0300 1A76 0315 0062;00E0 05AE 1A76 0315 0062;0061 05AE 0300 1A76 0315 0062; +0061 1A76 0315 0300 05AE 0062;0061 05AE 1A76 0300 0315 0062;0061 05AE 1A76 0300 0315 0062;0061 05AE 1A76 0300 0315 0062;0061 05AE 1A76 0300 0315 0062; +0061 0315 0300 05AE 1A77 0062;00E0 05AE 1A77 0315 0062;0061 05AE 0300 1A77 0315 0062;00E0 05AE 1A77 0315 0062;0061 05AE 0300 1A77 0315 0062; +0061 1A77 0315 0300 05AE 0062;0061 05AE 1A77 0300 0315 0062;0061 05AE 1A77 0300 0315 0062;0061 05AE 1A77 0300 0315 0062;0061 05AE 1A77 0300 0315 0062; +0061 0315 0300 05AE 1A78 0062;00E0 05AE 1A78 0315 0062;0061 05AE 0300 1A78 0315 0062;00E0 05AE 1A78 0315 0062;0061 05AE 0300 1A78 0315 0062; +0061 1A78 0315 0300 05AE 0062;0061 05AE 1A78 0300 0315 0062;0061 05AE 1A78 0300 0315 0062;0061 05AE 1A78 0300 0315 0062;0061 05AE 1A78 0300 0315 0062; +0061 0315 0300 05AE 1A79 0062;00E0 05AE 1A79 0315 0062;0061 05AE 0300 1A79 0315 0062;00E0 05AE 1A79 0315 0062;0061 05AE 0300 1A79 0315 0062; +0061 1A79 0315 0300 05AE 0062;0061 05AE 1A79 0300 0315 0062;0061 05AE 1A79 0300 0315 0062;0061 05AE 1A79 0300 0315 0062;0061 05AE 1A79 0300 0315 0062; +0061 0315 0300 05AE 1A7A 0062;00E0 05AE 1A7A 0315 0062;0061 05AE 0300 1A7A 0315 0062;00E0 05AE 1A7A 0315 0062;0061 05AE 0300 1A7A 0315 0062; +0061 1A7A 0315 0300 05AE 0062;0061 05AE 1A7A 0300 0315 0062;0061 05AE 1A7A 0300 0315 0062;0061 05AE 1A7A 0300 0315 0062;0061 05AE 1A7A 0300 0315 0062; +0061 0315 0300 05AE 1A7B 0062;00E0 05AE 1A7B 0315 0062;0061 05AE 0300 1A7B 0315 0062;00E0 05AE 1A7B 0315 0062;0061 05AE 0300 1A7B 0315 0062; +0061 1A7B 0315 0300 05AE 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062; +0061 0315 0300 05AE 1A7C 0062;00E0 05AE 1A7C 0315 0062;0061 05AE 0300 1A7C 0315 0062;00E0 05AE 1A7C 0315 0062;0061 05AE 0300 1A7C 0315 0062; +0061 1A7C 0315 0300 05AE 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062; +0061 059A 0316 302A 1A7F 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062; +0061 1A7F 059A 0316 302A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062; +0061 0315 0300 05AE 1AB0 0062;00E0 05AE 1AB0 0315 0062;0061 05AE 0300 1AB0 0315 0062;00E0 05AE 1AB0 0315 0062;0061 05AE 0300 1AB0 0315 0062; +0061 1AB0 0315 0300 05AE 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062; +0061 0315 0300 05AE 1AB1 0062;00E0 05AE 1AB1 0315 0062;0061 05AE 0300 1AB1 0315 0062;00E0 05AE 1AB1 0315 0062;0061 05AE 0300 1AB1 0315 0062; +0061 1AB1 0315 0300 05AE 0062;0061 05AE 1AB1 0300 0315 0062;0061 05AE 1AB1 0300 0315 0062;0061 05AE 1AB1 0300 0315 0062;0061 05AE 1AB1 0300 0315 0062; +0061 0315 0300 05AE 1AB2 0062;00E0 05AE 1AB2 0315 0062;0061 05AE 0300 1AB2 0315 0062;00E0 05AE 1AB2 0315 0062;0061 05AE 0300 1AB2 0315 0062; +0061 1AB2 0315 0300 05AE 0062;0061 05AE 1AB2 0300 0315 0062;0061 05AE 1AB2 0300 0315 0062;0061 05AE 1AB2 0300 0315 0062;0061 05AE 1AB2 0300 0315 0062; +0061 0315 0300 05AE 1AB3 0062;00E0 05AE 1AB3 0315 0062;0061 05AE 0300 1AB3 0315 0062;00E0 05AE 1AB3 0315 0062;0061 05AE 0300 1AB3 0315 0062; +0061 1AB3 0315 0300 05AE 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062; +0061 0315 0300 05AE 1AB4 0062;00E0 05AE 1AB4 0315 0062;0061 05AE 0300 1AB4 0315 0062;00E0 05AE 1AB4 0315 0062;0061 05AE 0300 1AB4 0315 0062; +0061 1AB4 0315 0300 05AE 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062; +0061 059A 0316 302A 1AB5 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062; +0061 1AB5 059A 0316 302A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062; +0061 059A 0316 302A 1AB6 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062; +0061 1AB6 059A 0316 302A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062; +0061 059A 0316 302A 1AB7 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062; +0061 1AB7 059A 0316 302A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062; +0061 059A 0316 302A 1AB8 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062; +0061 1AB8 059A 0316 302A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062; +0061 059A 0316 302A 1AB9 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062; +0061 1AB9 059A 0316 302A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062; +0061 059A 0316 302A 1ABA 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062; +0061 1ABA 059A 0316 302A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062; +0061 0315 0300 05AE 1ABB 0062;00E0 05AE 1ABB 0315 0062;0061 05AE 0300 1ABB 0315 0062;00E0 05AE 1ABB 0315 0062;0061 05AE 0300 1ABB 0315 0062; +0061 1ABB 0315 0300 05AE 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062; +0061 0315 0300 05AE 1ABC 0062;00E0 05AE 1ABC 0315 0062;0061 05AE 0300 1ABC 0315 0062;00E0 05AE 1ABC 0315 0062;0061 05AE 0300 1ABC 0315 0062; +0061 1ABC 0315 0300 05AE 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062; +0061 059A 0316 302A 1ABD 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062; +0061 1ABD 059A 0316 302A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062; +0061 3099 093C 0334 1B34 0062;0061 0334 093C 1B34 3099 0062;0061 0334 093C 1B34 3099 0062;0061 0334 093C 1B34 3099 0062;0061 0334 093C 1B34 3099 0062; +0061 1B34 3099 093C 0334 0062;0061 0334 1B34 093C 3099 0062;0061 0334 1B34 093C 3099 0062;0061 0334 1B34 093C 3099 0062;0061 0334 1B34 093C 3099 0062; +0061 05B0 094D 3099 1B44 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062; +0061 1B44 05B0 094D 3099 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062; +0061 0315 0300 05AE 1B6B 0062;00E0 05AE 1B6B 0315 0062;0061 05AE 0300 1B6B 0315 0062;00E0 05AE 1B6B 0315 0062;0061 05AE 0300 1B6B 0315 0062; +0061 1B6B 0315 0300 05AE 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062; +0061 059A 0316 302A 1B6C 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062; +0061 1B6C 059A 0316 302A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062; +0061 0315 0300 05AE 1B6D 0062;00E0 05AE 1B6D 0315 0062;0061 05AE 0300 1B6D 0315 0062;00E0 05AE 1B6D 0315 0062;0061 05AE 0300 1B6D 0315 0062; +0061 1B6D 0315 0300 05AE 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062; +0061 0315 0300 05AE 1B6E 0062;00E0 05AE 1B6E 0315 0062;0061 05AE 0300 1B6E 0315 0062;00E0 05AE 1B6E 0315 0062;0061 05AE 0300 1B6E 0315 0062; +0061 1B6E 0315 0300 05AE 0062;0061 05AE 1B6E 0300 0315 0062;0061 05AE 1B6E 0300 0315 0062;0061 05AE 1B6E 0300 0315 0062;0061 05AE 1B6E 0300 0315 0062; +0061 0315 0300 05AE 1B6F 0062;00E0 05AE 1B6F 0315 0062;0061 05AE 0300 1B6F 0315 0062;00E0 05AE 1B6F 0315 0062;0061 05AE 0300 1B6F 0315 0062; +0061 1B6F 0315 0300 05AE 0062;0061 05AE 1B6F 0300 0315 0062;0061 05AE 1B6F 0300 0315 0062;0061 05AE 1B6F 0300 0315 0062;0061 05AE 1B6F 0300 0315 0062; +0061 0315 0300 05AE 1B70 0062;00E0 05AE 1B70 0315 0062;0061 05AE 0300 1B70 0315 0062;00E0 05AE 1B70 0315 0062;0061 05AE 0300 1B70 0315 0062; +0061 1B70 0315 0300 05AE 0062;0061 05AE 1B70 0300 0315 0062;0061 05AE 1B70 0300 0315 0062;0061 05AE 1B70 0300 0315 0062;0061 05AE 1B70 0300 0315 0062; +0061 0315 0300 05AE 1B71 0062;00E0 05AE 1B71 0315 0062;0061 05AE 0300 1B71 0315 0062;00E0 05AE 1B71 0315 0062;0061 05AE 0300 1B71 0315 0062; +0061 1B71 0315 0300 05AE 0062;0061 05AE 1B71 0300 0315 0062;0061 05AE 1B71 0300 0315 0062;0061 05AE 1B71 0300 0315 0062;0061 05AE 1B71 0300 0315 0062; +0061 0315 0300 05AE 1B72 0062;00E0 05AE 1B72 0315 0062;0061 05AE 0300 1B72 0315 0062;00E0 05AE 1B72 0315 0062;0061 05AE 0300 1B72 0315 0062; +0061 1B72 0315 0300 05AE 0062;0061 05AE 1B72 0300 0315 0062;0061 05AE 1B72 0300 0315 0062;0061 05AE 1B72 0300 0315 0062;0061 05AE 1B72 0300 0315 0062; +0061 0315 0300 05AE 1B73 0062;00E0 05AE 1B73 0315 0062;0061 05AE 0300 1B73 0315 0062;00E0 05AE 1B73 0315 0062;0061 05AE 0300 1B73 0315 0062; +0061 1B73 0315 0300 05AE 0062;0061 05AE 1B73 0300 0315 0062;0061 05AE 1B73 0300 0315 0062;0061 05AE 1B73 0300 0315 0062;0061 05AE 1B73 0300 0315 0062; +0061 05B0 094D 3099 1BAA 0062;0061 3099 094D 1BAA 05B0 0062;0061 3099 094D 1BAA 05B0 0062;0061 3099 094D 1BAA 05B0 0062;0061 3099 094D 1BAA 05B0 0062; +0061 1BAA 05B0 094D 3099 0062;0061 3099 1BAA 094D 05B0 0062;0061 3099 1BAA 094D 05B0 0062;0061 3099 1BAA 094D 05B0 0062;0061 3099 1BAA 094D 05B0 0062; +0061 05B0 094D 3099 1BAB 0062;0061 3099 094D 1BAB 05B0 0062;0061 3099 094D 1BAB 05B0 0062;0061 3099 094D 1BAB 05B0 0062;0061 3099 094D 1BAB 05B0 0062; +0061 1BAB 05B0 094D 3099 0062;0061 3099 1BAB 094D 05B0 0062;0061 3099 1BAB 094D 05B0 0062;0061 3099 1BAB 094D 05B0 0062;0061 3099 1BAB 094D 05B0 0062; +0061 3099 093C 0334 1BE6 0062;0061 0334 093C 1BE6 3099 0062;0061 0334 093C 1BE6 3099 0062;0061 0334 093C 1BE6 3099 0062;0061 0334 093C 1BE6 3099 0062; +0061 1BE6 3099 093C 0334 0062;0061 0334 1BE6 093C 3099 0062;0061 0334 1BE6 093C 3099 0062;0061 0334 1BE6 093C 3099 0062;0061 0334 1BE6 093C 3099 0062; +0061 05B0 094D 3099 1BF2 0062;0061 3099 094D 1BF2 05B0 0062;0061 3099 094D 1BF2 05B0 0062;0061 3099 094D 1BF2 05B0 0062;0061 3099 094D 1BF2 05B0 0062; +0061 1BF2 05B0 094D 3099 0062;0061 3099 1BF2 094D 05B0 0062;0061 3099 1BF2 094D 05B0 0062;0061 3099 1BF2 094D 05B0 0062;0061 3099 1BF2 094D 05B0 0062; +0061 05B0 094D 3099 1BF3 0062;0061 3099 094D 1BF3 05B0 0062;0061 3099 094D 1BF3 05B0 0062;0061 3099 094D 1BF3 05B0 0062;0061 3099 094D 1BF3 05B0 0062; +0061 1BF3 05B0 094D 3099 0062;0061 3099 1BF3 094D 05B0 0062;0061 3099 1BF3 094D 05B0 0062;0061 3099 1BF3 094D 05B0 0062;0061 3099 1BF3 094D 05B0 0062; +0061 3099 093C 0334 1C37 0062;0061 0334 093C 1C37 3099 0062;0061 0334 093C 1C37 3099 0062;0061 0334 093C 1C37 3099 0062;0061 0334 093C 1C37 3099 0062; +0061 1C37 3099 093C 0334 0062;0061 0334 1C37 093C 3099 0062;0061 0334 1C37 093C 3099 0062;0061 0334 1C37 093C 3099 0062;0061 0334 1C37 093C 3099 0062; +0061 0315 0300 05AE 1CD0 0062;00E0 05AE 1CD0 0315 0062;0061 05AE 0300 1CD0 0315 0062;00E0 05AE 1CD0 0315 0062;0061 05AE 0300 1CD0 0315 0062; +0061 1CD0 0315 0300 05AE 0062;0061 05AE 1CD0 0300 0315 0062;0061 05AE 1CD0 0300 0315 0062;0061 05AE 1CD0 0300 0315 0062;0061 05AE 1CD0 0300 0315 0062; +0061 0315 0300 05AE 1CD1 0062;00E0 05AE 1CD1 0315 0062;0061 05AE 0300 1CD1 0315 0062;00E0 05AE 1CD1 0315 0062;0061 05AE 0300 1CD1 0315 0062; +0061 1CD1 0315 0300 05AE 0062;0061 05AE 1CD1 0300 0315 0062;0061 05AE 1CD1 0300 0315 0062;0061 05AE 1CD1 0300 0315 0062;0061 05AE 1CD1 0300 0315 0062; +0061 0315 0300 05AE 1CD2 0062;00E0 05AE 1CD2 0315 0062;0061 05AE 0300 1CD2 0315 0062;00E0 05AE 1CD2 0315 0062;0061 05AE 0300 1CD2 0315 0062; +0061 1CD2 0315 0300 05AE 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062; +0061 093C 0334 1CD4 0062;0061 0334 1CD4 093C 0062;0061 0334 1CD4 093C 0062;0061 0334 1CD4 093C 0062;0061 0334 1CD4 093C 0062; +0061 1CD4 093C 0334 0062;0061 1CD4 0334 093C 0062;0061 1CD4 0334 093C 0062;0061 1CD4 0334 093C 0062;0061 1CD4 0334 093C 0062; +0061 059A 0316 302A 1CD5 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062; +0061 1CD5 059A 0316 302A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062; +0061 059A 0316 302A 1CD6 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062; +0061 1CD6 059A 0316 302A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062; +0061 059A 0316 302A 1CD7 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062; +0061 1CD7 059A 0316 302A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062; +0061 059A 0316 302A 1CD8 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062; +0061 1CD8 059A 0316 302A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062; +0061 059A 0316 302A 1CD9 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062; +0061 1CD9 059A 0316 302A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062; +0061 0315 0300 05AE 1CDA 0062;00E0 05AE 1CDA 0315 0062;0061 05AE 0300 1CDA 0315 0062;00E0 05AE 1CDA 0315 0062;0061 05AE 0300 1CDA 0315 0062; +0061 1CDA 0315 0300 05AE 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062; +0061 0315 0300 05AE 1CDB 0062;00E0 05AE 1CDB 0315 0062;0061 05AE 0300 1CDB 0315 0062;00E0 05AE 1CDB 0315 0062;0061 05AE 0300 1CDB 0315 0062; +0061 1CDB 0315 0300 05AE 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062; +0061 059A 0316 302A 1CDC 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062; +0061 1CDC 059A 0316 302A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062; +0061 059A 0316 302A 1CDD 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062; +0061 1CDD 059A 0316 302A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062; +0061 059A 0316 302A 1CDE 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062; +0061 1CDE 059A 0316 302A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062; +0061 059A 0316 302A 1CDF 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062; +0061 1CDF 059A 0316 302A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062; +0061 0315 0300 05AE 1CE0 0062;00E0 05AE 1CE0 0315 0062;0061 05AE 0300 1CE0 0315 0062;00E0 05AE 1CE0 0315 0062;0061 05AE 0300 1CE0 0315 0062; +0061 1CE0 0315 0300 05AE 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062; +0061 093C 0334 1CE2 0062;0061 0334 1CE2 093C 0062;0061 0334 1CE2 093C 0062;0061 0334 1CE2 093C 0062;0061 0334 1CE2 093C 0062; +0061 1CE2 093C 0334 0062;0061 1CE2 0334 093C 0062;0061 1CE2 0334 093C 0062;0061 1CE2 0334 093C 0062;0061 1CE2 0334 093C 0062; +0061 093C 0334 1CE3 0062;0061 0334 1CE3 093C 0062;0061 0334 1CE3 093C 0062;0061 0334 1CE3 093C 0062;0061 0334 1CE3 093C 0062; +0061 1CE3 093C 0334 0062;0061 1CE3 0334 093C 0062;0061 1CE3 0334 093C 0062;0061 1CE3 0334 093C 0062;0061 1CE3 0334 093C 0062; +0061 093C 0334 1CE4 0062;0061 0334 1CE4 093C 0062;0061 0334 1CE4 093C 0062;0061 0334 1CE4 093C 0062;0061 0334 1CE4 093C 0062; +0061 1CE4 093C 0334 0062;0061 1CE4 0334 093C 0062;0061 1CE4 0334 093C 0062;0061 1CE4 0334 093C 0062;0061 1CE4 0334 093C 0062; +0061 093C 0334 1CE5 0062;0061 0334 1CE5 093C 0062;0061 0334 1CE5 093C 0062;0061 0334 1CE5 093C 0062;0061 0334 1CE5 093C 0062; +0061 1CE5 093C 0334 0062;0061 1CE5 0334 093C 0062;0061 1CE5 0334 093C 0062;0061 1CE5 0334 093C 0062;0061 1CE5 0334 093C 0062; +0061 093C 0334 1CE6 0062;0061 0334 1CE6 093C 0062;0061 0334 1CE6 093C 0062;0061 0334 1CE6 093C 0062;0061 0334 1CE6 093C 0062; +0061 1CE6 093C 0334 0062;0061 1CE6 0334 093C 0062;0061 1CE6 0334 093C 0062;0061 1CE6 0334 093C 0062;0061 1CE6 0334 093C 0062; +0061 093C 0334 1CE7 0062;0061 0334 1CE7 093C 0062;0061 0334 1CE7 093C 0062;0061 0334 1CE7 093C 0062;0061 0334 1CE7 093C 0062; +0061 1CE7 093C 0334 0062;0061 1CE7 0334 093C 0062;0061 1CE7 0334 093C 0062;0061 1CE7 0334 093C 0062;0061 1CE7 0334 093C 0062; +0061 093C 0334 1CE8 0062;0061 0334 1CE8 093C 0062;0061 0334 1CE8 093C 0062;0061 0334 1CE8 093C 0062;0061 0334 1CE8 093C 0062; +0061 1CE8 093C 0334 0062;0061 1CE8 0334 093C 0062;0061 1CE8 0334 093C 0062;0061 1CE8 0334 093C 0062;0061 1CE8 0334 093C 0062; +0061 059A 0316 302A 1CED 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062; +0061 1CED 059A 0316 302A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062; +0061 0315 0300 05AE 1CF4 0062;00E0 05AE 1CF4 0315 0062;0061 05AE 0300 1CF4 0315 0062;00E0 05AE 1CF4 0315 0062;0061 05AE 0300 1CF4 0315 0062; +0061 1CF4 0315 0300 05AE 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062; +0061 0315 0300 05AE 1CF8 0062;00E0 05AE 1CF8 0315 0062;0061 05AE 0300 1CF8 0315 0062;00E0 05AE 1CF8 0315 0062;0061 05AE 0300 1CF8 0315 0062; +0061 1CF8 0315 0300 05AE 0062;0061 05AE 1CF8 0300 0315 0062;0061 05AE 1CF8 0300 0315 0062;0061 05AE 1CF8 0300 0315 0062;0061 05AE 1CF8 0300 0315 0062; +0061 0315 0300 05AE 1CF9 0062;00E0 05AE 1CF9 0315 0062;0061 05AE 0300 1CF9 0315 0062;00E0 05AE 1CF9 0315 0062;0061 05AE 0300 1CF9 0315 0062; +0061 1CF9 0315 0300 05AE 0062;0061 05AE 1CF9 0300 0315 0062;0061 05AE 1CF9 0300 0315 0062;0061 05AE 1CF9 0300 0315 0062;0061 05AE 1CF9 0300 0315 0062; +0061 0315 0300 05AE 1DC0 0062;00E0 05AE 1DC0 0315 0062;0061 05AE 0300 1DC0 0315 0062;00E0 05AE 1DC0 0315 0062;0061 05AE 0300 1DC0 0315 0062; +0061 1DC0 0315 0300 05AE 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062; +0061 0315 0300 05AE 1DC1 0062;00E0 05AE 1DC1 0315 0062;0061 05AE 0300 1DC1 0315 0062;00E0 05AE 1DC1 0315 0062;0061 05AE 0300 1DC1 0315 0062; +0061 1DC1 0315 0300 05AE 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062; +0061 059A 0316 302A 1DC2 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062; +0061 1DC2 059A 0316 302A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062; +0061 0315 0300 05AE 1DC3 0062;00E0 05AE 1DC3 0315 0062;0061 05AE 0300 1DC3 0315 0062;00E0 05AE 1DC3 0315 0062;0061 05AE 0300 1DC3 0315 0062; +0061 1DC3 0315 0300 05AE 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062; +0061 0315 0300 05AE 1DC4 0062;00E0 05AE 1DC4 0315 0062;0061 05AE 0300 1DC4 0315 0062;00E0 05AE 1DC4 0315 0062;0061 05AE 0300 1DC4 0315 0062; +0061 1DC4 0315 0300 05AE 0062;0061 05AE 1DC4 0300 0315 0062;0061 05AE 1DC4 0300 0315 0062;0061 05AE 1DC4 0300 0315 0062;0061 05AE 1DC4 0300 0315 0062; +0061 0315 0300 05AE 1DC5 0062;00E0 05AE 1DC5 0315 0062;0061 05AE 0300 1DC5 0315 0062;00E0 05AE 1DC5 0315 0062;0061 05AE 0300 1DC5 0315 0062; +0061 1DC5 0315 0300 05AE 0062;0061 05AE 1DC5 0300 0315 0062;0061 05AE 1DC5 0300 0315 0062;0061 05AE 1DC5 0300 0315 0062;0061 05AE 1DC5 0300 0315 0062; +0061 0315 0300 05AE 1DC6 0062;00E0 05AE 1DC6 0315 0062;0061 05AE 0300 1DC6 0315 0062;00E0 05AE 1DC6 0315 0062;0061 05AE 0300 1DC6 0315 0062; +0061 1DC6 0315 0300 05AE 0062;0061 05AE 1DC6 0300 0315 0062;0061 05AE 1DC6 0300 0315 0062;0061 05AE 1DC6 0300 0315 0062;0061 05AE 1DC6 0300 0315 0062; +0061 0315 0300 05AE 1DC7 0062;00E0 05AE 1DC7 0315 0062;0061 05AE 0300 1DC7 0315 0062;00E0 05AE 1DC7 0315 0062;0061 05AE 0300 1DC7 0315 0062; +0061 1DC7 0315 0300 05AE 0062;0061 05AE 1DC7 0300 0315 0062;0061 05AE 1DC7 0300 0315 0062;0061 05AE 1DC7 0300 0315 0062;0061 05AE 1DC7 0300 0315 0062; +0061 0315 0300 05AE 1DC8 0062;00E0 05AE 1DC8 0315 0062;0061 05AE 0300 1DC8 0315 0062;00E0 05AE 1DC8 0315 0062;0061 05AE 0300 1DC8 0315 0062; +0061 1DC8 0315 0300 05AE 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062; +0061 0315 0300 05AE 1DC9 0062;00E0 05AE 1DC9 0315 0062;0061 05AE 0300 1DC9 0315 0062;00E0 05AE 1DC9 0315 0062;0061 05AE 0300 1DC9 0315 0062; +0061 1DC9 0315 0300 05AE 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062; +0061 059A 0316 302A 1DCA 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062; +0061 1DCA 059A 0316 302A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062; +0061 0315 0300 05AE 1DCB 0062;00E0 05AE 1DCB 0315 0062;0061 05AE 0300 1DCB 0315 0062;00E0 05AE 1DCB 0315 0062;0061 05AE 0300 1DCB 0315 0062; +0061 1DCB 0315 0300 05AE 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062; +0061 0315 0300 05AE 1DCC 0062;00E0 05AE 1DCC 0315 0062;0061 05AE 0300 1DCC 0315 0062;00E0 05AE 1DCC 0315 0062;0061 05AE 0300 1DCC 0315 0062; +0061 1DCC 0315 0300 05AE 0062;0061 05AE 1DCC 0300 0315 0062;0061 05AE 1DCC 0300 0315 0062;0061 05AE 1DCC 0300 0315 0062;0061 05AE 1DCC 0300 0315 0062; +0061 0345 035D 035C 1DCD 0062;0061 035C 035D 1DCD 0345 0062;0061 035C 035D 1DCD 0345 0062;0061 035C 035D 1DCD 0345 0062;0061 035C 035D 1DCD 0345 0062; +0061 1DCD 0345 035D 035C 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062; +0061 031B 1DCE 0321 1DCE 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062; +0061 1DCE 031B 1DCE 0321 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062; +0061 059A 0316 302A 1DCF 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062; +0061 1DCF 059A 0316 302A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062; +0061 1DCE 0321 0F74 1DD0 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062; +0061 1DD0 1DCE 0321 0F74 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062; +0061 0315 0300 05AE 1DD1 0062;00E0 05AE 1DD1 0315 0062;0061 05AE 0300 1DD1 0315 0062;00E0 05AE 1DD1 0315 0062;0061 05AE 0300 1DD1 0315 0062; +0061 1DD1 0315 0300 05AE 0062;0061 05AE 1DD1 0300 0315 0062;0061 05AE 1DD1 0300 0315 0062;0061 05AE 1DD1 0300 0315 0062;0061 05AE 1DD1 0300 0315 0062; +0061 0315 0300 05AE 1DD2 0062;00E0 05AE 1DD2 0315 0062;0061 05AE 0300 1DD2 0315 0062;00E0 05AE 1DD2 0315 0062;0061 05AE 0300 1DD2 0315 0062; +0061 1DD2 0315 0300 05AE 0062;0061 05AE 1DD2 0300 0315 0062;0061 05AE 1DD2 0300 0315 0062;0061 05AE 1DD2 0300 0315 0062;0061 05AE 1DD2 0300 0315 0062; +0061 0315 0300 05AE 1DD3 0062;00E0 05AE 1DD3 0315 0062;0061 05AE 0300 1DD3 0315 0062;00E0 05AE 1DD3 0315 0062;0061 05AE 0300 1DD3 0315 0062; +0061 1DD3 0315 0300 05AE 0062;0061 05AE 1DD3 0300 0315 0062;0061 05AE 1DD3 0300 0315 0062;0061 05AE 1DD3 0300 0315 0062;0061 05AE 1DD3 0300 0315 0062; +0061 0315 0300 05AE 1DD4 0062;00E0 05AE 1DD4 0315 0062;0061 05AE 0300 1DD4 0315 0062;00E0 05AE 1DD4 0315 0062;0061 05AE 0300 1DD4 0315 0062; +0061 1DD4 0315 0300 05AE 0062;0061 05AE 1DD4 0300 0315 0062;0061 05AE 1DD4 0300 0315 0062;0061 05AE 1DD4 0300 0315 0062;0061 05AE 1DD4 0300 0315 0062; +0061 0315 0300 05AE 1DD5 0062;00E0 05AE 1DD5 0315 0062;0061 05AE 0300 1DD5 0315 0062;00E0 05AE 1DD5 0315 0062;0061 05AE 0300 1DD5 0315 0062; +0061 1DD5 0315 0300 05AE 0062;0061 05AE 1DD5 0300 0315 0062;0061 05AE 1DD5 0300 0315 0062;0061 05AE 1DD5 0300 0315 0062;0061 05AE 1DD5 0300 0315 0062; +0061 0315 0300 05AE 1DD6 0062;00E0 05AE 1DD6 0315 0062;0061 05AE 0300 1DD6 0315 0062;00E0 05AE 1DD6 0315 0062;0061 05AE 0300 1DD6 0315 0062; +0061 1DD6 0315 0300 05AE 0062;0061 05AE 1DD6 0300 0315 0062;0061 05AE 1DD6 0300 0315 0062;0061 05AE 1DD6 0300 0315 0062;0061 05AE 1DD6 0300 0315 0062; +0061 0315 0300 05AE 1DD7 0062;00E0 05AE 1DD7 0315 0062;0061 05AE 0300 1DD7 0315 0062;00E0 05AE 1DD7 0315 0062;0061 05AE 0300 1DD7 0315 0062; +0061 1DD7 0315 0300 05AE 0062;0061 05AE 1DD7 0300 0315 0062;0061 05AE 1DD7 0300 0315 0062;0061 05AE 1DD7 0300 0315 0062;0061 05AE 1DD7 0300 0315 0062; +0061 0315 0300 05AE 1DD8 0062;00E0 05AE 1DD8 0315 0062;0061 05AE 0300 1DD8 0315 0062;00E0 05AE 1DD8 0315 0062;0061 05AE 0300 1DD8 0315 0062; +0061 1DD8 0315 0300 05AE 0062;0061 05AE 1DD8 0300 0315 0062;0061 05AE 1DD8 0300 0315 0062;0061 05AE 1DD8 0300 0315 0062;0061 05AE 1DD8 0300 0315 0062; +0061 0315 0300 05AE 1DD9 0062;00E0 05AE 1DD9 0315 0062;0061 05AE 0300 1DD9 0315 0062;00E0 05AE 1DD9 0315 0062;0061 05AE 0300 1DD9 0315 0062; +0061 1DD9 0315 0300 05AE 0062;0061 05AE 1DD9 0300 0315 0062;0061 05AE 1DD9 0300 0315 0062;0061 05AE 1DD9 0300 0315 0062;0061 05AE 1DD9 0300 0315 0062; +0061 0315 0300 05AE 1DDA 0062;00E0 05AE 1DDA 0315 0062;0061 05AE 0300 1DDA 0315 0062;00E0 05AE 1DDA 0315 0062;0061 05AE 0300 1DDA 0315 0062; +0061 1DDA 0315 0300 05AE 0062;0061 05AE 1DDA 0300 0315 0062;0061 05AE 1DDA 0300 0315 0062;0061 05AE 1DDA 0300 0315 0062;0061 05AE 1DDA 0300 0315 0062; +0061 0315 0300 05AE 1DDB 0062;00E0 05AE 1DDB 0315 0062;0061 05AE 0300 1DDB 0315 0062;00E0 05AE 1DDB 0315 0062;0061 05AE 0300 1DDB 0315 0062; +0061 1DDB 0315 0300 05AE 0062;0061 05AE 1DDB 0300 0315 0062;0061 05AE 1DDB 0300 0315 0062;0061 05AE 1DDB 0300 0315 0062;0061 05AE 1DDB 0300 0315 0062; +0061 0315 0300 05AE 1DDC 0062;00E0 05AE 1DDC 0315 0062;0061 05AE 0300 1DDC 0315 0062;00E0 05AE 1DDC 0315 0062;0061 05AE 0300 1DDC 0315 0062; +0061 1DDC 0315 0300 05AE 0062;0061 05AE 1DDC 0300 0315 0062;0061 05AE 1DDC 0300 0315 0062;0061 05AE 1DDC 0300 0315 0062;0061 05AE 1DDC 0300 0315 0062; +0061 0315 0300 05AE 1DDD 0062;00E0 05AE 1DDD 0315 0062;0061 05AE 0300 1DDD 0315 0062;00E0 05AE 1DDD 0315 0062;0061 05AE 0300 1DDD 0315 0062; +0061 1DDD 0315 0300 05AE 0062;0061 05AE 1DDD 0300 0315 0062;0061 05AE 1DDD 0300 0315 0062;0061 05AE 1DDD 0300 0315 0062;0061 05AE 1DDD 0300 0315 0062; +0061 0315 0300 05AE 1DDE 0062;00E0 05AE 1DDE 0315 0062;0061 05AE 0300 1DDE 0315 0062;00E0 05AE 1DDE 0315 0062;0061 05AE 0300 1DDE 0315 0062; +0061 1DDE 0315 0300 05AE 0062;0061 05AE 1DDE 0300 0315 0062;0061 05AE 1DDE 0300 0315 0062;0061 05AE 1DDE 0300 0315 0062;0061 05AE 1DDE 0300 0315 0062; +0061 0315 0300 05AE 1DDF 0062;00E0 05AE 1DDF 0315 0062;0061 05AE 0300 1DDF 0315 0062;00E0 05AE 1DDF 0315 0062;0061 05AE 0300 1DDF 0315 0062; +0061 1DDF 0315 0300 05AE 0062;0061 05AE 1DDF 0300 0315 0062;0061 05AE 1DDF 0300 0315 0062;0061 05AE 1DDF 0300 0315 0062;0061 05AE 1DDF 0300 0315 0062; +0061 0315 0300 05AE 1DE0 0062;00E0 05AE 1DE0 0315 0062;0061 05AE 0300 1DE0 0315 0062;00E0 05AE 1DE0 0315 0062;0061 05AE 0300 1DE0 0315 0062; +0061 1DE0 0315 0300 05AE 0062;0061 05AE 1DE0 0300 0315 0062;0061 05AE 1DE0 0300 0315 0062;0061 05AE 1DE0 0300 0315 0062;0061 05AE 1DE0 0300 0315 0062; +0061 0315 0300 05AE 1DE1 0062;00E0 05AE 1DE1 0315 0062;0061 05AE 0300 1DE1 0315 0062;00E0 05AE 1DE1 0315 0062;0061 05AE 0300 1DE1 0315 0062; +0061 1DE1 0315 0300 05AE 0062;0061 05AE 1DE1 0300 0315 0062;0061 05AE 1DE1 0300 0315 0062;0061 05AE 1DE1 0300 0315 0062;0061 05AE 1DE1 0300 0315 0062; +0061 0315 0300 05AE 1DE2 0062;00E0 05AE 1DE2 0315 0062;0061 05AE 0300 1DE2 0315 0062;00E0 05AE 1DE2 0315 0062;0061 05AE 0300 1DE2 0315 0062; +0061 1DE2 0315 0300 05AE 0062;0061 05AE 1DE2 0300 0315 0062;0061 05AE 1DE2 0300 0315 0062;0061 05AE 1DE2 0300 0315 0062;0061 05AE 1DE2 0300 0315 0062; +0061 0315 0300 05AE 1DE3 0062;00E0 05AE 1DE3 0315 0062;0061 05AE 0300 1DE3 0315 0062;00E0 05AE 1DE3 0315 0062;0061 05AE 0300 1DE3 0315 0062; +0061 1DE3 0315 0300 05AE 0062;0061 05AE 1DE3 0300 0315 0062;0061 05AE 1DE3 0300 0315 0062;0061 05AE 1DE3 0300 0315 0062;0061 05AE 1DE3 0300 0315 0062; +0061 0315 0300 05AE 1DE4 0062;00E0 05AE 1DE4 0315 0062;0061 05AE 0300 1DE4 0315 0062;00E0 05AE 1DE4 0315 0062;0061 05AE 0300 1DE4 0315 0062; +0061 1DE4 0315 0300 05AE 0062;0061 05AE 1DE4 0300 0315 0062;0061 05AE 1DE4 0300 0315 0062;0061 05AE 1DE4 0300 0315 0062;0061 05AE 1DE4 0300 0315 0062; +0061 0315 0300 05AE 1DE5 0062;00E0 05AE 1DE5 0315 0062;0061 05AE 0300 1DE5 0315 0062;00E0 05AE 1DE5 0315 0062;0061 05AE 0300 1DE5 0315 0062; +0061 1DE5 0315 0300 05AE 0062;0061 05AE 1DE5 0300 0315 0062;0061 05AE 1DE5 0300 0315 0062;0061 05AE 1DE5 0300 0315 0062;0061 05AE 1DE5 0300 0315 0062; +0061 0315 0300 05AE 1DE6 0062;00E0 05AE 1DE6 0315 0062;0061 05AE 0300 1DE6 0315 0062;00E0 05AE 1DE6 0315 0062;0061 05AE 0300 1DE6 0315 0062; +0061 1DE6 0315 0300 05AE 0062;0061 05AE 1DE6 0300 0315 0062;0061 05AE 1DE6 0300 0315 0062;0061 05AE 1DE6 0300 0315 0062;0061 05AE 1DE6 0300 0315 0062; +0061 0315 0300 05AE 1DE7 0062;00E0 05AE 1DE7 0315 0062;0061 05AE 0300 1DE7 0315 0062;00E0 05AE 1DE7 0315 0062;0061 05AE 0300 1DE7 0315 0062; +0061 1DE7 0315 0300 05AE 0062;0061 05AE 1DE7 0300 0315 0062;0061 05AE 1DE7 0300 0315 0062;0061 05AE 1DE7 0300 0315 0062;0061 05AE 1DE7 0300 0315 0062; +0061 0315 0300 05AE 1DE8 0062;00E0 05AE 1DE8 0315 0062;0061 05AE 0300 1DE8 0315 0062;00E0 05AE 1DE8 0315 0062;0061 05AE 0300 1DE8 0315 0062; +0061 1DE8 0315 0300 05AE 0062;0061 05AE 1DE8 0300 0315 0062;0061 05AE 1DE8 0300 0315 0062;0061 05AE 1DE8 0300 0315 0062;0061 05AE 1DE8 0300 0315 0062; +0061 0315 0300 05AE 1DE9 0062;00E0 05AE 1DE9 0315 0062;0061 05AE 0300 1DE9 0315 0062;00E0 05AE 1DE9 0315 0062;0061 05AE 0300 1DE9 0315 0062; +0061 1DE9 0315 0300 05AE 0062;0061 05AE 1DE9 0300 0315 0062;0061 05AE 1DE9 0300 0315 0062;0061 05AE 1DE9 0300 0315 0062;0061 05AE 1DE9 0300 0315 0062; +0061 0315 0300 05AE 1DEA 0062;00E0 05AE 1DEA 0315 0062;0061 05AE 0300 1DEA 0315 0062;00E0 05AE 1DEA 0315 0062;0061 05AE 0300 1DEA 0315 0062; +0061 1DEA 0315 0300 05AE 0062;0061 05AE 1DEA 0300 0315 0062;0061 05AE 1DEA 0300 0315 0062;0061 05AE 1DEA 0300 0315 0062;0061 05AE 1DEA 0300 0315 0062; +0061 0315 0300 05AE 1DEB 0062;00E0 05AE 1DEB 0315 0062;0061 05AE 0300 1DEB 0315 0062;00E0 05AE 1DEB 0315 0062;0061 05AE 0300 1DEB 0315 0062; +0061 1DEB 0315 0300 05AE 0062;0061 05AE 1DEB 0300 0315 0062;0061 05AE 1DEB 0300 0315 0062;0061 05AE 1DEB 0300 0315 0062;0061 05AE 1DEB 0300 0315 0062; +0061 0315 0300 05AE 1DEC 0062;00E0 05AE 1DEC 0315 0062;0061 05AE 0300 1DEC 0315 0062;00E0 05AE 1DEC 0315 0062;0061 05AE 0300 1DEC 0315 0062; +0061 1DEC 0315 0300 05AE 0062;0061 05AE 1DEC 0300 0315 0062;0061 05AE 1DEC 0300 0315 0062;0061 05AE 1DEC 0300 0315 0062;0061 05AE 1DEC 0300 0315 0062; +0061 0315 0300 05AE 1DED 0062;00E0 05AE 1DED 0315 0062;0061 05AE 0300 1DED 0315 0062;00E0 05AE 1DED 0315 0062;0061 05AE 0300 1DED 0315 0062; +0061 1DED 0315 0300 05AE 0062;0061 05AE 1DED 0300 0315 0062;0061 05AE 1DED 0300 0315 0062;0061 05AE 1DED 0300 0315 0062;0061 05AE 1DED 0300 0315 0062; +0061 0315 0300 05AE 1DEE 0062;00E0 05AE 1DEE 0315 0062;0061 05AE 0300 1DEE 0315 0062;00E0 05AE 1DEE 0315 0062;0061 05AE 0300 1DEE 0315 0062; +0061 1DEE 0315 0300 05AE 0062;0061 05AE 1DEE 0300 0315 0062;0061 05AE 1DEE 0300 0315 0062;0061 05AE 1DEE 0300 0315 0062;0061 05AE 1DEE 0300 0315 0062; +0061 0315 0300 05AE 1DEF 0062;00E0 05AE 1DEF 0315 0062;0061 05AE 0300 1DEF 0315 0062;00E0 05AE 1DEF 0315 0062;0061 05AE 0300 1DEF 0315 0062; +0061 1DEF 0315 0300 05AE 0062;0061 05AE 1DEF 0300 0315 0062;0061 05AE 1DEF 0300 0315 0062;0061 05AE 1DEF 0300 0315 0062;0061 05AE 1DEF 0300 0315 0062; +0061 0315 0300 05AE 1DF0 0062;00E0 05AE 1DF0 0315 0062;0061 05AE 0300 1DF0 0315 0062;00E0 05AE 1DF0 0315 0062;0061 05AE 0300 1DF0 0315 0062; +0061 1DF0 0315 0300 05AE 0062;0061 05AE 1DF0 0300 0315 0062;0061 05AE 1DF0 0300 0315 0062;0061 05AE 1DF0 0300 0315 0062;0061 05AE 1DF0 0300 0315 0062; +0061 0315 0300 05AE 1DF1 0062;00E0 05AE 1DF1 0315 0062;0061 05AE 0300 1DF1 0315 0062;00E0 05AE 1DF1 0315 0062;0061 05AE 0300 1DF1 0315 0062; +0061 1DF1 0315 0300 05AE 0062;0061 05AE 1DF1 0300 0315 0062;0061 05AE 1DF1 0300 0315 0062;0061 05AE 1DF1 0300 0315 0062;0061 05AE 1DF1 0300 0315 0062; +0061 0315 0300 05AE 1DF2 0062;00E0 05AE 1DF2 0315 0062;0061 05AE 0300 1DF2 0315 0062;00E0 05AE 1DF2 0315 0062;0061 05AE 0300 1DF2 0315 0062; +0061 1DF2 0315 0300 05AE 0062;0061 05AE 1DF2 0300 0315 0062;0061 05AE 1DF2 0300 0315 0062;0061 05AE 1DF2 0300 0315 0062;0061 05AE 1DF2 0300 0315 0062; +0061 0315 0300 05AE 1DF3 0062;00E0 05AE 1DF3 0315 0062;0061 05AE 0300 1DF3 0315 0062;00E0 05AE 1DF3 0315 0062;0061 05AE 0300 1DF3 0315 0062; +0061 1DF3 0315 0300 05AE 0062;0061 05AE 1DF3 0300 0315 0062;0061 05AE 1DF3 0300 0315 0062;0061 05AE 1DF3 0300 0315 0062;0061 05AE 1DF3 0300 0315 0062; +0061 0315 0300 05AE 1DF4 0062;00E0 05AE 1DF4 0315 0062;0061 05AE 0300 1DF4 0315 0062;00E0 05AE 1DF4 0315 0062;0061 05AE 0300 1DF4 0315 0062; +0061 1DF4 0315 0300 05AE 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062; +0061 0315 0300 05AE 1DF5 0062;00E0 05AE 1DF5 0315 0062;0061 05AE 0300 1DF5 0315 0062;00E0 05AE 1DF5 0315 0062;0061 05AE 0300 1DF5 0315 0062; +0061 1DF5 0315 0300 05AE 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062; +0061 035C 0315 0300 1DF6 0062;00E0 0315 1DF6 035C 0062;0061 0300 0315 1DF6 035C 0062;00E0 0315 1DF6 035C 0062;0061 0300 0315 1DF6 035C 0062; +0061 1DF6 035C 0315 0300 0062;00E0 1DF6 0315 035C 0062;0061 0300 1DF6 0315 035C 0062;00E0 1DF6 0315 035C 0062;0061 0300 1DF6 0315 035C 0062; +0061 0300 05AE 1D16D 1DF7 0062;00E0 1D16D 05AE 1DF7 0062;0061 1D16D 05AE 1DF7 0300 0062;00E0 1D16D 05AE 1DF7 0062;0061 1D16D 05AE 1DF7 0300 0062; +0061 1DF7 0300 05AE 1D16D 0062;00E0 1D16D 1DF7 05AE 0062;0061 1D16D 1DF7 05AE 0300 0062;00E0 1D16D 1DF7 05AE 0062;0061 1D16D 1DF7 05AE 0300 0062; +0061 0300 05AE 1D16D 1DF8 0062;00E0 1D16D 05AE 1DF8 0062;0061 1D16D 05AE 1DF8 0300 0062;00E0 1D16D 05AE 1DF8 0062;0061 1D16D 05AE 1DF8 0300 0062; +0061 1DF8 0300 05AE 1D16D 0062;00E0 1D16D 1DF8 05AE 0062;0061 1D16D 1DF8 05AE 0300 0062;00E0 1D16D 1DF8 05AE 0062;0061 1D16D 1DF8 05AE 0300 0062; +0061 059A 0316 302A 1DF9 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062; +0061 1DF9 059A 0316 302A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062; +0061 0315 0300 05AE 1DFB 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 0315 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 0315 0062; +0061 1DFB 0315 0300 05AE 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062; +0061 035D 035C 0315 1DFC 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062; +0061 1DFC 035D 035C 0315 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062; +0061 059A 0316 302A 1DFD 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062; +0061 1DFD 059A 0316 302A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062; +0061 0315 0300 05AE 1DFE 0062;00E0 05AE 1DFE 0315 0062;0061 05AE 0300 1DFE 0315 0062;00E0 05AE 1DFE 0315 0062;0061 05AE 0300 1DFE 0315 0062; +0061 1DFE 0315 0300 05AE 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062; +0061 059A 0316 302A 1DFF 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062; +0061 1DFF 059A 0316 302A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062; +0061 0315 0300 05AE 20D0 0062;00E0 05AE 20D0 0315 0062;0061 05AE 0300 20D0 0315 0062;00E0 05AE 20D0 0315 0062;0061 05AE 0300 20D0 0315 0062; +0061 20D0 0315 0300 05AE 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062; +0061 0315 0300 05AE 20D1 0062;00E0 05AE 20D1 0315 0062;0061 05AE 0300 20D1 0315 0062;00E0 05AE 20D1 0315 0062;0061 05AE 0300 20D1 0315 0062; +0061 20D1 0315 0300 05AE 0062;0061 05AE 20D1 0300 0315 0062;0061 05AE 20D1 0300 0315 0062;0061 05AE 20D1 0300 0315 0062;0061 05AE 20D1 0300 0315 0062; +0061 093C 0334 20D2 0062;0061 0334 20D2 093C 0062;0061 0334 20D2 093C 0062;0061 0334 20D2 093C 0062;0061 0334 20D2 093C 0062; +0061 20D2 093C 0334 0062;0061 20D2 0334 093C 0062;0061 20D2 0334 093C 0062;0061 20D2 0334 093C 0062;0061 20D2 0334 093C 0062; +0061 093C 0334 20D3 0062;0061 0334 20D3 093C 0062;0061 0334 20D3 093C 0062;0061 0334 20D3 093C 0062;0061 0334 20D3 093C 0062; +0061 20D3 093C 0334 0062;0061 20D3 0334 093C 0062;0061 20D3 0334 093C 0062;0061 20D3 0334 093C 0062;0061 20D3 0334 093C 0062; +0061 0315 0300 05AE 20D4 0062;00E0 05AE 20D4 0315 0062;0061 05AE 0300 20D4 0315 0062;00E0 05AE 20D4 0315 0062;0061 05AE 0300 20D4 0315 0062; +0061 20D4 0315 0300 05AE 0062;0061 05AE 20D4 0300 0315 0062;0061 05AE 20D4 0300 0315 0062;0061 05AE 20D4 0300 0315 0062;0061 05AE 20D4 0300 0315 0062; +0061 0315 0300 05AE 20D5 0062;00E0 05AE 20D5 0315 0062;0061 05AE 0300 20D5 0315 0062;00E0 05AE 20D5 0315 0062;0061 05AE 0300 20D5 0315 0062; +0061 20D5 0315 0300 05AE 0062;0061 05AE 20D5 0300 0315 0062;0061 05AE 20D5 0300 0315 0062;0061 05AE 20D5 0300 0315 0062;0061 05AE 20D5 0300 0315 0062; +0061 0315 0300 05AE 20D6 0062;00E0 05AE 20D6 0315 0062;0061 05AE 0300 20D6 0315 0062;00E0 05AE 20D6 0315 0062;0061 05AE 0300 20D6 0315 0062; +0061 20D6 0315 0300 05AE 0062;0061 05AE 20D6 0300 0315 0062;0061 05AE 20D6 0300 0315 0062;0061 05AE 20D6 0300 0315 0062;0061 05AE 20D6 0300 0315 0062; +0061 0315 0300 05AE 20D7 0062;00E0 05AE 20D7 0315 0062;0061 05AE 0300 20D7 0315 0062;00E0 05AE 20D7 0315 0062;0061 05AE 0300 20D7 0315 0062; +0061 20D7 0315 0300 05AE 0062;0061 05AE 20D7 0300 0315 0062;0061 05AE 20D7 0300 0315 0062;0061 05AE 20D7 0300 0315 0062;0061 05AE 20D7 0300 0315 0062; +0061 093C 0334 20D8 0062;0061 0334 20D8 093C 0062;0061 0334 20D8 093C 0062;0061 0334 20D8 093C 0062;0061 0334 20D8 093C 0062; +0061 20D8 093C 0334 0062;0061 20D8 0334 093C 0062;0061 20D8 0334 093C 0062;0061 20D8 0334 093C 0062;0061 20D8 0334 093C 0062; +0061 093C 0334 20D9 0062;0061 0334 20D9 093C 0062;0061 0334 20D9 093C 0062;0061 0334 20D9 093C 0062;0061 0334 20D9 093C 0062; +0061 20D9 093C 0334 0062;0061 20D9 0334 093C 0062;0061 20D9 0334 093C 0062;0061 20D9 0334 093C 0062;0061 20D9 0334 093C 0062; +0061 093C 0334 20DA 0062;0061 0334 20DA 093C 0062;0061 0334 20DA 093C 0062;0061 0334 20DA 093C 0062;0061 0334 20DA 093C 0062; +0061 20DA 093C 0334 0062;0061 20DA 0334 093C 0062;0061 20DA 0334 093C 0062;0061 20DA 0334 093C 0062;0061 20DA 0334 093C 0062; +0061 0315 0300 05AE 20DB 0062;00E0 05AE 20DB 0315 0062;0061 05AE 0300 20DB 0315 0062;00E0 05AE 20DB 0315 0062;0061 05AE 0300 20DB 0315 0062; +0061 20DB 0315 0300 05AE 0062;0061 05AE 20DB 0300 0315 0062;0061 05AE 20DB 0300 0315 0062;0061 05AE 20DB 0300 0315 0062;0061 05AE 20DB 0300 0315 0062; +0061 0315 0300 05AE 20DC 0062;00E0 05AE 20DC 0315 0062;0061 05AE 0300 20DC 0315 0062;00E0 05AE 20DC 0315 0062;0061 05AE 0300 20DC 0315 0062; +0061 20DC 0315 0300 05AE 0062;0061 05AE 20DC 0300 0315 0062;0061 05AE 20DC 0300 0315 0062;0061 05AE 20DC 0300 0315 0062;0061 05AE 20DC 0300 0315 0062; +0061 0315 0300 05AE 20E1 0062;00E0 05AE 20E1 0315 0062;0061 05AE 0300 20E1 0315 0062;00E0 05AE 20E1 0315 0062;0061 05AE 0300 20E1 0315 0062; +0061 20E1 0315 0300 05AE 0062;0061 05AE 20E1 0300 0315 0062;0061 05AE 20E1 0300 0315 0062;0061 05AE 20E1 0300 0315 0062;0061 05AE 20E1 0300 0315 0062; +0061 093C 0334 20E5 0062;0061 0334 20E5 093C 0062;0061 0334 20E5 093C 0062;0061 0334 20E5 093C 0062;0061 0334 20E5 093C 0062; +0061 20E5 093C 0334 0062;0061 20E5 0334 093C 0062;0061 20E5 0334 093C 0062;0061 20E5 0334 093C 0062;0061 20E5 0334 093C 0062; +0061 093C 0334 20E6 0062;0061 0334 20E6 093C 0062;0061 0334 20E6 093C 0062;0061 0334 20E6 093C 0062;0061 0334 20E6 093C 0062; +0061 20E6 093C 0334 0062;0061 20E6 0334 093C 0062;0061 20E6 0334 093C 0062;0061 20E6 0334 093C 0062;0061 20E6 0334 093C 0062; +0061 0315 0300 05AE 20E7 0062;00E0 05AE 20E7 0315 0062;0061 05AE 0300 20E7 0315 0062;00E0 05AE 20E7 0315 0062;0061 05AE 0300 20E7 0315 0062; +0061 20E7 0315 0300 05AE 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062; +0061 059A 0316 302A 20E8 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062; +0061 20E8 059A 0316 302A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062; +0061 0315 0300 05AE 20E9 0062;00E0 05AE 20E9 0315 0062;0061 05AE 0300 20E9 0315 0062;00E0 05AE 20E9 0315 0062;0061 05AE 0300 20E9 0315 0062; +0061 20E9 0315 0300 05AE 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062; +0061 093C 0334 20EA 0062;0061 0334 20EA 093C 0062;0061 0334 20EA 093C 0062;0061 0334 20EA 093C 0062;0061 0334 20EA 093C 0062; +0061 20EA 093C 0334 0062;0061 20EA 0334 093C 0062;0061 20EA 0334 093C 0062;0061 20EA 0334 093C 0062;0061 20EA 0334 093C 0062; +0061 093C 0334 20EB 0062;0061 0334 20EB 093C 0062;0061 0334 20EB 093C 0062;0061 0334 20EB 093C 0062;0061 0334 20EB 093C 0062; +0061 20EB 093C 0334 0062;0061 20EB 0334 093C 0062;0061 20EB 0334 093C 0062;0061 20EB 0334 093C 0062;0061 20EB 0334 093C 0062; +0061 059A 0316 302A 20EC 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062; +0061 20EC 059A 0316 302A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062; +0061 059A 0316 302A 20ED 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062; +0061 20ED 059A 0316 302A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062; +0061 059A 0316 302A 20EE 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062; +0061 20EE 059A 0316 302A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062; +0061 059A 0316 302A 20EF 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062; +0061 20EF 059A 0316 302A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062; +0061 0315 0300 05AE 20F0 0062;00E0 05AE 20F0 0315 0062;0061 05AE 0300 20F0 0315 0062;00E0 05AE 20F0 0315 0062;0061 05AE 0300 20F0 0315 0062; +0061 20F0 0315 0300 05AE 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062; +0061 0315 0300 05AE 2CEF 0062;00E0 05AE 2CEF 0315 0062;0061 05AE 0300 2CEF 0315 0062;00E0 05AE 2CEF 0315 0062;0061 05AE 0300 2CEF 0315 0062; +0061 2CEF 0315 0300 05AE 0062;0061 05AE 2CEF 0300 0315 0062;0061 05AE 2CEF 0300 0315 0062;0061 05AE 2CEF 0300 0315 0062;0061 05AE 2CEF 0300 0315 0062; +0061 0315 0300 05AE 2CF0 0062;00E0 05AE 2CF0 0315 0062;0061 05AE 0300 2CF0 0315 0062;00E0 05AE 2CF0 0315 0062;0061 05AE 0300 2CF0 0315 0062; +0061 2CF0 0315 0300 05AE 0062;0061 05AE 2CF0 0300 0315 0062;0061 05AE 2CF0 0300 0315 0062;0061 05AE 2CF0 0300 0315 0062;0061 05AE 2CF0 0300 0315 0062; +0061 0315 0300 05AE 2CF1 0062;00E0 05AE 2CF1 0315 0062;0061 05AE 0300 2CF1 0315 0062;00E0 05AE 2CF1 0315 0062;0061 05AE 0300 2CF1 0315 0062; +0061 2CF1 0315 0300 05AE 0062;0061 05AE 2CF1 0300 0315 0062;0061 05AE 2CF1 0300 0315 0062;0061 05AE 2CF1 0300 0315 0062;0061 05AE 2CF1 0300 0315 0062; +0061 05B0 094D 3099 2D7F 0062;0061 3099 094D 2D7F 05B0 0062;0061 3099 094D 2D7F 05B0 0062;0061 3099 094D 2D7F 05B0 0062;0061 3099 094D 2D7F 05B0 0062; +0061 2D7F 05B0 094D 3099 0062;0061 3099 2D7F 094D 05B0 0062;0061 3099 2D7F 094D 05B0 0062;0061 3099 2D7F 094D 05B0 0062;0061 3099 2D7F 094D 05B0 0062; +0061 0315 0300 05AE 2DE0 0062;00E0 05AE 2DE0 0315 0062;0061 05AE 0300 2DE0 0315 0062;00E0 05AE 2DE0 0315 0062;0061 05AE 0300 2DE0 0315 0062; +0061 2DE0 0315 0300 05AE 0062;0061 05AE 2DE0 0300 0315 0062;0061 05AE 2DE0 0300 0315 0062;0061 05AE 2DE0 0300 0315 0062;0061 05AE 2DE0 0300 0315 0062; +0061 0315 0300 05AE 2DE1 0062;00E0 05AE 2DE1 0315 0062;0061 05AE 0300 2DE1 0315 0062;00E0 05AE 2DE1 0315 0062;0061 05AE 0300 2DE1 0315 0062; +0061 2DE1 0315 0300 05AE 0062;0061 05AE 2DE1 0300 0315 0062;0061 05AE 2DE1 0300 0315 0062;0061 05AE 2DE1 0300 0315 0062;0061 05AE 2DE1 0300 0315 0062; +0061 0315 0300 05AE 2DE2 0062;00E0 05AE 2DE2 0315 0062;0061 05AE 0300 2DE2 0315 0062;00E0 05AE 2DE2 0315 0062;0061 05AE 0300 2DE2 0315 0062; +0061 2DE2 0315 0300 05AE 0062;0061 05AE 2DE2 0300 0315 0062;0061 05AE 2DE2 0300 0315 0062;0061 05AE 2DE2 0300 0315 0062;0061 05AE 2DE2 0300 0315 0062; +0061 0315 0300 05AE 2DE3 0062;00E0 05AE 2DE3 0315 0062;0061 05AE 0300 2DE3 0315 0062;00E0 05AE 2DE3 0315 0062;0061 05AE 0300 2DE3 0315 0062; +0061 2DE3 0315 0300 05AE 0062;0061 05AE 2DE3 0300 0315 0062;0061 05AE 2DE3 0300 0315 0062;0061 05AE 2DE3 0300 0315 0062;0061 05AE 2DE3 0300 0315 0062; +0061 0315 0300 05AE 2DE4 0062;00E0 05AE 2DE4 0315 0062;0061 05AE 0300 2DE4 0315 0062;00E0 05AE 2DE4 0315 0062;0061 05AE 0300 2DE4 0315 0062; +0061 2DE4 0315 0300 05AE 0062;0061 05AE 2DE4 0300 0315 0062;0061 05AE 2DE4 0300 0315 0062;0061 05AE 2DE4 0300 0315 0062;0061 05AE 2DE4 0300 0315 0062; +0061 0315 0300 05AE 2DE5 0062;00E0 05AE 2DE5 0315 0062;0061 05AE 0300 2DE5 0315 0062;00E0 05AE 2DE5 0315 0062;0061 05AE 0300 2DE5 0315 0062; +0061 2DE5 0315 0300 05AE 0062;0061 05AE 2DE5 0300 0315 0062;0061 05AE 2DE5 0300 0315 0062;0061 05AE 2DE5 0300 0315 0062;0061 05AE 2DE5 0300 0315 0062; +0061 0315 0300 05AE 2DE6 0062;00E0 05AE 2DE6 0315 0062;0061 05AE 0300 2DE6 0315 0062;00E0 05AE 2DE6 0315 0062;0061 05AE 0300 2DE6 0315 0062; +0061 2DE6 0315 0300 05AE 0062;0061 05AE 2DE6 0300 0315 0062;0061 05AE 2DE6 0300 0315 0062;0061 05AE 2DE6 0300 0315 0062;0061 05AE 2DE6 0300 0315 0062; +0061 0315 0300 05AE 2DE7 0062;00E0 05AE 2DE7 0315 0062;0061 05AE 0300 2DE7 0315 0062;00E0 05AE 2DE7 0315 0062;0061 05AE 0300 2DE7 0315 0062; +0061 2DE7 0315 0300 05AE 0062;0061 05AE 2DE7 0300 0315 0062;0061 05AE 2DE7 0300 0315 0062;0061 05AE 2DE7 0300 0315 0062;0061 05AE 2DE7 0300 0315 0062; +0061 0315 0300 05AE 2DE8 0062;00E0 05AE 2DE8 0315 0062;0061 05AE 0300 2DE8 0315 0062;00E0 05AE 2DE8 0315 0062;0061 05AE 0300 2DE8 0315 0062; +0061 2DE8 0315 0300 05AE 0062;0061 05AE 2DE8 0300 0315 0062;0061 05AE 2DE8 0300 0315 0062;0061 05AE 2DE8 0300 0315 0062;0061 05AE 2DE8 0300 0315 0062; +0061 0315 0300 05AE 2DE9 0062;00E0 05AE 2DE9 0315 0062;0061 05AE 0300 2DE9 0315 0062;00E0 05AE 2DE9 0315 0062;0061 05AE 0300 2DE9 0315 0062; +0061 2DE9 0315 0300 05AE 0062;0061 05AE 2DE9 0300 0315 0062;0061 05AE 2DE9 0300 0315 0062;0061 05AE 2DE9 0300 0315 0062;0061 05AE 2DE9 0300 0315 0062; +0061 0315 0300 05AE 2DEA 0062;00E0 05AE 2DEA 0315 0062;0061 05AE 0300 2DEA 0315 0062;00E0 05AE 2DEA 0315 0062;0061 05AE 0300 2DEA 0315 0062; +0061 2DEA 0315 0300 05AE 0062;0061 05AE 2DEA 0300 0315 0062;0061 05AE 2DEA 0300 0315 0062;0061 05AE 2DEA 0300 0315 0062;0061 05AE 2DEA 0300 0315 0062; +0061 0315 0300 05AE 2DEB 0062;00E0 05AE 2DEB 0315 0062;0061 05AE 0300 2DEB 0315 0062;00E0 05AE 2DEB 0315 0062;0061 05AE 0300 2DEB 0315 0062; +0061 2DEB 0315 0300 05AE 0062;0061 05AE 2DEB 0300 0315 0062;0061 05AE 2DEB 0300 0315 0062;0061 05AE 2DEB 0300 0315 0062;0061 05AE 2DEB 0300 0315 0062; +0061 0315 0300 05AE 2DEC 0062;00E0 05AE 2DEC 0315 0062;0061 05AE 0300 2DEC 0315 0062;00E0 05AE 2DEC 0315 0062;0061 05AE 0300 2DEC 0315 0062; +0061 2DEC 0315 0300 05AE 0062;0061 05AE 2DEC 0300 0315 0062;0061 05AE 2DEC 0300 0315 0062;0061 05AE 2DEC 0300 0315 0062;0061 05AE 2DEC 0300 0315 0062; +0061 0315 0300 05AE 2DED 0062;00E0 05AE 2DED 0315 0062;0061 05AE 0300 2DED 0315 0062;00E0 05AE 2DED 0315 0062;0061 05AE 0300 2DED 0315 0062; +0061 2DED 0315 0300 05AE 0062;0061 05AE 2DED 0300 0315 0062;0061 05AE 2DED 0300 0315 0062;0061 05AE 2DED 0300 0315 0062;0061 05AE 2DED 0300 0315 0062; +0061 0315 0300 05AE 2DEE 0062;00E0 05AE 2DEE 0315 0062;0061 05AE 0300 2DEE 0315 0062;00E0 05AE 2DEE 0315 0062;0061 05AE 0300 2DEE 0315 0062; +0061 2DEE 0315 0300 05AE 0062;0061 05AE 2DEE 0300 0315 0062;0061 05AE 2DEE 0300 0315 0062;0061 05AE 2DEE 0300 0315 0062;0061 05AE 2DEE 0300 0315 0062; +0061 0315 0300 05AE 2DEF 0062;00E0 05AE 2DEF 0315 0062;0061 05AE 0300 2DEF 0315 0062;00E0 05AE 2DEF 0315 0062;0061 05AE 0300 2DEF 0315 0062; +0061 2DEF 0315 0300 05AE 0062;0061 05AE 2DEF 0300 0315 0062;0061 05AE 2DEF 0300 0315 0062;0061 05AE 2DEF 0300 0315 0062;0061 05AE 2DEF 0300 0315 0062; +0061 0315 0300 05AE 2DF0 0062;00E0 05AE 2DF0 0315 0062;0061 05AE 0300 2DF0 0315 0062;00E0 05AE 2DF0 0315 0062;0061 05AE 0300 2DF0 0315 0062; +0061 2DF0 0315 0300 05AE 0062;0061 05AE 2DF0 0300 0315 0062;0061 05AE 2DF0 0300 0315 0062;0061 05AE 2DF0 0300 0315 0062;0061 05AE 2DF0 0300 0315 0062; +0061 0315 0300 05AE 2DF1 0062;00E0 05AE 2DF1 0315 0062;0061 05AE 0300 2DF1 0315 0062;00E0 05AE 2DF1 0315 0062;0061 05AE 0300 2DF1 0315 0062; +0061 2DF1 0315 0300 05AE 0062;0061 05AE 2DF1 0300 0315 0062;0061 05AE 2DF1 0300 0315 0062;0061 05AE 2DF1 0300 0315 0062;0061 05AE 2DF1 0300 0315 0062; +0061 0315 0300 05AE 2DF2 0062;00E0 05AE 2DF2 0315 0062;0061 05AE 0300 2DF2 0315 0062;00E0 05AE 2DF2 0315 0062;0061 05AE 0300 2DF2 0315 0062; +0061 2DF2 0315 0300 05AE 0062;0061 05AE 2DF2 0300 0315 0062;0061 05AE 2DF2 0300 0315 0062;0061 05AE 2DF2 0300 0315 0062;0061 05AE 2DF2 0300 0315 0062; +0061 0315 0300 05AE 2DF3 0062;00E0 05AE 2DF3 0315 0062;0061 05AE 0300 2DF3 0315 0062;00E0 05AE 2DF3 0315 0062;0061 05AE 0300 2DF3 0315 0062; +0061 2DF3 0315 0300 05AE 0062;0061 05AE 2DF3 0300 0315 0062;0061 05AE 2DF3 0300 0315 0062;0061 05AE 2DF3 0300 0315 0062;0061 05AE 2DF3 0300 0315 0062; +0061 0315 0300 05AE 2DF4 0062;00E0 05AE 2DF4 0315 0062;0061 05AE 0300 2DF4 0315 0062;00E0 05AE 2DF4 0315 0062;0061 05AE 0300 2DF4 0315 0062; +0061 2DF4 0315 0300 05AE 0062;0061 05AE 2DF4 0300 0315 0062;0061 05AE 2DF4 0300 0315 0062;0061 05AE 2DF4 0300 0315 0062;0061 05AE 2DF4 0300 0315 0062; +0061 0315 0300 05AE 2DF5 0062;00E0 05AE 2DF5 0315 0062;0061 05AE 0300 2DF5 0315 0062;00E0 05AE 2DF5 0315 0062;0061 05AE 0300 2DF5 0315 0062; +0061 2DF5 0315 0300 05AE 0062;0061 05AE 2DF5 0300 0315 0062;0061 05AE 2DF5 0300 0315 0062;0061 05AE 2DF5 0300 0315 0062;0061 05AE 2DF5 0300 0315 0062; +0061 0315 0300 05AE 2DF6 0062;00E0 05AE 2DF6 0315 0062;0061 05AE 0300 2DF6 0315 0062;00E0 05AE 2DF6 0315 0062;0061 05AE 0300 2DF6 0315 0062; +0061 2DF6 0315 0300 05AE 0062;0061 05AE 2DF6 0300 0315 0062;0061 05AE 2DF6 0300 0315 0062;0061 05AE 2DF6 0300 0315 0062;0061 05AE 2DF6 0300 0315 0062; +0061 0315 0300 05AE 2DF7 0062;00E0 05AE 2DF7 0315 0062;0061 05AE 0300 2DF7 0315 0062;00E0 05AE 2DF7 0315 0062;0061 05AE 0300 2DF7 0315 0062; +0061 2DF7 0315 0300 05AE 0062;0061 05AE 2DF7 0300 0315 0062;0061 05AE 2DF7 0300 0315 0062;0061 05AE 2DF7 0300 0315 0062;0061 05AE 2DF7 0300 0315 0062; +0061 0315 0300 05AE 2DF8 0062;00E0 05AE 2DF8 0315 0062;0061 05AE 0300 2DF8 0315 0062;00E0 05AE 2DF8 0315 0062;0061 05AE 0300 2DF8 0315 0062; +0061 2DF8 0315 0300 05AE 0062;0061 05AE 2DF8 0300 0315 0062;0061 05AE 2DF8 0300 0315 0062;0061 05AE 2DF8 0300 0315 0062;0061 05AE 2DF8 0300 0315 0062; +0061 0315 0300 05AE 2DF9 0062;00E0 05AE 2DF9 0315 0062;0061 05AE 0300 2DF9 0315 0062;00E0 05AE 2DF9 0315 0062;0061 05AE 0300 2DF9 0315 0062; +0061 2DF9 0315 0300 05AE 0062;0061 05AE 2DF9 0300 0315 0062;0061 05AE 2DF9 0300 0315 0062;0061 05AE 2DF9 0300 0315 0062;0061 05AE 2DF9 0300 0315 0062; +0061 0315 0300 05AE 2DFA 0062;00E0 05AE 2DFA 0315 0062;0061 05AE 0300 2DFA 0315 0062;00E0 05AE 2DFA 0315 0062;0061 05AE 0300 2DFA 0315 0062; +0061 2DFA 0315 0300 05AE 0062;0061 05AE 2DFA 0300 0315 0062;0061 05AE 2DFA 0300 0315 0062;0061 05AE 2DFA 0300 0315 0062;0061 05AE 2DFA 0300 0315 0062; +0061 0315 0300 05AE 2DFB 0062;00E0 05AE 2DFB 0315 0062;0061 05AE 0300 2DFB 0315 0062;00E0 05AE 2DFB 0315 0062;0061 05AE 0300 2DFB 0315 0062; +0061 2DFB 0315 0300 05AE 0062;0061 05AE 2DFB 0300 0315 0062;0061 05AE 2DFB 0300 0315 0062;0061 05AE 2DFB 0300 0315 0062;0061 05AE 2DFB 0300 0315 0062; +0061 0315 0300 05AE 2DFC 0062;00E0 05AE 2DFC 0315 0062;0061 05AE 0300 2DFC 0315 0062;00E0 05AE 2DFC 0315 0062;0061 05AE 0300 2DFC 0315 0062; +0061 2DFC 0315 0300 05AE 0062;0061 05AE 2DFC 0300 0315 0062;0061 05AE 2DFC 0300 0315 0062;0061 05AE 2DFC 0300 0315 0062;0061 05AE 2DFC 0300 0315 0062; +0061 0315 0300 05AE 2DFD 0062;00E0 05AE 2DFD 0315 0062;0061 05AE 0300 2DFD 0315 0062;00E0 05AE 2DFD 0315 0062;0061 05AE 0300 2DFD 0315 0062; +0061 2DFD 0315 0300 05AE 0062;0061 05AE 2DFD 0300 0315 0062;0061 05AE 2DFD 0300 0315 0062;0061 05AE 2DFD 0300 0315 0062;0061 05AE 2DFD 0300 0315 0062; +0061 0315 0300 05AE 2DFE 0062;00E0 05AE 2DFE 0315 0062;0061 05AE 0300 2DFE 0315 0062;00E0 05AE 2DFE 0315 0062;0061 05AE 0300 2DFE 0315 0062; +0061 2DFE 0315 0300 05AE 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062; +0061 0315 0300 05AE 2DFF 0062;00E0 05AE 2DFF 0315 0062;0061 05AE 0300 2DFF 0315 0062;00E0 05AE 2DFF 0315 0062;0061 05AE 0300 2DFF 0315 0062; +0061 2DFF 0315 0300 05AE 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062; +0061 0316 302A 031B 302A 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062; +0061 302A 0316 302A 031B 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062; +0061 0300 05AE 1D16D 302B 0062;00E0 1D16D 05AE 302B 0062;0061 1D16D 05AE 302B 0300 0062;00E0 1D16D 05AE 302B 0062;0061 1D16D 05AE 302B 0300 0062; +0061 302B 0300 05AE 1D16D 0062;00E0 1D16D 302B 05AE 0062;0061 1D16D 302B 05AE 0300 0062;00E0 1D16D 302B 05AE 0062;0061 1D16D 302B 05AE 0300 0062; +0061 035C 0315 0300 302C 0062;00E0 0315 302C 035C 0062;0061 0300 0315 302C 035C 0062;00E0 0315 302C 035C 0062;0061 0300 0315 302C 035C 0062; +0061 302C 035C 0315 0300 0062;00E0 302C 0315 035C 0062;0061 0300 302C 0315 035C 0062;00E0 302C 0315 035C 0062;0061 0300 302C 0315 035C 0062; +0061 302E 059A 0316 302D 0062;0061 0316 059A 302D 302E 0062;0061 0316 059A 302D 302E 0062;0061 0316 059A 302D 302E 0062;0061 0316 059A 302D 302E 0062; +0061 302D 302E 059A 0316 0062;0061 0316 302D 059A 302E 0062;0061 0316 302D 059A 302E 0062;0061 0316 302D 059A 302E 0062;0061 0316 302D 059A 302E 0062; +0061 1D16D 302E 059A 302E 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062; +0061 302E 1D16D 302E 059A 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062; +0061 1D16D 302E 059A 302F 0062;0061 059A 302E 302F 1D16D 0062;0061 059A 302E 302F 1D16D 0062;0061 059A 302E 302F 1D16D 0062;0061 059A 302E 302F 1D16D 0062; +0061 302F 1D16D 302E 059A 0062;0061 059A 302F 302E 1D16D 0062;0061 059A 302F 302E 1D16D 0062;0061 059A 302F 302E 1D16D 0062;0061 059A 302F 302E 1D16D 0062; +0061 094D 3099 093C 3099 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062; +0061 3099 094D 3099 093C 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062; +0061 094D 3099 093C 309A 0062;0061 093C 3099 309A 094D 0062;0061 093C 3099 309A 094D 0062;0061 093C 3099 309A 094D 0062;0061 093C 3099 309A 094D 0062; +0061 309A 094D 3099 093C 0062;0061 093C 309A 3099 094D 0062;0061 093C 309A 3099 094D 0062;0061 093C 309A 3099 094D 0062;0061 093C 309A 3099 094D 0062; +0061 0315 0300 05AE A66F 0062;00E0 05AE A66F 0315 0062;0061 05AE 0300 A66F 0315 0062;00E0 05AE A66F 0315 0062;0061 05AE 0300 A66F 0315 0062; +0061 A66F 0315 0300 05AE 0062;0061 05AE A66F 0300 0315 0062;0061 05AE A66F 0300 0315 0062;0061 05AE A66F 0300 0315 0062;0061 05AE A66F 0300 0315 0062; +0061 0315 0300 05AE A674 0062;00E0 05AE A674 0315 0062;0061 05AE 0300 A674 0315 0062;00E0 05AE A674 0315 0062;0061 05AE 0300 A674 0315 0062; +0061 A674 0315 0300 05AE 0062;0061 05AE A674 0300 0315 0062;0061 05AE A674 0300 0315 0062;0061 05AE A674 0300 0315 0062;0061 05AE A674 0300 0315 0062; +0061 0315 0300 05AE A675 0062;00E0 05AE A675 0315 0062;0061 05AE 0300 A675 0315 0062;00E0 05AE A675 0315 0062;0061 05AE 0300 A675 0315 0062; +0061 A675 0315 0300 05AE 0062;0061 05AE A675 0300 0315 0062;0061 05AE A675 0300 0315 0062;0061 05AE A675 0300 0315 0062;0061 05AE A675 0300 0315 0062; +0061 0315 0300 05AE A676 0062;00E0 05AE A676 0315 0062;0061 05AE 0300 A676 0315 0062;00E0 05AE A676 0315 0062;0061 05AE 0300 A676 0315 0062; +0061 A676 0315 0300 05AE 0062;0061 05AE A676 0300 0315 0062;0061 05AE A676 0300 0315 0062;0061 05AE A676 0300 0315 0062;0061 05AE A676 0300 0315 0062; +0061 0315 0300 05AE A677 0062;00E0 05AE A677 0315 0062;0061 05AE 0300 A677 0315 0062;00E0 05AE A677 0315 0062;0061 05AE 0300 A677 0315 0062; +0061 A677 0315 0300 05AE 0062;0061 05AE A677 0300 0315 0062;0061 05AE A677 0300 0315 0062;0061 05AE A677 0300 0315 0062;0061 05AE A677 0300 0315 0062; +0061 0315 0300 05AE A678 0062;00E0 05AE A678 0315 0062;0061 05AE 0300 A678 0315 0062;00E0 05AE A678 0315 0062;0061 05AE 0300 A678 0315 0062; +0061 A678 0315 0300 05AE 0062;0061 05AE A678 0300 0315 0062;0061 05AE A678 0300 0315 0062;0061 05AE A678 0300 0315 0062;0061 05AE A678 0300 0315 0062; +0061 0315 0300 05AE A679 0062;00E0 05AE A679 0315 0062;0061 05AE 0300 A679 0315 0062;00E0 05AE A679 0315 0062;0061 05AE 0300 A679 0315 0062; +0061 A679 0315 0300 05AE 0062;0061 05AE A679 0300 0315 0062;0061 05AE A679 0300 0315 0062;0061 05AE A679 0300 0315 0062;0061 05AE A679 0300 0315 0062; +0061 0315 0300 05AE A67A 0062;00E0 05AE A67A 0315 0062;0061 05AE 0300 A67A 0315 0062;00E0 05AE A67A 0315 0062;0061 05AE 0300 A67A 0315 0062; +0061 A67A 0315 0300 05AE 0062;0061 05AE A67A 0300 0315 0062;0061 05AE A67A 0300 0315 0062;0061 05AE A67A 0300 0315 0062;0061 05AE A67A 0300 0315 0062; +0061 0315 0300 05AE A67B 0062;00E0 05AE A67B 0315 0062;0061 05AE 0300 A67B 0315 0062;00E0 05AE A67B 0315 0062;0061 05AE 0300 A67B 0315 0062; +0061 A67B 0315 0300 05AE 0062;0061 05AE A67B 0300 0315 0062;0061 05AE A67B 0300 0315 0062;0061 05AE A67B 0300 0315 0062;0061 05AE A67B 0300 0315 0062; +0061 0315 0300 05AE A67C 0062;00E0 05AE A67C 0315 0062;0061 05AE 0300 A67C 0315 0062;00E0 05AE A67C 0315 0062;0061 05AE 0300 A67C 0315 0062; +0061 A67C 0315 0300 05AE 0062;0061 05AE A67C 0300 0315 0062;0061 05AE A67C 0300 0315 0062;0061 05AE A67C 0300 0315 0062;0061 05AE A67C 0300 0315 0062; +0061 0315 0300 05AE A67D 0062;00E0 05AE A67D 0315 0062;0061 05AE 0300 A67D 0315 0062;00E0 05AE A67D 0315 0062;0061 05AE 0300 A67D 0315 0062; +0061 A67D 0315 0300 05AE 0062;0061 05AE A67D 0300 0315 0062;0061 05AE A67D 0300 0315 0062;0061 05AE A67D 0300 0315 0062;0061 05AE A67D 0300 0315 0062; +0061 0315 0300 05AE A69E 0062;00E0 05AE A69E 0315 0062;0061 05AE 0300 A69E 0315 0062;00E0 05AE A69E 0315 0062;0061 05AE 0300 A69E 0315 0062; +0061 A69E 0315 0300 05AE 0062;0061 05AE A69E 0300 0315 0062;0061 05AE A69E 0300 0315 0062;0061 05AE A69E 0300 0315 0062;0061 05AE A69E 0300 0315 0062; +0061 0315 0300 05AE A69F 0062;00E0 05AE A69F 0315 0062;0061 05AE 0300 A69F 0315 0062;00E0 05AE A69F 0315 0062;0061 05AE 0300 A69F 0315 0062; +0061 A69F 0315 0300 05AE 0062;0061 05AE A69F 0300 0315 0062;0061 05AE A69F 0300 0315 0062;0061 05AE A69F 0300 0315 0062;0061 05AE A69F 0300 0315 0062; +0061 0315 0300 05AE A6F0 0062;00E0 05AE A6F0 0315 0062;0061 05AE 0300 A6F0 0315 0062;00E0 05AE A6F0 0315 0062;0061 05AE 0300 A6F0 0315 0062; +0061 A6F0 0315 0300 05AE 0062;0061 05AE A6F0 0300 0315 0062;0061 05AE A6F0 0300 0315 0062;0061 05AE A6F0 0300 0315 0062;0061 05AE A6F0 0300 0315 0062; +0061 0315 0300 05AE A6F1 0062;00E0 05AE A6F1 0315 0062;0061 05AE 0300 A6F1 0315 0062;00E0 05AE A6F1 0315 0062;0061 05AE 0300 A6F1 0315 0062; +0061 A6F1 0315 0300 05AE 0062;0061 05AE A6F1 0300 0315 0062;0061 05AE A6F1 0300 0315 0062;0061 05AE A6F1 0300 0315 0062;0061 05AE A6F1 0300 0315 0062; +0061 05B0 094D 3099 A806 0062;0061 3099 094D A806 05B0 0062;0061 3099 094D A806 05B0 0062;0061 3099 094D A806 05B0 0062;0061 3099 094D A806 05B0 0062; +0061 A806 05B0 094D 3099 0062;0061 3099 A806 094D 05B0 0062;0061 3099 A806 094D 05B0 0062;0061 3099 A806 094D 05B0 0062;0061 3099 A806 094D 05B0 0062; +0061 05B0 094D 3099 A8C4 0062;0061 3099 094D A8C4 05B0 0062;0061 3099 094D A8C4 05B0 0062;0061 3099 094D A8C4 05B0 0062;0061 3099 094D A8C4 05B0 0062; +0061 A8C4 05B0 094D 3099 0062;0061 3099 A8C4 094D 05B0 0062;0061 3099 A8C4 094D 05B0 0062;0061 3099 A8C4 094D 05B0 0062;0061 3099 A8C4 094D 05B0 0062; +0061 0315 0300 05AE A8E0 0062;00E0 05AE A8E0 0315 0062;0061 05AE 0300 A8E0 0315 0062;00E0 05AE A8E0 0315 0062;0061 05AE 0300 A8E0 0315 0062; +0061 A8E0 0315 0300 05AE 0062;0061 05AE A8E0 0300 0315 0062;0061 05AE A8E0 0300 0315 0062;0061 05AE A8E0 0300 0315 0062;0061 05AE A8E0 0300 0315 0062; +0061 0315 0300 05AE A8E1 0062;00E0 05AE A8E1 0315 0062;0061 05AE 0300 A8E1 0315 0062;00E0 05AE A8E1 0315 0062;0061 05AE 0300 A8E1 0315 0062; +0061 A8E1 0315 0300 05AE 0062;0061 05AE A8E1 0300 0315 0062;0061 05AE A8E1 0300 0315 0062;0061 05AE A8E1 0300 0315 0062;0061 05AE A8E1 0300 0315 0062; +0061 0315 0300 05AE A8E2 0062;00E0 05AE A8E2 0315 0062;0061 05AE 0300 A8E2 0315 0062;00E0 05AE A8E2 0315 0062;0061 05AE 0300 A8E2 0315 0062; +0061 A8E2 0315 0300 05AE 0062;0061 05AE A8E2 0300 0315 0062;0061 05AE A8E2 0300 0315 0062;0061 05AE A8E2 0300 0315 0062;0061 05AE A8E2 0300 0315 0062; +0061 0315 0300 05AE A8E3 0062;00E0 05AE A8E3 0315 0062;0061 05AE 0300 A8E3 0315 0062;00E0 05AE A8E3 0315 0062;0061 05AE 0300 A8E3 0315 0062; +0061 A8E3 0315 0300 05AE 0062;0061 05AE A8E3 0300 0315 0062;0061 05AE A8E3 0300 0315 0062;0061 05AE A8E3 0300 0315 0062;0061 05AE A8E3 0300 0315 0062; +0061 0315 0300 05AE A8E4 0062;00E0 05AE A8E4 0315 0062;0061 05AE 0300 A8E4 0315 0062;00E0 05AE A8E4 0315 0062;0061 05AE 0300 A8E4 0315 0062; +0061 A8E4 0315 0300 05AE 0062;0061 05AE A8E4 0300 0315 0062;0061 05AE A8E4 0300 0315 0062;0061 05AE A8E4 0300 0315 0062;0061 05AE A8E4 0300 0315 0062; +0061 0315 0300 05AE A8E5 0062;00E0 05AE A8E5 0315 0062;0061 05AE 0300 A8E5 0315 0062;00E0 05AE A8E5 0315 0062;0061 05AE 0300 A8E5 0315 0062; +0061 A8E5 0315 0300 05AE 0062;0061 05AE A8E5 0300 0315 0062;0061 05AE A8E5 0300 0315 0062;0061 05AE A8E5 0300 0315 0062;0061 05AE A8E5 0300 0315 0062; +0061 0315 0300 05AE A8E6 0062;00E0 05AE A8E6 0315 0062;0061 05AE 0300 A8E6 0315 0062;00E0 05AE A8E6 0315 0062;0061 05AE 0300 A8E6 0315 0062; +0061 A8E6 0315 0300 05AE 0062;0061 05AE A8E6 0300 0315 0062;0061 05AE A8E6 0300 0315 0062;0061 05AE A8E6 0300 0315 0062;0061 05AE A8E6 0300 0315 0062; +0061 0315 0300 05AE A8E7 0062;00E0 05AE A8E7 0315 0062;0061 05AE 0300 A8E7 0315 0062;00E0 05AE A8E7 0315 0062;0061 05AE 0300 A8E7 0315 0062; +0061 A8E7 0315 0300 05AE 0062;0061 05AE A8E7 0300 0315 0062;0061 05AE A8E7 0300 0315 0062;0061 05AE A8E7 0300 0315 0062;0061 05AE A8E7 0300 0315 0062; +0061 0315 0300 05AE A8E8 0062;00E0 05AE A8E8 0315 0062;0061 05AE 0300 A8E8 0315 0062;00E0 05AE A8E8 0315 0062;0061 05AE 0300 A8E8 0315 0062; +0061 A8E8 0315 0300 05AE 0062;0061 05AE A8E8 0300 0315 0062;0061 05AE A8E8 0300 0315 0062;0061 05AE A8E8 0300 0315 0062;0061 05AE A8E8 0300 0315 0062; +0061 0315 0300 05AE A8E9 0062;00E0 05AE A8E9 0315 0062;0061 05AE 0300 A8E9 0315 0062;00E0 05AE A8E9 0315 0062;0061 05AE 0300 A8E9 0315 0062; +0061 A8E9 0315 0300 05AE 0062;0061 05AE A8E9 0300 0315 0062;0061 05AE A8E9 0300 0315 0062;0061 05AE A8E9 0300 0315 0062;0061 05AE A8E9 0300 0315 0062; +0061 0315 0300 05AE A8EA 0062;00E0 05AE A8EA 0315 0062;0061 05AE 0300 A8EA 0315 0062;00E0 05AE A8EA 0315 0062;0061 05AE 0300 A8EA 0315 0062; +0061 A8EA 0315 0300 05AE 0062;0061 05AE A8EA 0300 0315 0062;0061 05AE A8EA 0300 0315 0062;0061 05AE A8EA 0300 0315 0062;0061 05AE A8EA 0300 0315 0062; +0061 0315 0300 05AE A8EB 0062;00E0 05AE A8EB 0315 0062;0061 05AE 0300 A8EB 0315 0062;00E0 05AE A8EB 0315 0062;0061 05AE 0300 A8EB 0315 0062; +0061 A8EB 0315 0300 05AE 0062;0061 05AE A8EB 0300 0315 0062;0061 05AE A8EB 0300 0315 0062;0061 05AE A8EB 0300 0315 0062;0061 05AE A8EB 0300 0315 0062; +0061 0315 0300 05AE A8EC 0062;00E0 05AE A8EC 0315 0062;0061 05AE 0300 A8EC 0315 0062;00E0 05AE A8EC 0315 0062;0061 05AE 0300 A8EC 0315 0062; +0061 A8EC 0315 0300 05AE 0062;0061 05AE A8EC 0300 0315 0062;0061 05AE A8EC 0300 0315 0062;0061 05AE A8EC 0300 0315 0062;0061 05AE A8EC 0300 0315 0062; +0061 0315 0300 05AE A8ED 0062;00E0 05AE A8ED 0315 0062;0061 05AE 0300 A8ED 0315 0062;00E0 05AE A8ED 0315 0062;0061 05AE 0300 A8ED 0315 0062; +0061 A8ED 0315 0300 05AE 0062;0061 05AE A8ED 0300 0315 0062;0061 05AE A8ED 0300 0315 0062;0061 05AE A8ED 0300 0315 0062;0061 05AE A8ED 0300 0315 0062; +0061 0315 0300 05AE A8EE 0062;00E0 05AE A8EE 0315 0062;0061 05AE 0300 A8EE 0315 0062;00E0 05AE A8EE 0315 0062;0061 05AE 0300 A8EE 0315 0062; +0061 A8EE 0315 0300 05AE 0062;0061 05AE A8EE 0300 0315 0062;0061 05AE A8EE 0300 0315 0062;0061 05AE A8EE 0300 0315 0062;0061 05AE A8EE 0300 0315 0062; +0061 0315 0300 05AE A8EF 0062;00E0 05AE A8EF 0315 0062;0061 05AE 0300 A8EF 0315 0062;00E0 05AE A8EF 0315 0062;0061 05AE 0300 A8EF 0315 0062; +0061 A8EF 0315 0300 05AE 0062;0061 05AE A8EF 0300 0315 0062;0061 05AE A8EF 0300 0315 0062;0061 05AE A8EF 0300 0315 0062;0061 05AE A8EF 0300 0315 0062; +0061 0315 0300 05AE A8F0 0062;00E0 05AE A8F0 0315 0062;0061 05AE 0300 A8F0 0315 0062;00E0 05AE A8F0 0315 0062;0061 05AE 0300 A8F0 0315 0062; +0061 A8F0 0315 0300 05AE 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062; +0061 0315 0300 05AE A8F1 0062;00E0 05AE A8F1 0315 0062;0061 05AE 0300 A8F1 0315 0062;00E0 05AE A8F1 0315 0062;0061 05AE 0300 A8F1 0315 0062; +0061 A8F1 0315 0300 05AE 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062; +0061 059A 0316 302A A92B 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062; +0061 A92B 059A 0316 302A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062; +0061 059A 0316 302A A92C 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062; +0061 A92C 059A 0316 302A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062; +0061 059A 0316 302A A92D 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062; +0061 A92D 059A 0316 302A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062; +0061 05B0 094D 3099 A953 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062; +0061 A953 05B0 094D 3099 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062; +0061 3099 093C 0334 A9B3 0062;0061 0334 093C A9B3 3099 0062;0061 0334 093C A9B3 3099 0062;0061 0334 093C A9B3 3099 0062;0061 0334 093C A9B3 3099 0062; +0061 A9B3 3099 093C 0334 0062;0061 0334 A9B3 093C 3099 0062;0061 0334 A9B3 093C 3099 0062;0061 0334 A9B3 093C 3099 0062;0061 0334 A9B3 093C 3099 0062; +0061 05B0 094D 3099 A9C0 0062;0061 3099 094D A9C0 05B0 0062;0061 3099 094D A9C0 05B0 0062;0061 3099 094D A9C0 05B0 0062;0061 3099 094D A9C0 05B0 0062; +0061 A9C0 05B0 094D 3099 0062;0061 3099 A9C0 094D 05B0 0062;0061 3099 A9C0 094D 05B0 0062;0061 3099 A9C0 094D 05B0 0062;0061 3099 A9C0 094D 05B0 0062; +0061 0315 0300 05AE AAB0 0062;00E0 05AE AAB0 0315 0062;0061 05AE 0300 AAB0 0315 0062;00E0 05AE AAB0 0315 0062;0061 05AE 0300 AAB0 0315 0062; +0061 AAB0 0315 0300 05AE 0062;0061 05AE AAB0 0300 0315 0062;0061 05AE AAB0 0300 0315 0062;0061 05AE AAB0 0300 0315 0062;0061 05AE AAB0 0300 0315 0062; +0061 0315 0300 05AE AAB2 0062;00E0 05AE AAB2 0315 0062;0061 05AE 0300 AAB2 0315 0062;00E0 05AE AAB2 0315 0062;0061 05AE 0300 AAB2 0315 0062; +0061 AAB2 0315 0300 05AE 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062; +0061 0315 0300 05AE AAB3 0062;00E0 05AE AAB3 0315 0062;0061 05AE 0300 AAB3 0315 0062;00E0 05AE AAB3 0315 0062;0061 05AE 0300 AAB3 0315 0062; +0061 AAB3 0315 0300 05AE 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062; +0061 059A 0316 302A AAB4 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062; +0061 AAB4 059A 0316 302A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062; +0061 0315 0300 05AE AAB7 0062;00E0 05AE AAB7 0315 0062;0061 05AE 0300 AAB7 0315 0062;00E0 05AE AAB7 0315 0062;0061 05AE 0300 AAB7 0315 0062; +0061 AAB7 0315 0300 05AE 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062; +0061 0315 0300 05AE AAB8 0062;00E0 05AE AAB8 0315 0062;0061 05AE 0300 AAB8 0315 0062;00E0 05AE AAB8 0315 0062;0061 05AE 0300 AAB8 0315 0062; +0061 AAB8 0315 0300 05AE 0062;0061 05AE AAB8 0300 0315 0062;0061 05AE AAB8 0300 0315 0062;0061 05AE AAB8 0300 0315 0062;0061 05AE AAB8 0300 0315 0062; +0061 0315 0300 05AE AABE 0062;00E0 05AE AABE 0315 0062;0061 05AE 0300 AABE 0315 0062;00E0 05AE AABE 0315 0062;0061 05AE 0300 AABE 0315 0062; +0061 AABE 0315 0300 05AE 0062;0061 05AE AABE 0300 0315 0062;0061 05AE AABE 0300 0315 0062;0061 05AE AABE 0300 0315 0062;0061 05AE AABE 0300 0315 0062; +0061 0315 0300 05AE AABF 0062;00E0 05AE AABF 0315 0062;0061 05AE 0300 AABF 0315 0062;00E0 05AE AABF 0315 0062;0061 05AE 0300 AABF 0315 0062; +0061 AABF 0315 0300 05AE 0062;0061 05AE AABF 0300 0315 0062;0061 05AE AABF 0300 0315 0062;0061 05AE AABF 0300 0315 0062;0061 05AE AABF 0300 0315 0062; +0061 0315 0300 05AE AAC1 0062;00E0 05AE AAC1 0315 0062;0061 05AE 0300 AAC1 0315 0062;00E0 05AE AAC1 0315 0062;0061 05AE 0300 AAC1 0315 0062; +0061 AAC1 0315 0300 05AE 0062;0061 05AE AAC1 0300 0315 0062;0061 05AE AAC1 0300 0315 0062;0061 05AE AAC1 0300 0315 0062;0061 05AE AAC1 0300 0315 0062; +0061 05B0 094D 3099 AAF6 0062;0061 3099 094D AAF6 05B0 0062;0061 3099 094D AAF6 05B0 0062;0061 3099 094D AAF6 05B0 0062;0061 3099 094D AAF6 05B0 0062; +0061 AAF6 05B0 094D 3099 0062;0061 3099 AAF6 094D 05B0 0062;0061 3099 AAF6 094D 05B0 0062;0061 3099 AAF6 094D 05B0 0062;0061 3099 AAF6 094D 05B0 0062; +0061 05B0 094D 3099 ABED 0062;0061 3099 094D ABED 05B0 0062;0061 3099 094D ABED 05B0 0062;0061 3099 094D ABED 05B0 0062;0061 3099 094D ABED 05B0 0062; +0061 ABED 05B0 094D 3099 0062;0061 3099 ABED 094D 05B0 0062;0061 3099 ABED 094D 05B0 0062;0061 3099 ABED 094D 05B0 0062;0061 3099 ABED 094D 05B0 0062; +0061 064B FB1E 05C2 FB1E 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062; +0061 FB1E 064B FB1E 05C2 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062; +0061 0315 0300 05AE FE20 0062;00E0 05AE FE20 0315 0062;0061 05AE 0300 FE20 0315 0062;00E0 05AE FE20 0315 0062;0061 05AE 0300 FE20 0315 0062; +0061 FE20 0315 0300 05AE 0062;0061 05AE FE20 0300 0315 0062;0061 05AE FE20 0300 0315 0062;0061 05AE FE20 0300 0315 0062;0061 05AE FE20 0300 0315 0062; +0061 0315 0300 05AE FE21 0062;00E0 05AE FE21 0315 0062;0061 05AE 0300 FE21 0315 0062;00E0 05AE FE21 0315 0062;0061 05AE 0300 FE21 0315 0062; +0061 FE21 0315 0300 05AE 0062;0061 05AE FE21 0300 0315 0062;0061 05AE FE21 0300 0315 0062;0061 05AE FE21 0300 0315 0062;0061 05AE FE21 0300 0315 0062; +0061 0315 0300 05AE FE22 0062;00E0 05AE FE22 0315 0062;0061 05AE 0300 FE22 0315 0062;00E0 05AE FE22 0315 0062;0061 05AE 0300 FE22 0315 0062; +0061 FE22 0315 0300 05AE 0062;0061 05AE FE22 0300 0315 0062;0061 05AE FE22 0300 0315 0062;0061 05AE FE22 0300 0315 0062;0061 05AE FE22 0300 0315 0062; +0061 0315 0300 05AE FE23 0062;00E0 05AE FE23 0315 0062;0061 05AE 0300 FE23 0315 0062;00E0 05AE FE23 0315 0062;0061 05AE 0300 FE23 0315 0062; +0061 FE23 0315 0300 05AE 0062;0061 05AE FE23 0300 0315 0062;0061 05AE FE23 0300 0315 0062;0061 05AE FE23 0300 0315 0062;0061 05AE FE23 0300 0315 0062; +0061 0315 0300 05AE FE24 0062;00E0 05AE FE24 0315 0062;0061 05AE 0300 FE24 0315 0062;00E0 05AE FE24 0315 0062;0061 05AE 0300 FE24 0315 0062; +0061 FE24 0315 0300 05AE 0062;0061 05AE FE24 0300 0315 0062;0061 05AE FE24 0300 0315 0062;0061 05AE FE24 0300 0315 0062;0061 05AE FE24 0300 0315 0062; +0061 0315 0300 05AE FE25 0062;00E0 05AE FE25 0315 0062;0061 05AE 0300 FE25 0315 0062;00E0 05AE FE25 0315 0062;0061 05AE 0300 FE25 0315 0062; +0061 FE25 0315 0300 05AE 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062; +0061 0315 0300 05AE FE26 0062;00E0 05AE FE26 0315 0062;0061 05AE 0300 FE26 0315 0062;00E0 05AE FE26 0315 0062;0061 05AE 0300 FE26 0315 0062; +0061 FE26 0315 0300 05AE 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062; +0061 059A 0316 302A FE27 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062; +0061 FE27 059A 0316 302A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062; +0061 059A 0316 302A FE28 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062; +0061 FE28 059A 0316 302A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062; +0061 059A 0316 302A FE29 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062; +0061 FE29 059A 0316 302A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062; +0061 059A 0316 302A FE2A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062; +0061 FE2A 059A 0316 302A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062; +0061 059A 0316 302A FE2B 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062; +0061 FE2B 059A 0316 302A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062; +0061 059A 0316 302A FE2C 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062; +0061 FE2C 059A 0316 302A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062; +0061 059A 0316 302A FE2D 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062; +0061 FE2D 059A 0316 302A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062; +0061 0315 0300 05AE FE2E 0062;00E0 05AE FE2E 0315 0062;0061 05AE 0300 FE2E 0315 0062;00E0 05AE FE2E 0315 0062;0061 05AE 0300 FE2E 0315 0062; +0061 FE2E 0315 0300 05AE 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062; +0061 0315 0300 05AE FE2F 0062;00E0 05AE FE2F 0315 0062;0061 05AE 0300 FE2F 0315 0062;00E0 05AE FE2F 0315 0062;0061 05AE 0300 FE2F 0315 0062; +0061 FE2F 0315 0300 05AE 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062; +0061 059A 0316 302A 101FD 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062; +0061 101FD 059A 0316 302A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062; +0061 059A 0316 302A 102E0 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062; +0061 102E0 059A 0316 302A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062; +0061 0315 0300 05AE 10376 0062;00E0 05AE 10376 0315 0062;0061 05AE 0300 10376 0315 0062;00E0 05AE 10376 0315 0062;0061 05AE 0300 10376 0315 0062; +0061 10376 0315 0300 05AE 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062; +0061 0315 0300 05AE 10377 0062;00E0 05AE 10377 0315 0062;0061 05AE 0300 10377 0315 0062;00E0 05AE 10377 0315 0062;0061 05AE 0300 10377 0315 0062; +0061 10377 0315 0300 05AE 0062;0061 05AE 10377 0300 0315 0062;0061 05AE 10377 0300 0315 0062;0061 05AE 10377 0300 0315 0062;0061 05AE 10377 0300 0315 0062; +0061 0315 0300 05AE 10378 0062;00E0 05AE 10378 0315 0062;0061 05AE 0300 10378 0315 0062;00E0 05AE 10378 0315 0062;0061 05AE 0300 10378 0315 0062; +0061 10378 0315 0300 05AE 0062;0061 05AE 10378 0300 0315 0062;0061 05AE 10378 0300 0315 0062;0061 05AE 10378 0300 0315 0062;0061 05AE 10378 0300 0315 0062; +0061 0315 0300 05AE 10379 0062;00E0 05AE 10379 0315 0062;0061 05AE 0300 10379 0315 0062;00E0 05AE 10379 0315 0062;0061 05AE 0300 10379 0315 0062; +0061 10379 0315 0300 05AE 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062; +0061 0315 0300 05AE 1037A 0062;00E0 05AE 1037A 0315 0062;0061 05AE 0300 1037A 0315 0062;00E0 05AE 1037A 0315 0062;0061 05AE 0300 1037A 0315 0062; +0061 1037A 0315 0300 05AE 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062; +0061 059A 0316 302A 10A0D 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062; +0061 10A0D 059A 0316 302A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062; +0061 0315 0300 05AE 10A0F 0062;00E0 05AE 10A0F 0315 0062;0061 05AE 0300 10A0F 0315 0062;00E0 05AE 10A0F 0315 0062;0061 05AE 0300 10A0F 0315 0062; +0061 10A0F 0315 0300 05AE 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062; +0061 0315 0300 05AE 10A38 0062;00E0 05AE 10A38 0315 0062;0061 05AE 0300 10A38 0315 0062;00E0 05AE 10A38 0315 0062;0061 05AE 0300 10A38 0315 0062; +0061 10A38 0315 0300 05AE 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062; +0061 093C 0334 10A39 0062;0061 0334 10A39 093C 0062;0061 0334 10A39 093C 0062;0061 0334 10A39 093C 0062;0061 0334 10A39 093C 0062; +0061 10A39 093C 0334 0062;0061 10A39 0334 093C 0062;0061 10A39 0334 093C 0062;0061 10A39 0334 093C 0062;0061 10A39 0334 093C 0062; +0061 059A 0316 302A 10A3A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062; +0061 10A3A 059A 0316 302A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062; +0061 05B0 094D 3099 10A3F 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062; +0061 10A3F 05B0 094D 3099 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062; +0061 0315 0300 05AE 10AE5 0062;00E0 05AE 10AE5 0315 0062;0061 05AE 0300 10AE5 0315 0062;00E0 05AE 10AE5 0315 0062;0061 05AE 0300 10AE5 0315 0062; +0061 10AE5 0315 0300 05AE 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062; +0061 059A 0316 302A 10AE6 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062; +0061 10AE6 059A 0316 302A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062; +0061 0315 0300 05AE 10D24 0062;00E0 05AE 10D24 0315 0062;0061 05AE 0300 10D24 0315 0062;00E0 05AE 10D24 0315 0062;0061 05AE 0300 10D24 0315 0062; +0061 10D24 0315 0300 05AE 0062;0061 05AE 10D24 0300 0315 0062;0061 05AE 10D24 0300 0315 0062;0061 05AE 10D24 0300 0315 0062;0061 05AE 10D24 0300 0315 0062; +0061 0315 0300 05AE 10D25 0062;00E0 05AE 10D25 0315 0062;0061 05AE 0300 10D25 0315 0062;00E0 05AE 10D25 0315 0062;0061 05AE 0300 10D25 0315 0062; +0061 10D25 0315 0300 05AE 0062;0061 05AE 10D25 0300 0315 0062;0061 05AE 10D25 0300 0315 0062;0061 05AE 10D25 0300 0315 0062;0061 05AE 10D25 0300 0315 0062; +0061 0315 0300 05AE 10D26 0062;00E0 05AE 10D26 0315 0062;0061 05AE 0300 10D26 0315 0062;00E0 05AE 10D26 0315 0062;0061 05AE 0300 10D26 0315 0062; +0061 10D26 0315 0300 05AE 0062;0061 05AE 10D26 0300 0315 0062;0061 05AE 10D26 0300 0315 0062;0061 05AE 10D26 0300 0315 0062;0061 05AE 10D26 0300 0315 0062; +0061 0315 0300 05AE 10D27 0062;00E0 05AE 10D27 0315 0062;0061 05AE 0300 10D27 0315 0062;00E0 05AE 10D27 0315 0062;0061 05AE 0300 10D27 0315 0062; +0061 10D27 0315 0300 05AE 0062;0061 05AE 10D27 0300 0315 0062;0061 05AE 10D27 0300 0315 0062;0061 05AE 10D27 0300 0315 0062;0061 05AE 10D27 0300 0315 0062; +0061 059A 0316 302A 10F46 0062;0061 302A 0316 10F46 059A 0062;0061 302A 0316 10F46 059A 0062;0061 302A 0316 10F46 059A 0062;0061 302A 0316 10F46 059A 0062; +0061 10F46 059A 0316 302A 0062;0061 302A 10F46 0316 059A 0062;0061 302A 10F46 0316 059A 0062;0061 302A 10F46 0316 059A 0062;0061 302A 10F46 0316 059A 0062; +0061 059A 0316 302A 10F47 0062;0061 302A 0316 10F47 059A 0062;0061 302A 0316 10F47 059A 0062;0061 302A 0316 10F47 059A 0062;0061 302A 0316 10F47 059A 0062; +0061 10F47 059A 0316 302A 0062;0061 302A 10F47 0316 059A 0062;0061 302A 10F47 0316 059A 0062;0061 302A 10F47 0316 059A 0062;0061 302A 10F47 0316 059A 0062; +0061 0315 0300 05AE 10F48 0062;00E0 05AE 10F48 0315 0062;0061 05AE 0300 10F48 0315 0062;00E0 05AE 10F48 0315 0062;0061 05AE 0300 10F48 0315 0062; +0061 10F48 0315 0300 05AE 0062;0061 05AE 10F48 0300 0315 0062;0061 05AE 10F48 0300 0315 0062;0061 05AE 10F48 0300 0315 0062;0061 05AE 10F48 0300 0315 0062; +0061 0315 0300 05AE 10F49 0062;00E0 05AE 10F49 0315 0062;0061 05AE 0300 10F49 0315 0062;00E0 05AE 10F49 0315 0062;0061 05AE 0300 10F49 0315 0062; +0061 10F49 0315 0300 05AE 0062;0061 05AE 10F49 0300 0315 0062;0061 05AE 10F49 0300 0315 0062;0061 05AE 10F49 0300 0315 0062;0061 05AE 10F49 0300 0315 0062; +0061 0315 0300 05AE 10F4A 0062;00E0 05AE 10F4A 0315 0062;0061 05AE 0300 10F4A 0315 0062;00E0 05AE 10F4A 0315 0062;0061 05AE 0300 10F4A 0315 0062; +0061 10F4A 0315 0300 05AE 0062;0061 05AE 10F4A 0300 0315 0062;0061 05AE 10F4A 0300 0315 0062;0061 05AE 10F4A 0300 0315 0062;0061 05AE 10F4A 0300 0315 0062; +0061 059A 0316 302A 10F4B 0062;0061 302A 0316 10F4B 059A 0062;0061 302A 0316 10F4B 059A 0062;0061 302A 0316 10F4B 059A 0062;0061 302A 0316 10F4B 059A 0062; +0061 10F4B 059A 0316 302A 0062;0061 302A 10F4B 0316 059A 0062;0061 302A 10F4B 0316 059A 0062;0061 302A 10F4B 0316 059A 0062;0061 302A 10F4B 0316 059A 0062; +0061 0315 0300 05AE 10F4C 0062;00E0 05AE 10F4C 0315 0062;0061 05AE 0300 10F4C 0315 0062;00E0 05AE 10F4C 0315 0062;0061 05AE 0300 10F4C 0315 0062; +0061 10F4C 0315 0300 05AE 0062;0061 05AE 10F4C 0300 0315 0062;0061 05AE 10F4C 0300 0315 0062;0061 05AE 10F4C 0300 0315 0062;0061 05AE 10F4C 0300 0315 0062; +0061 059A 0316 302A 10F4D 0062;0061 302A 0316 10F4D 059A 0062;0061 302A 0316 10F4D 059A 0062;0061 302A 0316 10F4D 059A 0062;0061 302A 0316 10F4D 059A 0062; +0061 10F4D 059A 0316 302A 0062;0061 302A 10F4D 0316 059A 0062;0061 302A 10F4D 0316 059A 0062;0061 302A 10F4D 0316 059A 0062;0061 302A 10F4D 0316 059A 0062; +0061 059A 0316 302A 10F4E 0062;0061 302A 0316 10F4E 059A 0062;0061 302A 0316 10F4E 059A 0062;0061 302A 0316 10F4E 059A 0062;0061 302A 0316 10F4E 059A 0062; +0061 10F4E 059A 0316 302A 0062;0061 302A 10F4E 0316 059A 0062;0061 302A 10F4E 0316 059A 0062;0061 302A 10F4E 0316 059A 0062;0061 302A 10F4E 0316 059A 0062; +0061 059A 0316 302A 10F4F 0062;0061 302A 0316 10F4F 059A 0062;0061 302A 0316 10F4F 059A 0062;0061 302A 0316 10F4F 059A 0062;0061 302A 0316 10F4F 059A 0062; +0061 10F4F 059A 0316 302A 0062;0061 302A 10F4F 0316 059A 0062;0061 302A 10F4F 0316 059A 0062;0061 302A 10F4F 0316 059A 0062;0061 302A 10F4F 0316 059A 0062; +0061 059A 0316 302A 10F50 0062;0061 302A 0316 10F50 059A 0062;0061 302A 0316 10F50 059A 0062;0061 302A 0316 10F50 059A 0062;0061 302A 0316 10F50 059A 0062; +0061 10F50 059A 0316 302A 0062;0061 302A 10F50 0316 059A 0062;0061 302A 10F50 0316 059A 0062;0061 302A 10F50 0316 059A 0062;0061 302A 10F50 0316 059A 0062; +0061 05B0 094D 3099 11046 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062; +0061 11046 05B0 094D 3099 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062; +0061 05B0 094D 3099 1107F 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062; +0061 1107F 05B0 094D 3099 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062; +0061 05B0 094D 3099 110B9 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062; +0061 110B9 05B0 094D 3099 0062;0061 3099 110B9 094D 05B0 0062;0061 3099 110B9 094D 05B0 0062;0061 3099 110B9 094D 05B0 0062;0061 3099 110B9 094D 05B0 0062; +0061 3099 093C 0334 110BA 0062;0061 0334 093C 110BA 3099 0062;0061 0334 093C 110BA 3099 0062;0061 0334 093C 110BA 3099 0062;0061 0334 093C 110BA 3099 0062; +0061 110BA 3099 093C 0334 0062;0061 0334 110BA 093C 3099 0062;0061 0334 110BA 093C 3099 0062;0061 0334 110BA 093C 3099 0062;0061 0334 110BA 093C 3099 0062; +0061 0315 0300 05AE 11100 0062;00E0 05AE 11100 0315 0062;0061 05AE 0300 11100 0315 0062;00E0 05AE 11100 0315 0062;0061 05AE 0300 11100 0315 0062; +0061 11100 0315 0300 05AE 0062;0061 05AE 11100 0300 0315 0062;0061 05AE 11100 0300 0315 0062;0061 05AE 11100 0300 0315 0062;0061 05AE 11100 0300 0315 0062; +0061 0315 0300 05AE 11101 0062;00E0 05AE 11101 0315 0062;0061 05AE 0300 11101 0315 0062;00E0 05AE 11101 0315 0062;0061 05AE 0300 11101 0315 0062; +0061 11101 0315 0300 05AE 0062;0061 05AE 11101 0300 0315 0062;0061 05AE 11101 0300 0315 0062;0061 05AE 11101 0300 0315 0062;0061 05AE 11101 0300 0315 0062; +0061 0315 0300 05AE 11102 0062;00E0 05AE 11102 0315 0062;0061 05AE 0300 11102 0315 0062;00E0 05AE 11102 0315 0062;0061 05AE 0300 11102 0315 0062; +0061 11102 0315 0300 05AE 0062;0061 05AE 11102 0300 0315 0062;0061 05AE 11102 0300 0315 0062;0061 05AE 11102 0300 0315 0062;0061 05AE 11102 0300 0315 0062; +0061 05B0 094D 3099 11133 0062;0061 3099 094D 11133 05B0 0062;0061 3099 094D 11133 05B0 0062;0061 3099 094D 11133 05B0 0062;0061 3099 094D 11133 05B0 0062; +0061 11133 05B0 094D 3099 0062;0061 3099 11133 094D 05B0 0062;0061 3099 11133 094D 05B0 0062;0061 3099 11133 094D 05B0 0062;0061 3099 11133 094D 05B0 0062; +0061 05B0 094D 3099 11134 0062;0061 3099 094D 11134 05B0 0062;0061 3099 094D 11134 05B0 0062;0061 3099 094D 11134 05B0 0062;0061 3099 094D 11134 05B0 0062; +0061 11134 05B0 094D 3099 0062;0061 3099 11134 094D 05B0 0062;0061 3099 11134 094D 05B0 0062;0061 3099 11134 094D 05B0 0062;0061 3099 11134 094D 05B0 0062; +0061 3099 093C 0334 11173 0062;0061 0334 093C 11173 3099 0062;0061 0334 093C 11173 3099 0062;0061 0334 093C 11173 3099 0062;0061 0334 093C 11173 3099 0062; +0061 11173 3099 093C 0334 0062;0061 0334 11173 093C 3099 0062;0061 0334 11173 093C 3099 0062;0061 0334 11173 093C 3099 0062;0061 0334 11173 093C 3099 0062; +0061 05B0 094D 3099 111C0 0062;0061 3099 094D 111C0 05B0 0062;0061 3099 094D 111C0 05B0 0062;0061 3099 094D 111C0 05B0 0062;0061 3099 094D 111C0 05B0 0062; +0061 111C0 05B0 094D 3099 0062;0061 3099 111C0 094D 05B0 0062;0061 3099 111C0 094D 05B0 0062;0061 3099 111C0 094D 05B0 0062;0061 3099 111C0 094D 05B0 0062; +0061 3099 093C 0334 111CA 0062;0061 0334 093C 111CA 3099 0062;0061 0334 093C 111CA 3099 0062;0061 0334 093C 111CA 3099 0062;0061 0334 093C 111CA 3099 0062; +0061 111CA 3099 093C 0334 0062;0061 0334 111CA 093C 3099 0062;0061 0334 111CA 093C 3099 0062;0061 0334 111CA 093C 3099 0062;0061 0334 111CA 093C 3099 0062; +0061 05B0 094D 3099 11235 0062;0061 3099 094D 11235 05B0 0062;0061 3099 094D 11235 05B0 0062;0061 3099 094D 11235 05B0 0062;0061 3099 094D 11235 05B0 0062; +0061 11235 05B0 094D 3099 0062;0061 3099 11235 094D 05B0 0062;0061 3099 11235 094D 05B0 0062;0061 3099 11235 094D 05B0 0062;0061 3099 11235 094D 05B0 0062; +0061 3099 093C 0334 11236 0062;0061 0334 093C 11236 3099 0062;0061 0334 093C 11236 3099 0062;0061 0334 093C 11236 3099 0062;0061 0334 093C 11236 3099 0062; +0061 11236 3099 093C 0334 0062;0061 0334 11236 093C 3099 0062;0061 0334 11236 093C 3099 0062;0061 0334 11236 093C 3099 0062;0061 0334 11236 093C 3099 0062; +0061 3099 093C 0334 112E9 0062;0061 0334 093C 112E9 3099 0062;0061 0334 093C 112E9 3099 0062;0061 0334 093C 112E9 3099 0062;0061 0334 093C 112E9 3099 0062; +0061 112E9 3099 093C 0334 0062;0061 0334 112E9 093C 3099 0062;0061 0334 112E9 093C 3099 0062;0061 0334 112E9 093C 3099 0062;0061 0334 112E9 093C 3099 0062; +0061 05B0 094D 3099 112EA 0062;0061 3099 094D 112EA 05B0 0062;0061 3099 094D 112EA 05B0 0062;0061 3099 094D 112EA 05B0 0062;0061 3099 094D 112EA 05B0 0062; +0061 112EA 05B0 094D 3099 0062;0061 3099 112EA 094D 05B0 0062;0061 3099 112EA 094D 05B0 0062;0061 3099 112EA 094D 05B0 0062;0061 3099 112EA 094D 05B0 0062; +0061 3099 093C 0334 1133B 0062;0061 0334 093C 1133B 3099 0062;0061 0334 093C 1133B 3099 0062;0061 0334 093C 1133B 3099 0062;0061 0334 093C 1133B 3099 0062; +0061 1133B 3099 093C 0334 0062;0061 0334 1133B 093C 3099 0062;0061 0334 1133B 093C 3099 0062;0061 0334 1133B 093C 3099 0062;0061 0334 1133B 093C 3099 0062; +0061 3099 093C 0334 1133C 0062;0061 0334 093C 1133C 3099 0062;0061 0334 093C 1133C 3099 0062;0061 0334 093C 1133C 3099 0062;0061 0334 093C 1133C 3099 0062; +0061 1133C 3099 093C 0334 0062;0061 0334 1133C 093C 3099 0062;0061 0334 1133C 093C 3099 0062;0061 0334 1133C 093C 3099 0062;0061 0334 1133C 093C 3099 0062; +0061 05B0 094D 3099 1134D 0062;0061 3099 094D 1134D 05B0 0062;0061 3099 094D 1134D 05B0 0062;0061 3099 094D 1134D 05B0 0062;0061 3099 094D 1134D 05B0 0062; +0061 1134D 05B0 094D 3099 0062;0061 3099 1134D 094D 05B0 0062;0061 3099 1134D 094D 05B0 0062;0061 3099 1134D 094D 05B0 0062;0061 3099 1134D 094D 05B0 0062; +0061 0315 0300 05AE 11366 0062;00E0 05AE 11366 0315 0062;0061 05AE 0300 11366 0315 0062;00E0 05AE 11366 0315 0062;0061 05AE 0300 11366 0315 0062; +0061 11366 0315 0300 05AE 0062;0061 05AE 11366 0300 0315 0062;0061 05AE 11366 0300 0315 0062;0061 05AE 11366 0300 0315 0062;0061 05AE 11366 0300 0315 0062; +0061 0315 0300 05AE 11367 0062;00E0 05AE 11367 0315 0062;0061 05AE 0300 11367 0315 0062;00E0 05AE 11367 0315 0062;0061 05AE 0300 11367 0315 0062; +0061 11367 0315 0300 05AE 0062;0061 05AE 11367 0300 0315 0062;0061 05AE 11367 0300 0315 0062;0061 05AE 11367 0300 0315 0062;0061 05AE 11367 0300 0315 0062; +0061 0315 0300 05AE 11368 0062;00E0 05AE 11368 0315 0062;0061 05AE 0300 11368 0315 0062;00E0 05AE 11368 0315 0062;0061 05AE 0300 11368 0315 0062; +0061 11368 0315 0300 05AE 0062;0061 05AE 11368 0300 0315 0062;0061 05AE 11368 0300 0315 0062;0061 05AE 11368 0300 0315 0062;0061 05AE 11368 0300 0315 0062; +0061 0315 0300 05AE 11369 0062;00E0 05AE 11369 0315 0062;0061 05AE 0300 11369 0315 0062;00E0 05AE 11369 0315 0062;0061 05AE 0300 11369 0315 0062; +0061 11369 0315 0300 05AE 0062;0061 05AE 11369 0300 0315 0062;0061 05AE 11369 0300 0315 0062;0061 05AE 11369 0300 0315 0062;0061 05AE 11369 0300 0315 0062; +0061 0315 0300 05AE 1136A 0062;00E0 05AE 1136A 0315 0062;0061 05AE 0300 1136A 0315 0062;00E0 05AE 1136A 0315 0062;0061 05AE 0300 1136A 0315 0062; +0061 1136A 0315 0300 05AE 0062;0061 05AE 1136A 0300 0315 0062;0061 05AE 1136A 0300 0315 0062;0061 05AE 1136A 0300 0315 0062;0061 05AE 1136A 0300 0315 0062; +0061 0315 0300 05AE 1136B 0062;00E0 05AE 1136B 0315 0062;0061 05AE 0300 1136B 0315 0062;00E0 05AE 1136B 0315 0062;0061 05AE 0300 1136B 0315 0062; +0061 1136B 0315 0300 05AE 0062;0061 05AE 1136B 0300 0315 0062;0061 05AE 1136B 0300 0315 0062;0061 05AE 1136B 0300 0315 0062;0061 05AE 1136B 0300 0315 0062; +0061 0315 0300 05AE 1136C 0062;00E0 05AE 1136C 0315 0062;0061 05AE 0300 1136C 0315 0062;00E0 05AE 1136C 0315 0062;0061 05AE 0300 1136C 0315 0062; +0061 1136C 0315 0300 05AE 0062;0061 05AE 1136C 0300 0315 0062;0061 05AE 1136C 0300 0315 0062;0061 05AE 1136C 0300 0315 0062;0061 05AE 1136C 0300 0315 0062; +0061 0315 0300 05AE 11370 0062;00E0 05AE 11370 0315 0062;0061 05AE 0300 11370 0315 0062;00E0 05AE 11370 0315 0062;0061 05AE 0300 11370 0315 0062; +0061 11370 0315 0300 05AE 0062;0061 05AE 11370 0300 0315 0062;0061 05AE 11370 0300 0315 0062;0061 05AE 11370 0300 0315 0062;0061 05AE 11370 0300 0315 0062; +0061 0315 0300 05AE 11371 0062;00E0 05AE 11371 0315 0062;0061 05AE 0300 11371 0315 0062;00E0 05AE 11371 0315 0062;0061 05AE 0300 11371 0315 0062; +0061 11371 0315 0300 05AE 0062;0061 05AE 11371 0300 0315 0062;0061 05AE 11371 0300 0315 0062;0061 05AE 11371 0300 0315 0062;0061 05AE 11371 0300 0315 0062; +0061 0315 0300 05AE 11372 0062;00E0 05AE 11372 0315 0062;0061 05AE 0300 11372 0315 0062;00E0 05AE 11372 0315 0062;0061 05AE 0300 11372 0315 0062; +0061 11372 0315 0300 05AE 0062;0061 05AE 11372 0300 0315 0062;0061 05AE 11372 0300 0315 0062;0061 05AE 11372 0300 0315 0062;0061 05AE 11372 0300 0315 0062; +0061 0315 0300 05AE 11373 0062;00E0 05AE 11373 0315 0062;0061 05AE 0300 11373 0315 0062;00E0 05AE 11373 0315 0062;0061 05AE 0300 11373 0315 0062; +0061 11373 0315 0300 05AE 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062; +0061 0315 0300 05AE 11374 0062;00E0 05AE 11374 0315 0062;0061 05AE 0300 11374 0315 0062;00E0 05AE 11374 0315 0062;0061 05AE 0300 11374 0315 0062; +0061 11374 0315 0300 05AE 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062; +0061 05B0 094D 3099 11442 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062; +0061 11442 05B0 094D 3099 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062; +0061 3099 093C 0334 11446 0062;0061 0334 093C 11446 3099 0062;0061 0334 093C 11446 3099 0062;0061 0334 093C 11446 3099 0062;0061 0334 093C 11446 3099 0062; +0061 11446 3099 093C 0334 0062;0061 0334 11446 093C 3099 0062;0061 0334 11446 093C 3099 0062;0061 0334 11446 093C 3099 0062;0061 0334 11446 093C 3099 0062; +0061 0315 0300 05AE 1145E 0062;00E0 05AE 1145E 0315 0062;0061 05AE 0300 1145E 0315 0062;00E0 05AE 1145E 0315 0062;0061 05AE 0300 1145E 0315 0062; +0061 1145E 0315 0300 05AE 0062;0061 05AE 1145E 0300 0315 0062;0061 05AE 1145E 0300 0315 0062;0061 05AE 1145E 0300 0315 0062;0061 05AE 1145E 0300 0315 0062; +0061 05B0 094D 3099 114C2 0062;0061 3099 094D 114C2 05B0 0062;0061 3099 094D 114C2 05B0 0062;0061 3099 094D 114C2 05B0 0062;0061 3099 094D 114C2 05B0 0062; +0061 114C2 05B0 094D 3099 0062;0061 3099 114C2 094D 05B0 0062;0061 3099 114C2 094D 05B0 0062;0061 3099 114C2 094D 05B0 0062;0061 3099 114C2 094D 05B0 0062; +0061 3099 093C 0334 114C3 0062;0061 0334 093C 114C3 3099 0062;0061 0334 093C 114C3 3099 0062;0061 0334 093C 114C3 3099 0062;0061 0334 093C 114C3 3099 0062; +0061 114C3 3099 093C 0334 0062;0061 0334 114C3 093C 3099 0062;0061 0334 114C3 093C 3099 0062;0061 0334 114C3 093C 3099 0062;0061 0334 114C3 093C 3099 0062; +0061 05B0 094D 3099 115BF 0062;0061 3099 094D 115BF 05B0 0062;0061 3099 094D 115BF 05B0 0062;0061 3099 094D 115BF 05B0 0062;0061 3099 094D 115BF 05B0 0062; +0061 115BF 05B0 094D 3099 0062;0061 3099 115BF 094D 05B0 0062;0061 3099 115BF 094D 05B0 0062;0061 3099 115BF 094D 05B0 0062;0061 3099 115BF 094D 05B0 0062; +0061 3099 093C 0334 115C0 0062;0061 0334 093C 115C0 3099 0062;0061 0334 093C 115C0 3099 0062;0061 0334 093C 115C0 3099 0062;0061 0334 093C 115C0 3099 0062; +0061 115C0 3099 093C 0334 0062;0061 0334 115C0 093C 3099 0062;0061 0334 115C0 093C 3099 0062;0061 0334 115C0 093C 3099 0062;0061 0334 115C0 093C 3099 0062; +0061 05B0 094D 3099 1163F 0062;0061 3099 094D 1163F 05B0 0062;0061 3099 094D 1163F 05B0 0062;0061 3099 094D 1163F 05B0 0062;0061 3099 094D 1163F 05B0 0062; +0061 1163F 05B0 094D 3099 0062;0061 3099 1163F 094D 05B0 0062;0061 3099 1163F 094D 05B0 0062;0061 3099 1163F 094D 05B0 0062;0061 3099 1163F 094D 05B0 0062; +0061 05B0 094D 3099 116B6 0062;0061 3099 094D 116B6 05B0 0062;0061 3099 094D 116B6 05B0 0062;0061 3099 094D 116B6 05B0 0062;0061 3099 094D 116B6 05B0 0062; +0061 116B6 05B0 094D 3099 0062;0061 3099 116B6 094D 05B0 0062;0061 3099 116B6 094D 05B0 0062;0061 3099 116B6 094D 05B0 0062;0061 3099 116B6 094D 05B0 0062; +0061 3099 093C 0334 116B7 0062;0061 0334 093C 116B7 3099 0062;0061 0334 093C 116B7 3099 0062;0061 0334 093C 116B7 3099 0062;0061 0334 093C 116B7 3099 0062; +0061 116B7 3099 093C 0334 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062; +0061 05B0 094D 3099 1172B 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062; +0061 1172B 05B0 094D 3099 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062; +0061 05B0 094D 3099 11839 0062;0061 3099 094D 11839 05B0 0062;0061 3099 094D 11839 05B0 0062;0061 3099 094D 11839 05B0 0062;0061 3099 094D 11839 05B0 0062; +0061 11839 05B0 094D 3099 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062; +0061 3099 093C 0334 1183A 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062; +0061 1183A 3099 093C 0334 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062; +0061 05B0 094D 3099 11A34 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062; +0061 11A34 05B0 094D 3099 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062; +0061 05B0 094D 3099 11A47 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062; +0061 11A47 05B0 094D 3099 0062;0061 3099 11A47 094D 05B0 0062;0061 3099 11A47 094D 05B0 0062;0061 3099 11A47 094D 05B0 0062;0061 3099 11A47 094D 05B0 0062; +0061 05B0 094D 3099 11A99 0062;0061 3099 094D 11A99 05B0 0062;0061 3099 094D 11A99 05B0 0062;0061 3099 094D 11A99 05B0 0062;0061 3099 094D 11A99 05B0 0062; +0061 11A99 05B0 094D 3099 0062;0061 3099 11A99 094D 05B0 0062;0061 3099 11A99 094D 05B0 0062;0061 3099 11A99 094D 05B0 0062;0061 3099 11A99 094D 05B0 0062; +0061 05B0 094D 3099 11C3F 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062; +0061 11C3F 05B0 094D 3099 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062; +0061 3099 093C 0334 11D42 0062;0061 0334 093C 11D42 3099 0062;0061 0334 093C 11D42 3099 0062;0061 0334 093C 11D42 3099 0062;0061 0334 093C 11D42 3099 0062; +0061 11D42 3099 093C 0334 0062;0061 0334 11D42 093C 3099 0062;0061 0334 11D42 093C 3099 0062;0061 0334 11D42 093C 3099 0062;0061 0334 11D42 093C 3099 0062; +0061 05B0 094D 3099 11D44 0062;0061 3099 094D 11D44 05B0 0062;0061 3099 094D 11D44 05B0 0062;0061 3099 094D 11D44 05B0 0062;0061 3099 094D 11D44 05B0 0062; +0061 11D44 05B0 094D 3099 0062;0061 3099 11D44 094D 05B0 0062;0061 3099 11D44 094D 05B0 0062;0061 3099 11D44 094D 05B0 0062;0061 3099 11D44 094D 05B0 0062; +0061 05B0 094D 3099 11D45 0062;0061 3099 094D 11D45 05B0 0062;0061 3099 094D 11D45 05B0 0062;0061 3099 094D 11D45 05B0 0062;0061 3099 094D 11D45 05B0 0062; +0061 11D45 05B0 094D 3099 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062; +0061 05B0 094D 3099 11D97 0062;0061 3099 094D 11D97 05B0 0062;0061 3099 094D 11D97 05B0 0062;0061 3099 094D 11D97 05B0 0062;0061 3099 094D 11D97 05B0 0062; +0061 11D97 05B0 094D 3099 0062;0061 3099 11D97 094D 05B0 0062;0061 3099 11D97 094D 05B0 0062;0061 3099 11D97 094D 05B0 0062;0061 3099 11D97 094D 05B0 0062; +0061 093C 0334 16AF0 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062; +0061 16AF0 093C 0334 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062; +0061 093C 0334 16AF1 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062; +0061 16AF1 093C 0334 0062;0061 16AF1 0334 093C 0062;0061 16AF1 0334 093C 0062;0061 16AF1 0334 093C 0062;0061 16AF1 0334 093C 0062; +0061 093C 0334 16AF2 0062;0061 0334 16AF2 093C 0062;0061 0334 16AF2 093C 0062;0061 0334 16AF2 093C 0062;0061 0334 16AF2 093C 0062; +0061 16AF2 093C 0334 0062;0061 16AF2 0334 093C 0062;0061 16AF2 0334 093C 0062;0061 16AF2 0334 093C 0062;0061 16AF2 0334 093C 0062; +0061 093C 0334 16AF3 0062;0061 0334 16AF3 093C 0062;0061 0334 16AF3 093C 0062;0061 0334 16AF3 093C 0062;0061 0334 16AF3 093C 0062; +0061 16AF3 093C 0334 0062;0061 16AF3 0334 093C 0062;0061 16AF3 0334 093C 0062;0061 16AF3 0334 093C 0062;0061 16AF3 0334 093C 0062; +0061 093C 0334 16AF4 0062;0061 0334 16AF4 093C 0062;0061 0334 16AF4 093C 0062;0061 0334 16AF4 093C 0062;0061 0334 16AF4 093C 0062; +0061 16AF4 093C 0334 0062;0061 16AF4 0334 093C 0062;0061 16AF4 0334 093C 0062;0061 16AF4 0334 093C 0062;0061 16AF4 0334 093C 0062; +0061 0315 0300 05AE 16B30 0062;00E0 05AE 16B30 0315 0062;0061 05AE 0300 16B30 0315 0062;00E0 05AE 16B30 0315 0062;0061 05AE 0300 16B30 0315 0062; +0061 16B30 0315 0300 05AE 0062;0061 05AE 16B30 0300 0315 0062;0061 05AE 16B30 0300 0315 0062;0061 05AE 16B30 0300 0315 0062;0061 05AE 16B30 0300 0315 0062; +0061 0315 0300 05AE 16B31 0062;00E0 05AE 16B31 0315 0062;0061 05AE 0300 16B31 0315 0062;00E0 05AE 16B31 0315 0062;0061 05AE 0300 16B31 0315 0062; +0061 16B31 0315 0300 05AE 0062;0061 05AE 16B31 0300 0315 0062;0061 05AE 16B31 0300 0315 0062;0061 05AE 16B31 0300 0315 0062;0061 05AE 16B31 0300 0315 0062; +0061 0315 0300 05AE 16B32 0062;00E0 05AE 16B32 0315 0062;0061 05AE 0300 16B32 0315 0062;00E0 05AE 16B32 0315 0062;0061 05AE 0300 16B32 0315 0062; +0061 16B32 0315 0300 05AE 0062;0061 05AE 16B32 0300 0315 0062;0061 05AE 16B32 0300 0315 0062;0061 05AE 16B32 0300 0315 0062;0061 05AE 16B32 0300 0315 0062; +0061 0315 0300 05AE 16B33 0062;00E0 05AE 16B33 0315 0062;0061 05AE 0300 16B33 0315 0062;00E0 05AE 16B33 0315 0062;0061 05AE 0300 16B33 0315 0062; +0061 16B33 0315 0300 05AE 0062;0061 05AE 16B33 0300 0315 0062;0061 05AE 16B33 0300 0315 0062;0061 05AE 16B33 0300 0315 0062;0061 05AE 16B33 0300 0315 0062; +0061 0315 0300 05AE 16B34 0062;00E0 05AE 16B34 0315 0062;0061 05AE 0300 16B34 0315 0062;00E0 05AE 16B34 0315 0062;0061 05AE 0300 16B34 0315 0062; +0061 16B34 0315 0300 05AE 0062;0061 05AE 16B34 0300 0315 0062;0061 05AE 16B34 0300 0315 0062;0061 05AE 16B34 0300 0315 0062;0061 05AE 16B34 0300 0315 0062; +0061 0315 0300 05AE 16B35 0062;00E0 05AE 16B35 0315 0062;0061 05AE 0300 16B35 0315 0062;00E0 05AE 16B35 0315 0062;0061 05AE 0300 16B35 0315 0062; +0061 16B35 0315 0300 05AE 0062;0061 05AE 16B35 0300 0315 0062;0061 05AE 16B35 0300 0315 0062;0061 05AE 16B35 0300 0315 0062;0061 05AE 16B35 0300 0315 0062; +0061 0315 0300 05AE 16B36 0062;00E0 05AE 16B36 0315 0062;0061 05AE 0300 16B36 0315 0062;00E0 05AE 16B36 0315 0062;0061 05AE 0300 16B36 0315 0062; +0061 16B36 0315 0300 05AE 0062;0061 05AE 16B36 0300 0315 0062;0061 05AE 16B36 0300 0315 0062;0061 05AE 16B36 0300 0315 0062;0061 05AE 16B36 0300 0315 0062; +0061 093C 0334 1BC9E 0062;0061 0334 1BC9E 093C 0062;0061 0334 1BC9E 093C 0062;0061 0334 1BC9E 093C 0062;0061 0334 1BC9E 093C 0062; +0061 1BC9E 093C 0334 0062;0061 1BC9E 0334 093C 0062;0061 1BC9E 0334 093C 0062;0061 1BC9E 0334 093C 0062;0061 1BC9E 0334 093C 0062; +0061 302A 031B 1DCE 1D165 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062; +0061 1D165 302A 031B 1DCE 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062; +0061 302A 031B 1DCE 1D166 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062; +0061 1D166 302A 031B 1DCE 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062; +0061 093C 0334 1D167 0062;0061 0334 1D167 093C 0062;0061 0334 1D167 093C 0062;0061 0334 1D167 093C 0062;0061 0334 1D167 093C 0062; +0061 1D167 093C 0334 0062;0061 1D167 0334 093C 0062;0061 1D167 0334 093C 0062;0061 1D167 0334 093C 0062;0061 1D167 0334 093C 0062; +0061 093C 0334 1D168 0062;0061 0334 1D168 093C 0062;0061 0334 1D168 093C 0062;0061 0334 1D168 093C 0062;0061 0334 1D168 093C 0062; +0061 1D168 093C 0334 0062;0061 1D168 0334 093C 0062;0061 1D168 0334 093C 0062;0061 1D168 0334 093C 0062;0061 1D168 0334 093C 0062; +0061 093C 0334 1D169 0062;0061 0334 1D169 093C 0062;0061 0334 1D169 093C 0062;0061 0334 1D169 093C 0062;0061 0334 1D169 093C 0062; +0061 1D169 093C 0334 0062;0061 1D169 0334 093C 0062;0061 1D169 0334 093C 0062;0061 1D169 0334 093C 0062;0061 1D169 0334 093C 0062; +0061 05AE 1D16D 302E 1D16D 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062; +0061 1D16D 05AE 1D16D 302E 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062; +0061 302A 031B 1DCE 1D16E 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062; +0061 1D16E 302A 031B 1DCE 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062; +0061 302A 031B 1DCE 1D16F 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062; +0061 1D16F 302A 031B 1DCE 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062; +0061 302A 031B 1DCE 1D170 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062; +0061 1D170 302A 031B 1DCE 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062; +0061 302A 031B 1DCE 1D171 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062; +0061 1D171 302A 031B 1DCE 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062; +0061 302A 031B 1DCE 1D172 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062; +0061 1D172 302A 031B 1DCE 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062; +0061 059A 0316 302A 1D17B 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062; +0061 1D17B 059A 0316 302A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062; +0061 059A 0316 302A 1D17C 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062; +0061 1D17C 059A 0316 302A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062; +0061 059A 0316 302A 1D17D 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062; +0061 1D17D 059A 0316 302A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062; +0061 059A 0316 302A 1D17E 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062; +0061 1D17E 059A 0316 302A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062; +0061 059A 0316 302A 1D17F 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062; +0061 1D17F 059A 0316 302A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062; +0061 059A 0316 302A 1D180 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062; +0061 1D180 059A 0316 302A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062; +0061 059A 0316 302A 1D181 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062; +0061 1D181 059A 0316 302A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062; +0061 059A 0316 302A 1D182 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062; +0061 1D182 059A 0316 302A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062; +0061 0315 0300 05AE 1D185 0062;00E0 05AE 1D185 0315 0062;0061 05AE 0300 1D185 0315 0062;00E0 05AE 1D185 0315 0062;0061 05AE 0300 1D185 0315 0062; +0061 1D185 0315 0300 05AE 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062; +0061 0315 0300 05AE 1D186 0062;00E0 05AE 1D186 0315 0062;0061 05AE 0300 1D186 0315 0062;00E0 05AE 1D186 0315 0062;0061 05AE 0300 1D186 0315 0062; +0061 1D186 0315 0300 05AE 0062;0061 05AE 1D186 0300 0315 0062;0061 05AE 1D186 0300 0315 0062;0061 05AE 1D186 0300 0315 0062;0061 05AE 1D186 0300 0315 0062; +0061 0315 0300 05AE 1D187 0062;00E0 05AE 1D187 0315 0062;0061 05AE 0300 1D187 0315 0062;00E0 05AE 1D187 0315 0062;0061 05AE 0300 1D187 0315 0062; +0061 1D187 0315 0300 05AE 0062;0061 05AE 1D187 0300 0315 0062;0061 05AE 1D187 0300 0315 0062;0061 05AE 1D187 0300 0315 0062;0061 05AE 1D187 0300 0315 0062; +0061 0315 0300 05AE 1D188 0062;00E0 05AE 1D188 0315 0062;0061 05AE 0300 1D188 0315 0062;00E0 05AE 1D188 0315 0062;0061 05AE 0300 1D188 0315 0062; +0061 1D188 0315 0300 05AE 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062; +0061 0315 0300 05AE 1D189 0062;00E0 05AE 1D189 0315 0062;0061 05AE 0300 1D189 0315 0062;00E0 05AE 1D189 0315 0062;0061 05AE 0300 1D189 0315 0062; +0061 1D189 0315 0300 05AE 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062; +0061 059A 0316 302A 1D18A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062; +0061 1D18A 059A 0316 302A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062; +0061 059A 0316 302A 1D18B 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062; +0061 1D18B 059A 0316 302A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062; +0061 0315 0300 05AE 1D1AA 0062;00E0 05AE 1D1AA 0315 0062;0061 05AE 0300 1D1AA 0315 0062;00E0 05AE 1D1AA 0315 0062;0061 05AE 0300 1D1AA 0315 0062; +0061 1D1AA 0315 0300 05AE 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062; +0061 0315 0300 05AE 1D1AB 0062;00E0 05AE 1D1AB 0315 0062;0061 05AE 0300 1D1AB 0315 0062;00E0 05AE 1D1AB 0315 0062;0061 05AE 0300 1D1AB 0315 0062; +0061 1D1AB 0315 0300 05AE 0062;0061 05AE 1D1AB 0300 0315 0062;0061 05AE 1D1AB 0300 0315 0062;0061 05AE 1D1AB 0300 0315 0062;0061 05AE 1D1AB 0300 0315 0062; +0061 0315 0300 05AE 1D1AC 0062;00E0 05AE 1D1AC 0315 0062;0061 05AE 0300 1D1AC 0315 0062;00E0 05AE 1D1AC 0315 0062;0061 05AE 0300 1D1AC 0315 0062; +0061 1D1AC 0315 0300 05AE 0062;0061 05AE 1D1AC 0300 0315 0062;0061 05AE 1D1AC 0300 0315 0062;0061 05AE 1D1AC 0300 0315 0062;0061 05AE 1D1AC 0300 0315 0062; +0061 0315 0300 05AE 1D1AD 0062;00E0 05AE 1D1AD 0315 0062;0061 05AE 0300 1D1AD 0315 0062;00E0 05AE 1D1AD 0315 0062;0061 05AE 0300 1D1AD 0315 0062; +0061 1D1AD 0315 0300 05AE 0062;0061 05AE 1D1AD 0300 0315 0062;0061 05AE 1D1AD 0300 0315 0062;0061 05AE 1D1AD 0300 0315 0062;0061 05AE 1D1AD 0300 0315 0062; +0061 0315 0300 05AE 1D242 0062;00E0 05AE 1D242 0315 0062;0061 05AE 0300 1D242 0315 0062;00E0 05AE 1D242 0315 0062;0061 05AE 0300 1D242 0315 0062; +0061 1D242 0315 0300 05AE 0062;0061 05AE 1D242 0300 0315 0062;0061 05AE 1D242 0300 0315 0062;0061 05AE 1D242 0300 0315 0062;0061 05AE 1D242 0300 0315 0062; +0061 0315 0300 05AE 1D243 0062;00E0 05AE 1D243 0315 0062;0061 05AE 0300 1D243 0315 0062;00E0 05AE 1D243 0315 0062;0061 05AE 0300 1D243 0315 0062; +0061 1D243 0315 0300 05AE 0062;0061 05AE 1D243 0300 0315 0062;0061 05AE 1D243 0300 0315 0062;0061 05AE 1D243 0300 0315 0062;0061 05AE 1D243 0300 0315 0062; +0061 0315 0300 05AE 1D244 0062;00E0 05AE 1D244 0315 0062;0061 05AE 0300 1D244 0315 0062;00E0 05AE 1D244 0315 0062;0061 05AE 0300 1D244 0315 0062; +0061 1D244 0315 0300 05AE 0062;0061 05AE 1D244 0300 0315 0062;0061 05AE 1D244 0300 0315 0062;0061 05AE 1D244 0300 0315 0062;0061 05AE 1D244 0300 0315 0062; +0061 0315 0300 05AE 1E000 0062;00E0 05AE 1E000 0315 0062;0061 05AE 0300 1E000 0315 0062;00E0 05AE 1E000 0315 0062;0061 05AE 0300 1E000 0315 0062; +0061 1E000 0315 0300 05AE 0062;0061 05AE 1E000 0300 0315 0062;0061 05AE 1E000 0300 0315 0062;0061 05AE 1E000 0300 0315 0062;0061 05AE 1E000 0300 0315 0062; +0061 0315 0300 05AE 1E001 0062;00E0 05AE 1E001 0315 0062;0061 05AE 0300 1E001 0315 0062;00E0 05AE 1E001 0315 0062;0061 05AE 0300 1E001 0315 0062; +0061 1E001 0315 0300 05AE 0062;0061 05AE 1E001 0300 0315 0062;0061 05AE 1E001 0300 0315 0062;0061 05AE 1E001 0300 0315 0062;0061 05AE 1E001 0300 0315 0062; +0061 0315 0300 05AE 1E002 0062;00E0 05AE 1E002 0315 0062;0061 05AE 0300 1E002 0315 0062;00E0 05AE 1E002 0315 0062;0061 05AE 0300 1E002 0315 0062; +0061 1E002 0315 0300 05AE 0062;0061 05AE 1E002 0300 0315 0062;0061 05AE 1E002 0300 0315 0062;0061 05AE 1E002 0300 0315 0062;0061 05AE 1E002 0300 0315 0062; +0061 0315 0300 05AE 1E003 0062;00E0 05AE 1E003 0315 0062;0061 05AE 0300 1E003 0315 0062;00E0 05AE 1E003 0315 0062;0061 05AE 0300 1E003 0315 0062; +0061 1E003 0315 0300 05AE 0062;0061 05AE 1E003 0300 0315 0062;0061 05AE 1E003 0300 0315 0062;0061 05AE 1E003 0300 0315 0062;0061 05AE 1E003 0300 0315 0062; +0061 0315 0300 05AE 1E004 0062;00E0 05AE 1E004 0315 0062;0061 05AE 0300 1E004 0315 0062;00E0 05AE 1E004 0315 0062;0061 05AE 0300 1E004 0315 0062; +0061 1E004 0315 0300 05AE 0062;0061 05AE 1E004 0300 0315 0062;0061 05AE 1E004 0300 0315 0062;0061 05AE 1E004 0300 0315 0062;0061 05AE 1E004 0300 0315 0062; +0061 0315 0300 05AE 1E005 0062;00E0 05AE 1E005 0315 0062;0061 05AE 0300 1E005 0315 0062;00E0 05AE 1E005 0315 0062;0061 05AE 0300 1E005 0315 0062; +0061 1E005 0315 0300 05AE 0062;0061 05AE 1E005 0300 0315 0062;0061 05AE 1E005 0300 0315 0062;0061 05AE 1E005 0300 0315 0062;0061 05AE 1E005 0300 0315 0062; +0061 0315 0300 05AE 1E006 0062;00E0 05AE 1E006 0315 0062;0061 05AE 0300 1E006 0315 0062;00E0 05AE 1E006 0315 0062;0061 05AE 0300 1E006 0315 0062; +0061 1E006 0315 0300 05AE 0062;0061 05AE 1E006 0300 0315 0062;0061 05AE 1E006 0300 0315 0062;0061 05AE 1E006 0300 0315 0062;0061 05AE 1E006 0300 0315 0062; +0061 0315 0300 05AE 1E008 0062;00E0 05AE 1E008 0315 0062;0061 05AE 0300 1E008 0315 0062;00E0 05AE 1E008 0315 0062;0061 05AE 0300 1E008 0315 0062; +0061 1E008 0315 0300 05AE 0062;0061 05AE 1E008 0300 0315 0062;0061 05AE 1E008 0300 0315 0062;0061 05AE 1E008 0300 0315 0062;0061 05AE 1E008 0300 0315 0062; +0061 0315 0300 05AE 1E009 0062;00E0 05AE 1E009 0315 0062;0061 05AE 0300 1E009 0315 0062;00E0 05AE 1E009 0315 0062;0061 05AE 0300 1E009 0315 0062; +0061 1E009 0315 0300 05AE 0062;0061 05AE 1E009 0300 0315 0062;0061 05AE 1E009 0300 0315 0062;0061 05AE 1E009 0300 0315 0062;0061 05AE 1E009 0300 0315 0062; +0061 0315 0300 05AE 1E00A 0062;00E0 05AE 1E00A 0315 0062;0061 05AE 0300 1E00A 0315 0062;00E0 05AE 1E00A 0315 0062;0061 05AE 0300 1E00A 0315 0062; +0061 1E00A 0315 0300 05AE 0062;0061 05AE 1E00A 0300 0315 0062;0061 05AE 1E00A 0300 0315 0062;0061 05AE 1E00A 0300 0315 0062;0061 05AE 1E00A 0300 0315 0062; +0061 0315 0300 05AE 1E00B 0062;00E0 05AE 1E00B 0315 0062;0061 05AE 0300 1E00B 0315 0062;00E0 05AE 1E00B 0315 0062;0061 05AE 0300 1E00B 0315 0062; +0061 1E00B 0315 0300 05AE 0062;0061 05AE 1E00B 0300 0315 0062;0061 05AE 1E00B 0300 0315 0062;0061 05AE 1E00B 0300 0315 0062;0061 05AE 1E00B 0300 0315 0062; +0061 0315 0300 05AE 1E00C 0062;00E0 05AE 1E00C 0315 0062;0061 05AE 0300 1E00C 0315 0062;00E0 05AE 1E00C 0315 0062;0061 05AE 0300 1E00C 0315 0062; +0061 1E00C 0315 0300 05AE 0062;0061 05AE 1E00C 0300 0315 0062;0061 05AE 1E00C 0300 0315 0062;0061 05AE 1E00C 0300 0315 0062;0061 05AE 1E00C 0300 0315 0062; +0061 0315 0300 05AE 1E00D 0062;00E0 05AE 1E00D 0315 0062;0061 05AE 0300 1E00D 0315 0062;00E0 05AE 1E00D 0315 0062;0061 05AE 0300 1E00D 0315 0062; +0061 1E00D 0315 0300 05AE 0062;0061 05AE 1E00D 0300 0315 0062;0061 05AE 1E00D 0300 0315 0062;0061 05AE 1E00D 0300 0315 0062;0061 05AE 1E00D 0300 0315 0062; +0061 0315 0300 05AE 1E00E 0062;00E0 05AE 1E00E 0315 0062;0061 05AE 0300 1E00E 0315 0062;00E0 05AE 1E00E 0315 0062;0061 05AE 0300 1E00E 0315 0062; +0061 1E00E 0315 0300 05AE 0062;0061 05AE 1E00E 0300 0315 0062;0061 05AE 1E00E 0300 0315 0062;0061 05AE 1E00E 0300 0315 0062;0061 05AE 1E00E 0300 0315 0062; +0061 0315 0300 05AE 1E00F 0062;00E0 05AE 1E00F 0315 0062;0061 05AE 0300 1E00F 0315 0062;00E0 05AE 1E00F 0315 0062;0061 05AE 0300 1E00F 0315 0062; +0061 1E00F 0315 0300 05AE 0062;0061 05AE 1E00F 0300 0315 0062;0061 05AE 1E00F 0300 0315 0062;0061 05AE 1E00F 0300 0315 0062;0061 05AE 1E00F 0300 0315 0062; +0061 0315 0300 05AE 1E010 0062;00E0 05AE 1E010 0315 0062;0061 05AE 0300 1E010 0315 0062;00E0 05AE 1E010 0315 0062;0061 05AE 0300 1E010 0315 0062; +0061 1E010 0315 0300 05AE 0062;0061 05AE 1E010 0300 0315 0062;0061 05AE 1E010 0300 0315 0062;0061 05AE 1E010 0300 0315 0062;0061 05AE 1E010 0300 0315 0062; +0061 0315 0300 05AE 1E011 0062;00E0 05AE 1E011 0315 0062;0061 05AE 0300 1E011 0315 0062;00E0 05AE 1E011 0315 0062;0061 05AE 0300 1E011 0315 0062; +0061 1E011 0315 0300 05AE 0062;0061 05AE 1E011 0300 0315 0062;0061 05AE 1E011 0300 0315 0062;0061 05AE 1E011 0300 0315 0062;0061 05AE 1E011 0300 0315 0062; +0061 0315 0300 05AE 1E012 0062;00E0 05AE 1E012 0315 0062;0061 05AE 0300 1E012 0315 0062;00E0 05AE 1E012 0315 0062;0061 05AE 0300 1E012 0315 0062; +0061 1E012 0315 0300 05AE 0062;0061 05AE 1E012 0300 0315 0062;0061 05AE 1E012 0300 0315 0062;0061 05AE 1E012 0300 0315 0062;0061 05AE 1E012 0300 0315 0062; +0061 0315 0300 05AE 1E013 0062;00E0 05AE 1E013 0315 0062;0061 05AE 0300 1E013 0315 0062;00E0 05AE 1E013 0315 0062;0061 05AE 0300 1E013 0315 0062; +0061 1E013 0315 0300 05AE 0062;0061 05AE 1E013 0300 0315 0062;0061 05AE 1E013 0300 0315 0062;0061 05AE 1E013 0300 0315 0062;0061 05AE 1E013 0300 0315 0062; +0061 0315 0300 05AE 1E014 0062;00E0 05AE 1E014 0315 0062;0061 05AE 0300 1E014 0315 0062;00E0 05AE 1E014 0315 0062;0061 05AE 0300 1E014 0315 0062; +0061 1E014 0315 0300 05AE 0062;0061 05AE 1E014 0300 0315 0062;0061 05AE 1E014 0300 0315 0062;0061 05AE 1E014 0300 0315 0062;0061 05AE 1E014 0300 0315 0062; +0061 0315 0300 05AE 1E015 0062;00E0 05AE 1E015 0315 0062;0061 05AE 0300 1E015 0315 0062;00E0 05AE 1E015 0315 0062;0061 05AE 0300 1E015 0315 0062; +0061 1E015 0315 0300 05AE 0062;0061 05AE 1E015 0300 0315 0062;0061 05AE 1E015 0300 0315 0062;0061 05AE 1E015 0300 0315 0062;0061 05AE 1E015 0300 0315 0062; +0061 0315 0300 05AE 1E016 0062;00E0 05AE 1E016 0315 0062;0061 05AE 0300 1E016 0315 0062;00E0 05AE 1E016 0315 0062;0061 05AE 0300 1E016 0315 0062; +0061 1E016 0315 0300 05AE 0062;0061 05AE 1E016 0300 0315 0062;0061 05AE 1E016 0300 0315 0062;0061 05AE 1E016 0300 0315 0062;0061 05AE 1E016 0300 0315 0062; +0061 0315 0300 05AE 1E017 0062;00E0 05AE 1E017 0315 0062;0061 05AE 0300 1E017 0315 0062;00E0 05AE 1E017 0315 0062;0061 05AE 0300 1E017 0315 0062; +0061 1E017 0315 0300 05AE 0062;0061 05AE 1E017 0300 0315 0062;0061 05AE 1E017 0300 0315 0062;0061 05AE 1E017 0300 0315 0062;0061 05AE 1E017 0300 0315 0062; +0061 0315 0300 05AE 1E018 0062;00E0 05AE 1E018 0315 0062;0061 05AE 0300 1E018 0315 0062;00E0 05AE 1E018 0315 0062;0061 05AE 0300 1E018 0315 0062; +0061 1E018 0315 0300 05AE 0062;0061 05AE 1E018 0300 0315 0062;0061 05AE 1E018 0300 0315 0062;0061 05AE 1E018 0300 0315 0062;0061 05AE 1E018 0300 0315 0062; +0061 0315 0300 05AE 1E01B 0062;00E0 05AE 1E01B 0315 0062;0061 05AE 0300 1E01B 0315 0062;00E0 05AE 1E01B 0315 0062;0061 05AE 0300 1E01B 0315 0062; +0061 1E01B 0315 0300 05AE 0062;0061 05AE 1E01B 0300 0315 0062;0061 05AE 1E01B 0300 0315 0062;0061 05AE 1E01B 0300 0315 0062;0061 05AE 1E01B 0300 0315 0062; +0061 0315 0300 05AE 1E01C 0062;00E0 05AE 1E01C 0315 0062;0061 05AE 0300 1E01C 0315 0062;00E0 05AE 1E01C 0315 0062;0061 05AE 0300 1E01C 0315 0062; +0061 1E01C 0315 0300 05AE 0062;0061 05AE 1E01C 0300 0315 0062;0061 05AE 1E01C 0300 0315 0062;0061 05AE 1E01C 0300 0315 0062;0061 05AE 1E01C 0300 0315 0062; +0061 0315 0300 05AE 1E01D 0062;00E0 05AE 1E01D 0315 0062;0061 05AE 0300 1E01D 0315 0062;00E0 05AE 1E01D 0315 0062;0061 05AE 0300 1E01D 0315 0062; +0061 1E01D 0315 0300 05AE 0062;0061 05AE 1E01D 0300 0315 0062;0061 05AE 1E01D 0300 0315 0062;0061 05AE 1E01D 0300 0315 0062;0061 05AE 1E01D 0300 0315 0062; +0061 0315 0300 05AE 1E01E 0062;00E0 05AE 1E01E 0315 0062;0061 05AE 0300 1E01E 0315 0062;00E0 05AE 1E01E 0315 0062;0061 05AE 0300 1E01E 0315 0062; +0061 1E01E 0315 0300 05AE 0062;0061 05AE 1E01E 0300 0315 0062;0061 05AE 1E01E 0300 0315 0062;0061 05AE 1E01E 0300 0315 0062;0061 05AE 1E01E 0300 0315 0062; +0061 0315 0300 05AE 1E01F 0062;00E0 05AE 1E01F 0315 0062;0061 05AE 0300 1E01F 0315 0062;00E0 05AE 1E01F 0315 0062;0061 05AE 0300 1E01F 0315 0062; +0061 1E01F 0315 0300 05AE 0062;0061 05AE 1E01F 0300 0315 0062;0061 05AE 1E01F 0300 0315 0062;0061 05AE 1E01F 0300 0315 0062;0061 05AE 1E01F 0300 0315 0062; +0061 0315 0300 05AE 1E020 0062;00E0 05AE 1E020 0315 0062;0061 05AE 0300 1E020 0315 0062;00E0 05AE 1E020 0315 0062;0061 05AE 0300 1E020 0315 0062; +0061 1E020 0315 0300 05AE 0062;0061 05AE 1E020 0300 0315 0062;0061 05AE 1E020 0300 0315 0062;0061 05AE 1E020 0300 0315 0062;0061 05AE 1E020 0300 0315 0062; +0061 0315 0300 05AE 1E021 0062;00E0 05AE 1E021 0315 0062;0061 05AE 0300 1E021 0315 0062;00E0 05AE 1E021 0315 0062;0061 05AE 0300 1E021 0315 0062; +0061 1E021 0315 0300 05AE 0062;0061 05AE 1E021 0300 0315 0062;0061 05AE 1E021 0300 0315 0062;0061 05AE 1E021 0300 0315 0062;0061 05AE 1E021 0300 0315 0062; +0061 0315 0300 05AE 1E023 0062;00E0 05AE 1E023 0315 0062;0061 05AE 0300 1E023 0315 0062;00E0 05AE 1E023 0315 0062;0061 05AE 0300 1E023 0315 0062; +0061 1E023 0315 0300 05AE 0062;0061 05AE 1E023 0300 0315 0062;0061 05AE 1E023 0300 0315 0062;0061 05AE 1E023 0300 0315 0062;0061 05AE 1E023 0300 0315 0062; +0061 0315 0300 05AE 1E024 0062;00E0 05AE 1E024 0315 0062;0061 05AE 0300 1E024 0315 0062;00E0 05AE 1E024 0315 0062;0061 05AE 0300 1E024 0315 0062; +0061 1E024 0315 0300 05AE 0062;0061 05AE 1E024 0300 0315 0062;0061 05AE 1E024 0300 0315 0062;0061 05AE 1E024 0300 0315 0062;0061 05AE 1E024 0300 0315 0062; +0061 0315 0300 05AE 1E026 0062;00E0 05AE 1E026 0315 0062;0061 05AE 0300 1E026 0315 0062;00E0 05AE 1E026 0315 0062;0061 05AE 0300 1E026 0315 0062; +0061 1E026 0315 0300 05AE 0062;0061 05AE 1E026 0300 0315 0062;0061 05AE 1E026 0300 0315 0062;0061 05AE 1E026 0300 0315 0062;0061 05AE 1E026 0300 0315 0062; +0061 0315 0300 05AE 1E027 0062;00E0 05AE 1E027 0315 0062;0061 05AE 0300 1E027 0315 0062;00E0 05AE 1E027 0315 0062;0061 05AE 0300 1E027 0315 0062; +0061 1E027 0315 0300 05AE 0062;0061 05AE 1E027 0300 0315 0062;0061 05AE 1E027 0300 0315 0062;0061 05AE 1E027 0300 0315 0062;0061 05AE 1E027 0300 0315 0062; +0061 0315 0300 05AE 1E028 0062;00E0 05AE 1E028 0315 0062;0061 05AE 0300 1E028 0315 0062;00E0 05AE 1E028 0315 0062;0061 05AE 0300 1E028 0315 0062; +0061 1E028 0315 0300 05AE 0062;0061 05AE 1E028 0300 0315 0062;0061 05AE 1E028 0300 0315 0062;0061 05AE 1E028 0300 0315 0062;0061 05AE 1E028 0300 0315 0062; +0061 0315 0300 05AE 1E029 0062;00E0 05AE 1E029 0315 0062;0061 05AE 0300 1E029 0315 0062;00E0 05AE 1E029 0315 0062;0061 05AE 0300 1E029 0315 0062; +0061 1E029 0315 0300 05AE 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062; +0061 0315 0300 05AE 1E02A 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062; +0061 1E02A 0315 0300 05AE 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062; +0061 059A 0316 302A 1E8D0 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062; +0061 1E8D0 059A 0316 302A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062; +0061 059A 0316 302A 1E8D1 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062; +0061 1E8D1 059A 0316 302A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062; +0061 059A 0316 302A 1E8D2 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062; +0061 1E8D2 059A 0316 302A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062; +0061 059A 0316 302A 1E8D3 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062; +0061 1E8D3 059A 0316 302A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062; +0061 059A 0316 302A 1E8D4 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062; +0061 1E8D4 059A 0316 302A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062; +0061 059A 0316 302A 1E8D5 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062; +0061 1E8D5 059A 0316 302A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062; +0061 059A 0316 302A 1E8D6 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062; +0061 1E8D6 059A 0316 302A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062; +0061 0315 0300 05AE 1E944 0062;00E0 05AE 1E944 0315 0062;0061 05AE 0300 1E944 0315 0062;00E0 05AE 1E944 0315 0062;0061 05AE 0300 1E944 0315 0062; +0061 1E944 0315 0300 05AE 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062; +0061 0315 0300 05AE 1E945 0062;00E0 05AE 1E945 0315 0062;0061 05AE 0300 1E945 0315 0062;00E0 05AE 1E945 0315 0062;0061 05AE 0300 1E945 0315 0062; +0061 1E945 0315 0300 05AE 0062;0061 05AE 1E945 0300 0315 0062;0061 05AE 1E945 0300 0315 0062;0061 05AE 1E945 0300 0315 0062;0061 05AE 1E945 0300 0315 0062; +0061 0315 0300 05AE 1E946 0062;00E0 05AE 1E946 0315 0062;0061 05AE 0300 1E946 0315 0062;00E0 05AE 1E946 0315 0062;0061 05AE 0300 1E946 0315 0062; +0061 1E946 0315 0300 05AE 0062;0061 05AE 1E946 0300 0315 0062;0061 05AE 1E946 0300 0315 0062;0061 05AE 1E946 0300 0315 0062;0061 05AE 1E946 0300 0315 0062; +0061 0315 0300 05AE 1E947 0062;00E0 05AE 1E947 0315 0062;0061 05AE 0300 1E947 0315 0062;00E0 05AE 1E947 0315 0062;0061 05AE 0300 1E947 0315 0062; +0061 1E947 0315 0300 05AE 0062;0061 05AE 1E947 0300 0315 0062;0061 05AE 1E947 0300 0315 0062;0061 05AE 1E947 0300 0315 0062;0061 05AE 1E947 0300 0315 0062; +0061 0315 0300 05AE 1E948 0062;00E0 05AE 1E948 0315 0062;0061 05AE 0300 1E948 0315 0062;00E0 05AE 1E948 0315 0062;0061 05AE 0300 1E948 0315 0062; +0061 1E948 0315 0300 05AE 0062;0061 05AE 1E948 0300 0315 0062;0061 05AE 1E948 0300 0315 0062;0061 05AE 1E948 0300 0315 0062;0061 05AE 1E948 0300 0315 0062; +0061 0315 0300 05AE 1E949 0062;00E0 05AE 1E949 0315 0062;0061 05AE 0300 1E949 0315 0062;00E0 05AE 1E949 0315 0062;0061 05AE 0300 1E949 0315 0062; +0061 1E949 0315 0300 05AE 0062;0061 05AE 1E949 0300 0315 0062;0061 05AE 1E949 0300 0315 0062;0061 05AE 1E949 0300 0315 0062;0061 05AE 1E949 0300 0315 0062; +0061 3099 093C 0334 1E94A 0062;0061 0334 093C 1E94A 3099 0062;0061 0334 093C 1E94A 3099 0062;0061 0334 093C 1E94A 3099 0062;0061 0334 093C 1E94A 3099 0062; +0061 1E94A 3099 093C 0334 0062;0061 0334 1E94A 093C 3099 0062;0061 0334 1E94A 093C 3099 0062;0061 0334 1E94A 093C 3099 0062;0061 0334 1E94A 093C 3099 0062; +# +@Part3 # PRI #29 Test +# +09C7 0334 09BE;09C7 0334 09BE;09C7 0334 09BE;09C7 0334 09BE;09C7 0334 09BE; +09C7 0334 09D7;09C7 0334 09D7;09C7 0334 09D7;09C7 0334 09D7;09C7 0334 09D7; +0B47 0334 0B3E;0B47 0334 0B3E;0B47 0334 0B3E;0B47 0334 0B3E;0B47 0334 0B3E; +0B47 0334 0B56;0B47 0334 0B56;0B47 0334 0B56;0B47 0334 0B56;0B47 0334 0B56; +0B47 0334 0B57;0B47 0334 0B57;0B47 0334 0B57;0B47 0334 0B57;0B47 0334 0B57; +0B92 0334 0BD7;0B92 0334 0BD7;0B92 0334 0BD7;0B92 0334 0BD7;0B92 0334 0BD7; +0BC6 0334 0BBE;0BC6 0334 0BBE;0BC6 0334 0BBE;0BC6 0334 0BBE;0BC6 0334 0BBE; +0BC6 0334 0BD7;0BC6 0334 0BD7;0BC6 0334 0BD7;0BC6 0334 0BD7;0BC6 0334 0BD7; +0BC7 0334 0BBE;0BC7 0334 0BBE;0BC7 0334 0BBE;0BC7 0334 0BBE;0BC7 0334 0BBE; +0CBF 0334 0CD5;0CBF 0334 0CD5;0CBF 0334 0CD5;0CBF 0334 0CD5;0CBF 0334 0CD5; +0CC6 0334 0CC2;0CC6 0334 0CC2;0CC6 0334 0CC2;0CC6 0334 0CC2;0CC6 0334 0CC2; +0CC6 0334 0CD5;0CC6 0334 0CD5;0CC6 0334 0CD5;0CC6 0334 0CD5;0CC6 0334 0CD5; +0CC6 0334 0CD6;0CC6 0334 0CD6;0CC6 0334 0CD6;0CC6 0334 0CD6;0CC6 0334 0CD6; +0CCA 0334 0CD5;0CCA 0334 0CD5;0CC6 0CC2 0334 0CD5;0CCA 0334 0CD5;0CC6 0CC2 0334 0CD5; +0D46 0334 0D3E;0D46 0334 0D3E;0D46 0334 0D3E;0D46 0334 0D3E;0D46 0334 0D3E; +0D46 0334 0D57;0D46 0334 0D57;0D46 0334 0D57;0D46 0334 0D57;0D46 0334 0D57; +0D47 0334 0D3E;0D47 0334 0D3E;0D47 0334 0D3E;0D47 0334 0D3E;0D47 0334 0D3E; +0DD9 0334 0DCF;0DD9 0334 0DCF;0DD9 0334 0DCF;0DD9 0334 0DCF;0DD9 0334 0DCF; +0DD9 0334 0DDF;0DD9 0334 0DDF;0DD9 0334 0DDF;0DD9 0334 0DDF;0DD9 0334 0DDF; +0F40 0334 0FB5;0F40 0334 0FB5;0F40 0334 0FB5;0F40 0334 0FB5;0F40 0334 0FB5; +0F42 0334 0FB7;0F42 0334 0FB7;0F42 0334 0FB7;0F42 0334 0FB7;0F42 0334 0FB7; +0F4C 0334 0FB7;0F4C 0334 0FB7;0F4C 0334 0FB7;0F4C 0334 0FB7;0F4C 0334 0FB7; +0F51 0334 0FB7;0F51 0334 0FB7;0F51 0334 0FB7;0F51 0334 0FB7;0F51 0334 0FB7; +0F56 0334 0FB7;0F56 0334 0FB7;0F56 0334 0FB7;0F56 0334 0FB7;0F56 0334 0FB7; +0F5B 0334 0FB7;0F5B 0334 0FB7;0F5B 0334 0FB7;0F5B 0334 0FB7;0F5B 0334 0FB7; +0F90 0334 0FB5;0F90 0334 0FB5;0F90 0334 0FB5;0F90 0334 0FB5;0F90 0334 0FB5; +0F92 0334 0FB7;0F92 0334 0FB7;0F92 0334 0FB7;0F92 0334 0FB7;0F92 0334 0FB7; +0F9C 0334 0FB7;0F9C 0334 0FB7;0F9C 0334 0FB7;0F9C 0334 0FB7;0F9C 0334 0FB7; +0FA1 0334 0FB7;0FA1 0334 0FB7;0FA1 0334 0FB7;0FA1 0334 0FB7;0FA1 0334 0FB7; +0FA6 0334 0FB7;0FA6 0334 0FB7;0FA6 0334 0FB7;0FA6 0334 0FB7;0FA6 0334 0FB7; +0FAB 0334 0FB7;0FAB 0334 0FB7;0FAB 0334 0FB7;0FAB 0334 0FB7;0FAB 0334 0FB7; +1025 0334 102E;1025 0334 102E;1025 0334 102E;1025 0334 102E;1025 0334 102E; +1100 0334 1161;1100 0334 1161;1100 0334 1161;1100 0334 1161;1100 0334 1161; +1100 0334 116E;1100 0334 116E;1100 0334 116E;1100 0334 116E;1100 0334 116E; +1101 0334 1166;1101 0334 1166;1101 0334 1166;1101 0334 1166;1101 0334 1166; +1101 0334 1173;1101 0334 1173;1101 0334 1173;1101 0334 1173;1101 0334 1173; +1102 0334 116B;1102 0334 116B;1102 0334 116B;1102 0334 116B;1102 0334 116B; +1103 0334 1163;1103 0334 1163;1103 0334 1163;1103 0334 1163;1103 0334 1163; +1103 0334 1170;1103 0334 1170;1103 0334 1170;1103 0334 1170;1103 0334 1170; +1104 0334 1168;1104 0334 1168;1104 0334 1168;1104 0334 1168;1104 0334 1168; +1104 0334 1175;1104 0334 1175;1104 0334 1175;1104 0334 1175;1104 0334 1175; +1105 0334 116D;1105 0334 116D;1105 0334 116D;1105 0334 116D;1105 0334 116D; +1106 0334 1165;1106 0334 1165;1106 0334 1165;1106 0334 1165;1106 0334 1165; +1106 0334 1172;1106 0334 1172;1106 0334 1172;1106 0334 1172;1106 0334 1172; +1107 0334 116A;1107 0334 116A;1107 0334 116A;1107 0334 116A;1107 0334 116A; +1108 0334 1162;1108 0334 1162;1108 0334 1162;1108 0334 1162;1108 0334 1162; +1108 0334 116F;1108 0334 116F;1108 0334 116F;1108 0334 116F;1108 0334 116F; +1109 0334 1167;1109 0334 1167;1109 0334 1167;1109 0334 1167;1109 0334 1167; +1109 0334 1174;1109 0334 1174;1109 0334 1174;1109 0334 1174;1109 0334 1174; +110A 0334 116C;110A 0334 116C;110A 0334 116C;110A 0334 116C;110A 0334 116C; +110B 0334 1164;110B 0334 1164;110B 0334 1164;110B 0334 1164;110B 0334 1164; +110B 0334 1171;110B 0334 1171;110B 0334 1171;110B 0334 1171;110B 0334 1171; +110C 0334 1169;110C 0334 1169;110C 0334 1169;110C 0334 1169;110C 0334 1169; +110D 0334 1161;110D 0334 1161;110D 0334 1161;110D 0334 1161;110D 0334 1161; +110D 0334 116E;110D 0334 116E;110D 0334 116E;110D 0334 116E;110D 0334 116E; +110E 0334 1166;110E 0334 1166;110E 0334 1166;110E 0334 1166;110E 0334 1166; +110E 0334 1173;110E 0334 1173;110E 0334 1173;110E 0334 1173;110E 0334 1173; +110F 0334 116B;110F 0334 116B;110F 0334 116B;110F 0334 116B;110F 0334 116B; +1110 0334 1163;1110 0334 1163;1110 0334 1163;1110 0334 1163;1110 0334 1163; +1110 0334 1170;1110 0334 1170;1110 0334 1170;1110 0334 1170;1110 0334 1170; +1111 0334 1168;1111 0334 1168;1111 0334 1168;1111 0334 1168;1111 0334 1168; +1111 0334 1175;1111 0334 1175;1111 0334 1175;1111 0334 1175;1111 0334 1175; +1112 0334 116D;1112 0334 116D;1112 0334 116D;1112 0334 116D;1112 0334 116D; +1B05 0334 1B35;1B05 0334 1B35;1B05 0334 1B35;1B05 0334 1B35;1B05 0334 1B35; +1B07 0334 1B35;1B07 0334 1B35;1B07 0334 1B35;1B07 0334 1B35;1B07 0334 1B35; +1B09 0334 1B35;1B09 0334 1B35;1B09 0334 1B35;1B09 0334 1B35;1B09 0334 1B35; +1B0B 0334 1B35;1B0B 0334 1B35;1B0B 0334 1B35;1B0B 0334 1B35;1B0B 0334 1B35; +1B0D 0334 1B35;1B0D 0334 1B35;1B0D 0334 1B35;1B0D 0334 1B35;1B0D 0334 1B35; +1B11 0334 1B35;1B11 0334 1B35;1B11 0334 1B35;1B11 0334 1B35;1B11 0334 1B35; +1B3A 0334 1B35;1B3A 0334 1B35;1B3A 0334 1B35;1B3A 0334 1B35;1B3A 0334 1B35; +1B3C 0334 1B35;1B3C 0334 1B35;1B3C 0334 1B35;1B3C 0334 1B35;1B3C 0334 1B35; +1B3E 0334 1B35;1B3E 0334 1B35;1B3E 0334 1B35;1B3E 0334 1B35;1B3E 0334 1B35; +1B3F 0334 1B35;1B3F 0334 1B35;1B3F 0334 1B35;1B3F 0334 1B35;1B3F 0334 1B35; +1B42 0334 1B35;1B42 0334 1B35;1B42 0334 1B35;1B42 0334 1B35;1B42 0334 1B35; +AC54 0334 11AE;AC54 0334 11AE;1100 1164 0334 11AE;AC54 0334 11AE;1100 1164 0334 11AE; +ACA8 0334 11B5;ACA8 0334 11B5;1100 1167 0334 11B5;ACA8 0334 11B5;1100 1167 0334 11B5; +ACFC 0334 11BC;ACFC 0334 11BC;1100 116A 0334 11BC;ACFC 0334 11BC;1100 116A 0334 11BC; +ADC0 0334 11AE;ADC0 0334 11AE;1100 1171 0334 11AE;ADC0 0334 11AE;1100 1171 0334 11AE; +AE14 0334 11B5;AE14 0334 11B5;1100 1174 0334 11B5;AE14 0334 11B5;1100 1174 0334 11B5; +AE68 0334 11BC;AE68 0334 11BC;1101 1162 0334 11BC;AE68 0334 11BC;1101 1162 0334 11BC; +AF2C 0334 11AE;AF2C 0334 11AE;1101 1169 0334 11AE;AF2C 0334 11AE;1101 1169 0334 11AE; +AF80 0334 11B5;AF80 0334 11B5;1101 116C 0334 11B5;AF80 0334 11B5;1101 116C 0334 11B5; +AFD4 0334 11BC;AFD4 0334 11BC;1101 116F 0334 11BC;AFD4 0334 11BC;1101 116F 0334 11BC; +B098 0334 11AE;B098 0334 11AE;1102 1161 0334 11AE;B098 0334 11AE;1102 1161 0334 11AE; +B0EC 0334 11B5;B0EC 0334 11B5;1102 1164 0334 11B5;B0EC 0334 11B5;1102 1164 0334 11B5; +B140 0334 11BC;B140 0334 11BC;1102 1167 0334 11BC;B140 0334 11BC;1102 1167 0334 11BC; +B204 0334 11AE;B204 0334 11AE;1102 116E 0334 11AE;B204 0334 11AE;1102 116E 0334 11AE; +B258 0334 11B5;B258 0334 11B5;1102 1171 0334 11B5;B258 0334 11B5;1102 1171 0334 11B5; +B2AC 0334 11BC;B2AC 0334 11BC;1102 1174 0334 11BC;B2AC 0334 11BC;1102 1174 0334 11BC; +B370 0334 11AE;B370 0334 11AE;1103 1166 0334 11AE;B370 0334 11AE;1103 1166 0334 11AE; +B3C4 0334 11B5;B3C4 0334 11B5;1103 1169 0334 11B5;B3C4 0334 11B5;1103 1169 0334 11B5; +B418 0334 11BC;B418 0334 11BC;1103 116C 0334 11BC;B418 0334 11BC;1103 116C 0334 11BC; +B4DC 0334 11AE;B4DC 0334 11AE;1103 1173 0334 11AE;B4DC 0334 11AE;1103 1173 0334 11AE; +B530 0334 11B5;B530 0334 11B5;1104 1161 0334 11B5;B530 0334 11B5;1104 1161 0334 11B5; +B584 0334 11BC;B584 0334 11BC;1104 1164 0334 11BC;B584 0334 11BC;1104 1164 0334 11BC; +B648 0334 11AE;B648 0334 11AE;1104 116B 0334 11AE;B648 0334 11AE;1104 116B 0334 11AE; +B69C 0334 11B5;B69C 0334 11B5;1104 116E 0334 11B5;B69C 0334 11B5;1104 116E 0334 11B5; +B6F0 0334 11BC;B6F0 0334 11BC;1104 1171 0334 11BC;B6F0 0334 11BC;1104 1171 0334 11BC; +B7B4 0334 11AE;B7B4 0334 11AE;1105 1163 0334 11AE;B7B4 0334 11AE;1105 1163 0334 11AE; +B808 0334 11B5;B808 0334 11B5;1105 1166 0334 11B5;B808 0334 11B5;1105 1166 0334 11B5; +B85C 0334 11BC;B85C 0334 11BC;1105 1169 0334 11BC;B85C 0334 11BC;1105 1169 0334 11BC; +B920 0334 11AE;B920 0334 11AE;1105 1170 0334 11AE;B920 0334 11AE;1105 1170 0334 11AE; +B974 0334 11B5;B974 0334 11B5;1105 1173 0334 11B5;B974 0334 11B5;1105 1173 0334 11B5; +B9C8 0334 11BC;B9C8 0334 11BC;1106 1161 0334 11BC;B9C8 0334 11BC;1106 1161 0334 11BC; +BA8C 0334 11AE;BA8C 0334 11AE;1106 1168 0334 11AE;BA8C 0334 11AE;1106 1168 0334 11AE; +BAE0 0334 11B5;BAE0 0334 11B5;1106 116B 0334 11B5;BAE0 0334 11B5;1106 116B 0334 11B5; +BB34 0334 11BC;BB34 0334 11BC;1106 116E 0334 11BC;BB34 0334 11BC;1106 116E 0334 11BC; +BBF8 0334 11AE;BBF8 0334 11AE;1106 1175 0334 11AE;BBF8 0334 11AE;1106 1175 0334 11AE; +BC4C 0334 11B5;BC4C 0334 11B5;1107 1163 0334 11B5;BC4C 0334 11B5;1107 1163 0334 11B5; +BCA0 0334 11BC;BCA0 0334 11BC;1107 1166 0334 11BC;BCA0 0334 11BC;1107 1166 0334 11BC; +BD64 0334 11AE;BD64 0334 11AE;1107 116D 0334 11AE;BD64 0334 11AE;1107 116D 0334 11AE; +BDB8 0334 11B5;BDB8 0334 11B5;1107 1170 0334 11B5;BDB8 0334 11B5;1107 1170 0334 11B5; +BE0C 0334 11BC;BE0C 0334 11BC;1107 1173 0334 11BC;BE0C 0334 11BC;1107 1173 0334 11BC; +BED0 0334 11AE;BED0 0334 11AE;1108 1165 0334 11AE;BED0 0334 11AE;1108 1165 0334 11AE; +BF24 0334 11B5;BF24 0334 11B5;1108 1168 0334 11B5;BF24 0334 11B5;1108 1168 0334 11B5; +BF78 0334 11BC;BF78 0334 11BC;1108 116B 0334 11BC;BF78 0334 11BC;1108 116B 0334 11BC; +C03C 0334 11AE;C03C 0334 11AE;1108 1172 0334 11AE;C03C 0334 11AE;1108 1172 0334 11AE; +C090 0334 11B5;C090 0334 11B5;1108 1175 0334 11B5;C090 0334 11B5;1108 1175 0334 11B5; +C0E4 0334 11BC;C0E4 0334 11BC;1109 1163 0334 11BC;C0E4 0334 11BC;1109 1163 0334 11BC; +C1A8 0334 11AE;C1A8 0334 11AE;1109 116A 0334 11AE;C1A8 0334 11AE;1109 116A 0334 11AE; +C1FC 0334 11B5;C1FC 0334 11B5;1109 116D 0334 11B5;C1FC 0334 11B5;1109 116D 0334 11B5; +C250 0334 11BC;C250 0334 11BC;1109 1170 0334 11BC;C250 0334 11BC;1109 1170 0334 11BC; +C314 0334 11AE;C314 0334 11AE;110A 1162 0334 11AE;C314 0334 11AE;110A 1162 0334 11AE; +C368 0334 11B5;C368 0334 11B5;110A 1165 0334 11B5;C368 0334 11B5;110A 1165 0334 11B5; +C3BC 0334 11BC;C3BC 0334 11BC;110A 1168 0334 11BC;C3BC 0334 11BC;110A 1168 0334 11BC; +C480 0334 11AE;C480 0334 11AE;110A 116F 0334 11AE;C480 0334 11AE;110A 116F 0334 11AE; +C4D4 0334 11B5;C4D4 0334 11B5;110A 1172 0334 11B5;C4D4 0334 11B5;110A 1172 0334 11B5; +C528 0334 11BC;C528 0334 11BC;110A 1175 0334 11BC;C528 0334 11BC;110A 1175 0334 11BC; +C5EC 0334 11AE;C5EC 0334 11AE;110B 1167 0334 11AE;C5EC 0334 11AE;110B 1167 0334 11AE; +C640 0334 11B5;C640 0334 11B5;110B 116A 0334 11B5;C640 0334 11B5;110B 116A 0334 11B5; +C694 0334 11BC;C694 0334 11BC;110B 116D 0334 11BC;C694 0334 11BC;110B 116D 0334 11BC; +C758 0334 11AE;C758 0334 11AE;110B 1174 0334 11AE;C758 0334 11AE;110B 1174 0334 11AE; +C7AC 0334 11B5;C7AC 0334 11B5;110C 1162 0334 11B5;C7AC 0334 11B5;110C 1162 0334 11B5; +C800 0334 11BC;C800 0334 11BC;110C 1165 0334 11BC;C800 0334 11BC;110C 1165 0334 11BC; +C8C4 0334 11AE;C8C4 0334 11AE;110C 116C 0334 11AE;C8C4 0334 11AE;110C 116C 0334 11AE; +C918 0334 11B5;C918 0334 11B5;110C 116F 0334 11B5;C918 0334 11B5;110C 116F 0334 11B5; +C96C 0334 11BC;C96C 0334 11BC;110C 1172 0334 11BC;C96C 0334 11BC;110C 1172 0334 11BC; +CA30 0334 11AE;CA30 0334 11AE;110D 1164 0334 11AE;CA30 0334 11AE;110D 1164 0334 11AE; +CA84 0334 11B5;CA84 0334 11B5;110D 1167 0334 11B5;CA84 0334 11B5;110D 1167 0334 11B5; +CAD8 0334 11BC;CAD8 0334 11BC;110D 116A 0334 11BC;CAD8 0334 11BC;110D 116A 0334 11BC; +CB9C 0334 11AE;CB9C 0334 11AE;110D 1171 0334 11AE;CB9C 0334 11AE;110D 1171 0334 11AE; +CBF0 0334 11B5;CBF0 0334 11B5;110D 1174 0334 11B5;CBF0 0334 11B5;110D 1174 0334 11B5; +CC44 0334 11BC;CC44 0334 11BC;110E 1162 0334 11BC;CC44 0334 11BC;110E 1162 0334 11BC; +CD08 0334 11AE;CD08 0334 11AE;110E 1169 0334 11AE;CD08 0334 11AE;110E 1169 0334 11AE; +CD5C 0334 11B5;CD5C 0334 11B5;110E 116C 0334 11B5;CD5C 0334 11B5;110E 116C 0334 11B5; +CDB0 0334 11BC;CDB0 0334 11BC;110E 116F 0334 11BC;CDB0 0334 11BC;110E 116F 0334 11BC; +CE74 0334 11AE;CE74 0334 11AE;110F 1161 0334 11AE;CE74 0334 11AE;110F 1161 0334 11AE; +CEC8 0334 11B5;CEC8 0334 11B5;110F 1164 0334 11B5;CEC8 0334 11B5;110F 1164 0334 11B5; +CF1C 0334 11BC;CF1C 0334 11BC;110F 1167 0334 11BC;CF1C 0334 11BC;110F 1167 0334 11BC; +CFE0 0334 11AE;CFE0 0334 11AE;110F 116E 0334 11AE;CFE0 0334 11AE;110F 116E 0334 11AE; +D034 0334 11B5;D034 0334 11B5;110F 1171 0334 11B5;D034 0334 11B5;110F 1171 0334 11B5; +D088 0334 11BC;D088 0334 11BC;110F 1174 0334 11BC;D088 0334 11BC;110F 1174 0334 11BC; +D14C 0334 11AE;D14C 0334 11AE;1110 1166 0334 11AE;D14C 0334 11AE;1110 1166 0334 11AE; +D1A0 0334 11B5;D1A0 0334 11B5;1110 1169 0334 11B5;D1A0 0334 11B5;1110 1169 0334 11B5; +D1F4 0334 11BC;D1F4 0334 11BC;1110 116C 0334 11BC;D1F4 0334 11BC;1110 116C 0334 11BC; +D2B8 0334 11AE;D2B8 0334 11AE;1110 1173 0334 11AE;D2B8 0334 11AE;1110 1173 0334 11AE; +D30C 0334 11B5;D30C 0334 11B5;1111 1161 0334 11B5;D30C 0334 11B5;1111 1161 0334 11B5; +D360 0334 11BC;D360 0334 11BC;1111 1164 0334 11BC;D360 0334 11BC;1111 1164 0334 11BC; +D424 0334 11AE;D424 0334 11AE;1111 116B 0334 11AE;D424 0334 11AE;1111 116B 0334 11AE; +D478 0334 11B5;D478 0334 11B5;1111 116E 0334 11B5;D478 0334 11B5;1111 116E 0334 11B5; +D4CC 0334 11BC;D4CC 0334 11BC;1111 1171 0334 11BC;D4CC 0334 11BC;1111 1171 0334 11BC; +D590 0334 11AE;D590 0334 11AE;1112 1163 0334 11AE;D590 0334 11AE;1112 1163 0334 11AE; +D5E4 0334 11B5;D5E4 0334 11B5;1112 1166 0334 11B5;D5E4 0334 11B5;1112 1166 0334 11B5; +D638 0334 11BC;D638 0334 11BC;1112 1169 0334 11BC;D638 0334 11BC;1112 1169 0334 11BC; +D6FC 0334 11AE;D6FC 0334 11AE;1112 1170 0334 11AE;D6FC 0334 11AE;1112 1170 0334 11AE; +D750 0334 11B5;D750 0334 11B5;1112 1173 0334 11B5;D750 0334 11B5;1112 1173 0334 11B5; +11131 0334 11127;11131 0334 11127;11131 0334 11127;11131 0334 11127;11131 0334 11127; +11132 0334 11127;11132 0334 11127;11132 0334 11127;11132 0334 11127;11132 0334 11127; +11347 0334 1133E;11347 0334 1133E;11347 0334 1133E;11347 0334 1133E;11347 0334 1133E; +11347 0334 11357;11347 0334 11357;11347 0334 11357;11347 0334 11357;11347 0334 11357; +114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0; +114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA; +114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD; +115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF; +115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF; +# +# EOF \ No newline at end of file diff --git a/claimtrie/normalization/case_folder.go b/claimtrie/normalization/case_folder.go new file mode 100644 index 00000000..7e4298ff --- /dev/null +++ b/claimtrie/normalization/case_folder.go @@ -0,0 +1,61 @@ +package normalization + +import ( + "bytes" + _ "embed" + "regexp" + "strconv" + "strings" + "unicode/utf8" +) + +//go:embed CaseFolding_v11.txt +var v11 string + +var foldMap map[rune][]rune + +func init() { + foldMap = map[rune][]rune{} + r, _ := regexp.Compile(`([[:xdigit:]]+?); (.); ([[:xdigit:] ]+?);`) + matches := r.FindAllStringSubmatch(v11, 1000000000) + for i := range matches { + if matches[i][2] == "C" || matches[i][2] == "F" { + key, err := strconv.ParseUint(matches[i][1], 16, len(matches[i][1])*4) + if err != nil { + panic(err) + } + splits := strings.Split(matches[i][3], " ") + var values []rune + for j := range splits { + value, err := strconv.ParseUint(splits[j], 16, len(splits[j])*4) + if err != nil { + panic(err) + } + values = append(values, rune(value)) + } + foldMap[rune(key)] = values + } + } +} + +func caseFold(name []byte) []byte { + var b bytes.Buffer + b.Grow(len(name)) + for i := 0; i < len(name); { + r, w := utf8.DecodeRune(name[i:]) + if r == utf8.RuneError && w < 2 { + // HACK: their RuneError is actually a valid character if coming from a width of 2 or more + return name + } + replacements := foldMap[r] + if len(replacements) > 0 { + for j := range replacements { + b.WriteRune(replacements[j]) + } + } else { + b.WriteRune(r) + } + i += w + } + return b.Bytes() +} diff --git a/claimtrie/normalization/char_decomposer.go b/claimtrie/normalization/char_decomposer.go new file mode 100644 index 00000000..8631cd31 --- /dev/null +++ b/claimtrie/normalization/char_decomposer.go @@ -0,0 +1,177 @@ +package normalization + +import ( + "bufio" + _ "embed" + "strconv" + "strings" + "unicode/utf8" +) + +//go:embed NFC_v11.txt +var decompositions string // the data file that came from ICU 63.2 + +var nfdMap map[rune][]rune +var nfdOrder map[rune]int32 + +func init() { + nfdMap = map[rune][]rune{} + nfdOrder = map[rune]int32{} + scanner := bufio.NewScanner(strings.NewReader(decompositions)) + for scanner.Scan() { + line := scanner.Text() + if len(line) <= 0 || line[0] == '#' || line[0] == '*' { + continue + } + if strings.ContainsAny(line, ":") { + // it's a ordering def: + addOrdering(line) + continue + } + splits := strings.Split(line, "=") + if len(splits) <= 1 { + splits = strings.Split(line, ">") + if len(splits) <= 1 { + continue + } + } + key, err := strconv.ParseUint(splits[0], 16, len(splits[0])*4) + if err != nil { + panic(err) + } + splits = strings.Split(splits[1], " ") + values := make([]rune, 0, len(splits)) + for j := range splits { + value, err := strconv.ParseUint(splits[j], 16, len(splits[j])*4) + if err != nil { + panic(err) + } + existing := nfdMap[rune(value)] + if len(existing) > 0 { + values = append(values, existing...) + } else { + values = append(values, rune(value)) + } + } + nfdMap[rune(key)] = values + } + + // run one more expansion pass to catch stragglers + for key, values := range nfdMap { + for i, value := range values { + other := nfdMap[value] + if len(other) > 0 { + newValues := make([]rune, len(values)+len(other)-1) + copy(newValues, values[:i]) + copy(newValues[i:i+len(other)], other) + copy(newValues[i+len(other):], values[i+1:]) + nfdMap[key] = newValues + } + } + } + + // assert no more expansions are necessary: + for _, values := range nfdMap { + for _, value := range values { + other := nfdMap[value] + if len(other) > 0 { + panic("Failed in NFD expansion") + } + } + } +} + +func addOrdering(line string) { + splits := strings.Split(line, ":") + ranges := strings.Split(splits[0], "..") + + value, err := strconv.ParseUint(splits[1], 16, len(splits[1])*4) + if err != nil { + panic(err) + } + + start, err := strconv.ParseUint(ranges[0], 16, len(ranges[0])*4) + if err != nil { + panic(err) + } + end := start + if len(ranges) > 1 { + end, err = strconv.ParseUint(ranges[1], 16, len(ranges[0])*4) + if err != nil { + panic(err) + } + } + for i := start; i <= end; i++ { + nfdOrder[rune(i)] = int32(value) + } +} + +func decompose(name []byte) []byte { + // see https://unicode.org/reports/tr15/ section 1.3 + runes := make([]rune, 0, len(name)) // we typically use ascii don't increase the length + for i := 0; i < len(name); { + r, w := utf8.DecodeRune(name[i:]) + if r == utf8.RuneError && w < 2 { + // HACK: their RuneError is actually a valid character if coming from a width of 2 or more + return name + } + replacements := nfdMap[r] + if len(replacements) > 0 { + runes = append(runes, replacements...) + } else { + hanguls := decomposeHangul(r) + if len(hanguls) > 0 { + runes = append(runes, hanguls...) + } else { + runes = append(runes, r) + } + } + i += w + } + repairOrdering(runes) + return []byte(string(runes)) +} + +func decomposeHangul(s rune) []rune { + // see https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf + + const SBase int32 = 0xAC00 + const LBase int32 = 0x1100 + const VBase int32 = 0x1161 + const TBase int32 = 0x11A7 + const LCount int32 = 19 + const VCount int32 = 21 + const TCount int32 = 28 + const NCount = VCount * TCount // 588 + const SCount = LCount * NCount // 11172 + + SIndex := s - SBase + if SIndex < 0 || SIndex >= SCount { + return nil + } + L := LBase + SIndex/NCount + V := VBase + (SIndex%NCount)/TCount + T := TBase + SIndex%TCount + result := []rune{L, V} + if T != TBase { + result = append(result, T) + } + return result +} + +func repairOrdering(runes []rune) { + for i := 1; i < len(runes); i++ { + a := runes[i-1] + b := runes[i] + oa := nfdOrder[a] + ob := nfdOrder[b] + if oa > ob && ob > 0 { + runes[i-1], runes[i] = b, a + if i >= 2 { + i -= 2 + } else { + i = 0 + } + } + } +} diff --git a/claimtrie/normalization/normalizer.go b/claimtrie/normalization/normalizer.go new file mode 100644 index 00000000..2bd4fa53 --- /dev/null +++ b/claimtrie/normalization/normalizer.go @@ -0,0 +1,22 @@ +package normalization + +import ( + "github.com/lbryio/lbcd/claimtrie/param" +) + +var Normalize = normalizeGo +var NormalizeTitle = "Normalizing strings via Go. Casefold and NFD table versions: 11.0.0 (from ICU 63.2)" + +func NormalizeIfNecessary(name []byte, height int32) []byte { + if height < param.ActiveParams.NormalizedNameForkHeight { + return name + } + return Normalize(name) +} + +func normalizeGo(value []byte) []byte { + + normalized := decompose(value) // may need to hard-code the version on this + // not using x/text/cases because it does too good of a job; it seems to use v14 tables even when it claims v13 + return caseFold(normalized) +} diff --git a/claimtrie/normalization/normalizer_icu.go b/claimtrie/normalization/normalizer_icu.go new file mode 100644 index 00000000..8302cc68 --- /dev/null +++ b/claimtrie/normalization/normalizer_icu.go @@ -0,0 +1,77 @@ +//go:build use_icu_normalization +// +build use_icu_normalization + +package normalization + +// #cgo CFLAGS: -O2 +// #cgo LDFLAGS: -licuio -licui18n -licuuc -licudata +// #include +// #include +// #include +// int icu_version() { +// UVersionInfo info; +// u_getVersion(info); +// return ((int)(info[0]) << 16) + info[1]; +// } +// int normalize(char* name, int length, char* result) { +// UErrorCode ec = U_ZERO_ERROR; +// static const UNormalizer2* normalizer = NULL; +// if (normalizer == NULL) normalizer = unorm2_getNFDInstance(&ec); +// UChar dest[256]; // maximum claim name size is 255; we won't have more UTF16 chars than bytes +// int dest_len; +// u_strFromUTF8(dest, 256, &dest_len, name, length, &ec); +// if (U_FAILURE(ec) || dest_len == 0) return 0; +// UChar normalized[256]; +// dest_len = unorm2_normalize(normalizer, dest, dest_len, normalized, 256, &ec); +// if (U_FAILURE(ec) || dest_len == 0) return 0; +// dest_len = u_strFoldCase(dest, 256, normalized, dest_len, U_FOLD_CASE_DEFAULT, &ec); +// if (U_FAILURE(ec) || dest_len == 0) return 0; +// u_strToUTF8(result, 512, &dest_len, dest, dest_len, &ec); +// return dest_len; +// } +import "C" +import ( + "bytes" + "encoding/hex" + "fmt" + "unsafe" +) + +func init() { + Normalize = normalizeICU + NormalizeTitle = "Normalizing strings via ICU. ICU version = " + IcuVersion() +} + +func IcuVersion() string { + // TODO: we probably need to explode if it's not 63.2 as it affects consensus + result := C.icu_version() + return fmt.Sprintf("%d.%d", result>>16, result&0xffff) +} + +func normalizeICU(value []byte) []byte { + original := value + if len(value) <= 0 { + return value + } + + other := normalizeGo(value) + + name := (*C.char)(unsafe.Pointer(&value[0])) + length := C.int(len(value)) + + // hopefully this is a stack alloc (but it may be a bit large for that): + var resultName [512]byte // inputs are restricted to 255 chars; it shouldn't expand too much past that + pointer := unsafe.Pointer(&resultName[0]) + + resultLength := C.normalize(name, length, (*C.char)(pointer)) + if resultLength > 0 { + value = C.GoBytes(pointer, resultLength) + } + + // return resultName[0:resultLength] -- we want to shrink the pointer (not use a slice on 1024) + if !bytes.Equal(other, value) { + fmt.Printf("Failed with %s, %s != %s,\n\t%s, %s != %s,\n", original, value, other, + hex.EncodeToString(original), hex.EncodeToString(value), hex.EncodeToString(other)) + } + return value +} diff --git a/claimtrie/normalization/normalizer_icu_test.go b/claimtrie/normalization/normalizer_icu_test.go new file mode 100644 index 00000000..3702a772 --- /dev/null +++ b/claimtrie/normalization/normalizer_icu_test.go @@ -0,0 +1,74 @@ +//go:build use_icu_normalization +// +build use_icu_normalization + +package normalization + +import ( + "bytes" + "encoding/hex" + "testing" + "unicode/utf8" + + "github.com/stretchr/testify/assert" +) + +func TestNormalizationICU(t *testing.T) { + testNormalization(t, normalizeICU) +} + +func BenchmarkNormalizeICU(b *testing.B) { + benchmarkNormalize(b, normalizeICU) +} + +var testStrings = []string{ + "Les-Masques-Blancs-Die-Dead-place-Sathonay-28-Août", + "Bez-komentu-výbuch-z-vnútra,-radšej-pozri-video...-", + "၂-နစ်အကြာမှာ", + "ငရဲပြည်မှ-6", + "@happyvision", + "ကမ္ဘာပျက်ကိန်း-9", + "ဝိညာဉ်နား၊-3", + "un-amore-nuovo-o-un-ritorno-cosa-mi-dona", + "è-innamorato-di-me-anche-se-non-lo-dice", + "ပြင်ဆင်ပါ-no.1", + "ပြင်ဆင်ပါ-no.4", + "ပြင်ဆင်ပါ-no.2", + "ပြင်ဆင်ပါ-no.3", + "ငရဲပြည်မှ-5", + "ပြင်ဆင်ပါ-no.6", + "ပြင်ဆင်ပါ-no.5", + "ပြင်ဆင်ပါ-no.7", + "ပြင်ဆင်ပါ-no.8", + "အချိန်-2", + "ဝိညာဉ်နား၊-4", + "ပြင်ဆင်ပါ-no.-13", + "ပြင်ဆင်ပါ-no.15", + "ပြင်ဆင်ပါ-9", + "schilddrüsenhormonsubstitution-nach", + "Linxextremismus-JPzuG_UBtEg", + "Ꮖ-Ꮩ-Ꭺ-N--------Ꭺ-N-Ꮹ-Ꭼ-Ꮮ-Ꭺ-on-Instagram_-“Our-next-destination-is-East-and-Southeast-Asia--selfie--asia”", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", +} + +func TestBlock760150_1020105(t *testing.T) { + test, _ := hex.DecodeString("43efbfbd") + assert.True(t, utf8.Valid(test)) + a := normalizeGo(test) + b := normalizeICU(test) + assert.Equal(t, a, b) + + for i, s := range testStrings { + a = normalizeGo([]byte(s)) + b = normalizeICU([]byte(s)) + assert.Equal(t, a, b, "%d: %s != %s", i, string(a), string(b)) + // t.Logf("%s -> %s", s, string(b)) + } +} + +func TestBlock1085612(t *testing.T) { + s, err := hex.DecodeString("6eccb7cd9dcc92cd90cc86cc80cc80cd91cd9dcd8acd80cd92cc94cc85cc8fccbdcda0ccbdcd80cda0cd84cc94cc8ccc9acd84cc94cd9bcda0cca7cc99ccaccd99cca9cca7") + assert.NoError(t, err) + a := normalizeICU(s) + b := normalizeGo(s) + assert.Equal(t, a, b, "%s != %s, %v", string(a), string(b), bytes.Equal(b, s)) +} diff --git a/claimtrie/normalization/normalizer_test.go b/claimtrie/normalization/normalizer_test.go new file mode 100644 index 00000000..6adcff67 --- /dev/null +++ b/claimtrie/normalization/normalizer_test.go @@ -0,0 +1,89 @@ +package normalization + +import ( + "bufio" + "bytes" + _ "embed" + "math/rand" + "strconv" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNormalizationGo(t *testing.T) { + testNormalization(t, normalizeGo) +} + +func testNormalization(t *testing.T, normalize func(value []byte) []byte) { + + r := require.New(t) + + r.Equal("test", string(normalize([]byte("TESt")))) + r.Equal("test 23", string(normalize([]byte("tesT 23")))) + r.Equal("\xFF", string(normalize([]byte("\xFF")))) + r.Equal("\xC3\x28", string(normalize([]byte("\xC3\x28")))) + r.Equal("\xCF\x89", string(normalize([]byte("\xE2\x84\xA6")))) + r.Equal("\xD1\x84", string(normalize([]byte("\xD0\xA4")))) + r.Equal("\xD5\xA2", string(normalize([]byte("\xD4\xB2")))) + r.Equal("\xE3\x81\xB5\xE3\x82\x99", string(normalize([]byte("\xE3\x81\xB6")))) + r.Equal("\xE1\x84\x81\xE1\x85\xAA\xE1\x86\xB0", string(normalize([]byte("\xEA\xBD\x91")))) +} + +func randSeq(n int) []byte { + var alphabet = []rune("abcdefghijklmnopqrstuvwxyz̃ABCDEFGHIJKLMNOPQRSTUVWXYZ̃") + + b := make([]rune, n) + for i := range b { + b[i] = alphabet[rand.Intn(len(alphabet))] + } + return []byte(string(b)) +} + +func BenchmarkNormalize(b *testing.B) { + benchmarkNormalize(b, normalizeGo) +} + +func benchmarkNormalize(b *testing.B, normalize func(value []byte) []byte) { + rand.Seed(42) + strings := make([][]byte, b.N) + for i := 0; i < b.N; i++ { + strings[i] = randSeq(32) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + s := normalize(strings[i]) + require.True(b, len(s) >= 8) + } +} + +//go:embed NormalizationTest_v11.txt +var nfdTests string + +func TestDecomposition(t *testing.T) { + r := require.New(t) + + scanner := bufio.NewScanner(strings.NewReader(nfdTests)) + for scanner.Scan() { + line := scanner.Text() + if len(line) <= 0 || line[0] == '@' || line[0] == '#' { + continue + } + splits := strings.Split(line, ";") + source := convertToBytes(splits[0]) + targetNFD := convertToBytes(splits[2]) + fixed := decompose(source) + r.True(bytes.Equal(targetNFD, fixed), "Failed on %s -> %s. Got %U, not %U", splits[0], splits[2], fixed, targetNFD) + } +} + +func convertToBytes(s string) []byte { + splits := strings.Split(s, " ") + var b bytes.Buffer + for i := range splits { + value, _ := strconv.ParseUint(splits[i], 16, len(splits[i])*4) + b.WriteRune(rune(value)) + } + return b.Bytes() +} diff --git a/claimtrie/param/delays.go b/claimtrie/param/delays.go new file mode 100644 index 00000000..d310877f --- /dev/null +++ b/claimtrie/param/delays.go @@ -0,0 +1,285 @@ +package param + +var DelayWorkarounds = generateDelayWorkarounds() // called "removal workarounds" in previous versions + +func generateDelayWorkarounds() map[string][]int32 { + return map[string][]int32{ + "travtest01": {426898}, + "gauntlet-invade-the-darkness-lvl-1-of": {583305}, + "fr-let-s-play-software-inc-jay": {588308}, + "fr-motorsport-manager-jay-s-racing": {588308}, + "fr-crusader-kings-2-la-dynastie-6": {588318}, + "fr-jurassic-world-evolution-let-s-play": {588318}, + "calling-tech-support-scammers-live-3": {588683, 646584}, + "let-s-play-jackbox-games": {589013}, + "lets-play-jackbox-games-5": {589013}, + "kabutothesnake-s-live-ps4-broadcast": {589538}, + "no-eas-strong-thunderstorm-advisory": {589554}, + "geometry-dash-level-requests": {589564}, + "geometry-dash-level-requests-2": {589564}, + "star-ocean-integrity-and-faithlessness": {589609}, + "@pop": {589613}, + "ullash": {589630}, + "today-s-professionals-2018-winter-3": {589640}, + "today-s-professionals-2018-winter-4": {589640}, + "today-s-professionals-2018-winter-10": {589641}, + "today-s-professionals-big-brother-6-13": {589641}, + "today-s-professionals-big-brother-6-14": {589641}, + "today-s-professionals-big-brother-6-26": {589641}, + "today-s-professionals-big-brother-6-27": {589641}, + "today-s-professionals-big-brother-6-28": {589641}, + "today-s-professionals-big-brother-6-29": {589641}, + "dark-souls-iii": {589697}, + "bobby-blades": {589760}, + "adrian": {589803}, + "roblox-2": {589803, 597925}, + "roblox-4": {589803}, + "roblox-5": {589803}, + "roblox-6": {589803}, + "roblox-7": {589803}, + "roblox-8": {589803}, + "madden-17": {589809}, + "madden-18-franchise": {589810}, + "fifa-14-android-astrodude44-vs": {589831}, + "gaming-with-silverwolf-live-stream-3": {589849}, + "gaming-with-silverwolf-live-stream-4": {589849}, + "gaming-with-silverwolf-live-stream-5": {589849}, + "gaming-with-silverwolf-videos-live": {589849}, + "gaming-with-silverwolf-live-stream-6": {589851}, + "live-q-a": {589851}, + "classic-sonic-games": {589870}, + "gta": {589926}, + "j-dog7973-s-fortnite-squad": {589926}, + "wow-warlords-of-draenor-horde-side": {589967}, + "minecraft-ps4-hardcore-survival-2-the-5": {589991}, + "happy-new-year-2017": {590013}, + "come-chill-with-rekzzey-2": {590020}, + "counter-strike-global-offensive-funny": {590031}, + "father-vs-son-stickfight-stickfight": {590178}, + "little-t-playing-subnautica-livestream": {590178}, + "today-s-professionals-big-brother-7-26-5": {590200}, + "50585be4e3159a7-1": {590206}, + "dark-souls-iii-soul-level-1-challenge": {590223}, + "dark-souls-iii-soul-level-1-challenge-3": {590223}, + "let-s-play-sniper-elite-4-authentic-2": {590225}, + "skyrim-special-edition-ps4-platinum-4": {590225}, + "let-s-play-final-fantasy-the-zodiac-2": {590226}, + "let-s-play-final-fantasy-the-zodiac-3": {590226}, + "ls-h-ppchen-halloween-stream-vom-31-10": {590401}, + "a-new-stream": {590669}, + "danganronpa-v3-killing-harmony-episode": {590708}, + "danganronpa-v3-killing-harmony-episode-4": {590708}, + "danganronpa-v3-killing-harmony-episode-6": {590708}, + "danganronpa-v3-killing-harmony-episode-8": {590708}, + "danganronpa-v3-killing-harmony-episode-9": {590708}, + "call-of-duty-infinite-warfare-gameplay-2": {591982}, + "destiny-the-taken-king-gameplay": {591982}, + "horizon-zero-dawn-100-complete-4": {591983}, + "ghost-recon-wildlands-100-complete-4": {591984}, + "nier-automata-100-complete-gameplay-25": {591985}, + "frustrert": {592291}, + "call-of-duty-black-ops-3-multiplayer": {593504}, + "rayman-legends-challenges-app-the": {593551}, + "super-mario-sunshine-3-player-race-2": {593552}, + "some-new-stuff-might-play-a-game": {593698}, + "memory-techniques-1-000-people-system": {595537}, + "propresenter-6-tutorials-new-features-4": {595559}, + "rocket-league-live": {595559}, + "fortnite-battle-royale": {595818}, + "fortnite-battle-royale-2": {595818}, + "ohare12345-s-live-ps4-broadcast": {595818}, + "super-smash-bros-u-home-run-contest-13": {595838}, + "super-smash-bros-u-home-run-contest-15": {595838}, + "super-smash-bros-u-home-run-contest-2": {595838, 595844}, + "super-smash-bros-u-home-run-contest-22": {595838, 595845}, + "super-smash-bros-u-multi-man-smash-3": {595838}, + "minecraft-survival-biedronka-i-czarny-2": {596828}, + "gramy-minecraft-jasmc-pl": {596829}, + "farcry-5-gameplay": {595818}, + "my-channel-trailer": {595818}, + "full-song-production-tutorial-aeternum": {596934}, + "blackboxglobalreview-hd": {597091}, + "tom-clancy-s-rainbow-six-siege": {597633}, + "5-new-technology-innovations-in-5": {597635}, + "5-new-technology-innovations-in-5-2": {597635}, + "how-to-play-nothing-else-matters-on": {597637}, + "rb6": {597639}, + "borderlands-2-tiny-tina-s-assault-on": {597658}, + "let-s-play-borderlands-the-pre-sequel": {597658}, + "caveman-world-mountains-of-unga-boonga": {597660}, + "for-honor-ps4-2": {597706}, + "fortnite-episode-1": {597728}, + "300-subscribers": {597750}, + "viscera-cleanup-detail-santa-s-rampage": {597755}, + "infinite-voxel-terrain-in-unity-update": {597777}, + "let-s-play-pok-mon-light-platinum": {597783}, + "video-2": {597785}, + "video-8": {597785}, + "finally": {597793}, + "let-s-play-mario-party-luigi-s-engine": {597796}, + "my-edited-video": {597799}, + "we-need-to-talk": {597800}, + "tf2-stream-2": {597811}, + "royal-thumble-tuesday-night-thumbdown": {597814}, + "beat-it-michael-jackson-cover": {597815}, + "black-ops-3": {597816}, + "call-of-duty-black-ops-3-campaign": {597819}, + "skyrim-special-edition-silent-2": {597822}, + "the-chainsmokers-everybody-hates-me": {597823}, + "experiment-glowing-1000-degree-knife-vs": {597824}, + "l1011widebody-friends-let-s-play-2": {597824}, + "call-of-duty-black-ops-4": {597825}, + "let-s-play-fallout-2-restoration-3": {597825}, + "let-s-play-fallout-2-restoration-19": {597826}, + "let-s-play-fallout-2-restoration-27": {597826}, + "2015": {597828}, + "payeer": {597829}, + "youtube-3": {597829}, + "bitcoin-5": {597830}, + "2016": {597831}, + "bitcoin-2": {597831}, + "dreamtowards": {597831}, + "surfearner": {597831}, + "100-000": {597832}, + "20000": {597833}, + "remme": {597833}, + "hycon": {597834}, + "robocraft": {597834}, + "saturday-night-baseball-with-37": {597834}, + "let-s-play-command-conquer-red-alert-9": {597835}, + "15-curiosidades-que-probablemente-ya": {597837}, + "elder-scrolls-online-road-to-level-20": {597893}, + "playerunknown-s-battlegrounds": {597894}, + "black-ops-3-fun": {597897}, + "mortal-kombat-xl-the-funniest": {597899}, + "try-not-to-laugh-2": {597899}, + "call-of-duty-advanced-warfare-domination": {597898}, + "my-live-stream-with-du-recorder-5": {597900}, + "ls-h-ppchen-halloween-stream-vom-31-10-2": {597904}, + "ls-h-ppchen-halloween-stream-vom-31-10-3": {597904}, + "how-it-feels-to-chew-5-gum-funny-8": {597905}, + "live-stream-mu-club-america-3": {597918}, + "black-death": {597927}, + "lets-play-spore-with-3": {597929}, + "true-mov-2": {597933}, + "fortnite-w-pat-the-rat-pat-the-rat": {597935}, + "jugando-pokemon-esmeralda-gba": {597935}, + "talking-about-my-channel-and-much-more-4": {597936}, + "-14": {597939}, + "-15": {597939}, + "-16": {597939}, + "-17": {597939}, + "-18": {597939}, + "-20": {597939}, + "-21": {597939}, + "-24": {597939}, + "-25": {597939}, + "-26": {597939}, + "-27": {597939}, + "-28": {597939}, + "-29": {597939}, + "-31": {597941}, + "-34": {597941}, + "-6": {597939}, + "-7": {597939}, + "10-4": {612097}, + "10-6": {612097}, + "10-7": {612097}, + "10-diy": {612097}, + "10-twitch": {612097}, + "100-5": {597909}, + "189f2f04a378c02-1": {612097}, + "2011-2": {597917}, + "2011-3": {597917}, + "2c61c818687ed09-1": {612097}, + "5-diy-4": {612097}, + "@andymcdandycdn": {640212}, + "@lividjava": {651654}, + "@mhx": {653957}, + "@tipwhatyoulike": {599792}, + "@wibbels": {612195}, + "@yisraeldov": {647416}, + "beyaz-hap-biseks-el-evlat": {657957}, + "bilgisayar-al-t-rma-s-recinde-ya-ananlar": {657957}, + "brave-como-ganhar-dinheiro-todos-os-dias": {598494}, + "c81e728d9d4c2f6-1": {598178}, + "call-of-duty-world-war-2": {597935}, + "chain-reaction": {597940}, + "commodore-64-an-lar-ve-oyunlar": {657957}, + "counter-strike-global-offensive-gameplay": {597900}, + "dead-island-riptide-co-op-walkthrough-2": {597904, 598105}, + "diy-10": {612097}, + "diy-11": {612097}, + "diy-13": {612097}, + "diy-14": {612097}, + "diy-19": {612097}, + "diy-4": {612097}, + "diy-6": {612097}, + "diy-7": {612097}, + "diy-9": {612097}, + "doktor-ve-patron-sahnesinin-haz-rl-k-ve": {657957}, + "eat-the-street": {597910}, + "fallout-4-modded": {597901}, + "fallout-4-walkthrough": {597900}, + "filmli-efecast-129-film-inde-film-inde": {657957}, + "filmli-efecast-130-ger-ek-hayatta-anime": {657957}, + "filmli-efecast-97-netflix-filmi-form-l": {657957}, + "for-honor-2": {597932}, + "for-honor-4": {597932}, + "gta-5": {597902}, + "gta-5-2": {597902}, + "helldriver-g-n-n-ekstrem-filmi": {657957}, + "hi-4": {597933}, + "hi-5": {597933}, + "hi-7": {597933}, + "kizoa-movie-video-slideshow-maker": {597900, 597932}, + "l1011widebody-friends-let-s-play-3": {598070}, + "lbry": {608276}, + "lets-play-spore-with": {597930}, + "madants": {625032}, + "mechwarrior-2-soundtrack-clan-jade": {598070}, + "milo-forbidden-conversation": {655173}, + "mobile-record": {597910}, + "mouths": {607379}, + "mp-aleyna-tilki-nin-zorla-seyrettirilen": {657957}, + "mp-atat-rk-e-eytan-diyen-yunan-as-ll": {657957}, + "mp-bah-eli-calan-avukatlar-yla-g-r-s-n": {657957}, + "mp-bu-podcast-babalar-in": {657957}, + "mp-bu-podcasti-akp-li-tan-d-klar-n-za": {657957}, + "mp-gaziantep-te-tacizle-su-lan-p-dayak": {650409}, + "mp-hatipo-lu-nun-ermeni-bir-ocu-u-canl": {657957}, + "mp-k-rt-annelerin-hdp-ye-tepkisi": {657957}, + "mp-kenan-sofuo-lu-nun-mamo-lu-na-destek": {657957}, + "mp-mamo-lu-nun-muhafazakar-g-r-nmesi": {657957}, + "mp-mhp-akp-gerginli-i": {657957}, + "mp-otob-ste-t-rkle-meyin-diye-ba-ran-svi": {657957}, + "mp-pace-i-kazand-m-diyip-21-bin-dolar": {657957}, + "mp-rusya-da-kad-nlara-tecav-zc-s-n-ld": {657957}, + "mp-s-n-rs-z-nafakan-n-kalkmas-adil-mi": {657957}, + "mp-susamam-ark-s-ve-serkan-nci-nin-ark": {657957}, + "mp-y-lmaz-zdil-in-kitap-paralar-yla-yard": {657957}, + "mp-yang-n-u-aklar-pahal-diyen-orman": {657957}, + "mp-yeni-zelanda-katliam-ndan-siyasi-rant": {657957}, + "my-edited-video-4": {597932}, + "my-live-stream-with-du-recorder": {597900}, + "my-live-stream-with-du-recorder-3": {597900}, + "new-channel-intro": {598235}, + "paladins-3": {597900}, + "popstar-sahnesi-kamera-arkas-g-r-nt-leri": {657957}, + "retro-bilgisayar-bulu-mas": {657957}, + "scp-t-rk-e-scp-002-canl-oda": {657957}, + "steep": {597900}, + "stephen-hicks-postmodernism-reprise": {655173}, + "super-smash-bros-u-brawl-co-op-event": {595841}, + "super-smash-bros-u-super-mario-u-smash": {595839}, + "super-smash-bros-u-zelda-smash-series": {595841}, + "superonline-fiber-den-efsane-kaz-k-yedim": {657957}, + "talking-about-my-channel-and-much-more-5": {597936}, + "test1337reflector356": {627814}, + "the-last-of-us-remastered-2": {597915}, + "tom-clancy-s-ghost-recon-wildlands-2": {597916}, + "tom-clancy-s-rainbow-six-siege-3": {597935}, + "wwe-2k18-with-that-guy-and-tricky": {597901}, + "yay-nc-bob-afet-kamera-arkas": {657957}, + } +} diff --git a/claimtrie/param/general.go b/claimtrie/param/general.go new file mode 100644 index 00000000..92ff06fe --- /dev/null +++ b/claimtrie/param/general.go @@ -0,0 +1,74 @@ +package param + +import "github.com/lbryio/lbcd/wire" + +type ClaimTrieParams struct { + MaxActiveDelay int32 + ActiveDelayFactor int32 + + MaxNodeManagerCacheSize int + + OriginalClaimExpirationTime int32 + ExtendedClaimExpirationTime int32 + ExtendedClaimExpirationForkHeight int32 + + MaxRemovalWorkaroundHeight int32 + + NormalizedNameForkHeight int32 + AllClaimsInMerkleForkHeight int32 +} + +var ( + ActiveParams = MainNet + + MainNet = ClaimTrieParams{ + MaxActiveDelay: 4032, + ActiveDelayFactor: 32, + MaxNodeManagerCacheSize: 32000, + + OriginalClaimExpirationTime: 262974, + ExtendedClaimExpirationTime: 2102400, + ExtendedClaimExpirationForkHeight: 400155, // https://lbry.io/news/hf1807 + MaxRemovalWorkaroundHeight: 658300, + NormalizedNameForkHeight: 539940, // targeting 21 March 2019}, https://lbry.com/news/hf1903 + AllClaimsInMerkleForkHeight: 658309, // targeting 30 Oct 2019}, https://lbry.com/news/hf1910 + } + + TestNet = ClaimTrieParams{ + MaxActiveDelay: 4032, + ActiveDelayFactor: 32, + MaxNodeManagerCacheSize: 32000, + + OriginalClaimExpirationTime: 262974, + ExtendedClaimExpirationTime: 2102400, + ExtendedClaimExpirationForkHeight: 278160, + MaxRemovalWorkaroundHeight: 1, // if you get a hash mismatch, come back to this + NormalizedNameForkHeight: 993380, + AllClaimsInMerkleForkHeight: 1198559, + } + + Regtest = ClaimTrieParams{ + MaxActiveDelay: 4032, + ActiveDelayFactor: 32, + MaxNodeManagerCacheSize: 32000, + + OriginalClaimExpirationTime: 500, + ExtendedClaimExpirationTime: 600, + ExtendedClaimExpirationForkHeight: 800, + MaxRemovalWorkaroundHeight: -1, + NormalizedNameForkHeight: 250, + AllClaimsInMerkleForkHeight: 349, + } +) + +func SetNetwork(net wire.BitcoinNet) { + + switch net { + case wire.MainNet: + ActiveParams = MainNet + case wire.TestNet3: + ActiveParams = TestNet + case wire.TestNet, wire.SimNet: // "regtest" + ActiveParams = Regtest + } +} diff --git a/claimtrie/param/takeovers.go b/claimtrie/param/takeovers.go new file mode 100644 index 00000000..7ba125ac --- /dev/null +++ b/claimtrie/param/takeovers.go @@ -0,0 +1,451 @@ +package param + +var TakeoverWorkarounds = generateTakeoverWorkarounds() + +func generateTakeoverWorkarounds() map[string]int { // TODO: the values here are unused; bools would probably be better + return map[string]int{ + "496856_HunterxHunterAMV": 496835, + "542978_namethattune1": 542429, + "543508_namethattune-5": 543306, + "546780_forecasts": 546624, + "548730_forecasts": 546780, + "551540_forecasts": 548730, + "552380_chicthinkingofyou": 550804, + "560363_takephotowithlbryteam": 559962, + "563710_test-img": 563700, + "566750_itila": 543261, + "567082_malabarismo-com-bolas-de-futebol-vs-chap": 563592, + "596860_180mphpullsthrougheurope": 596757, + "617743_vaccines": 572756, + "619609_copface-slamshandcuffedteengirlintoconcrete": 539940, + "620392_banker-exposes-satanic-elite": 597788, + "624997_direttiva-sulle-armi-ue-in-svizzera-di": 567908, + "624997_best-of-apex": 585580, + "629970_cannot-ignore-my-veins": 629914, + "633058_bio-waste-we-programmed-your-brain": 617185, + "633601_macrolauncher-overview-first-look": 633058, + "640186_its-up-to-you-and-i-2019": 639116, + "640241_tor-eas-3-20": 592645, + "640522_seadoxdark": 619531, + "640617_lbry-przewodnik-1-instalacja": 451186, + "640623_avxchange-2019-the-next-netflix-spotify": 606790, + "640684_algebra-introduction": 624152, + "640684_a-high-school-math-teacher-does-a": 600885, + "640684_another-random-life-update": 600884, + "640684_who-is-the-taylor-series-for": 600882, + "640684_tedx-talk-released": 612303, + "640730_e-mental": 615375, + "641143_amiga-1200-bespoke-virgin-cinema": 623542, + "641161_dreamscape-432-omega": 618894, + "641162_2019-topstone-carbon-force-etap-axs-bike": 639107, + "641186_arin-sings-big-floppy-penis-live-jazz-2": 638904, + "641421_edward-snowden-on-bitcoin-and-privacy": 522729, + "641421_what-is-libra-facebook-s-new": 598236, + "641421_what-are-stablecoins-counter-party-risk": 583508, + "641421_anthony-pomp-pompliano-discusses-crypto": 564416, + "641421_tim-draper-crypto-invest-summit-2019": 550329, + "641421_mass-adoption-and-what-will-it-take-to": 549781, + "641421_dragonwolftech-youtube-channel-trailer": 567128, + "641421_naomi-brockwell-s-weekly-crypto-recap": 540006, + "641421_blockchain-based-youtube-twitter": 580809, + "641421_andreas-antonopoulos-on-privacy-privacy": 533522, + "641817_mexico-submits-and-big-tech-worsens": 582977, + "641817_why-we-need-travel-bans": 581354, + "641880_censored-by-patreon-bitchute-shares": 482460, + "641880_crypto-wonderland": 485218, + "642168_1-diabolo-julio-cezar-16-cbmcp-freestyle": 374999, + "642314_tough-students": 615780, + "642697_gamercauldronep2": 642153, + "643406_the-most-fun-i-ve-had-in-a-long-time": 616506, + "643893_spitshine69-and-uk-freedom-audits": 616876, + "644480_my-mum-getting-attacked-a-duck": 567624, + "644486_the-cryptocurrency-experiment": 569189, + "644486_tag-you-re-it": 558316, + "644486_orange-county-mineral-society-rock-and": 397138, + "644486_sampling-with-the-gold-rush-nugget": 527960, + "644562_september-15-21-a-new-way-of-doing": 634792, + "644562_july-week-3-collective-frequency-general": 607942, + "644562_september-8-14-growing-up-general": 630977, + "644562_august-4-10-collective-frequency-general": 612307, + "644562_august-11-17-collective-frequency": 617279, + "644562_september-1-7-gentle-wake-up-call": 627104, + "644607_no-more-lol": 643497, + "644607_minion-masters-who-knew": 641313, + "645236_danganronpa-3-the-end-of-hope-s-peak": 644153, + "645348_captchabot-a-discord-bot-to-protect-your": 592810, + "645701_the-xero-hour-saint-greta-of-thunberg": 644081, + "645701_batman-v-superman-theological-notions": 590189, + "645918_emacs-is-great-ep-0-init-el-from-org": 575666, + "645918_emacs-is-great-ep-1-packages": 575666, + "645918_emacs-is-great-ep-40-pt-2-hebrew": 575668, + "645923_nasal-snuff-review-osp-batch-2": 575658, + "645923_why-bit-coin": 575658, + "645929_begin-quest": 598822, + "645929_filthy-foe": 588386, + "645929_unsanitary-snow": 588386, + "645929_famispam-1-music-box": 588386, + "645929_running-away": 598822, + "645931_my-beloved-chris-madsen": 589114, + "645931_space-is-consciousness-chris-madsen": 589116, + "645947_gasifier-rocket-stove-secondary-burn": 590595, + "645949_mouse-razer-abyssus-v2-e-mousepad": 591139, + "645949_pr-temporada-2018-league-of-legends": 591138, + "645949_windows-10-build-9901-pt-br": 591137, + "645949_abrindo-pacotes-do-festival-lunar-2018": 591139, + "645949_unboxing-camisetas-personalizadas-play-e": 591138, + "645949_abrindo-envelopes-do-festival-lunar-2017": 591138, + "645951_grub-my-grub-played-guruku-tersayang": 618033, + "645951_ismeeltimepiece": 618038, + "645951_thoughts-on-doom": 596485, + "645951_thoughts-on-god-of-war-about-as-deep-as": 596485, + "645956_linux-lite-3-6-see-what-s-new": 645195, + "646191_kahlil-gibran-the-prophet-part-1": 597637, + "646551_crypto-market-crash-should-you-sell-your": 442613, + "646551_live-crypto-trading-and-market-analysis": 442615, + "646551_5-reasons-trading-is-always-better-than": 500850, + "646551_digitex-futures-dump-panic-selling-or": 568065, + "646552_how-to-install-polarr-on-kali-linux-bynp": 466235, + "646586_electoral-college-kids-civics-lesson": 430818, + "646602_grapes-full-90-minute-watercolour": 537108, + "646602_meizu-mx4-the-second-ubuntu-phone": 537109, + "646609_how-to-set-up-the-ledger-nano-x": 569992, + "646609_how-to-buy-ethereum": 482354, + "646609_how-to-install-setup-the-exodus-multi": 482356, + "646609_how-to-manage-your-passwords-using": 531987, + "646609_cryptodad-s-live-q-a-friday-may-3rd-2019": 562303, + "646638_resident-evil-ada-chapter-5-final": 605612, + "646639_taurus-june-2019-career-love-tarot": 586910, + "646652_digital-bullpen-ep-5-building-a-digital": 589274, + "646661_sunlight": 591076, + "646661_grasp-lab-nasa-open-mct-series": 589414, + "646663_bunnula-s-creepers-tim-pool-s-beanie-a": 599669, + "646663_bunnula-music-hey-ya-by-outkast": 605685, + "646663_bunnula-tv-s-music-television-eunoia": 644437, + "646663_the-pussy-centipede-40-sneakers-and": 587265, + "646663_bunnula-reacts-ashton-titty-whitty": 596988, + "646677_filip-reviews-jeromes-dream-cataracts-so": 589751, + "646691_fascism-and-its-mobilizing-passions": 464342, + "646692_hsb-color-layers-action-for-adobe": 586533, + "646692_master-colorist-action-pack-extracting": 631830, + "646693_how-to-protect-your-garden-from-animals": 588476, + "646693_gardening-for-the-apocalypse-epic": 588472, + "646693_my-first-bee-hive-foundationless-natural": 588469, + "646693_dragon-fruit-and-passion-fruit-planting": 588470, + "646693_installing-my-first-foundationless": 588469, + "646705_first-naza-fpv": 590411, + "646717_first-burning-man-2019-detour-034": 630247, + "646717_why-bob-marley-was-an-idiot-test-driving": 477558, + "646717_we-are-addicted-to-gambling-ufc-207-w": 481398, + "646717_ghetto-swap-meet-selling-storage-lockers": 498291, + "646738_1-kings-chapter-7-summary-and-what-god": 586599, + "646814_brand-spanking-new-junior-high-school": 592378, + "646814_lupe-fiasco-freestyle-at-end-of-the-weak": 639535, + "646824_how-to-one-stroke-painting-doodles-mixed": 592404, + "646824_acrylic-pouring-landscape-with-a-tree": 592404, + "646824_how-to-make-a-diy-concrete-paste-planter": 595976, + "646824_how-to-make-a-rustic-sand-planter-sand": 592404, + "646833_3-day-festival-at-the-galilee-lake-and": 592842, + "646833_rainbow-circle-around-the-noon-sun-above": 592842, + "646833_energetic-self-control-demonstration": 623811, + "646833_bees-congregating": 592842, + "646856_formula-offroad-honefoss-sunday-track2": 592872, + "646862_h3video1-dc-vs-mb-1": 593237, + "646862_h3video1-iwasgoingto-load-up-gmod-but": 593237, + "646883_watch-this-game-developer-make-a-video": 592593, + "646883_how-to-write-secure-javascript": 592593, + "646883_blockchain-technology-explained-2-hour": 592593, + "646888_fl-studio-bits": 608155, + "646914_andy-s-shed-live-s03e02-the-longest": 592200, + "646914_gpo-telephone-776-phone-restoration": 592201, + "646916_toxic-studios-co-stream-pubg": 597126, + "646916_hyperlapse-of-prague-praha-from-inside": 597109, + "646933_videobits-1": 597378, + "646933_clouds-developing-daytime-8": 597378, + "646933_slechtvalk-in-watertoren-bodegraven": 597378, + "646933_timelapse-maansverduistering-16-juli": 605880, + "646933_startrails-27": 597378, + "646933_passing-clouds-daytime-3": 597378, + "646940_nerdgasm-unboxing-massive-playing-cards": 597421, + "646946_debunking-cops-volume-3-the-murder-of": 630570, + "646961_kingsong-ks16x-electric-unicycle-250km": 636725, + "646968_wild-mountain-goats-amazing-rock": 621940, + "646968_no-shelter-backcountry-camping-in": 621940, + "646968_can-i-live-in-this-through-winter-lets": 645750, + "646968_why-i-wear-a-chest-rig-backcountry-or": 621940, + "646989_marc-ivan-o-gorman-promo-producer-editor": 645656, + "647045_@moraltis": 646367, + "647045_moraltis-twitch-highlights-first-edit": 646368, + "647075_the-3-massive-tinder-convo-mistakes": 629464, + "647075_how-to-get-friend-zoned-via-text": 592298, + "647075_don-t-do-this-on-tinder": 624591, + "647322_world-of-tanks-7-kills": 609905, + "647322_the-tier-6-auto-loading-swedish-meatball": 591338, + "647416_hypnotic-soundscapes-garden-of-the": 596923, + "647416_hypnotic-soundscapes-the-cauldron-sacred": 596928, + "647416_schumann-resonance-to-theta-sweep": 596920, + "647416_conversational-indirect-hypnosis-why": 596913, + "647493_mimirs-brunnr": 590498, + "648143_live-ita-completiamo-the-evil-within-2": 646568, + "648203_why-we-love-people-that-hurt-us": 591128, + "648203_i-didn-t-like-my-baby-and-considered": 591128, + "648220_trade-talk-001-i-m-a-vlogger-now-fielder": 597303, + "648220_vise-restoration-record-no-6-vise": 597303, + "648540_amv-reign": 571863, + "648540_amv-virus": 571863, + "648588_audial-drift-(a-journey-into-sound)": 630217, + "648616_quick-zbrush-tip-transpose-master-scale": 463205, + "648616_how-to-create-3d-horns-maya-to-zbrush-2": 463205, + "648815_arduino-based-cartridge-game-handheld": 593252, + "648815_a-maze-update-3-new-game-modes-amazing": 593252, + "649209_denmark-trip": 591428, + "649209_stunning-4k-drone-footage": 591428, + "649215_how-to-create-a-channel-and-publish-a": 414908, + "649215_lbryclass-11-how-to-get-your-deposit": 632420, + "649543_spring-break-madness-at-universal": 599698, + "649921_navegador-brave-navegador-da-web-seguro": 649261, + "650191_stream-intro": 591301, + "650946_platelet-chan-fan-art": 584601, + "650946_aqua-fanart": 584601, + "650946_virginmedia-stores-password-in-plain": 619537, + "650946_running-linux-on-android-teaser": 604441, + "650946_hatsune-miku-ievan-polka": 600126, + "650946_digital-security-and-privacy-2-and-a-new": 600135, + "650993_my-editorial-comment-on-recent-youtube": 590305, + "650993_drive-7-18-2018": 590305, + "651011_old-world-put-on-realm-realms-gg": 591899, + "651011_make-your-own-soundboard-with-autohotkey": 591899, + "651011_ark-survival-https-discord-gg-ad26xa": 637680, + "651011_minecraft-featuring-seus-8-just-came-4": 596488, + "651057_found-footage-bikinis-at-the-beach-with": 593586, + "651057_found-footage-sexy-mom-a-mink-stole": 593586, + "651067_who-are-the-gentiles-gomer": 597094, + "651067_take-back-the-kingdom-ep-2-450-million": 597094, + "651067_mmxtac-implemented-footstep-sounds-and": 597094, + "651067_dynasoul-s-blender-to-unreal-animated": 597094, + "651103_calling-a-scammer-syntax-error": 612532, + "651103_quick-highlight-of-my-day": 647651, + "651103_calling-scammers-and-singing-christmas": 612531, + "651109_@livingtzm": 637322, + "651109_living-tzm-juuso-from-finland-september": 643412, + "651373_se-voc-rir-ou-sorrir-reinicie-o-v-deo": 649302, + "651476_what-is-pagan-online-polished-new-arpg": 592157, + "651476_must-have-elder-scrolls-online-addons": 592156, + "651476_who-should-play-albion-online": 592156, + "651730_person-detection-with-keras-tensorflow": 621276, + "651730_youtube-censorship-take-two": 587249, + "651730_new-red-tail-shark-and-two-silver-sharks": 587251, + "651730_around-auckland": 587250, + "651730_humanism-in-islam": 587250, + "651730_tigers-at-auckland-zoo": 587250, + "651730_gravity-demonstration": 587250, + "651730_copyright-question": 587249, + "651730_uberg33k-the-ultimate-software-developer": 599522, + "651730_chl-e-swarbrick-auckland-mayoral": 587250, + "651730_code-reviews": 587249, + "651730_raising-robots": 587251, + "651730_teaching-python": 587250, + "651730_kelly-tarlton-2016": 587250, + "652172_where-is-everything": 589491, + "652172_some-guy-and-his-camera": 617062, + "652172_practical-information-pt-1": 589491, + "652172_latent-vibrations": 589491, + "652172_maldek-compilation": 589491, + "652444_thank-you-etika-thank-you-desmond": 652121, + "652611_plants-vs-zombies-gw2-20190827183609": 624339, + "652611_wolfenstein-the-new-order-playthrough-6": 650299, + "652887_a-codeigniter-cms-open-source-download": 652737, + "652966_@pokesadventures": 632391, + "653009_flat-earth-uk-convention-is-a-bust": 585786, + "653009_flat-earth-reset-flat-earth-money-tree": 585786, + "653011_veil-of-thorns-dispirit-brutal-leech-3": 652475, + "653069_being-born-after-9-11": 632218, + "653069_8-years-on-youtube-what-it-has-done-for": 637130, + "653069_answering-questions-how-original": 521447, + "653069_talking-about-my-first-comedy-stand-up": 583450, + "653069_doing-push-ups-in-public": 650920, + "653069_vlog-extra": 465997, + "653069_crying-myself": 465997, + "653069_xbox-rejection": 465992, + "653354_msps-how-to-find-a-linux-job-where-no": 642537, + "653354_windows-is-better-than-linux-vlog-it-and": 646306, + "653354_luke-smith-is-wrong-about-everything": 507717, + "653354_advice-for-those-starting-out-in-tech": 612452, + "653354_treating-yourself-to-make-studying-more": 623561, + "653354_lpi-linux-essential-dns-tools-vlog-what": 559464, + "653354_is-learning-linux-worth-it-in-2019-vlog": 570886, + "653354_huawei-linux-and-cellphones-in-2019-vlog": 578501, + "653354_how-to-use-webmin-to-manage-linux": 511507, + "653354_latency-concurrency-and-the-best-value": 596857, + "653354_how-to-use-the-pomodoro-method-in-it": 506632, + "653354_negotiating-compensation-vlog-it-and": 542317, + "653354_procedural-goals-vs-outcome-goals-vlog": 626785, + "653354_intro-to-raid-understanding-how-raid": 529341, + "653354_smokeping": 574693, + "653354_richard-stallman-should-not-be-fired": 634928, + "653354_unusual-or-specialty-certifications-vlog": 620146, + "653354_gratitude-and-small-projects-vlog-it": 564900, + "653354_why-linux-on-the-smartphone-is-important": 649543, + "653354_opportunity-costs-vlog-it-devops-career": 549708, + "653354_double-giveaway-lpi-class-dates-and": 608129, + "653354_linux-on-the-smartphone-in-2019-librem": 530426, + "653524_celtic-folk-music-full-live-concert-mps": 589762, + "653745_aftermath-of-the-mac": 592768, + "653745_b-c-a-glock-17-threaded-barrel": 592770, + "653800_middle-earth-shadow-of-mordor-by": 590229, + "654079_tomand-jeremy-chirs45": 614296, + "654096_achamos-carteira-com-grana-olha-o-que": 466262, + "654096_viagem-bizarra-e-cansativa-ao-nordeste": 466263, + "654096_tedio-na-tailandia-limpeza-de-area": 466265, + "654425_schau-bung-2014-in-windischgarsten": 654410, + "654425_mitternachtseinlage-ball-rk": 654410, + "654425_zugabe-ball-rk-windischgarsten": 654412, + "654722_skytrain-in-korea": 463145, + "654722_luwak-coffee-the-shit-coffee": 463155, + "654722_puppet-show-in-bangkok-thailand": 462812, + "654722_kyaito-market-myanmar": 462813, + "654724_wipeout-zombies-bo3-custom-zombies-1st": 589569, + "654724_the-street-bo3-custom-zombies": 589544, + "654880_wwii-airsoft-pow": 586968, + "654880_dueling-geese-fight-to-the-death": 586968, + "654880_wwii-airsoft-torgau-raw-footage-part4": 586968, + "655173_april-2019-q-and-a": 554032, + "655173_the-meaning-and-reality-of-individual": 607892, + "655173_steven-pinker-progress-despite": 616984, + "655173_we-make-stories-out-of-totem-poles": 549090, + "655173_jamil-jivani-author-of-why-young-men": 542035, + "655173_commentaries-on-jb-peterson-rebel-wisdom": 528898, + "655173_auckland-clip-4-on-cain-and-abel": 629242, + "655173_peterson-vs-zizek-livestream-tickets": 545285, + "655173_auckland-clip-3-the-dawning-of-the-moral": 621154, + "655173_religious-belief-and-the-enlightenment": 606269, + "655173_auckland-lc-highlight-1-the-presumption": 565783, + "655173_q-a-sir-roger-scruton-dr-jordan-b": 544184, + "655173_cancellation-polish-national-foundation": 562529, + "655173_the-coddling-of-the-american-mind-haidt": 440185, + "655173_02-harris-weinstein-peterson-discussion": 430896, + "655173_jordan-peterson-threatens-everything-of": 519737, + "655173_on-claiming-belief-in-god-commentary": 581738, + "655173_how-to-make-the-world-better-really-with": 482317, + "655173_quillette-discussion-with-founder-editor": 413749, + "655173_jb-peterson-on-free-thought-and-speech": 462849, + "655173_marxism-zizek-peterson-official-video": 578453, + "655173_patreon-problem-solution-dave-rubin-dr": 490394, + "655173_next-week-st-louis-salt-lake-city": 445933, + "655173_conversations-with-john-anderson-jordan": 529981, + "655173_nz-australia-12-rules-tour-next-2-weeks": 518649, + "655173_a-call-to-rebellion-for-ontario-legal": 285451, + "655173_2016-personality-lecture-12": 578465, + "655173_on-the-vital-necessity-of-free-speech": 427404, + "655173_2017-01-23-social-justice-freedom-of": 578465, + "655173_discussion-sam-harris-the-idw-and-the": 423332, + "655173_march-2018-patreon-q-a": 413749, + "655173_take-aim-even-badly": 490395, + "655173_jp-f-wwbgo6a2w": 539940, + "655173_patreon-account-deletion": 503477, + "655173_canada-us-europe-tour-august-dec-2018": 413749, + "655173_leaders-myth-reality-general-stanley": 514333, + "655173_jp-ifi5kkxig3s": 539940, + "655173_documentary-a-glitch-in-the-matrix-david": 413749, + "655173_2017-08-14-patreon-q-and-a": 285451, + "655173_postmodernism-history-and-diagnosis": 285451, + "655173_23-minutes-from-maps-of-meaning-the": 413749, + "655173_milo-forbidden-conversation": 578493, + "655173_jp-wnjbasba-qw": 539940, + "655173_uk-12-rules-tour-october-and-november": 462849, + "655173_2015-maps-of-meaning-10-culture-anomaly": 578465, + "655173_ayaan-hirsi-ali-islam-mecca-vs-medina": 285452, + "655173_jp-f9393el2z1i": 539940, + "655173_campus-indoctrination-the-parasitization": 285453, + "655173_jp-owgc63khcl8": 539940, + "655173_the-death-and-resurrection-of-christ-a": 413749, + "655173_01-harris-weinstein-peterson-discussion": 430896, + "655173_enlightenment-now-steven-pinker-jb": 413749, + "655173_the-lindsay-shepherd-affair-update": 413749, + "655173_jp-g3fwumq5k8i": 539940, + "655173_jp-evvs3l-abv4": 539940, + "655173_former-australian-deputy-pm-john": 413750, + "655173_message-to-my-korean-readers-90-seconds": 477424, + "655173_jp--0xbomwjkgm": 539940, + "655173_ben-shapiro-jordan-peterson-and-a-12": 413749, + "655173_jp-91jwsb7zyhw": 539940, + "655173_deconstruction-the-lindsay-shepherd": 299272, + "655173_september-patreon-q-a": 285451, + "655173_jp-2c3m0tt5kce": 539940, + "655173_australia-s-john-anderson-dr-jordan-b": 413749, + "655173_jp-hdrlq7dpiws": 539940, + "655173_stephen-hicks-postmodernism-reprise": 578480, + "655173_october-patreon-q-a": 285451, + "655173_an-animated-intro-to-truth-order-and": 413749, + "655173_jp-bsh37-x5rny": 539940, + "655173_january-2019-q-a": 503477, + "655173_comedians-canaries-and-coalmines": 498586, + "655173_the-democrats-apology-and-promise": 465433, + "655173_jp-s4c-jodptn8": 539940, + "655173_2014-personality-lecture-16-extraversion": 578465, + "655173_dr-jordan-b-peterson-on-femsplainers": 490395, + "655173_higher-ed-our-cultural-inflection-point": 527291, + "655173_archetype-reality-friendship-and": 519736, + "655173_sir-roger-scruton-dr-jordan-b-peterson": 490395, + "655173_jp-cf2nqmqifxc": 539940, + "655173_penguin-uk-12-rules-for-life": 413749, + "655173_march-2019-q-and-a": 537138, + "655173_jp-ne5vbomsqjc": 539940, + "655173_dublin-london-harris-murray-new-usa-12": 413749, + "655173_12-rules-12-cities-tickets-now-available": 413749, + "655173_jp-j9j-bvdrgdi": 539940, + "655173_responsibility-conscience-and-meaning": 499123, + "655173_04-harris-murray-peterson-discussion": 436678, + "655173_jp-ayhaz9k008q": 539940, + "655173_with-jocko-willink-the-catastrophe-of": 490395, + "655173_interview-with-the-grievance-studies": 501296, + "655173_russell-brand-jordan-b-peterson-under": 413750, + "655173_goodbye-to-patreon": 496771, + "655173_revamped-podcast-announcement-with": 540943, + "655173_swedes-want-to-know": 285453, + "655173_auckland-clip-2-the-four-fundamental": 607892, + "655173_jp-dtirzqmgbdm": 539940, + "655173_political-correctness-a-force-for-good-a": 413750, + "655173_sean-plunket-full-interview-new-zealand": 597638, + "655173_q-a-the-meaning-and-reality-of": 616984, + "655173_lecture-and-q-a-with-jordan-peterson-the": 413749, + "655173_2017-personality-07-carl-jung-and-the": 578465, + "655173_nina-paley-animator-extraordinaire": 413750, + "655173_truth-as-the-antidote-to-suffering-with": 455127, + "655173_bishop-barron-word-on-fire": 599814, + "655173_zizek-vs-peterson-april-19": 527291, + "655173_revamped-podcast-with-westwood-one": 540943, + "655173_2016-11-19-university-of-toronto-free": 578465, + "655173_jp-1emrmtrj5jc": 539940, + "655173_who-is-joe-rogan-with-jordan-peterson": 585578, + "655173_who-dares-say-he-believes-in-god": 581738, + "655252_games-with-live2d": 589978, + "655252_kaenbyou-rin-live2d": 589978, + "655374_steam-groups-are-crazy": 607590, + "655379_asmr-captain-falcon-happily-beats-you-up": 644574, + "655379_pixel-art-series-5-link-holding-the": 442952, + "655379_who-can-cross-the-planck-length-the-hero": 610830, + "655379_ssbb-the-yoshi-grab-release-crash": 609747, + "655379_tas-captain-falcon-s-bizarre-adventure": 442958, + "655379_super-smash-bros-in-360-test": 442963, + "655379_what-if-luigi-was-b-u-f-f": 442971, + "655803_sun-time-lapse-test-7": 610634, + "655952_upper-build-complete": 591728, + "656758_cryptocurrency-awareness-adoption-the": 541770, + "656829_3d-printing-technologies-comparison": 462685, + "656829_3d-printing-for-everyone": 462685, + "657052_tni-punya-ilmu-kanuragan-gaya-baru": 657045, + "657052_papa-sunimah-nelpon-sri-utami-emon": 657045, + "657274_rapforlife-4-win": 656856, + "657274_bizzilion-proof-of-withdrawal": 656856, + "657420_quick-drawing-prince-tribute-colored": 605630, + "657453_white-boy-tom-mcdonald-facts": 597169, + "657453_is-it-ok-to-look-when-you-with-your-girl": 610508, + "657584_need-for-speed-ryzen-5-1600-gtx-1050-ti": 657161, + "657584_quantum-break-ryzen-5-1600-gtx-1050-ti-4": 657161, + "657584_nightcore-legends-never-die": 657161, + "657706_mtb-enduro-ferragosto-2019-sestri": 638904, + "657706_warface-free-for-all": 638908, + "657782_nick-warren-at-loveland-but-not-really": 444299, + "658098_le-temps-nous-glisse-entre-les-doigts": 600099, + } +} diff --git a/claimtrie/temporal/repo.go b/claimtrie/temporal/repo.go new file mode 100644 index 00000000..6b2df037 --- /dev/null +++ b/claimtrie/temporal/repo.go @@ -0,0 +1,9 @@ +package temporal + +// Repo defines APIs for Temporal to access persistence layer. +type Repo interface { + SetNodesAt(names [][]byte, heights []int32) error + NodesAt(height int32) ([][]byte, error) + Close() error + Flush() error +} diff --git a/claimtrie/temporal/temporalrepo/memory.go b/claimtrie/temporal/temporalrepo/memory.go new file mode 100644 index 00000000..0c1c8591 --- /dev/null +++ b/claimtrie/temporal/temporalrepo/memory.go @@ -0,0 +1,45 @@ +package temporalrepo + +type Memory struct { + cache map[int32]map[string]bool +} + +func NewMemory() *Memory { + return &Memory{ + cache: map[int32]map[string]bool{}, + } +} + +func (repo *Memory) SetNodesAt(names [][]byte, heights []int32) error { + + for i, height := range heights { + c, ok := repo.cache[height] + if !ok { + c = map[string]bool{} + repo.cache[height] = c + } + name := string(names[i]) + c[name] = true + } + + return nil +} + +func (repo *Memory) NodesAt(height int32) ([][]byte, error) { + + var names [][]byte + + for name := range repo.cache[height] { + names = append(names, []byte(name)) + } + + return names, nil +} + +func (repo *Memory) Close() error { + return nil +} + +func (repo *Memory) Flush() error { + return nil +} diff --git a/claimtrie/temporal/temporalrepo/pebble.go b/claimtrie/temporal/temporalrepo/pebble.go new file mode 100644 index 00000000..f7b083dc --- /dev/null +++ b/claimtrie/temporal/temporalrepo/pebble.go @@ -0,0 +1,87 @@ +package temporalrepo + +import ( + "bytes" + "encoding/binary" + + "github.com/pkg/errors" + + "github.com/cockroachdb/pebble" +) + +type Pebble struct { + db *pebble.DB +} + +func NewPebble(path string) (*Pebble, error) { + + db, err := pebble.Open(path, &pebble.Options{Cache: pebble.NewCache(16 << 20), MaxOpenFiles: 2000}) + repo := &Pebble{db: db} + + return repo, errors.Wrapf(err, "unable to open %s", path) +} + +func (repo *Pebble) SetNodesAt(name [][]byte, heights []int32) error { + + // key format: height(4B) + 0(1B) + name(varable length) + key := bytes.NewBuffer(nil) + batch := repo.db.NewBatch() + defer batch.Close() + for i, name := range name { + key.Reset() + binary.Write(key, binary.BigEndian, heights[i]) + binary.Write(key, binary.BigEndian, byte(0)) + key.Write(name) + + err := batch.Set(key.Bytes(), nil, pebble.NoSync) + if err != nil { + return errors.Wrap(err, "in set") + } + } + return errors.Wrap(batch.Commit(pebble.NoSync), "in commit") +} + +func (repo *Pebble) NodesAt(height int32) ([][]byte, error) { + + prefix := bytes.NewBuffer(nil) + binary.Write(prefix, binary.BigEndian, height) + binary.Write(prefix, binary.BigEndian, byte(0)) + + end := bytes.NewBuffer(nil) + binary.Write(end, binary.BigEndian, height) + binary.Write(end, binary.BigEndian, byte(1)) + + prefixIterOptions := &pebble.IterOptions{ + LowerBound: prefix.Bytes(), + UpperBound: end.Bytes(), + } + + var names [][]byte + + iter := repo.db.NewIter(prefixIterOptions) + for iter.First(); iter.Valid(); iter.Next() { + // Skipping the first 5 bytes (height and a null byte), we get the name. + name := make([]byte, len(iter.Key())-5) + copy(name, iter.Key()[5:]) // iter.Key() reuses its buffer + names = append(names, name) + } + + return names, errors.Wrap(iter.Close(), "in close") +} + +func (repo *Pebble) Close() error { + + err := repo.db.Flush() + if err != nil { + // if we fail to close are we going to try again later? + return errors.Wrap(err, "on flush") + } + + err = repo.db.Close() + return errors.Wrap(err, "on close") +} + +func (repo *Pebble) Flush() error { + _, err := repo.db.AsyncFlush() + return err +} diff --git a/claimtrie/temporal/temporalrepo/temporalrepo_test.go b/claimtrie/temporal/temporalrepo/temporalrepo_test.go new file mode 100644 index 00000000..090dc187 --- /dev/null +++ b/claimtrie/temporal/temporalrepo/temporalrepo_test.go @@ -0,0 +1,80 @@ +package temporalrepo + +import ( + "testing" + + "github.com/lbryio/lbcd/claimtrie/temporal" + + "github.com/stretchr/testify/require" +) + +func TestMemory(t *testing.T) { + + repo := NewMemory() + testTemporalRepo(t, repo) +} + +func TestPebble(t *testing.T) { + + repo, err := NewPebble(t.TempDir()) + require.NoError(t, err) + + testTemporalRepo(t, repo) +} + +func testTemporalRepo(t *testing.T, repo temporal.Repo) { + + r := require.New(t) + + nameA := []byte("a") + nameB := []byte("b") + nameC := []byte("c") + + testcases := []struct { + name []byte + heights []int32 + }{ + {nameA, []int32{1, 3, 2}}, + {nameA, []int32{2, 3}}, + {nameB, []int32{5, 4}}, + {nameB, []int32{5, 1}}, + {nameC, []int32{4, 3, 8}}, + } + + for _, i := range testcases { + names := make([][]byte, 0, len(i.heights)) + for range i.heights { + names = append(names, i.name) + } + err := repo.SetNodesAt(names, i.heights) + r.NoError(err) + } + + // a: 1, 2, 3 + // b: 1, 5, 4 + // c: 4, 3, 8 + + names, err := repo.NodesAt(2) + r.NoError(err) + r.ElementsMatch([][]byte{nameA}, names) + + names, err = repo.NodesAt(5) + r.NoError(err) + r.ElementsMatch([][]byte{nameB}, names) + + names, err = repo.NodesAt(8) + r.NoError(err) + r.ElementsMatch([][]byte{nameC}, names) + + names, err = repo.NodesAt(1) + r.NoError(err) + r.ElementsMatch([][]byte{nameA, nameB}, names) + + names, err = repo.NodesAt(4) + r.NoError(err) + r.ElementsMatch([][]byte{nameB, nameC}, names) + + names, err = repo.NodesAt(3) + r.NoError(err) + r.ElementsMatch([][]byte{nameA, nameC}, names) +} -- 2.45.2 From 0c5f94420ad0e0ee42fc3ea773430632ce33ba88 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 27 Jul 2021 09:33:10 -0400 Subject: [PATCH 349/459] [lbry] print out memory usage periodically --- lbcd.go | 2 ++ resourceLogging.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 resourceLogging.go diff --git a/lbcd.go b/lbcd.go index 1b2ad72d..ec6ef086 100644 --- a/lbcd.go +++ b/lbcd.go @@ -150,6 +150,8 @@ func btcdMain(serverChan chan<- *server) error { param.SetNetwork(activeNetParams.Params.Net) // prep the claimtrie params + go logMemoryUsage() + // Create server and start it. server, err := newServer(cfg.Listeners, cfg.AgentBlacklist, cfg.AgentWhitelist, db, activeNetParams.Params, interrupt) diff --git a/resourceLogging.go b/resourceLogging.go new file mode 100644 index 00000000..d6e92051 --- /dev/null +++ b/resourceLogging.go @@ -0,0 +1,74 @@ +package main + +import ( + "fmt" + + "github.com/shirou/gopsutil/v3/disk" + "github.com/shirou/gopsutil/v3/mem" + "github.com/shirou/gopsutil/v3/process" + + "os" + "path/filepath" + "time" +) + +func toGB(n uint64) float64 { + return float64(n) / 1024.0 / 1024.0 / 1024.0 +} + +func dirSize(path string) (int64, error) { + var size int64 + err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + size += info.Size() + } + return err + }) + return size, err +} + +func logMemoryUsage() { + last := "" + tick := time.NewTicker(40 * time.Second) + for range tick.C { + m, err := mem.VirtualMemory() + if err != nil { + btcdLog.Warnf("When reading memory size: %s", err.Error()) + continue + } + + d, err := disk.Usage(cfg.DataDir) + if err != nil { + btcdLog.Warnf("When reading disk usage: %s", err.Error()) + continue + } + + p, err := process.NewProcess(int32(os.Getpid())) + if err != nil { + btcdLog.Warnf("When reading process: %s", err.Error()) + continue + } + + m2, err := p.MemoryInfo() + if err != nil { + btcdLog.Warnf("When reading memory info: %s", err.Error()) + continue + } + + ds, err := dirSize(cfg.DataDir) + if err != nil { + btcdLog.Debugf("When reading directory: %s", err.Error()) + continue + } + + cur := fmt.Sprintf("RAM: using %.1f GB with %.1f available, DISK: using %.1f GB with %.1f available", + toGB(m2.RSS), toGB(m.Available), toGB(uint64(ds)), toGB(d.Free)) + if cur != last { + btcdLog.Infof(cur) + last = cur + } + } +} -- 2.45.2 From 6834591d526b89fe58e79416697f5dae91d21f47 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 30 Jul 2021 16:24:14 -0400 Subject: [PATCH 350/459] [lbry] rpc: support claim related methods --- btcjson/chainsvrresults.go | 7 + btcjson/chainsvrresults_test.go | 2 +- btcjson/claimcmds.go | 97 +++++++++ btcjson/help.go | 6 + btcjson/jsonrpc.go | 8 +- rpcclaimtrie.go | 352 ++++++++++++++++++++++++++++++++ rpcserverhelp.go | 84 ++++++++ 7 files changed, 553 insertions(+), 3 deletions(-) create mode 100644 btcjson/claimcmds.go create mode 100644 rpcclaimtrie.go diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index e658cccf..e82a14bc 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -298,6 +298,8 @@ type GetBlockTemplateResult struct { // Block proposal from BIP 0023. Capabilities []string `json:"capabilities,omitempty"` RejectReasion string `json:"reject-reason,omitempty"` + + ClaimTrieHash string `json:"claimtrie"` } // GetMempoolEntryResult models the data returned from the getmempoolentry's @@ -430,6 +432,9 @@ type ScriptPubKeyResult struct { Hex string `json:"hex,omitempty"` ReqSigs int32 `json:"reqSigs,omitempty"` Type string `json:"type"` + SubType string `json:"subtype"` + IsClaim bool `json:"isclaim"` + IsSupport bool `json:"issupport"` Addresses []string `json:"addresses,omitempty"` } @@ -588,6 +593,8 @@ func (v *Vin) MarshalJSON() ([]byte, error) { type PrevOut struct { Addresses []string `json:"addresses,omitempty"` Value float64 `json:"value"` + IsClaim bool `json:"isclaim"` + IsSupport bool `json:"issupport"` } // VinPrevOut is like Vin except it includes PrevOut. It is used by searchrawtransaction diff --git a/btcjson/chainsvrresults_test.go b/btcjson/chainsvrresults_test.go index bb04a003..cbdca095 100644 --- a/btcjson/chainsvrresults_test.go +++ b/btcjson/chainsvrresults_test.go @@ -70,7 +70,7 @@ func TestChainSvrCustomResults(t *testing.T) { }, Sequence: 4294967295, }, - expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"prevOut":{"addresses":["addr1"],"value":0},"sequence":4294967295}`, + expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"prevOut":{"addresses":["addr1"],"value":0,"isclaim":false,"issupport":false},"sequence":4294967295}`, }, } diff --git a/btcjson/claimcmds.go b/btcjson/claimcmds.go new file mode 100644 index 00000000..8f50fc0c --- /dev/null +++ b/btcjson/claimcmds.go @@ -0,0 +1,97 @@ +package btcjson + +func init() { + // No special flags for commands in this file. + flags := UsageFlag(0) + + MustRegisterCmd("getchangesinblock", (*GetChangesInBlockCmd)(nil), flags) + MustRegisterCmd("getclaimsforname", (*GetClaimsForNameCmd)(nil), flags) + MustRegisterCmd("getclaimsfornamebyid", (*GetClaimsForNameByIDCmd)(nil), flags) + MustRegisterCmd("getclaimsfornamebybid", (*GetClaimsForNameByBidCmd)(nil), flags) + MustRegisterCmd("getclaimsfornamebyseq", (*GetClaimsForNameBySeqCmd)(nil), flags) + MustRegisterCmd("normalize", (*GetNormalizedCmd)(nil), flags) +} + +// optional inputs are required to be pointers, but they support things like `jsonrpcdefault:"false"` +// optional inputs have to be at the bottom of the struct +// optional outputs require ",omitempty" +// traditional bitcoin fields are all lowercase + +type GetChangesInBlockCmd struct { + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` +} + +type GetChangesInBlockResult struct { + Hash string `json:"hash"` + Height int32 `json:"height"` + Names []string `json:"names"` +} + +type GetClaimsForNameCmd struct { + Name string `json:"name"` + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` + IncludeValues *bool `json:"includevalues" jsonrpcdefault:"false"` +} + +type GetClaimsForNameByIDCmd struct { + Name string `json:"name"` + PartialClaimIDs []string `json:"partialclaimids"` + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` + IncludeValues *bool `json:"includevalues" jsonrpcdefault:"false"` +} + +type GetClaimsForNameByBidCmd struct { + Name string `json:"name"` + Bids []int32 `json:"bids"` + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` + IncludeValues *bool `json:"includevalues" jsonrpcdefault:"false"` +} + +type GetClaimsForNameBySeqCmd struct { + Name string `json:"name"` + Sequences []int32 `json:"sequences" jsonrpcusage:"[sequence,...]"` + HashOrHeight *string `json:"hashorheight" jsonrpcdefault:""` + IncludeValues *bool `json:"includevalues" jsonrpcdefault:"false"` +} + +type GetClaimsForNameResult struct { + Hash string `json:"hash"` + Height int32 `json:"height"` + LastTakeoverHeight int32 `json:"lasttakeoverheight"` + NormalizedName string `json:"normalizedname"` + Claims []ClaimResult `json:"claims"` + // UnclaimedSupports []SupportResult `json:"supportswithoutclaim"` how would this work with other constraints? +} + +type SupportResult struct { + TXID string `json:"txid"` + N uint32 `json:"n"` + Height int32 `json:"height"` + ValidAtHeight int32 `json:"validatheight"` + Amount int64 `json:"amount"` + Address string `json:"address,omitempty"` + Value string `json:"value,omitempty"` +} + +type ClaimResult struct { + ClaimID string `json:"claimid"` + TXID string `json:"txid"` + N uint32 `json:"n"` + Bid int32 `json:"bid"` + Sequence int32 `json:"sequence"` + Height int32 `json:"height"` + ValidAtHeight int32 `json:"validatheight"` + Amount int64 `json:"amount"` + EffectiveAmount int64 `json:"effectiveamount"` + Supports []SupportResult `json:"supports,omitempty"` + Address string `json:"address,omitempty"` + Value string `json:"value,omitempty"` +} + +type GetNormalizedCmd struct { + Name string `json:"name"` +} + +type GetNormalizedResult struct { + NormalizedName string `json:"normalizedname"` +} diff --git a/btcjson/help.go b/btcjson/help.go index f502d09f..04d85635 100644 --- a/btcjson/help.go +++ b/btcjson/help.go @@ -547,6 +547,12 @@ func GenerateHelp(method string, descs map[string]string, resultTypes ...interfa return desc } + if strings.Contains(key, "base-") { + if desc, ok := descs[strings.ReplaceAll(key, "base-", "-")]; ok { + return desc + } + } + missingKey = key return key } diff --git a/btcjson/jsonrpc.go b/btcjson/jsonrpc.go index 553a7bc3..e94653da 100644 --- a/btcjson/jsonrpc.go +++ b/btcjson/jsonrpc.go @@ -226,8 +226,12 @@ func NewResponse(rpcVersion RPCVersion, id interface{}, marshalledResult []byte, // JSON-RPC client. func MarshalResponse(rpcVersion RPCVersion, id interface{}, result interface{}, rpcErr *RPCError) ([]byte, error) { if !rpcVersion.IsValid() { - str := fmt.Sprintf("rpcversion '%s' is invalid", rpcVersion) - return nil, makeError(ErrInvalidType, str) + if rpcVersion == "" { + rpcVersion = RpcVersion1 + } else { + str := fmt.Sprintf("rpcversion '%s' is unsupported", rpcVersion) + return nil, makeError(ErrInvalidType, str) + } } marshalledResult, err := json.Marshal(result) diff --git a/rpcclaimtrie.go b/rpcclaimtrie.go new file mode 100644 index 00000000..11706920 --- /dev/null +++ b/rpcclaimtrie.go @@ -0,0 +1,352 @@ +package main + +import ( + "bytes" + "encoding/hex" + "strconv" + "strings" + + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/claimtrie/node" + "github.com/lbryio/lbcd/claimtrie/normalization" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" +) + +var claimtrieHandlers = map[string]commandHandler{ + "getchangesinblock": handleGetChangesInBlock, + "getclaimsforname": handleGetClaimsForName, + "getclaimsfornamebyid": handleGetClaimsForNameByID, + "getclaimsfornamebybid": handleGetClaimsForNameByBid, + "getclaimsfornamebyseq": handleGetClaimsForNameBySeq, + "normalize": handleGetNormalized, +} + +func handleGetChangesInBlock(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetChangesInBlockCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + names, err := s.cfg.Chain.GetNamesChangedInBlock(height) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + return btcjson.GetChangesInBlockResult{ + Hash: hash, + Height: height, + Names: names, + }, nil +} + +func parseHashOrHeight(s *rpcServer, hashOrHeight *string) (string, int32, error) { + if hashOrHeight == nil || len(*hashOrHeight) == 0 { + + if !s.cfg.Chain.IsCurrent() { + return "", 0, &btcjson.RPCError{ + Code: btcjson.ErrRPCClientInInitialDownload, + Message: "Unable to query the chain tip during initial download", + } + } + + // just give them the latest block if a specific one wasn't requested + best := s.cfg.Chain.BestSnapshot() + return best.Hash.String(), best.Height, nil + } + + ht, err := strconv.ParseInt(*hashOrHeight, 10, 32) + if err == nil && len(*hashOrHeight) < 32 { + hs, err := s.cfg.Chain.BlockHashByHeight(int32(ht)) + if err != nil { + return "", 0, &btcjson.RPCError{ + Code: btcjson.ErrRPCBlockNotFound, + Message: "Unable to locate a block at height " + *hashOrHeight + ": " + err.Error(), + } + } + return hs.String(), int32(ht), nil + } + + hs, err := chainhash.NewHashFromStr(*hashOrHeight) + if err != nil { + return "", 0, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Unable to parse a height or hash from " + *hashOrHeight + ": " + err.Error(), + } + } + h, err := s.cfg.Chain.BlockHeightByHash(hs) + if err != nil { + return hs.String(), h, &btcjson.RPCError{ + Code: btcjson.ErrRPCBlockNotFound, + Message: "Unable to find a block with hash " + hs.String() + ": " + err.Error(), + } + } + return hs.String(), h, nil +} + +func handleGetClaimsForName(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetClaimsForNameCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + name, n, err := s.cfg.Chain.GetClaimsForName(height, c.Name) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + var results []btcjson.ClaimResult + for i := range n.Claims { + cr, err := toClaimResult(s, int32(i), n, c.IncludeValues) + if err != nil { + return nil, err + } + results = append(results, cr) + } + + return btcjson.GetClaimsForNameResult{ + Hash: hash, + Height: height, + LastTakeoverHeight: n.TakenOverAt, + NormalizedName: name, + Claims: results, + }, nil +} + +func handleGetClaimsForNameByID(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetClaimsForNameByIDCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + name, n, err := s.cfg.Chain.GetClaimsForName(height, c.Name) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + var results []btcjson.ClaimResult + for i := 0; i < len(n.Claims); i++ { + for _, id := range c.PartialClaimIDs { + if strings.HasPrefix(n.Claims[i].ClaimID.String(), id) { + cr, err := toClaimResult(s, int32(i), n, c.IncludeValues) + if err != nil { + return nil, err + } + results = append(results, cr) + break + } + } + } + + return btcjson.GetClaimsForNameResult{ + Hash: hash, + Height: height, + LastTakeoverHeight: n.TakenOverAt, + NormalizedName: name, + Claims: results, + }, nil +} + +func handleGetClaimsForNameByBid(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetClaimsForNameByBidCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + name, n, err := s.cfg.Chain.GetClaimsForName(height, c.Name) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + var results []btcjson.ClaimResult + for _, b := range c.Bids { // claims are already sorted in bid order + if b >= 0 && int(b) < len(n.Claims) { + cr, err := toClaimResult(s, b, n, c.IncludeValues) + if err != nil { + return nil, err + } + results = append(results, cr) + } + } + + return btcjson.GetClaimsForNameResult{ + Hash: hash, + Height: height, + LastTakeoverHeight: n.TakenOverAt, + NormalizedName: name, + Claims: results, + }, nil +} + +func handleGetClaimsForNameBySeq(s *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetClaimsForNameBySeqCmd) + hash, height, err := parseHashOrHeight(s, c.HashOrHeight) + if err != nil { + return nil, err + } + + name, n, err := s.cfg.Chain.GetClaimsForName(height, c.Name) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCMisc, + Message: "Message: " + err.Error(), + } + } + + sm := map[int32]bool{} + for _, seq := range c.Sequences { + sm[seq] = true + } + + var results []btcjson.ClaimResult + for i := 0; i < len(n.Claims); i++ { + if sm[n.Claims[i].Sequence] { + cr, err := toClaimResult(s, int32(i), n, c.IncludeValues) + if err != nil { + return nil, err + } + results = append(results, cr) + } + } + + return btcjson.GetClaimsForNameResult{ + Hash: hash, + Height: height, + LastTakeoverHeight: n.TakenOverAt, + NormalizedName: name, + Claims: results, + }, nil +} + +func toClaimResult(s *rpcServer, i int32, n *node.Node, includeValues *bool) (btcjson.ClaimResult, error) { + claim := n.Claims[i] + address, value, err := lookupValue(s, claim.OutPoint, includeValues) + supports, err := toSupportResults(s, i, n, includeValues) + effectiveAmount := n.SupportSums[claim.ClaimID.Key()] // should only be active supports + if claim.Status == node.Activated { + effectiveAmount += claim.Amount + } + return btcjson.ClaimResult{ + ClaimID: claim.ClaimID.String(), + Height: claim.AcceptedAt, + ValidAtHeight: claim.ActiveAt, + TXID: claim.OutPoint.Hash.String(), + N: claim.OutPoint.Index, + Bid: i, // assuming sorted by bid + Amount: claim.Amount, + EffectiveAmount: effectiveAmount, + Sequence: claim.Sequence, + Supports: supports, + Address: address, + Value: value, + }, err +} + +func toSupportResults(s *rpcServer, i int32, n *node.Node, includeValues *bool) ([]btcjson.SupportResult, error) { + var results []btcjson.SupportResult + c := n.Claims[i] + for _, sup := range n.Supports { + if sup.Status == node.Activated && c.ClaimID == sup.ClaimID { + address, value, err := lookupValue(s, sup.OutPoint, includeValues) + if err != nil { + return results, err + } + results = append(results, btcjson.SupportResult{ + TXID: sup.OutPoint.Hash.String(), + N: sup.OutPoint.Index, + Height: sup.AcceptedAt, + ValidAtHeight: sup.ActiveAt, + Amount: sup.Amount, + Value: value, + Address: address, + }) + } + } + return results, nil +} + +func lookupValue(s *rpcServer, outpoint wire.OutPoint, includeValues *bool) (string, string, error) { + if includeValues == nil || !*includeValues { + return "", "", nil + } + // TODO: maybe use addrIndex if the txIndex is not available + + if s.cfg.TxIndex == nil { + return "", "", &btcjson.RPCError{ + Code: btcjson.ErrRPCNoTxInfo, + Message: "The transaction index must be " + + "enabled to query the blockchain " + + "(specify --txindex)", + } + } + + txHash := &outpoint.Hash + blockRegion, err := s.cfg.TxIndex.TxBlockRegion(txHash) + if err != nil { + context := "Failed to retrieve transaction location" + return "", "", internalRPCError(err.Error(), context) + } + if blockRegion == nil { + return "", "", rpcNoTxInfoError(txHash) + } + + // Load the raw transaction bytes from the database. + var txBytes []byte + err = s.cfg.DB.View(func(dbTx database.Tx) error { + var err error + txBytes, err = dbTx.FetchBlockRegion(blockRegion) + return err + }) + if err != nil { + return "", "", rpcNoTxInfoError(txHash) + } + + // Deserialize the transaction + var msgTx wire.MsgTx + err = msgTx.Deserialize(bytes.NewReader(txBytes)) + if err != nil { + context := "Failed to deserialize transaction" + return "", "", internalRPCError(err.Error(), context) + } + + txo := msgTx.TxOut[outpoint.Index] + cs, err := txscript.ExtractClaimScript(txo.PkScript) + if err != nil { + context := "Failed to decode the claim script" + return "", "", internalRPCError(err.Error(), context) + } + + _, addresses, _, _ := txscript.ExtractPkScriptAddrs(txo.PkScript[cs.Size:], s.cfg.ChainParams) + return addresses[0].EncodeAddress(), hex.EncodeToString(cs.Value), nil +} + +func handleGetNormalized(_ *rpcServer, cmd interface{}, _ <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.GetNormalizedCmd) + r := btcjson.GetNormalizedResult{ + NormalizedName: string(normalization.Normalize([]byte(c.Name))), + } + return r, nil +} diff --git a/rpcserverhelp.go b/rpcserverhelp.go index e8f7a640..1ab92644 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -247,6 +247,7 @@ var helpDescsEnUS = map[string]string{ "getblockverboseresult-version": "The block version", "getblockverboseresult-versionHex": "The block version in hexadecimal", "getblockverboseresult-merkleroot": "Root hash of the merkle tree", + "getblockverboseresult-nameclaimroot": "Root hash of the claim trie", "getblockverboseresult-tx": "The transaction hashes (only when verbosity=1)", "getblockverboseresult-rawtx": "The transactions as JSON objects (only when verbosity=2)", "getblockverboseresult-time": "The block time in seconds since 1 Jan 1970 GMT", @@ -288,6 +289,7 @@ var helpDescsEnUS = map[string]string{ "getblockheaderverboseresult-difficulty": "The proof-of-work difficulty as a multiple of the minimum difficulty", "getblockheaderverboseresult-previousblockhash": "The hash of the previous block", "getblockheaderverboseresult-nextblockhash": "The hash of the next block (only if there is one)", + "getblockheaderverboseresult-nameclaimroot": "The hash of the root of the claim trie", // TemplateRequest help. "templaterequest-mode": "This is 'template', 'proposal', or omitted", @@ -339,6 +341,8 @@ var helpDescsEnUS = map[string]string{ "getblocktemplateresult-reject-reason": "Reason the proposal was invalid as-is (only applies to proposal responses)", "getblocktemplateresult-default_witness_commitment": "The witness commitment itself. Will be populated if the block has witness data", "getblocktemplateresult-weightlimit": "The current limit on the max allowed weight of a block", + "getblocktemplateresult-rules": "Rules that are required to process the output", + "getblocktemplateresult-claimtrie": "The hash of the root of the claim trie - a necessary block header", // GetBlockTemplateCmd help. "getblocktemplate--synopsis": "Returns a JSON object with information necessary to construct a block to mine or accepts a proposal to validate.\n" + @@ -708,6 +712,78 @@ var helpDescsEnUS = map[string]string{ "versionresult-patch": "The patch component of the JSON-RPC API version", "versionresult-prerelease": "Prerelease info about the current build", "versionresult-buildmetadata": "Metadata about the current build", + + "getclaimsforname--synopsis": "Look up claims for the given name as they stand at a give block", + "getclaimsfornamebyid--synopsis": "Look up claims for the given name as they stand at a give block", + "getclaimsfornamebybid--synopsis": "Look up claims for the given name as they stand at a give block", + "getclaimsfornamebyseq--synopsis": "Look up claims for the given name as they stand at a give block", + + "getclaimsforname-hashorheight": "Requested block hash or height; default to tip", + "getclaimsfornamebyid-hashorheight": "Requested block hash or height; default to tip", + "getclaimsfornamebybid-hashorheight": "Requested block hash or height; default to tip", + "getclaimsfornamebyseq-hashorheight": "Requested block hash or height; default to tip", + + "getclaimsforname-name": "Requested name for lookup", + "getclaimsfornamebyid-name": "Requested name for lookup", + "getclaimsfornamebybid-name": "Requested name for lookup", + "getclaimsfornamebyseq-name": "Requested name for lookup", + + "getclaimsfornamebyid-partialclaimids": "Limit the returned claims to those with matching (partial) claimIDs in this list", + "getclaimsfornamebybid-bids": "Limit the returned claims to those with bids to this list", + "getclaimsfornamebyseq-sequences": "Limit the returned claims to those with bids to this list", + + "getclaimsforname-includevalues": "Return the metadata and address", + "getclaimsfornamebyseq-includevalues": "Return the metadata and address", + "getclaimsfornamebybid-includevalues": "Return the metadata and address", + "getclaimsfornamebyid-includevalues": "Return the metadata and address", + + "getclaimsfornameresult-claims": "All the active claims on the given name", + "getclaimsfornameresult-normalizedname": "Lower-case version of the passed-in name", + "getclaimsfornameresult-height": "Height of the requested block", + "getclaimsfornameresult-lasttakeoverheight": "Height of the most recent name takeover", + "getclaimsfornameresult-hash": "Hash of the requested block", + + "getchangesinblock--synopsis": "Returns a list of names affected by a given block", + "getchangesinblockresult-names": "Names that changed (or were at least checked for change) on the given height", + "getchangesinblockresult-height": "Height that was requested", + "getchangesinblockresult-hash": "Hash of the block at the height requested", + + "scriptpubkeyresult-subtype": "Claims return Non-standard address types, but they use standard address types internally exposed here", + + "supportresult-value": "This is the metadata given as part of the support", + "supportresult-txid": "The hash of the transaction", + "supportresult-n": "The output (TXO) index", + "supportresult-address": "The destination address for the support", + "supportresult-amount": "LBC staked", + "supportresult-height": "The height when the stake was created or updated", + "supportresult-validatheight": "The height when the stake becomes valid", + "claimresult-value": "This is the metadata given as part of the claim", + "claimresult-txid": "The hash of the transaction", + "claimresult-n": "The output (TXO) index", + "claimresult-address": "The destination address for the claim", + "claimresult-supports": "The list of supports active on the claim", + "claimresult-validatheight": "The height when the stake becomes valid", + "claimresult-height": "The height when the stake was created or updated", + "claimresult-amount": "The stake amount in sats", + "claimresult-effectiveamount": "The stake amount plus the active supports' amounts", + "claimresult-sequence": "The order this claim was created compared to other claims on this name", + "claimresult-bid": "Bid of 0 means that this claim currently owns the name", + "claimresult-claimid": "20-byte hash of TXID:N, often used in indexes for the claims", + + "generatetoaddress--synopsis": "Mine blocks and send their reward to a given address", + "generatetoaddress--result0": "The list of generated blocks' hashes", + "generatetoaddress-maxtries": "The maximum number of hashes to attempt", + "generatetoaddress-address": "The destination -- the place where the LBC will be sent", + "generatetoaddress-numblocks": "The number of blocks to mine", + "getchangesinblock-hashorheight": "The requested height or block hash whose changes are of interest", + + "normalize--synopsis": "Used to show how lbcd will normalize a string", + "normalize--result0": "The normalized name", + "normalize-name": "The string to be normalized", + + "getblockverboseresult-getblockverboseresultbase": "", + "prevout-issupport": "Previous output created a support", + "prevout-isclaim": "Previous output created or updated a claim", } // rpcResultTypes specifies the result types that each RPC command can return. @@ -776,6 +852,14 @@ var rpcResultTypes = map[string][]interface{}{ "stopnotifyspent": nil, "rescan": nil, "rescanblocks": {(*[]btcjson.RescannedBlock)(nil)}, + + // ClaimTrie + "getclaimsforname": {(*btcjson.GetClaimsForNameResult)(nil)}, + "getclaimsfornamebyid": {(*btcjson.GetClaimsForNameResult)(nil)}, + "getclaimsfornamebybid": {(*btcjson.GetClaimsForNameResult)(nil)}, + "getclaimsfornamebyseq": {(*btcjson.GetClaimsForNameResult)(nil)}, + "normalize": {(*string)(nil)}, + "getchangesinblock": {(*btcjson.GetChangesInBlockResult)(nil)}, } // helpCacher provides a concurrent safe type that provides help and usage for -- 2.45.2 From 9d70ff6f6df02de4676f574a0243cbbf4da74b09 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 19:48:59 -0700 Subject: [PATCH 351/459] [lbry] rpcserver: add ClaimTrie root hash to GetBlockTemplate() --- rpcserver.go | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 4502a4cd..607733e1 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1748,23 +1748,24 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld targetDifficulty := fmt.Sprintf("%064x", blockchain.CompactToBig(header.Bits)) templateID := encodeTemplateID(state.prevHash, state.lastGenerated) reply := btcjson.GetBlockTemplateResult{ - Bits: strconv.FormatInt(int64(header.Bits), 16), - CurTime: header.Timestamp.Unix(), - Height: int64(template.Height), - PreviousHash: header.PrevBlock.String(), - WeightLimit: blockchain.MaxBlockWeight, - SigOpLimit: blockchain.MaxBlockSigOpsCost, - SizeLimit: wire.MaxBlockPayload, - Transactions: transactions, - Version: header.Version, - LongPollID: templateID, - SubmitOld: submitOld, - Target: targetDifficulty, - MinTime: state.minTimestamp.Unix(), - MaxTime: maxTime.Unix(), - Mutable: gbtMutableFields, - NonceRange: gbtNonceRange, - Capabilities: gbtCapabilities, + Bits: strconv.FormatInt(int64(header.Bits), 16), + CurTime: header.Timestamp.Unix(), + Height: int64(template.Height), + PreviousHash: header.PrevBlock.String(), + WeightLimit: blockchain.MaxBlockWeight, + SigOpLimit: blockchain.MaxBlockSigOpsCost, + SizeLimit: wire.MaxBlockPayload, + Transactions: transactions, + Version: header.Version, + LongPollID: templateID, + SubmitOld: submitOld, + Target: targetDifficulty, + MinTime: state.minTimestamp.Unix(), + MaxTime: maxTime.Unix(), + Mutable: gbtMutableFields, + NonceRange: gbtNonceRange, + Capabilities: gbtCapabilities, + ClaimTrieHash: header.ClaimTrie.String(), } // If the generated block template includes transactions with witness // data, then include the witness commitment in the GBT result. @@ -4663,5 +4664,8 @@ func (s *rpcServer) handleBlockchainNotification(notification *blockchain.Notifi func init() { rpcHandlers = rpcHandlersBeforeInit + for key := range claimtrieHandlers { + rpcHandlers[key] = claimtrieHandlers[key] + } rand.Seed(time.Now().UnixNano()) } -- 2.45.2 From e7d8637cc5f2c4df7dfb925a0ff5af6488bb84da Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 22:10:26 -0700 Subject: [PATCH 352/459] [lbry] rpcclient: update defaultMaxFeeRate from 0.1 LBC to 0.5 LBC --- rpcclient/rawtransactions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcclient/rawtransactions.go b/rpcclient/rawtransactions.go index d0f28c8a..3512ccb7 100644 --- a/rpcclient/rawtransactions.go +++ b/rpcclient/rawtransactions.go @@ -18,7 +18,7 @@ import ( const ( // defaultMaxFeeRate is the default maximum fee rate in sat/KB enforced // by bitcoind v0.19.0 or after for transaction broadcast. - defaultMaxFeeRate = btcutil.SatoshiPerBitcoin / 10 + defaultMaxFeeRate = btcutil.SatoshiPerBitcoin / 2 ) // SigHashType enumerates the available signature hashing types that the -- 2.45.2 From 3111601ac94d3ebc85de047044c70abe325f9c2f Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 4 Jan 2022 09:52:39 -0800 Subject: [PATCH 353/459] [lbry] rpcclient: add a blocknotify example using lbcd websocket --- rpcclient/examples/lbcdblocknotify/README.md | 46 ++++++++ rpcclient/examples/lbcdblocknotify/main.go | 105 +++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 rpcclient/examples/lbcdblocknotify/README.md create mode 100644 rpcclient/examples/lbcdblocknotify/main.go diff --git a/rpcclient/examples/lbcdblocknotify/README.md b/rpcclient/examples/lbcdblocknotify/README.md new file mode 100644 index 00000000..45ab3b29 --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/README.md @@ -0,0 +1,46 @@ +# lbcd Websockets Example + +This example shows how to use the rpcclient package to connect to a btcd RPC +server using TLS-secured websockets, register for block connected and block +disconnected notifications, and get the current block count. + +## Running the Example + +The first step is to clone the lbcd package: + +```bash +$ git clone github.com/lbryio/lbcd +``` + +Display available options: + +```bash +$ go run . -h + + -coinid string + Coin ID (default "1425") + -rpcpass string + LBCD RPC password (default "rpcpass") + -rpcserver string + LBCD RPC server (default "localhost:9245") + -rpcuser string + LBCD RPC username (default "rpcuser") + -stratum string + Stratum server (default "lbrypool.net:3334") + -stratumpass string + Stratum server password (default "password") +``` + +Start the program: + +```bash +$ go run . -stratumpass -rpcuser -rpcpass + +2022/01/10 23:16:21 NotifyBlocks: Registration Complete +2022/01/10 23:16:21 Block count: 1093112 +... +``` + +## License + +This example is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/rpcclient/examples/lbcdblocknotify/main.go b/rpcclient/examples/lbcdblocknotify/main.go new file mode 100644 index 00000000..431331ee --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/main.go @@ -0,0 +1,105 @@ +// Copyright (c) 2014-2017 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "log" + "net" + "path/filepath" + + "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/wire" + "github.com/lbryio/lbcutil" +) + +func send(stratum, stratumPass, coinid, blockHash string) error { + addr, err := net.ResolveTCPAddr("tcp", stratum) + if err != nil { + return fmt.Errorf("can't resolve addr: %w", err) + } + + conn, err := net.DialTCP("tcp", nil, addr) + if err != nil { + return fmt.Errorf("can't dial tcp: %w", err) + } + defer conn.Close() + + msg := fmt.Sprintf(`{"id":1,"method":"mining.update_block","params":[%q,%q,%q]}`, + stratumPass, coinid, blockHash) + + _, err = conn.Write([]byte(msg)) + if err != nil { + return fmt.Errorf("can't write message: %w", err) + } + + return nil +} + +func main() { + + var ( + coinid = flag.String("coinid", "1425", "Coin ID") + stratum = flag.String("stratum", "lbrypool.net:3334", "Stratum server") + stratumPass = flag.String("stratumpass", "password", "Stratum server password") + rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server") + rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username") + rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password") + notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled") + ) + + flag.Parse() + + ntfnHandlers := rpcclient.NotificationHandlers{ + OnFilteredBlockConnected: func(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) { + + blockHash := header.BlockHash().String() + + log.Printf("Block connected: %v (%d) %v", blockHash, height, header.Timestamp) + + if err := send(*stratum, *stratumPass, *coinid, blockHash); err != nil { + log.Printf("ERROR: failed to notify stratum: %s", err) + } + }, + } + + // Connect to local lbcd RPC server using websockets. + lbcdHomeDir := lbcutil.AppDataDir("lbcd", false) + certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) + if err != nil { + log.Fatalf("can't read lbcd certificate: %s", err) + } + connCfg := &rpcclient.ConnConfig{ + Host: *rpcserver, + Endpoint: "ws", + User: *rpcuser, + Pass: *rpcpass, + Certificates: certs, + DisableTLS: *notls, + } + client, err := rpcclient.New(connCfg, &ntfnHandlers) + if err != nil { + log.Fatalf("can't create rpc client: %s", err) + } + + // Register for block connect and disconnect notifications. + if err = client.NotifyBlocks(); err != nil { + log.Fatalf("can't register block notification: %s", err) + } + log.Printf("NotifyBlocks: Registration Complete") + + // Get the current block count. + blockCount, err := client.GetBlockCount() + if err != nil { + log.Fatalf("can't get block count: %s", err) + } + log.Printf("Block count: %d", blockCount) + + // Wait until the client either shuts down gracefully (or the user + // terminates the process with Ctrl+C). + client.WaitForShutdown() +} -- 2.45.2 From fb3ef35189721f51eccc8a68b743cb71aa122857 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 15 May 2022 22:59:30 -0700 Subject: [PATCH 354/459] [lbry] rpcclient: support SkipVerify of TLS certificate. (#39) --- rpcclient/infrastructure.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index 730f8bcb..943732ff 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -1192,6 +1192,9 @@ type ConnConfig struct { // the wire in cleartext. DisableTLS bool + // SkipVerify instruct the client to skip verifying TLS certificate. + SkipVerify bool + // Certificates are the bytes for a PEM-encoded certificate chain used // for the TLS connection. It has no effect if the DisableTLS parameter // is true. @@ -1295,7 +1298,8 @@ func newHTTPClient(config *ConnConfig) (*http.Client, error) { pool := x509.NewCertPool() pool.AppendCertsFromPEM(config.Certificates) tlsConfig = &tls.Config{ - RootCAs: pool, + RootCAs: pool, + InsecureSkipVerify: config.SkipVerify, } } } @@ -1318,7 +1322,8 @@ func dial(config *ConnConfig) (*websocket.Conn, error) { var scheme = "ws" if !config.DisableTLS { tlsConfig = &tls.Config{ - MinVersion: tls.VersionTLS12, + MinVersion: tls.VersionTLS12, + InsecureSkipVerify: config.SkipVerify, } if len(config.Certificates) > 0 { pool := x509.NewCertPool() -- 2.45.2 From 096dd3ff75619ee88721eaa559bbf88924449bc2 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 24 May 2022 00:00:31 -0700 Subject: [PATCH 355/459] [lbry] rpcclient: fix http response resource leaking --- rpcclient/infrastructure.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index 943732ff..9b93d739 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -803,6 +803,7 @@ func (c *Client) handleSendPostMessage(jReq *jsonRequest) { time.Sleep(backoff) continue } + defer httpResponse.Body.Close() break } if err != nil { @@ -810,9 +811,8 @@ func (c *Client) handleSendPostMessage(jReq *jsonRequest) { return } - // Read the raw bytes and close the response. + // Read the raw bytes from the response. respBytes, err := ioutil.ReadAll(httpResponse.Body) - httpResponse.Body.Close() if err != nil { err = fmt.Errorf("error reading json reply: %v", err) jReq.responseChan <- &Response{err: err} @@ -1386,6 +1386,7 @@ func dial(config *ConnConfig) (*websocket.Conn, error) { // cases above apply. return nil, errors.New(resp.Status) } + resp.Body.Close() return wsConn, nil } -- 2.45.2 From 3d8f36a5052281263e7fcab0464ba14fafedd49f Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 30 Jul 2021 14:12:28 -0400 Subject: [PATCH 356/459] [lbry] rpc: output segwit rule --- btcjson/chainsvrresults.go | 2 ++ rpcserver.go | 1 + 2 files changed, 3 insertions(+) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index e82a14bc..ecc26827 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -300,6 +300,8 @@ type GetBlockTemplateResult struct { RejectReasion string `json:"reject-reason,omitempty"` ClaimTrieHash string `json:"claimtrie"` + + Rules []string `json:"rules,omitempty"` } // GetMempoolEntryResult models the data returned from the getmempoolentry's diff --git a/rpcserver.go b/rpcserver.go index 607733e1..7014c7b6 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1771,6 +1771,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld // data, then include the witness commitment in the GBT result. if template.WitnessCommitment != nil { reply.DefaultWitnessCommitment = hex.EncodeToString(template.WitnessCommitment) + reply.Rules = append(reply.Rules, "!segwit") } if useCoinbaseValue { -- 2.45.2 From 5116f45617be7e64ebfb69406267b2abbfaf19e0 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 22:10:26 -0700 Subject: [PATCH 357/459] [lbry] rpc: fix getblock reponse --- btcjson/chainsvrresults.go | 62 ++++++++++++++++---------------------- rpcserver.go | 45 ++++++++++++++++++--------- rpcserverhelp.go | 2 +- 3 files changed, 57 insertions(+), 52 deletions(-) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index ecc26827..46d454c5 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -25,7 +25,7 @@ type GetBlockHeaderVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` - ClaimTrie string `json:"claimtrie"` + ClaimTrie string `json:"nameclaimroot,omitempty"` Time int64 `json:"time"` Nonce uint64 `json:"nonce"` Bits string `json:"bits"` @@ -66,6 +66,27 @@ type GetBlockStatsResult struct { UTXOSizeIncrease int64 `json:"utxo_size_inc"` } +type GetBlockVerboseResultBase struct { + Hash string `json:"hash"` + Confirmations int64 `json:"confirmations"` + StrippedSize int32 `json:"strippedsize"` + Size int32 `json:"size"` + Weight int32 `json:"weight"` + Height int64 `json:"height"` + Version int32 `json:"version"` + VersionHex string `json:"versionHex"` + MerkleRoot string `json:"merkleroot"` + Time int64 `json:"time"` + Nonce uint32 `json:"nonce"` + Bits string `json:"bits"` + Difficulty float64 `json:"difficulty"` + PreviousHash string `json:"previousblockhash,omitempty"` + NextHash string `json:"nextblockhash,omitempty"` + + ClaimTrie string `json:"nameclaimroot,omitempty"` + TxCount int `json:"nTx"` // For backwards compatibility only +} + // GetBlockVerboseResult models the data from the getblock command when the // verbose flag is set to 1. When the verbose flag is set to 0, getblock returns a // hex-encoded string. When the verbose flag is set to 1, getblock returns an object @@ -73,24 +94,8 @@ type GetBlockStatsResult struct { // getblock returns an object whose tx field is an array of raw transactions. // Use GetBlockVerboseTxResult to unmarshal data received from passing verbose=2 to getblock. type GetBlockVerboseResult struct { - Hash string `json:"hash"` - Confirmations int64 `json:"confirmations"` - StrippedSize int32 `json:"strippedsize"` - Size int32 `json:"size"` - Weight int32 `json:"weight"` - Height int64 `json:"height"` - Version int32 `json:"version"` - VersionHex string `json:"versionHex"` - MerkleRoot string `json:"merkleroot"` - ClaimTrie string `json:"claimTrie"` - Tx []string `json:"tx,omitempty"` - RawTx []TxRawResult `json:"rawtx,omitempty"` // Note: this field is always empty when verbose != 2. - Time int64 `json:"time"` - Nonce uint32 `json:"nonce"` - Bits string `json:"bits"` - Difficulty float64 `json:"difficulty"` - PreviousHash string `json:"previousblockhash"` - NextHash string `json:"nextblockhash,omitempty"` + GetBlockVerboseResultBase + Tx []string `json:"tx"` } // GetBlockVerboseTxResult models the data from the getblock command when the @@ -100,23 +105,8 @@ type GetBlockVerboseResult struct { // getblock returns an object whose tx field is an array of raw transactions. // Use GetBlockVerboseResult to unmarshal data received from passing verbose=1 to getblock. type GetBlockVerboseTxResult struct { - Hash string `json:"hash"` - Confirmations int64 `json:"confirmations"` - StrippedSize int32 `json:"strippedsize"` - Size int32 `json:"size"` - Weight int32 `json:"weight"` - Height int64 `json:"height"` - Version int32 `json:"version"` - VersionHex string `json:"versionHex"` - MerkleRoot string `json:"merkleroot"` - Tx []TxRawResult `json:"tx,omitempty"` - RawTx []TxRawResult `json:"rawtx,omitempty"` // Deprecated: removed in Bitcoin Core - Time int64 `json:"time"` - Nonce uint32 `json:"nonce"` - Bits string `json:"bits"` - Difficulty float64 `json:"difficulty"` - PreviousHash string `json:"previousblockhash"` - NextHash string `json:"nextblockhash,omitempty"` + GetBlockVerboseResultBase + Tx []TxRawResult `json:"tx"` } // GetChainTxStatsResult models the data from the getchaintxstats command. diff --git a/rpcserver.go b/rpcserver.go index 7014c7b6..04ff9e08 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1122,12 +1122,17 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i params := s.cfg.ChainParams blockHeader := &blk.MsgBlock().Header - blockReply := btcjson.GetBlockVerboseResult{ + var prevHashString string + if blockHeight > 0 { + prevHashString = blockHeader.PrevBlock.String() + } + + base := btcjson.GetBlockVerboseResultBase{ Hash: c.Hash, Version: blockHeader.Version, VersionHex: fmt.Sprintf("%08x", blockHeader.Version), MerkleRoot: blockHeader.MerkleRoot.String(), - PreviousHash: blockHeader.PrevBlock.String(), + PreviousHash: prevHashString, Nonce: blockHeader.Nonce, Time: blockHeader.Timestamp.Unix(), Confirmations: int64(1 + best.Height - blockHeight), @@ -1138,6 +1143,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i Bits: strconv.FormatInt(int64(blockHeader.Bits), 16), Difficulty: getDifficultyRatio(blockHeader.Bits, params), NextHash: nextHashString, + ClaimTrie: blockHeader.ClaimTrie.String(), } if *c.Verbosity == 1 { @@ -1147,20 +1153,29 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i txNames[i] = tx.Hash().String() } - blockReply.Tx = txNames - } else { - txns := blk.Transactions() - rawTxns := make([]btcjson.TxRawResult, len(txns)) - for i, tx := range txns { - rawTxn, err := createTxRawResult(params, tx.MsgTx(), - tx.Hash().String(), blockHeader, hash.String(), - blockHeight, best.Height) - if err != nil { - return nil, err - } - rawTxns[i] = *rawTxn + base.TxCount = len(txNames) + blockReply := btcjson.GetBlockVerboseResult{ + GetBlockVerboseResultBase: base, + Tx: txNames, } - blockReply.RawTx = rawTxns + return blockReply, nil + } + + txns := blk.Transactions() + rawTxns := make([]btcjson.TxRawResult, len(txns)) + for i, tx := range txns { + rawTxn, err := createTxRawResult(params, tx.MsgTx(), + tx.Hash().String(), blockHeader, hash.String(), + blockHeight, best.Height) + if err != nil { + return nil, err + } + rawTxns[i] = *rawTxn + } + base.TxCount = len(rawTxns) + blockReply := btcjson.GetBlockVerboseTxResult{ + GetBlockVerboseResultBase: base, + Tx: rawTxns, } return blockReply, nil diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 1ab92644..ac0bf42d 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -249,7 +249,7 @@ var helpDescsEnUS = map[string]string{ "getblockverboseresult-merkleroot": "Root hash of the merkle tree", "getblockverboseresult-nameclaimroot": "Root hash of the claim trie", "getblockverboseresult-tx": "The transaction hashes (only when verbosity=1)", - "getblockverboseresult-rawtx": "The transactions as JSON objects (only when verbosity=2)", + "getblockverboseresult-nTx": "The number of transactions (aka, count of TX)", "getblockverboseresult-time": "The block time in seconds since 1 Jan 1970 GMT", "getblockverboseresult-nonce": "The block nonce", "getblockverboseresult-bits": "The bits which represent the block difficulty", -- 2.45.2 From 81862c664ecea2ba31e25dc8e684f278c7ef7387 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 28 Oct 2021 14:02:44 -0400 Subject: [PATCH 358/459] [lbry] rpc: import getnetworkinfo from bchd --- addrmgr/addrmanager.go | 47 +++++---- blockchain/chain.go | 9 ++ rpcserver.go | 218 ++++++++++++++++++++++++++++++++++++----- rpcserverhelp.go | 22 +++++ server.go | 2 + version.go | 5 + 6 files changed, 257 insertions(+), 46 deletions(-) diff --git a/addrmgr/addrmanager.go b/addrmgr/addrmanager.go index b7730671..37236c1d 100644 --- a/addrmgr/addrmanager.go +++ b/addrmgr/addrmanager.go @@ -45,7 +45,7 @@ type AddrManager struct { nTried int nNew int lamtx sync.Mutex - localAddresses map[string]*localAddress + localAddresses map[string]*LocalAddress version int } @@ -69,9 +69,9 @@ type serializedAddrManager struct { TriedBuckets [triedBucketCount][]string } -type localAddress struct { - na *wire.NetAddress - score AddressPriority +type LocalAddress struct { + NA *wire.NetAddress + Score AddressPriority } // AddressPriority type is used to describe the hierarchy of local address @@ -178,7 +178,7 @@ func (a *AddrManager) updateAddress(netAddr, srcAddr *wire.NetAddress) { // note that to prevent causing excess garbage on getaddr // messages the netaddresses in addrmanager are *immutable*, // if we need to change them then we replace the pointer with a - // new copy so that we don't have to copy every na for getaddr. + // new copy so that we don't have to copy every NA for getaddr. if netAddr.Timestamp.After(ka.na.Timestamp) || (ka.na.Services&netAddr.Services) != netAddr.Services { @@ -755,7 +755,7 @@ func (a *AddrManager) HostToNetAddress(host string, port uint16, services wire.S // the relevant .onion address. func ipString(na *wire.NetAddress) string { if IsOnionCatTor(na) { - // We know now that na.IP is long enough. + // We know now that NA.IP is long enough. base32 := base32.StdEncoding.EncodeToString(na.IP[6:]) return strings.ToLower(base32) + ".onion" } @@ -882,7 +882,7 @@ func (a *AddrManager) Connected(addr *wire.NetAddress) { // so. now := time.Now() if now.After(ka.na.Timestamp.Add(time.Minute * 20)) { - // ka.na is immutable, so replace it. + // ka.NA is immutable, so replace it. naCopy := *ka.na naCopy.Timestamp = time.Now() ka.mtx.Lock() @@ -994,7 +994,7 @@ func (a *AddrManager) SetServices(addr *wire.NetAddress, services wire.ServiceFl // Update the services if needed. if ka.na.Services != services { - // ka.na is immutable, so replace it. + // ka.NA is immutable, so replace it. naCopy := *ka.na naCopy.Services = services ka.mtx.Lock() @@ -1003,7 +1003,7 @@ func (a *AddrManager) SetServices(addr *wire.NetAddress, services wire.ServiceFl } } -// AddLocalAddress adds na to the list of known local addresses to advertise +// AddLocalAddress adds NA to the list of known local addresses to advertise // with the given priority. func (a *AddrManager) AddLocalAddress(na *wire.NetAddress, priority AddressPriority) error { if !IsRoutable(na) { @@ -1015,13 +1015,13 @@ func (a *AddrManager) AddLocalAddress(na *wire.NetAddress, priority AddressPrior key := NetAddressKey(na) la, ok := a.localAddresses[key] - if !ok || la.score < priority { + if !ok || la.Score < priority { if ok { - la.score = priority + 1 + la.Score = priority + 1 } else { - a.localAddresses[key] = &localAddress{ - na: na, - score: priority, + a.localAddresses[key] = &LocalAddress{ + NA: na, + Score: priority, } } } @@ -1117,12 +1117,12 @@ func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.Net var bestscore AddressPriority var bestAddress *wire.NetAddress for _, la := range a.localAddresses { - reach := getReachabilityFrom(la.na, remoteAddr) + reach := getReachabilityFrom(la.NA, remoteAddr) if reach > bestreach || - (reach == bestreach && la.score > bestscore) { + (reach == bestreach && la.Score > bestscore) { bestreach = reach - bestscore = la.score - bestAddress = la.na + bestscore = la.Score + bestAddress = la.NA } } if bestAddress != nil { @@ -1146,6 +1146,15 @@ func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.Net return bestAddress } +// LocalAddresses returns the list of local addresses for our node. +func (a *AddrManager) LocalAddresses() []*LocalAddress { + var addrs []*LocalAddress + for _, addr := range a.localAddresses { + addrs = append(addrs, addr) + } + return addrs +} + // New returns a new bitcoin address manager. // Use Start to begin processing asynchronous address updates. func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager { @@ -1154,7 +1163,7 @@ func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager lookupFunc: lookupFunc, rand: rand.New(rand.NewSource(time.Now().UnixNano())), quit: make(chan struct{}), - localAddresses: make(map[string]*localAddress), + localAddresses: make(map[string]*LocalAddress), version: serialisationVersion, } am.reset() diff --git a/blockchain/chain.go b/blockchain/chain.go index 45496fca..00e2f3a6 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -199,6 +199,15 @@ func (b *BlockChain) HaveBlock(hash *chainhash.Hash) (bool, error) { return exists || b.IsKnownOrphan(hash), nil } +// GetWarnings returns a bool for whether unknownRules +// has been warned. +func (b *BlockChain) GetWarnings() bool { + b.chainLock.RLock() + defer b.chainLock.RUnlock() + + return b.unknownRulesWarned +} + // IsKnownOrphan returns whether the passed hash is currently a known orphan. // Keep in mind that only a limited number of orphans are held onto for a // limited amount of time, so this function must not be used as an absolute diff --git a/rpcserver.go b/rpcserver.go index 04ff9e08..5c20436d 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -27,21 +27,22 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/blockchain/indexers" - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/database" - "github.com/btcsuite/btcd/mempool" - "github.com/btcsuite/btcd/mining" - "github.com/btcsuite/btcd/mining/cpuminer" - "github.com/btcsuite/btcd/peer" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/btcutil" "github.com/btcsuite/websocket" + "github.com/lbryio/lbcd/addrmgr" + "github.com/lbryio/lbcd/blockchain" + "github.com/lbryio/lbcd/blockchain/indexers" + "github.com/lbryio/lbcd/btcec" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/mempool" + "github.com/lbryio/lbcd/mining" + "github.com/lbryio/lbcd/mining/cpuminer" + "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + btcutil "github.com/lbryio/lbcutil" ) // API version constants @@ -137,6 +138,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "decodescript": handleDecodeScript, "estimatefee": handleEstimateFee, "generate": handleGenerate, + "generatetoaddress": handleGenerateToAddress, "getaddednodeinfo": handleGetAddedNodeInfo, "getbestblock": handleGetBestBlock, "getbestblockhash": handleGetBestBlockHash, @@ -159,6 +161,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getmininginfo": handleGetMiningInfo, "getnettotals": handleGetNetTotals, "getnetworkhashps": handleGetNetworkHashPS, + "getnetworkinfo": handleGetNetworkInfo, "getnodeaddresses": handleGetNodeAddresses, "getpeerinfo": handleGetPeerInfo, "getrawmempool": handleGetRawMempool, @@ -233,7 +236,6 @@ var rpcUnimplemented = map[string]struct{}{ "estimatepriority": {}, "getchaintips": {}, "getmempoolentry": {}, - "getnetworkinfo": {}, "getwork": {}, "invalidateblock": {}, "preciousblock": {}, @@ -573,7 +575,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan default: return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidAddressOrKey, - Message: "Invalid address or key", + Message: "Invalid address or key: " + addr.String(), } } if !addr.IsForNet(params) { @@ -701,11 +703,12 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap // script doesn't fully parse, so ignore the error here. disbuf, _ := txscript.DisasmString(v.PkScript) + script := txscript.StripClaimScriptPrefix(v.PkScript) + // Ignore the error here since an error means the script // couldn't parse and there is no additional information about // it anyways. - scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs( - v.PkScript, chainParams) + scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script, chainParams) // Encode the addresses while checking if the address passes the // filter when needed. @@ -735,9 +738,19 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap vout.ScriptPubKey.Addresses = encodedAddrs vout.ScriptPubKey.Asm = disbuf vout.ScriptPubKey.Hex = hex.EncodeToString(v.PkScript) - vout.ScriptPubKey.Type = scriptClass.String() vout.ScriptPubKey.ReqSigs = int32(reqSigs) + if len(script) < len(v.PkScript) { + vout.ScriptPubKey.IsClaim = v.PkScript[0] == txscript.OP_CLAIMNAME || v.PkScript[0] == txscript.OP_UPDATECLAIM + vout.ScriptPubKey.IsSupport = v.PkScript[0] == txscript.OP_SUPPORTCLAIM + vout.ScriptPubKey.SubType = scriptClass.String() + vout.ScriptPubKey.Type = txscript.ScriptClass.String(0) + } else { + vout.ScriptPubKey.Type = scriptClass.String() + } + + // TODO here: isclaim, issupport, subtype, + voutList = append(voutList, vout) } @@ -882,7 +895,6 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) return float64(feeRate), nil } -// handleGenerate handles generate commands. func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { // Respond with an error if there are no addresses to pay the // created blocks to. @@ -919,7 +931,62 @@ func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i // Create a reply reply := make([]string, c.NumBlocks) - blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(c.NumBlocks) + blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(c.NumBlocks, nil) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: err.Error(), + } + } + + // Mine the correct number of blocks, assigning the hex representation of the + // hash of each one to its place in the reply. + for i, hash := range blockHashes { + reply[i] = hash.String() + } + + return reply, nil +} + +// handleGenerateToAddress handles generate commands. +func handleGenerateToAddress(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.GenerateToAddressCmd) + payToAddr, err := btcutil.DecodeAddress(c.Address, s.cfg.ChainParams) + + // Respond with an error if there are no addresses to pay the + // created blocks to. + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "No payment addresses specified ", + } + } + // cfg.miningAddrs = append(cfg.miningAddrs, maddr) + + // Respond with an error if there's virtually 0 chance of mining a block + // with the CPU. + if !s.cfg.ChainParams.GenerateSupported { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCDifficulty, + Message: fmt.Sprintf("No support for `generatetoaddress` on "+ + "the current network, %s, as it's unlikely to "+ + "be possible to mine a block with the CPU.", + s.cfg.ChainParams.Net), + } + } + + // Respond with an error if the client is requesting 0 blocks to be generated. + if c.NumBlocks == 0 { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: "Please request a nonzero number of blocks to generate.", + } + } + + // Create a reply + reply := make([]string, c.NumBlocks) + + blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(uint32(c.NumBlocks), payToAddr) if err != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInternal.Code, @@ -2537,6 +2604,84 @@ func handleGetNodeAddresses(s *rpcServer, cmd interface{}, closeChan <-chan stru return addresses, nil } +// handleGetNetworkInfo implements the getnetworkinfo command. +func handleGetNetworkInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + ver := wire.MsgVersion{} + _ = ver.AddUserAgent(userAgentName, userAgentVersion, cfg.UserAgentComments...) + + var localAddrs []btcjson.LocalAddressesResult + var ipv4Reachable, ipv6Reachable bool + for _, addr := range s.cfg.AddrMgr.LocalAddresses() { + localAddrs = append(localAddrs, btcjson.LocalAddressesResult{ + Address: addr.NA.IP.String(), + Port: addr.NA.Port, + Score: int32(addr.Score), + }) + if addr.NA.IP.To4() != nil { + ipv4Reachable = true + } else { + ipv6Reachable = true + } + } + + onionProxy := cfg.Proxy + if cfg.OnionProxy != "" { + onionProxy = cfg.OnionProxy + } + + var warnings string + unknownRulesWarned := s.cfg.Chain.GetWarnings() + if unknownRulesWarned { + warnings = "Warning: Unknown new rules activated! " + } + + var timeOffset int64 + if !s.cfg.SyncMgr.IsCurrent() { + ss := s.cfg.Chain.BestSnapshot() + bestHeader, err := s.cfg.Chain.HeaderByHash(&ss.Hash) + if err != nil { + return nil, err + } + timeOffset = int64(time.Since(bestHeader.Timestamp).Seconds()) + } + + reply := &btcjson.GetNetworkInfoResult{ + ProtocolVersion: int32(wire.ProtocolVersion), + Version: versionNumeric(), + Connections: s.cfg.ConnMgr.ConnectedCount(), + IncrementalFee: cfg.MinRelayTxFee, + LocalAddresses: localAddrs, + LocalRelay: !cfg.BlocksOnly, + LocalServices: s.cfg.Services.String(), + NetworkActive: true, + Networks: []btcjson.NetworksResult{ + { + Name: "ipv4", + Reachable: ipv4Reachable, + Proxy: cfg.Proxy, + }, + { + Name: "ipv6", + Reachable: ipv6Reachable, + Proxy: cfg.Proxy, + }, + { + Name: "onion", + + ProxyRandomizeCredentials: cfg.TorIsolation, + + Proxy: onionProxy, + Reachable: cfg.Proxy != "" || cfg.OnionProxy != "", + }, + }, + RelayFee: cfg.MinRelayTxFee, + SubVersion: ver.UserAgent, + TimeOffset: timeOffset, + Warnings: warnings, + } + return reply, nil +} + // handleGetPeerInfo implements the getpeerinfo command. func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { peers := s.cfg.ConnMgr.ConnectedPeers() @@ -2795,10 +2940,12 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i // doesn't fully parse, so ignore the error here. disbuf, _ := txscript.DisasmString(pkScript) + script := txscript.StripClaimScriptPrefix(pkScript) + // Get further info about the script. // Ignore the error here since an error means the script couldn't parse // and there is no additional information about it anyways. - scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(pkScript, + scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script, s.cfg.ChainParams) addresses := make([]string, len(addrs)) for i, addr := range addrs { @@ -2813,11 +2960,20 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i Asm: disbuf, Hex: hex.EncodeToString(pkScript), ReqSigs: int32(reqSigs), - Type: scriptClass.String(), Addresses: addresses, }, Coinbase: isCoinbase, } + + if len(script) < len(pkScript) { + txOutReply.ScriptPubKey.IsClaim = pkScript[0] == txscript.OP_CLAIMNAME || pkScript[0] == txscript.OP_UPDATECLAIM + txOutReply.ScriptPubKey.IsSupport = pkScript[0] == txscript.OP_SUPPORTCLAIM + txOutReply.ScriptPubKey.SubType = scriptClass.String() + txOutReply.ScriptPubKey.Type = txscript.ScriptClass.String(0) + } else { + txOutReply.ScriptPubKey.Type = scriptClass.String() + } + return txOutReply, nil } @@ -3066,6 +3222,8 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P vinListEntry.PrevOut = &btcjson.PrevOut{ Addresses: encodedAddrs, Value: btcutil.Amount(originTxOut.Value).ToBTC(), + IsClaim: originTxOut.PkScript[0] == txscript.OP_CLAIMNAME || originTxOut.PkScript[0] == txscript.OP_UPDATECLAIM, + IsSupport: originTxOut.PkScript[0] == txscript.OP_SUPPORTCLAIM, } } } @@ -3548,7 +3706,7 @@ func handleStop(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter case s.requestProcessShutdown <- struct{}{}: default: } - return "btcd stopping.", nil + return "lbcd stopping.", nil } // handleSubmitBlock implements the submitblock command. @@ -3756,7 +3914,7 @@ func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{ // NOTE: This is a btcsuite extension ported from github.com/decred/dcrd. func handleVersion(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { result := map[string]btcjson.VersionResult{ - "btcdjsonrpcapi": { + "lbcdjsonrpcapi": { VersionString: jsonrpcSemverString, Major: jsonrpcSemverMajor, Minor: jsonrpcSemverMinor, @@ -4350,7 +4508,7 @@ func (s *rpcServer) jsonRPCRead(w http.ResponseWriter, r *http.Request, isAdmin // jsonAuthFail sends a message back to the client if the http auth is rejected. func jsonAuthFail(w http.ResponseWriter) { - w.Header().Add("WWW-Authenticate", `Basic realm="btcd RPC"`) + w.Header().Add("WWW-Authenticate", `Basic realm="lbcd RPC"`) http.Error(w, "401 Unauthorized.", http.StatusUnauthorized) } @@ -4431,7 +4589,7 @@ func (s *rpcServer) Start() { func genCertPair(certFile, keyFile string) error { rpcsLog.Infof("Generating TLS certificates...") - org := "btcd autogenerated cert" + org := "lbcd autogenerated cert" validUntil := time.Now().Add(10 * 365 * 24 * time.Hour) cert, key, err := btcutil.NewTLSCertPair(org, validUntil, nil) if err != nil { @@ -4582,6 +4740,9 @@ type rpcserverConfig struct { // connection-related data and tasks. ConnMgr rpcserverConnManager + // AddrMgr is the server's instance of the AddressManager. + AddrMgr *addrmgr.AddrManager + // SyncMgr defines the sync manager for the RPC server to use. SyncMgr rpcserverSyncManager @@ -4612,6 +4773,9 @@ type rpcserverConfig struct { // The fee estimator keeps track of how long transactions are left in // the mempool before they are mined into blocks. FeeEstimator *mempool.FeeEstimator + + // Services represents the services supported by this node. + Services wire.ServiceFlag } // newRPCServer returns a new instance of the rpcServer struct. diff --git a/rpcserverhelp.go b/rpcserverhelp.go index ac0bf42d..a124e492 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -454,6 +454,27 @@ var helpDescsEnUS = map[string]string{ "getnetworkhashps-height": "Perform estimate ending with this height or -1 for current best chain block height", "getnetworkhashps--result0": "Estimated hashes per second", + // GetNetworkInfo help. + "getnetworkinfo--synopsis": "Returns an object containing various state info regarding P2P networking.", + "getnetworkinfo--result0--desc": "GetNetworkInfo object", + "getnetworkinfo--result0--key": "Field name", + "getnetworkinfo--result0--value": "Object containing the network info", + + // GetNetworkInfoResult help. + "getnetworkinforesult-version": "The server version", + "getnetworkinforesult-subversion": "The server subversion string", + "getnetworkinforesult-protocolversion": "The protocol version", + "getnetworkinforesult-localservices": "The services we offer to the network", + "getnetworkinforesult-localrelay": "True if transaction relay is requested from peers", + "getnetworkinforesult-timeoffset": "The time offset", + "getnetworkinforesult-connections": "The number of connections", + "getnetworkinforesult-networkactive": "Whether p2p networking is enabled", + "getnetworkinforesult-networks": "Information per network", + "getnetworkinforesult-relayfee": "Minimum relay fee for transactions in BTC/kB", + "getnetworkinforesult-incrementalfee": "Minimum fee increment for mempool limiting or BIP 125 replacement in BTC/kB", + "getnetworkinforesult-localaddresses": "List of local addresses", + "getnetworkinforesult-warnings": "Any network and blockchain warnings", + // GetNetTotalsCmd help. "getnettotals--synopsis": "Returns a JSON object containing network traffic statistics.", @@ -819,6 +840,7 @@ var rpcResultTypes = map[string][]interface{}{ "getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)}, "getnettotals": {(*btcjson.GetNetTotalsResult)(nil)}, "getnetworkhashps": {(*int64)(nil)}, + "getnetworkinfo": {(*map[string]btcjson.GetNetworkInfoResult)(nil)}, "getnodeaddresses": {(*[]btcjson.GetNodeAddressesResult)(nil)}, "getpeerinfo": {(*[]btcjson.GetPeerInfoResult)(nil)}, "getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)}, diff --git a/server.go b/server.go index 6f6050c6..84cb0be2 100644 --- a/server.go +++ b/server.go @@ -2950,6 +2950,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, Listeners: rpcListeners, StartupTime: startupTime.Unix(), ConnMgr: &rpcConnManager{&s}, + AddrMgr: amgr, SyncMgr: &rpcSyncMgr{&s, s.syncManager}, TimeSource: s.timeSource, Chain: s.chain, @@ -2962,6 +2963,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, AddrIndex: s.addrIndex, CfIndex: s.cfIndex, FeeEstimator: s.feeEstimator, + Services: s.services, }) if err != nil { return nil, err diff --git a/version.go b/version.go index d6ff9171..23f1f3de 100644 --- a/version.go +++ b/version.go @@ -57,6 +57,11 @@ func version() string { return version } +// Numeric returns the application version as an integer. +func versionNumeric() int32 { + return int32(2 ^ appMajor*3 ^ appMinor*5 ^ appPatch) +} + // normalizeVerString returns the passed string stripped of all characters which // are not valid according to the semantic versioning guidelines for pre-release // version and build metadata strings. In particular they MUST only contain -- 2.45.2 From 73d8f4762f69c35570a33251e0365a18bec5db39 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 28 Oct 2021 16:29:03 -0400 Subject: [PATCH 359/459] [lbry] rpc: import invalidate/reconsiderblock from bchd --- blockchain/chain.go | 109 ++++++++++++++++++++++++++++++++++++++++++ blockchain/process.go | 34 +++++++------ rpcserver.go | 28 ++++++++++- rpcserverhelp.go | 10 ++++ 4 files changed, 165 insertions(+), 16 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index 00e2f3a6..0e48b694 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1642,6 +1642,115 @@ func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Has return headers } +// InvalidateBlock takes a block hash and invalidates it. +// +// This function is safe for concurrent access. +func (b *BlockChain) InvalidateBlock(hash *chainhash.Hash) error { + return b.invalidateBlock(hash) +} + +// invalidateBlock takes a block hash and invalidates it. +func (b *BlockChain) invalidateBlock(hash *chainhash.Hash) error { + node := b.index.LookupNode(hash) + if node == nil { + err := fmt.Errorf("block %s is not known", hash) + return err + } + + // No need to invalidate if its already invalid. + if node.status.KnownInvalid() { + err := fmt.Errorf("block %s is already invalid", hash) + return err + } + + if node.parent == nil { + err := fmt.Errorf("block %s has no parent", hash) + return err + } + + b.index.SetStatusFlags(node, statusValidateFailed) + b.index.UnsetStatusFlags(node, statusValid) + + b.chainLock.Lock() + defer b.chainLock.Unlock() + detachNodes, attachNodes := b.getReorganizeNodes(node.parent) + + err := b.reorganizeChain(detachNodes, attachNodes) + if err != nil { + return err + } + + for i, e := 0, detachNodes.Front(); e != nil; i, e = i+1, e.Next() { + n := e.Value.(*blockNode) + + b.index.SetStatusFlags(n, statusInvalidAncestor) + b.index.UnsetStatusFlags(n, statusValid) + } + + if writeErr := b.index.flushToDB(); writeErr != nil { + log.Warnf("Error flushing block index changes to disk: %v", writeErr) + } + + return nil +} + +// ReconsiderBlock takes a block hash and allows it to be revalidated. +// +// This function is safe for concurrent access. +func (b *BlockChain) ReconsiderBlock(hash *chainhash.Hash) error { + return b.reconsiderBlock(hash) +} + +// reconsiderBlock takes a block hash and allows it to be revalidated. +func (b *BlockChain) reconsiderBlock(hash *chainhash.Hash) error { + node := b.index.LookupNode(hash) + if node == nil { + err := fmt.Errorf("block %s is not known", hash) + return err + } + + // No need to reconsider, it is already valid. + if node.status.KnownValid() { + err := fmt.Errorf("block %s is already valid", hash) + return err + } + + // Keep a reference to the first node in the chain of invalid + // blocks so we can reprocess after status flags are updated. + firstNode := node + + // Find previous node to the point where the blocks are valid again. + for n := node; n.status.KnownInvalid(); n = n.parent { + b.index.UnsetStatusFlags(n, statusInvalidAncestor) + b.index.UnsetStatusFlags(n, statusValidateFailed) + + firstNode = n + } + + var blk *btcutil.Block + err := b.db.View(func(dbTx database.Tx) error { + var err error + blk, err = dbFetchBlockByNode(dbTx, firstNode) + return err + }) + if err != nil { + return err + } + + // Process it all again. This will take care of the + // orphans as well. + _, _, err = b.ProcessBlock(blk, BFNoDupBlockCheck) + if err != nil { + return err + } + + if writeErr := b.index.flushToDB(); writeErr != nil { + log.Warnf("Error flushing block index changes to disk: %v", writeErr) + } + + return nil +} + // ClaimTrie returns the claimTrie associated wit hthe chain. func (b *BlockChain) ClaimTrie() *claimtrie.ClaimTrie { return b.claimTrie diff --git a/blockchain/process.go b/blockchain/process.go index a48b6e50..8aaa91bc 100644 --- a/blockchain/process.go +++ b/blockchain/process.go @@ -29,6 +29,10 @@ const ( // not be performed. BFNoPoWCheck + // BFNoDupBlockCheck signals if the block should skip existence + // checks. + BFNoDupBlockCheck + // BFNone is a convenience value to specifically indicate no flags. BFNone BehaviorFlags = 0 ) @@ -148,24 +152,26 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo blockHash := block.Hash() log.Tracef("Processing block %v", blockHash) - // The block must not already exist in the main chain or side chains. - exists, err := b.blockExists(blockHash) - if err != nil { - return false, false, err - } - if exists { - str := fmt.Sprintf("already have block %v", blockHash) - return false, false, ruleError(ErrDuplicateBlock, str) - } + if flags&BFNoDupBlockCheck != BFNoDupBlockCheck { + // The block must not already exist in the main chain or side chains. + exists, err := b.blockExists(blockHash) + if err != nil { + return false, false, err + } + if exists { + str := fmt.Sprintf("already have block %v", blockHash) + return false, false, ruleError(ErrDuplicateBlock, str) + } - // The block must not already exist as an orphan. - if _, exists := b.orphans[*blockHash]; exists { - str := fmt.Sprintf("already have block (orphan) %v", blockHash) - return false, false, ruleError(ErrDuplicateBlock, str) + // The block must not already exist as an orphan. + if _, exists := b.orphans[*blockHash]; exists { + str := fmt.Sprintf("already have block (orphan) %v", blockHash) + return false, false, ruleError(ErrDuplicateBlock, str) + } } // Perform preliminary sanity checks on the block and its transactions. - err = checkBlockSanity(block, b.chainParams.PowLimit, b.timeSource, flags) + err := checkBlockSanity(block, b.chainParams.PowLimit, b.timeSource, flags) if err != nil { return false, false, err } diff --git a/rpcserver.go b/rpcserver.go index 5c20436d..4797d64f 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -168,8 +168,10 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getrawtransaction": handleGetRawTransaction, "gettxout": handleGetTxOut, "help": handleHelp, + "invalidateblock": handleInvalidateBlock, "node": handleNode, "ping": handlePing, + "reconsiderblock": handleReconsiderBlock, "searchrawtransactions": handleSearchRawTransactions, "sendrawtransaction": handleSendRawTransaction, "setgenerate": handleSetGenerate, @@ -237,9 +239,7 @@ var rpcUnimplemented = map[string]struct{}{ "getchaintips": {}, "getmempoolentry": {}, "getwork": {}, - "invalidateblock": {}, "preciousblock": {}, - "reconsiderblock": {}, } // Commands that are available to a limited user @@ -2977,6 +2977,30 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i return txOutReply, nil } +// handleInvalidateBlock implements the invalidateblock command +func handleInvalidateBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.InvalidateBlockCmd) + + hash, err := chainhash.NewHashFromStr(c.BlockHash) + if err != nil { + return nil, err + } + + return nil, s.cfg.Chain.InvalidateBlock(hash) +} + +// handleReconsiderBlock implements the reconsiderblock command +func handleReconsiderBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.ReconsiderBlockCmd) + + hash, err := chainhash.NewHashFromStr(c.BlockHash) + if err != nil { + return nil, err + } + + return nil, s.cfg.Chain.ReconsiderBlock(hash) +} + // handleHelp implements the help command. func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*btcjson.HelpCmd) diff --git a/rpcserverhelp.go b/rpcserverhelp.go index a124e492..038b3495 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -568,10 +568,18 @@ var helpDescsEnUS = map[string]string{ "help--result0": "List of commands", "help--result1": "Help for specified command", + // InvalidateBlockCmd + "invalidateblock--synopsis": "Invalidate a block.", + "invalidateblock-blockhash": "Hash of the block you want to invalidate", + // PingCmd help. "ping--synopsis": "Queues a ping to be sent to each connected peer.\n" + "Ping times are provided by getpeerinfo via the pingtime and pingwait fields.", + // ReconsiderBlockCmd + "reconsiderblock--synopsis": "Reconsider a block for validation.", + "reconsiderblock-blockhash": "Hash of the block you want to reconsider", + // SearchRawTransactionsCmd help. "searchrawtransactions--synopsis": "Returns raw data for transactions involving the passed address.\n" + "Returned transactions are pulled from both the database, and transactions currently in the mempool.\n" + @@ -848,7 +856,9 @@ var rpcResultTypes = map[string][]interface{}{ "gettxout": {(*btcjson.GetTxOutResult)(nil)}, "node": nil, "help": {(*string)(nil), (*string)(nil)}, + "invalidateblock": nil, "ping": nil, + "reconsiderblock": nil, "searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)}, "sendrawtransaction": {(*string)(nil)}, "setgenerate": nil, -- 2.45.2 From 1ea849d509c1b50478d80a4c5090022666bf0605 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 28 Oct 2021 21:58:57 -0400 Subject: [PATCH 360/459] [lbry] rpc: added getchaintips RPC remove btcjson dep in chainquery --- blockchain/chainquery.go | 123 +++++++++++++++++++++++++++++++++++++ btcjson/chainsvrresults.go | 8 +++ rpcserver.go | 11 ++++ rpcserverhelp.go | 17 +++++ 4 files changed, 159 insertions(+) create mode 100644 blockchain/chainquery.go diff --git a/blockchain/chainquery.go b/blockchain/chainquery.go new file mode 100644 index 00000000..162a1d47 --- /dev/null +++ b/blockchain/chainquery.go @@ -0,0 +1,123 @@ +package blockchain + +import ( + "sort" + "strings" + + btcutil "github.com/lbryio/lbcutil" +) + +type ChainTip struct { // duplicate of btcjson.GetChainTipsResult to avoid circular reference + Height int64 + Hash string + BranchLen int64 + Status string +} + +// nodeHeightSorter implements sort.Interface to allow a slice of nodes to +// be sorted by height in ascending order. +type nodeHeightSorter []ChainTip + +// Len returns the number of nodes in the slice. It is part of the +// sort.Interface implementation. +func (s nodeHeightSorter) Len() int { + return len(s) +} + +// Swap swaps the nodes at the passed indices. It is part of the +// sort.Interface implementation. +func (s nodeHeightSorter) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Less returns whether the node with index i should sort before the node with +// index j. It is part of the sort.Interface implementation. +func (s nodeHeightSorter) Less(i, j int) bool { + // To ensure stable order when the heights are the same, fall back to + // sorting based on hash. + if s[i].Height == s[j].Height { + return strings.Compare(s[i].Hash, s[j].Hash) < 0 + } + return s[i].Height < s[j].Height +} + +// ChainTips returns information, in JSON-RPC format, about all the currently +// known chain tips in the block index. +func (b *BlockChain) ChainTips() []ChainTip { + // we need our current tip + // we also need all of our orphans that aren't in the prevOrphans + var results []ChainTip + + tip := b.bestChain.Tip() + results = append(results, ChainTip{ + Height: int64(tip.height), + Hash: tip.hash.String(), + BranchLen: 0, + Status: "active", + }) + + b.orphanLock.RLock() + defer b.orphanLock.RUnlock() + + notInBestChain := func(block *btcutil.Block) bool { + node := b.bestChain.NodeByHeight(block.Height()) + if node == nil { + return false + } + return node.hash.IsEqual(block.Hash()) + } + + for hash, orphan := range b.orphans { + if len(b.prevOrphans[hash]) > 0 { + continue + } + fork := orphan.block + for fork != nil && notInBestChain(fork) { + fork = b.orphans[*fork.Hash()].block + } + + result := ChainTip{ + Height: int64(orphan.block.Height()), + Hash: hash.String(), + BranchLen: int64(orphan.block.Height() - fork.Height()), + } + + // Determine the status of the chain tip. + // + // active: + // The current best chain tip. + // + // invalid: + // The block or one of its ancestors is invalid. + // + // headers-only: + // The block or one of its ancestors does not have the full block data + // available which also means the block can't be validated or + // connected. + // + // valid-fork: + // The block is fully validated which implies it was probably part of + // main chain at one point and was reorganized. + // + // valid-headers: + // The full block data is available and the header is valid, but the + // block was never validated which implies it was probably never part + // of the main chain. + tipStatus := b.index.LookupNode(&hash).status + if tipStatus.KnownInvalid() { + result.Status = "invalid" + } else if !tipStatus.HaveData() { + result.Status = "headers-only" + } else if tipStatus.KnownValid() { + result.Status = "valid-fork" + } else { + result.Status = "valid-headers" + } + + results = append(results, result) + } + + // Generate the results sorted by descending height. + sort.Sort(sort.Reverse(nodeHeightSorter(results))) + return results +} diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 46d454c5..811883c7 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -325,6 +325,14 @@ type GetMempoolEntryResult struct { Depends []string `json:"depends"` } +// GetChainTipsResult models the data returns from the getchaintips command. +type GetChainTipsResult struct { + Height int64 `json:"height"` + Hash string `json:"hash"` + BranchLen int64 `json:"branchlen"` + Status string `json:"status"` +} + // GetMempoolInfoResult models the data returned from the getmempoolinfo // command. type GetMempoolInfoResult struct { diff --git a/rpcserver.go b/rpcserver.go index 4797d64f..6cfb962a 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -147,6 +147,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getblockcount": handleGetBlockCount, "getblockhash": handleGetBlockHash, "getblockheader": handleGetBlockHeader, + "getchaintips": handleGetChainTips, "getblocktemplate": handleGetBlockTemplate, "getcfilter": handleGetCFilter, "getcfilterheader": handleGetCFilterHeader, @@ -1471,6 +1472,16 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct return blockHeaderReply, nil } +// handleGetChainTips implements the getchaintips command. +func handleGetChainTips(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + tips := s.cfg.Chain.ChainTips() + results := make([]btcjson.GetChainTipsResult, 0, len(tips)) + for _, tip := range tips { + results = append(results, btcjson.GetChainTipsResult(tip)) + } + return results, nil +} + // encodeTemplateID encodes the passed details into an ID that can be used to // uniquely identify a block template. func encodeTemplateID(prevHash *chainhash.Hash, lastGenerated time.Time) string { diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 038b3495..acc71212 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -353,6 +353,22 @@ var helpDescsEnUS = map[string]string{ "getblocktemplate--condition2": "mode=proposal, accepted", "getblocktemplate--result1": "An error string which represents why the proposal was rejected or nothing if accepted", + // GetChainTips help. + "getchaintips--synopsis": "Returns information about all known chain tips the in the block tree.\n\n" + + "The statuses in the result have the following meanings:\n" + + "active: The current best chain tip.\n" + + "invalid: The block or one of its ancestors is invalid.\n" + + "headers-only: The block or one of its ancestors does not have the full block data available which also means the block can't be validated or connected.\n" + + "valid-fork: The block is fully validated which implies it was probably part of the main chain at one point and was reorganized.\n" + + "valid-headers: The full block data is available and the header is valid, but the block was never validated which implies it was probably never part of the main chain.", + + // GetChainTipsResult help. + "getchaintipsresult-height": "The height of the chain tip", + "getchaintipsresult-hash": "The block hash of the chain tip", + "getchaintipsresult-branchlen": "The length of the branch that connects the tip to the main chain (0 for the main chain tip)", + "getchaintipsresult-status": "The status of the chain (active, invalid, headers-only, valid-fork, valid-headers)", + "getchaintipsresults--result0": "test", + // GetCFilterCmd help. "getcfilter--synopsis": "Returns a block's committed filter given its hash.", "getcfilter-filtertype": "The type of filter to return (0=regular)", @@ -837,6 +853,7 @@ var rpcResultTypes = map[string][]interface{}{ "getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)}, "getcfilter": {(*string)(nil)}, "getcfilterheader": {(*string)(nil)}, + "getchaintips": {(*[]btcjson.GetChainTipsResult)(nil)}, "getconnectioncount": {(*int32)(nil)}, "getcurrentnet": {(*uint32)(nil)}, "getdifficulty": {(*float64)(nil)}, -- 2.45.2 From 5537ebbf0ccc5fe962b0dff934eb96b42cb9e026 Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Fri, 14 Jan 2022 15:49:33 -0500 Subject: [PATCH 361/459] [lbry] rpc: add GetChainTips rpc command --- rpcclient/chain.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/rpcclient/chain.go b/rpcclient/chain.go index b3735cee..d2ee97b6 100644 --- a/rpcclient/chain.go +++ b/rpcclient/chain.go @@ -380,6 +380,49 @@ func (c *Client) GetChainTxStatsNBlocksBlockHash(nBlocks int32, blockHash chainh return c.GetChainTxStatsNBlocksBlockHashAsync(nBlocks, blockHash).Receive() } +// FutureGetChainTipsResult is a future promise to deliver the result of a +// GetChainTipsAsync RPC invocation (or an applicable error). +type FutureGetChainTipsResult chan *Response + +// Receive waits for the Response promised by the future and returns transaction statistics +func (r FutureGetChainTipsResult) Receive() ([]btcjson.GetChainTipsResult, error) { + res, err := ReceiveFuture(r) + if err != nil { + return nil, err + } + + var chainTips []btcjson.GetChainTipsResult + err = json.Unmarshal(res, &chainTips) + if err != nil { + return nil, err + } + + return chainTips, nil +} + +// GetChainTipsAsync returns an instance of a type that can be used to get +// the result of the RPC at some future time by invoking the Receive function on +// the returned instance. +// +// See GetChainTips for the blocking version and more details. +func (c *Client) GetChainTipsAsync() FutureGetChainTipsResult { + cmd := btcjson.NewGetChainTipsCmd() + return c.SendCmd(cmd) +} + +// GetChainTips returns information about all known tips in the block tree, +// including the main chain as well as orphaned branches. +// +// Possible values for status: +// "invalid" This branch contains at least one invalid block +// "headers-only" Not all blocks for this branch are available, but the headers are valid +// "valid-headers" All blocks are available for this branch, but they were never fully validated +// "valid-fork" This branch is not part of the active chain, but is fully validated +// "active" This is the tip of the active main chain, which is certainly valid +func (c *Client) GetChainTips() ([]btcjson.GetChainTipsResult, error) { + return c.GetChainTipsAsync().Receive() +} + // FutureGetDifficultyResult is a future promise to deliver the result of a // GetDifficultyAsync RPC invocation (or an applicable error). type FutureGetDifficultyResult chan *Response -- 2.45.2 From 64884458f92b071808ae35df43291af789534f1b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 19 Aug 2021 16:39:53 -0400 Subject: [PATCH 362/459] [lbry] rpc, mining: fix generatetoaddress --- mining/cpuminer/cpuminer.go | 9 +++++---- rpcserverhelp.go | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mining/cpuminer/cpuminer.go b/mining/cpuminer/cpuminer.go index b9d1d222..64cfaf50 100644 --- a/mining/cpuminer/cpuminer.go +++ b/mining/cpuminer/cpuminer.go @@ -274,7 +274,7 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, blockHeight int32, // increment the number of hashes completed for each // attempt accordingly. header.Nonce = i - hash := header.BlockHash() + hash := header.BlockPoWHash() hashesCompleted += 2 // The block is solved when the new block hash is less @@ -544,7 +544,7 @@ func (m *CPUMiner) NumWorkers() int32 { // detecting when it is performing stale work and reacting accordingly by // generating a new block template. When a block is solved, it is submitted. // The function returns a list of the hashes of generated blocks. -func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) { +func (m *CPUMiner) GenerateNBlocks(n uint32, payToAddr btcutil.Address) ([]*chainhash.Hash, error) { m.Lock() // Respond with an error if server is already mining. @@ -590,8 +590,9 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) { // Choose a payment address at random. rand.Seed(time.Now().UnixNano()) - payToAddr := m.cfg.MiningAddrs[rand.Intn(len(m.cfg.MiningAddrs))] - + if payToAddr == nil { + payToAddr = m.cfg.MiningAddrs[rand.Intn(len(m.cfg.MiningAddrs))] + } // Create a new block template using the available transactions // in the memory pool as a source of transactions to potentially // include in the block. diff --git a/rpcserverhelp.go b/rpcserverhelp.go index acc71212..2d191649 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -842,6 +842,7 @@ var rpcResultTypes = map[string][]interface{}{ "decodescript": {(*btcjson.DecodeScriptResult)(nil)}, "estimatefee": {(*float64)(nil)}, "generate": {(*[]string)(nil)}, + "generatetoaddress": {(*[]string)(nil)}, "getaddednodeinfo": {(*[]string)(nil), (*[]btcjson.GetAddedNodeInfoResult)(nil)}, "getbestblock": {(*btcjson.GetBestBlockResult)(nil)}, "getbestblockhash": {(*string)(nil)}, -- 2.45.2 From 405897fa382532740b5e4505bdee159e882dfffe Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 26 Nov 2021 11:36:30 -0500 Subject: [PATCH 363/459] [lbry] blockchain: fix crash on unlock generate/invalidate loop --- blockchain/accept.go | 4 +++- blockchain/chain.go | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/blockchain/accept.go b/blockchain/accept.go index 6acba30d..67657e4f 100644 --- a/blockchain/accept.go +++ b/blockchain/accept.go @@ -84,9 +84,11 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) // Notify the caller that the new block was accepted into the block // chain. The caller would typically want to react by relaying the // inventory to other peers. + b.notificationSendLock.Lock() + defer b.notificationSendLock.Unlock() b.chainLock.Unlock() + defer b.chainLock.Lock() b.sendNotification(NTBlockAccepted, block) - b.chainLock.Lock() return isMainChain, nil } diff --git a/blockchain/chain.go b/blockchain/chain.go index 0e48b694..4da5fbc1 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -116,6 +116,12 @@ type BlockChain struct { // fields in this struct below this point. chainLock sync.RWMutex + // notificationSendLock helps us only process one block at a time. + // It's definitely a hack. DCRD has much better structure in this regard. + // Without this you will get an error if you invalidate a block and then generate more right after. + // Taken from https://github.com/gcash/bchd/pull/308 + notificationSendLock sync.Mutex + // These fields are related to the memory block index. They both have // their own locks, however they are often also protected by the chain // lock to help prevent logic races when blocks are being processed. @@ -683,9 +689,11 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, // Notify the caller that the block was connected to the main chain. // The caller would typically want to react with actions such as // updating wallets. + b.notificationSendLock.Lock() + defer b.notificationSendLock.Unlock() b.chainLock.Unlock() + defer b.chainLock.Lock() b.sendNotification(NTBlockConnected, block) - b.chainLock.Lock() return nil } @@ -808,9 +816,11 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view // Notify the caller that the block was disconnected from the main // chain. The caller would typically want to react with actions such as // updating wallets. + b.notificationSendLock.Lock() + defer b.notificationSendLock.Unlock() b.chainLock.Unlock() + defer b.chainLock.Lock() b.sendNotification(NTBlockDisconnected, block) - b.chainLock.Lock() return nil } @@ -1646,6 +1656,8 @@ func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Has // // This function is safe for concurrent access. func (b *BlockChain) InvalidateBlock(hash *chainhash.Hash) error { + b.chainLock.Lock() + defer b.chainLock.Unlock() return b.invalidateBlock(hash) } @@ -1671,8 +1683,6 @@ func (b *BlockChain) invalidateBlock(hash *chainhash.Hash) error { b.index.SetStatusFlags(node, statusValidateFailed) b.index.UnsetStatusFlags(node, statusValid) - b.chainLock.Lock() - defer b.chainLock.Unlock() detachNodes, attachNodes := b.getReorganizeNodes(node.parent) err := b.reorganizeChain(detachNodes, attachNodes) @@ -1727,6 +1737,7 @@ func (b *BlockChain) reconsiderBlock(hash *chainhash.Hash) error { firstNode = n } + // do we need an rlock on chainstate for this section? var blk *btcutil.Block err := b.db.View(func(dbTx database.Tx) error { var err error -- 2.45.2 From 67848302462651515c99e7ae1c66a008fc26ec49 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Wed, 29 Dec 2021 21:30:44 -0800 Subject: [PATCH 364/459] [lbry] blockchain: clear statusValid upon statusValidateFailed is set The status management of index does need some refactoring. For now, we just manually clear the statusValid in every occurance of statusValidateFailed being set. Co-authored-by: Roy Lee --- blockchain/chain.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index 4da5fbc1..9a6ec216 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1004,6 +1004,7 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error err = b.checkConnectBlock(n, block, view, nil) if err != nil { if _, ok := err.(RuleError); ok { + b.index.UnsetStatusFlags(n, statusValid) b.index.SetStatusFlags(n, statusValidateFailed) for de := e.Next(); de != nil; de = de.Next() { dn := de.Value.(*blockNode) @@ -1141,6 +1142,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla if err == nil { b.index.SetStatusFlags(node, statusValid) } else if _, ok := err.(RuleError); ok { + b.index.UnsetStatusFlags(node, statusValid) b.index.SetStatusFlags(node, statusValidateFailed) } else { return false, err @@ -1175,6 +1177,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla // that status of the block as invalid and flush the // index state to disk before returning with the error. if _, ok := err.(RuleError); ok { + b.index.UnsetStatusFlags(node, statusValid) b.index.SetStatusFlags( node, statusValidateFailed, ) @@ -1720,7 +1723,7 @@ func (b *BlockChain) reconsiderBlock(hash *chainhash.Hash) error { } // No need to reconsider, it is already valid. - if node.status.KnownValid() { + if node.status.KnownValid() && !node.status.KnownInvalid() { // second clause works around old bug err := fmt.Errorf("block %s is already valid", hash) return err } -- 2.45.2 From e0870db24e56b4c9fb92629e5eb4cee621ca4a7c Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 19 Aug 2021 14:41:48 -0400 Subject: [PATCH 365/459] [lbry] mining: calculate claimtrie root hash for generate RPC --- mining/mining.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mining/mining.go b/mining/mining.go index 4daad1a6..6eb00316 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -843,6 +843,11 @@ mempoolLoop: // chain with no issues. block := btcutil.NewBlock(&msgBlock) block.SetHeight(nextBlockHeight) + + if err := g.chain.SetClaimtrieHeader(block, blockUtxos); err != nil { + return nil, err + } + if err := g.chain.CheckConnectBlockTemplate(block); err != nil { return nil, err } -- 2.45.2 From 29f64f9dcf6133a5a87734d1b6fe76a75a13067c Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 23:22:36 -0700 Subject: [PATCH 366/459] [lbry] mining: enlarge updateHash channel buffers --- mining/cpuminer/cpuminer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mining/cpuminer/cpuminer.go b/mining/cpuminer/cpuminer.go index 64cfaf50..7659d1a2 100644 --- a/mining/cpuminer/cpuminer.go +++ b/mining/cpuminer/cpuminer.go @@ -638,6 +638,6 @@ func New(cfg *Config) *CPUMiner { numWorkers: defaultNumWorkers, updateNumWorkers: make(chan struct{}), queryHashesPerSec: make(chan float64), - updateHashes: make(chan uint64), + updateHashes: make(chan uint64, 512), } } -- 2.45.2 From d20a2e53b429138363af857653f9fd89deb71c6e Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 7 Feb 2022 23:18:14 -0800 Subject: [PATCH 367/459] [lbry] mining: return witness_script instead of raw witness_commitment in GBT --- mining/mining.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mining/mining.go b/mining/mining.go index 6eb00316..4f3ac9e5 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -868,7 +868,7 @@ mempoolLoop: } // AddWitnessCommitment adds the witness commitment as an OP_RETURN outpout -// within the coinbase tx. The raw commitment is returned. +// within the coinbase tx. The witness script is returned. func AddWitnessCommitment(coinbaseTx *btcutil.Tx, blockTxns []*btcutil.Tx) []byte { @@ -907,7 +907,7 @@ func AddWitnessCommitment(coinbaseTx *btcutil.Tx, coinbaseTx.MsgTx().TxOut = append(coinbaseTx.MsgTx().TxOut, commitmentOutput) - return witnessCommitment + return witnessScript } // UpdateBlockTime updates the timestamp in the header of the passed block to -- 2.45.2 From 6c0360fa42f3bf3215353968430b5cb4d0f1b661 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 9 Nov 2021 15:50:02 -0500 Subject: [PATCH 368/459] [lbry] rpcserver: made estimatesmartfee call estimatefee (for now) --- rpcserver.go | 24 +++++++++++++++++++++--- rpcserverhelp.go | 12 +++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 6cfb962a..195d1c6c 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -137,6 +137,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "decoderawtransaction": handleDecodeRawTransaction, "decodescript": handleDecodeScript, "estimatefee": handleEstimateFee, + "estimatesmartfee": handleEstimateSmartFee, "generate": handleGenerate, "generatetoaddress": handleGenerateToAddress, "getaddednodeinfo": handleGetAddedNodeInfo, @@ -879,23 +880,40 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) c := cmd.(*btcjson.EstimateFeeCmd) if s.cfg.FeeEstimator == nil { - return nil, errors.New("Fee estimation disabled") + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: "Fee estimation disabled", + } } if c.NumBlocks <= 0 { - return -1.0, errors.New("Parameter NumBlocks must be positive") + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Parameter NumBlocks must be positive", + } } feeRate, err := s.cfg.FeeEstimator.EstimateFee(uint32(c.NumBlocks)) if err != nil { - return -1.0, err + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: err.Error(), + } } // Convert to satoshis per kb. return float64(feeRate), nil } +func handleEstimateSmartFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.EstimateSmartFeeCmd) + + rpcsLog.Debugf("EstimateSmartFee is not implemented; falling back to EstimateFee. Requested mode: %s", c.EstimateMode) + + return handleEstimateFee(s, &btcjson.EstimateFeeCmd{NumBlocks: c.ConfTarget}, closeChan) +} + func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { // Respond with an error if there are no addresses to pay the // created blocks to. diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 2d191649..881cfeb5 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -123,9 +123,18 @@ var helpDescsEnUS = map[string]string{ "blocks have been generated.", "estimatefee-numblocks": "The maximum number of blocks which can be " + "generated before the transaction is mined.", - "estimatefee--result0": "Estimated fee per kilobyte in satoshis for a block to " + + "estimatefee--result0": "Estimated fee per kilobyte in satoshis necessary for a block to " + "be mined in the next NumBlocks blocks.", + "estimatesmartfee--synopsis": "Estimate the fee per kilobyte in satoshis " + + "required for a transaction to be mined before a certain number of " + + "blocks have been generated. Same as estimatefee presently.", + "estimatesmartfee-conftarget": "The maximum number of blocks which can be " + + "generated before the transaction is mined.", + "estimatesmartfee-estimatemode": "Unused at present.", + "estimatesmartfee--result0": "Estimated fee per kilobyte in satoshis necessary for a block to " + + "be mined in the next ConfTarget blocks.", + // GenerateCmd help "generate--synopsis": "Generates a set number of blocks (simnet or regtest only) and returns a JSON\n" + " array of their hashes.", @@ -841,6 +850,7 @@ var rpcResultTypes = map[string][]interface{}{ "decoderawtransaction": {(*btcjson.TxRawDecodeResult)(nil)}, "decodescript": {(*btcjson.DecodeScriptResult)(nil)}, "estimatefee": {(*float64)(nil)}, + "estimatesmartfee": {(*float64)(nil)}, "generate": {(*[]string)(nil)}, "generatetoaddress": {(*[]string)(nil)}, "getaddednodeinfo": {(*[]string)(nil), (*[]btcjson.GetAddedNodeInfoResult)(nil)}, -- 2.45.2 From 8c984993a8cd734b8c3309b93729cc1164878552 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Wed, 29 Dec 2021 16:58:17 -0500 Subject: [PATCH 369/459] [lbry] rpcserver: made invalidate/reconsiderBlock return RPC errors --- rpcserver.go | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 195d1c6c..378155a0 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3012,10 +3012,20 @@ func handleInvalidateBlock(s *rpcServer, cmd interface{}, closeChan <-chan struc hash, err := chainhash.NewHashFromStr(c.BlockHash) if err != nil { - return nil, err + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Unable to parse hash: " + err.Error(), + } } - return nil, s.cfg.Chain.InvalidateBlock(hash) + err = s.cfg.Chain.InvalidateBlock(hash) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: "Unable to invalidate block: " + err.Error(), + } + } + return nil, nil } // handleReconsiderBlock implements the reconsiderblock command @@ -3024,10 +3034,20 @@ func handleReconsiderBlock(s *rpcServer, cmd interface{}, closeChan <-chan struc hash, err := chainhash.NewHashFromStr(c.BlockHash) if err != nil { - return nil, err + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Unable to parse hash: " + err.Error(), + } } - return nil, s.cfg.Chain.ReconsiderBlock(hash) + err = s.cfg.Chain.ReconsiderBlock(hash) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInternal.Code, + Message: "Unable to reconsider block: " + err.Error(), + } + } + return nil, nil } // handleHelp implements the help command. @@ -4303,7 +4323,7 @@ func (s *rpcServer) processRequest(request *btcjson.Request, isAdmin bool, close } else { jsonErr = &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidRequest.Code, - Message: "Invalid request: malformed", + Message: "Invalid request: " + err.Error(), } } } -- 2.45.2 From 568544961f0ac6cafa91158435e1369568314eb9 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 19 Apr 2022 18:41:17 -0700 Subject: [PATCH 370/459] [lbry] rpcserver: log the reason of submitblock rejection --- rpcserver.go | 1 + 1 file changed, 1 insertion(+) diff --git a/rpcserver.go b/rpcserver.go index 378155a0..91ddf64e 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3808,6 +3808,7 @@ func handleSubmitBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) // nodes. This will in turn relay it to the network like normal. _, err = s.cfg.SyncMgr.SubmitBlock(block, blockchain.BFNone) if err != nil { + rpcsLog.Infof("Rejected block %s via submitblock: %s", block.Hash(), err) return fmt.Sprintf("rejected: %s", err.Error()), nil } -- 2.45.2 From de2a54820766e1d12c1cdc70bc9ba8f9afc42c9d Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 14 Dec 2021 15:28:28 -0500 Subject: [PATCH 371/459] [lbry] btcjson: ladded claim related fields for wallet --- btcjson/walletsvrresults.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index 16df09bb..2b7354e7 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -25,7 +25,6 @@ type CreateWalletResult struct { type embeddedAddressInfo struct { Address string `json:"address"` ScriptPubKey string `json:"scriptPubKey"` - Solvable bool `json:"solvable"` Descriptor *string `json:"desc,omitempty"` IsScript bool `json:"isscript"` IsChange bool `json:"ischange"` @@ -229,6 +228,7 @@ type InfoWalletResult struct { PaytxFee float64 `json:"paytxfee"` RelayFee float64 `json:"relayfee"` Errors string `json:"errors"` + Staked float64 `json:"staked"` } // ListTransactionsResult models the data from the listtransactions command. @@ -293,7 +293,9 @@ type ListUnspentResult struct { RedeemScript string `json:"redeemScript,omitempty"` Amount float64 `json:"amount"` Confirmations int64 `json:"confirmations"` + Solvable bool `json:"solvable"` Spendable bool `json:"spendable"` + IsStake bool `json:"isstake"` } // SignRawTransactionError models the data that contains script verification -- 2.45.2 From 023aa5d6b0e5002dafecad25d1e13604480f53e5 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 12 Nov 2021 16:49:24 -0500 Subject: [PATCH 372/459] [lbry] btcjson: added optional address type for getnewaddress --- btcjson/walletsvrcmds.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index e4d676ff..8569c1d5 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -242,7 +242,8 @@ func NewGetBalancesCmd() *GetBalancesCmd { // GetNewAddressCmd defines the getnewaddress JSON-RPC command. type GetNewAddressCmd struct { - Account *string + Account *string + AddressType *string // must be one of legacy / p2pkh or p2sh-p2wkh / p2sh-segwit, or p2wkh / bech32 } // NewGetNewAddressCmd returns a new instance which can be used to issue a -- 2.45.2 From 0a0e79bc41aebea171d0f01695ac1475fad10fa2 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Tue, 3 Aug 2021 22:10:55 -0700 Subject: [PATCH 373/459] [lbry] enable segwit --- blockchain/merkle.go | 4 ++-- blockchain/weight.go | 4 ++-- netsync/manager.go | 9 ++++++++- peer/peer.go | 8 +++++++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/blockchain/merkle.go b/blockchain/merkle.go index 29479c1d..92b59c5e 100644 --- a/blockchain/merkle.go +++ b/blockchain/merkle.go @@ -230,8 +230,8 @@ func ValidateWitnessCommitment(blk *btcutil.Block) error { coinbaseWitness := coinbaseTx.MsgTx().TxIn[0].Witness if len(coinbaseWitness) != 1 { str := fmt.Sprintf("the coinbase transaction has %d items in "+ - "its witness stack when only one is allowed", - len(coinbaseWitness)) + "its witness stack when only one is allowed. Height: %d", + len(coinbaseWitness), blk.Height()) return ruleError(ErrInvalidWitnessCommitment, str) } witnessNonce := coinbaseWitness[0] diff --git a/blockchain/weight.go b/blockchain/weight.go index 9a3a10b3..7dc51b3f 100644 --- a/blockchain/weight.go +++ b/blockchain/weight.go @@ -20,11 +20,11 @@ const ( // weight of a "base" byte is 4, while the weight of a witness byte is // 1. As a result, for a block to be valid, the BlockWeight MUST be // less than, or equal to MaxBlockWeight. - MaxBlockWeight = 4000000 + MaxBlockWeight = 8000000 // MaxBlockBaseSize is the maximum number of bytes within a block // which can be allocated to non-witness data. - MaxBlockBaseSize = 2000000 + MaxBlockBaseSize = 8000000 // MaxBlockSigOpsCost is the maximum number of signature operations // allowed for a block. It is calculated via a weighted algorithm which diff --git a/netsync/manager.go b/netsync/manager.go index 2e3f05b0..69093610 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -1293,9 +1293,16 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) { break } } + + e := wire.BaseEncoding + // we think that the iv.Type set above is sufficient. If not: + // if peer.IsWitnessEnabled() { + // e = wire.WitnessEncoding + //} + state.requestQueue = requestQueue if len(gdmsg.InvList) > 0 { - peer.QueueMessage(gdmsg, nil) + peer.QueueMessageWithEncoding(gdmsg, nil, e) } } diff --git a/peer/peer.go b/peer/peer.go index ab8add08..ffedc6dc 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -2241,9 +2241,15 @@ func newPeerBase(origCfg *Config, inbound bool) *Peer { cfg.TrickleInterval = DefaultTrickleInterval } + encoding := wire.BaseEncoding + // we think this gets overwritten downstream. If not: + // if cfg.Services&wire.SFNodeWitness > 0 { + // encoding = wire.WitnessEncoding + //} + p := Peer{ inbound: inbound, - wireEncoding: wire.BaseEncoding, + wireEncoding: encoding, knownInventory: lru.NewCache(maxKnownInventory), stallControl: make(chan stallControlMsg, 1), // nonblocking sync outputQueue: make(chan outMsg, outputBufferSize), -- 2.45.2 From f3e1c96de95a9f6715f2bc8e61e445e6ea9809cf Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 30 Jul 2021 14:11:10 -0400 Subject: [PATCH 374/459] [lbry] config: enable upnp by default --- config.go | 2 ++ server.go | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/config.go b/config.go index 748a626d..adee6f78 100644 --- a/config.go +++ b/config.go @@ -66,6 +66,7 @@ const ( sampleConfigFilename = "sample-lbcd.conf" defaultTxIndex = false defaultAddrIndex = false + defaultUpnp = true ) var ( @@ -439,6 +440,7 @@ func loadConfig() (*config, []string, error) { Generate: defaultGenerate, TxIndex: defaultTxIndex, AddrIndex: defaultAddrIndex, + Upnp: defaultUpnp, } // Service options which are only added on Windows. diff --git a/server.go b/server.go index 84cb0be2..8a6ea6c5 100644 --- a/server.go +++ b/server.go @@ -3035,11 +3035,16 @@ func initListeners(amgr *addrmgr.AddrManager, listenAddrs []string, services wir } } } else { - if cfg.Upnp { + if cfg.Upnp && !cfg.RegressionTest && !cfg.SimNet { var err error nat, err = Discover() if err != nil { - srvrLog.Warnf("Can't discover upnp: %v", err) + srvrLog.Infof("Can't discover UPnP-enabled device: %v", err) + } else { + address, err := nat.GetExternalAddress() + if err == nil && address != nil { + srvrLog.Infof("UPnP successfully registered on %s", address.String()) + } } // nil nat here is fine, just means no upnp on network. } -- 2.45.2 From b8b2bd1584664f269b1e2371e255ab36883c6e73 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 22:09:51 -0700 Subject: [PATCH 375/459] [lbry] config: enable txindex by default --- config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.go b/config.go index adee6f78..de8385d3 100644 --- a/config.go +++ b/config.go @@ -64,7 +64,7 @@ const ( defaultMaxOrphanTxSize = 100000 defaultSigCacheMaxSize = 100000 sampleConfigFilename = "sample-lbcd.conf" - defaultTxIndex = false + defaultTxIndex = true defaultAddrIndex = false defaultUpnp = true ) -- 2.45.2 From 2add30af9a92763bea1e475782976370666e7151 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:30:24 -0400 Subject: [PATCH 376/459] [lbry] config: Add a number of missing options to sample-lbcd.conf. Correct "blacklist is applied before the blacklist" typo in help text. --- config.go | 2 +- sample-btcd.conf | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/config.go b/config.go index de8385d3..85325afc 100644 --- a/config.go +++ b/config.go @@ -100,7 +100,7 @@ type config struct { AddPeers []string `short:"a" long:"addpeer" description:"Add a peer to connect with at startup"` AddrIndex bool `long:"addrindex" description:"Maintain a full address-based transaction index which makes the searchrawtransactions RPC available"` AgentBlacklist []string `long:"agentblacklist" description:"A comma separated list of user-agent substrings which will cause lbcd to reject any peers whose user-agent contains any of the blacklisted substrings."` - AgentWhitelist []string `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause lbcd to require all peers' user-agents to contain one of the whitelisted substrings. The blacklist is applied before the blacklist, and an empty whitelist will allow all agents that do not fail the blacklist."` + AgentWhitelist []string `long:"agentwhitelist" description:"A comma separated list of user-agent substrings which will cause lbcd to require all peers' user-agents to contain one of the whitelisted substrings. The blacklist is applied before the whitelist, and an empty whitelist will allow all agents that do not fail the blacklist."` BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"` BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."` BlockMaxSize uint32 `long:"blockmaxsize" description:"Maximum block size in bytes to be used when creating a block"` diff --git a/sample-btcd.conf b/sample-btcd.conf index 0a765fca..e1b6cba6 100644 --- a/sample-btcd.conf +++ b/sample-btcd.conf @@ -46,7 +46,7 @@ ; to correlate connections. ; torisolation=1 -; Use Universal Plug and Play (UPnP) to automatically open the listen port +; Do NOT use Universal Plug and Play (UPnP) to automatically open the listen port ; and obtain the external IP address from supported devices. NOTE: This option ; will have no effect if exernal IP addresses are specified. ; upnp=1 @@ -114,6 +114,9 @@ ; banduration=24h ; banduration=11h30m15s +; Minimum time between attempts to send new inventory to a connected peer. +; trickleinterval=10s + ; Add whitelisted IP networks and IPs. Connected peers whose IP matches a ; whitelist will not have their ban score increased. ; whitelist=127.0.0.1 @@ -167,6 +170,16 @@ ; Must not include characters '/', ':', '(' and ')'. ; uacomment= +; A comma separated list of user-agent substrings which will cause lbcd to reject +; any peers whose user-agent contains any of the blacklisted substrings. +; agentblacklist= + +; A comma separated list of user-agent substrings which will cause lbcd to require +; all peers' user-agents to contain one of the whitelisted substrings. The blacklist +; is applied before the whitelist, and an empty whitelist will allow all agents that +; do not fail the blacklist. +; agentwhitelist= + ; Disable committed peer filtering (CF). ; nocfilters=1 @@ -223,6 +236,9 @@ ; Specify the maximum number of concurrent RPC websocket clients. ; rpcmaxwebsockets=25 +; Max number of concurrent RPC requests that may be processed concurrently. +; rpcmaxconcurrentreqs=20 + ; Mirror some JSON-RPC quirks of Bitcoin Core -- NOTE: Discouraged unless ; interoperability issues need to be worked around ; rpcquirks=1 @@ -237,6 +253,12 @@ ; the default). ; notls=1 +; File containing the certificate file. +; rpccert=~/.lbcd/rpc.cert + +; File containing the certificate key. +; rpckey=~/.lbcd/rpc.key + ; ------------------------------------------------------------------------------ ; Mempool Settings - The following options @@ -264,6 +286,10 @@ ; Reject non-standard transactions regardless of default network settings. ; rejectnonstd=1 +; Reject transactions that attempt to replace existing transactions within +; the mempool through the Replace-By-Fee (RBF) signaling policy. +; rejectreplacement=0 + ; ------------------------------------------------------------------------------ ; Optional Indexes @@ -319,6 +345,12 @@ ; to the consensus limit if it is larger than that value. ; blockmaxsize=750000 +; Mininum block weight to be used when creating a block. +; blockminweight=0 + +; Maximum block weight to be used when creating a block. +; blockmaxweight=3000000 + ; Specify the size in bytes of the high-priority/low-fee area when creating a ; block. Transactions which consist of large amounts, old inputs, and small ; sizes have the highest priority. One consequence of this is that as low-fee @@ -331,6 +363,8 @@ ; ------------------------------------------------------------------------------ ; Debug ; ------------------------------------------------------------------------------ +; Directory to log output. +; logdir=~/.lbcd/logs ; Debug logging level. ; Valid levels are {trace, debug, info, warn, error, critical} @@ -339,6 +373,9 @@ ; available subsystems. ; debuglevel=info +; Write CPU profile to the specified file. +; cpuprofile= + ; The port used to listen for HTTP profile requests. The profile server will ; be disabled if this option is not specified. The profile information can be ; accessed at http://localhost:/debug/pprof once running. -- 2.45.2 From 6c2a3d8bcf045d9fe8b3be3e6022b4d46a3f11da Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Tue, 19 Apr 2022 15:31:00 -0400 Subject: [PATCH 377/459] [lbry] config: Embed sample-lbcd.conf contents at build time. Use embedded config if the sample-lbcd.conf is not found at runtime. --- config.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/config.go b/config.go index 85325afc..b87fafb9 100644 --- a/config.go +++ b/config.go @@ -7,6 +7,7 @@ package main import ( "bufio" "crypto/rand" + _ "embed" "encoding/base64" "encoding/hex" "errors" @@ -79,6 +80,9 @@ var ( defaultLogDir = filepath.Join(defaultHomeDir, defaultLogDirname) ) +//go:embed sample-lbcd.conf +var sampleConfig string + // runServiceCommand is only set to a real function on Windows. It is used // to parse and execute service commands specified via the -s flag. var runServiceCommand func(string) error @@ -1178,11 +1182,15 @@ func createDefaultConfigFile(destinationPath string) error { } generatedRPCPass := base64.StdEncoding.EncodeToString(randomBytes) + var reader *bufio.Reader src, err := os.Open(sampleConfigPath) if err != nil { - return err + // Fall back to sample config embedded at build time. + reader = bufio.NewReader(strings.NewReader(sampleConfig)) + } else { + reader = bufio.NewReader(src) + defer src.Close() } - defer src.Close() dest, err := os.OpenFile(destinationPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) @@ -1193,7 +1201,6 @@ func createDefaultConfigFile(destinationPath string) error { // We copy every line from the sample config file to the destination, // only replacing the two lines for rpcuser and rpcpass - reader := bufio.NewReader(src) for err != io.EOF { var line string line, err = reader.ReadString('\n') -- 2.45.2 From fe1637c2236e6d0157898ba8166377d99b3671a5 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:33:36 -0400 Subject: [PATCH 378/459] [lbry] config: Verify completeness of sample-lbcd.conf using reflection on config struct. --- config_test.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/config_test.go b/config_test.go index 84e7d444..15953b15 100644 --- a/config_test.go +++ b/config_test.go @@ -1,9 +1,11 @@ package main import ( + "fmt" "io/ioutil" "os" "path/filepath" + "reflect" "regexp" "runtime" "testing" @@ -14,6 +16,108 @@ var ( rpcpassRegexp = regexp.MustCompile("(?m)^rpcpass=.+$") ) +// Define a struct "configCmdLineOnly" containing a subset of configuration +// parameters which are command-line only. These fields are copied line-by-line +// from "config" struct in "config.go", and the field names, types, and tags must +// match for the test to work. +// +type configCmdLineOnly struct { + ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"` + DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` + DropCfIndex bool `long:"dropcfindex" description:"Deletes the index used for committed filtering (CF) support from the database on start up and then exits."` + DropTxIndex bool `long:"droptxindex" description:"Deletes the hash-based transaction index from the database on start up and then exits."` + DisableCheckpoints bool `long:"nocheckpoints" description:"Disable built-in checkpoints. Don't do this unless you know what you're doing."` + NoWinService bool `long:"nowinservice" description:"Do not start as a background service on Windows -- NOTE: This flag only works on the command line, not in the config file"` + DisableStallHandler bool `long:"nostalldetect" description:"Disables the stall handler system for each peer, useful in simnet/regtest integration tests frameworks"` + RegressionTest bool `long:"regtest" description:"Use the regression test network"` + SimNet bool `long:"simnet" description:"Use the simulation test network"` + SigNet bool `long:"signet" description:"Use the signet test network"` + SigNetChallenge string `long:"signetchallenge" description:"Connect to a custom signet network defined by this challenge instead of using the global default signet test network -- Can be specified multiple times"` + SigNetSeedNode []string `long:"signetseednode" description:"Specify a seed node for the signet network instead of using the global default signet network seed nodes"` + ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` +} + +func fieldEq(f1, f2 reflect.StructField) bool { + return (f1.Name == f2.Name) && (f1.Type == f2.Type) && (f1.Tag == f2.Tag) +} + +func TestSampleConfigFileComplete(t *testing.T) { + // find out where the sample config lives + _, path, _, ok := runtime.Caller(0) + if !ok { + t.Fatalf("Failed finding config file path") + } + sampleConfigFile := filepath.Join(filepath.Dir(path), sampleConfigFilename) + + // Read the sample config file + content, err := ioutil.ReadFile(sampleConfigFile) + if err != nil { + t.Fatalf("Failed reading sample config file: %v", err) + } + + allFields := reflect.VisibleFields(reflect.TypeOf(config{})) + cmdlineFields := reflect.VisibleFields(reflect.TypeOf(configCmdLineOnly{})) + + // Verify cmdlineFields is a subset of allFields. + for _, cf := range cmdlineFields { + // Check for presence of field "cf" in config struct. + var field *reflect.StructField + for _, f := range allFields { + f := f // new instance of loop var for return + if fieldEq(cf, f) { + field = &f + break + } + } + if field == nil { + t.Errorf("cmdline field: %s type: %s is not present in type %s", + cf.Name, cf.Type, reflect.TypeOf(config{})) + } + } + + // Verify sample config covers all parameters. + for _, f := range allFields { + longname, ok := f.Tag.Lookup("long") + if !ok { + // Field has no long-form name, so not eligible for + // inclusion in sample config. + continue + } + + // Check for presence of field "f" in our configCmdLineOnly struct. + var cmdline *reflect.StructField + for _, cf := range cmdlineFields { + cf := cf // new instance of loop var for return + if fieldEq(cf, f) { + cmdline = &cf + break + } + } + + // Look for assignment (="), or commented assignment ("; ="). + pattern := fmt.Sprintf("(?m)^(;\\s*)?%s=.*$", longname) + assignment, err := regexp.Compile(pattern) + if err != nil { + t.Errorf("config field: %s longname: %s failed compiling regexp (%s): %v", + f.Name, longname, pattern, err) + continue + } + + assigned := assignment.Match(content) + + // Field "f" must be present in either the sample config (=X), + // or it must be one of the command line only fields, but not both. + if !assigned && (cmdline == nil) { + t.Errorf("config field: %s longname: %s assignment (%s) should be present in %s", + f.Name, longname, assignment, sampleConfigFilename) + } + if assigned && (cmdline != nil) { + t.Errorf("config field: %s longname: %s should not be present in both %s and type %s", + f.Name, longname, sampleConfigFilename, reflect.TypeOf(configCmdLineOnly{}).Name()) + } + } +} + func TestCreateDefaultConfigFile(t *testing.T) { // find out where the sample config lives _, path, _, ok := runtime.Caller(0) -- 2.45.2 From d6a6b5355129650372e3d4ae33d901a31e3774ba Mon Sep 17 00:00:00 2001 From: Brannon King Date: Mon, 9 Aug 2021 16:19:47 -0400 Subject: [PATCH 379/459] [lbry] upnp: brought in upnp fix from dcrd --- upnp.go | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/upnp.go b/upnp.go index c74e4ed7..402924f5 100644 --- a/upnp.go +++ b/upnp.go @@ -39,7 +39,7 @@ import ( "fmt" "net" "net/http" - "os" + "net/url" "strconv" "strings" "time" @@ -126,8 +126,9 @@ func Discover() (nat NAT, err error) { if err != nil { return } + var serviceIP string = getServiceIP(serviceURL) var ourIP string - ourIP, err = getOurIP() + ourIP, err = getOurIP(serviceIP) if err != nil { return } @@ -212,13 +213,22 @@ func getChildService(d *device, serviceType string) *service { return nil } -// getOurIP returns a best guess at what the local IP is. -func getOurIP() (ip string, err error) { - hostname, err := os.Hostname() - if err != nil { - return +func getServiceIP(serviceURL string) (routerIP string) { + url, _ := url.Parse(serviceURL) + return url.Hostname() +} + +// getOurIP returns the local IP that is on the same subnet as the serviceIP. +func getOurIP(serviceIP string) (ip string, err error) { + _, serviceNet, _ := net.ParseCIDR(serviceIP + "/24") + addrs, err := net.InterfaceAddrs() + for _, addr := range addrs { + ip, _, _ := net.ParseCIDR(addr.String()) + if serviceNet.Contains(ip) { + return ip.String(), nil + } } - return net.LookupCNAME(hostname) + return } // getServiceURL parses the xml description at the given root url to find the -- 2.45.2 From a07bb527dff1529deea786139e0a191283d7f7e6 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 19 Aug 2021 14:41:48 -0400 Subject: [PATCH 380/459] [lbry] test: fixed all current tests and delete three. Co-authored-by: Roy Lee --- blockchain/bench_test.go | 8 +- blockchain/chain_test.go | 96 ------- blockchain/common_test.go | 17 +- blockchain/difficulty.go | 7 +- blockchain/example_test.go | 2 +- blockchain/fullblocks_test.go | 2 +- blockchain/fullblocktests/generate.go | 12 +- blockchain/fullblocktests/params.go | 10 +- blockchain/merkle_test.go | 6 +- blockchain/notifications_test.go | 51 ---- blockchain/testdata/blk_0_to_4.dat.bz2 | Bin 1684 -> 0 bytes blockchain/testdata/blk_3A.dat.bz2 | Bin 801 -> 0 bytes blockchain/testdata/blk_4A.dat.bz2 | Bin 271 -> 0 bytes blockchain/testdata/blk_5A.dat.bz2 | Bin 480 -> 0 bytes blockchain/testdata/reorgtest.hex | 180 ------------- blockchain/validate_test.go | 343 +----------------------- btcjson/chainsvrcmds_test.go | 4 +- chaincfg/genesis.go | 46 +--- chaincfg/genesis_test.go | 244 ----------------- database/ffldb/interface_test.go | 23 +- database/ffldb/whitebox_test.go | 23 +- database/testdata/blocks1-256.bz2 | Bin 37555 -> 42273 bytes integration/bip0009_test.go | 5 +- integration/csv_fork_test.go | 11 +- integration/rpcserver_test.go | 1 + integration/rpctest/blockgen.go | 3 +- integration/rpctest/rpc_harness.go | 7 +- integration/rpctest/rpc_harness_test.go | 29 +- mempool/mempool_test.go | 2 +- mempool/policy.go | 5 + mempool/policy_test.go | 6 +- peer/peer_test.go | 4 +- txscript/data/script_tests.json | 37 +-- txscript/data/tx_invalid.json | 4 - txscript/example_test.go | 8 +- txscript/opcode_test.go | 12 + txscript/scriptbuilder_test.go | 11 +- wire/bench_test.go | 4 +- wire/blockheader.go | 2 +- wire/blockheader_test.go | 14 +- wire/common_test.go | 2 +- wire/message_test.go | 6 +- wire/msgblock_test.go | 42 ++- wire/msgheaders_test.go | 22 +- wire/msgmerkleblock_test.go | 36 ++- 45 files changed, 237 insertions(+), 1110 deletions(-) delete mode 100644 blockchain/notifications_test.go delete mode 100644 blockchain/testdata/blk_0_to_4.dat.bz2 delete mode 100644 blockchain/testdata/blk_3A.dat.bz2 delete mode 100644 blockchain/testdata/blk_4A.dat.bz2 delete mode 100644 blockchain/testdata/blk_5A.dat.bz2 delete mode 100644 blockchain/testdata/reorgtest.hex diff --git a/blockchain/bench_test.go b/blockchain/bench_test.go index 43d3152b..3246e653 100644 --- a/blockchain/bench_test.go +++ b/blockchain/bench_test.go @@ -6,14 +6,12 @@ package blockchain import ( "testing" - - "github.com/btcsuite/btcutil" ) // BenchmarkIsCoinBase performs a simple benchmark against the IsCoinBase // function. func BenchmarkIsCoinBase(b *testing.B) { - tx, _ := btcutil.NewBlock(&Block100000).Tx(1) + tx, _ := GetBlock100000().Tx(1) b.ResetTimer() for i := 0; i < b.N; i++ { IsCoinBase(tx) @@ -23,9 +21,9 @@ func BenchmarkIsCoinBase(b *testing.B) { // BenchmarkIsCoinBaseTx performs a simple benchmark against the IsCoinBaseTx // function. func BenchmarkIsCoinBaseTx(b *testing.B) { - tx := Block100000.Transactions[1] + tx, _ := GetBlock100000().Tx(1) b.ResetTimer() for i := 0; i < b.N; i++ { - IsCoinBaseTx(tx) + IsCoinBaseTx(tx.MsgTx()) } } diff --git a/blockchain/chain_test.go b/blockchain/chain_test.go index b2a155bc..2e77e578 100644 --- a/blockchain/chain_test.go +++ b/blockchain/chain_test.go @@ -15,102 +15,6 @@ import ( btcutil "github.com/lbryio/lbcutil" ) -// TestHaveBlock tests the HaveBlock API to ensure proper functionality. -func TestHaveBlock(t *testing.T) { - // Load up blocks such that there is a side chain. - // (genesis block) -> 1 -> 2 -> 3 -> 4 - // \-> 3a - testFiles := []string{ - "blk_0_to_4.dat.bz2", - "blk_3A.dat.bz2", - } - - var blocks []*btcutil.Block - for _, file := range testFiles { - blockTmp, err := loadBlocks(file) - if err != nil { - t.Errorf("Error loading file: %v\n", err) - return - } - blocks = append(blocks, blockTmp...) - } - - // Create a new database and chain instance to run tests against. - chain, teardownFunc, err := chainSetup("haveblock", - &chaincfg.MainNetParams) - if err != nil { - t.Errorf("Failed to setup chain instance: %v", err) - return - } - defer teardownFunc() - - // Since we're not dealing with the real block chain, set the coinbase - // maturity to 1. - chain.TstSetCoinbaseMaturity(1) - - for i := 1; i < len(blocks); i++ { - _, isOrphan, err := chain.ProcessBlock(blocks[i], BFNone) - if err != nil { - t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) - return - } - if isOrphan { - t.Errorf("ProcessBlock incorrectly returned block %v "+ - "is an orphan\n", i) - return - } - } - - // Insert an orphan block. - _, isOrphan, err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), - BFNone) - if err != nil { - t.Errorf("Unable to process block: %v", err) - return - } - if !isOrphan { - t.Errorf("ProcessBlock indicated block is an not orphan when " + - "it should be\n") - return - } - - tests := []struct { - hash string - want bool - }{ - // Genesis block should be present (in the main chain). - {hash: chaincfg.MainNetParams.GenesisHash.String(), want: true}, - - // Block 3a should be present (on a side chain). - {hash: "00000000474284d20067a4d33f6a02284e6ef70764a3a26d6a5b9df52ef663dd", want: true}, - - // Block 100000 should be present (as an orphan). - {hash: "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506", want: true}, - - // Random hashes should not be available. - {hash: "123", want: false}, - } - - for i, test := range tests { - hash, err := chainhash.NewHashFromStr(test.hash) - if err != nil { - t.Errorf("NewHashFromStr: %v", err) - continue - } - - result, err := chain.HaveBlock(hash) - if err != nil { - t.Errorf("HaveBlock #%d unexpected error: %v", i, err) - return - } - if result != test.want { - t.Errorf("HaveBlock #%d got %v want %v", i, result, - test.want) - continue - } - } -} - // TestCalcSequenceLock tests the LockTimeToSequence function, and the // CalcSequenceLock method of a Chain instance. The tests exercise several // combinations of inputs to the CalcSequenceLock function in order to ensure diff --git a/blockchain/common_test.go b/blockchain/common_test.go index 16ad6756..ae25889d 100644 --- a/blockchain/common_test.go +++ b/blockchain/common_test.go @@ -5,6 +5,7 @@ package blockchain import ( + "bytes" "compress/bzip2" "encoding/binary" "fmt" @@ -63,13 +64,13 @@ func isSupportedDbType(dbType string) bool { func loadBlocks(filename string) (blocks []*btcutil.Block, err error) { filename = filepath.Join("testdata/", filename) - var network = wire.MainNet + var network = 0xd9b4bef9 // bitcoin's network ID var dr io.Reader var fi io.ReadCloser fi, err = os.Open(filename) if err != nil { - return + return blocks, err } if strings.HasSuffix(filename, ".bz2") { @@ -95,7 +96,7 @@ func loadBlocks(filename string) (blocks []*btcutil.Block, err error) { break } if rintbuf != uint32(network) { - break + continue } err = binary.Read(dr, binary.LittleEndian, &rintbuf) blocklen := rintbuf @@ -105,14 +106,20 @@ func loadBlocks(filename string) (blocks []*btcutil.Block, err error) { // read block dr.Read(rbytes) + // inject claimtrie: + tail := make([]byte, len(rbytes)-68) + copy(tail, rbytes[68:]) + rbytes = append(rbytes[:68], bytes.Repeat([]byte{23}, chainhash.HashSize)...) + rbytes = append(rbytes, tail...) + block, err = btcutil.NewBlockFromBytes(rbytes) if err != nil { - return + return blocks, err } blocks = append(blocks, block) } - return + return blocks, err } // chainSetup is used to create a new db and chain instance with the genesis diff --git a/blockchain/difficulty.go b/blockchain/difficulty.go index 2f16e2e5..051998ba 100644 --- a/blockchain/difficulty.go +++ b/blockchain/difficulty.go @@ -245,10 +245,11 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim // Get the block node at the previous retarget (targetTimespan days // worth of blocks). - firstNode := lastNode.RelativeAncestor(b.blocksPerRetarget) - if lastNode.height == 0 { - firstNode = lastNode + blocksBack := b.blocksPerRetarget + if blocksBack > lastNode.height { + blocksBack = lastNode.height } + firstNode := lastNode.RelativeAncestor(blocksBack) if firstNode == nil { return 0, AssertError("unable to obtain previous retarget block") } diff --git a/blockchain/example_test.go b/blockchain/example_test.go index da0cce79..432602df 100644 --- a/blockchain/example_test.go +++ b/blockchain/example_test.go @@ -69,7 +69,7 @@ func ExampleBlockChain_ProcessBlock() { fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan) // Output: - // Failed to process block: already have block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f + // Failed to process block: already have block 9c89283ba0f3227f6c03b70216b9f665f0118d5e0fa729cedf4fb34d6a34f463 } // This example demonstrates how to convert the compact "bits" in a block header diff --git a/blockchain/fullblocks_test.go b/blockchain/fullblocks_test.go index 4c45c099..d7a7d7c2 100644 --- a/blockchain/fullblocks_test.go +++ b/blockchain/fullblocks_test.go @@ -139,7 +139,7 @@ func TestFullBlocks(t *testing.T) { // Create a new database and chain instance to run tests against. chain, teardownFunc, err := chainSetup("fullblocktest", - &chaincfg.RegressionNetParams) + fullblocktests.FbRegressionNetParams) if err != nil { t.Errorf("Failed to setup chain instance: %v", err) return diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index dc182a90..56f4601a 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -31,7 +31,7 @@ const ( // Intentionally defined here rather than using constants from codebase // to ensure consensus changes are detected. maxBlockSigOps = 20000 - maxBlockSize = 2000000 + maxBlockSize = 8000000 minCoinbaseScriptLen = 2 maxCoinbaseScriptLen = 100 medianTimeBlocks = 11 @@ -342,10 +342,8 @@ func solveBlock(header *wire.BlockHeader) bool { return default: hdr.Nonce = i - hash := hdr.BlockHash() - if blockchain.HashToBig(&hash).Cmp( - targetDifficulty) <= 0 { - + hash := hdr.BlockPoWHash() + if blockchain.HashToBig(&hash).Cmp(targetDifficulty) <= 0 { results <- sbResult{true, i} return } @@ -811,7 +809,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { // Create a test generator instance initialized with the genesis block // as the tip. - g, err := makeTestGenerator(regressionNetParams) + g, err := makeTestGenerator(FbRegressionNetParams) if err != nil { return nil, err } @@ -1444,7 +1442,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { // Keep incrementing the nonce until the hash treated as // a uint256 is higher than the limit. b46.Header.Nonce++ - blockHash := b46.BlockHash() + blockHash := b46.Header.BlockPoWHash() hashNum := blockchain.HashToBig(&blockHash) if hashNum.Cmp(g.params.PowLimit) >= 0 { break diff --git a/blockchain/fullblocktests/params.go b/blockchain/fullblocktests/params.go index fa23e841..d0463806 100644 --- a/blockchain/fullblocktests/params.go +++ b/blockchain/fullblocktests/params.go @@ -54,6 +54,7 @@ var ( Version: 1, PrevBlock: *newHashFromStr("0000000000000000000000000000000000000000000000000000000000000000"), MerkleRoot: *newHashFromStr("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"), + ClaimTrie: chainhash.Hash{1}, // EmptyTrieHash Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000] Nonce: 2, @@ -83,23 +84,25 @@ var ( LockTime: 0, }}, } + + regTestGenesisBlockHash = regTestGenesisBlock.BlockHash() ) -// regressionNetParams defines the network parameters for the regression test +// FbRegressionNetParams defines the network parameters for the regression test // network. // // NOTE: The test generator intentionally does not use the existing definitions // in the chaincfg package since the intent is to be able to generate known // good tests which exercise that code. Using the chaincfg parameters would // allow them to change out from under the tests potentially invalidating them. -var regressionNetParams = &chaincfg.Params{ +var FbRegressionNetParams = &chaincfg.Params{ Name: "regtest", Net: wire.TestNet, DefaultPort: "18444", // Chain parameters GenesisBlock: ®TestGenesisBlock, - GenesisHash: newHashFromStr("5bec7567af40504e0994db3b573c186fffcc4edefe096ff2e58d00523bd7e8a6"), + GenesisHash: ®TestGenesisBlockHash, PowLimit: regressionPowLimit, PowLimitBits: 0x207fffff, CoinbaseMaturity: 100, @@ -113,6 +116,7 @@ var regressionNetParams = &chaincfg.Params{ ReduceMinDifficulty: true, MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2 GenerateSupported: true, + MinerConfirmationWindow: 1, // Checkpoints ordered from oldest to newest. Checkpoints: nil, diff --git a/blockchain/merkle_test.go b/blockchain/merkle_test.go index 275ffef3..c43ed281 100644 --- a/blockchain/merkle_test.go +++ b/blockchain/merkle_test.go @@ -6,16 +6,14 @@ package blockchain import ( "testing" - - "github.com/btcsuite/btcutil" ) // TestMerkle tests the BuildMerkleTreeStore API. func TestMerkle(t *testing.T) { - block := btcutil.NewBlock(&Block100000) + block := GetBlock100000() merkles := BuildMerkleTreeStore(block.Transactions(), false) calculatedMerkleRoot := merkles[len(merkles)-1] - wantMerkle := &Block100000.Header.MerkleRoot + wantMerkle := block.MsgBlock().Header.MerkleRoot if !wantMerkle.IsEqual(calculatedMerkleRoot) { t.Errorf("BuildMerkleTreeStore: merkle root mismatch - "+ "got %v, want %v", calculatedMerkleRoot, wantMerkle) diff --git a/blockchain/notifications_test.go b/blockchain/notifications_test.go deleted file mode 100644 index fde58735..00000000 --- a/blockchain/notifications_test.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2017 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package blockchain - -import ( - "testing" - - "github.com/btcsuite/btcd/chaincfg" -) - -// TestNotifications ensures that notification callbacks are fired on events. -func TestNotifications(t *testing.T) { - blocks, err := loadBlocks("blk_0_to_4.dat.bz2") - if err != nil { - t.Fatalf("Error loading file: %v\n", err) - } - - // Create a new database and chain instance to run tests against. - chain, teardownFunc, err := chainSetup("notifications", - &chaincfg.MainNetParams) - if err != nil { - t.Fatalf("Failed to setup chain instance: %v", err) - } - defer teardownFunc() - - notificationCount := 0 - callback := func(notification *Notification) { - if notification.Type == NTBlockAccepted { - notificationCount++ - } - } - - // Register callback multiple times then assert it is called that many - // times. - const numSubscribers = 3 - for i := 0; i < numSubscribers; i++ { - chain.Subscribe(callback) - } - - _, _, err = chain.ProcessBlock(blocks[1], BFNone) - if err != nil { - t.Fatalf("ProcessBlock fail on block 1: %v\n", err) - } - - if notificationCount != numSubscribers { - t.Fatalf("Expected notification callback to be executed %d "+ - "times, found %d", numSubscribers, notificationCount) - } -} diff --git a/blockchain/testdata/blk_0_to_4.dat.bz2 b/blockchain/testdata/blk_0_to_4.dat.bz2 deleted file mode 100644 index 274c710d275f032791bcbd4b463be9c1901b85ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1684 zcmV;F25b33T4*^jL0KkKS>X=}n*alCfB*mg|NsB~|NsC0|NsC0|Ns2||NsC0|NsC0 z|NsC0|M$=Y9t(Fm>CWv=ZMtEpNSUHxp$!c(Z3M^-0D77zBWYbXck0U6}AU2aVH2qV`dLgwvPe^%9G-UM$sLAC$Pg80Q9*m>ZdY(kc z(@#dHpifBk4^vN5z?wA;JtwA7hND2p(1o z=yg{qttlfz;)yXscsGR(5C)TK6Hpv_Pk>L|Z$1FW7sl#J#f5^EFk?RGk}2}OQHWmt zCkrKivn*Y95NXEdtS9#2ha(9rE7%A7=&0QG&d&pIMBeyzspkuNJ(?qSQ*WlrMpak8 z*#&ikj*8fm%)b*GMLucZmne_XVc-mAw}&pfrK$R9bk-2m>Pl|WZ6ypg0U`aLL?yLB zaglMf!D^hc6$a?m!JU$?PbMk6A+rg{oNcusEjSN_3N#`iplPsy*!(=L!Ig^nmLMgg zr!s^Vyw#5Tx<+i~CyKFzqBszwrEO;|Ty+a(TrGL#4C`@%f0QMQqcPHXNFpQ3;`w2A zw3ryzNfMdP7{fMQHwb{!)D_XvWvP`m(xa?NW0zD~ym1E)UUA%x*lSR76U4I?b7@RE z+hXztqDF1tCtThrVK$+c+%}C0sSaZI7XFbr_u8<8J-VqX9hn>H58bpWzK_K7IM4b7 z2|niAf9pH6Mb?Z=(h;bWKLE5W6R=Dq^33r~jta*kM+b~nJ~RY=*B8}?+XsY^p+wU$D*u+(fl02==XNV5 zazgd?ICllOR_iyij-Vav$@XDvA;60lopJ5pB~QnGFM_tk4EV7(wud8sxU&{_{T2kJ zs>Mq{NE8LxZ8JyGPh9fm{pN-~B+W$F@|W17K413j9EX`=oFW^>@3Dksc>`tQ@S_kCRq9#_IJ-KV=AoS`veBIfAfB;Zn=C8aiK zKF(x>$`mYn_m6Z*d_m+vjD#?mJzkjrp#KV;U2*>WFu2Z+5~v_6A-<1*TvK&L2f2bq>1VIw2fElyv7wSUV2wi| eLqeg%m7b@}t+ANUN4}&X{}*yaI8cz`4+)z-{1!U^ diff --git a/blockchain/testdata/blk_3A.dat.bz2 b/blockchain/testdata/blk_3A.dat.bz2 deleted file mode 100644 index 01266565d573ca0f7e7601d011fb4f98e243445a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 801 zcmV++1K#{XT4*^jL0KkKSvvUkH~;}T|NsBz_5c0;|L_05_I~^R?|c2;-~aRc|NsC0 z|NsB{fBe7!yv*vg#8pi;rf2{F00hXxK`;O&1i>&(F`xh=00009hJX>80$>0DWGA3Z zdWM0tjUJ#8R2l#P000dD000008UO$Q00E!?XaEL)Gyu>5GyniJGyoa}R5qXnhJer- z00001paVbvG&Ilv0000000E!|hJXM70004@rkVs()dWqFU;rje005W(695T-009p| z3Jk%wT+;0O$0FY!ne@1J8)9k90GOeZGInoM1&UY41q8TUM5S9l{fm}~XuF$g0*D{bOg6L;u&U>AFG>g9|;M&U> z1w|OguMnW1sS^dz91cXDHw_xR;eW~XC=|3qoP{edVW5%|YD6QM5zK{VS=8ad7%;1d zU~4^Rhb-VQrZcE9Ps0!X7C(3F9(fyu+l&#w%G;BTbA{&QHx6`P!%=P%#gtH^OVA-I zU0=IB4bB*n=X-fliQ7?Y1%y@<0Nvt5A3~51XAKg~+yUbLM1Vp-)MEMbrqxHDyC1NH z7!W1`ED$8}380;NL$K-BvBN}`5tR59j9nL^$p5T@?qBpcyuwz>6O2K)mibZ!0&YD7 z_s4+p_+ab}Gy#5e(@dU@Z%D-ChuU~&14RA!fF!Dd`cgP=NT~SjahqqpIK}{;HC~TT z2(ILkeuBLc?gM2zZY*x^7$rC=;p80^7A^UV-7;G;LGs%_hy~6qb f_`c&%W+X@o@c@qy4iiSpcZ<0qoG3^ge0v-K)fQGt diff --git a/blockchain/testdata/blk_4A.dat.bz2 b/blockchain/testdata/blk_4A.dat.bz2 deleted file mode 100644 index 19b409e752f37840b271e4e9f0b90dcd06e1cad3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271 zcmV+q0r37pT4*^jL0KkKS)#5T-T(kw|Nr)=P(OnG%3!|lLXNzfU?7AN6cRr~MVBQ2 zA0t9myXT+)lo>RJ)HG?4qfADgrVz=aL&yZgWZ0T&8X6v^L)7&eZ8XCv>8MpdQ2+rL z00A_>00000BLX&n000cEjyQmUh5!K)7oh+EqJZEaPB5`2`g%`}NewXJA%&J^c!3*M z$>&bK9{A*x-#>_1L8fteTKC-0?Cz6_@US3)f1n@oih|ATh}}(4Jy`UR58d*`H|r@9 zn^e@jIT!g%N-p)E1~|{dn8BDHZ~gm547v*zyOjpf)Jn$MfHXv+%N;`K))-t6TsWFQ05 zP|5&g8fefoGyr4_o>LZzc~ zp`#N(0j7qTG-v>6p`g*AX^7K602wj>FouSJ0i#BNrj1;cQ3j$xfC2yjL;;2u@c;+{ zmmo%n6kwkqz!};kMF*mNWE62tG=RVH)POU#z~VBHgOiEVpItH$l30xDGRXF!C4(!F zm2p{67q;92;Dsoa7tNZKHpsy7arVhE-@{}&c0R9zbN=av#Q`5aLQlstV5M*uJm_9Y z86x2&VkO?P4`X!KirXud5$d4O57oTkVI{TPp^6!Lon|}lzctd=a|8u7D^ip4@NQJ~ z_nL9s#MxZGz5`XDg8QmCNR3Wap_q`;|3sOV5M=z}Mz6txyzLMvx&+SI{NZ!vu^oW_ zKcRFYm;`k@0xyy)8C6JtU?Ql;?N1QXCWw(aH32%xW1Ud@xYp{1wLJJx?+;2#Ip0x+ W5)=|hP-7M^@pmLsg$WN38`vQD7Tcl# diff --git a/blockchain/testdata/reorgtest.hex b/blockchain/testdata/reorgtest.hex deleted file mode 100644 index 5b9e75e7..00000000 --- a/blockchain/testdata/reorgtest.hex +++ /dev/null @@ -1,180 +0,0 @@ -File path: reorgTest/blk_0_to_4.dat - -Block 0: - f9beb4d9 - 1d010000 - - 01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 3ba3edfd 7a7b12b2 7ac72c3e 67768f61 7fc81bc3 888a5132 3a9fb8aa - 4b1e5e4a 29ab5f49 ffff001d 1dac2b7c - 01 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff4d04ff ff001d01 04455468 65205469 6d657320 30332f4a - 616e2f32 30303920 4368616e 63656c6c 6f72206f 6e206272 696e6b20 6f662073 - 65636f6e 64206261 696c6f75 7420666f 72206261 6e6b73ff ffffff01 00f2052a - 01000000 43410467 8afdb0fe 55482719 67f1a671 30b7105c d6a828e0 3909a679 - 62e0ea1f 61deb649 f6bc3f4c ef38c4f3 5504e51e c112de5c 384df7ba 0b8d578a - 4c702b6b f11d5fac 00000000 -Block 1: - f9beb4d9 - d4000000 - - 01000000 6fe28c0a b6f1b372 c1a6a246 ae63f74f 931e8365 e15a089c 68d61900 - 00000000 3bbd67ad e98fbbb7 0718cd80 f9e9acf9 3b5fae91 7bb2b41d 4c3bb82c - 77725ca5 81ad5f49 ffff001d 44e69904 - 01 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff04722f 2e2bffff ffff0100 f2052a01 00000043 41046868 - 0737c76d abb801cb 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 - b5ac9e8b 4c9f49be 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ac00 - 000000 -Block 2: - f9beb4d9 - 95010000 - - 01000000 13ca7940 4c11c63e ca906bbd f190b751 2872b857 1b5143ae e8cb5737 - 00000000 fc07c983 d7391736 0aeda657 29d0d4d3 2533eb84 76ee9d64 aa27538f - 9b4fc00a d9af5f49 ffff001d 630bea22 - 02 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff04eb96 14e5ffff ffff0100 f2052a01 00000043 41046868 - 0737c76d abb801cb 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 - b5ac9e8b 4c9f49be 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ac00 - 000000 - - 01000000 0163451d 1002611c 1388d5ba 4ddfdf99 196a86b5 990fb5b0 dc786207 - 4fdcb8ee d2000000 004a4930 46022100 3dde52c6 5e339f45 7fe1015e 70eed208 - 872eb71e dd484c07 206b190e cb2ec3f8 02210011 c78dcfd0 3d43fa63 61242a33 - 6291ba2a 8c1ef5bc d5472126 2468f2bf 8dee4d01 ffffffff 0200ca9a 3b000000 - 001976a9 14cb2abd e8bccacc 32e893df 3a054b9e f7f227a4 ce88ac00 286bee00 - 00000019 76a914ee 26c56fc1 d942be8d 7a24b2a1 001dd894 69398088 ac000000 - 00 -Block 3: - f9beb4d9 - 96020000 - - 01000000 7d338254 0506faab 0d4cf179 45dda023 49db51f9 6233f24c 28002258 - 00000000 4806fe80 bf85931b 882ea645 77ca5a03 22bb8af2 3f277b20 55f160cd - 972c8e8b 31b25f49 ffff001d e8f0c653 - 03 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff044abd 8159ffff ffff0100 f2052a01 00000043 4104b95c - 249d84f4 17e3e395 a1274254 28b54067 1cc15881 eb828c17 b722a53f c599e21c - a5e56c90 f340988d 3933acc7 6beb832f d64cab07 8ddf3ce7 32923031 d1a8ac00 - 000000 - - 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb - bad253d3 77010000 008c4930 46022100 96ee0d02 b35fd61e 4960b44f f396f67e - 01fe17f9 de4e0c17 b6a963bd ab2b50a6 02210034 920d4daa 7e9f8abe 5675c931 - 495809f9 0b9c1189 d05fbaf1 dd6696a5 b0d8f301 41046868 0737c76d abb801cb - 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 b5ac9e8b 4c9f49be - 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ffff ffff0100 286bee00 - 00000019 76a914c5 22664fb0 e55cdc5c 0cea73b4 aad97ec8 34323288 ac000000 - 00 - - 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb - bad253d3 77000000 008c4930 46022100 b08b922a c4bde411 1c229f92 9fe6eb6a - 50161f98 1f4cf47e a9214d35 bf74d380 022100d2 f6640327 e677a1e1 cc474991 - b9a48ba5 bd1e0c94 d1c8df49 f7b0193b 7ea4fa01 4104b95c 249d84f4 17e3e395 - a1274254 28b54067 1cc15881 eb828c17 b722a53f c599e21c a5e56c90 f340988d - 3933acc7 6beb832f d64cab07 8ddf3ce7 32923031 d1a8ffff ffff0100 ca9a3b00 - 00000019 76a914c5 22664fb0 e55cdc5c 0cea73b4 aad97ec8 34323288 ac000000 - 00 - -Block 4: - f9beb4d9 - 73010000 - - 01000000 5da36499 06f35e09 9be42a1d 87b6dd42 11bc1400 6c220694 0807eaae - 00000000 48eeeaed 2d9d8522 e6201173 743823fd 4b87cd8a ca8e6408 ec75ca38 - 302c2ff0 89b45f49 ffff001d 00530839 - 02 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff04d41d 2213ffff ffff0100 f2052a01 00000043 4104678a - fdb0fe55 48271967 f1a67130 b7105cd6 a828e039 09a67962 e0ea1f61 deb649f6 - bc3f4cef 38c4f355 04e51ec1 12de5c38 4df7ba0b 8d578a4c 702b6bf1 1d5fac00 - 000000 - - 01000000 0163451d 1002611c 1388d5ba 4ddfdf99 196a86b5 990fb5b0 dc786207 - 4fdcb8ee d2000000 004a4930 46022100 8c8fd57b 48762135 8d8f3e69 19f33e08 - 804736ff 83db47aa 248512e2 6df9b8ba 022100b0 c59e5ee7 bfcbfcd1 a4d83da9 - 55fb260e fda7f42a 25522625 a3d6f2d9 1174a701 ffffffff 0100f205 2a010000 - 001976a9 14c52266 4fb0e55c dc5c0cea 73b4aad9 7ec83432 3288ac00 000000 - -File path: reorgTest/blk_3A.dat -Block 3A: - f9beb4d9 - 96020000 - - 01000000 7d338254 0506faab 0d4cf179 45dda023 49db51f9 6233f24c 28002258 - 00000000 5a15f573 1177a353 bdca7aab 20e16624 dfe90adc 70accadc 68016732 - 302c20a7 31b25f49 ffff001d 6a901440 - 03 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff04ad1b e7d5ffff ffff0100 f2052a01 00000043 4104ed83 - 704c95d8 29046f1a c2780621 1132102c 34e9ac7f fa1b7111 0658e5b9 d1bdedc4 - 16f5cefc 1db0625c d0c75de8 192d2b59 2d7e3b00 bcfb4a0e 860d880f d1fcac00 - 000000 - - 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb - bad253d3 77010000 008c4930 46022100 96ee0d02 b35fd61e 4960b44f f396f67e - 01fe17f9 de4e0c17 b6a963bd ab2b50a6 02210034 920d4daa 7e9f8abe 5675c931 - 495809f9 0b9c1189 d05fbaf1 dd6696a5 b0d8f301 41046868 0737c76d abb801cb - 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 b5ac9e8b 4c9f49be - 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ffff ffff0100 286bee00 - 00000019 76a914c5 22664fb0 e55cdc5c 0cea73b4 aad97ec8 34323288 ac000000 - 00 - - 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb - bad253d3 77000000 008c4930 46022100 9cc67ddd aa6f592a 6b2babd4 d6ff954f - 25a784cf 4fe4bb13 afb9f49b 08955119 022100a2 d99545b7 94080757 fcf2b563 - f2e91287 86332f46 0ec6b90f f085fb28 41a69701 4104b95c 249d84f4 17e3e395 - a1274254 28b54067 1cc15881 eb828c17 b722a53f c599e21c a5e56c90 f340988d - 3933acc7 6beb832f d64cab07 8ddf3ce7 32923031 d1a8ffff ffff0100 ca9a3b00 - 00000019 76a914ee 26c56fc1 d942be8d 7a24b2a1 001dd894 69398088 ac000000 - 00 - -File path: reorgTest/blk_4A.dat -Block 4A: - f9beb4d9 - d4000000 - - 01000000 aae77468 2205667d 4f413a58 47cc8fe8 9795f1d5 645d5b24 1daf3c92 - 00000000 361c9cde a09637a0 d0c05c3b 4e7a5d91 9edb184a 0a4c7633 d92e2ddd - f04cb854 89b45f49 ffff001d 9e9aa1e8 - 01 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff0401b8 f3eaffff ffff0100 f2052a01 00000043 4104678a - fdb0fe55 48271967 f1a67130 b7105cd6 a828e039 09a67962 e0ea1f61 deb649f6 - bc3f4cef 38c4f355 04e51ec1 12de5c38 4df7ba0b 8d578a4c 702b6bf1 1d5fac00 - 000000 - -File path: reorgTest/blk_5A.dat -Block 5A: - f9beb4d9 - 73010000 - - 01000000 ebc7d0de 9c31a71b 7f41d275 2c080ba4 11e1854b d45cb2cf 8c1e4624 - 00000000 a607774b 79b8eb50 b52a5a32 c1754281 ec67f626 9561df28 57d1fe6a - ea82c696 e1b65f49 ffff001d 4a263577 - 02 - - 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 - 00000000 00ffffff ff049971 0c7dffff ffff0100 f2052a01 00000043 4104678a - fdb0fe55 48271967 f1a67130 b7105cd6 a828e039 09a67962 e0ea1f61 deb649f6 - bc3f4cef 38c4f355 04e51ec1 12de5c38 4df7ba0b 8d578a4c 702b6bf1 1d5fac00 - 000000 - - 01000000 0163451d 1002611c 1388d5ba 4ddfdf99 196a86b5 990fb5b0 dc786207 - 4fdcb8ee d2000000 004a4930 46022100 8c8fd57b 48762135 8d8f3e69 19f33e08 - 804736ff 83db47aa 248512e2 6df9b8ba 022100b0 c59e5ee7 bfcbfcd1 a4d83da9 - 55fb260e fda7f42a 25522625 a3d6f2d9 1174a701 ffffffff 0100f205 2a010000 - 001976a9 14c52266 4fb0e55c dc5c0cea 73b4aad9 7ec83432 3288ac00 000000 - diff --git a/blockchain/validate_test.go b/blockchain/validate_test.go index 6298ad06..db6ea663 100644 --- a/blockchain/validate_test.go +++ b/blockchain/validate_test.go @@ -64,96 +64,11 @@ func TestSequenceLocksActive(t *testing.T) { } } -// TestCheckConnectBlockTemplate tests the CheckConnectBlockTemplate function to -// ensure it fails. -func TestCheckConnectBlockTemplate(t *testing.T) { - // Create a new database and chain instance to run tests against. - chain, teardownFunc, err := chainSetup("checkconnectblocktemplate", - &chaincfg.MainNetParams) - if err != nil { - t.Errorf("Failed to setup chain instance: %v", err) - return - } - defer teardownFunc() - - // Since we're not dealing with the real block chain, set the coinbase - // maturity to 1. - chain.TstSetCoinbaseMaturity(1) - - // Load up blocks such that there is a side chain. - // (genesis block) -> 1 -> 2 -> 3 -> 4 - // \-> 3a - testFiles := []string{ - "blk_0_to_4.dat.bz2", - "blk_3A.dat.bz2", - } - - var blocks []*btcutil.Block - for _, file := range testFiles { - blockTmp, err := loadBlocks(file) - if err != nil { - t.Fatalf("Error loading file: %v\n", err) - } - blocks = append(blocks, blockTmp...) - } - - for i := 1; i <= 3; i++ { - isMainChain, _, err := chain.ProcessBlock(blocks[i], BFNone) - if err != nil { - t.Fatalf("CheckConnectBlockTemplate: Received unexpected error "+ - "processing block %d: %v", i, err) - } - if !isMainChain { - t.Fatalf("CheckConnectBlockTemplate: Expected block %d to connect "+ - "to main chain", i) - } - } - - // Block 3 should fail to connect since it's already inserted. - err = chain.CheckConnectBlockTemplate(blocks[3]) - if err == nil { - t.Fatal("CheckConnectBlockTemplate: Did not received expected error " + - "on block 3") - } - - // Block 4 should connect successfully to tip of chain. - err = chain.CheckConnectBlockTemplate(blocks[4]) - if err != nil { - t.Fatalf("CheckConnectBlockTemplate: Received unexpected error on "+ - "block 4: %v", err) - } - - // Block 3a should fail to connect since does not build on chain tip. - err = chain.CheckConnectBlockTemplate(blocks[5]) - if err == nil { - t.Fatal("CheckConnectBlockTemplate: Did not received expected error " + - "on block 3a") - } - - // Block 4 should connect even if proof of work is invalid. - invalidPowBlock := *blocks[4].MsgBlock() - invalidPowBlock.Header.Nonce++ - err = chain.CheckConnectBlockTemplate(btcutil.NewBlock(&invalidPowBlock)) - if err != nil { - t.Fatalf("CheckConnectBlockTemplate: Received unexpected error on "+ - "block 4 with bad nonce: %v", err) - } - - // Invalid block building on chain tip should fail to connect. - invalidBlock := *blocks[4].MsgBlock() - invalidBlock.Header.Bits-- - err = chain.CheckConnectBlockTemplate(btcutil.NewBlock(&invalidBlock)) - if err == nil { - t.Fatal("CheckConnectBlockTemplate: Did not received expected error " + - "on block 4 with invalid difficulty bits") - } -} - // TestCheckBlockSanity tests the CheckBlockSanity function to ensure it works // as expected. func TestCheckBlockSanity(t *testing.T) { powLimit := chaincfg.MainNetParams.PowLimit - block := btcutil.NewBlock(&Block100000) + block := GetBlock100000() timeSource := NewMedianTime() err := CheckBlockSanity(block, powLimit, timeSource) if err != nil { @@ -235,254 +150,12 @@ func TestCheckSerializedHeight(t *testing.T) { } } -// Block100000 defines block 100,000 of the block chain. It is used to +var block100000Hex = "0000002024cbdc8644ee3983e66b003a0733891c069ca74c114c034c7b3e2e7ad7a12cd67e95e0555c0e056f6f2af538268ff9d21b420e529750d08eacb25c40f1322936637109b8a051157604c1c163cd39237687f6244b4e6d2b3a94e9d816babaecbb10c56058c811041b2b9c43000701000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2003a086010410c56058081011314abf0100000d2f6e6f64655374726174756d2f000000000180354a6e0a0000001976a914b5e74e7cc9e1f480a6599895c92aab1401f870f188ac000000000100000002f1b75decc2c1c59c2178852822de412f574ad9796b65ac9092a79630d8109aaf000000006a47304402202f78ed3bf8dcadb6c17e289cd06e9c96b02c6f23aa1f446a4a7896a31cfd1e4702202862261e2eb59475ac91092c620b3cac5a831372bafc446d5ee450866040b532012103db4f3785354d84311fab7624c52784a61e3046d8f364463d327bdd96281b5b90feffffff987ee6b4bf95548d01e443683261dd0ffdcb2eb335b2f7119df0d41b60756b92010000006a47304402200c422c7560b6418d45443138bb957ec44eb293a639f4b2235a622205ca6cac370220759f15d5dc2543fd1aef80104c93427fcb025847bf895669025d1d82c62fbf6801210201864b998db5436990a0029fc3fb153c09e8c2689214b91c8ed68784995c8da0feffffff022bccfedd000000001976a914738f16132942a01d00cb9699bd058c4925aada3288ac1f4d030c000000001976a914c4292e757f5ff6a27c2f0a87d3a4aea5e46c275a88ac9f86010001000000015fbb26ad6d818186032baeef4d3f475dfe165c6da2d93411b8ec5f9f523cf1a4000000006a4730440220356999ad5a9f6f09b676f17dd4a2617a0af234722d68a50edc3768c983c0623d022056b4e5531608aeb0205fde9c44f741158da3bba1f4c3788c9fe79d36d43ea355012103509893a2a7c765d49ac9ff70126cb1af54871d70baba2c7e39ec9b4096289a9bfeffffff02389332fa080000001976a914f85e054405fbcedc2341cf8bf41ea989090587a288acf9321a41000000001976a914e85e90c048fdfbe1c2117a7132856ff4b39b470188ac9f86010001000000013508189b9bb61ac2aa536b905447b58f6c58c17cdef305240f566caa689d760a010000006a4730440220669a2b86e5abe58bae54829d3c271669540a9ad965c2fb79e8cc1fb609c0b60002202f958403d979138075cb53d8cb5ff6bb14e18d66dfdb6701c7d43a8ceeed0fa80121029935a602205a3fb72446064f3bc3a55ab9cd2e3459bf2ffdf80a48ab029d4b42feffffff02523c2f13000000001976a914c5b2ae398496f0f9ceaf81b83c28a27ddc890e3588ac211958f2000000001976a914ac65f1d16e5a2af37408b5d65406000a7ea143ca88ac9f8601000100000001bdd724322c555a21d5eb62d4aadbdc051663bcd4ec03f8d9005992f299783c21000000006a47304402205448141a2a788f73310025123bd24f5bee01dd8f48f18d7abc62d7c26465008902207ab46e6ddf6ba416decf3fbb97b6946a1428ea0a7c25a55cab47c47110d8e9ce0121029d6ff3b1235f2a08560b23dd4a08b14cc415b544801b885365736ea8ab1d3470feffffff029d104ccf000000001976a914999d5b0e3d5efcf601c711127b91841afbf5c37a88ace5c5a07f070000001976a9144aade372298eb387da9b6ac69d215a213e822f3f88ac9f86010001000000011658304d4ce796cd450228a10fdf647c6ea42295c9f5e1663df11481af1c884d010000006b483045022100a35d5d3ccde85b41559047d976ae6210b8e6ba5653c53aae1adc90048de0761002200d6bd6ebc6d73f97855f435c6fd595009ee71d23bb34870ab83ad53f67eeb22b012102d2f681ebfd1a570416d602986a47ca4254d8dedf2935b3f8c2ba55dcee8e98f4feffffff025ee913e6020000001976a91468076c9380d3c6b468ad1d6109c36770fb181e8f88acb165394f000000001976a9147ae970e81b3657cbb59df26517e372165807be0088ac9f86010001000000018f285109f78524a88ff328a4f94de2ac03224c50984b11c68adda192e8f78efa010000006b483045022100d77f2ac32dd6a3015f02f7115a13f617c57952fc5d53a33a87dc3fc00ffe1864022006455f74cff864b10424e445c530a59243f86d309dc92c5010ec5709e38471ab012102fdac7335b41edcd2846fc7e2166bb48312ee583ed6ff70fb5c27bcb2addaad86feffffff028b7a6d5c000000001976a914c65106d2e7ea4ec6aa8aa30ba4d11cfd1143123388ac5934c228000000001976a914d1c4d190b07edb972b91f33c36c6568b80358dd488ac9f860100" + +// GetBlock100000 defines block 100,000 of the block chain. It is used to // test Block operations. -var Block100000 = wire.MsgBlock{ - Header: wire.BlockHeader{ - Version: 1, - PrevBlock: chainhash.Hash([32]byte{ // Make go vet happy. - 0x50, 0x12, 0x01, 0x19, 0x17, 0x2a, 0x61, 0x04, - 0x21, 0xa6, 0xc3, 0x01, 0x1d, 0xd3, 0x30, 0xd9, - 0xdf, 0x07, 0xb6, 0x36, 0x16, 0xc2, 0xcc, 0x1f, - 0x1c, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - }), // 000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250 - MerkleRoot: chainhash.Hash([32]byte{ // Make go vet happy. - 0x66, 0x57, 0xa9, 0x25, 0x2a, 0xac, 0xd5, 0xc0, - 0xb2, 0x94, 0x09, 0x96, 0xec, 0xff, 0x95, 0x22, - 0x28, 0xc3, 0x06, 0x7c, 0xc3, 0x8d, 0x48, 0x85, - 0xef, 0xb5, 0xa4, 0xac, 0x42, 0x47, 0xe9, 0xf3, - }), // f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766 - Timestamp: time.Unix(1293623863, 0), // 2010-12-29 11:57:43 +0000 UTC - Bits: 0x1b04864c, // 453281356 - Nonce: 0x10572b0f, // 274148111 - }, - Transactions: []*wire.MsgTx{ - { - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - Hash: chainhash.Hash{}, - Index: 0xffffffff, - }, - SignatureScript: []byte{ - 0x04, 0x4c, 0x86, 0x04, 0x1b, 0x02, 0x06, 0x02, - }, - Sequence: 0xffffffff, - }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0x12a05f200, // 5000000000 - PkScript: []byte{ - 0x41, // OP_DATA_65 - 0x04, 0x1b, 0x0e, 0x8c, 0x25, 0x67, 0xc1, 0x25, - 0x36, 0xaa, 0x13, 0x35, 0x7b, 0x79, 0xa0, 0x73, - 0xdc, 0x44, 0x44, 0xac, 0xb8, 0x3c, 0x4e, 0xc7, - 0xa0, 0xe2, 0xf9, 0x9d, 0xd7, 0x45, 0x75, 0x16, - 0xc5, 0x81, 0x72, 0x42, 0xda, 0x79, 0x69, 0x24, - 0xca, 0x4e, 0x99, 0x94, 0x7d, 0x08, 0x7f, 0xed, - 0xf9, 0xce, 0x46, 0x7c, 0xb9, 0xf7, 0xc6, 0x28, - 0x70, 0x78, 0xf8, 0x01, 0xdf, 0x27, 0x6f, 0xdf, - 0x84, // 65-byte signature - 0xac, // OP_CHECKSIG - }, - }, - }, - LockTime: 0, - }, - { - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - Hash: chainhash.Hash([32]byte{ // Make go vet happy. - 0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60, - 0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac, - 0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07, - 0x79, 0xac, 0x88, 0xfd, 0xf3, 0x57, 0xa1, 0x87, - }), // 87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03 - Index: 0, - }, - SignatureScript: []byte{ - 0x49, // OP_DATA_73 - 0x30, 0x46, 0x02, 0x21, 0x00, 0xc3, 0x52, 0xd3, - 0xdd, 0x99, 0x3a, 0x98, 0x1b, 0xeb, 0xa4, 0xa6, - 0x3a, 0xd1, 0x5c, 0x20, 0x92, 0x75, 0xca, 0x94, - 0x70, 0xab, 0xfc, 0xd5, 0x7d, 0xa9, 0x3b, 0x58, - 0xe4, 0xeb, 0x5d, 0xce, 0x82, 0x02, 0x21, 0x00, - 0x84, 0x07, 0x92, 0xbc, 0x1f, 0x45, 0x60, 0x62, - 0x81, 0x9f, 0x15, 0xd3, 0x3e, 0xe7, 0x05, 0x5c, - 0xf7, 0xb5, 0xee, 0x1a, 0xf1, 0xeb, 0xcc, 0x60, - 0x28, 0xd9, 0xcd, 0xb1, 0xc3, 0xaf, 0x77, 0x48, - 0x01, // 73-byte signature - 0x41, // OP_DATA_65 - 0x04, 0xf4, 0x6d, 0xb5, 0xe9, 0xd6, 0x1a, 0x9d, - 0xc2, 0x7b, 0x8d, 0x64, 0xad, 0x23, 0xe7, 0x38, - 0x3a, 0x4e, 0x6c, 0xa1, 0x64, 0x59, 0x3c, 0x25, - 0x27, 0xc0, 0x38, 0xc0, 0x85, 0x7e, 0xb6, 0x7e, - 0xe8, 0xe8, 0x25, 0xdc, 0xa6, 0x50, 0x46, 0xb8, - 0x2c, 0x93, 0x31, 0x58, 0x6c, 0x82, 0xe0, 0xfd, - 0x1f, 0x63, 0x3f, 0x25, 0xf8, 0x7c, 0x16, 0x1b, - 0xc6, 0xf8, 0xa6, 0x30, 0x12, 0x1d, 0xf2, 0xb3, - 0xd3, // 65-byte pubkey - }, - Sequence: 0xffffffff, - }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0x2123e300, // 556000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0xc3, 0x98, 0xef, 0xa9, 0xc3, 0x92, 0xba, 0x60, - 0x13, 0xc5, 0xe0, 0x4e, 0xe7, 0x29, 0x75, 0x5e, - 0xf7, 0xf5, 0x8b, 0x32, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - { - Value: 0x108e20f00, // 4444000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0x94, 0x8c, 0x76, 0x5a, 0x69, 0x14, 0xd4, 0x3f, - 0x2a, 0x7a, 0xc1, 0x77, 0xda, 0x2c, 0x2f, 0x6b, - 0x52, 0xde, 0x3d, 0x7c, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - }, - LockTime: 0, - }, - { - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - Hash: chainhash.Hash([32]byte{ // Make go vet happy. - 0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d, - 0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27, - 0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65, - 0xe4, 0x1c, 0x61, 0xd0, 0x78, 0x29, 0x4e, 0xcf, - }), // cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3 - Index: 1, - }, - SignatureScript: []byte{ - 0x47, // OP_DATA_71 - 0x30, 0x44, 0x02, 0x20, 0x03, 0x2d, 0x30, 0xdf, - 0x5e, 0xe6, 0xf5, 0x7f, 0xa4, 0x6c, 0xdd, 0xb5, - 0xeb, 0x8d, 0x0d, 0x9f, 0xe8, 0xde, 0x6b, 0x34, - 0x2d, 0x27, 0x94, 0x2a, 0xe9, 0x0a, 0x32, 0x31, - 0xe0, 0xba, 0x33, 0x3e, 0x02, 0x20, 0x3d, 0xee, - 0xe8, 0x06, 0x0f, 0xdc, 0x70, 0x23, 0x0a, 0x7f, - 0x5b, 0x4a, 0xd7, 0xd7, 0xbc, 0x3e, 0x62, 0x8c, - 0xbe, 0x21, 0x9a, 0x88, 0x6b, 0x84, 0x26, 0x9e, - 0xae, 0xb8, 0x1e, 0x26, 0xb4, 0xfe, 0x01, - 0x41, // OP_DATA_65 - 0x04, 0xae, 0x31, 0xc3, 0x1b, 0xf9, 0x12, 0x78, - 0xd9, 0x9b, 0x83, 0x77, 0xa3, 0x5b, 0xbc, 0xe5, - 0xb2, 0x7d, 0x9f, 0xff, 0x15, 0x45, 0x68, 0x39, - 0xe9, 0x19, 0x45, 0x3f, 0xc7, 0xb3, 0xf7, 0x21, - 0xf0, 0xba, 0x40, 0x3f, 0xf9, 0x6c, 0x9d, 0xee, - 0xb6, 0x80, 0xe5, 0xfd, 0x34, 0x1c, 0x0f, 0xc3, - 0xa7, 0xb9, 0x0d, 0xa4, 0x63, 0x1e, 0xe3, 0x95, - 0x60, 0x63, 0x9d, 0xb4, 0x62, 0xe9, 0xcb, 0x85, - 0x0f, // 65-byte pubkey - }, - Sequence: 0xffffffff, - }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0xf4240, // 1000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0xb0, 0xdc, 0xbf, 0x97, 0xea, 0xbf, 0x44, 0x04, - 0xe3, 0x1d, 0x95, 0x24, 0x77, 0xce, 0x82, 0x2d, - 0xad, 0xbe, 0x7e, 0x10, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - { - Value: 0x11d260c0, // 299000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0x6b, 0x12, 0x81, 0xee, 0xc2, 0x5a, 0xb4, 0xe1, - 0xe0, 0x79, 0x3f, 0xf4, 0xe0, 0x8a, 0xb1, 0xab, - 0xb3, 0x40, 0x9c, 0xd9, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - }, - LockTime: 0, - }, - { - Version: 1, - TxIn: []*wire.TxIn{ - { - PreviousOutPoint: wire.OutPoint{ - Hash: chainhash.Hash([32]byte{ // Make go vet happy. - 0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73, - 0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac, - 0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90, - 0x9b, 0xa1, 0xc4, 0x3d, 0xed, 0x5f, 0x51, 0xf4, - }), // f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b - Index: 0, - }, - SignatureScript: []byte{ - 0x49, // OP_DATA_73 - 0x30, 0x46, 0x02, 0x21, 0x00, 0xbb, 0x1a, 0xd2, - 0x6d, 0xf9, 0x30, 0xa5, 0x1c, 0xce, 0x11, 0x0c, - 0xf4, 0x4f, 0x7a, 0x48, 0xc3, 0xc5, 0x61, 0xfd, - 0x97, 0x75, 0x00, 0xb1, 0xae, 0x5d, 0x6b, 0x6f, - 0xd1, 0x3d, 0x0b, 0x3f, 0x4a, 0x02, 0x21, 0x00, - 0xc5, 0xb4, 0x29, 0x51, 0xac, 0xed, 0xff, 0x14, - 0xab, 0xba, 0x27, 0x36, 0xfd, 0x57, 0x4b, 0xdb, - 0x46, 0x5f, 0x3e, 0x6f, 0x8d, 0xa1, 0x2e, 0x2c, - 0x53, 0x03, 0x95, 0x4a, 0xca, 0x7f, 0x78, 0xf3, - 0x01, // 73-byte signature - 0x41, // OP_DATA_65 - 0x04, 0xa7, 0x13, 0x5b, 0xfe, 0x82, 0x4c, 0x97, - 0xec, 0xc0, 0x1e, 0xc7, 0xd7, 0xe3, 0x36, 0x18, - 0x5c, 0x81, 0xe2, 0xaa, 0x2c, 0x41, 0xab, 0x17, - 0x54, 0x07, 0xc0, 0x94, 0x84, 0xce, 0x96, 0x94, - 0xb4, 0x49, 0x53, 0xfc, 0xb7, 0x51, 0x20, 0x65, - 0x64, 0xa9, 0xc2, 0x4d, 0xd0, 0x94, 0xd4, 0x2f, - 0xdb, 0xfd, 0xd5, 0xaa, 0xd3, 0xe0, 0x63, 0xce, - 0x6a, 0xf4, 0xcf, 0xaa, 0xea, 0x4e, 0xa1, 0x4f, - 0xbb, // 65-byte pubkey - }, - Sequence: 0xffffffff, - }, - }, - TxOut: []*wire.TxOut{ - { - Value: 0xf4240, // 1000000 - PkScript: []byte{ - 0x76, // OP_DUP - 0xa9, // OP_HASH160 - 0x14, // OP_DATA_20 - 0x39, 0xaa, 0x3d, 0x56, 0x9e, 0x06, 0xa1, 0xd7, - 0x92, 0x6d, 0xc4, 0xbe, 0x11, 0x93, 0xc9, 0x9b, - 0xf2, 0xeb, 0x9e, 0xe0, - 0x88, // OP_EQUALVERIFY - 0xac, // OP_CHECKSIG - }, - }, - }, - LockTime: 0, - }, - }, +func GetBlock100000() *btcutil.Block { + var block100000Bytes, _ = hex.DecodeString(block100000Hex) + var results, _ = btcutil.NewBlockFromBytes(block100000Bytes) + return results } diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index fa8305c2..95320dbd 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -388,7 +388,7 @@ func TestChainSvrCmds(t *testing.T) { return btcjson.NewGetBlockFilterCmd("0000afaf", nil) }, marshalled: `{"jsonrpc":"1.0","method":"getblockfilter","params":["0000afaf"],"id":1}`, - unmarshalled: &btcjson.GetBlockFilterCmd{"0000afaf", nil}, + unmarshalled: &btcjson.GetBlockFilterCmd{BlockHash: "0000afaf", FilterType: nil}, }, { name: "getblockfilter optional filtertype", @@ -399,7 +399,7 @@ func TestChainSvrCmds(t *testing.T) { return btcjson.NewGetBlockFilterCmd("0000afaf", btcjson.NewFilterTypeName(btcjson.FilterTypeBasic)) }, marshalled: `{"jsonrpc":"1.0","method":"getblockfilter","params":["0000afaf","basic"],"id":1}`, - unmarshalled: &btcjson.GetBlockFilterCmd{"0000afaf", btcjson.NewFilterTypeName(btcjson.FilterTypeBasic)}, + unmarshalled: &btcjson.GetBlockFilterCmd{BlockHash: "0000afaf", FilterType: btcjson.NewFilterTypeName(btcjson.FilterTypeBasic)}, }, { name: "getblockhash", diff --git a/chaincfg/genesis.go b/chaincfg/genesis.go index a4df289d..bfa2a845 100644 --- a/chaincfg/genesis.go +++ b/chaincfg/genesis.go @@ -86,15 +86,6 @@ var genesisBlock = wire.MsgBlock{ Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -// regTestGenesisHash is the hash of the first block in the block chain for the -// regression test network (genesis block). -var regTestGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x56, 0x75, 0x68, 0x69, 0x76, 0x67, 0x4f, 0x50, - 0xa0, 0xa1, 0x95, 0x3d, 0x17, 0x2e, 0x9e, 0xcf, - 0x4a, 0x4a, 0x62, 0x1d, 0xc9, 0xa4, 0xc3, 0x79, - 0x5d, 0xec, 0xd4, 0x99, 0x12, 0xcf, 0x3f, 0x6e, -}) - // regTestGenesisMerkleRoot is the hash of the first transaction in the genesis // block for the regression test network. It is the same as the merkle root for // the main network. @@ -115,14 +106,9 @@ var regTestGenesisBlock = wire.MsgBlock{ Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -// testNet3GenesisHash is the hash of the first block in the block chain for the -// test network (version 3). -var testNet3GenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, - 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae, - 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, - 0x01, 0xea, 0x33, 0x09, 0x00, 0x00, 0x00, 0x00, -}) +// regTestGenesisHash is the hash of the first block in the block chain for the +// regression test network (genesis block). +var regTestGenesisHash = regTestGenesisBlock.BlockHash() // testNet3GenesisMerkleRoot is the hash of the first transaction in the genesis // block for the test network (version 3). It is the same as the merkle root @@ -144,14 +130,9 @@ var testNet3GenesisBlock = wire.MsgBlock{ Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -// simNetGenesisHash is the hash of the first block in the block chain for the -// simulation test network. -var simNetGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, - 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, - 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, - 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, -}) +// testNet3GenesisHash is the hash of the first block in the block chain for the +// test network (version 3). +var testNet3GenesisHash = testNet3GenesisBlock.BlockHash() // simNetGenesisMerkleRoot is the hash of the first transaction in the genesis // block for the simulation test network. It is the same as the merkle root for @@ -172,14 +153,9 @@ var simNetGenesisBlock = wire.MsgBlock{ Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } -// sigNetGenesisHash is the hash of the first block in the block chain for the -// signet test network. -var sigNetGenesisHash = chainhash.Hash{ - 0xf6, 0x1e, 0xee, 0x3b, 0x63, 0xa3, 0x80, 0xa4, - 0x77, 0xa0, 0x63, 0xaf, 0x32, 0xb2, 0xbb, 0xc9, - 0x7c, 0x9f, 0xf9, 0xf0, 0x1f, 0x2c, 0x42, 0x25, - 0xe9, 0x73, 0x98, 0x81, 0x08, 0x00, 0x00, 0x00, -} +// simNetGenesisHash is the hash of the first block in the block chain for the +// simulation test network. +var simNetGenesisHash = simNetGenesisBlock.BlockHash() // sigNetGenesisMerkleRoot is the hash of the first transaction in the genesis // block for the signet test network. It is the same as the merkle root for @@ -199,3 +175,7 @@ var sigNetGenesisBlock = wire.MsgBlock{ }, Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } + +// sigNetGenesisHash is the hash of the first block in the block chain for the +// signet test network. +var sigNetGenesisHash = sigNetGenesisBlock.BlockHash() diff --git a/chaincfg/genesis_test.go b/chaincfg/genesis_test.go index 1daf8479..b3b54e5d 100644 --- a/chaincfg/genesis_test.go +++ b/chaincfg/genesis_test.go @@ -21,13 +21,6 @@ func TestGenesisBlock(t *testing.T) { t.Fatalf("TestGenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), genesisBlockBytes) { - t.Fatalf("TestGenesisBlock: Genesis block does not appear valid - "+ - "got %v, want %v", spew.Sdump(buf.Bytes()), - spew.Sdump(genesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := MainNetParams.GenesisBlock.BlockHash() if !MainNetParams.GenesisHash.IsEqual(&hash) { @@ -47,14 +40,6 @@ func TestRegTestGenesisBlock(t *testing.T) { t.Fatalf("TestRegTestGenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), regTestGenesisBlockBytes) { - t.Fatalf("TestRegTestGenesisBlock: Genesis block does not "+ - "appear valid - got %v, want %v", - spew.Sdump(buf.Bytes()), - spew.Sdump(regTestGenesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := RegressionNetParams.GenesisBlock.BlockHash() if !RegressionNetParams.GenesisHash.IsEqual(&hash) { @@ -74,14 +59,6 @@ func TestTestNet3GenesisBlock(t *testing.T) { t.Fatalf("TestTestNet3GenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), testNet3GenesisBlockBytes) { - t.Fatalf("TestTestNet3GenesisBlock: Genesis block does not "+ - "appear valid - got %v, want %v", - spew.Sdump(buf.Bytes()), - spew.Sdump(testNet3GenesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := TestNet3Params.GenesisBlock.BlockHash() if !TestNet3Params.GenesisHash.IsEqual(&hash) { @@ -101,14 +78,6 @@ func TestSimNetGenesisBlock(t *testing.T) { t.Fatalf("TestSimNetGenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), simNetGenesisBlockBytes) { - t.Fatalf("TestSimNetGenesisBlock: Genesis block does not "+ - "appear valid - got %v, want %v", - spew.Sdump(buf.Bytes()), - spew.Sdump(simNetGenesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := SimNetParams.GenesisBlock.BlockHash() if !SimNetParams.GenesisHash.IsEqual(&hash) { @@ -128,14 +97,6 @@ func TestSigNetGenesisBlock(t *testing.T) { t.Fatalf("TestSigNetGenesisBlock: %v", err) } - // Ensure the encoded block matches the expected bytes. - if !bytes.Equal(buf.Bytes(), sigNetGenesisBlockBytes) { - t.Fatalf("TestSigNetGenesisBlock: Genesis block does not "+ - "appear valid - got %v, want %v", - spew.Sdump(buf.Bytes()), - spew.Sdump(sigNetGenesisBlockBytes)) - } - // Check hash of the block against expected hash. hash := SigNetParams.GenesisBlock.BlockHash() if !SigNetParams.GenesisHash.IsEqual(&hash) { @@ -144,208 +105,3 @@ func TestSigNetGenesisBlock(t *testing.T) { spew.Sdump(SigNetParams.GenesisHash)) } } - -// genesisBlockBytes are the wire encoded bytes for the genesis block of the -// main network as of protocol version 60002. -var genesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |....;...| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |z{..z.,>| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |gv.a....| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |..Q2:...| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0x29, 0xab, 0x5f, 0x49, /* |K.^J)._I| */ - 0xff, 0xff, 0x00, 0x1d, 0x1d, 0xac, 0x2b, 0x7c, /* |......+|| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..M.....| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..EThe T| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |imes 03/| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |Jan/2009| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* | Chancel| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* |lor on b| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |rink of | */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |second b| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |ailout f| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |or banks| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |*....CA.| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |g....UH'| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |.g..q0..| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |\..(.9..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |yb...a..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |I..?L.8.| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |.U......| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |\8M....W| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} - -// regTestGenesisBlockBytes are the wire encoded bytes for the genesis block of -// the regression test network as of protocol version 60002. -var regTestGenesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |....;...| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |z{..z.,>| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |gv.a....| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |..Q2:...| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0xda, 0xe5, 0x49, 0x4d, /* |K.^J)._I| */ - 0xff, 0xff, 0x7f, 0x20, 0x02, 0x00, 0x00, 0x00, /* |......+|| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..M.....| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..EThe T| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |imes 03/| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |Jan/2009| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* | Chancel| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* |lor on b| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |rink of | */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |second b| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |ailout f| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |or banks| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |*....CA.| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |g....UH'| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |.g..q0..| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |\..(.9..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |yb...a..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |I..?L.8.| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |.U......| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |\8M....W| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} - -// testNet3GenesisBlockBytes are the wire encoded bytes for the genesis block of -// the test network (version 3) as of protocol version 60002. -var testNet3GenesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |....;...| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |z{..z.,>| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |gv.a....| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |..Q2:...| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0xda, 0xe5, 0x49, 0x4d, /* |K.^J)._I| */ - 0xff, 0xff, 0x00, 0x1d, 0x1a, 0xa4, 0xae, 0x18, /* |......+|| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..M.....| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..EThe T| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |imes 03/| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |Jan/2009| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* | Chancel| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* |lor on b| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |rink of | */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |second b| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |ailout f| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |or banks| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |*....CA.| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |g....UH'| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |.g..q0..| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |\..(.9..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |yb...a..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |I..?L.8.| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |.U......| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |\8M....W| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} - -// simNetGenesisBlockBytes are the wire encoded bytes for the genesis block of -// the simulation test network as of protocol version 70002. -var simNetGenesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |....;...| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |z{..z.,>| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |gv.a....| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |..Q2:...| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0x45, 0x06, 0x86, 0x53, /* |K.^J)._I| */ - 0xff, 0xff, 0x7f, 0x20, 0x02, 0x00, 0x00, 0x00, /* |......+|| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..M.....| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..EThe T| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |imes 03/| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |Jan/2009| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* | Chancel| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* |lor on b| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |rink of | */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |second b| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |ailout f| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |or banks| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |*....CA.| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |g....UH'| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |.g..q0..| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |\..(.9..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |yb...a..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |I..?L.8.| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |.U......| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |\8M....W| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} - -// sigNetGenesisBlockBytes are the wire encoded bytes for the genesis block of -// the signet test network as of protocol version 70002. -var sigNetGenesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |...@....| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |........| */ - 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |....;...| */ - 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |z{..z.,>| */ - 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |gv.a....| */ - 0x4b, 0x1e, 0x5e, 0x4a, 0x00, 0x8f, 0x4d, 0x5f, /* |..Q2:...| */ - 0xae, 0x77, 0x03, 0x1e, 0x8a, 0xd2, 0x22, 0x03, /* |K.^J..M_| */ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |.w....".| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ - 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |........| */ - 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..M.....| */ - 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |..EThe T| */ - 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |imes 03/| */ - 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* |Jan/2009| */ - 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* | Chancel| */ - 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |lor on b| */ - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |rink of| */ - 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |second b| */ - 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |ailout f| */ - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |or banks| */ - 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |........| */ - 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |*....CA.| */ - 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |g....UH'| */ - 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |.g..q0..| */ - 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |\..(.9..| */ - 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |yb...a..| */ - 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |I..?L.8.| */ - 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |.U......| */ - 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |\8M....W| */ - 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ -} diff --git a/database/ffldb/interface_test.go b/database/ffldb/interface_test.go index b1b4cac7..f7330f4f 100644 --- a/database/ffldb/interface_test.go +++ b/database/ffldb/interface_test.go @@ -61,12 +61,10 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu dr := bzip2.NewReader(fi) // Set the first block as the genesis block. - blocks := make([]*btcutil.Block, 0, 256) - genesis := btcutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) - blocks = append(blocks, genesis) + blocks := make([]*btcutil.Block, 0, 257) // Load the remaining blocks. - for height := 1; ; height++ { + for { var net uint32 err := binary.Read(dr, binary.LittleEndian, &net) if err == io.EOF { @@ -75,20 +73,18 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu } if err != nil { t.Errorf("Failed to load network type for block %d: %v", - height, err) + len(blocks), err) return nil, err } if net != uint32(network) { - t.Errorf("Block doesn't match network: %v expects %v", - net, network) - return nil, err + continue } var blockLen uint32 err = binary.Read(dr, binary.LittleEndian, &blockLen) if err != nil { t.Errorf("Failed to load block size for block %d: %v", - height, err) + len(blocks), err) return nil, err } @@ -96,17 +92,22 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu blockBytes := make([]byte, blockLen) _, err = io.ReadFull(dr, blockBytes) if err != nil { - t.Errorf("Failed to load block %d: %v", height, err) + t.Errorf("Failed to load block %d: %v", len(blocks), err) return nil, err } // Deserialize and store the block. block, err := btcutil.NewBlockFromBytes(blockBytes) if err != nil { - t.Errorf("Failed to parse block %v: %v", height, err) + t.Errorf("Failed to parse block %v: %v", len(blocks), err) return nil, err } + // NOTE: there's a bug here in that it doesn't read the checksum; + // we account for that by checking the network above; it probably skips every other block blocks = append(blocks, block) + if len(blocks) == 257 { + break + } } return blocks, nil diff --git a/database/ffldb/whitebox_test.go b/database/ffldb/whitebox_test.go index 4314c69f..15c83cec 100644 --- a/database/ffldb/whitebox_test.go +++ b/database/ffldb/whitebox_test.go @@ -54,12 +54,10 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu dr := bzip2.NewReader(fi) // Set the first block as the genesis block. - blocks := make([]*btcutil.Block, 0, 256) - genesis := btcutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) - blocks = append(blocks, genesis) + blocks := make([]*btcutil.Block, 0, 257) // Load the remaining blocks. - for height := 1; ; height++ { + for { var net uint32 err := binary.Read(dr, binary.LittleEndian, &net) if err == io.EOF { @@ -68,20 +66,18 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu } if err != nil { t.Errorf("Failed to load network type for block %d: %v", - height, err) + len(blocks), err) return nil, err } if net != uint32(network) { - t.Errorf("Block doesn't match network: %v expects %v", - net, network) - return nil, err + continue } var blockLen uint32 err = binary.Read(dr, binary.LittleEndian, &blockLen) if err != nil { t.Errorf("Failed to load block size for block %d: %v", - height, err) + len(blocks), err) return nil, err } @@ -89,17 +85,22 @@ func loadBlocks(t *testing.T, dataFile string, network wire.BitcoinNet) ([]*btcu blockBytes := make([]byte, blockLen) _, err = io.ReadFull(dr, blockBytes) if err != nil { - t.Errorf("Failed to load block %d: %v", height, err) + t.Errorf("Failed to load block %d: %v", len(blocks), err) return nil, err } // Deserialize and store the block. block, err := btcutil.NewBlockFromBytes(blockBytes) if err != nil { - t.Errorf("Failed to parse block %v: %v", height, err) + t.Errorf("Failed to parse block %v: %v", len(blocks), err) return nil, err } + // there's a bug here in that it doesn't read the checksum + // and then it maybe ends up skipping a block blocks = append(blocks, block) + if len(blocks) == 257 { + break + } } return blocks, nil diff --git a/database/testdata/blocks1-256.bz2 b/database/testdata/blocks1-256.bz2 index 6b8bda4429200c0566bb13c28c35d6397272e475..8e9b44c004d757b18c93bd96f5acb5d74d3b119a 100644 GIT binary patch literal 42273 zcmV);K!(3UT4*^jL0KkKSs%#<+yI}=fB*mg|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0 z|NsC0|Nr1_zW@)ObATIQ3F`ZRA7%hOZ#i$dyRFsru4*^CyEMydY}=|ghrRDRJH2ji zd^z6%(BAvI?|?n`y}Px-wC>rPu9eq!eA(#OYU{h#Uc*z~Gu?MR?zP)*UiSCEKJ&c# z+r0O4cYEFM9BZw!TX&lF?XKB-;0w8Yvwe4`Z#8!BcW-m0S3A!2r@8H(tvhqKw^7u0 zw_e`&Ztpqv?>xTUJA1b_^=`|jZ1=s_de+?{_R6~T?{_slPjT+-_qVY3cY)sPy>71B z+}E1i>g&BdJbQb3_q)CT?_T$JON9FzoprlTu000Su#J~xr0%be^005Ynm0MKZt zM5xf4Kuk;k36lT`fJ`Gs0GcqE6A6lXU;qdVj3$^y05k$&FaR0}fCSS`4KPhG6+c5J zCMHZHR4RyRFa*s21jNM1$&E}JA?jf?)6p=RWMMN2so@%)fMjUVFle4kf@ISs6wOo2 zh9(tH^wFg9VlgzyiHOL`W(dQXvva#P^vTxfC6cz5MnZ$ z6HQDLO+7;sOcO??PfZ#yCK0qv88Hn2(lqj68f3&WCetc@j3o5b^kp>iVGNVgO*F($ zA(4dAdSYZWGBlu(A_S2%%6^o2PYQacgxXI{O`{V{Ddh4rnHXfrP!)zO4 zY)y@*Xo!UkCNYe01UAq^gwWd>K-(H=gBZq}8yiqGK+|B@HliRH(rvV%gf!TjV@;rJ zZ8no&Hj`p)HrU%6h)Nq`Z4k&DI2br^#x~n%8*GLUG}zl>ZKlT#7&e;*#x}&p4T+65 zIiwv%8e({8Bw)+CZbxG+g1gO_MX5O0K#gvl@qN_b$v3ly77F*pzaASMY?c3|3B z+sqJD-Y}Vmof!>~$P$sfEKXO(^w&%MmOZG_laS2T3915J8UhMuunEta|6EJ zVcwD|t;}AVOudWqJ4FJWQ(IhS@iH@VyNp64dd6fPoO>!1kAI{LNjb>hT=O;R?6>(- z1&+3Ux@3G>42ljJB*rt`d2V7whl}6T{uH@(-s&{&iY<~CZF{FJYMV@57)wZfh$@aE z@ih*{SpAIR4LJXwMXsB2-qKI;x6tgB)^v@S>wVvzAAyoBb+HvEN328;jxIdmIZ%B0 zNSnLud%6>!@{-qgj=Glj(v^3+cf2=WN0gJN4^Nv10o*&e zXZZR$Iyt`m5fptFa^0T~$Jp<8+s@DXe{aRT`8T`m7JXzIFl~*u%yhC4BrMCCNhHRQ zBpXNxu;$wAS`74{=vjMyYuPk)?*7BdkXQ(n6ba}Gb@=_Iy~>OZxRyU0977v^hvoGLtjOU z;A-g3b6E@A$-s9_Z}<0`&~k&mokS*B@T}QBydV0_E3i<_f6{zM$}Vo4cN}Al>tV1j zGnI9t*;v9?EwU(8e#tmmvkQ4$9ThG)?X?W`UAI-=NgW+GVfc5YqhS2xSVXJ4Mm`On z3KQ4VPt%=G`qv(UXIm+fLJ}4<5G(6I+hQ9MKsEvq2+w7r=at*<`96dA@O7af3fSl2 zB#2{R*fz#;ZXXiW$;gO5l^ALwaYO_?G(&Vw0mMoo6C6th)Tdn%l~u%>rh-(;DV#S% zoit6k*AYdh5~C*KmYtAT2OLNPE|Ofh?eG1q&p%~ z2UE5gQ>3n`I-yYtfvHX_rcDJzAPRXPe>R~F1CO*K_IX(WG-_sI2B;sk9anK~(bhB?Du?W_Cj#FutqPYfZ>mIKXP0K7B=a^ppo$%7h*=YxUXIK< zj;s|yx<2yEDDy5zhdeF?B>!568k(7GL0j|*wmZuABYGt_3qKrR7bFVwW;53PTkLB7 z*ZIjo)ma|Pl{LjG_F2}dHs!@OjZO#qSo`CeWulVS;hp_&4t$^GX|V9Y%3XHsJr~cV;;Z@Urvh4D-ZM3m2FS%}j#fp3RP*3YM zu92ib{u#QC6!a}rjBC@e=~QxEYQ&bly*f7Pskh8{cP9oTkl7*4Hlo4VEd~SDV@TO? zHt+E7p;~Cz+->pLN@*G&wV1}p=HACC2*EU~VZ^a_>|D+2J%$@6-ZXCB*`IT&g-1A$ zD95nBGf>g~nCSbTdJWqPtI;#I=X6pr&0{`~Z7okb3;4Xd1FZ1lqh`}h2K@gC7n5_e zuu(Dged)mFXhzRLSVT60xJVCZSS@_9hiw+kOj`6g#2?oZ55_Waci(z&`UPc!^KO-h z!n`q#)(t7+AMo=QqWye3D5+?|-Mtj?2m}HFWB_#=PyqI4F5^V$G!BEtebtDqAwNJ- z{R4)B&?W8a!P6&TVLhJ}O7)`CP|JIhH84-Ssqc3>Zx9_7+rGVQ`YvnX^56Vq{?-Fw z#bB_R(+y_O?x z&3i&rFb>gzhPyU}4K6XLVjJa|mS_ny1|6G*0ukad31Wif_gUZ$+1y$B7{1H;jQ^jC zGK^MjAjasSa5#9%FfD7N@wNS0wgC^nV0Z7W-bZfuR$kt{?pcUv)H9UhV}3~_^W8LL zUvkV(2_Mr1^<ju#W7#nUK{>w7W@MYADsq`lSmga0$(kg zt9UeQ@7bhhXXn7L4AHS0#u`5}hU4aESQxIB3&RY1GVC#L4}ODY%?sl`)Gp6A9vkwp z5Nw!go)PjaG*}v>yDs80%+ufC%CPkrZvAGs$I&rpbCJ4!D?~E{!zIN)b-0)`&!_xR zzPF9P71#RQ#*&ktb%+x_e*uN!(X0C&&GX>wuROoxJ-$lj1ge4^73HiqGwtbzC#d&GZ^C5fgH>r2Kg6*8lSX2WR`Z-5+bP z!f-#io=f(gaqix&oS(4<-JSMIIM!ivTU=K+`C$Lg4s|X3=L6qM>sfpm`>oOMg$k*< z)Rrj)U=V-?VD;GLU(V86^Ugp(AOZN2Nh?0&C5Yjo01Z*MB>EVyKjb=@s{b{kUjva~ zgdhhqninI#Y-v8YQ#pIFC;sx-%gt=A#uys6D7cmwZT3S%mj{vdPHP?$qqhol62S_FSp=-)E<{N@DxJqj23eA zYev>ZKtunj&TZQ08r~ZD002NCBoF|AKmy2`xEr^7m$bNB%*&JX#hZ3)jSF4U1Rwzj z1Cq0@ugmG9##Ff@X>#LuucjxQ??M0FyRN5Z`$3!_027-j8ExA|_w?(z9RqR1@h}aw zv}Z#wq{(pXNTsa{co>uYGCfR~1&7|d&&0lx#D%bjRyiBM6FG<6`2A77EpwEx;lLlKfJ^`7?V6J|55t4QvJCY4U7nx^^j^7m)E6 zJiH8dA}aF`N9jxsesq- z;jAaI(e!KA`nL;GL?8hVzc@{rO__jSd1v2oKgrrYG5P(7e>Xe+RV%-t1 zbO$srNd3^ajxt8#O_7$;E{FgGq`hM*b?YpLI&2{b6ft?_`@OoGBB>4!mohNcSaS+d ztBU30RbgKrkADQcpBY+ec-HCk3yAzVXas^Jhp2T5b^Zl7`tCpgAOPBA>`674wJ|p4 zM@(}t#Ckl|u={$^|9=kWA`pN=0GFOlz0~WEK}*SY8HKjL;xveebD(6F#bJ_b{4U9K zJGd^~PFSH9v$+33J`3Ib%R99aQ*US==vha11RH+IDndWQd$+Ehx1D=}k_KTs{O657m2y?kwH9;%zJaud@eQazckB3ZBG#}v zvT8JoAOIk%gc$ws?6LCF30R)!{=1hfXi~OtzD@SuVST{3ZuXuMwq}rQH|dBjmx*1E z-f1G3fZ3RYbs+MnKh;U|=#a=S;$XLwbb~xy^S-*G(MXGKj++g-UFtd4y3Erb^6T^F zJR{Em1;lguCQ~%(xv$9z$ z-04KEMD`m9r9Bcife5Wl@-57sA^8<a9w06P?v6yGz1_H zXC-}qkl~fr_Yf#F@29#y-^jInI+1vgkwW!Q(rUnr!ffyHDoLkUArt9n(bRX$Te#j= zrnkJ2*=(OlOoH{1&N5egYHFmjBaAwGH@~7XZ2-|Tv3LDd#H?PGlD!@Ef9*v!o$*Ls zvLW;2#<~6XQ*i^A>iE*S78^?Q$+;l_1N{U=J65n@3L4clo42I$B6$m@>@sf?A{QYK z@A9PCkL%_7dX`tP2WO(Ium7KL03AEWBOgJb+?LjG*Fw3a=}uQ^*SeXvjoc$_GxT|t z?Hd$Z@#gV3(;VKqMLjBqfxNr2OauY|PK@iSn$vj@*HfZkWn2m@6>V&2W8~-a`0IF3 ztsnU%NP^M6C57B%g`I0&1aG2xX-N{UWnaNz0Ds`7anfg;kMG)`7DQfq`5-l~rrk>G z$8Xxh+s!Mq_YKaI5EH7tN)J}s^q=(2O;lEf`86}~=4pCL={GA^XM2GEN&IqS!d#e% z^6QlrRERKg>0+F4Y9Rul_K0k#j8en4O>qxh>10v7AEshs!~}^agG4x0Uh`%2WI?D$|pwnxE?w`efTv z1~K;>Ge3Jiwv+6n%Fiv)DaQPXJT30r6tg=Mndi!njZ@M#hWCE;v~&Hjjd){RXq;ew zoxtJU%=E$$9!16WM6*MShNTVKg@0>pdPXJVZvs8gY!CnlC-^($7%7|zHpMAw9&DSH zg|Q-c+jq0Ebeag`UcPy(wJH4Cwa&LEC&PYR1|!RuX3CgSUwHC1@miP@ zW-g@zs(F2KgH5gULD!}mLBiNlqlKpOvb zbBL8HKktgDKQFLEm&YY~J^v{o_*?Khl;OZ5DNx@TYPyI3Eix^6!AE6+?PG0I$M|#v zAqZ2Kh&uj^zcn-PO-rlF8&cp)V@yP(v6vgiKmY_b<^g>2Z{A^Jkyc~pAra%aZ2;CV z3em7gA2O+Y6DS2+%xkh!XbM>f7$Y^FsOv8tDm?Q92?jyYv8+5|glvwtxaTT%N=)6@ z&)|KVVOCV-$a(zVO}n5f6bZ>5{k(WLvbs9 ze?j%p%w&IEb4}Aw%c%|Hbnh}|Fl?=)XX>chY^SS9jZwrm8|MWK#ZT^a3qHJU7GD<00K`D_Zk#y4o1?9{rc~!=bd@H8NVrq>DFwyq}oRT+>&aWn@BLT zkFqvwCDqxGIa>D>{IOsrll*UBXS{t=mBL8S;g_pGs4wr;Xip#oIbm+n^cGEZwA zMwOrV<^j^218VcM_ufo6FCiS}+d{1{3p2IK?Ll44rHQW6J-hp{8B-_v{l_OGj4Bdr zi4Z?~iaEivU1}+&!z}K@FEBNGg%DqJv|@ANI57dKH&$nud;S;A_E!cety^e&sKu#O zo`>5oJ{LT2IHB}!l7C{h$X%UY#_t1cQAj@VS#r`8+EMM`eT(mv(@tyt2V%r+S+jL0 zqn-{i_bu5&|HY4;#2Qkr%MiEsMnjC;I{g)6Wx7r=?|u! zOou?it*c+QB#AZ+$edwd(?Eqpv@feARF0X1UzsYoUptCL?tTt0AahY{GjP#iMoL#d zscO1(ykuRnLAoM^wXLLfJCt00nVX<)DfUzI9-SSi_O9W7h-kon1T~yl9ekygS?f8u zN(HnPewx)~-yx37Qn~J40le)bVFNN1E;Py6Rm;|qZET0|Hxw=Q!rH=@?oaiZ3agfh zuP&PLQ6g-e^Yb|}IZJT~TJ>;UVhgow3oD0Y<>CzVHhC|_y~3v?~pj>x#-CIMyP;dfbaTYRbEw@yzhl4;)X zx9*{MJd8TOC#bZ&5@5YxTam;H`gO(P2+4^EptTpJC|Op8Hc+p}^%xXT{(@#bUx%U8N^-9XVo=L<7? z;gRs=*ZH8&pT>MSTpmC-{zDe9G%zsArkWaJyK&m2bP(Jg&c<2fQ#}#fAFK$P;e7@K zdMxBB4B+u8ZaIi=yU<8D0Y~6}62o{0S|x-8I3LIMdGad(pO5GN4jgbKB+f>%$X^K# z&gbl&OH{A2l2OZOB9LSyt+MiEzVZlsa+Q{bgo{ZF}tZ7^0*=uDw+^ zx*d?!#|<0#04POgWN&^QK3lp?cL*a4f5H%e6pi~d(rtf{t1B}kpmt_W5=DyLP5kiw zyG^f6A>QIq<=?b29w2M4x)J|Qn%|2P`uRBBtjp@|VrMMp6{jxF)*o2)w8U!UCvJ2@1jA zg?N_`gC51cPLD=Y#`G;>dFF6ewdH(+rMer-hmMDBUh%aBdg-|bgK=t#C9^+3C#9(jzdse zn#hVA=CLe*LI5XdUV0|2NW|Lb7eT=1xtcf_*+RWJLKhH(0uTXo_FVznzxFc)O>l$& zDl9BsEBpS@YJZH!=z*F_I^+j-JLosZndB>;yAAF1mn;7*Qsw&XMv{N2+daEUU07xr z={$p0nd4}>i66a&{Lc}E>Co@{LJlX|`+A9+$JswCwE4FhaJ2di{kff9ius@)7{|A$TV<>KYD6>j*-eLaW!-)E98t%3|_ zHb|CTf+s>~W!f}-m&GDK`zHIF2w~`<+#%rH!S!}|dcC=8uHEVwKQG6hL23X$y89~2 zwjK&ms4A}>I`M7Zc~<9N#=6~&FsF@Hx-Dg0@_x#L(3gkb^%P-ucjE~zysY^$g*x2N z=!78)fNq;b&O~Z!DcS5aUn4_Q0RRAiLIE^x9)}Qe3wf(O52tgnbUL6%9MQuNju2TM zGf0F-13x_->4L-C`~-DFRQ(MBU+@AJrpg(dENF|(U^)Ty5D&y?@$pFx9!xF+0MVm# zWJ!z;jL<+JENx)L_|e0Kk_w>+L!gI@COA>@KBtHscyP?^KQnj&%YTRb-sG$2K+0@j zj6rhDyzYj{<{@~JQxOmuvdfG z3xaa1>~Kf}gn&5kh(jJ!u|_6jL?H-=?lfV%m4D^OGJzK4vC`9}29ruGc+$kR0_Dd< zk_!fWApjvTkZOaWHeCiTQ7L>vg=1HOEvFAOb_(JHB9bp|1SkDSeV9uQNRbaH*byKK zVDLwgc=O9Uc&5-GBYIdQ3lNOb<(ObHdvM7JV-HLQ^JyL_F}EiOw&CaER&Gp`<|h=_o_ygxc|vB@7cI7?WZF zIEKcHZ6FYZUDt;Y7Mz(T1HCgp5}`AT3h>owXiM^*q$Wt0JP^+!oa@t@nTEzU{Mnrg zh3T$tmLVGm00BVVJN!Gwiv4u8;0}ZntT`Yqzx%szK+Gx%Db7`X#Xt_IR8(JhmT>s@Phw`UZnS?hWl7G z#asAaX52<|fP1b+JoGVpYcNXsA`pN=0DTigON`|Ww}=(Jv# zAL{q4E(|md7;&sH?Roh=$1^*AIu03#=-b0M=vXY<0}tgw4}qgb?wi;blFeug;dQW! zqgYp|csF-<28;K-33d%+Hqd-s>>o{sVD^o1t#l0M-YNDi7bb(RXf+KN)-7vZLq@Uq zEeGl5qZ#{Q91BSIm}MA$R=DTEUu@jyyX{zT z;}7r2KqJV+!Qr*>v~`VXUzFF@WyPZ1iv;oH!!Oy-R31kTqkgT6cLs;B9PFaL&2Yw$e4` zZ$+(6=B92~i$X2A_cs8b!bWMzmsD%A zd}GjWaS9IE{tFg_PaI2y$0OuxrF(-!{&Tg4OTOrQe}yc(e&zEp88R{m05Gt9cJ??y z|0~HN-guj2Zc?r|qO^;4A3aZMd;$=JCPSZS2m}D#*I_e9o(hY=(S@Xw#P}HTZ@-_K-$yj#B7M&y&pYOb{Rd5ip}`U(eKGbDq<@r(X>zJE+ZYO<6B+Yi@69 zX?d9`_D_B>yx(9gFXMNK_nd2V68r!VAOJ?Mr*?)?HZau_^;TgLxuXB1T;t}JF#Zy# zGbCn6UT-6DC97jieI~mR)uR$kx7OX@I=8pI4m%o{7$hFbH?@o646p8QD2a-AA%F4_ z;kByainI|3k80`@v7Z=?3$vkmUJW(F?wy?XTQu9JP=vg10+Qe%2m^j+m3VQUfBON> z^n`H$rxkl{(=U zl2Sb}H_Q3>O?k+VANud2?IG;ai4xhl=kTYDBP)N+90cBWi1qkbUnT}(i(8cP6@IsC z7g23yH+5%nPIqvLzt7SkpC#t)&24()Pp}`7GUJ|ixu#L|d^7*v0-pVuHRFB8qx4Qd zgdh-rKKrIBd=_bauD>(-M)sYgo&#NL0uMU>MycJjAVS_S4sovh()`M zL@HSRhMBwizXggOU#TYOF3atV^quFg98Z>TYXo_dgCTBQLo1R@%4nK&5|Y^F)!P1i zYb$LSrV1<_k&`1CftT6u)x5L`hL0oW$H=hdgJp6m1xyx8a#GxDTt9~n!VrKu++P8? z4OtWbN2cmlxHfJWw?$DQ`oT8&;p6~77jOrcU#4dl5K?AR;bR5SsZ2PDR0A-H!p@WR zbe4a+nDJAS1po;R;rgqGTQPxaPB$k9VW#w{2~KSTecct5}v1?Uw>;3~q!gJwi-GiS1^1T_NboG|F5k1Bm_x zVbj0MZ$=DgZhZkvXVg1e2C?X_8Jn~V_72MIvb5u8I=#ASu>1v_YbTEE zgxI@lB)BgJtT{VFIvP}<|B3LH-R1|3Xtfw&__UTlM$HApX~iYMqxhA|Kz^l}H-qq}#>qp?=vl3krU*g+iSZn;IXdLvChv$s z2k+__-!0NzkH_n$16PrbLJ%N8fda>#e@BYII4I_}Fp_q@wd8XU&5zkr4Sb zkx)LjmXWLu*j4)>+((M&>HRxIMNL>Z6-O+5Q$_bFy77ox-V~iO?=NRFPy&O z!x&2EdC0yXx@vX*AfJWxU->UzI{WuN582&i_6PW^@zWZaNsCj3h7bS*w25nVf#8iS zIW#I8&qfo$ zBW@dBW5}QY2$Ahl2DCfMt9{#p?D1W{?5|(GIKv349_Dr$eh8GmHQS9@oR2aNHnZ2! zXKDY|@_fMJ1qu`bbp7H`pvRloAE(~6>(yrAjVQNjoxx&z*i|)VWxQO3S10OO=Kv4^ z01aegZp`X?3abY238cNk_CP=1U{j>D;k!0bMz}tT3U_E)2VD@iQO{$Z@-O`yN>zK)OhhvY!M5APhqlC@|)XRr6=iYHOfr^RxCXEz1LA zH>|1E_9y~3s`mySU&23Tqpy2HzQs{s?eCZLo%?QAGt4CHDMsyLdi6_Sz*LuXdm;Ht z^jqJQV{9*|=xn~xL7WIb{qfd+vs8%R$DNwtcmhKv)= z=%t!|rT15q*JUX1kiw=F$# z{lTPJUFhqDaR>lS%zywOJ*E479@1w#REJp1Xy4cGCpi8IqDph?ulgDtL0DR13Vc!a zxH?z#{o?F@>%KK;ZcNuatMyj-ij9iRZU@i#-{L5p*4VsLR^32^gc&Nni*ls-G7Q=5 z#xr%AzxBCsTk&J9_t`!|7M+gsG~wxPvkwXZx9~evGD!w{hn%uglFaJayz#XSCkA+A zTz{wBE$7#VXB?q5siTUzwQ{r!5FkJRnkUh_g|Zn3x8whN^IgR4oSm-GW4Ox`x79L2 z3UnAVy9&>FBL7K8h`p0VkLt*o#An}b^EOhoSlC{tl}Ttbs3)lDNh;>Dkv`FYfdBxR z59xNPg>p2#E&GLc)>B&B=dFDkz23Zgk$}Yuj#{?!bPi$IN;j08C1R5TKQXHQ*(ulL zQRBmZlqF6aJ7L2dr(s!c&5YDCssxjD9$!}%I*Vsx33%s5ibv&VrT-1qU!{os(TGHn z;)NXpb8}EZ016i%)0m;4!d=y>#=_=KzN28iPwMdBYeM#)CcQ$XYVnW~5z+(X#h;z6 z(8Z*ITtf|SlZ|uHf#WID(xs+YYQ+2>KgOdC@7v{&tBK`qkkZyk{azQlOyo&5+S?`D z+pn$ib3Nou#Etdb-(I?-^k*TqpI+kOYo_11`}?{a zXWXDsSu+xg=S^4@1^3I#0P*xwf9lV$c$~1(#~1BElh}x`D~$Py8hOQ6sS*BV*FW_t z!s_31Q&~n~>DjtY^8$Ef0`Hm{3%S5%qI6Uc0128T9?mLqdd-X#7`Ecjn6rRiu#Qt6 znk|mhx?tRh-%Z-4E3Up-D9BU+yF4Nw*-sl3pP^E50^m=xq&QzAPZ-5JL!4YjHSzi7r3Z~YW-5LGpfZsA>)7YI--*IT)^g$8Y=YQ?AOfAu4?Q9dEM|qmiv2!;9+7-yuEN)%a+$Ik z20=M>1VRu2U7IYlCq7NqS-re!_N*(ZRs3nqEi18sH(ED(tis99$}t8!%@jfqGKfMD zkvUbQdzUfohffK`u0@E~%2|R>rg=*R*8WcqU;sb>Uuv~0VzJzrQ<$N&(+HSH{i*^J z{#)3B1k-oC%6I8@ZIK8-ApkDCHxKoh4VJ$_zYi zhqTmbYdubTSFx~!SA%U-TEYJeGQrqcUuN=b{YDUn8z2u!jO4@YTPk*!_m0+S z?*RYCN($V|j2_Mk9863#iAC~jEsB@UT7TboiMi>qmA4^&Q?I}$p9N1?>2E&m112`M zNu?nPvvP6{z`C;Z(qHq`g?_zJQ5xOaE+Gg$S?+!D`9Ujn>Bq^==h2xBQ0%R<4j6_( zMLnqVODzU!$zOPcMUPMEpPvM(m~-}1p=!q3xcVdH<3+SV*x47(B%)c>VS%Aa_-R{k zm;eF-9?cDb5mK2Zjo}%lF8g>uYj201nXE$?iARwD0IR%R@Xq~Ud7GS_0ssKA@XxZf z&urP0%%u2q$jQJTSpHN108{mIHVa@&I{P`ftWEc)2$-T{>2Xuv{(R5&Y}Os-LJOao z=gs`Cba78Rr_0otOhtovi$ITJQ=r zRa=tq&-h=Fd?9l4Dz^tSvZ%DH-sS_%1DcwFNAPk!Ljg4tj8DMLP~lsVA3JGOfM#U+*$-Zw#Fb5v;H z5P%L%&%7yYx1?5NNMB{G`JbPL_BJ)(N278+wo`st=dE*ky3=M`CI3zZDfJ)Bstif@ zAQW*MytY*9<%E(FDLck{6jk{!zUx`PZSuV0o3wQNh~N9n_=1ukYYzjyCk5xgQ8(!3 zJP;s2R79YDFT!X{4rh){UmD8<00A2N+~EHgf0>i}Pqei=s#X`6YB|L(b|YzAciw8} zrL!=)RO^>%9{~vD^KVhshwPT$B85*AF zT&$TN_Cf>*0#fDgj(ASfeb=e-KDH6NB{68Pr&e#tb&#K3zyLtB8nIh(ZAf0rDRLEgqQ%4p`i)`f^(2B7u$CjtT{R(yyoY-bjkT zLI+OB-MOrocHj|6bz;Hg*B)!&I8ECKykRlsZXfq(G zJg$`YnpvmX@wlQ$%}i`)-8afG`}>Cp3Q)g)0?hpT5dC)fAPBk7)Ihhw8|u|kF!@yw zOEooZpACE)_yWl@4G%uF#5!9L5GkXLd>oC~xw{uk)vrle5w#Rk*`2+E24J(Hyo}dn zO}^jRq}j(x*=OBG-y;Gm`H2r=j>Ukw4Hri#E&_>bD+R)Xi_1=dhE$1B*^&^Vn%A^> zqw>A;zWcN2$X_FM^08GbkNJk2LuN}ngPYCyyo?z{Ju|(UrGNksW9P`5k2^&;jGB2x z|HOZ}?zOFFrt&@$!xfTNn(OfL7_Cq@OQ%##4t+fF6BeUMX}lG6Aeq+;?8g7j9|BWw~% zI0_PnSo@UxXkp=OGi;HV?LyCokoOG}WpwncL)pPnNUG_=h@#?HlNQyp9bqj20Ht#= zCK^sd<7kMLPw99gf#Q5opybNq>Ny^hh0EhQeb-&{>+PRI!a_^Ve-lBB%k3m~_gFWN z%JFwn!#)dJAHl2RUE}jw{LIbq8Hr~Z&i|Yod$FW;>|Yx>_O%a|y+&&J1{0)FpL%94 zRoK$nGb6Qxdk?FATRo5ZkM7I}*8tI-(?#Di3iqzN^Qk1Jy#~5$1=|hfP~gxeOAf>G z4^QvH?lG`v8K!5h#Aul&EDtMq%;s)hW=^g{uGVUQI!H2;;qSX^rq{#GX@Evk!q{I_ zk+DEx=kJnj9&GMNjRgoWaJ7rPWXxj@a(Emw*(;w zT!gudaV9T*6@q@+f6{)5P9U~y^NCKHjY!65j#Y|u`CXAGZX|AZyu+48yBmhl2dgUo zj;w3eX=&6Dt+mnN3vhliHn~~4v`ILs>6~Z~7~c2|B2~-b2tpHNKVB;~{ZssD8C`M| ziPota$BYR9zm+M4&m(~ZDAA&h&E=Nmwix)Cglq3=Z)RyWWOY0v%gN%?XuVazwV5yM z>TI9|=RaymMlX&5`I-TQ?zgaS+ zRJby~l54}kk}JRfgSH*!dzW+96x>VjWc2bo$zsv8D>b9X9`6jmaCTj*wohH4OvH$E zpLC(yWoO~3=K67F8{g2de^$|V`tytp3g;uD&CgtOPL!>##-Xw1t!{eNE!J5ee2%L^d0dX!Y5U6p>p!d>)=k&yVW~n-q)T3 zhV7oq$;zk~5FH@Mp<0v@hKAJZRbrMbTNk9V$eyv|rEv`rdwrkt92o0UouxN1??2J@u2qKqfBuDmb1W?} z5wZuU<_>-@?ouIpA<{$R<>zrVJ{xeoJl!XtLJ$Z*6SAskYPn8#9uj@6!@U|143P)` zM5lxx0b)Q$`+`NJS0W4WBclv&ex!+0dWrnWCk&NDLQaPtP zrZ8?fvy8sv?&fJ7CKOlkk0iHvo~S?p;PBDJ-}@Ad^GgRdDq}b&SP8uS_oh23?Ni^-WXUlO|O+6<2eS66O1Ib!Mzgm~&D0W=;|j%Vc}603x+-yg)ZBnoj6p3>qh&6#jjVD*w&fE zFnt#YZ#49;YPR>qrSx=^FP#Q!tW#XOS1MbG04j%OmW_aqken$e_g_cAFG5n+URDxO zMwZ6Qvj6vWW`HG4=J!1_1Zk)CtK&^?AG3*;(NTK(e!wQ<$Lj z&WfRsZRipg*3&Y#*82U=eJ&X&wFR2)YRY2nbH!Nx7Cv8IJbuDJGoB}HKLd)$tFJso zyJg?!QFE8pd)kQ;sngk(b3YxiMFvi!KC-^rNnuoo`k_Ixy^xySR!x)v9Nyn(#YDnY z58iUwxJedHoQGq2ipQz*qRQ0uG>ax18jX1{lcHhA5`O*?s?W?CS_3M<~`{N zic{(5m58@{SK7H~SFOz7OZiw{12+5061P9jp;7dV3)e}a*erUn@BFp46zPnA`&(aW zOIY(>UX4{b9HJdVD`le2yL>f#A8W^#_U8t$@qo2&&wU+%DSOcNrXa47uGSpGMrhx*^r)<^Y@HNj z(b%F{S3TqR&!C^ne^s41%g3_DI!nte0!?}B!o_-5hNN|WUpM6pApi=)ee|KKhEH-0 zEEN73OShQ+bpmHy>LJj|s0_i?hqp55{T2#Ye-oAiT*LG$sOCrcJD#fmfdBxP$T+o6 z8QI~Pn78X+?=0ogMjqzKVUhOYAG$w%(0yLp2ep55n1Pe1@5 z2k&xpu?43xrErBA$9>}f*0_#I-hQ&@7p}kBY#1}>Q^>gOD(Gb&hR_AcgvS3!&Aj#u zg_O2rWlv?*#OpHchl%;4E8K|`R`6=YvrN8U0d0DiOGZ;2Tc1m>ePTbw%(IS918vD- z>^8-hr0owB00VqqS?e}a(BiQqWUg`J>{HsOR^*uZV3Lc-00Ge@3)*9J>g$fAbLzO` zt(&7QwukmOl@hYXh(ZUM&5zx8(~!IG?;8NXJouYL(a8J^5pNmizt`!a5P(7evpt65i89w^QrLQVNo#n7VA3drkHQT9$v$6S2gu6Ska#RPu+8Lns)x_X6YJO zGD@B)TDht)-HZ8AdnODPc72(Ds(@ z{2YD+M+=C@6tcMGVR~dAReR%-H(S9?Xc6pR|INvUt-{+eAtTW)`>V?J;&lOMFr^CF zn1lc%LTN_IyLcuyV7bY02pR{qHFYhlSK<6Z&i|?Z`PSij6oS*wz{;wQ-DY}+Bm)xG zQ?YQVNY@(AWIYGupKw$6YC~zySwv72tVNYvtMuRESfbGsTK{yR4-vZ+BB^M?3DF%N z!bop|*HnDMmy3wFZkI>2|Ln(aQJGrFGck-d^-3`+IJf8ro#xCw!WwkZPRgjyi-{52 zWYx9i*0k_w88#P&Kb;P^;mnQ&${vGU-BP^^w)p_MqwNfa_n-Yx@ybcnuZb#ssT4eN z|3~I<6$JONNqx}>08iEZCJr-QNHNYP{{)O)tp;T`&V0=LKmiEl%TZ$V#~bh`F!5kR zbOWsulEt>c_^iI!XA7s}fsS|8Um^%&j@%5+`9Fvq~nV{k`~Yve&o9~t$1X)Cbm_+Ng!+syzNc0RH#-O1nJ zwIZ%yY&8NaB@{vsgs0gMgdt`Uv)cc<$Y;EzfB+KG(+aGieon8rp|T+iLF8JAUXq4x zwDJENxsoIc@gT*Q@EPs-zN)=FK}=*x!gv=Y@@VmByTs}Um0FmP^iGhIX&Q>FiIykN zf7DP<8-kQ${SuzaAX12!tIi^31sa~1&w5Pj8 zL;PN~zR_cF`?*3Z1UAa2$&5DE6?B;?=SQd);E=BAprPdq8FX!vrYwFUI0!W@0-Tt9pEh zH|f2x^ih*GzfFn<(i!-a2Pe+Gmx(RgFLAi@0I)z$zwL)D6L)$Mu0ScpdQX3Pf*pfU zcz~b}Ko9~JC|%e}xSyB(^T{?J#F6_2r}Pp=|!#E(8q^fg;lzHy(^! z8s+o8yp~O>+h8^~!=!F^#p|FK85eeam$hNFXxTH2_+eVQK@2!H9?otB zHopT{7Q5z8Gasd*Ou9q|3d}>rxxWeY%smEsv_f2qSlL5k8Rkb5FRS1|{2Ej+*tlbO zE2I)jUFt{%oqS?*;~weeNZ z=tJ$0;(Z2Too={n=xU|>$p04^^zUQ48`&Gy8(@9X^r=qx$pxi!(G4@pR#Jqw(TETL zdw-DHj)}&`FU|$cQe1vNN$w&be1stgUOPROBjMjP4+n`1+CB0<4E9jSr?=Z9|9d)K zik)}HWAYypqr{n5jYpaWvTfLZ41eR;a>W<9{Qv3JaN+TnMS-^< znD9hXMw`~ga~gwr-qJ8ltqKzt<$*zQ0IvZqr>1O*@xAA3MZbnU-OX;hXF-67NLKeX z?{nfFwOk)S<7EGs`JQE*wior-d!`hZ*qb{s+~|2IjV0|Bq-#rsI-iZy%5q-scJpx1 zn+8kWYP6>>F=Kt9;)N{1h%fMbX`Ro#*r_CBD%I@W`fq*KH6K4h2g&NO#{W8@f3sOt{ zbH-k&zXw$!KSIQ4aTH4w87s-}N>`n6+#B{-|Af-42ryF&o4gH$%8b5 ze#g+>T(dEL(B|BRII|G~ObSMqS`D3k5=uj~#0!;pQPAhby~bO4YJM-;D1;!PI-JX{ z^ZbTnYIEWU3T!HJ5~w#j-c#xzG(f=Y%q{PG+&#IT35C9uZrJzu$-3+DfEm8Hh^|SjQ73wOBEW{tPB6m$=WQA|g zJA#;wt3Md4C*7er{MtWhv*7&UxQKH=v0fR&#RfX0&F$rU#|1!;EYGzV8!~q3N#5$> zYZ`4Y6+oQRw)0yA3+?-I%&*mveAjs6b&yzl3&xXhR=TII19q>%-1JC+48LL@iNbW$MpZgczNQt5~K zi4#SYv}P@wfm4?zafO5G7?%NzVgjZH48oAUT$i%JNIJmyPQL4Pe~e<=rCGWvFI zbcA>B1@AQPwdnbjrSMi#c2BHv5GRsu4qn}2&3kh%vV5DVH3TQ_)M0}OvTc?nCYzG_ z_#(Xy0+9z8#7D()d3E{anPrYD{(%H*&*nn*zeqpmQ$R>@$J?t!Vvt+lh7%^OU$}RDM z3F&o%=O*f;CcI(Wq}N!mhyVoP_IuoUdR5^tSf@rdn&8+{8|{w(3gNiPalsu z$3Qu4Rfc-3ErxOHH&ML{ACBX`ymPE<{(v<6`Ph)hNH0MrW-nal)Z8p|GJtx9t*4S; zhBbgil>NS!p(dnoX4r6Eo80)vAt_>!xd!N;a+weSfCvC1Dte_;Cy!6ca_W)K#+OgW zo490$4l)pE*B9)KBg^Odb_!JnS~*3kE&aB0MiYlqfKs=4P~n`dN@pYp4CB%zY^`>& z2mnJ7JQI=AZakzgR(r4B$Ibc2olqFxo^yhb=Gn-3>pi7~oa(cNCVN*gWRAjcLJ%HG zUrQ2uuhFD})EeeH(j<}5@)(|)hgB@mttY}V7uofj3jl+(Xq?XP;>nULt{s717N)eL3Y`H9_og_tKk}h0*TIy8islb#+wy3=EDXBUy!dqE}8#E~4k!L`H7N;QSs@45bAs=r|IM49p`<{A-(K1!jny_92;b_=L@$`_*%n;*LJ$Z*2zeDo zV98##^CVAmN^!_ss)qR%&VR)+-+##RzJ33!x?QmdKnAR<7t%k&C zg7u87V-EFBG_dmRQv!n6+>2nE&_r|dhUSFZ=uI*Ii?LLU&rP(S8T}Uw5S3l406#Zf zEnynhVMB7E%+IqM0%$d^<5{S}P8wl4E-SWTy6C68yJW4(xyWQM#v7F0@E~1L&bbg$iXZ zBZk4Ll$KYAuIt3qo%VQ)KaR#JMb@#rG1gOJcu#Z{QF8vmMrclS72uuscY)P7vm#Cl zxj<=_dxf_DG&LhFJS|m7Qy#9=Mz?*OF@co3ChVn&8~K>>X5ad(FZVxTIW*iSmCnK5 zqEHYcA{{+e(cpX&J>GHqdGsZw?lP(g6q~^aw%_ ziGJE1_IZzr7nK?AoCrR4Rs*)Eq0J)Ov|;hzUWX{$L=h_emCLs6Pf59@RlT(;RTs8- zb+n-OI`(g9&;bB9alFUVs9e576aSo2m3^3gKGQ+ZNktF*>2vew-0UD5Km8Z@1Rw!u zsu2CQScCuuE*&TYd7Dz_XHwpVV)RnYIauj0I|+|bqZDJhr0%korXzfDHV!G~!B4^` zGVA1|(G>Z{Vi}yk%AneM6xD+pjUrCB@rfjlz*4gigdto__?ihtYHBBVxsj#Z^W>qL zM#z5o&{<%uTrWkZ$CJCOC(Cd;rC7hq3hTns?$x7Vi1NDEsG!Pq@@(kOsh2n_h7S)i z)xLG7vj6*?rljoVV{=WUt!x(v*%AI2-~8*KX8PsiuDe@b%-tmL=wcU)bcX-|00bEc zo!rw9fE)OBxQF#d6`t?8XG23HZK}^?1pz#wu^eAFil#>lj13Kxx7g4$n*79 z9Y!%kg&WQan26 zrwI_ha#HgWL#&uW6sU#$M+|humZ%OHDu99`XZ<&xems+_W!e~QQRVoT}j_#@O583Uhpi8H-Sz&bsuQ!;dSY-v&x*tb2vkd5ed5F-t!HL zv0finssh1Zef&{ae4rr}EJP#pE15>G4hQZBN85H3;6U#$EZqTUQ>rGQWiY*EfPUAX zbVBX3;TVB@=s1owqU#ZaEF1*lZp*mOTW0^nfOJ_e7#sbAYSOk`?;?}1mlGtrF86?w zlwuv$Lukavv2s=2Be>QaV7HqRt_FIDni2v`;JWd<@M7U1?jDw;lP;dPMjJ&Y_djh_ zywaSpc)w13;RQMW&FzK#d6}vU`jqet+5rH7AdmbU5*GzK>yDM85P(7ek8I%`5p}6` zZtt)4>#>+MbY0iiIyj^+Y0rw?ULkwF9W1j~{z+)?EpriUTO?mzi z#RZueft?NHJYbvY^`JraBD^6n#)g_4gmHqTj%!PUm)VE6`q#|&wd9buPC*}n@Q|#E zu)m&JO2Llp_Z8LIocNCAmWid?+7hF*ggfVmc}4j?ssG`b8w)H3#HlxcgaO_UY?mfe z#e=tJtJNrhh8n_O0T4ri_q7|WY({}sU6{iW@G7Kb9Mgl2C{Um_s`EEf#^e{iLpkE%K--IKJNyNrBZ1Un;ttAXn}c*Gdtly?8`Lep@4gvkKe~4(JK@N4 z6ws~rH52=0zMtXm0f;nhqlzY7$Uo(au#nCfh{V}!%lb$sn07TdxzvulaE{V$tBAv)E#nFhW7R#6dE&b<_Hi9*z5=SYgB7-e%=zNAQPN zRJD~W{+W!r5CAyiEl;#7w)WpL_mJf4`uEv=qLIV(3$|*hn={}b^J}vW@1+oDi0x6# zo@c}@4)`7u*Q8pSjb-Y^NL3&kg~lX9p24}d=@MxS(HbJ1g(<*50MKg~U5YRNJBKgV zEtQ$*;_yNcI>odwMll_Z&6sm}^PwYS?|t2Cp{oY8`M)Hh5QHY*X{x{>j+cLg1 zXaq(07L||y?yLMSgK?c}=Pi)~bKxx*9jW06LKA5(T?cNx@uS0*yx&XuWJWGp2Q$d( z@goIc9dv2O0LH6J%90pqC65EBXNIGX-pteB<7wsw`5qF&&wIAd8DM~<2vCtnDn4t+ zXeBoH{}b>(4-kYAD18R?Fyu^)JT?YCWG>j1s@YLDxOONzvyGGlE@&o^X!M%uNmKoX zx{>chXra6RdylVe^*;LGE&F75lNt!Mot_-8OXi9{M4;gfsM95{y{f(S?ddxyL*W@U zR|Rwoxoh#946g?VVmGyJyUVB`01IbuJh}+9a8p!nCaR!VtUwA%rno&yrm(2yBa}06 z&)~ztc)ztMbN})1{#dhAY~cU^Wj^7jfm;nHx5PM`;x_b2CF6;F-)8?{k4=w9RbrpK z`&qc(_Ga7PojoxV!*bh-00E^Q8#Vk%zUZ`5n!-_B6W1B6_?DFyt$%DOLkTp8+P(%o z6xS2=(a+DNzY8@#(wW@<@H#nlNkyL-sr|UUKMR6oJ~(jBk++E z9MQXE)wxcZ1^el|8A1!4#yeM}bzlFj7S_CKVn^+z$FeaREV4z#^@Y7|){Sne`=)0u z_8m$cOw z<49P1zjq|fCwfRPuV;~#Iv4~X1Yaln@t}TUQ1T!EI@7mO@<(+! zDlf7uKN5c&yrN;e0uTU?`Z#gU#>{3jvVBymiOn~@jYP}~fgwm6@$-sAHxtGs+u=C*jN37GjJO9sSprSSbM znoP2JW(&p6cl@4Q@DPA2A)&9Hea-w42teUjoEn-g|0dZ?;)(v>s>$Dkx&PbLFd@A4 zwj_ALL-<+MBjLs=8lz=TGQ1TeTSU13;h|;wh9Mr59YrR|9KMnzRsL@`m}8MW@#@@P zh|GTYUHKvCRv!mujdcuCfNr>;W(+k&-1@W?j1hb>8Jgt%X=rT{lq+~IFFbWRZhgga z39^yiob;q&k0|4Fc9k9t3atboL<((|gm>;}zI{In5XvR`qcrzNny`e3ghOYcm~a3B z1k>1LjKnOZ$+zWM3aq$~UUTwv!@`Xti|Ptc;+nSeiYb1%KHNr*TbnaeYF^j?V@Xar zD18l&^X4_R?^?k{0M;RcR_6C&HYx|+n!n@bz+1ztC6?>z!H^PMX)<8HmeNIedf}l# z7Gd}k+HDvOg?TZ3wf?$ix6KB4IT{WP%^3V^sc`?cog#aceIcK};Y=0krx#jHe$_zV zk|-05G{)A#F;gd>o`m7LvC#8Q2tp98C_7nL@MugCRMx5vlsMg%HUDgJP8*?L8?@HX zQTmBpmvvEr?Nc`$F^l02_CZa@k!EQ^-sJU~!^kFV3ZrhD`Nw+OggNJ8gz0@bs1kbH zon5i|#J-2FBb`mMMwzDbxxREXyS#$;x4Dqa`v+3>ADpR2UIq4Wb# z>)X(P01?R!g!}YQm7dxTSDsBi&M;a#7ns3~Ed^G7YLG0Z^G>C;s;peOI{o*QSf*-( zApnE`!%;4WgAS{P;;MX9eI15Bkg59jDtmyiYcM?H70JBArE=~e2m~MpRPtj+xU$$4 zMAaq&1o=L8>bHT`SsQZD_lN&<_kdbTxaE#2Xw}a;swG#rkmA@t?SF48ey_qw`58k+VLh z#6X>wthD0TIoNhwqisKWg${=gKAj5(C32UvzBjHxBZyn!x@c znUm8Ru(vD85Ssdh+2orEdEH<)0MU4DOJmlG000|ABJPp5p*8P%!<`5Te#J86d;8Xv zKKk_n$B#{W1>x1l-$PnyQO1K1tZz`}gyX+-VLJwI5j_j3?2BEzVm2gh z=~W>N5{TD4$k9^ZAX#s9tyIV3T-;a0YCmL&pYF_m)jZ|}+MawUz3U;Bqs})rYS)zu z1TFxKaxLD#QQ18Z<%$3RlBzSdL(r-FhuO4}^pk-_4b?7~2WKoW`Ar%wo~UI$a4C-Z z4M2VKbTN7pPDO2$g2P@w7jgaI+dR#=OA5H z3PTS9z|D^lNPQ}yN7zMyIABH95-TymvHMN;dcAYVYS|zF0s~CrAe*exJIcXq1~#XL z7nv8w4LT$`2Z5j@u^mj~emGdcP!iwYEQ^VCf)~6EXGvP0P6<8u!s2<6;tGTTc)dJk zr)~@q&ce#YG3uF!Rg>=$K66;a9vz!6jlTBH~KZz@wMl$aUV-RZCqk$|13 z%%%Jsid1`*j453lY~QEyF}lSJ02^NoKi?b>RDXmDfqI+qemGbNeMBk_4Tmu#47j72 z=d%keR~=8aUQ_BgwNXR#L3EKOh^%3c}_ z(SJWl4biPtszI`!8VwV-S-G2gDErqRpTKUx?Op03Nscyp(~xFGfwZJ+jHE)b>(czn zak85s(PX+Ub2$a{OZdnAKNMV;uRlu!nCZ-^`qnY`1<-4dgdqiul~LndcMn!MUvyz# zTw%KWa5E29Ka_-xQBCLm^kS%8!pg>+aAAb@dbh*%ks!)25~@5*RH3p`ohsIcj}iKf zGs?M-ga!jat=}CTAjRxAP8>-%{x5qsn3J#}2tsOZbMT^*_$HFskyMb3VQMA4eEH$N z!Sn&cV32sxp#otgc;eBQVVLijbLvS||+eJe0F(~YD{E|%nyNR0C)2PN{a z72eJ;uc9$FyUPIpfDY?(#-TsX`D+bYx*#AB1rlGmQAv)xkKHv{6TR*}elS_{h@ae{ zyKBj2{nfsc9@kBE(m|0x5tXc9&IkYy08;e9BbFwoL#HsdM?-7O=hgXIjHEkPD9mNW z=Af8*Z|A;zr;ia2hXX*aL(H}x=j>3CVmU$9R3MFjLm+|*U zaK6dp>E&2-6I1OxYa_Y?|5*Y63pbdl9z>Zk>TfO)aw{n9D7)p5Nz(3BsY)*EN~`4S=`>mzfkgz3dRqi(Tc!*=SrB;)d=2nLI=%YKI0`T((zTdB}1(AfXRCKMZ4I;r6A)mPZj(`Z8@{0@d?Skc@@8HMU2}gj#ytAJgi-jUzX7caD=~PfrB<;hQ zvR}(-r>h^Fo+>e_J2iR8CALVP)uxZ7KvS?Vwu@|)TBy&K zb7;3NTPk)!b4qu6&D0vx=_ixFUNvW>7Dl(G^u{i4?dF%5cYc_*bTg^&HbtxEFO$AC znA{Q-%tQB{lSAXP#$rB3Y^@H#biJ7Mc!%Uw&Yrzntv%$g3a@_&cd3AJB~#Z>`?Ol% z+eRi=gmp~(fFPyWOO#UO!CFA&eA)H5qMVVP^G%yhBc9kv+(1ZJ^gJt2uWL?3AI8-f&G^kj5#*k)ty?WuhYi2m{N(XU47?|J#JrF7L^gE?=8b0BFEdFXkOF@5xPQ*2^bv+|Qct{0I>_M^1p z8)W+EQ~R8^rQ0hE=Pm`Qc!z$ELbBih1q%AQq10h*@~K(A1KQ{1+2S|m`hFGp@X_UV z3>gKpg;CbGitG%MFu`l%t)wPmNsRf)Fjo=ohmp)vx_Ud~>qBEq65__JHUnfOTmLsp zIx!TaGh*oX>uyNs6Y7fS)mk+OIA~yxGgUvYa}b0A5C+rs2JaReAIZ`awk;R@zc?)g z?pRXzW$~xb8Ty3S**vRE=FMnU{d?fNC{Hxj54|ig*Rdv9=>tcIMWoaFo9%I7sdS(K z7L&crysm-ui~Tsk^2h447Ha?UIwO6|miWdO-Fj~{AAQ8~jJ|sJ-fE4`Rg&n_e@E6H z72CxC1mlj_JWpU`O!!%xx;*+d9BD!m=gJzjC&7$olE6zLkOTq%MHo8SLi4bh8kGp$ z0-`jNk&ZHpVmaHqX?JAWNUwc=!~dS>>`h~7D>_n`G@yenmnne zEilX0#N6Gk%7_AYOINNrSsQQw5goTSbb3Ac&nR|VY1_=@(Ap4+*4@hJGTTrD0y%!$ z%_GAVg^R0Bgda;@G94QBQj$sp<)?C|!cquBHPv7G`7!3StKR=>D~FM2T;|J|*>79? z_?>Xjn!uv1X|pF~qgK50GmSqF#fz_5r0o9_t19TMghVXjCKDfa)@z$y4!Sd&7N7cC zo5tehggLzK0xeUO_?Q3$95#;Qb1mCc93fMBOztPw2CRk72VHKTNYW3(Tv+c>WamYB zFhQ4!`bVtsxtr_(2mzN@e)ePMJxpsKib8`I>g3`1NQam66T9u(y4bFQC^alWppT|* zApJFSI(8xP7#8=TW6Sqb005CGp6y*T-iaTYV2H395voomk|5Q>gf=KN?iHe8S=GAivDq_pO9aJ_ zWnhMTGXMAWv_Z$pRqrxvqUa+RyJKXl5*YEdc3vr#^@)0w_%NS2Y8qW8HViy6W^{be zfpT6}jL{v%IfDr5g)g?=K_o#q4#MYb_@WR10t<>bK!E@Q);6Jw6YOb){0_%(_r4`T zi$%*rifP^Yj|D;8w*hVQc@jj*7wJsh1L{9oFu4ok##}CG#H!y(AOhZjQv9U=DDS_3 zAOZjszFKy3p zea5k5QDwc;u7}9CG|B&2OW~hfaD;tDm*h5fPfw_KFIw232BVRqdVt!{&UeucC1;#$IR z&w;(o;L-EffQ~e@4bPlH5QLb=Oi?ghaG^+A=57y^>a4gqo|9W^AMdQty&u+LF>mP= zo27)W(lH{=qLcM=c(Ug}`(ELK;OKG@y029IMMIDO*tMPjF{?Fsdz@eY7uoGig^2#j|E9UYy!TkB{RE z%6OZiXk2mq3DbN~Gp0B7I{106HH(YWUk?%(M#+DCiY9Zi^47zljklSc44wKwZTXhv ztKF<-1e|Y^sMAsUwJh=wGEXVxnl3((S|RV5IQEl0)~CN{?;fufGv1KZGU$}jGHgN+ zh0bJVYl~Si*Ng5yPPTt>&3G1}u$0%Neu>%c&zLY)a%j0HC;N;wmFbMu=wZvDcKfR{ zd)iGs$gCNlLTKA6Iq}{cBNZa+VRC;LVqLO+%+?8r8fh-nFL!@*a@ua^uVUAJE10oQ zy`Z9U#!8%f9h8g4AqYa%D5v5bXy)-ld+=huiaDw6#l7$Lssh~m+c$kJJJK^mrKiYt zNM}>lMUr_R$YcNl3<^h;NAi-Q4>P9nuE6mdj8Z;|Bg?s`i!T1w+me(2MR$Xk=9%84 zq&=C;DRL@YK3vEgb$~Z%^1xtp-N<>!wNx2?RlZ;!%8k&4P7Jf8LAM=?l|m`t5C{Xd z;?NWk3AGYj!J!gBEkp}bT6{`4kNhDB1MYpbyisS+Tr8L%xd0FWcQs}bu!%T=8Ij}r z*fIWj<@7MWnd$@DtqMDIsuyD=p-fIb4Zfy{NrGT-PJJd)i#tbbX@Qk%SXr5=*?pN+ z`tq50HGxA4=kDTCd*|n39`l=Cq&Obj%GXMqAwZHrO*$PfZylxC~g|rzW2Fpsq7hvu(-wgB@t-Me@@=l?}wBe#D%-Nk;% zzt={4Xmoq2`G);?&{?7JBjZU`v9~X|a;_9J<%}S}X~V0Cp((?z4A$xI?DEoknfj%r zOUxPA$~Y^pm0ZW9mX}!kxDe{8DGb9q9B`~R`8)b6?0u9Sh#<}%X-242caHPg)r-kX zUN4X;jr6~Cl}fsk-?0b)T4&1KZG{GZvImv&2;)}b2Q#4oF%_69Mc1Z)?KWC6#$!4*pVmYYJg7ox68tBP z`9Ugeml+u( zxN*G2*qm5r*h29bA-{WH^co+U*~9E(Q50~10NmXLF)*Zm_o;A9j6YxBM@82``k^@{ zSWo<7F#Lc508WuqLd`}+DFKuXE3W5w*akU% zJikY=L4JP_taIF&fH18&C6y-K%hIbtHLB--YrVSzPSKD)hb(r@3|D-bCiW@H^vZtC zAKrGZ60)Xg$~5t{aQa(TsT_%#YLEKm#T(7w(+jEVhmmX=i;Rq}$1D|ot>M?44g1bZ z*Vo7?&)acV!!m8v&loiwAzFc1OQ)wV4B&NVK}=Sm%oQP7!I>*`fbH-HfYCIP^&_ z&Dd{|Yr|XOws$C@KmZ~ixx}Fvy_yzm8uolBM()FkuRzmu%i+A{`kBebYmY5glHuD^Ry)mU?BG(Z%dIAOv0_NA z_7lPw@Be)sK6)?H`1J?A0uTdfc}OT^^2!b8qnuuVgaI+AyYYKZ!J3m&)m%3agdtis z@OB>wzoL#U4H20 zjOxuKF%ZwsBwL&s`7bIKsT^c7HLH#KoOq`R zr1%Dz>+ydnH^&?&#i7WAPTazpB#`#}@{>Qb>~R19zX}?dk=#d$C;kmNoWo>p*1|Mf zlm1SC zxCjIRMAA+9nTdPd9)9Yx><87D<-6Z3L@DHZlq-m>4haRl4GnAAsJH!8i|9b1Lxatm zz*eO_FZa@GCJ!~uo?WGjR1Xjv6|(#8!q0slV{qp!$95QXkU@NhitZxI|%)&PJ& zALeALe(2?G!>2=D)m5NE(Iv1Mr=Wm-Y+{!qyRt=O4dG)fCxYsjn}8$s>&_WYsI8Adr2cD^d?ge5)TOvb5r(d`&F0oGwyPZ zV>8FbaR6aaQJYg{`p{1QhdVN}TRN1x#JZ)(BF6Fx)Wvq?zo&DrNSyKqeg z{T|YA^A2Wty_Hg&!z^!bzg-gqX~$Ew=MVHeUa7>{hA7&Y?V3y$!yNlh>NSs^c~q{fdC6I0W}y6pxYnt z@teEXX~#^suC_`Ra-MthlCS!__Diafic=6@V{kaZ001Oy@pp-BV8ULq$*-<+$r==P z9fF0sGwni5PqRp=aY_Gwa%mM76yZtc+4g#x?}F+x%a!KrI*9p*FvSR5N&?o{M@Z`zsXLEAx3X8 z*{a)kga9H{{`UN!0099@TYXlf!j7v26c1MWN}&rFZTANT6>Rp7NC}^TX_KfCjvh;m z+OFM>nUH+D?`jNIoAfhQn&dWa8*!-N4Y|pEe%`oLlUaQ`n(cJ^Lm7Q2FSv9v5w$F^ z5pgBiiNFE@2nBnYyOM=lY3FKe^*BZlN30>{mQ8u`quJz|UZ2)wG1;`{jgc7tahbm2 z(J&Q#YUs-wB4Nam&;bB|H=cJ+nJDG9&+s|EJC6jN6s=kEqa<{yV}v!EDxtZC?V>&% zAa434NgFOpWa`DP7=(tq_Qwjr&8H>4LSTUc03bjBeo(h#BYtbp@wFVTM+aYn*yMMZ zuV)kbEpxzv|ApOS-kiLwl;ysO`M$Lp`m%LOsW~~$${bfJDWHNJq*UoDq041n;;Sl% zvZrlSs*6?HqS@7IB8Z%wqIEgb7NurYn&_%UkvW#FS6t|> zw^cDWWmZKoT%xKb9%C!EiwkF5n{i||P{hgI;1(Y^EVWMCH^U2k$3!;;5j zDItuaRMnq#FhJzJ#j?9#v43$dchCxk{w$sqKArrf%8&=R`t8>Y}psDE6TZd z;SFw(S=8XCJ`KrAf#!qyUv2x>lxvl?5ZN(?@dYMQ|6a$O9b%i+zH!vuM*>tNvykeN zJw_+MFH4Bo9Mr#X8SL7_q&nNw)^WS}<~6Kms@JYQ_U_z*h`c}Rbsz1ffa+Xir!mgx>W@>JqEI!d9neh|^Z9k?Dz1f_PKsbfr#5qYbu^^aV_hW`1Nj(;|~3=twod4YFRy8Zq5NZO*NBQd8Q<+U-@Xn z*(C(NjpuqjJ|rOX3ydTdB9i&4>+0F@u+Cn8YIR|x$N+#l88g`U@fpqtda2)WnF3HRATiMl$9;{gAOdO z7mJ#~v;qMDGoEqfw^1x_2JBDEAgDs>7frN6ghE7ep)ahIda9*xI~Gp%cuzM-WrcTn znN~}PbdrF7AiRgmH?RH;HzOy<#_SuKUG#7Eq4~a!t4d5S&mWxPg6l^=Il;EIC2V!q z>sR??zuKy}#8JA|)%yyNj6nJw@hJ?wsx#NG0JpWNX|7Z+1tf?+I{nf!{_kqG^=ff) z!n_m_vLrwo(+njuKNYCcUkxb&puerq&w|zW(B4%p_J+(T+Z#|^Gqa{z39Y$3S zwwn5Pjt5WU0evEKoc2in1{YwLe%N|iG^y?9mYP{U1fHkayu}1^f&B$C{Y6~o>h&<= zFs{|x^@HY0T5pQ=v+F^wct#IWI2*eev)zyLsi2F1tZHDHUY1hLehPHUbU%zPeBQmqv*M%;pI$u&ir+IoxW-u5eFX& zBt7DihVpD&s zN1p%%3}sCfLkImgQ#t*mxvi-=`?(nm_R?e6yI8vP#VEDD4tEbf0tX9h*aG%+sR$aQ zU!%ls1BR$zw6*nw#u(N}>P|uL>u48so)|PLg1&bHa)*_DcVs@VfA%rXlSwHm>%(A{ zS36EW;ACN*K<;x>Rm63GQtd+gI0PRZWrkNRH0G^(FlC=SuaBo_#c*a&6O-Z};G3i9 z3RoQ8QDcSgjuM*ds#cE*D(>8Pbm{APny=R$V=rnypUGz6@y4k7YZ)G&Sdo>Flwxb+ zW(tuvSf~fu$)t0!Y95kq3w!zk3eCZERwMd@g>)>vEAl?pd#5c~oagM74Mm%5m9+UJ zbKvp;Nz~LV@Zi|5QeN8V;NT4?NzX{dwWCE?uE1rjr7vyTq!SDQ0DwCyqcbn)O-3xDR?jJJ>(PBL zrfA$r5Ty0d)pk!Z&g${}HpvB2zXIk({|?b!FwR5zER4sFIJlhr6`2p5eA?-ZR*5V_ zK4o^Wax?~x85~YP0sy4A z$}roI_IBcF^9mAQv1uIQcal1y5P&p~bNQ2xp6M^=_75CGzFgZHlh;hw+FD&e^`SwM zq4BUrCXD6fwF_g2spjjiGZ!9_1EtziAzh|9)DF0---Sc@bgQel?{J< z!4f|`5=)|_i0E!X7O^)`P{gfA&1v*9V0(s^)?t< zY5e2UX(a@$boH89P~ctVLPb5fxbNYeoaiC_)T}pIF0HS+tw^o*2U_Q{|Mb4`b>soQ z>rM`-SNXPi!r$X|>DpiV6?<5St>4O`#$Ea6{r8Y4f3y00-F+MuN~@vPOGv*3c?v3{ zB(Ll!U-f!vq(RCHgXsR!F-H1z_UN!U^laTqjO0ypu@djG(z`AD7}!4g3r-ya+M?DY zLl-&r=2w~HFNG$n^TMdRs>k(jk}7X`c482KLIB-p-|(=dVSii;cqMVuSfVX&OM5^gB_uII%X!Exn_=LfS1z9gu?u->%`)^m%k8% z0h;Qc6m&_}R;^Hfm!asKxjHIljOg6$$C9V6j+CF7+9}&^ocSY>YNPw1kTP1==H_O- z%W6ZO-1f5_T;{D`3ru9l9n|Ej@T1}CoSAW@xbifDUD2R&dDWHoFm^?PD2?JRaRWfZ zF&Y3M4X0D)gBopS(DTDT2tokfPY-OlI$F8D|ED=o0lEcRN{O?b+iWxA9rIit{wHXn z^a{hF?_Kd!r%+S2889njsrc>OEcYE(9D)pSzOG#puX&}=u?(|cH3f4&GM~n)j`zA( z_~#M#7^f@FTS{hq3R-GttNjRzU*~E#=Edh4fi;rAglw`m8E?dFQCDW-g|)9nlHI`X zam0tqXNH2uLB)FsambPI_^wms;g{?PH=ekU&@Z_4@Hhwu8*zr0?V<=m0KkH*h%;IM z5CwuZG$!Ecwk2D1MuD)WR2JFsJSd`|M|`#HFE_J`5^v6DH;$ZDU_K!5-Z>~Tp=QOy*e>2IXsd;Apkg;004nJ z+>SYTsC5%a0DvGPIZenEYo+<=*nS0m9gnhpB5^dkm?qL^$WutEatJ~J2mp7M<&N=3 z##3_BV@`9;_cb_5yB;x}A!jeI<=^dJL6LmYjx`@r3EFKs zM@2+unYoyIp69txuu!0yld;qoBO?^Sa=VPQHLcg`4sF^9nUCi+63M7H_2WnOpW~f^7m;Od2}_pAQc`vBe`KI#s(qREd1!f44BvjmH~#L{>CU3< zv^%>)eQvJ2iWvVYUp$g&NCu@W8cIglZB-XD`2YYmN9e^Q7L=mZpF`$&%V~fC`+GH5 z6BB@>I!&tnL0yPK0SE))XRWX5wuNakKVJB=o2D4%Mf7fU6WA$S0t5&E3!<3J%_2219mDk! zyCSfidmX1o(SkI|a?#4TB=a2WqN{kajv~wHy(~2^MhblSp>JsYbiTqCpg;g4ABQD( z&A^UtNA(v7AOPN$tchCcOfHTel*0EKAOJvYFGFu!Ywfq;7RvCtaYD2|K_?baU*4BR z-!LeU;{o_12i#@mTZ1;pb2rK`8Iza`+c8pazZG~6YOL0Z((`f}e-sTa{mdK@E{2(X zF21njKKR?PC7ml^+K+`Iw{m!ca|S_(rVs!Fx`L0P=85Am>|f;zZC9%X-gNe^n&O?| zt@Ci{BoTDuiyvlEjrrj;I<92njB?3!K!~K<$nAJ4++p;#&c<2Q(KPdTdsn7#26X>L zx-p+$JYU@BeNaLW0r}$oO&5qj0OR?lD@};E?0y^CG*+Oakn~j?S1|4r+>A&tQZ;HM zYu`tpKCS9<)x1UVyy#Aadd)#laur^m8I@UbBvsj=OTq79ng3JY+SM(TAkk25$o`*3 zZTHT%Jo$w+3n1|u@0WV>-1erq8L|-EgROoKHDtH2e@DUKKT#i;?_O5L=jU|8bcEE6 zOXB+FN$aMd^$Hmkzq|&eY7gxSi`Sxo{x=ixC!Jsa-z%xoH`YQBf(D~VLI4vUygerk zFzb8Sd8Sq4%m;ev+GEVcf{9yD8iCU1EA|)F4lsGu zI?YyIiU-^lL?#Ed`Zs=Z3@=cU&9}kCkWE9)Ar;eb7=O{0rUb;{M zEv+?|Vh~#+QSq<%J*?2Rkv2s(+DUZF>E{aui#q*Nif5 zT7=`P` zoUu{n8fz3(BN7*19;1LW*&?#N4b*H2z4i-=B7Y1z=VQ@fPl=74}e1e&Jn=zQ5S zqKA4NJnF#Y_YQzP@~{14wZ^d3BU6RZZYwN$`v?b{yP z`cj3%G%@I*;2bavH2ZJ0fB=Dqwr37gi024%pElqz%j5Wpzog=jtE+UTL*YTDn&yW3J`!cf=>wm)rA}jMo3x=#Udk0cz;L&TYAn=PxKx z*7Bw#iZK^sclOF}GJU)c-TA;k00@BQ(YM@@Ek%dg4)lEWmTy%e5ao6yqVwE@N@INP zblKu-pfb4VPBbt=O|pQ1KpH>-08UUXSTVhc0SExnOn_=L0y2%crq5&Fq(K`Pd74Sa zZA0cfV~X~7;|i!OCLiC$W=K54*(EXE24BmChunQ{?R!S)csscje%&UYfy4rL@iL!D|Uuc-}T$#0Ab$P{@w^jkH?k6^$dV%u4CePCL z_BW>DJ&y zDKIwuE1x&lwWRTdl8JU6J#`PH$wjI{6mt{Rq=BP1&O zTh&&VhaOEV>ik7Tej(%M`uH2Vjkn)3SYMJM+$}{Z3=O;f4Ac*L1_58d$4SL8xU-)l zQ-8i82m~MmWG%#sOo}gow;ExQrZl;xB^S`UHk|nP5-;KGNHv^f3E>C;P=4%_lBP1t zw(YBDZf^l**3N&^0f8Yp;!2yOjd&lE&n2Up1W8L^00x^sKMG$z9hwTBylS_Jk}^;F zbBUUl_^O`lAvTbb>t`_f$nSd<3E5PJdX#um?G`Uuya_M>AP@qLwTkRVsN=%G3}dfk ztd@_cQ_+dy=A2Y(FS9mpEt)N5!p4@@TkB4?~CYB z#vyduL?93gb0M8C`RcWSPat$Z89oyC#rpgxs}ynCy6L8(Yf2;>c~fy#C_j(x%H5st z`k^4z7t0KWPBUjTZH|sq7VRt0skL0 z5ntqp8z#KyEoByx$E){XY(+gFwP(O1N$orh$oqXnWWJSDbJEAR|F2RVsO@c)0OREz zW;O#n;*`6_t$J1-oUC(vT(nw0&lSlnP-C-du^-s*kawllD+S`>i#-WQZem;(vW%AG z-n@2c0`)`uYDms-p>BUVrS^~O7nsvDmFeiG>h6+$C5!)Wh1z?8Vv^z; zT$Y9Gah>KZ!>jB0tB{8+sCeOm1ONg%j*WPQ!L;YDtw#zX@ih|UM+b3C<>~8j)&&8h z#~C;G*n&GKMNv_z&qcg{t6{v+^mQ?>)#SO%xY5$NkrL|2!VrKeJRBadrrOrn0>b!s zFg}MU--GSa(yw+u_O7|gd@DEGkyXw5%hB8-KBN%uS=d@+ch6irCoR1D6l$H-T^A|? z8;YL-15X7;aQyhO{Z1*uvsj4dLj&15(_2YWKD%zrbrzKcN8EFAUERh5brJJTZ3IR) zkmWMUzkF~;#IVu$JMt{2T2Tt!HfD3KI)$h`mz~6Cl@9S zgmj&F+Mq6*=AX3Cko(I}StrnjW4OF)M>b*q-A0mc?MYBlv@&duR7_sc-0dyN_l)VN zH%!L$m-~O>)PI%PEs#I}1!g9BxxHKEO&I>T5WuL??cu-T%E*12n43Kvw7WgE{OeQy zNo`BDI*roA-~s^hYrtO9t@yEE_qsO)j!uZuv2y|t0FrmCYuhTN?=6N@s@i!t4T-lx z+bV7ERfvd-WYSVg#`7XH>c1>F&%AaCT~WBW>Pfp6p*nb9>Erju@tjk@AIY_~;6^s; zQOrM~DBw!g7l;5ne#~jRCikFa$)4?~*p$O9xy5CcFDp=0%=Uw-vH!l@3DxU;6ZM80 zrzWYpCxdhX_H;TM4sY?u-C287>$_j5S-3eB*nO633c5A95YB?M8jbj%_VLicg_>81 zjgXP3P3u}fGk?!r)p*h6()Xlke@{=wQyr1k)}vxMW)u(>ya%MWNHM>zZksk^puZFF zGz+l~GbU7-J>`t6EK-Q~9RO&gm$tW>Cn$#fzp$U?eP7WYYgCOd&2USuK;1 zTc$t}t*Q*b$(LIemhts~MGxc&=^)5JCJdr3CHP9u_(@qf!?^QB}`|*$ER0Vr>U5Vv7!o@F?F{JNt zxhwgvj+=e9C8>ON@7yJ3Y2!JXE4rg!XndJXWH!J61Omc(m%g39gz`lcr9l-vAX4!R z+L8~Xl?I!)B{M)E05NW)X+s)BuvuSsBjT~^e_64pZoCs|FLeA6*QYY_?sQ)OdhMAu zAm!sOQs(r-nyLM;ayghh8Rg)8Q~}fp8(avX7ZKH zqr$n{o2IpXQi=-XQM&zZXQje#B*bT|jM|QuE>}f8L5XR~?7(s5yH4z60A0g)Mdg)$Wf}4t!XZZP`?~P{ONZa%!m1L= z6|U?axW&IoWR&8cB-ui5zGdz`^h=SQlr#rsOeb)y`bAR? z_LUr}tamOz7U*()Ft9G4{)KlvSUwfSL;xA*IV<#<=l{%F z6x(W)U+HF_guZs9=+I%4Rn{BlglB+l0Rz=(00I;MApj5btZZwUKts&?&ie!%-3)KT zyK_WO*QYNs)KJ;SRLZ~SVz{)Jhi4)kyLr6z(I7=p>hnw19NaTH8HLF59c41^5|>g7 z4l;4I|8G)tr6Ee@e*gf0LIFb>6&JEUdlU3@9Y=Y|$N2VptCr4glhm{nTT2hbiFz0F-BJ zcOl7OyVfZG&c5c9U1x3JpeX)p9xv?R!qHR2`R`to_^i8ENaMYB5trm%`PneV2crJb z`bA1{*4MnJyK=?ro_7vX*%fQ$x7AgjUiX>jFZh@CCh{o}GH&L6ae+Z2`t?IH*zRe6 zNB3xB*Xy^)a5I)vPzU@g)w`2IV{O_!p^K8Riug3?7VXJfMEaV@%1n!o9K~MZ?vV`Vg})H3{fK{C*rB1000UHPhY}O{YLL{Dk+Ik zlb-N;a-4(yh~|b#JHv{8VP3TJdMVKo;DsXS9c9kp{T%a*M+PWm!9t5!hO38_4!rd- z7!WH7bn%wbrfKci8y%}N_>yGQoq9&CxcF$xJr!Rpr+Ztt>`^$uw-0$VZ(gh?4RRVB zDar@uSRg=w0xRKdgPvcUvYa}GHD9|Jko<#h>-u7fHzp65MWgJ@F$e$vCwihe>=7ne zACFLLxxn0l@1WsDsV z_1Du20uTjjrd9kB zY~?wBZP)EDzs{pRNXB{gtx{R(%`i>AsQ655jYqzAk5`J|NOE74kG20 zQDqMWFy@9&Rev9vi5uS+Kq=c#h2l+ln8~zk%bxtmy!_tW^$QJ6808*ILtC^*BUV_E zFEK}^03ZTC(;l?viX)#N3YI$0Z0b31fcIUCdK^VTm;T|+9ZAuq+ALq~!dekB zqUOc~X`%!VBWZ1b&?qUqY>Ufkz#e99L1xFi+4elITBxkC^*jmJD%KceKZ7+GJ-IPGy@Ls6QqKw8ii%$Mz?${jWNdh<4IEwkxN<%`PD;iGN$SqCvDJN>LNh z`feZDZwJCAQnVe9F0^C}V1JFZeo%w}CM#W)Om?Iv3n**MxPlYjD*D%FcKWA2tX5is zY?9u;Ulj9RjP&6=-;*fL$!4F9vm^dK(}4KXLY*du2a z?Uh|XKgK}ftp{JIeHm<>ar%ALF1Qn$+2WI-^+fVD0eXa9BZNcat%8?87m#Z{7+&DS! zH0E6}(Glc>AEp7FPljyqpg;gAsoz{O zmm(?6;l9>6N`Iw5MyR8SSk?@McfN6GpIPJPKaTXBa&}wxZOrJonT;1bnP|k_|2*)Z z!^W#`dVHcDDe zCmy}OSAgrK%>8PP+y4v9+4LpP_R@cFvF|dyX1`ad^boan5O?K7h}SnqcpobLv&s8H zn|)CNWZj{0Ze+p)5CtJE`i17Cfw!3)?o5K!D(;etlJ}Jd4cwZRwZw_dXQpw_WBqn; zqU2+&c+cMR)9Ja(X#B>*#ymCS2e5%`GwCuMOvzyIcY6p3&Tz}4HR5Z5C;$W&wYr~~ zo34|z9j{IG3-z1ZQ|?{Jp>R?k-F~X>5TZEAiSsx{a>=Sqw%6#r>`BYg%XAC%8Wipp zyaUrKR}$@3SSl^-C5ZDJbv&_^_h%lBzIE)a=b23=7b5)28J5rD#g?xRr}E9PK9&%K z0uTX{D;IN^XzRpyFR^rRkR1Q)mXw*~3ziwdD3moKb5FkNXX(Dd^X(y=J7af62hk{C zs|)=*J%vcRL>BA1aei6ZKZiC@gP?r)?@UUHvQpn zUF=?I&rWvHGm2WU+L!i#b0l2H649%6HS)jXkM7&7Am<$P!B{y5b5aZ1sWP)r3B9+L zevYik;OhQbjAmcXp+l8v0>-JGZQO^1sdNy400Mx>1OP0MG7y9yjWPiMfCWA1rAqzt zjm?ge`|bXzr(_PgLEQpe`7KDk1AUvi2gie)?Q%pmb?ugyqa5Gri5C`7Cg+ODllg|u zSvzkLf%|d2lZqkrc_Zz0nW|qBB#wNnurllvP{bes8lVCKg4-Ec9$FR`8=p$1_Z&AF znseHxL9Neywzc#XO*7{+Qi<*cba8JJU;)$KD4_gqPgQ@!Ly6r$sxoAE1jW+ zQt(zF1OPw+k>7o~gYhGii;)15+vI8l=I`ONPdUOSDka?Lms!n}xvs@xhQ;E)3$<)n zP3fN6JOxDsu+A-0+oQ=nLDdKC7EN?|A#hup@J&Q)&rgjyJ^Zqg(b+~pqsvm%pekv? z_TT;S$+cF@Cl(V@X)C6aY%)K}oQ~%qTEt!FAIzP&{g(zeYAr!XFsc+fM=amFJ}W50 z{%`;YEL^)P_$wU)Ba%o&5iT*H@l9l!mzn)|#E#*in=)#dNxN^f6wQ77P)?EK#a z>Y>ht{}j58>;f_0&GW|{n|PNtE^y~RzdaZpTp|)_?&)g{$0If=WOv84E9;~I=92Ui z)?Q8x4jTxDMy5?P=DuZ{Fz9YGp1wVm5fVcFx-}2^6oK&Y$=Wiv{FKO)AlzcO#8xFL zic0-Ss}rq9$tL9;SpJOXfuUaJZ$+MS`}NZ77{`AncWec|-j4Yzk$BOy z)L?NdG`l?5sVQ4uay@-+V&<(pUwX?eo4VOul~hBsGL}~P?wF{>fIUX9|s`>5k>&USsV?p{9nsJ##I3HZ=@4{=pd zsEHhTIzH?&ZP~IUt*CRG=#TtG@zSl_XBrN)8xh{cd<(7qWL60QsejdLK;A6*YSguL zXnzlU`}k_DJDagRkb7%(EsXh02OJ%j_=GVNZU?mj2eh|v)D>AyoZl}Q5h2xYZ$>i= zEfv@)R@Af`~%tgXT`oESevqjxH*K5_|A~=#n!IxbvI#JSmv-=bY1_Z|= zHnSV4a2xx}bj-@7PeO~QH^g!5^- z#oBC_=)dQ5Ot;#fXMbp8cfw6aVLPuf>}%+|)sBeh{P4~lkp2j`v)2*713OY;Qk`Sp zG@AVq3RYc*Cdtsn+1~uxsmZn<&6B{SG(r$G4>*BZ_xQeOze2*N9FF&XAC0nqx_Kp~ z+E=V-bnQUuQ^nHI=${y+F5`9QmnN{>YhQpsAPQqE?A_#G+1SI)iF&&L0R`tvm}D7V zGdRhp2mKiZd4$v~l7ImKK>Fu8w!Ou3E@YRXmam$w;G!t7qx0%^alR9G+o1Qc5Q z*@>7ax;nFVPm@&asGV;z{2bn}sF=jXk%OGO@r3~`?9z~O6|(%O-J)DY38Sw(h)zwuER;0_59YI%2#pN6 zkRN(zzS9Jz(gKix00J5w-RhY&&d@N`edv&Nj!Cj44Hn4`fSwx-qmnCUv1>~4w>3#R zuij7lasUVd%w;(8NYvsa;*-#&YJ6TS`@vn_0wJ2NZ}FGYl?Mk@gLCRrS@aQ9g=o)1 zkH3>vBA7NH6Vef$18d#K(_b+c zc?zC28VP@0x7R#V^y_L5U>uEV1rW-7@*G>lcUcWai#Blc1UKYHT=|+r7kwIb$4YtTm5c_rYg6b0uTbGZy3I+XXc|{)#yifaYe&KUN;-XqrvdE zTs|9x;5ZM}&*8kgkHPbHJ3DM=sZtOmEgQ$>;Ul$RAt7}s9zQaWE)k$e|F)7y3z9$h R5Rkw8UC9*TLO_2cA8=B~x`qG% literal 37555 zcmV)8K*qm9T4*^jL0KkKSr@A=?*Lyo|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0 z|NsC0|Nr1%0`GtT00*bHz1|n5T)=M=pBnqU;dPxJy+dC1_BM0g?t47Wcf|GKdY#;B zx%Jb_&i2~vj_uc8@w++d_r2Xc+bQeWwB7AnH@m&s?|Z7VcLwh6_&)Ua-C7%VGQQc~ z>${h|?$>*(yBXJ;E3Q`cd%f+uRJ}XA?=#ch z^LF0cm$dfxz3JWU#m@D$*Rj3c>USOO?{`dUw52*PZ4) zZsq3L?C!nYb#Ajg-1geucDp>i-Q{VQx3xUI&gD6`Uawu6^=;dCb=vn_^?SRn>aKNl zE$pv*o-NzE&uh^0y|K@GzIV4+$bmfo002w?nqp#L0%cFrLlY(dm;eaCCJBH5N#bAt zO*GR4VqgTqU=ssCXc_@FgCjbAaCIAVQ4yFcx0gyDQ{z0Gs4FX^(;0dOf69QlWOd2#a z4FC-Q0fYo#1w0VRlT9>W35k^S(-Q<>m=TeQsvT87z%&|Zsek|g&_ zj3y%jGfhmMr>UAIk3kuxqef2@z$c;x$u^Pc4@lCq5G;R}q9*?O-;!gJMnwV1tNmyb zJ@fx!pSG8@UQWKV&A3<1{kZJNqQ08k z6D?(C9~^K8No6azD{saS5up0CIL)USziD_I?C)=&!gQRRl1VS{+J?XC_#bbw?xgcw zjlnWQhmuJmK$1=Nq>@QeY{iyDRa8VqDzR1~h>SsCD;S`vMFkaz#a1j>F^Y@@ixB}8 zR7F^*f~;V~WLU;U0gMLL5g4e*#6~J23L=XU6%+sgVk!!%C^905f(&B?Rz?W0j2J=! zkz&A5Bv=9>DkzG^F;zul6^s@Nf+(vMV51aRs)#D6ixx2yRYe3*Q4s|eF+^2@v4W~9 z3lL()AgmOMip7Gf76_n>7{x?j!Bi0#Dx^^qh$zHCR8?TA005$jqA-Mjq=2G;p(GR_ zERkRYhGl^yhX}|(fNQV-4dYK>n#ItplMB?#{#=cV!a#-X6#_w-Hww)~IQDocyC!q_ zP;QC6GWpfg{SRTvVKK%&;D83JAV?@cB9MTfNoG=P`RhZcW`%~VouXmT%%>Q`%gFiG znI{I2!l$s1vkuvTf^(_QFeC#yn%e`wLK@aVJW{_@>IkMu*Tz znP6aPZ9IqEsuH!41X8oO@$DzHuf2m$q6GXXz?)H=) z8Oo<|u~gic8#@ls4^23kc~Cpor9%wuOfhH~@7+O`A-6w1U~OG zKw{EgNhFbmD_5u(-)^8l4f&a^9R_dO&uKNTUsBR*+$IlA*>~OFPl4v}nJizqrf9w) zqe22=T4Ir+f2Wo>`sLWI3k8mhw?H3J4@8NVOJTC0;$We@CRKTKF-3MYHiCQ2x3BU( z)}O1pcK`t1iH=|ZvOy7K09X-1NkIVYB$7zO4T7V2@@RyR?lKpdotDOu@DKn100025 z8j|2a5i)c~hdx1-v5bPtJMzV|CO3sRfYNWYLAI?F)Ks#b?V*}=K)U~Rs~`0}`9jfr zq@K;^8mYzZ93voGNFdj?bzU>-R^QcyxFYAQ$zjzXUTxHHURb0-{WBrwQ(ZhX(djB$ z`|{b~h9T^fOv9~7I81ym3u$cwRR4{rh|WgWszLs;K?0NUxzv@B&3M~d!H89)Ki8|p zAx&K5^LeTg6__5a@+Dnc!orx%+h*yBU8H0mz)})hyp3;X`sbgdLE`m z?DM(0Suen3X-SJQGFHiJ0yCcr?|5*sFDL6h7#NVcZP%#TI4$qq*)#tOc#{r?EQZ$3 z@2aWLp$#GztTlv&s>7+oXsj0TsvJKrUA^1=xCTk?v&P>l6P;n&yXO^LN(W_@q8;<+ zrl^L0MY!5`jO_o#dV1AP-7?iu{WwR>bh*tHu{|g2=;Y@7OV2^dGW>g#(m%7hqc51| zzcxELdBOX6%VscLc4GgiyT#Xi{j2Y7xDyeuA-Ni0gT+xi?gf7B=ljdA!DA@CvcVa z0|L+;v>c%L7r?;)(hZ#!uzUkvOYL5>NO9@tvhh0$`rHzF$Y-2yK|#}W7;QdVP@gZ+ zsaaj}*SXBqyKiTPvBhP!4o2f%PFbD9m|>CUYfa|p_$#mW%GO>rXDT<-Io!O+ur6g+)r2!T9)G#e18LaZ{9x-(kfMX?ERZ|fqNIO zME-!VUTi4TBS-t#Yyc}w_xB<;JV`o%DIac@7nw_d$iX@5|TOOcDXyH_y!EDC<-4 zp|dc+urTQkwTFY@)y(Qp%58N!TtBnjTp9Kr7BaYo8#iI4v7ogav*%~Y0v&t_4WK;m zs=m@rZ7B+osQl1Akfx1co1S^%Ikray<`Wy)L8)zO^LY$qI#2!G2Dw%`Dr z5h{+fe|-9E$fmiB08zRveD1Yhcfwjt`wk1Iq2R`X1Q91A_9FYJ^&CP00aaVyE^zPKKH@`iDe(E?g>zB zM}%7D;S$eKl={FXK@rn&5>;QeQly&S%rH!KMK``jv;;EAMXa9wnFszdSnAk@(`fr1 z-F= zHj`aS%|-LLjNoBDsEib}NSwq5JLd6T7693-79 zDa>6lA#reFs2?X-X75sY!}Ai3TB3CwkYdOYjVslXg2Yd1enXi;DDq zzWn4VT)GEKJ7~9}y%gc+VRK3Rba`|;zJX#GA9Sf|N_4kmm@4D}qpUcsJR#}R86^G< zK3?Ss!&$nw>89d_t1|k&(zzOxU|5m0sk1dZMgpjHbS26>7RoL1{!7IW2-RKL0>wZ8 z&XXqs4L;1xknu*uwWRl0<1N;nGu^qkNAlVzq+3u3ApfQF#4g+wm$A|d!l1-_#J;yG zm3x<}PZ#pXr1xG8Mz6(W3cqYjn`{FN9tt7SJ^^!VBXJqHN)y}$W&%S+7+*{gN8(YL z5ohchr<3tZ=0#=0qo6$Obbi|LG=kcor0YLPK%_&LwJHl&e<-7n0%_7Ta;(=}?ZcGW z7T+s3xx;mUgx3d_b@*|}#dzL(mHFl|$h7?z$9%yOaT#1n%`PLi)RS9__>lx%bOy-Akf0XxoAo4bGs7|!&K zVdF4s+eNgQ3=(XFg^_SFGpAPBZD=(#bR(ZH3bbYqvRA4Zo{_Q@@-*w8gy+Zad|ABU zng4o-FaT?4s=bRnwy7h7^VJ49_PuGt6%Aw3^Ipp5ilKx@+Z*_<&m%won)`+4@VZhV zHg!;XUaY*>_#7oW>`w9d$demj4)B-L*Vf+Fq$4Eu;;nfzU&F4!7U$Y;%AhWCArS@4 zB!BjEb@@nDgj}0dN(C~)NpQOJmA$-mN*V2{*!6eX*_INd= z=fDLXe|P-UT#c#q@ZPo1k2PUb7tiD4X_n7hlBX;1ska~8f}x~aVURQY=<+tUzpc8Q zt}=$!+y>*`gZNj!5}6~H{CYxa&DUZ!e6P7Q>tOFrPa3)|*u*W5>(T_uBFMBznE3Ltoe!nHloq_n88!ROprYEC+-9f037NNO1u(LBUw5W@{UzH{ zvCt>#Fg;Vo6hJ%Fop`;K%e8Y>BbS@MN%9|0Q1jv&Cs+^WQ3dArTb$@NUIfB^_Etm{#jDAgQ26YLod%U4$7rV$nkip#Q; zvi&FM<=Wu3y>RFweN0i2m&BIh_6I)3sl3>%#?p>Oi$q6=fLPteH>3$a5%w<^?vPMx92tvP>l`P47rW>_nRV zfTuj5mXN3^1KHqn*R7R%+`@egteS@{*&XrjM}$b7JMs=%nfx8OU+@sd&h}0>q$MBB>Xtm9SQ3y(jn(R)=rk;Q9OyH<*O6iS5u|W4h`{~KFJ0>Vg z-T)so!4so}@3v1B6kS5-Vz>J_5MmX%qd4QCPk{?u2foQxU_6MN!AHoM(wxhl*b;TM z1Vc4s3M`q+D(3}9B?WVa2OXyh?MVLn(58ibwBV0>n8?IKhxzI6M3eipVcjT~Gg@sj zr3x+?rRe|yL6CuI#nExc0uEL0z;~%k$8}GWF4o}+u)v>uH8KGVcw;$W=TtOdp<1JY z>&0-7e74P}{5i5mO07Yj)vr2GA`vMe_~&8aJdLJv*Zvq)>xYGcx>e%fBr_I(A0_M8 z-2LHMP!X^vW`ssRiVCJe8%@HcwnK0tLj!mXR8aCCWjmL9=>r&1a;T&p5CGt3I6#)n zhJ$eIk5qwZ7)WCkTnYj$7IOL0cD_r5wZRr z+F$0YH)+(-acsHH3%sf~mV>de!rMD)&xx*pi?5t-?`=cTH&3+WJ_0#<$&N1s;tVj1 z$dZbT!Ut-R-|uHiCcl-y7L}JrexMik7fubi8A`5AQwV^<3O zvMAAehg72IDOeXh@D!UxlQsEJl=%P>u7uKX`3!JcHnGka85W3nE#PSINg{E0{wD=S zhbu{ICpZI4(!`e|;c+h^v9W_rsI((Fd5G*^&@x1f@g~_SaIHAVGpyN+_`OUdWwfb%tOm<=fAr+k#^ol)(mY~0;e6ub=ZYCNZ#N- zSNQxcn83j??A=7`CZ0T&ugeN+;a%HG&NJe)xG5?EB8&P(r;-b`nFqjTo4=QjzwCje zHv%x^VocPEEI8_gyF}U z9pvK~V+b=B5R9h2qxin_J4Xdc(z@@#F}NTA05l9fPEw?hhAjzx_ADd}+D-w64KyhY zD-2Tu&1aX5;B7dB|7ae%NN8CnroskUKKeuTG8&qB??RczamaLa)$>;Xcns?hoc{q* z9+M4;1OOmB{j6i;?=bEeCj>{!Ndv>{hTuK?$PU_V`q;=oS?|dw)c;^gbCJ@}{&ol( zG}`__Ye=$*XQ*$OKh8J%p~-)M$$^{R1wVz|BB4`wOXN{NrnbI*51{T&F}p(eEGcsd*hV!#dDi#q_s*aTQp>WFk}=m;i!mO@#$~$1$9Q z)DGq=0clhG9_ZIYpO1%oOOXCn9@L{E;4r4!r6aiu+H?x)UIj?Swau?7%vC_yz7;uw zrt09C8M>e143Sp^{62F%Y7cKvioYprA2YA`bO&hOf^B|EM;d3yQ%a&@eJ!T_R8agz zHhPGZCFS`JR!m?Xu<>>N0p^zY0%^=&eE6sE2t;-_DF`HSb^{%BhQ$r;{|s3<%TMHJ=< z2|zw&$9M{Q@6bFxgY)Pr{WDSmS9tx6(qg>iC`@J*O^=qiWa6wb>`x=paOV7;29 zV-v2R9sV)9Z$OA=;{Vh%5`ROu$rsj-RJs|{-y{i0!c%SF3;fZ?K;p6@pI>rjuC#f!b=sjjvC}>NP?9n+E)e&15F=|TC@q-uXa7u-Bg5j0PQo)`j zZ>sI6uXDvqO08=l=3gWk4;h$nL2?eU*{%W%^aTRLTQ5o{K@?D|^S*KJ0afG3xl;<< z`AWFU4nje8|G`DTW0H%|5#FYonpW5RaHNV}l>`v=l>xAdqQ8a;@-ZLES1y)nap^|N zIod@?T5cf9@Xl5fFaWqwn6+$OsG1-tMX10B6x1(glQ5#>XBtB$*!pSG>0O!ob;qZaXL6Ha7B;80j?8 z{}q;zbcgif=%+p44x-ZaH9&k3`(9`qpP1PT9|b4bsqA|LO!Nt_em#gvlaEL4(It8d z{!m={WQ44r9K>E;Th~1_A+S4*pXAl@ald22vvnJl-!F=%~@s9ixdn@!ZJ2y)eN8w!b_^*|_SCkF)X@Lc_ zuw z%2r~joj8{{}al_64lG#3>B!L0}UvOp^dlC?}*6T9gg>t3e3y-T;K&pW}WcNL3cv+tRdd}&IGy{^+PfR0r+x@iY*)P$?01PsOC(oy1 z#nV-XH;RVIrmexLdt5^@oZl~M2Pq|3lTiCp+~(TAv`vbqFsoFHAuLO>0_62)5V};3 zOoU&*!AT*Ssn8y)OE*&%QZ|;1KgR^NDcJ048K=(eRlPU%O$hf`=^u$tJ|lmjoAU@A z22e`ua92W66s3+L0MV-b1)c zp==w?W|Ijsh{zsEg;)*9q1CY2OX;-hEtF)9qaXXP(lKfS@vT8WbO@;Ctn`>awixJ5 zkV?)8pif(N0QQe{=&aezjmMHNo?ETY^11IR!EdZ_!IP58gB@qp<-~N+t*?b>RLn%g zBYyR+@6h4Mn-UrR_R;?*34M45Io7xf_*(Zp^<^_lSHz~6k_BPtIy9ZiK!4^Bs1SEO zL$hL`wZf=(T*2y~oWMIxy6PqMz(N{8P}4W|pB179@)(-XAjQRkU!41R;6Y}dy1iZH zl6bmLiQw?c>}CK2(KdPV8fM1N;+H;Sk9K)H<=O1uWB5zYcRRt=XKd?r9f0mUADj;B z1kD2Xk&Au~#!EdkP#pWw$}6b@&a38XB~2m?1X}Qyg-crDKjGbHl-QA*j?XLP02O3% zDqvOZPs?=4Ii!(#j%Q`3+QV`#&)scQXNmK`XHg!swI9*|7TH>Be-H?P+t3PoGl?WE zNcJP|@|^46ceBYkMF~TM^25yD__nO291fj)$oXZA9*cUzECm{cyBXYR*XKgpffH<&>{;tfFZqBo_tinP;NIski2aIz4{*5|TACBfs!izV=|dyCoG9 zz~!gb{RZ}x*h1SSvXSt_*rdAQ05^tmZPcKq-8^b8<}>mZn^a(S$=>fT_0@k(le0xB zK?dbLJY%G$iM7h{J9;n{$k1uCEb_d0Py8G(rOp>cf|7CMeG@dK{!;U2!)zL+_y}bA z{vZIA0^M#9j!2K%_}_HXFCUCjUg&#;sn(m=v-z5dK1I$IIt6L%GF+~z;sj%>iGs-d ztwx5ygjCKHN1|PuTfJ-I_%#Z|fvfH1>!bv8)_lRy@E429$}Gis61OSMxbSDz90@-Cpc5pAmFzC% zYat}Wlhp$p$6TauFQ=x^D4)icV=O~eLCeNu;Fb$?r*7OHQnkQS^TBhzu)J|9JlHor z?PK}DGx#cRf26S-3hMvZl^6^)kqvEki=jR_iW!vp(FbX$%oxxTSxvk6$5_(ADL%Ez z!Ueg?O*nIv)V)v;ai!VF!R*GG*C)mAP4+8xmZbJMta#t;W_i+fm4b~f*dUjha6a-Y zX2JI?JN?gjWF@k#tSrEV6khcjk}3V3Tp;b)Du|yCd_WE^D{IHURBOmvapg&qb>t+c z@@-?b-+xDKrnuU7Y4peX;Bg%xn0&YA4i$<>dUQ;t1V8EA6A(Fp zwrw(9N>E;KX!cv;Qwg@;0pX!)ETZj*harI_6CDaPvSq9GXW)OGvhu|)!;XB0(TJry zEA$e5YR3r`w()t@f{N}U7$8ZfOgOhgw}fEuKE0U7n@DSRoF=b?(t?0zr{N#2H;AhD zlhh|tg05^rc{EgFH-g3J>NVz27WM8Ok7qs;zO~8!3eqC22PPS(% z$I9%xedtE-HQmt@k77Q@Kf^Bj0K8LJt(EDkiPF#_agy4YO%tOr(y4JEzR4NF6i3%I zJ}zq8*%t9Psk`Bl&Umodgy>{zxN;@qfWNL%(_)wLP8N&oU=lgq9Dqt| z45sReb`|n^m5`3}J#aMnY&tKzZlfj69wy|%qeVR9L9=9aS6VJcn$fsqqGrGZ0c^t! zz!HaD_Brrds;Is!h4AnDj;w$`T$pz~3eJwFW^OlCp|v&VUr_`JrY_fv*wiB*{1HQ> zR9)Qq@r7O+)U>nyKGEI*OcRiEO-mEd2KKBpH?vYs7uhTuHSqby@?Ho|&=lDH8%gut z3izkU4iz>ozAqE>=S(RPr|;P8A|P6gr=^v%d8#W>c|X)r!}J#dn9~_T)~P6(6P%<` zE{)0DChf+U2F04m&PV&3%*-3+4`4C;;48GBRV=7DnNTimgz3Kx^pTbA%!zv9b5y;b z;d{+zn0p^~5_mVrU6ScAev{rYKQeCpCghkx5R^kwq#uCSlazx1u}>%7v5hENn$qC| zI+}DOBOI3rSn1uR!~SbHAwBm@Iu}+8arJHf0(R`XtN?2dIb-?9Peb2X9SQ#iHuF*W zU19p5XpS20Aupl(RS-xBO_Jw`rpj&CDRbz?c-bQHge57#@|=7^lGT3jF(C>YU&mCT;k>TZ&&`H!$wxFytAfws_qJ?=$8 z>`UJbOaBfBicz+->C*3^M)}d`Yzwnv00~p~NLFygppXX-Q4;XQV2szX6Xouw$#!pM zJMeu91+nXl3+=g^nVSKEu~g&8h*%dXFDPm5jk@=NEWGR&R>8ea)8I@e{=%+a^WVy5 zWT<32ar3O+*9548(8C~dP@wwfMrF{=qio`JGZ{2I63&2e`rj#S>+7)g+RvfFPN>~j zf6i*P#-AoVlyJM@VsZHvChWhU**l+~ykDY%Z z2Ncg4P0;z6=~g6?y1;>y`0RsZM)4#MYRjZ)Rc~F+Zqd) zpsIJ-n0KL%roT^=ziQw8%ZoKe=F2G=Vv{j748R*U~naE^xh~17J(XDZ;esTXq6@GOwywuuo3t@JQ zCA2c!7{lIA_5 z!5H9~7v%4w!st_~Uy(*9mTV6d;{XfU3W?XhM_{0EpLx+~S9FoPdCnpZ7j{_5e3d1% zKJIfK4LU5ZpUbtozoFsH4;`Up0Xo?u7K_-;;^L+`ZtNS2`<3pztx~bEQlFcyE|pzD zyMWzLIFR8v~Tg??*(FfRCxe=H^UvFViAfjX&96|Oup1Sc102c5Y8d|HhWhucJAAy9 zU%SlT$}N_Xw!888G70-zPy4(QBWI!AVdvw%HyPVt>IrzJXVRA!E3|N4Vi$$y!8;4U zY>*ka?;IBem#wf3hQtMZn>3UnJWar}D-?+o$msXO*k|%y@QYZMK8!y1a5hUqLmBC> zAdKG1;O7u0XA8z9X>izL{~5&vMf=|&!hTIp@%5TxFUyUGaZ95fM9EA)72K2>hDZdR zd*|7`S6C4|Q zN@h(Z`%r@zs(r0MlA1OnT9@BhQX{^W_#gE*7fEe`mSrC9dnbnxq}}i*?`PN)KebIA zu7;u6s)>U|Ao`4z3Oc@16lTJ z(f=$05I}$g0003fxZ=ctLVW>5=-9ogS{uLLHS~39zSq7vauxJOg=w{x8n@`@TJ1NA zNtwqK8fDEFTGX^QYqr{P+ck-*tIJhOD(Y48Q2t*R z_0B7+2_s?lYXSRf_|;=?dj1)Yv8TJT12Qk8q9%r;eFr`x0)CSGgxRk&cE1=L||Z}$GTNm<(>%Xz0QWjq=VrC``!OcoOPuj(6DP9E~cTQl(aFR=eMWZjrc z5yAkJgf-3G>EO77ky?(J%@Wh=5q{RNw)|^ApsmS2I$gSP_uH9@=?J6v-TRWTF^8g0 zY_q=d6nkitvXy$lKHTUSn2_tyF4BrZ*`TH6*+ZthdifoXP;vFOlCo<6H{mA)2mn9; z02j9j!|0f3icy5q?EPNRnqj|bkZTLfu8pz!Df&O9A#SnU{q=RLR7}_TUB=~2yPi3K zvqzi0n-JQUWKLx#3EOEozTg|QF>lV8eJ zCyanlg)xM9%++q6#WDrg(>b1AZ#Cf3$?Coh8DsQFqekXFX3WbDw0Eepi=Ix=T+!S%qE>XLnQ zJZ&Sl3e+7PQc1Oa44GCUz8I;2Htja%C=E8`$4`E(f4#Rg&1i_6T_@5S!Rr}s*+Ss2 zQ-oA?q4L^jv`d%EM_MPsF(J3_{TsR7Ym=g+bf~K)JR2^xQ;>fv3nKe4WrqbBKi>s2 zP%^agjI8kT0O=N_Kn3FhO9pLr_a#(jyn9Q)APeqwTkQDMY<#g{C}DD#sYfHsdsIGb zRAzou_V4l!=O8abKb7bEAn$m&9ELQzzpj7_%i&gR6|{7cawMrl1`9fTgtg=Dg^}vp zxJNY!t_BSD>>CCD&R+=a{E9c3-iXv;hYZP;joK47d=&1afrfOJoB11AkXjJts0xu@ zY0~2@ejy!Uje{J$nJ~Nqcvi4A8F~>ukDis6vXfewm5&pyDZmi=Kq%@O?-UO>Xh-!fmpQ!1v9L&ud^N+*mN@V{yu3K z5NBWm1`HY4Fkrx`<^wtfYL`_OM(eIEaaOWbt#emUw-01EAUTaHXb324v75*e9p-2o;v+=yY{nw`w!4G8 zpO%*!0tlNpnZygqt+;q|V_9q4Vk+eaGx+3g9CbRLgkxkH&`tGYp*&I!mLQo4=1JEE zq{szdU#@PKK24!vgzwp7EQbRP>0hbpx`)efOyy*(a3N;AkhrZDyoYqq&R|cFJSLP^ zXxDw_0&a+D8H5eJ-3saL+S4m6i2lawPW&srwf<}8%vBqoX4*6(*njt488~K|9<08R z`s^3eC&e=Tb_oVK+^L6wl}iQd>hB7OCCE`b+A3j#hZa0(2_l-C^vD*C{<2WceP!~+Q$2GN#BEnQPW zhFl~rJwC?r}F^8S^GiK z;ZBi1%eqBRD2c?n9>Qt7UW0Tr9&Debt`0>bK|!@?<~I`|wts7nAhI0Z1^Is7QwD7U zz#9}=ZYqS*x-9Ha;ovp8!xIUe{Z1s@B|ojO84og2OuJqtqwaF}of9I`J{xwICP!0H zRS9>k1R>hXcskaT;Oi@!W_Yb1X=tV7{17$u+uw5`tIAn=*n5;HZn@slpo@8+<)ndqG10G}rjN7*|V|Tc){W|sY zO_+E!RxrevJYB4P$I&~8u>NhS8^@0D?9i?;&4F3D7CVthKUqmI{fA$OX7eu`X~G&D zguCRcJC9;*swzJAp%4j4(B^uPzDI;sMRqc$E3z*SvCLJ#JM>@m!}Nk;j>TQQH)Ycg z;#%P`j%m^=M)PU|*BiQ;uPdHSl<0UZY#^_#Qp9}^!4m~fzUJ6pg>LGt?zo7O-A{^2 z*U)@#(N6mqPe)d6J$LTM^$z=kkb!&c#ecT>2S#W}qMO=;sQPEVuBo^iC*5-z}~vm7}YJWDEXDwan{MP?{aNBjMHZ;Malui4^RKu~#s2#LV=cSv5OPBExF zeuuF8WbU4r;pu~zlGIsB_^a4_Nt|Cf2|D-6t$I7QOm2<7bvwRpXvVhiw}s3LLY$1y z$rf*q05397&3(bmRSw8q_GRhSyQuf5Y<%u4J5dpD=h_bA4D;-Ej~25JP8v5dC|WcJ z;+vN=1=Qq1fLgxt@{*fKbf4KQ(5*WfrbnqN^w=6SRpI&%=^g#kmY}9yd2e}`1;UKh z37$4WI*Rsf_$LV}g~!h;du9PEAw#~oZ1!5Bf3`IFeXF)ZtnKdeatr1jUC2eFSogHn1z`8ZEF5EgtGM1pqN+{}U&g^u#WxbC2b>`(`OFvC3Im9u{A{@sHD&28a(LvAqW;0WXC6WK2Yn0l zQ2%Sa%r!P38F{?O6yx=p*tF-*RJX*w;NF<{pvBKP z7j$P3qEgs}5|rUsw7x64Y)v=p4lf^l^V}U=JUG6kj20TpW=Kd3BYJ(;Ykf=X1!OKs z7mi|0fG6#xelqZ!tWl5Mm*9JAi=1Y6?9)hb+nS`AVOA(SJ##`=(ZVKAoy*7D2{=k{hiNLd?)Xo=a1t#UOfkcGMH?mSG z|32j`0Wz-{2jC7rblzQEG@N>eoJmotLj|)FMpY;KrcGXe_Q32Xwq{s2&-!mB@{>wm z$mGA;u_A1(R5Ocz3a*v*L7_%jw`%d48>Ll!b;Z>eR#qV7vv8;wIcG(a!DT+0S#o1{o5J^ja_we^7ruY*;Lw1%4+G z0hT9?cyG70ZkYGJcx|#fTzCRcc6B`V?mV$Gcvq7Ic_Ht??Z`MnM|>2oIO@Sdf*uMf zdaOi-**5u4+#byzQSc}cRR8ooo=AQ_b$qj?Sg90fS=kF@)s>{78uHZjOP-x5oRFqj z&AB-49>CXD=x1q}6zAV&1X{x7%Y+k&a*AR2w}04P&F}^oBU%vF@8#lb5;Q|(;r5s< z2ZMIw7_WlTwl=W{Cn-C_0u!kyuyT}JPXmrVD)wEkg16xI(Nh!b*GA$eApNo$)%f~L z9}twgk{DB<9lXeS&tj%bSR#hyk2I06bL?@!!nU+xr~4JE=`ljs+oO;nxJSYsquI!| z4@|(ixO9nRgUf)APO zHC-1-Mu`F%?(-j}0=-sw0muI02t zHA8RuNt{wi9{ZW5dkLa6<(N z)}x;N`Q1=d|8?1|@?NLpN!Uo8!{kOuazfnSLaI?2H|AgGx5Z~db{Ofs$80l1emiyd zSX~ybB4ojmll(sa)E!B+rHIc~Wk$xSc?EUn_&k59v&Lok>V2yQgZpsF-FD%Wk zRmdEBoOiVbxE0iU{_4owaly5X0X6pEQ6;B!si1D^z>MI=`e12)>Spf(S<@mW_isCW z>6O9WA+`EZKPmEVy0XA~UdSdAscc&R`jr7>$y(uH6W_bvHwAZSiI(%XM2G@u(@Bfd zrIgIB=&;?LG#3mf`Nwv1+tRIYNAX(S=u?TebBvQyLVpRJFwLmD@-kBNQy--6B~JgE zqfb+Wj^SIw)y)`udeb~ywB52=L^LW$+X}@^sC%v4tn-Q zHBuA;60W?;bvcpCK& ztK$bw=YE|&Xw7J{879u;p%4HWI+HxTRK!^sJ?^z>Qgv~;EXw-H#9oW8Bc;a*K@>6iI_Lqu?wI8BItku z47lg)q6g5WOc8hg% z<0i&l_J2+33db%_TzgiRr_7buwYm&zSBo_P5zqvthL_SdePGke6cM6ZeG$PRGa2<$oOn9H5w8zj z0=lL)_~xL?mK_K3rM)Y))>6rXhSBA$K}8`ZL_l7@!K`t8cjH51H#8SrqN_p6%y46W z2LUf>z#Zd?D0U8hc7($3@_d9wBpX)PZAc{@x8Ns!sC~KgPyVE9g-*hrf9kpIv zyh;UF%DegG(*CtJTMHzO082o$zc+>ybHSVn8%+g9|8OzzRzTLTw)Me9d2Pg8TXa+< z22w{r!wa(HSxGei8fZT(f`-0S*<={VyX!9Ve7~I&=uSFR``F$_v+14h8RM76#cJRA zCEdoNM?lV_2Nb^bT=gM(iSB-ov)dmiK`V0t*5(Upy^OJBv?u9%%}nfvIiykRA8SXjhRGg7vd!qzZ>n+A&{<_s>G1{d)GB7Q2d7SIt z&&2~lSe5yM*)ANmM9^@fSo*kEsE({m_-IPBXV>IrbU!z^+8v-I(>I(TOIKwx|MDZN zlGutuHPLkAI*9d`dauC>t~tF8Z7>YX8XV1jX@6n->)=)cy%+oMl-<3@v{C%$dfoX! zjV!WU#8PO5Uhwxp1|DsAknnIBcGI&x(J^$Cn&P{6Z2a$40arZo;xPRJKMKs!6BIN3 zHb*-+0vy;9F%dGm&LM1%KD03$)*AhvoOlf%HBU6SW-*hhN=J8*%iI!&14gn?Gp^a`JjGMDEO;O8C^r!{2H0W3tVh z{eHX8vDlqR6sM+4X^n`(Ii$iIi$={kG4VYk-v-6dmzisw*rgWyBN<#B(8+Z^myEo0 zYV}v1)G@8c8qpRY0yO(6$kan?{JI&hDKK-z`+i?>rT5yp%Qc4q+qZ4Aqdtj5rqRL4$tUTSi70@QlO3JoRGjO zF~(1n%7$uR$y``c-)+&x1V%zcS!cqrm-zSUkn4h553EXxwh5w!jRu&CoH8=@GZ;j% z+=mMPpLJ3uYIQ@@ko@OglllIx?dbN;;S<>69a5XZi{fCktb+ptBToT?w6Op}GWRof z?3)S%{xcyz;r_0qYvwQZ%`MQUCD*EoyTkXW|3U>g`g)_SHMAEGh2P&D;ki#R2s^ZI zU|5p%%kE8$YhNP@>|UDz|2~QA!YPzK3PcA_d>nYa7N2@^_+4tRzp^_K3g!*`8GI*U zwvXF;97?Oah8_Y8CEKyN8=0b?a^jk-t4bT%f(lfx-IOY_F0Hq^!3Ft}R>B+z>=K3c>TA_Z2IsZ&)-2!0TLqHyyOMM)-?&k6 zPu?B|qAHr!NK0s~y;ukU9EO-VpMu<2h<|08-39tUz|!YWs-BQfcux%j-S+M)Xf{C( zy`k&PN#(C6w;D+@m#cOCLg%n&T?iC^60EBStoG0~s(l(Hsid2YYc!Y^yMVa38tK55 z#mm{MXm&VU%dsUBPUxBtE`{6`C<&|yTR9$$7IC8G%=s^%Zb<0ZZs;kG@`ry_=wIHUo5E;0Z^{?IaH zqt9Ql636QouvSA<>7YM?;&d*lW{Q*Fo*k8F z`x@E%EKYj~&Yvz;`vfH&Z9TgRC7TtzJGez~z}U|JCs2Pl+*D_LJ@oR0+!oVaCyvpH zzI_Uom{dSmGc18{{K7Njbp3)*;K=@!g*zgcIjw~nV#tmyM*6M)q2@!A-e-a zPa0i&LAeu8jp1&we@p84U}MCnIlslLHpxu3+dq^oWi7)q3{%6l5(j|jS~DYTskE2` z7?lrp2`5IhO}|-^wUx#!j8n#meoNdFi~Gd4Z=jmAF(y#abkCX{4)Pr zb!`0}{DpKq2EspI`F(BcV}3|H4aJ4OlM7uO;@WyG>@=zw?e#4J>Mo(zQm=TO?Cs53 zl>Gtw>>+aVW&dAt%Tq>(k%f(k2?4b)QH-gWfA4b2KZUP3SE%5|k!2lQ0;S_ibu)vN zp4I8@n%T+&VPq5=OmOCkSwVo4C%IGrc{0!QQhQ&Ni_jtrvZ0ig5U|sTzcq1cG{XQ! z_0Q$n$@K&?Y2P{6Lhw8;a#OuCpb-iZT<>n?>dkZw-mhTy8fyxZ(QC^dPHm&U69!=! zIqQ|RAz0OC`#UB2;KQ>hL%yF;qW{8nHY7atx@mG@y{3+U@d z(jeYFAuryR^57#adKhF_>=%HU=vZLhCMcCCA}$T+1r;}~(v_03(}Wg>OT7H4Rb5(^ z=X=TbH4Cw@WdBB6Y}A$2C6-9P#7AqfwT-K9@~KuVHe26uMM#fk2vA};Kc9z5==@Hz zF*t*&f9tUO8*{a&f>!q4CLMLjOO6IzICVY5FE6Y*0tcVCGhIUE!wVY~>oEhLe-WwM z-2Kf`eIOzK5H$blws1Gm#@RshqSsjH6A`-f<{Di1z7&kd^^2L?DkV19+haCUQ_b#? zoJ7)^1zdH1?L?iYgkcKIVc#EY6%E?*W~1akYwzC$`cj<~1e1{%inTz;@V!15ajP~5 zBZ^lvy$c-wELgSFG>q!K;p+51dwwl8O4ZwjeqBXXHKmkh%a(~x!U3L@B zp=SEB%uO*p0U0XyVA+d~I!-U*>*Eda+p7bhFr5EEo_oZ31#z(4aRQ@-%X2zhuSY#7 zK4GY)^QRrjgfVq1K?csCugofW1*X0rHA&5vJBPC`JMnqMZ*Y;!H2X);qko8Cb$JKE z1I*Vln5%AcWrakVMu*U+Jmb6w>2kLwx0HdcF*KudB<_l#<)(KomMGpS`(AO=nrQ9! zxf3~&k*W+zjBNzsuORV_Uw)@OB`Nh3dO^_j zncN`A^KknQZRzd0V7QNBK+bvKXnf9qukyUvK=SKfld7wz92r4NWDMa%;P13ysk z|B$xJG(!tTnyqUp$os%lp9Vqv1NnS~J}Q7k&1sFCOE*Mvu!7#xZn&v)LOJE9WiJM!Jl> z2$Hk}GUyhQEO73Uf`jK~V0Q1*d~0q0v>*3mi|wMjVTevS9Bqm)pzm^Z|1BB{1{gRy z=L`^u_MkO90a`iIGn)!)W;|q9#C5xl2$4u!b<%fTxJ3R^NET&~ z({=qmZU*^G=1^S-v2nyHuV)gBe9QmnuQ%aWoCjSQzIDp_Ip#{-%R#E1Sc5kLv3^LY zGx^x40@oCdZ*p^ytO#e=sX2u(ERg;5~sC<(C{*N++EEZ*9abR@i;L{of~m;U=oy@Mm99B(#7IMO(e zreEnwo0rq=b2)TgN}om{#z6=3f6!n9eKPI?@tRClMe?#v%{E}zh}ZTL4y z6{la2?*NHm(aBS)Tc?K|N{UOPcRRG%MiTU&k!yn1yeUmM(gOsMjAd;2ze9za#yaEN zp)=l3MNhHH9-T2&7@{j45-lNySFYz%hFSVzMSnzi3qiBj2|S_O6)o(SC!cb}W+`)}^130+~;@NJs9lO6LOe}Fr%%9lg19HLB44ap7YfuqCYJ1D2(& zlq-1Si;HMS?fNp>jYNar_2Y=yHRI^@;qZX(CyY82`gR+tOx5;%LaQi=B~_%jQpnPv zGY!KSO}rHolUd-e>4lcqXy4V(elD=W8HNgR9xJ8MA!{kX*FJ@p9e~_;zui(HxHSNT z>%R{2`lCA(sWiq9|77G8M?ITf6uA8W( zeLRsdj~@6tH~M}i%jV@sCIeYgNyFK*N7fLr$x`Wy^pkB*(4% zVBk@l$zA6Z&zF5X)s2t+Jy1m#pmy5#tXr_*1I(Ihzp6+TzNs~ukA4J)&qI?0KmAr4 z?nBJdwNpensuYJ$V%DzoJ^|_a{t*HHLB2*}U>h4j=CCrbz`x|8?el;O)cqx6%z!ef z#V$Pkzd$7)O>TKZ`;;(w6yAx)9G#{(J$(2N zhjuKs_o-B^{m2-5XKUVL|Lz#~1IHBdkTRq#1pa_uJ}RG7HIBz&Xl~YBCsp{+U%l1Z zoBKss)x|nWcGTxNlILtJ$xXl3_r{iXr6{dnm$*h~@iF2&AQEE`v2dMlDkIJj0Fxe0our_l0u?5(y7OmZ}QybYIG)(wUF!Be% znn}f1oS9g6Z$myLn#cK_KSe76+do+N|T|ue;q^nL+(cQK314@ApOmF~Io*W0q*IObCOU1>Nc%#7fb}vE0=rV@eclw)IVHmmcn&P`~S4<#iO;$;$@jXdQ-YKk!Sb3uKA$&HOYux)Q(s?Vk z$e(A*&pp|kQ3F56xS?r3Zl)^3OZ6LR9`PD({~#6htEl(ie%X&hNdM}L0LBlxkGtDH zKpA6wmG}Bu4w*NWzxK#oR8 z6BKx0iUdG?%s>SBz@z$M4zpFb$mU2tvY^}NXqDf%QF?XVM{jmyF&H|5Mn&Mv#ya>*O?~BpA z2o0jMsn=w#IpQb+EN-X%bVRFulM%wN`M+9BHnj$ET8YNt2m?qwc_{r4C5DiM?B;Yg z5Y{cYcF=;Fok(p*0G@3KgpQPb5-j<0Hk;T1=AZ2Ya}dD#S~8}Jsbw8T@>UwDm^c&_ zIihpB(tkyMrrUHBTMemXWHK+QaEFfhu9$QgHzD3eP5)Ja&x>o~Ntu=IFO}I9Zyhq^ z@NJ4e>%cMOK4G7mf#cvtQO*1cED@MsvBkP(adfCNirS%a25qg>wDZ-`@`K36bzW=i`@^Qpx@l^dek zmC;~c&qAE_Q-_RI*<|vChv_f*uqzUMhMi3Qs`Wf|E@K#QId)q&DMbQu5i)auGHV!5 z@ou%oZnHI)uj(dZ(bo+}`dngA04kQ&@*4KMkvix?qZLue)2g&p;EZ<1X?RzndQu@r z`Iw5E9Xh(YT@?N?%fcMRv_{UUqmofVn*4M@)2hc}oxvYx*inrahpH7Fw>7>L94&f0 z-l(lD~pSvR*4pC1uB>)kP33GjC_lLVk4gl(Kk!!S(KuI38i^UO%L@ z!Kq}KTXK!p72q}NdDpyNoh-cFOlucm}3c>8GVCN^`{2Xe4hs7q({ zlLzYFY?tRxApJy47o07h)O;@^n-);%x}uo!&|yOw&OqOuc=$u;>i)OMqi~SbBq<{; zA=Qc6oj%Usi0hdTD7PmULITA{?-Z>I@UzFGyJN#y=~!lk-o0m&lpF*9c+bPjCBZ4` zRxbb>ruTJV)9Iq?X)QYZGtu3_ty1N~*GEouKU`opuNcd-AQuv$e zR`2VsI)X3`M)%{KF^l9t=Ouaz0C|P}_t0c!r&8M-$-8xIAjvyrmLJ@1*oOFyGfeKt z8!5X=$H0}Hml!@lAx89hSxALh3q>WU^zKsZMr;?GzGfJ&+@zk1R!p40@``T}RH@WI z#P4Ev2I{!i)-l0PI@AT+au?GK1)Di7vaw=GkGi@g&@2vcBZ!JVylYq+w|T=-Sy(b4 zTrF#Gy9(02{r|#8pW5@TLOStCg@Z`v2VTcHH3p7l&Zk3MN! z8_!2PZ>&1E6NZVcLbiMwEr${R;u~Y7LZvS{GGA3s$$Lj$1h={7q`6L+`W z3B1b#*Tv9QhhvdPBuO3cu=#7g{=odNLX+4pTXJl|3V(txm1PSbk)4L;Agc>ojh%!I zA_1g6NhXD#YNB1fY(Iod!c7TSp<))t1#f>uYb_)GKMI~xSk|NG*)kd1JhXfrOR)M7 zW%k7c?aOang&+lFLK+{2BPe!8wnhP2tx6)`B(%RVyigoD3xs(~;}&m=`L*Lm3nrYL zK+vpY>01zZa%BABY2ehy>^G$Js*U@GnKLaqm#OB^2VUPy^_aD{f&;xG1GU5wwKB_V)hcBV#gp_0|nsh~Gs`8Kg38UkrXXTmku?Mo0 znb-S#$KFSVXSmwHDKk&~whhzJ6i(iFB0`jcVVlwmYq&ehP?${EBKdI`$JH2iAOecF z$g`2{TA|DE#aCT2yK?98LP814ftMbIA~{R9W%Z48!Ybba9dlRpC!4b{>>H$+Y!xr^ z+V-geM|Smk513B9e&5MrygSf3rj??q*HZ9MT}mA=hq%aHMn%U7muZn(rr@cD{k!9#d zM@K783Yjm9;ETRzgE^4*if;54FCWLDfA#Sfh@v+Ptz(HqSO!W0h^tCr4wh_(0Dq1v zgG~gj+D$A{7H{~p2m?*#11drO!5KY{$4!u0FoWou4)(j}AQTJ_^-7x;=;1wav!S~e zCcNph0}beNU`x0(*YMwI4^pZso*r#8c&Ah$bSQ|2_54TjyBJbRvA4@TEPFo2{8W09 zT1T9e(4v{~*Z)i;UsKc?I!qg#I6T$mg60$j>k4l(wq&@aH-}$tyDVI09X5`9FExC_ z-stj^{7unI)r36DlnV@3Pp%e#V)?`#bFWR&pXB{9t8>kUr3W{DmNSOMJ#VFD{`{FX zf}DuJZGK_)yrO4+fbvg85!Yjt?lzoma{UTz!Nr!u6}I_jY5uH}EwrzLeBjN1am5}v zW{L~3@>qN+o4Iiw(bfRSUrFtm!m$$mdZ=r5TN_Qpg>`Jh*Io?=PF=^&LO>^5DZ`f;X zA68@2k>3{kij=Ri3X}#&RJGuqd7~pl9Furt+b`?<{G}Jh2*MzoA7x3*=$J)Sb_WI~k-Y zk@m!Vf)nnFeLt@~0OunK`|wl)Qpg7+4p2rKQ4@RJx9yH}*0qxAyx@$ot98(J4x=6! z^5iUte;{!iZ7$@|n;}ehC;r!pwWECugI9+_D-6@SJu6buN2%^kbG94;dFmp!X7648 z5?C8>(GO20R{$oHv8PeVb6skEshgAnI+MM>vd(Ewr>N5k)WwaQL(Ge?-2b^GSiTos zaV)K}OKVd#x9VGFz7S?P^`mAwD)O9u4Ovx~TytbaHh!#TcW_dvE%qP1ba-jS!EL_k z{(W8v6T5&bE-atcW9p{9T~y~&5v*&md>#EF78O-OYq2mHQ-Fk}3~kk^c^0t4kD#$m zvwe@mJ>^6SQSJom&0yn?(kjeW%gen$#&|erp))8`Tq2^lY@^EkIAmN0C)l9+7^W(= zdDu{Il8|Flb8*V!bW=@NLEF+x)uc^Z3ZK^Dxl^qc+V|?;B}5*&S+{y-ym6ZRwoM?M zwVjdxF->KlgQ5aF zoT(%NF@${SRK}#yh53o@IC8I<#M?Dtr$@wvItW3eSbzZ!I4+wtOk+D$Htsl@p(PoO zh)mo{%zd<0i>(jXa``AL6UQz)S$=$_C!`J=!ZpUf+*?}t*fe~yO8XTu(|nw1wt|EFN?4dVvP)Ea?i!-`(T4+I@C z1ROJ!56fyCKrd!aqBXe6bM1+$=^VNTW&~na;HPkT*vN++;gxm z=Xh4s1P=oKy_yhaoC`TROa!CR9-(MXP7?^;6|y!Q1Z)^VpnIeApX#i63FA%uxq zUCnF3^$&mwYjW4?3gW%sXenZoxrA#i{3HI;GFRp=oG=0g!EgUaN1u-~9ujr3p_;{i z@0jC}dY*)cB3mxti~a*;Kh8??fD$2>pa#vYU>=-n=RY0fKF%oM4qrfbPY%*)_4I;||*9TNZdAz8qO30$O9>*-(N>ZlAuSP{pPv4rk0)uv7jGQcla z%C?@!5JR>bbZ4tB5Zx!4&Eq-FrJYw|lY5F;T8ogOfmA{$5j4M@9Kk=u1BJe9dfLjo z87|Pec8}|i9gQ#NIzRX3xJ;w<9oQ07NhrFb#POY@dwi=aH2gfnkPm#1wrB$j?X!Dg zY;tO!t=%ooBV}j+s?aKukPXBUEZy_39zCQ!G;n+bD~*N(-C1Pc6U~@-;H#S^5>yq+ zfnXRN*EA+{^-}kCvjS+Szu3!2jd)+oQ>b4I)7Sy9)m?ikawgZbbzmsuws?L|z&XvL zQ}C1MwP@;2 z9wp2KE^XtD6=`rzb4=`y>V-4Q#({+RG-I~T@{^mO6<1>KnoJ;>l?%!=QAqdqM5Wo) z2IyN~MX9y&an`Fo$b8(#11~v2eS=y*8wA9^M77rNhfH77N}}EUK3|bX4{f=OqKhuG&V2;p)@Nv?#Nhw_Ajm?7M@SB z;GV|Uk0Z!Du?Ho!3o9K8HxEB+pi7Pyb8jou4Ia77SMW9)fI?-b@Mo>+J!BJ%8{7l?*APU;%g|euGg}k4W8RGjiC1a#Pm^O14 zWyVQ9Xy4-_PM>8s$vvjIzHHt47U6v!75TrLU@L=-UGaqGq6H9OFt#{0bPVhSZcx2j zW3J+u(B8gyUb1d7!+7!og2vxs^1;S89c^ERkeUYDv)Eci^++`omB9xdUiJ?+<#LPZ zHJHX45PP+R7VQq7fU02^FhWMI?RooSzMHwfz(<+~I7!`frD`cu;o_0O7$gJu@05U3| z%gi?_O8j1r5Lo9%3I!?b&vA&+J%nHE$AIZOvK_7HR!mXIacl32w66J*964@Yr;X`u zR2e3v5PH10d8hrA7?w=sG0Vp!RIJu-W)N%)R&&fs3h({8s95e@6V+*-`uzR?S2M+C z6p7(is?dDO0KJ0$e*Gs)mRc1=05S~ZgSUAVf7}e`q>8L-)1+x8_OT5j+|XKjEH9FA z;>A2c*zMO%S=r0r%}X96-SmX2jhYt4swrkMLgg%7kk+5omjz3@mHXLfxDjtNxTaEt z18~qWb-)C?F8tpbwt%^HzQ&s9XI271$tPE)2PH(=nn2yQc(?NDUk)E3+wy>D%LzIa z`Hk;Vpiw#+Riz$BN77oYkt1coE_YBX?KwFG!?saP_~j4wgVVjyQYG_H=R2g5{L=g4v*-_R|CLpZV}JqJEz731h{rXufsb*6{+)7b(CJoj)^h zJ0=wO+>OBm4T63uBfsT`@>MtRKc_m2BLrSUGWn;ZJZkYVHbHH>}9BoarOfVgz|y zkM+!M1bLJZ&%nuoTl~K+D&Um<$NF2`02PYKD8*N%jWiir>t?}QNT$BxfoR!OL2J{c zT{^?(ZOLb;Q^6Ayyudk)THe-Hv!kqzQZq9RLT{JIjH-#$5IZYMP;#~g+9~n)%j&@# z{HZ%dFacNuWCrXFT3=1CF~0nbw11QvVm{;0r#gU24oTAZ`B|E(cWnF-Rc@$k2IaV7;uRk3mm8-OfS7eAF=2#(i8b zJHrtfZ~6yf|3P)E(zyD}5e7@b!lwJ$K99(o5KD4|S`sTyjeg47th!NA`tHS$fym>` z8>2Kb0oqNy_4H)2>hgzZ4)-}_^P{d+mOohk=wq->x?K;~IK!;%8!VERIPtqoNQhfs zuWXdEUhos>>CkXr&&Q~JvCjCH7dh`)3D-3-fofRKbh&66qZ$0ZS25ez37Ly_P&S&F z=t*6)0}andO}WJU`F@o51*8wpOMdITW$-=#!2k#lAV7w$pJjHh1$uw7VnV=YqC5z_S5*X*%nQ%AY=p*^=l-<4K_@WWwyzw4~f6n};az?yxk? zxuS14yu>F-*9(F88s^^;hKMRyzbtKiVH8@LH`Lr6QRyX3>O$t}x&meZz_9{Lh#<=S zbSEln8I#BzQu)K&KNz0hwZhs3$oYM4jQqJF5m>a=hibdWD-$EgIep7M8U4rojqlS> zG-=xqGS#7!MV54-o_&6i{b>@zBT5lhXAp-;>~PJdQq8DdU)WBAK2X}5-!y=`mmMjF zp0{8DPyg63%^OCR}?IH8C69`sZv3AXE>a)v8YBO46yl4McUq2q7qBS zA$1iI3#BmX>IqS|+Q8J8D1o(vTVe^0vpmbJAuf6fC29M5k? zq)3R!d(CpLD&0y06z4P7wDuU?cjceVYXEVMOXbM!c=VsdD}^flDyt?WMfl!z7%m#} zrPRx$!Q8noT&AC~xYD+D^?xkC!$zxIiKxk8Paa2AGcTW^T4yk(xvrwGTgj4u$JK$Q zrqdVF^!h>!`(Ae*az76^+f~M_{Jharpyr?P$d}^=(&%Jg-kX1>RQ087rT@cQ-AA#> zU)=if*Gz5Sjl>*X_@bQZn38rPmCCj1{8Uy~hi9+1ivVIMu{&X;qvTX^xJ&f#(Gtn0 z;$<3-Hz)9Um`ow|X()i+GHTYR*JI1E6eZYbMTAeBc%W+cs|p>1*Bv&I-=;b3s(k$e#>v> z16rC8Wa`H(|19JkNWa$V6^v(8a z^PI@M-E;MmBA-QLqtl4eT{J(&5;?xLAa{VlsGc!&7?B(vmtXZm&NkM_^1w-_JcCqO zZn8Xlq}Wb<t%rF+7}Yb~>sgz9hbVx)@bL_vRtNoK z3T#4@NUL=K<@j`GV{>tixFMU6IcmUnqt0`5=IfUW2ysPzvJ{kBaPY52AV$h~%t zZ>H#h@#G|j=hDAP)Fxe=8KA+d@mA}V(q^)ZCtjyum#HFq^a#WI^;-LmkYo<`6&~TD zmPI^698bu^1zRl`XE`!mCE(+)aytT(B`m@jsRGI}w{!^Xpo<%8d^UQ~*?$oCgVh1WT&k=*|pd9d<9H}Ip*H!vs0 z6gu1apbrQnHq4zF_quM)Y|>a1VO&?tMSboKEs>+h>5PH~7i zp?9%EZ%Gcb2Fl%HrPh*Mp3_yCm=^%(&0Q6+%(L#34Yl0KOFW=3vlM#Zo(h;O>!g!% zGa31?jP#y!LRZdjpQ7fvsV2%JZ$yc$b^X=&!hdlKHfSn;#l$x9d9I6hKbF$}kJ@4C zH7FUbs^K4hRns zP@$T_fxxL?BGJ{Yr8q7%v1s-!T+9!9x*UD6q;y-d6Hg=SNOzZI!!!-F`ldA~WS$|D z@LMuFm)m!Z4#JO-eCnocmB{TJ#;Ha>+NvWJ+!n=y#_iVAy&E}IYnc&O`679-DBK+L z922J7^iAz{Scf``_mo1l>meOecho~<$b?EHO~yQChr9by3cwwFFtP8|ExxvLqv4{N z{Gy{vGQdKdpkOWj6xa7Gn!D=E#bU&=QzHQSiNOob|H8{NiTB;Nq%BonVxM75grez& z_*_DEcU~L7p@x&`v@k$z_L$5CcX(*=-3V1}6$;{K1sO6=mj+LyF%ZHsfs1Q+IkAAT zQX;F~1Ps{MTZ4ZlbLw&_(15jHhEzmr6N z#bvCa6E&B@lu2ynaIKoi(bM(>Ba$xtVl*8yxF87gwA|`B$=g-l94a3?Qt7ub-UZgk zqM|z8@-=<;2!uEIcZCVi$C2n6tIAZl)`{R>PSOPbMHjRhYz2r385wrKheo zw8b$AvsPjfFLPhr>lZFC&$T{6Y&;>ihG#4tvmCG(k^_pT7OK*5J(_xW+=(;xV?@|G zyisP8S7z3V-ZcJyv-=et8(Dn1EXUmmv)+Dg`CWp&&t-`Oz@uWRc~sdU@g+C2Q=kb6 zaXLal7Jm|5${FfaKtQFwH zM+uqJq*WR8I>G-@f$n9XCRjVv#@}58@&l!8DP`jC%K(<`v1bp&SI@lm+VX9YR63@- zW_ll1bs(JSf!Ki6VT;LO@O2D}>7=ICPJR6NIlScj75yAO8Dn|YIUnM|-m7ca6xztK zBwlt>D&}7=>LBM`Deg%Fz(L6Ns8ERa>=?)=Z6ycsQ(Ci#^^sfs|60XX@Dw=~6@=-!#hvE~`O{XN~1kX2mqL1*NMMN_ybA3%J(Buh3JX5A~LC z{BEvRA`8tGC@&PeS~*+MMLHwvp^Y7d{4?E@T&_1E1k^U9AiJZ*`|%LeEsS``hV3|9 z*jIljz766qCHO*nHAB&7`kk?iay`6jBK`-$IzNlIJmk=GKp^tTTQm_6qN@9aVwlUW z&G68IB^tsmbFw(`valR5&IX&C{&LCxegD*DR}@XrJG>rchQuZ&OrXw(>PHNQHY4Z; zi9?N^)QxM*RU6l4$^SQSv62oPAH)^}b0&Mn+IPz%J!ELfB%lM@CP6RsJJ|@EQ+U7l z%08VU=#-jh{^Y9)Rtp8E;8FKGw=d8fY756g{_V;SonZLfa%Cr{3{YNr;do|R&YTb4 z1`TqtuU>>Zz0VWP{W>C4ux@vzn_pbMT-l-2?P*VTafrWa?ImH1JLp6(MSreqD0mM+ z0T&#G!XSXN|6~tun{C#w)3$cK(lnBvu(gM&Vw!#Aod6V5Si0-K(fW{FlJgDNz5;(J zfQv+^W`3VbK#tD6v@(0k6+>6PRSm)N7fL;+Cg+KTEvTEhS40r-(>yBTv1yg~O5EWg z2sioupNkO&s0OS>=7|2WroW1pwvyM$1emyELcsB{Iv@QukgjSmp>R-UH&!{rH+bs-chDY&8iDP*V~ zk1s?2s<`BQNsz^b_G&5HT8Qv%Uq5kO!l{KRs{aYX0Y;PlD{r@F>B&>58`LI(r{_`_ z6WZC9lH<#4-KoBQ5SGUrzDvAkZ{N0Rht=u6sO z`5eK2yA{pOj9*qY0v7UwOiqw%`9;Uj0eRO^*<*@WYxF+ebwZNL3fd&&<7Cv2I?C(72~0J)Q&l^mSIhpN}%>T8^> z6)e?`_wgA>cJ`#&zi#I5D+3UTS2S`gc&^-@%Db#kbInXSS4#3gF_R%l%* zS)%;p3RJx=bfu9B5$t$%I_yS=sT$t~F?MeHLt=^4O;eQ{dMovNU9axwC3f$BQEq?Vz zb1AKHgM$jvRuRa3Je;?EJJ+<&0NZcgGU67libhCcExzWv4W7vZwkt{hiqBd1#!X2; z%x^n_S?x0{vTWjN?_9DIADTu^owN4>Qi_}j)J&Fo zS)*;_MpBDWdE-OpP_^b7va1pR&>AZD%AqH68n-XAIVbEge3CE3IB^;mi9A~yHqcjG zw|>YL!FuIS?QQZ-kHj;2C_u=)@!~E>PjD=aGtsQ_eyl5#*WK4vw;F7Y&i2e9ygq5C zJrP_YuqO(VwdTAvf5TYe5T05CS0cB!?PAW<(%1G4295yK=u!nc_;&6KShJ8sU~Z6l z3M&$)$N;ZQ8H?e+M}}7vtS+2K6Q3Ed?|c-hcw_Ou>#uv#NBvc4{f;`}@O$MCcy5P{4IP$o zc|QEw|6ldXB6pCzNrBsdw?k+tUm;;cohB*gcQ0gDIV4Gmj%S0~=+0rN!2FUja`aY+ zAh)iF{wjvzu2usLfaurL*8gTcyXq%a(1amvZO|lB&?(B3rCc*@@DV*B)gP}dkCO$^ zCIKm1@6vx)QYr(*@#NkZ8IbYDzO=&sr7FfGq)ZnRc?`BXLPlOUx*!}{uS5WpZX?ZG zP446~FwAWZE5xZ}@BwiHAf~M9a%d__!8P{2p~jlT3}KWkX5O-?MwTaqAtNgDdM?pm zS4&N%Ajl<0|AhUysJ528<*8e617QCiTN&dCVZv9Yu-hb?mM zV|j%|U`Dr#4ih5r36F0yrV0FibHub`O|Ut^1#H~h3ahkp2d%b61G_wLagMl_Y1zzY z%Nx&hc+)NaF3+y>2|b+ujyeq&hzC3$EFm^6yB1i>Wlc;cpeN5-3`Gxodu$Pg;Ae7o z-6uGxE49kOmwhOz1L93c`hm={5tN8+Y}}pUfY4Gq>H<)T{GY%l6HN%2YoF!Atv4fn zs@9S`vIXvyLTC`U_DiHH%Pv(+hSuGq_pHJ+BMk! z66ccFpq_<=CC^#v=RbBbvlJ;Ouhz1uO{DT4_n%!|#Wz%ELrEiULDY|(1DMnQ*ZlVl zv{kRN9lYv*`|zF?-(*=}_p-zIN&pM4(KyE#*;9Q1N#XV)pA-!Ddw|&!i7Gl}ABj$a z@=45Aie*y))n-jUHKPSf;jUzS1334&WH^6E1UMi-fbRfTEb*5DgnwCVWt*#6yTyY1 z;N9S{w3!qfH@tRN0ztoTyiiiQ@CKZ?6@x6-pR;0c2l!`f* zCpO~1?K^_0MTaQ6fHv7KGM-vR$bI}CYW+_DcCS+KTKtYSbw|xjW&6uhZ#ugFFY?kG zUsy(JJqytZ9_o~_z-LekZ((&?4I?5L13PiKRA>^^wN(RPyYT1!`5umHevYHX`Y{kK z`5@APqY{yn{49!;WQVpZaq+XqZY|XAYo8fNw~?us0001i0tGMGJk>dcvUkfqNC*R$ zIG{DrsXgbBz$n*!eTMUfe+kq(uc-zESBDDu{){Mf5e}d>oB1tq@vV6dxdPLRU7aE% zT9s^M?U(C2uQ0*Nna}gW^|=}K2QsXCvQu>1TSd31oc|H=xnSbGHTlxLmTD7{;|~@5 zk5GXwxVJD+X(pIGhf)bvS}vq%CS#P(B5`!P6D8)BYdIfG>LKFdmftjg zw!P+dCxKITjfW49YT_Sh3;4p8U(Ye46phzYYj za=O$r2Tsw^#GA8?o>v--onQc{cr*r1e!vAs8a>XoxX-Q%Q#U(sY@kAz@ZsX4X>v-yF1!i7d1^5>~m7IU2XZ z{T4)qEA1p&Qkcx(yx&%cIS)f|pkeEtP&#kj7orFCkuw=XhBu@DC7h0d zRIBT4ezzk=^+yP2ONqj}wx&bQr^ls#FE_t)x=@KT>)lmbip;XQb?b4wQokIgt}w)` zn_L$p*j~vPYyhWXTpq)|TjqqO46MVj_&zwX<}Ctp=?kIWvoWUg)~Us4$K`fELv2(ddm#|pN;is z<(eYBgsRnXQ-qJqTwuiH(uMM6QCSMY>GcPDKOP*QMjvS!a^0K0+(LJgWQ_Ww74GV+ zuJ@NdP{G$O&(=UZyKuY982=pBKV@~4ySauD?!;=~%d|A=ZwCrl53yI%QWbh~`Sy;N zu;A$E67k|XLldB2`DL0b`ZD)gM<}D9Bc<3ZY6Ypa&W&0s>+?H5XAddO!=st5Vg-UI za87)OtrP98Nh5kT$TYDaJI@?J*zPdZYU3$7&6PAtuMD#Aso>Ie)tP54m76gge%DIR zh6c2l&{+C4Lm_&+v)6Ke)+q@9Fx32q&A=qXW8-d=Df82AZQW6zpMM~q7qJ4?ok*hA zh2B9kR!$iQ;fbzAb_)CjZ#TyDf;frDHwT@y&@F=NI#xhuu;KjJ6!Y5%L0TEt2!IQH zbumB6J4A=aRSft54tD%t^Iu+4-W^fSIy2D&%}m}h=Stb^h{c&`7e~Qyjm_tCFyL1a zf&F`{_+X|@bl8H6y3q@i=x94m9mLWuJ)0VdsM%)U!V63eB6T8cptp}sV=ax6@N`&7 z+TU=lQt;WKh>>Z%=BLh@+qB;fAoRmcn#x|}4oG{Wu1^0G!jYn(Z}Kox}m8(mO! zYV-Tt4jRXI?0{}^j-#dTJUX1*6Y=Db7#+iWJx1+4OqlJ>ECpfmEM|2|zvS-z z!QBtw!+eo@NOdOqX^4Hsj~z7e)xD*qe&ciIAqf}O%=KTT)4+*+??C?(-Pjqy9zi1KG=FQ7l5mvL+g-7pqbuPtvPXWCj3i0U_O?)#Uia1UAy#TXq>XYhNIJ zRht0?E2q?CX`!WtIdD?zADQ+g)Hk9+)BOP2G3wg?vE)`MslM6xDBwOzSG~&C-I_@8 zwE$7eqGn$Q9W8kEO`K4x=*!e(y0+*4-Q z=o=4Oi>47X3VAr1+I?ngFn`sx1CwTHQ>Uh~i7C+`wv`XV>5+h4h}Hs4qg-Fp2z7c# zFML>f=YK_4P0lN`5k_v=nLpFcOsDmC64Y{{-_u4d61O0*%BiY}31XWa;D(!DODJh? zwe$+Meg!_itom8!%t+8E$PrCbin!a}2O~kLBv`2-_k2oNSi61R*jUW~{Eaau55ap; zMw+byrw{ZqdkK~JqcEFk)*bKfP(%nMB%j!iQ0bXFx z-G0&^xtjEs-zMOVL9zz($UgpV@h$b!((-~Os7hng{ve%|VyhP%*Z}3%v`wy)NE5hs z&-&eEbqc-FGHR(De4x7vX}sEQcFzmVO=qoN7n{q(xOUMyK7aa*3W7ac)axZ9%L2u; zmyS-B7v?m~mlq9yoq&1jI*_wTfttl=xitk3p1x-5chIkOQ;^x>_*^?DidL5OyOWt6P&bJd2Y`QAN*{5I{bGqla08NTnR#Zvm=&1xx5A|k&R+L;zO z2jKpxUvM(F=v*0s8YkUu3@TcSL+p3zel7Lh(rqZhYsgG(PjRo4+Lwc(-Ae#lE0EzK zNf8mCZIceE7h1_}67=e*T=Kq8ojHqQZ|k@1UW9V>{XDc#&M+*}o{f6Yg+=!DqsX3?$g3apEB9Um(A zpjHH@HjG+3&Je(zGj?gjls1YunBhkjp!*zS9rALJ11`a7Uk%k%%ht2*Vcs33d!fwr z#F$srH^-7O%$kO)^PbZh#OAOEDl4{*%;hYFNNfv=D#}~i&3&FmC&?AvR|yf4dM>n5 z7oxjDHb1|5{Ok=o&XZBB#U>U93&J^eEitpyoHa)k4*j=5UPnJL)K4o#E0df{8$8#i z=-395O{xcysV3?wRJEL=*&rY{zMwAvIojiE`(A&;9@^J!b)nl8nu#GccFR_U|E`7k znSGicyf4};$zJ+CoM>iG!d-pO7R+|J1Jew9j@Ft5M1>wbU-!_+cd^nKYFbs8!Ufx_ ze6`KO0h}b(Dklk%TpvY3>HvWP1PBl#XIX>h$;lwV)^+>W0!dSU@4{rZj{BL`9$4GB z#n-P{2M!yBC`<>LVTT!cj6iV+`hCM*lhVtOEy6Ufk~6%PXQ*k%PfCs*#U@xhsKB;# zcHr6h$@A(bw2+=-vvZRfcNlFV3%fJpm?X{rdrjW%3}ZL}$Wl$D?%G)qW$=`A17Ly5 z#@CY}VaQ9A)>sxz;8+L|i8z06q8{Ctjq-n10c)_%d8E2-*sX3PeyJfEdV-jMaf)L| z=TY{j1&vwo`{)VyjfV)ir5&JZ^A$br7cJf#P?@vQc)NUv3E|J&_xS1bWLb^1dZQoF zGT?b)d&yL{PQAU1J!OfYeiW7uhv4vZPFJZSFc+~p3@BY#e+7o>A*SkD_ zHkw};T)O!G{Z}Fn{o}NJVt|umP_dtHEpZKF0o?b%+WB!R-QJB(I?N+Hn%E!qhB$~_ zu%qf}bo%1Xl8;1Xc5gwZy8B8l&(+IQtXBuXFpB|w16W#xsJtL@YN04}ndEZas`+kA zJX{zP*F?<3i~o;S00q{UbKYB-9m4xon{@9S%x!Q0Tp6j0r zKIw&zXEMUrXjP{%?uUs~_gj1EtJLzG#`RMFUR9W@mC6-JD%0K+R7kvNS{ z^FM*Ae7@7)D&9>uVM|3^dhcx`q?;GfI+1dv1UMc%Vij|9JB}q6b~u6U(cn zJH!o>Svo#SvV+Q{^uM;lUWZ`>2oNAZfmVK($@I1g01AQHixeeO*Q*t>!+N31Ph|Bx zGLu^twPg{Fy;*^cc@aY<@+%2+Ce_#)xgssQDo>BV1w*V- z(wleC=<-KC!5VanMvQ@OR<>*2EM8Ujq{5hxyKGwD1FFW0H&Jl=g$CH%z}mD7Yu(dv z?2E@s;|H(6(5tntnd#Vt4l&E-@91V4nYx=HX@fUWa_B8dBb<_h0YqKp8%M|n@%@39 zyo?$p`VvvxGRO||*!bi>pP6F<(jF~Um4}s~!)&&N$SS|I2TGiB*d|s;XxX|?GC`tM zuQb=MHv!)zuy1@-=uOje%Y8SQj+Vef1>*iy4`I@eqg&t@t9^lwQcCOk@{u z{|9a`=Z^5=1e2s2Z=h$d7CtpH6@G&+VZ9-md8{prEH*vI;M^y%)=gE4TPdt?&rcw4 zhX`ahwlX6J?J?&(xr{{0pmiA5mZPm?f&y8#5PE$*-PMGTvGoM@cQe|9a;L%MNxDGH zPItG>Np-(#^vbvO zYlkPNa&>c(=5}Q?L()|JtMBPnFnoSyD=J*2_@S`Qiju9l=kE+ZTVV+N^Z3Xx(^v)c z5WVqznmd(W+;tmQ62VK!J3k2qIZFsbAhIi~%bFMz5!+U`hjw<1C-76K!Acftr~L@= z_D5Y@Yn)aqA07kx#-{v8f~d&2n&!CuD)^OPgGu^YTVDori{ceo-4X2Yba!~bt<{<8 z>TMp5fJh4&P39#~7<(f<_lx%{Eh<;OYQM1@(<~|uA)4yU3Zl7ja{|%X%TtoMyYRpe z$(L@>daFcLhvldIS>r#cI06I!000000aUy?5J>D?Wl5R~m`n%HTUvVZJ{N*w8(Lh{ z^_#Ko~Xplcg?!2@UUQ z=1B;g&Dm9zy3=xYiF>)`U_;pefc-`yAIuk`d63N fn*wjQQLZMzvf=dzVx*Eu|Ha&qP81{s>dU*pKfkT7 diff --git a/integration/bip0009_test.go b/integration/bip0009_test.go index fa94d2d0..e22fdaba 100644 --- a/integration/bip0009_test.go +++ b/integration/bip0009_test.go @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. // This file is ignored during the regular tests due to the following build tag. +//go:build rpctest // +build rpctest package integration @@ -129,7 +130,7 @@ func assertSoftForkStatus(r *rpctest.Harness, t *testing.T, forkKey string, stat // specific soft fork deployment to test. func testBIP0009(t *testing.T, forkKey string, deploymentID uint32) { // Initialize the primary mining node with only the genesis block. - r, err := rpctest.New(&chaincfg.RegressionNetParams, nil, nil, "") + r, err := rpctest.New(&chaincfg.SimNetParams, nil, nil, "") if err != nil { t.Fatalf("unable to create primary harness: %v", err) } @@ -320,7 +321,7 @@ func TestBIP0009Mining(t *testing.T) { t.Parallel() // Initialize the primary mining node with only the genesis block. - r, err := rpctest.New(&chaincfg.SimNetParams, nil, nil, "") + r, err := rpctest.New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatalf("unable to create primary harness: %v", err) } diff --git a/integration/csv_fork_test.go b/integration/csv_fork_test.go index 1b4ae02b..ac8512e0 100644 --- a/integration/csv_fork_test.go +++ b/integration/csv_fork_test.go @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. // This file is ignored during the regular tests due to the following build tag. +//go:build rpctest // +build rpctest package integration @@ -113,13 +114,13 @@ func TestBIP0113Activation(t *testing.T) { if err != nil { t.Fatal("unable to create primary harness: ", err) } - if err := r.SetUp(true, 1); err != nil { + if err := r.SetUp(true, 10); err != nil { t.Fatalf("unable to setup test chain: %v", err) } defer r.TearDown() // Create a fresh output for usage within the test below. - const outputValue = btcutil.SatoshiPerBitcoin + const outputValue = btcutil.SatoshiPerBitcoin / 50 outputKey, testOutput, testPkScript, err := makeTestOutput(r, t, outputValue) if err != nil { @@ -189,7 +190,7 @@ func TestBIP0113Activation(t *testing.T) { // to create a single mature output, then an additional block to create // a new output, and then mined a single block above to include our // transaction. - assertChainHeight(r, t, 103) + assertChainHeight(r, t, 112) // Next, mine enough blocks to ensure that the soft-fork becomes // activated. Assert that the block version of the second-to-last block @@ -205,7 +206,7 @@ func TestBIP0113Activation(t *testing.T) { t.Fatalf("unable to generate blocks: %v", err) } - assertChainHeight(r, t, 299) + assertChainHeight(r, t, 308) assertSoftForkStatus(r, t, csvKey, blockchain.ThresholdActive) // The timeLockDeltas slice represents a series of deviations from the @@ -426,7 +427,7 @@ func TestBIP0068AndBIP0112Activation(t *testing.T) { } const ( - outputAmt = btcutil.SatoshiPerBitcoin + outputAmt = btcutil.SatoshiPerBitcoin / 50 relativeBlockLock = 10 ) diff --git a/integration/rpcserver_test.go b/integration/rpcserver_test.go index 9fbddc6b..2ed6b408 100644 --- a/integration/rpcserver_test.go +++ b/integration/rpcserver_test.go @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. // This file is ignored during the regular tests due to the following build tag. +//go:build rpctest // +build rpctest package integration diff --git a/integration/rpctest/blockgen.go b/integration/rpctest/blockgen.go index dae3b7fd..afa35896 100644 --- a/integration/rpctest/blockgen.go +++ b/integration/rpctest/blockgen.go @@ -44,7 +44,7 @@ func solveBlock(header *wire.BlockHeader, targetDifficulty *big.Int) bool { return default: hdr.Nonce = i - hash := hdr.BlockHash() + hash := hdr.BlockPoWHash() if blockchain.HashToBig(&hash).Cmp(targetDifficulty) <= 0 { select { case results <- sbResult{true, i}: @@ -205,6 +205,7 @@ func CreateBlock(prevBlock *btcutil.Block, inclusionTxs []*btcutil.Tx, MerkleRoot: *merkles[len(merkles)-1], Timestamp: ts, Bits: net.PowLimitBits, + ClaimTrie: chainhash.Hash{1}, // EmptyTrieHash } for _, tx := range blockTxns { if err := block.AddTransaction(tx.MsgTx()); err != nil { diff --git a/integration/rpctest/rpc_harness.go b/integration/rpctest/rpc_harness.go index 1d1eaefa..17603aa7 100644 --- a/integration/rpctest/rpc_harness.go +++ b/integration/rpctest/rpc_harness.go @@ -256,11 +256,11 @@ func (h *Harness) SetUp(createTestChain bool, numMatureOutputs uint32) error { return err } + numToGenerate := uint32(0) // Create a test chain with the desired number of mature coinbase // outputs. if createTestChain && numMatureOutputs != 0 { - numToGenerate := (uint32(h.ActiveNet.CoinbaseMaturity) + - numMatureOutputs) + numToGenerate = uint32(h.ActiveNet.CoinbaseMaturity) + numMatureOutputs _, err := h.Client.Generate(numToGenerate) if err != nil { return err @@ -273,6 +273,9 @@ func (h *Harness) SetUp(createTestChain bool, numMatureOutputs uint32) error { if err != nil { return err } + if numToGenerate > 0 && uint32(height) < numToGenerate { + return fmt.Errorf("failed to generate this many blocks: %d", numToGenerate) + } ticker := time.NewTicker(time.Millisecond * 100) for range ticker.C { walletHeight := h.wallet.SyncedHeight() diff --git a/integration/rpctest/rpc_harness_test.go b/integration/rpctest/rpc_harness_test.go index de9db318..bfb3ceb1 100644 --- a/integration/rpctest/rpc_harness_test.go +++ b/integration/rpctest/rpc_harness_test.go @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. // This file is ignored during the regular tests due to the following build tag. +//go:build rpctest // +build rpctest package rpctest @@ -63,7 +64,7 @@ func testSendOutputs(r *Harness, t *testing.T) { // First, generate a small spend which will require only a single // input. - txid := genSpend(btcutil.Amount(5 * btcutil.SatoshiPerBitcoin)) + txid := genSpend(btcutil.Amount(btcutil.SatoshiPerBitcoin)) // Generate a single block, the transaction the wallet created should // be found in this block. @@ -75,7 +76,7 @@ func testSendOutputs(r *Harness, t *testing.T) { // Next, generate a spend much greater than the block reward. This // transaction should also have been mined properly. - txid = genSpend(btcutil.Amount(500 * btcutil.SatoshiPerBitcoin)) + txid = genSpend(btcutil.Amount(10 * btcutil.SatoshiPerBitcoin)) blockHashes, err = r.Client.Generate(1) if err != nil { t.Fatalf("unable to generate single block: %v", err) @@ -105,7 +106,7 @@ func assertConnectedTo(t *testing.T, nodeA *Harness, nodeB *Harness) { func testConnectNode(r *Harness, t *testing.T) { // Create a fresh test harness. - harness, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -153,7 +154,7 @@ func testActiveHarnesses(r *Harness, t *testing.T) { numInitialHarnesses := len(ActiveHarnesses()) // Create a single test harness. - harness1, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness1, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -181,7 +182,7 @@ func testJoinMempools(r *Harness, t *testing.T) { // Create a local test harness with only the genesis block. The nodes // will be synced below so the same transaction can be sent to both // nodes without it being an orphan. - harness, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -281,7 +282,7 @@ func testJoinMempools(r *Harness, t *testing.T) { func testJoinBlocks(r *Harness, t *testing.T) { // Create a second harness with only the genesis block so it is behind // the main harness. - harness, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -335,7 +336,7 @@ func testGenerateAndSubmitBlock(r *Harness, t *testing.T) { if err != nil { t.Fatalf("unable to create script: %v", err) } - output := wire.NewTxOut(btcutil.SatoshiPerBitcoin, pkScript) + output := wire.NewTxOut(btcutil.SatoshiPerBitcoin/50, pkScript) const numTxns = 5 txns := make([]*btcutil.Tx, 0, numTxns) @@ -469,7 +470,7 @@ func testGenerateAndSubmitBlockWithCustomCoinbaseOutputs(r *Harness, func testMemWalletReorg(r *Harness, t *testing.T) { // Create a fresh harness, we'll be using the main harness to force a // re-org on this local harness. - harness, err := New(&chaincfg.SimNetParams, nil, nil, "") + harness, err := New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { t.Fatal(err) } @@ -478,8 +479,8 @@ func testMemWalletReorg(r *Harness, t *testing.T) { } defer harness.TearDown() - // The internal wallet of this harness should now have 250 BTC. - expectedBalance := btcutil.Amount(250 * btcutil.SatoshiPerBitcoin) + // The internal wallet of this harness should now have 250 BTC, but BTC is 50x LBC per generated coin. + expectedBalance := btcutil.Amount(5 * btcutil.SatoshiPerBitcoin) walletBalance := harness.ConfirmedBalance() if expectedBalance != walletBalance { t.Fatalf("wallet balance incorrect: expected %v, got %v", @@ -520,7 +521,7 @@ func testMemWalletLockedOutputs(r *Harness, t *testing.T) { if err != nil { t.Fatalf("unable to create script: %v", err) } - outputAmt := btcutil.Amount(50 * btcutil.SatoshiPerBitcoin) + outputAmt := btcutil.Amount(btcutil.SatoshiPerBitcoin) output := wire.NewTxOut(int64(outputAmt), pkScript) tx, err := r.CreateTransaction([]*wire.TxOut{output}, 10, true) if err != nil { @@ -566,7 +567,7 @@ const ( func TestMain(m *testing.M) { var err error - mainHarness, err = New(&chaincfg.SimNetParams, nil, nil, "") + mainHarness, err = New(&chaincfg.RegressionNetParams, nil, nil, "") if err != nil { fmt.Println("unable to create main harness: ", err) os.Exit(1) @@ -601,9 +602,7 @@ func TestMain(m *testing.M) { } func TestHarness(t *testing.T) { - // We should have (numMatureOutputs * 50 BTC) of mature unspendable - // outputs. - expectedBalance := btcutil.Amount(numMatureOutputs * 50 * btcutil.SatoshiPerBitcoin) + expectedBalance := btcutil.Amount(numMatureOutputs * btcutil.SatoshiPerBitcoin) harnessBalance := mainHarness.ConfirmedBalance() if harnessBalance != expectedBalance { t.Fatalf("expected wallet balance of %v instead have %v", diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index b24045ba..b4070dd7 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -1457,7 +1457,7 @@ func TestAncestorsDescendants(t *testing.T) { func TestRBF(t *testing.T) { t.Parallel() - const defaultFee = btcutil.SatoshiPerBitcoin + const defaultFee = btcutil.SatoshiPerBitcoin / 50 testCases := []struct { name string diff --git a/mempool/policy.go b/mempool/policy.go index 21899b0f..e91ce260 100644 --- a/mempool/policy.go +++ b/mempool/policy.go @@ -176,6 +176,8 @@ func checkPkScriptStandard(pkScript []byte, scriptClass txscript.ScriptClass) er // GetDustThreshold calculates the dust limit for a *wire.TxOut by taking the // size of a typical spending transaction and multiplying it by 3 to account // for the minimum dust relay fee of 3000sat/kvb. +const dustCap = math.MaxInt64 / 1001 + func GetDustThreshold(txOut *wire.TxOut) int64 { // The total serialized size consists of the output and the associated // input script to redeem it. Since there is no input script @@ -273,6 +275,9 @@ func IsDust(txOut *wire.TxOut, minRelayTxFee btcutil.Amount) bool { // // The following is equivalent to (value/totalSize) * (1/3) * 1000 // without needing to do floating point math. + if txOut.Value > dustCap { + return false + } return txOut.Value*1000/GetDustThreshold(txOut) < int64(minRelayTxFee) } diff --git a/mempool/policy_test.go b/mempool/policy_test.go index b677ab82..5e4d4ff0 100644 --- a/mempool/policy_test.go +++ b/mempool/policy_test.go @@ -48,7 +48,7 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) { { "max standard tx size with max satoshi relay fee", maxStandardTxWeight / 4, - btcutil.MaxSatoshi, + btcutil.MaxSatoshi / 100, // overflow on purpose btcutil.MaxSatoshi, }, { @@ -252,11 +252,11 @@ func TestDust(t *testing.T) { false, }, { - // Maximum int64 value causes overflow. + // Maximum int64 value causes overflow if we're not careful "maximum int64 value", wire.TxOut{Value: 1<<63 - 1, PkScript: pkScript}, 1<<63 - 1, - true, + false, }, { // Unspendable pkScript due to an invalid public key diff --git a/peer/peer_test.go b/peer/peer_test.go index 0cb9c66c..4a2a0048 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -519,7 +519,7 @@ func TestPeerListeners(t *testing.T) { { "OnBlock", wire.NewMsgBlock(wire.NewBlockHeader(1, - &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), + &chainhash.Hash{}, &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), }, { "OnInv", @@ -585,7 +585,7 @@ func TestPeerListeners(t *testing.T) { { "OnMerkleBlock", wire.NewMsgMerkleBlock(wire.NewBlockHeader(1, - &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), + &chainhash.Hash{}, &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), }, // only one version message is allowed // only one verack message is allowed diff --git a/txscript/data/script_tests.json b/txscript/data/script_tests.json index 5c054ed3..4a0717dc 100644 --- a/txscript/data/script_tests.json +++ b/txscript/data/script_tests.json @@ -232,8 +232,8 @@ ["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC", "OK"], -["1","NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], +["1","NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], ["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "OK", "Discourage NOPx flag allows OP_NOP"], @@ -446,9 +446,6 @@ ["NOP", "CHECKSEQUENCEVERIFY 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP4 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP5 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP6 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP7 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP8 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP9 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP10 1", "P2SH,STRICTENC", "OK"], @@ -857,8 +854,8 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["1", "NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["1", "NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], ["Ensure 100% coverage of discouraged NOPS"], ["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], @@ -866,9 +863,6 @@ ["1", "CHECKSEQUENCEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], @@ -957,16 +951,6 @@ ["NOP", "HASH160", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], ["NOP", "HASH256", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], -["NOP", -"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", -"P2SH,STRICTENC", -"PUSH_SIZE", -">520 byte push"], -["0", -"IF 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ENDIF 1", -"P2SH,STRICTENC", -"PUSH_SIZE", -">520 byte push in non-executed IF branch"], ["1", "0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", "P2SH,STRICTENC", @@ -987,11 +971,6 @@ "P2SH,STRICTENC", "STACK_SIZE", ">1,000 stack+altstack size"], -["NOP", -"0 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", -"P2SH,STRICTENC", -"SCRIPT_SIZE", -"10,001-byte scriptPubKey"], ["NOP1","NOP10", "P2SH,STRICTENC", "EVAL_FALSE"], @@ -1786,28 +1765,28 @@ "2-of-2 with two identical keys and sigs pushed using OP_DUP" ], [ - "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP4 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "", "OK", "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY" ], [ - "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 NOP8", + "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 NOP4", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "", "OK", "P2PK with non-push scriptSig but with P2SH validation" ], [ - "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP4 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "P2SH", "SIG_PUSHONLY", "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY" ], [ - "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP8 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x47 0x3044022018a2a81a93add5cb5f5da76305718e4ea66045ec4888b28d84cb22fae7f4645b02201e6daa5ed5d2e4b2b2027cf7ffd43d8d9844dd49f74ef86899ec8e669dfd39aa01 NOP4 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", "HASH160 0x14 0x215640c2f72f0d16b4eced26762035a42ffed39a EQUAL", "SIGPUSHONLY", "SIG_PUSHONLY", diff --git a/txscript/data/tx_invalid.json b/txscript/data/tx_invalid.json index db465109..393d447b 100644 --- a/txscript/data/tx_invalid.json +++ b/txscript/data/tx_invalid.json @@ -275,10 +275,6 @@ ["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], "0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151540b00000000000001510002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], -["Witness with a push of 521 bytes"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349", 1000]], -"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015102fd0902000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002755100000000", "P2SH,WITNESS"], - ["Witness with unknown version which push false on the stack should be invalid (even without DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x02 0x0000", 2000]], "0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015101010100000000", "P2SH,WITNESS"], diff --git a/txscript/example_test.go b/txscript/example_test.go index 82a11799..6f9dc16b 100644 --- a/txscript/example_test.go +++ b/txscript/example_test.go @@ -25,7 +25,7 @@ func ExamplePayToAddrScript() { // which is useful to ensure the accuracy of the address and determine // the address type. It is also required for the upcoming call to // PayToAddrScript. - addressStr := "12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV" + addressStr := "bHW58d37s1hBjj3wPBkn5zpCX3F8ZW3uWf" address, err := btcutil.DecodeAddress(addressStr, &chaincfg.MainNetParams) if err != nil { fmt.Println(err) @@ -48,8 +48,8 @@ func ExamplePayToAddrScript() { fmt.Println("Script Disassembly:", disasm) // Output: - // Script Hex: 76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac - // Script Disassembly: OP_DUP OP_HASH160 128004ff2fcaf13b2b91eb654b1dc2b674f7ec61 OP_EQUALVERIFY OP_CHECKSIG + // Script Hex: 76a914345991dbf57bfb014b87006acdfafbfc5fe8292f88ac + // Script Disassembly: OP_DUP OP_HASH160 345991dbf57bfb014b87006acdfafbfc5fe8292f OP_EQUALVERIFY OP_CHECKSIG } // This example demonstrates extracting information from a standard public key @@ -76,7 +76,7 @@ func ExampleExtractPkScriptAddrs() { // Output: // Script Class: pubkeyhash - // Addresses: [12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV] + // Addresses: [bER6Ddq6YfRKDJDmmdeaqrP8XHmDJcYSJQ] // Required Signatures: 1 } diff --git a/txscript/opcode_test.go b/txscript/opcode_test.go index 91263c21..86d08838 100644 --- a/txscript/opcode_test.go +++ b/txscript/opcode_test.go @@ -117,6 +117,12 @@ func TestOpcodeDisasm(t *testing.T) { case 0xb2: // OP_NOP3 is an alias of OP_CHECKSEQUENCEVERIFY expectedStr = "OP_CHECKSEQUENCEVERIFY" + case OP_CLAIMNAME: + expectedStr = "OP_CLAIMNAME" + case OP_SUPPORTCLAIM: + expectedStr = "OP_SUPPORTCLAIM" + case OP_UPDATECLAIM: + expectedStr = "OP_UPDATECLAIM" default: val := byte(opcodeVal - (0xb0 - 1)) expectedStr = "OP_NOP" + strconv.Itoa(int(val)) @@ -184,6 +190,12 @@ func TestOpcodeDisasm(t *testing.T) { case 0xb2: // OP_NOP3 is an alias of OP_CHECKSEQUENCEVERIFY expectedStr = "OP_CHECKSEQUENCEVERIFY" + case OP_CLAIMNAME: + expectedStr = "OP_CLAIMNAME" + case OP_SUPPORTCLAIM: + expectedStr = "OP_SUPPORTCLAIM" + case OP_UPDATECLAIM: + expectedStr = "OP_UPDATECLAIM" default: val := byte(opcodeVal - (0xb0 - 1)) expectedStr = "OP_NOP" + strconv.Itoa(int(val)) diff --git a/txscript/scriptbuilder_test.go b/txscript/scriptbuilder_test.go index 89f2b861..0bb67aa1 100644 --- a/txscript/scriptbuilder_test.go +++ b/txscript/scriptbuilder_test.go @@ -220,19 +220,10 @@ func TestScriptBuilderAddData(t *testing.T) { expected: append([]byte{OP_PUSHDATA2, 0, 1}, bytes.Repeat([]byte{0x49}, 256)...), }, { - name: "push data len 520", + name: "push data len 520", // bitcoin has a 520 byte cap, but lbry is 20k data: bytes.Repeat([]byte{0x49}, 520), expected: append([]byte{OP_PUSHDATA2, 0x08, 0x02}, bytes.Repeat([]byte{0x49}, 520)...), }, - - // BIP0062: OP_PUSHDATA4 can never be used, as pushes over 520 - // bytes are not allowed, and those below can be done using - // other operators. - { - name: "push data len 521", - data: bytes.Repeat([]byte{0x49}, 521), - expected: nil, - }, { name: "push data len 32767 (canonical)", data: bytes.Repeat([]byte{0x49}, 32767), diff --git a/wire/bench_test.go b/wire/bench_test.go index 1eb6c413..42caac86 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -419,7 +419,7 @@ func BenchmarkDecodeHeaders(b *testing.B) { if err != nil { b.Fatalf("NewHashFromStr: unexpected error: %v", err) } - m.AddBlockHeader(NewBlockHeader(1, hash, hash, 0, uint32(i))) + m.AddBlockHeader(NewBlockHeader(1, hash, hash, hash, 0, uint32(i))) } // Serialize it so the bytes are available to test the decode below. @@ -565,7 +565,7 @@ func BenchmarkDecodeMerkleBlock(b *testing.B) { if err != nil { b.Fatalf("NewHashFromStr: unexpected error: %v", err) } - m.Header = *NewBlockHeader(1, hash, hash, 0, uint32(10000)) + m.Header = *NewBlockHeader(1, hash, hash, hash, 0, uint32(10000)) for i := 0; i < 105; i++ { hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i)) if err != nil { diff --git a/wire/blockheader.go b/wire/blockheader.go index 372b7b46..4019c179 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -45,7 +45,7 @@ type BlockHeader struct { // blockHeaderLen is a constant that represents the number of bytes for a block // header. -const blockHeaderLen = 80 +const blockHeaderLen = 112 // BlockHash computes the block identifier hash for the given block header. func (h *BlockHeader) BlockHash() chainhash.Hash { diff --git a/wire/blockheader_test.go b/wire/blockheader_test.go index fef06967..66e37d6c 100644 --- a/wire/blockheader_test.go +++ b/wire/blockheader_test.go @@ -24,7 +24,7 @@ func TestBlockHeader(t *testing.T) { hash := mainNetGenesisHash merkleHash := mainNetGenesisMerkleRoot bits := uint32(0x1d00ffff) - bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bh := NewBlockHeader(1, &hash, &merkleHash, &merkleHash, bits, nonce) // Ensure we get the same data back out. if !bh.PrevBlock.IsEqual(&hash) { @@ -57,10 +57,12 @@ func TestBlockHeaderWire(t *testing.T) { Version: 1, PrevBlock: mainNetGenesisHash, MerkleRoot: mainNetGenesisMerkleRoot, + ClaimTrie: mainNetGenesisMerkleRoot, Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Bits: bits, Nonce: nonce, } + baseBlockHdr.ClaimTrie[0] = 0x33 // baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr. baseBlockHdrEncoded := []byte{ @@ -73,6 +75,10 @@ func TestBlockHeaderWire(t *testing.T) { 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot + 0x33, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, + 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, + 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // ClaimTrie 0x29, 0xab, 0x5f, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0xf3, 0xe0, 0x01, 0x00, // Nonce @@ -196,10 +202,12 @@ func TestBlockHeaderSerialize(t *testing.T) { Version: 1, PrevBlock: mainNetGenesisHash, MerkleRoot: mainNetGenesisMerkleRoot, + ClaimTrie: mainNetGenesisMerkleRoot, Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Bits: bits, Nonce: nonce, } + baseBlockHdr.ClaimTrie[0] = 0x33 // baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr. baseBlockHdrEncoded := []byte{ @@ -212,6 +220,10 @@ func TestBlockHeaderSerialize(t *testing.T) { 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot + 0x33, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, + 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, + 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // ClaimTrie 0x29, 0xab, 0x5f, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0xf3, 0xe0, 0x01, 0x00, // Nonce diff --git a/wire/common_test.go b/wire/common_test.go index d71cc9c9..f76cc4db 100644 --- a/wire/common_test.go +++ b/wire/common_test.go @@ -127,7 +127,7 @@ func TestElementWire(t *testing.T) { }, { MainNet, - []byte{0xf9, 0xbe, 0xb4, 0xd9}, + []byte{0xfa, 0xe4, 0xaa, 0xf1}, }, // Type not supported by the "fast" path and requires reflection. { diff --git a/wire/message_test.go b/wire/message_test.go index b2ae3f63..65754b41 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -66,7 +66,7 @@ func TestMessage(t *testing.T) { msgFilterAdd := NewMsgFilterAdd([]byte{0x01}) msgFilterClear := NewMsgFilterClear() msgFilterLoad := NewMsgFilterLoad([]byte{0x01}, 10, 0, BloomUpdateNone) - bh := NewBlockHeader(1, &chainhash.Hash{}, &chainhash.Hash{}, 0, 0) + bh := NewBlockHeader(1, &chainhash.Hash{}, &chainhash.Hash{}, &chainhash.Hash{}, 0, 0) msgMerkleBlock := NewMsgMerkleBlock(bh) msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block") msgGetCFilters := NewMsgGetCFilters(GCSFilterRegular, 0, &chainhash.Hash{}) @@ -89,7 +89,7 @@ func TestMessage(t *testing.T) { {msgGetAddr, msgGetAddr, pver, MainNet, 24}, {msgAddr, msgAddr, pver, MainNet, 25}, {msgGetBlocks, msgGetBlocks, pver, MainNet, 61}, - {msgBlock, msgBlock, pver, MainNet, 239}, + {msgBlock, msgBlock, pver, MainNet, 271}, {msgInv, msgInv, pver, MainNet, 25}, {msgGetData, msgGetData, pver, MainNet, 25}, {msgNotFound, msgNotFound, pver, MainNet, 25}, @@ -103,7 +103,7 @@ func TestMessage(t *testing.T) { {msgFilterAdd, msgFilterAdd, pver, MainNet, 26}, {msgFilterClear, msgFilterClear, pver, MainNet, 24}, {msgFilterLoad, msgFilterLoad, pver, MainNet, 35}, - {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 110}, + {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 142}, {msgReject, msgReject, pver, MainNet, 79}, {msgGetCFilters, msgGetCFilters, pver, MainNet, 61}, {msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61}, diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index b76220b3..c2f92bad 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -24,7 +24,7 @@ func TestBlock(t *testing.T) { merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce - bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) + bh := NewBlockHeader(1, prevHash, merkleHash, merkleHash, bits, nonce) // Ensure the command is expected value. wantCmd := "block" @@ -92,7 +92,7 @@ func TestBlockTxHashes(t *testing.T) { // TestBlockHash tests the ability to generate the hash of a block accurately. func TestBlockHash(t *testing.T) { // Block 1 hash. - hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048" + hashStr := "a6b9bbfdd71af02426d2fc8131cfb843a27946e1f660a9dbca7556a0bb4a8ce2" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewHashFromStr: %v", err) @@ -224,15 +224,15 @@ func TestBlockWireErrors(t *testing.T) { // Force error in merkle root. {&blockOne, blockOneBytes, pver, BaseEncoding, 36, io.ErrShortWrite, io.EOF}, // Force error in timestamp. - {&blockOne, blockOneBytes, pver, BaseEncoding, 68, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 68 + 32, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - {&blockOne, blockOneBytes, pver, BaseEncoding, 72, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 72 + 32, io.ErrShortWrite, io.EOF}, // Force error in header nonce. - {&blockOne, blockOneBytes, pver, BaseEncoding, 76, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 76 + 32, io.ErrShortWrite, io.EOF}, // Force error in transaction count. - {&blockOne, blockOneBytes, pver, BaseEncoding, 80, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 80 + 32, io.ErrShortWrite, io.EOF}, // Force error in transactions. - {&blockOne, blockOneBytes, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 81 + 32, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -342,15 +342,15 @@ func TestBlockSerializeErrors(t *testing.T) { // Force error in merkle root. {&blockOne, blockOneBytes, 36, io.ErrShortWrite, io.EOF}, // Force error in timestamp. - {&blockOne, blockOneBytes, 68, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 68 + 32, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - {&blockOne, blockOneBytes, 72, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 72 + 32, io.ErrShortWrite, io.EOF}, // Force error in header nonce. - {&blockOne, blockOneBytes, 76, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 76 + 32, io.ErrShortWrite, io.EOF}, // Force error in transaction count. - {&blockOne, blockOneBytes, 80, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 80 + 32, io.ErrShortWrite, io.EOF}, // Force error in transactions. - {&blockOne, blockOneBytes, 81, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 81 + 32, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -413,6 +413,10 @@ func TestBlockOverflowErrors(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -465,7 +469,7 @@ func TestBlockSerializeSize(t *testing.T) { size int // Expected serialized size }{ // Block with no transactions. - {noTxBlock, 81}, + {noTxBlock, 81 + 32}, // First block in the mainnet block chain. {&blockOne, len(blockOneBytes)}, @@ -498,6 +502,12 @@ var blockOne = MsgBlock{ 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, }), + ClaimTrie: chainhash.Hash([chainhash.HashSize]byte{ + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, + }), Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST Bits: 0x1d00ffff, // 486604799 @@ -552,6 +562,10 @@ var blockOneBytes = []byte{ 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -585,5 +599,5 @@ var blockOneBytes = []byte{ // Transaction location information for block one transactions. var blockOneTxLocs = []TxLoc{ - {TxStart: 81, TxLen: 134}, + {TxStart: 81 + 32, TxLen: 134}, } diff --git a/wire/msgheaders_test.go b/wire/msgheaders_test.go index 9b94545b..0501bc7e 100644 --- a/wire/msgheaders_test.go +++ b/wire/msgheaders_test.go @@ -28,7 +28,7 @@ func TestHeaders(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num headers (varInt) + max allowed headers (header length + 1 byte // for the number of transactions which is always 0). - wantPayload := uint32(162009) + wantPayload := uint32(226009) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ @@ -64,7 +64,7 @@ func TestHeadersWire(t *testing.T) { merkleHash := blockOne.Header.MerkleRoot bits := uint32(0x1d00ffff) nonce := uint32(0x9962e301) - bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bh := NewBlockHeader(1, &hash, &merkleHash, &merkleHash, bits, nonce) bh.Version = blockOne.Header.Version bh.Timestamp = blockOne.Header.Timestamp @@ -88,6 +88,10 @@ func TestHeadersWire(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -232,7 +236,7 @@ func TestHeadersWireErrors(t *testing.T) { merkleHash := blockOne.Header.MerkleRoot bits := uint32(0x1d00ffff) nonce := uint32(0x9962e301) - bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bh := NewBlockHeader(1, &hash, &merkleHash, &merkleHash, bits, nonce) bh.Version = blockOne.Header.Version bh.Timestamp = blockOne.Header.Timestamp @@ -250,6 +254,10 @@ func TestHeadersWireErrors(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -269,7 +277,7 @@ func TestHeadersWireErrors(t *testing.T) { // Intentionally invalid block header that has a transaction count used // to force errors. - bhTrans := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bhTrans := NewBlockHeader(1, &hash, &merkleHash, &merkleHash, bits, nonce) bhTrans.Version = blockOne.Header.Version bhTrans.Timestamp = blockOne.Header.Timestamp @@ -286,6 +294,10 @@ func TestHeadersWireErrors(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -309,7 +321,7 @@ func TestHeadersWireErrors(t *testing.T) { // Force error with greater than max headers. {maxHeaders, maxHeadersEncoded, pver, BaseEncoding, 3, wireErr, wireErr}, // Force error with number of transactions. - {transHeader, transHeaderEncoded, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF}, + {transHeader, transHeaderEncoded, pver, BaseEncoding, 81 + 32, io.ErrShortWrite, io.EOF}, // Force error with included transactions. {transHeader, transHeaderEncoded, pver, BaseEncoding, len(transHeaderEncoded), nil, wireErr}, } diff --git a/wire/msgmerkleblock_test.go b/wire/msgmerkleblock_test.go index eb7b3601..cda9865a 100644 --- a/wire/msgmerkleblock_test.go +++ b/wire/msgmerkleblock_test.go @@ -26,7 +26,7 @@ func TestMerkleBlock(t *testing.T) { merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce - bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) + bh := NewBlockHeader(1, prevHash, merkleHash, merkleHash, bits, nonce) // Ensure the command is expected value. wantCmd := "merkleblock" @@ -118,7 +118,7 @@ func TestMerkleBlockCrossProtocol(t *testing.T) { merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce - bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) + bh := NewBlockHeader(1, prevHash, merkleHash, merkleHash, bits, nonce) msg := NewMsgMerkleBlock(bh) @@ -229,48 +229,48 @@ func TestMerkleBlockWireErrors(t *testing.T) { }, // Force error in timestamp. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 68, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 68 + 32, io.ErrShortWrite, io.EOF, }, // Force error in difficulty bits. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 72, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 72 + 32, io.ErrShortWrite, io.EOF, }, // Force error in header nonce. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 76, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 76 + 32, io.ErrShortWrite, io.EOF, }, // Force error in transaction count. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 80, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 80 + 32, io.ErrShortWrite, io.EOF, }, // Force error in num hashes. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 84, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 84 + 32, io.ErrShortWrite, io.EOF, }, // Force error in hashes. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 85, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 85 + 32, io.ErrShortWrite, io.EOF, }, // Force error in num flag bytes. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 117, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 117 + 32, io.ErrShortWrite, io.EOF, }, // Force error in flag bytes. { - &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 118, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 118 + 32, io.ErrShortWrite, io.EOF, }, // Force error due to unsupported protocol version. { &merkleBlockOne, merkleBlockOneBytes, pverNoMerkleBlock, - BaseEncoding, 119, wireErr, wireErr, + BaseEncoding, 119 + 32, wireErr, wireErr, }, } @@ -331,7 +331,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) { // allowed tx hashes. var buf bytes.Buffer WriteVarInt(&buf, pver, maxTxPerBlock+1) - numHashesOffset := 84 + numHashesOffset := 84 + 32 exceedMaxHashes := make([]byte, numHashesOffset) copy(exceedMaxHashes, merkleBlockOneBytes[:numHashesOffset]) exceedMaxHashes = append(exceedMaxHashes, buf.Bytes()...) @@ -340,7 +340,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) { // allowed flag bytes. buf.Reset() WriteVarInt(&buf, pver, maxFlagsPerMerkleBlock+1) - numFlagBytesOffset := 117 + numFlagBytesOffset := 117 + 32 exceedMaxFlagBytes := make([]byte, numFlagBytesOffset) copy(exceedMaxFlagBytes, merkleBlockOneBytes[:numFlagBytesOffset]) exceedMaxFlagBytes = append(exceedMaxFlagBytes, buf.Bytes()...) @@ -388,6 +388,12 @@ var merkleBlockOne = MsgMerkleBlock{ 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, }), + ClaimTrie: chainhash.Hash([chainhash.HashSize]byte{ + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, + }), Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST Bits: 0x1d00ffff, // 486604799 Nonce: 0x9962e301, // 2573394689 @@ -416,6 +422,10 @@ var merkleBlockOneBytes = []byte{ 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x33, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, + 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // ClaimTrie 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce -- 2.45.2 From 1b823c055fc27a40200a9dc07bbceac88f992a4d Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 26 Nov 2021 11:36:53 -0500 Subject: [PATCH 381/459] [lbry] test: don't remove old regression DB --- lbcd.go | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/lbcd.go b/lbcd.go index ec6ef086..e47efdb8 100644 --- a/lbcd.go +++ b/lbcd.go @@ -183,34 +183,6 @@ func btcdMain(serverChan chan<- *server) error { return nil } -// removeRegressionDB removes the existing regression test database if running -// in regression test mode and it already exists. -func removeRegressionDB(dbPath string) error { - // Don't do anything if not in regression test mode. - if !cfg.RegressionTest { - return nil - } - - // Remove the old regression test database if it already exists. - fi, err := os.Stat(dbPath) - if err == nil { - btcdLog.Infof("Removing regression test database from '%s'", dbPath) - if fi.IsDir() { - err := os.RemoveAll(dbPath) - if err != nil { - return err - } - } else { - err := os.Remove(dbPath) - if err != nil { - return err - } - } - } - - return nil -} - // dbPath returns the path to the block database given a database type. func blockDbPath(dbType string) string { // The database name is based on the database type. @@ -277,11 +249,6 @@ func loadBlockDB() (database.DB, error) { // The database name is based on the database type. dbPath := blockDbPath(cfg.DbType) - - // The regression test is special in that it needs a clean database for - // each run, so remove it now if it already exists. - removeRegressionDB(dbPath) - btcdLog.Infof("Loading block database from '%s'", dbPath) db, err := database.Open(cfg.DbType, dbPath, activeNetParams.Net) if err != nil { -- 2.45.2 From 4dd45057066537e58a07e2894bf16c839e9d6363 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Thu, 19 Aug 2021 14:41:48 -0400 Subject: [PATCH 382/459] [lbry] docs: update docs for LBRY Co-authored-by: Roy Lee --- CHANGES | 1230 ----------------- LICENSE | 1 + README.md | 168 +-- blockchain/README.md | 68 +- blockchain/fullblocktests/README.md | 6 +- blockchain/indexers/README.md | 6 +- btcec/README.md | 61 +- btcjson/README.md | 64 +- chaincfg/README.md | 81 +- chaincfg/chainhash/README.md | 6 +- connmgr/README.md | 20 +- database/README.md | 30 +- database/ffldb/README.md | 4 +- database/internal/treap/README.md | 4 +- doc.go | 6 +- docs/code_contribution_guidelines.md | 319 ----- docs/configuration.md | 110 +- docs/configuring_tor.md | 34 +- docs/contact.md | 15 - docs/controlling.md | 12 +- docs/developer_resources.md | 37 - docs/index.md | 48 +- docs/installation.md | 76 - docs/json_rpc_api.md | 1160 ++++++++-------- docs/mining.md | 16 +- docs/table_of_content.md | 13 - docs/update.md | 8 - docs/using_docker.md | 160 --- docs/wallet.md | 5 - integration/README.md | 7 +- integration/rpctest/README.md | 14 - mempool/README.md | 18 - mining/README.md | 15 +- mining/cpuminer/README.md | 6 +- netsync/README.md | 12 - peer/README.md | 23 +- release/README.md | 181 --- rpcclient/README.md | 37 +- rpcclient/examples/bitcoincorehttp/README.md | 4 +- .../examples/bitcoincorehttpbulk/README.md | 4 +- rpcclient/examples/btcdwebsockets/README.md | 4 +- .../examples/btcwalletwebsockets/README.md | 4 +- rpcclient/examples/customcommand/README.md | 4 +- rpcclient/examples/customcommand/main.go | 4 +- sample-btcd.conf => sample-lbcd.conf | 44 +- txscript/README.md | 58 +- wire/README.md | 43 +- 47 files changed, 836 insertions(+), 3414 deletions(-) delete mode 100644 CHANGES delete mode 100644 docs/code_contribution_guidelines.md delete mode 100644 docs/contact.md delete mode 100644 docs/developer_resources.md delete mode 100644 docs/installation.md delete mode 100644 docs/table_of_content.md delete mode 100644 docs/update.md delete mode 100644 docs/using_docker.md delete mode 100644 docs/wallet.md delete mode 100644 release/README.md rename sample-btcd.conf => sample-lbcd.conf (94%) diff --git a/CHANGES b/CHANGES deleted file mode 100644 index fd59a886..00000000 --- a/CHANGES +++ /dev/null @@ -1,1230 +0,0 @@ -============================================================================ -User visible changes for btcd - A full-node bitcoin implementation written in Go -============================================================================ - -Changes in 0.22.0 (Tue Jun 01 2021) - - Protocol and network-related changes: - - Add support for witness tx and block in notfound msg (#1625) - - Add support for receiving sendaddrv2 messages from a peer (#1670) - - Fix bug in peer package causing last block height to go backwards - (#1606) - - Add chain parameters for connecting to the public Signet network - (#1692, #1718) - - Crypto changes: - - Fix bug causing panic due to bad R and S signature components in - btcec.RecoverCompact (#1691) - - Set the name (secp256k1) in the CurveParams of the S256 curve - (#1565) - - Notable developer-related package changes: - - Remove unknown block version warning in the blockchain package, - due to false positives triggered by AsicBoost (#1463) - - Add chaincfg.RegisterHDKeyID function to populate HD key ID pairs - (#1617) - - Add new method mining.AddWitnessCommitment to add the witness - commitment as an OP_RETURN output within the coinbase transaction. - (#1716) - - RPC changes: - - Support Batch JSON-RPC in rpcclient and server (#1583) - - Add rpcclient method to invoke getdescriptorinfo JSON-RPC command - (#1578) - - Update the rpcserver handler for validateaddress JSON-RPC command to - have parity with the bitcoind 0.20.0 interface (#1613) - - Add rpcclient method to invoke getblockfilter JSON-RPC command - (#1579) - - Add signmessagewithprivkey JSON-RPC command in rpcserver (#1585) - - Add rpcclient method to invoke importmulti JSON-RPC command (#1579) - - Add watchOnly argument in rpcclient method to invoke - listtransactions JSON-RPC command (#1628) - - Update btcjson.ListTransactionsResult for compatibility with Bitcoin - Core 0.20.0 (#1626) - - Support nullable optional JSON-RPC parameters (#1594) - - Add rpcclient and server method to invoke getnodeaddresses JSON-RPC - command (#1590) - - Add rpcclient methods to invoke PSBT JSON-RPC commands (#1596) - - Add rpcclient method to invoke listsinceblock with the - include_watchonly parameter enabled (#1451) - - Add rpcclient method to invoke deriveaddresses JSON-RPC command - (#1631) - - Add rpcclient method to invoke getblocktemplate JSON-RPC command - (#1629) - - Add rpcclient method to invoke getaddressinfo JSON-RPC command - (#1633) - - Add rpcclient method to invoke getwalletinfo JSON-RPC command - (#1638) - - Fix error message in rpcserver when an unknown RPC command is - encountered (#1695) - - Fix error message returned by estimatefee when the number of blocks - exceeds the max depth (#1678) - - Update btcjson.GetBlockChainInfoResult to include new fields in - Bitcoin Core (#1676) - - Add ExtraHeaders in rpcclient.ConnConfig struct (#1669) - - Fix bitcoind compatibility issue with the sendrawtransaction - JSON-RPC command (#1659) - - Add new JSON-RPC errors to btcjson package, and documented them - (#1648) - - Add rpcclient method to invoke createwallet JSON-RPC command - (#1650) - - Add rpcclient methods to invoke backupwallet, dumpwallet, loadwallet - and unloadwallet JSON-RPC commands (#1645) - - Fix unmarshalling error in getmininginfo JSON-RPC command, for valid - integers in scientific notation (#1644) - - Add rpcclient method to invoke gettxoutsetinfo JSON-RPC command - (#1641) - - Add rpcclient method to invoke signrawtransactionwithwallet JSON-RPC - command (#1642) - - Add txid to getblocktemplate response of rpcserver (#1639) - - Fix monetary unit used in createrawtransaction JSON-RPC command in - rpcserver (#1614) - - Add rawtx field to btcjson.GetBlockVerboseTxResult to provide - backwards compatibility with older versions of Bitcoin Core (#1677) - - Misc changes: - - Update btcutil dependency (#1704) - - Add Dockerfile to build and run btcd on Docker (#1465) - - Rework documentation and publish on https://btcd.readthedocs.io (#1468) - - Add support for Go 1.15 (#1619) - - Add Go 1.14 as the minimum supported version of Golang (#1621) - - Contributors (alphabetical order): - - 10gic - - Andrew Tugarinov - - Anirudha Bose - - Appelberg-s - - Armando Ochoa - - Aurèle Oulès - - Calvin Kim - - Christian Lehmann - - Conner Fromknecht - - Dan Cline - - David Mazary - - Elliott Minns - - Federico Bond - - Friedger Müffke - - Gustavo Chain - - Hanjun Kim - - Henry Fisher - - Iskander Sharipov - - Jake Sylvestre - - Johan T. Halseth - - John C. Vernaleo - - Liran Sharir - - Mikael Lindlof - - Olaoluwa Osuntokun - - Oliver Gugger - - Rjected - - Steven Kreuzer - - Torkel Rogstad - - Tristyn - - Victor Lavaud - - Vinayak Borkar - - Wilmer Paulino - - Yaacov Akiba Slama - - ebiiim - - ipriver - - wakiyamap - - yyforyongyu - -Changes in 0.21.0 (Thu Aug 27 2020) - - Network-related changes: - - Handle notfound messages from peers in netsync package (#1603) - - RPC changes: - - Add compatibility for getblock RPC changes in bitcoind 0.15.0 (#1529) - - Add new optional Params field to rpcclient.ConnConfig (#1467) - - Add new error code ErrRPCInWarmup in btcjson (#1541) - - Add compatibility for changes to getmempoolentry response in bitcoind - 0.19.0 (#1524) - - Add rpcclient methods for estimatesmartfee and generatetoaddress - commands (#1500) - - Add rpcclient method for getblockstats command (#1500) - - Parse serialized transaction from createrawtransaction command using - both segwit, and legacy format (#1502) - - Support cookie-based authentication in rpcclient (#1460) - - Add rpcclient method for getchaintxstats command (#1571) - - Add rpcclient method for fundrawtransaction command (#1553) - - Add rpcclient method for getbalances command (#1595) - - Add new method rpcclient.GetTransactionWatchOnly (#1592) - - Crypto changes: - - Fix panic in fieldVal.SetByteSlice when called with large values, and - improve the method to be 35% faster (#1602) - - btcctl changes: - - Add -regtest mode to btcctl (#1556) - - Misc changes: - - Fix a bug due to a deadlock in connmgr's dynamic ban scoring (#1509) - - Add blockchain.NewUtxoEntry() to directly create entries for - UtxoViewpoint (#1588) - - Replace LRU cache implementation in peer package with a generic one - from decred/dcrd (#1599) - - Contributors (alphabetical order): - - Anirudha Bose - - Antonin Hildebrand - - Dan Cline - - Daniel McNally - - David Hill - - Federico Bond - - George Tankersley - - Henry - - Henry Harder - - Iskander Sharipov - - Ivan Kuznetsov - - Jake Sylvestre - - Javed Khan - - JeremyRand - - Jin - - John C. Vernaleo - - Kulpreet Singh - - Mikael Lindlof - - Murray Nesbitt - - Nisen - - Olaoluwa Osuntokun - - Oliver Gugger - - Steven Roose - - Torkel Rogstad - - Tyler Chambers - - Wilmer Paulino - - Yash Bhutwala - - adiabat - - jalavosus - - mohanson - - qqjettkgjzhxmwj - - qshuai - - shuai.qi - - tpkeeper - -Changes in v0.20.1 (Wed Nov 13 2019) - - RPC changes: - - Add compatibility for bitcoind v0.19.0 in rpcclient and btcjson - packages (#1484) - - Contributors (alphabetical order): - - Eugene Zeigel - - Olaoluwa Osuntokun - - Wilmer Paulino - -Changes in v0.20.0 (Tue Oct 15 2019) - - Significant changes made since 0.12.0. See git log or refer to release - notes on GitHub for full details. - - Contributors (alphabetical order): - - Albert Puigsech Galicia - - Alex Akselrod - - Alex Bosworth - - Alex Manuskin - - Alok Menghrajani - - Anatoli Babenia - - Andy Weidenbaum - - Calvin McAnarney - - Chris Martin - - Chris Pacia - - Chris Shepherd - - Conner Fromknecht - - Craig Sturdy - - Cédric Félizard - - Daniel Krawisz - - Daniel Martí - - Daniel McNally - - Dario Nieuwenhuis - - Dave Collins - - David Hill - - David de Kloet - - GeertJohan - - Grace Noah - - Gregory Trubetskoy - - Hector Jusforgues - - Iskander (Alex) Sharipov - - Janus Troelsen - - Jasper - - Javed Khan - - Jeremiah Goyette - - Jim Posen - - Jimmy Song - - Johan T. Halseth - - John C. Vernaleo - - Jonathan Gillham - - Josh Rickmar - - Jon Underwood - - Jonathan Zeppettini - - Jouke Hofman - - Julian Meyer - - Kai - - Kamil Slowikowski - - Kefkius - - Leonardo Lazzaro - - Marco Peereboom - - Marko Bencun - - Mawueli Kofi Adzoe - - Michail Kargakis - - Mitchell Paull - - Nathan Bass - - Nicola 'tekNico' Larosa - - Olaoluwa Osuntokun - - Pedro Martelletto - - Ricardo Velhote - - Roei Erez - - Ruben de Vries - - Rune T. Aune - - Sad Pencil - - Shuai Qi - - Steven Roose - - Tadge Dryja - - Tibor Bősze - - Tomás Senart - - Tzu-Jung Lee - - Vadym Popov - - Waldir Pimenta - - Wilmer Paulino - - benma - - danda - - dskloet - - esemplastic - - jadeblaquiere - - nakagawa - - preminem - - qshuai - -Changes in 0.12.0 (Fri Nov 20 2015) - - Protocol and network related changes: - - Add a new checkpoint at block height 382320 (#555) - - Implement BIP0065 which includes support for version 4 blocks, a new - consensus opcode (OP_CHECKLOCKTIMEVERIFY) that enforces transaction - lock times, and a double-threshold switchover mechanism (#535, #459, - #455) - - Implement BIP0111 which provides a new bloom filter service flag and - hence provides support for protocol version 70011 (#499) - - Add a new parameter --nopeerbloomfilters to allow disabling bloom - filter support (#499) - - Reject non-canonically encoded variable length integers (#507) - - Add mainnet peer discovery DNS seed (seed.bitcoin.jonasschnelli.ch) - (#496) - - Correct reconnect handling for persistent peers (#463, #464) - - Ignore requests for block headers if not fully synced (#444) - - Add CLI support for specifying the zone id on IPv6 addresses (#538) - - Fix a couple of issues where the initial block sync could stall (#518, - #229, #486) - - Fix an issue which prevented the --onion option from working as - intended (#446) - - Transaction relay (memory pool) changes: - - Require transactions to only include signatures encoded with the - canonical 'low-s' encoding (#512) - - Add a new parameter --minrelaytxfee to allow the minimum transaction - fee in BTC/kB to be overridden (#520) - - Retain memory pool transactions when they redeem another one that is - removed when a block is accepted (#539) - - Do not send reject messages for a transaction if it is valid but - causes an orphan transaction which depends on it to be determined - as invalid (#546) - - Refrain from attempting to add orphans to the memory pool multiple - times when the transaction they redeem is added (#551) - - Modify minimum transaction fee calculations to scale based on bytes - instead of full kilobyte boundaries (#521, #537) - - Implement signature cache: - - Provides a limited memory cache of validated signatures which is a - huge optimization when verifying blocks for transactions that are - already in the memory pool (#506) - - Add a new parameter '--sigcachemaxsize' which allows the size of the - new cache to be manually changed if desired (#506) - - Mining support changes: - - Notify getblocktemplate long polling clients when a block is pushed - via submitblock (#488) - - Speed up getblocktemplate by making use of the new signature cache - (#506) - - RPC changes: - - Implement getmempoolinfo command (#453) - - Implement getblockheader command (#461) - - Modify createrawtransaction command to accept a new optional parameter - 'locktime' (#529) - - Modify listunspent result to include the 'spendable' field (#440) - - Modify getinfo command to include 'errors' field (#511) - - Add timestamps to blockconnected and blockdisconnected notifications - (#450) - - Several modifications to searchrawtranscations command: - - Accept a new optional parameter 'vinextra' which causes the results - to include information about the outputs referenced by a transaction's - inputs (#485, #487) - - Skip entries in the mempool too (#495) - - Accept a new optional parameter 'reverse' to return the results in - reverse order (most recent to oldest) (#497) - - Accept a new optional parameter 'filteraddrs' which causes the - results to only include inputs and outputs which involve the - provided addresses (#516) - - Change the notification order to notify clients about mined - transactions (recvtx, redeemingtx) before the blockconnected - notification (#449) - - Update verifymessage RPC to use the standard algorithm so it is - compatible with other implementations (#515) - - Improve ping statistics by pinging on an interval (#517) - - Websocket changes: - - Implement session command which returns a per-session unique id (#500, - #503) - - btcctl utility changes: - - Add getmempoolinfo command (#453) - - Add getblockheader command (#461) - - Add getwalletinfo command (#471) - - Notable developer-related package changes: - - Introduce a new peer package which acts a common base for creating and - concurrently managing bitcoin network peers (#445) - - Various cleanup of the new peer package (#528, #531, #524, #534, - #549) - - Blocks heights now consistently use int32 everywhere (#481) - - The BlockHeader type in the wire package now provides the BtcDecode - and BtcEncode methods (#467) - - Update wire package to recognize BIP0064 (getutxo) service bit (#489) - - Export LockTimeThreshold constant from txscript package (#454) - - Export MaxDataCarrierSize constant from txscript package (#466) - - Provide new IsUnspendable function from the txscript package (#478) - - Export variable length string functions from the wire package (#514) - - Export DNS Seeds for each network from the chaincfg package (#544) - - Preliminary work towards separating the memory pool into a separate - package (#525, #548) - - Misc changes: - - Various documentation updates (#442, #462, #465, #460, #470, #473, - #505, #530, #545) - - Add installation instructions for gentoo (#542) - - Ensure an error is shown if OS limits can't be set at startup (#498) - - Tighten the standardness checks for multisig scripts (#526) - - Test coverage improvement (#468, #494, #527, #543, #550) - - Several optimizations (#457, #474, #475, #476, #508, #509) - - Minor code cleanup and refactoring (#472, #479, #482, #519, #540) - - Contributors (alphabetical order): - - Ben Echols - - Bruno Clermont - - danda - - Daniel Krawisz - - Dario Nieuwenhuis - - Dave Collins - - David Hill - - Javed Khan - - Jonathan Gillham - - Joseph Becher - - Josh Rickmar - - Justus Ranvier - - Mawuli Adzoe - - Olaoluwa Osuntokun - - Rune T. Aune - -Changes in 0.11.1 (Wed May 27 2015) - - Protocol and network related changes: - - Use correct sub-command in reject message for rejected transactions - (#436, #437) - - Add a new parameter --torisolation which forces new circuits for each - connection when using tor (#430) - - Transaction relay (memory pool) changes: - - Reduce the default number max number of allowed orphan transactions - to 1000 (#419) - - Add a new parameter --maxorphantx which allows the maximum number of - orphan transactions stored in the mempool to be specified (#419) - - RPC changes: - - Modify listtransactions result to include the 'involveswatchonly' and - 'vout' fields (#427) - - Update getrawtransaction result to omit the 'confirmations' field - when it is 0 (#420, #422) - - Update signrawtransaction result to include errors (#423) - - btcctl utility changes: - - Add gettxoutproof command (#428) - - Add verifytxoutproof command (#428) - - Notable developer-related package changes: - - The btcec package now provides the ability to perform ECDH - encryption and decryption (#375) - - The block and header validation in the blockchain package has been - split to help pave the way toward concurrent downloads (#386) - - Misc changes: - - Minor peer optimization (#433) - - Contributors (alphabetical order): - - Dave Collins - - David Hill - - Federico Bond - - Ishbir Singh - - Josh Rickmar - -Changes in 0.11.0 (Wed May 06 2015) - - Protocol and network related changes: - - **IMPORTANT: Update is required due to the following point** - - Correct a few corner cases in script handling which could result in - forking from the network on non-standard transactions (#425) - - Add a new checkpoint at block height 352940 (#418) - - Optimized script execution (#395, #400, #404, #409) - - Fix a case that could lead stalled syncs (#138, #296) - - Network address manager changes: - - Implement eclipse attack countermeasures as proposed in - http://cs-people.bu.edu/heilman/eclipse (#370, #373) - - Optional address indexing changes: - - Fix an issue where a reorg could cause an orderly shutdown when the - address index is active (#340, #357) - - Transaction relay (memory pool) changes: - - Increase maximum allowed space for nulldata transactions to 80 bytes - (#331) - - Implement support for the following rules specified by BIP0062: - - The S value in ECDSA signature must be at most half the curve order - (rule 5) (#349) - - Script execution must result in a single non-zero value on the stack - (rule 6) (#347) - - NOTE: All 7 rules of BIP0062 are now implemented - - Use network adjusted time in finalized transaction checks to improve - consistency across nodes (#332) - - Process orphan transactions on acceptance of new transactions (#345) - - RPC changes: - - Add support for a limited RPC user which is not allowed admin level - operations on the server (#363) - - Implement node command for more unified control over connected peers - (#79, #341) - - Implement generate command for regtest/simnet to support - deterministically mining a specified number of blocks (#362, #407) - - Update searchrawtransactions to return the matching transactions in - order (#354) - - Correct an issue with searchrawtransactions where it could return - duplicates (#346, #354) - - Increase precision of 'difficulty' field in getblock result to 8 - (#414, #415) - - Omit 'nextblockhash' field from getblock result when it is empty - (#416, #417) - - Add 'id' and 'timeoffset' fields to getpeerinfo result (#335) - - Websocket changes: - - Implement new commands stopnotifyspent, stopnotifyreceived, - stopnotifyblocks, and stopnotifynewtransactions to allow clients to - cancel notification registrations (#122, #342) - - btcctl utility changes: - - A single dash can now be used as an argument to cause that argument to - be read from stdin (#348) - - Add generate command - - Notable developer-related package changes: - - The new version 2 btcjson package has now replaced the deprecated - version 1 package (#368) - - The btcec package now performs all signing using RFC6979 deterministic - signatures (#358, #360) - - The txscript package has been significantly cleaned up and had a few - API changes (#387, #388, #389, #390, #391, #392, #393, #395, #396, - #400, #403, #404, #405, #406, #408, #409, #410, #412) - - A new PkScriptLocs function has been added to the wire package MsgTx - type which provides callers that deal with scripts optimization - opportunities (#343) - - Misc changes: - - Minor wire hashing optimizations (#366, #367) - - Other minor internal optimizations - - Contributors (alphabetical order): - - Alex Akselrod - - Arne Brutschy - - Chris Jepson - - Daniel Krawisz - - Dave Collins - - David Hill - - Jimmy Song - - Jonas Nick - - Josh Rickmar - - Olaoluwa Osuntokun - - Oleg Andreev - -Changes in 0.10.0 (Sun Mar 01 2015) - - Protocol and network related changes: - - Add a new checkpoint at block height 343185 - - Implement BIP066 which includes support for version 3 blocks, a new - consensus rule which prevents non-DER encoded signatures, and a - double-threshold switchover mechanism - - Rather than announcing all known addresses on getaddr requests which - can possibly result in multiple messages, randomize the results and - limit them to the max allowed by a single message (1000 addresses) - - Add more reserved IP spaces to the address manager - - Transaction relay (memory pool) changes: - - Make transactions which contain reserved opcodes nonstandard - - No longer accept or relay free and low-fee transactions that have - insufficient priority to be mined in the next block - - Implement support for the following rules specified by BIP0062: - - ECDSA signature must use strict DER encoding (rule 1) - - The signature script must only contain push operations (rule 2) - - All push operations must use the smallest possible encoding (rule 3) - - All stack values interpreted as a number must be encoding using the - shortest possible form (rule 4) - - NOTE: Rule 1 was already enforced, however the entire script now - evaluates to false rather than only the signature verification as - required by BIP0062 - - Allow transactions with nulldata transaction outputs to be treated as - standard - - Mining support changes: - - Modify the getblocktemplate RPC to generate and return block templates - for version 3 blocks which are compatible with BIP0066 - - Allow getblocktemplate to serve blocks when the current time is - less than the minimum allowed time for a generated block template - (https://github.com/btcsuite/btcd/issues/209) - - Crypto changes: - - Optimize scalar multiplication by the base point by using a - pre-computed table which results in approximately a 35% speedup - (https://github.com/btcsuite/btcec/issues/2) - - Optimize general scalar multiplication by using the secp256k1 - endomorphism which results in approximately a 17-20% speedup - (https://github.com/btcsuite/btcec/issues/1) - - Optimize general scalar multiplication by using non-adjacent form - which results in approximately an additional 8% speedup - (https://github.com/btcsuite/btcec/issues/3) - - Implement optional address indexing: - - Add a new parameter --addrindex which will enable the creation of an - address index which can be queried to determine all transactions which - involve a given address - (https://github.com/btcsuite/btcd/issues/190) - - Add a new logging subsystem for address index related operations - - Support new searchrawtransactions RPC - (https://github.com/btcsuite/btcd/issues/185) - - RPC changes: - - Require TLS version 1.2 as the minimum version for all TLS connections - - Provide support for disabling TLS when only listening on localhost - (https://github.com/btcsuite/btcd/pull/192) - - Modify help output for all commands to provide much more consistent - and detailed information - - Correct case in getrawtransaction which would refuse to serve certain - transactions with invalid scripts - (https://github.com/btcsuite/btcd/issues/210) - - Correct error handling in the getrawtransaction RPC which could lead - to a crash in rare cases - (https://github.com/btcsuite/btcd/issues/196) - - Update getinfo RPC to include the appropriate 'timeoffset' calculated - from the median network time - - Modify listreceivedbyaddress result type to include txids field so it - is compatible - - Add 'iswatchonly' field to validateaddress result - - Add 'startingpriority' and 'currentpriority' fields to getrawmempool - (https://github.com/btcsuite/btcd/issues/178) - - Don't omit the 'confirmations' field from getrawtransaction when it is - zero - - Websocket changes: - - Modify the behavior of the rescan command to automatically register - for notifications about transactions paying to rescanned addresses - or spending outputs from the final rescan utxo set when the rescan - is through the best block in the chain - - btcctl utility changes: - - Make the list of commands available via the -l option rather than - dumping the entire list on usage errors - - Alphabetize and categorize the list of commands by chain and wallet - - Make the help option only show the help options instead of also - dumping all of the commands - - Make the usage syntax much more consistent and correct a few cases of - misnamed fields - (https://github.com/btcsuite/btcd/issues/305) - - Improve usage errors to show the specific parameter number, reason, - and error code - - Only show the usage for specific command is shown when a valid command - is provided with invalid parameters - - Add support for a SOCK5 proxy - - Modify output for integer fields (such as timestamps) to display - normally instead in scientific notation - - Add invalidateblock command - - Add reconsiderblock command - - Add createnewaccount command - - Add renameaccount command - - Add searchrawtransactions command - - Add importaddress command - - Add importpubkey command - - showblock utility changes: - - Remove utility in favor of the RPC getblock method - - Notable developer-related package changes: - - Many of the core packages have been relocated into the btcd repository - (https://github.com/btcsuite/btcd/issues/214) - - A new version of the btcjson package that has been completely - redesigned from the ground up based based upon how the project has - evolved and lessons learned while using it since it was first written - is now available in the btcjson/v2/btcjson directory - - This will ultimately replace the current version so anyone making - use of this package will need to update their code accordingly - - The btcec package now provides better facilities for working directly - with its public and private keys without having to mix elements from - the ecdsa package - - Update the script builder to ensure all rules specified by BIP0062 are - adhered to when creating scripts - - The blockchain package now provides a MedianTimeSource interface and - concrete implementation for providing time samples from remote peers - and using that data to calculate an offset against the local time - - Misc changes: - - Fix a slow memory leak due to tickers not being stopped - (https://github.com/btcsuite/btcd/issues/189) - - Fix an issue where a mix of orphans and SPV clients could trigger a - condition where peers would no longer be served - (https://github.com/btcsuite/btcd/issues/231) - - The RPC username and password can now contain symbols which previously - conflicted with special symbols used in URLs - - Improve handling of obtaining random nonces to prevent cases where it - could error when not enough entropy was available - - Improve handling of home directory creation errors such as in the case - of unmounted symlinks (https://github.com/btcsuite/btcd/issues/193) - - Improve the error reporting for rejected transactions to include the - inputs which are missing and/or being double spent - - Update sample config file with new options and correct a comment - regarding the fact the RPC server only listens on localhost by default - (https://github.com/btcsuite/btcd/issues/218) - - Update the continuous integration builds to run several tools which - help keep code quality high - - Significant amount of internal code cleanup and improvements - - Other minor internal optimizations - - Code Contributors (alphabetical order): - - Beldur - - Ben Holden-Crowther - - Dave Collins - - David Evans - - David Hill - - Guilherme Salgado - - Javed Khan - - Jimmy Song - - John C. Vernaleo - - Jonathan Gillham - - Josh Rickmar - - Michael Ford - - Michail Kargakis - - kac - - Olaoluwa Osuntokun - -Changes in 0.9.0 (Sat Sep 20 2014) - - Protocol and network related changes: - - Add a new checkpoint at block height 319400 - - Add support for BIP0037 bloom filters - (https://github.com/conformal/btcd/issues/132) - - Implement BIP0061 reject handling and hence support for protocol - version 70002 (https://github.com/conformal/btcd/issues/133) - - Add testnet DNS seeds for peer discovery (testnet-seed.alexykot.me - and testnet-seed.bitcoin.schildbach.de) - - Add mainnet DNS seed for peer discovery (seeds.bitcoin.open-nodes.org) - - Make multisig transactions with non-null dummy data nonstandard - (https://github.com/conformal/btcd/issues/131) - - Make transactions with an excessive number of signature operations - nonstandard - - Perform initial DNS lookups concurrently which allows connections - more quickly - - Improve the address manager to significantly reduce memory usage and - add tests - - Remove orphan transactions when they appear in a mined block - (https://github.com/conformal/btcd/issues/166) - - Apply incremental back off on connection retries for persistent peers - that give invalid replies to mirror the logic used for failed - connections (https://github.com/conformal/btcd/issues/103) - - Correct rate-limiting of free and low-fee transactions - - Mining support changes: - - Implement getblocktemplate RPC with the following support: - (https://github.com/conformal/btcd/issues/124) - - BIP0022 Non-Optional Sections - - BIP0022 Long Polling - - BIP0023 Basic Pool Extensions - - BIP0023 Mutation coinbase/append - - BIP0023 Mutations time, time/increment, and time/decrement - - BIP0023 Mutation transactions/add - - BIP0023 Mutations prevblock, coinbase, and generation - - BIP0023 Block Proposals - - Implement built-in concurrent CPU miner - (https://github.com/conformal/btcd/issues/137) - NOTE: CPU mining on mainnet is pointless. This has been provided - for testing purposes such as for the new simulation test network - - Add --generate flag to enable CPU mining - - Deprecate the --getworkkey flag in favor of --miningaddr which - specifies which addresses generated blocks will choose from to pay - the subsidy to - - RPC changes: - - Implement gettxout command - (https://github.com/conformal/btcd/issues/141) - - Implement validateaddress command - - Implement verifymessage command - - Mark getunconfirmedbalance RPC as wallet-only - - Mark getwalletinfo RPC as wallet-only - - Update getgenerate, setgenerate, gethashespersec, and getmininginfo - to return the appropriate information about new CPU mining status - - Modify getpeerinfo pingtime and pingwait field types to float64 so - they are compatible - - Improve disconnect handling for normal HTTP clients - - Make error code returns for invalid hex more consistent - - Websocket changes: - - Switch to a new more efficient websocket package - (https://github.com/conformal/btcd/issues/134) - - Add rescanfinished notification - - Modify the rescanprogress notification to include block hash as well - as height (https://github.com/conformal/btcd/issues/151) - - btcctl utility changes: - - Accept --simnet flag which automatically selects the appropriate port - and TLS certificates needed to communicate with btcd and btcwallet on - the simulation test network - - Fix createrawtransaction command to send amounts denominated in BTC - - Add estimatefee command - - Add estimatepriority command - - Add getmininginfo command - - Add getnetworkinfo command - - Add gettxout command - - Add lockunspent command - - Add signrawtransaction command - - addblock utility changes: - - Accept --simnet flag which automatically selects the appropriate port - and TLS certificates needed to communicate with btcd and btcwallet on - the simulation test network - - Notable developer-related package changes: - - Provide a new bloom package in btcutil which allows creating and - working with BIP0037 bloom filters - - Provide a new hdkeychain package in btcutil which allows working with - BIP0032 hierarchical deterministic key chains - - Introduce a new btcnet package which houses network parameters - - Provide new simnet network (--simnet) which is useful for private - simulation testing - - Enforce low S values in serialized signatures as detailed in BIP0062 - - Return errors from all methods on the btcdb.Db interface - (https://github.com/conformal/btcdb/issues/5) - - Allow behavior flags to alter btcchain.ProcessBlock - (https://github.com/conformal/btcchain/issues/5) - - Provide a new SerializeSize API for blocks - (https://github.com/conformal/btcwire/issues/19) - - Several of the core packages now work with Google App Engine - - Misc changes: - - Correct an issue where the database could corrupt under certain - circumstances which would require a new chain download - - Slightly optimize deserialization - - Use the correct IP block for he.net - - Fix an issue where it was possible the block manager could hang on - shutdown - - Update sample config file so the comments are on a separate line - rather than the end of a line so they are not interpreted as settings - (https://github.com/conformal/btcd/issues/135) - - Correct an issue where getdata requests were not being properly - throttled which could lead to larger than necessary memory usage - - Always show help when given the help flag even when the config file - contains invalid entries - - General code cleanup and minor optimizations - -Changes in 0.8.0-beta (Sun May 25 2014) - - Btcd is now Beta (https://github.com/conformal/btcd/issues/130) - - Add a new checkpoint at block height 300255 - - Protocol and network related changes: - - Lower the minimum transaction relay fee to 1000 satoshi to match - recent reference client changes - (https://github.com/conformal/btcd/issues/100) - - Raise the maximum signature script size to support standard 15-of-15 - multi-signature pay-to-sript-hash transactions with compressed pubkeys - to remain compatible with the reference client - (https://github.com/conformal/btcd/issues/128) - - Reduce max bytes allowed for a standard nulldata transaction to 40 for - compatibility with the reference client - - Introduce a new btcnet package which houses all of the network params - for each network (mainnet, testnet3, regtest) to ultimately enable - easier addition and tweaking of networks without needing to change - several packages - - Fix several script discrepancies found by reference client test data - - Add new DNS seed for peer discovery (seed.bitnodes.io) - - Reduce the max known inventory cache from 20000 items to 1000 items - - Fix an issue where unknown inventory types could lead to a hung peer - - Implement inventory rebroadcast handler for sendrawtransaction - (https://github.com/conformal/btcd/issues/99) - - Update user agent to fully support BIP0014 - (https://github.com/conformal/btcwire/issues/10) - - Implement initial mining support: - - Add a new logging subsystem for mining related operations - - Implement infrastructure for creating block templates - - Provide options to control block template creation settings - - Support the getwork RPC - - Allow address identifiers to apply to more than one network since both - testnet3 and the regression test network unfortunately use the same - identifier - - RPC changes: - - Set the content type for HTTP POST RPC connections to application/json - (https://github.com/conformal/btcd/issues/121) - - Modified the RPC server startup so it only requires at least one valid - listen interface - - Correct an error path where it was possible certain errors would not - be returned - - Implement getwork command - (https://github.com/conformal/btcd/issues/125) - - Update sendrawtransaction command to reject orphans - - Update sendrawtransaction command to include the reason a transaction - was rejected - - Update getinfo command to populate connection count field - - Update getinfo command to include relay fee field - (https://github.com/conformal/btcd/issues/107) - - Allow transactions submitted with sendrawtransaction to bypass the - rate limiter - - Allow the getcurrentnet and getbestblock extensions to be accessed via - HTTP POST in addition to Websockets - (https://github.com/conformal/btcd/issues/127) - - Websocket changes: - - Rework notifications to ensure they are delivered in the order they - occur - - Rename notifynewtxs command to notifyreceived (funds received) - - Rename notifyallnewtxs command to notifynewtransactions - - Rename alltx notification to txaccepted - - Rename allverbosetx notification to txacceptedverbose - (https://github.com/conformal/btcd/issues/98) - - Add rescan progress notification - - Add recvtx notification - - Add redeemingtx notification - - Modify notifyspent command to accept an array of outpoints - (https://github.com/conformal/btcd/issues/123) - - Significantly optimize the rescan command to yield up to a 60x speed - increase - - btcctl utility changes: - - Add createencryptedwallet command - - Add getblockchaininfo command - - Add importwallet command - - Add addmultisigaddress command - - Add setgenerate command - - Accept --testnet and --wallet flags which automatically select - the appropriate port and TLS certificates needed to communicate - with btcd and btcwallet (https://github.com/conformal/btcd/issues/112) - - Allow path expansion from config file entries - (https://github.com/conformal/btcd/issues/113) - - Minor refactor simplify handling of options - - addblock utility changes: - - Improve logging by making it consistent with the logging provided by - btcd (https://github.com/conformal/btcd/issues/90) - - Improve several package APIs for developers: - - Add new amount type for consistently handling monetary values - - Add new coin selector API - - Add new WIF (Wallet Import Format) API - - Add new crypto types for private keys and signatures - - Add new API to sign transactions including script merging and hash - types - - Expose function to extract all pushed data from a script - (https://github.com/conformal/btcscript/issues/8) - - Misc changes: - - Optimize address manager shuffling to do 67% less work on average - - Resolve a couple of benign data races found by the race detector - (https://github.com/conformal/btcd/issues/101) - - Add IP address to all peer related errors to clarify which peer is the - cause (https://github.com/conformal/btcd/issues/102) - - Fix a UPNP case issue that prevented the --upnp option from working - with some UPNP servers - - Update documentation in the sample config file regarding debug levels - - Adjust some logging levels to improve debug messages - - Improve the throughput of query messages to the block manager - - Several minor optimizations to reduce GC churn and enhance speed - - Other minor refactoring - - General code cleanup - -Changes in 0.7.0 (Thu Feb 20 2014) - - Fix an issue when parsing scripts which contain a multi-signature script - which require zero signatures such as testnet block - 000000001881dccfeda317393c261f76d09e399e15e27d280e5368420f442632 - (https://github.com/conformal/btcscript/issues/7) - - Add check to ensure all transactions accepted to mempool only contain - canonical data pushes (https://github.com/conformal/btcscript/issues/6) - - Fix an issue causing excessive memory consumption - - Significantly rework and improve the websocket notification system: - - Each client is now independent so slow clients no longer limit the - speed of other connected clients - - Potentially long-running operations such as rescans are now run in - their own handler and rate-limited to one operation at a time without - preventing simultaneous requests from the same client for the faster - requests or notifications - - A couple of scenarios which could cause shutdown to hang have been - resolved - - Update notifynewtx notifications to support all address types instead - of only pay-to-pubkey-hash - - Provide a --rpcmaxwebsockets option to allow limiting the number of - concurrent websocket clients - - Add a new websocket command notifyallnewtxs to request notifications - (https://github.com/conformal/btcd/issues/86) (thanks @flammit) - - Improve btcctl utility in the following ways: - - Add getnetworkhashps command - - Add gettransaction command (wallet-specific) - - Add signmessage command (wallet-specific) - - Update getwork command to accept - - Continue cleanup and work on implementing the RPC API: - - Implement getnettotals command - (https://github.com/conformal/btcd/issues/84) - - Implement networkhashps command - (https://github.com/conformal/btcd/issues/87) - - Update getpeerinfo to always include syncnode field even when false - - Remove help addenda for getpeerinfo now that it supports all fields - - Close standard RPC connections on auth failure - - Provide a --rpcmaxclients option to allow limiting the number of - concurrent RPC clients (https://github.com/conformal/btcd/issues/68) - - Include IP address in RPC auth failure log messages - - Resolve a rather harmless data races found by the race detector - (https://github.com/conformal/btcd/issues/94) - - Increase block priority size and max standard transaction size to 50k - and 100k, respectively (https://github.com/conformal/btcd/issues/71) - - Add rate limiting of free transactions to the memory pool to prevent - penny flooding (https://github.com/conformal/btcd/issues/40) - - Provide a --logdir option (https://github.com/conformal/btcd/issues/95) - - Change the default log file path to include the network - - Add a new ScriptBuilder interface to btcscript to support creation of - custom scripts (https://github.com/conformal/btcscript/issues/5) - - General code cleanup - -Changes in 0.6.0 (Tue Feb 04 2014) - - Fix an issue when parsing scripts which contain invalid signatures that - caused a chain fork on block - 0000000000000001e4241fd0b3469a713f41c5682605451c05d3033288fb2244 - - Correct an issue which could lead to an error in removeBlockNode - (https://github.com/conformal/btcchain/issues/4) - - Improve addblock utility as follows: - - Check imported blocks against all chain rules and checkpoints - - Skip blocks which are already known so you can stop and restart the - import or start the import after you have already downloaded a portion - of the chain - - Correct an issue where the utility did not shutdown cleanly after - processing all blocks - - Add error on attempt to import orphan blocks - - Improve error handling and reporting - - Display statistics after input file has been fully processed - - Rework, optimize, and improve headers-first mode: - - Resuming the chain sync from any point before the final checkpoint - will now use headers-first mode - (https://github.com/conformal/btcd/issues/69) - - Verify all checkpoints as opposed to only the final one - - Reduce and bound memory usage - - Rollback to the last known good point when a header does not match a - checkpoint - - Log information about what is happening with headers - - Improve btcctl utility in the following ways: - - Add getaddednodeinfo command - - Add getnettotals command - - Add getblocktemplate command (wallet-specific) - - Add getwork command (wallet-specific) - - Add getnewaddress command (wallet-specific) - - Add walletpassphrasechange command (wallet-specific) - - Add walletlock command (wallet-specific) - - Add sendfrom command (wallet-specific) - - Add sendmany command (wallet-specific) - - Add settxfee command (wallet-specific) - - Add listsinceblock command (wallet-specific) - - Add listaccounts command (wallet-specific) - - Add keypoolrefill command (wallet-specific) - - Add getreceivedbyaccount command (wallet-specific) - - Add getrawchangeaddress command (wallet-specific) - - Add gettxoutsetinfo command (wallet-specific) - - Add listaddressgroupings command (wallet-specific) - - Add listlockunspent command (wallet-specific) - - Add listlock command (wallet-specific) - - Add listreceivedbyaccount command (wallet-specific) - - Add validateaddress command (wallet-specific) - - Add verifymessage command (wallet-specific) - - Add sendtoaddress command (wallet-specific) - - Continue cleanup and work on implementing the RPC API: - - Implement submitblock command - (https://github.com/conformal/btcd/issues/61) - - Implement help command - - Implement ping command - - Implement getaddednodeinfo command - (https://github.com/conformal/btcd/issues/78) - - Implement getinfo command - - Update getpeerinfo to support bytesrecv and bytessent - (https://github.com/conformal/btcd/issues/83) - - Improve and correct several RPC server and websocket areas: - - Change the connection endpoint for websockets from /wallet to /ws - (https://github.com/conformal/btcd/issues/80) - - Implement an alternative authentication for websockets so clients - such as javascript from browsers that don't support setting HTTP - headers can authenticate (https://github.com/conformal/btcd/issues/77) - - Add an authentication deadline for RPC connections - (https://github.com/conformal/btcd/issues/68) - - Use standard authentication failure responses for RPC connections - - Make automatically generated certificate more standard so it works - from client such as node.js and Firefox - - Correct some minor issues which could prevent the RPC server from - shutting down in an orderly fashion - - Make all websocket notifications require registration - - Change the data sent over websockets to text since it is JSON-RPC - - Allow connections that do not have an Origin header set - - Expose and track the number of bytes read and written per peer - (https://github.com/conformal/btcwire/issues/6) - - Correct an issue with sendrawtransaction when invoked via websockets - which prevented a minedtx notification from being added - - Rescan operations issued from remote wallets are no stopped when - the wallet disconnects mid-operation - (https://github.com/conformal/btcd/issues/66) - - Several optimizations related to fetching block information from the - database - - General code cleanup - -Changes in 0.5.0 (Mon Jan 13 2014) - - Optimize initial block download by introducing a new mode which - downloads the block headers first (up to the final checkpoint) - - Improve peer handling to remove the potential for slow peers to cause - sluggishness amongst all peers - (https://github.com/conformal/btcd/issues/63) - - Fix an issue where the initial block sync could stall when the sync peer - disconnects (https://github.com/conformal/btcd/issues/62) - - Correct an issue where --externalip was doing a DNS lookup on the full - host:port instead of just the host portion - (https://github.com/conformal/btcd/issues/38) - - Fix an issue which could lead to a panic on chain switches - (https://github.com/conformal/btcd/issues/70) - - Improve btcctl utility in the following ways: - - Show getdifficulty output as floating point to 6 digits of precision - - Show all JSON object replies formatted as standard JSON - - Allow btcctl getblock to accept optional params - - Add getaccount command (wallet-specific) - - Add getaccountaddress command (wallet-specific) - - Add sendrawtransaction command - - Continue cleanup and work on implementing RPC API calls - - Update getrawmempool to support new optional verbose flag - - Update getrawtransaction to match the reference client - - Update getblock to support new optional verbose flag - - Update raw transactions to fully match the reference client including - support for all transaction types and address types - - Correct getrawmempool fee field to return BTC instead of Satoshi - - Correct getpeerinfo service flag to return 8 digit string so it - matches the reference client - - Correct verifychain to return a boolean - - Implement decoderawtransaction command - - Implement createrawtransaction command - - Implement decodescript command - - Implement gethashespersec command - - Allow RPC handler overrides when invoked via a websocket versus - legacy connection - - Add new DNS seed for peer discovery - - Display user agent on new valid peer log message - (https://github.com/conformal/btcd/issues/64) - - Notify wallet when new transactions that pay to registered addresses - show up in the mempool before being mined into a block - - Support a tor-specific proxy in addition to a normal proxy - (https://github.com/conformal/btcd/issues/47) - - Remove deprecated sqlite3 imports from utilities - - Remove leftover profile write from addblock utility - - Quite a bit of code cleanup and refactoring to improve maintainability - -Changes in 0.4.0 (Thu Dec 12 2013) - - Allow listen interfaces to be specified via --listen instead of only the - port (https://github.com/conformal/btcd/issues/33) - - Allow listen interfaces for the RPC server to be specified via - --rpclisten instead of only the port - (https://github.com/conformal/btcd/issues/34) - - Only disable listening when --connect or --proxy are used when no - --listen interface are specified - (https://github.com/conformal/btcd/issues/10) - - Add several new standard transaction checks to transaction memory pool: - - Support nulldata scripts as standard - - Only allow a max of one nulldata output per transaction - - Enforce a maximum of 3 public keys in multi-signature transactions - - The number of signatures in multi-signature transactions must not - exceed the number of public keys - - The number of inputs to a signature script must match the expected - number of inputs for the script type - - The number of inputs pushed onto the stack by a redeeming signature - script must match the number of inputs consumed by the referenced - public key script - - When a block is connected, remove any transactions from the memory pool - which are now double spends as a result of the newly connected - transactions - - Don't relay transactions resurrected during a chain switch since - other peers will also be switching chains and therefore already know - about them - - Cleanup a few cases where rejected transactions showed as an error - rather than as a rejected transaction - - Ignore the default configuration file when --regtest (regression test - mode) is specified - - Implement TLS support for RPC including automatic certificate generation - - Support HTTP authentication headers for web sockets - - Update address manager to recognize and properly work with Tor - addresses (https://github.com/conformal/btcd/issues/36) and - (https://github.com/conformal/btcd/issues/37) - - Improve btcctl utility in the following ways: - - Add the ability to specify a configuration file - - Add a default entry for the RPC cert to point to the location - it will likely be in the btcd home directory - - Implement --version flag - - Provide a --notls option to support non-TLS configurations - - Fix a couple of minor races found by the Go race detector - - Improve logging - - Allow logging level to be specified on a per subsystem basis - (https://github.com/conformal/btcd/issues/48) - - Allow logging levels to be dynamically changed via RPC - (https://github.com/conformal/btcd/issues/15) - - Implement a rolling log file with a max of 10MB per file and a - rotation size of 3 which results in a max logging size of 30 MB - - Correct a minor issue with the rescanning websocket call - (https://github.com/conformal/btcd/issues/54) - - Fix a race with pushing address messages that could lead to a panic - (https://github.com/conformal/btcd/issues/58) - - Improve which external IP address is reported to peers based on which - interface they are connected through - (https://github.com/conformal/btcd/issues/35) - - Add --externalip option to allow an external IP address to be specified - for cases such as tor hidden services or advanced network configurations - (https://github.com/conformal/btcd/issues/38) - - Add --upnp option to support automatic port mapping via UPnP - (https://github.com/conformal/btcd/issues/51) - - Update Ctrl+C interrupt handler to properly sync address manager and - remove the UPnP port mapping (if needed) - - Continue cleanup and work on implementing RPC API calls - - Add importprivkey (import private key) command to btcctl - - Update getrawtransaction to provide addresses properly, support - new verbose param, and match the reference implementation with the - exception of MULTISIG (thanks @flammit) - - Update getblock with new verbose flag (thanks @flammit) - - Add listtransactions command to btcctl - - Add getbalance command to btcctl - - Add basic support for btcd to run as a native Windows service - (https://github.com/conformal/btcd/issues/42) - - Package addblock utility with Windows MSIs - - Add support for TravisCI (continuous build integration) - - Cleanup some documentation and usage - - Several other minor bug fixes and general code cleanup - -Changes in 0.3.3 (Wed Nov 13 2013) - - Significantly improve initial block chain download speed - (https://github.com/conformal/btcd/issues/20) - - Add a new checkpoint at block height 267300 - - Optimize most recently used inventory handling - (https://github.com/conformal/btcd/issues/21) - - Optimize duplicate transaction input check - (https://github.com/conformal/btcchain/issues/2) - - Optimize transaction hashing - (https://github.com/conformal/btcd/issues/25) - - Rework and optimize wallet listener notifications - (https://github.com/conformal/btcd/issues/22) - - Optimize serialization and deserialization - (https://github.com/conformal/btcd/issues/27) - - Add support for minimum transaction fee to memory pool acceptance - (https://github.com/conformal/btcd/issues/29) - - Improve leveldb database performance by removing explicit GC call - - Fix an issue where Ctrl+C was not always finishing orderly database - shutdown - - Fix an issue in the script handling for OP_CHECKSIG - - Impose max limits on all variable length protocol entries to prevent - abuse from malicious peers - - Enforce DER signatures for transactions allowed into the memory pool - - Separate the debug profile http server from the RPC server - - Rework of the RPC code to improve performance and make the code cleaner - - The getrawtransaction RPC call now properly checks the memory pool - before consulting the db (https://github.com/conformal/btcd/issues/26) - - Add support for the following RPC calls: getpeerinfo, getconnectedcount, - addnode, verifychain - (https://github.com/conformal/btcd/issues/13) - (https://github.com/conformal/btcd/issues/17) - - Implement rescan websocket extension to allow wallet rescans - - Use correct paths for application data storage for all supported - operating systems (https://github.com/conformal/btcd/issues/30) - - Add a default redirect to the http profiling page when accessing the - http profile server - - Add a new --cpuprofile option which can be used to generate CPU - profiling data on platforms that support it - - Several other minor performance optimizations - - Other minor bug fixes and general code cleanup - -Changes in 0.3.2 (Tue Oct 22 2013) - - Fix an issue that could cause the download of the block chain to stall - (https://github.com/conformal/btcd/issues/12) - - Remove deprecated sqlite as an available database backend - - Close sqlite compile issue as sqlite has now been removed - (https://github.com/conformal/btcd/issues/11) - - Change default RPC ports to 8334 (mainnet) and 18334 (testnet) - - Continue cleanup and work on implementing RPC API calls - - Add support for the following RPC calls: getrawmempool, - getbestblockhash, decoderawtransaction, getdifficulty, - getconnectioncount, getpeerinfo, and addnode - - Improve the btcctl utility that is used to issue JSON-RPC commands - - Fix an issue preventing btcd from cleanly shutting down with the RPC - stop command - - Add a number of database interface tests to ensure backends implement - the expected interface - - Expose some additional information from btcscript to be used for - identifying "standard"" transactions - - Add support for plan9 - thanks @mischief - (https://github.com/conformal/btcd/pull/19) - - Other minor bug fixes and general code cleanup - -Changes in 0.3.1-alpha (Tue Oct 15 2013) - - Change default database to leveldb - NOTE: This does mean you will have to redownload the block chain. Since we - are still in alpha, we didn't feel writing a converter was worth the time as - it would take away from more important issues at this stage - - Add a warning if there are multiple block chain databases of different types - - Fix issue with unexpected EOF in leveldb -- https://github.com/conformal/btcd/issues/18 - - Fix issue preventing block 21066 on testnet -- https://github.com/conformal/btcchain/issues/1 - - Fix issue preventing block 96464 on testnet -- https://github.com/conformal/btcscript/issues/1 - - Optimize transaction lookups - - Correct a few cases of list removal that could result in improper cleanup - of no longer needed orphans - - Add functionality to increase ulimits on non-Windows platforms - - Add support for mempool command which allows remote peers to query the - transaction memory pool via the bitcoin protocol - - Clean up logging a bit - - Add a flag to disable checkpoints for developers - - Add a lot of useful debug logging such as message summaries - - Other minor bug fixes and general code cleanup - -Initial Release 0.3.0-alpha (Sat Oct 05 2013): - - Initial release diff --git a/LICENSE b/LICENSE index 53ba0c56..fa218625 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,6 @@ ISC License +Copyright (c) 2021 The LBRY developers Copyright (c) 2013-2017 The btcsuite developers Copyright (c) 2015-2016 The Decred developers diff --git a/README.md b/README.md index 5ec1454f..37e86a49 100644 --- a/README.md +++ b/README.md @@ -1,121 +1,133 @@ -btcd -==== +# lbcd -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) -[![Coverage Status](https://coveralls.io/repos/github/btcsuite/btcd/badge.svg?branch=master)](https://coveralls.io/github/btcsuite/btcd?branch=master) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) +[![Coverage Status](https://coveralls.io/repos/github/lbryio/lbcd/badge.svg?branch=master)](https://coveralls.io/github/lbryio/lbcd?branch=master) [![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd) + -btcd is an alternative full node bitcoin implementation written in Go (golang). +`lbcd` is a full node implementation of LBRY's blockchain written in Go (golang). -This project is currently under active development and is in a Beta state. It -is extremely stable and has been in production use since October 2013. +This project is currently under active development and is in a Beta state while +we ensure it matches LBRYcrd's functionality. The intention is that it properly +downloads, validates, and serves the block chain using the exact rules +(including consensus bugs) for block acceptance as LBRYcrd. +We have taken great care to avoid lbcd causing a fork to the blockchain. -It properly downloads, validates, and serves the block chain using the exact -rules (including consensus bugs) for block acceptance as Bitcoin Core. We have -taken great care to avoid btcd causing a fork to the block chain. It includes a -full block validation testing framework which contains all of the 'official' -block acceptance tests (and some additional ones) that is run on every pull -request to help ensure it properly follows consensus. Also, it passes all of -the JSON test data in the Bitcoin Core code. +Note: `lbcd` does *NOT* include wallet functionality. That functionality is provided by the +[lbcwallet](https://github.com/lbryio/lbcwallet) and the [LBRY SDK](https://github.com/lbryio/lbry-sdk). -It also properly relays newly mined blocks, maintains a transaction pool, and -relays individual transactions that have not yet made it into a block. It -ensures all individual transactions admitted to the pool follow the rules -required by the block chain and also includes more strict checks which filter -transactions based on miner requirements ("standard" transactions). +## Security -One key difference between btcd and Bitcoin Core is that btcd does *NOT* include -wallet functionality and this was a very intentional design decision. See the -blog entry [here](https://web.archive.org/web/20171125143919/https://blog.conformal.com/btcd-not-your-moms-bitcoin-daemon) -for more details. This means you can't actually make or receive payments -directly with btcd. That functionality is provided by the -[btcwallet](https://github.com/btcsuite/btcwallet) and -[Paymetheus](https://github.com/btcsuite/Paymetheus) (Windows-only) projects -which are both under active development. +We take security seriously. Please contact [security](mailto:security@lbry.com) regarding any security issues. +Our PGP key is [here](https://lbry.com/faq/pgp-key) if you need it. + +We maintain a mailing list for notifications of upgrades, security issues, +and soft/hard forks. To join, visit [fork list](https://lbry.com/forklist) ## Requirements -[Go](http://golang.org) 1.16 or newer. +All common operating systems are supported. lbcd requires at least 8GB of RAM +and at least 100GB of disk storage. Both RAM and disk requirements increase slowly over time. +Using a fast NVMe disk is recommended. + +`lbcd` is not immune to data loss. It expects a clean shutdown via SIGINT or +SIGTERM. SIGKILL, immediate VM kills, and sudden power loss can cause data +corruption, thus requiring chain resynchronization for recovery. + +For compilation, [Go](http://golang.org) 1.16 or newer is required. ## Installation -https://github.com/btcsuite/btcd/releases +Acquire binary files from [releases](https://github.com/lbryio/lbcd/releases) -#### Linux/BSD/MacOSX/POSIX - Build from Source +### To build from Source on Linux/BSD/MacOSX/POSIX -- Install Go according to the installation instructions here: - http://golang.org/doc/install +Install Go according to its [installation instructions](http://golang.org/doc/install). -- Ensure Go was installed properly and is a supported version: +``` sh +git clone https://github.com/lbryio/lbcd +cd lbcd -```bash -$ go version -$ go env GOROOT GOPATH +# Build lbcd +go build . + +# Build lbcctl +go build ./cmd/lbcctl ``` -NOTE: The `GOROOT` and `GOPATH` above must not be the same path. It is -recommended that `GOPATH` is set to a directory in your home directory such as -`~/goprojects` to avoid write permission issues. It is also recommended to add -`$GOPATH/bin` to your `PATH` at this point. +Both [GoLand](https://www.jetbrains.com/go/) +and [VS Code](https://code.visualstudio.com/docs/languages/go) IDEs are supported. -- Run the following commands to obtain btcd, all dependencies, and install it: +## Usage -```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd -$ GO111MODULE=on go install -v . ./cmd/... +By default, data and logs are stored in ``: + +- Linux: `~/.lbcd/` +- MacOS: `/Users//Library/Application Support/Lbcd/` + +To enable RPC access a username and password is required. Example: + +``` sh +./lbcd --rpcuser=rpcuser --rpcpass=rpcpass ``` -- btcd (and utilities) will now be installed in ```$GOPATH/bin```. If you did - not already add the bin directory to your system path during Go installation, - we recommend you do so now. +Interact with lbcd via RPC using `lbcctl` -## Updating - -#### Linux/BSD/MacOSX/POSIX - Build from Source - -- Run the following commands to update btcd, all dependencies, and install it: - -```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd -$ git pull -$ GO111MODULE=on go install -v . ./cmd/... +``` sh +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass getblockcount +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass getblocktemplate ``` -## Getting Started +By default, the RPCs are served over TLS. `lbcd` generates (if not exists) `rpc.cert` and +`rpc.key` under `` where `lbcctl` would search and use them. -btcd has several configuration options available to tweak how it runs, but all -of the basic operations described in the intro section work with zero -configuration. +The RPCs can also be served without TLS *(on localhost only)* using (`--notls`) -#### Linux/BSD/POSIX/Source - -```bash -$ ./btcd +``` sh +./lbcd --rpcuser=rpcuser --rpcpass=rpcpass --notls +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass --notls getblockcount ``` -## IRC +## Working with Different Networks -- irc.libera.chat -- channel #btcd -- [webchat](https://web.libera.chat/gamja/?channels=btcd) +By default, `lbcd` and `lbcctl` use the following ports for different networks respectively: -## Issue Tracker +| Network | RPC Port | Network Port | +| ------- | -------- | ------------ | +| mainnet | 9245 | 9246 | +| testnet | 19245 | 19246 | +| regtest | 29245 | 29246 | -The [integrated github issue tracker](https://github.com/btcsuite/btcd/issues) -is used for this project. +Running `lbcd` and `lbcctl` with `--testnet` or `--regtest` would use different chain params as well as default RPC and Network ports. -## Documentation +``` sh +./lbcd --rpcuser=rpcuser --rpcpass=rpcpass --regtest +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass --regtest getblockcount +``` -The documentation is a work-in-progress. It is located in the [docs](https://github.com/btcsuite/btcd/tree/master/docs) folder. +The default Network and RPC ports of `lbcd` can be overriden using `--listen` and `--rpclisten` +`lbcctl` can also connect to RPC server specified by `--rpcserver` -## Release Verification +``` sh +./lbcd --rpcuser=rpcuser --rpcpass=rpcpass --regtest --listen=127.0.0.1:29248 --rpclisten=127.0.0.1:29247 +./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass --regtest --rpcserver=127.0.0.1:29247 getblockcount +``` +Note: Wallet related RPCs are provided by [lbcwallet](https://github.com/lbryio/lbcwallet). + +## Contributing + +Contributions to this project are welcome, encouraged, and compensated. +The [integrated github issue tracker](https://github.com/lbryio/lbcd/issues) +is used for this project. All pull requests will be considered. + + ## License -btcd is licensed under the [copyfree](http://copyfree.org) ISC License. +lbcd is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/blockchain/README.md b/blockchain/README.md index 2237780c..cb9ddb45 100644 --- a/blockchain/README.md +++ b/blockchain/README.md @@ -1,30 +1,9 @@ blockchain ========== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain) -Package blockchain implements bitcoin block handling and chain selection rules. -The test coverage is currently only around 60%, but will be increasing over -time. See `test_coverage.txt` for the gocov coverage report. Alternatively, if -you are running a POSIX OS, you can run the `cov_report.sh` script for a -real-time report. Package blockchain is licensed under the liberal ISC license. - -There is an associated blog post about the release of this package -[here](https://blog.conformal.com/btcchain-the-bitcoin-chain-package-from-bctd/). - -This package has intentionally been designed so it can be used as a standalone -package for any projects needing to handle processing of blocks into the bitcoin -block chain. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/blockchain -``` - -## Bitcoin Chain Processing Overview +### Bitcoin Chain Processing Overview Before a block is allowed into the block chain, it must go through an intensive series of validation rules. The following list serves as a general outline of @@ -57,47 +36,4 @@ is by no means exhaustive: transaction values - Run the transaction scripts to verify the spender is allowed to spend the coins - - Insert the block into the block database - -## Examples - -* [ProcessBlock Example](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain#example-BlockChain-ProcessBlock) - Demonstrates how to create a new chain instance and use ProcessBlock to - attempt to add a block to the chain. This example intentionally - attempts to insert a duplicate genesis block to illustrate how an invalid - block is handled. - -* [CompactToBig Example](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain#example-CompactToBig) - Demonstrates how to convert the compact "bits" in a block header which - represent the target difficulty to a big integer and display it using the - typical hex notation. - -* [BigToCompact Example](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain#example-BigToCompact) - Demonstrates how to convert a target difficulty into the - compact "bits" in a block header which represent that target difficulty. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - - -Package blockchain is licensed under the [copyfree](http://copyfree.org) ISC -License. + - Insert the block into the block database \ No newline at end of file diff --git a/blockchain/fullblocktests/README.md b/blockchain/fullblocktests/README.md index 943989be..de7781dc 100644 --- a/blockchain/fullblocktests/README.md +++ b/blockchain/fullblocktests/README.md @@ -1,9 +1,9 @@ fullblocktests ============== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain/fullblocktests) +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/lbryio/lbcd/blockchain/fullblocktests) Package fullblocktests provides a set of full block tests to be used for testing the consensus validation rules. The tests are intended to be flexible enough to @@ -20,7 +20,7 @@ of blocks that exercise the consensus validation rules. ## Installation and Updating ```bash -$ go get -u github.com/btcsuite/btcd/blockchain/fullblocktests +$ go get -u github.com/lbryio/lbcd/blockchain/fullblocktests ``` ## License diff --git a/blockchain/indexers/README.md b/blockchain/indexers/README.md index f4849152..989cb555 100644 --- a/blockchain/indexers/README.md +++ b/blockchain/indexers/README.md @@ -1,9 +1,9 @@ indexers ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain/indexers?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/blockchain/indexers) +[![GoDoc](https://pkg.go.dev/github.com/lbryio/lbcd/blockchain/indexers?status.png)](https://pkg.go.dev/github.com/lbryio/lbcd/blockchain/indexers) Package indexers implements optional block chain indexes. @@ -23,7 +23,7 @@ via an RPC interface. ## Installation ```bash -$ go get -u github.com/btcsuite/btcd/blockchain/indexers +$ go get -u github.com/lbryio/lbcd/blockchain/indexers ``` ## License diff --git a/btcec/README.md b/btcec/README.md index a6dd2cf2..0cf57a80 100644 --- a/btcec/README.md +++ b/btcec/README.md @@ -1,68 +1,11 @@ btcec ===== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/btcec?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/btcec) -Package btcec implements elliptic curve cryptography needed for working with +btcec implements elliptic curve cryptography needed for working with Bitcoin (secp256k1 only for now). It is designed so that it may be used with the standard crypto/ecdsa packages provided with go. A comprehensive suite of test is provided to ensure proper functionality. Package btcec was originally based on work from ThePiachu which is licensed under the same terms as Go, but it has -signficantly diverged since then. The btcsuite developers original is licensed -under the liberal ISC license. - -Although this package was primarily written for btcd, it has intentionally been -designed so it can be used as a standalone package for any projects needing to -use secp256k1 elliptic curve cryptography. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/btcec -``` - -## Examples - -* [Sign Message](https://pkg.go.dev/github.com/btcsuite/btcd/btcec#example-package--SignMessage) - Demonstrates signing a message with a secp256k1 private key that is first - parsed form raw bytes and serializing the generated signature. - -* [Verify Signature](https://pkg.go.dev/github.com/btcsuite/btcd/btcec#example-package--VerifySignature) - Demonstrates verifying a secp256k1 signature against a public key that is - first parsed from raw bytes. The signature is also parsed from raw bytes. - -* [Encryption](https://pkg.go.dev/github.com/btcsuite/btcd/btcec#example-package--EncryptMessage) - Demonstrates encrypting a message for a public key that is first parsed from - raw bytes, then decrypting it using the corresponding private key. - -* [Decryption](https://pkg.go.dev/github.com/btcsuite/btcd/btcec#example-package--DecryptMessage) - Demonstrates decrypting a message using a private key that is first parsed - from raw bytes. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package btcec is licensed under the [copyfree](http://copyfree.org) ISC License -except for btcec.go and btcec_test.go which is under the same license as Go. - +signficantly diverged since then. \ No newline at end of file diff --git a/btcjson/README.md b/btcjson/README.md index 48f32263..9d981333 100644 --- a/btcjson/README.md +++ b/btcjson/README.md @@ -1,70 +1,8 @@ btcjson ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson) Package btcjson implements concrete types for marshalling to and from the bitcoin JSON-RPC API. A comprehensive suite of tests is provided to ensure -proper functionality. - -Although this package was primarily written for the btcsuite, it has -intentionally been designed so it can be used as a standalone package for any -projects needing to marshal to and from bitcoin JSON-RPC requests and responses. - -Note that although it's possible to use this package directly to implement an -RPC client, it is not recommended since it is only intended as an infrastructure -package. Instead, RPC clients should use the -[btcrpcclient](https://github.com/btcsuite/btcrpcclient) package which provides -a full blown RPC client with many features such as automatic connection -management, websocket support, automatic notification re-registration on -reconnect, and conversion from the raw underlying RPC types (strings, floats, -ints, etc) to higher-level types with many nice and useful properties. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/btcjson -``` - -## Examples - -* [Marshal Command](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson#example-MarshalCmd) - Demonstrates how to create and marshal a command into a JSON-RPC request. - -* [Unmarshal Command](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson#example-UnmarshalCmd) - Demonstrates how to unmarshal a JSON-RPC request and then unmarshal the - concrete request into a concrete command. - -* [Marshal Response](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson#example-MarshalResponse) - Demonstrates how to marshal a JSON-RPC response. - -* [Unmarshal Response](https://pkg.go.dev/github.com/btcsuite/btcd/btcjson#example-package--UnmarshalResponse) - Demonstrates how to unmarshal a JSON-RPC response and then unmarshal the - result field in the response to a concrete type. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package btcjson is licensed under the [copyfree](http://copyfree.org) ISC -License. +proper functionality. \ No newline at end of file diff --git a/chaincfg/README.md b/chaincfg/README.md index 72fac2e7..da3254c7 100644 --- a/chaincfg/README.md +++ b/chaincfg/README.md @@ -1,85 +1,8 @@ chaincfg ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/chaincfg) Package chaincfg defines chain configuration parameters for the three standard -Bitcoin networks and provides the ability for callers to define their own custom -Bitcoin networks. - -Although this package was primarily written for btcd, it has intentionally been -designed so it can be used as a standalone package for any projects needing to -use parameters for the standard Bitcoin networks or for projects needing to -define their own network. - -## Sample Use - -```Go -package main - -import ( - "flag" - "fmt" - "log" - - "github.com/btcsuite/btcutil" - "github.com/btcsuite/btcd/chaincfg" -) - -var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network") - -// By default (without -testnet), use mainnet. -var chainParams = &chaincfg.MainNetParams - -func main() { - flag.Parse() - - // Modify active network parameters if operating on testnet. - if *testnet { - chainParams = &chaincfg.TestNet3Params - } - - // later... - - // Create and print new payment address, specific to the active network. - pubKeyHash := make([]byte, 20) - addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, chainParams) - if err != nil { - log.Fatal(err) - } - fmt.Println(addr) -} -``` - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/chaincfg -``` - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package chaincfg is licensed under the [copyfree](http://copyfree.org) ISC -License. +LBRY networks and provides the ability for callers to define their own custom +LBRY networks. \ No newline at end of file diff --git a/chaincfg/chainhash/README.md b/chaincfg/chainhash/README.md index b7ddf19e..da54f734 100644 --- a/chaincfg/chainhash/README.md +++ b/chaincfg/chainhash/README.md @@ -1,9 +1,9 @@ chainhash ========= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/chaincfg/chainhash) +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/lbryio/lbcd/chaincfg/chainhash) ======= chainhash provides a generic hash type and associated functions that allows the @@ -12,7 +12,7 @@ specific hash algorithm to be abstracted. ## Installation and Updating ```bash -$ go get -u github.com/btcsuite/btcd/chaincfg/chainhash +$ go get -u github.com/lbryio/lbcd/chaincfg/chainhash ``` ## GPG Verification Key diff --git a/connmgr/README.md b/connmgr/README.md index b1aa3cc7..5237bf46 100644 --- a/connmgr/README.md +++ b/connmgr/README.md @@ -1,13 +1,11 @@ connmgr ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/connmgr) -Package connmgr implements a generic Bitcoin network connection manager. +Package connmgr implements a generic network connection manager. -## Overview +### Overview Connection Manager handles all the general connection concerns such as maintaining a set number of outbound connections, sourcing peers, banning, @@ -18,20 +16,10 @@ connection requests from a source or a set of given addresses, dial them and notify the caller on connections. The main intended use is to initialize a pool of active connections and maintain them to remain connected to the P2P network. -In addition the connection manager provides the following utilities: +In addition, the connection manager provides the following utilities: - Notifications on connections or disconnections - Handle failures and retry new addresses from the source - Connect only to specified addresses - Permanent connections with increasing backoff retry timers -- Disconnect or Remove an established connection - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/connmgr -``` - -## License - -Package connmgr is licensed under the [copyfree](http://copyfree.org) ISC License. +- Disconnect or Remove an established connection \ No newline at end of file diff --git a/database/README.md b/database/README.md index 21563d1a..6e937304 100644 --- a/database/README.md +++ b/database/README.md @@ -1,9 +1,7 @@ database ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/database) Package database provides a block and metadata storage database. @@ -13,8 +11,8 @@ one entity can have the database open at a time (for most database backends), and that entity will be btcd. When a client wants programmatic access to the data provided by btcd, they'll -likely want to use the [rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) -package which makes use of the [JSON-RPC API](https://github.com/btcsuite/btcd/tree/master/docs/json_rpc_api.md). +likely want to use the [rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) +package which makes use of the [JSON-RPC API](https://github.com/lbryio/lbcd/tree/master/docs/json_rpc_api.md). However, this package could be extremely useful for any applications requiring Bitcoin block storage capabilities. @@ -32,26 +30,4 @@ storage, and strict checksums in key areas to ensure data integrity. - Nested buckets - Iteration support including cursors with seek capability - Supports registration of backend databases -- Comprehensive test coverage - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/database -``` - -## Examples - -* [Basic Usage Example](https://pkg.go.dev/github.com/btcsuite/btcd/database#example-package--BasicUsage) - Demonstrates creating a new database and using a managed read-write - transaction to store and retrieve metadata. - -* [Block Storage and Retrieval Example](https://pkg.go.dev/github.com/btcsuite/btcd/database#example-package--BlockStorageAndRetrieval) - Demonstrates creating a new database, using a managed read-write transaction - to store a block, and then using a managed read-only transaction to fetch the - block. - -## License - -Package database is licensed under the [copyfree](http://copyfree.org) ISC -License. +- Comprehensive test coverage \ No newline at end of file diff --git a/database/ffldb/README.md b/database/ffldb/README.md index 5b855faa..4a43fb73 100644 --- a/database/ffldb/README.md +++ b/database/ffldb/README.md @@ -1,9 +1,9 @@ ffldb ===== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/database/ffldb?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/database/ffldb) +[![GoDoc](https://pkg.go.dev/github.com/lbryio/lbcd/database/ffldb?status.png)](https://pkg.go.dev/github.com/lbryio/lbcd/database/ffldb) ======= Package ffldb implements a driver for the database package that uses leveldb for diff --git a/database/internal/treap/README.md b/database/internal/treap/README.md index 14c3159a..28f0c810 100644 --- a/database/internal/treap/README.md +++ b/database/internal/treap/README.md @@ -1,9 +1,9 @@ treap ===== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/database/internal/treap?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/database/internal/treap) +[![GoDoc](https://pkg.go.dev/github.com/lbryio/lbcd/database/internal/treap?status.png)](https://pkg.go.dev/github.com/lbryio/lbcd/database/internal/treap) Package treap implements a treap data structure that is used to hold ordered key/value pairs using a combination of binary search tree and heap semantics. diff --git a/doc.go b/doc.go index ce62a7cc..ee4a9405 100644 --- a/doc.go +++ b/doc.go @@ -71,8 +71,8 @@ Application Options: fee to the given amount in thousands of bytes per minute (default: 15) --listen= Add an interface/port to listen for connections - (default all interfaces port: 8333, testnet: - 18333, signet: 38333) + (default all interfaces port: 9246, testnet: + 19246, regtest: 29246, signet: 39246) --logdir= Directory to log output --maxorphantx= Max number of orphan transactions to keep in memory (default: 100) @@ -123,7 +123,7 @@ Application Options: --rpclimitpass= Password for limited RPC connections --rpclimituser= Username for limited RPC connections --rpclisten= Add an interface/port to listen for RPC - connections (default port: 8334, testnet: 18334) + connections (default port: 9245, testnet: 19245, regtest: 29245) --rpcmaxclients= Max number of RPC clients for standard connections (default: 10) --rpcmaxconcurrentreqs= Max number of concurrent RPC requests that may be diff --git a/docs/code_contribution_guidelines.md b/docs/code_contribution_guidelines.md deleted file mode 100644 index c0a7eecc..00000000 --- a/docs/code_contribution_guidelines.md +++ /dev/null @@ -1,319 +0,0 @@ -# Code contribution guidelines - -Developing cryptocurrencies is an exciting endeavor that touches a wide variety -of areas such as wire protocols, peer-to-peer networking, databases, -cryptography, language interpretation (transaction scripts), RPC, and -websockets. They also represent a radical shift to the current fiscal system -and as a result provide an opportunity to help reshape the entire financial -system. There are few projects that offer this level of diversity and impact -all in one code base. - -However, as exciting as it is, one must keep in mind that cryptocurrencies -represent real money and introducing bugs and security vulnerabilities can have -far more dire consequences than in typical projects where having a small bug is -minimal by comparison. In the world of cryptocurrencies, even the smallest bug -in the wrong area can cost people a significant amount of money. For this -reason, the btcd suite has a formalized and rigorous development process which -is outlined on this page. - -We highly encourage code contributions, however it is imperative that you adhere -to the guidelines established on this page. - -## Minimum Recommended Skillset - -The following list is a set of core competencies that we recommend you possess -before you really start attempting to contribute code to the project. These are -not hard requirements as we will gladly accept code contributions as long as -they follow the guidelines set forth on this page. That said, if you don't have -the following basic qualifications you will likely find it quite difficult to -contribute. - -- A reasonable understanding of bitcoin at a high level (see the - [Required Reading](#ReqReading) section for the original white paper) -- Experience in some type of C-like language -- An understanding of data structures and their performance implications -- Familiarity with unit testing -- Debugging experience -- Ability to understand not only the area you are making a change in, but also - the code your change relies on, and the code which relies on your changed code - -Building on top of those core competencies, the recommended skill set largely -depends on the specific areas you are looking to contribute to. For example, -if you wish to contribute to the cryptography code, you should have a good -understanding of the various aspects involved with cryptography such as the -security and performance implications. - -## Required Reading - -- [Effective Go](http://golang.org/doc/effective_go.html) - The entire btcd - suite follows the guidelines in this document. For your code to be accepted, - it must follow the guidelines therein. -- [Original Satoshi Whitepaper](http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCkQFjAA&url=http%3A%2F%2Fbitcoin.org%2Fbitcoin.pdf&ei=os3VUuH8G4SlsASV74GoAg&usg=AFQjCNEipPLigou_1MfB7DQjXCNdlylrBg&sig2=FaHDuT5z36GMWDEnybDJLg&bvm=bv.59378465,d.b2I) - This is the white paper that started it all. Having a solid - foundation to build on will make the code much more comprehensible. - -## Development Practices - -Developers are expected to work in their own trees and submit pull requests when -they feel their feature or bug fix is ready for integration into the master -branch. - -## Share Early, Share Often - -We firmly believe in the share early, share often approach. The basic premise -of the approach is to announce your plans **before** you start work, and once -you have started working, craft your changes into a stream of small and easily -reviewable commits. - -This approach has several benefits: - -- Announcing your plans to work on a feature **before** you begin work avoids - duplicate work -- It permits discussions which can help you achieve your goals in a way that is - consistent with the existing architecture -- It minimizes the chances of you spending time and energy on a change that - might not fit with the consensus of the community or existing architecture and - potentially be rejected as a result -- Incremental development helps ensure you are on the right track with regards - to the rest of the community -- The quicker your changes are merged to master, the less time you will need to - spend rebasing and otherwise trying to keep up with the main code base - -## Testing - -One of the major design goals of all core btcd packages is to aim for complete -test coverage. This is financial software so bugs and regressions can cost -people real money. For this reason every effort must be taken to ensure the -code is as accurate and bug-free as possible. Thorough testing is a good way to -help achieve that goal. - -Unless a new feature you submit is completely trivial, it will probably be -rejected unless it is also accompanied by adequate test coverage for both -positive and negative conditions. That is to say, the tests must ensure your -code works correctly when it is fed correct data as well as incorrect data -(error paths). - -Go provides an excellent test framework that makes writing test code and -checking coverage statistics straight forward. For more information about the -test coverage tools, see the [golang cover blog post](http://blog.golang.org/cover). - -A quick summary of test practices follows: - -- All new code should be accompanied by tests that ensure the code behaves - correctly when given expected values, and, perhaps even more importantly, that - it handles errors gracefully -- When you fix a bug, it should be accompanied by tests which exercise the bug - to both prove it has been resolved and to prevent future regressions - -## Code Documentation and Commenting - -- At a minimum every function must be commented with its intended purpose and - any assumptions that it makes - - Function comments must always begin with the name of the function per - [Effective Go](http://golang.org/doc/effective_go.html) - - Function comments should be complete sentences since they allow a wide - variety of automated presentations such as [go.dev](https://go.dev) - - The general rule of thumb is to look at it as if you were completely - unfamiliar with the code and ask yourself, would this give me enough - information to understand what this function does and how I'd probably want - to use it? -- Exported functions should also include detailed information the caller of the - function will likely need to know and/or understand: - -**WRONG** - -```Go -// convert a compact uint32 to big.Int -func CompactToBig(compact uint32) *big.Int { -``` - -**RIGHT** - -```Go -// CompactToBig converts a compact representation of a whole number N to a -// big integer. The representation is similar to IEEE754 floating point -// numbers. -// -// Like IEEE754 floating point, there are three basic components: the sign, -// the exponent, and the mantissa. They are broken out as follows: -// -// * the most significant 8 bits represent the unsigned base 256 exponent -// * bit 23 (the 24th bit) represents the sign bit -// * the least significant 23 bits represent the mantissa -// -// ------------------------------------------------- -// | Exponent | Sign | Mantissa | -// ------------------------------------------------- -// | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] | -// ------------------------------------------------- -// -// The formula to calculate N is: -// N = (-1^sign) * mantissa * 256^(exponent-3) -// -// This compact form is only used in bitcoin to encode unsigned 256-bit numbers -// which represent difficulty targets, thus there really is not a need for a -// sign bit, but it is implemented here to stay consistent with bitcoind. -func CompactToBig(compact uint32) *big.Int { -``` - -- Comments in the body of the code are highly encouraged, but they should - explain the intention of the code as opposed to just calling out the - obvious - -**WRONG** - -```Go -// return err if amt is less than 5460 -if amt < 5460 { - return err -} -``` - -**RIGHT** - -```Go -// Treat transactions with amounts less than the amount which is considered dust -// as non-standard. -if amt < 5460 { - return err -} -``` - -**NOTE:** The above should really use a constant as opposed to a magic number, -but it was left as a magic number to show how much of a difference a good -comment can make. - -## Model Git Commit Messages - -This project prefers to keep a clean commit history with well-formed commit -messages. This section illustrates a model commit message and provides a bit -of background for it. This content was originally created by Tim Pope and made -available on his website, however that website is no longer active, so it is -being provided here. - -Here’s a model Git commit message: - -```text -Short (50 chars or less) summary of changes - -More detailed explanatory text, if necessary. Wrap it to about 72 -characters or so. In some contexts, the first line is treated as the -subject of an email and the rest of the text as the body. The blank -line separating the summary from the body is critical (unless you omit -the body entirely); tools like rebase can get confused if you run the -two together. - -Write your commit message in the present tense: "Fix bug" and not "Fixed -bug." This convention matches up with commit messages generated by -commands like git merge and git revert. - -Further paragraphs come after blank lines. - -- Bullet points are okay, too -- Typically a hyphen or asterisk is used for the bullet, preceded by a - single space, with blank lines in between, but conventions vary here -- Use a hanging indent -``` - -Prefix the summary with the subsystem/package when possible. Many other -projects make use of the code and this makes it easier for them to tell when -something they're using has changed. Have a look at [past -commits](https://github.com/btcsuite/btcd/commits/master) for examples of -commit messages. - -Here are some of the reasons why wrapping your commit messages to 72 columns is -a good thing. - -- git log doesn’t do any special special wrapping of the commit messages. With - the default pager of less -S, this means your paragraphs flow far off the edge - of the screen, making them difficult to read. On an 80 column terminal, if we - subtract 4 columns for the indent on the left and 4 more for symmetry on the - right, we’re left with 72 columns. -- git format-patch --stdout converts a series of commits to a series of emails, - using the messages for the message body. Good email netiquette dictates we - wrap our plain text emails such that there’s room for a few levels of nested - reply indicators without overflow in an 80 column terminal. - -## Code Approval Process - -This section describes the code approval process that is used for code -contributions. This is how to get your changes into btcd. - -## Code Review - -All code which is submitted will need to be reviewed before inclusion into the -master branch. This process is performed by the project maintainers and usually -other committers who are interested in the area you are working in as well. - -## Code Review Timeframe - -The timeframe for a code review will vary greatly depending on factors such as -the number of other pull requests which need to be reviewed, the size and -complexity of the contribution, how well you followed the guidelines presented -on this page, and how easy it is for the reviewers to digest your commits. For -example, if you make one monolithic commit that makes sweeping changes to things -in multiple subsystems, it will obviously take much longer to review. You will -also likely be asked to split the commit into several smaller, and hence more -manageable, commits. - -Keeping the above in mind, most small changes will be reviewed within a few -days, while large or far reaching changes may take weeks. This is a good reason -to stick with the [Share Early, Share Often](#ShareOften) development practice -outlined above. - -## What is the review looking for? - -The review is mainly ensuring the code follows the [Development Practices](#DevelopmentPractices) -and [Code Contribution Standards](#Standards). However, there are a few other -checks which are generally performed as follows: - -- The code is stable and has no stability or security concerns -- The code is properly using existing APIs and generally fits well into the - overall architecture -- The change is not something which is deemed inappropriate by community - consensus - -## Rework Code (if needed) - -After the code review, the change will be accepted immediately if no issues are -found. If there are any concerns or questions, you will be provided with -feedback along with the next steps needed to get your contribution merged with -master. In certain cases the code reviewer(s) or interested committers may help -you rework the code, but generally you will simply be given feedback for you to -make the necessary changes. - -This process will continue until the code is finally accepted. - -## Acceptance - -Once your code is accepted, it will be integrated with the master branch. -Typically it will be rebased and fast-forward merged to master as we prefer to -keep a clean commit history over a tangled weave of merge commits. However, -regardless of the specific merge method used, the code will be integrated with -the master branch and the pull request will be closed. - -Rejoice as you will now be listed as a [contributor](https://github.com/btcsuite/btcd/graphs/contributors)! - -## Contribution Standards - -## Contribution Checklist - -- [  ] All changes are Go version 1.3 compliant -- [  ] The code being submitted is commented according to the - [Code Documentation and Commenting](#CodeDocumentation) section -- [  ] For new code: Code is accompanied by tests which exercise both - the positive and negative (error paths) conditions (if applicable) -- [  ] For bug fixes: Code is accompanied by new tests which trigger - the bug being fixed to prevent regressions -- [  ] Any new logging statements use an appropriate subsystem and - logging level -- [  ] Code has been formatted with `go fmt` -- [  ] Running `go test` does not fail any tests -- [  ] Running `go vet` does not report any issues -- [  ] Running [golint](https://github.com/golang/lint) does not - report any **new** issues that did not already exist - -## Licensing of Contributions - -All contributions must be licensed with the -[ISC license](https://github.com/btcsuite/btcd/blob/master/LICENSE). This is -the same license as all of the code in the btcd suite. diff --git a/docs/configuration.md b/docs/configuration.md index c6f95b27..1a02007b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,11 +1,11 @@ # Configuration -btcd has a number of [configuration](https://pkg.go.dev/github.com/btcsuite/btcd) -options, which can be viewed by running: `$ btcd --help`. +lbcd has a number of configuration +options, which can be viewed by running: `$ lbcd --help`. ## Peer server listen interface -btcd allows you to bind to specific interfaces which enables you to setup +lbcd allows you to bind to specific interfaces which enables you to setup configurations with varying levels of complexity. The listen parameter can be specified on the command line as shown below with the -- prefix or in the configuration file without the -- prefix (as can all long command line options). @@ -16,42 +16,42 @@ interfaces as a couple of the examples below illustrate. Command Line Examples: -|Flags|Comment| -|----------|------------| -|--listen=|all interfaces on default port which is changed by `--testnet` and `--regtest` (**default**)| -|--listen=0.0.0.0|all IPv4 interfaces on default port which is changed by `--testnet` and `--regtest`| -|--listen=::|all IPv6 interfaces on default port which is changed by `--testnet` and `--regtest`| -|--listen=:8333|all interfaces on port 8333| -|--listen=0.0.0.0:8333|all IPv4 interfaces on port 8333| -|--listen=[::]:8333|all IPv6 interfaces on port 8333| -|--listen=127.0.0.1:8333|only IPv4 localhost on port 8333| -|--listen=[::1]:8333|only IPv6 localhost on port 8333| -|--listen=:8336|all interfaces on non-standard port 8336| -|--listen=0.0.0.0:8336|all IPv4 interfaces on non-standard port 8336| -|--listen=[::]:8336|all IPv6 interfaces on non-standard port 8336| -|--listen=127.0.0.1:8337 --listen=[::1]:8333|IPv4 localhost on port 8337 and IPv6 localhost on port 8333| -|--listen=:8333 --listen=:8337|all interfaces on ports 8333 and 8337| +| Flags | Comment | +| ------------------------------------------- | -------------------------------------------------------------------------------------------- | +| --listen= | all interfaces on default port which is changed by `--testnet` and `--regtest` (**default**) | +| --listen=0.0.0.0 | all IPv4 interfaces on default port which is changed by `--testnet` and `--regtest` | +| --listen=:: | all IPv6 interfaces on default port which is changed by `--testnet` and `--regtest` | +| --listen=:9246 | all interfaces on port 9246 | +| --listen=0.0.0.0:9246 | all IPv4 interfaces on port 9246 | +| --listen=[::]:9246 | all IPv6 interfaces on port 9246 | +| --listen=127.0.0.1:9246 | only IPv4 localhost on port 9246 | +| --listen=[::1]:9246 | only IPv6 localhost on port 9246 | +| --listen=:9247 | all interfaces on non-standard port 9247 | +| --listen=0.0.0.0:9247 | all IPv4 interfaces on non-standard port 9247 | +| --listen=[::]:9247 | all IPv6 interfaces on non-standard port 9247 | +| --listen=127.0.0.1:9248 --listen=[::1]:9246 | IPv4 localhost on port 9248 and IPv6 localhost on port 9246 | +| --listen=:9246 --listen=:9248 | all interfaces on ports 9246 and 9248 | -The following config file would configure btcd to only listen on localhost for both IPv4 and IPv6: +The following config file would configure lbcd to only listen on localhost for both IPv4 and IPv6: ```text [Application Options] -listen=127.0.0.1:8333 -listen=[::1]:8333 +listen=127.0.0.1:9246 +listen=[::1]:9246 ``` -In addition, if you are starting btcd with TLS and want to make it +In addition, if you are starting lbcd with TLS and want to make it available via a hostname, then you will need to generate the TLS certificates for that host. For example, ``` -gencerts --host=myhostname.example.com --directory=/home/me/.btcd/ +gencerts --host=myhostname.example.com --directory=/home/me/.lbcd/ ``` ## RPC server listen interface -btcd allows you to bind the RPC server to specific interfaces which enables you +lbcd allows you to bind the RPC server to specific interfaces which enables you to setup configurations with varying levels of complexity. The `rpclisten` parameter can be specified on the command line as shown below with the -- prefix or in the configuration file without the -- prefix (as can all long command line @@ -76,23 +76,23 @@ A few things to note regarding the RPC server: Command Line Examples: -|Flags|Comment| -|----------|------------| -|--rpclisten=|all interfaces on default port which is changed by `--testnet`| -|--rpclisten=0.0.0.0|all IPv4 interfaces on default port which is changed by `--testnet`| -|--rpclisten=::|all IPv6 interfaces on default port which is changed by `--testnet`| -|--rpclisten=:8334|all interfaces on port 8334| -|--rpclisten=0.0.0.0:8334|all IPv4 interfaces on port 8334| -|--rpclisten=[::]:8334|all IPv6 interfaces on port 8334| -|--rpclisten=127.0.0.1:8334|only IPv4 localhost on port 8334| -|--rpclisten=[::1]:8334|only IPv6 localhost on port 8334| -|--rpclisten=:8336|all interfaces on non-standard port 8336| -|--rpclisten=0.0.0.0:8336|all IPv4 interfaces on non-standard port 8336| -|--rpclisten=[::]:8336|all IPv6 interfaces on non-standard port 8336| -|--rpclisten=127.0.0.1:8337 --listen=[::1]:8334|IPv4 localhost on port 8337 and IPv6 localhost on port 8334| -|--rpclisten=:8334 --listen=:8337|all interfaces on ports 8334 and 8337| +| Flags | Comment | +| ---------------------------------------------- | ------------------------------------------------------------------- | +| --rpclisten= | all interfaces on default port which is changed by `--testnet` | +| --rpclisten=0.0.0.0 | all IPv4 interfaces on default port which is changed by `--testnet` | +| --rpclisten=:: | all IPv6 interfaces on default port which is changed by `--testnet` | +| --rpclisten=:9245 | all interfaces on port 9245 | +| --rpclisten=0.0.0.0:9245 | all IPv4 interfaces on port 9245 | +| --rpclisten=[::]:9245 | all IPv6 interfaces on port 9245 | +| --rpclisten=127.0.0.1:9245 | only IPv4 localhost on port 9245 | +| --rpclisten=[::1]:9245 | only IPv6 localhost on port 9245 | +| --rpclisten=:9247 | all interfaces on non-standard port 9247 | +| --rpclisten=0.0.0.0:9247 | all IPv4 interfaces on non-standard port 9247 | +| --rpclisten=[::]:9247 | all IPv6 interfaces on non-standard port 9247 | +| --rpclisten=127.0.0.1:9248 --listen=[::1]:9245 | IPv4 localhost on port 9248 and IPv6 localhost on port 9245 | +| --rpclisten=:9245 --listen=:9248 | all interfaces on ports 9245 and 9248 | -The following config file would configure the btcd RPC server to listen to all interfaces on the default port, including external interfaces, for both IPv4 and IPv6: +The following config file would configure the lbcd RPC server to listen to all interfaces on the default port, including external interfaces, for both IPv4 and IPv6: ```text [Application Options] @@ -102,21 +102,21 @@ rpclisten= ## Default ports -While btcd is highly configurable when it comes to the network configuration, +While lbcd is highly configurable when it comes to the network configuration, the following is intended to be a quick reference for the default ports used so port forwarding can be configured as required. -btcd provides a `--upnp` flag which can be used to automatically map the bitcoin +lbcd by default will automatically map the peer-to-peer listening port if your router supports UPnP. If your router does -not support UPnP, or you don't wish to use it, please note that only the bitcoin +not support UPnP, or you don't wish to use it, please note that only the peer-to-peer port should be forwarded unless you specifically want to allow RPC -access to your btcd from external sources such as in more advanced network -configurations. +access to your lbcd from external sources such as in more advanced network +configurations. You can disable UPnP with the `--noupnp` daemon option. -|Name|Port| -|----|----| -|Default Bitcoin peer-to-peer port|TCP 8333| -|Default RPC port|TCP 8334| +| Name | Port | +| ------------------------- | -------- | +| Default peer-to-peer port | TCP 9246 | +| Default RPC port | TCP 9245 | ## Using bootstrap.dat @@ -129,7 +129,7 @@ on the last time it was updated. See [this](https://bitcointalk.org/index.php?topic=145386.0) thread on bitcointalk for more details. -**NOTE:** Using bootstrap.dat is entirely optional. Btcd will download the +**NOTE:** Using bootstrap.dat is entirely optional. lbcd will download the block chain from other peers through the Bitcoin protocol with no extra configuration needed. @@ -165,14 +165,14 @@ checkpoints for the known-good block chain at periodic intervals. This ensures that not only is it a valid chain, but it is the same chain that everyone else is using. -### How do I use bootstrap.dat with btcd? +### How do I use bootstrap.dat with lbcd? -btcd comes with a separate utility named `addblock` which can be used to import +lbcd comes with a separate utility named `addblock` which can be used to import `bootstrap.dat`. This approach is used since the import is a one-time operation and we prefer to keep the daemon itself as lightweight as possible. -1. Stop btcd if it is already running. This is required since addblock needs to - access the database used by btcd and it will be locked if btcd is using it. +1. Stop lbcd if it is already running. This is required since addblock needs to + access the database used by lbcd and it will be locked if lbcd is using it. 2. Note the path to the downloaded bootstrap.dat file. 3. Run the addblock utility with the `-i` argument pointing to the location of boostrap.dat: @@ -180,7 +180,7 @@ and we prefer to keep the daemon itself as lightweight as possible. **Windows:** ```bat -"%PROGRAMFILES%\Btcd Suite\Btcd\addblock" -i C:\Path\To\bootstrap.dat +"%PROGRAMFILES%\lbcd Suite\lbcd\addblock" -i C:\Path\To\bootstrap.dat ``` **Linux/Unix/BSD/POSIX:** diff --git a/docs/configuring_tor.md b/docs/configuring_tor.md index ecb03bfc..84bc0efd 100644 --- a/docs/configuring_tor.md +++ b/docs/configuring_tor.md @@ -1,9 +1,9 @@ # Configuring TOR -btcd provides full support for anonymous networking via the +lbcd provides full support for anonymous networking via the [Tor Project](https://www.torproject.org/), including [client-only](#Client) and [hidden service](#HiddenService) configurations along with -[stream isolation](#TorStreamIsolation). In addition, btcd supports a hybrid, +[stream isolation](#TorStreamIsolation). In addition, lbcd supports a hybrid, [bridge mode](#Bridge) which is not anonymous, but allows it to operate as a bridge between regular nodes and hidden service nodes without routing the regular connections through Tor. @@ -15,15 +15,15 @@ hidden service for this reason. ## Client-only -Configuring btcd as a Tor client is straightforward. The first step is +Configuring lbcd as a Tor client is straightforward. The first step is obviously to install Tor and ensure it is working. Once that is done, all that -typically needs to be done is to specify the `--proxy` flag via the btcd command -line or in the btcd configuration file. Typically the Tor proxy address will be +typically needs to be done is to specify the `--proxy` flag via the lbcd command +line or in the lbcd configuration file. Typically the Tor proxy address will be 127.0.0.1:9050 (if using standalone Tor) or 127.0.0.1:9150 (if using the Tor Browser Bundle). If you have Tor configured to require a username and password, you may specify them with the `--proxyuser` and `--proxypass` flags. -By default, btcd assumes the proxy specified with `--proxy` is a Tor proxy and +By default, lbcd assumes the proxy specified with `--proxy` is a Tor proxy and hence will send all traffic, including DNS resolution requests, via the specified proxy. @@ -34,7 +34,7 @@ not be reachable for inbound connections unless you also configure a Tor ### Command line example ```bash -./btcd --proxy=127.0.0.1:9050 +./lbcd --proxy=127.0.0.1:9050 ``` ### Config file example @@ -51,7 +51,7 @@ The first step is to configure Tor to provide a hidden service. Documentation for this can be found on the Tor project website [here](https://www.torproject.org/docs/tor-hidden-service.html.en). However, there is no need to install a web server locally as the linked instructions -discuss since btcd will act as the server. +discuss since lbcd will act as the server. In short, the instructions linked above entail modifying your `torrc` file to add something similar to the following, restarting Tor, and opening the @@ -59,12 +59,12 @@ add something similar to the following, restarting Tor, and opening the address. ```text -HiddenServiceDir /var/tor/btcd -HiddenServicePort 8333 127.0.0.1:8333 +HiddenServiceDir /var/tor/lbcd +HiddenServicePort 9246 127.0.0.1:9246 ``` Once Tor is configured to provide the hidden service and you have obtained your -generated .onion address, configuring btcd as a Tor hidden service requires +generated .onion address, configuring lbcd as a Tor hidden service requires three flags: * `--proxy` to identify the Tor (SOCKS 5) proxy to use for outgoing traffic. @@ -76,7 +76,7 @@ three flags: ### Command line example ```bash -./btcd --proxy=127.0.0.1:9050 --listen=127.0.0.1 --externalip=fooanon.onion +./lbcd --proxy=127.0.0.1:9050 --listen=127.0.0.1 --externalip=fooanon.onion ``` ### Config file example @@ -91,13 +91,13 @@ externalip=fooanon.onion ## Bridge mode (not anonymous) -btcd provides support for operating as a bridge between regular nodes and hidden +lbcd provides support for operating as a bridge between regular nodes and hidden service nodes. In particular this means only traffic which is directed to or from a .onion address is sent through Tor while other traffic is sent normally. _As a result, this mode is **NOT** anonymous._ This mode works by specifying an onion-specific proxy, which is pointed at Tor, -by using the `--onion` flag via the btcd command line or in the btcd +by using the `--onion` flag via the lbcd command line or in the lbcd configuration file. If you have Tor configured to require a username and password, you may specify them with the `--onionuser` and `--onionpass` flags. @@ -111,7 +111,7 @@ routed via Tor due to the `--onion` flag. ### Command line example ```bash -./btcd --onion=127.0.0.1:9050 --externalip=fooanon.onion +./lbcd --onion=127.0.0.1:9050 --externalip=fooanon.onion ``` ### Config file example @@ -128,13 +128,13 @@ externalip=fooanon.onion Tor stream isolation forces Tor to build a new circuit for each connection making it harder to correlate connections. -btcd provides support for Tor stream isolation by using the `--torisolation` +lbcd provides support for Tor stream isolation by using the `--torisolation` flag. This option requires --proxy or --onionproxy to be set. ### Command line example ```bash -./btcd --proxy=127.0.0.1:9050 --torisolation +./lbcd --proxy=127.0.0.1:9050 --torisolation ``` ### Config file example diff --git a/docs/contact.md b/docs/contact.md deleted file mode 100644 index 1ed9fc0b..00000000 --- a/docs/contact.md +++ /dev/null @@ -1,15 +0,0 @@ -# Contact - -## IRC - -* [irc.libera.chat](irc://irc.libera.chat), channel `#btcd` - -## Mailing Lists - -* [btcd](mailto:btcd+subscribe@opensource.conformal.com): discussion of btcd and its packages. -* [btcd-commits](mailto:btcd-commits+subscribe@opensource.conformal.com): readonly mail-out of source code changes. - -## Issue Tracker - -The [integrated github issue tracker](https://github.com/btcsuite/btcd/issues) -is used for this project. diff --git a/docs/controlling.md b/docs/controlling.md index 93ab403b..a187e412 100644 --- a/docs/controlling.md +++ b/docs/controlling.md @@ -1,11 +1,11 @@ -# Controlling and querying btcd via btcctl +# Controlling and querying lbcd via lbcctl -btcctl is a command line utility that can be used to both control and query btcd -via [RPC](http://www.wikipedia.org/wiki/Remote_procedure_call). btcd does +lbcctl is a command line utility that can be used to both control and query lbcd +via [RPC](http://www.wikipedia.org/wiki/Remote_procedure_call). lbcd does **not** enable its RPC server by default; You must configure at minimum both an RPC username and password or both an RPC limited username and password: -* btcd.conf configuration file +* lbcd.conf configuration file ```bash [Application Options] @@ -15,7 +15,7 @@ rpclimituser=mylimituser rpclimitpass=Limitedp4ssw0rd ``` -* btcctl.conf configuration file +* lbcctl.conf configuration file ```bash [Application Options] @@ -31,4 +31,4 @@ rpclimituser=mylimituser rpclimitpass=Limitedp4ssw0rd ``` -For a list of available options, run: `$ btcctl --help` +For a list of available options, run: `$ lbcctl --help` diff --git a/docs/developer_resources.md b/docs/developer_resources.md deleted file mode 100644 index cec8ce99..00000000 --- a/docs/developer_resources.md +++ /dev/null @@ -1,37 +0,0 @@ -# Developer Resources - -* [Code Contribution Guidelines](https://github.com/btcsuite/btcd/tree/master/docs/code_contribution_guidelines.md) - -* [JSON-RPC Reference](https://github.com/btcsuite/btcd/tree/master/docs/json_rpc_api.md) - * [RPC Examples](https://github.com/btcsuite/btcd/tree/master/docs/json_rpc_api.md#ExampleCode) - -* The btcsuite Bitcoin-related Go Packages: - * [btcrpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) - Implements a - robust and easy to use Websocket-enabled Bitcoin JSON-RPC client - * [btcjson](https://github.com/btcsuite/btcd/tree/master/btcjson) - Provides an extensive API - for the underlying JSON-RPC command and return values - * [wire](https://github.com/btcsuite/btcd/tree/master/wire) - Implements the - Bitcoin wire protocol - * [peer](https://github.com/btcsuite/btcd/tree/master/peer) - - Provides a common base for creating and managing Bitcoin network peers. - * [blockchain](https://github.com/btcsuite/btcd/tree/master/blockchain) - - Implements Bitcoin block handling and chain selection rules - * [blockchain/fullblocktests](https://github.com/btcsuite/btcd/tree/master/blockchain/fullblocktests) - - Provides a set of block tests for testing the consensus validation rules - * [txscript](https://github.com/btcsuite/btcd/tree/master/txscript) - - Implements the Bitcoin transaction scripting language - * [btcec](https://github.com/btcsuite/btcd/tree/master/btcec) - Implements - support for the elliptic curve cryptographic functions needed for the - Bitcoin scripts - * [database](https://github.com/btcsuite/btcd/tree/master/database) - - Provides a database interface for the Bitcoin block chain - * [mempool](https://github.com/btcsuite/btcd/tree/master/mempool) - - Package mempool provides a policy-enforced pool of unmined bitcoin - transactions. - * [btcutil](https://github.com/btcsuite/btcutil) - Provides Bitcoin-specific - convenience functions and types - * [chainhash](https://github.com/btcsuite/btcd/tree/master/chaincfg/chainhash) - - Provides a generic hash type and associated functions that allows the - specific hash algorithm to be abstracted. - * [connmgr](https://github.com/btcsuite/btcd/tree/master/connmgr) - - Package connmgr implements a generic Bitcoin network connection manager. diff --git a/docs/index.md b/docs/index.md index 9d980626..a3792a6f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,57 +1,11 @@ -# btcd +# lbcd -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd) - -btcd is an alternative full node bitcoin implementation written in Go (golang). - -This project is currently under active development and is in a Beta state. It -is extremely stable and has been in production use since October 2013. - -It properly downloads, validates, and serves the block chain using the exact -rules (including consensus bugs) for block acceptance as Bitcoin Core. We have -taken great care to avoid btcd causing a fork to the block chain. It includes a -full block validation testing framework which contains all of the 'official' -block acceptance tests (and some additional ones) that is run on every pull -request to help ensure it properly follows consensus. Also, it passes all of -the JSON test data in the Bitcoin Core code. - -It also properly relays newly mined blocks, maintains a transaction pool, and -relays individual transactions that have not yet made it into a block. It -ensures all individual transactions admitted to the pool follow the rules -required by the block chain and also includes more strict checks which filter -transactions based on miner requirements ("standard" transactions). - -One key difference between btcd and Bitcoin Core is that btcd does *NOT* include -wallet functionality and this was a very intentional design decision. See the -blog entry [here](https://web.archive.org/web/20171125143919/https://blog.conformal.com/btcd-not-your-moms-bitcoin-daemon) -for more details. This means you can't actually make or receive payments -directly with btcd. That functionality is provided by the -[btcwallet](https://github.com/btcsuite/btcwallet) and -[Paymetheus](https://github.com/btcsuite/Paymetheus) (Windows-only) projects -which are both under active development. - -## Documentation - -Documentation is a work-in-progress. It is available at [btcd.readthedocs.io](https://btcd.readthedocs.io). ## Contents -* [Installation](installation.md) -* [Update](update.md) * [Configuration](configuration.md) * [Configuring TOR](configuring_tor.md) -* [Docker](using_docker.md) * [Controlling](controlling.md) * [Mining](mining.md) -* [Wallet](wallet.md) -* [Developer resources](developer_resources.md) * [JSON RPC API](json_rpc_api.md) -* [Code contribution guidelines](code_contribution_guidelines.md) -* [Contact](contact.md) - -## License - -btcd is licensed under the [copyfree](http://copyfree.org) ISC License. - diff --git a/docs/installation.md b/docs/installation.md deleted file mode 100644 index a74db560..00000000 --- a/docs/installation.md +++ /dev/null @@ -1,76 +0,0 @@ -# Installation - -The first step is to install btcd. See one of the following sections for -details on how to install on the supported operating systems. - -## Requirements - -[Go](http://golang.org) 1.16 or newer. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -* Download the Conformal public key: - https://raw.githubusercontent.com/btcsuite/btcd/master/release/GIT-GPG-KEY-conformal.txt - -* Import the public key into your GPG keyring: - - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -* Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - - ```bash - git tag -v TAG_NAME - ``` - -## Windows Installation - -* Install the MSI available at: [btcd windows installer](https://github.com/btcsuite/btcd/releases) -* Launch btcd from the Start Menu - -## Linux/BSD/MacOSX/POSIX Installation - -* Install Go according to the [installation instructions](http://golang.org/doc/install) -* Ensure Go was installed properly and is a supported version: - -```bash -go version -go env GOROOT GOPATH -``` - -NOTE: The `GOROOT` and `GOPATH` above must not be the same path. It is -recommended that `GOPATH` is set to a directory in your home directory such as -`~/goprojects` to avoid write permission issues. It is also recommended to add -`$GOPATH/bin` to your `PATH` at this point. - -* Run the following commands to obtain btcd, all dependencies, and install it: - -```bash -git clone https://github.com/btcsuite/btcd $GOPATH/src/github.com/btcsuite/btcd -cd $GOPATH/src/github.com/btcsuite/btcd -GO111MODULE=on go install -v . ./cmd/... -``` - -* btcd (and utilities) will now be installed in ```$GOPATH/bin```. If you did - not already add the bin directory to your system path during Go installation, - we recommend you do so now. - -## Gentoo Linux Installation - -* [Install Layman](https://gitlab.com/bitcoin/gentoo) and enable the Bitcoin overlay. -* Copy or symlink `/var/lib/layman/bitcoin/Documentation/package.keywords/btcd-live` to `/etc/portage/package.keywords/` -* Install btcd: `$ emerge net-p2p/btcd` - -## Startup - -Typically btcd will run and start downloading the block chain with no extra -configuration necessary, however, there is an optional method to use a -`bootstrap.dat` file that may speed up the initial block chain download process. - -* [Using bootstrap.dat](https://github.com/btcsuite/btcd/blob/master/docs/configuration.md#using-bootstrapdat) diff --git a/docs/json_rpc_api.md b/docs/json_rpc_api.md index db292d2b..17ccba64 100644 --- a/docs/json_rpc_api.md +++ b/docs/json_rpc_api.md @@ -27,27 +27,19 @@ ### 1. Overview -btcd provides a [JSON-RPC](http://json-rpc.org/wiki/specification) API that is +lbcd provides a [JSON-RPC](http://json-rpc.org/wiki/specification) API that is fully compatible with the original bitcoind/bitcoin-qt. There are a few key -differences between btcd and bitcoind as far as how RPCs are serviced: -* Unlike bitcoind that has the wallet and chain intermingled in the same process - which leads to several issues, btcd intentionally splits the wallet and chain - services into independent processes. See the blog post - [here](https://blog.conformal.com/btcd-not-your-moms-bitcoin-daemon/) for - further details on why they were separated. This means that if you are - talking directly to btcd, only chain-related RPCs are available. However both - chain-related and wallet-related RPCs are available via - [btcwallet](https://github.com/btcsuite/btcwallet). -* btcd is secure by default which means that the RPC connection is TLS-enabled +differences between lbcd and bitcoind as far as how RPCs are serviced: +* lbcd is secure by default which means that the RPC connection is TLS-enabled by default -* btcd provides access to the API through both +* lbcd provides access to the API through both [HTTP POST](http://en.wikipedia.org/wiki/POST_%28HTTP%29) requests and [Websockets](http://en.wikipedia.org/wiki/WebSocket) -Websockets are the preferred transport for btcd RPC and are used by applications +Websockets are the preferred transport for lbcd RPC and are used by applications such as [btcwallet](https://github.com/btcsuite/btcwallet) for inter-process -communication with btcd. The websocket connection endpoint for btcd is -`wss://your_ip_or_domain:8334/ws`. +communication with lbcd. The websocket connection endpoint for lbcd is +`wss://your_ip_or_domain:9245/ws`. In addition to the [standard API](#Methods), an [extension API](#WSExtMethods) has been developed that is exclusive to clients using Websockets. In its current @@ -64,7 +56,7 @@ The original bitcoind/bitcoin-qt JSON-RPC API documentation is available at [htt ### 2. HTTP POST Versus Websockets -The btcd RPC server supports both [HTTP POST](http://en.wikipedia.org/wiki/POST_%28HTTP%29) +The lbcd RPC server supports both [HTTP POST](http://en.wikipedia.org/wiki/POST_%28HTTP%29) requests and the preferred [Websockets](http://en.wikipedia.org/wiki/WebSocket). All of the [standard](#Methods) and [extension](#ExtensionMethods) methods described in this documentation can be accessed through both. As the name @@ -72,16 +64,16 @@ indicates, the [Websocket-specific extension](#WSExtMethods) methods can only be accessed when connected via Websockets. As mentioned in the [overview](#Overview), the websocket connection endpoint for -btcd is `wss://your_ip_or_domain:8334/ws`. +lbcd is `wss://your_ip_or_domain:9245/ws`. The most important differences between the two transports as it pertains to the JSON-RPC API are: -| |HTTP POST Requests|Websockets| -|---|------------------|----------| -|Allows multiple requests across a single connection|No|Yes| -|Supports asynchronous notifications|No|Yes| -|Scales well with large numbers of requests|No|Yes| +| | HTTP POST Requests | Websockets | +| --------------------------------------------------- | ------------------ | ---------- | +| Allows multiple requests across a single connection | No | Yes | +| Supports asynchronous notifications | No | Yes | +| Scales well with large numbers of requests | No | Yes |
@@ -92,18 +84,18 @@ JSON-RPC API are: **3.1 Authentication Overview**
The following authentication details are needed before establishing a connection -to a btcd RPC server: +to a lbcd RPC server: -* **rpcuser** is the full-access username configured for the btcd RPC server -* **rpcpass** is the full-access password configured for the btcd RPC server -* **rpclimituser** is the limited username configured for the btcd RPC server -* **rpclimitpass** is the limited password configured for the btcd RPC server -* **rpccert** is the PEM-encoded X.509 certificate (public key) that the btcd - server is configured with. It is automatically generated by btcd and placed - in the btcd home directory (which is typically `%LOCALAPPDATA%\Btcd` on - Windows and `~/.btcd` on POSIX-like OSes) +* **rpcuser** is the full-access username configured for the lbcd RPC server +* **rpcpass** is the full-access password configured for the lbcd RPC server +* **rpclimituser** is the limited username configured for the lbcd RPC server +* **rpclimitpass** is the limited password configured for the lbcd RPC server +* **rpccert** is the PEM-encoded X.509 certificate (public key) that the lbcd + server is configured with. It is automatically generated by lbcd and placed + in the lbcd home directory (which is typically `%LOCALAPPDATA%\lbcd` on + Windows and `~/.lbcd` on POSIX-like OSes) -**NOTE:** As mentioned above, btcd is secure by default which means the RPC +**NOTE:** As mentioned above, lbcd is secure by default which means the RPC server is not running unless configured with a **rpcuser** and **rpcpass** and/or a **rpclimituser** and **rpclimitpass**, and uses TLS authentication for all connections. @@ -117,7 +109,7 @@ two, mutually exclusive, methods. **3.2 HTTP Basic Access Authentication**
-The btcd RPC server uses HTTP [basic access authentication](http://en.wikipedia.org/wiki/Basic_access_authentication) with the **rpcuser** +The lbcd RPC server uses HTTP [basic access authentication](http://en.wikipedia.org/wiki/Basic_access_authentication) with the **rpcuser** and **rpcpass** detailed above. If the supplied credentials are invalid, you will be disconnected immediately upon making the connection. @@ -139,8 +131,8 @@ authenticated will cause the websocket to be closed immediately. ### 4. Command-line Utility -btcd comes with a separate utility named `btcctl` which can be used to issue -these RPC commands via HTTP POST requests to btcd after configuring it with the +lbcd comes with a separate utility named `lbcctl` which can be used to issue +these RPC commands via HTTP POST requests to lbcd after configuring it with the information in the [Authentication](#Authentication) section above. It can also be used to communicate with any server/daemon/service which provides a JSON-RPC API compatible with the original bitcoind/bitcoin-qt client. @@ -156,38 +148,38 @@ API compatible with the original bitcoind/bitcoin-qt client. The following is an overview of the RPC methods and their current status. Click the method name for further details such as parameter and return information. -|#|Method|Safe for limited user?|Description| -|---|------|----------|-----------| -|1|[addnode](#addnode)|N|Attempts to add or remove a persistent peer.| -|2|[createrawtransaction](#createrawtransaction)|Y|Returns a new transaction spending the provided inputs and sending to the provided addresses.| -|3|[decoderawtransaction](#decoderawtransaction)|Y|Returns a JSON object representing the provided serialized, hex-encoded transaction.| -|4|[decodescript](#decodescript)|Y|Returns a JSON object with information about the provided hex-encoded script.| -|5|[getaddednodeinfo](#getaddednodeinfo)|N|Returns information about manually added (persistent) peers.| -|6|[getbestblockhash](#getbestblockhash)|Y|Returns the hash of the of the best (most recent) block in the longest block chain.| -|7|[getblock](#getblock)|Y|Returns information about a block given its hash.| -|8|[getblockcount](#getblockcount)|Y|Returns the number of blocks in the longest block chain.| -|9|[getblockhash](#getblockhash)|Y|Returns hash of the block in best block chain at the given height.| -|10|[getblockheader](#getblockheader)|Y|Returns the block header of the block.| -|11|[getconnectioncount](#getconnectioncount)|N|Returns the number of active connections to other peers.| -|12|[getdifficulty](#getdifficulty)|Y|Returns the proof-of-work difficulty as a multiple of the minimum difficulty.| -|13|[getgenerate](#getgenerate)|N|Return if the server is set to generate coins (mine) or not.| -|14|[gethashespersec](#gethashespersec)|N|Returns a recent hashes per second performance measurement while generating coins (mining).| -|15|[getinfo](#getinfo)|Y|Returns a JSON object containing various state info.| -|16|[getmempoolinfo](#getmempoolinfo)|N|Returns a JSON object containing mempool-related information.| -|17|[getmininginfo](#getmininginfo)|N|Returns a JSON object containing mining-related information.| -|18|[getnettotals](#getnettotals)|Y|Returns a JSON object containing network traffic statistics.| -|19|[getnetworkhashps](#getnetworkhashps)|Y|Returns the estimated network hashes per second for the block heights provided by the parameters.| -|20|[getpeerinfo](#getpeerinfo)|N|Returns information about each connected network peer as an array of json objects.| -|21|[getrawmempool](#getrawmempool)|Y|Returns an array of hashes for all of the transactions currently in the memory pool.| -|22|[getrawtransaction](#getrawtransaction)|Y|Returns information about a transaction given its hash.| -|23|[help](#help)|Y|Returns a list of all commands or help for a specified command.| -|24|[ping](#ping)|N|Queues a ping to be sent to each connected peer.| -|25|[sendrawtransaction](#sendrawtransaction)|Y|Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.
btcd does not yet implement the `allowhighfees` parameter, so it has no effect| -|26|[setgenerate](#setgenerate) |N|Set the server to generate coins (mine) or not.
NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.| -|27|[stop](#stop)|N|Shutdown btcd.| -|28|[submitblock](#submitblock)|Y|Attempts to submit a new serialized, hex-encoded block to the network.| -|29|[validateaddress](#validateaddress)|Y|Verifies the given address is valid. NOTE: Since btcd does not have a wallet integrated, btcd will only return whether the address is valid or not.| -|30|[verifychain](#verifychain)|N|Verifies the block chain database.| +| # | Method | Safe for limited user? | Description | +| --- | --------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | [addnode](#addnode) | N | Attempts to add or remove a persistent peer. | +| 2 | [createrawtransaction](#createrawtransaction) | Y | Returns a new transaction spending the provided inputs and sending to the provided addresses. | +| 3 | [decoderawtransaction](#decoderawtransaction) | Y | Returns a JSON object representing the provided serialized, hex-encoded transaction. | +| 4 | [decodescript](#decodescript) | Y | Returns a JSON object with information about the provided hex-encoded script. | +| 5 | [getaddednodeinfo](#getaddednodeinfo) | N | Returns information about manually added (persistent) peers. | +| 6 | [getbestblockhash](#getbestblockhash) | Y | Returns the hash of the of the best (most recent) block in the longest block chain. | +| 7 | [getblock](#getblock) | Y | Returns information about a block given its hash. | +| 8 | [getblockcount](#getblockcount) | Y | Returns the number of blocks in the longest block chain. | +| 9 | [getblockhash](#getblockhash) | Y | Returns hash of the block in best block chain at the given height. | +| 10 | [getblockheader](#getblockheader) | Y | Returns the block header of the block. | +| 11 | [getconnectioncount](#getconnectioncount) | N | Returns the number of active connections to other peers. | +| 12 | [getdifficulty](#getdifficulty) | Y | Returns the proof-of-work difficulty as a multiple of the minimum difficulty. | +| 13 | [getgenerate](#getgenerate) | N | Return if the server is set to generate coins (mine) or not. | +| 14 | [gethashespersec](#gethashespersec) | N | Returns a recent hashes per second performance measurement while generating coins (mining). | +| 15 | [getinfo](#getinfo) | Y | Returns a JSON object containing various state info. | +| 16 | [getmempoolinfo](#getmempoolinfo) | N | Returns a JSON object containing mempool-related information. | +| 17 | [getmininginfo](#getmininginfo) | N | Returns a JSON object containing mining-related information. | +| 18 | [getnettotals](#getnettotals) | Y | Returns a JSON object containing network traffic statistics. | +| 19 | [getnetworkhashps](#getnetworkhashps) | Y | Returns the estimated network hashes per second for the block heights provided by the parameters. | +| 20 | [getpeerinfo](#getpeerinfo) | N | Returns information about each connected network peer as an array of json objects. | +| 21 | [getrawmempool](#getrawmempool) | Y | Returns an array of hashes for all of the transactions currently in the memory pool. | +| 22 | [getrawtransaction](#getrawtransaction) | Y | Returns information about a transaction given its hash. | +| 23 | [help](#help) | Y | Returns a list of all commands or help for a specified command. | +| 24 | [ping](#ping) | N | Queues a ping to be sent to each connected peer. | +| 25 | [sendrawtransaction](#sendrawtransaction) | Y | Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.
lbcd does not yet implement the `allowhighfees` parameter, so it has no effect | +| 26 | [setgenerate](#setgenerate) | N | Set the server to generate coins (mine) or not.
NOTE: Since lbcd does not have the wallet integrated to provide payment addresses, lbcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function. | +| 27 | [stop](#stop) | N | Shutdown lbcd. | +| 28 | [submitblock](#submitblock) | Y | Attempts to submit a new serialized, hex-encoded block to the network. | +| 29 | [validateaddress](#validateaddress) | Y | Verifies the given address is valid. NOTE: Since lbcd does not have a wallet integrated, lbcd will only return whether the address is valid or not. | +| 30 | [verifychain](#verifychain) | N | Verifies the block chain database. |
@@ -195,370 +187,370 @@ the method name for further details such as parameter and return information. -| | | -|---|---| -|Method|addnode| -|Parameters|1. peer (string, required) - ip address and port of the peer to operate on
2. command (string, required) - `add` to add a persistent peer, `remove` to remove a persistent peer, or `onetry` to try a single connection to a peer| -|Description|Attempts to add or remove a persistent peer.| -|Returns|Nothing| +| | | +| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | addnode | +| Parameters | 1. peer (string, required) - ip address and port of the peer to operate on
2. command (string, required) - `add` to add a persistent peer, `remove` to remove a persistent peer, or `onetry` to try a single connection to a peer | +| Description | Attempts to add or remove a persistent peer. | +| Returns | Nothing | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|createrawtransaction| -|Parameters|1. transaction inputs (JSON array, required) - json array of json objects
`[`
  `{`
    `"txid": "hash", (string, required) the hash of the input transaction`
    `"vout": n (numeric, required) the specific output of the input transaction to redeem`
  `}, ...`
`]`
2. addresses and amounts (JSON object, required) - json object with addresses as keys and amounts as values
`{`
  `"address": n.nnn (numeric, required) the address to send to as the key and the amount in BTC as the value`
  `, ...`
`}`
3. locktime (int64, optional, default=0) - specifies the transaction locktime. If non-zero, the inputs will also have their locktimes activated. | -|Description|Returns a new transaction spending the provided inputs and sending to the provided addresses.
The transaction inputs are not signed in the created transaction.
The `signrawtransaction` RPC command provided by wallet must be used to sign the resulting transaction.| -|Returns|`"transaction" (string) hex-encoded bytes of the serialized transaction`| -|Example Parameters|1. transaction inputs `[{"txid":"e6da89de7a6b8508ce8f371a3d0535b04b5e108cb1a6e9284602d3bfd357c018","vout":1}]`
2. addresses and amounts `{"13cgrTP7wgbZYWrY9BZ22BV6p82QXQT3nY": 0.49213337}`
3. locktime `0`| -|Example Return|`010000000118c057d3bfd3024628e9a6b18c105e4bb035053d1a378fce08856b7ade89dae6010000`
`0000ffffffff0199efee02000000001976a9141cb013db35ecccc156fdfd81d03a11c51998f99388`
`ac00000000`
**Newlines added for display purposes. The actual return does not contain newlines.**| +| | | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | createrawtransaction | +| Parameters | 1. transaction inputs (JSON array, required) - json array of json objects
`[`
  `{`
    `"txid": "hash", (string, required) the hash of the input transaction`
    `"vout": n (numeric, required) the specific output of the input transaction to redeem`
  `}, ...`
`]`
2. addresses and amounts (JSON object, required) - json object with addresses as keys and amounts as values
`{`
  `"address": n.nnn (numeric, required) the address to send to as the key and the amount in BTC as the value`
  `, ...`
`}`
3. locktime (int64, optional, default=0) - specifies the transaction locktime. If non-zero, the inputs will also have their locktimes activated. | +| Description | Returns a new transaction spending the provided inputs and sending to the provided addresses.
The transaction inputs are not signed in the created transaction.
The `signrawtransaction` RPC command provided by wallet must be used to sign the resulting transaction. | +| Returns | `"transaction" (string) hex-encoded bytes of the serialized transaction` | +| Example Parameters | 1. transaction inputs `[{"txid":"e6da89de7a6b8508ce8f371a3d0535b04b5e108cb1a6e9284602d3bfd357c018","vout":1}]`
2. addresses and amounts `{"13cgrTP7wgbZYWrY9BZ22BV6p82QXQT3nY": 0.49213337}`
3. locktime `0` | +| Example Return | `010000000118c057d3bfd3024628e9a6b18c105e4bb035053d1a378fce08856b7ade89dae6010000`
`0000ffffffff0199efee02000000001976a9141cb013db35ecccc156fdfd81d03a11c51998f99388`
`ac00000000`
**Newlines added for display purposes. The actual return does not contain newlines.** | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|decoderawtransaction| -|Parameters|1. data (string, required) - serialized, hex-encoded transaction| -|Description|Returns a JSON object representing the provided serialized, hex-encoded transaction.| -|Returns|`{ (json object)`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}`| -|Example Return|`{`
  `"txid": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"version": 1,`
  `"locktime": 0,`
  `"vin": [`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6...",`
      `"sequence": 4294967295,`
    `}`
  For non-coinbase transactions:
    `{`
      `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
      `"vout": 0,`
      `"scriptSig": {`
        `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
        `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
      `}`
      `"sequence": 4294967295,`
    `}`
  `]`
  `"vout": [`
    `{`
      `"value": 50,`
      `"n": 0,`
      `"scriptPubKey": {`
        `"asm": "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4ce...",`
        `"hex": "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4...",`
        `"reqSigs": 1,`
        `"type": "pubkey"`
        `"addresses": [`
          `"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",`
        `]`
      `}`
    `}`
  `]`
`}`| +| | | +| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | decoderawtransaction | +| Parameters | 1. data (string, required) - serialized, hex-encoded transaction | +| Description | Returns a JSON object representing the provided serialized, hex-encoded transaction. | +| Returns | `{ (json object)`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}` | +| Example Return | `{`
  `"txid": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"version": 1,`
  `"locktime": 0,`
  `"vin": [`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6...",`
      `"sequence": 4294967295,`
    `}`
  For non-coinbase transactions:
    `{`
      `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
      `"vout": 0,`
      `"scriptSig": {`
        `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
        `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
      `}`
      `"sequence": 4294967295,`
    `}`
  `]`
  `"vout": [`
    `{`
      `"value": 50,`
      `"n": 0,`
      `"scriptPubKey": {`
        `"asm": "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4ce...",`
        `"hex": "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4...",`
        `"reqSigs": 1,`
        `"type": "pubkey"`
        `"addresses": [`
          `"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",`
        `]`
      `}`
    `}`
  `]`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|decodescript| -|Parameters|1. script (string, required) - hex-encoded script| -|Description|Returns a JSON object with information about the provided hex-encoded script.| -|Returns|`{ (json object)`
  `"asm": "asm", (string) disassembly of the script`
  `"reqSigs": n, (numeric) the number of required signatures`
  `"type": "scripttype", (string) the type of the script (e.g. 'pubkeyhash')`
  `"addresses": [ (json array of string) the bitcoin addresses associated with this script`
    `"bitcoinaddress", (string) the bitcoin address`
    `...`
  `]`
  `"p2sh": "scripthash", (string) the script hash for use in pay-to-script-hash transactions`
`}`| -|Example Return|`{`
  `"asm": "OP_DUP OP_HASH160 b0a4d8a91981106e4ed85165a66748b19f7b7ad4 OP_EQUALVERIFY OP_CHECKSIG",`
  `"reqSigs": 1,`
  `"type": "pubkeyhash",`
  `"addresses": [`
    `"1H71QVBpzuLTNUh5pewaH3UTLTo2vWgcRJ"`
  `]`
  `"p2sh": "359b84ff799f48231990ff0298206f54117b08b6"`
`}`| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | decodescript | +| Parameters | 1. script (string, required) - hex-encoded script | +| Description | Returns a JSON object with information about the provided hex-encoded script. | +| Returns | `{ (json object)`
  `"asm": "asm", (string) disassembly of the script`
  `"reqSigs": n, (numeric) the number of required signatures`
  `"type": "scripttype", (string) the type of the script (e.g. 'pubkeyhash')`
  `"addresses": [ (json array of string) the bitcoin addresses associated with this script`
    `"bitcoinaddress", (string) the bitcoin address`
    `...`
  `]`
  `"p2sh": "scripthash", (string) the script hash for use in pay-to-script-hash transactions`
`}` | +| Example Return | `{`
  `"asm": "OP_DUP OP_HASH160 b0a4d8a91981106e4ed85165a66748b19f7b7ad4 OP_EQUALVERIFY OP_CHECKSIG",`
  `"reqSigs": 1,`
  `"type": "pubkeyhash",`
  `"addresses": [`
    `"1H71QVBpzuLTNUh5pewaH3UTLTo2vWgcRJ"`
  `]`
  `"p2sh": "359b84ff799f48231990ff0298206f54117b08b6"`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getaddednodeinfo| -|Parameters|1. dns (boolean, required) - specifies whether the returned data is a JSON object including DNS and connection information, or just a list of added peers
2. node (string, optional) - only return information about this specific peer instead of all added peers.| -|Description|Returns information about manually added (persistent) peers.| -|Returns (dns=false)|`["ip:port", ...]`| -|Returns (dns=true)|`[ (json array of objects)`
  `{ (json object)`
    `"addednode": "ip_or_domain", (string) the ip address or domain of the added peer`
    `"connected": true or false, (boolean) whether or not the peer is currently connected`
    `"addresses": [ (json array or objects) DNS lookup and connection information about the peer`
      `{ (json object)`
        `"address": "ip", (string) the ip address for this DNS entry`
        `"connected": "inbound/outbound/false" (string) the connection 'direction' (if connected)`
      `}, ...`
    `]`
  `}, ...`
`]`| -|Example Return (dns=false)|`["192.168.0.10:8333", "mydomain.org:8333"]`| -|Example Return (dns=true)|`[`
  `{`
    `"addednode": "mydomain.org:8333",`
    `"connected": true,`
    `"addresses": [`
      `{`
        `"address": "1.2.3.4",`
        `"connected": "outbound"`
      `},`
      `{`
        `"address": "5.6.7.8",`
        `"connected": "false"`
      `}`
    `]`
  `}`
`]`| +| | | +| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getaddednodeinfo | +| Parameters | 1. dns (boolean, required) - specifies whether the returned data is a JSON object including DNS and connection information, or just a list of added peers
2. node (string, optional) - only return information about this specific peer instead of all added peers. | +| Description | Returns information about manually added (persistent) peers. | +| Returns (dns=false) | `["ip:port", ...]` | +| Returns (dns=true) | `[ (json array of objects)`
  `{ (json object)`
    `"addednode": "ip_or_domain", (string) the ip address or domain of the added peer`
    `"connected": true or false, (boolean) whether or not the peer is currently connected`
    `"addresses": [ (json array or objects) DNS lookup and connection information about the peer`
      `{ (json object)`
        `"address": "ip", (string) the ip address for this DNS entry`
        `"connected": "inbound/outbound/false" (string) the connection 'direction' (if connected)`
      `}, ...`
    `]`
  `}, ...`
`]` | +| Example Return (dns=false) | `["192.168.0.10:9246", "mydomain.org:9246"]` | +| Example Return (dns=true) | `[`
  `{`
    `"addednode": "mydomain.org:9246",`
    `"connected": true,`
    `"addresses": [`
      `{`
        `"address": "1.2.3.4",`
        `"connected": "outbound"`
      `},`
      `{`
        `"address": "5.6.7.8",`
        `"connected": "false"`
      `}`
    `]`
  `}`
`]` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getbestblockhash| -|Parameters|None| -|Description|Returns the hash of the of the best (most recent) block in the longest block chain.| -|Returns|string| -|Example Return|`0000000000000001f356adc6b29ab42b59f913a396e170f80190dba615bd1e60`| +| | | +| -------------- | ----------------------------------------------------------------------------------- | +| Method | getbestblockhash | +| Parameters | None | +| Description | Returns the hash of the of the best (most recent) block in the longest block chain. | +| Returns | string | +| Example Return | `0000000000000001f356adc6b29ab42b59f913a396e170f80190dba615bd1e60` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getblock| -|Parameters|1. block hash (string, required) - the hash of the block
2. verbosity (int, optional, default=1) - Specifies whether the block data should be returned as a hex-encoded string (0), as parsed data with a slice of TXIDs (1), or as parsed data with parsed transaction data (2). -|Description|Returns information about a block given its hash.| -|Returns (verbosity=0)|`"data" (string) hex-encoded bytes of the serialized block`| -|Returns (verbosity=1)|`{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"strippedsize", n (numeric) the size of the block without witness data`
  `"size": n, (numeric) the size of the block`
  `"weight": n, (numeric) value of the weight metric`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"tx": [ (json array of string) the transaction hashes`
    `"transactionhash", (string) hash of the parent transaction`
    `...`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`
`}`| -|Returns (verbosity=2)|`{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"strippedsize", n (numeric) the size of the block without witness data`
  `"size": n, (numeric) the size of the block`
  `"weight": n, (numeric) value of the weight metric`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"rawtx": [ (array of json objects) the transactions as json objects`
    `(see getrawtransaction json object details)`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block`
`}`| -|Example Return (verbosity=0)|`"010000000000000000000000000000000000000000000000000000000000000000000000`
`3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49`
`ffff001d1dac2b7c01010000000100000000000000000000000000000000000000000000`
`00000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f`
`4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f`
`6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104`
`678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f`
`4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"`
**Newlines added for display purposes. The actual return does not contain newlines.**| -|Example Return (verbosity=1)|`{`
  `"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",`
  `"confirmations": 277113,`
  `"size": 285,`
  `"height": 0,`
  `"version": 1,`
  `"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"tx": [`
    `"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"`
  `],`
  `"time": 1231006505,`
  `"nonce": 2083236893,`
  `"bits": "1d00ffff",`
  `"difficulty": 1,`
  `"previousblockhash": "0000000000000000000000000000000000000000000000000000000000000000",`
  `"nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"`
`}`| +| | | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getblock | +| Parameters | 1. block hash (string, required) - the hash of the block
2. verbosity (int, optional, default=1) - Specifies whether the block data should be returned as a hex-encoded string (0), as parsed data with a slice of TXIDs (1), or as parsed data with parsed transaction data (2). | +| Description | Returns information about a block given its hash. | +| Returns (verbosity=0) | `"data" (string) hex-encoded bytes of the serialized block` | +| Returns (verbosity=1) | `{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"strippedsize", n (numeric) the size of the block without witness data`
  `"size": n, (numeric) the size of the block`
  `"weight": n, (numeric) value of the weight metric`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"tx": [ (json array of string) the transaction hashes`
    `"transactionhash", (string) hash of the parent transaction`
    `...`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`
`}` | +| Returns (verbosity=2) | `{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"strippedsize", n (numeric) the size of the block without witness data`
  `"size": n, (numeric) the size of the block`
  `"weight": n, (numeric) value of the weight metric`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"rawtx": [ (array of json objects) the transactions as json objects`
    `(see getrawtransaction json object details)`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block`
`}` | +| Example Return (verbosity=0) | `"010000000000000000000000000000000000000000000000000000000000000000000000`
`3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49`
`ffff001d1dac2b7c01010000000100000000000000000000000000000000000000000000`
`00000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f`
`4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f`
`6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104`
`678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f`
`4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"`
**Newlines added for display purposes. The actual return does not contain newlines.** | +| Example Return (verbosity=1) | `{`
  `"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",`
  `"confirmations": 277113,`
  `"size": 285,`
  `"height": 0,`
  `"version": 1,`
  `"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"tx": [`
    `"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"`
  `],`
  `"time": 1231006505,`
  `"nonce": 2083236893,`
  `"bits": "1d00ffff",`
  `"difficulty": 1,`
  `"previousblockhash": "0000000000000000000000000000000000000000000000000000000000000000",`
  `"nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getblockcount| -|Parameters|None| -|Description|Returns the number of blocks in the longest block chain.| -|Returns|numeric| -|Example Return|`276820`| +| | | +| -------------- | -------------------------------------------------------- | +| Method | getblockcount | +| Parameters | None | +| Description | Returns the number of blocks in the longest block chain. | +| Returns | numeric | +| Example Return | `276820` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getblockhash| -|Parameters|1. block height (numeric, required)| -|Description|Returns hash of the block in best block chain at the given height.| -|Returns|string| -|Example Return|`000000000000000096579458d1c0f1531fcfc58d57b4fce51eb177d8d10e784d`| +| | | +| -------------- | ------------------------------------------------------------------ | +| Method | getblockhash | +| Parameters | 1. block height (numeric, required) | +| Description | Returns hash of the block in best block chain at the given height. | +| Returns | string | +| Example Return | `000000000000000096579458d1c0f1531fcfc58d57b4fce51eb177d8d10e784d` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getblockheader| -|Parameters|1. block hash (string, required) - the hash of the block
2. verbose (boolean, optional, default=true) - specifies the block header is returned as a JSON object instead of a hex-encoded string| -|Description|Returns hex-encoded bytes of the serialized block header.| -|Returns (verbose=false)|`"data" (string) hex-encoded bytes of the serialized block`| -|Returns (verbose=true)|`{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits": n, (numeric) the bits which represent the block difficulty`
  `"difficulty": n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`
`}`| -|Example Return (verbose=false)|`"0200000035ab154183570282ce9afc0b494c9fc6a3cfea05aa8c1add2ecc564900000000`
`38ba3d78e4500a5a7570dbe61960398add4410d278b21cd9708e6d9743f374d544fc0552`
`27f1001c29c1ea3b"`
**Newlines added for display purposes. The actual return does not contain newlines.**| -|Example Return (verbose=true)|`{`
  `"hash": "00000000009e2958c15ff9290d571bf9459e93b19765c6801ddeccadbb160a1e",`
  `"confirmations": 392076,`
  `"height": 100000,`
  `"version": 2,`
  `"merkleroot": "d574f343976d8e70d91cb278d21044dd8a396019e6db70755a0a50e4783dba38",`
  `"time": 1376123972,`
  `"nonce": 1005240617,`
  `"bits": "1c00f127",`
  `"difficulty": 271.75767393,`
  `"previousblockhash": "000000004956cc2edd1a8caa05eacfa3c69f4c490bfc9ace820257834115ab35",`
  `"nextblockhash": "0000000000629d100db387f37d0f37c51118f250fb0946310a8c37316cbc4028"`
`}`| +| | | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | getblockheader | +| Parameters | 1. block hash (string, required) - the hash of the block
2. verbose (boolean, optional, default=true) - specifies the block header is returned as a JSON object instead of a hex-encoded string | +| Description | Returns hex-encoded bytes of the serialized block header. | +| Returns (verbose=false) | `"data" (string) hex-encoded bytes of the serialized block` | +| Returns (verbose=true) | `{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits": n, (numeric) the bits which represent the block difficulty`
  `"difficulty": n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`
`}` | +| Example Return (verbose=false) | `"0200000035ab154183570282ce9afc0b494c9fc6a3cfea05aa8c1add2ecc564900000000`
`38ba3d78e4500a5a7570dbe61960398add4410d278b21cd9708e6d9743f374d544fc0552`
`27f1001c29c1ea3b"`
**Newlines added for display purposes. The actual return does not contain newlines.** | +| Example Return (verbose=true) | `{`
  `"hash": "00000000009e2958c15ff9290d571bf9459e93b19765c6801ddeccadbb160a1e",`
  `"confirmations": 392076,`
  `"height": 100000,`
  `"version": 2,`
  `"merkleroot": "d574f343976d8e70d91cb278d21044dd8a396019e6db70755a0a50e4783dba38",`
  `"time": 1376123972,`
  `"nonce": 1005240617,`
  `"bits": "1c00f127",`
  `"difficulty": 271.75767393,`
  `"previousblockhash": "000000004956cc2edd1a8caa05eacfa3c69f4c490bfc9ace820257834115ab35",`
  `"nextblockhash": "0000000000629d100db387f37d0f37c51118f250fb0946310a8c37316cbc4028"`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getconnectioncount| -|Parameters|None| -|Description|Returns the number of active connections to other peers| -|Returns|numeric| -|Example Return|`8`| +| | | +| -------------- | ------------------------------------------------------- | +| Method | getconnectioncount | +| Parameters | None | +| Description | Returns the number of active connections to other peers | +| Returns | numeric | +| Example Return | `8` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getdifficulty| -|Parameters|None| -|Description|Returns the proof-of-work difficulty as a multiple of the minimum difficulty.| -|Returns|numeric| -|Example Return|`1180923195.260000`| +| | | +| -------------- | ----------------------------------------------------------------------------- | +| Method | getdifficulty | +| Parameters | None | +| Description | Returns the proof-of-work difficulty as a multiple of the minimum difficulty. | +| Returns | numeric | +| Example Return | `1180923195.260000` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getgenerate| -|Parameters|None| -|Description|Return if the server is set to generate coins (mine) or not.| -|Returns|`false` (boolean)| +| | | +| ----------- | ------------------------------------------------------------ | +| Method | getgenerate | +| Parameters | None | +| Description | Return if the server is set to generate coins (mine) or not. | +| Returns | `false` (boolean) | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|gethashespersec| -|Parameters|None| -|Description|Returns a recent hashes per second performance measurement while generating coins (mining).| -|Returns|`0` (numeric)| +| | | +| ----------- | ------------------------------------------------------------------------------------------- | +| Method | gethashespersec | +| Parameters | None | +| Description | Returns a recent hashes per second performance measurement while generating coins (mining). | +| Returns | `0` (numeric) | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getinfo| -|Parameters|None| -|Description|Returns a JSON object containing various state info.| -|Notes|NOTE: Since btcd does NOT contain wallet functionality, wallet-related fields are not returned. See getinfo in btcwallet for a version which includes that information.| -|Returns|`{ (json object)`
  `"version": n, (numeric) the version of the server`
  `"protocolversion": n, (numeric) the latest supported protocol version`
  `"blocks": n, (numeric) the number of blocks processed`
  `"timeoffset": n, (numeric) the time offset`
  `"connections": n, (numeric) the number of connected peers`
  `"proxy": "host:port", (string) the proxy used by the server`
  `"difficulty": n.nn, (numeric) the current target difficulty`
  `"testnet": true or false, (boolean) whether or not server is using testnet`
  `"relayfee": n.nn, (numeric) the minimum relay fee for non-free transactions in BTC/KB`
`}`| -|Example Return|`{`
  `"version": 70000`
  `"protocolversion": 70001, `
  `"blocks": 298963,`
  `"timeoffset": 0,`
  `"connections": 17,`
  `"proxy": "",`
  `"difficulty": 8000872135.97,`
  `"testnet": false,`
  `"relayfee": 0.00001,`
`}`| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | getinfo | +| Parameters | None | +| Description | Returns a JSON object containing various state info. | +| Notes | NOTE: Since lbcd does NOT contain wallet functionality, wallet-related fields are not returned. See getinfo in btcwallet for a version which includes that information. | +| Returns | `{ (json object)`
  `"version": n, (numeric) the version of the server`
  `"protocolversion": n, (numeric) the latest supported protocol version`
  `"blocks": n, (numeric) the number of blocks processed`
  `"timeoffset": n, (numeric) the time offset`
  `"connections": n, (numeric) the number of connected peers`
  `"proxy": "host:port", (string) the proxy used by the server`
  `"difficulty": n.nn, (numeric) the current target difficulty`
  `"testnet": true or false, (boolean) whether or not server is using testnet`
  `"relayfee": n.nn, (numeric) the minimum relay fee for non-free transactions in BTC/KB`
`}` | +| Example Return | `{`
  `"version": 70000`
  `"protocolversion": 70001, `
  `"blocks": 298963,`
  `"timeoffset": 0,`
  `"connections": 17,`
  `"proxy": "",`
  `"difficulty": 8000872135.97,`
  `"testnet": false,`
  `"relayfee": 0.00001,`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getmempoolinfo| -|Parameters|None| -|Description|Returns a JSON object containing mempool-related information.| -|Returns|`{ (json object)`
  `"bytes": n, (numeric) size in bytes of the mempool`
  `"size": n, (numeric) number of transactions in the mempool`
`}`| -Example Return|`{`
  `"bytes": 310768,`
  `"size": 157,`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getmempoolinfo | +| Parameters | None | +| Description | Returns a JSON object containing mempool-related information. | +| Returns | `{ (json object)`
  `"bytes": n, (numeric) size in bytes of the mempool`
  `"size": n, (numeric) number of transactions in the mempool`
`}` | +| Example Return | `{`
  `"bytes": 310768,`
  `"size": 157,`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getmininginfo| -|Parameters|None| -|Description|Returns a JSON object containing mining-related information.| -|Returns|`{ (json object)`
  `"blocks": n, (numeric) latest best block`
  `"currentblocksize": n, (numeric) size of the latest best block`
  `"currentblockweight": n, (numeric) weight of the latest best block`
  `"currentblocktx": n, (numeric) number of transactions in the latest best block`
  `"difficulty": n.nn, (numeric) current target difficulty`
  `"errors": "errors", (string) any current errors`
  `"generate": true or false, (boolean) whether or not server is set to generate coins`
  `"genproclimit": n, (numeric) number of processors to use for coin generation (-1 when disabled)`
  `"hashespersec": n, (numeric) recent hashes per second performance measurement while generating coins`
  `"networkhashps": n, (numeric) estimated network hashes per second for the most recent blocks`
  `"pooledtx": n, (numeric) number of transactions in the memory pool`
  `"testnet": true or false, (boolean) whether or not server is using testnet`
`}`| -|Example Return|`{`
  `"blocks": 236526,`
  `"currentblocksize": 185,`
  `"currentblockweight": 740,`
  `"currentblocktx": 1,`
  `"difficulty": 256,`
  `"errors": "",`
  `"generate": false,`
  `"genproclimit": -1,`
  `"hashespersec": 0,`
  `"networkhashps": 33081554756,`
  `"pooledtx": 8,`
  `"testnet": true,`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getmininginfo | +| Parameters | None | +| Description | Returns a JSON object containing mining-related information. | +| Returns | `{ (json object)`
  `"blocks": n, (numeric) latest best block`
  `"currentblocksize": n, (numeric) size of the latest best block`
  `"currentblockweight": n, (numeric) weight of the latest best block`
  `"currentblocktx": n, (numeric) number of transactions in the latest best block`
  `"difficulty": n.nn, (numeric) current target difficulty`
  `"errors": "errors", (string) any current errors`
  `"generate": true or false, (boolean) whether or not server is set to generate coins`
  `"genproclimit": n, (numeric) number of processors to use for coin generation (-1 when disabled)`
  `"hashespersec": n, (numeric) recent hashes per second performance measurement while generating coins`
  `"networkhashps": n, (numeric) estimated network hashes per second for the most recent blocks`
  `"pooledtx": n, (numeric) number of transactions in the memory pool`
  `"testnet": true or false, (boolean) whether or not server is using testnet`
`}` | +| Example Return | `{`
  `"blocks": 236526,`
  `"currentblocksize": 185,`
  `"currentblockweight": 740,`
  `"currentblocktx": 1,`
  `"difficulty": 256,`
  `"errors": "",`
  `"generate": false,`
  `"genproclimit": -1,`
  `"hashespersec": 0,`
  `"networkhashps": 33081554756,`
  `"pooledtx": 8,`
  `"testnet": true,`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getnettotals| -|Parameters|None| -|Description|Returns a JSON object containing network traffic statistics.| -|Returns|`{`
  `"totalbytesrecv": n, (numeric) total bytes received`
  `"totalbytessent": n, (numeric) total bytes sent`
  `"timemillis": n (numeric) number of milliseconds since 1 Jan 1970 GMT`
`}`| -|Example Return|`{`
  `"totalbytesrecv": 1150990,`
  `"totalbytessent": 206739,`
  `"timemillis": 1391626433845`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getnettotals | +| Parameters | None | +| Description | Returns a JSON object containing network traffic statistics. | +| Returns | `{`
  `"totalbytesrecv": n, (numeric) total bytes received`
  `"totalbytessent": n, (numeric) total bytes sent`
  `"timemillis": n (numeric) number of milliseconds since 1 Jan 1970 GMT`
`}` | +| Example Return | `{`
  `"totalbytesrecv": 1150990,`
  `"totalbytessent": 206739,`
  `"timemillis": 1391626433845`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getnetworkhashps| -|Parameters|1. blocks (numeric, optional, default=120) - The number of blocks, or -1 for blocks since last difficulty change
2. height (numeric, optional, default=-1) - Perform estimate ending with this height or -1 for current best chain block height| -|Description|Returns the estimated network hashes per second for the block heights provided by the parameters.| -|Returns|numeric| -|Example Return|`6573971939`| +| | | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getnetworkhashps | +| Parameters | 1. blocks (numeric, optional, default=120) - The number of blocks, or -1 for blocks since last difficulty change
2. height (numeric, optional, default=-1) - Perform estimate ending with this height or -1 for current best chain block height | +| Description | Returns the estimated network hashes per second for the block heights provided by the parameters. | +| Returns | numeric | +| Example Return | `6573971939` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getpeerinfo| -|Parameters|None| -|Description|Returns data about each connected network peer as an array of json objects.| -|Returns|`[`
  `{`
    `"addr": "host:port", (string) the ip address and port of the peer`
    `"services": "00000001", (string) the services supported by the peer`
    `"lastrecv": n, (numeric) time the last message was received in seconds since 1 Jan 1970 GMT`
    `"lastsend": n, (numeric) time the last message was sent in seconds since 1 Jan 1970 GMT`
    `"bytessent": n, (numeric) total bytes sent`
    `"bytesrecv": n, (numeric) total bytes received`
    `"conntime": n, (numeric) time the connection was made in seconds since 1 Jan 1970 GMT`
    `"pingtime": n, (numeric) number of microseconds the last ping took`
    `"pingwait": n, (numeric) number of microseconds a queued ping has been waiting for a response`
    `"version": n, (numeric) the protocol version of the peer`
    `"subver": "useragent", (string) the user agent of the peer`
    `"inbound": true_or_false, (boolean) whether or not the peer is an inbound connection`
    `"startingheight": n, (numeric) the latest block height the peer knew about when the connection was established`
    `"currentheight": n, (numeric) the latest block height the peer is known to have relayed since connected`
    `"syncnode": true_or_false, (boolean) whether or not the peer is the sync peer`
  `}, ...`
`]`| -|Example Return|`[`
  `{`
    `"addr": "178.172.xxx.xxx:8333",`
    `"services": "00000001",`
    `"lastrecv": 1388183523,`
    `"lastsend": 1388185470,`
    `"bytessent": 287592965,`
    `"bytesrecv": 780340,`
    `"conntime": 1388182973,`
    `"pingtime": 405551,`
    `"pingwait": 183023,`
    `"version": 70001,`
    `"subver": "/btcd:0.4.0/",`
    `"inbound": false,`
    `"startingheight": 276921,`
    `"currentheight": 276955,`
    `"syncnode": true,`
  `}`
`]`| +| | | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getpeerinfo | +| Parameters | None | +| Description | Returns data about each connected network peer as an array of json objects. | +| Returns | `[`
  `{`
    `"addr": "host:port", (string) the ip address and port of the peer`
    `"services": "00000001", (string) the services supported by the peer`
    `"lastrecv": n, (numeric) time the last message was received in seconds since 1 Jan 1970 GMT`
    `"lastsend": n, (numeric) time the last message was sent in seconds since 1 Jan 1970 GMT`
    `"bytessent": n, (numeric) total bytes sent`
    `"bytesrecv": n, (numeric) total bytes received`
    `"conntime": n, (numeric) time the connection was made in seconds since 1 Jan 1970 GMT`
    `"pingtime": n, (numeric) number of microseconds the last ping took`
    `"pingwait": n, (numeric) number of microseconds a queued ping has been waiting for a response`
    `"version": n, (numeric) the protocol version of the peer`
    `"subver": "useragent", (string) the user agent of the peer`
    `"inbound": true_or_false, (boolean) whether or not the peer is an inbound connection`
    `"startingheight": n, (numeric) the latest block height the peer knew about when the connection was established`
    `"currentheight": n, (numeric) the latest block height the peer is known to have relayed since connected`
    `"syncnode": true_or_false, (boolean) whether or not the peer is the sync peer`
  `}, ...`
`]` | +| Example Return | `[`
  `{`
    `"addr": "178.172.xxx.xxx:9246",`
    `"services": "00000001",`
    `"lastrecv": 1388183523,`
    `"lastsend": 1388185470,`
    `"bytessent": 287592965,`
    `"bytesrecv": 780340,`
    `"conntime": 1388182973,`
    `"pingtime": 405551,`
    `"pingwait": 183023,`
    `"version": 70001,`
    `"subver": "/lbcd:0.4.0/",`
    `"inbound": false,`
    `"startingheight": 276921,`
    `"currentheight": 276955,`
    `"syncnode": true,`
  `}`
`]` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getrawtransaction| -|Parameters|1. transaction hash (string, required) - the hash of the transaction
2. verbose (int, optional, default=0) - specifies the transaction is returned as a JSON object instead of hex-encoded string| -|Description|Returns information about a transaction given its hash.| -|Returns (verbose=0)|`"data" (string) hex-encoded bytes of the serialized transaction`| -|Returns (verbose=1)|`{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}`| -|Example Return (verbose=0)|`"010000000104be666c7053ef26c6110597dad1c1e81b5e6be53d17a8b9d0b34772054bac60000000`
`008c493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f`
`022100fbce8d84fcf2839127605818ac6c3e7a1531ebc69277c504599289fb1e9058df0141045a33`
`76eeb85e494330b03c1791619d53327441002832f4bd618fd9efa9e644d242d5e1145cb9c2f71965`
`656e276633d4ff1a6db5e7153a0a9042745178ebe0f5ffffffff0280841e00000000001976a91406`
`f1b6703d3f56427bfcfd372f952d50d04b64bd88ac4dd52700000000001976a9146b63f291c295ee`
`abd9aee6be193ab2d019e7ea7088ac00000000`
**Newlines added for display purposes. The actual return does not contain newlines.**| -|Example Return (verbose=1)|`{`
  `"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...",`
  `"txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9",`
  `"version": 1,`
  `"locktime": 0,`
  `"vin": [`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f",`
      `"sequence": 0,`
    `}`
  For non-coinbase transactions:
    `{`
      `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
      `"vout": 0,`
      `"scriptSig": {`
        `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
        `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
      `}`
      `"sequence": 4294967295,`
    `}`
  `]`
  `"vout": [`
    `{`
      `"value": 25.1394,`
      `"n": 0,`
      `"scriptPubKey": {`
        `"asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG",`
        `"hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac",`
        `"reqSigs": 1,`
        `"type": "pubkeyhash"`
        `"addresses": [`
          `"1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh",`
        `]`
      `}`
    `}`
  `]`
`}`| +| | | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getrawtransaction | +| Parameters | 1. transaction hash (string, required) - the hash of the transaction
2. verbose (int, optional, default=0) - specifies the transaction is returned as a JSON object instead of hex-encoded string | +| Description | Returns information about a transaction given its hash. | +| Returns (verbose=0) | `"data" (string) hex-encoded bytes of the serialized transaction` | +| Returns (verbose=1) | `{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}` | +| Example Return (verbose=0) | `"010000000104be666c7053ef26c6110597dad1c1e81b5e6be53d17a8b9d0b34772054bac60000000`
`008c493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f`
`022100fbce8d84fcf2839127605818ac6c3e7a1531ebc69277c504599289fb1e9058df0141045a33`
`76eeb85e494330b03c1791619d53327441002832f4bd618fd9efa9e644d242d5e1145cb9c2f71965`
`656e276633d4ff1a6db5e7153a0a9042745178ebe0f5ffffffff0280841e00000000001976a91406`
`f1b6703d3f56427bfcfd372f952d50d04b64bd88ac4dd52700000000001976a9146b63f291c295ee`
`abd9aee6be193ab2d019e7ea7088ac00000000`
**Newlines added for display purposes. The actual return does not contain newlines.** | +| Example Return (verbose=1) | `{`
  `"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...",`
  `"txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9",`
  `"version": 1,`
  `"locktime": 0,`
  `"vin": [`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f",`
      `"sequence": 0,`
    `}`
  For non-coinbase transactions:
    `{`
      `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
      `"vout": 0,`
      `"scriptSig": {`
        `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
        `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
      `}`
      `"sequence": 4294967295,`
    `}`
  `]`
  `"vout": [`
    `{`
      `"value": 25.1394,`
      `"n": 0,`
      `"scriptPubKey": {`
        `"asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG",`
        `"hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac",`
        `"reqSigs": 1,`
        `"type": "pubkeyhash"`
        `"addresses": [`
          `"1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh",`
        `]`
      `}`
    `}`
  `]`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|help| -|Parameters|1. command (string, optional) - the command to get help for| -|Description|Returns a list of all commands or help for a specified command.
When no `command` parameter is specified, a list of avaialable commands is returned
When `command` is a valid method, the help text for that method is returned.| -|Returns|string| -|Example Return|getblockcount
Returns a numeric for the number of blocks in the longest block chain.| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | help | +| Parameters | 1. command (string, optional) - the command to get help for | +| Description | Returns a list of all commands or help for a specified command.
When no `command` parameter is specified, a list of avaialable commands is returned
When `command` is a valid method, the help text for that method is returned. | +| Returns | string | +| Example Return | getblockcount
Returns a numeric for the number of blocks in the longest block chain. | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|ping| -|Parameters|None| -|Description|Queues a ping to be sent to each connected peer.
Ping times are provided by [getpeerinfo](#getpeerinfo) via the `pingtime` and `pingwait` fields.| -|Returns|Nothing| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | ping | +| Parameters | None | +| Description | Queues a ping to be sent to each connected peer.
Ping times are provided by [getpeerinfo](#getpeerinfo) via the `pingtime` and `pingwait` fields. | +| Returns | Nothing | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getrawmempool| -|Parameters|1. verbose (boolean, optional, default=false)| -|Description|Returns an array of hashes for all of the transactions currently in the memory pool.
The `verbose` flag specifies that each transaction is returned as a JSON object.| -|Notes|Since btcd does not perform any mining, the priority related fields `startingpriority` and `currentpriority` that are available when the `verbose` flag is set are always 0.| -|Returns (verbose=false)|`[ (json array of string)`
  `"transactionhash", (string) hash of the transaction`
  `...`
`]`| -|Returns (verbose=true)|`{ (json object)`
  `"transactionhash": { (json object)`
    `"size": n, (numeric) transaction size in bytes`
    `"vsize": n, (numeric) transaction virtual size`
    `"weight": n, (numeric) The transaction's weight (between vsize*4-3 and vsize*4)`
    `"fee" : n, (numeric) transaction fee in bitcoins`
    `"time": n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT`
    `"height": n, (numeric) block height when transaction entered the pool`
    `"startingpriority": n, (numeric) priority when transaction entered the pool`
    `"currentpriority": n, (numeric) current priority`
    `"depends": [ (json array) unconfirmed transactions used as inputs for this transaction`
      `"transactionhash", (string) hash of the parent transaction`
      `...`
    `]`
  `}, ...`
`}`| -|Example Return (verbose=false)|`[`
  `"3480058a397b6ffcc60f7e3345a61370fded1ca6bef4b58156ed17987f20d4e7",`
  `"cbfe7c056a358c3a1dbced5a22b06d74b8650055d5195c1c2469e6b63a41514a"`
`]`| -|Example Return (verbose=true)|`{`
  `"1697a19cede08694278f19584e8dcc87945f40c6b59a942dd8906f133ad3f9cc": {`
    `"size": 226,`
    `"fee" : 0.0001,`
    `"time": 1387992789,`
    `"height": 276836,`
    `"startingpriority": 0,`
    `"currentpriority": 0,`
    `"depends": [`
      `"aa96f672fcc5a1ec6a08a94aa46d6b789799c87bd6542967da25a96b2dee0afb",`
    `]`
`}`| +| | | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getrawmempool | +| Parameters | 1. verbose (boolean, optional, default=false) | +| Description | Returns an array of hashes for all of the transactions currently in the memory pool.
The `verbose` flag specifies that each transaction is returned as a JSON object. | +| Notes | Since lbcd does not perform any mining, the priority related fields `startingpriority` and `currentpriority` that are available when the `verbose` flag is set are always 0. | +| Returns (verbose=false) | `[ (json array of string)`
  `"transactionhash", (string) hash of the transaction`
  `...`
`]` | +| Returns (verbose=true) | `{ (json object)`
  `"transactionhash": { (json object)`
    `"size": n, (numeric) transaction size in bytes`
    `"vsize": n, (numeric) transaction virtual size`
    `"weight": n, (numeric) The transaction's weight (between vsize*4-3 and vsize*4)`
    `"fee" : n, (numeric) transaction fee in bitcoins`
    `"time": n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT`
    `"height": n, (numeric) block height when transaction entered the pool`
    `"startingpriority": n, (numeric) priority when transaction entered the pool`
    `"currentpriority": n, (numeric) current priority`
    `"depends": [ (json array) unconfirmed transactions used as inputs for this transaction`
      `"transactionhash", (string) hash of the parent transaction`
      `...`
    `]`
  `}, ...`
`}` | +| Example Return (verbose=false) | `[`
  `"3480058a397b6ffcc60f7e3345a61370fded1ca6bef4b58156ed17987f20d4e7",`
  `"cbfe7c056a358c3a1dbced5a22b06d74b8650055d5195c1c2469e6b63a41514a"`
`]` | +| Example Return (verbose=true) | `{`
  `"1697a19cede08694278f19584e8dcc87945f40c6b59a942dd8906f133ad3f9cc": {`
    `"size": 226,`
    `"fee" : 0.0001,`
    `"time": 1387992789,`
    `"height": 276836,`
    `"startingpriority": 0,`
    `"currentpriority": 0,`
    `"depends": [`
      `"aa96f672fcc5a1ec6a08a94aa46d6b789799c87bd6542967da25a96b2dee0afb",`
    `]`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|setgenerate| -|Parameters|1. generate (boolean, required) - `true` to enable generation, `false` to disable it
2. genproclimit (numeric, optional) - the number of processors (cores) to limit generation to or `-1` for default| -|Description|Set the server to generate coins (mine) or not.| -|Notes|NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.| -|Returns|Nothing| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | setgenerate | +| Parameters | 1. generate (boolean, required) - `true` to enable generation, `false` to disable it
2. genproclimit (numeric, optional) - the number of processors (cores) to limit generation to or `-1` for default | +| Description | Set the server to generate coins (mine) or not. | +| Notes | NOTE: Since lbcd does not have the wallet integrated to provide payment addresses, lbcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function. | +| Returns | Nothing | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|sendrawtransaction| -|Parameters|1. signedhex (string, required) serialized, hex-encoded signed transaction
2. allowhighfees (boolean, optional, default=false) whether or not to allow insanely high fees| -|Description|Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.| -|Notes|btcd does not yet implement the `allowhighfees` parameter, so it has no effect| -|Returns|`"hash" (string) the hash of the transaction`| -|Example Return|`"1697a19cede08694278f19584e8dcc87945f40c6b59a942dd8906f133ad3f9cc"`| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | sendrawtransaction | +| Parameters | 1. signedhex (string, required) serialized, hex-encoded signed transaction
2. allowhighfees (boolean, optional, default=false) whether or not to allow insanely high fees | +| Description | Submits the serialized, hex-encoded transaction to the local peer and relays it to the network. | +| Notes | lbcd does not yet implement the `allowhighfees` parameter, so it has no effect | +| Returns | `"hash" (string) the hash of the transaction` | +| Example Return | `"1697a19cede08694278f19584e8dcc87945f40c6b59a942dd8906f133ad3f9cc"` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|submitblock| -|Parameters|1. data (string, required) serialized, hex-encoded block
2. params (json object, optional, default=nil) this parameter is currently ignored| -|Description|Attempts to submit a new serialized, hex-encoded block to the network.| -|Returns (success)|Success: Nothing
Failure: `"rejected: reason"` (string)| +| | | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | submitblock | +| Parameters | 1. data (string, required) serialized, hex-encoded block
2. params (json object, optional, default=nil) this parameter is currently ignored | +| Description | Attempts to submit a new serialized, hex-encoded block to the network. | +| Returns (success) | Success: Nothing
Failure: `"rejected: reason"` (string) | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|stop| -|Parameters|None| -|Description|Shutdown btcd.| -|Returns|`"btcd stopping."` (string)| +| | | +| ----------- | --------------------------- | +| Method | stop | +| Parameters | None | +| Description | Shutdown lbcd. | +| Returns | `"lbcd stopping."` (string) | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|validateaddress| -|Parameters|1. address (string, required) - bitcoin address| -|Description|Verify an address is valid.| -|Returns|`{ (json object)`
  `"isvalid": true or false, (bool) whether or not the address is valid.`
  `"address": "bitcoinaddress", (string) the bitcoin address validated.`
}| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | validateaddress | +| Parameters | 1. address (string, required) - bitcoin address | +| Description | Verify an address is valid. | +| Returns | `{ (json object)`
  `"isvalid": true or false, (bool) whether or not the address is valid.`
  `"address": "bitcoinaddress", (string) the bitcoin address validated.`
} | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|verifychain| -|Parameters|1. checklevel (numeric, optional, default=3) - how in-depth the verification is (0=least amount of checks, higher levels are clamped to the highest supported level)
2. numblocks (numeric, optional, default=288) - the number of blocks starting from the end of the chain to verify| -|Description|Verifies the block chain database.
The actual checks performed by the `checklevel` parameter is implementation specific. For btcd this is:
`checklevel=0` - Look up each block and ensure it can be loaded from the database.
`checklevel=1` - Perform basic context-free sanity checks on each block.| -|Notes|Btcd currently only supports `checklevel` 0 and 1, but the default is still 3 for compatibility. Per the information in the Parameters section above, higher levels are automatically clamped to the highest supported level, so this means the default is effectively 1 for btcd.| -|Returns|`true` or `false` (boolean)| -|Example Return|`true`| +| | | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | verifychain | +| Parameters | 1. checklevel (numeric, optional, default=3) - how in-depth the verification is (0=least amount of checks, higher levels are clamped to the highest supported level)
2. numblocks (numeric, optional, default=288) - the number of blocks starting from the end of the chain to verify | +| Description | Verifies the block chain database.
The actual checks performed by the `checklevel` parameter is implementation specific. For lbcd this is:
`checklevel=0` - Look up each block and ensure it can be loaded from the database.
`checklevel=1` - Perform basic context-free sanity checks on each block. | +| Notes | lbcd currently only supports `checklevel` 0 and 1, but the default is still 3 for compatibility. Per the information in the Parameters section above, higher levels are automatically clamped to the highest supported level, so this means the default is effectively 1 for lbcd. | +| Returns | `true` or `false` (boolean) | +| Example Return | `true` | [Return to Overview](#MethodOverview)
@@ -570,18 +562,18 @@ Example Return|`{`
  `"bytes": 310768,`
  `"size": **6.1 Method Overview**
-The following is an overview of the RPC methods which are implemented by btcd, but not the original bitcoind client. Click the method name for further details such as parameter and return information. +The following is an overview of the RPC methods which are implemented by lbcd, but not the original bitcoind client. Click the method name for further details such as parameter and return information. -|#|Method|Safe for limited user?|Description| -|---|------|----------|-----------| -|1|[debuglevel](#debuglevel)|N|Dynamically changes the debug logging level.| -|2|[getbestblock](#getbestblock)|Y|Get block height and hash of best block in the main chain.|None| -|3|[getcurrentnet](#getcurrentnet)|Y|Get bitcoin network btcd is running on.|None| -|4|[searchrawtransactions](#searchrawtransactions)|Y|Query for transactions related to a particular address.|None| -|5|[node](#node)|N|Attempts to add or remove a peer. |None| -|6|[generate](#generate)|N|When in simnet or regtest mode, generate a set number of blocks. |None| -|7|[version](#version)|Y|Returns the JSON-RPC API version.| -|8|[getheaders](#getheaders)|Y|Returns block headers starting with the first known block hash from the request.| +| # | Method | Safe for limited user? | Description | +| --- | ----------------------------------------------- | ---------------------- | -------------------------------------------------------------------------------- | +| 1 | [debuglevel](#debuglevel) | N | Dynamically changes the debug logging level. | +| 2 | [getbestblock](#getbestblock) | Y | Get block height and hash of best block in the main chain. | None | +| 3 | [getcurrentnet](#getcurrentnet) | Y | Get bitcoin network lbcd is running on. | None | +| 4 | [searchrawtransactions](#searchrawtransactions) | Y | Query for transactions related to a particular address. | None | +| 5 | [node](#node) | N | Attempts to add or remove a peer. | None | +| 6 | [generate](#generate) | N | When in simnet or regtest mode, generate a set number of blocks. | None | +| 7 | [version](#version) | Y | Returns the JSON-RPC API version. | +| 8 | [getheaders](#getheaders) | Y | Returns block headers starting with the first known block hash from the request. |
@@ -590,102 +582,102 @@ The following is an overview of the RPC methods which are implemented by btcd, b -| | | -|---|---| -|Method|debuglevel| -|Parameters|1. _levelspec_ (string)| -|Description|Dynamically changes the debug logging level.
The levelspec can either a debug level or of the form `=,=,...`
The valid debug levels are `trace`, `debug`, `info`, `warn`, `error`, and `critical`.
The valid subsystems are `AMGR`, `ADXR`, `BCDB`, `BMGR`, `BTCD`, `CHAN`, `DISC`, `PEER`, `RPCS`, `SCRP`, `SRVR`, and `TXMP`.
Additionally, the special keyword `show` can be used to get a list of the available subsystems.| -|Returns|string| -|Example Return|`Done.`| -|Example `show` Return|`Supported subsystems [AMGR ADXR BCDB BMGR BTCD CHAN DISC PEER RPCS SCRP SRVR TXMP]`| +| | | +| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | debuglevel | +| Parameters | 1. _levelspec_ (string) | +| Description | Dynamically changes the debug logging level.
The levelspec can either a debug level or of the form `=,=,...`
The valid debug levels are `trace`, `debug`, `info`, `warn`, `error`, and `critical`.
The valid subsystems are `AMGR`, `ADXR`, `BCDB`, `BMGR`, `lbcd`, `CHAN`, `DISC`, `PEER`, `RPCS`, `SCRP`, `SRVR`, and `TXMP`.
Additionally, the special keyword `show` can be used to get a list of the available subsystems. | +| Returns | string | +| Example Return | `Done.` | +| Example `show` Return | `Supported subsystems [AMGR ADXR BCDB BMGR lbcd CHAN DISC PEER RPCS SCRP SRVR TXMP]` | [Return to Overview](#ExtMethodOverview)
***
-| | | -|---|---| -|Method|getbestblock| -|Parameters|None| -|Description|Get block height and hash of best block in the main chain.| -|Returns|`{ (json object)`
 `"hash": "data", (string) the hex-encoded bytes of the best block hash`
 `"height": n (numeric) the block height of the best block`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | getbestblock | +| Parameters | None | +| Description | Get block height and hash of best block in the main chain. | +| Returns | `{ (json object)`
 `"hash": "data", (string) the hex-encoded bytes of the best block hash`
 `"height": n (numeric) the block height of the best block`
`}` | [Return to Overview](#ExtMethodOverview)
***
-| | | -|---|---| -|Method|getcurrentnet| -|Parameters|None| -|Description|Get bitcoin network btcd is running on.| -|Returns|numeric| -|Example Return|`3652501241` (mainnet)
`118034699` (testnet3)| +| | | +| -------------- | -------------------------------------------------- | +| Method | getcurrentnet | +| Parameters | None | +| Description | Get bitcoin network lbcd is running on. | +| Returns | numeric | +| Example Return | `3652501241` (mainnet)
`118034699` (testnet3) | [Return to Overview](#ExtMethodOverview)
***
-| | | -|---|---| -|Method|searchrawtransactions| -|Parameters|1. address (string, required) - bitcoin address
2. verbose (int, optional, default=true) - specifies the transaction is returned as a JSON object instead of hex-encoded string
3. skip (int, optional, default=0) - the number of leading transactions to leave out of the final response
4. count (int, optional, default=100) - the maximum number of transactions to return
5. vinextra (int, optional, default=0) - Specify that extra data from previous output will be returned in vin
6. reverse (boolean, optional, default=false) - Specifies that the transactions should be returned in reverse chronological order| -|Description|Returns raw data for transactions involving the passed address. Returned transactions are pulled from both the database, and transactions currently in the mempool. Transactions pulled from the mempool will have the `"confirmations"` field set to 0. Usage of this RPC requires the optional `--addrindex` flag to be activated, otherwise all responses will simply return with an error stating the address index has not yet been built up. Similarly, until the address index has caught up with the current best height, all requests will return an error response in order to avoid serving stale data.| -|Returns (verbose=0)|`[ (json array of strings)`
   `"serializedtx", ... hex-encoded bytes of the serialized transaction`
`]` | -|Returns (verbose=1)|`[ (array of json objects)`
   `{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"txinwitness": “data", (string) the witness stack for the input`
    `"sequence": n, (numeric) the script sequence number`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"prevOut": { (json object) Data from the origin transaction output with index vout.`
        `"addresses": ["value",...], (array of string) previous output addresses`
        `"value": n.nnn, (numeric) previous output value`
      `}`
      `"txinwitness": “data", (string) the witness stack for the input`
    `"sequence": n, (numeric) the script sequence number`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"address", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
   `]`
   `"blockhash":"hash" Hash of the block the transaction is part of.`
   `"confirmations":n, Number of numeric confirmations of block.`
   `"time":t, Transaction time in seconds since the epoch.`
   `"blocktime":t, Block time in seconds since the epoch.`
`},...`
`]`| +| | | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | searchrawtransactions | +| Parameters | 1. address (string, required) - bitcoin address
2. verbose (int, optional, default=true) - specifies the transaction is returned as a JSON object instead of hex-encoded string
3. skip (int, optional, default=0) - the number of leading transactions to leave out of the final response
4. count (int, optional, default=100) - the maximum number of transactions to return
5. vinextra (int, optional, default=0) - Specify that extra data from previous output will be returned in vin
6. reverse (boolean, optional, default=false) - Specifies that the transactions should be returned in reverse chronological order | +| Description | Returns raw data for transactions involving the passed address. Returned transactions are pulled from both the database, and transactions currently in the mempool. Transactions pulled from the mempool will have the `"confirmations"` field set to 0. Usage of this RPC requires the optional `--addrindex` flag to be activated, otherwise all responses will simply return with an error stating the address index has not yet been built up. Similarly, until the address index has caught up with the current best height, all requests will return an error response in order to avoid serving stale data. | +| Returns (verbose=0) | `[ (json array of strings)`
   `"serializedtx", ... hex-encoded bytes of the serialized transaction`
`]` | +| Returns (verbose=1) | `[ (array of json objects)`
   `{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"txinwitness": “data", (string) the witness stack for the input`
    `"sequence": n, (numeric) the script sequence number`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"prevOut": { (json object) Data from the origin transaction output with index vout.`
        `"addresses": ["value",...], (array of string) previous output addresses`
        `"value": n.nnn, (numeric) previous output value`
      `}`
      `"txinwitness": “data", (string) the witness stack for the input`
    `"sequence": n, (numeric) the script sequence number`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"address", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
   `]`
   `"blockhash":"hash" Hash of the block the transaction is part of.`
   `"confirmations":n, Number of numeric confirmations of block.`
   `"time":t, Transaction time in seconds since the epoch.`
   `"blocktime":t, Block time in seconds since the epoch.`
`},...`
`]` | [Return to Overview](#ExtMethodOverview)
***
-| | | -|---|---| -|Method|node| -|Parameters|1. command (string, required) - `connect` to add a peer (defaults to temporary), `remove` to remove a persistent peer, or `disconnect` to remove all matching non-persistent peers
2. peer (string, required) - ip address and port, or ID of the peer to operate on
3. connection type (string, optional) - `perm` indicates the peer should be added as a permanent peer, `temp` indicates a connection should only be attempted once. | -|Description|Attempts to add or remove a peer.| -|Returns|Nothing| +| | | +| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | node | +| Parameters | 1. command (string, required) - `connect` to add a peer (defaults to temporary), `remove` to remove a persistent peer, or `disconnect` to remove all matching non-persistent peers
2. peer (string, required) - ip address and port, or ID of the peer to operate on
3. connection type (string, optional) - `perm` indicates the peer should be added as a permanent peer, `temp` indicates a connection should only be attempted once. | +| Description | Attempts to add or remove a peer. | +| Returns | Nothing | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|generate| -|Parameters|1. numblocks (int, required) - The number of blocks to generate | -|Description|When in simnet or regtest mode, generates `numblocks` blocks. If blocks arrive from elsewhere, they are built upon but don't count toward the number of blocks to generate. Only generated blocks are returned. This RPC call will exit with an error if the server is already CPU mining, and will prevent the server from CPU mining for another command while it runs. | -|Returns|`[ (json array of strings)`
   `"blockhash", ... hash of the generated block`
`]` | +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | generate | +| Parameters | 1. numblocks (int, required) - The number of blocks to generate | +| Description | When in simnet or regtest mode, generates `numblocks` blocks. If blocks arrive from elsewhere, they are built upon but don't count toward the number of blocks to generate. Only generated blocks are returned. This RPC call will exit with an error if the server is already CPU mining, and will prevent the server from CPU mining for another command while it runs. | +| Returns | `[ (json array of strings)`
   `"blockhash", ... hash of the generated block`
`]` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|version| -|Parameters|None| -|Description|Returns the version of the JSON-RPC API built into this release of btcd.| -|Returns|`{ (json object)`
  `"btcdjsonrpcapi": {`
    `"versionstring": "x.y.z", (string) the version of the JSON-RPC API`
    `"major": x, (numeric) the major version of the JSON-RPC API`
    `"minor": y, (numeric) the minor version of the JSON-RPC API`
    `"patch": z, (numeric) the patch version of the JSON-RPC API`
    `"prerelease": "", (string) prerelease info for the JSON-RPC API`
    `"buildmetadata": "" (string) metadata about the server build`
  `}`
`}`| -|Example Return|`{`
  `"btcdjsonrpcapi": {`
    `"versionstring": "1.0.0",`
    `"major": 1, `
    `"minor": 0,`
    `"patch": 0,`
    `"prerelease": "",`
    `"buildmetadata": ""`
  `}`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | version | +| Parameters | None | +| Description | Returns the version of the JSON-RPC API built into this release of lbcd. | +| Returns | `{ (json object)`
  `"lbcdjsonrpcapi": {`
    `"versionstring": "x.y.z", (string) the version of the JSON-RPC API`
    `"major": x, (numeric) the major version of the JSON-RPC API`
    `"minor": y, (numeric) the minor version of the JSON-RPC API`
    `"patch": z, (numeric) the patch version of the JSON-RPC API`
    `"prerelease": "", (string) prerelease info for the JSON-RPC API`
    `"buildmetadata": "" (string) metadata about the server build`
  `}`
`}` | +| Example Return | `{`
  `"lbcdjsonrpcapi": {`
    `"versionstring": "1.0.0",`
    `"major": 1, `
    `"minor": 0,`
    `"patch": 0,`
    `"prerelease": "",`
    `"buildmetadata": ""`
  `}`
`}` | [Return to Overview](#MethodOverview)
***
-| | | -|---|---| -|Method|getheaders| -|Parameters|1. Block Locators (JSON array, required)
 `[ (json array of strings)`
  `"blocklocator", (string) the known block hash`
  `...`
 `]`
2. hashstop (string) - last desired block's hash| -|Description|Returns block headers starting with the first known block hash from the request.| -|Returns|`[ (json array of strings)`
  `"blockheader",`
  `...`
`]`| -|Example Return|`[`
  `"0000002099417930b2ae09feda10e38b58c0f6bb44b4d60fa33f0e000000000000000000d53...",`
  `"000000203ba25a173bfd24d09e0c76002a910b685ca297bd09a17b020000000000000000702..."`
`]`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | getheaders | +| Parameters | 1. Block Locators (JSON array, required)
 `[ (json array of strings)`
  `"blocklocator", (string) the known block hash`
  `...`
 `]`
2. hashstop (string) - last desired block's hash | +| Description | Returns block headers starting with the first known block hash from the request. | +| Returns | `[ (json array of strings)`
  `"blockheader",`
  `...`
`]` | +| Example Return | `[`
  `"0000002099417930b2ae09feda10e38b58c0f6bb44b4d60fa33f0e000000000000000000d53...",`
  `"000000203ba25a173bfd24d09e0c76002a910b685ca297bd09a17b020000000000000000702..."`
`]` | [Return to Overview](#MethodOverview)
*** @@ -701,21 +693,21 @@ The following is an overview of the RPC methods which are implemented by btcd, b The following is an overview of the RPC method requests available exclusively to Websocket clients. All of these RPC methods are available to the limited user. Click the method name for further details such as parameter and return information. -|#|Method|Description|Notifications| -|---|------|-----------|-------------| -|1|[authenticate](#authenticate)|Authenticate the connection against the username and passphrase configured for the RPC server.
NOTE: This is only required if an HTTP Authorization header is not being used.|None| -|2|[notifyblocks](#notifyblocks)|Send notifications when a block is connected or disconnected from the best chain.|[blockconnected](#blockconnected), [blockdisconnected](#blockdisconnected), [filteredblockconnected](#filteredblockconnected), and [filteredblockdisconnected](#filteredblockdisconnected)| -|3|[stopnotifyblocks](#stopnotifyblocks)|Cancel registered notifications for whenever a block is connected or disconnected from the main (best) chain. |None| -|4|[notifyreceived](#notifyreceived)|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send notifications when a txout spends to an address.|[recvtx](#recvtx) and [redeemingtx](#redeemingtx)| -|5|[stopnotifyreceived](#stopnotifyreceived)|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered notifications for when a txout spends to any of the passed addresses.|None| -|6|[notifyspent](#notifyspent)|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send notification when a txout is spent.|[redeemingtx](#redeemingtx)| -|7|[stopnotifyspent](#stopnotifyspent)|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered spending notifications for each passed outpoint.|None| -|8|[rescan](#rescan)|*DEPRECATED, for similar functionality see [rescanblocks](#rescanblocks)*
Rescan block chain for transactions to addresses and spent transaction outpoints.|[recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished) | -|9|[notifynewtransactions](#notifynewtransactions)|Send notifications for all new transactions as they are accepted into the mempool.|[txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose)| -|10|[stopnotifynewtransactions](#stopnotifynewtransactions)|Stop sending either a txaccepted or a txacceptedverbose notification when a new transaction is accepted into the mempool.|None| -|11|[session](#session)|Return details regarding a websocket client's current connection.|None| -|12|[loadtxfilter](#loadtxfilter)|Load, add to, or reload a websocket client's transaction filter for mempool transactions, new blocks and rescanblocks.|[relevanttxaccepted](#relevanttxaccepted)| -|13|[rescanblocks](#rescanblocks)|Rescan blocks for transactions matching the loaded transaction filter.|None| +| # | Method | Description | Notifications | +| --- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 1 | [authenticate](#authenticate) | Authenticate the connection against the username and passphrase configured for the RPC server.
NOTE: This is only required if an HTTP Authorization header is not being used. | None | +| 2 | [notifyblocks](#notifyblocks) | Send notifications when a block is connected or disconnected from the best chain. | [blockconnected](#blockconnected), [blockdisconnected](#blockdisconnected), [filteredblockconnected](#filteredblockconnected), and [filteredblockdisconnected](#filteredblockdisconnected) | +| 3 | [stopnotifyblocks](#stopnotifyblocks) | Cancel registered notifications for whenever a block is connected or disconnected from the main (best) chain. | None | +| 4 | [notifyreceived](#notifyreceived) | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send notifications when a txout spends to an address. | [recvtx](#recvtx) and [redeemingtx](#redeemingtx) | +| 5 | [stopnotifyreceived](#stopnotifyreceived) | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered notifications for when a txout spends to any of the passed addresses. | None | +| 6 | [notifyspent](#notifyspent) | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send notification when a txout is spent. | [redeemingtx](#redeemingtx) | +| 7 | [stopnotifyspent](#stopnotifyspent) | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered spending notifications for each passed outpoint. | None | +| 8 | [rescan](#rescan) | *DEPRECATED, for similar functionality see [rescanblocks](#rescanblocks)*
Rescan block chain for transactions to addresses and spent transaction outpoints. | [recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished) | +| 9 | [notifynewtransactions](#notifynewtransactions) | Send notifications for all new transactions as they are accepted into the mempool. | [txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose) | +| 10 | [stopnotifynewtransactions](#stopnotifynewtransactions) | Stop sending either a txaccepted or a txacceptedverbose notification when a new transaction is accepted into the mempool. | None | +| 11 | [session](#session) | Return details regarding a websocket client's current connection. | None | +| 12 | [loadtxfilter](#loadtxfilter) | Load, add to, or reload a websocket client's transaction filter for mempool transactions, new blocks and rescanblocks. | [relevanttxaccepted](#relevanttxaccepted) | +| 13 | [rescanblocks](#rescanblocks) | Rescan blocks for transactions matching the loaded transaction filter. | None |
@@ -723,177 +715,177 @@ user. Click the method name for further details such as parameter and return in -| | | -|---|---| -|Method|authenticate| -|Parameters|1. username (string, required)
2. passphrase (string, required)| -|Description|Authenticate the connection against the username and password configured for the RPC server.
Invoking any other method before authenticating with this command will close the connection.
NOTE: This is only required if an HTTP Authorization header is not being used.| -|Returns|Success: Nothing
Failure: Nothing (websocket disconnected)| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | authenticate | +| Parameters | 1. username (string, required)
2. passphrase (string, required) | +| Description | Authenticate the connection against the username and password configured for the RPC server.
Invoking any other method before authenticating with this command will close the connection.
NOTE: This is only required if an HTTP Authorization header is not being used. | +| Returns | Success: Nothing
Failure: Nothing (websocket disconnected) | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|notifyblocks| -|Notifications|[blockconnected](#blockconnected), [blockdisconnected](#blockdisconnected), [filteredblockconnected](#filteredblockconnected), and [filteredblockdisconnected](#filteredblockdisconnected)| -|Parameters|None| -|Description|Request notifications for whenever a block is connected or disconnected from the main (best) chain.
NOTE: If a client subscribes to both block and transaction (recvtx and redeemingtx) notifications, the blockconnected notification will be sent after all transaction notifications have been sent. This allows clients to know when all relevant transactions for a block have been received.| -|Returns|Nothing| +| | | +| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | notifyblocks | +| Notifications | [blockconnected](#blockconnected), [blockdisconnected](#blockdisconnected), [filteredblockconnected](#filteredblockconnected), and [filteredblockdisconnected](#filteredblockdisconnected) | +| Parameters | None | +| Description | Request notifications for whenever a block is connected or disconnected from the main (best) chain.
NOTE: If a client subscribes to both block and transaction (recvtx and redeemingtx) notifications, the blockconnected notification will be sent after all transaction notifications have been sent. This allows clients to know when all relevant transactions for a block have been received. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|stopnotifyblocks| -|Notifications|None| -|Parameters|None| -|Description|Cancel sending notifications for whenever a block is connected or disconnected from the main (best) chain.| -|Returns|Nothing| +| | | +| ------------- | ---------------------------------------------------------------------------------------------------------- | +| Method | stopnotifyblocks | +| Notifications | None | +| Parameters | None | +| Description | Cancel sending notifications for whenever a block is connected or disconnected from the main (best) chain. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|notifyreceived| -|Notifications|[recvtx](#recvtx) and [redeemingtx](#redeemingtx)| -|Parameters|1. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]`| -|Description|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send a recvtx notification when a transaction added to mempool or appears in a newly-attached block contains a txout pkScript sending to any of the passed addresses. Matching outpoints are automatically registered for redeemingtx notifications.| -|Returns|Nothing| +| | | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | notifyreceived | +| Notifications | [recvtx](#recvtx) and [redeemingtx](#redeemingtx) | +| Parameters | 1. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]` | +| Description | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send a recvtx notification when a transaction added to mempool or appears in a newly-attached block contains a txout pkScript sending to any of the passed addresses. Matching outpoints are automatically registered for redeemingtx notifications. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|stopnotifyreceived| -|Notifications|None| -|Parameters|1. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]`| -|Description|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered receive notifications for each passed address.| -|Returns|Nothing| +| | | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | stopnotifyreceived | +| Notifications | None | +| Parameters | 1. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]` | +| Description | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered receive notifications for each passed address. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|notifyspent| -|Notifications|[redeemingtx](#redeemingtx)| -|Parameters|1. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]`| -|Description|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this btcd instance) and when such a transaction first appears in a newly-attached block.| -|Returns|Nothing| +| | | +| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | notifyspent | +| Notifications | [redeemingtx](#redeemingtx) | +| Parameters | 1. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]` | +| Description | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this lbcd instance) and when such a transaction first appears in a newly-attached block. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|stopnotifyspent| -|Notifications|None| -|Parameters|1. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]`| -|Description|*DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered spending notifications for each passed outpoint.| -|Returns|Nothing| +| | | +| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | stopnotifyspent | +| Notifications | None | +| Parameters | 1. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]` | +| Description | *DEPRECATED, for similar functionality see [loadtxfilter](#loadtxfilter)*
Cancel registered spending notifications for each passed outpoint. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|rescan| -|Notifications|[recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished)| -|Parameters|1. BeginBlock (string, required) block hash to begin rescanning from
2. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]`
3. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]`
4. EndBlock (string, optional) hash of final block to rescan| -|Description|*DEPRECATED, for similar functionality see [rescanblocks](#rescanblocks)*
Rescan block chain for transactions to addresses, starting at block BeginBlock and ending at EndBlock. The current known UTXO set for all passed addresses at height BeginBlock should included in the Outpoints argument. If EndBlock is omitted, the rescan continues through the best block in the main chain. Additionally, if no EndBlock is provided, the client is automatically registered for transaction notifications for all rescanned addresses and the final UTXO set. Rescan results are sent as recvtx and redeemingtx notifications. This call returns once the rescan completes.| -|Returns|Nothing| +| | | +| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | rescan | +| Notifications | [recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished) | +| Parameters | 1. BeginBlock (string, required) block hash to begin rescanning from
2. Addresses (JSON array, required)
 `[ (json array of strings)`
  `"bitcoinaddress", (string) the bitcoin address`
  `...`
 `]`
3. Outpoints (JSON array, required)
 `[ (JSON array)`
  `{ (JSON object)`
   `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`
   `"index":n (numeric) the txout index of the outpoint`
  `},`
  `...`
 `]`
4. EndBlock (string, optional) hash of final block to rescan | +| Description | *DEPRECATED, for similar functionality see [rescanblocks](#rescanblocks)*
Rescan block chain for transactions to addresses, starting at block BeginBlock and ending at EndBlock. The current known UTXO set for all passed addresses at height BeginBlock should included in the Outpoints argument. If EndBlock is omitted, the rescan continues through the best block in the main chain. Additionally, if no EndBlock is provided, the client is automatically registered for transaction notifications for all rescanned addresses and the final UTXO set. Rescan results are sent as recvtx and redeemingtx notifications. This call returns once the rescan completes. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|notifynewtransactions| -|Notifications|[txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose)| -|Parameters|1. verbose (boolean, optional, default=false) - specifies which type of notification to receive. If verbose is true, then the caller receives [txacceptedverbose](#txacceptedverbose), otherwise the caller receives [txaccepted](#txaccepted)| -|Description|Send either a [txaccepted](#txaccepted) or a [txacceptedverbose](#txacceptedverbose) notification when a new transaction is accepted into the mempool.| -|Returns|Nothing| +| | | +| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | notifynewtransactions | +| Notifications | [txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose) | +| Parameters | 1. verbose (boolean, optional, default=false) - specifies which type of notification to receive. If verbose is true, then the caller receives [txacceptedverbose](#txacceptedverbose), otherwise the caller receives [txaccepted](#txaccepted) | +| Description | Send either a [txaccepted](#txaccepted) or a [txacceptedverbose](#txacceptedverbose) notification when a new transaction is accepted into the mempool. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|stopnotifynewtransactions| -|Notifications|None| -|Parameters|None| -|Description|Stop sending either a [txaccepted](#txaccepted) or a [txacceptedverbose](#txacceptedverbose) notification when a new transaction is accepted into the mempool.| -|Returns|Nothing| +| | | +| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | stopnotifynewtransactions | +| Notifications | None | +| Parameters | None | +| Description | Stop sending either a [txaccepted](#txaccepted) or a [txacceptedverbose](#txacceptedverbose) notification when a new transaction is accepted into the mempool. | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|session| -|Notifications|None| -|Parameters|None| -|Description|Return a JSON object with details regarding a websocket client's current connection to the RPC server. This currently only includes the session ID, a random unsigned 64-bit integer that is created for each newly connected client. Session IDs may be used to verify that the current connection was not lost and subsequently reestablished.| -|Returns|`{ (json object)`
  `"sessionid": n (numeric) the session ID`
`}`| -|Example Return|`{`
  `"sessionid": 67089679842`
`}`| +| | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | session | +| Notifications | None | +| Parameters | None | +| Description | Return a JSON object with details regarding a websocket client's current connection to the RPC server. This currently only includes the session ID, a random unsigned 64-bit integer that is created for each newly connected client. Session IDs may be used to verify that the current connection was not lost and subsequently reestablished. | +| Returns | `{ (json object)`
  `"sessionid": n (numeric) the session ID`
`}` | +| Example Return | `{`
  `"sessionid": 67089679842`
`}` | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|loadtxfilter| -|Notifications|[relevanttxaccepted](#relevanttxaccepted)| -|Parameters|1. Reload (boolean, required) - Load a new filter instead of adding data to an existing one
2. Addresses (JSON array, required) - Array of addresses to add to the transaction filter
3. Outpoints (JSON array, required) - Array of outpoints to add to the transaction filter| -|Description|Load, add to, or reload a websocket client's transaction filter for mempool transactions, new blocks and [rescanblocks](#rescanblocks).| -|Returns|Nothing| +| | | +| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | loadtxfilter | +| Notifications | [relevanttxaccepted](#relevanttxaccepted) | +| Parameters | 1. Reload (boolean, required) - Load a new filter instead of adding data to an existing one
2. Addresses (JSON array, required) - Array of addresses to add to the transaction filter
3. Outpoints (JSON array, required) - Array of outpoints to add to the transaction filter | +| Description | Load, add to, or reload a websocket client's transaction filter for mempool transactions, new blocks and [rescanblocks](#rescanblocks). | +| Returns | Nothing | [Return to Overview](#WSExtMethodOverview)
***
-| | | -|---|---| -|Method|rescanblocks| -|Notifications|None| -|Parameters|1. Blockhashes (JSON array, required) - List of hashes to rescan. Each next block must be a child of the previous.| -|Description|Rescan blocks for transactions matching the loaded transaction filter.| -|Returns|`[ (JSON array)`
  `{ (JSON object)`
    `"hash": "data", (string) Hash of the matching block.`
    `"transactions": [ (JSON array) List of matching transactions, serialized and hex-encoded.`
      `"serializedtx" (string) Serialized and hex-encoded transaction.`
    `]`
  `}`
`]`| -|Example Return|`[`
  `{`
    `"hash": "0000002099417930b2ae09feda10e38b58c0f6bb44b4d60fa33f0e000000000000000000d53...",`
    `"transactions": [`
      `"493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8..."`
    `]`
  `}`
`]`| +| | | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | rescanblocks | +| Notifications | None | +| Parameters | 1. Blockhashes (JSON array, required) - List of hashes to rescan. Each next block must be a child of the previous. | +| Description | Rescan blocks for transactions matching the loaded transaction filter. | +| Returns | `[ (JSON array)`
  `{ (JSON object)`
    `"hash": "data", (string) Hash of the matching block.`
    `"transactions": [ (JSON array) List of matching transactions, serialized and hex-encoded.`
      `"serializedtx" (string) Serialized and hex-encoded transaction.`
    `]`
  `}`
`]` | +| Example Return | `[`
  `{`
    `"hash": "0000002099417930b2ae09feda10e38b58c0f6bb44b4d60fa33f0e000000000000000000d53...",`
    `"transactions": [`
      `"493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8..."`
    `]`
  `}`
`]` |
### 8. Notifications (Websocket-specific) -btcd uses standard JSON-RPC notifications to notify clients of changes, rather than requiring clients to poll btcd for updates. JSON-RPC notifications are a subset of requests, but do not contain an ID. The notification type is categorized by the `method` field and additional details are sent as a JSON array in the `params` field. +lbcd uses standard JSON-RPC notifications to notify clients of changes, rather than requiring clients to poll lbcd for updates. JSON-RPC notifications are a subset of requests, but do not contain an ID. The notification type is categorized by the `method` field and additional details are sent as a JSON array in the `params` field. @@ -901,19 +893,19 @@ btcd uses standard JSON-RPC notifications to notify clients of changes, rather t The following is an overview of the JSON-RPC notifications used for Websocket connections. Click the method name for further details of the context(s) in which they are sent and their parameters. -|#|Method|Description|Request| -|---|------|-----------|-------| -|1|[blockconnected](#blockconnected)|*DEPRECATED, for similar functionality see [filteredblockconnected](#filteredblockconnected)*
Block connected to the main chain.|[notifyblocks](#notifyblocks)| -|2|[blockdisconnected](#blockdisconnected)|*DEPRECATED, for similar functionality see [filteredblockdisconnected](#filteredblockdisconnected)*
Block disconnected from the main chain.|[notifyblocks](#notifyblocks)| -|3|[recvtx](#recvtx)|*DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Processed a transaction output spending to a wallet address.|[notifyreceived](#notifyreceived) and [rescan](#rescan)| -|4|[redeemingtx](#redeemingtx)|*DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Processed a transaction that spends a registered outpoint.|[notifyspent](#notifyspent) and [rescan](#rescan)| -|5|[txaccepted](#txaccepted)|Received a new transaction after requesting simple notifications of all new transactions accepted into the mempool.|[notifynewtransactions](#notifynewtransactions)| -|6|[txacceptedverbose](#txacceptedverbose)|Received a new transaction after requesting verbose notifications of all new transactions accepted into the mempool.|[notifynewtransactions](#notifynewtransactions)| -|7|[rescanprogress](#rescanprogress)|*DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
A rescan operation that is underway has made progress.|[rescan](#rescan)| -|8|[rescanfinished](#rescanfinished)|*DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
A rescan operation has completed.|[rescan](#rescan)| -|9|[relevanttxaccepted](#relevanttxaccepted)|A transaction matching the tx filter has been accepted into the mempool.|[loadtxfilter](#loadtxfilter)| -|10|[filteredblockconnected](#filteredblockconnected)|Block connected to the main chain; contains any transactions that match the client's tx filter.|[notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter)| -|11|[filteredblockdisconnected](#filteredblockdisconnected)|Block disconnected from the main chain.|[notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter)| +| # | Method | Description | Request | +| --- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| 1 | [blockconnected](#blockconnected) | *DEPRECATED, for similar functionality see [filteredblockconnected](#filteredblockconnected)*
Block connected to the main chain. | [notifyblocks](#notifyblocks) | +| 2 | [blockdisconnected](#blockdisconnected) | *DEPRECATED, for similar functionality see [filteredblockdisconnected](#filteredblockdisconnected)*
Block disconnected from the main chain. | [notifyblocks](#notifyblocks) | +| 3 | [recvtx](#recvtx) | *DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Processed a transaction output spending to a wallet address. | [notifyreceived](#notifyreceived) and [rescan](#rescan) | +| 4 | [redeemingtx](#redeemingtx) | *DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Processed a transaction that spends a registered outpoint. | [notifyspent](#notifyspent) and [rescan](#rescan) | +| 5 | [txaccepted](#txaccepted) | Received a new transaction after requesting simple notifications of all new transactions accepted into the mempool. | [notifynewtransactions](#notifynewtransactions) | +| 6 | [txacceptedverbose](#txacceptedverbose) | Received a new transaction after requesting verbose notifications of all new transactions accepted into the mempool. | [notifynewtransactions](#notifynewtransactions) | +| 7 | [rescanprogress](#rescanprogress) | *DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
A rescan operation that is underway has made progress. | [rescan](#rescan) | +| 8 | [rescanfinished](#rescanfinished) | *DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
A rescan operation has completed. | [rescan](#rescan) | +| 9 | [relevanttxaccepted](#relevanttxaccepted) | A transaction matching the tx filter has been accepted into the mempool. | [loadtxfilter](#loadtxfilter) | +| 10 | [filteredblockconnected](#filteredblockconnected) | Block connected to the main chain; contains any transactions that match the client's tx filter. | [notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter) | +| 11 | [filteredblockdisconnected](#filteredblockdisconnected) | Block disconnected from the main chain. | [notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter) |
@@ -921,142 +913,142 @@ The following is an overview of the JSON-RPC notifications used for Websocket co -| | | -|---|---| -|Method|blockconnected| -|Request|[notifyblocks](#notifyblocks)| -|Parameters|1. BlockHash (string) hex-encoded bytes of the attached block hash
2. BlockHeight (numeric) height of the attached block
3. BlockTime (numeric) unix time of the attached block| -|Description|*DEPRECATED, for similar functionality see [filteredblockconnected](#filteredblockconnected)*
Notifies when a block has been added to the main chain. Notification is sent to all connected clients.| -|Example|Example blockconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockconnected",`
 `"params":`
  `[`
   `"000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd",`
   `280330,`
   `1389636265`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | blockconnected | +| Request | [notifyblocks](#notifyblocks) | +| Parameters | 1. BlockHash (string) hex-encoded bytes of the attached block hash
2. BlockHeight (numeric) height of the attached block
3. BlockTime (numeric) unix time of the attached block | +| Description | *DEPRECATED, for similar functionality see [filteredblockconnected](#filteredblockconnected)*
Notifies when a block has been added to the main chain. Notification is sent to all connected clients. | +| Example | Example blockconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockconnected",`
 `"params":`
  `[`
   `"000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd",`
   `280330,`
   `1389636265`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|blockdisconnected| -|Request|[notifyblocks](#notifyblocks)| -|Parameters|1. BlockHash (string) hex-encoded bytes of the disconnected block hash
2. BlockHeight (numeric) height of the disconnected block
3. BlockTime (numeric) unix time of the disconnected block| -|Description|*DEPRECATED, for similar functionality see [filteredblockdisconnected](#filteredblockdisconnected)*
Notifies when a block has been removed from the main chain. Notification is sent to all connected clients.| -|Example|Example blockdisconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockdisconnected",`
 `"params":`
  `[`
   `"000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd",`
   `280330,`
   `1389636265`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | blockdisconnected | +| Request | [notifyblocks](#notifyblocks) | +| Parameters | 1. BlockHash (string) hex-encoded bytes of the disconnected block hash
2. BlockHeight (numeric) height of the disconnected block
3. BlockTime (numeric) unix time of the disconnected block | +| Description | *DEPRECATED, for similar functionality see [filteredblockdisconnected](#filteredblockdisconnected)*
Notifies when a block has been removed from the main chain. Notification is sent to all connected clients. | +| Example | Example blockdisconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockdisconnected",`
 `"params":`
  `[`
   `"000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd",`
   `280330,`
   `1389636265`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|recvtx| -|Request|[rescan](#rescan) or [notifyreceived](#notifyreceived)| -|Parameters|1. Transaction (string) full transaction encoded as a hex string
2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined| -|Description|*DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Notifies a client when a transaction is processed that contains at least a single output with a pkScript sending to a requested address. If multiple outputs send to requested addresses, a single notification is sent. If a mempool (unmined) transaction is processed, the block details object (second parameter) is excluded.| -|Example|Example recvtx notification for mainnet transaction 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad when processed by mempool (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000..."`
  `],`
 `"id": null`
`}`
The recvtx notification for the same txout, after the transaction was mined into block 276425:
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000...",`
   `{`
    `"height": 276425,`
    `"hash": "000000000000000325474bb799b9e591f965ca4461b72cb7012b808db92bb2fc",`
    `"index": 684,`
    `"time": 1387737310`
   `}`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | recvtx | +| Request | [rescan](#rescan) or [notifyreceived](#notifyreceived) | +| Parameters | 1. Transaction (string) full transaction encoded as a hex string
2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined | +| Description | *DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Notifies a client when a transaction is processed that contains at least a single output with a pkScript sending to a requested address. If multiple outputs send to requested addresses, a single notification is sent. If a mempool (unmined) transaction is processed, the block details object (second parameter) is excluded. | +| Example | Example recvtx notification for mainnet transaction 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad when processed by mempool (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000..."`
  `],`
 `"id": null`
`}`
The recvtx notification for the same txout, after the transaction was mined into block 276425:
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000...",`
   `{`
    `"height": 276425,`
    `"hash": "000000000000000325474bb799b9e591f965ca4461b72cb7012b808db92bb2fc",`
    `"index": 684,`
    `"time": 1387737310`
   `}`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|redeemingtx| -|Requests|[notifyspent](#notifyspent) and [rescan](#rescan)| -|Parameters|1. Transaction (string) full transaction encoded as a hex string
2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined| -|Description|*DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Notifies a client when an registered outpoint is spent by a transaction accepted to mempool and/or mined into a block.| -|Example|Example redeemingtx notification for mainnet outpoint 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad:0 after being spent by transaction 4ad0c16ac973ff675dec1f3e5f1273f1c45be2a63554343f21b70240a1e43ece (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "redeemingtx",`
 `"params":`
  `[`
   `"0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000..."`
  `],`
 `"id": null`
`}`
The redeemingtx notification for the same txout, after the spending transaction was mined into block 279143:
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000...",`
   `{`
    `"height": 279143,`
    `"hash": "00000000000000017188b968a371bab95aa43522665353b646e41865abae02a4",`
    `"index": 6,`
    `"time": 1389115004`
   `}`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | redeemingtx | +| Requests | [notifyspent](#notifyspent) and [rescan](#rescan) | +| Parameters | 1. Transaction (string) full transaction encoded as a hex string
2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined | +| Description | *DEPRECATED, for similar functionality see [relevanttxaccepted](#relevanttxaccepted) and [filteredblockconnected](#filteredblockconnected)*
Notifies a client when an registered outpoint is spent by a transaction accepted to mempool and/or mined into a block. | +| Example | Example redeemingtx notification for mainnet outpoint 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad:0 after being spent by transaction 4ad0c16ac973ff675dec1f3e5f1273f1c45be2a63554343f21b70240a1e43ece (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "redeemingtx",`
 `"params":`
  `[`
   `"0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000..."`
  `],`
 `"id": null`
`}`
The redeemingtx notification for the same txout, after the spending transaction was mined into block 279143:
`{`
 `"jsonrpc": "1.0",`
 `"method": "recvtx",`
 `"params":`
  `[`
   `"0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000...",`
   `{`
    `"height": 279143,`
    `"hash": "00000000000000017188b968a371bab95aa43522665353b646e41865abae02a4",`
    `"index": 6,`
    `"time": 1389115004`
   `}`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|txaccepted| -|Request|[notifynewtransactions](#notifynewtransactions)| -|Parameters|1. TxHash (string) hex-encoded bytes of the transaction hash
2. Amount (numeric) sum of the value of all the transaction outpoints| -|Description|Notifies when a new transaction has been accepted and the client has requested standard transaction details.| -|Example|Example txaccepted notification for mainnet transaction id "16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261" (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "txaccepted",`
 `"params":`
  `[`
   `"16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261",`
   `55838384`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | txaccepted | +| Request | [notifynewtransactions](#notifynewtransactions) | +| Parameters | 1. TxHash (string) hex-encoded bytes of the transaction hash
2. Amount (numeric) sum of the value of all the transaction outpoints | +| Description | Notifies when a new transaction has been accepted and the client has requested standard transaction details. | +| Example | Example txaccepted notification for mainnet transaction id "16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261" (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "txaccepted",`
 `"params":`
  `[`
   `"16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261",`
   `55838384`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|txacceptedverbose| -|Request|[notifynewtransactions](#notifynewtransactions)| -|Parameters|1. RawTx (json object) the transaction as a json object (see getrawtransaction json object details)| -|Description|Notifies when a new transaction has been accepted and the client has requested verbose transaction details.| -|Example|Example txacceptedverbose notification (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "txacceptedverbose",`
 `"params":`
  `[`
   `{`
    `"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...",`
    `"txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9",`
    `"version": 1,`
    `"locktime": 0,`
    `"vin": [`
    For coinbase transactions:
      `{ (json object)`
        `"coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f",`
        `"sequence": 0,`
      `}`
    For non-coinbase transactions:
      `{`
        `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
        `"vout": 0,`
        `"scriptSig": {`
          `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
          `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
        `}`
        `"sequence": 4294967295,`
      `}`
    `],`
    `"vout": [`
     `{`
      `"value": 25.1394,`
      `"n": 0,`
      `"scriptPubKey": {`
       `"asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG",`
       `"hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac",`
       `"reqSigs": 1,`
       `"type": "pubkeyhash"`
       `"addresses": [`
        `"1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh",`
       `]`
     `}`
    `]`
   `}`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | txacceptedverbose | +| Request | [notifynewtransactions](#notifynewtransactions) | +| Parameters | 1. RawTx (json object) the transaction as a json object (see getrawtransaction json object details) | +| Description | Notifies when a new transaction has been accepted and the client has requested verbose transaction details. | +| Example | Example txacceptedverbose notification (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "txacceptedverbose",`
 `"params":`
  `[`
   `{`
    `"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...",`
    `"txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9",`
    `"version": 1,`
    `"locktime": 0,`
    `"vin": [`
    For coinbase transactions:
      `{ (json object)`
        `"coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f",`
        `"sequence": 0,`
      `}`
    For non-coinbase transactions:
      `{`
        `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
        `"vout": 0,`
        `"scriptSig": {`
          `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
          `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
        `}`
        `"sequence": 4294967295,`
      `}`
    `],`
    `"vout": [`
     `{`
      `"value": 25.1394,`
      `"n": 0,`
      `"scriptPubKey": {`
       `"asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG",`
       `"hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac",`
       `"reqSigs": 1,`
       `"type": "pubkeyhash"`
       `"addresses": [`
        `"1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh",`
       `]`
     `}`
    `]`
   `}`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|rescanprogress| -|Request|[rescan](#rescan)| -|Parameters|1. Hash (string) hash of the last processed block
2. Height (numeric) height of the last processed block
3. Time (numeric) UNIX time of the last processed block| -|Description|*DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
Notifies a client with the current progress at periodic intervals when a long-running [rescan](#rescan) is underway.| -|Example|`{`
 `"jsonrpc": "1.0",`
 `"method": "rescanprogress",`
 `"params":`
  `[`
   `"0000000000000ea86b49e11843b2ad937ac89ae74a963c7edd36e0147079b89d",`
   `127213,`
   `1306533807`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | rescanprogress | +| Request | [rescan](#rescan) | +| Parameters | 1. Hash (string) hash of the last processed block
2. Height (numeric) height of the last processed block
3. Time (numeric) UNIX time of the last processed block | +| Description | *DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
Notifies a client with the current progress at periodic intervals when a long-running [rescan](#rescan) is underway. | +| Example | `{`
 `"jsonrpc": "1.0",`
 `"method": "rescanprogress",`
 `"params":`
  `[`
   `"0000000000000ea86b49e11843b2ad937ac89ae74a963c7edd36e0147079b89d",`
   `127213,`
   `1306533807`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|rescanfinished| -|Request|[rescan](#rescan)| -|Parameters|1. Hash (string) hash of the last rescanned block
2. Height (numeric) height of the last rescanned block
3. Time (numeric) UNIX time of the last rescanned block | -|Description|*DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
Notifies a client that the [rescan](#rescan) has completed and no further notifications will be sent.| -|Example|`{`
 `"jsonrpc": "1.0",`
 `"method": "rescanfinished",`
 `"params":`
  `[`
   `"0000000000000ea86b49e11843b2ad937ac89ae74a963c7edd36e0147079b89d",`
   `127213,`
   `1306533807`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Method | rescanfinished | +| Request | [rescan](#rescan) | +| Parameters | 1. Hash (string) hash of the last rescanned block
2. Height (numeric) height of the last rescanned block
3. Time (numeric) UNIX time of the last rescanned block | +| Description | *DEPRECATED, notifications not used by [rescanblocks](#rescanblocks)*
Notifies a client that the [rescan](#rescan) has completed and no further notifications will be sent. | +| Example | `{`
 `"jsonrpc": "1.0",`
 `"method": "rescanfinished",`
 `"params":`
  `[`
   `"0000000000000ea86b49e11843b2ad937ac89ae74a963c7edd36e0147079b89d",`
   `127213,`
   `1306533807`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|relevanttxaccepted| -|Request|[loadtxfilter](#loadtxfilter)| -|Parameters|1. Transaction (string) hex-encoded serialized transaction matching the client's filter loaded ith [loadtxfilter](#loadtxfilter)| -|Description|Notifies a client that a transaction matching the client's tx filter has been accepted into he mempool.| -|Example|Example `relevanttxaccepted` notification (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "relevanttxaccepted",`
 `"params": [`
  `"01000000014221abdcca25c8a3b0c044034875dece048c77d567a806f0c2e7e0f5e25a8f100..."`
 `],`
 `"id": null`
`}`| +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | relevanttxaccepted | +| Request | [loadtxfilter](#loadtxfilter) | +| Parameters | 1. Transaction (string) hex-encoded serialized transaction matching the client's filter loaded ith [loadtxfilter](#loadtxfilter) | +| Description | Notifies a client that a transaction matching the client's tx filter has been accepted into he mempool. | +| Example | Example `relevanttxaccepted` notification (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "relevanttxaccepted",`
 `"params": [`
  `"01000000014221abdcca25c8a3b0c044034875dece048c77d567a806f0c2e7e0f5e25a8f100..."`
 `],`
 `"id": null`
`}` | ***
-| | | -|---|---| -|Method|filteredblockconnected| -|Request|[notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter)| -|Parameters|1. BlockHeight (numeric) height of the attached block
2. Header (string) hex-encoded serialized header of the attached block
3. Transactions (JSON array) hex-encoded serialized transactions matching the filter for the client connection loaded with [loadtxfilter](#loadtxfilter)| -|Description|Notifies when a block has been added to the main chain. Notification is sent to all connected clients.| -|Example|Example filteredblockconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "filteredblockconnected",`
 `"params":`
  `[`
   `280330,`
   `"0200000052d1e8813f697293e41942aa230e7e4fcc44832d78a1372202000000000000006aa...",`
   `[`
    `"01000000014221abdcca25c8a3b0c044034875dece048c77d567a806f0c2e7e0f5e25a8f100..."`
   `]`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | filteredblockconnected | +| Request | [notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter) | +| Parameters | 1. BlockHeight (numeric) height of the attached block
2. Header (string) hex-encoded serialized header of the attached block
3. Transactions (JSON array) hex-encoded serialized transactions matching the filter for the client connection loaded with [loadtxfilter](#loadtxfilter) | +| Description | Notifies when a block has been added to the main chain. Notification is sent to all connected clients. | +| Example | Example filteredblockconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "filteredblockconnected",`
 `"params":`
  `[`
   `280330,`
   `"0200000052d1e8813f697293e41942aa230e7e4fcc44832d78a1372202000000000000006aa...",`
   `[`
    `"01000000014221abdcca25c8a3b0c044034875dece048c77d567a806f0c2e7e0f5e25a8f100..."`
   `]`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
***
-| | | -|---|---| -|Method|filteredblockdisconnected| -|Request|[notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter)| -|Parameters|1. BlockHeight (numeric) height of the disconnected block
2. Header (string) hex-encoded serialized header of the disconnected block| -|Description|Notifies when a block has been removed from the main chain. Notification is sent to all connected clients.| -|Example|Example blockdisconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockdisconnected",`
 `"params":`
  `[`
   `280330,`
   `"0200000052d1e8813f697293e41942aa230e7e4fcc44832d78a1372202000000000000006aa..."`
  `],`
 `"id": null`
`}`| +| | | +| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Method | filteredblockdisconnected | +| Request | [notifyblocks](#notifyblocks), [loadtxfilter](#loadtxfilter) | +| Parameters | 1. BlockHeight (numeric) height of the disconnected block
2. Header (string) hex-encoded serialized header of the disconnected block | +| Description | Notifies when a block has been removed from the main chain. Notification is sent to all connected clients. | +| Example | Example blockdisconnected notification for mainnet block 280330 (newlines added for readability):
`{`
 `"jsonrpc": "1.0",`
 `"method": "blockdisconnected",`
 `"params":`
  `[`
   `280330,`
   `"0200000052d1e8813f697293e41942aa230e7e4fcc44832d78a1372202000000000000006aa..."`
  `],`
 `"id": null`
`}` | [Return to Overview](#NotificationOverview)
@@ -1075,7 +1067,7 @@ various languages. **9.1 Go** This section provides examples of using the RPC interface using Go and the -[rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) package. +[rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) package. * [Using getblockcount to Retrieve the Current Block Height](#ExampleGetBlockCount) * [Using getblock to Retrieve the Genesis Block](#ExampleGetBlock) @@ -1087,8 +1079,8 @@ This section provides examples of using the RPC interface using Go and the **9.1.1 Using getblockcount to Retrieve the Current Block Height**
The following is an example Go application which uses the -[rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) package to connect with -a btcd instance via Websockets, issues [getblockcount](#getblockcount) to +[rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) package to connect with +a lbcd instance via Websockets, issues [getblockcount](#getblockcount) to retrieve the current block height, and displays it. ```Go @@ -1099,16 +1091,16 @@ import ( "log" "path/filepath" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) func main() { // Load the certificate for the TLS connection which is automatically - // generated by btcd when it starts the RPC server and doesn't already + // generated by lbcd when it starts the RPC server and doesn't already // have one. - btcdHomeDir := btcutil.AppDataDir("btcd", false) - certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert")) + lbcdHomeDir := btcutil.AppDataDir("lbcd", false) + certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) } @@ -1116,8 +1108,8 @@ func main() { // Create a new RPC client using websockets. Since this example is // not long-lived, the connection will be closed as soon as the program // exits. - connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8334", + connCfg := &btcrpcclient.ConnConfig{ + Host: "localhost:9245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", @@ -1149,8 +1141,8 @@ Which results in: **9.1.2 Using getblock to Retrieve the Genesis Block**
The following is an example Go application which uses the -[rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) package to connect with -a btcd instance via Websockets, issues [getblock](#getblock) to retrieve +[rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) package to connect with +a lbcd instance via Websockets, issues [getblock](#getblock) to retrieve information about the Genesis block, and display a few details about it. ```Go @@ -1162,17 +1154,17 @@ import ( "path/filepath" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) func main() { // Load the certificate for the TLS connection which is automatically - // generated by btcd when it starts the RPC server and doesn't already + // generated by lbcd when it starts the RPC server and doesn't already // have one. - btcdHomeDir := btcutil.AppDataDir("btcd", false) - certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert")) + lbcdHomeDir := btcutil.AppDataDir("lbcd", false) + certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) } @@ -1180,8 +1172,8 @@ func main() { // Create a new RPC client using websockets. Since this example is // not long-lived, the connection will be closed as soon as the program // exits. - connCfg := &rpcclient.ConnConfig{ - Host: "localhost:18334", + connCfg := &btcrpcclient.ConnConfig{ + Host: "localhost:19245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", @@ -1239,8 +1231,8 @@ Num transactions: 1 Notifications (Websocket-specific)**
The following is an example Go application which uses the -[rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient) package to connect with -a btcd instance via Websockets and registers for +[rpcclient](https://github.com/lbryio/lbcd/tree/master/rpcclient) package to connect with +a lbcd instance via Websockets and registers for [blockconnected](#blockconnected) and [blockdisconnected](#blockdisconnected) notifications with [notifyblocks](#notifyblocks). It also sets up handlers for the notifications. @@ -1254,9 +1246,9 @@ import ( "path/filepath" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcutil" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/rpcclient" + btcutil "github.com/lbryio/lbcutil" ) func main() { @@ -1272,17 +1264,17 @@ func main() { } // Load the certificate for the TLS connection which is automatically - // generated by btcd when it starts the RPC server and doesn't already + // generated by lbcd when it starts the RPC server and doesn't already // have one. - btcdHomeDir := btcutil.AppDataDir("btcd", false) - certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert")) + lbcdHomeDir := btcutil.AppDataDir("lbcd", false) + certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) if err != nil { log.Fatal(err) } // Create a new RPC client using websockets. - connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8334", + connCfg := &btcrpcclient.ConnConfig{ + Host: "localhost:9245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", @@ -1337,7 +1329,7 @@ Example output: **9.2.1 Using notifyblocks to be Notified of Block Connects and Disconnects**
The following is example node.js code which uses [ws](https://github.com/einaros/ws) -(can be installed with `npm install ws`) to connect with a btcd instance, +(can be installed with `npm install ws`) to connect with a lbcd instance, issues [notifyblocks](#notifyblocks) to register for [blockconnected](#blockconnected) and [blockdisconnected](#blockdisconnected) notifications, and displays all incoming messages. @@ -1347,17 +1339,17 @@ var fs = require('fs'); var WebSocket = require('ws'); // Load the certificate for the TLS connection which is automatically -// generated by btcd when it starts the RPC server and doesn't already +// generated by lbcd when it starts the RPC server and doesn't already // have one. -var cert = fs.readFileSync('/path/to/btcd/appdata/rpc.cert'); +var cert = fs.readFileSync('/path/to/lbcd/appdata/rpc.cert'); var user = "yourusername"; var password = "yourpassword"; -// Initiate the websocket connection. The btcd generated certificate acts as +// Initiate the websocket connection. The lbcd generated certificate acts as // its own certificate authority, so it needs to be specified in the 'ca' array // for the certificate to properly validate. -var ws = new WebSocket('wss://127.0.0.1:8334/ws', { +var ws = new WebSocket('wss://127.0.0.1:9245/ws', { headers: { 'Authorization': 'Basic '+new Buffer(user+':'+password).toString('base64') }, diff --git a/docs/mining.md b/docs/mining.md index 29a3e898..226d560b 100644 --- a/docs/mining.md +++ b/docs/mining.md @@ -1,6 +1,6 @@ # Mining -btcd supports the `getblocktemplate` RPC. +lbcd supports the `getblocktemplate` RPC. The limited user cannot access this RPC. ## Add the payment addresses with the `miningaddr` option @@ -13,18 +13,20 @@ miningaddr=12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX miningaddr=1M83ju3EChKYyysmM2FXtLNftbacagd8FR ``` -## Add btcd's RPC TLS certificate to system Certificate Authority list +## Add lbcd's RPC TLS certificate to system Certificate Authority list -`cgminer` uses [curl](http://curl.haxx.se/) to fetch data from the RPC server. -Since curl validates the certificate by default, we must install the `btcd` RPC +Various miners use [curl](http://curl.haxx.se/) to fetch data from the RPC server. +Since curl validates the certificate by default, we must install the `lbcd` RPC certificate into the default system Certificate Authority list. ## Ubuntu -1. Copy rpc.cert to /usr/share/ca-certificates: `# cp /home/user/.btcd/rpc.cert /usr/share/ca-certificates/btcd.crt` -2. Add btcd.crt to /etc/ca-certificates.conf: `# echo btcd.crt >> /etc/ca-certificates.conf` +1. Copy rpc.cert to /usr/share/ca-certificates: `# cp /home/user/.lbcd/rpc.cert /usr/share/ca-certificates/lbcd.crt` +2. Add lbcd.crt to /etc/ca-certificates.conf: `# echo lbcd.crt >> /etc/ca-certificates.conf` 3. Update the CA certificate list: `# update-ca-certificates` ## Set your mining software url to use https -`cgminer -o https://127.0.0.1:8334 -u rpcuser -p rpcpassword` +`cgminer -o https://127.0.0.1:9245 -u rpcuser -p rpcpassword` + +Alternatively, you can disable TLS with the `--notls` option for the server. diff --git a/docs/table_of_content.md b/docs/table_of_content.md deleted file mode 100644 index 85f08a97..00000000 --- a/docs/table_of_content.md +++ /dev/null @@ -1,13 +0,0 @@ -# Contents - -* [Installation](installation.md) -* [Update](update.md) -* [Configuration](configuration.md) -* [Configuring TOR](configuring_tor.md) -* [Controlling](controlling.md) -* [Mining](mining.md) -* [Wallet](wallet.md) -* [Developer resources](developer_resources.md) -* [JSON RPC API](json_rpc_api.md) -* [Code contribution guidelines](code_contribution_guidelines.md) -* [Contact](contact.md) diff --git a/docs/update.md b/docs/update.md deleted file mode 100644 index 1fb847cf..00000000 --- a/docs/update.md +++ /dev/null @@ -1,8 +0,0 @@ -# Update - -* Run the following commands to update btcd, all dependencies, and install it: - -```bash -cd $GOPATH/src/github.com/btcsuite/btcd -git pull && GO111MODULE=on go install -v . ./cmd/... -``` diff --git a/docs/using_docker.md b/docs/using_docker.md deleted file mode 100644 index 0809abc1..00000000 --- a/docs/using_docker.md +++ /dev/null @@ -1,160 +0,0 @@ -# Using Docker - -- [Using Docker](#using-docker) - - [Introduction](#introduction) - - [Docker volumes](#docker-volumes) - - [Known error messages when starting the btcd container](#known-error-messages-when-starting-the-btcd-container) - - [Examples](#examples) - - [Preamble](#preamble) - - [Full node without RPC port](#full-node-without-rpc-port) - - [Full node with RPC port](#full-node-with-rpc-port) - - [Full node with RPC port running on TESTNET](#full-node-with-rpc-port-running-on-testnet) - -## Introduction - -With Docker you can easily set up *btcd* to run your Bitcoin full node. You can find the official *btcd* Docker images on Docker Hub [btcsuite/btcd](https://hub.docker.com/r/btcsuite/btcd). The Docker source file of this image is located at [Dockerfile](https://github.com/btcsuite/btcd/blob/master/Dockerfile). - -This documentation focuses on running Docker container with *docker-compose.yml* files. These files are better to read and you can use them as a template for your own use. For more information about Docker and Docker compose visit the official [Docker documentation](https://docs.docker.com/). - -## Docker volumes - -**Special diskspace hint**: The following examples are using a Docker managed volume. The volume is named *btcd-data* This will use a lot of disk space, because it contains the full Bitcoin blockchain. Please make yourself familiar with [Docker volumes](https://docs.docker.com/storage/volumes/). - -The *btcd-data* volume will be reused, if you upgrade your *docker-compose.yml* file. Keep in mind, that it is not automatically removed by Docker, if you delete the btcd container. If you don't need the volume anymore, please delete it manually with the command: - -```bash -docker volume ls -docker volume rm btcd-data -``` - -For binding a local folder to your *btcd* container please read the [Docker documentation](https://docs.docker.com/). The preferred way is to use a Docker managed volume. - -## Known error messages when starting the btcd container - -We pass all needed arguments to *btcd* as command line parameters in our *docker-compose.yml* file. It doesn't make sense to create a *btcd.conf* file. This would make things too complicated. Anyhow *btcd* will complain with following log messages when starting. These messages can be ignored: - -```bash -Error creating a default config file: open /sample-btcd.conf: no such file or directory -... -[WRN] BTCD: open /root/.btcd/btcd.conf: no such file or directory -``` - -## Examples - -### Preamble - -All following examples uses some defaults: - -- container_name: btcd - Name of the docker container that is be shown by e.g. ```docker ps -a``` - -- hostname: btcd **(very important to set a fixed name before first start)** - The internal hostname in the docker container. By default, docker is recreating the hostname every time you change the *docker-compose.yml* file. The default hostnames look like *ef00548d4fa5*. This is a problem when using the *btcd* RPC port. The RPC port is using a certificate to validate the hostname. If the hostname changes you need to recreate the certificate. To avoid this, you should set a fixed hostname before the first start. This ensures, that the docker volume is created with a certificate with this hostname. - -- restart: unless-stopped - Starts the *btcd* container when Docker starts, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker restarts. - -To use the following examples create an empty directory. In this directory create a file named *docker-compose.yml*, copy and paste the example into the *docker-compose.yml* file and run it. - -```bash -mkdir ~/btcd-docker -cd ~/btcd-docker -touch docker-compose.yaml -nano docker-compose.yaml (use your favourite editor to edit the compose file) -docker-compose up (creates and starts a new btcd container) -``` - -With the following commands you can control *docker-compose*: - -```docker-compose up -d``` (creates and starts the container in background) - -```docker-compose down``` (stops and delete the container. **The docker volume btcd-data will not be deleted**) - -```docker-compose stop``` (stops the container) - -```docker-compose start``` (starts the container) - -```docker ps -a``` (list all running and stopped container) - -```docker volume ls``` (lists all docker volumes) - -```docker logs btcd``` (shows the log ) - -```docker-compose help``` (brings up some helpful information) - -### Full node without RPC port - -Let's start with an easy example. If you just want to create a full node without the need of using the RPC port, you can use the following example. This example will launch *btcd* and exposes only the default p2p port 8333 to the outside world: - -```yaml -version: "2" - -services: - btcd: - container_name: btcd - hostname: btcd - image: btcsuite/btcd:latest - restart: unless-stopped - volumes: - - btcd-data:/root/.btcd - ports: - - 8333:8333 - -volumes: - btcd-data: -``` - -### Full node with RPC port - -To use the RPC port of *btcd* you need to specify a *username* and a very strong *password*. If you want to connect to the RPC port from the internet, you need to expose port 8334(RPC) as well. - -```yaml -version: "2" - -services: - btcd: - container_name: btcd - hostname: btcd - image: btcsuite/btcd:latest - restart: unless-stopped - volumes: - - btcd-data:/root/.btcd - ports: - - 8333:8333 - - 8334:8334 - command: [ - "--rpcuser=[CHOOSE_A_USERNAME]", - "--rpcpass=[CREATE_A_VERY_HARD_PASSWORD]" - ] - -volumes: - btcd-data: -``` - -### Full node with RPC port running on TESTNET - -To run a node on testnet, you need to provide the *--testnet* argument. The ports for testnet are 18333 (p2p) and 18334 (RPC): - -```yaml -version: "2" - -services: - btcd: - container_name: btcd - hostname: btcd - image: btcsuite/btcd:latest - restart: unless-stopped - volumes: - - btcd-data:/root/.btcd - ports: - - 18333:18333 - - 18334:18334 - command: [ - "--testnet", - "--rpcuser=[CHOOSE_A_USERNAME]", - "--rpcpass=[CREATE_A_VERY_HARD_PASSWORD]" - ] - -volumes: - btcd-data: -``` diff --git a/docs/wallet.md b/docs/wallet.md deleted file mode 100644 index cc123aa7..00000000 --- a/docs/wallet.md +++ /dev/null @@ -1,5 +0,0 @@ -# Wallet - -btcd was intentionally developed without an integrated wallet for security -reasons. Please see [btcwallet](https://github.com/btcsuite/btcwallet) for more -information. diff --git a/integration/README.md b/integration/README.md index 5f6f14ea..db58a898 100644 --- a/integration/README.md +++ b/integration/README.md @@ -1,13 +1,8 @@ integration =========== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) This contains integration tests which make use of the -[rpctest](https://github.com/btcsuite/btcd/tree/master/integration/rpctest) +[rpctest](https://github.com/lbryio/lbcd/tree/master/integration/rpctest) package to programmatically drive nodes via RPC. - -## License - -This code is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/integration/rpctest/README.md b/integration/rpctest/README.md index 79f45bc8..8ccfc879 100644 --- a/integration/rpctest/README.md +++ b/integration/rpctest/README.md @@ -1,9 +1,7 @@ rpctest ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/integration/rpctest) Package rpctest provides a btcd-specific RPC testing harness crafting and executing integration tests by driving a `btcd` instance via the `RPC` @@ -16,15 +14,3 @@ This package was designed specifically to act as an RPC testing harness for `btcd`. However, the constructs presented are general enough to be adapted to any project wishing to programmatically drive a `btcd` instance of its systems/integration tests. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/integration/rpctest -``` - -## License - -Package rpctest is licensed under the [copyfree](http://copyfree.org) ISC -License. - diff --git a/mempool/README.md b/mempool/README.md index 5f1e4a4c..1e19f843 100644 --- a/mempool/README.md +++ b/mempool/README.md @@ -1,9 +1,7 @@ mempool ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/mempool) Package mempool provides a policy-enforced pool of unmined bitcoin transactions. @@ -33,11 +31,6 @@ proceed. Typically, this will involve things such as relaying the transactions to other peers on the network and notifying the mining process that new transactions are available. -This package has intentionally been designed so it can be used as a standalone -package for any projects needing the ability create an in-memory pool of bitcoin -transactions that are not only valid by consensus rules, but also adhere to a -configurable policy. - ## Feature Overview The following is a quick overview of the major features. It is not intended to @@ -70,14 +63,3 @@ be an exhaustive list. - The starting priority for the transaction - Manual control of transaction removal - Recursive removal of all dependent transactions - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/mempool -``` - -## License - -Package mempool is licensed under the [copyfree](http://copyfree.org) ISC -License. diff --git a/mining/README.md b/mining/README.md index 3abd1953..40a30a20 100644 --- a/mining/README.md +++ b/mining/README.md @@ -1,21 +1,8 @@ mining ====== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/mining) ## Overview -This package is currently a work in progress. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/mining -``` - -## License - -Package mining is licensed under the [copyfree](http://copyfree.org) ISC -License. +This package is currently a work in progress. \ No newline at end of file diff --git a/mining/cpuminer/README.md b/mining/cpuminer/README.md index 47247be9..270e435d 100644 --- a/mining/cpuminer/README.md +++ b/mining/cpuminer/README.md @@ -1,9 +1,9 @@ cpuminer ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![Build Status](https://github.com/lbryio/lbcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/lbryio/lbcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/mining/cpuminer) +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/lbryio/lbcd/mining/cpuminer) ======= ## Overview @@ -16,7 +16,7 @@ now. ## Installation and Updating ```bash -$ go get -u github.com/btcsuite/btcd/mining/cpuminer +$ go get -u github.com/lbryio/lbcd/mining/cpuminer ``` ## License diff --git a/netsync/README.md b/netsync/README.md index a4966815..22f51701 100644 --- a/netsync/README.md +++ b/netsync/README.md @@ -1,9 +1,7 @@ netsync ======= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/netsync) ## Overview @@ -13,13 +11,3 @@ download, keep the chain and unconfirmed transaction pool in sync, and announce new blocks connected to the chain. Currently the sync manager selects a single sync peer that it downloads all blocks from until it is up to date with the longest chain the sync peer is aware of. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/netsync -``` - -## License - -Package netsync is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/peer/README.md b/peer/README.md index 217f5dc3..51761319 100644 --- a/peer/README.md +++ b/peer/README.md @@ -1,16 +1,11 @@ peer ==== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/peer) Package peer provides a common base for creating and managing bitcoin network peers. -This package has intentionally been designed so it can be used as a standalone -package for any projects needing a full featured bitcoin peer base to build on. - ## Overview This package builds upon the wire package, which provides the fundamental @@ -54,20 +49,4 @@ A quick overview of the major features peer provides are as follows: filtering and address randomization - Ability to wait for shutdown/disconnect - Comprehensive test coverage - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/peer -``` - -## Examples - -* [New Outbound Peer Example](https://pkg.go.dev/github.com/btcsuite/btcd/peer#example-package--NewOutboundPeer) - Demonstrates the basic process for initializing and creating an outbound peer. - Peers negotiate by exchanging version and verack messages. For demonstration, - a simple handler for the version message is attached to the peer. - -## License - -Package peer is licensed under the [copyfree](http://copyfree.org) ISC License. + \ No newline at end of file diff --git a/release/README.md b/release/README.md deleted file mode 100644 index 7128ef1f..00000000 --- a/release/README.md +++ /dev/null @@ -1,181 +0,0 @@ -# `btcd`'s Reproducible Build System - -This package contains the build script that the `btcd` project uses in order to -build binaries for each new release. As of `go1.13`, with some new build flags, -binaries are now reproducible, allowing developers to build the binary on -distinct machines, and end up with a byte-for-byte identical binary. -Every release should note which Go version was used to build the release, so -that version should be used for verifying the release. - -## Building a New Release - -### Tagging and pushing a new tag (for maintainers) - -Before running release scripts, a few things need to happen in order to finally -create a release and make sure there are no mistakes in the release process. - -First, make sure that before the tagged commit there are modifications to the -[CHANGES](../CHANGES) file committed. -The CHANGES file should be a changelog that roughly mirrors the release notes. -Generally, the PRs that have been merged since the last release have been -listed in the CHANGES file and categorized. -For example, these changes have had the following format in the past: -``` -Changes in X.YY.Z (Month Day Year): - - Protocol and Network-related changes: - - PR Title One (#PRNUM) - - PR Title Two (#PRNUMTWO) - ... - - RPC changes: - - Crypto changes: - ... - - - Contributors (alphabetical order): - - Contributor A - - Contributor B - - Contributor C - ... -``` - -If the previous tag is, for example, `vA.B.C`, then you can get the list of -contributors (from `vA.B.C` until the current `HEAD`) using the following command: -```bash -git log vA.B.C..HEAD --pretty="%an" | sort | uniq -``` -After committing changes to the CHANGES file, the tagged release commit -should be created. - -The tagged commit should be a commit that bumps version numbers in `version.go` -and `cmd/btcctl/version.go`. -For example (taken from [f3ec130](https://github.com/btcsuite/btcd/commit/f3ec13030e4e828869954472cbc51ac36bee5c1d)): -```diff -diff --git a/cmd/btcctl/version.go b/cmd/btcctl/version.go -index 2195175c71..f65cacef7e 100644 ---- a/cmd/btcctl/version.go -+++ b/cmd/btcctl/version.go -@@ -18,7 +18,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr - const ( - appMajor uint = 0 - appMinor uint = 20 -- appPatch uint = 0 -+ appPatch uint = 1 - - // appPreRelease MUST only contain characters from semanticAlphabet - // per the semantic versioning spec. -diff --git a/version.go b/version.go -index 92fd60fdd4..fba55b5a37 100644 ---- a/version.go -+++ b/version.go -@@ -18,7 +18,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr - const ( - appMajor uint = 0 - appMinor uint = 20 -- appPatch uint = 0 -+ appPatch uint = 1 - - // appPreRelease MUST only contain characters from semanticAlphabet - // per the semantic versioning spec. -``` - -Next, this commit should be signed by the maintainer using `git commit -S`. -The commit should be tagged and signed with `git tag -s`, and should be -pushed using `git push origin TAG`. - -### Building a release on macOS/Linux/Windows (WSL) - -No prior set up is needed on Linux or macOS is required in order to build the -release binaries. However, on Windows, the only way to build the release -binaries at the moment is by using the Windows Subsystem Linux. One can build -the release binaries following these steps: - -1. `git clone https://github.com/btcsuite/btcd.git` -2. `cd btcd` -3. `./release/release.sh # is the name of the next release/tag` - -This will then create a directory of the form `btcd-` containing archives -of the release binaries for each supported operating system and architecture, -and a manifest file containing the hash of each archive. - -### Pushing a release (for maintainers) - -Now that the directory `btcd-` is created, the manifest file needs to be -signed by a maintainer and the release files need to be published to GitHub. - -Sign the `manifest-.txt` file like so: -```sh -gpg --sign --detach-sig manifest-.txt -``` -This will create a file named `manifest-.txt.sig`, which will must -be included in the release files later. - -#### Note before publishing -Before publishing, go through the reproducible build process that is outlined -in this document with the files created from `release/release.sh`. This includes -verifying commit and tag signatures using `git verify-commit` and git `verify-tag` -respectively. - -Now that we've double-checked everything and have all of the necessary files, -it's time to publish release files on GitHub. -Follow [this documentation](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository) -to create a release using the GitHub UI, and make sure to write release notes -which roughly follow the format of [previous release notes](https://github.com/btcsuite/btcd/releases/tag/v0.20.1-beta). -This is different from the [CHANGES](../CHANGES) file, which should be before the -tagged commit in the git history. -Much of the information in the release notes will be the same as the CHANGES -file. -It's important to include the Go version used to produce the release files in -the release notes, so users know the correct version of Go to use to reproduce -and verify the build. -When following the GitHub documentation, include every file in the `btcd-` -directory. - -At this point, a signed commit and tag on that commit should be pushed to the main -branch. The directory created from running `release/release.sh` should be included -as release files in the GitHub release UI, and the `manifest-.txt` file -signature, called `manifest-.txt.sig`, should also be included. -A release notes document should be created and written in the GitHub release UI. -Once all of this is done, feel free to click `Publish Release`! - -## Verifying a Release - -With `go1.13`, it's now possible for third parties to verify release binaries. -Before this version of `go`, one had to trust the release manager(s) to build the -proper binary. With this new system, third parties can now _independently_ run -the release process, and verify that all the hashes of the release binaries -match exactly that of the release binaries produced by said third parties. - -To verify a release, one must obtain the following tools (many of these come -installed by default in most Unix systems): `gpg`/`gpg2`, `shashum`, and -`tar`/`unzip`. - -Once done, verifiers can proceed with the following steps: - -1. Acquire the archive containing the release binaries for one's specific - operating system and architecture, and the manifest file along with its - signature. -2. Verify the signature of the manifest file with `gpg --verify - manifest-.txt.sig`. This will require obtaining the PGP keys which - signed the manifest file, which are included in the release notes. -3. Recompute the `SHA256` hash of the archive with `shasum -a 256 `, - locate the corresponding one in the manifest file, and ensure they match - __exactly__. - -At this point, verifiers can use the release binaries acquired if they trust -the integrity of the release manager(s). Otherwise, one can proceed with the -guide to verify the release binaries were built properly by obtaining `shasum` -and `go` (matching the same version used in the release): - -4. Extract the release binaries contained within the archive, compute their - hashes as done above, and note them down. -5. Ensure `go` is installed, matching the same version as noted in the release - notes. -6. Obtain a copy of `btcd`'s source code with `git clone - https://github.com/btcsuite/btcd` and checkout the source code of the - release with `git checkout `. -7. Proceed to verify the tag with `git verify-tag ` and compile the - binaries from source for the intended operating system and architecture with - `BTCDBUILDSYS=OS-ARCH ./release/release.sh `. -8. Extract the archive found in the `btcd-` directory created by the - release script and recompute the `SHA256` hash of the release binaries (btcd - and btcctl) with `shasum -a 256 `. These should match __exactly__ - as the ones noted above. \ No newline at end of file diff --git a/rpcclient/README.md b/rpcclient/README.md index 08b16f75..c5a42063 100644 --- a/rpcclient/README.md +++ b/rpcclient/README.md @@ -1,13 +1,11 @@ rpcclient ========= -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) [![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/rpcclient) rpcclient implements a Websocket-enabled Bitcoin JSON-RPC client package written in [Go](http://golang.org/). It provides a robust and easy to use client for -interfacing with a Bitcoin RPC server that uses a btcd/bitcoin core compatible +interfacing with a Bitcoin RPC server that uses a lbcd/bitcoin core compatible Bitcoin JSON-RPC API. ## Status @@ -16,26 +14,11 @@ This package is currently under active development. It is already stable and the infrastructure is complete. However, there are still several RPCs left to implement and the API is not stable yet. -## Documentation - -* [API Reference](https://pkg.go.dev/github.com/btcsuite/btcd/rpcclient) -* [btcd Websockets Example](https://github.com/btcsuite/btcd/tree/master/rpcclient/examples/btcdwebsockets) - Connects to a btcd RPC server using TLS-secured websockets, registers for - block connected and block disconnected notifications, and gets the current - block count -* [btcwallet Websockets Example](https://github.com/btcsuite/btcd/tree/master/rpcclient/examples/btcwalletwebsockets) - Connects to a btcwallet RPC server using TLS-secured websockets, registers for - notifications about changes to account balances, and gets a list of unspent - transaction outputs (utxos) the wallet can sign -* [Bitcoin Core HTTP POST Example](https://github.com/btcsuite/btcd/tree/master/rpcclient/examples/bitcoincorehttp) - Connects to a bitcoin core RPC server using HTTP POST mode with TLS disabled - and gets the current block count - ## Major Features -* Supports Websockets (btcd/btcwallet) and HTTP POST mode (bitcoin core) -* Provides callback and registration functions for btcd/btcwallet notifications -* Supports btcd extensions +* Supports Websockets (lbcd/lbcwallet) and HTTP POST mode (bitcoin core) +* Provides callback and registration functions for lbcd/lbcwallet notifications +* Supports lbcd extensions * Translates to and from higher-level and easier to use Go types * Offers a synchronous (blocking) and asynchronous API * When running in Websockets mode (the default): @@ -43,14 +26,4 @@ implement and the API is not stable yet. * Outstanding commands are automatically reissued * Registered notifications are automatically reregistered * Back-off support on reconnect attempts - -## Installation - -```bash -$ go get -u github.com/btcsuite/btcd/rpcclient -``` - -## License - -Package rpcclient is licensed under the [copyfree](http://copyfree.org) ISC -License. + \ No newline at end of file diff --git a/rpcclient/examples/bitcoincorehttp/README.md b/rpcclient/examples/bitcoincorehttp/README.md index 4d1f0adf..e26e68ce 100644 --- a/rpcclient/examples/bitcoincorehttp/README.md +++ b/rpcclient/examples/bitcoincorehttp/README.md @@ -10,7 +10,7 @@ block count. The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -24,7 +24,7 @@ password for the RPC server: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/bitcoincorehttp +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/bitcoincorehttp $ go run *.go ``` diff --git a/rpcclient/examples/bitcoincorehttpbulk/README.md b/rpcclient/examples/bitcoincorehttpbulk/README.md index ca900b6e..6d1a02c0 100644 --- a/rpcclient/examples/bitcoincorehttpbulk/README.md +++ b/rpcclient/examples/bitcoincorehttpbulk/README.md @@ -8,7 +8,7 @@ This example shows how to use the rpclient package to connect to a Bitcoin Core The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -22,7 +22,7 @@ password for the RPC server: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/bitcoincorehttp +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/bitcoincorehttp $ go run *.go ``` diff --git a/rpcclient/examples/btcdwebsockets/README.md b/rpcclient/examples/btcdwebsockets/README.md index a1686484..4168a0fa 100644 --- a/rpcclient/examples/btcdwebsockets/README.md +++ b/rpcclient/examples/btcdwebsockets/README.md @@ -13,7 +13,7 @@ demonstrate clean shutdown. The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -27,7 +27,7 @@ password for the RPC server: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/btcdwebsockets +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/btcdwebsockets $ go run *.go ``` diff --git a/rpcclient/examples/btcwalletwebsockets/README.md b/rpcclient/examples/btcwalletwebsockets/README.md index e495dff8..1e95a6c1 100644 --- a/rpcclient/examples/btcwalletwebsockets/README.md +++ b/rpcclient/examples/btcwalletwebsockets/README.md @@ -14,7 +14,7 @@ demonstrate clean shutdown. The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -28,7 +28,7 @@ password for the RPC server: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/btcwalletwebsockets +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/btcwalletwebsockets $ go run *.go ``` diff --git a/rpcclient/examples/customcommand/README.md b/rpcclient/examples/customcommand/README.md index 0e36d649..21670cc8 100644 --- a/rpcclient/examples/customcommand/README.md +++ b/rpcclient/examples/customcommand/README.md @@ -9,7 +9,7 @@ implementing the `name_show` command from Namecoin Core. The first step is to use `go get` to download and install the rpcclient package: ```bash -$ go get github.com/btcsuite/btcd/rpcclient +$ go get github.com/lbryio/lbcd/rpcclient ``` Next, modify the `main.go` source to specify the correct RPC username and @@ -23,7 +23,7 @@ password for the RPC server of your Namecoin Core node: Finally, navigate to the example's directory and run it with: ```bash -$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/customcommand +$ cd $GOPATH/src/github.com/lbryio/lbcd/rpcclient/examples/customcommand $ go run *.go ``` diff --git a/rpcclient/examples/customcommand/main.go b/rpcclient/examples/customcommand/main.go index 1e14c06f..e89719d5 100644 --- a/rpcclient/examples/customcommand/main.go +++ b/rpcclient/examples/customcommand/main.go @@ -9,8 +9,8 @@ import ( "encoding/json" "log" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/rpcclient" + "github.com/lbryio/lbcd/btcjson" + "github.com/lbryio/lbcd/rpcclient" ) // NameShowCmd defines the name_show JSON-RPC command. diff --git a/sample-btcd.conf b/sample-lbcd.conf similarity index 94% rename from sample-btcd.conf rename to sample-lbcd.conf index e1b6cba6..a3970d95 100644 --- a/sample-btcd.conf +++ b/sample-lbcd.conf @@ -6,12 +6,12 @@ ; The directory to store data such as the block chain and peer addresses. The ; block chain takes several GB, so this location must have a lot of free space. -; The default is ~/.btcd/data on POSIX OSes, $LOCALAPPDATA/Btcd/data on Windows, -; ~/Library/Application Support/Btcd/data on Mac OS, and $home/btcd/data on +; The default is ~/.lbcd/data on POSIX OSes, $LOCALAPPDATA/Lbcd/data on Windows, +; ~/Library/Application Support/Lbcd/data on Mac OS, and $home/lbcd/data on ; Plan9. Environment variables are expanded so they may be used. NOTE: Windows ; environment variables are typically %VARIABLE%, but they must be accessed with ; $VARIABLE here. Also, ~ is expanded to $LOCALAPPDATA on Windows. -; datadir=~/.btcd/data +; datadir=~/.lbcd/data ; ------------------------------------------------------------------------------ @@ -52,7 +52,7 @@ ; upnp=1 ; Specify the external IP addresses your node is listening on. One address per -; line. btcd will not contact 3rd-party sites to obtain external ip addresses. +; line. lbcd will not contact 3rd-party sites to obtain external ip addresses. ; This means if you are behind NAT, your node will not be able to advertise a ; reachable address unless you specify it here or enable the 'upnp' option (and ; have a supported device). @@ -64,7 +64,7 @@ ; ; Only one of the following two options, 'addpeer' and 'connect', may be ; specified. Both allow you to specify peers that you want to stay connected -; with, but the behavior is slightly different. By default, btcd will query DNS +; with, but the behavior is slightly different. By default, lbcd will query DNS ; to find peers to connect to, so unless you have a specific reason such as ; those described below, you probably won't need to modify anything here. ; @@ -86,9 +86,9 @@ ; You may specify each IP address with or without a port. The default port will ; be added automatically if one is not specified here. ; addpeer=192.168.1.1 -; addpeer=10.0.0.2:8333 +; addpeer=10.0.0.2:9246 ; addpeer=fe80::1 -; addpeer=[fe80::2]:8333 +; addpeer=[fe80::2]:9246 ; Add persistent peers that you ONLY want to connect to as desired. One peer ; per line. You may specify each IP address with or without a port. The @@ -96,9 +96,9 @@ ; NOTE: Specifying this option has other side effects as described above in ; the 'addpeer' versus 'connect' summary section. ; connect=192.168.1.1 -; connect=10.0.0.2:8333 +; connect=10.0.0.2:9246 ; connect=fe80::1 -; connect=[fe80::2]:8333 +; connect=[fe80::2]:9246 ; Maximum number of inbound and outbound peers. ; maxpeers=125 @@ -124,7 +124,7 @@ ; whitelist=192.168.0.0/24 ; whitelist=fd00::/16 -; Disable DNS seeding for peers. By default, when btcd starts, it will use +; Disable DNS seeding for peers. By default, when lbcd starts, it will use ; DNS to query for available peers to connect with. ; nodnsseed=1 @@ -138,16 +138,16 @@ ; listen=0.0.0.0 ; All ipv6 interfaces on default port: ; listen=:: -; All interfaces on port 8333: -; listen=:8333 -; All ipv4 interfaces on port 8333: -; listen=0.0.0.0:8333 -; All ipv6 interfaces on port 8333: -; listen=[::]:8333 -; Only ipv4 localhost on port 8333: -; listen=127.0.0.1:8333 -; Only ipv6 localhost on port 8333: -; listen=[::1]:8333 +; All interfaces on port 9246: +; listen=:9246 +; All ipv4 interfaces on port 9246: +; listen=0.0.0.0:9246 +; All ipv6 interfaces on port 9246: +; listen=[::]:9246 +; Only ipv4 localhost on port 9246: +; listen=127.0.0.1:9246 +; Only ipv6 localhost on port 9246: +; listen=[::1]:9246 ; Only ipv4 localhost on non-standard port 8336: ; listen=127.0.0.1:8336 ; All interfaces on non-standard port 8336: @@ -185,7 +185,7 @@ ; ------------------------------------------------------------------------------ ; RPC server options - The following options control the built-in RPC server -; which is used to control and query information from a running btcd process. +; which is used to control and query information from a running lbcd process. ; ; NOTE: The RPC server is disabled by default if rpcuser AND rpcpass, or ; rpclimituser AND rpclimitpass, are not specified. @@ -369,7 +369,7 @@ ; Debug logging level. ; Valid levels are {trace, debug, info, warn, error, critical} ; You may also specify =,=,... to set -; log level for individual subsystems. Use btcd --debuglevel=show to list +; log level for individual subsystems. Use lbcd --debuglevel=show to list ; available subsystems. ; debuglevel=info diff --git a/txscript/README.md b/txscript/README.md index f0abb518..e0b8fdd6 100644 --- a/txscript/README.md +++ b/txscript/README.md @@ -1,67 +1,15 @@ txscript ======== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) -[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/txscript?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/txscript) - Package txscript implements the bitcoin transaction script language. There is a comprehensive test suite. -This package has intentionally been designed so it can be used as a standalone -package for any projects needing to use or validate bitcoin transaction scripts. +This package has been augmented to include support for LBRY's custom claim operations. +See https://lbry.tech/spec ## Bitcoin Scripts Bitcoin provides a stack-based, FORTH-like language for the scripts in the bitcoin transactions. This language is not turing complete although it is still fairly powerful. A description of the language -can be found at https://en.bitcoin.it/wiki/Script - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/txscript -``` - -## Examples - -* [Standard Pay-to-pubkey-hash Script](https://pkg.go.dev/github.com/btcsuite/btcd/txscript#example-PayToAddrScript) - Demonstrates creating a script which pays to a bitcoin address. It also - prints the created script hex and uses the DisasmString function to display - the disassembled script. - -* [Extracting Details from Standard Scripts](https://pkg.go.dev/github.com/btcsuite/btcd/txscript#example-ExtractPkScriptAddrs) - Demonstrates extracting information from a standard public key script. - -* [Manually Signing a Transaction Output](https://pkg.go.dev/github.com/btcsuite/btcd/txscript#example-SignTxOutput) - Demonstrates manually creating and signing a redeem transaction. - -* [Counting Opcodes in Scripts](http://godoc.org/github.com/decred/dcrd/txscript#example-ScriptTokenizer) - Demonstrates creating a script tokenizer instance and using it to count the - number of opcodes a script contains. - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package txscript is licensed under the [copyfree](http://copyfree.org) ISC -License. +can be found at https://en.bitcoin.it/wiki/Script \ No newline at end of file diff --git a/wire/README.md b/wire/README.md index 8660bbfd..c14a3640 100644 --- a/wire/README.md +++ b/wire/README.md @@ -1,26 +1,14 @@ wire ==== -[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) -[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/wire) -======= - Package wire implements the bitcoin wire protocol. A comprehensive suite of tests with 100% test coverage is provided to ensure proper functionality. There is an associated blog post about the release of this package [here](https://blog.conformal.com/btcwire-the-bitcoin-wire-protocol-package-from-btcd/). -This package has intentionally been designed so it can be used as a standalone -package for any projects needing to interface with bitcoin peers at the wire -protocol level. - -## Installation and Updating - -```bash -$ go get -u github.com/btcsuite/btcd/wire -``` +This package has been augmented from the original btcd implementation. +The block header was modified to contain the claimtrie hash. ## Bitcoin Message Overview @@ -85,29 +73,4 @@ from a remote peer is: if err != nil { // Log and handle the error } -``` - -## GPG Verification Key - -All official release tags are signed by Conformal so users can ensure the code -has not been tampered with and is coming from the btcsuite developers. To -verify the signature perform the following: - -- Download the public key from the Conformal website at - https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt - -- Import the public key into your GPG keyring: - ```bash - gpg --import GIT-GPG-KEY-conformal.txt - ``` - -- Verify the release tag with the following command where `TAG_NAME` is a - placeholder for the specific tag: - ```bash - git tag -v TAG_NAME - ``` - -## License - -Package wire is licensed under the [copyfree](http://copyfree.org) ISC -License. +``` \ No newline at end of file -- 2.45.2 From b4623ef2dd3521c6cb06b88dfddd6d329696e7e2 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 24 Sep 2021 13:25:27 -0400 Subject: [PATCH 383/459] [lbry] increase open file limit to 2048 --- limits/limits_unix.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/limits/limits_unix.go b/limits/limits_unix.go index 7ebf8667..e55a1c28 100644 --- a/limits/limits_unix.go +++ b/limits/limits_unix.go @@ -12,8 +12,8 @@ import ( ) const ( - fileLimitWant = 2048 - fileLimitMin = 1024 + fileLimitWant = 2048 * 12 + fileLimitMin = 2048 * 8 ) // SetLimits raises some process limits to values which allow btcd and -- 2.45.2 From 2bd6e4c3a9db30da7ad6584262cbc40ef68f1fc6 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Fri, 24 Sep 2021 13:25:27 -0400 Subject: [PATCH 384/459] [lbry] ffldb: increase open file limit and flush more often --- database/ffldb/blockio.go | 2 +- database/ffldb/db.go | 9 +++++---- database/ffldb/dbcache.go | 14 +++++--------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/database/ffldb/blockio.go b/database/ffldb/blockio.go index ae71a891..2ed4eccf 100644 --- a/database/ffldb/blockio.go +++ b/database/ffldb/blockio.go @@ -37,7 +37,7 @@ const ( // maxOpenFiles is the max number of open files to maintain in the // open blocks cache. Note that this does not include the current // write file, so there will typically be one more than this value open. - maxOpenFiles = 25 + maxOpenFiles = 40 // maxBlockFileSize is the maximum size for each file used to store // blocks. diff --git a/database/ffldb/db.go b/database/ffldb/db.go index 0d6acd51..ee6d55f0 100644 --- a/database/ffldb/db.go +++ b/database/ffldb/db.go @@ -2001,10 +2001,11 @@ func openDB(dbPath string, network wire.BitcoinNet, create bool) (database.DB, e // Open the metadata database (will create it if needed). opts := opt.Options{ - ErrorIfExist: create, - Strict: opt.DefaultStrict, - Compression: opt.NoCompression, - Filter: filter.NewBloomFilter(10), + ErrorIfExist: create, + Strict: opt.DefaultStrict, + Compression: opt.NoCompression, + Filter: filter.NewBloomFilter(10), + OpenFilesCacheCapacity: 2000, } ldb, err := leveldb.OpenFile(metadataDbPath, &opts) if err != nil { diff --git a/database/ffldb/dbcache.go b/database/ffldb/dbcache.go index 15c554a7..1bc21a35 100644 --- a/database/ffldb/dbcache.go +++ b/database/ffldb/dbcache.go @@ -23,7 +23,7 @@ const ( // defaultFlushSecs is the default number of seconds to use as a // threshold in between database cache flushes when the cache size has // not been exceeded. - defaultFlushSecs = 300 // 5 minutes + defaultFlushSecs = 120 // 2 minutes // ldbBatchHeaderSize is the size of a leveldb batch header which // includes the sequence header and record counter. @@ -499,10 +499,12 @@ func (c *dbCache) flush() error { // Since the cached keys to be added and removed use an immutable treap, // a snapshot is simply obtaining the root of the tree under the lock // which is used to atomically swap the root. - c.cacheLock.RLock() + c.cacheLock.Lock() cachedKeys := c.cachedKeys cachedRemove := c.cachedRemove - c.cacheLock.RUnlock() + c.cachedKeys = treap.NewImmutable() + c.cachedRemove = treap.NewImmutable() + c.cacheLock.Unlock() // Nothing to do if there is no data to flush. if cachedKeys.Len() == 0 && cachedRemove.Len() == 0 { @@ -514,12 +516,6 @@ func (c *dbCache) flush() error { return err } - // Clear the cache since it has been flushed. - c.cacheLock.Lock() - c.cachedKeys = treap.NewImmutable() - c.cachedRemove = treap.NewImmutable() - c.cacheLock.Unlock() - return nil } -- 2.45.2 From d35a82412fc06c2c336ca4f00fded6a59d509d32 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 14 Aug 2018 17:59:48 -0700 Subject: [PATCH 385/459] [lbry] align port settings between lbcd, lbcctl, and lbcwallet --- Dockerfile | 4 +- addrmgr/addrmanager_test.go | 90 +++++++++---------- addrmgr/network_test.go | 4 +- chaincfg/params.go | 6 +- cmd/lbcctl/config.go | 40 ++++----- config.go | 4 +- connmgr/connmanager_test.go | 2 +- docs/README.md | 1 - params.go | 24 ++--- peer/peer_test.go | 40 ++++----- rpcclient/example_test.go | 2 +- rpcclient/examples/bitcoincorehttp/main.go | 2 +- .../examples/bitcoincorehttpbulk/main.go | 2 +- rpcclient/examples/btcdwebsockets/main.go | 2 +- .../examples/btcwalletwebsockets/main.go | 2 +- rpcclient/wallet.go | 2 +- sample-lbcd.conf | 20 ++--- wire/message_test.go | 4 +- wire/msgaddr_test.go | 10 +-- wire/msgversion_test.go | 24 ++--- wire/netaddress_test.go | 10 +-- 21 files changed, 146 insertions(+), 149 deletions(-) delete mode 120000 docs/README.md diff --git a/Dockerfile b/Dockerfile index ec45ee64..ddd4f647 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,8 +11,8 @@ # For more information how to use this docker image visit: # https://github.com/btcsuite/btcd/tree/master/docs # -# 8333 Mainnet Bitcoin peer-to-peer port -# 8334 Mainet RPC port +# 9246 Mainnet Bitcoin peer-to-peer port +# 9245 Mainet RPC port ARG ARCH=amd64 # using the SHA256 instead of tags diff --git a/addrmgr/addrmanager_test.go b/addrmgr/addrmanager_test.go index d623479c..182f65da 100644 --- a/addrmgr/addrmanager_test.go +++ b/addrmgr/addrmanager_test.go @@ -34,61 +34,61 @@ var someIP = "173.194.115.66" func addNaTests() { // IPv4 // Localhost - addNaTest("127.0.0.1", 8333, "127.0.0.1:8333") - addNaTest("127.0.0.1", 8334, "127.0.0.1:8334") + addNaTest("127.0.0.1", 9244, "127.0.0.1:9244") + addNaTest("127.0.0.1", 9245, "127.0.0.1:9245") // Class A - addNaTest("1.0.0.1", 8333, "1.0.0.1:8333") - addNaTest("2.2.2.2", 8334, "2.2.2.2:8334") - addNaTest("27.253.252.251", 8335, "27.253.252.251:8335") - addNaTest("123.3.2.1", 8336, "123.3.2.1:8336") + addNaTest("1.0.0.1", 9244, "1.0.0.1:9244") + addNaTest("2.2.2.2", 9245, "2.2.2.2:9245") + addNaTest("27.253.252.251", 9246, "27.253.252.251:9246") + addNaTest("123.3.2.1", 9247, "123.3.2.1:9247") // Private Class A - addNaTest("10.0.0.1", 8333, "10.0.0.1:8333") - addNaTest("10.1.1.1", 8334, "10.1.1.1:8334") - addNaTest("10.2.2.2", 8335, "10.2.2.2:8335") - addNaTest("10.10.10.10", 8336, "10.10.10.10:8336") + addNaTest("10.0.0.1", 9244, "10.0.0.1:9244") + addNaTest("10.1.1.1", 9245, "10.1.1.1:9245") + addNaTest("10.2.2.2", 9246, "10.2.2.2:9246") + addNaTest("10.10.10.10", 9247, "10.10.10.10:9247") // Class B - addNaTest("128.0.0.1", 8333, "128.0.0.1:8333") - addNaTest("129.1.1.1", 8334, "129.1.1.1:8334") - addNaTest("180.2.2.2", 8335, "180.2.2.2:8335") - addNaTest("191.10.10.10", 8336, "191.10.10.10:8336") + addNaTest("128.0.0.1", 9244, "128.0.0.1:9244") + addNaTest("129.1.1.1", 9245, "129.1.1.1:9245") + addNaTest("180.2.2.2", 9246, "180.2.2.2:9246") + addNaTest("191.10.10.10", 9247, "191.10.10.10:9247") // Private Class B - addNaTest("172.16.0.1", 8333, "172.16.0.1:8333") - addNaTest("172.16.1.1", 8334, "172.16.1.1:8334") - addNaTest("172.16.2.2", 8335, "172.16.2.2:8335") - addNaTest("172.16.172.172", 8336, "172.16.172.172:8336") + addNaTest("172.16.0.1", 9244, "172.16.0.1:9244") + addNaTest("172.16.1.1", 9245, "172.16.1.1:9245") + addNaTest("172.16.2.2", 9246, "172.16.2.2:9246") + addNaTest("172.16.172.172", 9247, "172.16.172.172:9247") // Class C - addNaTest("193.0.0.1", 8333, "193.0.0.1:8333") - addNaTest("200.1.1.1", 8334, "200.1.1.1:8334") - addNaTest("205.2.2.2", 8335, "205.2.2.2:8335") - addNaTest("223.10.10.10", 8336, "223.10.10.10:8336") + addNaTest("193.0.0.1", 9244, "193.0.0.1:9244") + addNaTest("200.1.1.1", 9245, "200.1.1.1:9245") + addNaTest("205.2.2.2", 9246, "205.2.2.2:9246") + addNaTest("223.10.10.10", 9247, "223.10.10.10:9247") // Private Class C - addNaTest("192.168.0.1", 8333, "192.168.0.1:8333") - addNaTest("192.168.1.1", 8334, "192.168.1.1:8334") - addNaTest("192.168.2.2", 8335, "192.168.2.2:8335") - addNaTest("192.168.192.192", 8336, "192.168.192.192:8336") + addNaTest("192.168.0.1", 9244, "192.168.0.1:9244") + addNaTest("192.168.1.1", 9245, "192.168.1.1:9245") + addNaTest("192.168.2.2", 9246, "192.168.2.2:9246") + addNaTest("192.168.192.192", 9247, "192.168.192.192:9247") // IPv6 // Localhost - addNaTest("::1", 8333, "[::1]:8333") - addNaTest("fe80::1", 8334, "[fe80::1]:8334") + addNaTest("::1", 9244, "[::1]:9244") + addNaTest("fe80::1", 9245, "[fe80::1]:9245") // Link-local - addNaTest("fe80::1:1", 8333, "[fe80::1:1]:8333") - addNaTest("fe91::2:2", 8334, "[fe91::2:2]:8334") - addNaTest("fea2::3:3", 8335, "[fea2::3:3]:8335") - addNaTest("feb3::4:4", 8336, "[feb3::4:4]:8336") + addNaTest("fe80::1:1", 9244, "[fe80::1:1]:9244") + addNaTest("fe91::2:2", 9245, "[fe91::2:2]:9245") + addNaTest("fea2::3:3", 9246, "[fea2::3:3]:9246") + addNaTest("feb3::4:4", 9247, "[feb3::4:4]:9247") // Site-local - addNaTest("fec0::1:1", 8333, "[fec0::1:1]:8333") - addNaTest("fed1::2:2", 8334, "[fed1::2:2]:8334") - addNaTest("fee2::3:3", 8335, "[fee2::3:3]:8335") - addNaTest("fef3::4:4", 8336, "[fef3::4:4]:8336") + addNaTest("fec0::1:1", 9244, "[fec0::1:1]:9244") + addNaTest("fed1::2:2", 9245, "[fed1::2:2]:9245") + addNaTest("fee2::3:3", 9246, "[fee2::3:3]:9246") + addNaTest("fef3::4:4", 9247, "[fef3::4:4]:9247") } func addNaTest(ip string, port uint16, want string) { @@ -119,7 +119,7 @@ func TestAddAddressByIP(t *testing.T) { err error }{ { - someIP + ":8333", + someIP + ":9244", nil, }, { @@ -127,7 +127,7 @@ func TestAddAddressByIP(t *testing.T) { addrErr, }, { - someIP[:12] + ":8333", + someIP[:12] + ":9244", fmtErr, }, { @@ -212,7 +212,7 @@ func TestAttempt(t *testing.T) { n := addrmgr.New("testattempt", lookupFunc) // Add a new address and get it - err := n.AddAddressByIP(someIP + ":8333") + err := n.AddAddressByIP(someIP + ":9244") if err != nil { t.Fatalf("Adding address failed: %v", err) } @@ -234,7 +234,7 @@ func TestConnected(t *testing.T) { n := addrmgr.New("testconnected", lookupFunc) // Add a new address and get it - err := n.AddAddressByIP(someIP + ":8333") + err := n.AddAddressByIP(someIP + ":9244") if err != nil { t.Fatalf("Adding address failed: %v", err) } @@ -261,14 +261,14 @@ func TestNeedMoreAddresses(t *testing.T) { var err error for i := 0; i < addrsToAdd; i++ { - s := fmt.Sprintf("%d.%d.173.147:8333", i/128+60, i%128+60) + s := fmt.Sprintf("%d.%d.173.147:9244", i/128+60, i%128+60) addrs[i], err = n.DeserializeNetAddress(s, wire.SFNodeNetwork) if err != nil { t.Errorf("Failed to turn %s into an address: %v", s, err) } } - srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0) + srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 9244, 0) n.AddAddresses(addrs, srcAddr) numAddrs := n.NumAddresses() @@ -289,14 +289,14 @@ func TestGood(t *testing.T) { var err error for i := 0; i < addrsToAdd; i++ { - s := fmt.Sprintf("%d.173.147.%d:8333", i/64+60, i%64+60) + s := fmt.Sprintf("%d.173.147.%d:9244", i/64+60, i%64+60) addrs[i], err = n.DeserializeNetAddress(s, wire.SFNodeNetwork) if err != nil { t.Errorf("Failed to turn %s into an address: %v", s, err) } } - srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0) + srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 9244, 0) n.AddAddresses(addrs, srcAddr) for _, addr := range addrs { @@ -323,7 +323,7 @@ func TestGetAddress(t *testing.T) { } // Add a new address and get it - err := n.AddAddressByIP(someIP + ":8333") + err := n.AddAddressByIP(someIP + ":9244") if err != nil { t.Fatalf("Adding address failed: %v", err) } diff --git a/addrmgr/network_test.go b/addrmgr/network_test.go index 6f2565fe..cb86a193 100644 --- a/addrmgr/network_test.go +++ b/addrmgr/network_test.go @@ -39,7 +39,7 @@ func TestIPTypes(t *testing.T) { rfc4193, rfc4380, rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598, local, valid, routable bool) ipTest { nip := net.ParseIP(ip) - na := *wire.NewNetAddressIPPort(nip, 8333, wire.SFNodeNetwork) + na := *wire.NewNetAddressIPPort(nip, 9246, wire.SFNodeNetwork) test := ipTest{na, rfc1918, rfc2544, rfc3849, rfc3927, rfc3964, rfc4193, rfc4380, rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598, local, valid, routable} return test @@ -192,7 +192,7 @@ func TestGroupKey(t *testing.T) { for i, test := range tests { nip := net.ParseIP(test.ip) - na := *wire.NewNetAddressIPPort(nip, 8333, wire.SFNodeNetwork) + na := *wire.NewNetAddressIPPort(nip, 9246, wire.SFNodeNetwork) if key := addrmgr.GroupKey(&na); key != test.expected { t.Errorf("TestGroupKey #%d (%s): unexpected group key "+ "- got '%s', want '%s'", i, test.name, diff --git a/chaincfg/params.go b/chaincfg/params.go index b2144963..1efb9b3d 100644 --- a/chaincfg/params.go +++ b/chaincfg/params.go @@ -62,7 +62,7 @@ var ( DefaultSignetDNSSeeds = []DNSSeed{ {"178.128.221.177", false}, {"2a01:7c8:d005:390::5", false}, - {"v7ajjeirttkbnt32wpy3c6w3emwnfr3fkla7hpxcfokr3ysd3kqtzmqd.onion:38333", false}, + {"v7ajjeirttkbnt32wpy3c6w3emwnfr3fkla7hpxcfokr3ysd3kqtzmqd.onion:39246", false}, } ) @@ -522,7 +522,7 @@ var TestNet3Params = Params{ var SimNetParams = Params{ Name: "simnet", Net: wire.SimNet, - DefaultPort: "18555", + DefaultPort: "39246", DNSSeeds: []DNSSeed{}, // NOTE: There must NOT be any seeds. // Chain parameters @@ -615,7 +615,7 @@ func CustomSignetParams(challenge []byte, dnsSeeds []DNSSeed) Params { return Params{ Name: "signet", Net: wire.BitcoinNet(net), - DefaultPort: "38333", + DefaultPort: "39246", DNSSeeds: dnsSeeds, // Chain parameters diff --git a/cmd/lbcctl/config.go b/cmd/lbcctl/config.go index e00cac77..ef961df9 100644 --- a/cmd/lbcctl/config.go +++ b/cmd/lbcctl/config.go @@ -96,20 +96,20 @@ type config struct { ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"` ListCommands bool `short:"l" long:"listcommands" description:"List all of the supported commands and exit"` NoTLS bool `long:"notls" description:"Disable TLS"` + TLSSkipVerify bool `long:"skipverify" description:"Do not verify tls certificates (not recommended!)"` Proxy string `long:"proxy" description:"Connect via SOCKS5 proxy (eg. 127.0.0.1:9050)"` ProxyPass string `long:"proxypass" default-mask:"-" description:"Password for proxy server"` ProxyUser string `long:"proxyuser" description:"Username for proxy server"` - RegressionTest bool `long:"regtest" description:"Connect to the regression test network"` RPCCert string `short:"c" long:"rpccert" description:"RPC server certificate chain for validation"` RPCPassword string `short:"P" long:"rpcpass" default-mask:"-" description:"RPC password"` RPCServer string `short:"s" long:"rpcserver" description:"RPC server to connect to"` RPCUser string `short:"u" long:"rpcuser" description:"RPC username"` - SimNet bool `long:"simnet" description:"Connect to the simulation test network"` - TLSSkipVerify bool `long:"skipverify" description:"Do not verify tls certificates (not recommended!)"` - TestNet3 bool `long:"testnet" description:"Connect to testnet"` - SigNet bool `long:"signet" description:"Connect to signet"` + TestNet3 bool `long:"testnet" description:"Connect to testnet (default RPC server: localhost:19245)"` + RegressionTest bool `long:"regtest" description:"Connect to the regression test network (default RPC server: localhost:29245)"` + SimNet bool `long:"simnet" description:"Connect to the simulation test network (default RPC server: localhost:39245)"` + SigNet bool `long:"signet" description:"Connect to signet (default RPC server: localhost:49245)"` + Wallet bool `long:"wallet" description:"Connect to wallet RPC server instead (default: localhost:9244, testnet: localhost:19244, regtest: localhost:29244)"` ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` - Wallet bool `long:"wallet" description:"Connect to wallet"` } // normalizeAddress returns addr with the passed default port appended if @@ -121,35 +121,33 @@ func normalizeAddress(addr string, chain *chaincfg.Params, useWallet bool) (stri switch chain { case &chaincfg.TestNet3Params: if useWallet { - defaultPort = "18332" + defaultPort = "19244" } else { - defaultPort = "18334" - } - case &chaincfg.SimNetParams: - if useWallet { - defaultPort = "18554" - } else { - defaultPort = "18556" + defaultPort = "19245" } case &chaincfg.RegressionNetParams: if useWallet { - // TODO: add port once regtest is supported in btcwallet - paramErr := fmt.Errorf("cannot use -wallet with -regtest, btcwallet not yet compatible with regtest") - return "", paramErr + defaultPort = "29244" } else { defaultPort = "29245" } + case &chaincfg.SimNetParams: + if useWallet { + defaultPort = "39244" + } else { + defaultPort = "39245" + } case &chaincfg.SigNetParams: if useWallet { - defaultPort = "38332" + defaultPort = "49244" } else { - defaultPort = "38332" + defaultPort = "49245" } default: if useWallet { - defaultPort = "8332" + defaultPort = "9244" } else { - defaultPort = "8334" + defaultPort = "9245" } } diff --git a/config.go b/config.go index b87fafb9..93e83e9b 100644 --- a/config.go +++ b/config.go @@ -125,7 +125,7 @@ type config struct { ExternalIPs []string `long:"externalip" description:"Add an ip to the list of local addresses we claim to listen on to peers"` Generate bool `long:"generate" description:"Generate (mine) bitcoins using the CPU"` FreeTxRelayLimit float64 `long:"limitfreerelay" description:"Limit relay of transactions with no transaction fee to the given amount in thousands of bytes per minute"` - Listeners []string `long:"listen" description:"Add an interface/port to listen for connections (default all interfaces port: 8333, testnet: 18333)"` + Listeners []string `long:"listen" description:"Add an interface/port to listen for connections (default all interfaces port: 9246, testnet: 19246, regtest: 29246)"` LogDir string `long:"logdir" description:"Directory to log output."` MaxOrphanTxs int `long:"maxorphantx" description:"Max number of orphan transactions to keep in memory"` MaxPeers int `long:"maxpeers" description:"Max number of inbound and outbound peers"` @@ -158,7 +158,7 @@ type config struct { RPCKey string `long:"rpckey" description:"File containing the certificate key"` RPCLimitPass string `long:"rpclimitpass" default-mask:"-" description:"Password for limited RPC connections"` RPCLimitUser string `long:"rpclimituser" description:"Username for limited RPC connections"` - RPCListeners []string `long:"rpclisten" description:"Add an interface/port to listen for RPC connections (default port: 8334, testnet: 18334)"` + RPCListeners []string `long:"rpclisten" description:"Add an interface/port to listen for RPC connections (default port: 9245, testnet: 19245, regtest: 29245)"` RPCMaxClients int `long:"rpcmaxclients" description:"Max number of RPC clients for standard connections"` RPCMaxConcurrentReqs int `long:"rpcmaxconcurrentreqs" description:"Max number of concurrent RPC requests that may be processed concurrently"` RPCMaxWebsockets int `long:"rpcmaxwebsockets" description:"Max number of RPC websocket connections"` diff --git a/connmgr/connmanager_test.go b/connmgr/connmanager_test.go index 94cb65ff..900dbc19 100644 --- a/connmgr/connmanager_test.go +++ b/connmgr/connmanager_test.go @@ -617,7 +617,7 @@ func TestListeners(t *testing.T) { // Setup a connection manager with a couple of mock listeners that // notify a channel when they receive mock connections. receivedConns := make(chan net.Conn) - listener1 := newMockListener("127.0.0.1:8333") + listener1 := newMockListener("127.0.0.1:9246") listener2 := newMockListener("127.0.0.1:9333") listeners := []net.Listener{listener1, listener2} cmgr, err := New(&Config{ diff --git a/docs/README.md b/docs/README.md deleted file mode 120000 index dd0ea36c..00000000 --- a/docs/README.md +++ /dev/null @@ -1 +0,0 @@ -index.md \ No newline at end of file diff --git a/params.go b/params.go index 664a7e6a..81fd18dd 100644 --- a/params.go +++ b/params.go @@ -28,7 +28,15 @@ type params struct { // to emulate the full reference implementation RPC API. var mainNetParams = params{ Params: &chaincfg.MainNetParams, - rpcPort: "8334", + rpcPort: "9245", +} + +// testNet3Params contains parameters specific to the test network (version 3) +// (wire.TestNet3). NOTE: The RPC port is intentionally different than the +// reference implementation - see the mainNetParams comment for details. +var testNet3Params = params{ + Params: &chaincfg.TestNet3Params, + rpcPort: "19245", } // regressionNetParams contains parameters specific to the regression test @@ -37,29 +45,21 @@ var mainNetParams = params{ // details. var regressionNetParams = params{ Params: &chaincfg.RegressionNetParams, - rpcPort: "18334", -} - -// testNet3Params contains parameters specific to the test network (version 3) -// (wire.TestNet3). NOTE: The RPC port is intentionally different than the -// reference implementation - see the mainNetParams comment for details. -var testNet3Params = params{ - Params: &chaincfg.TestNet3Params, - rpcPort: "18334", + rpcPort: "29245", } // simNetParams contains parameters specific to the simulation test network // (wire.SimNet). var simNetParams = params{ Params: &chaincfg.SimNetParams, - rpcPort: "18556", + rpcPort: "39245", } // sigNetParams contains parameters specific to the Signet network // (wire.SigNet). var sigNetParams = params{ Params: &chaincfg.SigNetParams, - rpcPort: "38332", + rpcPort: "49245", } // netName returns the name used when referring to a bitcoin network. At the diff --git a/peer/peer_test.go b/peer/peer_test.go index 4a2a0048..dcc0f257 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -290,13 +290,13 @@ func TestPeerConnection(t *testing.T) { "basic handshake", func() (*peer.Peer, *peer.Peer, error) { inConn, outConn := pipe( - &conn{raddr: "10.0.0.1:8333"}, - &conn{raddr: "10.0.0.2:8333"}, + &conn{raddr: "10.0.0.1:9246"}, + &conn{raddr: "10.0.0.2:9246"}, ) inPeer := peer.NewInboundPeer(peer1Cfg) inPeer.AssociateConnection(inConn) - outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:8333") + outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:9246") if err != nil { return nil, nil, err } @@ -316,13 +316,13 @@ func TestPeerConnection(t *testing.T) { "socks proxy", func() (*peer.Peer, *peer.Peer, error) { inConn, outConn := pipe( - &conn{raddr: "10.0.0.1:8333", proxy: true}, - &conn{raddr: "10.0.0.2:8333"}, + &conn{raddr: "10.0.0.1:9246", proxy: true}, + &conn{raddr: "10.0.0.2:9246"}, ) inPeer := peer.NewInboundPeer(peer1Cfg) inPeer.AssociateConnection(inConn) - outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:8333") + outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:9246") if err != nil { return nil, nil, err } @@ -457,8 +457,8 @@ func TestPeerListeners(t *testing.T) { AllowSelfConns: true, } inConn, outConn := pipe( - &conn{raddr: "10.0.0.1:8333"}, - &conn{raddr: "10.0.0.2:8333"}, + &conn{raddr: "10.0.0.1:9246"}, + &conn{raddr: "10.0.0.2:9246"}, ) inPeer := peer.NewInboundPeer(peerCfg) inPeer.AssociateConnection(inConn) @@ -468,7 +468,7 @@ func TestPeerListeners(t *testing.T) { verack <- struct{}{} }, } - outPeer, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + outPeer, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Errorf("NewOutboundPeer: unexpected err %v\n", err) return @@ -630,9 +630,9 @@ func TestOutboundPeer(t *testing.T) { } r, w := io.Pipe() - c := &conn{raddr: "10.0.0.1:8333", Writer: w, Reader: r} + c := &conn{raddr: "10.0.0.1:9246", Writer: w, Reader: r} - p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return @@ -687,8 +687,8 @@ func TestOutboundPeer(t *testing.T) { peerCfg.NewestBlock = newestBlock r1, w1 := io.Pipe() - c1 := &conn{raddr: "10.0.0.1:8333", Writer: w1, Reader: r1} - p1, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + c1 := &conn{raddr: "10.0.0.1:9246", Writer: w1, Reader: r1} + p1, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return @@ -717,8 +717,8 @@ func TestOutboundPeer(t *testing.T) { peerCfg.ChainParams = &chaincfg.RegressionNetParams peerCfg.Services = wire.SFNodeBloom r2, w2 := io.Pipe() - c2 := &conn{raddr: "10.0.0.1:8333", Writer: w2, Reader: r2} - p2, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + c2 := &conn{raddr: "10.0.0.1:9246", Writer: w2, Reader: r2} + p2, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return @@ -773,20 +773,20 @@ func TestUnsupportedVersionPeer(t *testing.T) { localNA := wire.NewNetAddressIPPort( net.ParseIP("10.0.0.1"), - uint16(8333), + uint16(9246), wire.SFNodeNetwork, ) remoteNA := wire.NewNetAddressIPPort( net.ParseIP("10.0.0.2"), - uint16(8333), + uint16(9246), wire.SFNodeNetwork, ) localConn, remoteConn := pipe( - &conn{laddr: "10.0.0.1:8333", raddr: "10.0.0.2:8333"}, - &conn{laddr: "10.0.0.2:8333", raddr: "10.0.0.1:8333"}, + &conn{laddr: "10.0.0.1:9246", raddr: "10.0.0.2:9246"}, + &conn{laddr: "10.0.0.2:9246", raddr: "10.0.0.1:9246"}, ) - p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") + p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:9246") if err != nil { t.Fatalf("NewOutboundPeer: unexpected err - %v\n", err) } diff --git a/rpcclient/example_test.go b/rpcclient/example_test.go index f044e9f1..f617e6ce 100644 --- a/rpcclient/example_test.go +++ b/rpcclient/example_test.go @@ -11,7 +11,7 @@ import ( ) var connCfg = &ConnConfig{ - Host: "localhost:8332", + Host: "localhost:9244", User: "user", Pass: "pass", HTTPPostMode: true, diff --git a/rpcclient/examples/bitcoincorehttp/main.go b/rpcclient/examples/bitcoincorehttp/main.go index 54e727de..eba2fcb4 100644 --- a/rpcclient/examples/bitcoincorehttp/main.go +++ b/rpcclient/examples/bitcoincorehttp/main.go @@ -13,7 +13,7 @@ import ( func main() { // Connect to local bitcoin core RPC server using HTTP POST mode. connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8332", + Host: "localhost:9245", User: "yourrpcuser", Pass: "yourrpcpass", HTTPPostMode: true, // Bitcoin core only supports HTTP POST mode diff --git a/rpcclient/examples/bitcoincorehttpbulk/main.go b/rpcclient/examples/bitcoincorehttpbulk/main.go index fd21ede4..36b12e5d 100644 --- a/rpcclient/examples/bitcoincorehttpbulk/main.go +++ b/rpcclient/examples/bitcoincorehttpbulk/main.go @@ -14,7 +14,7 @@ import ( func main() { // Connect to local bitcoin core RPC server using HTTP POST mode. connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8332", + Host: "localhost:9245", User: "yourrpcuser", Pass: "yourrpcpass", DisableConnectOnNew: true, diff --git a/rpcclient/examples/btcdwebsockets/main.go b/rpcclient/examples/btcdwebsockets/main.go index 30bb4188..1a12da9e 100644 --- a/rpcclient/examples/btcdwebsockets/main.go +++ b/rpcclient/examples/btcdwebsockets/main.go @@ -38,7 +38,7 @@ func main() { log.Fatal(err) } connCfg := &rpcclient.ConnConfig{ - Host: "localhost:8334", + Host: "localhost:9245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", diff --git a/rpcclient/examples/btcwalletwebsockets/main.go b/rpcclient/examples/btcwalletwebsockets/main.go index b0bc6f83..f506f3d3 100644 --- a/rpcclient/examples/btcwalletwebsockets/main.go +++ b/rpcclient/examples/btcwalletwebsockets/main.go @@ -34,7 +34,7 @@ func main() { log.Fatal(err) } connCfg := &rpcclient.ConnConfig{ - Host: "localhost:18332", + Host: "localhost:19245", Endpoint: "ws", User: "yourrpcuser", Pass: "yourrpcpass", diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index df928969..784f0688 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -2792,7 +2792,7 @@ func (c *Client) UnloadWalletAsync(walletName *string) FutureUnloadWalletResult } // UnloadWallet unloads the referenced wallet. If the RPC server URL already -// contains the name of the wallet, like http://127.0.0.1:8332/wallet/, +// contains the name of the wallet, like http://127.0.0.1:9245/wallet/, // the parameter must be nil, or it'll return an error. func (c *Client) UnloadWallet(walletName *string) error { return c.UnloadWalletAsync(walletName).Receive() diff --git a/sample-lbcd.conf b/sample-lbcd.conf index a3970d95..2a84c797 100644 --- a/sample-lbcd.conf +++ b/sample-lbcd.conf @@ -211,16 +211,16 @@ ; rpclisten=0.0.0.0 ; All ipv6 interfaces on default port: ; rpclisten=:: -; All interfaces on port 8334: -; rpclisten=:8334 -; All ipv4 interfaces on port 8334: -; rpclisten=0.0.0.0:8334 -; All ipv6 interfaces on port 8334: -; rpclisten=[::]:8334 -; Only ipv4 localhost on port 8334: -; rpclisten=127.0.0.1:8334 -; Only ipv6 localhost on port 8334: -; rpclisten=[::1]:8334 +; All interfaces on port 9245: +; rpclisten=:9245 +; All ipv4 interfaces on port 9245: +; rpclisten=0.0.0.0:9245 +; All ipv6 interfaces on port 9245: +; rpclisten=[::]:9245 +; Only ipv4 localhost on port 9245: +; rpclisten=127.0.0.1:9245 +; Only ipv6 localhost on port 9245: +; rpclisten=[::1]:9245 ; Only ipv4 localhost on non-standard port 8337: ; rpclisten=127.0.0.1:8337 ; All interfaces on non-standard port 8337: diff --git a/wire/message_test.go b/wire/message_test.go index 65754b41..2ec5d8d1 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -40,10 +40,10 @@ func TestMessage(t *testing.T) { // Create the various types of messages to test. // MsgVersion. - addrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 8333} + addrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 9246} you := NewNetAddress(addrYou, SFNodeNetwork) you.Timestamp = time.Time{} // Version message has zero value timestamp. - addrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333} + addrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 9246} me := NewNetAddress(addrMe, SFNodeNetwork) me.Timestamp = time.Time{} // Version message has zero value timestamp. msgVersion := NewMsgVersion(me, you, 123123, 0) diff --git a/wire/msgaddr_test.go b/wire/msgaddr_test.go index 7516d324..a823b812 100644 --- a/wire/msgaddr_test.go +++ b/wire/msgaddr_test.go @@ -38,7 +38,7 @@ func TestAddr(t *testing.T) { } // Ensure NetAddresses are added properly. - tcpAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333} + tcpAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 9246} na := NewNetAddress(tcpAddr, SFNodeNetwork) err := msg.AddAddress(na) if err != nil { @@ -105,7 +105,7 @@ func TestAddrWire(t *testing.T) { Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } na2 := &NetAddress{ Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST @@ -129,7 +129,7 @@ func TestAddrWire(t *testing.T) { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian 0x29, 0xab, 0x5f, 0x49, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -216,7 +216,7 @@ func TestAddrWireErrors(t *testing.T) { Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } na2 := &NetAddress{ Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST @@ -234,7 +234,7 @@ func TestAddrWireErrors(t *testing.T) { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian 0x29, 0xab, 0x5f, 0x49, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/wire/msgversion_test.go b/wire/msgversion_test.go index dc2b6e09..f5166e23 100644 --- a/wire/msgversion_test.go +++ b/wire/msgversion_test.go @@ -22,9 +22,9 @@ func TestVersion(t *testing.T) { // Create version message data. lastBlock := int32(234234) - tcpAddrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333} + tcpAddrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 9246} me := NewNetAddress(tcpAddrMe, SFNodeNetwork) - tcpAddrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 8333} + tcpAddrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 9246} you := NewNetAddress(tcpAddrYou, SFNodeNetwork) nonce, err := RandomUint64() if err != nil { @@ -377,7 +377,7 @@ func TestVersionOptionalFields(t *testing.T) { Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("192.168.0.1"), - Port: 8333, + Port: 9246, }, } onlyRequiredVersionEncoded := make([]byte, len(baseVersionEncoded)-55) @@ -390,7 +390,7 @@ func TestVersionOptionalFields(t *testing.T) { Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } addrMeVersionEncoded := make([]byte, len(baseVersionEncoded)-29) copy(addrMeVersionEncoded, baseVersionEncoded) @@ -480,13 +480,13 @@ var baseVersion = &MsgVersion{ Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("192.168.0.1"), - Port: 8333, + Port: 9246, }, AddrMe: NetAddress{ Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, }, Nonce: 123123, // 0x1e0f3 UserAgent: "/btcdtest:0.0.1/", @@ -503,12 +503,12 @@ var baseVersionEncoded = []byte{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian // AddrMe -- No timestamp for NetAddress in version message 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian 0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce 0x10, // Varint for user agent length 0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73, @@ -526,13 +526,13 @@ var baseVersionBIP0037 = &MsgVersion{ Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("192.168.0.1"), - Port: 8333, + Port: 9246, }, AddrMe: NetAddress{ Timestamp: time.Time{}, // Zero value -- no timestamp in version Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, }, Nonce: 123123, // 0x1e0f3 UserAgent: "/btcdtest:0.0.1/", @@ -549,12 +549,12 @@ var baseVersionBIP0037Encoded = []byte{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian // AddrMe -- No timestamp for NetAddress in version message 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian 0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce 0x10, // Varint for user agent length 0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73, diff --git a/wire/netaddress_test.go b/wire/netaddress_test.go index 128a7fbc..3d1bf809 100644 --- a/wire/netaddress_test.go +++ b/wire/netaddress_test.go @@ -18,7 +18,7 @@ import ( // TestNetAddress tests the NetAddress API. func TestNetAddress(t *testing.T) { ip := net.ParseIP("127.0.0.1") - port := 8333 + port := 9246 // Test NewNetAddress. na := NewNetAddress(&net.TCPAddr{IP: ip, Port: port}, 0) @@ -79,7 +79,7 @@ func TestNetAddressWire(t *testing.T) { Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } // baseNetAddrNoTS is baseNetAddr with a zero value for the timestamp. @@ -92,7 +92,7 @@ func TestNetAddressWire(t *testing.T) { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian } // baseNetAddrNoTSEncoded is the wire encoded bytes of baseNetAddrNoTS. @@ -101,7 +101,7 @@ func TestNetAddressWire(t *testing.T) { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 - 0x20, 0x8d, // Port 8333 in big-endian + 0x24, 0x1e, // Port 9246 in big-endian } tests := []struct { @@ -211,7 +211,7 @@ func TestNetAddressWireErrors(t *testing.T) { Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), - Port: 8333, + Port: 9246, } tests := []struct { -- 2.45.2 From 239d681f288dbaec4bff4ad463b4f129d5693998 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Fri, 10 Dec 2021 11:06:55 -0500 Subject: [PATCH 386/459] [lbry] contrib: add linode deployment using docker --- contrib/linode/Dockerfile.deploy | 38 ++++++++++++++ contrib/linode/docker-compose.yml | 19 +++++++ contrib/linode/lbcd_stack_script.sh | 79 +++++++++++++++++++++++++++++ contrib/linode/run.sh | 2 + 4 files changed, 138 insertions(+) create mode 100644 contrib/linode/Dockerfile.deploy create mode 100644 contrib/linode/docker-compose.yml create mode 100644 contrib/linode/lbcd_stack_script.sh create mode 100755 contrib/linode/run.sh diff --git a/contrib/linode/Dockerfile.deploy b/contrib/linode/Dockerfile.deploy new file mode 100644 index 00000000..b9440234 --- /dev/null +++ b/contrib/linode/Dockerfile.deploy @@ -0,0 +1,38 @@ +# This Dockerfile builds btcd from source and creates a small (55 MB) docker container based on alpine linux. +# +# Clone this repository and run the following command to build and tag a fresh btcd amd64 container: +# +# docker build . -t yourregistry/btcd +# +# You can use the following command to buid an arm64v8 container: +# +# docker build . -t yourregistry/btcd --build-arg ARCH=arm64v8 +# +# For more information how to use this docker image visit: +# https://github.com/lbryio/lbcd/tree/master/docs +# +# 9246 Mainnet Bitcoin peer-to-peer port +# 9245 Mainet RPC port + +FROM golang AS build-container + +# ENV GO111MODULE=on + +ADD . /app +WORKDIR /app +RUN set -ex \ + && if [ "${ARCH}" = "amd64" ]; then export GOARCH=amd64; fi \ + && if [ "${ARCH}" = "arm64v8" ]; then export GOARCH=arm64; fi \ + && echo "Compiling for $GOARCH" \ + && CGO_ENABLED=0 go build . + +FROM debian:11-slim + +COPY --from=build-container /app/lbcd / +COPY --from=build-container /app/contrib/linode/run.sh / + +VOLUME ["/root/.lbcd"] + +EXPOSE 9245 9246 + +ENTRYPOINT ["/run.sh"] diff --git a/contrib/linode/docker-compose.yml b/contrib/linode/docker-compose.yml new file mode 100644 index 00000000..23b396d3 --- /dev/null +++ b/contrib/linode/docker-compose.yml @@ -0,0 +1,19 @@ +version: "3" + +volumes: + lbcd: + external: true + +services: + lbcd: + image: lbry/lbcd:linode_deployment + container_name: lbcd + ulimits: + memlock: + soft: -1 + hard: -1 + volumes: + - lbcd:/root/.lbcd:rw + ports: + - "REPLACE_ME:9245:9245" + - "9246:9246" diff --git a/contrib/linode/lbcd_stack_script.sh b/contrib/linode/lbcd_stack_script.sh new file mode 100644 index 00000000..8348d144 --- /dev/null +++ b/contrib/linode/lbcd_stack_script.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# +# +# +# +# +# +# +# + +source + +# For debugging +exec > >(tee -i /var/log/stackscript.log) 2>&1 +set -xeo pipefail + +function user_add_sudo { + USERNAME="$1" + USERPASS="$2" + if [ ! -n "$USERNAME" ] || [ ! -n "$USERPASS" ]; then + echo "No new username and/or password entered" + return 1; + fi + adduser "$USERNAME" --disabled-password --gecos "" + echo "$USERNAME:$USERPASS" | chpasswd + apt-get install -y sudo + usermod -aG sudo "$USERNAME" +} + +function download_snapshot { + if [ -z "${AWS_ACCESS_KEY_ID}" ]; then + wget "${SNAPSHOT_URL}" + else + echo "[default] + access_key = ${AWS_ACCESS_KEY_ID} + secret_key = ${AWS_SECRET_ACCESS_KEY}" > ~/.s3cfg + if [ -z "${ENDPOINT_URL}" ]; then + s4cmd --verbose get "${SNAPSHOT_URL}" + else + s4cmd --verbose get "${SNAPSHOT_URL}" --endpoint-url "${ENDPOINT_URL}" + fi + fi +} + +function download_and_start { + download_snapshot + # get the snapshot data into place + SNAPSHOT_FILE_NAME=$(echo "${SNAPSHOT_URL}" | rev | cut -d/ -f1 | rev) + unzip "${SNAPSHOT_FILE_NAME}" -d ~/.lbcd/ + mv ~/.lbcd/"${SNAPSHOT_FILE_NAME}" ~/.lbcd/data + rm "${SNAPSHOT_FILE_NAME}" + # get our private ip + PRIVATE_IP=$(ip addr | grep "${PRIVATE_IP_PREFIX}" | cut -d'/' -f1 | rev | cut -d" " -f 1 | rev) + # download the compose-compose and put our private ip in the for RPC endpoint + wget "${DOCKER_COMPOSE_FILE_URL}" -O - | sed 's/REPLACE_ME/'"${PRIVATE_IP}"'/g' > docker-compose.yml + # Create our volume and start lbcd + docker volume create --driver local \ + --opt type=none \ + --opt device=~/.lbcd\ + --opt o=bind lbcd + docker-compose up -d +} +# add a non-root sudo user +user_add_sudo "${USERNAME}" "${PASSWORD}" +# Update and install dependencies +sudo apt-get update && sudo apt-get upgrade -y +sudo apt-get install -y unzip wget s4cmd +apt install -y apt-transport-https ca-certificates curl software-properties-common && \ + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \ + add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \ + apt install -y docker-ce docker-ce-cli containerd.io && \ + systemctl enable docker && sudo systemctl start docker && \ + curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \ + chmod +x /usr/local/bin/docker-compose +# make sure we can use docker +usermod -aG docker $USERNAME +export -f download_and_start +export -f download_snapshot +su "${USERNAME}" -c 'bash -c "cd ~ && download_and_start"' \ No newline at end of file diff --git a/contrib/linode/run.sh b/contrib/linode/run.sh new file mode 100755 index 00000000..2966339c --- /dev/null +++ b/contrib/linode/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +/lbcd --txindex --notls --rpcuser=lbry --rpcpass=lbry --rpclisten= -- 2.45.2 From a7f971f404bb1f5941e4ae1cd084ff81404d7c97 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 23 Jan 2022 23:06:30 -0800 Subject: [PATCH 387/459] [lbry] rpc: update getrawtransaction to take verbose as boolean --- btcjson/chainsvrcmds.go | 4 ++-- btcjson/chainsvrcmds_test.go | 10 +++++----- docs/json_rpc_api.md | 2 +- rpcclient/rawtransactions.go | 4 ++-- rpcserver.go | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index 0cfb2e17..95993dac 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -650,7 +650,7 @@ func NewGetRawMempoolCmd(verbose *bool) *GetRawMempoolCmd { // Core even though it really should be a bool. type GetRawTransactionCmd struct { Txid string - Verbose *int `jsonrpcdefault:"0"` + Verbose *bool `jsonrpcdefault:"false"` } // NewGetRawTransactionCmd returns a new instance which can be used to issue a @@ -658,7 +658,7 @@ type GetRawTransactionCmd struct { // // The parameters which are pointers indicate they are optional. Passing nil // for optional parameters will use the default value. -func NewGetRawTransactionCmd(txHash string, verbose *int) *GetRawTransactionCmd { +func NewGetRawTransactionCmd(txHash string, verbose *bool) *GetRawTransactionCmd { return &GetRawTransactionCmd{ Txid: txHash, Verbose: verbose, diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index 95320dbd..824e87d7 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -872,21 +872,21 @@ func TestChainSvrCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123"],"id":1}`, unmarshalled: &btcjson.GetRawTransactionCmd{ Txid: "123", - Verbose: btcjson.Int(0), + Verbose: btcjson.Bool(false), }, }, { name: "getrawtransaction optional", newCmd: func() (interface{}, error) { - return btcjson.NewCmd("getrawtransaction", "123", 1) + return btcjson.NewCmd("getrawtransaction", "123", true) }, staticCmd: func() interface{} { - return btcjson.NewGetRawTransactionCmd("123", btcjson.Int(1)) + return btcjson.NewGetRawTransactionCmd("123", btcjson.Bool(true)) }, - marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123",1],"id":1}`, + marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123",true],"id":1}`, unmarshalled: &btcjson.GetRawTransactionCmd{ Txid: "123", - Verbose: btcjson.Int(1), + Verbose: btcjson.Bool(true), }, }, { diff --git a/docs/json_rpc_api.md b/docs/json_rpc_api.md index 17ccba64..195b227c 100644 --- a/docs/json_rpc_api.md +++ b/docs/json_rpc_api.md @@ -436,7 +436,7 @@ the method name for further details such as parameter and return information. | | | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Method | getrawtransaction | -| Parameters | 1. transaction hash (string, required) - the hash of the transaction
2. verbose (int, optional, default=0) - specifies the transaction is returned as a JSON object instead of hex-encoded string | +| Parameters | 1. transaction hash (string, required) - the hash of the transaction
2. verbose (bool, optional, default=false) - specifies the transaction is returned as a JSON object instead of hex-encoded string | | Description | Returns information about a transaction given its hash. | | Returns (verbose=0) | `"data" (string) hex-encoded bytes of the serialized transaction` | | Returns (verbose=1) | `{ (json object)`
  `"hex": "data", (string) hex-encoded transaction`
  `"txid": "hash", (string) the hash of the transaction`
  `"version": n, (numeric) the transaction version`
  `"locktime": n, (numeric) the transaction lock time`
  `"vin": [ (array of json objects) the transaction inputs as json objects`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "data", (string) the hex-encoded bytes of the signature script`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}`
  For non-coinbase transactions:
    `{ (json object)`
      `"txid": "hash", (string) the hash of the origin transaction`
      `"vout": n, (numeric) the index of the output being redeemed from the origin transaction`
      `"scriptSig": { (json object) the signature script used to redeem the origin transaction`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
      `}`
      `"sequence": n, (numeric) the script sequence number`
    `"txinwitness": “data", (string) the witness stack for the input`
    `}, ...`
  `]`
  `"vout": [ (array of json objects) the transaction outputs as json objects`
    `{ (json object)`
      `"value": n, (numeric) the value in BTC`
      `"n": n, (numeric) the index of this transaction output`
      `"scriptPubKey": { (json object) the public key script used to pay coins`
        `"asm": "asm", (string) disassembly of the script`
        `"hex": "data", (string) hex-encoded bytes of the script`
        `"reqSigs": n, (numeric) the number of required signatures`
        `"type": "scripttype" (string) the type of the script (e.g. 'pubkeyhash')`
        `"addresses": [ (json array of string) the bitcoin addresses associated with this output`
          `"bitcoinaddress", (string) the bitcoin address`
          `...`
        `]`
      `}`
    `}, ...`
  `]`
`}` | diff --git a/rpcclient/rawtransactions.go b/rpcclient/rawtransactions.go index 3512ccb7..e4402f1d 100644 --- a/rpcclient/rawtransactions.go +++ b/rpcclient/rawtransactions.go @@ -108,7 +108,7 @@ func (c *Client) GetRawTransactionAsync(txHash *chainhash.Hash) FutureGetRawTran hash = txHash.String() } - cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(0)) + cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Bool(false)) return c.SendCmd(cmd) } @@ -154,7 +154,7 @@ func (c *Client) GetRawTransactionVerboseAsync(txHash *chainhash.Hash) FutureGet hash = txHash.String() } - cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(1)) + cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Bool(true)) return c.SendCmd(cmd) } diff --git a/rpcserver.go b/rpcserver.go index 91ddf64e..9dd42a70 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -2782,7 +2782,7 @@ func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan str verbose := false if c.Verbose != nil { - verbose = *c.Verbose != 0 + verbose = *c.Verbose } // Try to fetch the transaction from the memory pool and if that fails, -- 2.45.2 From d99883a62046d8bb370b2d62877ffd971093adbc Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 10 Feb 2022 14:47:25 -0800 Subject: [PATCH 388/459] [lbry] btcjson: take integers for boolean parameters. This is for backward compatibility with lbrycrd/bitcoind where some clients use intger values (0/1) for boolean. --- btcjson/cmdparse.go | 10 +++++ btcjson/cmdparse_test.go | 83 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/btcjson/cmdparse.go b/btcjson/cmdparse.go index 4fb8dd62..c0190bf3 100644 --- a/btcjson/cmdparse.go +++ b/btcjson/cmdparse.go @@ -134,6 +134,16 @@ func UnmarshalCmd(r *Request) (interface{}, error) { // Unmarshal the parameter into the struct field. concreteVal := rvf.Addr().Interface() if err := json.Unmarshal(r.Params[i], &concreteVal); err != nil { + // Parse Integer into Bool for compatibility with lbrycrd. + if rvf.Kind() == reflect.Ptr && + rvf.Elem().Type().Kind() == reflect.Bool { + boolInt, errBoolInt := strconv.Atoi(string(r.Params[i])) + if errBoolInt == nil { + rvf.Elem().SetBool(boolInt != 0) + continue + } + } + // The most common error is the wrong type, so // explicitly detect that error and make it nicer. fieldName := strings.ToLower(rt.Field(i).Name) diff --git a/btcjson/cmdparse_test.go b/btcjson/cmdparse_test.go index c1414c64..0da6442c 100644 --- a/btcjson/cmdparse_test.go +++ b/btcjson/cmdparse_test.go @@ -557,7 +557,7 @@ func TestUnmarshalCmdErrors(t *testing.T) { request: btcjson.Request{ Jsonrpc: btcjson.RpcVersion1, Method: "getblock", - Params: []json.RawMessage{[]byte("1")}, + Params: []json.RawMessage{[]byte("1.0")}, ID: nil, }, err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType}, @@ -591,3 +591,84 @@ func TestUnmarshalCmdErrors(t *testing.T) { } } } + +// TestUnmarshalCmdBoolParams tests the parsing of boolean paramers of the UnmarshalCmd function. +func TestUnmarshalCmdBoolParams(t *testing.T) { + t.Parallel() + + txid := []byte(`"ab91c149aff2b37a4a1856e9935ea623c973f47886d032ed7511ad8ca37855bb"`) + tests := []struct { + name string + request btcjson.Request + expect bool + }{ + { + name: "parse true", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("true")}, + ID: nil, + }, + expect: true, + }, + { + name: "parse false", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("false")}, + ID: nil, + }, + expect: false, + }, + { + name: "parse integer 0 to false", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("0")}, + ID: nil, + }, + expect: false, + }, + { + name: "parse integer 1 to true", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("1")}, + ID: nil, + }, + expect: true, + }, + { + name: "parse integer 100 to true", + request: btcjson.Request{ + Jsonrpc: btcjson.RpcVersion1, + Method: "getrawtransaction", + Params: []json.RawMessage{txid, []byte("100")}, + ID: nil, + }, + expect: true, + }, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + cmd, err := btcjson.UnmarshalCmd(&test.request) + if err != nil { + t.Errorf("Test #%d (%s) error - got %T (%v)", i, test.name, + err, err) + continue + } + cc := cmd.(*btcjson.GetRawTransactionCmd) + verbose := *cc.Verbose + if verbose != test.expect { + t.Errorf("Test #%d (%s) got %t, want %v", i, test.name, + verbose, test.expect) + continue + } + + } +} -- 2.45.2 From 324c443c6427c1ae7c7848c98ef39c1f4e7e9aff Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 26 Jan 2022 20:11:56 -0800 Subject: [PATCH 389/459] [lbry] fees: initial import from DCRD vendored https://github.com/decred/dcrd/tree/master/internal/fees Commit of the last modification commit a6e205b88fbb44f7ee85be25a81f4dad155670d8 Author: Dave Collins Date: Sat Dec 26 12:17:48 2020 -0600 fees: Remove deprecated DisableLog. --- fees/README.md | 23 + fees/cmd/dumpfeedb/dumpfeedb.go | 52 ++ fees/doc.go | 107 ++++ fees/estimator.go | 920 ++++++++++++++++++++++++++++++++ fees/log.go | 21 + 5 files changed, 1123 insertions(+) create mode 100644 fees/README.md create mode 100644 fees/cmd/dumpfeedb/dumpfeedb.go create mode 100644 fees/doc.go create mode 100644 fees/estimator.go create mode 100644 fees/log.go diff --git a/fees/README.md b/fees/README.md new file mode 100644 index 00000000..03b85696 --- /dev/null +++ b/fees/README.md @@ -0,0 +1,23 @@ +fees +==== + + +[![Build Status](https://github.com/decred/dcrd/workflows/Build%20and%20Test/badge.svg)](https://github.com/decred/dcrd/actions) +[![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![Doc](https://img.shields.io/badge/doc-reference-blue.svg)](https://pkg.go.dev/github.com/decred/dcrd/internal/fees) + +Package fees provides decred-specific methods for tracking and estimating fee +rates for new transactions to be mined into the network. Fee rate estimation has +two main goals: + +- Ensuring transactions are mined within a target _confirmation range_ + (expressed in blocks); +- Attempting to minimize fees while maintaining be above restriction. + +This package was started in order to resolve issue decred/dcrd#1412 and related. +See that issue for discussion of the selected approach. + +## License + +Package dcrutil is licensed under the [copyfree](http://copyfree.org) ISC +License. diff --git a/fees/cmd/dumpfeedb/dumpfeedb.go b/fees/cmd/dumpfeedb/dumpfeedb.go new file mode 100644 index 00000000..38e2492a --- /dev/null +++ b/fees/cmd/dumpfeedb/dumpfeedb.go @@ -0,0 +1,52 @@ +// Copyright (c) 2018-2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +// Tool dumpfeedb can be used to dump the internal state of the buckets of an +// estimator's feedb so that it can be externally analyzed. +package main + +import ( + "errors" + "fmt" + "os" + "path" + + "github.com/decred/dcrd/dcrutil/v4" + "github.com/decred/dcrd/internal/fees" + flags "github.com/jessevdk/go-flags" +) + +type config struct { + DB string `short:"b" long:"db" description:"Path to fee database"` +} + +func main() { + cfg := config{ + DB: path.Join(dcrutil.AppDataDir("dcrd", false), "data", "mainnet", "feesdb"), + } + + parser := flags.NewParser(&cfg, flags.Default) + _, err := parser.Parse() + if err != nil { + var e *flags.Error + if !errors.As(err, &e) || e.Type != flags.ErrHelp { + parser.WriteHelp(os.Stderr) + } + return + } + + ecfg := fees.EstimatorConfig{ + DatabaseFile: cfg.DB, + ReplaceBucketsOnLoad: true, + MinBucketFee: 1, + MaxBucketFee: 2, + FeeRateStep: fees.DefaultFeeRateStep, + } + est, err := fees.NewEstimator(&ecfg) + if err != nil { + panic(err) + } + + fmt.Println(est.DumpBuckets()) +} diff --git a/fees/doc.go b/fees/doc.go new file mode 100644 index 00000000..77419317 --- /dev/null +++ b/fees/doc.go @@ -0,0 +1,107 @@ +// Copyright (c) 2018-2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +Package fees provides decred-specific methods for tracking and estimating fee +rates for new transactions to be mined into the network. Fee rate estimation has +two main goals: + +- Ensuring transactions are mined within a target _confirmation range_ + (expressed in blocks); +- Attempting to minimize fees while maintaining be above restriction. + +Preliminaries + +There are two main regimes against which fee estimation needs to be evaluated +according to how full blocks being mined are (and consequently how important fee +rates are): _low contention_ and _high contention_: + +In a low contention regime, the mempool sits mostly empty, transactions are +usually mined very soon after being published and transaction fees are mostly +sent using the minimum relay fee. + +In a high contention regime, the mempool is usually filled with unmined +transactions, there is active dispute for space in a block (by transactions +using higher fees) and blocks are usually full. + +The exact point of where these two regimes intersect is arbitrary, but it should +be clear in the examples and simulations which of these is being discussed. + +Note: a very high contention scenario (> 90% of blocks being full and +transactions remaining in the mempool indefinitely) is one in which stakeholders +should be discussing alternative solutions (increase block size, provide other +second layer alternatives, etc). Also, the current fill rate of blocks in decred +is low, so while we try to account for this regime, I personally expect that the +implementation will need more tweaks as it approaches this. + +The current approach to implement this estimation is based on bitcoin core's +algorithm. References [1] and [2] provide a high level description of how it +works there. Actual code is linked in references [3] and [4]. + +Outline of the Algorithm + +The algorithm is currently based in fee estimation as used in v0.14 of bitcoin +core (which is also the basis for the v0.15+ method). A more comprehensive +overview is available in reference [1]. + +This particular version was chosen because it's simpler to implement and should +be sufficient for low contention regimes. It probably overestimates fees in +higher contention regimes and longer target confirmation windows, but as pointed +out earlier should be sufficient for current fill rate of decred's network. + +The basic algorithm is as follows (as executed by a single full node): + +Stats building stage: + +- For each transaction observed entering mempool, record the block at which it + was first seen +- For each mined transaction which was previously observed to enter the mempool, + record how long (in blocks) it took to be mined and its fee rate +- Group mined transactions into fee rate _buckets_ and _confirmation ranges_, + creating a table of how many transactions were mined at each confirmation + range and fee rate bucket and their total committed fee +- Whenever a new block is mined, decay older transactions to account for a + dynamic fee environment + +Estimation stage: + +- Input a target confirmation range (how many blocks to wait for the tx to be + mined) +- Starting at the highest fee bucket, look for buckets where the chance of + confirmation within the desired confirmation window is > 95% +- Average all such buckets to get the estimated fee rate + +Simulation + +Development of the estimator was originally performed and simulated using the +code in [5]. Simulation of the current code can be performed by using the +dcrfeesim tool available in [6]. + +Acknowledgements + +Thanks to @davecgh for providing the initial review of the results and the +original developers of the bitcoin core code (the brunt of which seems to have +been made by @morcos). + +## References + +[1] Introduction to Bitcoin Core Estimation: +https://bitcointechtalk.com/an-introduction-to-bitcoin-core-fee-estimation-27920880ad0 + +[2] Proposed Changes to Fee Estimation in version 0.15: +https://gist.github.com/morcos/d3637f015bc4e607e1fd10d8351e9f41 + +[3] Source for fee estimation in v0.14: +https://github.com/bitcoin/bitcoin/blob/v0.14.2/src/policy/fees.cpp + +[4] Source for fee estimation in version 0.16.2: +https://github.com/bitcoin/bitcoin/blob/v0.16.2/src/policy/fees.cpp + +[5] Source for the original dcrfeesim and estimator work: +https://github.com/matheusd/dcrfeesim_dev + +[6] Source for the current dcrfeesim, using this module: +https://github.com/matheusd/dcrfeesim +*/ +package fees diff --git a/fees/estimator.go b/fees/estimator.go new file mode 100644 index 00000000..d98f037f --- /dev/null +++ b/fees/estimator.go @@ -0,0 +1,920 @@ +// Copyright (c) 2018-2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package fees + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "math" + "sort" + "sync" + + "github.com/decred/dcrd/blockchain/stake/v4" + "github.com/decred/dcrd/chaincfg/chainhash" + "github.com/decred/dcrd/dcrutil/v4" + "github.com/syndtr/goleveldb/leveldb" + ldbutil "github.com/syndtr/goleveldb/leveldb/util" +) + +const ( + // DefaultMaxBucketFeeMultiplier is the default multiplier used to find the + // largest fee bucket, starting at the minimum fee. + DefaultMaxBucketFeeMultiplier int = 100 + + // DefaultMaxConfirmations is the default number of confirmation ranges to + // track in the estimator. + DefaultMaxConfirmations uint32 = 32 + + // DefaultFeeRateStep is the default multiplier between two consecutive fee + // rate buckets. + DefaultFeeRateStep float64 = 1.1 + + // defaultDecay is the default value used to decay old transactions from the + // estimator. + defaultDecay float64 = 0.998 + + // maxAllowedBucketFees is an upper bound of how many bucket fees can be + // used in the estimator. This is verified during estimator initialization + // and database loading. + maxAllowedBucketFees = 2000 + + // maxAllowedConfirms is an upper bound of how many confirmation ranges can + // be used in the estimator. This is verified during estimator + // initialization and database loading. + maxAllowedConfirms = 788 +) + +var ( + // ErrNoSuccessPctBucketFound is the error returned when no bucket has been + // found with the minimum required percentage success. + ErrNoSuccessPctBucketFound = errors.New("no bucket with the minimum " + + "required success percentage found") + + // ErrNotEnoughTxsForEstimate is the error returned when not enough + // transactions have been seen by the fee generator to give an estimate. + ErrNotEnoughTxsForEstimate = errors.New("not enough transactions seen for " + + "estimation") + + dbByteOrder = binary.BigEndian + + dbKeyVersion = []byte("version") + dbKeyBucketFees = []byte("bucketFeeBounds") + dbKeyMaxConfirms = []byte("maxConfirms") + dbKeyBestHeight = []byte("bestHeight") + dbKeyBucketPrefix = []byte{0x01, 0x70, 0x1d, 0x00} +) + +// ErrTargetConfTooLarge is the type of error returned when an user of the +// estimator requested a confirmation range higher than tracked by the estimator. +type ErrTargetConfTooLarge struct { + MaxConfirms int32 + ReqConfirms int32 +} + +func (e ErrTargetConfTooLarge) Error() string { + return fmt.Sprintf("target confirmation requested (%d) higher than "+ + "maximum confirmation range tracked by estimator (%d)", e.ReqConfirms, + e.MaxConfirms) +} + +type feeRate float64 + +type txConfirmStatBucketCount struct { + txCount float64 + feeSum float64 +} + +type txConfirmStatBucket struct { + confirmed []txConfirmStatBucketCount + confirmCount float64 + feeSum float64 +} + +// EstimatorConfig stores the configuration parameters for a given fee +// estimator. It is used to initialize an empty fee estimator. +type EstimatorConfig struct { + // MaxConfirms is the maximum number of confirmation ranges to check. + MaxConfirms uint32 + + // MinBucketFee is the value of the fee rate of the lowest bucket for which + // estimation is tracked. + MinBucketFee dcrutil.Amount + + // MaxBucketFee is the value of the fee for the highest bucket for which + // estimation is tracked. + // + // It MUST be higher than MinBucketFee. + MaxBucketFee dcrutil.Amount + + // ExtraBucketFee is an additional bucket fee rate to include in the + // database for tracking transactions. Specifying this can be useful when + // the default relay fee of the network is undergoing change (due to a new + // release of the software for example), so that the older fee can be + // tracked exactly. + // + // It MUST have a value between MinBucketFee and MaxBucketFee, otherwise + // it's ignored. + ExtraBucketFee dcrutil.Amount + + // FeeRateStep is the multiplier to generate the fee rate buckets (each + // bucket is higher than the previous one by this factor). + // + // It MUST have a value > 1.0. + FeeRateStep float64 + + // DatabaseFile is the location of the estimator database file. If empty, + // updates to the estimator state are not backed by the filesystem. + DatabaseFile string + + // ReplaceBucketsOnLoad indicates whether to replace the buckets in the + // current estimator by those stored in the feesdb file instead of + // validating that they are both using the same set of fees. + ReplaceBucketsOnLoad bool +} + +// memPoolTxDesc is an aux structure used to track the local estimator mempool. +type memPoolTxDesc struct { + addedHeight int64 + bucketIndex int32 + fees feeRate +} + +// Estimator tracks historical data for published and mined transactions in +// order to estimate fees to be used in new transactions for confirmation +// within a target block window. +type Estimator struct { + // bucketFeeBounds are the upper bounds for each individual fee bucket. + bucketFeeBounds []feeRate + + // buckets are the confirmed tx count and fee sum by bucket fee. + buckets []txConfirmStatBucket + + // memPool are the mempool transaction count and fee sum by bucket fee. + memPool []txConfirmStatBucket + + // memPoolTxs is the map of transaction hashes and data of known mempool txs. + memPoolTxs map[chainhash.Hash]memPoolTxDesc + + maxConfirms int32 + decay float64 + bestHeight int64 + db *leveldb.DB + lock sync.RWMutex +} + +// NewEstimator returns an empty estimator given a config. This estimator +// then needs to be fed data for published and mined transactions before it can +// be used to estimate fees for new transactions. +func NewEstimator(cfg *EstimatorConfig) (*Estimator, error) { + // Sanity check the config. + if cfg.MaxBucketFee <= cfg.MinBucketFee { + return nil, errors.New("maximum bucket fee should not be lower than " + + "minimum bucket fee") + } + if cfg.FeeRateStep <= 1.0 { + return nil, errors.New("fee rate step should not be <= 1.0") + } + if cfg.MinBucketFee <= 0 { + return nil, errors.New("minimum bucket fee rate cannot be <= 0") + } + if cfg.MaxConfirms > maxAllowedConfirms { + return nil, fmt.Errorf("confirmation count requested (%d) larger than "+ + "maximum allowed (%d)", cfg.MaxConfirms, maxAllowedConfirms) + } + + decay := defaultDecay + maxConfirms := cfg.MaxConfirms + max := float64(cfg.MaxBucketFee) + var bucketFees []feeRate + prevF := 0.0 + extraBucketFee := float64(cfg.ExtraBucketFee) + for f := float64(cfg.MinBucketFee); f < max; f *= cfg.FeeRateStep { + if (f > extraBucketFee) && (prevF < extraBucketFee) { + // Add the extra bucket fee for tracking. + bucketFees = append(bucketFees, feeRate(extraBucketFee)) + } + bucketFees = append(bucketFees, feeRate(f)) + prevF = f + } + + // The last bucket catches everything else, so it uses an upper bound of + // +inf which any rate must be lower than. + bucketFees = append(bucketFees, feeRate(math.Inf(1))) + + nbBuckets := len(bucketFees) + res := &Estimator{ + bucketFeeBounds: bucketFees, + buckets: make([]txConfirmStatBucket, nbBuckets), + memPool: make([]txConfirmStatBucket, nbBuckets), + maxConfirms: int32(maxConfirms), + decay: decay, + memPoolTxs: make(map[chainhash.Hash]memPoolTxDesc), + bestHeight: -1, + } + + for i := range bucketFees { + res.buckets[i] = txConfirmStatBucket{ + confirmed: make([]txConfirmStatBucketCount, maxConfirms), + } + res.memPool[i] = txConfirmStatBucket{ + confirmed: make([]txConfirmStatBucketCount, maxConfirms), + } + } + + if cfg.DatabaseFile != "" { + db, err := leveldb.OpenFile(cfg.DatabaseFile, nil) + if err != nil { + return nil, fmt.Errorf("error opening estimator database: %v", err) + } + res.db = db + + err = res.loadFromDatabase(cfg.ReplaceBucketsOnLoad) + if err != nil { + return nil, fmt.Errorf("error loading estimator data from db: %v", + err) + } + } + + return res, nil +} + +// DumpBuckets returns the internal estimator state as a string. +func (stats *Estimator) DumpBuckets() string { + res := " |" + for c := 0; c < int(stats.maxConfirms); c++ { + if c == int(stats.maxConfirms)-1 { + res += fmt.Sprintf(" %15s", "+Inf") + } else { + res += fmt.Sprintf(" %15d|", c+1) + } + } + res += "\n" + + l := len(stats.bucketFeeBounds) + for i := 0; i < l; i++ { + res += fmt.Sprintf("%10.8f", stats.bucketFeeBounds[i]/1e8) + for c := 0; c < int(stats.maxConfirms); c++ { + avg := float64(0) + count := stats.buckets[i].confirmed[c].txCount + if stats.buckets[i].confirmed[c].txCount > 0 { + avg = stats.buckets[i].confirmed[c].feeSum / + stats.buckets[i].confirmed[c].txCount / 1e8 + } + + res += fmt.Sprintf("| %.8f %6.1f", avg, count) + } + res += "\n" + } + + return res +} + +// loadFromDatabase loads the estimator data from the currently opened database +// and performs any db upgrades if required. After loading, it updates the db +// with the current estimator configuration. +// +// Argument replaceBuckets indicates if the buckets in the current stats should +// be completely replaced by what is stored in the database or if the data +// should be validated against what is current in the estimator. +// +// The database should *not* be used while loading is taking place. +// +// The current code does not support loading from a database created with a +// different set of configuration parameters (fee rate buckets, max confirmation +// range, etc) than the current estimator is configured with. If an incompatible +// file is detected during loading, an error is returned and the user must +// either reconfigure the estimator to use the same parameters to allow the +// database to be loaded or they must ignore the database file (possibly by +// deleting it) so that the new parameters are used. In the future it might be +// possible to load from a different set of configuration parameters. +// +// The current code does not currently save mempool information, since saving +// information in the estimator without saving the corresponding data in the +// mempool itself could result in transactions lingering in the mempool +// estimator forever. +func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error { + if stats.db == nil { + return errors.New("estimator database is not open") + } + + // Database version is currently hardcoded here as this is the only + // place that uses it. + currentDbVersion := []byte{1} + + version, err := stats.db.Get(dbKeyVersion, nil) + if err != nil && !errors.Is(err, leveldb.ErrNotFound) { + return fmt.Errorf("error reading version from db: %v", err) + } + if len(version) < 1 { + // No data in the file. Fill with the current config. + batch := new(leveldb.Batch) + b := bytes.NewBuffer(nil) + var maxConfirmsBytes [4]byte + var bestHeightBytes [8]byte + + batch.Put(dbKeyVersion, currentDbVersion) + + dbByteOrder.PutUint32(maxConfirmsBytes[:], uint32(stats.maxConfirms)) + batch.Put(dbKeyMaxConfirms, maxConfirmsBytes[:]) + + dbByteOrder.PutUint64(bestHeightBytes[:], uint64(stats.bestHeight)) + batch.Put(dbKeyBestHeight, bestHeightBytes[:]) + + err := binary.Write(b, dbByteOrder, stats.bucketFeeBounds) + if err != nil { + return fmt.Errorf("error writing bucket fees to db: %v", err) + } + batch.Put(dbKeyBucketFees, b.Bytes()) + + err = stats.db.Write(batch, nil) + if err != nil { + return fmt.Errorf("error writing initial estimator db file: %v", + err) + } + + err = stats.updateDatabase() + if err != nil { + return fmt.Errorf("error adding initial estimator data to db: %v", + err) + } + + log.Debug("Initialized fee estimator database") + + return nil + } + + if !bytes.Equal(currentDbVersion, version) { + return fmt.Errorf("incompatible database version: %d", version) + } + + maxConfirmsBytes, err := stats.db.Get(dbKeyMaxConfirms, nil) + if err != nil { + return fmt.Errorf("error reading max confirmation range from db file: "+ + "%v", err) + } + if len(maxConfirmsBytes) != 4 { + return errors.New("wrong number of bytes in stored maxConfirms") + } + fileMaxConfirms := int32(dbByteOrder.Uint32(maxConfirmsBytes)) + if fileMaxConfirms > maxAllowedConfirms { + return fmt.Errorf("confirmation count stored in database (%d) larger "+ + "than maximum allowed (%d)", fileMaxConfirms, maxAllowedConfirms) + } + + feesBytes, err := stats.db.Get(dbKeyBucketFees, nil) + if err != nil { + return fmt.Errorf("error reading fee bounds from db file: %v", err) + } + if feesBytes == nil { + return errors.New("fee bounds not found in database file") + } + fileNbBucketFees := len(feesBytes) / 8 + if fileNbBucketFees > maxAllowedBucketFees { + return fmt.Errorf("more fee buckets stored in file (%d) than allowed "+ + "(%d)", fileNbBucketFees, maxAllowedBucketFees) + } + fileBucketFees := make([]feeRate, fileNbBucketFees) + err = binary.Read(bytes.NewReader(feesBytes), dbByteOrder, + &fileBucketFees) + if err != nil { + return fmt.Errorf("error decoding file bucket fees: %v", err) + } + + if !replaceBuckets { + if stats.maxConfirms != fileMaxConfirms { + return errors.New("max confirmation range in database file different " + + "than currently configured max confirmation") + } + + if len(stats.bucketFeeBounds) != len(fileBucketFees) { + return errors.New("number of bucket fees stored in database file " + + "different than currently configured bucket fees") + } + + for i, f := range fileBucketFees { + if stats.bucketFeeBounds[i] != f { + return errors.New("bucket fee rates stored in database file " + + "different than currently configured fees") + } + } + } + + fileBuckets := make([]txConfirmStatBucket, fileNbBucketFees) + + iter := stats.db.NewIterator(ldbutil.BytesPrefix(dbKeyBucketPrefix), nil) + err = nil + var fbytes [8]byte + for iter.Next() { + key := iter.Key() + if len(key) != 8 { + err = fmt.Errorf("bucket key read from db has wrong length (%d)", + len(key)) + break + } + idx := int(int32(dbByteOrder.Uint32(key[4:]))) + if (idx >= len(fileBuckets)) || (idx < 0) { + err = fmt.Errorf("wrong bucket index read from db (%d vs %d)", + idx, len(fileBuckets)) + break + } + value := iter.Value() + if len(value) != 8+8+int(fileMaxConfirms)*16 { + err = errors.New("wrong size of data in bucket read from db") + break + } + + b := bytes.NewBuffer(value) + readf := func() float64 { + // We ignore the error here because the only possible one is EOF and + // we already previously checked the length of the source byte array + // for consistency. + b.Read(fbytes[:]) + return math.Float64frombits(dbByteOrder.Uint64(fbytes[:])) + } + + fileBuckets[idx].confirmCount = readf() + fileBuckets[idx].feeSum = readf() + fileBuckets[idx].confirmed = make([]txConfirmStatBucketCount, fileMaxConfirms) + for i := range fileBuckets[idx].confirmed { + fileBuckets[idx].confirmed[i].txCount = readf() + fileBuckets[idx].confirmed[i].feeSum = readf() + } + } + iter.Release() + if err != nil { + return err + } + err = iter.Error() + if err != nil { + return fmt.Errorf("error on bucket iterator: %v", err) + } + + stats.bucketFeeBounds = fileBucketFees + stats.buckets = fileBuckets + stats.maxConfirms = fileMaxConfirms + log.Debug("Loaded fee estimator database") + + return nil +} + +// updateDatabase updates the current database file with the current bucket +// data. This is called during normal operation after processing mined +// transactions, so it only updates data that might have changed. +func (stats *Estimator) updateDatabase() error { + if stats.db == nil { + return errors.New("estimator database is closed") + } + + batch := new(leveldb.Batch) + buf := bytes.NewBuffer(nil) + + var key [8]byte + copy(key[:], dbKeyBucketPrefix) + var fbytes [8]byte + writef := func(f float64) { + dbByteOrder.PutUint64(fbytes[:], math.Float64bits(f)) + _, err := buf.Write(fbytes[:]) + if err != nil { + panic(err) // only possible error is ErrTooLarge + } + } + + for i, b := range stats.buckets { + dbByteOrder.PutUint32(key[4:], uint32(i)) + buf.Reset() + writef(b.confirmCount) + writef(b.feeSum) + for _, c := range b.confirmed { + writef(c.txCount) + writef(c.feeSum) + } + batch.Put(key[:], buf.Bytes()) + } + + var bestHeightBytes [8]byte + + dbByteOrder.PutUint64(bestHeightBytes[:], uint64(stats.bestHeight)) + batch.Put(dbKeyBestHeight, bestHeightBytes[:]) + + err := stats.db.Write(batch, nil) + if err != nil { + return fmt.Errorf("error writing update to estimator db file: %v", + err) + } + + return nil +} + +// lowerBucket returns the bucket that has the highest upperBound such that it +// is still lower than rate. +func (stats *Estimator) lowerBucket(rate feeRate) int32 { + res := sort.Search(len(stats.bucketFeeBounds), func(i int) bool { + return stats.bucketFeeBounds[i] >= rate + }) + return int32(res) +} + +// confirmRange returns the confirmation range index to be used for the given +// number of blocks to confirm. The last confirmation range has an upper bound +// of +inf to mean that it represents all confirmations higher than the second +// to last bucket. +func (stats *Estimator) confirmRange(blocksToConfirm int32) int32 { + idx := blocksToConfirm - 1 + if idx >= stats.maxConfirms { + return stats.maxConfirms - 1 + } + return idx +} + +// updateMovingAverages updates the moving averages for the existing confirmed +// statistics and increases the confirmation ranges for mempool txs. This is +// meant to be called when a new block is mined, so that we discount older +// information. +func (stats *Estimator) updateMovingAverages(newHeight int64) { + log.Debugf("Updated moving averages into block %d", newHeight) + + // decay the existing stats so that, over time, we rely on more up to date + // information regarding fees. + for b := 0; b < len(stats.buckets); b++ { + bucket := &stats.buckets[b] + bucket.feeSum *= stats.decay + bucket.confirmCount *= stats.decay + for c := 0; c < len(bucket.confirmed); c++ { + conf := &bucket.confirmed[c] + conf.feeSum *= stats.decay + conf.txCount *= stats.decay + } + } + + // For unconfirmed (mempool) transactions, every transaction will now take + // at least one additional block to confirm. So for every fee bucket, we + // move the stats up one confirmation range. + for b := 0; b < len(stats.memPool); b++ { + bucket := &stats.memPool[b] + + // The last confirmation range represents all txs confirmed at >= than + // the initial maxConfirms, so we *add* the second to last range into + // the last range. + c := len(bucket.confirmed) - 1 + bucket.confirmed[c].txCount += bucket.confirmed[c-1].txCount + bucket.confirmed[c].feeSum += bucket.confirmed[c-1].feeSum + + // For the other ranges, just move up the stats. + for c--; c > 0; c-- { + bucket.confirmed[c] = bucket.confirmed[c-1] + } + + // and finally, the very first confirmation range (ie, what will enter + // the mempool now that a new block has been mined) is zeroed so we can + // start tracking brand new txs. + bucket.confirmed[0].txCount = 0 + bucket.confirmed[0].feeSum = 0 + } + + stats.bestHeight = newHeight +} + +// newMemPoolTx records a new memPool transaction into the stats. A brand new +// mempool transaction has a minimum confirmation range of 1, so it is inserted +// into the very first confirmation range bucket of the appropriate fee rate +// bucket. +func (stats *Estimator) newMemPoolTx(bucketIdx int32, fees feeRate) { + conf := &stats.memPool[bucketIdx].confirmed[0] + conf.feeSum += float64(fees) + conf.txCount++ +} + +// newMinedTx moves a mined tx from the mempool into the confirmed statistics. +// Note that this should only be called if the transaction had been seen and +// previously tracked by calling newMemPoolTx for it. Failing to observe that +// will result in undefined statistical results. +func (stats *Estimator) newMinedTx(blocksToConfirm int32, rate feeRate) { + bucketIdx := stats.lowerBucket(rate) + confirmIdx := stats.confirmRange(blocksToConfirm) + bucket := &stats.buckets[bucketIdx] + + // increase the counts for all confirmation ranges starting at the first + // confirmIdx because it took at least `blocksToConfirm` for this tx to be + // mined. This is used to simplify the bucket selection during estimation, + // so that we only need to check a single confirmation range (instead of + // iterating to sum all confirmations with <= `minConfs`). + for c := int(confirmIdx); c < len(bucket.confirmed); c++ { + conf := &bucket.confirmed[c] + conf.feeSum += float64(rate) + conf.txCount++ + } + bucket.confirmCount++ + bucket.feeSum += float64(rate) +} + +func (stats *Estimator) removeFromMemPool(blocksInMemPool int32, rate feeRate) { + bucketIdx := stats.lowerBucket(rate) + confirmIdx := stats.confirmRange(blocksInMemPool + 1) + bucket := &stats.memPool[bucketIdx] + conf := &bucket.confirmed[confirmIdx] + conf.feeSum -= float64(rate) + conf.txCount-- + if conf.txCount < 0 { + // If this happens, it means a transaction has been called on this + // function but not on a previous newMemPoolTx. This leaves the fee db + // in an undefined state and should never happen in regular use. If this + // happens, then there is a logic or coding error somewhere, either in + // the estimator itself or on its hooking to the mempool/network sync + // manager. Either way, the easiest way to fix this is to completely + // delete the database and start again. During development, you can use + // a panic() here and we might return it after being confident that the + // estimator is completely bug free. + log.Errorf("Transaction count in bucket index %d and confirmation "+ + "index %d became < 0", bucketIdx, confirmIdx) + } +} + +// estimateMedianFee estimates the median fee rate for the current recorded +// statistics such that at least successPct transactions have been mined on all +// tracked fee rate buckets with fee >= to the median. +// In other words, this is the median fee of the lowest bucket such that it and +// all higher fee buckets have >= successPct transactions confirmed in at most +// `targetConfs` confirmations. +// Note that sometimes the requested combination of targetConfs and successPct is +// not achievable (hypothetical example: 99% of txs confirmed within 1 block) +// or there are not enough recorded statistics to derive a successful estimate +// (eg: confirmation tracking has only started or there was a period of very few +// transactions). In those situations, the appropriate error is returned. +func (stats *Estimator) estimateMedianFee(targetConfs int32, successPct float64) (feeRate, error) { + if targetConfs <= 0 { + return 0, errors.New("target confirmation range cannot be <= 0") + } + + const minTxCount float64 = 1 + + if (targetConfs - 1) >= stats.maxConfirms { + // We might want to add support to use a targetConf at +infinity to + // allow us to make estimates at confirmation interval higher than what + // we currently track. + return 0, ErrTargetConfTooLarge{MaxConfirms: stats.maxConfirms, + ReqConfirms: targetConfs} + } + + startIdx := len(stats.buckets) - 1 + confirmRangeIdx := stats.confirmRange(targetConfs) + + var totalTxs, confirmedTxs float64 + bestBucketsStt := startIdx + bestBucketsEnd := startIdx + curBucketsEnd := startIdx + + for b := startIdx; b >= 0; b-- { + totalTxs += stats.buckets[b].confirmCount + confirmedTxs += stats.buckets[b].confirmed[confirmRangeIdx].txCount + + // Add the mempool (unconfirmed) transactions to the total tx count + // since a very large mempool for the given bucket might mean that + // miners are reluctant to include these in their mined blocks. + totalTxs += stats.memPool[b].confirmed[confirmRangeIdx].txCount + + if totalTxs > minTxCount { + if confirmedTxs/totalTxs < successPct { + if curBucketsEnd == startIdx { + return 0, ErrNoSuccessPctBucketFound + } + break + } + + bestBucketsStt = b + bestBucketsEnd = curBucketsEnd + curBucketsEnd = b - 1 + totalTxs = 0 + confirmedTxs = 0 + } + } + + txCount := float64(0) + for b := bestBucketsStt; b <= bestBucketsEnd; b++ { + txCount += stats.buckets[b].confirmCount + } + if txCount <= 0 { + return 0, ErrNotEnoughTxsForEstimate + } + txCount /= 2 + for b := bestBucketsStt; b <= bestBucketsEnd; b++ { + if stats.buckets[b].confirmCount < txCount { + txCount -= stats.buckets[b].confirmCount + } else { + median := stats.buckets[b].feeSum / stats.buckets[b].confirmCount + return feeRate(median), nil + } + } + + return 0, errors.New("this isn't supposed to be reached") +} + +// EstimateFee is the public version of estimateMedianFee. It calculates the +// suggested fee for a transaction to be confirmed in at most `targetConf` +// blocks after publishing with a high degree of certainty. +// +// This function is safe to be called from multiple goroutines but might block +// until concurrent modifications to the internal database state are complete. +func (stats *Estimator) EstimateFee(targetConfs int32) (dcrutil.Amount, error) { + stats.lock.RLock() + rate, err := stats.estimateMedianFee(targetConfs, 0.95) + stats.lock.RUnlock() + + if err != nil { + return 0, err + } + + rate = feeRate(math.Round(float64(rate))) + if rate < stats.bucketFeeBounds[0] { + // Prevent our public facing api to ever return something lower than the + // minimum fee + rate = stats.bucketFeeBounds[0] + } + + return dcrutil.Amount(rate), nil +} + +// Enable establishes the current best height of the blockchain after +// initializing the chain. All new mempool transactions will be added at this +// block height. +func (stats *Estimator) Enable(bestHeight int64) { + log.Debugf("Setting best height as %d", bestHeight) + stats.lock.Lock() + stats.bestHeight = bestHeight + stats.lock.Unlock() +} + +// IsEnabled returns whether the fee estimator is ready to accept new mined and +// mempool transactions. +func (stats *Estimator) IsEnabled() bool { + stats.lock.RLock() + enabled := stats.bestHeight > -1 + stats.lock.RUnlock() + return enabled +} + +// AddMemPoolTransaction adds a mempool transaction to the estimator in order to +// account for it in the estimations. It assumes that this transaction is +// entering the mempool at the currently recorded best chain hash, using the +// total fee amount (in atoms) and with the provided size (in bytes). +// +// This is safe to be called from multiple goroutines. +func (stats *Estimator) AddMemPoolTransaction(txHash *chainhash.Hash, fee, size int64, txType stake.TxType) { + stats.lock.Lock() + defer stats.lock.Unlock() + + if stats.bestHeight < 0 { + return + } + + if _, exists := stats.memPoolTxs[*txHash]; exists { + // we should not double count transactions + return + } + + // Ignore tspends for the purposes of fee estimation, since they remain + // in the mempool for a long time and have special rules about when + // they can be included in blocks. + if txType == stake.TxTypeTSpend { + return + } + + // Note that we use this less exact version instead of fee * 1000 / size + // (using ints) because it naturally "downsamples" the fee rates towards the + // minimum at values less than 0.001 DCR/KB. This is needed because due to + // how the wallet estimates the final fee given an input rate and the final + // tx size, there's usually a small discrepancy towards a higher effective + // rate in the published tx. + rate := feeRate(fee / size * 1000) + + if rate < stats.bucketFeeBounds[0] { + // Transactions paying less than the current relaying fee can only + // possibly be included in the high priority/zero fee area of blocks, + // which are usually of limited size, so we explicitly don't track + // those. + // This also naturally handles votes (SSGen transactions) which don't + // carry a tx fee and are required for inclusion in blocks. Note that + // the test is explicitly < instead of <= so that we *can* track + // transactions that pay *exactly* the minimum fee. + return + } + + log.Debugf("Adding mempool tx %s using fee rate %.8f", txHash, rate/1e8) + + tx := memPoolTxDesc{ + addedHeight: stats.bestHeight, + bucketIndex: stats.lowerBucket(rate), + fees: rate, + } + stats.memPoolTxs[*txHash] = tx + stats.newMemPoolTx(tx.bucketIndex, rate) +} + +// RemoveMemPoolTransaction removes a mempool transaction from statistics +// tracking. +// +// This is safe to be called from multiple goroutines. +func (stats *Estimator) RemoveMemPoolTransaction(txHash *chainhash.Hash) { + stats.lock.Lock() + defer stats.lock.Unlock() + + desc, exists := stats.memPoolTxs[*txHash] + if !exists { + return + } + + log.Debugf("Removing tx %s from mempool", txHash) + + stats.removeFromMemPool(int32(stats.bestHeight-desc.addedHeight), desc.fees) + delete(stats.memPoolTxs, *txHash) +} + +// processMinedTransaction moves the transaction that exist in the currently +// tracked mempool into a mined state. +// +// This function is *not* safe to be called from multiple goroutines. +func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhash.Hash) { + desc, exists := stats.memPoolTxs[*txh] + if !exists { + // We cannot use transactions that we didn't know about to estimate + // because that opens up the possibility of miners introducing dummy, + // high fee transactions which would tend to then increase the average + // fee estimate. + // Tracking only previously known transactions forces miners trying to + // pull off this attack to broadcast their transactions and possibly + // forfeit their coins by having the transaction mined by a competitor. + log.Tracef("Processing previously unknown mined tx %s", txh) + return + } + + stats.removeFromMemPool(int32(blockHeight-desc.addedHeight), desc.fees) + delete(stats.memPoolTxs, *txh) + + if blockHeight <= desc.addedHeight { + // This shouldn't usually happen but we need to explicitly test for + // because we can't account for non positive confirmation ranges in + // mined transactions. + log.Errorf("Mined transaction %s (%d) that was known from "+ + "mempool at a higher block height (%d)", txh, blockHeight, + desc.addedHeight) + return + } + + mineDelay := int32(blockHeight - desc.addedHeight) + log.Debugf("Processing mined tx %s (rate %.8f, delay %d)", txh, + desc.fees/1e8, mineDelay) + stats.newMinedTx(mineDelay, desc.fees) +} + +// ProcessBlock processes all mined transactions in the provided block. +// +// This function is safe to be called from multiple goroutines. +func (stats *Estimator) ProcessBlock(block *dcrutil.Block) error { + stats.lock.Lock() + defer stats.lock.Unlock() + + if stats.bestHeight < 0 { + return nil + } + + blockHeight := block.Height() + if blockHeight <= stats.bestHeight { + // we don't explicitly track reorgs right now + log.Warnf("Trying to process mined transactions at block %d when "+ + "previous best block was at height %d", blockHeight, + stats.bestHeight) + return nil + } + + stats.updateMovingAverages(blockHeight) + + for _, tx := range block.Transactions() { + stats.processMinedTransaction(blockHeight, tx.Hash()) + } + + for _, tx := range block.STransactions() { + stats.processMinedTransaction(blockHeight, tx.Hash()) + } + + if stats.db != nil { + return stats.updateDatabase() + } + + return nil +} + +// Close closes the database (if it is currently opened). +func (stats *Estimator) Close() { + stats.lock.Lock() + + if stats.db != nil { + log.Trace("Closing fee estimator database") + stats.db.Close() + stats.db = nil + } + + stats.lock.Unlock() +} diff --git a/fees/log.go b/fees/log.go new file mode 100644 index 00000000..08793d69 --- /dev/null +++ b/fees/log.go @@ -0,0 +1,21 @@ +// Copyright (c) 2018-2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package fees + +import ( + "github.com/decred/slog" +) + +// log is a logger that is initialized with no output filters. This means the +// package will not perform any logging by default until the caller requests it. +// The default amount of logging is none. +var log = slog.Disabled + +// UseLogger uses a specified Logger to output fee estimator logging info. This +// should be used in preference to SetLogWriter if the caller is also using +// slog. +func UseLogger(logger slog.Logger) { + log = logger +} -- 2.45.2 From d126d0c10eaf57e396f56006ea1e122eb74c9ba0 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 26 Jan 2022 20:42:17 -0800 Subject: [PATCH 390/459] [lbry] fees: port estimatesmartfee from DCRD 1. logger 2. blockheight: int64 -> int32 3. dcrutil -> lbcutl 4. MaxConfirimation: 42 5. MinBucketFee: mempool.MinRelayFee (default 1000) 6. BucketFee Spacing: 1.1 -> 1.05 Note: DCRD implementation of estimatesmartfee is based on bitcoin core 0.14 Lbrycrd (0.17) includes the updates of bitcoin core 0.15. They are slightly different, but shouldn't matter much. --- fees/cmd/dumpfeedb/dumpfeedb.go | 10 +++++-- fees/estimator.go | 52 +++++++++++++-------------------- fees/log.go | 18 ++++++++---- log.go | 27 +++++++++-------- 4 files changed, 54 insertions(+), 53 deletions(-) diff --git a/fees/cmd/dumpfeedb/dumpfeedb.go b/fees/cmd/dumpfeedb/dumpfeedb.go index 38e2492a..b15974bf 100644 --- a/fees/cmd/dumpfeedb/dumpfeedb.go +++ b/fees/cmd/dumpfeedb/dumpfeedb.go @@ -12,20 +12,24 @@ import ( "os" "path" - "github.com/decred/dcrd/dcrutil/v4" - "github.com/decred/dcrd/internal/fees" + "github.com/btcsuite/btclog" flags "github.com/jessevdk/go-flags" + "github.com/lbryio/lbcd/fees" + "github.com/lbryio/lbcutil" ) type config struct { DB string `short:"b" long:"db" description:"Path to fee database"` } +var feesLog = btclog.NewBackend(os.Stdout).Logger("FEES") + func main() { cfg := config{ - DB: path.Join(dcrutil.AppDataDir("dcrd", false), "data", "mainnet", "feesdb"), + DB: path.Join(lbcutil.AppDataDir("lbcd", false), "data", "mainnet", "feesdb"), } + fees.UseLogger(feesLog) parser := flags.NewParser(&cfg, flags.Default) _, err := parser.Parse() if err != nil { diff --git a/fees/estimator.go b/fees/estimator.go index d98f037f..7f7a8751 100644 --- a/fees/estimator.go +++ b/fees/estimator.go @@ -13,9 +13,8 @@ import ( "sort" "sync" - "github.com/decred/dcrd/blockchain/stake/v4" - "github.com/decred/dcrd/chaincfg/chainhash" - "github.com/decred/dcrd/dcrutil/v4" + "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcutil" "github.com/syndtr/goleveldb/leveldb" ldbutil "github.com/syndtr/goleveldb/leveldb/util" ) @@ -27,11 +26,11 @@ const ( // DefaultMaxConfirmations is the default number of confirmation ranges to // track in the estimator. - DefaultMaxConfirmations uint32 = 32 + DefaultMaxConfirmations uint32 = 42 // DefaultFeeRateStep is the default multiplier between two consecutive fee // rate buckets. - DefaultFeeRateStep float64 = 1.1 + DefaultFeeRateStep float64 = 1.05 // defaultDecay is the default value used to decay old transactions from the // estimator. @@ -102,13 +101,13 @@ type EstimatorConfig struct { // MinBucketFee is the value of the fee rate of the lowest bucket for which // estimation is tracked. - MinBucketFee dcrutil.Amount + MinBucketFee lbcutil.Amount // MaxBucketFee is the value of the fee for the highest bucket for which // estimation is tracked. // // It MUST be higher than MinBucketFee. - MaxBucketFee dcrutil.Amount + MaxBucketFee lbcutil.Amount // ExtraBucketFee is an additional bucket fee rate to include in the // database for tracking transactions. Specifying this can be useful when @@ -118,7 +117,7 @@ type EstimatorConfig struct { // // It MUST have a value between MinBucketFee and MaxBucketFee, otherwise // it's ignored. - ExtraBucketFee dcrutil.Amount + ExtraBucketFee lbcutil.Amount // FeeRateStep is the multiplier to generate the fee rate buckets (each // bucket is higher than the previous one by this factor). @@ -138,7 +137,7 @@ type EstimatorConfig struct { // memPoolTxDesc is an aux structure used to track the local estimator mempool. type memPoolTxDesc struct { - addedHeight int64 + addedHeight int32 bucketIndex int32 fees feeRate } @@ -161,7 +160,7 @@ type Estimator struct { maxConfirms int32 decay float64 - bestHeight int64 + bestHeight int32 db *leveldb.DB lock sync.RWMutex } @@ -324,7 +323,7 @@ func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error { dbByteOrder.PutUint64(bestHeightBytes[:], uint64(stats.bestHeight)) batch.Put(dbKeyBestHeight, bestHeightBytes[:]) - err := binary.Write(b, dbByteOrder, stats.bucketFeeBounds) + err = binary.Write(b, dbByteOrder, stats.bucketFeeBounds) if err != nil { return fmt.Errorf("error writing bucket fees to db: %v", err) } @@ -534,7 +533,7 @@ func (stats *Estimator) confirmRange(blocksToConfirm int32) int32 { // statistics and increases the confirmation ranges for mempool txs. This is // meant to be called when a new block is mined, so that we discount older // information. -func (stats *Estimator) updateMovingAverages(newHeight int64) { +func (stats *Estimator) updateMovingAverages(newHeight int32) { log.Debugf("Updated moving averages into block %d", newHeight) // decay the existing stats so that, over time, we rely on more up to date @@ -718,7 +717,7 @@ func (stats *Estimator) estimateMedianFee(targetConfs int32, successPct float64) // // This function is safe to be called from multiple goroutines but might block // until concurrent modifications to the internal database state are complete. -func (stats *Estimator) EstimateFee(targetConfs int32) (dcrutil.Amount, error) { +func (stats *Estimator) EstimateFee(targetConfs int32) (lbcutil.Amount, error) { stats.lock.RLock() rate, err := stats.estimateMedianFee(targetConfs, 0.95) stats.lock.RUnlock() @@ -734,13 +733,13 @@ func (stats *Estimator) EstimateFee(targetConfs int32) (dcrutil.Amount, error) { rate = stats.bucketFeeBounds[0] } - return dcrutil.Amount(rate), nil + return lbcutil.Amount(rate), nil } // Enable establishes the current best height of the blockchain after // initializing the chain. All new mempool transactions will be added at this // block height. -func (stats *Estimator) Enable(bestHeight int64) { +func (stats *Estimator) Enable(bestHeight int32) { log.Debugf("Setting best height as %d", bestHeight) stats.lock.Lock() stats.bestHeight = bestHeight @@ -762,7 +761,7 @@ func (stats *Estimator) IsEnabled() bool { // total fee amount (in atoms) and with the provided size (in bytes). // // This is safe to be called from multiple goroutines. -func (stats *Estimator) AddMemPoolTransaction(txHash *chainhash.Hash, fee, size int64, txType stake.TxType) { +func (stats *Estimator) AddMemPoolTransaction(txHash *chainhash.Hash, fee, size int64) { stats.lock.Lock() defer stats.lock.Unlock() @@ -775,13 +774,6 @@ func (stats *Estimator) AddMemPoolTransaction(txHash *chainhash.Hash, fee, size return } - // Ignore tspends for the purposes of fee estimation, since they remain - // in the mempool for a long time and have special rules about when - // they can be included in blocks. - if txType == stake.TxTypeTSpend { - return - } - // Note that we use this less exact version instead of fee * 1000 / size // (using ints) because it naturally "downsamples" the fee rates towards the // minimum at values less than 0.001 DCR/KB. This is needed because due to @@ -828,7 +820,7 @@ func (stats *Estimator) RemoveMemPoolTransaction(txHash *chainhash.Hash) { log.Debugf("Removing tx %s from mempool", txHash) - stats.removeFromMemPool(int32(stats.bestHeight-desc.addedHeight), desc.fees) + stats.removeFromMemPool(stats.bestHeight-desc.addedHeight, desc.fees) delete(stats.memPoolTxs, *txHash) } @@ -836,7 +828,7 @@ func (stats *Estimator) RemoveMemPoolTransaction(txHash *chainhash.Hash) { // tracked mempool into a mined state. // // This function is *not* safe to be called from multiple goroutines. -func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhash.Hash) { +func (stats *Estimator) processMinedTransaction(blockHeight int32, txh *chainhash.Hash) { desc, exists := stats.memPoolTxs[*txh] if !exists { // We cannot use transactions that we didn't know about to estimate @@ -850,7 +842,7 @@ func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhas return } - stats.removeFromMemPool(int32(blockHeight-desc.addedHeight), desc.fees) + stats.removeFromMemPool(blockHeight-desc.addedHeight, desc.fees) delete(stats.memPoolTxs, *txh) if blockHeight <= desc.addedHeight { @@ -863,7 +855,7 @@ func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhas return } - mineDelay := int32(blockHeight - desc.addedHeight) + mineDelay := blockHeight - desc.addedHeight log.Debugf("Processing mined tx %s (rate %.8f, delay %d)", txh, desc.fees/1e8, mineDelay) stats.newMinedTx(mineDelay, desc.fees) @@ -872,7 +864,7 @@ func (stats *Estimator) processMinedTransaction(blockHeight int64, txh *chainhas // ProcessBlock processes all mined transactions in the provided block. // // This function is safe to be called from multiple goroutines. -func (stats *Estimator) ProcessBlock(block *dcrutil.Block) error { +func (stats *Estimator) ProcessBlock(block *lbcutil.Block) error { stats.lock.Lock() defer stats.lock.Unlock() @@ -895,10 +887,6 @@ func (stats *Estimator) ProcessBlock(block *dcrutil.Block) error { stats.processMinedTransaction(blockHeight, tx.Hash()) } - for _, tx := range block.STransactions() { - stats.processMinedTransaction(blockHeight, tx.Hash()) - } - if stats.db != nil { return stats.updateDatabase() } diff --git a/fees/log.go b/fees/log.go index 08793d69..769c320d 100644 --- a/fees/log.go +++ b/fees/log.go @@ -5,17 +5,23 @@ package fees import ( - "github.com/decred/slog" + "github.com/btcsuite/btclog" ) // log is a logger that is initialized with no output filters. This means the // package will not perform any logging by default until the caller requests it. // The default amount of logging is none. -var log = slog.Disabled +var log btclog.Logger -// UseLogger uses a specified Logger to output fee estimator logging info. This -// should be used in preference to SetLogWriter if the caller is also using -// slog. -func UseLogger(logger slog.Logger) { +// DisableLog disables all library log output. Logging output is disabled +// by default until either UseLogger or SetLogWriter are called. +func DisableLog() { + log = btclog.Disabled +} + +// UseLogger uses a specified Logger to output package logging info. +// This should be used in preference to SetLogWriter if the caller is also +// using btclog. +func UseLogger(logger btclog.Logger) { log = logger } diff --git a/log.go b/log.go index cc845475..2809b1a7 100644 --- a/log.go +++ b/log.go @@ -16,6 +16,7 @@ import ( "github.com/lbryio/lbcd/claimtrie/node" "github.com/lbryio/lbcd/connmgr" "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" "github.com/lbryio/lbcd/mining" "github.com/lbryio/lbcd/mining/cpuminer" @@ -57,13 +58,14 @@ var ( adxrLog = backendLog.Logger("ADXR") amgrLog = backendLog.Logger("AMGR") - cmgrLog = backendLog.Logger("CMGR") bcdbLog = backendLog.Logger("BCDB") btcdLog = backendLog.Logger("MAIN") chanLog = backendLog.Logger("CHAN") - lbryLog = backendLog.Logger("LBRY") + cmgrLog = backendLog.Logger("CMGR") discLog = backendLog.Logger("DISC") + feesLog = backendLog.Logger("FEES") indxLog = backendLog.Logger("INDX") + lbryLog = backendLog.Logger("LBRY") minrLog = backendLog.Logger("MINR") peerLog = backendLog.Logger("PEER") rpcsLog = backendLog.Logger("RPCS") @@ -76,30 +78,31 @@ var ( // Initialize package-global logger variables. func init() { addrmgr.UseLogger(amgrLog) - connmgr.UseLogger(cmgrLog) - database.UseLogger(bcdbLog) blockchain.UseLogger(chanLog) - node.UseLogger(lbryLog) - indexers.UseLogger(indxLog) - mining.UseLogger(minrLog) + connmgr.UseLogger(cmgrLog) cpuminer.UseLogger(minrLog) + database.UseLogger(bcdbLog) + fees.UseLogger(feesLog) + indexers.UseLogger(indxLog) + mempool.UseLogger(txmpLog) + mining.UseLogger(minrLog) + netsync.UseLogger(syncLog) + node.UseLogger(lbryLog) peer.UseLogger(peerLog) txscript.UseLogger(scrpLog) - netsync.UseLogger(syncLog) - mempool.UseLogger(txmpLog) } // subsystemLoggers maps each subsystem identifier to its associated logger. var subsystemLoggers = map[string]btclog.Logger{ "ADXR": adxrLog, "AMGR": amgrLog, - "CMGR": cmgrLog, "BCDB": bcdbLog, - "MAIN": btcdLog, "CHAN": chanLog, - "LBRY": lbryLog, + "CMGR": cmgrLog, "DISC": discLog, "INDX": indxLog, + "LBRY": lbryLog, + "MAIN": btcdLog, "MINR": minrLog, "PEER": peerLog, "RPCS": rpcsLog, -- 2.45.2 From 7513046f70519280d8511a90e495697ad337d5cf Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sat, 29 Jan 2022 16:27:52 -0800 Subject: [PATCH 391/459] [lbry] fees: replace estimatefee with esimatesmartfee --- mempool/mempool.go | 27 ++++++++++++++---- netsync/interface.go | 3 +- netsync/manager.go | 34 ++++++++++------------ rpcserver.go | 35 ++++++++++++++++++++--- server.go | 68 ++++++++++++++++++-------------------------- 5 files changed, 97 insertions(+), 70 deletions(-) diff --git a/mempool/mempool.go b/mempool/mempool.go index de3b8028..a2dc5c20 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -100,9 +100,15 @@ type Config struct { // This can be nil if the address index is not enabled. AddrIndex *indexers.AddrIndex - // FeeEstimatator provides a feeEstimator. If it is not nil, the mempool - // records all new transactions it observes into the feeEstimator. - FeeEstimator *FeeEstimator + // AddTxToFeeEstimation defines an optional function to be called whenever a + // new transaction is added to the mempool, which can be used to track fees + // for the purposes of smart fee estimation. + AddTxToFeeEstimation func(txHash *chainhash.Hash, fee, size int64) + + // RemoveTxFromFeeEstimation defines an optional function to be called + // whenever a transaction is removed from the mempool in order to track fee + // estimation. + RemoveTxFromFeeEstimation func(txHash *chainhash.Hash) } // Policy houses the policy (configuration parameters) which is used to @@ -491,6 +497,13 @@ func (mp *TxPool) removeTransaction(tx *btcutil.Tx, removeRedeemers bool) { delete(mp.outpoints, txIn.PreviousOutPoint) } delete(mp.pool, *txHash) + + // Inform associated fee estimator that the transaction has been removed + // from the mempool + if mp.cfg.RemoveTxFromFeeEstimation != nil { + mp.cfg.RemoveTxFromFeeEstimation(txHash) + } + atomic.StoreInt64(&mp.lastUpdated, time.Now().Unix()) } } @@ -559,9 +572,11 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil mp.cfg.AddrIndex.AddUnconfirmedTx(tx, utxoView) } - // Record this tx for fee estimation if enabled. - if mp.cfg.FeeEstimator != nil { - mp.cfg.FeeEstimator.ObserveTransaction(txD) + // Inform the associated fee estimator that a new transaction has been added + // to the mempool. + size := GetTxVirtualSize(txD.Tx) + if mp.cfg.AddTxToFeeEstimation != nil { + mp.cfg.AddTxToFeeEstimation(txD.Tx.Hash(), txD.Fee, size) } return txD diff --git a/netsync/interface.go b/netsync/interface.go index 9361bfbc..2a646f07 100644 --- a/netsync/interface.go +++ b/netsync/interface.go @@ -8,6 +8,7 @@ import ( "github.com/lbryio/lbcd/blockchain" "github.com/lbryio/lbcd/chaincfg" "github.com/lbryio/lbcd/chaincfg/chainhash" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" "github.com/lbryio/lbcd/peer" "github.com/lbryio/lbcd/wire" @@ -37,5 +38,5 @@ type Config struct { DisableCheckpoints bool MaxPeers int - FeeEstimator *mempool.FeeEstimator + FeeEstimator *fees.Estimator } diff --git a/netsync/manager.go b/netsync/manager.go index 69093610..72fce625 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -16,6 +16,7 @@ import ( "github.com/lbryio/lbcd/chaincfg" "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" peerpkg "github.com/lbryio/lbcd/peer" "github.com/lbryio/lbcd/wire" @@ -205,7 +206,7 @@ type SyncManager struct { nextCheckpoint *chaincfg.Checkpoint // An optional fee estimator. - feeEstimator *mempool.FeeEstimator + feeEstimator *fees.Estimator } // resetHeaderState sets the headers-first mode state to values appropriate for @@ -1414,6 +1415,13 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not iv := wire.NewInvVect(wire.InvTypeBlock, block.Hash()) sm.peerNotifier.RelayInventory(iv, block.MsgBlock().Header) + if !sm.feeEstimator.IsEnabled() { + // fee estimation can only start after we have performed an initial + // sync, otherwise we'll start adding mempool transactions at the + // wrong height. + sm.feeEstimator.Enable(block.Height()) + } + // A block has been connected to the main block chain. case blockchain.NTBlockConnected: block, ok := notification.Data.(*btcutil.Block) @@ -1422,6 +1430,12 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not break } + // Account for transactions mined in the newly connected block for fee + // estimation. This must be done before attempting to remove + // transactions from the mempool because the mempool will alert the + // estimator of the txs that are leaving + sm.feeEstimator.ProcessBlock(block) + // Remove all of the transactions (except the coinbase) in the // connected block from the transaction pool. Secondly, remove any // transactions which are now double spends as a result of these @@ -1438,20 +1452,6 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not sm.peerNotifier.AnnounceNewTransactions(acceptedTxs) } - // Register block with the fee estimator, if it exists. - if sm.feeEstimator != nil { - err := sm.feeEstimator.RegisterBlock(block) - - // If an error is somehow generated then the fee estimator - // has entered an invalid state. Since it doesn't know how - // to recover, create a new one. - if err != nil { - sm.feeEstimator = mempool.NewFeeEstimator( - mempool.DefaultEstimateFeeMaxRollback, - mempool.DefaultEstimateFeeMinRegisteredBlocks) - } - } - // A block has been disconnected from the main block chain. case blockchain.NTBlockDisconnected: block, ok := notification.Data.(*btcutil.Block) @@ -1473,10 +1473,6 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not } } - // Rollback previous block recorded by the fee estimator. - if sm.feeEstimator != nil { - sm.feeEstimator.Rollback(block.Hash()) - } } } diff --git a/rpcserver.go b/rpcserver.go index 9dd42a70..f2796ba6 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -36,6 +36,7 @@ import ( "github.com/lbryio/lbcd/chaincfg" "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" "github.com/lbryio/lbcd/mining" "github.com/lbryio/lbcd/mining/cpuminer" @@ -893,7 +894,7 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) } } - feeRate, err := s.cfg.FeeEstimator.EstimateFee(uint32(c.NumBlocks)) + feeRate, err := s.cfg.FeeEstimator.EstimateFee(int32(c.NumBlocks)) if err != nil { return nil, &btcjson.RPCError{ @@ -906,12 +907,36 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) return float64(feeRate), nil } +// handleEstimateSmartFee implements the estimatesmartfee command. +// +// The default estimation mode when unset is assumed as "conservative". As of +// 2018-12, the only supported mode is "conservative". func handleEstimateSmartFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*btcjson.EstimateSmartFeeCmd) - rpcsLog.Debugf("EstimateSmartFee is not implemented; falling back to EstimateFee. Requested mode: %s", c.EstimateMode) + mode := btcjson.EstimateModeConservative + if c.EstimateMode != nil { + mode = *c.EstimateMode + } - return handleEstimateFee(s, &btcjson.EstimateFeeCmd{NumBlocks: c.ConfTarget}, closeChan) + if mode != btcjson.EstimateModeConservative { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "Only the default and conservative modes " + + "are supported for smart fee estimation at the moment", + } + } + + fee, err := s.cfg.FeeEstimator.EstimateFee(int32(c.ConfTarget)) + if err != nil { + return nil, internalRPCError(err.Error(), "Could not estimate fee") + } + + feeRate := float64(fee) / btcutil.SatoshiPerBitcoin + return &btcjson.EstimateSmartFeeResult{ + FeeRate: &feeRate, + Blocks: c.ConfTarget, + }, nil } func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { @@ -4013,6 +4038,7 @@ type rpcServer struct { gbtWorkState *gbtWorkState helpCacher *helpCacher requestProcessShutdown chan struct{} + feeEstimator *fees.Estimator quit chan int } @@ -4846,7 +4872,7 @@ type rpcserverConfig struct { // The fee estimator keeps track of how long transactions are left in // the mempool before they are mined into blocks. - FeeEstimator *mempool.FeeEstimator + FeeEstimator *fees.Estimator // Services represents the services supported by this node. Services wire.ServiceFlag @@ -4860,6 +4886,7 @@ func newRPCServer(config *rpcserverConfig) (*rpcServer, error) { gbtWorkState: newGbtWorkState(config.TimeSource), helpCacher: newHelpCacher(), requestProcessShutdown: make(chan struct{}), + feeEstimator: config.FeeEstimator, quit: make(chan int), } if cfg.RPCUser != "" && cfg.RPCPass != "" { diff --git a/server.go b/server.go index 8a6ea6c5..305b7852 100644 --- a/server.go +++ b/server.go @@ -14,6 +14,7 @@ import ( "fmt" "math" "net" + "path" "runtime" "sort" "strconv" @@ -31,6 +32,7 @@ import ( claimtrieconfig "github.com/lbryio/lbcd/claimtrie/config" "github.com/lbryio/lbcd/connmgr" "github.com/lbryio/lbcd/database" + "github.com/lbryio/lbcd/fees" "github.com/lbryio/lbcd/mempool" "github.com/lbryio/lbcd/mining" "github.com/lbryio/lbcd/mining/cpuminer" @@ -38,6 +40,7 @@ import ( "github.com/lbryio/lbcd/peer" "github.com/lbryio/lbcd/txscript" "github.com/lbryio/lbcd/wire" + "github.com/lbryio/lbcutil" btcutil "github.com/lbryio/lbcutil" "github.com/lbryio/lbcutil/bloom" ) @@ -241,7 +244,7 @@ type server struct { // The fee estimator keeps track of how long transactions are left in // the mempool before they are mined into blocks. - feeEstimator *mempool.FeeEstimator + feeEstimator *fees.Estimator // cfCheckptCaches stores a cached slice of filter headers for cfcheckpt // messages for each filter type. @@ -2417,13 +2420,7 @@ func (s *server) Stop() error { s.rpcServer.Stop() } - // Save fee estimator state in the database. - s.db.Update(func(tx database.Tx) error { - metadata := tx.Metadata() - metadata.Put(mempool.EstimateFeeDatabaseKey, s.feeEstimator.Save()) - - return nil - }) + s.feeEstimator.Close() // Signal the remaining goroutines to quit. close(s.quit) @@ -2755,35 +2752,25 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, return nil, err } - // Search for a FeeEstimator state in the database. If none can be found - // or if it cannot be loaded, create a new one. - db.Update(func(tx database.Tx) error { - metadata := tx.Metadata() - feeEstimationData := metadata.Get(mempool.EstimateFeeDatabaseKey) - if feeEstimationData != nil { - // delete it from the database so that we don't try to restore the - // same thing again somehow. - metadata.Delete(mempool.EstimateFeeDatabaseKey) + feC := fees.EstimatorConfig{ + MinBucketFee: cfg.minRelayTxFee, + MaxBucketFee: lbcutil.Amount(fees.DefaultMaxBucketFeeMultiplier) * cfg.minRelayTxFee, + MaxConfirms: fees.DefaultMaxConfirmations, + FeeRateStep: fees.DefaultFeeRateStep, + DatabaseFile: path.Join(cfg.DataDir, "feesdb"), - // If there is an error, log it and make a new fee estimator. - var err error - s.feeEstimator, err = mempool.RestoreFeeEstimator(feeEstimationData) - - if err != nil { - peerLog.Errorf("Failed to restore fee estimator %v", err) - } - } - - return nil - }) - - // If no feeEstimator has been found, or if the one that has been found - // is behind somehow, create a new one and start over. - if s.feeEstimator == nil || s.feeEstimator.LastKnownHeight() != s.chain.BestSnapshot().Height { - s.feeEstimator = mempool.NewFeeEstimator( - mempool.DefaultEstimateFeeMaxRollback, - mempool.DefaultEstimateFeeMinRegisteredBlocks) + // 1e5 is the previous (up to 1.1.0) mempool.DefaultMinRelayTxFee that + // un-upgraded wallets will be using, so track this particular rate + // explicitly. Note that bumping this value will cause the existing fees + // database to become invalid and will force nodes to explicitly delete + // it. + ExtraBucketFee: 1e5, } + fe, err := fees.NewEstimator(&feC) + if err != nil { + return nil, err + } + s.feeEstimator = fe txC := mempool.Config{ Policy: mempool.Policy{ @@ -2804,11 +2791,12 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, CalcSequenceLock: func(tx *btcutil.Tx, view *blockchain.UtxoViewpoint) (*blockchain.SequenceLock, error) { return s.chain.CalcSequenceLock(tx, view, true) }, - IsDeploymentActive: s.chain.IsDeploymentActive, - SigCache: s.sigCache, - HashCache: s.hashCache, - AddrIndex: s.addrIndex, - FeeEstimator: s.feeEstimator, + IsDeploymentActive: s.chain.IsDeploymentActive, + SigCache: s.sigCache, + HashCache: s.hashCache, + AddrIndex: s.addrIndex, + AddTxToFeeEstimation: s.feeEstimator.AddMemPoolTransaction, + RemoveTxFromFeeEstimation: s.feeEstimator.RemoveMemPoolTransaction, } s.txMemPool = mempool.New(&txC) -- 2.45.2 From 43d3086ce1d79faa71b4ed85f4349ac103563164 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 15 Feb 2022 23:08:44 -0800 Subject: [PATCH 392/459] [lbry] mempool: update getrawmempool and implement getmempoolentry TODO:: 1. Populate Ancestor and decsendent related fields instead of mocking. 2. Move and refator the implementation of getmempoolentry to the mempool package. --- btcjson/chainsvrresults.go | 1 + mempool/mempool.go | 44 +++++++++++++++++-------------- mempool/mempool_test.go | 2 +- rpcserver.go | 53 ++++++++++++++++++++++++++++++++++++-- rpcserverhelp.go | 29 +++++++++++++++++++++ 5 files changed, 107 insertions(+), 22 deletions(-) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 811883c7..ffa0a103 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -323,6 +323,7 @@ type GetMempoolEntryResult struct { WTxId string `json:"wtxid"` Fees MempoolFees `json:"fees"` Depends []string `json:"depends"` + SpentBy []string `json:"spentby"` } // GetChainTipsResult models the data returns from the getchaintips command. diff --git a/mempool/mempool.go b/mempool/mempool.go index a2dc5c20..45cf602b 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -1507,36 +1507,42 @@ func (mp *TxPool) MiningDescs() []*mining.TxDesc { // populated btcjson result. // // This function is safe for concurrent access. -func (mp *TxPool) RawMempoolVerbose() map[string]*btcjson.GetRawMempoolVerboseResult { +func (mp *TxPool) RawMempoolVerbose() map[string]*btcjson.GetMempoolEntryResult { mp.mtx.RLock() defer mp.mtx.RUnlock() - result := make(map[string]*btcjson.GetRawMempoolVerboseResult, + result := make(map[string]*btcjson.GetMempoolEntryResult, len(mp.pool)) - bestHeight := mp.cfg.BestHeight() for _, desc := range mp.pool { // Calculate the current priority based on the inputs to // the transaction. Use zero if one or more of the // input transactions can't be found for some reason. tx := desc.Tx - var currentPriority float64 - utxos, err := mp.fetchInputUtxos(tx) - if err == nil { - currentPriority = mining.CalcPriority(tx.MsgTx(), utxos, - bestHeight+1) - } - mpd := &btcjson.GetRawMempoolVerboseResult{ - Size: int32(tx.MsgTx().SerializeSize()), - Vsize: int32(GetTxVirtualSize(tx)), - Weight: int32(blockchain.GetTransactionWeight(tx)), - Fee: btcutil.Amount(desc.Fee).ToBTC(), - Time: desc.Added.Unix(), - Height: int64(desc.Height), - StartingPriority: desc.StartingPriority, - CurrentPriority: currentPriority, - Depends: make([]string, 0), + mpd := &btcjson.GetMempoolEntryResult{ + VSize: int32(GetTxVirtualSize(tx)), + Size: int32(tx.MsgTx().SerializeSize()), + Weight: blockchain.GetTransactionWeight(tx), + Fee: btcutil.Amount(desc.Fee).ToBTC(), + ModifiedFee: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + Time: desc.Added.Unix(), + Height: int64(desc.Height), + DescendantCount: 1, // TODO + DescendantSize: GetTxVirtualSize(tx), // TODO + DescendantFees: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + AncestorCount: 1, // TODO + AncestorSize: GetTxVirtualSize(tx), // TODO + AncestorFees: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + WTxId: desc.Tx.WitnessHash().String(), + Fees: btcjson.MempoolFees{ + Base: btcutil.Amount(desc.Fee).ToBTC(), + Modified: btcutil.Amount(desc.Fee).ToBTC(), // TODO + Ancestor: btcutil.Amount(desc.Fee).ToBTC(), // TODO + Descendant: btcutil.Amount(desc.Fee).ToBTC(), // TODO + }, + Depends: make([]string, 0), // TODO + SpentBy: make([]string, 0), // TODO } for _, txIn := range tx.MsgTx().TxIn { hash := &txIn.PreviousOutPoint.Hash diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index b4070dd7..17d2d452 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -560,7 +560,7 @@ func TestOrphanReject(t *testing.T) { // Ensure no transactions were reported as accepted. if len(acceptedTxns) != 0 { - t.Fatal("ProcessTransaction: reported %d accepted "+ + t.Fatalf("ProcessTransaction: reported %d accepted "+ "transactions from failed orphan attempt", len(acceptedTxns)) } diff --git a/rpcserver.go b/rpcserver.go index f2796ba6..0724a757 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -161,6 +161,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getheaders": handleGetHeaders, "getinfo": handleGetInfo, "getmempoolinfo": handleGetMempoolInfo, + "getmempoolentry": handleGetMempoolEntry, "getmininginfo": handleGetMiningInfo, "getnettotals": handleGetNetTotals, "getnetworkhashps": handleGetNetworkHashPS, @@ -239,8 +240,6 @@ var rpcAskWallet = map[string]struct{}{ // Commands that are currently unimplemented, but should ultimately be. var rpcUnimplemented = map[string]struct{}{ "estimatepriority": {}, - "getchaintips": {}, - "getmempoolentry": {}, "getwork": {}, "preciousblock": {}, } @@ -2483,6 +2482,56 @@ func handleGetMempoolInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct return ret, nil } +// handleGetMempoolEntry implements the getmempoolentry command. +func handleGetMempoolEntry(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + + c := cmd.(*btcjson.GetMempoolEntryCmd) + txHash, err := chainhash.NewHashFromStr(c.TxID) + if err != nil { + if err != nil { + return nil, rpcDecodeHexError(c.TxID) + } + } + + mp := s.cfg.TxMemPool + for _, desc := range mp.TxDescs() { + tx := desc.Tx + if tx.Hash().IsEqual(txHash) { + continue + } + desc.Tx.WitnessHash() + + ret := &btcjson.GetMempoolEntryResult{ + VSize: int32(mempool.GetTxVirtualSize(tx)), + Size: int32(tx.MsgTx().SerializeSize()), + Weight: blockchain.GetTransactionWeight(tx), + Fee: btcutil.Amount(desc.Fee).ToBTC(), + ModifiedFee: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + Time: desc.Added.Unix(), + Height: int64(desc.Height), + DescendantCount: 1, // TODO + DescendantSize: mempool.GetTxVirtualSize(tx), // TODO + DescendantFees: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + AncestorCount: 1, // TODO + AncestorSize: mempool.GetTxVirtualSize(tx), // TODO + AncestorFees: btcutil.Amount(desc.Fee).ToBTC(), // TODO, Deprecated + WTxId: desc.Tx.WitnessHash().String(), + Fees: btcjson.MempoolFees{ + Base: btcutil.Amount(desc.Fee).ToBTC(), + Modified: btcutil.Amount(desc.Fee).ToBTC(), // TODO + Ancestor: btcutil.Amount(desc.Fee).ToBTC(), // TODO + Descendant: btcutil.Amount(desc.Fee).ToBTC(), // TODO + }, + Depends: make([]string, 0), // TODO + SpentBy: make([]string, 0), // TODO + } + + return ret, nil + } + + return nil, rpcNoTxInfoError(txHash) +} + // handleGetMiningInfo implements the getmininginfo command. We only return the // fields that are not related to wallet functionality. func handleGetMiningInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 881cfeb5..4cfde4d3 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -470,6 +470,34 @@ var helpDescsEnUS = map[string]string{ "getmininginforesult-pooledtx": "Number of transactions in the memory pool", "getmininginforesult-testnet": "Whether or not server is using testnet", + "mempoolfees-base": "Transaction fee in LBC", + "mempoolfees-modified": "Transaction fee with fee deltas used for mining priority in LBC", + "mempoolfees-ancestor": "Modified fees (see above) of in-mempool ancestors (including this one) in LBC", + "mempoolfees-descendant": "modified fees (see above) of in-mempool descendants (including this one) in LBC", + + // GetMempoolEntryCmd help. + "getmempoolentry--synopsis": "Returns mempool data for given transaction.", + "getmempoolentry-txid": "The hash of the transaction", + + // GetMempoolEntryResult help. + "getmempoolentryresult-vsize": "Virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted.", + "getmempoolentryresult-size": "(DEPRECATED) same as vsize. ", + "getmempoolentryresult-weight": "Transaction weight as defined in BIP 141.", + "getmempoolentryresult-fee": "(DEPRECATED)Transaction fee in LBC", + "getmempoolentryresult-modifiedfee": "(DEPRECATED)Transaction fee with fee deltas used for mining priority", + "getmempoolentryresult-time": "Local time transaction entered pool in seconds since 1 Jan 1970 GMT", + "getmempoolentryresult-height": "Block height when transaction entered pool", + "getmempoolentryresult-descendantcount": "Number of in-mempool descendant transactions (including this one)", + "getmempoolentryresult-descendantsize": "Virtual transaction size of in-mempool descendants (including this one)", + "getmempoolentryresult-descendantfees": "(DEPRECATED)Modified fees (see above) of in-mempool descendants (including this one)", + "getmempoolentryresult-ancestorcount": "Number of in-mempool ancestor transactions (including this one)", + "getmempoolentryresult-ancestorsize": "Virtual transaction size of in-mempool ancestors (including this one)", + "getmempoolentryresult-ancestorfees": "(DEPRECATED)Modified fees (see above) of in-mempool ancestors (including this one)", + "getmempoolentryresult-wtxid": "hash of serialized transaction, including witness data", + "getmempoolentryresult-fees": "(json object)", + "getmempoolentryresult-depends": "Unconfirmed transactions used as inputs for this transaction", + "getmempoolentryresult-spentby": "Unconfirmed transactions spending outputs from this transaction", + // GetMiningInfoCmd help. "getmininginfo--synopsis": "Returns a JSON object containing mining-related information.", @@ -872,6 +900,7 @@ var rpcResultTypes = map[string][]interface{}{ "gethashespersec": {(*float64)(nil)}, "getheaders": {(*[]string)(nil)}, "getinfo": {(*btcjson.InfoChainResult)(nil)}, + "getmempoolentry": {(*btcjson.GetMempoolEntryResult)(nil)}, "getmempoolinfo": {(*btcjson.GetMempoolInfoResult)(nil)}, "getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)}, "getnettotals": {(*btcjson.GetNetTotalsResult)(nil)}, -- 2.45.2 From 3662f316aba3a89601bc880a57f5fcfe297b3a40 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 20:48:01 -0700 Subject: [PATCH 393/459] [lbry] version: add version package --- version/version.go | 258 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 version/version.go diff --git a/version/version.go b/version/version.go new file mode 100644 index 00000000..a4b33597 --- /dev/null +++ b/version/version.go @@ -0,0 +1,258 @@ +package version + +import ( + "fmt" + "runtime/debug" + "strconv" + "strings" +) + +var appTag = "v0.0.0-local.0" + +// Full returns full version string conforming to semantic versioning 2.0.0 +// spec (http://semver.org/). +// +// Major.Minor.Patch-Prerelease+Buildmeta +// +// Prerelease must be either empty or in the form of Phase.Revision. The Phase +// must be local, dev, alpha, beta, or rc. +// Buildmeta is full length of 40-digit git commit ID with "-dirty" appended +// refelecting uncommited chanegs. +// +// This function relies injected git version tag in the form of: +// +// vMajor.Minor.Patch-Prerelease +// +// The injection can be done with go build flags for example: +// +// go build -ldflags "-X github.com/lbryio/lbcd/version.appTag=v1.2.3-beta.45" +// +// Without explicitly injected tag, a default one - "v0.0.0-local.0" is used +// indicating a local development build. + +// The version is encoded into a int32 numeric form, which imposes valid ranges +// on each component: +// +// Major: 0 - 41 +// Minor: 0 - 99 +// Patch: 0 - 999 +// +// Prerelease: Phase.Revision +// Phase: [ local | dev | alpha | beta | rc | ] +// Revision: 0 - 99 +// +// Buildmeta: CommitID or CommitID-dirty +// +// Examples: +// +// 1.2.3-beta.45+950b68348261e0b4ff288d216269b8ad2a384411 +// 2.6.4-alpha.3+92d00aaee19d1709ae64b36682ae9897ef91a2ca-dirty + +func Full() string { + return parsed.full() +} + +// Numeric returns numeric form of full version (excluding meta) in a 32-bit decimal number. +// See Full() for more details. +func Numeric() int32 { + numeric := parsed.major*100000000 + + parsed.minor*1000000 + + parsed.patch*1000 + + parsed.phase.numeric()*100 + + parsed.revision + + return int32(numeric) +} + +func init() { + + version, prerelease, err := parseTag(appTag) + if err != nil { + panic(fmt.Errorf("parse tag: %s; %w", appTag, err)) + } + + major, minor, patch, err := parseVersion(version) + if err != nil { + panic(fmt.Errorf("parse version: %s; %w", version, err)) + } + + phase, revision, err := parsePrerelease(prerelease) + if err != nil { + panic(fmt.Errorf("parse prerelease: %s; %w", prerelease, err)) + } + + info, ok := debug.ReadBuildInfo() + if !ok { + panic(fmt.Errorf("binary must be built with Go 1.18+ with module support")) + } + + var commit string + var modified bool + for _, s := range info.Settings { + if s.Key == "vcs.revision" { + commit = s.Value + } + if s.Key == "vcs.modified" && s.Value == "true" { + modified = true + } + } + + parsed = parsedVersion{ + version: version, + major: major, + minor: minor, + patch: patch, + + prerelease: prerelease, + phase: phase, + revision: revision, + + commit: commit, + modified: modified, + } +} + +var parsed parsedVersion + +type parsedVersion struct { + version string + // Semantic Version + major int + minor int + patch int + + // Prerelease + prerelease string + phase releasePhase + revision int + + // Build Metadata + commit string + modified bool +} + +func (v parsedVersion) buildmeta() string { + if !v.modified { + return v.commit + } + return v.commit + "-dirty" +} + +func (v parsedVersion) full() string { + return fmt.Sprintf("%s-%s+%s", v.version, v.prerelease, v.buildmeta()) +} + +func parseTag(tag string) (version string, prerelease string, err error) { + + if len(tag) == 0 || tag[0] != 'v' { + return "", "", fmt.Errorf("tag must be prefixed with v; %s", tag) + } + + strs := strings.Split(tag[1:], "-") + + if len(strs) != 2 { + return "", "", fmt.Errorf("tag must be in the form of Version.Revision; %s", tag) + } + + version = strs[0] + prerelease = strs[1] + + return version, prerelease, nil +} + +func parseVersion(ver string) (major int, minor int, patch int, err error) { + + strs := strings.Split(ver, ".") + + if len(strs) != 3 { + return major, minor, patch, fmt.Errorf("invalid format; must be in the form of Major.Minor.Patch") + } + + major, err = strconv.Atoi(strs[0]) + if err != nil { + return major, minor, patch, fmt.Errorf("invalid major: %s", strs[0]) + } + if major < 0 || major > 41 { + return major, minor, patch, fmt.Errorf("major must between 0 - 41; got %d", major) + } + + minor, err = strconv.Atoi(strs[1]) + if err != nil { + return major, minor, patch, fmt.Errorf("invalid minor: %s", strs[1]) + } + if minor < 0 || minor > 99 { + return major, minor, patch, fmt.Errorf("minor must between 0 - 99; got %d", minor) + } + + patch, err = strconv.Atoi(strs[2]) + if err != nil { + return major, minor, patch, fmt.Errorf("invalid patch: %s", strs[2]) + } + if patch < 0 || patch > 999 { + return major, minor, patch, fmt.Errorf("patch must between 0 - 999; got %d", patch) + } + + return major, minor, patch, nil +} + +func parsePrerelease(pre string) (phase releasePhase, revision int, err error) { + + phase = Unkown + + if pre == "" { + return GA, 0, nil + } + + strs := strings.Split(pre, ".") + if len(strs) != 2 { + return phase, revision, fmt.Errorf("prerelease must be in the form of Phase.Revision; got: %s", pre) + } + + phase = releasePhase(strs[0]) + if phase.numeric() == -1 { + return phase, revision, fmt.Errorf("phase must be local, dev, alpha, beta, or rc; got: %s", strs[0]) + } + + revision, err = strconv.Atoi(strs[1]) + if err != nil { + return phase, revision, fmt.Errorf("invalid revision: %s", strs[0]) + } + if revision < 0 || revision > 99 { + return phase, revision, fmt.Errorf("revision must between 0 - 999; got %d", revision) + } + + return phase, revision, nil +} + +type releasePhase string + +const ( + Unkown releasePhase = "unkown" + Local releasePhase = "local" + Dev releasePhase = "dev" + Alpha releasePhase = "alpha" + Beta releasePhase = "beta" + RC releasePhase = "rc" + GA releasePhase = "" +) + +func (p releasePhase) numeric() int { + + switch p { + case Local: + return 0 + case Dev: + return 1 + case Alpha: + return 2 + case Beta: + return 3 + case RC: + return 4 + case GA: + return 5 + } + + // Unknown phase + return -1 +} -- 2.45.2 From 7c5a2c6f58db001d497545830ef7d1eaeee2f390 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 20:50:17 -0700 Subject: [PATCH 394/459] [lbry] version: update codebase to use version package --- cmd/lbcctl/config.go | 3 +- cmd/lbcctl/version.go | 75 ----------------------------------------- config.go | 3 +- lbcd.go | 3 +- rpcserver.go | 5 +-- server.go | 3 +- service_windows.go | 4 ++- version.go | 77 ------------------------------------------- 8 files changed, 14 insertions(+), 159 deletions(-) delete mode 100644 cmd/lbcctl/version.go delete mode 100644 version.go diff --git a/cmd/lbcctl/config.go b/cmd/lbcctl/config.go index ef961df9..e31ecef6 100644 --- a/cmd/lbcctl/config.go +++ b/cmd/lbcctl/config.go @@ -16,6 +16,7 @@ import ( flags "github.com/jessevdk/go-flags" "github.com/lbryio/lbcd/btcjson" "github.com/lbryio/lbcd/chaincfg" + "github.com/lbryio/lbcd/version" btcutil "github.com/lbryio/lbcutil" ) @@ -214,7 +215,7 @@ func loadConfig() (*config, []string, error) { appName = strings.TrimSuffix(appName, filepath.Ext(appName)) usageMessage := fmt.Sprintf("Use %s -h to show options", appName) if preCfg.ShowVersion { - fmt.Println(appName, "version", version()) + fmt.Println(appName, "version", version.Full()) os.Exit(0) } diff --git a/cmd/lbcctl/version.go b/cmd/lbcctl/version.go deleted file mode 100644 index fcd70ce4..00000000 --- a/cmd/lbcctl/version.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2013 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package main - -import ( - "bytes" - "fmt" - "strings" -) - -// semanticAlphabet -const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" - -// These constants define the application version and follow the semantic -// versioning 2.0.0 spec (http://semver.org/). -const ( - appMajor uint = 0 - appMinor uint = 22 - appPatch uint = 100 - - // appPreRelease MUST only contain characters from semanticAlphabet - // per the semantic versioning spec. - appPreRelease = "beta" -) - -// appBuild is defined as a variable so it can be overridden during the build -// process with '-ldflags "-X main.appBuild foo' if needed. It MUST only -// contain characters from semanticAlphabet per the semantic versioning spec. -var appBuild string - -// version returns the application version as a properly formed string per the -// semantic versioning 2.0.0 spec (http://semver.org/). -func version() string { - // Start with the major, minor, and patch versions. - version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch) - - // Append pre-release version if there is one. The hyphen called for - // by the semantic versioning spec is automatically appended and should - // not be contained in the pre-release string. The pre-release version - // is not appended if it contains invalid characters. - preRelease := normalizeVerString(appPreRelease) - if preRelease != "" { - version = fmt.Sprintf("%s-%s", version, preRelease) - } - - // Append build metadata if there is any. The plus called for - // by the semantic versioning spec is automatically appended and should - // not be contained in the build metadata string. The build metadata - // string is not appended if it contains invalid characters. - build := normalizeVerString(appBuild) - if build != "" { - version = fmt.Sprintf("%s+%s", version, build) - } - - return version -} - -// normalizeVerString returns the passed string stripped of all characters which -// are not valid according to the semantic versioning guidelines for pre-release -// version and build metadata strings. In particular they MUST only contain -// characters in semanticAlphabet. -func normalizeVerString(str string) string { - var result bytes.Buffer - for _, r := range str { - if strings.ContainsRune(semanticAlphabet, r) { - // Ignoring the error here since it can only fail if - // the the system is out of memory and there are much - // bigger issues at that point. - _, _ = result.WriteRune(r) - } - } - return result.String() -} diff --git a/config.go b/config.go index 93e83e9b..fe77a818 100644 --- a/config.go +++ b/config.go @@ -32,6 +32,7 @@ import ( _ "github.com/lbryio/lbcd/database/ffldb" "github.com/lbryio/lbcd/mempool" "github.com/lbryio/lbcd/peer" + "github.com/lbryio/lbcd/version" "github.com/lbryio/lbcd/wire" btcutil "github.com/lbryio/lbcutil" ) @@ -469,7 +470,7 @@ func loadConfig() (*config, []string, error) { appName = strings.TrimSuffix(appName, filepath.Ext(appName)) usageMessage := fmt.Sprintf("Use %s -h to show usage", appName) if preCfg.ShowVersion { - fmt.Println(appName, "version", version()) + fmt.Println(appName, "version", version.Full()) os.Exit(0) } diff --git a/lbcd.go b/lbcd.go index e47efdb8..1110eeab 100644 --- a/lbcd.go +++ b/lbcd.go @@ -19,6 +19,7 @@ import ( "github.com/lbryio/lbcd/claimtrie/param" "github.com/lbryio/lbcd/database" "github.com/lbryio/lbcd/limits" + "github.com/lbryio/lbcd/version" "github.com/felixge/fgprof" ) @@ -64,7 +65,7 @@ func btcdMain(serverChan chan<- *server) error { defer btcdLog.Info("Shutdown complete") // Show version at startup. - btcdLog.Infof("Version %s", version()) + btcdLog.Infof("Version %s", version.Full()) // Enable http profiling server if requested. if cfg.Profile != "" { diff --git a/rpcserver.go b/rpcserver.go index 0724a757..fddfaaa3 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -42,6 +42,7 @@ import ( "github.com/lbryio/lbcd/mining/cpuminer" "github.com/lbryio/lbcd/peer" "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/version" "github.com/lbryio/lbcd/wire" btcutil "github.com/lbryio/lbcutil" ) @@ -2451,7 +2452,7 @@ func handleGetHeaders(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) func handleGetInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { best := s.cfg.Chain.BestSnapshot() ret := &btcjson.InfoChainResult{ - Version: int32(1000000*appMajor + 10000*appMinor + 100*appPatch), + Version: version.Numeric(), ProtocolVersion: int32(maxProtocolVersion), Blocks: best.Height, TimeOffset: int64(s.cfg.TimeSource.Offset().Seconds()), @@ -2750,7 +2751,7 @@ func handleGetNetworkInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct reply := &btcjson.GetNetworkInfoResult{ ProtocolVersion: int32(wire.ProtocolVersion), - Version: versionNumeric(), + Version: version.Numeric(), Connections: s.cfg.ConnMgr.ConnectedCount(), IncrementalFee: cfg.MinRelayTxFee, LocalAddresses: localAddrs, diff --git a/server.go b/server.go index 305b7852..82da9ee1 100644 --- a/server.go +++ b/server.go @@ -39,6 +39,7 @@ import ( "github.com/lbryio/lbcd/netsync" "github.com/lbryio/lbcd/peer" "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/version" "github.com/lbryio/lbcd/wire" "github.com/lbryio/lbcutil" btcutil "github.com/lbryio/lbcutil" @@ -71,7 +72,7 @@ var ( // userAgentVersion is the user agent version and is used to help // identify ourselves to other bitcoin peers. - userAgentVersion = fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch) + userAgentVersion = version.Full() ) // zeroHash is the zero value hash (all zeros). It is defined as a convenience. diff --git a/service_windows.go b/service_windows.go index 378c9204..448720b7 100644 --- a/service_windows.go +++ b/service_windows.go @@ -10,6 +10,8 @@ import ( "path/filepath" "time" + "github.com/lbryio/lbcd/version" + "github.com/btcsuite/winsvc/eventlog" "github.com/btcsuite/winsvc/mgr" "github.com/btcsuite/winsvc/svc" @@ -36,7 +38,7 @@ var elog *eventlog.Log // been started to the Windows event log. func logServiceStartOfDay(srvr *server) { var message string - message += fmt.Sprintf("Version %s\n", version()) + message += fmt.Sprintf("Version %s\n", version.Full()) message += fmt.Sprintf("Configuration directory: %s\n", defaultHomeDir) message += fmt.Sprintf("Configuration file: %s\n", cfg.ConfigFile) message += fmt.Sprintf("Data directory: %s\n", cfg.DataDir) diff --git a/version.go b/version.go deleted file mode 100644 index 23f1f3de..00000000 --- a/version.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2013-2014 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package main - -import ( - "bytes" - "fmt" - "strings" -) - -// semanticAlphabet -const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" - -// These constants define the application version and follow the semantic -// versioning 2.0.0 spec (http://semver.org/). -const ( - appMajor uint = 0 - appMinor uint = 22 - appPatch uint = 0 - - // appPreRelease MUST only contain characters from semanticAlphabet - // per the semantic versioning spec. - appPreRelease = "beta" -) - -// appBuild is defined as a variable so it can be overridden during the build -// process with '-ldflags "-X main.appBuild foo' if needed. It MUST only -// contain characters from semanticAlphabet per the semantic versioning spec. -var appBuild string - -// version returns the application version as a properly formed string per the -// semantic versioning 2.0.0 spec (http://semver.org/). -func version() string { - // Start with the major, minor, and patch versions. - version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch) - - // Append pre-release version if there is one. The hyphen called for - // by the semantic versioning spec is automatically appended and should - // not be contained in the pre-release string. The pre-release version - // is not appended if it contains invalid characters. - preRelease := normalizeVerString(appPreRelease) - if preRelease != "" { - version = fmt.Sprintf("%s-%s", version, preRelease) - } - - // Append build metadata if there is any. The plus called for - // by the semantic versioning spec is automatically appended and should - // not be contained in the build metadata string. The build metadata - // string is not appended if it contains invalid characters. - build := normalizeVerString(appBuild) - if build != "" { - version = fmt.Sprintf("%s+%s", version, build) - } - - return version -} - -// Numeric returns the application version as an integer. -func versionNumeric() int32 { - return int32(2 ^ appMajor*3 ^ appMinor*5 ^ appPatch) -} - -// normalizeVerString returns the passed string stripped of all characters which -// are not valid according to the semantic versioning guidelines for pre-release -// version and build metadata strings. In particular they MUST only contain -// characters in semanticAlphabet. -func normalizeVerString(str string) string { - var result bytes.Buffer - for _, r := range str { - if strings.ContainsRune(semanticAlphabet, r) { - result.WriteRune(r) - } - } - return result.String() -} -- 2.45.2 From bf7a513006682829d0e4bdb8e4b3754fab8b2a78 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 22:41:59 -0700 Subject: [PATCH 395/459] [lbry] go mod: update go modules --- go.mod | 54 ++++- go.sum | 658 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 669 insertions(+), 43 deletions(-) diff --git a/go.mod b/go.mod index 767c2740..852c0428 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,56 @@ -module github.com/btcsuite/btcd +module github.com/lbryio/lbcd + +go 1.18 require ( github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f - github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd - github.com/btcsuite/goleveldb v1.0.0 github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 github.com/btcsuite/winsvc v1.0.0 + github.com/cockroachdb/errors v1.9.0 + github.com/cockroachdb/pebble v0.0.0-20220523221036-bb2c1501ac23 github.com/davecgh/go-spew v1.1.1 - github.com/decred/dcrd/lru v1.0.0 - github.com/jessevdk/go-flags v1.4.0 + github.com/decred/dcrd/lru v1.1.1 + github.com/felixge/fgprof v0.9.2 + github.com/jessevdk/go-flags v1.5.0 github.com/jrick/logrotate v1.0.0 - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect - golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 + github.com/lbryio/lbcutil v1.0.202-rc3 + github.com/pkg/errors v0.9.1 + github.com/shirou/gopsutil/v3 v3.22.4 + github.com/spf13/cobra v1.1.3 + github.com/stretchr/testify v1.7.1 + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/vmihailenco/msgpack/v5 v5.3.2 + golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 ) -go 1.16 +require ( + github.com/DataDog/zstd v1.5.2 // indirect + github.com/aead/siphash v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect + github.com/cockroachdb/redact v1.1.3 // indirect + github.com/codahale/hdrhistogram v0.9.0 // indirect + github.com/getsentry/sentry-go v0.13.0 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/pprof v0.0.0-20220520215854-d04f2422c8a1 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/kkdai/bstream v1.0.0 // indirect + github.com/klauspost/compress v1.15.4 // indirect + github.com/kr/pretty v0.3.0 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect + github.com/rogpeppe/go-internal v1.8.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/tklauser/go-sysconf v0.3.10 // indirect + github.com/tklauser/numcpus v0.5.0 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect + golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf // indirect + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) diff --git a/go.sum b/go.sum index e9ee276d..9079426b 100644 --- a/go.sum +++ b/go.sum @@ -1,107 +1,695 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0 h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/datadriven v1.0.1-0.20211007161720-b558070c3be0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/datadriven v1.0.1-0.20220214170620-9913f5bc19b7/go.mod h1:hi0MtSY3AYDQNDi83kDkMH5/yqM/CsIrsOITkSoH7KI= +github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= +github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= +github.com/cockroachdb/errors v1.8.8/go.mod h1:z6VnEL3hZ/2ONZEvG7S5Ym0bU2AqPcEKnIiA1wbsSu0= +github.com/cockroachdb/errors v1.9.0 h1:B48dYem5SlAY7iU8AKsgedb4gH6mo+bDkbtLIvM/a88= +github.com/cockroachdb/errors v1.9.0/go.mod h1:vaNcEYYqbIqB5JhKBhFV9CneUqeuEbB2OYJBK4GBNYQ= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f h1:6jduT9Hfc0njg5jJ1DdKCFPdMBrp/mdZfCpa5h+WM74= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v0.0.0-20220523221036-bb2c1501ac23 h1:/Pvbuwd61qRxNCIpSIWbx7Oqy1tinfErdetF91DU9gQ= +github.com/cockroachdb/pebble v0.0.0-20220523221036-bb2c1501ac23/go.mod h1:buxOO9GBtOcq1DiXDpIPYrmxY020K2A8lOrwno5FetU= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codahale/hdrhistogram v0.9.0 h1:9GjrtRI+mLEFPtTfR/AZhcxp+Ii8NZYWq5104FbZQY0= +github.com/codahale/hdrhistogram v0.9.0/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/decred/dcrd/lru v1.1.1 h1:kWFDaW0OWx6AD6Ki342c+JPmHbiVdE6rK81pT3fuo/Y= +github.com/decred/dcrd/lru v1.1.1/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/felixge/fgprof v0.9.2 h1:tAMHtWMyl6E0BimjVbFt7fieU6FpjttsZN7j0wT5blc= +github.com/felixge/fgprof v0.9.2/go.mod h1:+VNi+ZXtHIQ6wIw6bUT8nXQRefQflWECoFyRealT5sg= +github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo= +github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/pprof v0.0.0-20220520215854-d04f2422c8a1 h1:K4bn56FHdjFCfjSo3wWaD6rJL8r9yvmmncJNMhdkKrw= +github.com/google/pprof v0.0.0-20220520215854-d04f2422c8a1/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v1.0.0 h1:Se5gHwgp2VT2uHfDrkbbgbgEvV9cimLELwrPJctSjg8= +github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.15.4 h1:1kn4/7MepF/CHmYub99/nNX8az0IJjfSOU/jbnTVfqQ= +github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/lbryio/lbcutil v1.0.202-rc3 h1:J7zYnIj3iN/ndPYKqMKBukLaLM1GhCEaiaMOYIMdUCU= +github.com/lbryio/lbcutil v1.0.202-rc3/go.mod h1:LGPtVBBzh4cFXfLFb8ginlFcbA2QwumLNFd0yk/as2o= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 h1:aczX6NMOtt6L4YT0fQvKkDK6LZEtdOso9sUH89V1+P0= +github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281/go.mod h1:lc+czkgO/8F7puNki5jk8QyujbfK1LOT7Wl0ON2hxyk= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= +github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil/v3 v3.22.4 h1:srAQaiX6jX/cYL6q29aE0m8lOskT9CurZ9N61YR3yoI= +github.com/shirou/gopsutil/v3 v3.22.4/go.mod h1:D01hZJ4pVHPpCTZ3m3T2+wDF2YAGfd+H4ifUguaQzHM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +github.com/tklauser/numcpus v0.5.0 h1:ooe7gN0fg6myJ0EKoTAf5hebTZrH52px3New/D9iJ+A= +github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vmihailenco/msgpack/v5 v5.3.2 h1:MsXyN2rqdM8NM0lLiIpTn610e8Zcoj8ZuHxsMOi9qhI= +github.com/vmihailenco/msgpack/v5 v5.3.2/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 h1:SLP7Q4Di66FONjDJbCYrCRrh97focO6sLogHO7/g8F0= +golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf h1:oXVg4h2qJDd9htKxb5SCpFBHLipW6hXmL3qpUixS2jw= +golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf/go.mod h1:yh0Ynu2b5ZUe3MQfp2nM0ecK7wsgouWTDN0FNeJuIys= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -- 2.45.2 From 3cb961257cb348a3caf4267308cbe22cb7a3793f Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 22:47:49 -0700 Subject: [PATCH 396/459] [lbry] ci: fixed various lint errors --- blockchain/checkpoints.go | 3 ++- blockchain/validate.go | 5 +---- btcec/genprecomps.go | 1 + btcec/gensecp256k1.go | 1 + btcec/precompute.go | 2 +- database/ffldb/db.go | 14 +++++++------- database/ffldb/dbcache.go | 6 +++--- database/ffldb/ldbtreapiter.go | 4 ++-- database/ffldb/whitebox_test.go | 4 ++-- limits/limits_unix.go | 1 + signalsigterm.go | 1 + upnp.go | 4 ++-- 12 files changed, 24 insertions(+), 22 deletions(-) diff --git a/blockchain/checkpoints.go b/blockchain/checkpoints.go index a82d70dd..e9b2d5a2 100644 --- a/blockchain/checkpoints.go +++ b/blockchain/checkpoints.go @@ -172,7 +172,8 @@ func (b *BlockChain) findPreviousCheckpoint() (*blockNode, error) { func isNonstandardTransaction(tx *btcutil.Tx) bool { // Check all of the output public key scripts for non-standard scripts. for _, txOut := range tx.MsgTx().TxOut { - scriptClass := txscript.GetScriptClass(txOut.PkScript) + stripped := txscript.StripClaimScriptPrefix(txOut.PkScript) + scriptClass := txscript.GetScriptClass(stripped) if scriptClass == txscript.NonStandardTy { return true } diff --git a/blockchain/validate.go b/blockchain/validate.go index 19183aa9..85946611 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -224,10 +224,7 @@ func withinLevelBounds(reduction int64, lv int64) bool { return false } reduction++ - if ((reduction*reduction + reduction) >> 1) <= lv { - return false - } - return true + return ((reduction*reduction + reduction) >> 1) > lv } // CheckTransactionSanity performs some preliminary checks on a transaction to diff --git a/btcec/genprecomps.go b/btcec/genprecomps.go index f09ab311..ea40ceac 100644 --- a/btcec/genprecomps.go +++ b/btcec/genprecomps.go @@ -5,6 +5,7 @@ // This file is ignored during the regular build due to the following build tag. // It is called by go generate and used to automatically generate pre-computed // tables used to accelerate operations. +//go:build ignore // +build ignore package main diff --git a/btcec/gensecp256k1.go b/btcec/gensecp256k1.go index 1928702d..e079f553 100644 --- a/btcec/gensecp256k1.go +++ b/btcec/gensecp256k1.go @@ -4,6 +4,7 @@ // This file is ignored during the regular build due to the following build tag. // This build tag is set during go generate. +//go:build gensecp256k1 // +build gensecp256k1 package btcec diff --git a/btcec/precompute.go b/btcec/precompute.go index 034cd553..3d2eedbb 100644 --- a/btcec/precompute.go +++ b/btcec/precompute.go @@ -12,7 +12,7 @@ import ( "strings" ) -//go:generate go run -tags gensecp256k1 genprecomps.go +//go:rm -f gensecp256k1.go; generate go run -tags gensecp256k1 genprecomps.go // loadS256BytePoints decompresses and deserializes the pre-computed byte points // used to accelerate scalar base multiplication for the secp256k1 curve. This diff --git a/database/ffldb/db.go b/database/ffldb/db.go index ee6d55f0..843ef6bb 100644 --- a/database/ffldb/db.go +++ b/database/ffldb/db.go @@ -14,18 +14,18 @@ import ( "sort" "sync" - "github.com/btcsuite/goleveldb/leveldb" - "github.com/btcsuite/goleveldb/leveldb/comparer" - ldberrors "github.com/btcsuite/goleveldb/leveldb/errors" - "github.com/btcsuite/goleveldb/leveldb/filter" - "github.com/btcsuite/goleveldb/leveldb/iterator" - "github.com/btcsuite/goleveldb/leveldb/opt" - "github.com/btcsuite/goleveldb/leveldb/util" "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/database" "github.com/lbryio/lbcd/database/internal/treap" "github.com/lbryio/lbcd/wire" btcutil "github.com/lbryio/lbcutil" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/comparer" + ldberrors "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/filter" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/util" ) const ( diff --git a/database/ffldb/dbcache.go b/database/ffldb/dbcache.go index 1bc21a35..eff239c6 100644 --- a/database/ffldb/dbcache.go +++ b/database/ffldb/dbcache.go @@ -10,10 +10,10 @@ import ( "sync" "time" - "github.com/btcsuite/goleveldb/leveldb" - "github.com/btcsuite/goleveldb/leveldb/iterator" - "github.com/btcsuite/goleveldb/leveldb/util" "github.com/lbryio/lbcd/database/internal/treap" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/util" ) const ( diff --git a/database/ffldb/ldbtreapiter.go b/database/ffldb/ldbtreapiter.go index 0a552633..2073abbe 100644 --- a/database/ffldb/ldbtreapiter.go +++ b/database/ffldb/ldbtreapiter.go @@ -5,9 +5,9 @@ package ffldb import ( - "github.com/btcsuite/goleveldb/leveldb/iterator" - "github.com/btcsuite/goleveldb/leveldb/util" "github.com/lbryio/lbcd/database/internal/treap" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/util" ) // ldbTreapIter wraps a treap iterator to provide the additional functionality diff --git a/database/ffldb/whitebox_test.go b/database/ffldb/whitebox_test.go index 15c83cec..31a8ab34 100644 --- a/database/ffldb/whitebox_test.go +++ b/database/ffldb/whitebox_test.go @@ -17,11 +17,11 @@ import ( "path/filepath" "testing" - "github.com/btcsuite/goleveldb/leveldb" - ldberrors "github.com/btcsuite/goleveldb/leveldb/errors" "github.com/lbryio/lbcd/database" "github.com/lbryio/lbcd/wire" btcutil "github.com/lbryio/lbcutil" + "github.com/syndtr/goleveldb/leveldb" + ldberrors "github.com/syndtr/goleveldb/leveldb/errors" ) var ( diff --git a/limits/limits_unix.go b/limits/limits_unix.go index e55a1c28..f8511458 100644 --- a/limits/limits_unix.go +++ b/limits/limits_unix.go @@ -2,6 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. +//go:build !windows && !plan9 // +build !windows,!plan9 package limits diff --git a/signalsigterm.go b/signalsigterm.go index 83165501..63bdb9c0 100644 --- a/signalsigterm.go +++ b/signalsigterm.go @@ -2,6 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris // +build darwin dragonfly freebsd linux netbsd openbsd solaris package main diff --git a/upnp.go b/upnp.go index 402924f5..d07d5ce9 100644 --- a/upnp.go +++ b/upnp.go @@ -136,7 +136,7 @@ func Discover() (nat NAT, err error) { return } err = errors.New("UPnP port discovery failed") - return + return nat, err } // service represents the Service type in an UPnP xml description. @@ -269,7 +269,7 @@ func getServiceURL(rootURL string) (url string, err error) { return } url = combineURL(rootURL, d.ControlURL) - return + return url, err } // combineURL appends subURL onto rootURL. -- 2.45.2 From badb894e3aacb027d00cf21bb2f5aa6f3e4e1196 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 22:43:25 -0700 Subject: [PATCH 397/459] [lbry] ci: update .gitignore --- .gitignore | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.gitignore b/.gitignore index c3effe5f..2095e17a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Databases btcd.db +lbcd.db *-shm *-wal @@ -33,6 +34,22 @@ _testmain.go *.exe +.DS_Store + # Code coverage files profile.tmp profile.cov + +# IDE +.idea +.vscode + +# Binaries +btcd +btcctl +lbcd +lbcctl + +# CI artifacts +dist +debug -- 2.45.2 From 76e482bb73b4929cb365b0aa34b3453f98005eee Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 22:46:07 -0700 Subject: [PATCH 398/459] [lbry] ci: remove release/release.sh --- release/release.sh | 108 --------------------------------------------- 1 file changed, 108 deletions(-) delete mode 100755 release/release.sh diff --git a/release/release.sh b/release/release.sh deleted file mode 100755 index de49f641..00000000 --- a/release/release.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Company 0, LLC. -# Copyright (c) 2016-2020 The btcsuite developers -# Use of this source code is governed by an ISC -# license that can be found in the LICENSE file. - -# Simple bash script to build basic btcd tools for all the platforms we support -# with the golang cross-compiler. - -set -e - -# If no tag specified, use date + version otherwise use tag. -if [[ $1x = x ]]; then - DATE=`date +%Y%m%d` - VERSION="01" - TAG=$DATE-$VERSION -else - TAG=$1 -fi - -go mod vendor -tar -cvzf vendor.tar.gz vendor - -PACKAGE=btcd -MAINDIR=$PACKAGE-$TAG -mkdir -p $MAINDIR - -cp vendor.tar.gz $MAINDIR/ -rm vendor.tar.gz -rm -r vendor - -PACKAGESRC="$MAINDIR/$PACKAGE-source-$TAG.tar" -git archive -o $PACKAGESRC HEAD -gzip -f $PACKAGESRC > "$PACKAGESRC.gz" - -cd $MAINDIR - -# If BTCDBUILDSYS is set the default list is ignored. Useful to release -# for a subset of systems/architectures. -SYS=${BTCDBUILDSYS:-" - darwin-amd64 - dragonfly-amd64 - freebsd-386 - freebsd-amd64 - freebsd-arm - illumos-amd64 - linux-386 - linux-amd64 - linux-armv6 - linux-armv7 - linux-arm64 - linux-ppc64 - linux-ppc64le - linux-mips - linux-mipsle - linux-mips64 - linux-mips64le - linux-s390x - netbsd-386 - netbsd-amd64 - netbsd-arm - netbsd-arm64 - openbsd-386 - openbsd-amd64 - openbsd-arm - openbsd-arm64 - solaris-amd64 - windows-386 - windows-amd64 -"} - -# Use the first element of $GOPATH in the case where GOPATH is a list -# (something that is totally allowed). -PKG="github.com/btcsuite/btcd" -COMMIT=$(git describe --abbrev=40 --dirty) - -for i in $SYS; do - OS=$(echo $i | cut -f1 -d-) - ARCH=$(echo $i | cut -f2 -d-) - ARM= - - if [[ $ARCH = "armv6" ]]; then - ARCH=arm - ARM=6 - elif [[ $ARCH = "armv7" ]]; then - ARCH=arm - ARM=7 - fi - - mkdir $PACKAGE-$i-$TAG - cd $PACKAGE-$i-$TAG - - echo "Building:" $OS $ARCH $ARM - env CGO_ENABLED=0 GOOS=$OS GOARCH=$ARCH GOARM=$ARM go build -v -trimpath -ldflags="-s -w -buildid=" github.com/btcsuite/btcd - env CGO_ENABLED=0 GOOS=$OS GOARCH=$ARCH GOARM=$ARM go build -v -trimpath -ldflags="-s -w -buildid=" github.com/btcsuite/btcd/cmd/btcctl - cd .. - - if [[ $OS = "windows" ]]; then - zip -r $PACKAGE-$i-$TAG.zip $PACKAGE-$i-$TAG - else - tar -cvzf $PACKAGE-$i-$TAG.tar.gz $PACKAGE-$i-$TAG - fi - - rm -r $PACKAGE-$i-$TAG -done - -shasum -a 256 * > manifest-$TAG.txt -- 2.45.2 From d4cddda35c0679522162e13a9e2002873a66eeb6 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 24 May 2022 00:41:56 -0700 Subject: [PATCH 399/459] [lbry] ci: update gocelan.sh --- goclean.sh | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/goclean.sh b/goclean.sh index dad9f8f1..7540af6f 100755 --- a/goclean.sh +++ b/goclean.sh @@ -10,10 +10,4 @@ set -ex env GORACE="halt_on_error=1" go test -race -tags="rpctest" -covermode atomic -coverprofile=profile.cov ./... - -# Automatic checks -golangci-lint run --deadline=10m --disable-all \ ---enable=gofmt \ ---enable=vet \ ---enable=gosimple \ ---enable=unconvert +go test -bench=. -benchtime=4000x ./claimtrie/ -- 2.45.2 From 7ee3d7d26bfe1ae1a7ac1561d2de9b61b56f00fa Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 22:40:51 -0700 Subject: [PATCH 400/459] [lbry] ci: add .golangci-lint.yml --- .golangci.yml | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 .golangci.yml diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..a32e6267 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,152 @@ +linters-settings: + depguard: + list-type: blacklist + packages: + # logging is allowed only by logutils.Log, logrus + # is allowed to use only in logutils package + - github.com/sirupsen/logrus + packages-with-error-message: + - github.com/sirupsen/logrus: "logging is allowed only by logutils.Log" + dupl: + threshold: 100 + funlen: + lines: 100 + statements: 50 + gci: + local-prefixes: github.com/golangci/golangci-lint + goconst: + min-len: 2 + min-occurrences: 2 + gocritic: + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + disabled-checks: + - dupImport # https://github.com/go-critic/go-critic/issues/845 + - ifElseChain + - octalLiteral + - whyNoLint + - wrapperFunc + gocyclo: + min-complexity: 15 + goimports: + local-prefixes: github.com/golangci/golangci-lint + gomnd: + settings: + mnd: + # don't include the "operation" and "assign" + checks: + - argument + - case + - condition + - return + govet: + check-shadowing: true + settings: + printf: + funcs: + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + lll: + line-length: 140 + maligned: + suggest-new: true + misspell: + locale: US + nolintlint: + allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space) + allow-unused: false # report any unused nolint directives + require-explanation: false # don't require an explanation for nolint directives + require-specific: false # don't require nolint directives to be specific about which linter is being skipped + +linters: + disable-all: true + enable: + - asciicheck + - bodyclose + # - deadcode + - depguard + # - dogsled + # - dupl + # - errcheck + # - exhaustive + - exportloopref + # - funlen + # - gochecknoglobals + # - gochecknoinits + # - gocognit + # - goconst + # - gocritic + # - gocyclo + # - godot + # - godox + # - goerr113 + - gofmt + - goimports + # - gomnd + - goprintffuncname + # - gosec + # - gosimple + # - govet + # - ineffassign + # - interfacer + # - lll + # - maligned + # - misspell + - nakedret + # - nestif + # - noctx + # - nolintlint + # - prealloc + - rowserrcheck + # - revive + # - scopelint + # - staticcheck + # - structcheck + # - stylecheck + # - testpackage + # - typecheck + - unconvert + # - unparam + # - unused + # - varcheck + # - whitespace + # - wsl + +issues: + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + - path: _test\.go + linters: + - gomnd + + - path: pkg/golinters/errcheck.go + text: "SA1019: errCfg.Exclude is deprecated: use ExcludeFunctions instead" + - path: pkg/commands/run.go + text: "SA1019: lsc.Errcheck.Exclude is deprecated: use ExcludeFunctions instead" + + # TODO must be removed after the release of the next version (v1.41.0) + - path: pkg/commands/run.go + linters: + - gomnd + # TODO must be removed after the release of the next version (v1.41.0) + - path: pkg/golinters/nolintlint/nolintlint.go + linters: + - gomnd + # TODO must be removed after the release of the next version (v1.41.0) + - path: pkg/printers/tab.go + linters: + - gomnd + + +run: + skip-dirs: + - test/testdata_etc + - internal/cache + - internal/renameio + - internal/robustio -- 2.45.2 From 2cfa235a33c39b24e425e9f62748be06f4742b67 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 22:44:16 -0700 Subject: [PATCH 401/459] [lbry] ci: update Dockerfile Use $ARCH/debian:bullseye-20220418-slim as base image --- Dockerfile | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index ddd4f647..912841ec 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,30 +1,24 @@ -# This Dockerfile builds btcd from source and creates a small (55 MB) docker container based on alpine linux. +# This Dockerfile builds lbcd from source and creates a small (55 MB) docker container based on alpine linux. # -# Clone this repository and run the following command to build and tag a fresh btcd amd64 container: +# Clone this repository and run the following command to build and tag a fresh lbcd amd64 container: # -# docker build . -t yourregistry/btcd +# docker build . -t yourregistry/lbcd # # You can use the following command to buid an arm64v8 container: # -# docker build . -t yourregistry/btcd --build-arg ARCH=arm64v8 +# docker build . -t yourregistry/lbcd --build-arg ARCH=arm64v8 # # For more information how to use this docker image visit: -# https://github.com/btcsuite/btcd/tree/master/docs +# https://github.com/lbryio/lbcd/tree/master/docs # -# 9246 Mainnet Bitcoin peer-to-peer port +# 9246 Mainnet LBRY peer-to-peer port # 9245 Mainet RPC port ARG ARCH=amd64 -# using the SHA256 instead of tags -# https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests -# https://cloud.google.com/architecture/using-container-images -# https://github.com/google/go-containerregistry/blob/main/cmd/crane/README.md -# ➜ ~ crane digest golang:1.16-alpine3.12 -# sha256:db2475a1dbb2149508e5db31d7d77a75e6600d54be645f37681f03f2762169ba -FROM golang@sha256:db2475a1dbb2149508e5db31d7d77a75e6600d54be645f37681f03f2762169ba AS build-container + +FROM golang:1.18.2 AS build-container ARG ARCH -ENV GO111MODULE=on ADD . /app WORKDIR /app @@ -35,12 +29,12 @@ RUN set -ex \ && echo "Compiling for $GOARCH" \ && go install -v . ./cmd/... -FROM $ARCH/alpine:3.12 +FROM $ARCH/debian:bullseye-20220418-slim COPY --from=build-container /go/bin /bin -VOLUME ["/root/.btcd"] +VOLUME ["/root/.lbcd"] -EXPOSE 8333 8334 +EXPOSE 9245 9246 -ENTRYPOINT ["btcd"] +ENTRYPOINT ["lbcd"] -- 2.45.2 From 0375a6d38b2e0d98a734846352e96b8b5585f71b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 22:41:12 -0700 Subject: [PATCH 402/459] [lbry] ci: support GoReleaser --- .goreleaser.yml | 66 +++++++++++++++++++++++++++++++++++++++++++ Dockerfile.goreleaser | 9 ++++++ 2 files changed, 75 insertions(+) create mode 100644 .goreleaser.yml create mode 100644 Dockerfile.goreleaser diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 00000000..d9806332 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,66 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy + # you may remove this if you don't need go generate + - go generate ./... +builds: + - + main: . + id: "lbcd" + binary: "lbcd" + env: + - CGO_ENABLED=0 + flags: + - -trimpath + ldflags: + - -s -w + - -X github.com/lbryio/lbcd/version.appTag={{ .Tag }} + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + - windows_amd64 + mod_timestamp: '{{ .CommitTimestamp }}' + - + main: ./cmd/lbcctl + id: "lbcctl" + binary: "lbcctl" + flags: + - -trimpath + ldflags: + - -s -w + - -X github.com/lbryio/lbcd/version.appTag={{ .Tag }} + env: + - CGO_ENABLED=0 + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + - windows_amd64 + mod_timestamp: '{{ .CommitTimestamp }}' +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ .Version }}+{{ .Commit }}" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + +dockers: + - use: buildx + dockerfile: Dockerfile.goreleaser + image_templates: + - "docker.io/lbry/lbcd:{{ .Tag }}" + - "docker.io/lbry/lbcd:latest" + +release: + draft: true + prerelease: auto diff --git a/Dockerfile.goreleaser b/Dockerfile.goreleaser new file mode 100644 index 00000000..2a8943df --- /dev/null +++ b/Dockerfile.goreleaser @@ -0,0 +1,9 @@ +FROM debian:bullseye-20220418-slim + +COPY lbcd lbcctl /bin/ + +VOLUME ["/root/.lbcd"] + +EXPOSE 9245 9246 + +ENTRYPOINT ["lbcd"] -- 2.45.2 From aef4e45bd74213adef6af0a0e98a16f5eb755306 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 23 May 2022 22:40:25 -0700 Subject: [PATCH 403/459] [lbry] ci: add github workflows --- .github/workflows/{go.yml => basic-check.yml} | 11 ++-- .github/workflows/full-sync-part-1.yml | 35 ++++++++++++ .github/workflows/full-sync-part-2.yml | 37 ++++++++++++ .github/workflows/golangci-lint.yml | 57 +++++++++++++++++++ .github/workflows/release.yml | 57 +++++++++++++++++++ 5 files changed, 190 insertions(+), 7 deletions(-) rename .github/workflows/{go.yml => basic-check.yml} (71%) create mode 100644 .github/workflows/full-sync-part-1.yml create mode 100644 .github/workflows/full-sync-part-2.yml create mode 100644 .github/workflows/golangci-lint.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/go.yml b/.github/workflows/basic-check.yml similarity index 71% rename from .github/workflows/go.yml rename to .github/workflows/basic-check.yml index 5da1bebc..43399646 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/basic-check.yml @@ -9,23 +9,20 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: [1.16.8, 1.17.1] + go: [1.18.2] steps: - name: Set up Go uses: actions/setup-go@v2 with: go-version: ${{ matrix.go }} + - name: Check out source uses: actions/checkout@v2 - - name: Install Linters - run: "curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.26.0" + - name: Build - env: - GO111MODULE: "on" run: go build ./... + - name: Test - env: - GO111MODULE: "on" run: | sh ./goclean.sh diff --git a/.github/workflows/full-sync-part-1.yml b/.github/workflows/full-sync-part-1.yml new file mode 100644 index 00000000..9d13a84b --- /dev/null +++ b/.github/workflows/full-sync-part-1.yml @@ -0,0 +1,35 @@ +name: Full Sync From 0 + +on: + workflow_dispatch: + inputs: + note: + description: 'Note' + required: false + default: '' + +jobs: + build: + name: Go CI + runs-on: self-hosted + strategy: + matrix: + go: [1.18.2] + steps: + - run: | + echo "Note ${{ github.event.inputs.note }}!" + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + - name: Checkout source + uses: actions/checkout@v2 + - name: Build lbcd + run: go build . + - name: Create datadir + run: echo "TEMP_DATA_DIR=$(mktemp -d)" >> $GITHUB_ENV + - name: Run lbcd + run: ./lbcd --datadir=${{env.TEMP_DATA_DIR}}/data --logdir=${{env.TEMP_DATA_DIR}}/logs --nolisten --norpc + - name: Remove datadir + if: always() + run: rm -rf ${{env.TEMP_DATA_DIR}} diff --git a/.github/workflows/full-sync-part-2.yml b/.github/workflows/full-sync-part-2.yml new file mode 100644 index 00000000..f7f95c84 --- /dev/null +++ b/.github/workflows/full-sync-part-2.yml @@ -0,0 +1,37 @@ +name: Full Sync From 814k + +on: + workflow_dispatch: + inputs: + note: + description: 'Note' + required: false + default: '' + +jobs: + build: + name: Go CI + runs-on: self-hosted + strategy: + matrix: + go: [1.18.2] + steps: + - run: | + echo "Note ${{ github.event.inputs.note }}!" + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + - name: Checkout source + uses: actions/checkout@v2 + - name: Build lbcd + run: go build . + - name: Create datadir + run: echo "TEMP_DATA_DIR=$(mktemp -d)" >> $GITHUB_ENV + - name: Copy initial data + run: cp -r /home/lbry/lbcd_814k/* ${{env.TEMP_DATA_DIR}} + - name: Run lbcd + run: ./lbcd --datadir=${{env.TEMP_DATA_DIR}}/data --logdir=${{env.TEMP_DATA_DIR}}/logs --nolisten --norpc + - name: Remove datadir + if: always() + run: rm -rf ${{env.TEMP_DATA_DIR}} diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 00000000..1d58c316 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,57 @@ +name: golangci-lint + +env: + # go needs absolute directories, using the $HOME variable doesn't work here. + GOCACHE: /home/runner/work/go/pkg/build + GOPATH: /home/runner/work/go + GO_VERSION: '^1.18.2' + +on: + push: + tags: + - v* + branches: + - "*" + pull_request: + branches: + - "*" + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - name: setup go ${{ env.GO_VERSION }} + uses: actions/setup-go@v2 + with: + go-version: '${{ env.GO_VERSION }}' + + - name: checkout source + uses: actions/checkout@v2 + + - name: compile code + run: go install -v ./... + + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: latest + + # Optional: working directory, useful for monorepos + # working-directory: somedir + + # Optional: golangci-lint command line arguments. + # args: --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true then the action will use pre-installed Go. + skip-go-installation: true + + # Optional: if set to true then the action don't cache or restore ~/go/pkg. + # skip-pkg-cache: true + + # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. + # skip-build-cache: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..a54ac02b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,57 @@ +name: goreleaser + +on: + workflow_dispatch: + inputs: + note: + description: 'Note' + required: false + default: '' + pull_request: + push: + tags: + - '*' + +permissions: + contents: write + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - + name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.18.2 + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry docker.io + if: github.event_name != 'pull_request' + uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + - + name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + distribution: goreleaser + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - + name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: lbcd-${{ github.sha }} + path: | + dist/checksums.txt + dist/*.tar.gz -- 2.45.2 From 4a8d390a0694b721395770f935fd428ecd3b20bf Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 25 May 2022 21:49:12 -0700 Subject: [PATCH 404/459] [lbry] ci: GoReleaser zero out buildid for reproducible builds (#40) --- .goreleaser.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index d9806332..f68a4732 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -17,6 +17,7 @@ builds: - -trimpath ldflags: - -s -w + - -buildid= - -X github.com/lbryio/lbcd/version.appTag={{ .Tag }} targets: - linux_amd64 @@ -33,6 +34,7 @@ builds: - -trimpath ldflags: - -s -w + - -buildid= - -X github.com/lbryio/lbcd/version.appTag={{ .Tag }} env: - CGO_ENABLED=0 -- 2.45.2 From e48200f53ae53f11ba702829cf76fa1250ee7d09 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 25 May 2022 21:29:29 -0700 Subject: [PATCH 405/459] [lbry] wire: limit the blocks of getdata message In the cuurent codebase, OnGetData() handler penalizes / ban peers requesting large blocks. server.go: @@ -649,7 +649,7 @@ func (sp *serverPeer) OnGetData(_ *peer.Peer, msg *wire.MsgGetData) { // bursts of small requests are not penalized as that would potentially ban // peers performing IBD. // This incremental score decays each minute to half of its value. if sp.addBanScore(0, uint32(length)*99/wire.MaxInvPerMsg, "getdata") { return } This accidentally penalize nodes trying to catch up checkpoints whose 'getdata' requests would be as large as the wire.MaxInvPerMsg, and get banned very soon. This patch limit getdata request to wire.MaxInvPerMsg/99 blocks. --- netsync/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netsync/manager.go b/netsync/manager.go index 72fce625..351fb7cd 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -903,7 +903,7 @@ func (sm *SyncManager) fetchHeaderBlocks() { numRequested++ } sm.startHeader = e.Next() - if numRequested >= wire.MaxInvPerMsg { + if numRequested >= wire.MaxInvPerMsg/99 { break } } -- 2.45.2 From 6e3611819366aff218cb4c9762f6d0ee9f7d6403 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 26 May 2022 21:52:15 -0700 Subject: [PATCH 406/459] [lbry] claimtrie: update CLI to support other tools - fix default app dir name - enable debug level for cli - block sub command to output hash, height, or both --- claimtrie/cmd/cmd/block.go | 34 +++++++++++++++++++++++++++++----- claimtrie/cmd/cmd/helper.go | 6 +++--- claimtrie/cmd/cmd/root.go | 23 +++++++++++++---------- claimtrie/config/config.go | 18 ++++++++---------- 4 files changed, 53 insertions(+), 28 deletions(-) diff --git a/claimtrie/cmd/cmd/block.go b/claimtrie/cmd/cmd/block.go index d0ee7719..b22c0b65 100644 --- a/claimtrie/cmd/cmd/block.go +++ b/claimtrie/cmd/cmd/block.go @@ -23,12 +23,14 @@ func NewBlocCommands() *cobra.Command { return cmd } - func NewBlockBestCommand() *cobra.Command { + var showHash bool + var showHeight bool + cmd := &cobra.Command{ Use: "best", - Short: "Show the height and hash of the best block", + Short: "Show the block hash and height of the best block", RunE: func(cmd *cobra.Command, args []string) error { db, err := loadBlocksDB() @@ -43,12 +45,23 @@ func NewBlockBestCommand() *cobra.Command { } state := chain.BestSnapshot() - fmt.Printf("Block %7d: %s\n", state.Height, state.Hash.String()) + + switch { + case showHeight && showHash: + fmt.Printf("%s:%d\n", state.Hash, state.Height) + case !showHeight && showHash: + fmt.Printf("%s\n", state.Hash) + case showHeight && !showHash: + fmt.Printf("%d\n", state.Height) + } return nil }, } + cmd.Flags().BoolVar(&showHeight, "showheight", true, "Display block height") + cmd.Flags().BoolVar(&showHash, "showhash", true, "Display block hash") + return cmd } @@ -56,10 +69,12 @@ func NewBlockListCommand() *cobra.Command { var fromHeight int32 var toHeight int32 + var showHash bool + var showHeight bool cmd := &cobra.Command{ Use: "list", - Short: "List merkle hash of blocks between ", + Short: "List block hash and height between blocks ", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { @@ -83,7 +98,14 @@ func NewBlockListCommand() *cobra.Command { if err != nil { return errors.Wrapf(err, "load hash for %d", ht) } - fmt.Printf("Block %7d: %s\n", ht, hash.String()) + switch { + case showHeight && showHash: + fmt.Printf("%s:%d\n", hash, ht) + case !showHeight && showHash: + fmt.Printf("%s\n", hash) + case showHeight && !showHash: + fmt.Printf("%d\n", ht) + } } return nil @@ -92,6 +114,8 @@ func NewBlockListCommand() *cobra.Command { cmd.Flags().Int32Var(&fromHeight, "from", 0, "From height (inclusive)") cmd.Flags().Int32Var(&toHeight, "to", 0, "To height (inclusive)") + cmd.Flags().BoolVar(&showHeight, "showheight", true, "Display block height") + cmd.Flags().BoolVar(&showHash, "showhash", true, "Display block hash") cmd.Flags().SortFlags = false return cmd diff --git a/claimtrie/cmd/cmd/helper.go b/claimtrie/cmd/cmd/helper.go index e75da402..eb8266c8 100644 --- a/claimtrie/cmd/cmd/helper.go +++ b/claimtrie/cmd/cmd/helper.go @@ -15,7 +15,7 @@ import ( func loadBlocksDB() (database.DB, error) { dbPath := filepath.Join(dataDir, netName, "blocks_ffldb") - log.Infof("Loading blocks database: %s", dbPath) + log.Debugf("Loading blocks database: %s", dbPath) db, err := database.Open("ffldb", dbPath, chainPramas().Net) if err != nil { return nil, errors.Wrapf(err, "open blocks database") @@ -27,7 +27,7 @@ func loadBlocksDB() (database.DB, error) { func loadChain(db database.DB) (*blockchain.BlockChain, error) { paramsCopy := chaincfg.MainNetParams - log.Infof("Loading chain from database") + log.Debugf("Loading chain from database") startTime := time.Now() chain, err := blockchain.New(&blockchain.Config{ @@ -40,7 +40,7 @@ func loadChain(db database.DB) (*blockchain.BlockChain, error) { return nil, errors.Wrapf(err, "create blockchain") } - log.Infof("Loaded chain from database (%s)", time.Since(startTime)) + log.Debugf("Loaded chain from database (%s)", time.Since(startTime)) return chain, err diff --git a/claimtrie/cmd/cmd/root.go b/claimtrie/cmd/cmd/root.go index 8b2fb75f..885c3ef9 100644 --- a/claimtrie/cmd/cmd/root.go +++ b/claimtrie/cmd/cmd/root.go @@ -3,20 +3,21 @@ package cmd import ( "os" - "github.com/btcsuite/btclog" "github.com/lbryio/lbcd/claimtrie/config" "github.com/lbryio/lbcd/claimtrie/param" "github.com/lbryio/lbcd/limits" "github.com/lbryio/lbcd/wire" + "github.com/btcsuite/btclog" "github.com/spf13/cobra" ) var ( - log btclog.Logger - cfg = config.DefaultConfig - netName string - dataDir string + log = btclog.NewBackend(os.Stdout).Logger("CMDL") + cfg = config.DefaultConfig + netName string + dataDir string + debugLevel string ) var rootCmd = NewRootCommand() @@ -28,6 +29,9 @@ func NewRootCommand() *cobra.Command { Short: "ClaimTrie Command Line Interface", SilenceUsage: true, PersistentPreRun: func(cmd *cobra.Command, args []string) { + level, _ := btclog.LevelFromString(debugLevel) + log.SetLevel(level) + switch netName { case "mainnet": param.SetNetwork(wire.MainNet) @@ -37,21 +41,20 @@ func NewRootCommand() *cobra.Command { param.SetNetwork(wire.TestNet) } }, + PersistentPostRun: func(cmd *cobra.Command, args []string) { + os.Stdout.Sync() + }, } cmd.PersistentFlags().StringVar(&netName, "netname", "mainnet", "Net name") cmd.PersistentFlags().StringVarP(&dataDir, "datadir", "b", cfg.DataDir, "Data dir") + cmd.PersistentFlags().StringVarP(&debugLevel, "debuglevel", "d", cfg.DebugLevel, "Debug level") return cmd } func Execute() { - backendLogger := btclog.NewBackend(os.Stdout) - defer os.Stdout.Sync() - log = backendLogger.Logger("CMDL") - log.SetLevel(btclog.LevelDebug) - // Up some limits. if err := limits.SetLimits(); err != nil { log.Errorf("failed to set limits: %v\n", err) diff --git a/claimtrie/config/config.go b/claimtrie/config/config.go index 4920ca17..67de7396 100644 --- a/claimtrie/config/config.go +++ b/claimtrie/config/config.go @@ -8,11 +8,10 @@ import ( ) var DefaultConfig = Config{ - Params: param.MainNet, - - RamTrie: true, // as it stands the other trie uses more RAM, more time, and 40GB+ of disk space - - DataDir: filepath.Join(btcutil.AppDataDir("chain", false), "data"), + Params: param.MainNet, + RamTrie: true, // as it stands the other trie uses more RAM, more time, and 40GB+ of disk space + DebugLevel: "info", + DataDir: filepath.Join(btcutil.AppDataDir("lbcd", false), "data"), BlockRepoPebble: pebbleConfig{ Path: "blocks_pebble_db", @@ -30,11 +29,10 @@ var DefaultConfig = Config{ // Config is the container of all configurations. type Config struct { - Params param.ClaimTrieParams - - RamTrie bool - - DataDir string + Params param.ClaimTrieParams + RamTrie bool + DataDir string + DebugLevel string BlockRepoPebble pebbleConfig NodeRepoPebble pebbleConfig -- 2.45.2 From 5d5f53c8d8e3e0a9ab2ea02c7b1caa131964507a Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 26 May 2022 21:16:30 -0700 Subject: [PATCH 407/459] [lbry] contrib: add a helper script for generating snapshots --- contrib/snapshot.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 contrib/snapshot.sh diff --git a/contrib/snapshot.sh b/contrib/snapshot.sh new file mode 100755 index 00000000..9b885514 --- /dev/null +++ b/contrib/snapshot.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +read -r -d '' help << EOM +snapshot.sh - helper script for generating snapshot from lbcd's app dir. + +The default output name "lbcd_snapshot___.tar.zst" + +To extract the snapshot (data/mainter/): + + zstd -d lbcd_snapshot___.tar.zst | tar xf - -C + +Default appdir of lbcd on different OSes: + + Darwin) "\${HOME}/Library/Application Support/Lbcd" + Linux) "\${HOME}/.lbcd" + Windows) "%%LOCALAPPDATA%%/lbcd" + +Options: + + -h Display this message. + -d Specify APPDIR to copy the snapshot from. + + -o Specify the output filename of snapshot. + -b Specify the best block height of the snapshot. (ignored if -o is specified) + -l Specify git tag of the running lbcd. (ignored if -o is specified) + -t Specify the date when the snapshot is generated. (ignored if -o is specified) +EOM + +while getopts o:d:b:l:t:h flag +do + case "${flag}" in + h) printf "${help}\n\n"; exit 0;; + d) appdir=${OPTARG};; + + o) snapshot=${OPTARG};; + b) height=${OPTARG};; + l) lbcd_ver=${OPTARG};; + t) date=${OPTARG};; + esac +done + +if [ -z "$appdir" ]; then + case $(uname) in + Darwin) appdir="${HOME}/Library/Application Support/Lbcd" ;; + Linux) appdir="${HOME}/.lbcd" ;; + Windows) appdir="%LOCALAPPDATA%/lbcd" ;; + esac +fi + + +if [ -z ${snapshot} ]; then + git_repo=$(git rev-parse --show-toplevel) + [ -z "${height}" ] && height=$(go run ${git_repo}/claimtrie/cmd block best --showhash=false) + [ -z "${lbcd_ver}" ] && lbcd_ver=$(git describe --tags) + [ -z "${date}" ] && date=$(date +"%Y-%m-%d") + snapshot="lbcd_snapshot_${height}_${lbcd_ver}_${date}.tar.zst" +fi + + +echo "Generating $snapshot ..." + +tar c -C "${appdir}" data/mainnet | zstd -9 --no-progress -o "${snapshot}" + -- 2.45.2 From 8f95946b17a854763f77cd9f099d823c5957fe97 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Wed, 11 May 2022 09:03:51 -0400 Subject: [PATCH 408/459] [lbry] claimtrie: created node cache --- claimtrie/node/cache.go | 101 ++++++++++++++++++++++++++ claimtrie/node/manager.go | 97 +++++++++++++++++++------ claimtrie/node/node.go | 28 ++++++- claimtrie/node/normalizing_manager.go | 3 + 4 files changed, 204 insertions(+), 25 deletions(-) create mode 100644 claimtrie/node/cache.go diff --git a/claimtrie/node/cache.go b/claimtrie/node/cache.go new file mode 100644 index 00000000..0f556af1 --- /dev/null +++ b/claimtrie/node/cache.go @@ -0,0 +1,101 @@ +package node + +import ( + "container/list" + "sync" + + "github.com/lbryio/lbcd/claimtrie/change" +) + +type cacheLeaf struct { + node *Node + element *list.Element + changes []change.Change + height int32 +} + +type Cache struct { + nodes map[string]*cacheLeaf + order *list.List + mtx sync.Mutex + limit int +} + +func (nc *Cache) insert(name []byte, n *Node, height int32) { + key := string(name) + + nc.mtx.Lock() + defer nc.mtx.Unlock() + + existing := nc.nodes[key] + if existing != nil { + existing.node = n + existing.height = height + existing.changes = nil + nc.order.MoveToFront(existing.element) + return + } + + for nc.order.Len() >= nc.limit { + // TODO: maybe ensure that we don't remove nodes that have a lot of changes? + delete(nc.nodes, nc.order.Back().Value.(string)) + nc.order.Remove(nc.order.Back()) + } + + element := nc.order.PushFront(key) + nc.nodes[key] = &cacheLeaf{node: n, element: element, height: height} +} + +func (nc *Cache) fetch(name []byte, height int32) (*Node, []change.Change, int32) { + key := string(name) + + nc.mtx.Lock() + defer nc.mtx.Unlock() + + existing := nc.nodes[key] + if existing != nil && existing.height <= height { + nc.order.MoveToFront(existing.element) + return existing.node, existing.changes, existing.height + } + return nil, nil, -1 +} + +func (nc *Cache) addChanges(changes []change.Change, height int32) { + nc.mtx.Lock() + defer nc.mtx.Unlock() + + for _, c := range changes { + key := string(c.Name) + existing := nc.nodes[key] + if existing != nil && existing.height <= height { + existing.changes = append(existing.changes, c) + } + } +} + +func (nc *Cache) drop(names [][]byte) { + nc.mtx.Lock() + defer nc.mtx.Unlock() + + for _, name := range names { + key := string(name) + existing := nc.nodes[key] + if existing != nil { + // we can't roll it backwards because we don't know its previous height value; just toast it + delete(nc.nodes, key) + nc.order.Remove(existing.element) + } + } +} + +func (nc *Cache) clear() { + nc.mtx.Lock() + defer nc.mtx.Unlock() + nc.nodes = map[string]*cacheLeaf{} + nc.order = list.New() + // we'll let the GC sort out the remains... +} + +func NewCache(limit int) *Cache { + return &Cache{limit: limit, nodes: map[string]*cacheLeaf{}, order: list.New()} +} diff --git a/claimtrie/node/manager.go b/claimtrie/node/manager.go index 814bfc80..31ba0f1a 100644 --- a/claimtrie/node/manager.go +++ b/claimtrie/node/manager.go @@ -21,6 +21,7 @@ type Manager interface { IterateNames(predicate func(name []byte) bool) Hash(name []byte) (*chainhash.Hash, int32) Flush() error + ClearCache() } type BaseManager struct { @@ -30,31 +31,60 @@ type BaseManager struct { changes []change.Change tempChanges map[string][]change.Change + + cache *Cache } func NewBaseManager(repo Repo) (*BaseManager, error) { nm := &BaseManager{ - repo: repo, + repo: repo, + cache: NewCache(10000), // TODO: how many should we cache? } return nm, nil } +func (nm *BaseManager) ClearCache() { + nm.cache.clear() +} + func (nm *BaseManager) NodeAt(height int32, name []byte) (*Node, error) { - changes, err := nm.repo.LoadChanges(name) - if err != nil { - return nil, errors.Wrap(err, "in load changes") - } + n, changes, oldHeight := nm.cache.fetch(name, height) + if n == nil { + changes, err := nm.repo.LoadChanges(name) + if err != nil { + return nil, errors.Wrap(err, "in load changes") + } - if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block - changes = append(changes, nm.tempChanges[string(name)]...) - } + if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block + changes = append(changes, nm.tempChanges[string(name)]...) + } - n, err := nm.newNodeFromChanges(changes, height) - if err != nil { - return nil, errors.Wrap(err, "in new node") + n, err = nm.newNodeFromChanges(changes, height) + if err != nil { + return nil, errors.Wrap(err, "in new node") + } + // TODO: how can we tell what needs to be cached? + if nm.tempChanges == nil && height == nm.height && n != nil && (len(changes) > 7 || len(name) < 12) { + nm.cache.insert(name, n, height) + } + } else { + if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block + changes = append(changes, nm.tempChanges[string(name)]...) + } + n = n.Clone() + updated, err := nm.updateFromChanges(n, changes, height) + if err != nil { + return nil, errors.Wrap(err, "in update from changes") + } + if !updated { + n.AdjustTo(oldHeight, height, name) + } + if nm.tempChanges == nil && height == nm.height { // TODO: how many changes before we update the cache? + nm.cache.insert(name, n, height) + } } return n, nil @@ -66,17 +96,13 @@ func (nm *BaseManager) node(name []byte) (*Node, error) { return nm.NodeAt(nm.height, name) } -// newNodeFromChanges returns a new Node constructed from the changes. -// The changes must preserve their order received. -func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) { +func (nm *BaseManager) updateFromChanges(n *Node, changes []change.Change, height int32) (bool, error) { - if len(changes) == 0 { - return nil, nil - } - - n := New() - previous := changes[0].Height count := len(changes) + if count == 0 { + return false, nil + } + previous := changes[0].Height for i, chg := range changes { if chg.Height < previous { @@ -95,15 +121,37 @@ func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) delay := nm.getDelayForName(n, chg) err := n.ApplyChange(chg, delay) if err != nil { - return nil, errors.Wrap(err, "in apply change") + return false, errors.Wrap(err, "in apply change") } } if count <= 0 { - return nil, nil + // we applied no changes, which means we shouldn't exist if we had all the changes + // or might mean nothing significant if we are applying a partial changeset + return false, nil } lastChange := changes[count-1] - return n.AdjustTo(lastChange.Height, height, lastChange.Name), nil + n.AdjustTo(lastChange.Height, height, lastChange.Name) + return true, nil +} + +// newNodeFromChanges returns a new Node constructed from the changes. +// The changes must preserve their order received. +func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) { + + if len(changes) == 0 { + return nil, nil + } + + n := New() + updated, err := nm.updateFromChanges(n, changes, height) + if err != nil { + return nil, errors.Wrap(err, "in update from changes") + } + if updated { + return n, nil + } + return nil, nil } func (nm *BaseManager) AppendChange(chg change.Change) { @@ -220,6 +268,7 @@ func (nm *BaseManager) IncrementHeightTo(height int32, temporary bool) ([][]byte } if !temporary { + nm.cache.addChanges(nm.changes, height) if err := nm.repo.AppendChanges(nm.changes); err != nil { // destroys names return nil, errors.Wrap(err, "in append changes") } @@ -255,6 +304,8 @@ func (nm *BaseManager) DecrementHeightTo(affectedNames [][]byte, height int32) ( return affectedNames, errors.Wrap(err, "in drop changes") } } + + nm.cache.drop(affectedNames) } nm.height = height diff --git a/claimtrie/node/node.go b/claimtrie/node/node.go index fe6db947..ff45fc11 100644 --- a/claimtrie/node/node.go +++ b/claimtrie/node/node.go @@ -110,7 +110,7 @@ func (n *Node) ApplyChange(chg change.Change, delay int32) error { } // AdjustTo activates claims and computes takeovers until it reaches the specified height. -func (n *Node) AdjustTo(height, maxHeight int32, name []byte) *Node { +func (n *Node) AdjustTo(height, maxHeight int32, name []byte) { changed := n.handleExpiredAndActivated(height) > 0 n.updateTakeoverHeight(height, name, changed) if maxHeight > height { @@ -120,7 +120,6 @@ func (n *Node) AdjustTo(height, maxHeight int32, name []byte) *Node { height = h } } - return n } func (n *Node) updateTakeoverHeight(height int32, name []byte, refindBest bool) { @@ -340,3 +339,28 @@ func (n *Node) SortClaimsByBid() { return OutPointLess(n.Claims[j].OutPoint, n.Claims[i].OutPoint) }) } + +func (n *Node) Clone() *Node { + clone := New() + if n.SupportSums != nil { + clone.SupportSums = map[string]int64{} + for key, value := range n.SupportSums { + clone.SupportSums[key] = value + } + } + clone.Supports = make(ClaimList, len(n.Supports)) + for i, support := range n.Supports { + clone.Supports[i] = &Claim{} + *clone.Supports[i] = *support + } + clone.Claims = make(ClaimList, len(n.Claims)) + for i, claim := range n.Claims { + clone.Claims[i] = &Claim{} + *clone.Claims[i] = *claim + } + clone.TakenOverAt = n.TakenOverAt + if n.BestClaim != nil { + clone.BestClaim = clone.Claims.find(byID(n.BestClaim.ClaimID)) + } + return clone +} diff --git a/claimtrie/node/normalizing_manager.go b/claimtrie/node/normalizing_manager.go index 2f6c4cfe..604fa34d 100644 --- a/claimtrie/node/normalizing_manager.go +++ b/claimtrie/node/normalizing_manager.go @@ -34,6 +34,7 @@ func (nm *NormalizingManager) IncrementHeightTo(height int32, temporary bool) ([ func (nm *NormalizingManager) DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) { if nm.normalizedAt > height { nm.normalizedAt = -1 + nm.ClearCache() } return nm.Manager.DecrementHeightTo(affectedNames, height) } @@ -110,5 +111,7 @@ func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int3 return true } + + nm.Manager.ClearCache() nm.Manager.IterateNames(predicate) } -- 2.45.2 From 92a7a2087ae17c692b2d7cfeaeeb03d0a30d3074 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Fri, 3 Jun 2022 12:19:55 -0400 Subject: [PATCH 409/459] [lbry] runtime: Allow environment var GOGC= to override hard-coded SetGCPercent(10). --- lbcd.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lbcd.go b/lbcd.go index 1110eeab..b9606653 100644 --- a/lbcd.go +++ b/lbcd.go @@ -281,7 +281,9 @@ func main() { // limits the garbage collector from excessively overallocating during // bursts. This value was arrived at with the help of profiling live // usage. - debug.SetGCPercent(10) + if _, ok := os.LookupEnv("GOGC"); !ok { + debug.SetGCPercent(10) + } // Up some limits. if err := limits.SetLimits(); err != nil { -- 2.45.2 From 15191b7ede02f4c052a2a61c55c8ef7a95d8e134 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Fri, 3 Jun 2022 15:08:09 -0400 Subject: [PATCH 410/459] [lbry] runtime: Add --memprofile option * Add --memprofile option. Add memprofile to sample config. * Add --memprofile to doc.go. --- config.go | 1 + doc.go | 1 + lbcd.go | 19 +++++++++++++++++++ sample-lbcd.conf | 3 +++ 4 files changed, 24 insertions(+) diff --git a/config.go b/config.go index fe77a818..aee85c3f 100644 --- a/config.go +++ b/config.go @@ -117,6 +117,7 @@ type config struct { ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"` ConnectPeers []string `long:"connect" description:"Connect only to the specified peers at startup"` CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"` + MemProfile string `long:"memprofile" description:"Write memory profile to the specified file"` DataDir string `short:"b" long:"datadir" description:"Directory to store data"` DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` DebugLevel string `short:"d" long:"debuglevel" description:"Logging level for all subsystems {trace, debug, info, warn, error, critical} -- You may also specify =,=,... to set the log level for individual subsystems -- Use show to list available subsystems"` diff --git a/doc.go b/doc.go index ee4a9405..84a96ea8 100644 --- a/doc.go +++ b/doc.go @@ -78,6 +78,7 @@ Application Options: memory (default: 100) --maxpeers= Max number of inbound and outbound peers (default: 125) + --memprofile= Write memory profile to the specified file --miningaddr= Add the specified payment address to the list of addresses to use for generated blocks -- At least one address is required if the generate option is diff --git a/lbcd.go b/lbcd.go index b9606653..3a7860b1 100644 --- a/lbcd.go +++ b/lbcd.go @@ -92,6 +92,25 @@ func btcdMain(serverChan chan<- *server) error { defer pprof.StopCPUProfile() } + // Write memory profile if requested. + if cfg.MemProfile != "" { + f, err := os.Create(cfg.MemProfile + ".heap") + if err != nil { + btcdLog.Errorf("Unable to create mem profile: %v", err) + return err + } + defer f.Close() + defer pprof.Lookup("heap").WriteTo(f, 0) + + f, err = os.Create(cfg.MemProfile + ".allocs") + if err != nil { + btcdLog.Errorf("Unable to create mem profile: %v", err) + return err + } + defer f.Close() + defer pprof.Lookup("allocs").WriteTo(f, 0) + } + // Perform upgrades to btcd as new versions require it. if err := doUpgrades(); err != nil { btcdLog.Errorf("%v", err) diff --git a/sample-lbcd.conf b/sample-lbcd.conf index 2a84c797..f2c0b8c7 100644 --- a/sample-lbcd.conf +++ b/sample-lbcd.conf @@ -376,6 +376,9 @@ ; Write CPU profile to the specified file. ; cpuprofile= +; Write memory profile to the specified file. +; memprofile= + ; The port used to listen for HTTP profile requests. The profile server will ; be disabled if this option is not specified. The profile information can be ; accessed at http://localhost:/debug/pprof once running. -- 2.45.2 From b06df3d750e35fd0f307a511510abe5e572fae99 Mon Sep 17 00:00:00 2001 From: Brannon King Date: Wed, 21 Jul 2021 15:58:47 -0400 Subject: [PATCH 411/459] added buffer pool for pebble merge string --- claimtrie/node/noderepo/pebble.go | 64 ++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/claimtrie/node/noderepo/pebble.go b/claimtrie/node/noderepo/pebble.go index cb5d25e4..e5ee75ed 100644 --- a/claimtrie/node/noderepo/pebble.go +++ b/claimtrie/node/noderepo/pebble.go @@ -2,7 +2,9 @@ package noderepo import ( "bytes" + "io" "sort" + "sync" "github.com/cockroachdb/pebble" "github.com/lbryio/lbcd/claimtrie/change" @@ -13,9 +15,69 @@ type Pebble struct { db *pebble.DB } +type pooledMerger struct { + values [][]byte + index []int + pool *sync.Pool + buffer []byte +} + +func (a *pooledMerger) Len() int { return len(a.index) } +func (a *pooledMerger) Less(i, j int) bool { return a.index[i] < a.index[j] } +func (a *pooledMerger) Swap(i, j int) { + a.index[i], a.index[j] = a.index[j], a.index[i] + a.values[i], a.values[j] = a.values[j], a.values[i] +} + +func (a *pooledMerger) MergeNewer(value []byte) error { + a.values = append(a.values, value) + a.index = append(a.index, len(a.values)) + return nil +} + +func (a *pooledMerger) MergeOlder(value []byte) error { + a.values = append(a.values, value) + a.index = append(a.index, -len(a.values)) + return nil +} + +func (a *pooledMerger) Finish(includesBase bool) ([]byte, io.Closer, error) { + sort.Sort(a) + + a.buffer = a.pool.Get().([]byte)[:0] + for i := range a.values { + a.buffer = append(a.buffer, a.values[i]...) + } + + return a.buffer, a, nil +} + +func (a *pooledMerger) Close() error { + a.pool.Put(a.buffer) + return nil +} + func NewPebble(path string) (*Pebble, error) { - db, err := pebble.Open(path, &pebble.Options{Cache: pebble.NewCache(64 << 20), BytesPerSync: 8 << 20, MaxOpenFiles: 2000}) + mp := &sync.Pool{ + New: func() interface{} { + return make([]byte, 0, 256) + }, + } + + db, err := pebble.Open(path, &pebble.Options{ + Merger: &pebble.Merger{ + Merge: func(key, value []byte) (pebble.ValueMerger, error) { + p := &pooledMerger{pool: mp} + return p, p.MergeNewer(value) + }, + Name: pebble.DefaultMerger.Name, // yes, it's a lie + }, + Cache: pebble.NewCache(64 << 20), + BytesPerSync: 8 << 20, + MaxOpenFiles: 2000, + }) + repo := &Pebble{db: db} return repo, errors.Wrapf(err, "unable to open %s", path) -- 2.45.2 From 0241e18f4229976b4bd8ffb609c09c4465a63108 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Tue, 24 May 2022 09:00:09 -0400 Subject: [PATCH 412/459] Harden Marshal/Unmarshal logic for Change.SpentChildren. --- claimtrie/change/change.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/claimtrie/change/change.go b/claimtrie/change/change.go index aac349c6..95a0e3d5 100644 --- a/claimtrie/change/change.go +++ b/claimtrie/change/change.go @@ -78,9 +78,10 @@ func (c *Change) Marshal(enc *bytes.Buffer) error { binary.BigEndian.PutUint32(temp[:4], uint32(len(c.SpentChildren))) enc.Write(temp[:4]) for key := range c.SpentChildren { - binary.BigEndian.PutUint16(temp[:2], uint16(len(key))) // technically limited to 255; not sure we trust it + keySize := uint16(len(key)) + binary.BigEndian.PutUint16(temp[:2], keySize) // technically limited to 255; not sure we trust it enc.Write(temp[:2]) - enc.WriteString(key) + enc.WriteString(key[:keySize]) } } else { binary.BigEndian.PutUint32(temp[:4], 0) -- 2.45.2 From 5f7b1f1b4f2ebe85c7a41b51ad1f030701c0bb66 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Tue, 24 May 2022 09:17:45 -0400 Subject: [PATCH 413/459] Copy value received by MergeOlder/MergeNewer so caller can't trash the merge result by modifying the contents. --- claimtrie/node/noderepo/pebble.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/claimtrie/node/noderepo/pebble.go b/claimtrie/node/noderepo/pebble.go index e5ee75ed..32ca2c04 100644 --- a/claimtrie/node/noderepo/pebble.go +++ b/claimtrie/node/noderepo/pebble.go @@ -30,13 +30,17 @@ func (a *pooledMerger) Swap(i, j int) { } func (a *pooledMerger) MergeNewer(value []byte) error { - a.values = append(a.values, value) + vc := a.pool.Get().([]byte)[:0] + vc = append(vc, value...) + a.values = append(a.values, vc) a.index = append(a.index, len(a.values)) return nil } func (a *pooledMerger) MergeOlder(value []byte) error { - a.values = append(a.values, value) + vc := a.pool.Get().([]byte)[:0] + vc = append(vc, value...) + a.values = append(a.values, vc) a.index = append(a.index, -len(a.values)) return nil } @@ -53,6 +57,9 @@ func (a *pooledMerger) Finish(includesBase bool) ([]byte, io.Closer, error) { } func (a *pooledMerger) Close() error { + for i := range a.values { + a.pool.Put(a.values[i]) + } a.pool.Put(a.buffer) return nil } -- 2.45.2 From 70852905e05956a27d9709839057c05860a955b5 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Mon, 6 Jun 2022 17:19:26 -0400 Subject: [PATCH 414/459] Allow environment var GOMAXPROCS= to override NumCPU(). --- claimtrie/claimtrie.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/claimtrie/claimtrie.go b/claimtrie/claimtrie.go index 68ef6488..d6062c30 100644 --- a/claimtrie/claimtrie.go +++ b/claimtrie/claimtrie.go @@ -449,7 +449,7 @@ func (ct *ClaimTrie) makeNameHashNext(names [][]byte, all bool, interrupt <-chan wg.Done() } - threads := int(0.8 * float32(runtime.NumCPU())) + threads := int(0.8 * float32(runtime.GOMAXPROCS(0))) if threads < 1 { threads = 1 } -- 2.45.2 From b859832907edb75fa6d277d81a1e2ef0c2c9b005 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Tue, 14 Jun 2022 11:58:35 -0400 Subject: [PATCH 415/459] Copy netsync/blocklogger.go to claimtrie/logger.go. --- claimtrie/logger.go | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 claimtrie/logger.go diff --git a/claimtrie/logger.go b/claimtrie/logger.go new file mode 100644 index 00000000..34a549a1 --- /dev/null +++ b/claimtrie/logger.go @@ -0,0 +1,80 @@ +// Copyright (c) 2015-2017 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package netsync + +import ( + "sync" + "time" + + "github.com/btcsuite/btclog" + btcutil "github.com/lbryio/lbcutil" +) + +// blockProgressLogger provides periodic logging for other services in order +// to show users progress of certain "actions" involving some or all current +// blocks. Ex: syncing to best chain, indexing all blocks, etc. +type blockProgressLogger struct { + receivedLogBlocks int64 + receivedLogTx int64 + lastBlockLogTime time.Time + + subsystemLogger btclog.Logger + progressAction string + sync.Mutex +} + +// newBlockProgressLogger returns a new block progress logger. +// The progress message is templated as follows: +// {progressAction} {numProcessed} {blocks|block} in the last {timePeriod} +// ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) +func newBlockProgressLogger(progressMessage string, logger btclog.Logger) *blockProgressLogger { + return &blockProgressLogger{ + lastBlockLogTime: time.Now(), + progressAction: progressMessage, + subsystemLogger: logger, + } +} + +// LogBlockHeight logs a new block height as an information message to show +// progress to the user. In order to prevent spam, it limits logging to one +// message every 10 seconds with duration and totals included. +func (b *blockProgressLogger) LogBlockHeight(block *btcutil.Block) { + b.Lock() + defer b.Unlock() + + b.receivedLogBlocks++ + b.receivedLogTx += int64(len(block.MsgBlock().Transactions)) + + now := time.Now() + duration := now.Sub(b.lastBlockLogTime) + if duration < time.Second*10 { + return + } + + // Truncate the duration to 10s of milliseconds. + durationMillis := int64(duration / time.Millisecond) + tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10) + + // Log information about new block height. + blockStr := "blocks" + if b.receivedLogBlocks == 1 { + blockStr = "block" + } + txStr := "transactions" + if b.receivedLogTx == 1 { + txStr = "transaction" + } + b.subsystemLogger.Infof("%s %d %s in the last %s (%d %s, height %d, %s)", + b.progressAction, b.receivedLogBlocks, blockStr, tDuration, b.receivedLogTx, + txStr, block.Height(), block.MsgBlock().Header.Timestamp) + + b.receivedLogBlocks = 0 + b.receivedLogTx = 0 + b.lastBlockLogTime = now +} + +func (b *blockProgressLogger) SetLastLogTime(time time.Time) { + b.lastBlockLogTime = time +} -- 2.45.2 From 2b7f06585546d75bbfee87ebcfcf27edb4743b07 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Tue, 14 Jun 2022 13:06:45 -0400 Subject: [PATCH 416/459] Adjust and rename blockProgressLogger -> nameProgressLogger. Use it in makeNameHashNext() to track progress. --- claimtrie/claimtrie.go | 11 +++++-- claimtrie/logger.go | 72 +++++++++++++++++++----------------------- claimtrie/node/log.go | 8 +++++ 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/claimtrie/claimtrie.go b/claimtrie/claimtrie.go index d6062c30..4a6d6307 100644 --- a/claimtrie/claimtrie.go +++ b/claimtrie/claimtrie.go @@ -49,6 +49,9 @@ type ClaimTrie struct { // Registrered cleanup functions which are invoked in the Close() in reverse order. cleanups []func() error + + // nameLogger communicates progress of claimtrie rebuild. + nameLogger *nameProgressLogger } func New(cfg config.Config) (*ClaimTrie, error) { @@ -345,15 +348,19 @@ func (ct *ClaimTrie) ResetHeight(height int32) error { func (ct *ClaimTrie) runFullTrieRebuild(names [][]byte, interrupt <-chan struct{}) { var nhns chan NameHashNext if names == nil { - node.LogOnce("Building the entire claim trie in RAM...") - + node.Log("Building the entire claim trie in RAM...") + ct.nameLogger = newNameProgressLogger("Processed", node.GetLogger()) nhns = ct.makeNameHashNext(nil, true, interrupt) } else { + ct.nameLogger = nil nhns = ct.makeNameHashNext(names, false, interrupt) } for nhn := range nhns { ct.merkleTrie.Update(nhn.Name, nhn.Hash, false) + if ct.nameLogger != nil { + ct.nameLogger.LogName(nhn.Name) + } } } diff --git a/claimtrie/logger.go b/claimtrie/logger.go index 34a549a1..1d7eb529 100644 --- a/claimtrie/logger.go +++ b/claimtrie/logger.go @@ -2,53 +2,51 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package netsync +package claimtrie import ( "sync" "time" "github.com/btcsuite/btclog" - btcutil "github.com/lbryio/lbcutil" ) -// blockProgressLogger provides periodic logging for other services in order +// nameProgressLogger provides periodic logging for other services in order // to show users progress of certain "actions" involving some or all current -// blocks. Ex: syncing to best chain, indexing all blocks, etc. -type blockProgressLogger struct { - receivedLogBlocks int64 - receivedLogTx int64 - lastBlockLogTime time.Time +// claim names. Ex: rebuilding claimtrie. +type nameProgressLogger struct { + totalLogName int64 + recentLogName int64 + lastLogNameTime time.Time subsystemLogger btclog.Logger progressAction string sync.Mutex } -// newBlockProgressLogger returns a new block progress logger. +// newNameProgressLogger returns a new name progress logger. // The progress message is templated as follows: -// {progressAction} {numProcessed} {blocks|block} in the last {timePeriod} -// ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) -func newBlockProgressLogger(progressMessage string, logger btclog.Logger) *blockProgressLogger { - return &blockProgressLogger{ - lastBlockLogTime: time.Now(), - progressAction: progressMessage, - subsystemLogger: logger, +// {progressAction} {numProcessed} {names|name} in the last {timePeriod} (total {totalProcessed}) +func newNameProgressLogger(progressMessage string, logger btclog.Logger) *nameProgressLogger { + return &nameProgressLogger{ + lastLogNameTime: time.Now(), + progressAction: progressMessage, + subsystemLogger: logger, } } -// LogBlockHeight logs a new block height as an information message to show -// progress to the user. In order to prevent spam, it limits logging to one +// LogName logs a new name as an information message to show progress +// to the user. In order to prevent spam, it limits logging to one // message every 10 seconds with duration and totals included. -func (b *blockProgressLogger) LogBlockHeight(block *btcutil.Block) { - b.Lock() - defer b.Unlock() +func (n *nameProgressLogger) LogName(name []byte) { + n.Lock() + defer n.Unlock() - b.receivedLogBlocks++ - b.receivedLogTx += int64(len(block.MsgBlock().Transactions)) + n.totalLogName++ + n.recentLogName++ now := time.Now() - duration := now.Sub(b.lastBlockLogTime) + duration := now.Sub(n.lastLogNameTime) if duration < time.Second*10 { return } @@ -57,24 +55,18 @@ func (b *blockProgressLogger) LogBlockHeight(block *btcutil.Block) { durationMillis := int64(duration / time.Millisecond) tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10) - // Log information about new block height. - blockStr := "blocks" - if b.receivedLogBlocks == 1 { - blockStr = "block" + // Log information about progress. + nameStr := "names" + if n.recentLogName == 1 { + nameStr = "name" } - txStr := "transactions" - if b.receivedLogTx == 1 { - txStr = "transaction" - } - b.subsystemLogger.Infof("%s %d %s in the last %s (%d %s, height %d, %s)", - b.progressAction, b.receivedLogBlocks, blockStr, tDuration, b.receivedLogTx, - txStr, block.Height(), block.MsgBlock().Header.Timestamp) + n.subsystemLogger.Infof("%s %d %s in the last %s (total %d)", + n.progressAction, n.recentLogName, nameStr, tDuration, n.totalLogName) - b.receivedLogBlocks = 0 - b.receivedLogTx = 0 - b.lastBlockLogTime = now + n.recentLogName = 0 + n.lastLogNameTime = now } -func (b *blockProgressLogger) SetLastLogTime(time time.Time) { - b.lastBlockLogTime = time +func (n *nameProgressLogger) SetLastLogTime(time time.Time) { + n.lastLogNameTime = time } diff --git a/claimtrie/node/log.go b/claimtrie/node/log.go index 86293b58..ab93d97d 100644 --- a/claimtrie/node/log.go +++ b/claimtrie/node/log.go @@ -29,6 +29,10 @@ func UseLogger(logger btclog.Logger) { log = logger } +func GetLogger() btclog.Logger { + return log +} + var loggedStrings = map[string]bool{} // is this gonna get too large? var loggedStringsMutex sync.Mutex @@ -42,6 +46,10 @@ func LogOnce(s string) { log.Info(s) } +func Log(s string) { + log.Info(s) +} + func Warn(s string) { log.Warn(s) } -- 2.45.2 From ca9b4e5529729e70305af66a076fc6559dc27e28 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Tue, 14 Jun 2022 13:38:43 -0400 Subject: [PATCH 417/459] Rename nameProgressLogger -> claimProgressLogger and tweak log message. --- claimtrie/claimtrie.go | 12 ++++++------ claimtrie/logger.go | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/claimtrie/claimtrie.go b/claimtrie/claimtrie.go index 4a6d6307..667916dd 100644 --- a/claimtrie/claimtrie.go +++ b/claimtrie/claimtrie.go @@ -50,8 +50,8 @@ type ClaimTrie struct { // Registrered cleanup functions which are invoked in the Close() in reverse order. cleanups []func() error - // nameLogger communicates progress of claimtrie rebuild. - nameLogger *nameProgressLogger + // claimLogger communicates progress of claimtrie rebuild. + claimLogger *claimProgressLogger } func New(cfg config.Config) (*ClaimTrie, error) { @@ -349,17 +349,17 @@ func (ct *ClaimTrie) runFullTrieRebuild(names [][]byte, interrupt <-chan struct{ var nhns chan NameHashNext if names == nil { node.Log("Building the entire claim trie in RAM...") - ct.nameLogger = newNameProgressLogger("Processed", node.GetLogger()) + ct.claimLogger = newClaimProgressLogger("Processed", node.GetLogger()) nhns = ct.makeNameHashNext(nil, true, interrupt) } else { - ct.nameLogger = nil + ct.claimLogger = nil nhns = ct.makeNameHashNext(names, false, interrupt) } for nhn := range nhns { ct.merkleTrie.Update(nhn.Name, nhn.Hash, false) - if ct.nameLogger != nil { - ct.nameLogger.LogName(nhn.Name) + if ct.claimLogger != nil { + ct.claimLogger.LogName(nhn.Name) } } } diff --git a/claimtrie/logger.go b/claimtrie/logger.go index 1d7eb529..ab5a38b4 100644 --- a/claimtrie/logger.go +++ b/claimtrie/logger.go @@ -11,10 +11,10 @@ import ( "github.com/btcsuite/btclog" ) -// nameProgressLogger provides periodic logging for other services in order +// claimProgressLogger provides periodic logging for other services in order // to show users progress of certain "actions" involving some or all current // claim names. Ex: rebuilding claimtrie. -type nameProgressLogger struct { +type claimProgressLogger struct { totalLogName int64 recentLogName int64 lastLogNameTime time.Time @@ -24,21 +24,21 @@ type nameProgressLogger struct { sync.Mutex } -// newNameProgressLogger returns a new name progress logger. +// newClaimProgressLogger returns a new name progress logger. // The progress message is templated as follows: // {progressAction} {numProcessed} {names|name} in the last {timePeriod} (total {totalProcessed}) -func newNameProgressLogger(progressMessage string, logger btclog.Logger) *nameProgressLogger { - return &nameProgressLogger{ +func newClaimProgressLogger(progressMessage string, logger btclog.Logger) *claimProgressLogger { + return &claimProgressLogger{ lastLogNameTime: time.Now(), progressAction: progressMessage, subsystemLogger: logger, } } -// LogName logs a new name as an information message to show progress -// to the user. In order to prevent spam, it limits logging to one -// message every 10 seconds with duration and totals included. -func (n *nameProgressLogger) LogName(name []byte) { +// LogName logs a new claim name as an information message to show progress +// to the user. In order to prevent spam, it limits logging to one message +// every 10 seconds with duration and totals included. +func (n *claimProgressLogger) LogName(name []byte) { n.Lock() defer n.Unlock() @@ -60,13 +60,13 @@ func (n *nameProgressLogger) LogName(name []byte) { if n.recentLogName == 1 { nameStr = "name" } - n.subsystemLogger.Infof("%s %d %s in the last %s (total %d)", + n.subsystemLogger.Infof("%s %d claim %s in the last %s (total %d)", n.progressAction, n.recentLogName, nameStr, tDuration, n.totalLogName) n.recentLogName = 0 n.lastLogNameTime = now } -func (n *nameProgressLogger) SetLastLogTime(time time.Time) { +func (n *claimProgressLogger) SetLastLogTime(time time.Time) { n.lastLogNameTime = time } -- 2.45.2 From 3a179a0eeea7e62b1308279c88b708c53f617f49 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 5 Jul 2022 20:11:29 -0700 Subject: [PATCH 418/459] [lbry] rpc: un-embedded attributes in getaddressinfo result lbcwallet failed to re-generate RPC help message. The help message generator doesn't handle embedded fields properly. --- btcjson/walletsvrresults.go | 21 ++++++++++++++++++++- btcjson/walletsvrresults_test.go | 6 ++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index 2b7354e7..4939454d 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -53,7 +53,26 @@ type embeddedAddressInfo struct { // 3. Information about the embedded address in case of P2SH or P2WSH. // Same structure as (1). type GetAddressInfoResult struct { - embeddedAddressInfo + // The following fields are identical to embeddedAddressInfo. + // However, the utility to generate RPC help message can't handle + // embedded field properly. So, spell out the attributes individually. + Address string `json:"address"` + ScriptPubKey string `json:"scriptPubKey"` + Descriptor *string `json:"desc,omitempty"` + IsScript bool `json:"isscript"` + IsChange bool `json:"ischange"` + IsWitness bool `json:"iswitness"` + WitnessVersion int `json:"witness_version,omitempty"` + WitnessProgram *string `json:"witness_program,omitempty"` + ScriptType *txscript.ScriptClass `json:"script,omitempty"` + Hex *string `json:"hex,omitempty"` + PubKeys *[]string `json:"pubkeys,omitempty"` + SignaturesRequired *int `json:"sigsrequired,omitempty"` + PubKey *string `json:"pubkey,omitempty"` + IsCompressed *bool `json:"iscompressed,omitempty"` + HDMasterFingerprint *string `json:"hdmasterfingerprint,omitempty"` + Labels []string `json:"labels"` + IsMine bool `json:"ismine"` IsWatchOnly bool `json:"iswatchonly"` Timestamp *int `json:"timestamp,omitempty"` diff --git a/btcjson/walletsvrresults_test.go b/btcjson/walletsvrresults_test.go index 510c367c..0db2eafc 100644 --- a/btcjson/walletsvrresults_test.go +++ b/btcjson/walletsvrresults_test.go @@ -37,10 +37,8 @@ func TestGetAddressInfoResult(t *testing.T) { name: "GetAddressInfoResult - ScriptType", result: `{"script":"nonstandard","address":"1abc"}`, want: GetAddressInfoResult{ - embeddedAddressInfo: embeddedAddressInfo{ - Address: "1abc", - ScriptType: nonStandard, - }, + Address: "1abc", + ScriptType: nonStandard, }, }, { -- 2.45.2 From d5922cd725783207f8c3c7d2d72dbd9a94a63682 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 6 Jul 2022 20:44:22 -0700 Subject: [PATCH 419/459] [lbry] version: fix version string handling --- version/version.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index a4b33597..af3965ea 100644 --- a/version/version.go +++ b/version/version.go @@ -139,7 +139,10 @@ func (v parsedVersion) buildmeta() string { } func (v parsedVersion) full() string { - return fmt.Sprintf("%s-%s+%s", v.version, v.prerelease, v.buildmeta()) + if len(v.prerelease) > 0 { + return fmt.Sprintf("%s-%s+%s", v.version, v.prerelease, v.buildmeta()) + } + return fmt.Sprintf("%s+%s", v.version, v.buildmeta()) } func parseTag(tag string) (version string, prerelease string, err error) { @@ -148,7 +151,13 @@ func parseTag(tag string) (version string, prerelease string, err error) { return "", "", fmt.Errorf("tag must be prefixed with v; %s", tag) } - strs := strings.Split(tag[1:], "-") + tag = tag[1:] + + if !strings.Contains(tag, "-") { + return tag, "", nil + } + + strs := strings.Split(tag, "-") if len(strs) != 2 { return "", "", fmt.Errorf("tag must be in the form of Version.Revision; %s", tag) -- 2.45.2 From bb93a4934971da95c16c287d7ac9d90a5101da42 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 11 Jul 2022 16:44:18 -0700 Subject: [PATCH 420/459] [lbry] config: allow non-localhost connections with TLS disabled --- config.go | 16 +--------------- doc.go | 4 +--- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/config.go b/config.go index aee85c3f..1e5f0392 100644 --- a/config.go +++ b/config.go @@ -977,13 +977,8 @@ func loadConfig() (*config, []string, error) { // Only allow TLS to be disabled if the RPC is bound to localhost // addresses. if !cfg.DisableRPC && cfg.DisableTLS { - allowedTLSListeners := map[string]struct{}{ - "localhost": {}, - "127.0.0.1": {}, - "::1": {}, - } for _, addr := range cfg.RPCListeners { - host, _, err := net.SplitHostPort(addr) + _, _, err := net.SplitHostPort(addr) if err != nil { str := "%s: RPC listen interface '%s' is " + "invalid: %v" @@ -992,15 +987,6 @@ func loadConfig() (*config, []string, error) { fmt.Fprintln(os.Stderr, usageMessage) return nil, nil, err } - if _, ok := allowedTLSListeners[host]; !ok { - str := "%s: the --notls option may not be used " + - "when binding RPC to non localhost " + - "addresses: %s" - err := fmt.Errorf(str, funcName, addr) - fmt.Fprintln(os.Stderr, err) - fmt.Fprintln(os.Stderr, usageMessage) - return nil, nil, err - } } } diff --git a/doc.go b/doc.go index 84a96ea8..fc7e4573 100644 --- a/doc.go +++ b/doc.go @@ -102,9 +102,7 @@ Application Options: server is disabled by default if no rpcuser/rpcpass or rpclimituser/rpclimitpass is specified - --notls Disable TLS for the RPC server -- NOTE: This is - only allowed if the RPC server is bound to - localhost + --notls Disable TLS for the RPC server --onion= Connect to tor hidden services via SOCKS5 proxy (eg. 127.0.0.1:9050) --onionpass= Password for onion proxy server -- 2.45.2 From 8d1005706baa180ad78454f85066c2aff6bb8ef5 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Jul 2022 10:45:00 -0700 Subject: [PATCH 421/459] rpc: remove deprecated and unimplemented 'setaccount' --- btcjson/walletsvrcmds.go | 16 ---------------- btcjson/walletsvrcmds_test.go | 14 -------------- rpcclient/wallet.go | 27 --------------------------- rpcserver.go | 1 - 4 files changed, 58 deletions(-) diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index 8569c1d5..1c4da304 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -650,21 +650,6 @@ func NewSendToAddressCmd(address string, amount float64, comment, commentTo *str } } -// SetAccountCmd defines the setaccount JSON-RPC command. -type SetAccountCmd struct { - Address string - Account string -} - -// NewSetAccountCmd returns a new instance which can be used to issue a -// setaccount JSON-RPC command. -func NewSetAccountCmd(address, account string) *SetAccountCmd { - return &SetAccountCmd{ - Address: address, - Account: account, - } -} - // SetTxFeeCmd defines the settxfee JSON-RPC command. type SetTxFeeCmd struct { Amount float64 // In BTC @@ -1123,7 +1108,6 @@ func init() { MustRegisterCmd("sendfrom", (*SendFromCmd)(nil), flags) MustRegisterCmd("sendmany", (*SendManyCmd)(nil), flags) MustRegisterCmd("sendtoaddress", (*SendToAddressCmd)(nil), flags) - MustRegisterCmd("setaccount", (*SetAccountCmd)(nil), flags) MustRegisterCmd("settxfee", (*SetTxFeeCmd)(nil), flags) MustRegisterCmd("signmessage", (*SignMessageCmd)(nil), flags) MustRegisterCmd("signrawtransaction", (*SignRawTransactionCmd)(nil), flags) diff --git a/btcjson/walletsvrcmds_test.go b/btcjson/walletsvrcmds_test.go index d33888d4..d2cf1956 100644 --- a/btcjson/walletsvrcmds_test.go +++ b/btcjson/walletsvrcmds_test.go @@ -1205,20 +1205,6 @@ func TestWalletSvrCmds(t *testing.T) { CommentTo: btcjson.String("commentto"), }, }, - { - name: "setaccount", - newCmd: func() (interface{}, error) { - return btcjson.NewCmd("setaccount", "1Address", "acct") - }, - staticCmd: func() interface{} { - return btcjson.NewSetAccountCmd("1Address", "acct") - }, - marshalled: `{"jsonrpc":"1.0","method":"setaccount","params":["1Address","acct"],"id":1}`, - unmarshalled: &btcjson.SetAccountCmd{ - Address: "1Address", - Account: "acct", - }, - }, { name: "settxfee", newCmd: func() (interface{}, error) { diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index 784f0688..acccca9a 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -1279,33 +1279,6 @@ func (c *Client) GetAccount(address btcutil.Address) (string, error) { return c.GetAccountAsync(address).Receive() } -// FutureSetAccountResult is a future promise to deliver the result of a -// SetAccountAsync RPC invocation (or an applicable error). -type FutureSetAccountResult chan *Response - -// Receive waits for the Response promised by the future and returns the result -// of setting the account to be associated with the passed address. -func (r FutureSetAccountResult) Receive() error { - _, err := ReceiveFuture(r) - return err -} - -// SetAccountAsync returns an instance of a type that can be used to get the -// result of the RPC at some future time by invoking the Receive function on the -// returned instance. -// -// See SetAccount for the blocking version and more details. -func (c *Client) SetAccountAsync(address btcutil.Address, account string) FutureSetAccountResult { - addr := address.EncodeAddress() - cmd := btcjson.NewSetAccountCmd(addr, account) - return c.SendCmd(cmd) -} - -// SetAccount sets the account associated with the passed address. -func (c *Client) SetAccount(address btcutil.Address, account string) error { - return c.SetAccountAsync(address, account).Receive() -} - // FutureGetAddressesByAccountResult is a future promise to deliver the result // of a GetAddressesByAccountAsync RPC invocation (or an applicable error). type FutureGetAddressesByAccountResult struct { diff --git a/rpcserver.go b/rpcserver.go index fddfaaa3..a47ccbec 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -229,7 +229,6 @@ var rpcAskWallet = map[string]struct{}{ "sendfrom": {}, "sendmany": {}, "sendtoaddress": {}, - "setaccount": {}, "settxfee": {}, "signmessage": {}, "signrawtransaction": {}, -- 2.45.2 From fae4063046884b5172f07d86035b06641da12a47 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 14 Jul 2022 10:51:42 -0700 Subject: [PATCH 422/459] rpc: remove deprecated and unimplemented 'move' --- btcjson/walletsvrcmds.go | 25 ------------- btcjson/walletsvrcmds_test.go | 51 -------------------------- rpcclient/wallet.go | 68 ----------------------------------- rpcserver.go | 1 - 4 files changed, 145 deletions(-) diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index 1c4da304..f43e3c22 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -556,30 +556,6 @@ func NewLockUnspentCmd(unlock bool, transactions []TransactionInput) *LockUnspen } } -// MoveCmd defines the move JSON-RPC command. -type MoveCmd struct { - FromAccount string - ToAccount string - Amount float64 // In BTC - MinConf *int `jsonrpcdefault:"1"` - Comment *string -} - -// NewMoveCmd returns a new instance which can be used to issue a move JSON-RPC -// command. -// -// The parameters which are pointers indicate they are optional. Passing nil -// for optional parameters will use the default value. -func NewMoveCmd(fromAccount, toAccount string, amount float64, minConf *int, comment *string) *MoveCmd { - return &MoveCmd{ - FromAccount: fromAccount, - ToAccount: toAccount, - Amount: amount, - MinConf: minConf, - Comment: comment, - } -} - // SendFromCmd defines the sendfrom JSON-RPC command. type SendFromCmd struct { FromAccount string @@ -1104,7 +1080,6 @@ func init() { MustRegisterCmd("listunspent", (*ListUnspentCmd)(nil), flags) MustRegisterCmd("loadwallet", (*LoadWalletCmd)(nil), flags) MustRegisterCmd("lockunspent", (*LockUnspentCmd)(nil), flags) - MustRegisterCmd("move", (*MoveCmd)(nil), flags) MustRegisterCmd("sendfrom", (*SendFromCmd)(nil), flags) MustRegisterCmd("sendmany", (*SendManyCmd)(nil), flags) MustRegisterCmd("sendtoaddress", (*SendToAddressCmd)(nil), flags) diff --git a/btcjson/walletsvrcmds_test.go b/btcjson/walletsvrcmds_test.go index d2cf1956..e19adf6c 100644 --- a/btcjson/walletsvrcmds_test.go +++ b/btcjson/walletsvrcmds_test.go @@ -996,57 +996,6 @@ func TestWalletSvrCmds(t *testing.T) { }, }, }, - { - name: "move", - newCmd: func() (interface{}, error) { - return btcjson.NewCmd("move", "from", "to", 0.5) - }, - staticCmd: func() interface{} { - return btcjson.NewMoveCmd("from", "to", 0.5, nil, nil) - }, - marshalled: `{"jsonrpc":"1.0","method":"move","params":["from","to",0.5],"id":1}`, - unmarshalled: &btcjson.MoveCmd{ - FromAccount: "from", - ToAccount: "to", - Amount: 0.5, - MinConf: btcjson.Int(1), - Comment: nil, - }, - }, - { - name: "move optional1", - newCmd: func() (interface{}, error) { - return btcjson.NewCmd("move", "from", "to", 0.5, 6) - }, - staticCmd: func() interface{} { - return btcjson.NewMoveCmd("from", "to", 0.5, btcjson.Int(6), nil) - }, - marshalled: `{"jsonrpc":"1.0","method":"move","params":["from","to",0.5,6],"id":1}`, - unmarshalled: &btcjson.MoveCmd{ - FromAccount: "from", - ToAccount: "to", - Amount: 0.5, - MinConf: btcjson.Int(6), - Comment: nil, - }, - }, - { - name: "move optional2", - newCmd: func() (interface{}, error) { - return btcjson.NewCmd("move", "from", "to", 0.5, 6, "comment") - }, - staticCmd: func() interface{} { - return btcjson.NewMoveCmd("from", "to", 0.5, btcjson.Int(6), btcjson.String("comment")) - }, - marshalled: `{"jsonrpc":"1.0","method":"move","params":["from","to",0.5,6,"comment"],"id":1}`, - unmarshalled: &btcjson.MoveCmd{ - FromAccount: "from", - ToAccount: "to", - Amount: 0.5, - MinConf: btcjson.Int(6), - Comment: btcjson.String("comment"), - }, - }, { name: "sendfrom", newCmd: func() (interface{}, error) { diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index acccca9a..6f54730b 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -1355,74 +1355,6 @@ func (r FutureMoveResult) Receive() (bool, error) { return moveResult, nil } -// MoveAsync returns an instance of a type that can be used to get the result of -// the RPC at some future time by invoking the Receive function on the returned -// instance. -// -// See Move for the blocking version and more details. -func (c *Client) MoveAsync(fromAccount, toAccount string, amount btcutil.Amount) FutureMoveResult { - cmd := btcjson.NewMoveCmd(fromAccount, toAccount, amount.ToBTC(), nil, - nil) - return c.SendCmd(cmd) -} - -// Move moves specified amount from one account in your wallet to another. Only -// funds with the default number of minimum confirmations will be used. -// -// See MoveMinConf and MoveComment for different options. -func (c *Client) Move(fromAccount, toAccount string, amount btcutil.Amount) (bool, error) { - return c.MoveAsync(fromAccount, toAccount, amount).Receive() -} - -// MoveMinConfAsync returns an instance of a type that can be used to get the -// result of the RPC at some future time by invoking the Receive function on the -// returned instance. -// -// See MoveMinConf for the blocking version and more details. -func (c *Client) MoveMinConfAsync(fromAccount, toAccount string, - amount btcutil.Amount, minConfirms int) FutureMoveResult { - - cmd := btcjson.NewMoveCmd(fromAccount, toAccount, amount.ToBTC(), - &minConfirms, nil) - return c.SendCmd(cmd) -} - -// MoveMinConf moves specified amount from one account in your wallet to -// another. Only funds with the passed number of minimum confirmations will be -// used. -// -// See Move to use the default number of minimum confirmations and MoveComment -// for additional options. -func (c *Client) MoveMinConf(fromAccount, toAccount string, amount btcutil.Amount, minConf int) (bool, error) { - return c.MoveMinConfAsync(fromAccount, toAccount, amount, minConf).Receive() -} - -// MoveCommentAsync returns an instance of a type that can be used to get the -// result of the RPC at some future time by invoking the Receive function on the -// returned instance. -// -// See MoveComment for the blocking version and more details. -func (c *Client) MoveCommentAsync(fromAccount, toAccount string, - amount btcutil.Amount, minConfirms int, comment string) FutureMoveResult { - - cmd := btcjson.NewMoveCmd(fromAccount, toAccount, amount.ToBTC(), - &minConfirms, &comment) - return c.SendCmd(cmd) -} - -// MoveComment moves specified amount from one account in your wallet to -// another and stores the provided comment in the wallet. The comment -// parameter is only available in the wallet. Only funds with the passed number -// of minimum confirmations will be used. -// -// See Move and MoveMinConf to use defaults. -func (c *Client) MoveComment(fromAccount, toAccount string, amount btcutil.Amount, - minConf int, comment string) (bool, error) { - - return c.MoveCommentAsync(fromAccount, toAccount, amount, minConf, - comment).Receive() -} - // FutureRenameAccountResult is a future promise to deliver the result of a // RenameAccountAsync RPC invocation (or an applicable error). type FutureRenameAccountResult chan *Response diff --git a/rpcserver.go b/rpcserver.go index a47ccbec..1e37f458 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -225,7 +225,6 @@ var rpcAskWallet = map[string]struct{}{ "listtransactions": {}, "listunspent": {}, "lockunspent": {}, - "move": {}, "sendfrom": {}, "sendmany": {}, "sendtoaddress": {}, -- 2.45.2 From 5499a2c1b3999cfcf4ebdc108a9aeddeeed0b52c Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 17 Jul 2022 11:06:34 -0700 Subject: [PATCH 423/459] [lbry] claimtrie: more verbose error message in ResetHeight --- claimtrie/claimtrie.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/claimtrie/claimtrie.go b/claimtrie/claimtrie.go index 667916dd..2bc0cdbf 100644 --- a/claimtrie/claimtrie.go +++ b/claimtrie/claimtrie.go @@ -333,13 +333,23 @@ func (ct *ClaimTrie) ResetHeight(height int32) error { if passedHashFork { names = nil // force them to reconsider all names } + + var fullRebuildRequired bool + err = ct.merkleTrie.SetRoot(hash) if err == merkletrie.ErrFullRebuildRequired { + fullRebuildRequired = true + } else if err != nil { + return errors.Wrapf(err, "setRoot") + } + + if fullRebuildRequired { ct.runFullTrieRebuild(names, nil) } if !ct.MerkleHash().IsEqual(hash) { - return errors.Errorf("unable to restore the hash at height %d", height) + return errors.Errorf("unable to restore the hash at height %d"+ + " (fullTriedRebuilt: %t)", height, fullRebuildRequired) } return errors.WithStack(ct.blockRepo.Delete(height+1, oldHeight)) -- 2.45.2 From 13e31d033aa8db3afc00b127e00f5999d5071d3a Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Thu, 14 Jul 2022 17:44:39 -0400 Subject: [PATCH 424/459] [rpc mempool] Add support for usage, total_fee, mempoolminfee, minrelaytxfee to RPC getmempoolinfo. --- btcjson/chainsvrresults.go | 8 +++- mempool/mempool.go | 72 +++++++++++++++++++++++++++++++- mempool/memusage.go | 84 ++++++++++++++++++++++++++++++++++++++ rpcserver.go | 14 +------ rpcserverhelp.go | 8 +++- 5 files changed, 168 insertions(+), 18 deletions(-) create mode 100644 mempool/memusage.go diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index ffa0a103..261cdcf4 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -337,8 +337,12 @@ type GetChainTipsResult struct { // GetMempoolInfoResult models the data returned from the getmempoolinfo // command. type GetMempoolInfoResult struct { - Size int64 `json:"size"` - Bytes int64 `json:"bytes"` + Size int64 `json:"size"` // Current tx count + Bytes int64 `json:"bytes"` // Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted + Usage int64 `json:"usage"` // Total memory usage for the mempool + TotalFee float64 `json:"total_fee"` // Total fees for the mempool in BTC, ignoring modified fees through prioritizetransaction + MemPoolMinFee float64 `json:"mempoolminfee"` // Minimum fee rate in BTC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee + MinRelayTxFee float64 `json:"minrelaytxfee"` // Current minimum relay fee for transactions } // NetworksResult models the networks data from the getnetworkinfo command. diff --git a/mempool/mempool.go b/mempool/mempool.go index 45cf602b..9f2e4f28 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -8,6 +8,7 @@ import ( "container/list" "fmt" "math" + "reflect" "sync" "sync/atomic" "time" @@ -156,6 +157,15 @@ type Policy struct { RejectReplacement bool } +// aggregateInfo tracks aggregated serialized size, memory usage, and fees +// for TxDesc in the mempool. +type aggregateInfo struct { + totalCount int64 + totalBytes int64 + totalMem int64 + totalFee int64 +} + // TxDesc is a descriptor containing a transaction in the mempool along with // additional metadata. type TxDesc struct { @@ -166,6 +176,20 @@ type TxDesc struct { StartingPriority float64 } +func (txD *TxDesc) incr(info *aggregateInfo) { + info.totalCount += 1 + info.totalBytes += int64(txD.Tx.MsgTx().SerializeSize()) + info.totalMem += int64(dynamicMemUsage(reflect.ValueOf(txD), false, 0)) + info.totalFee += txD.Fee +} + +func (txD *TxDesc) decr(info *aggregateInfo) { + info.totalCount -= 1 + info.totalBytes -= int64(txD.Tx.MsgTx().SerializeSize()) + info.totalMem -= int64(dynamicMemUsage(reflect.ValueOf(txD), false, 0)) + info.totalFee -= txD.Fee +} + // orphanTx is normal transaction that references an ancestor transaction // that is not yet available. It also contains additional information related // to it such as an expiration time to help prevent caching the orphan forever. @@ -175,6 +199,18 @@ type orphanTx struct { expiration time.Time } +func (otx *orphanTx) incr(info *aggregateInfo) { + info.totalCount += 1 + info.totalBytes += int64(otx.tx.MsgTx().SerializeSize()) + info.totalMem += int64(dynamicMemUsage(reflect.ValueOf(otx), true, 0)) +} + +func (otx *orphanTx) decr(info *aggregateInfo) { + info.totalCount -= 1 + info.totalBytes -= int64(otx.tx.MsgTx().SerializeSize()) + info.totalMem -= int64(dynamicMemUsage(reflect.ValueOf(otx), false, 0)) +} + // TxPool is used as a source of transactions that need to be mined into blocks // and relayed to other peers. It is safe for concurrent access from multiple // peers. @@ -196,6 +232,9 @@ type TxPool struct { // the scan will only run when an orphan is added to the pool as opposed // to on an unconditional timer. nextExpireScan time.Time + + // stats are aggregated over pool, orphans, etc. + stats aggregateInfo } // Ensure the TxPool type implements the mining.TxSource interface. @@ -240,6 +279,9 @@ func (mp *TxPool) removeOrphan(tx *btcutil.Tx, removeRedeemers bool) { // Remove the transaction from the orphan pool. delete(mp.orphans, *txHash) + + // Update stats. + otx.decr(&mp.stats) } // RemoveOrphan removes the passed orphan transaction from the orphan pool and @@ -336,11 +378,12 @@ func (mp *TxPool) addOrphan(tx *btcutil.Tx, tag Tag) { // orphan if space is still needed. mp.limitNumOrphans() - mp.orphans[*tx.Hash()] = &orphanTx{ + otx := &orphanTx{ tx: tx, tag: tag, expiration: time.Now().Add(orphanTTL), } + mp.orphans[*tx.Hash()] = otx for _, txIn := range tx.MsgTx().TxIn { if _, exists := mp.orphansByPrev[txIn.PreviousOutPoint]; !exists { mp.orphansByPrev[txIn.PreviousOutPoint] = @@ -349,6 +392,9 @@ func (mp *TxPool) addOrphan(tx *btcutil.Tx, tag Tag) { mp.orphansByPrev[txIn.PreviousOutPoint][*tx.Hash()] = tx } + // Update stats. + otx.incr(&mp.stats) + log.Debugf("Stored orphan transaction %v (total: %d)", tx.Hash(), len(mp.orphans)) } @@ -498,6 +544,9 @@ func (mp *TxPool) removeTransaction(tx *btcutil.Tx, removeRedeemers bool) { } delete(mp.pool, *txHash) + // Update stats. + txDesc.decr(&mp.stats) + // Inform associated fee estimator that the transaction has been removed // from the mempool if mp.cfg.RemoveTxFromFeeEstimation != nil { @@ -579,6 +628,9 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil mp.cfg.AddTxToFeeEstimation(txD.Tx.Hash(), txD.Fee, size) } + // Update stats. + txD.incr(&mp.stats) + return txD } @@ -1503,6 +1555,24 @@ func (mp *TxPool) MiningDescs() []*mining.TxDesc { return descs } +func (mp *TxPool) MempoolInfo() *btcjson.GetMempoolInfoResult { + mp.mtx.RLock() + policy := mp.cfg.Policy + stats := mp.stats + mp.mtx.RUnlock() + + ret := &btcjson.GetMempoolInfoResult{ + Size: stats.totalCount, + Usage: stats.totalMem, + Bytes: stats.totalBytes, + TotalFee: btcutil.Amount(stats.totalFee).ToBTC(), + MemPoolMinFee: btcutil.Amount(calcMinRequiredTxRelayFee(1000, policy.MinRelayTxFee)).ToBTC(), + MinRelayTxFee: policy.MinRelayTxFee.ToBTC(), + } + + return ret +} + // RawMempoolVerbose returns all the entries in the mempool as a fully // populated btcjson result. // diff --git a/mempool/memusage.go b/mempool/memusage.go new file mode 100644 index 00000000..f6a546a0 --- /dev/null +++ b/mempool/memusage.go @@ -0,0 +1,84 @@ +// Copyright (c) 2013-2016 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package mempool + +import ( + "reflect" +) + +func dynamicMemUsage(v reflect.Value, debug bool, level int) uintptr { + t := v.Type() + bytes := t.Size() + if debug { + println("[", level, "]", t.Kind().String(), "(", t.String(), ") ->", t.Size()) + } + + // For complex types, we need to peek inside slices/arrays/structs/maps and chase pointers. + switch t.Kind() { + case reflect.Pointer, reflect.Interface: + if !v.IsNil() { + bytes += dynamicMemUsage(v.Elem(), debug, level+1) + } + case reflect.Array, reflect.Slice: + for j := 0; j < v.Len(); j++ { + vi := v.Index(j) + k := vi.Type().Kind() + if debug { + println("[", level, "] index:", j, "kind:", k.String()) + } + elemB := uintptr(0) + if t.Kind() == reflect.Array { + if (k == reflect.Pointer || k == reflect.Interface) && !vi.IsNil() { + elemB += dynamicMemUsage(vi.Elem(), debug, level+1) + } + } else { // slice + elemB += dynamicMemUsage(vi, debug, level+1) + } + if k == reflect.Uint8 { + // short circuit for byte slice/array + bytes += elemB * uintptr(v.Len()) + if debug { + println("...", v.Len(), "elements") + } + break + } + bytes += elemB + } + case reflect.Map: + iter := v.MapRange() + for iter.Next() { + vk := iter.Key() + vv := iter.Value() + if debug { + println("[", level, "] key:", vk.Type().Kind().String()) + } + bytes += dynamicMemUsage(vk, debug, level+1) + if debug { + println("[", level, "] value:", vv.Type().Kind().String()) + } + bytes += dynamicMemUsage(vv, debug, level+1) + if debug { + println("...", v.Len(), "map elements") + } + debug = false + } + case reflect.Struct: + for _, f := range reflect.VisibleFields(t) { + vf := v.FieldByIndex(f.Index) + k := vf.Type().Kind() + if debug { + println("[", level, "] field:", f.Name, "kind:", k.String()) + } + if (k == reflect.Pointer || k == reflect.Interface) && !vf.IsNil() { + bytes += dynamicMemUsage(vf.Elem(), debug, level+1) + } else if k == reflect.Array || k == reflect.Slice { + bytes -= vf.Type().Size() + bytes += dynamicMemUsage(vf, debug, level+1) + } + } + } + + return bytes +} diff --git a/rpcserver.go b/rpcserver.go index 1e37f458..e2f21981 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -2466,19 +2466,7 @@ func handleGetInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in // handleGetMempoolInfo implements the getmempoolinfo command. func handleGetMempoolInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - mempoolTxns := s.cfg.TxMemPool.TxDescs() - - var numBytes int64 - for _, txD := range mempoolTxns { - numBytes += int64(txD.Tx.MsgTx().SerializeSize()) - } - - ret := &btcjson.GetMempoolInfoResult{ - Size: int64(len(mempoolTxns)), - Bytes: numBytes, - } - - return ret, nil + return s.cfg.TxMemPool.MempoolInfo(), nil } // handleGetMempoolEntry implements the getmempoolentry command. diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 4cfde4d3..8c339855 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -453,8 +453,12 @@ var helpDescsEnUS = map[string]string{ "getmempoolinfo--synopsis": "Returns memory pool information", // GetMempoolInfoResult help. - "getmempoolinforesult-bytes": "Size in bytes of the mempool", - "getmempoolinforesult-size": "Number of transactions in the mempool", + "getmempoolinforesult-bytes": "Size in bytes of the mempool", + "getmempoolinforesult-size": "Number of transactions in the mempool", + "getmempoolinforesult-usage": "Total memory usage for the mempool", + "getmempoolinforesult-total_fee": "Total fees for the mempool in LBC, ignoring modified fees through prioritizetransaction", + "getmempoolinforesult-mempoolminfee": "Minimum fee rate in LBC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee", + "getmempoolinforesult-minrelaytxfee": "Current minimum relay fee for transactions", // GetMiningInfoResult help. "getmininginforesult-blocks": "Height of the latest best block", -- 2.45.2 From abb1b8b388535c5e55acfa5452d61b41d149f771 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Thu, 14 Jul 2022 17:58:24 -0400 Subject: [PATCH 425/459] [rpc mempool] Add support for unbroadcastcount to RPC getmempoolinfo. --- btcjson/chainsvrresults.go | 1 + mempool/mempool.go | 18 ++++++++++++++++++ rpcserver.go | 1 + rpcserverhelp.go | 1 + server.go | 5 +++++ 5 files changed, 26 insertions(+) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 261cdcf4..ee588fbf 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -343,6 +343,7 @@ type GetMempoolInfoResult struct { TotalFee float64 `json:"total_fee"` // Total fees for the mempool in BTC, ignoring modified fees through prioritizetransaction MemPoolMinFee float64 `json:"mempoolminfee"` // Minimum fee rate in BTC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee MinRelayTxFee float64 `json:"minrelaytxfee"` // Current minimum relay fee for transactions + UnbroadcastCount int64 `json:"unbroadcastcount"` // Current number of transactions that haven't passed initial broadcast yet } // NetworksResult models the networks data from the getnetworkinfo command. diff --git a/mempool/mempool.go b/mempool/mempool.go index 9f2e4f28..688e532d 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -235,6 +235,9 @@ type TxPool struct { // stats are aggregated over pool, orphans, etc. stats aggregateInfo + + // unbroadcast is a set of transactions yet to be broadcast. + unbroadcast map[chainhash.Hash]bool } // Ensure the TxPool type implements the mining.TxSource interface. @@ -1555,10 +1558,23 @@ func (mp *TxPool) MiningDescs() []*mining.TxDesc { return descs } +func (mp *TxPool) AddUnbroadcastTx(hash *chainhash.Hash) { + mp.mtx.Lock() + mp.unbroadcast[*hash] = true + mp.mtx.Unlock() +} + +func (mp *TxPool) RemoveUnbroadcastTx(hash *chainhash.Hash) { + mp.mtx.Lock() + delete(mp.unbroadcast, *hash) + mp.mtx.Unlock() +} + func (mp *TxPool) MempoolInfo() *btcjson.GetMempoolInfoResult { mp.mtx.RLock() policy := mp.cfg.Policy stats := mp.stats + unbroadcastCount := int64(len(mp.unbroadcast)) mp.mtx.RUnlock() ret := &btcjson.GetMempoolInfoResult{ @@ -1568,6 +1584,7 @@ func (mp *TxPool) MempoolInfo() *btcjson.GetMempoolInfoResult { TotalFee: btcutil.Amount(stats.totalFee).ToBTC(), MemPoolMinFee: btcutil.Amount(calcMinRequiredTxRelayFee(1000, policy.MinRelayTxFee)).ToBTC(), MinRelayTxFee: policy.MinRelayTxFee.ToBTC(), + UnbroadcastCount: unbroadcastCount, } return ret @@ -1646,5 +1663,6 @@ func New(cfg *Config) *TxPool { orphansByPrev: make(map[wire.OutPoint]map[chainhash.Hash]*btcutil.Tx), nextExpireScan: time.Now().Add(orphanExpireScanInterval), outpoints: make(map[wire.OutPoint]*btcutil.Tx), + unbroadcast: make(map[chainhash.Hash]bool), } } diff --git a/rpcserver.go b/rpcserver.go index e2f21981..1fc32a06 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3746,6 +3746,7 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st // Keep track of all the sendrawtransaction request txns so that they // can be rebroadcast if they don't make their way into a block. txD := acceptedTxs[0] + s.cfg.TxMemPool.AddUnbroadcastTx(txD.Tx.Hash()) iv := wire.NewInvVect(wire.InvTypeTx, txD.Tx.Hash()) s.cfg.ConnMgr.AddRebroadcastInventory(iv, txD) diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 8c339855..3a6eb87b 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -459,6 +459,7 @@ var helpDescsEnUS = map[string]string{ "getmempoolinforesult-total_fee": "Total fees for the mempool in LBC, ignoring modified fees through prioritizetransaction", "getmempoolinforesult-mempoolminfee": "Minimum fee rate in LBC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee", "getmempoolinforesult-minrelaytxfee": "Current minimum relay fee for transactions", + "getmempoolinforesult-unbroadcastcount": "Current number of transactions that haven't passed initial broadcast yet", // GetMiningInfoResult help. "getmininginforesult-blocks": "Height of the latest best block", diff --git a/server.go b/server.go index 82da9ee1..db13ed64 100644 --- a/server.go +++ b/server.go @@ -699,6 +699,11 @@ func (sp *serverPeer) OnGetData(_ *peer.Peer, msg *wire.MsgGetData) { if i == len(msg.InvList)-1 && c != nil { <-c } + } else if iv.Type == wire.InvTypeWitnessTx || iv.Type == wire.InvTypeTx { + // We interpret fulfilling a GETDATA for a transaction as a + // successful initial broadcast and remove it from our + // unbroadcast set. + sp.server.txMemPool.RemoveUnbroadcastTx(&iv.Hash) } numAdded++ waitChan = c -- 2.45.2 From a8a44aa988b7c384b1515d78f2e54c11e91f3e96 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Thu, 14 Jul 2022 18:06:27 -0400 Subject: [PATCH 426/459] [rpc mempool] Hide debugging functionality of dynamicMemUsage(). --- mempool/mempool.go | 8 ++++---- mempool/memusage.go | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/mempool/mempool.go b/mempool/mempool.go index 688e532d..4ef5a018 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -179,14 +179,14 @@ type TxDesc struct { func (txD *TxDesc) incr(info *aggregateInfo) { info.totalCount += 1 info.totalBytes += int64(txD.Tx.MsgTx().SerializeSize()) - info.totalMem += int64(dynamicMemUsage(reflect.ValueOf(txD), false, 0)) + info.totalMem += int64(dynamicMemUsage(reflect.ValueOf(txD))) info.totalFee += txD.Fee } func (txD *TxDesc) decr(info *aggregateInfo) { info.totalCount -= 1 info.totalBytes -= int64(txD.Tx.MsgTx().SerializeSize()) - info.totalMem -= int64(dynamicMemUsage(reflect.ValueOf(txD), false, 0)) + info.totalMem -= int64(dynamicMemUsage(reflect.ValueOf(txD))) info.totalFee -= txD.Fee } @@ -202,13 +202,13 @@ type orphanTx struct { func (otx *orphanTx) incr(info *aggregateInfo) { info.totalCount += 1 info.totalBytes += int64(otx.tx.MsgTx().SerializeSize()) - info.totalMem += int64(dynamicMemUsage(reflect.ValueOf(otx), true, 0)) + info.totalMem += int64(dynamicMemUsage(reflect.ValueOf(otx))) } func (otx *orphanTx) decr(info *aggregateInfo) { info.totalCount -= 1 info.totalBytes -= int64(otx.tx.MsgTx().SerializeSize()) - info.totalMem -= int64(dynamicMemUsage(reflect.ValueOf(otx), false, 0)) + info.totalMem -= int64(dynamicMemUsage(reflect.ValueOf(otx))) } // TxPool is used as a source of transactions that need to be mined into blocks diff --git a/mempool/memusage.go b/mempool/memusage.go index f6a546a0..e65ef8c2 100644 --- a/mempool/memusage.go +++ b/mempool/memusage.go @@ -8,7 +8,11 @@ import ( "reflect" ) -func dynamicMemUsage(v reflect.Value, debug bool, level int) uintptr { +func dynamicMemUsage(v reflect.Value) uintptr { + return _dynamicMemUsage(v, false, 0) +} + +func _dynamicMemUsage(v reflect.Value, debug bool, level int) uintptr { t := v.Type() bytes := t.Size() if debug { @@ -19,7 +23,7 @@ func dynamicMemUsage(v reflect.Value, debug bool, level int) uintptr { switch t.Kind() { case reflect.Pointer, reflect.Interface: if !v.IsNil() { - bytes += dynamicMemUsage(v.Elem(), debug, level+1) + bytes += _dynamicMemUsage(v.Elem(), debug, level+1) } case reflect.Array, reflect.Slice: for j := 0; j < v.Len(); j++ { @@ -31,10 +35,10 @@ func dynamicMemUsage(v reflect.Value, debug bool, level int) uintptr { elemB := uintptr(0) if t.Kind() == reflect.Array { if (k == reflect.Pointer || k == reflect.Interface) && !vi.IsNil() { - elemB += dynamicMemUsage(vi.Elem(), debug, level+1) + elemB += _dynamicMemUsage(vi.Elem(), debug, level+1) } } else { // slice - elemB += dynamicMemUsage(vi, debug, level+1) + elemB += _dynamicMemUsage(vi, debug, level+1) } if k == reflect.Uint8 { // short circuit for byte slice/array @@ -54,11 +58,11 @@ func dynamicMemUsage(v reflect.Value, debug bool, level int) uintptr { if debug { println("[", level, "] key:", vk.Type().Kind().String()) } - bytes += dynamicMemUsage(vk, debug, level+1) + bytes += _dynamicMemUsage(vk, debug, level+1) if debug { println("[", level, "] value:", vv.Type().Kind().String()) } - bytes += dynamicMemUsage(vv, debug, level+1) + bytes += _dynamicMemUsage(vv, debug, level+1) if debug { println("...", v.Len(), "map elements") } @@ -72,10 +76,10 @@ func dynamicMemUsage(v reflect.Value, debug bool, level int) uintptr { println("[", level, "] field:", f.Name, "kind:", k.String()) } if (k == reflect.Pointer || k == reflect.Interface) && !vf.IsNil() { - bytes += dynamicMemUsage(vf.Elem(), debug, level+1) + bytes += _dynamicMemUsage(vf.Elem(), debug, level+1) } else if k == reflect.Array || k == reflect.Slice { bytes -= vf.Type().Size() - bytes += dynamicMemUsage(vf, debug, level+1) + bytes += _dynamicMemUsage(vf, debug, level+1) } } } -- 2.45.2 From eefb1260ebe23de7ad806b74adccdd12b4c4c54a Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Thu, 14 Jul 2022 18:29:55 -0400 Subject: [PATCH 427/459] [rpc mempool] Correct comment BTC -> LBC. --- btcjson/chainsvrresults.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index ee588fbf..6a918eb1 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -340,8 +340,8 @@ type GetMempoolInfoResult struct { Size int64 `json:"size"` // Current tx count Bytes int64 `json:"bytes"` // Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted Usage int64 `json:"usage"` // Total memory usage for the mempool - TotalFee float64 `json:"total_fee"` // Total fees for the mempool in BTC, ignoring modified fees through prioritizetransaction - MemPoolMinFee float64 `json:"mempoolminfee"` // Minimum fee rate in BTC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee + TotalFee float64 `json:"total_fee"` // Total fees for the mempool in LBC, ignoring modified fees through prioritizetransaction + MemPoolMinFee float64 `json:"mempoolminfee"` // Minimum fee rate in LBC/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee MinRelayTxFee float64 `json:"minrelaytxfee"` // Current minimum relay fee for transactions UnbroadcastCount int64 `json:"unbroadcastcount"` // Current number of transactions that haven't passed initial broadcast yet } -- 2.45.2 From 7f9fe4b97058830be58f79e8a54530863d5cd829 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Mon, 18 Jul 2022 11:52:15 -0400 Subject: [PATCH 428/459] [rpc mempool] More tweaks to dynamicMemUsage(). Add toggleable assertions for max depth and switch completness. Toggle them when running in mempool_test.go. Drop support for reflect.Map, as it's not needed at this time. --- mempool/mempool_test.go | 6 ++++ mempool/memusage.go | 73 +++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 17d2d452..1b343cd8 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -21,6 +21,12 @@ import ( btcutil "github.com/lbryio/lbcutil" ) +func init() { + // Toggle assert & debug messages when running tests. + dynamicMemUsageAssert = true + dynamicMemUsageDebug = false +} + // fakeChain is used by the pool harness to provide generated test utxos and // a current faked chain height to the pool callbacks. This, in turn, allows // transactions to appear as though they are spending completely valid utxos. diff --git a/mempool/memusage.go b/mempool/memusage.go index e65ef8c2..c4030a08 100644 --- a/mempool/memusage.go +++ b/mempool/memusage.go @@ -5,83 +5,84 @@ package mempool import ( + "fmt" "reflect" ) +var ( + dynamicMemUsageAssert = false + dynamicMemUsageDebug = false + dynamicMemUsageMaxDepth = 10 +) + func dynamicMemUsage(v reflect.Value) uintptr { - return _dynamicMemUsage(v, false, 0) + return dynamicMemUsageCrawl(v, 0) } -func _dynamicMemUsage(v reflect.Value, debug bool, level int) uintptr { +func dynamicMemUsageCrawl(v reflect.Value, depth int) uintptr { t := v.Type() bytes := t.Size() - if debug { - println("[", level, "]", t.Kind().String(), "(", t.String(), ") ->", t.Size()) + if dynamicMemUsageDebug { + println("[", depth, "]", t.Kind().String(), "(", t.String(), ") ->", t.Size()) } - // For complex types, we need to peek inside slices/arrays/structs/maps and chase pointers. + if depth >= dynamicMemUsageMaxDepth { + if dynamicMemUsageAssert { + panic("crawl reached maximum depth") + } + return bytes + } + + // For complex types, we need to peek inside slices/arrays/structs and chase pointers. switch t.Kind() { case reflect.Pointer, reflect.Interface: if !v.IsNil() { - bytes += _dynamicMemUsage(v.Elem(), debug, level+1) + bytes += dynamicMemUsageCrawl(v.Elem(), depth+1) } case reflect.Array, reflect.Slice: for j := 0; j < v.Len(); j++ { vi := v.Index(j) k := vi.Type().Kind() - if debug { - println("[", level, "] index:", j, "kind:", k.String()) + if dynamicMemUsageDebug { + println("[", depth, "] index:", j, "kind:", k.String()) } - elemB := uintptr(0) + elemBytes := uintptr(0) if t.Kind() == reflect.Array { if (k == reflect.Pointer || k == reflect.Interface) && !vi.IsNil() { - elemB += _dynamicMemUsage(vi.Elem(), debug, level+1) + elemBytes += dynamicMemUsageCrawl(vi.Elem(), depth+1) } } else { // slice - elemB += _dynamicMemUsage(vi, debug, level+1) + elemBytes += dynamicMemUsageCrawl(vi, depth+1) } if k == reflect.Uint8 { // short circuit for byte slice/array - bytes += elemB * uintptr(v.Len()) - if debug { + bytes += elemBytes * uintptr(v.Len()) + if dynamicMemUsageDebug { println("...", v.Len(), "elements") } break } - bytes += elemB - } - case reflect.Map: - iter := v.MapRange() - for iter.Next() { - vk := iter.Key() - vv := iter.Value() - if debug { - println("[", level, "] key:", vk.Type().Kind().String()) - } - bytes += _dynamicMemUsage(vk, debug, level+1) - if debug { - println("[", level, "] value:", vv.Type().Kind().String()) - } - bytes += _dynamicMemUsage(vv, debug, level+1) - if debug { - println("...", v.Len(), "map elements") - } - debug = false + bytes += elemBytes } case reflect.Struct: for _, f := range reflect.VisibleFields(t) { vf := v.FieldByIndex(f.Index) k := vf.Type().Kind() - if debug { - println("[", level, "] field:", f.Name, "kind:", k.String()) + if dynamicMemUsageDebug { + println("[", depth, "] field:", f.Name, "kind:", k.String()) } if (k == reflect.Pointer || k == reflect.Interface) && !vf.IsNil() { - bytes += _dynamicMemUsage(vf.Elem(), debug, level+1) + bytes += dynamicMemUsageCrawl(vf.Elem(), depth+1) } else if k == reflect.Array || k == reflect.Slice { bytes -= vf.Type().Size() - bytes += _dynamicMemUsage(vf, debug, level+1) + bytes += dynamicMemUsageCrawl(vf, depth+1) } } + case reflect.Uint8: + default: + if dynamicMemUsageAssert { + panic(fmt.Sprintf("unsupported kind: %v", t.Kind())) + } } return bytes -- 2.45.2 From b147fe2a5b6e111cded7ab23df3bbf2500b353a6 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 27 Jul 2022 10:18:35 -0700 Subject: [PATCH 429/459] Revert "[lbry] claimtrie: created node cache" This reverts commit 8f95946b17a854763f77cd9f099d823c5957fe97. --- claimtrie/node/cache.go | 101 -------------------------- claimtrie/node/manager.go | 95 ++++++------------------ claimtrie/node/node.go | 28 +------ claimtrie/node/normalizing_manager.go | 3 - 4 files changed, 24 insertions(+), 203 deletions(-) delete mode 100644 claimtrie/node/cache.go diff --git a/claimtrie/node/cache.go b/claimtrie/node/cache.go deleted file mode 100644 index 0f556af1..00000000 --- a/claimtrie/node/cache.go +++ /dev/null @@ -1,101 +0,0 @@ -package node - -import ( - "container/list" - "sync" - - "github.com/lbryio/lbcd/claimtrie/change" -) - -type cacheLeaf struct { - node *Node - element *list.Element - changes []change.Change - height int32 -} - -type Cache struct { - nodes map[string]*cacheLeaf - order *list.List - mtx sync.Mutex - limit int -} - -func (nc *Cache) insert(name []byte, n *Node, height int32) { - key := string(name) - - nc.mtx.Lock() - defer nc.mtx.Unlock() - - existing := nc.nodes[key] - if existing != nil { - existing.node = n - existing.height = height - existing.changes = nil - nc.order.MoveToFront(existing.element) - return - } - - for nc.order.Len() >= nc.limit { - // TODO: maybe ensure that we don't remove nodes that have a lot of changes? - delete(nc.nodes, nc.order.Back().Value.(string)) - nc.order.Remove(nc.order.Back()) - } - - element := nc.order.PushFront(key) - nc.nodes[key] = &cacheLeaf{node: n, element: element, height: height} -} - -func (nc *Cache) fetch(name []byte, height int32) (*Node, []change.Change, int32) { - key := string(name) - - nc.mtx.Lock() - defer nc.mtx.Unlock() - - existing := nc.nodes[key] - if existing != nil && existing.height <= height { - nc.order.MoveToFront(existing.element) - return existing.node, existing.changes, existing.height - } - return nil, nil, -1 -} - -func (nc *Cache) addChanges(changes []change.Change, height int32) { - nc.mtx.Lock() - defer nc.mtx.Unlock() - - for _, c := range changes { - key := string(c.Name) - existing := nc.nodes[key] - if existing != nil && existing.height <= height { - existing.changes = append(existing.changes, c) - } - } -} - -func (nc *Cache) drop(names [][]byte) { - nc.mtx.Lock() - defer nc.mtx.Unlock() - - for _, name := range names { - key := string(name) - existing := nc.nodes[key] - if existing != nil { - // we can't roll it backwards because we don't know its previous height value; just toast it - delete(nc.nodes, key) - nc.order.Remove(existing.element) - } - } -} - -func (nc *Cache) clear() { - nc.mtx.Lock() - defer nc.mtx.Unlock() - nc.nodes = map[string]*cacheLeaf{} - nc.order = list.New() - // we'll let the GC sort out the remains... -} - -func NewCache(limit int) *Cache { - return &Cache{limit: limit, nodes: map[string]*cacheLeaf{}, order: list.New()} -} diff --git a/claimtrie/node/manager.go b/claimtrie/node/manager.go index 31ba0f1a..814bfc80 100644 --- a/claimtrie/node/manager.go +++ b/claimtrie/node/manager.go @@ -21,7 +21,6 @@ type Manager interface { IterateNames(predicate func(name []byte) bool) Hash(name []byte) (*chainhash.Hash, int32) Flush() error - ClearCache() } type BaseManager struct { @@ -31,60 +30,31 @@ type BaseManager struct { changes []change.Change tempChanges map[string][]change.Change - - cache *Cache } func NewBaseManager(repo Repo) (*BaseManager, error) { nm := &BaseManager{ - repo: repo, - cache: NewCache(10000), // TODO: how many should we cache? + repo: repo, } return nm, nil } -func (nm *BaseManager) ClearCache() { - nm.cache.clear() -} - func (nm *BaseManager) NodeAt(height int32, name []byte) (*Node, error) { - n, changes, oldHeight := nm.cache.fetch(name, height) - if n == nil { - changes, err := nm.repo.LoadChanges(name) - if err != nil { - return nil, errors.Wrap(err, "in load changes") - } + changes, err := nm.repo.LoadChanges(name) + if err != nil { + return nil, errors.Wrap(err, "in load changes") + } - if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block - changes = append(changes, nm.tempChanges[string(name)]...) - } + if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block + changes = append(changes, nm.tempChanges[string(name)]...) + } - n, err = nm.newNodeFromChanges(changes, height) - if err != nil { - return nil, errors.Wrap(err, "in new node") - } - // TODO: how can we tell what needs to be cached? - if nm.tempChanges == nil && height == nm.height && n != nil && (len(changes) > 7 || len(name) < 12) { - nm.cache.insert(name, n, height) - } - } else { - if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block - changes = append(changes, nm.tempChanges[string(name)]...) - } - n = n.Clone() - updated, err := nm.updateFromChanges(n, changes, height) - if err != nil { - return nil, errors.Wrap(err, "in update from changes") - } - if !updated { - n.AdjustTo(oldHeight, height, name) - } - if nm.tempChanges == nil && height == nm.height { // TODO: how many changes before we update the cache? - nm.cache.insert(name, n, height) - } + n, err := nm.newNodeFromChanges(changes, height) + if err != nil { + return nil, errors.Wrap(err, "in new node") } return n, nil @@ -96,13 +66,17 @@ func (nm *BaseManager) node(name []byte) (*Node, error) { return nm.NodeAt(nm.height, name) } -func (nm *BaseManager) updateFromChanges(n *Node, changes []change.Change, height int32) (bool, error) { +// newNodeFromChanges returns a new Node constructed from the changes. +// The changes must preserve their order received. +func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) { - count := len(changes) - if count == 0 { - return false, nil + if len(changes) == 0 { + return nil, nil } + + n := New() previous := changes[0].Height + count := len(changes) for i, chg := range changes { if chg.Height < previous { @@ -121,37 +95,15 @@ func (nm *BaseManager) updateFromChanges(n *Node, changes []change.Change, heigh delay := nm.getDelayForName(n, chg) err := n.ApplyChange(chg, delay) if err != nil { - return false, errors.Wrap(err, "in apply change") + return nil, errors.Wrap(err, "in apply change") } } if count <= 0 { - // we applied no changes, which means we shouldn't exist if we had all the changes - // or might mean nothing significant if we are applying a partial changeset - return false, nil - } - lastChange := changes[count-1] - n.AdjustTo(lastChange.Height, height, lastChange.Name) - return true, nil -} - -// newNodeFromChanges returns a new Node constructed from the changes. -// The changes must preserve their order received. -func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) { - - if len(changes) == 0 { return nil, nil } - - n := New() - updated, err := nm.updateFromChanges(n, changes, height) - if err != nil { - return nil, errors.Wrap(err, "in update from changes") - } - if updated { - return n, nil - } - return nil, nil + lastChange := changes[count-1] + return n.AdjustTo(lastChange.Height, height, lastChange.Name), nil } func (nm *BaseManager) AppendChange(chg change.Change) { @@ -268,7 +220,6 @@ func (nm *BaseManager) IncrementHeightTo(height int32, temporary bool) ([][]byte } if !temporary { - nm.cache.addChanges(nm.changes, height) if err := nm.repo.AppendChanges(nm.changes); err != nil { // destroys names return nil, errors.Wrap(err, "in append changes") } @@ -304,8 +255,6 @@ func (nm *BaseManager) DecrementHeightTo(affectedNames [][]byte, height int32) ( return affectedNames, errors.Wrap(err, "in drop changes") } } - - nm.cache.drop(affectedNames) } nm.height = height diff --git a/claimtrie/node/node.go b/claimtrie/node/node.go index ff45fc11..fe6db947 100644 --- a/claimtrie/node/node.go +++ b/claimtrie/node/node.go @@ -110,7 +110,7 @@ func (n *Node) ApplyChange(chg change.Change, delay int32) error { } // AdjustTo activates claims and computes takeovers until it reaches the specified height. -func (n *Node) AdjustTo(height, maxHeight int32, name []byte) { +func (n *Node) AdjustTo(height, maxHeight int32, name []byte) *Node { changed := n.handleExpiredAndActivated(height) > 0 n.updateTakeoverHeight(height, name, changed) if maxHeight > height { @@ -120,6 +120,7 @@ func (n *Node) AdjustTo(height, maxHeight int32, name []byte) { height = h } } + return n } func (n *Node) updateTakeoverHeight(height int32, name []byte, refindBest bool) { @@ -339,28 +340,3 @@ func (n *Node) SortClaimsByBid() { return OutPointLess(n.Claims[j].OutPoint, n.Claims[i].OutPoint) }) } - -func (n *Node) Clone() *Node { - clone := New() - if n.SupportSums != nil { - clone.SupportSums = map[string]int64{} - for key, value := range n.SupportSums { - clone.SupportSums[key] = value - } - } - clone.Supports = make(ClaimList, len(n.Supports)) - for i, support := range n.Supports { - clone.Supports[i] = &Claim{} - *clone.Supports[i] = *support - } - clone.Claims = make(ClaimList, len(n.Claims)) - for i, claim := range n.Claims { - clone.Claims[i] = &Claim{} - *clone.Claims[i] = *claim - } - clone.TakenOverAt = n.TakenOverAt - if n.BestClaim != nil { - clone.BestClaim = clone.Claims.find(byID(n.BestClaim.ClaimID)) - } - return clone -} diff --git a/claimtrie/node/normalizing_manager.go b/claimtrie/node/normalizing_manager.go index 604fa34d..2f6c4cfe 100644 --- a/claimtrie/node/normalizing_manager.go +++ b/claimtrie/node/normalizing_manager.go @@ -34,7 +34,6 @@ func (nm *NormalizingManager) IncrementHeightTo(height int32, temporary bool) ([ func (nm *NormalizingManager) DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) { if nm.normalizedAt > height { nm.normalizedAt = -1 - nm.ClearCache() } return nm.Manager.DecrementHeightTo(affectedNames, height) } @@ -111,7 +110,5 @@ func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int3 return true } - - nm.Manager.ClearCache() nm.Manager.IterateNames(predicate) } -- 2.45.2 From daa3137dc4344628c779e5729562664685d3f978 Mon Sep 17 00:00:00 2001 From: Jonathan Moody <103143855+moodyjon@users.noreply.github.com> Date: Thu, 21 Jul 2022 14:27:06 -0400 Subject: [PATCH 430/459] [rpc blockchain] Add support for mediantime, chainwork to RPC getblock. --- blockchain/chain.go | 49 ++++++++++++++++++++++++++++++++++++++ btcjson/chainsvrresults.go | 2 ++ rpcserver.go | 44 +++++++++++++++------------------- rpcserverhelp.go | 2 ++ 4 files changed, 72 insertions(+), 25 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index 9a6ec216..ef05d947 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -8,6 +8,7 @@ package blockchain import ( "container/list" "fmt" + "math/big" "sync" "time" @@ -1373,6 +1374,54 @@ func (b *BlockChain) BlockHashByHeight(blockHeight int32) (*chainhash.Hash, erro return &node.hash, nil } +// BlockAttributes desribes a Block in relation to others on the main chain. +type BlockAttributes struct { + Height int32 + Confirmations int32 + MedianTime time.Time + ChainWork *big.Int + PrevHash *chainhash.Hash + NextHash *chainhash.Hash +} + +// BlockAttributesByHash returns BlockAttributes for the block with the given hash +// relative to other blocks in the main chain. A BestState snapshot describing +// the main chain is also returned for convenience. +// +// This function is safe for concurrent access. +func (b *BlockChain) BlockAttributesByHash(hash *chainhash.Hash, prevHash *chainhash.Hash) ( + attrs *BlockAttributes, best *BestState, err error) { + best = b.BestSnapshot() + node := b.index.LookupNode(hash) + if node == nil || !b.bestChain.Contains(node) { + str := fmt.Sprintf("block %s is not in the main chain", hash) + return nil, best, errNotInMainChain(str) + } + + attrs = &BlockAttributes{ + Height: node.height, + Confirmations: 1 + best.Height - node.height, + MedianTime: node.CalcPastMedianTime(), + ChainWork: node.workSum, + } + + // Populate prev block hash if there is one. + if node.height > 0 { + attrs.PrevHash = prevHash + } + + // Populate next block hash if there is one. + if node.height < best.Height { + nextHash, err := b.BlockHashByHeight(node.height + 1) + if err != nil { + return nil, best, err + } + attrs.NextHash = nextHash + } + + return attrs, best, nil +} + // HeightRange returns a range of block hashes for the given start and end // heights. It is inclusive of the start height and exclusive of the end // height. The end height will be limited to the current main chain height. diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 6a918eb1..c6a5d550 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -77,9 +77,11 @@ type GetBlockVerboseResultBase struct { VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` Time int64 `json:"time"` + MedianTime int64 `json:"mediantime"` Nonce uint32 `json:"nonce"` Bits string `json:"bits"` Difficulty float64 `json:"difficulty"` + ChainWork string `json:"chainwork"` PreviousHash string `json:"previousblockhash,omitempty"` NextHash string `json:"nextblockhash,omitempty"` diff --git a/rpcserver.go b/rpcserver.go index 1fc32a06..96f92201 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1209,31 +1209,23 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i return nil, internalRPCError(err.Error(), context) } - // Get the block height from chain. - blockHeight, err := s.cfg.Chain.BlockHeightByHash(hash) - if err != nil { - context := "Failed to obtain block height" - return nil, internalRPCError(err.Error(), context) - } - blk.SetHeight(blockHeight) - best := s.cfg.Chain.BestSnapshot() - - // Get next block hash unless there are none. - var nextHashString string - if blockHeight < best.Height { - nextHash, err := s.cfg.Chain.BlockHashByHeight(blockHeight + 1) - if err != nil { - context := "No next block" - return nil, internalRPCError(err.Error(), context) - } - nextHashString = nextHash.String() - } - params := s.cfg.ChainParams blockHeader := &blk.MsgBlock().Header + + // Get further details (height, confirmations, nexthash, mediantime, etc.) from chain. + attrs, best, err := s.cfg.Chain.BlockAttributesByHash(hash, &blockHeader.PrevBlock) + if err != nil { + context := "Failed to obtain block details" + return nil, internalRPCError(err.Error(), context) + } + var prevHashString string - if blockHeight > 0 { - prevHashString = blockHeader.PrevBlock.String() + if attrs.PrevHash != nil { + prevHashString = attrs.PrevHash.String() + } + var nextHashString string + if attrs.NextHash != nil { + nextHashString = attrs.NextHash.String() } base := btcjson.GetBlockVerboseResultBase{ @@ -1244,13 +1236,15 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i PreviousHash: prevHashString, Nonce: blockHeader.Nonce, Time: blockHeader.Timestamp.Unix(), - Confirmations: int64(1 + best.Height - blockHeight), - Height: int64(blockHeight), + MedianTime: attrs.MedianTime.Unix(), + Confirmations: int64(attrs.Confirmations), + Height: int64(attrs.Height), Size: int32(len(blkBytes)), StrippedSize: int32(blk.MsgBlock().SerializeSizeStripped()), Weight: int32(blockchain.GetBlockWeight(blk)), Bits: strconv.FormatInt(int64(blockHeader.Bits), 16), Difficulty: getDifficultyRatio(blockHeader.Bits, params), + ChainWork: attrs.ChainWork.Text(16), NextHash: nextHashString, ClaimTrie: blockHeader.ClaimTrie.String(), } @@ -1275,7 +1269,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i for i, tx := range txns { rawTxn, err := createTxRawResult(params, tx.MsgTx(), tx.Hash().String(), blockHeader, hash.String(), - blockHeight, best.Height) + attrs.Height, best.Height) if err != nil { return nil, err } diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 3a6eb87b..2be322ce 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -260,9 +260,11 @@ var helpDescsEnUS = map[string]string{ "getblockverboseresult-tx": "The transaction hashes (only when verbosity=1)", "getblockverboseresult-nTx": "The number of transactions (aka, count of TX)", "getblockverboseresult-time": "The block time in seconds since 1 Jan 1970 GMT", + "getblockverboseresult-mediantime": "The median block time in seconds since 1 Jan 1970 GMT", "getblockverboseresult-nonce": "The block nonce", "getblockverboseresult-bits": "The bits which represent the block difficulty", "getblockverboseresult-difficulty": "The proof-of-work difficulty as a multiple of the minimum difficulty", + "getblockverboseresult-chainwork": "Expected number of hashes required to produce the chain up to this block (in hex)", "getblockverboseresult-previousblockhash": "The hash of the previous block", "getblockverboseresult-nextblockhash": "The hash of the next block (only if there is one)", "getblockverboseresult-strippedsize": "The size of the block without witness data", -- 2.45.2 From ea63a44c7bd03de4c0c610340b38716c16e6263f Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 28 Jul 2022 07:45:25 -0700 Subject: [PATCH 431/459] [lbry] rpcclient: fix stratum update_block format for blocknotify --- rpcclient/examples/lbcdblocknotify/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcclient/examples/lbcdblocknotify/main.go b/rpcclient/examples/lbcdblocknotify/main.go index 431331ee..004460b6 100644 --- a/rpcclient/examples/lbcdblocknotify/main.go +++ b/rpcclient/examples/lbcdblocknotify/main.go @@ -29,7 +29,7 @@ func send(stratum, stratumPass, coinid, blockHash string) error { } defer conn.Close() - msg := fmt.Sprintf(`{"id":1,"method":"mining.update_block","params":[%q,%q,%q]}`, + msg := fmt.Sprintf(`{"id":1,"method":"mining.update_block","params":[%q,%s,%q]}`, stratumPass, coinid, blockHash) _, err = conn.Write([]byte(msg)) -- 2.45.2 From 05f52c11a1e65f06520ff95cdb2680387774aca7 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 28 Jul 2022 17:14:40 -0700 Subject: [PATCH 432/459] docs: update README.md --- README.md | 398 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 300 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index 37e86a49..daceea8d 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,310 @@ [![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -`lbcd` is a full node implementation of LBRY's blockchain written in Go (golang). +**lbcd** is a full node implementation of LBRY's blockchain written in Go (golang). -This project is currently under active development and is in a Beta state while -we ensure it matches LBRYcrd's functionality. The intention is that it properly -downloads, validates, and serves the block chain using the exact rules -(including consensus bugs) for block acceptance as LBRYcrd. -We have taken great care to avoid lbcd causing a fork to the blockchain. +Software stack developed by LBRY teams has been all migrated to **lbcd**. -Note: `lbcd` does *NOT* include wallet functionality. That functionality is provided by the +We're working with exchanges and pool oerators to migrate from **lbrycrd** to **lbcd**. + +If you're integrating with **lbcd+lbcwallet**, please check the Wiki for current [supported RPCs](wiki/RPC-availability). + +Note: **lbcd** does *NOT* include wallet functionality. That functionality is provided by the [lbcwallet](https://github.com/lbryio/lbcwallet) and the [LBRY SDK](https://github.com/lbryio/lbry-sdk). +## Requirements + +All common operating systems are supported. lbcd requires at least 8GB of RAM +and at least 100GB of disk storage. Both RAM and disk requirements increase slowly over time. +Using a fast NVMe disk is recommended. + +## Installation + +Acquire binary files from [releases](https://github.com/lbryio/lbcd/releases) + +For compilation, [Go](http://golang.org) 1.18 or newer is required. +Install Go according to its [installation instructions](http://golang.org/doc/install). + +``` sh +# lbcd (full node) +$ go install github.com/lbryio/lbcd@latest + +# lbcctl (rpc client utility) +$ go install github.com/lbryio/lbcd/cmd/lbcctl@latest +``` + +## Usage + +Default application folder `${LBCDDIR}`: + +- Linux: `~/.lbcd/` +- MacOS: `/Users//Library/Application Support/Lbcd/` + +### Start the **lbcd** + +``` sh +./lbcd +``` + +**lbcd** loads config file at `"${LBCDDIR}/lbcd.conf"`. + +If no config is found, it creates a [default one](sample-lbcd.conf), which includes all available options with default settings except randomly generated *RPC credentials* (see below). + +### RPC server + +RPC credentials (`rpcuser` and `rpcpass`) is required to enable RPC server. It can be specify in the `"${LBCDIR}/lbcd.conf"`, using command line options: + +``` sh +./lbcd --rpcuser=rpcuser --rpcpass=rpcpass + +2022-07-28 12:28:19.627 [INF] RPCS: RPC server listening on 0.0.0.0:9245 +2022-07-28 12:28:19.627 [INF] RPCS: RPC server listening on [::]:9245 +``` + +### Working with TLS (Default) + +By default, **lbcd** runs RPC server with TLS enabled, and generates the `rpc.cert` and `rpc.key` under `${LBCDDIR}`, if not exist already. + +To interact with the RPC server, a client has to either specify the `rpc.cert`, or disable the certification verification for TLS. + +Interact with **lbcd** RPC using `lbcctl` + +``` sh +$ ./lbcctl --rpccert "${LBCDDIR}/rpc.cert" getblockcount + +# or disable the certificate verification +$ ./lbcctl --skipverify getblockcount + +1200062 +``` + +Interact with **lbcd** RPC using `curl` + +``` sh +$ curl --user rpcuser:rpcpass \ + --cacert "${LBCDDIR}/rpc.cert" \ + --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockcount", "params": []}' \ + -H 'content-type: text/plain;' \ + https://127.0.0.1:9245/ + +# or disable the certificate verification +$ curl --user rpcuser:rpcpass \ + --insecure \ + --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockcount", "params": []}' \ + -H 'content-type: text/plain;' \ + https://127.0.0.1:9245/ +``` + +``` json +{"jsonrpc":"1.0","result":1200062,"error":null,"id":"curltest"} +``` + +### Working without TLS + +TLS can be disabled using the `--notls` option: + +``` sh +$ ./lbcd --notls +``` + +``` sh +$ ./lbcctl --notls getblockcount + +1200062 +``` + +``` sh +$ curl --user rpcuser:rpcpass \ + --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockcount", "params": []}' \ + -H 'content-type: text/plain;' \ + http://127.0.0.1:9245/ +``` + +``` json +{"jsonrpc":"1.0","result":1200062,"error":null,"id":"curltest"} +``` + +## Using Snapshots (optional) + +[Snapshots](https://snapshots.lbry.com/blockchain/) are created bi-weekly to help new users catch up current block height. + +The snapshots are archived and compressed in [zstd](https://facebook.github.io/zstd/) format for it's compression ratio and speed. + +Download the snapshot, and uncompress it: + +``` sh +time curl -O https://snapshots.lbry.com/blockchain/lbcd_snapshot_1199527_v0.22.105_2022-07-27.tar.zst +zstd -d lbcd_snapshot_1199527_v0.22.105_2022-07-27.tar.zst | tar xf - -C "${LBCDIR}" +``` + +If preferred, a user can download and uncompress the snapshot on the fly: +By the time the download is finished, the snapshots should be almost uncompressed already. + +``` sh +mkdir -p "${LBCDDIR}" + +time curl https://snapshots.lbry.com/blockchain/lbcd_snapshot_1199527_v0.22.105_2022-07-27.tar.zst | zstd -d | tar xf - -C "${LBCDIR}" + +# % Total % Received % Xferd Average Speed Time Time Time Current +# Dload Upload Total Spent Left Speed +# 100 64.9G 100 64.9G 0 0 37.0M 0 0:29:49 0:29:49 --:--:-- 33.0M +# +# real 29m49.962s +# user 6m53.710s +# sys 8m56.545s +``` + +## Working with RPCs + +Using `lbcctl -l` to list available RPCs: + +``` sh +$ lbcctl -l + +Chain Server Commands: +addnode "addr" "add|remove|onetry" +createrawtransaction [{"txid":"value","vout":n},...] {"address":amount,...} (locktime) +debuglevel "levelspec" +decoderawtransaction "hextx" +decodescript "hexscript" +deriveaddresses "descriptor" ({"value":value}) +fundrawtransaction "hextx" {"changeaddress":changeaddress,"changeposition":changeposition,"changetype":changetype,"includewatching":includewatching,"lockunspents":lockunspents,"feerate":feerate,"subtractfeefromoutputs":[subtractfeefromoutput,...],"replaceable":replaceable,"conftarget":conftarget,"estimatemode":estimatemode} (iswitness) +generate numblocks + +[skipped] + +Wallet Server Commands (--wallet): +addmultisigaddress nrequired ["key",...] ("account") +addwitnessaddress "address" +backupwallet "destination" +createmultisig nrequired ["key",...] +createnewaccount "account" +createwallet "walletname" (disableprivatekeys=false blank=false passphrase="" avoidreuse=false) +dumpprivkey "address" +dumpwallet "filename" +encryptwallet "passphrase" +estimatefee numblocks +estimatepriority numblocks +estimatesmartfee conftarget (estimatemode="CONSERVATIVE") +getaccount "address" +getaccountaddress "account" +getaddressesbyaccount "account" + +[skipped] +``` + +Using `lbcctl help rpcname` to show the RPC spec: + +``` sh +$ lbcctl help getblock + +getblock "hash" (verbosity=1) + +Returns information about a block given its hash. + +Arguments: +1. hash (string, required) The hash of the block +2. verbosity (numeric, optional, default=1) Specifies whether the block data should be returned as a hex-encoded string (0), as parsed data with a slice of TXIDs (1), or as parsed data with parsed transaction data (2) + +Result (verbosity=0): +"value" (string) Hex-encoded bytes of the serialized block + +Result (verbosity=1): +{ + "getblockverboseresultbase": { (object) + "hash": "value", (string) The hash of the block (same as provided) + "confirmations": n, (numeric) The number of confirmations + "strippedsize": n, (numeric) The size of the block without witness data + "size": n, (numeric) The size of the block + "weight": n, (numeric) The weight of the block + "height": n, (numeric) The height of the block in the block chain + "version": n, (numeric) The block version + "versionHex": "value", (string) The block version in hexadecimal + "merkleroot": "value", (string) Root hash of the merkle tree + "time": n, (numeric) The block time in seconds since 1 Jan 1970 GMT + "mediantime": n, (numeric) The median block time in seconds since 1 Jan 1970 GMT + "nonce": n, (numeric) The block nonce + "bits": "value", (string) The bits which represent the block difficulty + "difficulty": n.nnn, (numeric) The proof-of-work difficulty as a multiple of the minimum difficulty + "chainwork": "value", (string) Expected number of hashes required to produce the chain up to this block (in hex) + "previousblockhash": "value", (string) The hash of the previous block + "nextblockhash": "value", (string) The hash of the next block (only if there is one) + "nameclaimroot": "value", (string) Root hash of the claim trie + "nTx": n, (numeric) The number of transactions (aka, count of TX) + }, + "tx": ["value",...], (array of string) The transaction hashes (only when verbosity=1) +} +``` + +## **lbcd** & **lbcwallet** + +*Wallet* related functianlities and RPCs are provided by a separate programe - [**lbcwallet**](https://github.com/lbryio/lbcwallet). + +Once setup, lbcwallet can serve wallet related RPCs as well as proxy lbcd RPCs to an assocated lbcd now. +It's sufficient for user to connect just the **lbcwallet** instead of both. + +``` mermaid +sequenceDiagram + actor C as lbcctl + participant W as lbcwallet (port: 9244) + participant D as lbcd (port: 9245) + + rect rgb(200,200,200) + Note over C,D: lbcctl getblockcount + C ->>+ D: getblockcount + D -->>- C: response + end + + rect rgb(200,200,200) + Note over C,W: lbcctl --wallet balance + C ->>+ W: getbalance + W -->>- C: response + end + + rect rgb(200,200,200) + Note over C,D: lbcctl --wallet getblockcount (lbcd RPC service proxied by lbcwallet) + C ->>+ W: getblockcount + W ->>+ D: getblockcount + D -->>- W: response + W -->>- C: response + end +``` + +While **lbcd** can run standalone as a full node, **lbcwallet** requires an associated **lbcd** instance for scanning and sync'ing block data. + +``` mermaid +sequenceDiagram + participant W as lbcwallet (RPC port: 9244) + participant D as lbcd (RPC port: 9245, P2P port: 9246) + participant D2 as other lbcd node(s) (P2P port: 9246) + + rect rgb(200,200,200) + Note over W,D: Asynchronous websocket notifications + W ->> D: subscribe to notifications + D -->> W: notification + D -->> W: notification + end + + rect rgb(200,200,200) + Note over W,D: lbcd RPCs + W ->>+ D: getblockheader + D ->>- W: response + end + + rect rgb(200,200,200) + Note over D,D2: P2P messages over port 9246 + D -->> D2: P2P message + D2 -->> D: P2P message + end + +``` + +## Data integrity + +**lbcd** is not immune to data loss. It expects a clean shutdown via SIGINT or +SIGTERM. SIGKILL, immediate VM kills, and sudden power loss can cause data +corruption, thus requiring chain resynchronization for recovery. + ## Security We take security seriously. Please contact [security](mailto:security@lbry.com) regarding any security issues. @@ -24,97 +317,6 @@ Our PGP key is [here](https://lbry.com/faq/pgp-key) if you need it. We maintain a mailing list for notifications of upgrades, security issues, and soft/hard forks. To join, visit [fork list](https://lbry.com/forklist) -## Requirements - -All common operating systems are supported. lbcd requires at least 8GB of RAM -and at least 100GB of disk storage. Both RAM and disk requirements increase slowly over time. -Using a fast NVMe disk is recommended. - -`lbcd` is not immune to data loss. It expects a clean shutdown via SIGINT or -SIGTERM. SIGKILL, immediate VM kills, and sudden power loss can cause data -corruption, thus requiring chain resynchronization for recovery. - -For compilation, [Go](http://golang.org) 1.16 or newer is required. - -## Installation - -Acquire binary files from [releases](https://github.com/lbryio/lbcd/releases) - -### To build from Source on Linux/BSD/MacOSX/POSIX - -Install Go according to its [installation instructions](http://golang.org/doc/install). - -``` sh -git clone https://github.com/lbryio/lbcd -cd lbcd - -# Build lbcd -go build . - -# Build lbcctl -go build ./cmd/lbcctl -``` - -Both [GoLand](https://www.jetbrains.com/go/) -and [VS Code](https://code.visualstudio.com/docs/languages/go) IDEs are supported. - -## Usage - -By default, data and logs are stored in ``: - -- Linux: `~/.lbcd/` -- MacOS: `/Users//Library/Application Support/Lbcd/` - -To enable RPC access a username and password is required. Example: - -``` sh -./lbcd --rpcuser=rpcuser --rpcpass=rpcpass -``` - -Interact with lbcd via RPC using `lbcctl` - -``` sh -./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass getblockcount -./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass getblocktemplate -``` - -By default, the RPCs are served over TLS. `lbcd` generates (if not exists) `rpc.cert` and -`rpc.key` under `` where `lbcctl` would search and use them. - -The RPCs can also be served without TLS *(on localhost only)* using (`--notls`) - -``` sh -./lbcd --rpcuser=rpcuser --rpcpass=rpcpass --notls -./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass --notls getblockcount -``` - -## Working with Different Networks - -By default, `lbcd` and `lbcctl` use the following ports for different networks respectively: - -| Network | RPC Port | Network Port | -| ------- | -------- | ------------ | -| mainnet | 9245 | 9246 | -| testnet | 19245 | 19246 | -| regtest | 29245 | 29246 | - -Running `lbcd` and `lbcctl` with `--testnet` or `--regtest` would use different chain params as well as default RPC and Network ports. - -``` sh -./lbcd --rpcuser=rpcuser --rpcpass=rpcpass --regtest -./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass --regtest getblockcount -``` - -The default Network and RPC ports of `lbcd` can be overriden using `--listen` and `--rpclisten` -`lbcctl` can also connect to RPC server specified by `--rpcserver` - -``` sh -./lbcd --rpcuser=rpcuser --rpcpass=rpcpass --regtest --listen=127.0.0.1:29248 --rpclisten=127.0.0.1:29247 -./lbcctl --rpcuser=rpcuser --rpcpass=rpcpass --regtest --rpcserver=127.0.0.1:29247 getblockcount -``` - -Note: Wallet related RPCs are provided by [lbcwallet](https://github.com/lbryio/lbcwallet). - ## Contributing Contributions to this project are welcome, encouraged, and compensated. -- 2.45.2 From 6b0e7592c6e136611caae04831a36db432cc1c39 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 29 Jul 2022 12:10:53 -0700 Subject: [PATCH 433/459] btcjson: remove WebsocketOnly for wallet extension RPCs --- btcjson/walletsvrwscmds.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/btcjson/walletsvrwscmds.go b/btcjson/walletsvrwscmds.go index e1e60fbe..e6a3aa72 100644 --- a/btcjson/walletsvrwscmds.go +++ b/btcjson/walletsvrwscmds.go @@ -114,9 +114,8 @@ func NewWalletIsLockedCmd() *WalletIsLockedCmd { } func init() { - // The commands in this file are only usable with a wallet server via - // websockets. - flags := UFWalletOnly | UFWebsocketOnly + // The commands in this file are only usable with a wallet server. + flags := UFWalletOnly MustRegisterCmd("createencryptedwallet", (*CreateEncryptedWalletCmd)(nil), flags) MustRegisterCmd("exportwatchingwallet", (*ExportWatchingWalletCmd)(nil), flags) -- 2.45.2 From 66c8567a27ad48d0c2f705884ca235fec4147b90 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 7 Aug 2022 23:15:05 -0700 Subject: [PATCH 434/459] ci: bump to Go 1.19 --- .github/workflows/basic-check.yml | 2 +- .github/workflows/full-sync-part-1.yml | 2 +- .github/workflows/full-sync-part-2.yml | 2 +- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/release.yml | 2 +- Dockerfile | 2 +- README.md | 2 +- go.mod | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/basic-check.yml b/.github/workflows/basic-check.yml index 43399646..7493189a 100644 --- a/.github/workflows/basic-check.yml +++ b/.github/workflows/basic-check.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: [1.18.2] + go: [1.19] steps: - name: Set up Go uses: actions/setup-go@v2 diff --git a/.github/workflows/full-sync-part-1.yml b/.github/workflows/full-sync-part-1.yml index 9d13a84b..fd7164fe 100644 --- a/.github/workflows/full-sync-part-1.yml +++ b/.github/workflows/full-sync-part-1.yml @@ -14,7 +14,7 @@ jobs: runs-on: self-hosted strategy: matrix: - go: [1.18.2] + go: [1.19] steps: - run: | echo "Note ${{ github.event.inputs.note }}!" diff --git a/.github/workflows/full-sync-part-2.yml b/.github/workflows/full-sync-part-2.yml index f7f95c84..5babd4e7 100644 --- a/.github/workflows/full-sync-part-2.yml +++ b/.github/workflows/full-sync-part-2.yml @@ -14,7 +14,7 @@ jobs: runs-on: self-hosted strategy: matrix: - go: [1.18.2] + go: [1.19] steps: - run: | echo "Note ${{ github.event.inputs.note }}!" diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 1d58c316..83e4cbee 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -4,7 +4,7 @@ env: # go needs absolute directories, using the $HOME variable doesn't work here. GOCACHE: /home/runner/work/go/pkg/build GOPATH: /home/runner/work/go - GO_VERSION: '^1.18.2' + GO_VERSION: '^1.19' on: push: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a54ac02b..281f88a2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.18.2 + go-version: 1.19 # Login against a Docker registry except on PR # https://github.com/docker/login-action diff --git a/Dockerfile b/Dockerfile index 912841ec..3065cd9b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ ARG ARCH=amd64 -FROM golang:1.18.2 AS build-container +FROM golang:1.19 AS build-container ARG ARCH diff --git a/README.md b/README.md index daceea8d..4c3116d9 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Using a fast NVMe disk is recommended. Acquire binary files from [releases](https://github.com/lbryio/lbcd/releases) -For compilation, [Go](http://golang.org) 1.18 or newer is required. +For compilation, [Go](http://golang.org) 1.19 or newer is required. Install Go according to its [installation instructions](http://golang.org/doc/install). ``` sh diff --git a/go.mod b/go.mod index 852c0428..5d51ab74 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/lbryio/lbcd -go 1.18 +go 1.19 require ( github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f -- 2.45.2 From e3237512186527b9858cf8ef4ecc923e8bc49908 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 7 Aug 2022 23:40:46 -0700 Subject: [PATCH 435/459] ci: gofmt with go 1.19 Go 1.19 introduces various updates to gofmt. --- addrmgr/doc.go | 2 +- blockchain/chain.go | 49 ++--- blockchain/chainview.go | 24 ++- blockchain/checkpoints.go | 16 +- blockchain/difficulty.go | 21 +- blockchain/doc.go | 66 +++---- blockchain/fullblocktests/generate.go | 6 +- blockchain/indexers/blocklogger.go | 5 +- blockchain/merkle.go | 2 +- blockchain/notifications.go | 6 +- blockchain/upgrade.go | 123 ++++++------ blockchain/validate.go | 12 +- btcec/btcec_test.go | 4 +- btcec/field.go | 35 ++-- btcjson/doc.go | 36 ++-- btcjson/help.go | 26 +-- btcjson/walletsvrcmds.go | 3 +- btcjson/walletsvrresults.go | 10 +- chaincfg/chainhash/hashfuncs.go | 10 +- chaincfg/doc.go | 52 ++--- chaincfg/params.go | 5 +- claimtrie/logger.go | 3 +- claimtrie/merkletrie/vertex.go | 9 +- cmd/lbcctl/config.go | 8 +- config.go | 8 +- config_test.go | 1 - connmgr/doc.go | 2 +- database/doc.go | 28 +-- database/ffldb/blockio.go | 4 +- database/ffldb/doc.go | 2 +- database/internal/treap/treapiter.go | 15 +- doc.go | 266 +++++++++++++------------- fees/doc.go | 42 ++-- integration/bip0009_test.go | 20 +- integration/csv_fork_test.go | 39 ++-- mempool/doc.go | 58 +++--- mining/mining.go | 40 ++-- netsync/blocklogger.go | 5 +- peer/doc.go | 84 ++++---- peer/peer.go | 16 +- rpcclient/doc.go | 62 +++--- rpcclient/extensions.go | 3 +- rpcclient/wallet.go | 8 +- txscript/doc.go | 4 +- txscript/error.go | 8 +- txscript/scriptbuilder.go | 21 +- txscript/scriptnum.go | 25 +-- wire/doc.go | 20 +- wire/msgtx.go | 18 +- 49 files changed, 685 insertions(+), 647 deletions(-) diff --git a/addrmgr/doc.go b/addrmgr/doc.go index 8ddc8bfd..c500fbb5 100644 --- a/addrmgr/doc.go +++ b/addrmgr/doc.go @@ -5,7 +5,7 @@ /* Package addrmgr implements concurrency safe Bitcoin address manager. -Address Manager Overview +# Address Manager Overview In order maintain the peer-to-peer Bitcoin network, there needs to be a source of addresses to connect to as nodes come and go. The Bitcoin protocol provides diff --git a/blockchain/chain.go b/blockchain/chain.go index ef05d947..485c3e0b 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -37,8 +37,9 @@ const ( // from the block being located. // // For example, assume a block chain with a side chain as depicted below: -// genesis -> 1 -> 2 -> ... -> 15 -> 16 -> 17 -> 18 -// \-> 16a -> 17a +// +// genesis -> 1 -> 2 -> ... -> 15 -> 16 -> 17 -> 18 +// \-> 16a -> 17a // // The block locator for block 17a would be the hashes of blocks: // [17a 16a 15 14 13 12 11 10 9 8 7 6 4 genesis] @@ -488,7 +489,7 @@ func (b *BlockChain) calcSequenceLock(node *blockNode, tx *btcutil.Tx, utxoView // LockTimeToSequence converts the passed relative locktime to a sequence // number in accordance to BIP-68. // See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki -// * (Compatibility) +// - (Compatibility) func LockTimeToSequence(isSeconds bool, locktime uint32) uint32 { // If we're expressing the relative lock time in blocks, then the // corresponding sequence number is simply the desired input age. @@ -1107,8 +1108,8 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error // a reorganization to become the main chain). // // The flags modify the behavior of this function as follows: -// - BFFastAdd: Avoids several expensive transaction validation operations. -// This is useful when using checkpoints. +// - BFFastAdd: Avoids several expensive transaction validation operations. +// This is useful when using checkpoints. // // This function MUST be called with the chain state lock held (for writes). func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, flags BehaviorFlags) (bool, error) { @@ -1249,8 +1250,8 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla // isCurrent returns whether or not the chain believes it is current. Several // factors are used to guess, but the key factors that allow the chain to // believe it is current are: -// - Latest block height is after the latest checkpoint (if enabled) -// - Latest block has a timestamp newer than ~6 hours ago (as LBRY block time is one fourth of bitcoin) +// - Latest block height is after the latest checkpoint (if enabled) +// - Latest block has a timestamp newer than ~6 hours ago (as LBRY block time is one fourth of bitcoin) // // This function MUST be called with the chain state lock held (for reads). func (b *BlockChain) isCurrent() bool { @@ -1273,8 +1274,8 @@ func (b *BlockChain) isCurrent() bool { // IsCurrent returns whether or not the chain believes it is current. Several // factors are used to guess, but the key factors that allow the chain to // believe it is current are: -// - Latest block height is after the latest checkpoint (if enabled) -// - Latest block has a timestamp newer than 24 hours ago +// - Latest block height is after the latest checkpoint (if enabled) +// - Latest block has a timestamp newer than 24 hours ago // // This function is safe for concurrent access. func (b *BlockChain) IsCurrent() bool { @@ -1557,11 +1558,11 @@ func (b *BlockChain) IntervalBlockHashes(endHash *chainhash.Hash, interval int, // // In addition, there are two special cases: // -// - When no locators are provided, the stop hash is treated as a request for -// that block, so it will either return the node associated with the stop hash -// if it is known, or nil if it is unknown -// - When locators are provided, but none of them are known, nodes starting -// after the genesis block will be returned +// - When no locators are provided, the stop hash is treated as a request for +// that block, so it will either return the node associated with the stop hash +// if it is known, or nil if it is unknown +// - When locators are provided, but none of them are known, nodes starting +// after the genesis block will be returned // // This is primarily a helper function for the locateBlocks and locateHeaders // functions. @@ -1645,11 +1646,11 @@ func (b *BlockChain) locateBlocks(locator BlockLocator, hashStop *chainhash.Hash // // In addition, there are two special cases: // -// - When no locators are provided, the stop hash is treated as a request for -// that block, so it will either return the stop hash itself if it is known, -// or nil if it is unknown -// - When locators are provided, but none of them are known, hashes starting -// after the genesis block will be returned +// - When no locators are provided, the stop hash is treated as a request for +// that block, so it will either return the stop hash itself if it is known, +// or nil if it is unknown +// - When locators are provided, but none of them are known, hashes starting +// after the genesis block will be returned // // This function is safe for concurrent access. func (b *BlockChain) LocateBlocks(locator BlockLocator, hashStop *chainhash.Hash, maxHashes uint32) []chainhash.Hash { @@ -1690,11 +1691,11 @@ func (b *BlockChain) locateHeaders(locator BlockLocator, hashStop *chainhash.Has // // In addition, there are two special cases: // -// - When no locators are provided, the stop hash is treated as a request for -// that header, so it will either return the header for the stop hash itself -// if it is known, or nil if it is unknown -// - When locators are provided, but none of them are known, headers starting -// after the genesis block will be returned +// - When no locators are provided, the stop hash is treated as a request for +// that header, so it will either return the header for the stop hash itself +// if it is known, or nil if it is unknown +// - When locators are provided, but none of them are known, headers starting +// after the genesis block will be returned // // This function is safe for concurrent access. func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Hash) []wire.BlockHeader { diff --git a/blockchain/chainview.go b/blockchain/chainview.go index a4c3692c..dd70ab2d 100644 --- a/blockchain/chainview.go +++ b/blockchain/chainview.go @@ -36,11 +36,13 @@ func fastLog2Floor(n uint32) uint8 { // for comparing chains. // // For example, assume a block chain with a side chain as depicted below: -// genesis -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -// \-> 4a -> 5a -> 6a +// +// genesis -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 +// \-> 4a -> 5a -> 6a // // The chain view for the branch ending in 6a consists of: -// genesis -> 1 -> 2 -> 3 -> 4a -> 5a -> 6a +// +// genesis -> 1 -> 2 -> 3 -> 4a -> 5a -> 6a type chainView struct { mtx sync.Mutex nodes []*blockNode @@ -258,12 +260,14 @@ func (c *chainView) next(node *blockNode) *blockNode { // view. // // For example, assume a block chain with a side chain as depicted below: -// genesis -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -// \-> 4a -> 5a -> 6a +// +// genesis -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 +// \-> 4a -> 5a -> 6a // // Further, assume the view is for the longer chain depicted above. That is to // say it consists of: -// genesis -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 +// +// genesis -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 // // Invoking this function with block node 5 would return block node 6 while // invoking it with block node 5a would return nil since that node is not part @@ -321,12 +325,14 @@ func (c *chainView) findFork(node *blockNode) *blockNode { // the chain view. It will return nil if there is no common block. // // For example, assume a block chain with a side chain as depicted below: -// genesis -> 1 -> 2 -> ... -> 5 -> 6 -> 7 -> 8 -// \-> 6a -> 7a +// +// genesis -> 1 -> 2 -> ... -> 5 -> 6 -> 7 -> 8 +// \-> 6a -> 7a // // Further, assume the view is for the longer chain depicted above. That is to // say it consists of: -// genesis -> 1 -> 2 -> ... -> 5 -> 6 -> 7 -> 8. +// +// genesis -> 1 -> 2 -> ... -> 5 -> 6 -> 7 -> 8. // // Invoking this function with block node 7a would return block node 5 while // invoking it with block node 7 would return itself since it is already part of diff --git a/blockchain/checkpoints.go b/blockchain/checkpoints.go index e9b2d5a2..800167d2 100644 --- a/blockchain/checkpoints.go +++ b/blockchain/checkpoints.go @@ -185,14 +185,14 @@ func isNonstandardTransaction(tx *btcutil.Tx) bool { // checkpoint candidate. // // The factors used to determine a good checkpoint are: -// - The block must be in the main chain -// - The block must be at least 'CheckpointConfirmations' blocks prior to the -// current end of the main chain -// - The timestamps for the blocks before and after the checkpoint must have -// timestamps which are also before and after the checkpoint, respectively -// (due to the median time allowance this is not always the case) -// - The block must not contain any strange transaction such as those with -// nonstandard scripts +// - The block must be in the main chain +// - The block must be at least 'CheckpointConfirmations' blocks prior to the +// current end of the main chain +// - The timestamps for the blocks before and after the checkpoint must have +// timestamps which are also before and after the checkpoint, respectively +// (due to the median time allowance this is not always the case) +// - The block must not contain any strange transaction such as those with +// nonstandard scripts // // The intent is that candidates are reviewed by a developer to make the final // decision and then manually added to the list of checkpoints for a network. diff --git a/blockchain/difficulty.go b/blockchain/difficulty.go index 051998ba..1ceb0da1 100644 --- a/blockchain/difficulty.go +++ b/blockchain/difficulty.go @@ -42,18 +42,21 @@ func HashToBig(hash *chainhash.Hash) *big.Int { // Like IEEE754 floating point, there are three basic components: the sign, // the exponent, and the mantissa. They are broken out as follows: // -// * the most significant 8 bits represent the unsigned base 256 exponent -// * bit 23 (the 24th bit) represents the sign bit -// * the least significant 23 bits represent the mantissa +// - the most significant 8 bits represent the unsigned base 256 exponent // -// ------------------------------------------------- -// | Exponent | Sign | Mantissa | -// ------------------------------------------------- -// | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] | -// ------------------------------------------------- +// - bit 23 (the 24th bit) represents the sign bit +// +// - the least significant 23 bits represent the mantissa +// +// ------------------------------------------------- +// | Exponent | Sign | Mantissa | +// ------------------------------------------------- +// | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] | +// ------------------------------------------------- // // The formula to calculate N is: -// N = (-1^sign) * mantissa * 256^(exponent-3) +// +// N = (-1^sign) * mantissa * 256^(exponent-3) // // This compact form is only used in bitcoin to encode unsigned 256-bit numbers // which represent difficulty targets, thus there really is not a need for a diff --git a/blockchain/doc.go b/blockchain/doc.go index 24417541..d57acc29 100644 --- a/blockchain/doc.go +++ b/blockchain/doc.go @@ -26,42 +26,42 @@ caller a high level of flexibility in how they want to react to certain events such as orphan blocks which need their parents requested and newly connected main chain blocks which might result in wallet updates. -Bitcoin Chain Processing Overview +# Bitcoin Chain Processing Overview Before a block is allowed into the block chain, it must go through an intensive series of validation rules. The following list serves as a general outline of those rules to provide some intuition into what is going on under the hood, but is by no means exhaustive: - - Reject duplicate blocks - - Perform a series of sanity checks on the block and its transactions such as - verifying proof of work, timestamps, number and character of transactions, - transaction amounts, script complexity, and merkle root calculations - - Compare the block against predetermined checkpoints for expected timestamps - and difficulty based on elapsed time since the checkpoint - - Save the most recent orphan blocks for a limited time in case their parent - blocks become available - - Stop processing if the block is an orphan as the rest of the processing - depends on the block's position within the block chain - - Perform a series of more thorough checks that depend on the block's position - within the block chain such as verifying block difficulties adhere to - difficulty retarget rules, timestamps are after the median of the last - several blocks, all transactions are finalized, checkpoint blocks match, and - block versions are in line with the previous blocks - - Determine how the block fits into the chain and perform different actions - accordingly in order to ensure any side chains which have higher difficulty - than the main chain become the new main chain - - When a block is being connected to the main chain (either through - reorganization of a side chain to the main chain or just extending the - main chain), perform further checks on the block's transactions such as - verifying transaction duplicates, script complexity for the combination of - connected scripts, coinbase maturity, double spends, and connected - transaction values - - Run the transaction scripts to verify the spender is allowed to spend the - coins - - Insert the block into the block database + - Reject duplicate blocks + - Perform a series of sanity checks on the block and its transactions such as + verifying proof of work, timestamps, number and character of transactions, + transaction amounts, script complexity, and merkle root calculations + - Compare the block against predetermined checkpoints for expected timestamps + and difficulty based on elapsed time since the checkpoint + - Save the most recent orphan blocks for a limited time in case their parent + blocks become available + - Stop processing if the block is an orphan as the rest of the processing + depends on the block's position within the block chain + - Perform a series of more thorough checks that depend on the block's position + within the block chain such as verifying block difficulties adhere to + difficulty retarget rules, timestamps are after the median of the last + several blocks, all transactions are finalized, checkpoint blocks match, and + block versions are in line with the previous blocks + - Determine how the block fits into the chain and perform different actions + accordingly in order to ensure any side chains which have higher difficulty + than the main chain become the new main chain + - When a block is being connected to the main chain (either through + reorganization of a side chain to the main chain or just extending the + main chain), perform further checks on the block's transactions such as + verifying transaction duplicates, script complexity for the combination of + connected scripts, coinbase maturity, double spends, and connected + transaction values + - Run the transaction scripts to verify the spender is allowed to spend the + coins + - Insert the block into the block database -Errors +# Errors Errors returned by this package are either the raw errors provided by underlying calls or of type blockchain.RuleError. This allows the caller to differentiate @@ -70,12 +70,12 @@ violations through type assertions. In addition, callers can programmatically determine the specific rule violation by examining the ErrorCode field of the type asserted blockchain.RuleError. -Bitcoin Improvement Proposals +# Bitcoin Improvement Proposals This package includes spec changes outlined by the following BIPs: - BIP0016 (https://en.bitcoin.it/wiki/BIP_0016) - BIP0030 (https://en.bitcoin.it/wiki/BIP_0030) - BIP0034 (https://en.bitcoin.it/wiki/BIP_0034) + BIP0016 (https://en.bitcoin.it/wiki/BIP_0016) + BIP0030 (https://en.bitcoin.it/wiki/BIP_0030) + BIP0034 (https://en.bitcoin.it/wiki/BIP_0034) */ package blockchain diff --git a/blockchain/fullblocktests/generate.go b/blockchain/fullblocktests/generate.go index 56f4601a..1e53e8fe 100644 --- a/blockchain/fullblocktests/generate.go +++ b/blockchain/fullblocktests/generate.go @@ -464,9 +464,9 @@ func createSpendTxForTx(tx *wire.MsgTx, fee btcutil.Amount) *wire.MsgTx { // - A coinbase that pays the required subsidy to an OP_TRUE script // - When a spendable output is provided: // - A transaction that spends from the provided output the following outputs: -// - One that pays the inputs amount minus 1 atom to an OP_TRUE script -// - One that contains an OP_RETURN output with a random uint64 in order to -// ensure the transaction has a unique hash +// - One that pays the inputs amount minus 1 atom to an OP_TRUE script +// - One that contains an OP_RETURN output with a random uint64 in order to +// ensure the transaction has a unique hash // // Additionally, if one or more munge functions are specified, they will be // invoked with the block prior to solving it. This provides callers with the diff --git a/blockchain/indexers/blocklogger.go b/blockchain/indexers/blocklogger.go index 845618e7..f7ec1408 100644 --- a/blockchain/indexers/blocklogger.go +++ b/blockchain/indexers/blocklogger.go @@ -27,8 +27,9 @@ type blockProgressLogger struct { // newBlockProgressLogger returns a new block progress logger. // The progress message is templated as follows: -// {progressAction} {numProcessed} {blocks|block} in the last {timePeriod} -// ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) +// +// {progressAction} {numProcessed} {blocks|block} in the last {timePeriod} +// ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) func newBlockProgressLogger(progressMessage string, logger btclog.Logger) *blockProgressLogger { return &blockProgressLogger{ lastBlockLogTime: time.Now(), diff --git a/blockchain/merkle.go b/blockchain/merkle.go index 92b59c5e..313cc617 100644 --- a/blockchain/merkle.go +++ b/blockchain/merkle.go @@ -86,7 +86,7 @@ func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash. // // The above stored as a linear array is as follows: // -// [h1 h2 h3 h4 h12 h34 root] +// [h1 h2 h3 h4 h12 h34 root] // // As the above shows, the merkle root is always the last element in the array. // diff --git a/blockchain/notifications.go b/blockchain/notifications.go index 25cc4f1f..5139e89e 100644 --- a/blockchain/notifications.go +++ b/blockchain/notifications.go @@ -50,9 +50,9 @@ func (n NotificationType) String() string { // Notification defines notification that is sent to the caller via the callback // function provided during the call to New and consists of a notification type // as well as associated data that depends on the type as follows: -// - NTBlockAccepted: *btcutil.Block -// - NTBlockConnected: *btcutil.Block -// - NTBlockDisconnected: *btcutil.Block +// - NTBlockAccepted: *btcutil.Block +// - NTBlockConnected: *btcutil.Block +// - NTBlockDisconnected: *btcutil.Block type Notification struct { Type NotificationType Data interface{} diff --git a/blockchain/upgrade.go b/blockchain/upgrade.go index a899cb4e..258b40d7 100644 --- a/blockchain/upgrade.go +++ b/blockchain/upgrade.go @@ -232,24 +232,25 @@ func determineMainChainBlocks(blocksMap map[chainhash.Hash]*blockChainContext, t // // The legacy format is as follows: // -//
[,...] +//
[,...] // -// Field Type Size -// version VLQ variable -// block height VLQ variable -// header code VLQ variable -// unspentness bitmap []byte variable -// compressed txouts -// compressed amount VLQ variable -// compressed script []byte variable +// Field Type Size +// version VLQ variable +// block height VLQ variable +// header code VLQ variable +// unspentness bitmap []byte variable +// compressed txouts +// compressed amount VLQ variable +// compressed script []byte variable // // The serialized header code format is: -// bit 0 - containing transaction is a coinbase -// bit 1 - output zero is unspent -// bit 2 - output one is unspent -// bits 3-x - number of bytes in unspentness bitmap. When both bits 1 and 2 -// are unset, it encodes N-1 since there must be at least one unspent -// output. +// +// bit 0 - containing transaction is a coinbase +// bit 1 - output zero is unspent +// bit 2 - output one is unspent +// bits 3-x - number of bytes in unspentness bitmap. When both bits 1 and 2 +// are unset, it encodes N-1 since there must be at least one unspent +// output. // // The rationale for the header code scheme is as follows: // - Transactions which only pay to a single output and a change output are @@ -269,65 +270,65 @@ func determineMainChainBlocks(blocksMap map[chainhash.Hash]*blockChainContext, t // From tx in main blockchain: // Blk 1, 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098 // -// 010103320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52 -// <><><><------------------------------------------------------------------> -// | | \--------\ | -// | height | compressed txout 0 -// version header code +// 010103320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52 +// <><><><------------------------------------------------------------------> +// | | \--------\ | +// | height | compressed txout 0 +// version header code // -// - version: 1 -// - height: 1 -// - header code: 0x03 (coinbase, output zero unspent, 0 bytes of unspentness) -// - unspentness: Nothing since it is zero bytes -// - compressed txout 0: -// - 0x32: VLQ-encoded compressed amount for 5000000000 (50 BTC) -// - 0x04: special script type pay-to-pubkey -// - 0x96...52: x-coordinate of the pubkey +// - version: 1 +// - height: 1 +// - header code: 0x03 (coinbase, output zero unspent, 0 bytes of unspentness) +// - unspentness: Nothing since it is zero bytes +// - compressed txout 0: +// - 0x32: VLQ-encoded compressed amount for 5000000000 (50 BTC) +// - 0x04: special script type pay-to-pubkey +// - 0x96...52: x-coordinate of the pubkey // // Example 2: // From tx in main blockchain: // Blk 113931, 4a16969aa4764dd7507fc1de7f0baa4850a246de90c45e59a3207f9a26b5036f // -// 0185f90b0a011200e2ccd6ec7c6e2e581349c77e067385fa8236bf8a800900b8025be1b3efc63b0ad48e7f9f10e87544528d58 -// <><----><><><------------------------------------------><--------------------------------------------> -// | | | \-------------------\ | | -// version | \--------\ unspentness | compressed txout 2 -// height header code compressed txout 0 +// 0185f90b0a011200e2ccd6ec7c6e2e581349c77e067385fa8236bf8a800900b8025be1b3efc63b0ad48e7f9f10e87544528d58 +// <><----><><><------------------------------------------><--------------------------------------------> +// | | | \-------------------\ | | +// version | \--------\ unspentness | compressed txout 2 +// height header code compressed txout 0 // -// - version: 1 -// - height: 113931 -// - header code: 0x0a (output zero unspent, 1 byte in unspentness bitmap) -// - unspentness: [0x01] (bit 0 is set, so output 0+2 = 2 is unspent) -// NOTE: It's +2 since the first two outputs are encoded in the header code -// - compressed txout 0: -// - 0x12: VLQ-encoded compressed amount for 20000000 (0.2 BTC) -// - 0x00: special script type pay-to-pubkey-hash -// - 0xe2...8a: pubkey hash -// - compressed txout 2: -// - 0x8009: VLQ-encoded compressed amount for 15000000 (0.15 BTC) -// - 0x00: special script type pay-to-pubkey-hash -// - 0xb8...58: pubkey hash +// - version: 1 +// - height: 113931 +// - header code: 0x0a (output zero unspent, 1 byte in unspentness bitmap) +// - unspentness: [0x01] (bit 0 is set, so output 0+2 = 2 is unspent) +// NOTE: It's +2 since the first two outputs are encoded in the header code +// - compressed txout 0: +// - 0x12: VLQ-encoded compressed amount for 20000000 (0.2 BTC) +// - 0x00: special script type pay-to-pubkey-hash +// - 0xe2...8a: pubkey hash +// - compressed txout 2: +// - 0x8009: VLQ-encoded compressed amount for 15000000 (0.15 BTC) +// - 0x00: special script type pay-to-pubkey-hash +// - 0xb8...58: pubkey hash // // Example 3: // From tx in main blockchain: // Blk 338156, 1b02d1c8cfef60a189017b9a420c682cf4a0028175f2f563209e4ff61c8c3620 // -// 0193d06c100000108ba5b9e763011dd46a006572d820e448e12d2bbb38640bc718e6 -// <><----><><----><--------------------------------------------------> -// | | | \-----------------\ | -// version | \--------\ unspentness | -// height header code compressed txout 22 +// 0193d06c100000108ba5b9e763011dd46a006572d820e448e12d2bbb38640bc718e6 +// <><----><><----><--------------------------------------------------> +// | | | \-----------------\ | +// version | \--------\ unspentness | +// height header code compressed txout 22 // -// - version: 1 -// - height: 338156 -// - header code: 0x10 (2+1 = 3 bytes in unspentness bitmap) -// NOTE: It's +1 since neither bit 1 nor 2 are set, so N-1 is encoded. -// - unspentness: [0x00 0x00 0x10] (bit 20 is set, so output 20+2 = 22 is unspent) -// NOTE: It's +2 since the first two outputs are encoded in the header code -// - compressed txout 22: -// - 0x8ba5b9e763: VLQ-encoded compressed amount for 366875659 (3.66875659 BTC) -// - 0x01: special script type pay-to-script-hash -// - 0x1d...e6: script hash +// - version: 1 +// - height: 338156 +// - header code: 0x10 (2+1 = 3 bytes in unspentness bitmap) +// NOTE: It's +1 since neither bit 1 nor 2 are set, so N-1 is encoded. +// - unspentness: [0x00 0x00 0x10] (bit 20 is set, so output 20+2 = 22 is unspent) +// NOTE: It's +2 since the first two outputs are encoded in the header code +// - compressed txout 22: +// - 0x8ba5b9e763: VLQ-encoded compressed amount for 366875659 (3.66875659 BTC) +// - 0x01: special script type pay-to-script-hash +// - 0x1d...e6: script hash func deserializeUtxoEntryV0(serialized []byte) (map[uint32]*UtxoEntry, error) { // Deserialize the version. // diff --git a/blockchain/validate.go b/blockchain/validate.go index 85946611..eaa290b5 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -334,8 +334,8 @@ func CheckTransactionSanity(tx *btcutil.Tx, enforceSoftFork bool) error { // target difficulty as claimed. // // The flags modify the behavior of this function as follows: -// - BFNoPoWCheck: The check to ensure the block hash is less than the target -// difficulty is not performed. +// - BFNoPoWCheck: The check to ensure the block hash is less than the target +// difficulty is not performed. func checkProofOfWork(header *wire.BlockHeader, powLimit *big.Int, flags BehaviorFlags) error { // The target difficulty must be larger than zero. target := CompactToBig(header.Bits) @@ -669,8 +669,8 @@ func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int32) error { // which depend on its position within the block chain. // // The flags modify the behavior of this function as follows: -// - BFFastAdd: All checks except those involving comparing the header against -// the checkpoints are not performed. +// - BFFastAdd: All checks except those involving comparing the header against +// the checkpoints are not performed. // // This function MUST be called with the chain state lock held (for writes). func (b *BlockChain) checkBlockHeaderContext(header *wire.BlockHeader, prevNode *blockNode, flags BehaviorFlags) error { @@ -748,8 +748,8 @@ func (b *BlockChain) checkBlockHeaderContext(header *wire.BlockHeader, prevNode // on its position within the block chain. // // The flags modify the behavior of this function as follows: -// - BFFastAdd: The transaction are not checked to see if they are finalized -// and the somewhat expensive BIP0034 validation is not performed. +// - BFFastAdd: The transaction are not checked to see if they are finalized +// and the somewhat expensive BIP0034 validation is not performed. // // The flags are also passed to checkBlockHeaderContext. See its documentation // for how the flags modify its behavior. diff --git a/btcec/btcec_test.go b/btcec/btcec_test.go index 42a69037..dffc1217 100644 --- a/btcec/btcec_test.go +++ b/btcec/btcec_test.go @@ -527,7 +527,7 @@ type baseMultTest struct { x, y string } -//TODO: add more test vectors +// TODO: add more test vectors var s256BaseMultTests = []baseMultTest{ { "AA5E28D6A97A2479A65527F7290311A3624D4CC0FA1578598EE3C2613BF99522", @@ -556,7 +556,7 @@ var s256BaseMultTests = []baseMultTest{ }, } -//TODO: test different curves as well? +// TODO: test different curves as well? func TestBaseMult(t *testing.T) { s256 := S256() for i, e := range s256BaseMultTests { diff --git a/btcec/field.go b/btcec/field.go index 98105ed8..d13d899b 100644 --- a/btcec/field.go +++ b/btcec/field.go @@ -125,27 +125,30 @@ var ( // the arithmetic needed for elliptic curve operations. // // The following depicts the internal representation: -// ----------------------------------------------------------------- -// | n[9] | n[8] | ... | n[0] | -// | 32 bits available | 32 bits available | ... | 32 bits available | -// | 22 bits for value | 26 bits for value | ... | 26 bits for value | -// | 10 bits overflow | 6 bits overflow | ... | 6 bits overflow | -// | Mult: 2^(26*9) | Mult: 2^(26*8) | ... | Mult: 2^(26*0) | -// ----------------------------------------------------------------- +// +// ----------------------------------------------------------------- +// | n[9] | n[8] | ... | n[0] | +// | 32 bits available | 32 bits available | ... | 32 bits available | +// | 22 bits for value | 26 bits for value | ... | 26 bits for value | +// | 10 bits overflow | 6 bits overflow | ... | 6 bits overflow | +// | Mult: 2^(26*9) | Mult: 2^(26*8) | ... | Mult: 2^(26*0) | +// ----------------------------------------------------------------- // // For example, consider the number 2^49 + 1. It would be represented as: -// n[0] = 1 -// n[1] = 2^23 -// n[2..9] = 0 +// +// n[0] = 1 +// n[1] = 2^23 +// n[2..9] = 0 // // The full 256-bit value is then calculated by looping i from 9..0 and // doing sum(n[i] * 2^(26i)) like so: -// n[9] * 2^(26*9) = 0 * 2^234 = 0 -// n[8] * 2^(26*8) = 0 * 2^208 = 0 -// ... -// n[1] * 2^(26*1) = 2^23 * 2^26 = 2^49 -// n[0] * 2^(26*0) = 1 * 2^0 = 1 -// Sum: 0 + 0 + ... + 2^49 + 1 = 2^49 + 1 +// +// n[9] * 2^(26*9) = 0 * 2^234 = 0 +// n[8] * 2^(26*8) = 0 * 2^208 = 0 +// ... +// n[1] * 2^(26*1) = 2^23 * 2^26 = 2^49 +// n[0] * 2^(26*0) = 1 * 2^0 = 1 +// Sum: 0 + 0 + ... + 2^49 + 1 = 2^49 + 1 type fieldVal struct { n [10]uint32 } diff --git a/btcjson/doc.go b/btcjson/doc.go index 165b9ef9..e2e52cd2 100644 --- a/btcjson/doc.go +++ b/btcjson/doc.go @@ -5,7 +5,7 @@ /* Package btcjson provides primitives for working with the bitcoin JSON-RPC API. -Overview +# Overview When communicating via the JSON-RPC protocol, all of the commands need to be marshalled to and from the the wire in the appropriate format. This package @@ -14,7 +14,7 @@ provides data structures and primitives to ease this process. In addition, it also provides some additional features such as custom command registration, command categorization, and reflection-based help generation. -JSON-RPC Protocol Overview +# JSON-RPC Protocol Overview This information is not necessary in order to use this package, but it does provide some intuition into what the marshalling and unmarshalling that is @@ -47,39 +47,39 @@ with it) doesn't always follow the spec and will sometimes return an error string in the result field with a null error for certain commands. However, for the most part, the error field will be set as described on failure. -Marshalling and Unmarshalling +# Marshalling and Unmarshalling Based upon the discussion above, it should be easy to see how the types of this package map into the required parts of the protocol - Request Objects (type Request) - - Commands (type Cmd) - - Notifications (type Ntfn) + - Commands (type Cmd) + - Notifications (type Ntfn) - Response Objects (type Response) - - Result (type Result) + - Result (type Result) To simplify the marshalling of the requests and responses, the MarshalCmd and MarshalResponse functions are provided. They return the raw bytes ready to be sent across the wire. Unmarshalling a received Request object is a two step process: - 1) Unmarshal the raw bytes into a Request struct instance via json.Unmarshal - 2) Use UnmarshalCmd on the Result field of the unmarshalled Request to create - a concrete command or notification instance with all struct fields set - accordingly + 1. Unmarshal the raw bytes into a Request struct instance via json.Unmarshal + 2. Use UnmarshalCmd on the Result field of the unmarshalled Request to create + a concrete command or notification instance with all struct fields set + accordingly This approach is used since it provides the caller with access to the additional fields in the request that are not part of the command such as the ID. Unmarshalling a received Response object is also a two step process: - 1) Unmarhsal the raw bytes into a Response struct instance via json.Unmarshal - 2) Depending on the ID, unmarshal the Result field of the unmarshalled - Response to create a concrete type instance + 1. Unmarhsal the raw bytes into a Response struct instance via json.Unmarshal + 2. Depending on the ID, unmarshal the Result field of the unmarshalled + Response to create a concrete type instance As above, this approach is used since it provides the caller with access to the fields in the response such as the ID and Error. -Command Creation +# Command Creation This package provides two approaches for creating a new command. This first, and preferred, method is to use one of the NewCmd functions. This allows @@ -93,7 +93,7 @@ obviously, run-time which means any mistakes won't be found until the code is actually executed. However, it is quite useful for user-supplied commands that are intentionally dynamic. -Custom Command Registration +# Custom Command Registration The command handling of this package is built around the concept of registered commands. This is true for the wide variety of commands already provided by the @@ -104,7 +104,7 @@ function for this purpose. A list of all registered methods can be obtained with the RegisteredCmdMethods function. -Command Inspection +# Command Inspection All registered commands are registered with flags that identify information such as whether the command applies to a chain server, wallet server, or is a @@ -112,7 +112,7 @@ notification along with the method name to use. These flags can be obtained with the MethodUsageFlags flags, and the method can be obtained with the CmdMethod function. -Help Generation +# Help Generation To facilitate providing consistent help to users of the RPC server, this package exposes the GenerateHelp and function which uses reflection on registered @@ -122,7 +122,7 @@ generate the final help text. In addition, the MethodUsageText function is provided to generate consistent one-line usage for registered commands and notifications using reflection. -Errors +# Errors There are 2 distinct type of errors supported by this package: diff --git a/btcjson/help.go b/btcjson/help.go index 04d85635..4188b53f 100644 --- a/btcjson/help.go +++ b/btcjson/help.go @@ -476,11 +476,12 @@ func isValidResultType(kind reflect.Kind) bool { // an error will use the key in place of the description. // // The following outlines the required keys: -// "--synopsis" Synopsis for the command -// "-" Description for each command argument -// "-" Description for each object field -// "--condition<#>" Description for each result condition -// "--result<#>" Description for each primitive result num +// +// "--synopsis" Synopsis for the command +// "-" Description for each command argument +// "-" Description for each object field +// "--condition<#>" Description for each result condition +// "--result<#>" Description for each primitive result num // // Notice that the "special" keys synopsis, condition<#>, and result<#> are // preceded by a double dash to ensure they don't conflict with field names. @@ -492,16 +493,17 @@ func isValidResultType(kind reflect.Kind) bool { // For example, consider the 'help' command itself. There are two possible // returns depending on the provided parameters. So, the help would be // generated by calling the function as follows: -// GenerateHelp("help", descs, (*string)(nil), (*string)(nil)). +// +// GenerateHelp("help", descs, (*string)(nil), (*string)(nil)). // // The following keys would then be required in the provided descriptions map: // -// "help--synopsis": "Returns a list of all commands or help for ...." -// "help-command": "The command to retrieve help for", -// "help--condition0": "no command provided" -// "help--condition1": "command specified" -// "help--result0": "List of commands" -// "help--result1": "Help for specified command" +// "help--synopsis": "Returns a list of all commands or help for ...." +// "help-command": "The command to retrieve help for", +// "help--condition0": "no command provided" +// "help--condition1": "command specified" +// "help--result0": "List of commands" +// "help--result1": "Help for specified command" func GenerateHelp(method string, descs map[string]string, resultTypes ...interface{}) (string, error) { // Look up details about the provided method and error out if not // registered. diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index f43e3c22..cf77877a 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -833,7 +833,8 @@ func (s *ScriptPubKey) UnmarshalJSON(data []byte) error { // // Descriptors are typically ranged when specified in the form of generic HD // chain paths. -// Example of a ranged descriptor: pkh(tpub.../*) +// +// Example of a ranged descriptor: pkh(tpub.../*) // // The value can be an int to specify the end of the range, or the range // itself, as []int{begin, end}. diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index 4939454d..42402496 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -47,11 +47,11 @@ type embeddedAddressInfo struct { // Reference: https://bitcoincore.org/en/doc/0.20.0/rpc/wallet/getaddressinfo // // The GetAddressInfoResult has three segments: -// 1. General information about the address. -// 2. Metadata (Timestamp, HDKeyPath, HDSeedID) and wallet fields -// (IsMine, IsWatchOnly). -// 3. Information about the embedded address in case of P2SH or P2WSH. -// Same structure as (1). +// 1. General information about the address. +// 2. Metadata (Timestamp, HDKeyPath, HDSeedID) and wallet fields +// (IsMine, IsWatchOnly). +// 3. Information about the embedded address in case of P2SH or P2WSH. +// Same structure as (1). type GetAddressInfoResult struct { // The following fields are identical to embeddedAddressInfo. // However, the utility to generate RPC help message can't handle diff --git a/chaincfg/chainhash/hashfuncs.go b/chaincfg/chainhash/hashfuncs.go index 194c60e3..70ac038d 100644 --- a/chaincfg/chainhash/hashfuncs.go +++ b/chaincfg/chainhash/hashfuncs.go @@ -39,11 +39,11 @@ func DoubleHashH(b []byte) Hash { // LbryPoWHashH calculates returns the PoW Hash. // -// doubled := SHA256(SHA256(b)) -// expanded := SHA512(doubled) -// left := RIPEMD160(expanded[0:32]) -// right := RIPEMD160(expanded[32:64]) -// result := SHA256(SHA256(left||right)) +// doubled := SHA256(SHA256(b)) +// expanded := SHA512(doubled) +// left := RIPEMD160(expanded[0:32]) +// right := RIPEMD160(expanded[32:64]) +// result := SHA256(SHA256(left||right)) func LbryPoWHashH(b []byte) Hash { doubled := DoubleHashB(b) expanded := sha512.Sum512(doubled) diff --git a/chaincfg/doc.go b/chaincfg/doc.go index fb5fa677..66b0a67a 100644 --- a/chaincfg/doc.go +++ b/chaincfg/doc.go @@ -18,40 +18,40 @@ // When a network parameter is needed, it may then be looked up through this // variable (either directly, or hidden in a library call). // -// package main +// package main // -// import ( -// "flag" -// "fmt" -// "log" +// import ( +// "flag" +// "fmt" +// "log" // -// btcutil "github.com/lbryio/lbcutil" -// "github.com/lbryio/lbcd/chaincfg" -// ) +// btcutil "github.com/lbryio/lbcutil" +// "github.com/lbryio/lbcd/chaincfg" +// ) // -// var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network") +// var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network") // -// // By default (without -testnet), use mainnet. -// var chainParams = &chaincfg.MainNetParams +// // By default (without -testnet), use mainnet. +// var chainParams = &chaincfg.MainNetParams // -// func main() { -// flag.Parse() +// func main() { +// flag.Parse() // -// // Modify active network parameters if operating on testnet. -// if *testnet { -// chainParams = &chaincfg.TestNet3Params -// } +// // Modify active network parameters if operating on testnet. +// if *testnet { +// chainParams = &chaincfg.TestNet3Params +// } // -// // later... +// // later... // -// // Create and print new payment address, specific to the active network. -// pubKeyHash := make([]byte, 20) -// addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, chainParams) -// if err != nil { -// log.Fatal(err) -// } -// fmt.Println(addr) -// } +// // Create and print new payment address, specific to the active network. +// pubKeyHash := make([]byte, 20) +// addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, chainParams) +// if err != nil { +// log.Fatal(err) +// } +// fmt.Println(addr) +// } // // If an application does not use one of the three standard Bitcoin networks, // a new Params struct may be created which defines the parameters for the diff --git a/chaincfg/params.go b/chaincfg/params.go index 1efb9b3d..47291453 100644 --- a/chaincfg/params.go +++ b/chaincfg/params.go @@ -794,8 +794,9 @@ func IsBech32SegwitPrefix(prefix string) bool { // ErrInvalidHDKeyID error will be returned. // // Reference: -// SLIP-0132 : Registered HD version bytes for BIP-0032 -// https://github.com/satoshilabs/slips/blob/master/slip-0132.md +// +// SLIP-0132 : Registered HD version bytes for BIP-0032 +// https://github.com/satoshilabs/slips/blob/master/slip-0132.md func RegisterHDKeyID(hdPublicKeyID []byte, hdPrivateKeyID []byte) error { if len(hdPublicKeyID) != 4 || len(hdPrivateKeyID) != 4 { return ErrInvalidHDKeyID diff --git a/claimtrie/logger.go b/claimtrie/logger.go index ab5a38b4..ef004ea0 100644 --- a/claimtrie/logger.go +++ b/claimtrie/logger.go @@ -26,7 +26,8 @@ type claimProgressLogger struct { // newClaimProgressLogger returns a new name progress logger. // The progress message is templated as follows: -// {progressAction} {numProcessed} {names|name} in the last {timePeriod} (total {totalProcessed}) +// +// {progressAction} {numProcessed} {names|name} in the last {timePeriod} (total {totalProcessed}) func newClaimProgressLogger(progressMessage string, logger btclog.Logger) *claimProgressLogger { return &claimProgressLogger{ lastLogNameTime: time.Now(), diff --git a/claimtrie/merkletrie/vertex.go b/claimtrie/merkletrie/vertex.go index 77f1f04a..d3326990 100644 --- a/claimtrie/merkletrie/vertex.go +++ b/claimtrie/merkletrie/vertex.go @@ -17,10 +17,11 @@ func newVertex(hash *chainhash.Hash) *vertex { // TODO: more professional to use msgpack here? // nbuf decodes the on-disk format of a node, which has the following form: -// ch(1B) hash(32B) -// ... -// ch(1B) hash(32B) -// vhash(32B) +// +// ch(1B) hash(32B) +// ... +// ch(1B) hash(32B) +// vhash(32B) type nbuf []byte func (nb nbuf) entries() int { diff --git a/cmd/lbcctl/config.go b/cmd/lbcctl/config.go index e31ecef6..90289663 100644 --- a/cmd/lbcctl/config.go +++ b/cmd/lbcctl/config.go @@ -175,10 +175,10 @@ func cleanAndExpandPath(path string) string { // line options. // // The configuration proceeds as follows: -// 1) Start with a default config with sane settings -// 2) Pre-parse the command line to check for an alternative config file -// 3) Load configuration file overwriting defaults with any specified options -// 4) Parse CLI options and overwrite/add any specified options +// 1. Start with a default config with sane settings +// 2. Pre-parse the command line to check for an alternative config file +// 3. Load configuration file overwriting defaults with any specified options +// 4. Parse CLI options and overwrite/add any specified options // // The above results in functioning properly without any config settings // while still allowing the user to override settings with config files and diff --git a/config.go b/config.go index 1e5f0392..27500be5 100644 --- a/config.go +++ b/config.go @@ -409,10 +409,10 @@ func newConfigParser(cfg *config, so *serviceOptions, options flags.Options) *fl // line options. // // The configuration proceeds as follows: -// 1) Start with a default config with sane settings -// 2) Pre-parse the command line to check for an alternative config file -// 3) Load configuration file overwriting defaults with any specified options -// 4) Parse CLI options and overwrite/add any specified options +// 1. Start with a default config with sane settings +// 2. Pre-parse the command line to check for an alternative config file +// 3. Load configuration file overwriting defaults with any specified options +// 4. Parse CLI options and overwrite/add any specified options // // The above results in lbcd functioning properly without any config settings // while still allowing the user to override settings with config files and diff --git a/config_test.go b/config_test.go index 15953b15..ad09ffb5 100644 --- a/config_test.go +++ b/config_test.go @@ -20,7 +20,6 @@ var ( // parameters which are command-line only. These fields are copied line-by-line // from "config" struct in "config.go", and the field names, types, and tags must // match for the test to work. -// type configCmdLineOnly struct { ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"` DbType string `long:"dbtype" description:"Database backend to use for the Block Chain"` diff --git a/connmgr/doc.go b/connmgr/doc.go index acb90c31..d101c434 100644 --- a/connmgr/doc.go +++ b/connmgr/doc.go @@ -5,7 +5,7 @@ /* Package connmgr implements a generic Bitcoin network connection manager. -Connection Manager Overview +# Connection Manager Overview Connection Manager handles all the general connection concerns such as maintaining a set number of outbound connections, sourcing peers, banning, diff --git a/database/doc.go b/database/doc.go index 49720671..80a2669d 100644 --- a/database/doc.go +++ b/database/doc.go @@ -5,7 +5,7 @@ /* Package database provides a block and metadata storage database. -Overview +# Overview As of Feb 2016, there are over 400,000 blocks in the Bitcoin block chain and and over 112 million transactions (which turns out to be over 60GB of data). @@ -18,15 +18,15 @@ storage, and strict checksums in key areas to ensure data integrity. A quick overview of the features database provides are as follows: - - Key/value metadata store - - Bitcoin block storage - - Efficient retrieval of block headers and regions (transactions, scripts, etc) - - Read-only and read-write transactions with both manual and managed modes - - Nested buckets - - Supports registration of backend databases - - Comprehensive test coverage + - Key/value metadata store + - Bitcoin block storage + - Efficient retrieval of block headers and regions (transactions, scripts, etc) + - Read-only and read-write transactions with both manual and managed modes + - Nested buckets + - Supports registration of backend databases + - Comprehensive test coverage -Database +# Database The main entry point is the DB interface. It exposes functionality for transactional-based access and storage of metadata and block data. It is @@ -43,14 +43,14 @@ The Begin function provides an unmanaged transaction while the View and Update functions provide a managed transaction. These are described in more detail below. -Transactions +# Transactions The Tx interface provides facilities for rolling back or committing changes that took place while the transaction was active. It also provides the root metadata bucket under which all keys, values, and nested buckets are stored. A transaction can either be read-only or read-write and managed or unmanaged. -Managed versus Unmanaged Transactions +# Managed versus Unmanaged Transactions A managed transaction is one where the caller provides a function to execute within the context of the transaction and the commit or rollback is handled @@ -63,7 +63,7 @@ call Commit or Rollback when they are finished with it. Leaving transactions open for long periods of time can have several adverse effects, so it is recommended that managed transactions are used instead. -Buckets +# Buckets The Bucket interface provides the ability to manipulate key/value pairs and nested buckets as well as iterate through them. @@ -73,7 +73,7 @@ CreateBucket, CreateBucketIfNotExists, and DeleteBucket functions work with buckets. The ForEach function allows the caller to provide a function to be called with each key/value pair and nested bucket in the current bucket. -Metadata Bucket +# Metadata Bucket As discussed above, all of the functions which are used to manipulate key/value pairs and nested buckets exist on the Bucket interface. The root metadata @@ -81,7 +81,7 @@ bucket is the upper-most bucket in which data is stored and is created at the same time as the database. Use the Metadata function on the Tx interface to retrieve it. -Nested Buckets +# Nested Buckets The CreateBucket and CreateBucketIfNotExists functions on the Bucket interface provide the ability to create an arbitrary number of nested buckets. It is diff --git a/database/ffldb/blockio.go b/database/ffldb/blockio.go index 2ed4eccf..a0abfe72 100644 --- a/database/ffldb/blockio.go +++ b/database/ffldb/blockio.go @@ -622,8 +622,8 @@ func (s *blockStore) syncBlocks() error { // were partially written. // // There are effectively two scenarios to consider here: -// 1) Transient write failures from which recovery is possible -// 2) More permanent failures such as hard disk death and/or removal +// 1. Transient write failures from which recovery is possible +// 2. More permanent failures such as hard disk death and/or removal // // In either case, the write cursor will be repositioned to the old block file // offset regardless of any other errors that occur while attempting to undo diff --git a/database/ffldb/doc.go b/database/ffldb/doc.go index cca5ebc5..e9f42d5e 100644 --- a/database/ffldb/doc.go +++ b/database/ffldb/doc.go @@ -10,7 +10,7 @@ This driver is the recommended driver for use with lbcd. It makes use leveldb for the metadata, flat files for block storage, and checksums in key areas to ensure data integrity. -Usage +# Usage This package is a driver to the database package and provides the database type of "ffldb". The parameters the Open and Create functions take are the diff --git a/database/internal/treap/treapiter.go b/database/internal/treap/treapiter.go index d6981aaf..ae7ed853 100644 --- a/database/internal/treap/treapiter.go +++ b/database/internal/treap/treapiter.go @@ -318,13 +318,14 @@ func (iter *Iterator) ForceReseek() { // unexpected keys and/or values. // // For example: -// iter := t.Iterator(nil, nil) -// for iter.Next() { -// if someCondition { -// t.Delete(iter.Key()) -// iter.ForceReseek() -// } -// } +// +// iter := t.Iterator(nil, nil) +// for iter.Next() { +// if someCondition { +// t.Delete(iter.Key()) +// iter.ForceReseek() +// } +// } func (t *Mutable) Iterator(startKey, limitKey []byte) *Iterator { iter := &Iterator{ t: t, diff --git a/doc.go b/doc.go index fc7e4573..cbfa6b6b 100644 --- a/doc.go +++ b/doc.go @@ -18,142 +18,144 @@ on Windows. The -C (--configfile) flag, as shown below, can be used to override this location. Usage: - lbcd [OPTIONS] + + lbcd [OPTIONS] Application Options: - --addcheckpoint= Add a custom checkpoint. Format: - ':' - -a, --addpeer= Add a peer to connect with at startup - --addrindex Maintain a full address-based transaction index - which makes the searchrawtransactions RPC - available - --banduration= How long to ban misbehaving peers. Valid time - units are {s, m, h}. Minimum 1 second (default: - 24h0m0s) - --banthreshold= Maximum allowed ban score before disconnecting - and banning misbehaving peers. (default: 100) - --blockmaxsize= Maximum block size in bytes to be used when - creating a block (default: 750000) - --blockminsize= Mininum block size in bytes to be used when - creating a block - --blockmaxweight= Maximum block weight to be used when creating a - block (default: 3000000) - --blockminweight= Mininum block weight to be used when creating a - block - --blockprioritysize= Size in bytes for high-priority/low-fee - transactions when creating a block (default: - 50000) - --blocksonly Do not accept transactions from remote peers. - -C, --configfile= Path to configuration file - --connect= Connect only to the specified peers at startup - --cpuprofile= Write CPU profile to the specified file - -b, --datadir= Directory to store data - --dbtype= Database backend to use for the Block Chain - (default: ffldb) - -d, --debuglevel= Logging level for all subsystems {trace, debug, - info, warn, error, critical} -- You may also - specify - =,=,... to - set the log level for individual subsystems -- - Use show to list available subsystems (default: - info) - --dropaddrindex Deletes the address-based transaction index from - the database on start up and then exits. - --dropcfindex Deletes the index used for committed filtering - (CF) support from the database on start up and - then exits. - --droptxindex Deletes the hash-based transaction index from the - database on start up and then exits. - --externalip= Add an ip to the list of local addresses we claim - to listen on to peers - --generate Generate (mine) bitcoins using the CPU - --limitfreerelay= Limit relay of transactions with no transaction - fee to the given amount in thousands of bytes per - minute (default: 15) - --listen= Add an interface/port to listen for connections - (default all interfaces port: 9246, testnet: - 19246, regtest: 29246, signet: 39246) - --logdir= Directory to log output - --maxorphantx= Max number of orphan transactions to keep in - memory (default: 100) - --maxpeers= Max number of inbound and outbound peers - (default: 125) - --memprofile= Write memory profile to the specified file - --miningaddr= Add the specified payment address to the list of - addresses to use for generated blocks -- At least - one address is required if the generate option is - set - --minrelaytxfee= The minimum transaction fee in BTC/kB to be - considered a non-zero fee. (default: 1e-05) - --nobanning Disable banning of misbehaving peers - --nocfilters Disable committed filtering (CF) support - --nocheckpoints Disable built-in checkpoints. Don't do this - unless you know what you're doing. - --nodnsseed Disable DNS seeding for peers - --nolisten Disable listening for incoming connections -- - NOTE: Listening is automatically disabled if the - --connect or --proxy options are used without - also specifying listen interfaces via --listen - --noonion Disable connecting to tor hidden services - --nopeerbloomfilters Disable bloom filtering support - --norelaypriority Do not require free or low-fee transactions to - have high priority for relaying - --norpc Disable built-in RPC server -- NOTE: The RPC - server is disabled by default if no - rpcuser/rpcpass or rpclimituser/rpclimitpass is - specified - --notls Disable TLS for the RPC server - --onion= Connect to tor hidden services via SOCKS5 proxy - (eg. 127.0.0.1:9050) - --onionpass= Password for onion proxy server - --onionuser= Username for onion proxy server - --profile= Enable HTTP profiling on given port -- NOTE port - must be between 1024 and 65536 - --proxy= Connect via SOCKS5 proxy (eg. 127.0.0.1:9050) - --proxypass= Password for proxy server - --proxyuser= Username for proxy server - --regtest Use the regression test network - --rejectnonstd Reject non-standard transactions regardless of - the default settings for the active network. - --relaynonstd Relay non-standard transactions regardless of the - default settings for the active network. - --rpccert= File containing the certificate file - --rpckey= File containing the certificate key - --rpclimitpass= Password for limited RPC connections - --rpclimituser= Username for limited RPC connections - --rpclisten= Add an interface/port to listen for RPC - connections (default port: 9245, testnet: 19245, regtest: 29245) - --rpcmaxclients= Max number of RPC clients for standard - connections (default: 10) - --rpcmaxconcurrentreqs= Max number of concurrent RPC requests that may be - processed concurrently (default: 20) - --rpcmaxwebsockets= Max number of RPC websocket connections (default: - 25) - --rpcquirks Mirror some JSON-RPC quirks of Bitcoin Core -- - NOTE: Discouraged unless interoperability issues - need to be worked around - -P, --rpcpass= Password for RPC connections - -u, --rpcuser= Username for RPC connections - --sigcachemaxsize= The maximum number of entries in the signature - verification cache (default: 100000) - --simnet Use the simulation test network - --testnet Use the test network - --torisolation Enable Tor stream isolation by randomizing user - credentials for each connection. - --trickleinterval= Minimum time between attempts to send new - inventory to a connected peer (default: 10s) - --txindex Maintain a full hash-based transaction index - which makes all transactions available via the - getrawtransaction RPC - --uacomment= Comment to add to the user agent -- See BIP 14 - for more information. - --upnp Use UPnP to map our listening port outside of NAT - -V, --version Display version information and exit - --whitelist= Add an IP network or IP that will not be banned. - (eg. 192.168.1.0/24 or ::1) + + --addcheckpoint= Add a custom checkpoint. Format: + ':' + -a, --addpeer= Add a peer to connect with at startup + --addrindex Maintain a full address-based transaction index + which makes the searchrawtransactions RPC + available + --banduration= How long to ban misbehaving peers. Valid time + units are {s, m, h}. Minimum 1 second (default: + 24h0m0s) + --banthreshold= Maximum allowed ban score before disconnecting + and banning misbehaving peers. (default: 100) + --blockmaxsize= Maximum block size in bytes to be used when + creating a block (default: 750000) + --blockminsize= Mininum block size in bytes to be used when + creating a block + --blockmaxweight= Maximum block weight to be used when creating a + block (default: 3000000) + --blockminweight= Mininum block weight to be used when creating a + block + --blockprioritysize= Size in bytes for high-priority/low-fee + transactions when creating a block (default: + 50000) + --blocksonly Do not accept transactions from remote peers. + -C, --configfile= Path to configuration file + --connect= Connect only to the specified peers at startup + --cpuprofile= Write CPU profile to the specified file + -b, --datadir= Directory to store data + --dbtype= Database backend to use for the Block Chain + (default: ffldb) + -d, --debuglevel= Logging level for all subsystems {trace, debug, + info, warn, error, critical} -- You may also + specify + =,=,... to + set the log level for individual subsystems -- + Use show to list available subsystems (default: + info) + --dropaddrindex Deletes the address-based transaction index from + the database on start up and then exits. + --dropcfindex Deletes the index used for committed filtering + (CF) support from the database on start up and + then exits. + --droptxindex Deletes the hash-based transaction index from the + database on start up and then exits. + --externalip= Add an ip to the list of local addresses we claim + to listen on to peers + --generate Generate (mine) bitcoins using the CPU + --limitfreerelay= Limit relay of transactions with no transaction + fee to the given amount in thousands of bytes per + minute (default: 15) + --listen= Add an interface/port to listen for connections + (default all interfaces port: 9246, testnet: + 19246, regtest: 29246, signet: 39246) + --logdir= Directory to log output + --maxorphantx= Max number of orphan transactions to keep in + memory (default: 100) + --maxpeers= Max number of inbound and outbound peers + (default: 125) + --memprofile= Write memory profile to the specified file + --miningaddr= Add the specified payment address to the list of + addresses to use for generated blocks -- At least + one address is required if the generate option is + set + --minrelaytxfee= The minimum transaction fee in BTC/kB to be + considered a non-zero fee. (default: 1e-05) + --nobanning Disable banning of misbehaving peers + --nocfilters Disable committed filtering (CF) support + --nocheckpoints Disable built-in checkpoints. Don't do this + unless you know what you're doing. + --nodnsseed Disable DNS seeding for peers + --nolisten Disable listening for incoming connections -- + NOTE: Listening is automatically disabled if the + --connect or --proxy options are used without + also specifying listen interfaces via --listen + --noonion Disable connecting to tor hidden services + --nopeerbloomfilters Disable bloom filtering support + --norelaypriority Do not require free or low-fee transactions to + have high priority for relaying + --norpc Disable built-in RPC server -- NOTE: The RPC + server is disabled by default if no + rpcuser/rpcpass or rpclimituser/rpclimitpass is + specified + --notls Disable TLS for the RPC server + --onion= Connect to tor hidden services via SOCKS5 proxy + (eg. 127.0.0.1:9050) + --onionpass= Password for onion proxy server + --onionuser= Username for onion proxy server + --profile= Enable HTTP profiling on given port -- NOTE port + must be between 1024 and 65536 + --proxy= Connect via SOCKS5 proxy (eg. 127.0.0.1:9050) + --proxypass= Password for proxy server + --proxyuser= Username for proxy server + --regtest Use the regression test network + --rejectnonstd Reject non-standard transactions regardless of + the default settings for the active network. + --relaynonstd Relay non-standard transactions regardless of the + default settings for the active network. + --rpccert= File containing the certificate file + --rpckey= File containing the certificate key + --rpclimitpass= Password for limited RPC connections + --rpclimituser= Username for limited RPC connections + --rpclisten= Add an interface/port to listen for RPC + connections (default port: 9245, testnet: 19245, regtest: 29245) + --rpcmaxclients= Max number of RPC clients for standard + connections (default: 10) + --rpcmaxconcurrentreqs= Max number of concurrent RPC requests that may be + processed concurrently (default: 20) + --rpcmaxwebsockets= Max number of RPC websocket connections (default: + 25) + --rpcquirks Mirror some JSON-RPC quirks of Bitcoin Core -- + NOTE: Discouraged unless interoperability issues + need to be worked around + -P, --rpcpass= Password for RPC connections + -u, --rpcuser= Username for RPC connections + --sigcachemaxsize= The maximum number of entries in the signature + verification cache (default: 100000) + --simnet Use the simulation test network + --testnet Use the test network + --torisolation Enable Tor stream isolation by randomizing user + credentials for each connection. + --trickleinterval= Minimum time between attempts to send new + inventory to a connected peer (default: 10s) + --txindex Maintain a full hash-based transaction index + which makes all transactions available via the + getrawtransaction RPC + --uacomment= Comment to add to the user agent -- See BIP 14 + for more information. + --upnp Use UPnP to map our listening port outside of NAT + -V, --version Display version information and exit + --whitelist= Add an IP network or IP that will not be banned. + (eg. 192.168.1.0/24 or ::1) Help Options: - -h, --help Show this help message + -h, --help Show this help message */ package main diff --git a/fees/doc.go b/fees/doc.go index 77419317..627337b6 100644 --- a/fees/doc.go +++ b/fees/doc.go @@ -7,11 +7,11 @@ Package fees provides decred-specific methods for tracking and estimating fee rates for new transactions to be mined into the network. Fee rate estimation has two main goals: -- Ensuring transactions are mined within a target _confirmation range_ - (expressed in blocks); -- Attempting to minimize fees while maintaining be above restriction. + - Ensuring transactions are mined within a target _confirmation range_ + (expressed in blocks); + - Attempting to minimize fees while maintaining be above restriction. -Preliminaries +# Preliminaries There are two main regimes against which fee estimation needs to be evaluated according to how full blocks being mined are (and consequently how important fee @@ -39,7 +39,7 @@ The current approach to implement this estimation is based on bitcoin core's algorithm. References [1] and [2] provide a high level description of how it works there. Actual code is linked in references [3] and [4]. -Outline of the Algorithm +# Outline of the Algorithm The algorithm is currently based in fee estimation as used in v0.14 of bitcoin core (which is also the basis for the v0.15+ method). A more comprehensive @@ -54,31 +54,31 @@ The basic algorithm is as follows (as executed by a single full node): Stats building stage: -- For each transaction observed entering mempool, record the block at which it - was first seen -- For each mined transaction which was previously observed to enter the mempool, - record how long (in blocks) it took to be mined and its fee rate -- Group mined transactions into fee rate _buckets_ and _confirmation ranges_, - creating a table of how many transactions were mined at each confirmation - range and fee rate bucket and their total committed fee -- Whenever a new block is mined, decay older transactions to account for a - dynamic fee environment + - For each transaction observed entering mempool, record the block at which it + was first seen + - For each mined transaction which was previously observed to enter the mempool, + record how long (in blocks) it took to be mined and its fee rate + - Group mined transactions into fee rate _buckets_ and _confirmation ranges_, + creating a table of how many transactions were mined at each confirmation + range and fee rate bucket and their total committed fee + - Whenever a new block is mined, decay older transactions to account for a + dynamic fee environment Estimation stage: -- Input a target confirmation range (how many blocks to wait for the tx to be - mined) -- Starting at the highest fee bucket, look for buckets where the chance of - confirmation within the desired confirmation window is > 95% -- Average all such buckets to get the estimated fee rate + - Input a target confirmation range (how many blocks to wait for the tx to be + mined) + - Starting at the highest fee bucket, look for buckets where the chance of + confirmation within the desired confirmation window is > 95% + - Average all such buckets to get the estimated fee rate -Simulation +# Simulation Development of the estimator was originally performed and simulated using the code in [5]. Simulation of the current code can be performed by using the dcrfeesim tool available in [6]. -Acknowledgements +# Acknowledgements Thanks to @davecgh for providing the initial review of the results and the original developers of the bitcoin core code (the brunt of which seems to have diff --git a/integration/bip0009_test.go b/integration/bip0009_test.go index e22fdaba..333da952 100644 --- a/integration/bip0009_test.go +++ b/integration/bip0009_test.go @@ -282,19 +282,20 @@ func testBIP0009(t *testing.T, forkKey string, deploymentID uint32) { // - Assert the chain height is 0 and the state is ThresholdDefined // - Generate 1 fewer blocks than needed to reach the first state transition // - Assert chain height is expected and state is still ThresholdDefined +// // - Generate 1 more block to reach the first state transition // - Assert chain height is expected and state moved to ThresholdStarted -// - Generate enough blocks to reach the next state transition window, but only -// signal support in 1 fewer than the required number to achieve -// ThresholdLockedIn +// - Generate enough blocks to reach the next state transition window, but only +// signal support in 1 fewer than the required number to achieve +// ThresholdLockedIn // - Assert chain height is expected and state is still ThresholdStarted -// - Generate enough blocks to reach the next state transition window with only -// the exact number of blocks required to achieve locked in status signalling -// support. +// - Generate enough blocks to reach the next state transition window with only +// the exact number of blocks required to achieve locked in status signalling +// support. // - Assert chain height is expected and state moved to ThresholdLockedIn -// - Generate 1 fewer blocks than needed to reach the next state transition +// - Generate 1 fewer blocks than needed to reach the next state transition // - Assert chain height is expected and state is still ThresholdLockedIn -// - Generate 1 more block to reach the next state transition +// - Generate 1 more block to reach the next state transition // - Assert chain height is expected and state moved to ThresholdActive func TestBIP0009(t *testing.T) { t.Parallel() @@ -309,11 +310,14 @@ func TestBIP0009(t *testing.T) { // Overview: // - Generate block 1 // - Assert bit is NOT set (ThresholdDefined) +// // - Generate enough blocks to reach first state transition // - Assert bit is NOT set for block prior to state transition // - Assert bit is set for block at state transition (ThresholdStarted) +// // - Generate enough blocks to reach second state transition // - Assert bit is set for block at state transition (ThresholdLockedIn) +// // - Generate enough blocks to reach third state transition // - Assert bit is set for block prior to state transition (ThresholdLockedIn) // - Assert bit is NOT set for block at state transition (ThresholdActive) diff --git a/integration/csv_fork_test.go b/integration/csv_fork_test.go index ac8512e0..298a2367 100644 --- a/integration/csv_fork_test.go +++ b/integration/csv_fork_test.go @@ -95,17 +95,22 @@ func makeTestOutput(r *rpctest.Harness, t *testing.T, // them. // // Overview: -// - Pre soft-fork: -// - Transactions with non-final lock-times from the PoV of MTP should be -// rejected from the mempool. -// - Transactions within non-final MTP based lock-times should be accepted -// in valid blocks. // -// - Post soft-fork: -// - Transactions with non-final lock-times from the PoV of MTP should be -// rejected from the mempool and when found within otherwise valid blocks. -// - Transactions with final lock-times from the PoV of MTP should be -// accepted to the mempool and mined in future block. +// - Pre soft-fork: +// +// - Transactions with non-final lock-times from the PoV of MTP should be +// rejected from the mempool. +// +// - Transactions within non-final MTP based lock-times should be accepted +// in valid blocks. +// +// - Post soft-fork: +// +// - Transactions with non-final lock-times from the PoV of MTP should be +// rejected from the mempool and when found within otherwise valid blocks. +// +// - Transactions with final lock-times from the PoV of MTP should be +// accepted to the mempool and mined in future block. func TestBIP0113Activation(t *testing.T) { t.Parallel() @@ -391,13 +396,13 @@ func assertTxInBlock(r *rpctest.Harness, t *testing.T, blockHash *chainhash.Hash // 112 and BIP 68 rule-set after the activation of the CSV-package soft-fork. // // Overview: -// - Pre soft-fork: -// - A transaction spending a CSV output validly should be rejected from the -// mempool, but accepted in a valid generated block including the -// transaction. -// - Post soft-fork: -// - See the cases exercised within the table driven tests towards the end -// of this test. +// - Pre soft-fork: +// - A transaction spending a CSV output validly should be rejected from the +// mempool, but accepted in a valid generated block including the +// transaction. +// - Post soft-fork: +// - See the cases exercised within the table driven tests towards the end +// of this test. func TestBIP0068AndBIP0112Activation(t *testing.T) { t.Parallel() diff --git a/mempool/doc.go b/mempool/doc.go index 3adad018..1bd7c5a9 100644 --- a/mempool/doc.go +++ b/mempool/doc.go @@ -31,40 +31,40 @@ proceed. Typically, this will involve things such as relaying the transactions to other peers on the network and notifying the mining process that new transactions are available. -Feature Overview +# Feature Overview The following is a quick overview of the major features. It is not intended to be an exhaustive list. - - Maintain a pool of fully validated transactions - - Reject non-fully-spent duplicate transactions - - Reject coinbase transactions - - Reject double spends (both from the chain and other transactions in pool) - - Reject invalid transactions according to the network consensus rules - - Full script execution and validation with signature cache support - - Individual transaction query support - - Orphan transaction support (transactions that spend from unknown outputs) - - Configurable limits (see transaction acceptance policy) - - Automatic addition of orphan transactions that are no longer orphans as new - transactions are added to the pool - - Individual orphan transaction query support - - Configurable transaction acceptance policy - - Option to accept or reject standard transactions - - Option to accept or reject transactions based on priority calculations - - Rate limiting of low-fee and free transactions - - Non-zero fee threshold - - Max signature operations per transaction - - Max orphan transaction size - - Max number of orphan transactions allowed - - Additional metadata tracking for each transaction - - Timestamp when the transaction was added to the pool - - Most recent block height when the transaction was added to the pool - - The fee the transaction pays - - The starting priority for the transaction - - Manual control of transaction removal - - Recursive removal of all dependent transactions + - Maintain a pool of fully validated transactions + - Reject non-fully-spent duplicate transactions + - Reject coinbase transactions + - Reject double spends (both from the chain and other transactions in pool) + - Reject invalid transactions according to the network consensus rules + - Full script execution and validation with signature cache support + - Individual transaction query support + - Orphan transaction support (transactions that spend from unknown outputs) + - Configurable limits (see transaction acceptance policy) + - Automatic addition of orphan transactions that are no longer orphans as new + transactions are added to the pool + - Individual orphan transaction query support + - Configurable transaction acceptance policy + - Option to accept or reject standard transactions + - Option to accept or reject transactions based on priority calculations + - Rate limiting of low-fee and free transactions + - Non-zero fee threshold + - Max signature operations per transaction + - Max orphan transaction size + - Max number of orphan transactions allowed + - Additional metadata tracking for each transaction + - Timestamp when the transaction was added to the pool + - Most recent block height when the transaction was added to the pool + - The fee the transaction pays + - The starting priority for the transaction + - Manual control of transaction removal + - Recursive removal of all dependent transactions -Errors +# Errors Errors returned by this package are either the raw errors provided by underlying calls or of type mempool.RuleError. Since there are two classes of rules diff --git a/mining/mining.go b/mining/mining.go index 4f3ac9e5..61e4a1d1 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -420,26 +420,26 @@ func NewBlkTmplGenerator(policy *Policy, params *chaincfg.Params, // // Given the above, a block generated by this function is of the following form: // -// ----------------------------------- -- -- -// | Coinbase Transaction | | | -// |-----------------------------------| | | -// | | | | ----- policy.BlockPrioritySize -// | High-priority Transactions | | | -// | | | | -// |-----------------------------------| | -- -// | | | -// | | | -// | | |--- policy.BlockMaxSize -// | Transactions prioritized by fee | | -// | until <= policy.TxMinFreeFee | | -// | | | -// | | | -// | | | -// |-----------------------------------| | -// | Low-fee/Non high-priority (free) | | -// | transactions (while block size | | -// | <= policy.BlockMinSize) | | -// ----------------------------------- -- +// ----------------------------------- -- -- +// | Coinbase Transaction | | | +// |-----------------------------------| | | +// | | | | ----- policy.BlockPrioritySize +// | High-priority Transactions | | | +// | | | | +// |-----------------------------------| | -- +// | | | +// | | | +// | | |--- policy.BlockMaxSize +// | Transactions prioritized by fee | | +// | until <= policy.TxMinFreeFee | | +// | | | +// | | | +// | | | +// |-----------------------------------| | +// | Low-fee/Non high-priority (free) | | +// | transactions (while block size | | +// | <= policy.BlockMinSize) | | +// ----------------------------------- -- func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress btcutil.Address) (*BlockTemplate, error) { // Extend the most recently known best block. best := g.chain.BestSnapshot() diff --git a/netsync/blocklogger.go b/netsync/blocklogger.go index 34a549a1..b7a394ec 100644 --- a/netsync/blocklogger.go +++ b/netsync/blocklogger.go @@ -27,8 +27,9 @@ type blockProgressLogger struct { // newBlockProgressLogger returns a new block progress logger. // The progress message is templated as follows: -// {progressAction} {numProcessed} {blocks|block} in the last {timePeriod} -// ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) +// +// {progressAction} {numProcessed} {blocks|block} in the last {timePeriod} +// ({numTxs}, height {lastBlockHeight}, {lastBlockTimeStamp}) func newBlockProgressLogger(progressMessage string, logger btclog.Logger) *blockProgressLogger { return &blockProgressLogger{ lastBlockLogTime: time.Now(), diff --git a/peer/doc.go b/peer/doc.go index 1bb8cf32..1a12609c 100644 --- a/peer/doc.go +++ b/peer/doc.go @@ -6,7 +6,7 @@ Package peer provides a common base for creating and managing Bitcoin network peers. -Overview +# Overview This package builds upon the wire package, which provides the fundamental primitives necessary to speak the bitcoin wire protocol, in order to simplify @@ -16,41 +16,41 @@ Payment Verification (SPV) nodes, proxies, etc. A quick overview of the major features peer provides are as follows: - - Provides a basic concurrent safe bitcoin peer for handling bitcoin - communications via the peer-to-peer protocol - - Full duplex reading and writing of bitcoin protocol messages - - Automatic handling of the initial handshake process including protocol - version negotiation - - Asynchronous message queuing of outbound messages with optional channel for - notification when the message is actually sent - - Flexible peer configuration - - Caller is responsible for creating outgoing connections and listening for - incoming connections so they have flexibility to establish connections as - they see fit (proxies, etc) - - User agent name and version - - Bitcoin network - - Service support signalling (full nodes, bloom filters, etc) - - Maximum supported protocol version - - Ability to register callbacks for handling bitcoin protocol messages - - Inventory message batching and send trickling with known inventory detection - and avoidance - - Automatic periodic keep-alive pinging and pong responses - - Random nonce generation and self connection detection - - Proper handling of bloom filter related commands when the caller does not - specify the related flag to signal support - - Disconnects the peer when the protocol version is high enough - - Does not invoke the related callbacks for older protocol versions - - Snapshottable peer statistics such as the total number of bytes read and - written, the remote address, user agent, and negotiated protocol version - - Helper functions pushing addresses, getblocks, getheaders, and reject - messages - - These could all be sent manually via the standard message output function, - but the helpers provide additional nice functionality such as duplicate - filtering and address randomization - - Ability to wait for shutdown/disconnect - - Comprehensive test coverage + - Provides a basic concurrent safe bitcoin peer for handling bitcoin + communications via the peer-to-peer protocol + - Full duplex reading and writing of bitcoin protocol messages + - Automatic handling of the initial handshake process including protocol + version negotiation + - Asynchronous message queuing of outbound messages with optional channel for + notification when the message is actually sent + - Flexible peer configuration + - Caller is responsible for creating outgoing connections and listening for + incoming connections so they have flexibility to establish connections as + they see fit (proxies, etc) + - User agent name and version + - Bitcoin network + - Service support signalling (full nodes, bloom filters, etc) + - Maximum supported protocol version + - Ability to register callbacks for handling bitcoin protocol messages + - Inventory message batching and send trickling with known inventory detection + and avoidance + - Automatic periodic keep-alive pinging and pong responses + - Random nonce generation and self connection detection + - Proper handling of bloom filter related commands when the caller does not + specify the related flag to signal support + - Disconnects the peer when the protocol version is high enough + - Does not invoke the related callbacks for older protocol versions + - Snapshottable peer statistics such as the total number of bytes read and + written, the remote address, user agent, and negotiated protocol version + - Helper functions pushing addresses, getblocks, getheaders, and reject + messages + - These could all be sent manually via the standard message output function, + but the helpers provide additional nice functionality such as duplicate + filtering and address randomization + - Ability to wait for shutdown/disconnect + - Comprehensive test coverage -Peer Configuration +# Peer Configuration All peer configuration is handled with the Config struct. This allows the caller to specify things such as the user agent name and version, the bitcoin @@ -58,7 +58,7 @@ network to use, which services it supports, and callbacks to invoke when bitcoin messages are received. See the documentation for each field of the Config struct for more details. -Inbound and Outbound Peers +# Inbound and Outbound Peers A peer can either be inbound or outbound. The caller is responsible for establishing the connection to remote peers and listening for incoming peers. @@ -73,7 +73,7 @@ Disconnect to disconnect from the peer and clean up all resources. WaitForDisconnect can be used to block until peer disconnection and resource cleanup has completed. -Callbacks +# Callbacks In order to do anything useful with a peer, it is necessary to react to bitcoin messages. This is accomplished by creating an instance of the MessageListeners @@ -92,7 +92,7 @@ It is often useful to use closures which encapsulate state when specifying the callback handlers. This provides a clean method for accessing that state when callbacks are invoked. -Queuing Messages and Inventory +# Queuing Messages and Inventory The QueueMessage function provides the fundamental means to send messages to the remote peer. As the name implies, this employs a non-blocking queue. A done @@ -106,7 +106,7 @@ QueueInventory function. It employs batching and trickling along with intelligent known remote peer inventory detection and avoidance through the use of a most-recently used algorithm. -Message Sending Helper Functions +# Message Sending Helper Functions In addition to the bare QueueMessage function previously described, the PushAddrMsg, PushGetBlocksMsg, PushGetHeadersMsg, and PushRejectMsg functions @@ -128,13 +128,13 @@ appropriate reject message based on the provided parameters as well as optionally provides a flag to cause it to block until the message is actually sent. -Peer Statistics +# Peer Statistics A snapshot of the current peer statistics can be obtained with the StatsSnapshot function. This includes statistics such as the total number of bytes read and written, the remote address, user agent, and negotiated protocol version. -Logging +# Logging This package provides extensive logging capabilities through the UseLogger function which allows a btclog.Logger to be specified. For example, logging at @@ -142,7 +142,7 @@ the debug level provides summaries of every message sent and received, and logging at the trace level provides full dumps of parsed messages as well as the raw message bytes using a format similar to hexdump -C. -Bitcoin Improvement Proposals +# Bitcoin Improvement Proposals This package supports all BIPS supported by the wire package. (https://pkg.go.dev/github.com/lbryio/lbcd/wire#hdr-Bitcoin_Improvement_Proposals) diff --git a/peer/peer.go b/peer/peer.go index ffedc6dc..6fe622f5 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -2096,10 +2096,10 @@ func (p *Peer) writeLocalVersionMsg() error { // peer. The events should occur in the following order, otherwise an error is // returned: // -// 1. Remote peer sends their version. -// 2. We send our version. -// 3. We send our verack. -// 4. Remote peer sends their verack. +// 1. Remote peer sends their version. +// 2. We send our version. +// 3. We send our verack. +// 4. Remote peer sends their verack. func (p *Peer) negotiateInboundProtocol() error { if err := p.readRemoteVersionMsg(); err != nil { return err @@ -2121,10 +2121,10 @@ func (p *Peer) negotiateInboundProtocol() error { // peer. The events should occur in the following order, otherwise an error is // returned: // -// 1. We send our version. -// 2. Remote peer sends their version. -// 3. Remote peer sends their verack. -// 4. We send our verack. +// 1. We send our version. +// 2. Remote peer sends their version. +// 3. Remote peer sends their verack. +// 4. We send our verack. func (p *Peer) negotiateOutboundProtocol() error { if err := p.writeLocalVersionMsg(); err != nil { return err diff --git a/rpcclient/doc.go b/rpcclient/doc.go index d82a40a1..7a02dded 100644 --- a/rpcclient/doc.go +++ b/rpcclient/doc.go @@ -5,7 +5,7 @@ /* Package rpcclient implements a websocket-enabled Bitcoin JSON-RPC client. -Overview +# Overview This client provides a robust and easy to use client for interfacing with a Bitcoin RPC server that uses a btcd/bitcoin core compatible Bitcoin JSON-RPC @@ -24,7 +24,7 @@ btcd or btcwallet by default. However, configuration options are provided to fall back to HTTP POST and disable TLS to support talking with inferior bitcoin core style RPC servers. -Websockets vs HTTP POST +# Websockets vs HTTP POST In HTTP POST-based JSON-RPC, every request creates a new HTTP connection, issues the call, waits for the response, and closes the connection. This adds @@ -40,7 +40,7 @@ can be invoked without having to go through a connect/disconnect cycle for every call. In addition, the websocket interface provides other nice features such as the ability to register for asynchronous notifications of various events. -Synchronous vs Asynchronous API +# Synchronous vs Asynchronous API The client provides both a synchronous (blocking) and asynchronous API. @@ -57,7 +57,7 @@ the Receive method on the returned instance will either return the result immediately if it has already arrived, or block until it has. This is useful since it provides the caller with greater control over concurrency. -Notifications +# Notifications The first important part of notifications is to realize that they will only work when connected via websockets. This should intuitively make sense @@ -67,7 +67,7 @@ All notifications provided by btcd require registration to opt-in. For example, if you want to be notified when funds are received by a set of addresses, you register the addresses via the NotifyReceived (or NotifyReceivedAsync) function. -Notification Handlers +# Notification Handlers Notifications are exposed by the client through the use of callback handlers which are setup via a NotificationHandlers instance that is specified by the @@ -83,7 +83,7 @@ will cause a deadlock as more server responses won't be read until the callback returns, but the callback would be waiting for a response. Thus, any additional RPCs must be issued an a completely decoupled manner. -Automatic Reconnection +# Automatic Reconnection By default, when running in websockets mode, this client will automatically keep trying to reconnect to the RPC server should the connection be lost. There @@ -116,7 +116,7 @@ chain services will be available. Depending on your application, you might only need chain-related RPCs. In contrast, btcwallet provides pass through treatment for chain-related RPCs, so it supports them in addition to wallet-related RPCs. -Errors +# Errors There are 3 categories of errors that will be returned throughout this package: @@ -144,35 +144,35 @@ The third category of errors, that is errors returned by the server, can be detected by type asserting the error in a *btcjson.RPCError. For example, to detect if a command is unimplemented by the remote RPC server: - amount, err := client.GetBalance("") - if err != nil { - if jerr, ok := err.(*btcjson.RPCError); ok { - switch jerr.Code { - case btcjson.ErrRPCUnimplemented: - // Handle not implemented error + amount, err := client.GetBalance("") + if err != nil { + if jerr, ok := err.(*btcjson.RPCError); ok { + switch jerr.Code { + case btcjson.ErrRPCUnimplemented: + // Handle not implemented error - // Handle other specific errors you care about - } - } + // Handle other specific errors you care about + } + } - // Log or otherwise handle the error knowing it was not one returned - // from the remote RPC server. - } + // Log or otherwise handle the error knowing it was not one returned + // from the remote RPC server. + } -Example Usage +# Example Usage The following full-blown client examples are in the examples directory: - - bitcoincorehttp - Connects to a bitcoin core RPC server using HTTP POST mode with TLS disabled - and gets the current block count - - btcdwebsockets - Connects to a btcd RPC server using TLS-secured websockets, registers for - block connected and block disconnected notifications, and gets the current - block count - - btcwalletwebsockets - Connects to a btcwallet RPC server using TLS-secured websockets, registers - for notifications about changes to account balances, and gets a list of - unspent transaction outputs (utxos) the wallet can sign + - bitcoincorehttp + Connects to a bitcoin core RPC server using HTTP POST mode with TLS disabled + and gets the current block count + - btcdwebsockets + Connects to a btcd RPC server using TLS-secured websockets, registers for + block connected and block disconnected notifications, and gets the current + block count + - btcwalletwebsockets + Connects to a btcwallet RPC server using TLS-secured websockets, registers + for notifications about changes to account balances, and gets a list of + unspent transaction outputs (utxos) the wallet can sign */ package rpcclient diff --git a/rpcclient/extensions.go b/rpcclient/extensions.go index da44e91f..c21101c3 100644 --- a/rpcclient/extensions.go +++ b/rpcclient/extensions.go @@ -56,7 +56,8 @@ func (c *Client) DebugLevelAsync(levelSpec string) FutureDebugLevelResult { // specification. // // The levelspec can be either a debug level or of the form: -// =,=,... +// +// =,=,... // // Additionally, the special keyword 'show' can be used to get a list of the // available subsystems. diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index 6f54730b..bc4dd917 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -1016,10 +1016,10 @@ func (c *Client) CreateWalletAsync(name string, opts ...CreateWalletOpt) FutureC // // Optional parameters can be specified using functional-options pattern. The // following functions are available: -// * WithCreateWalletDisablePrivateKeys -// * WithCreateWalletBlank -// * WithCreateWalletPassphrase -// * WithCreateWalletAvoidReuse +// - WithCreateWalletDisablePrivateKeys +// - WithCreateWalletBlank +// - WithCreateWalletPassphrase +// - WithCreateWalletAvoidReuse func (c *Client) CreateWallet(name string, opts ...CreateWalletOpt) (*btcjson.CreateWalletResult, error) { return c.CreateWalletAsync(name, opts...).Receive() } diff --git a/txscript/doc.go b/txscript/doc.go index 7da52161..179cb227 100644 --- a/txscript/doc.go +++ b/txscript/doc.go @@ -12,7 +12,7 @@ overview to provide information on how to use the package. This package provides data structures and functions to parse and execute bitcoin transaction scripts. -Script Overview +# Script Overview Bitcoin transaction scripts are written in a stack-base, FORTH-like language. @@ -30,7 +30,7 @@ is used to prove the the spender is authorized to perform the transaction. One benefit of using a scripting language is added flexibility in specifying what conditions must be met in order to spend bitcoins. -Errors +# Errors Errors returned by this package are of type txscript.Error. This allows the caller to programmatically determine the specific error by examining the diff --git a/txscript/error.go b/txscript/error.go index f42b893e..e0a1fc2e 100644 --- a/txscript/error.go +++ b/txscript/error.go @@ -427,10 +427,10 @@ func (e ErrorCode) String() string { // Error identifies a script-related error. It is used to indicate three // classes of errors: -// 1) Script execution failures due to violating one of the many requirements -// imposed by the script engine or evaluating to false -// 2) Improper API usage by callers -// 3) Internal consistency check failures +// 1. Script execution failures due to violating one of the many requirements +// imposed by the script engine or evaluating to false +// 2. Improper API usage by callers +// 3. Internal consistency check failures // // The caller can use type assertions on the returned errors to access the // ErrorCode field to ascertain the specific reason for the error. As an diff --git a/txscript/scriptbuilder.go b/txscript/scriptbuilder.go index 7984dd96..49dff6b4 100644 --- a/txscript/scriptbuilder.go +++ b/txscript/scriptbuilder.go @@ -37,16 +37,17 @@ func (e ErrScriptNotCanonical) Error() string { // For example, the following would build a 2-of-3 multisig script for usage in // a pay-to-script-hash (although in this situation MultiSigScript() would be a // better choice to generate the script): -// builder := txscript.NewScriptBuilder() -// builder.AddOp(txscript.OP_2).AddData(pubKey1).AddData(pubKey2) -// builder.AddData(pubKey3).AddOp(txscript.OP_3) -// builder.AddOp(txscript.OP_CHECKMULTISIG) -// script, err := builder.Script() -// if err != nil { -// // Handle the error. -// return -// } -// fmt.Printf("Final multi-sig script: %x\n", script) +// +// builder := txscript.NewScriptBuilder() +// builder.AddOp(txscript.OP_2).AddData(pubKey1).AddData(pubKey2) +// builder.AddData(pubKey3).AddOp(txscript.OP_3) +// builder.AddOp(txscript.OP_CHECKMULTISIG) +// script, err := builder.Script() +// if err != nil { +// // Handle the error. +// return +// } +// fmt.Printf("Final multi-sig script: %x\n", script) type ScriptBuilder struct { script []byte err error diff --git a/txscript/scriptnum.go b/txscript/scriptnum.go index 81f26361..e75bdeaa 100644 --- a/txscript/scriptnum.go +++ b/txscript/scriptnum.go @@ -89,18 +89,19 @@ func checkMinimalDataEncoding(v []byte) error { // Bytes returns the number serialized as a little endian with a sign bit. // // Example encodings: -// 127 -> [0x7f] -// -127 -> [0xff] -// 128 -> [0x80 0x00] -// -128 -> [0x80 0x80] -// 129 -> [0x81 0x00] -// -129 -> [0x81 0x80] -// 256 -> [0x00 0x01] -// -256 -> [0x00 0x81] -// 32767 -> [0xff 0x7f] -// -32767 -> [0xff 0xff] -// 32768 -> [0x00 0x80 0x00] -// -32768 -> [0x00 0x80 0x80] +// +// 127 -> [0x7f] +// -127 -> [0xff] +// 128 -> [0x80 0x00] +// -128 -> [0x80 0x80] +// 129 -> [0x81 0x00] +// -129 -> [0x81 0x80] +// 256 -> [0x00 0x01] +// -256 -> [0x00 0x81] +// 32767 -> [0xff 0x7f] +// -32767 -> [0xff 0xff] +// 32768 -> [0x00 0x80 0x00] +// -32768 -> [0x00 0x80 0x80] func (n scriptNum) Bytes() []byte { // Zero encodes as an empty byte slice. if n == 0 { diff --git a/wire/doc.go b/wire/doc.go index b8b8c56f..5e03ff20 100644 --- a/wire/doc.go +++ b/wire/doc.go @@ -14,7 +14,7 @@ supported bitcoin messages to and from the wire. This package does not deal with the specifics of message handling such as what to do when a message is received. This provides the caller with a high level of flexibility. -Bitcoin Message Overview +# Bitcoin Message Overview The bitcoin protocol consists of exchanging messages between peers. Each message is preceded by a header which identifies information about it such as @@ -30,7 +30,7 @@ messages, all of the details of marshalling and unmarshalling to and from the wire using bitcoin encoding are handled so the caller doesn't have to concern themselves with the specifics. -Message Interaction +# Message Interaction The following provides a quick summary of how the bitcoin messages are intended to interact with one another. As stated above, these interactions are not @@ -62,13 +62,13 @@ interactions in no particular order. in BIP0031. The BIP0031Version constant can be used to detect a recent enough protocol version for this purpose (version > BIP0031Version). -Common Parameters +# Common Parameters There are several common parameters that arise when using this package to read and write bitcoin messages. The following sections provide a quick overview of these parameters so the next sections can build on them. -Protocol Version +# Protocol Version The protocol version should be negotiated with the remote peer at a higher level than this package via the version (MsgVersion) message exchange, however, @@ -77,7 +77,7 @@ latest protocol version this package supports and is typically the value to use for all outbound connections before a potentially lower protocol version is negotiated. -Bitcoin Network +# Bitcoin Network The bitcoin network is a magic number which is used to identify the start of a message and which bitcoin network the message applies to. This package provides @@ -88,7 +88,7 @@ the following constants: wire.TestNet3 (Test network version 3) wire.SimNet (Simulation test network) -Determining Message Type +# Determining Message Type As discussed in the bitcoin message overview section, this package reads and writes bitcoin messages using a generic interface named Message. In @@ -106,7 +106,7 @@ switch or type assertion. An example of a type switch follows: fmt.Printf("Number of tx in block: %v", msg.Header.TxnCount) } -Reading Messages +# Reading Messages In order to unmarshall bitcoin messages from the wire, use the ReadMessage function. It accepts any io.Reader, but typically this will be a net.Conn to @@ -121,7 +121,7 @@ a remote node running a bitcoin peer. Example syntax is: // Log and handle the error } -Writing Messages +# Writing Messages In order to marshall bitcoin messages to the wire, use the WriteMessage function. It accepts any io.Writer, but typically this will be a net.Conn to @@ -139,7 +139,7 @@ from a remote peer is: // Log and handle the error } -Errors +# Errors Errors returned by this package are either the raw errors provided by underlying calls to read/write from streams such as io.EOF, io.ErrUnexpectedEOF, and @@ -147,7 +147,7 @@ io.ErrShortWrite, or of type wire.MessageError. This allows the caller to differentiate between general IO errors and malformed messages through type assertions. -Bitcoin Improvement Proposals +# Bitcoin Improvement Proposals This package includes spec changes outlined by the following BIPs: diff --git a/wire/msgtx.go b/wire/msgtx.go index 34bdeaed..a60f7a82 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -114,16 +114,18 @@ const ( // transaction from one that would require a different parsing logic. // // Position of FLAG in a bitcoin tx message: -// ┌─────────┬────────────────────┬─────────────┬─────┐ -// │ VERSION │ FLAG │ TX-IN-COUNT │ ... │ -// │ 4 bytes │ 2 bytes (optional) │ varint │ │ -// └─────────┴────────────────────┴─────────────┴─────┘ +// +// ┌─────────┬────────────────────┬─────────────┬─────┐ +// │ VERSION │ FLAG │ TX-IN-COUNT │ ... │ +// │ 4 bytes │ 2 bytes (optional) │ varint │ │ +// └─────────┴────────────────────┴─────────────┴─────┘ // // Zooming into the FLAG field: -// ┌── FLAG ─────────────┬────────┐ -// │ TxFlagMarker (0x00) │ TxFlag │ -// │ 1 byte │ 1 byte │ -// └─────────────────────┴────────┘ +// +// ┌── FLAG ─────────────┬────────┐ +// │ TxFlagMarker (0x00) │ TxFlag │ +// │ 1 byte │ 1 byte │ +// └─────────────────────┴────────┘ const TxFlagMarker = 0x00 // TxFlag is the second byte of the FLAG field in a bitcoin tx message. -- 2.45.2 From a9351b3e3a58b78fa4490cdb9f6234910afde113 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 7 Aug 2022 23:03:33 -0700 Subject: [PATCH 436/459] lbcdblocknotify: support --run to execute custom command --- rpcclient/examples/lbcdblocknotify/main.go | 74 +++++++++++++++------- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/rpcclient/examples/lbcdblocknotify/main.go b/rpcclient/examples/lbcdblocknotify/main.go index 004460b6..af538642 100644 --- a/rpcclient/examples/lbcdblocknotify/main.go +++ b/rpcclient/examples/lbcdblocknotify/main.go @@ -5,19 +5,69 @@ package main import ( + "errors" "flag" "fmt" "io/ioutil" "log" "net" + "os" + "os/exec" "path/filepath" + "strings" "github.com/lbryio/lbcd/rpcclient" "github.com/lbryio/lbcd/wire" "github.com/lbryio/lbcutil" ) -func send(stratum, stratumPass, coinid, blockHash string) error { +var ( + coinid = flag.String("coinid", "1425", "Coin ID") + stratum = flag.String("stratum", "", "Stratum server") + stratumPass = flag.String("stratumpass", "", "Stratum server password") + rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server") + rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username") + rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password") + notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled") + run = flag.String("run", "", "Run custom shell command") +) + +func onFilteredBlockConnected(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) { + + blockHash := header.BlockHash().String() + + log.Printf("Block connected: %v (%d) %v", blockHash, height, header.Timestamp) + + if cmd := *run; len(cmd) != 0 { + cmd = strings.ReplaceAll(cmd, "%s", blockHash) + err := execCustomCommand(cmd) + if err != nil { + log.Printf("ERROR: execCustomCommand: %s", err) + } + } + + if len(*stratum) > 0 && len(*stratumPass) > 0 { + err := stratumUpdateBlock(*stratum, *stratumPass, *coinid, blockHash) + if err != nil { + log.Printf("ERROR: stratumUpdateBlock: %s", err) + } + } +} +func execCustomCommand(cmd string) error { + strs := strings.Split(cmd, " ") + path, err := exec.LookPath(strs[0]) + if errors.Is(err, exec.ErrDot) { + err = nil + } + if err != nil { + return err + } + c := exec.Command(path, strs[1:]...) + c.Stdout = os.Stdout + return c.Run() +} + +func stratumUpdateBlock(stratum, stratumPass, coinid, blockHash string) error { addr, err := net.ResolveTCPAddr("tcp", stratum) if err != nil { return fmt.Errorf("can't resolve addr: %w", err) @@ -39,32 +89,12 @@ func send(stratum, stratumPass, coinid, blockHash string) error { return nil } - func main() { - var ( - coinid = flag.String("coinid", "1425", "Coin ID") - stratum = flag.String("stratum", "lbrypool.net:3334", "Stratum server") - stratumPass = flag.String("stratumpass", "password", "Stratum server password") - rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server") - rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username") - rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password") - notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled") - ) - flag.Parse() ntfnHandlers := rpcclient.NotificationHandlers{ - OnFilteredBlockConnected: func(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) { - - blockHash := header.BlockHash().String() - - log.Printf("Block connected: %v (%d) %v", blockHash, height, header.Timestamp) - - if err := send(*stratum, *stratumPass, *coinid, blockHash); err != nil { - log.Printf("ERROR: failed to notify stratum: %s", err) - } - }, + OnFilteredBlockConnected: onFilteredBlockConnected, } // Connect to local lbcd RPC server using websockets. -- 2.45.2 From fdedbf86f8bd7454d8f0c1e9df717b4ea4fca214 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sat, 6 Aug 2022 11:10:45 -0700 Subject: [PATCH 437/459] mining: include 'segwit' rule when no segwit txns in GBT According to the BIP0009, all active softfork deployment should be included in the rules. We add the '!' to indicate the enforcement if the template has any segwit transactions in it. Otherwise, plain `segwit` is fine. --- rpcserver.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpcserver.go b/rpcserver.go index 96f92201..55b0485e 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1900,6 +1900,8 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld if template.WitnessCommitment != nil { reply.DefaultWitnessCommitment = hex.EncodeToString(template.WitnessCommitment) reply.Rules = append(reply.Rules, "!segwit") + } else { + reply.Rules = append(reply.Rules, "segwit") } if useCoinbaseValue { -- 2.45.2 From 78bed14956993eee7b3cf5b1a21858257e40a298 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 12 Aug 2022 02:21:51 -0700 Subject: [PATCH 438/459] go mod: bump lbcutil to v1.0.202 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5d51ab74..77fd4cce 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/felixge/fgprof v0.9.2 github.com/jessevdk/go-flags v1.5.0 github.com/jrick/logrotate v1.0.0 - github.com/lbryio/lbcutil v1.0.202-rc3 + github.com/lbryio/lbcutil v1.0.202 github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil/v3 v3.22.4 github.com/spf13/cobra v1.1.3 diff --git a/go.sum b/go.sum index 9079426b..29fa50be 100644 --- a/go.sum +++ b/go.sum @@ -284,8 +284,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/lbryio/lbcutil v1.0.202-rc3 h1:J7zYnIj3iN/ndPYKqMKBukLaLM1GhCEaiaMOYIMdUCU= -github.com/lbryio/lbcutil v1.0.202-rc3/go.mod h1:LGPtVBBzh4cFXfLFb8ginlFcbA2QwumLNFd0yk/as2o= +github.com/lbryio/lbcutil v1.0.202 h1:L0aRMs2bdCUAicD8Xe4NmUEvevDDea3qkIpCSACnftI= +github.com/lbryio/lbcutil v1.0.202/go.mod h1:LGPtVBBzh4cFXfLFb8ginlFcbA2QwumLNFd0yk/as2o= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 h1:aczX6NMOtt6L4YT0fQvKkDK6LZEtdOso9sUH89V1+P0= github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281/go.mod h1:lc+czkgO/8F7puNki5jk8QyujbfK1LOT7Wl0ON2hxyk= -- 2.45.2 From fcfb2af76f8e9b38f9f76b79530eca7cf8c94a99 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 12 Aug 2022 02:07:30 -0700 Subject: [PATCH 439/459] netsync: revert base/segwit encoding hack --- netsync/manager.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/netsync/manager.go b/netsync/manager.go index 351fb7cd..169cec8f 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -1294,16 +1294,9 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) { break } } - - e := wire.BaseEncoding - // we think that the iv.Type set above is sufficient. If not: - // if peer.IsWitnessEnabled() { - // e = wire.WitnessEncoding - //} - state.requestQueue = requestQueue if len(gdmsg.InvList) > 0 { - peer.QueueMessageWithEncoding(gdmsg, nil, e) + peer.QueueMessage(gdmsg, nil) } } -- 2.45.2 From be0d7de8da3d71241053a154357b15edb69d948e Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 10 Aug 2022 00:34:59 -0700 Subject: [PATCH 440/459] mining: accomodate pre-BIP0141 coinbase structure Some popular pool software, yiimp for example, constructs coinbase in pre-BIP0141 style, which results in rejection of submitblock. --- blockchain/merkle.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/blockchain/merkle.go b/blockchain/merkle.go index 313cc617..107c93cf 100644 --- a/blockchain/merkle.go +++ b/blockchain/merkle.go @@ -11,6 +11,7 @@ import ( "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" btcutil "github.com/lbryio/lbcutil" ) @@ -227,6 +228,20 @@ func ValidateWitnessCommitment(blk *btcutil.Block) error { // coinbase transaction MUST have exactly one witness element within // its witness data and that element must be exactly // CoinbaseWitnessDataLen bytes. + // + // Some popular pool software, for example yiimp, uses pre-BIP0141 + // coinbase struture. In this case, we don't just accept it, but also + // turn it into post-BIP0141 format. + if len(coinbaseTx.MsgTx().TxIn[0].Witness) == 0 { + log.Infof("pre-BIP0141 coinbase transaction detected. Height: %d", blk.Height()) + + var witnessNonce [CoinbaseWitnessDataLen]byte + coinbaseTx.MsgTx().TxIn[0].Witness = wire.TxWitness{witnessNonce[:]} + blk.MsgBlock().Transactions[0].TxIn[0].Witness = wire.TxWitness{witnessNonce[:]} + + // Clear cached serialized block. + blk.SetBytes(nil) + } coinbaseWitness := coinbaseTx.MsgTx().TxIn[0].Witness if len(coinbaseWitness) != 1 { str := fmt.Sprintf("the coinbase transaction has %d items in "+ -- 2.45.2 From ff324e0fdbc29aef46367fa7d8be68529642e8b2 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 14 Aug 2022 14:17:41 -0700 Subject: [PATCH 441/459] doc: update snapshot related instructions --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4c3116d9..ee8f1c53 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ If no config is found, it creates a [default one](sample-lbcd.conf), which inclu ### RPC server -RPC credentials (`rpcuser` and `rpcpass`) is required to enable RPC server. It can be specify in the `"${LBCDIR}/lbcd.conf"`, using command line options: +RPC credentials (`rpcuser` and `rpcpass`) is required to enable RPC server. It can be specify in the `"${LBCDDIR}/lbcd.conf"`, using command line options: ``` sh ./lbcd --rpcuser=rpcuser --rpcpass=rpcpass @@ -138,7 +138,7 @@ Download the snapshot, and uncompress it: ``` sh time curl -O https://snapshots.lbry.com/blockchain/lbcd_snapshot_1199527_v0.22.105_2022-07-27.tar.zst -zstd -d lbcd_snapshot_1199527_v0.22.105_2022-07-27.tar.zst | tar xf - -C "${LBCDIR}" +zstd -d --stdout lbcd_snapshot_1199527_v0.22.105_2022-07-27.tar.zst | tar xf - -C "${LBCDDIR}" ``` If preferred, a user can download and uncompress the snapshot on the fly: @@ -147,7 +147,7 @@ By the time the download is finished, the snapshots should be almost uncompresse ``` sh mkdir -p "${LBCDDIR}" -time curl https://snapshots.lbry.com/blockchain/lbcd_snapshot_1199527_v0.22.105_2022-07-27.tar.zst | zstd -d | tar xf - -C "${LBCDIR}" +time curl https://snapshots.lbry.com/blockchain/lbcd_snapshot_1199527_v0.22.105_2022-07-27.tar.zst | zstd -d --stdout | tar xf - -C "${LBCDDIR}" # % Total % Received % Xferd Average Speed Time Time Time Current # Dload Upload Total Spent Left Speed -- 2.45.2 From 98e5771989d0e89be878d4bd59ea778d31e8dfc7 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 14 Aug 2022 20:44:32 -0700 Subject: [PATCH 442/459] rpc: implement setban, lisnbanned, clearbanned RPCs --- btcjson/chainsvrcmds.go | 54 +++++++++++++++++++ btcjson/chainsvrresults.go | 9 ++++ rpcadapters.go | 52 ++++++++++++++++++ rpcclient/net.go | 69 ++++++++++++++++++++++++ rpcserver.go | 105 ++++++++++++++++++++++++++++++++++++- rpcserverhelp.go | 27 +++++++++- server.go | 66 ++++++++++++++++++++--- 7 files changed, 371 insertions(+), 11 deletions(-) diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index 95993dac..30024dda 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -48,6 +48,15 @@ func NewAddNodeCmd(addr string, subCmd AddNodeSubCmd) *AddNodeCmd { } } +// ClearBannedCmd defines the clearbanned JSON-RPC command. +type ClearBannedCmd struct{} + +// NewClearBannedCmd returns a new instance which can be used to issue an clearbanned +// JSON-RPC command. +func NewClearBannedCmd() *ClearBannedCmd { + return &ClearBannedCmd{} +} + // TransactionInput represents the inputs to a transaction. Specifically a // transaction hash and output number pair. type TransactionInput struct { @@ -757,6 +766,15 @@ func NewInvalidateBlockCmd(blockHash string) *InvalidateBlockCmd { } } +// ListBannedCmd defines the listbanned JSON-RPC command. +type ListBannedCmd struct{} + +// NewListBannedCmd returns a new instance which can be used to issue a listbanned +// JSON-RPC command. +func NewListBannedCmd() *ListBannedCmd { + return &ListBannedCmd{} +} + // PingCmd defines the ping JSON-RPC command. type PingCmd struct{} @@ -903,6 +921,39 @@ func NewBitcoindSendRawTransactionCmd(hexTx string, maxFeeRate int32) *SendRawTr } } +// SetBanSubCmd defines the type used in the setban JSON-RPC command for the +// sub command field. +type SetBanSubCmd string + +const ( + // SBAdd indicates the specified host should be added as a persistent + // peer. + SBAdd SetBanSubCmd = "add" + + // SBRemove indicates the specified peer should be removed. + SBRemove SetBanSubCmd = "remove" +) + +// SetBanCmd defines the setban JSON-RPC command. +type SetBanCmd struct { + Addr string + SubCmd SetBanSubCmd `jsonrpcusage:"\"add|remove\""` + BanTime *int `jsonrpcdefault:"0"` + Absolute *bool `jsonrpcdefault:"false"` +} + +// NewSetBanCmd returns a new instance which can be used to issue an setban +// JSON-RPC command. +func NewSetBanCmd(addr string, subCmd SetBanSubCmd, banTime *int, + absolute *bool) *SetBanCmd { + return &SetBanCmd{ + Addr: addr, + SubCmd: subCmd, + BanTime: banTime, + Absolute: absolute, + } +} + // SetGenerateCmd defines the setgenerate JSON-RPC command. type SetGenerateCmd struct { Generate bool @@ -1080,6 +1131,9 @@ func init() { MustRegisterCmd("getnetworkhashps", (*GetNetworkHashPSCmd)(nil), flags) MustRegisterCmd("getnodeaddresses", (*GetNodeAddressesCmd)(nil), flags) MustRegisterCmd("getpeerinfo", (*GetPeerInfoCmd)(nil), flags) + MustRegisterCmd("listbanned", (*ListBannedCmd)(nil), flags) + MustRegisterCmd("setban", (*SetBanCmd)(nil), flags) + MustRegisterCmd("clearbanned", (*ClearBannedCmd)(nil), flags) MustRegisterCmd("getrawmempool", (*GetRawMempoolCmd)(nil), flags) MustRegisterCmd("getrawtransaction", (*GetRawTransactionCmd)(nil), flags) MustRegisterCmd("gettxout", (*GetTxOutCmd)(nil), flags) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index c6a5d550..ad71dcd3 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -721,6 +721,15 @@ type InfoChainResult struct { Errors string `json:"errors"` } +// ListBannedResult models the data returned from the listbanned command. +type ListBannedResult struct { + Address string `json:"address"` + BanCreated int64 `json:"ban_created"` + BannedUntil int64 `json:"banned_until"` + BanDuration int64 `json:"ban_duration"` + TimeRemaining int64 `json:"time_remaining"` +} + // TxRawResult models the data from the getrawtransaction command. type TxRawResult struct { Hex string `json:"hex"` diff --git a/rpcadapters.go b/rpcadapters.go index 2a1af72f..d6f809fc 100644 --- a/rpcadapters.go +++ b/rpcadapters.go @@ -6,6 +6,7 @@ package main import ( "sync/atomic" + "time" "github.com/lbryio/lbcd/blockchain" "github.com/lbryio/lbcd/chaincfg/chainhash" @@ -181,6 +182,57 @@ func (cm *rpcConnManager) ConnectedPeers() []rpcserverPeer { return peers } +// BannedPeers returns a map consisting of all banned host with banned period. +// +// This function is safe for concurrent access and is part of the +// rpcserverConnManager interface implementation. +func (cm *rpcConnManager) BannedPeers() map[string]bannedPeriod { + replyChan := make(chan map[string]bannedPeriod) + cm.server.query <- listBannedPeersMsg{reply: replyChan} + return <-replyChan +} + +// SetBan removes the peer associated with the provided address from the +// list of persistent peers. +// +// This function is safe for concurrent access and is part of the +// rpcserverConnManager interface implementation. +func (cm *rpcConnManager) SetBan(addr string, since, until time.Time) error { + replyChan := make(chan error) + cm.server.query <- setBanMsg{ + addr: addr, + since: since, + until: until, + reply: replyChan, + } + return <-replyChan +} + +// RemoveBan removes a host from banned list. +// +// This function is safe for concurrent access and is part of the +// rpcserverConnManager interface implementation. +func (cm *rpcConnManager) RemoveBan(addr string) error { + replyChan := make(chan error) + cm.server.query <- removeBanMsg{ + addr: addr, + reply: replyChan, + } + return <-replyChan +} + +// ClearBanned removes all banned host with banned period. +// +// This function is safe for concurrent access and is part of the +// rpcserverConnManager interface implementation. +func (cm *rpcConnManager) ClearBanned() error { + replyChan := make(chan error) + cm.server.query <- clearBannedMsg{ + reply: replyChan, + } + return <-replyChan +} + // PersistentPeers returns an array consisting of all the added persistent // peers. // diff --git a/rpcclient/net.go b/rpcclient/net.go index 2d268235..385875df 100644 --- a/rpcclient/net.go +++ b/rpcclient/net.go @@ -355,6 +355,75 @@ func (c *Client) GetPeerInfo() ([]btcjson.GetPeerInfoResult, error) { return c.GetPeerInfoAsync().Receive() } +// FutureListBannedResult is a future promise to deliver the result of a +// ListBannedAsync RPC invocation (or an applicable error). +type FutureListBannedResult chan *Response + +// Receive waits for the Response promised by the future and returns data about +// each connected network peer. +func (r FutureListBannedResult) Receive() ([]btcjson.ListBannedResult, error) { + res, err := ReceiveFuture(r) + if err != nil { + return nil, err + } + + // Unmarshal result as an array of ListBanned result objects. + var bannedPeers []btcjson.ListBannedResult + err = json.Unmarshal(res, &bannedPeers) + if err != nil { + return nil, err + } + + return bannedPeers, nil +} + +// SetBanCommand enumerates the available commands that the SetBanCommand function +// accepts. +type SetBanCommand string + +// Constants used to indicate the command for the SetBanCommand function. +const ( + // SBAdd indicates the specified host should be added as a banned + // peer. + SBAdd SetBanCommand = "add" + + // SBRemove indicates the specified peer should be removed. + SBRemove SetBanCommand = "remove" +) + +// String returns the SetBanCommand in human-readable form. +func (cmd SetBanCommand) String() string { + return string(cmd) +} + +// FutureSetBanResult is a future promise to deliver the result of an +// SetBanAsync RPC invocation (or an applicable error). +type FutureSetBanResult chan *Response + +// Receive waits for the Response promised by the future and returns an error if +// any occurred when performing the specified command. +func (r FutureSetBanResult) Receive() error { + _, err := ReceiveFuture(r) + return err +} + +// SetBanAsync returns an instance of a type that can be used to get the result +// of the RPC at some future time by invoking the Receive function on the +// returned instance. +func (c *Client) SetBanAsync(addr string, command string, banTime *int, + absolute *bool) FutureSetBanResult { + cmd := btcjson.NewSetBanCmd(addr, btcjson.SetBanSubCmd(command), banTime, + absolute) + return c.SendCmd(cmd) +} + +// SetBan attempts to perform the passed command on the passed persistent peer. +// For example, it can be used to add or a remove a banned peer. +func (c *Client) SetBan(addr string, command string, banTime *int, + absolute *bool) error { + return c.SetBanAsync(addr, command, banTime, absolute).Receive() +} + // FutureGetNetTotalsResult is a future promise to deliver the result of a // GetNetTotalsAsync RPC invocation (or an applicable error). type FutureGetNetTotalsResult chan *Response diff --git a/rpcserver.go b/rpcserver.go index 55b0485e..f02e347a 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -134,6 +134,7 @@ type commandHandler func(*rpcServer, interface{}, <-chan struct{}) (interface{}, var rpcHandlers map[string]commandHandler var rpcHandlersBeforeInit = map[string]commandHandler{ "addnode": handleAddNode, + "clearbanned": handleClearBanned, "createrawtransaction": handleCreateRawTransaction, "debuglevel": handleDebugLevel, "decoderawtransaction": handleDecodeRawTransaction, @@ -150,10 +151,10 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getblockcount": handleGetBlockCount, "getblockhash": handleGetBlockHash, "getblockheader": handleGetBlockHeader, - "getchaintips": handleGetChainTips, "getblocktemplate": handleGetBlockTemplate, "getcfilter": handleGetCFilter, "getcfilterheader": handleGetCFilterHeader, + "getchaintips": handleGetChainTips, "getconnectioncount": handleGetConnectionCount, "getcurrentnet": handleGetCurrentNet, "getdifficulty": handleGetDifficulty, @@ -161,8 +162,8 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "gethashespersec": handleGetHashesPerSec, "getheaders": handleGetHeaders, "getinfo": handleGetInfo, - "getmempoolinfo": handleGetMempoolInfo, "getmempoolentry": handleGetMempoolEntry, + "getmempoolinfo": handleGetMempoolInfo, "getmininginfo": handleGetMiningInfo, "getnettotals": handleGetNetTotals, "getnetworkhashps": handleGetNetworkHashPS, @@ -174,11 +175,13 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "gettxout": handleGetTxOut, "help": handleHelp, "invalidateblock": handleInvalidateBlock, + "listbanned": handleListBanned, "node": handleNode, "ping": handlePing, "reconsiderblock": handleReconsiderBlock, "searchrawtransactions": handleSearchRawTransactions, "sendrawtransaction": handleSendRawTransaction, + "setban": handleSetBan, "setgenerate": handleSetGenerate, "signmessagewithprivkey": handleSignMessageWithPrivKey, "stop": handleStop, @@ -398,6 +401,21 @@ func handleAddNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in return nil, nil } +// handleClearBanned handles clearbanned commands. +func handleClearBanned(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + + err := s.cfg.ConnMgr.ClearBanned() + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: err.Error(), + } + } + + // no data returned unless an error. + return nil, nil +} + // handleNode handles node commands. func handleNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*btcjson.NodeCmd) @@ -3146,6 +3164,24 @@ func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter return help, nil } +// handleListBanned handles the listbanned command. +func handleListBanned(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + banned := s.cfg.ConnMgr.BannedPeers() + reply := make([]*btcjson.ListBannedResult, 0, len(banned)) + for address, period := range banned { + since, until := period.since, period.until + r := btcjson.ListBannedResult{ + Address: address, + BanCreated: since.Unix(), + BannedUntil: until.Unix(), + BanDuration: int64(until.Sub(since).Seconds()), + TimeRemaining: int64(time.Until(until).Seconds()), + } + reply = append(reply, &r) + } + return reply, nil +} + // handlePing implements the ping command. func handlePing(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { // Ask server to ping \o_ @@ -3749,6 +3785,59 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st return tx.Hash().String(), nil } +// handleSetBan handles the setban command. +func handleSetBan(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.SetBanCmd) + + addr := net.ParseIP(c.Addr) + if addr == nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "invalid addr for setban", + } + } + + since := time.Now() + until := since.Add(time.Second * time.Duration(*c.BanTime)) + if *c.BanTime == 0 { + until = since.Add(defaultBanDuration) + } + if *c.Absolute { + until = time.Unix(int64(*c.BanTime), 0) + } + + var err error + switch c.SubCmd { + case "add": + err = s.cfg.ConnMgr.SetBan(addr.String(), since, until) + addr := addr.String() + peers := s.cfg.ConnMgr.ConnectedPeers() + for _, peer := range peers { + p := peer.ToPeer() + if p.NA().IP.String() == addr { + p.Disconnect() + } + } + case "remove": + err = s.cfg.ConnMgr.RemoveBan(addr.String()) + default: + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: "invalid subcommand for setban", + } + } + + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: err.Error(), + } + } + + // no data returned unless an error. + return nil, nil +} + // handleSetGenerate implements the setgenerate command. func handleSetGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*btcjson.SetGenerateCmd) @@ -4806,6 +4895,18 @@ type rpcserverConnManager interface { // ConnectedPeers returns an array consisting of all connected peers. ConnectedPeers() []rpcserverPeer + // BannedPeers returns an array consisting of all Banned peers. + BannedPeers() map[string]bannedPeriod + + // SetBan add the addr to the ban list. + SetBan(addr string, since time.Time, until time.Time) error + + // RemoveBan remove the subnet from the ban list. + RemoveBan(subnet string) error + + // ClearBanned removes all banned IPs. + ClearBanned() error + // PersistentPeers returns an array consisting of all the persistent // peers. PersistentPeers() []rpcserverPeer diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 2be322ce..b7680783 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -56,6 +56,9 @@ var helpDescsEnUS = map[string]string{ "createrawtransaction-locktime": "Locktime value; a non-zero value will also locktime-activate the inputs", "createrawtransaction--result0": "Hex-encoded bytes of the serialized transaction", + // ClearBannedCmd help. + "clearbanned--synopsis": "Clear all banned IPs.", + // ScriptSig help. "scriptsig-asm": "Disassembly of the script", "scriptsig-hex": "Hex-encoded bytes of the script", @@ -636,6 +639,16 @@ var helpDescsEnUS = map[string]string{ "ping--synopsis": "Queues a ping to be sent to each connected peer.\n" + "Ping times are provided by getpeerinfo via the pingtime and pingwait fields.", + // ListBannedCmd help. + "listbanned--synopsis": "List all banned IPs.", + + // ListBannedResult help. + "listbannedresult-address": "The IP of the banned node.", + "listbannedresult-ban_created": "The UNIX epoch time the ban was created.", + "listbannedresult-banned_until": "The UNIX epoch time the ban expires.", + "listbannedresult-ban_duration": "The duration of the ban, in seconds.", + "listbannedresult-time_remaining": "The time remaining on the ban, in seconds", + // ReconsiderBlockCmd "reconsiderblock--synopsis": "Reconsider a block for validation.", "reconsiderblock-blockhash": "Hash of the block you want to reconsider", @@ -664,6 +677,13 @@ var helpDescsEnUS = map[string]string{ "sendrawtransaction--result0": "The hash of the transaction", "allowhighfeesormaxfeerate-value": "Either the boolean value for the allowhighfees parameter in bitcoind < v0.19.0 or the numerical value for the maxfeerate field in bitcoind v0.19.0 and later", + // SetBanCmd help. + "setban--synopsis": "Add or remove an IP from the banned list. (Currently, subnet is not supported.)", + "setban-addr": "The IP to ban. (Currently, subnet is not supported.)", + "setban-subcmd": "'add' to add an IP to the list, 'remove' to remove an IP from the list", + "setban-bantime": "Time in seconds the IP is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)", + "setban-absolute": "If set, the bantime must be an absolute timestamp expressed in UNIX epoch time; default to false.", + // SetGenerateCmd help. "setgenerate--synopsis": "Set the server to generate coins (mine) or not.", "setgenerate-generate": "Use true to enable generation, false to disable it", @@ -880,6 +900,7 @@ var helpDescsEnUS = map[string]string{ // pointer to the type (or nil to indicate no return value). var rpcResultTypes = map[string][]interface{}{ "addnode": nil, + "clearbanned": nil, "createrawtransaction": {(*string)(nil)}, "debuglevel": {(*string)(nil), (*string)(nil)}, "decoderawtransaction": {(*btcjson.TxRawDecodeResult)(nil)}, @@ -892,11 +913,11 @@ var rpcResultTypes = map[string][]interface{}{ "getbestblock": {(*btcjson.GetBestBlockResult)(nil)}, "getbestblockhash": {(*string)(nil)}, "getblock": {(*string)(nil), (*btcjson.GetBlockVerboseResult)(nil)}, + "getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)}, "getblockcount": {(*int64)(nil)}, "getblockhash": {(*string)(nil)}, "getblockheader": {(*string)(nil), (*btcjson.GetBlockHeaderVerboseResult)(nil)}, "getblocktemplate": {(*btcjson.GetBlockTemplateResult)(nil), (*string)(nil), nil}, - "getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)}, "getcfilter": {(*string)(nil)}, "getcfilterheader": {(*string)(nil)}, "getchaintips": {(*[]btcjson.GetChainTipsResult)(nil)}, @@ -918,13 +939,15 @@ var rpcResultTypes = map[string][]interface{}{ "getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)}, "getrawtransaction": {(*string)(nil), (*btcjson.TxRawResult)(nil)}, "gettxout": {(*btcjson.GetTxOutResult)(nil)}, - "node": nil, "help": {(*string)(nil), (*string)(nil)}, "invalidateblock": nil, + "listbanned": {(*[]btcjson.ListBannedResult)(nil)}, + "node": nil, "ping": nil, "reconsiderblock": nil, "searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)}, "sendrawtransaction": {(*string)(nil)}, + "setban": nil, "setgenerate": nil, "signmessagewithprivkey": {(*string)(nil)}, "stop": {(*string)(nil)}, diff --git a/server.go b/server.go index db13ed64..e7ccb3f1 100644 --- a/server.go +++ b/server.go @@ -156,13 +156,18 @@ type updatePeerHeightsMsg struct { originPeer *peer.Peer } +type bannedPeriod struct { + since time.Time + until time.Time +} + // peerState maintains state of inbound, persistent, outbound peers as well // as banned peers and outbound groups. type peerState struct { inboundPeers map[int32]*serverPeer outboundPeers map[int32]*serverPeer persistentPeers map[int32]*serverPeer - banned map[string]time.Time + banned map[string]bannedPeriod outboundGroups map[string]int } @@ -1656,10 +1661,10 @@ func (s *server) handleAddPeerMsg(state *peerState, sp *serverPeer) bool { sp.Disconnect() return false } - if banEnd, ok := state.banned[host]; ok { - if time.Now().Before(banEnd) { - srvrLog.Debugf("Peer %s is banned for another %v - disconnecting", - host, time.Until(banEnd)) + if ban, ok := state.banned[host]; ok { + if time.Now().Before(ban.until) { + srvrLog.Infof("Peer %s is banned for another %v - disconnecting", + host, time.Until(ban.until)) sp.Disconnect() return false } @@ -1781,7 +1786,12 @@ func (s *server) handleBanPeerMsg(state *peerState, sp *serverPeer) { direction := directionString(sp.Inbound()) srvrLog.Infof("Banned peer %s (%s) for %v", host, direction, cfg.BanDuration) - state.banned[host] = time.Now().Add(cfg.BanDuration) + + since := time.Now() + state.banned[host] = bannedPeriod{ + since: since, + until: since.Add(cfg.BanDuration), + } } // handleRelayInvMsg deals with relaying inventory to peers that are not already @@ -1876,6 +1886,25 @@ type getPeersMsg struct { reply chan []*serverPeer } +type listBannedPeersMsg struct { + reply chan map[string]bannedPeriod +} + +type setBanMsg struct { + addr string + since time.Time + until time.Time + reply chan error +} + +type removeBanMsg struct { + addr string + reply chan error +} + +type clearBannedMsg struct { + reply chan error +} type getOutboundGroup struct { key string reply chan int @@ -1924,6 +1953,29 @@ func (s *server) handleQuery(state *peerState, querymsg interface{}) { }) msg.reply <- peers + case listBannedPeersMsg: + banned := map[string]bannedPeriod{} + for host, ban := range state.banned { + banned[host] = ban + } + msg.reply <- banned + + case setBanMsg: + ban := bannedPeriod{ + since: msg.since, + until: msg.until, + } + state.banned[msg.addr] = ban + msg.reply <- nil + + case removeBanMsg: + delete(state.banned, msg.addr) + msg.reply <- nil + + case clearBannedMsg: + state.banned = map[string]bannedPeriod{} + msg.reply <- nil + case connectNodeMsg: // TODO: duplicate oneshots? // Limit max number of total peers. @@ -2161,7 +2213,7 @@ func (s *server) peerHandler() { inboundPeers: make(map[int32]*serverPeer), persistentPeers: make(map[int32]*serverPeer), outboundPeers: make(map[int32]*serverPeer), - banned: make(map[string]time.Time), + banned: make(map[string]bannedPeriod), outboundGroups: make(map[string]int), } -- 2.45.2 From ce37025d5a24dc1fcaa0a01ba28aa40d95a4b944 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 30 Aug 2022 13:17:34 -0700 Subject: [PATCH 443/459] txscript: validate claimscript size --- txscript/claimscript.go | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/txscript/claimscript.go b/txscript/claimscript.go index 1737ff60..4d3a8236 100644 --- a/txscript/claimscript.go +++ b/txscript/claimscript.go @@ -33,6 +33,9 @@ const ( // ErrInvalidClaimUpdateScript is returned a claim update script does not conform to the format. ErrInvalidClaimUpdateScript + + // ErrInvalidClaimName is returned when the claim name is invalid. + ErrInvalidClaimName ) func claimScriptError(c ErrorCode, desc string) Error { @@ -98,11 +101,15 @@ func ExtractClaimScript(script []byte) (*ClaimScript, error) { if !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP || !tokenizer.Next() || tokenizer.Opcode() != OP_DROP { - str := fmt.Sprintf("expect OP_2DROP OP_DROP") - return nil, claimScriptError(ErrInvalidClaimNameScript, str) + return nil, claimScriptError(ErrInvalidClaimNameScript, "expect OP_2DROP OP_DROP") } cs.Size = int(tokenizer.ByteIndex()) + if cs.Size > MaxClaimScriptSize { + str := fmt.Sprintf("script size %d exceeds limit %d", cs.Size, MaxClaimScriptSize) + return nil, claimScriptError(ErrInvalidClaimNameScript, str) + } + return &cs, nil case OP_SUPPORTCLAIM: @@ -128,8 +135,7 @@ func ExtractClaimScript(script []byte) (*ClaimScript, error) { case tokenizer.Opcode() == OP_2DROP: // Case 1: OP_SUPPORTCLAIM OP_2DROP OP_DROP if !tokenizer.Next() || tokenizer.Opcode() != OP_DROP { - str := fmt.Sprintf("expect OP_2DROP OP_DROP") - return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + return nil, claimScriptError(ErrInvalidClaimSupportScript, "expect OP_2DROP OP_DROP") } case len(tokenizer.Data()) != 0: @@ -138,19 +144,21 @@ func ExtractClaimScript(script []byte) (*ClaimScript, error) { cs.Value = tokenizer.Data() if !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP || !tokenizer.Next() || tokenizer.Opcode() != OP_2DROP { - str := fmt.Sprintf("expect OP_2DROP OP_2DROP") - return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + return nil, claimScriptError(ErrInvalidClaimSupportScript, "expect OP_2DROP OP_2DROP") } default: - str := fmt.Sprintf("expect OP_2DROP OP_DROP") - return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + return nil, claimScriptError(ErrInvalidClaimSupportScript, "expect OP_2DROP OP_DROP") } cs.Size = int(tokenizer.ByteIndex()) + if cs.Size > MaxClaimScriptSize { + str := fmt.Sprintf("script size %d exceeds limit %d", cs.Size, MaxClaimScriptSize) + return nil, claimScriptError(ErrInvalidClaimSupportScript, str) + } + return &cs, nil case OP_UPDATECLAIM: - // OP_UPDATECLAIM OP_2DROP OP_2DROP if !tokenizer.Next() || len(tokenizer.Data()) > MaxClaimNameSize { str := fmt.Sprintf("name size %d exceeds limit %d", len(tokenizer.data), MaxClaimNameSize) @@ -177,6 +185,11 @@ func ExtractClaimScript(script []byte) (*ClaimScript, error) { } cs.Size = int(tokenizer.ByteIndex()) + if cs.Size > MaxClaimScriptSize { + str := fmt.Sprintf("script size %d exceeds limit %d", cs.Size, MaxClaimScriptSize) + return nil, claimScriptError(ErrInvalidClaimUpdateScript, str) + } + return &cs, nil default: @@ -205,10 +218,11 @@ func AllClaimsAreSane(script []byte, enforceSoftFork bool) error { } if enforceSoftFork { if !utf8.Valid(cs.Name) { - return fmt.Errorf("claim name is not valid UTF-8") + return claimScriptError(ErrInvalidClaimName, "claim name is not valid UTF-8") } if bytes.ContainsAny(cs.Name, illegalChars) { - return fmt.Errorf("claim name has illegal chars; it should not contain any of these: %s", illegalChars) + str := fmt.Sprintf("claim name has illegal chars; it should not contain any of these: %s", illegalChars) + return claimScriptError(ErrInvalidClaimName, str) } } -- 2.45.2 From 2d04d31894586d69524d43b78e605239499032b2 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 19 Aug 2022 11:57:29 -0700 Subject: [PATCH 444/459] rpc: implement rescanblockchain rpcclient --- btcjson/walletsvrcmds.go | 19 +++++++++++++++++++ btcjson/walletsvrresults.go | 6 ++++++ rpcclient/wallet.go | 38 +++++++++++++++++++++++++++++++++++++ rpcserver.go | 1 + 4 files changed, 64 insertions(+) diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index cf77877a..bc1515f9 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -960,6 +960,24 @@ func NewImportMultiCmd(requests []ImportMultiRequest, options *ImportMultiOption } } +// RescanBlockchainCmd defines the RescanBlockchain JSON-RPC command. +type RescanBlockchainCmd struct { + StartHeight *int64 `jsonrpcdefault:"0"` + StopHeight *int64 `jsonrpcdefault:"0"` +} + +// NewRescanBlockchainCmd returns a new instance which can be used to issue +// an RescanBlockchain JSON-RPC command. +// +// The parameters which are pointers indicate they are optional. Passing nil +// for optional parameters will use the default value. +func NewRescanBlockchainCmd(startHeight *int64, stopHeight *int64) *RescanBlockchainCmd { + return &RescanBlockchainCmd{ + StartHeight: startHeight, + StopHeight: stopHeight, + } +} + // PsbtInput represents an input to include in the PSBT created by the // WalletCreateFundedPsbtCmd command. type PsbtInput struct { @@ -1081,6 +1099,7 @@ func init() { MustRegisterCmd("listunspent", (*ListUnspentCmd)(nil), flags) MustRegisterCmd("loadwallet", (*LoadWalletCmd)(nil), flags) MustRegisterCmd("lockunspent", (*LockUnspentCmd)(nil), flags) + MustRegisterCmd("rescanblockchain", (*RescanBlockchainCmd)(nil), flags) MustRegisterCmd("sendfrom", (*SendFromCmd)(nil), flags) MustRegisterCmd("sendmany", (*SendManyCmd)(nil), flags) MustRegisterCmd("sendtoaddress", (*SendToAddressCmd)(nil), flags) diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index 42402496..0c07ac1c 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -317,6 +317,12 @@ type ListUnspentResult struct { IsStake bool `json:"isstake"` } +// RescanBlockchainResult models the data returned from the rescanblockchain command. +type RescanBlockchainResult struct { + StartHeight int64 `json:"start_height"` + StoptHeight int64 `json:"stop_height"` +} + // SignRawTransactionError models the data that contains script verification // errors from the signrawtransaction request. type SignRawTransactionError struct { diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index bc4dd917..54a5c56f 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -2027,6 +2027,44 @@ func (c *Client) ListReceivedByAddressIncludeEmpty(minConfirms int, includeEmpty includeEmpty).Receive() } +// FutureRescanBlockchainResult is a future promise to deliver the error result of a +// RescanBlockchainAsync RPC invocation. +type FutureRescanBlockchainResult chan *Response + +// Receive waits for the Response promised by the future and returns the result +// of locking or unlocking the unspent output(s). +func (r FutureRescanBlockchainResult) Receive() (*btcjson.RescanBlockchainResult, error) { + res, err := ReceiveFuture(r) + if err != nil { + return nil, err + } + + // Unmarshal as an array of listreceivedbyaddress result objects. + var received btcjson.RescanBlockchainResult + err = json.Unmarshal(res, &received) + if err != nil { + return nil, err + } + + return &received, nil +} + +// RescanBlockchainAsync returns an instance of a type that can be used to get the +// result of the RPC at some future time by invoking the Receive function on the +// returned instance. +// +// See RescanBlockchain for the blocking version and more details. +func (c *Client) RescanBlockchainAsync(startHeight *int64, stopHeight *int64) FutureRescanBlockchainResult { + cmd := btcjson.NewRescanBlockchainCmd(startHeight, stopHeight) + return c.SendCmd(cmd) +} + +// RescanBlockchain rescans the local blockchain for wallet related +// transactions from the startHeight to the the inclusive stopHeight. +func (c *Client) RescanBlockchain(startHeight *int64, stopHeight *int64) (*btcjson.RescanBlockchainResult, error) { + return c.RescanBlockchainAsync(startHeight, stopHeight).Receive() +} + // ************************ // Wallet Locking Functions // ************************ diff --git a/rpcserver.go b/rpcserver.go index f02e347a..c9ca0eda 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -228,6 +228,7 @@ var rpcAskWallet = map[string]struct{}{ "listtransactions": {}, "listunspent": {}, "lockunspent": {}, + "rescanblockchain": {}, "sendfrom": {}, "sendmany": {}, "sendtoaddress": {}, -- 2.45.2 From 5d7a219e355e42e07d204bfa4767c83027c7f346 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 31 Aug 2022 18:00:47 -0700 Subject: [PATCH 445/459] rpc: make getblock return orphan blocks with confirmation=-1 --- blockchain/chain.go | 7 +++++-- rpcserver.go | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index 485c3e0b..b2690422 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1394,8 +1394,8 @@ func (b *BlockChain) BlockAttributesByHash(hash *chainhash.Hash, prevHash *chain attrs *BlockAttributes, best *BestState, err error) { best = b.BestSnapshot() node := b.index.LookupNode(hash) - if node == nil || !b.bestChain.Contains(node) { - str := fmt.Sprintf("block %s is not in the main chain", hash) + if node == nil { + str := fmt.Sprintf("block %s not found", hash) return nil, best, errNotInMainChain(str) } @@ -1405,6 +1405,9 @@ func (b *BlockChain) BlockAttributesByHash(hash *chainhash.Hash, prevHash *chain MedianTime: node.CalcPastMedianTime(), ChainWork: node.workSum, } + if !b.bestChain.Contains(node) { + attrs.Confirmations = -1 + } // Populate prev block hash if there is one. if node.height > 0 { diff --git a/rpcserver.go b/rpcserver.go index c9ca0eda..ab052bc4 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1211,7 +1211,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i if err != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCBlockNotFound, - Message: "Block not found", + Message: "Block not found: " + err.Error(), } } // If verbosity is 0, return the serialized block as a hex encoded string. -- 2.45.2 From 8a80f0683a3767f2e02c922e85af516ca60dacc9 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 1 Sep 2022 13:30:27 -0700 Subject: [PATCH 446/459] [lbry] policy: relax dust thrashold to 1000 dewies/kB An output is considered dust if the cost to the network to spend the coins is more than 1/3 of the minimum free transaction relay fee, which has a default rate of 1000 satoshis/kb bitcoind refactored dust threshold calculation, which removed the multiply factor of 3 from the code, but increased the DUST_RELAY_TX_FEE from 1000 to 3000 (satoshi/kb). lbrycrd adopted the refactored code but also kept the rate to 1000 dewies/kB, which means: An output is considered dust if the cost to the network to spend the coins is more than the minimum free transaction relay fee. --- mempool/policy.go | 6 +++--- mempool/policy_test.go | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mempool/policy.go b/mempool/policy.go index e91ce260..aa391c5d 100644 --- a/mempool/policy.go +++ b/mempool/policy.go @@ -249,7 +249,7 @@ func GetDustThreshold(txOut *wire.TxOut) int64 { totalSize += 107 } - return 3 * int64(totalSize) + return int64(totalSize) } // IsDust returns whether or not the passed transaction output amount is @@ -264,7 +264,7 @@ func IsDust(txOut *wire.TxOut, minRelayTxFee btcutil.Amount) bool { } // The output is considered dust if the cost to the network to spend the - // coins is more than 1/3 of the minimum free transaction relay fee. + // coins is more than the minimum free transaction relay fee. // minFreeTxRelayFee is in Satoshi/KB, so multiply by 1000 to // convert to bytes. // @@ -273,7 +273,7 @@ func IsDust(txOut *wire.TxOut, minRelayTxFee btcutil.Amount) bool { // fee of 1000, this equates to values less than 546 satoshi being // considered dust. // - // The following is equivalent to (value/totalSize) * (1/3) * 1000 + // The following is equivalent to (value/totalSize) * 1000 // without needing to do floating point math. if txOut.Value > dustCap { return false diff --git a/mempool/policy_test.go b/mempool/policy_test.go index 5e4d4ff0..aed2c4d7 100644 --- a/mempool/policy_test.go +++ b/mempool/policy_test.go @@ -233,14 +233,14 @@ func TestDust(t *testing.T) { true, }, { - "38 byte public key script with value 584", - wire.TxOut{Value: 584, PkScript: pkScript}, + "38 byte public key script with value 194", + wire.TxOut{Value: 194, PkScript: pkScript}, 1000, true, }, { - "38 byte public key script with value 585", - wire.TxOut{Value: 585, PkScript: pkScript}, + "38 byte public key script with value 195", + wire.TxOut{Value: 195, PkScript: pkScript}, 1000, false, }, -- 2.45.2 From c5193e74acec6630d5cc20bc6eb190211addd6cf Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 14 Sep 2022 18:27:18 -0700 Subject: [PATCH 447/459] rpc: support hex data output for createrawtransaction --- btcjson/chainsvrcmds.go | 6 +-- btcjson/chainsvrcmds_test.go | 37 ++++++++++---- rpcclient/rawtransactions.go | 19 +++++--- rpcserver.go | 94 ++++++++++++++++++++++++++---------- rpcserverhelp.go | 8 +-- 5 files changed, 115 insertions(+), 49 deletions(-) diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index 30024dda..d6263fff 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -67,7 +67,7 @@ type TransactionInput struct { // CreateRawTransactionCmd defines the createrawtransaction JSON-RPC command. type CreateRawTransactionCmd struct { Inputs []TransactionInput - Amounts map[string]float64 `jsonrpcusage:"{\"address\":amount,...}"` // In BTC + Outputs map[string]interface{} `jsonrpcusage:"{\"address\":amount, \"data\":\"hex\", ...}"` LockTime *int64 } @@ -76,7 +76,7 @@ type CreateRawTransactionCmd struct { // // Amounts are in BTC. Passing in nil and the empty slice as inputs is equivalent, // both gets interpreted as the empty slice. -func NewCreateRawTransactionCmd(inputs []TransactionInput, amounts map[string]float64, +func NewCreateRawTransactionCmd(inputs []TransactionInput, outputs map[string]interface{}, lockTime *int64) *CreateRawTransactionCmd { // to make sure we're serializing this to the empty list and not null, we // explicitly initialize the list @@ -85,7 +85,7 @@ func NewCreateRawTransactionCmd(inputs []TransactionInput, amounts map[string]fl } return &CreateRawTransactionCmd{ Inputs: inputs, - Amounts: amounts, + Outputs: outputs, LockTime: lockTime, } } diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index 824e87d7..4cdcb131 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -52,13 +52,13 @@ func TestChainSvrCmds(t *testing.T) { txInputs := []btcjson.TransactionInput{ {Txid: "123", Vout: 1}, } - amounts := map[string]float64{"456": .0123} - return btcjson.NewCreateRawTransactionCmd(txInputs, amounts, nil) + txOutputs := map[string]interface{}{"456": .0123} + return btcjson.NewCreateRawTransactionCmd(txInputs, txOutputs, nil) }, marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","params":[[{"txid":"123","vout":1}],{"456":0.0123}],"id":1}`, unmarshalled: &btcjson.CreateRawTransactionCmd{ Inputs: []btcjson.TransactionInput{{Txid: "123", Vout: 1}}, - Amounts: map[string]float64{"456": .0123}, + Outputs: map[string]interface{}{"456": .0123}, }, }, { @@ -67,13 +67,13 @@ func TestChainSvrCmds(t *testing.T) { return btcjson.NewCmd("createrawtransaction", `[]`, `{"456":0.0123}`) }, staticCmd: func() interface{} { - amounts := map[string]float64{"456": .0123} - return btcjson.NewCreateRawTransactionCmd(nil, amounts, nil) + txOutputs := map[string]interface{}{"456": .0123} + return btcjson.NewCreateRawTransactionCmd(nil, txOutputs, nil) }, marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","params":[[],{"456":0.0123}],"id":1}`, unmarshalled: &btcjson.CreateRawTransactionCmd{ Inputs: []btcjson.TransactionInput{}, - Amounts: map[string]float64{"456": .0123}, + Outputs: map[string]interface{}{"456": .0123}, }, }, { @@ -86,16 +86,35 @@ func TestChainSvrCmds(t *testing.T) { txInputs := []btcjson.TransactionInput{ {Txid: "123", Vout: 1}, } - amounts := map[string]float64{"456": .0123} - return btcjson.NewCreateRawTransactionCmd(txInputs, amounts, btcjson.Int64(12312333333)) + txOutputs := map[string]interface{}{"456": .0123} + return btcjson.NewCreateRawTransactionCmd(txInputs, txOutputs, btcjson.Int64(12312333333)) }, marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","params":[[{"txid":"123","vout":1}],{"456":0.0123},12312333333],"id":1}`, unmarshalled: &btcjson.CreateRawTransactionCmd{ Inputs: []btcjson.TransactionInput{{Txid: "123", Vout: 1}}, - Amounts: map[string]float64{"456": .0123}, + Outputs: map[string]interface{}{"456": .0123}, LockTime: btcjson.Int64(12312333333), }, }, + { + name: "createrawtransaction with data", + newCmd: func() (interface{}, error) { + return btcjson.NewCmd("createrawtransaction", `[{"txid":"123","vout":1}]`, + `{"data":"6a134920616d204672616374616c456e6372797074"}`) + }, + staticCmd: func() interface{} { + txInputs := []btcjson.TransactionInput{ + {Txid: "123", Vout: 1}, + } + txOutputs := map[string]interface{}{"data": "6a134920616d204672616374616c456e6372797074"} + return btcjson.NewCreateRawTransactionCmd(txInputs, txOutputs, nil) + }, + marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","params":[[{"txid":"123","vout":1}],{"data":"6a134920616d204672616374616c456e6372797074"}],"id":1}`, + unmarshalled: &btcjson.CreateRawTransactionCmd{ + Inputs: []btcjson.TransactionInput{{Txid: "123", Vout: 1}}, + Outputs: map[string]interface{}{"data": "6a134920616d204672616374616c456e6372797074"}, + }, + }, { name: "fundrawtransaction - empty opts", newCmd: func() (i interface{}, e error) { diff --git a/rpcclient/rawtransactions.go b/rpcclient/rawtransactions.go index e4402f1d..6d14d228 100644 --- a/rpcclient/rawtransactions.go +++ b/rpcclient/rawtransactions.go @@ -291,13 +291,18 @@ func (r FutureCreateRawTransactionResult) Receive() (*wire.MsgTx, error) { // // See CreateRawTransaction for the blocking version and more details. func (c *Client) CreateRawTransactionAsync(inputs []btcjson.TransactionInput, - amounts map[btcutil.Address]btcutil.Amount, lockTime *int64) FutureCreateRawTransactionResult { + outputs map[btcutil.Address]interface{}, lockTime *int64) FutureCreateRawTransactionResult { - convertedAmts := make(map[string]float64, len(amounts)) - for addr, amount := range amounts { - convertedAmts[addr.String()] = amount.ToBTC() + convertedData := make(map[string]interface{}, len(outputs)) + for key, value := range outputs { + switch val := value.(type) { + case btcutil.Amount: + convertedData[key.String()] = val.ToBTC() + case string: + convertedData[key.String()] = val + } } - cmd := btcjson.NewCreateRawTransactionCmd(inputs, convertedAmts, lockTime) + cmd := btcjson.NewCreateRawTransactionCmd(inputs, convertedData, lockTime) return c.SendCmd(cmd) } @@ -305,9 +310,9 @@ func (c *Client) CreateRawTransactionAsync(inputs []btcjson.TransactionInput, // and sending to the provided addresses. If the inputs are either nil or an // empty slice, it is interpreted as an empty slice. func (c *Client) CreateRawTransaction(inputs []btcjson.TransactionInput, - amounts map[btcutil.Address]btcutil.Amount, lockTime *int64) (*wire.MsgTx, error) { + outputs map[btcutil.Address]interface{}, lockTime *int64) (*wire.MsgTx, error) { - return c.CreateRawTransactionAsync(inputs, amounts, lockTime).Receive() + return c.CreateRawTransactionAsync(inputs, outputs, lockTime).Receive() } // FutureSendRawTransactionResult is a future promise to deliver the result diff --git a/rpcserver.go b/rpcserver.go index ab052bc4..742f65ab 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -327,6 +327,15 @@ func rpcDecodeHexError(gotHex string) *btcjson.RPCError { gotHex)) } +// rpcInvalidAddressOrKey is a convenience function for returning a nicely +// formatted RPC error which indicates the address or key is invalid. +func rpcInvalidAddressOrKeyError(addr string, msg string) *btcjson.RPCError { + return &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidAddressOrKey, + Message: msg, + } +} + // rpcNoTxInfoError is a convenience function for returning a nicely formatted // RPC error which indicates there is no information available for the provided // transaction hash. @@ -568,59 +577,92 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan // Add all transaction outputs to the transaction after performing // some validity checks. params := s.cfg.ChainParams - for encodedAddr, amount := range c.Amounts { - // Ensure amount is in the valid range for monetary amounts. - if amount <= 0 || amount*btcutil.SatoshiPerBitcoin > btcutil.MaxSatoshi { + + // Ensure amount is in the valid range for monetary amounts. + // Decode the provided address. + // Ensure the address is one of the supported types and that + // the network encoded with the address matches the network the + // server is currently on. + // Create a new script which pays to the provided address. + // Convert the amount to satoshi. + handleAmountFn := func(amount float64, encodedAddr string) (*wire.TxOut, + error) { + + if amount <= 0 || + amount*btcutil.SatoshiPerBitcoin > btcutil.MaxSatoshi { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCType, - Message: "Invalid amount", + Message: "invalid amount", } } - // Decode the provided address. addr, err := btcutil.DecodeAddress(encodedAddr, params) if err != nil { - return nil, &btcjson.RPCError{ - Code: btcjson.ErrRPCInvalidAddressOrKey, - Message: "Invalid address or key: " + err.Error(), - } + return nil, rpcInvalidAddressOrKeyError(encodedAddr, + "invalid address or key") } - // Ensure the address is one of the supported types and that - // the network encoded with the address matches the network the - // server is currently on. switch addr.(type) { case *btcutil.AddressPubKeyHash: case *btcutil.AddressScriptHash: default: - return nil, &btcjson.RPCError{ - Code: btcjson.ErrRPCInvalidAddressOrKey, - Message: "Invalid address or key: " + addr.String(), - } + return nil, rpcInvalidAddressOrKeyError(addr.String(), + "invalid address or key") } if !addr.IsForNet(params) { - return nil, &btcjson.RPCError{ - Code: btcjson.ErrRPCInvalidAddressOrKey, - Message: "Invalid address: " + encodedAddr + - " is for the wrong network", - } + return nil, rpcInvalidAddressOrKeyError(addr.String(), + "wrong network") } - // Create a new script which pays to the provided address. pkScript, err := txscript.PayToAddrScript(addr) if err != nil { - context := "Failed to generate pay-to-address script" + context := "failed to generate pay-to-address script" return nil, internalRPCError(err.Error(), context) } - // Convert the amount to satoshi. satoshi, err := btcutil.NewAmount(amount) if err != nil { - context := "Failed to convert amount" + context := "failed to convert amount" return nil, internalRPCError(err.Error(), context) } - txOut := wire.NewTxOut(int64(satoshi), pkScript) + return wire.NewTxOut(int64(satoshi), pkScript), nil + } + + handleDataFn := func(key string, value string) (*wire.TxOut, error) { + if key != "data" { + context := "output key must be an address or \"data\"" + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidParameter, + Message: context, + } + } + var data []byte + data, err := hex.DecodeString(value) + if err != nil { + return nil, rpcDecodeHexError(value) + } + return wire.NewTxOut(0, data), nil + } + + for key, value := range c.Outputs { + var err error + var txOut *wire.TxOut + switch value := value.(type) { + case float64: + txOut, err = handleAmountFn(value, key) + case string: + txOut, err = handleDataFn(key, value) + default: + context := "output value must be a string or float" + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCType, + Message: context, + } + } + if err != nil { + return nil, err + } mtx.AddTxOut(txOut) } diff --git a/rpcserverhelp.go b/rpcserverhelp.go index b7680783..44d92683 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -49,10 +49,10 @@ var helpDescsEnUS = map[string]string{ "The transaction inputs are not signed in the created transaction.\n" + "The signrawtransaction RPC command provided by wallet must be used to sign the resulting transaction.", "createrawtransaction-inputs": "The inputs to the transaction", - "createrawtransaction-amounts": "JSON object with the destination addresses as keys and amounts as values", - "createrawtransaction-amounts--key": "address", - "createrawtransaction-amounts--value": "n.nnn", - "createrawtransaction-amounts--desc": "The destination address as the key and the amount in LBC as the value", + "createrawtransaction-outputs": "JSON object with the destination addresses as keys and amounts as values", + "createrawtransaction-outputs--key": "address or \"data\"", + "createrawtransaction-outputs--value": "value in BTC as floating point number or hex-encoded data for \"data\"", + "createrawtransaction-outputs--desc": "The destination address as the key and the amount in LBC as the value", "createrawtransaction-locktime": "Locktime value; a non-zero value will also locktime-activate the inputs", "createrawtransaction--result0": "Hex-encoded bytes of the serialized transaction", -- 2.45.2 From 5acfa4c81b5f4c07ff5856870b439a0585a9e31d Mon Sep 17 00:00:00 2001 From: Guilherme de Paula Date: Tue, 3 Nov 2020 00:36:21 -0300 Subject: [PATCH 448/459] rpcserver: add GetBlockStats --- btcjson/chainsvrresults.go | 58 ++--- integration/rpcserver_test.go | 270 ++++++++++++++++++++++- rpcserver.go | 398 ++++++++++++++++++++++++++++++++++ rpcserverhelp.go | 38 ++++ 4 files changed, 735 insertions(+), 29 deletions(-) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index ad71dcd3..edc4b52e 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -35,35 +35,37 @@ type GetBlockHeaderVerboseResult struct { } // GetBlockStatsResult models the data from the getblockstats command. +// Pointers are used instead of values to allow for optional fields. type GetBlockStatsResult struct { - AverageFee int64 `json:"avgfee"` - AverageFeeRate int64 `json:"avgfeerate"` - AverageTxSize int64 `json:"avgtxsize"` - FeeratePercentiles []int64 `json:"feerate_percentiles"` - Hash string `json:"blockhash"` - Height int64 `json:"height"` - Ins int64 `json:"ins"` - MaxFee int64 `json:"maxfee"` - MaxFeeRate int64 `json:"maxfeerate"` - MaxTxSize int64 `json:"maxtxsize"` - MedianFee int64 `json:"medianfee"` - MedianTime int64 `json:"mediantime"` - MedianTxSize int64 `json:"mediantxsize"` - MinFee int64 `json:"minfee"` - MinFeeRate int64 `json:"minfeerate"` - MinTxSize int64 `json:"mintxsize"` - Outs int64 `json:"outs"` - SegWitTotalSize int64 `json:"swtotal_size"` - SegWitTotalWeight int64 `json:"swtotal_weight"` - SegWitTxs int64 `json:"swtxs"` - Subsidy int64 `json:"subsidy"` - Time int64 `json:"time"` - TotalOut int64 `json:"total_out"` - TotalSize int64 `json:"total_size"` - TotalWeight int64 `json:"total_weight"` - Txs int64 `json:"txs"` - UTXOIncrease int64 `json:"utxo_increase"` - UTXOSizeIncrease int64 `json:"utxo_size_inc"` + AverageFee *int64 `json:"avgfee,omitempty"` + AverageFeeRate *int64 `json:"avgfeerate,omitempty"` + AverageTxSize *int64 `json:"avgtxsize,omitempty"` + FeeratePercentiles *[]int64 `json:"feerate_percentiles,omitempty"` + Hash *string `json:"blockhash,omitempty"` + Height *int64 `json:"height,omitempty"` + Ins *int64 `json:"ins,omitempty"` + MaxFee *int64 `json:"maxfee,omitempty"` + MaxFeeRate *int64 `json:"maxfeerate,omitempty"` + MaxTxSize *int64 `json:"maxtxsize,omitempty"` + MedianFee *int64 `json:"medianfee,omitempty"` + MedianTime *int64 `json:"mediantime,omitempty"` + MedianTxSize *int64 `json:"mediantxsize,omitempty"` + MinFee *int64 `json:"minfee,omitempty"` + MinFeeRate *int64 `json:"minfeerate,omitempty"` + MinTxSize *int64 `json:"mintxsize,omitempty"` + Outs *int64 `json:"outs,omitempty"` + SegWitTotalSize *int64 `json:"swtotal_size,omitempty"` + SegWitTotalWeight *int64 `json:"swtotal_weight,omitempty"` + SegWitTxs *int64 `json:"swtxs,omitempty"` + Subsidy *int64 `json:"subsidy,omitempty"` + Time *int64 `json:"time,omitempty"` + TotalOut *int64 `json:"total_out,omitempty"` + TotalSize *int64 `json:"total_size,omitempty"` + TotalWeight *int64 `json:"total_weight,omitempty"` + TotalFee *int64 `json:"totalfee,omitempty"` + Txs *int64 `json:"txs,omitempty"` + UTXOIncrease *int64 `json:"utxo_increase,omitempty"` + UTXOSizeIncrease *int64 `json:"utxo_size_inc,omitempty"` } type GetBlockVerboseResultBase struct { diff --git a/integration/rpcserver_test.go b/integration/rpcserver_test.go index 2ed6b408..970454c7 100644 --- a/integration/rpcserver_test.go +++ b/integration/rpcserver_test.go @@ -13,7 +13,9 @@ import ( "fmt" "os" "runtime/debug" + "sort" "testing" + "time" "github.com/lbryio/lbcd/chaincfg" "github.com/lbryio/lbcd/chaincfg/chainhash" @@ -133,13 +135,278 @@ func testBulkClient(r *rpctest.Harness, t *testing.T) { t.Fatalf("expected hash %s to be in generated hash list", blockHash) } } +} +func testGetBlockStats(r *rpctest.Harness, t *testing.T) { + t.Parallel() + + baseFeeRate := int64(10) + txValue := int64(50000000) + txQuantity := 10 + txs := make([]*btcutil.Tx, txQuantity) + fees := make([]int64, txQuantity) + sizes := make([]int64, txQuantity) + feeRates := make([]int64, txQuantity) + var outputCount int + + // Generate test sample. + for i := 0; i < txQuantity; i++ { + address, err := r.NewAddress() + if err != nil { + t.Fatalf("Unable to generate address: %v", err) + } + + pkScript, err := txscript.PayToAddrScript(address) + if err != nil { + t.Fatalf("Unable to generate PKScript: %v", err) + } + + // This feerate is not the actual feerate. See comment below. + feeRate := baseFeeRate * int64(i) + + tx, err := r.CreateTransaction([]*wire.TxOut{wire.NewTxOut(txValue, pkScript)}, btcutil.Amount(feeRate), true) + if err != nil { + t.Fatalf("Unable to generate segwit transaction: %v", err) + } + + txs[i] = btcutil.NewTx(tx) + sizes[i] = int64(tx.SerializeSize()) + + // memWallet.fundTx makes some assumptions when calculating fees. + // For instance, it assumes the signature script has exactly 108 bytes + // and it does not account for the size of the change output. + // This needs to be taken into account when getting the true feerate. + scriptSigOffset := 108 - len(tx.TxIn[0].SignatureScript) + changeOutputSize := tx.TxOut[len(tx.TxOut)-1].SerializeSize() + fees[i] = (sizes[i] + int64(scriptSigOffset) - int64(changeOutputSize)) * feeRate + feeRates[i] = fees[i] / sizes[i] + + outputCount += len(tx.TxOut) + } + + stats := func(slice []int64) (int64, int64, int64, int64, int64) { + var total, average, min, max, median int64 + min = slice[0] + length := len(slice) + for _, item := range slice { + if min > item { + min = item + } + if max < item { + max = item + } + total += item + } + average = total / int64(length) + sort.Slice(slice, func(i, j int) bool { return slice[i] < slice[j] }) + if length == 0 { + median = 0 + } else if length%2 == 0 { + median = (slice[length/2-1] + slice[length/2]) / 2 + } else { + median = slice[length/2] + } + return total, average, min, max, median + } + + totalFee, avgFee, minFee, maxFee, medianFee := stats(fees) + totalSize, avgSize, minSize, maxSize, medianSize := stats(sizes) + _, avgFeeRate, minFeeRate, maxFeeRate, _ := stats(feeRates) + + tests := []struct { + name string + txs []*btcutil.Tx + stats []string + expectedResults map[string]interface{} + }{ + { + name: "empty block", + txs: []*btcutil.Tx{}, + stats: []string{}, + expectedResults: map[string]interface{}{ + "avgfee": int64(0), + "avgfeerate": int64(0), + "avgtxsize": int64(0), + "feerate_percentiles": []int64{0, 0, 0, 0, 0}, + "ins": int64(0), + "maxfee": int64(0), + "maxfeerate": int64(0), + "maxtxsize": int64(0), + "medianfee": int64(0), + "mediantxsize": int64(0), + "minfee": int64(0), + "mintxsize": int64(0), + "outs": int64(1), + "swtotal_size": int64(0), + "swtotal_weight": int64(0), + "swtxs": int64(0), + "total_out": int64(0), + "total_size": int64(0), + "total_weight": int64(0), + "txs": int64(1), + "utxo_increase": int64(1), + }, + }, + { + name: "block with 10 transactions + coinbase", + txs: txs, + stats: []string{"avgfee", "avgfeerate", "avgtxsize", "feerate_percentiles", + "ins", "maxfee", "maxfeerate", "maxtxsize", "medianfee", "mediantxsize", + "minfee", "minfeerate", "mintxsize", "outs", "subsidy", "swtxs", + "total_size", "total_weight", "totalfee", "txs", "utxo_increase"}, + expectedResults: map[string]interface{}{ + "avgfee": avgFee, + "avgfeerate": avgFeeRate, + "avgtxsize": avgSize, + "feerate_percentiles": []int64{feeRates[0], feeRates[2], + feeRates[4], feeRates[7], feeRates[8]}, + "ins": int64(txQuantity), + "maxfee": maxFee, + "maxfeerate": maxFeeRate, + "maxtxsize": maxSize, + "medianfee": medianFee, + "mediantxsize": medianSize, + "minfee": minFee, + "minfeerate": minFeeRate, + "mintxsize": minSize, + "outs": int64(outputCount + 1), // Coinbase output also counts. + "subsidy": int64(5000000000), + "swtotal_weight": nil, // This stat was not selected, so it should be nil. + "swtxs": int64(0), + "total_size": totalSize, + "total_weight": totalSize * 4, + "totalfee": totalFee, + "txs": int64(txQuantity + 1), // Coinbase transaction also counts. + "utxo_increase": int64(outputCount + 1 - txQuantity), + "utxo_size_inc": nil, + }, + }, + } + for _, test := range tests { + // Submit a new block with the provided transactions. + block, err := r.GenerateAndSubmitBlock(test.txs, -1, time.Time{}) + if err != nil { + t.Fatalf("Unable to generate block: %v from test %s", err, test.name) + } + + blockStats, err := r.Node.GetBlockStats(block.Hash(), &test.stats) + if err != nil { + t.Fatalf("Call to `getblockstats` on test %s failed: %v", test.name, err) + } + + if blockStats.Height != (*int64)(nil) && *blockStats.Height != int64(block.Height()) { + t.Fatalf("Unexpected result in test %s, stat: %v, expected: %v, got: %v", test.name, "height", block.Height(), *blockStats.Height) + } + + for stat, value := range test.expectedResults { + var result interface{} + switch stat { + case "avgfee": + result = blockStats.AverageFee + case "avgfeerate": + result = blockStats.AverageFeeRate + case "avgtxsize": + result = blockStats.AverageTxSize + case "feerate_percentiles": + result = blockStats.FeeratePercentiles + case "blockhash": + result = blockStats.Hash + case "height": + result = blockStats.Height + case "ins": + result = blockStats.Ins + case "maxfee": + result = blockStats.MaxFee + case "maxfeerate": + result = blockStats.MaxFeeRate + case "maxtxsize": + result = blockStats.MaxTxSize + case "medianfee": + result = blockStats.MedianFee + case "mediantime": + result = blockStats.MedianTime + case "mediantxsize": + result = blockStats.MedianTxSize + case "minfee": + result = blockStats.MinFee + case "minfeerate": + result = blockStats.MinFeeRate + case "mintxsize": + result = blockStats.MinTxSize + case "outs": + result = blockStats.Outs + case "swtotal_size": + result = blockStats.SegWitTotalSize + case "swtotal_weight": + result = blockStats.SegWitTotalWeight + case "swtxs": + result = blockStats.SegWitTxs + case "subsidy": + result = blockStats.Subsidy + case "time": + result = blockStats.Time + case "total_out": + result = blockStats.TotalOut + case "total_size": + result = blockStats.TotalSize + case "total_weight": + result = blockStats.TotalWeight + case "totalfee": + result = blockStats.TotalFee + case "txs": + result = blockStats.Txs + case "utxo_increase": + result = blockStats.UTXOIncrease + case "utxo_size_inc": + result = blockStats.UTXOSizeIncrease + } + + var equality bool + + // Check for nil equality. + if value == nil && result == (*int64)(nil) { + equality = true + break + } else if result == nil || value == nil { + equality = false + } + + var resultValue interface{} + switch v := value.(type) { + case int64: + resultValue = *result.(*int64) + equality = v == resultValue + case string: + resultValue = *result.(*string) + equality = v == resultValue + case []int64: + resultValue = *result.(*[]int64) + resultSlice := resultValue.([]int64) + equality = true + for i, item := range resultSlice { + if item != v[i] { + equality = false + break + } + } + } + if !equality { + if result != nil { + t.Fatalf("Unexpected result in test %s, stat: %v, expected: %v, got: %v", test.name, stat, value, resultValue) + } else { + t.Fatalf("Unexpected result in test %s, stat: %v, expected: %v, got: %v", test.name, stat, value, "") + } + } + + } + } } var rpcTestCases = []rpctest.HarnessTestCase{ testGetBestBlock, testGetBlockCount, testGetBlockHash, + testGetBlockStats, testBulkClient, } @@ -151,7 +418,8 @@ func TestMain(m *testing.M) { // In order to properly test scenarios on as if we were on mainnet, // ensure that non-standard transactions aren't accepted into the // mempool or relayed. - btcdCfg := []string{"--rejectnonstd"} + // Enable transaction index to be able to fully test GetBlockStats + btcdCfg := []string{"--rejectnonstd", "--txindex"} primaryHarness, err = rpctest.New( &chaincfg.SimNetParams, nil, btcdCfg, "", ) diff --git a/rpcserver.go b/rpcserver.go index 742f65ab..3cc71472 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -21,6 +21,7 @@ import ( "net" "net/http" "os" + "sort" "strconv" "strings" "sync" @@ -151,6 +152,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getblockcount": handleGetBlockCount, "getblockhash": handleGetBlockHash, "getblockheader": handleGetBlockHeader, + "getblockstats": handleGetBlockStats, "getblocktemplate": handleGetBlockTemplate, "getcfilter": handleGetCFilter, "getcfilterheader": handleGetCFilterHeader, @@ -1578,6 +1580,402 @@ func handleGetChainTips(s *rpcServer, cmd interface{}, closeChan <-chan struct{} return results, nil } +// handleGetBlockStats implements the getblockstats command. +func handleGetBlockStats(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + c := cmd.(*btcjson.GetBlockStatsCmd) + + // Check whether a block height or hash was provided. + blockHeight, ok := c.HashOrHeight.Value.(int) + var hash *chainhash.Hash + var err error + if ok { + // Block height was provided. + hash, err = s.cfg.Chain.BlockHashByHeight(int32(blockHeight)) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCOutOfRange, + Message: "Block number out of range", + } + } + } else { + // Block hash was provided. + hashString := c.HashOrHeight.Value.(string) + hash, err = chainhash.NewHashFromStr(hashString) + if err != nil { + return nil, rpcDecodeHexError(hashString) + } + + // Get the block height from chain. + blockHeightByHash, err := s.cfg.Chain.BlockHeightByHash(hash) + if err != nil { + context := "Failed to obtain block height" + return nil, internalRPCError(err.Error(), context) + } + blockHeight = int(blockHeightByHash) + } + + // Load block bytes from the database. + var blkBytes []byte + err = s.cfg.DB.View(func(dbTx database.Tx) error { + var err error + blkBytes, err = dbTx.FetchBlock(hash) + return err + }) + if err != nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCBlockNotFound, + Message: "Block not found", + } + } + + // Deserialize the block. + blk, err := btcutil.NewBlockFromBytes(blkBytes) + if err != nil { + context := "Failed to deserialize block" + return nil, internalRPCError(err.Error(), context) + } + + selectedStats := c.Stats + + // Create a set of selected stats to facilitate queries. + statsSet := make(map[string]bool) + for _, value := range *selectedStats { + statsSet[value] = true + } + + // Return all stats if an empty array was provided. + allStats := len(*selectedStats) == 0 + calcFees := statsSet["avgfee"] || statsSet["avgfeerate"] || statsSet["maxfee"] || statsSet["maxfeerate"] || + statsSet["medianfee"] || statsSet["totalfee"] || statsSet["feerate_percentiles"] + + if calcFees && s.cfg.TxIndex == nil { + return nil, &btcjson.RPCError{ + Code: btcjson.ErrRPCNoTxInfo, + Message: "The transaction index must be " + + "enabled to obtain fee statistics " + + "(specify --txindex)", + } + } + + txs := blk.Transactions() + txCount := len(txs) + var inputCount, outputCount int + var totalOutputValue int64 + + // Create a map of transaction statistics. + txStats := make([]map[string]interface{}, txCount) + for i, tx := range txs { + size := tx.MsgTx().SerializeSize() + witnessSize := size - tx.MsgTx().SerializeSizeStripped() + weight := int64(tx.MsgTx().SerializeSizeStripped()*4 + witnessSize) + + var fee, feeRate int64 + if (calcFees || allStats) && s.cfg.TxIndex != nil && !blockchain.IsCoinBaseTx(tx.MsgTx()) { + fee, err = calculateFee(tx, s.cfg.TxIndex, s.cfg.DB) + if err != nil { + context := "Failed to calculate fees" + return nil, internalRPCError(err.Error(), context) + } + if weight != 0 { + feeRate = fee * 4 / weight + } + } + segwit := tx.HasWitness() + txStats[i] = map[string]interface{}{"tx": tx, "fee": fee, "size": int64(size), + "feeRate": feeRate, "weight": weight, "segwit": segwit} + inputCount += len(tx.MsgTx().TxIn) + outputCount += len(tx.MsgTx().TxOut) + + // Coinbase is excluded from the total output. + if !blockchain.IsCoinBase(tx) { + for _, txOut := range tx.MsgTx().TxOut { + totalOutputValue += txOut.Value + } + } + } + + var totalFees, minFee, maxFee, minFeeRate, maxFeeRate, segwitCount, + segwitWeight, totalWeight, totalSize, minSize, maxSize, segwitSize int64 + if txCount > 1 { + minFee = txStats[1]["fee"].(int64) + minFeeRate = txStats[1]["feeRate"].(int64) + } + for i := 0; i < len(txStats); i++ { + var fee, feeRate int64 + tx := txStats[i]["tx"].(*btcutil.Tx) + if !blockchain.IsCoinBaseTx(tx.MsgTx()) { + // Fee statistics. + fee = txStats[i]["fee"].(int64) + feeRate = txStats[i]["feeRate"].(int64) + if minFee > fee { + minFee = fee + } + if maxFee < fee { + maxFee = fee + } + if minFeeRate > feeRate { + minFeeRate = feeRate + } + if maxFeeRate < feeRate { + maxFeeRate = feeRate + } + totalFees += txStats[i]["fee"].(int64) + + // Segwit statistics. + if txStats[i]["segwit"].(bool) { + segwitCount++ + segwitSize += txStats[i]["size"].(int64) + segwitWeight += txStats[i]["weight"].(int64) + } + + // Size statistics. + size := txStats[i]["size"].(int64) + if minSize == 0 { + minSize = size + } + if maxSize < size { + maxSize = size + } else if minSize > size { + minSize = size + } + totalSize += txStats[i]["size"].(int64) + + totalWeight += txStats[i]["weight"].(int64) + } + } + + var avgFee, avgFeeRate, avgSize int64 + if txCount > 1 { + avgFee = totalFees / int64(txCount-1) + } + if totalWeight != 0 { + avgFeeRate = totalFees * 4 / totalWeight + } + if txCount > 1 { + avgSize = totalSize / int64(txCount-1) + } + + subsidy := blockchain.CalcBlockSubsidy(int32(blockHeight), s.cfg.ChainParams) + + medianStat := func(stat string) int64 { + size := len(txStats) - 1 + if size == 0 { + return 0 + } + statArray := make([]int64, size) + // Start with the second element to ignore entry associated with coinbase. + for i, stats := range txStats[1:] { + statArray[i] = stats[stat].(int64) + } + sort.Slice(statArray, func(i, j int) bool { + return statArray[i] < statArray[j] + }) + if size%2 == 0 { + return (statArray[size/2-1] + statArray[size/2]) / 2 + } + return statArray[size/2] + } + + var medianFee int64 + if totalFees > 0 { + medianFee = medianStat("fee") + } else { + medianFee = 0 + } + medianSize := medianStat("size") + + // Calculate feerate percentiles. + var feeratePercentiles []int64 + if allStats || calcFees { + + // Sort by feerate. + sort.Slice(txStats, func(i, j int) bool { + return txStats[i]["feeRate"].(int64) < txStats[j]["feeRate"].(int64) + }) + totalWeight := float64(totalWeight) + + // Find 10th, 25th, 50th, 75th and 90th percentile weight units. + weights := []float64{ + totalWeight / 10, totalWeight / 4, totalWeight / 2, + (totalWeight * 3) / 4, (totalWeight * 9) / 10} + var cumulativeWeight int64 + feeratePercentiles = make([]int64, len(weights)) + nextPercentileIndex := 0 + for i := 0; i < len(txStats); i++ { + cumulativeWeight += txStats[i]["weight"].(int64) + for nextPercentileIndex < len(weights) && float64(cumulativeWeight) >= weights[nextPercentileIndex] { + feeratePercentiles[nextPercentileIndex] = txStats[i]["feeRate"].(int64) + nextPercentileIndex++ + } + } + + // Fill any remaining percentiles with the last value. + for i := nextPercentileIndex; i < len(weights); i++ { + feeratePercentiles[i] = txStats[len(txStats)-1]["feeRate"].(int64) + } + } + + var blockHash string + if allStats || statsSet["blockhash"] { + blockHash = blk.Hash().String() + } + + medianTime, err := medianBlockTime(blk.Hash(), s.cfg.Chain) + if err != nil { + context := "Failed to obtain block median time" + return nil, internalRPCError(err.Error(), context) + } + + resultMap := map[string]int64{ + "avgfee": avgFee, + "avgfeerate": avgFeeRate, + "avgtxsize": avgSize, + "height": int64(blockHeight), + "ins": int64(inputCount - 1), // Coinbase input is not included. + "maxfee": maxFee, + "maxfeerate": maxFeeRate, + "maxtxsize": maxSize, + "medianfee": medianFee, + "mediantime": medianTime.Unix(), + "mediantxsize": medianSize, + "minfee": minFee, + "minfeerate": minFeeRate, + "mintxsize": minSize, + "outs": int64(outputCount), + "swtotal_size": segwitSize, + "swtotal_weight": segwitWeight, + "swtxs": segwitCount, + "subsidy": subsidy, + "time": blk.MsgBlock().Header.Timestamp.Unix(), + "total_out": totalOutputValue, + "total_size": totalSize, + "total_weight": totalWeight, + "totalfee": totalFees, + "txs": int64(len(txs)), + "utxo_increase": int64(outputCount - (inputCount - 1)), + } + + // This function determines whether a statistic goes into the + // final result, except for blockhash and feerate_percentiles + // which are handled separately. + resultFilter := func(stat string) *int64 { + if allStats && s.cfg.TxIndex == nil { + // There are no fee statistics to send. + excludedStats := []string{"avgfee", "avgfeerate", "maxfee", "maxfeerate", "medianfee", "minfee", "minfeerate"} + for _, excluded := range excludedStats { + if stat == excluded { + return nil + } + } + } + if allStats || statsSet[stat] { + if value, ok := resultMap[stat]; ok { + return &value + } + } + return nil + } + + result := &btcjson.GetBlockStatsResult{ + AverageFee: resultFilter("avgfee"), + AverageFeeRate: resultFilter("avgfeerate"), + AverageTxSize: resultFilter("avgtxsize"), + FeeratePercentiles: &feeratePercentiles, + Hash: &blockHash, + Height: resultFilter("height"), + Ins: resultFilter("ins"), + MaxFee: resultFilter("maxfee"), + MaxFeeRate: resultFilter("maxfeerate"), + MaxTxSize: resultFilter("maxtxsize"), + MedianFee: resultFilter("medianfee"), + MedianTime: resultFilter("mediantime"), + MedianTxSize: resultFilter("mediantxsize"), + MinFee: resultFilter("minfee"), + MinFeeRate: resultFilter("minfeerate"), + MinTxSize: resultFilter("mintxsize"), + Outs: resultFilter("outs"), + SegWitTotalSize: resultFilter("swtotal_size"), + SegWitTotalWeight: resultFilter("swtotal_weight"), + SegWitTxs: resultFilter("swtxs"), + Subsidy: resultFilter("subsidy"), + Time: resultFilter("time"), + TotalOut: resultFilter("total_out"), + TotalSize: resultFilter("total_size"), + TotalWeight: resultFilter("total_weight"), + TotalFee: resultFilter("totalfee"), + Txs: resultFilter("txs"), + UTXOIncrease: resultFilter("utxo_increase"), + UTXOSizeIncrease: resultFilter("utxo_size_inc"), + } + return result, nil +} + +// calculateFee returns the fee of a transaction. +func calculateFee(tx *btcutil.Tx, txIndex *indexers.TxIndex, db database.DB) (int64, error) { + var inValue, outValue int64 + for _, input := range tx.MsgTx().TxIn { + prevTxHash := input.PreviousOutPoint.Hash + // Look up the location of the previous transaction in the index. + blockRegion, err := txIndex.TxBlockRegion(&prevTxHash) + if err != nil { + context := "Failed to retrieve transaction location" + return 0, internalRPCError(err.Error(), context) + } + if blockRegion == nil { + return 0, rpcNoTxInfoError(&prevTxHash) + } + + // Load the raw transaction bytes from the database. + var txBytes []byte + err = db.View(func(dbTx database.Tx) error { + var err error + txBytes, err = dbTx.FetchBlockRegion(blockRegion) + return err + }) + if err != nil { + return 0, rpcNoTxInfoError(&prevTxHash) + } + + var msgTx wire.MsgTx + err = msgTx.Deserialize(bytes.NewReader(txBytes)) + if err != nil { + context := "Failed to deserialize transaction" + return 0, internalRPCError(err.Error(), context) + } + prevOutValue := msgTx.TxOut[input.PreviousOutPoint.Index].Value + inValue += prevOutValue + } + for _, output := range tx.MsgTx().TxOut { + outValue += output.Value + } + fee := inValue - outValue + return fee, nil +} + +// medianBlockTime returns the median time of a block and its 10 previous blocks +// as per BIP113. +func medianBlockTime(blockHash *chainhash.Hash, chain *blockchain.BlockChain) (*time.Time, error) { + blockTimes := make([]time.Time, 0) + currentHash := blockHash + for i := 0; i < 11; i++ { + header, err := chain.HeaderByHash(currentHash) + if err != nil { + return nil, err + } + blockTimes = append(blockTimes, header.Timestamp) + genesisPrevBlock, _ := chainhash.NewHashFromStr("0000000000000000000000000000000000000000000000000000000000000000") + if header.PrevBlock.IsEqual(genesisPrevBlock) { + // This is the genesis block so there's no need to iterate further. + break + } + currentHash = &header.PrevBlock + } + sort.Slice(blockTimes, func(i, j int) bool { + return blockTimes[i].Before(blockTimes[j]) + }) + return &blockTimes[len(blockTimes)/2], nil +} + // encodeTemplateID encodes the passed details into an ID that can be used to // uniquely identify a block template. func encodeTemplateID(prevHash *chainhash.Hash, lastGenerated time.Time) string { diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 44d92683..06dbba53 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -200,6 +200,43 @@ var helpDescsEnUS = map[string]string{ "getblockchaininforesult-softforks": "The status of the super-majority soft-forks", "getblockchaininforesult-unifiedsoftforks": "The status of the super-majority soft-forks used by bitcoind on or after v0.19.0", + // GetBlockStatsCmd help. + "getblockstats--synopsis": "Returns statistics about a block given its hash or height. --txindex must be enabled for fee and feerate statistics.", + "getblockstats-hashorheight": "The hash or height of the block", + "hashorheight-value": "The hash or height of the block", + "getblockstats-stats": "Selected statistics", + + // GetBlockStatsResult help. + "getblockstatsresult-avgfee": "The average fee in the block", + "getblockstatsresult-avgfeerate": "The average feerate in the block (in satoshis per virtual byte)", + "getblockstatsresult-avgtxsize": "The average transaction size in the block", + "getblockstatsresult-blockhash": "The block hash", + "getblockstatsresult-feerate_percentiles": "Feerates at the 10th, 25th, 50th, 75th, and 90th percentile weight unit (in satoshis per virtual byte)", + "getblockstatsresult-height": "The block height", + "getblockstatsresult-ins": "The number of inputs (excluding coinbase)", + "getblockstatsresult-maxfee": "Maxium fee in the block", + "getblockstatsresult-maxfeerate": "Maximum feerate in the block (in satoshis per virtual byte)", + "getblockstatsresult-maxtxsize": "Maximum transaction size", + "getblockstatsresult-medianfee": "Truncated median fee", + "getblockstatsresult-mediantime": "The median time from the block and its previous 10 blocks (BIP113)", + "getblockstatsresult-mediantxsize": "Truncated median transaction size", + "getblockstatsresult-minfee": "Minimum fee in the block", + "getblockstatsresult-minfeerate": "Minimum feerate in the block (in satoshis per virtual byte)", + "getblockstatsresult-mintxsize": "Minimum transaction size", + "getblockstatsresult-outs": "The number of outputs", + "getblockstatsresult-subsidy": "The block subsidy", + "getblockstatsresult-swtotal_size": "Total size of all segwit transactions in the block (excluding coinbase)", + "getblockstatsresult-swtotal_weight": "Total weight of all segwit transactions in the block (excluding coinbase)", + "getblockstatsresult-swtxs": "The number of segwit transactions in the block (excluding coinbase)", + "getblockstatsresult-time": "The block time", + "getblockstatsresult-total_out": "Total amount in all outputs (excluding coinbase)", + "getblockstatsresult-total_size": "Total size of all transactions (excluding coinbase)", + "getblockstatsresult-total_weight": "Total weight of all transactions (excluding coinbase)", + "getblockstatsresult-totalfee": "The total of fees", + "getblockstatsresult-txs": "The number of transactions (excluding coinbase)", + "getblockstatsresult-utxo_increase": "The increase/decrease in the number of unspent outputs", + "getblockstatsresult-utxo_size_inc": "The increase/decrease in size for the utxo index", + // SoftForkDescription help. "softforkdescription-reject": "The current activation status of the softfork", "softforkdescription-version": "The block version that signals enforcement of this softfork", @@ -917,6 +954,7 @@ var rpcResultTypes = map[string][]interface{}{ "getblockcount": {(*int64)(nil)}, "getblockhash": {(*string)(nil)}, "getblockheader": {(*string)(nil), (*btcjson.GetBlockHeaderVerboseResult)(nil)}, + "getblockstats": {(*btcjson.GetBlockStatsResult)(nil)}, "getblocktemplate": {(*btcjson.GetBlockTemplateResult)(nil), (*string)(nil), nil}, "getcfilter": {(*string)(nil)}, "getcfilterheader": {(*string)(nil)}, -- 2.45.2 From 81ec217899796e85cd68b57c46c34173477179aa Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Tue, 20 Sep 2022 23:39:34 -0700 Subject: [PATCH 449/459] rpcserver: fix up getblockstats --- integration/rpcserver_test.go | 17 ++++++++++------- integration/rpctest/rpc_harness.go | 13 +++++++++++++ rpcserver.go | 9 ++++++--- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/integration/rpcserver_test.go b/integration/rpcserver_test.go index 970454c7..5f59b594 100644 --- a/integration/rpcserver_test.go +++ b/integration/rpcserver_test.go @@ -21,6 +21,9 @@ import ( "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/integration/rpctest" "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/txscript" + "github.com/lbryio/lbcd/wire" + "github.com/lbryio/lbcutil" ) func testGetBestBlock(r *rpctest.Harness, t *testing.T) { @@ -143,7 +146,7 @@ func testGetBlockStats(r *rpctest.Harness, t *testing.T) { baseFeeRate := int64(10) txValue := int64(50000000) txQuantity := 10 - txs := make([]*btcutil.Tx, txQuantity) + txs := make([]*lbcutil.Tx, txQuantity) fees := make([]int64, txQuantity) sizes := make([]int64, txQuantity) feeRates := make([]int64, txQuantity) @@ -164,12 +167,12 @@ func testGetBlockStats(r *rpctest.Harness, t *testing.T) { // This feerate is not the actual feerate. See comment below. feeRate := baseFeeRate * int64(i) - tx, err := r.CreateTransaction([]*wire.TxOut{wire.NewTxOut(txValue, pkScript)}, btcutil.Amount(feeRate), true) + tx, err := r.CreateTransaction([]*wire.TxOut{wire.NewTxOut(txValue, pkScript)}, lbcutil.Amount(feeRate), true) if err != nil { t.Fatalf("Unable to generate segwit transaction: %v", err) } - txs[i] = btcutil.NewTx(tx) + txs[i] = lbcutil.NewTx(tx) sizes[i] = int64(tx.SerializeSize()) // memWallet.fundTx makes some assumptions when calculating fees. @@ -215,13 +218,13 @@ func testGetBlockStats(r *rpctest.Harness, t *testing.T) { tests := []struct { name string - txs []*btcutil.Tx + txs []*lbcutil.Tx stats []string expectedResults map[string]interface{} }{ { name: "empty block", - txs: []*btcutil.Tx{}, + txs: []*lbcutil.Tx{}, stats: []string{}, expectedResults: map[string]interface{}{ "avgfee": int64(0), @@ -270,7 +273,7 @@ func testGetBlockStats(r *rpctest.Harness, t *testing.T) { "minfeerate": minFeeRate, "mintxsize": minSize, "outs": int64(outputCount + 1), // Coinbase output also counts. - "subsidy": int64(5000000000), + "subsidy": int64(100000000), "swtotal_weight": nil, // This stat was not selected, so it should be nil. "swtxs": int64(0), "total_size": totalSize, @@ -289,7 +292,7 @@ func testGetBlockStats(r *rpctest.Harness, t *testing.T) { t.Fatalf("Unable to generate block: %v from test %s", err, test.name) } - blockStats, err := r.Node.GetBlockStats(block.Hash(), &test.stats) + blockStats, err := r.GetBlockStats(block.Hash(), &test.stats) if err != nil { t.Fatalf("Call to `getblockstats` on test %s failed: %v", test.name, err) } diff --git a/integration/rpctest/rpc_harness.go b/integration/rpctest/rpc_harness.go index 17603aa7..4bd72f9c 100644 --- a/integration/rpctest/rpc_harness.go +++ b/integration/rpctest/rpc_harness.go @@ -16,6 +16,7 @@ import ( "testing" "time" + "github.com/lbryio/lbcd/btcjson" "github.com/lbryio/lbcd/chaincfg" "github.com/lbryio/lbcd/chaincfg/chainhash" "github.com/lbryio/lbcd/rpcclient" @@ -512,6 +513,18 @@ func (h *Harness) GenerateAndSubmitBlockWithCustomCoinbaseOutputs( return newBlock, nil } +// GetBlockStats returns block statistics. First argument specifies height or +// hash of the target block. Second argument allows to select certain stats to +// return. If second argument is empty, all stats are returned. +func (h *Harness) GetBlockStats(hashOrHeight interface{}, stats *[]string) ( + *btcjson.GetBlockStatsResult, error) { + + h.Lock() + defer h.Unlock() + + return h.Client.GetBlockStats(hashOrHeight, stats) +} + // generateListeningAddresses returns two strings representing listening // addresses designated for the current rpc test. If there haven't been any // test instances created, the default ports are used. Otherwise, in order to diff --git a/rpcserver.go b/rpcserver.go index 3cc71472..28b0f670 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1635,16 +1635,19 @@ func handleGetBlockStats(s *rpcServer, cmd interface{}, closeChan <-chan struct{ return nil, internalRPCError(err.Error(), context) } - selectedStats := c.Stats + var selectedStats []string + if c.Stats != nil { + selectedStats = *c.Stats + } // Create a set of selected stats to facilitate queries. statsSet := make(map[string]bool) - for _, value := range *selectedStats { + for _, value := range selectedStats { statsSet[value] = true } // Return all stats if an empty array was provided. - allStats := len(*selectedStats) == 0 + allStats := len(selectedStats) == 0 calcFees := statsSet["avgfee"] || statsSet["avgfeerate"] || statsSet["maxfee"] || statsSet["maxfeerate"] || statsSet["medianfee"] || statsSet["totalfee"] || statsSet["feerate_percentiles"] -- 2.45.2 From 2adfcd211da7a75dcdfa7d7917e2dfa40e332f3b Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 23 Sep 2022 17:48:05 -0700 Subject: [PATCH 450/459] rpcclient: add -quiet option to the lbcdblocknotify example --- rpcclient/examples/lbcdblocknotify/README.md | 2 ++ rpcclient/examples/lbcdblocknotify/main.go | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rpcclient/examples/lbcdblocknotify/README.md b/rpcclient/examples/lbcdblocknotify/README.md index 45ab3b29..55fc19b0 100644 --- a/rpcclient/examples/lbcdblocknotify/README.md +++ b/rpcclient/examples/lbcdblocknotify/README.md @@ -29,6 +29,8 @@ $ go run . -h Stratum server (default "lbrypool.net:3334") -stratumpass string Stratum server password (default "password") + -quiet + Do not print logs ``` Start the program: diff --git a/rpcclient/examples/lbcdblocknotify/main.go b/rpcclient/examples/lbcdblocknotify/main.go index af538642..9b672a59 100644 --- a/rpcclient/examples/lbcdblocknotify/main.go +++ b/rpcclient/examples/lbcdblocknotify/main.go @@ -30,13 +30,16 @@ var ( rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password") notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled") run = flag.String("run", "", "Run custom shell command") + quiet = flag.Bool("quiet", false, "Do not print logs") ) func onFilteredBlockConnected(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) { blockHash := header.BlockHash().String() - log.Printf("Block connected: %v (%d) %v", blockHash, height, header.Timestamp) + if !*quiet { + log.Printf("Block connected: %v (%d) %v", blockHash, height, header.Timestamp) + } if cmd := *run; len(cmd) != 0 { cmd = strings.ReplaceAll(cmd, "%s", blockHash) -- 2.45.2 From 9bcd3d059179aad0c204d55cf528c8cc47722496 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Fri, 23 Sep 2022 17:49:01 -0700 Subject: [PATCH 451/459] cotrib: add a helper script to show miner of a bkock --- contrib/showminer.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100755 contrib/showminer.sh diff --git a/contrib/showminer.sh b/contrib/showminer.sh new file mode 100755 index 00000000..9ee52624 --- /dev/null +++ b/contrib/showminer.sh @@ -0,0 +1,42 @@ +#! /bin/bash + +read -r -d '' help << EOM +$0 - helper script for displaying miner of a mined block. + +Options: + + -h Display this message. + + --height Specify blockheight. + --hash Specify blockhash. +EOM + +while getopts ":h-:" optchar; do + case "${optchar}" in + -) + case "${OPTARG}" in + hash) + blockhash="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 )) + ;; + height) + blockheight="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 )) + blockhash=$(lbcctl getblockhash ${blockheight}) + ;; + *) echo "Unknown long option --${OPTARG}" >&2; exit -2 ;; + esac + ;; + h) printf "${help}\n\n"; exit 2;; + *) echo "Unknown option -${OPTARG}" >&2; exit -2;; + esac +done + + +block=$(lbcctl getblock $blockhash) +blockheight=$(lbcctl getblock $blockhash | jq -r .height) + +coinbase_txid=$(echo ${block} | jq -r '.tx[0]') +coinbase_raw=$(lbcctl getrawtransaction ${coinbase_txid} 1) +coinbase=$(echo ${coinbase_raw} | jq '.vin[0].coinbase') +miner=$(echo ${coinbase} | grep -o '2f.*2f' | xxd -r -p | strings) + +echo ${blockheight}: ${blockhash}: ${miner} -- 2.45.2 From 6bc9a2b4dd9685284a8d0ec5b88cdf6573755daf Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 25 Sep 2022 18:38:41 -0700 Subject: [PATCH 452/459] mining: always returns .coinbasevalue in getblocktemplate Although the BIPs specify that coinbasetxn and coinbasevalue are mutually exclusive, both the latest bitcoind (22.0.0) and lbrycrd (0.17.3) return .coinbasevalue regardeless if 'coinbasetxn' is specified in the capabilities. We'll make lbcd behave the same for compatibility. --- rpcserver.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rpcserver.go b/rpcserver.go index 28b0f670..359f8f2c 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -2368,7 +2368,6 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld if useCoinbaseValue { reply.CoinbaseAux = gbtCoinbaseAux - reply.CoinbaseValue = &msgBlock.Transactions[0].TxOut[0].Value } else { // Ensure the template has a valid payment address associated // with it when a full coinbase is requested. @@ -2401,6 +2400,9 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld reply.CoinbaseTxn = &resultTx } + // Return coinbasevalue anyway as lbrycrd and bitcoind do. + reply.CoinbaseValue = &msgBlock.Transactions[0].TxOut[0].Value + return &reply, nil } -- 2.45.2 From 987a533423148ea271aceed7c212c8c8319528da Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Mon, 22 Aug 2022 16:39:48 -0700 Subject: [PATCH 453/459] rpc: update rpc cmd requests to support multi-account Most of the updates add optional arguments with default values. --- btcjson/walletsvrcmds.go | 71 +++++++------ btcjson/walletsvrcmds_test.go | 173 +++++++++++++++++++++++--------- btcjson/walletsvrresults.go | 2 +- btcjson/walletsvrwscmds.go | 6 +- btcjson/walletsvrwscmds_test.go | 8 +- rpcclient/wallet.go | 94 +++++++++-------- 6 files changed, 226 insertions(+), 128 deletions(-) diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index bc1515f9..56369a82 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -176,12 +176,13 @@ func NewGetAccountCmd(address string) *GetAccountCmd { // GetAccountAddressCmd defines the getaccountaddress JSON-RPC command. type GetAccountAddressCmd struct { - Account string + Account *string `jsonrpcdefault:"\"default\""` + AddressType *string `jsonrpcdefault:"\"legacy\""` } // NewGetAccountAddressCmd returns a new instance which can be used to issue a // getaccountaddress JSON-RPC command. -func NewGetAccountAddressCmd(account string) *GetAccountAddressCmd { +func NewGetAccountAddressCmd(account *string) *GetAccountAddressCmd { return &GetAccountAddressCmd{ Account: account, } @@ -189,12 +190,13 @@ func NewGetAccountAddressCmd(account string) *GetAccountAddressCmd { // GetAddressesByAccountCmd defines the getaddressesbyaccount JSON-RPC command. type GetAddressesByAccountCmd struct { - Account string + Account *string `jsonrpcdefault:"\"default\""` + AddressType *string `jsonrpcdefault:"\"*\""` } // NewGetAddressesByAccountCmd returns a new instance which can be used to issue // a getaddressesbyaccount JSON-RPC command. -func NewGetAddressesByAccountCmd(account string) *GetAddressesByAccountCmd { +func NewGetAddressesByAccountCmd(account *string) *GetAddressesByAccountCmd { return &GetAddressesByAccountCmd{ Account: account, } @@ -215,8 +217,9 @@ func NewGetAddressInfoCmd(address string) *GetAddressInfoCmd { // GetBalanceCmd defines the getbalance JSON-RPC command. type GetBalanceCmd struct { - Account *string - MinConf *int `jsonrpcdefault:"1"` + Account *string `jsonrpcdefault:"\"default\""` + MinConf *int `jsonrpcdefault:"1"` + AddressType *string `jsonrpcdefault:"\"*\""` } // NewGetBalanceCmd returns a new instance which can be used to issue a @@ -242,8 +245,8 @@ func NewGetBalancesCmd() *GetBalancesCmd { // GetNewAddressCmd defines the getnewaddress JSON-RPC command. type GetNewAddressCmd struct { - Account *string - AddressType *string // must be one of legacy / p2pkh or p2sh-p2wkh / p2sh-segwit, or p2wkh / bech32 + Account *string `jsonrpcdefault:"\"default\""` + AddressType *string `jsonrpcdefault:"\"legacy\""` } // NewGetNewAddressCmd returns a new instance which can be used to issue a @@ -259,7 +262,8 @@ func NewGetNewAddressCmd(account *string) *GetNewAddressCmd { // GetRawChangeAddressCmd defines the getrawchangeaddress JSON-RPC command. type GetRawChangeAddressCmd struct { - Account *string + Account *string `jsonrpcdefault:"\"default\""` + AddressType *string `jsonrpcdefault:"\"legacy\""` } // NewGetRawChangeAddressCmd returns a new instance which can be used to issue a @@ -275,8 +279,8 @@ func NewGetRawChangeAddressCmd(account *string) *GetRawChangeAddressCmd { // GetReceivedByAccountCmd defines the getreceivedbyaccount JSON-RPC command. type GetReceivedByAccountCmd struct { - Account string - MinConf *int `jsonrpcdefault:"1"` + Account *string `jsonrpcdefault:"\"default\""` + MinConf *int `jsonrpcdefault:"1"` } // NewGetReceivedByAccountCmd returns a new instance which can be used to issue @@ -284,7 +288,7 @@ type GetReceivedByAccountCmd struct { // // The parameters which are pointers indicate they are optional. Passing nil // for optional parameters will use the default value. -func NewGetReceivedByAccountCmd(account string, minConf *int) *GetReceivedByAccountCmd { +func NewGetReceivedByAccountCmd(account *string, minConf *int) *GetReceivedByAccountCmd { return &GetReceivedByAccountCmd{ Account: account, MinConf: minConf, @@ -407,7 +411,8 @@ func NewKeyPoolRefillCmd(newSize *uint) *KeyPoolRefillCmd { // ListAccountsCmd defines the listaccounts JSON-RPC command. type ListAccountsCmd struct { - MinConf *int `jsonrpcdefault:"1"` + MinConf *int `jsonrpcdefault:"1"` + AddressType *string `jsonrpcdefault:"\"*\""` } // NewListAccountsCmd returns a new instance which can be used to issue a @@ -501,10 +506,10 @@ func NewListSinceBlockCmd(blockHash *string, targetConfirms *int, includeWatchOn // ListTransactionsCmd defines the listtransactions JSON-RPC command. type ListTransactionsCmd struct { - Account *string - Count *int `jsonrpcdefault:"10"` - From *int `jsonrpcdefault:"0"` - IncludeWatchOnly *bool `jsonrpcdefault:"false"` + Account *string `jsonrpcdefault:"\"default\""` + Count *int `jsonrpcdefault:"10"` + From *int `jsonrpcdefault:"0"` + IncludeWatchOnly *bool `jsonrpcdefault:"false"` } // NewListTransactionsCmd returns a new instance which can be used to issue a @@ -562,6 +567,7 @@ type SendFromCmd struct { ToAddress string Amount float64 // In BTC MinConf *int `jsonrpcdefault:"1"` + AddressType *string `jsonrpcdefault:"\"*\""` Comment *string CommentTo *string } @@ -571,12 +577,15 @@ type SendFromCmd struct { // // The parameters which are pointers indicate they are optional. Passing nil // for optional parameters will use the default value. -func NewSendFromCmd(fromAccount, toAddress string, amount float64, minConf *int, comment, commentTo *string) *SendFromCmd { +func NewSendFromCmd(fromAccount, toAddress string, amount float64, + minConf *int, addrType *string, comment, commentTo *string) *SendFromCmd { + return &SendFromCmd{ FromAccount: fromAccount, ToAddress: toAddress, Amount: amount, MinConf: minConf, + AddressType: addrType, Comment: comment, CommentTo: commentTo, } @@ -587,6 +596,7 @@ type SendManyCmd struct { FromAccount string Amounts map[string]float64 `jsonrpcusage:"{\"address\":amount,...}"` // In BTC MinConf *int `jsonrpcdefault:"1"` + AddressType *string `jsonrpcdefault:"\"*\""` Comment *string } @@ -595,21 +605,24 @@ type SendManyCmd struct { // // The parameters which are pointers indicate they are optional. Passing nil // for optional parameters will use the default value. -func NewSendManyCmd(fromAccount string, amounts map[string]float64, minConf *int, comment *string) *SendManyCmd { +func NewSendManyCmd(fromAccount string, amounts map[string]float64, + minConf *int, addrType *string, comment *string) *SendManyCmd { return &SendManyCmd{ FromAccount: fromAccount, Amounts: amounts, MinConf: minConf, + AddressType: addrType, Comment: comment, } } // SendToAddressCmd defines the sendtoaddress JSON-RPC command. type SendToAddressCmd struct { - Address string - Amount float64 - Comment *string - CommentTo *string + Address string + Amount float64 + AddressType *string `jsonrpcdefault:"\"*\""` + Comment *string + CommentTo *string } // NewSendToAddressCmd returns a new instance which can be used to issue a @@ -617,12 +630,14 @@ type SendToAddressCmd struct { // // The parameters which are pointers indicate they are optional. Passing nil // for optional parameters will use the default value. -func NewSendToAddressCmd(address string, amount float64, comment, commentTo *string) *SendToAddressCmd { +func NewSendToAddressCmd(address string, amount float64, addrType *string, + comment, commentTo *string) *SendToAddressCmd { return &SendToAddressCmd{ - Address: address, - Amount: amount, - Comment: comment, - CommentTo: commentTo, + Address: address, + Amount: amount, + AddressType: addrType, + Comment: comment, + CommentTo: commentTo, } } diff --git a/btcjson/walletsvrcmds_test.go b/btcjson/walletsvrcmds_test.go index e19adf6c..b4b976d4 100644 --- a/btcjson/walletsvrcmds_test.go +++ b/btcjson/walletsvrcmds_test.go @@ -287,11 +287,12 @@ func TestWalletSvrCmds(t *testing.T) { return btcjson.NewCmd("getaccountaddress", "acct") }, staticCmd: func() interface{} { - return btcjson.NewGetAccountAddressCmd("acct") + return btcjson.NewGetAccountAddressCmd(btcjson.String("acct")) }, marshalled: `{"jsonrpc":"1.0","method":"getaccountaddress","params":["acct"],"id":1}`, unmarshalled: &btcjson.GetAccountAddressCmd{ - Account: "acct", + Account: btcjson.String("acct"), + AddressType: btcjson.String("legacy"), }, }, { @@ -300,11 +301,12 @@ func TestWalletSvrCmds(t *testing.T) { return btcjson.NewCmd("getaddressesbyaccount", "acct") }, staticCmd: func() interface{} { - return btcjson.NewGetAddressesByAccountCmd("acct") + return btcjson.NewGetAddressesByAccountCmd(btcjson.String("acct")) }, marshalled: `{"jsonrpc":"1.0","method":"getaddressesbyaccount","params":["acct"],"id":1}`, unmarshalled: &btcjson.GetAddressesByAccountCmd{ - Account: "acct", + Account: btcjson.String("acct"), + AddressType: btcjson.String("*"), }, }, { @@ -330,8 +332,9 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"getbalance","params":[],"id":1}`, unmarshalled: &btcjson.GetBalanceCmd{ - Account: nil, - MinConf: btcjson.Int(1), + Account: btcjson.String("default"), + MinConf: btcjson.Int(1), + AddressType: btcjson.String("*"), }, }, { @@ -344,8 +347,9 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"getbalance","params":["acct"],"id":1}`, unmarshalled: &btcjson.GetBalanceCmd{ - Account: btcjson.String("acct"), - MinConf: btcjson.Int(1), + Account: btcjson.String("acct"), + MinConf: btcjson.Int(1), + AddressType: btcjson.String("*"), }, }, { @@ -358,8 +362,9 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"getbalance","params":["acct",6],"id":1}`, unmarshalled: &btcjson.GetBalanceCmd{ - Account: btcjson.String("acct"), - MinConf: btcjson.Int(6), + Account: btcjson.String("acct"), + MinConf: btcjson.Int(6), + AddressType: btcjson.String("*"), }, }, { @@ -383,7 +388,8 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"getnewaddress","params":[],"id":1}`, unmarshalled: &btcjson.GetNewAddressCmd{ - Account: nil, + Account: btcjson.String("default"), + AddressType: btcjson.String("legacy"), }, }, { @@ -396,7 +402,8 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"getnewaddress","params":["acct"],"id":1}`, unmarshalled: &btcjson.GetNewAddressCmd{ - Account: btcjson.String("acct"), + Account: btcjson.String("acct"), + AddressType: btcjson.String("legacy"), }, }, { @@ -409,7 +416,8 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"getrawchangeaddress","params":[],"id":1}`, unmarshalled: &btcjson.GetRawChangeAddressCmd{ - Account: nil, + Account: btcjson.String("default"), + AddressType: btcjson.String("legacy"), }, }, { @@ -422,7 +430,8 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"getrawchangeaddress","params":["acct"],"id":1}`, unmarshalled: &btcjson.GetRawChangeAddressCmd{ - Account: btcjson.String("acct"), + Account: btcjson.String("acct"), + AddressType: btcjson.String("legacy"), }, }, { @@ -431,11 +440,11 @@ func TestWalletSvrCmds(t *testing.T) { return btcjson.NewCmd("getreceivedbyaccount", "acct") }, staticCmd: func() interface{} { - return btcjson.NewGetReceivedByAccountCmd("acct", nil) + return btcjson.NewGetReceivedByAccountCmd(btcjson.String("acct"), nil) }, marshalled: `{"jsonrpc":"1.0","method":"getreceivedbyaccount","params":["acct"],"id":1}`, unmarshalled: &btcjson.GetReceivedByAccountCmd{ - Account: "acct", + Account: btcjson.String("acct"), MinConf: btcjson.Int(1), }, }, @@ -445,11 +454,11 @@ func TestWalletSvrCmds(t *testing.T) { return btcjson.NewCmd("getreceivedbyaccount", "acct", 6) }, staticCmd: func() interface{} { - return btcjson.NewGetReceivedByAccountCmd("acct", btcjson.Int(6)) + return btcjson.NewGetReceivedByAccountCmd(btcjson.String("acct"), btcjson.Int(6)) }, marshalled: `{"jsonrpc":"1.0","method":"getreceivedbyaccount","params":["acct",6],"id":1}`, unmarshalled: &btcjson.GetReceivedByAccountCmd{ - Account: "acct", + Account: btcjson.String("acct"), MinConf: btcjson.Int(6), }, }, @@ -601,7 +610,8 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"listaccounts","params":[],"id":1}`, unmarshalled: &btcjson.ListAccountsCmd{ - MinConf: btcjson.Int(1), + MinConf: btcjson.Int(1), + AddressType: btcjson.String("*"), }, }, { @@ -614,7 +624,8 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"listaccounts","params":[6],"id":1}`, unmarshalled: &btcjson.ListAccountsCmd{ - MinConf: btcjson.Int(6), + MinConf: btcjson.Int(6), + AddressType: btcjson.String("*"), }, }, { @@ -844,7 +855,7 @@ func TestWalletSvrCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"listtransactions","params":[],"id":1}`, unmarshalled: &btcjson.ListTransactionsCmd{ - Account: nil, + Account: btcjson.String("default"), Count: btcjson.Int(10), From: btcjson.Int(0), IncludeWatchOnly: btcjson.Bool(false), @@ -1002,7 +1013,7 @@ func TestWalletSvrCmds(t *testing.T) { return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5) }, staticCmd: func() interface{} { - return btcjson.NewSendFromCmd("from", "1Address", 0.5, nil, nil, nil) + return btcjson.NewSendFromCmd("from", "1Address", 0.5, nil, nil, nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5],"id":1}`, unmarshalled: &btcjson.SendFromCmd{ @@ -1010,6 +1021,7 @@ func TestWalletSvrCmds(t *testing.T) { ToAddress: "1Address", Amount: 0.5, MinConf: btcjson.Int(1), + AddressType: btcjson.String("*"), Comment: nil, CommentTo: nil, }, @@ -1020,7 +1032,7 @@ func TestWalletSvrCmds(t *testing.T) { return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6) }, staticCmd: func() interface{} { - return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), nil, nil) + return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), nil, nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6],"id":1}`, unmarshalled: &btcjson.SendFromCmd{ @@ -1028,6 +1040,7 @@ func TestWalletSvrCmds(t *testing.T) { ToAddress: "1Address", Amount: 0.5, MinConf: btcjson.Int(6), + AddressType: btcjson.String("*"), Comment: nil, CommentTo: nil, }, @@ -1035,37 +1048,59 @@ func TestWalletSvrCmds(t *testing.T) { { name: "sendfrom optional2", newCmd: func() (interface{}, error) { - return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "comment") + return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "legacy") }, staticCmd: func() interface{} { - return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), - btcjson.String("comment"), nil) + return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), btcjson.String("legacy"), + nil, nil) }, - marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"comment"],"id":1}`, + marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"legacy"],"id":1}`, unmarshalled: &btcjson.SendFromCmd{ FromAccount: "from", ToAddress: "1Address", Amount: 0.5, MinConf: btcjson.Int(6), - Comment: btcjson.String("comment"), + AddressType: btcjson.String("legacy"), + Comment: nil, CommentTo: nil, }, }, { name: "sendfrom optional3", newCmd: func() (interface{}, error) { - return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "comment", "commentto") + return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "legacy", "comment") }, staticCmd: func() interface{} { - return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), - btcjson.String("comment"), btcjson.String("commentto")) + return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), btcjson.String("legacy"), + btcjson.String("comment"), nil) }, - marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"comment","commentto"],"id":1}`, + marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"legacy","comment"],"id":1}`, unmarshalled: &btcjson.SendFromCmd{ FromAccount: "from", ToAddress: "1Address", Amount: 0.5, MinConf: btcjson.Int(6), + AddressType: btcjson.String("legacy"), + Comment: btcjson.String("comment"), + CommentTo: nil, + }, + }, + { + name: "sendfrom optional4", + newCmd: func() (interface{}, error) { + return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "legacy", "comment", "commentto") + }, + staticCmd: func() interface{} { + return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), btcjson.String("legacy"), + btcjson.String("comment"), btcjson.String("commentto")) + }, + marshalled: `{"jsonrpc":"1.0","method":"sendfrom","params":["from","1Address",0.5,6,"legacy","comment","commentto"],"id":1}`, + unmarshalled: &btcjson.SendFromCmd{ + FromAccount: "from", + ToAddress: "1Address", + Amount: 0.5, + MinConf: btcjson.Int(6), + AddressType: btcjson.String("legacy"), Comment: btcjson.String("comment"), CommentTo: btcjson.String("commentto"), }, @@ -1077,13 +1112,14 @@ func TestWalletSvrCmds(t *testing.T) { }, staticCmd: func() interface{} { amounts := map[string]float64{"1Address": 0.5} - return btcjson.NewSendManyCmd("from", amounts, nil, nil) + return btcjson.NewSendManyCmd("from", amounts, nil, nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5}],"id":1}`, unmarshalled: &btcjson.SendManyCmd{ FromAccount: "from", Amounts: map[string]float64{"1Address": 0.5}, MinConf: btcjson.Int(1), + AddressType: btcjson.String("*"), Comment: nil, }, }, @@ -1094,30 +1130,50 @@ func TestWalletSvrCmds(t *testing.T) { }, staticCmd: func() interface{} { amounts := map[string]float64{"1Address": 0.5} - return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), nil) + return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5},6],"id":1}`, unmarshalled: &btcjson.SendManyCmd{ FromAccount: "from", Amounts: map[string]float64{"1Address": 0.5}, MinConf: btcjson.Int(6), + AddressType: btcjson.String("*"), Comment: nil, }, }, { name: "sendmany optional2", newCmd: func() (interface{}, error) { - return btcjson.NewCmd("sendmany", "from", `{"1Address":0.5}`, 6, "comment") + return btcjson.NewCmd("sendmany", "from", `{"1Address":0.5}`, 6, "legacy") }, staticCmd: func() interface{} { amounts := map[string]float64{"1Address": 0.5} - return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), btcjson.String("comment")) + return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), btcjson.String("legacy"), nil) }, - marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5},6,"comment"],"id":1}`, + marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5},6,"legacy"],"id":1}`, unmarshalled: &btcjson.SendManyCmd{ FromAccount: "from", Amounts: map[string]float64{"1Address": 0.5}, MinConf: btcjson.Int(6), + AddressType: btcjson.String("legacy"), + Comment: nil, + }, + }, + { + name: "sendmany optional3", + newCmd: func() (interface{}, error) { + return btcjson.NewCmd("sendmany", "from", `{"1Address":0.5}`, 6, "legacy", "comment") + }, + staticCmd: func() interface{} { + amounts := map[string]float64{"1Address": 0.5} + return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), btcjson.String("legacy"), btcjson.String("comment")) + }, + marshalled: `{"jsonrpc":"1.0","method":"sendmany","params":["from",{"1Address":0.5},6,"legacy","comment"],"id":1}`, + unmarshalled: &btcjson.SendManyCmd{ + FromAccount: "from", + Amounts: map[string]float64{"1Address": 0.5}, + MinConf: btcjson.Int(6), + AddressType: btcjson.String("legacy"), Comment: btcjson.String("comment"), }, }, @@ -1127,31 +1183,50 @@ func TestWalletSvrCmds(t *testing.T) { return btcjson.NewCmd("sendtoaddress", "1Address", 0.5) }, staticCmd: func() interface{} { - return btcjson.NewSendToAddressCmd("1Address", 0.5, nil, nil) + return btcjson.NewSendToAddressCmd("1Address", 0.5, nil, nil, nil) }, marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","params":["1Address",0.5],"id":1}`, unmarshalled: &btcjson.SendToAddressCmd{ - Address: "1Address", - Amount: 0.5, - Comment: nil, - CommentTo: nil, + Address: "1Address", + Amount: 0.5, + AddressType: btcjson.String("*"), + Comment: nil, + CommentTo: nil, }, }, { name: "sendtoaddress optional1", newCmd: func() (interface{}, error) { - return btcjson.NewCmd("sendtoaddress", "1Address", 0.5, "comment", "commentto") + return btcjson.NewCmd("sendtoaddress", "1Address", 0.5, "legacy") }, staticCmd: func() interface{} { - return btcjson.NewSendToAddressCmd("1Address", 0.5, btcjson.String("comment"), + return btcjson.NewSendToAddressCmd("1Address", 0.5, btcjson.String("legacy"), nil, nil) + }, + marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","params":["1Address",0.5,"legacy"],"id":1}`, + unmarshalled: &btcjson.SendToAddressCmd{ + Address: "1Address", + Amount: 0.5, + AddressType: btcjson.String("legacy"), + Comment: nil, + CommentTo: nil, + }, + }, + { + name: "sendtoaddress optional2", + newCmd: func() (interface{}, error) { + return btcjson.NewCmd("sendtoaddress", "1Address", 0.5, "legacy", "comment", "commentto") + }, + staticCmd: func() interface{} { + return btcjson.NewSendToAddressCmd("1Address", 0.5, btcjson.String("legacy"), btcjson.String("comment"), btcjson.String("commentto")) }, - marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","params":["1Address",0.5,"comment","commentto"],"id":1}`, + marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","params":["1Address",0.5,"legacy","comment","commentto"],"id":1}`, unmarshalled: &btcjson.SendToAddressCmd{ - Address: "1Address", - Amount: 0.5, - Comment: btcjson.String("comment"), - CommentTo: btcjson.String("commentto"), + Address: "1Address", + Amount: 0.5, + AddressType: btcjson.String("legacy"), + Comment: btcjson.String("comment"), + CommentTo: btcjson.String("commentto"), }, }, { diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index 0c07ac1c..fbfbd1e5 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -174,6 +174,7 @@ type GetTransactionResult struct { TimeReceived int64 `json:"timereceived"` Details []GetTransactionDetailsResult `json:"details"` Hex string `json:"hex"` + Generated bool `json:"generated"` } type ScanningOrFalse struct { @@ -288,7 +289,6 @@ type ListReceivedByAccountResult struct { // ListReceivedByAddressResult models the data from the listreceivedbyaddress // command. type ListReceivedByAddressResult struct { - Account string `json:"account"` Address string `json:"address"` Amount float64 `json:"amount"` Confirmations uint64 `json:"confirmations"` diff --git a/btcjson/walletsvrwscmds.go b/btcjson/walletsvrwscmds.go index e6a3aa72..c1fa9151 100644 --- a/btcjson/walletsvrwscmds.go +++ b/btcjson/walletsvrwscmds.go @@ -40,7 +40,7 @@ func NewExportWatchingWalletCmd(account *string, download *bool) *ExportWatching // GetUnconfirmedBalanceCmd defines the getunconfirmedbalance JSON-RPC command. type GetUnconfirmedBalanceCmd struct { - Account *string + Account *string `jsonrpcdefault:"\"default\""` } // NewGetUnconfirmedBalanceCmd returns a new instance which can be used to issue @@ -58,7 +58,7 @@ func NewGetUnconfirmedBalanceCmd(account *string) *GetUnconfirmedBalanceCmd { // command. type ListAddressTransactionsCmd struct { Addresses []string - Account *string + Account *string `jsonrpcdefault:"\"default\""` } // NewListAddressTransactionsCmd returns a new instance which can be used to @@ -75,7 +75,7 @@ func NewListAddressTransactionsCmd(addresses []string, account *string) *ListAdd // ListAllTransactionsCmd defines the listalltransactions JSON-RPC command. type ListAllTransactionsCmd struct { - Account *string + Account *string `jsonrpcdefault:"\"default\""` } // NewListAllTransactionsCmd returns a new instance which can be used to issue a diff --git a/btcjson/walletsvrwscmds_test.go b/btcjson/walletsvrwscmds_test.go index 3c9751fc..6d2fa252 100644 --- a/btcjson/walletsvrwscmds_test.go +++ b/btcjson/walletsvrwscmds_test.go @@ -71,7 +71,7 @@ func TestWalletSvrWsCmds(t *testing.T) { { name: "exportwatchingwallet optional2", newCmd: func() (interface{}, error) { - return btcjson.NewCmd("exportwatchingwallet", "acct", true) + return btcjson.NewCmd("exportwatchingwallet", btcjson.String("acct"), true) }, staticCmd: func() interface{} { return btcjson.NewExportWatchingWalletCmd(btcjson.String("acct"), @@ -93,7 +93,7 @@ func TestWalletSvrWsCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"getunconfirmedbalance","params":[],"id":1}`, unmarshalled: &btcjson.GetUnconfirmedBalanceCmd{ - Account: nil, + Account: btcjson.String("default"), }, }, { @@ -120,7 +120,7 @@ func TestWalletSvrWsCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"listaddresstransactions","params":[["1Address"]],"id":1}`, unmarshalled: &btcjson.ListAddressTransactionsCmd{ Addresses: []string{"1Address"}, - Account: nil, + Account: btcjson.String("default"), }, }, { @@ -148,7 +148,7 @@ func TestWalletSvrWsCmds(t *testing.T) { }, marshalled: `{"jsonrpc":"1.0","method":"listalltransactions","params":[],"id":1}`, unmarshalled: &btcjson.ListAllTransactionsCmd{ - Account: nil, + Account: btcjson.String("default"), }, }, { diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index 54a5c56f..cfd202da 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -536,9 +536,10 @@ func (r FutureSendToAddressResult) Receive() (*chainhash.Hash, error) { // returned instance. // // See SendToAddress for the blocking version and more details. -func (c *Client) SendToAddressAsync(address btcutil.Address, amount btcutil.Amount) FutureSendToAddressResult { +func (c *Client) SendToAddressAsync(address btcutil.Address, amount btcutil.Amount, + addrType *string) FutureSendToAddressResult { addr := address.EncodeAddress() - cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), nil, nil) + cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), addrType, nil, nil) return c.SendCmd(cmd) } @@ -550,8 +551,9 @@ func (c *Client) SendToAddressAsync(address btcutil.Address, amount btcutil.Amou // // NOTE: This function requires to the wallet to be unlocked. See the // WalletPassphrase function for more details. -func (c *Client) SendToAddress(address btcutil.Address, amount btcutil.Amount) (*chainhash.Hash, error) { - return c.SendToAddressAsync(address, amount).Receive() +func (c *Client) SendToAddress(address btcutil.Address, amount btcutil.Amount, + addrType *string) (*chainhash.Hash, error) { + return c.SendToAddressAsync(address, amount, addrType).Receive() } // SendToAddressCommentAsync returns an instance of a type that can be used to @@ -560,12 +562,12 @@ func (c *Client) SendToAddress(address btcutil.Address, amount btcutil.Amount) ( // // See SendToAddressComment for the blocking version and more details. func (c *Client) SendToAddressCommentAsync(address btcutil.Address, - amount btcutil.Amount, comment, + amount btcutil.Amount, addrType *string, comment string, commentTo string) FutureSendToAddressResult { addr := address.EncodeAddress() - cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), &comment, - &commentTo) + cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), addrType, + &comment, &commentTo) return c.SendCmd(cmd) } @@ -581,9 +583,10 @@ func (c *Client) SendToAddressCommentAsync(address btcutil.Address, // // NOTE: This function requires to the wallet to be unlocked. See the // WalletPassphrase function for more details. -func (c *Client) SendToAddressComment(address btcutil.Address, amount btcutil.Amount, comment, commentTo string) (*chainhash.Hash, error) { - return c.SendToAddressCommentAsync(address, amount, comment, - commentTo).Receive() +func (c *Client) SendToAddressComment(address btcutil.Address, amount btcutil.Amount, + addrType *string, comment, commentTo string) (*chainhash.Hash, error) { + return c.SendToAddressCommentAsync(address, amount, addrType, + comment, commentTo).Receive() } // FutureSendFromResult is a future promise to deliver the result of a @@ -615,10 +618,11 @@ func (r FutureSendFromResult) Receive() (*chainhash.Hash, error) { // returned instance. // // See SendFrom for the blocking version and more details. -func (c *Client) SendFromAsync(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount) FutureSendFromResult { +func (c *Client) SendFromAsync(fromAccount string, toAddress btcutil.Address, + amount btcutil.Amount, addrType *string) FutureSendFromResult { addr := toAddress.EncodeAddress() cmd := btcjson.NewSendFromCmd(fromAccount, addr, amount.ToBTC(), nil, - nil, nil) + addrType, nil, nil) return c.SendCmd(cmd) } @@ -630,8 +634,8 @@ func (c *Client) SendFromAsync(fromAccount string, toAddress btcutil.Address, am // // NOTE: This function requires to the wallet to be unlocked. See the // WalletPassphrase function for more details. -func (c *Client) SendFrom(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount) (*chainhash.Hash, error) { - return c.SendFromAsync(fromAccount, toAddress, amount).Receive() +func (c *Client) SendFrom(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount, addrType *string) (*chainhash.Hash, error) { + return c.SendFromAsync(fromAccount, toAddress, amount, addrType).Receive() } // SendFromMinConfAsync returns an instance of a type that can be used to get @@ -639,10 +643,12 @@ func (c *Client) SendFrom(fromAccount string, toAddress btcutil.Address, amount // the returned instance. // // See SendFromMinConf for the blocking version and more details. -func (c *Client) SendFromMinConfAsync(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount, minConfirms int) FutureSendFromResult { +func (c *Client) SendFromMinConfAsync(fromAccount string, + toAddress btcutil.Address, amount btcutil.Amount, + minConfirms int, addrType *string) FutureSendFromResult { addr := toAddress.EncodeAddress() cmd := btcjson.NewSendFromCmd(fromAccount, addr, amount.ToBTC(), - &minConfirms, nil, nil) + &minConfirms, addrType, nil, nil) return c.SendCmd(cmd) } @@ -655,9 +661,10 @@ func (c *Client) SendFromMinConfAsync(fromAccount string, toAddress btcutil.Addr // // NOTE: This function requires to the wallet to be unlocked. See the // WalletPassphrase function for more details. -func (c *Client) SendFromMinConf(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount, minConfirms int) (*chainhash.Hash, error) { +func (c *Client) SendFromMinConf(fromAccount string, toAddress btcutil.Address, + amount btcutil.Amount, minConfirms int, addrType *string) (*chainhash.Hash, error) { return c.SendFromMinConfAsync(fromAccount, toAddress, amount, - minConfirms).Receive() + minConfirms, addrType).Receive() } // SendFromCommentAsync returns an instance of a type that can be used to get @@ -667,11 +674,11 @@ func (c *Client) SendFromMinConf(fromAccount string, toAddress btcutil.Address, // See SendFromComment for the blocking version and more details. func (c *Client) SendFromCommentAsync(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount, minConfirms int, - comment, commentTo string) FutureSendFromResult { + addrType *string, comment, commentTo string) FutureSendFromResult { addr := toAddress.EncodeAddress() cmd := btcjson.NewSendFromCmd(fromAccount, addr, amount.ToBTC(), - &minConfirms, &comment, &commentTo) + &minConfirms, addrType, &comment, &commentTo) return c.SendCmd(cmd) } @@ -687,11 +694,11 @@ func (c *Client) SendFromCommentAsync(fromAccount string, // NOTE: This function requires to the wallet to be unlocked. See the // WalletPassphrase function for more details. func (c *Client) SendFromComment(fromAccount string, toAddress btcutil.Address, - amount btcutil.Amount, minConfirms int, + amount btcutil.Amount, minConfirms int, addrType *string, comment, commentTo string) (*chainhash.Hash, error) { return c.SendFromCommentAsync(fromAccount, toAddress, amount, - minConfirms, comment, commentTo).Receive() + minConfirms, addrType, comment, commentTo).Receive() } // FutureSendManyResult is a future promise to deliver the result of a @@ -728,7 +735,7 @@ func (c *Client) SendManyAsync(fromAccount string, amounts map[btcutil.Address]b for addr, amount := range amounts { convertedAmounts[addr.EncodeAddress()] = amount.ToBTC() } - cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts, nil, nil) + cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts, nil, nil, nil) return c.SendCmd(cmd) } @@ -751,14 +758,14 @@ func (c *Client) SendMany(fromAccount string, amounts map[btcutil.Address]btcuti // See SendManyMinConf for the blocking version and more details. func (c *Client) SendManyMinConfAsync(fromAccount string, amounts map[btcutil.Address]btcutil.Amount, - minConfirms int) FutureSendManyResult { + minConfirms int, addrType *string) FutureSendManyResult { convertedAmounts := make(map[string]float64, len(amounts)) for addr, amount := range amounts { convertedAmounts[addr.EncodeAddress()] = amount.ToBTC() } cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts, - &minConfirms, nil) + &minConfirms, nil, addrType) return c.SendCmd(cmd) } @@ -773,9 +780,10 @@ func (c *Client) SendManyMinConfAsync(fromAccount string, // WalletPassphrase function for more details. func (c *Client) SendManyMinConf(fromAccount string, amounts map[btcutil.Address]btcutil.Amount, - minConfirms int) (*chainhash.Hash, error) { + minConfirms int, addrType *string) (*chainhash.Hash, error) { - return c.SendManyMinConfAsync(fromAccount, amounts, minConfirms).Receive() + return c.SendManyMinConfAsync(fromAccount, amounts, minConfirms, + addrType).Receive() } // SendManyCommentAsync returns an instance of a type that can be used to get @@ -785,14 +793,14 @@ func (c *Client) SendManyMinConf(fromAccount string, // See SendManyComment for the blocking version and more details. func (c *Client) SendManyCommentAsync(fromAccount string, amounts map[btcutil.Address]btcutil.Amount, minConfirms int, - comment string) FutureSendManyResult { + addrType *string, comment string) FutureSendManyResult { convertedAmounts := make(map[string]float64, len(amounts)) for addr, amount := range amounts { convertedAmounts[addr.EncodeAddress()] = amount.ToBTC() } cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts, - &minConfirms, &comment) + &minConfirms, &comment, addrType) return c.SendCmd(cmd) } @@ -808,10 +816,10 @@ func (c *Client) SendManyCommentAsync(fromAccount string, // WalletPassphrase function for more details. func (c *Client) SendManyComment(fromAccount string, amounts map[btcutil.Address]btcutil.Amount, minConfirms int, - comment string) (*chainhash.Hash, error) { + addrType *string, comment string) (*chainhash.Hash, error) { return c.SendManyCommentAsync(fromAccount, amounts, minConfirms, - comment).Receive() + addrType, comment).Receive() } // ************************* @@ -1135,8 +1143,8 @@ func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) { // function on the returned instance. // // See GetRawChangeAddress for the blocking version and more details. -func (c *Client) GetRawChangeAddressAsync(account string) FutureGetRawChangeAddressResult { - cmd := btcjson.NewGetRawChangeAddressCmd(&account) +func (c *Client) GetRawChangeAddressAsync(account *string) FutureGetRawChangeAddressResult { + cmd := btcjson.NewGetRawChangeAddressCmd(account) result := FutureGetRawChangeAddressResult{ network: c.chainParams, responseChannel: c.SendCmd(cmd), @@ -1147,7 +1155,7 @@ func (c *Client) GetRawChangeAddressAsync(account string) FutureGetRawChangeAddr // GetRawChangeAddress returns a new address for receiving change that will be // associated with the provided account. Note that this is only for raw // transactions and NOT for normal use. -func (c *Client) GetRawChangeAddress(account string) (btcutil.Address, error) { +func (c *Client) GetRawChangeAddress(account *string) (btcutil.Address, error) { return c.GetRawChangeAddressAsync(account).Receive() } @@ -1226,7 +1234,7 @@ func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) { // the returned instance. // // See GetAccountAddress for the blocking version and more details. -func (c *Client) GetAccountAddressAsync(account string) FutureGetAccountAddressResult { +func (c *Client) GetAccountAddressAsync(account *string) FutureGetAccountAddressResult { cmd := btcjson.NewGetAccountAddressCmd(account) result := FutureGetAccountAddressResult{ network: c.chainParams, @@ -1237,7 +1245,7 @@ func (c *Client) GetAccountAddressAsync(account string) FutureGetAccountAddressR // GetAccountAddress returns the current Bitcoin address for receiving payments // to the specified account. -func (c *Client) GetAccountAddress(account string) (btcutil.Address, error) { +func (c *Client) GetAccountAddress(account *string) (btcutil.Address, error) { return c.GetAccountAddressAsync(account).Receive() } @@ -1317,7 +1325,7 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) // function on the returned instance. // // See GetAddressesByAccount for the blocking version and more details. -func (c *Client) GetAddressesByAccountAsync(account string) FutureGetAddressesByAccountResult { +func (c *Client) GetAddressesByAccountAsync(account *string) FutureGetAddressesByAccountResult { cmd := btcjson.NewGetAddressesByAccountCmd(account) result := FutureGetAddressesByAccountResult{ network: c.chainParams, @@ -1328,7 +1336,7 @@ func (c *Client) GetAddressesByAccountAsync(account string) FutureGetAddressesBy // GetAddressesByAccount returns the list of addresses associated with the // passed account. -func (c *Client) GetAddressesByAccount(account string) ([]btcutil.Address, error) { +func (c *Client) GetAddressesByAccount(account *string) ([]btcutil.Address, error) { return c.GetAddressesByAccountAsync(account).Receive() } @@ -1709,7 +1717,7 @@ func (r FutureGetReceivedByAccountResult) Receive() (btcutil.Amount, error) { // function on the returned instance. // // See GetReceivedByAccount for the blocking version and more details. -func (c *Client) GetReceivedByAccountAsync(account string) FutureGetReceivedByAccountResult { +func (c *Client) GetReceivedByAccountAsync(account *string) FutureGetReceivedByAccountResult { cmd := btcjson.NewGetReceivedByAccountCmd(account, nil) return c.SendCmd(cmd) } @@ -1719,7 +1727,7 @@ func (c *Client) GetReceivedByAccountAsync(account string) FutureGetReceivedByAc // // See GetReceivedByAccountMinConf to override the minimum number of // confirmations. -func (c *Client) GetReceivedByAccount(account string) (btcutil.Amount, error) { +func (c *Client) GetReceivedByAccount(account *string) (btcutil.Amount, error) { return c.GetReceivedByAccountAsync(account).Receive() } @@ -1728,8 +1736,8 @@ func (c *Client) GetReceivedByAccount(account string) (btcutil.Amount, error) { // function on the returned instance. // // See GetReceivedByAccountMinConf for the blocking version and more details. -func (c *Client) GetReceivedByAccountMinConfAsync(account string, minConfirms int) FutureGetReceivedByAccountResult { - cmd := btcjson.NewGetReceivedByAccountCmd(account, &minConfirms) +func (c *Client) GetReceivedByAccountMinConfAsync(account *string, minConfirms *int) FutureGetReceivedByAccountResult { + cmd := btcjson.NewGetReceivedByAccountCmd(account, minConfirms) return c.SendCmd(cmd) } @@ -1738,7 +1746,7 @@ func (c *Client) GetReceivedByAccountMinConfAsync(account string, minConfirms in // confirmations. // // See GetReceivedByAccount to use the default minimum number of confirmations. -func (c *Client) GetReceivedByAccountMinConf(account string, minConfirms int) (btcutil.Amount, error) { +func (c *Client) GetReceivedByAccountMinConf(account *string, minConfirms *int) (btcutil.Amount, error) { return c.GetReceivedByAccountMinConfAsync(account, minConfirms).Receive() } -- 2.45.2 From cbc4d489e8d2fc1b15a6798960cee766ab45dd1f Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 29 Sep 2022 16:45:21 -0700 Subject: [PATCH 454/459] lbcctl: support --timed, --quiet options --- cmd/lbcctl/config.go | 2 ++ cmd/lbcctl/lbcctl.go | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/cmd/lbcctl/config.go b/cmd/lbcctl/config.go index 90289663..81b26103 100644 --- a/cmd/lbcctl/config.go +++ b/cmd/lbcctl/config.go @@ -111,6 +111,8 @@ type config struct { SigNet bool `long:"signet" description:"Connect to signet (default RPC server: localhost:49245)"` Wallet bool `long:"wallet" description:"Connect to wallet RPC server instead (default: localhost:9244, testnet: localhost:19244, regtest: localhost:29244)"` ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` + Timed bool `short:"t" long:"timed" description:"Display RPC response time"` + Quiet bool `short:"q" long:"quiet" description:"Do not output results to stdout"` } // normalizeAddress returns addr with the passed default port appended if diff --git a/cmd/lbcctl/lbcctl.go b/cmd/lbcctl/lbcctl.go index 79349186..40132c65 100644 --- a/cmd/lbcctl/lbcctl.go +++ b/cmd/lbcctl/lbcctl.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "strings" + "time" "github.com/lbryio/lbcd/btcjson" ) @@ -133,6 +134,8 @@ func main() { os.Exit(1) } + started := time.Now() + // Send the JSON-RPC request to the server using the user-specified // connection configuration. result, err := sendPostRequest(marshalledJSON, cfg) @@ -141,6 +144,16 @@ func main() { os.Exit(1) } + if cfg.Timed { + elapsed := time.Since(started) + defer fmt.Fprintf(os.Stderr, "%s\n", elapsed) + } + + var output io.Writer = os.Stdout + if cfg.Quiet { + output = io.Discard + } + // Choose how to display the result based on its type. strResult := string(result) if strings.HasPrefix(strResult, "{") || strings.HasPrefix(strResult, "[") { @@ -150,7 +163,7 @@ func main() { err) os.Exit(1) } - fmt.Println(dst.String()) + fmt.Fprintln(output, dst.String()) } else if strings.HasPrefix(strResult, `"`) { var str string @@ -159,9 +172,9 @@ func main() { err) os.Exit(1) } - fmt.Println(str) + fmt.Fprintln(output, str) } else if strResult != "null" { - fmt.Println(strResult) + fmt.Fprintln(output, strResult) } } -- 2.45.2 From 979d6435944570a3bd468c9f690efe1d0a320532 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sat, 20 Aug 2022 00:35:10 -0700 Subject: [PATCH 455/459] [lbry] claimtrie: created node cache --- claimtrie/claimtrie.go | 97 +++++++------------------- claimtrie/node/cache.go | 85 +++++++++++++++++++++++ claimtrie/node/manager.go | 99 ++++++++++++++++++++------- claimtrie/node/node.go | 28 +++++++- claimtrie/node/normalizing_manager.go | 3 + 5 files changed, 213 insertions(+), 99 deletions(-) create mode 100644 claimtrie/node/cache.go diff --git a/claimtrie/claimtrie.go b/claimtrie/claimtrie.go index 2bc0cdbf..1d848e13 100644 --- a/claimtrie/claimtrie.go +++ b/claimtrie/claimtrie.go @@ -4,9 +4,7 @@ import ( "bytes" "fmt" "path/filepath" - "runtime" "sort" - "sync" "github.com/pkg/errors" @@ -249,17 +247,17 @@ func (ct *ClaimTrie) AppendBlock(temporary bool) error { names = append(names, expirations...) names = removeDuplicates(names) - nhns := ct.makeNameHashNext(names, false, nil) - for nhn := range nhns { + for _, name := range names { - ct.merkleTrie.Update(nhn.Name, nhn.Hash, true) - if nhn.Next <= 0 { + hash, next := ct.nodeManager.Hash(name) + ct.merkleTrie.Update(name, hash, true) + if next <= 0 { continue } - newName := normalization.NormalizeIfNecessary(nhn.Name, nhn.Next) + newName := normalization.NormalizeIfNecessary(name, next) updateNames = append(updateNames, newName) - updateHeights = append(updateHeights, nhn.Next) + updateHeights = append(updateHeights, next) } if !temporary && len(updateNames) > 0 { err = ct.temporalRepo.SetNodesAt(updateNames, updateHeights) @@ -356,22 +354,29 @@ func (ct *ClaimTrie) ResetHeight(height int32) error { } func (ct *ClaimTrie) runFullTrieRebuild(names [][]byte, interrupt <-chan struct{}) { - var nhns chan NameHashNext if names == nil { node.Log("Building the entire claim trie in RAM...") ct.claimLogger = newClaimProgressLogger("Processed", node.GetLogger()) - nhns = ct.makeNameHashNext(nil, true, interrupt) - } else { - ct.claimLogger = nil - nhns = ct.makeNameHashNext(names, false, interrupt) - } - for nhn := range nhns { - ct.merkleTrie.Update(nhn.Name, nhn.Hash, false) - if ct.claimLogger != nil { - ct.claimLogger.LogName(nhn.Name) + ct.nodeManager.IterateNames(func(name []byte) bool { + if interruptRequested(interrupt) { + return false + } + clone := make([]byte, len(name)) + copy(clone, name) + hash, _ := ct.nodeManager.Hash(clone) + ct.merkleTrie.Update(clone, hash, false) + ct.claimLogger.LogName(name) + return true + }) + + } else { + for _, name := range names { + hash, _ := ct.nodeManager.Hash(name) + ct.merkleTrie.Update(name, hash, false) } } + } // MerkleHash returns the Merkle Hash of the claimTrie. @@ -437,12 +442,6 @@ func (ct *ClaimTrie) FlushToDisk() { } } -type NameHashNext struct { - Name []byte - Hash *chainhash.Hash - Next int32 -} - func interruptRequested(interrupted <-chan struct{}) bool { select { case <-interrupted: // should never block on nil @@ -452,53 +451,3 @@ func interruptRequested(interrupted <-chan struct{}) bool { return false } - -func (ct *ClaimTrie) makeNameHashNext(names [][]byte, all bool, interrupt <-chan struct{}) chan NameHashNext { - inputs := make(chan []byte, 512) - outputs := make(chan NameHashNext, 512) - - var wg sync.WaitGroup - hashComputationWorker := func() { - for name := range inputs { - hash, next := ct.nodeManager.Hash(name) - outputs <- NameHashNext{name, hash, next} - } - wg.Done() - } - - threads := int(0.8 * float32(runtime.GOMAXPROCS(0))) - if threads < 1 { - threads = 1 - } - for threads > 0 { - threads-- - wg.Add(1) - go hashComputationWorker() - } - go func() { - if all { - ct.nodeManager.IterateNames(func(name []byte) bool { - if interruptRequested(interrupt) { - return false - } - clone := make([]byte, len(name)) - copy(clone, name) // iteration name buffer is reused on future loops - inputs <- clone - return true - }) - } else { - for _, name := range names { - if interruptRequested(interrupt) { - break - } - inputs <- name - } - } - close(inputs) - }() - go func() { - wg.Wait() - close(outputs) - }() - return outputs -} diff --git a/claimtrie/node/cache.go b/claimtrie/node/cache.go new file mode 100644 index 00000000..905ecd1d --- /dev/null +++ b/claimtrie/node/cache.go @@ -0,0 +1,85 @@ +package node + +import ( + "container/list" + + "github.com/lbryio/lbcd/claimtrie/change" +) + +type cacheLeaf struct { + node *Node + element *list.Element + changes []change.Change + height int32 +} + +type Cache struct { + nodes map[string]*cacheLeaf + order *list.List + limit int +} + +func (nc *Cache) insert(name []byte, n *Node, height int32) { + key := string(name) + + existing := nc.nodes[key] + if existing != nil { + existing.node = n + existing.height = height + existing.changes = nil + nc.order.MoveToFront(existing.element) + return + } + + for nc.order.Len() >= nc.limit { + // TODO: maybe ensure that we don't remove nodes that have a lot of changes? + delete(nc.nodes, nc.order.Back().Value.(string)) + nc.order.Remove(nc.order.Back()) + } + + element := nc.order.PushFront(key) + nc.nodes[key] = &cacheLeaf{node: n, element: element, height: height} +} + +func (nc *Cache) fetch(name []byte, height int32) (*Node, []change.Change, int32) { + key := string(name) + + existing := nc.nodes[key] + if existing != nil && existing.height <= height { + nc.order.MoveToFront(existing.element) + return existing.node, existing.changes, existing.height + } + return nil, nil, -1 +} + +func (nc *Cache) addChanges(changes []change.Change, height int32) { + for _, c := range changes { + key := string(c.Name) + existing := nc.nodes[key] + if existing != nil && existing.height <= height { + existing.changes = append(existing.changes, c) + } + } +} + +func (nc *Cache) drop(names [][]byte) { + for _, name := range names { + key := string(name) + existing := nc.nodes[key] + if existing != nil { + // we can't roll it backwards because we don't know its previous height value; just toast it + delete(nc.nodes, key) + nc.order.Remove(existing.element) + } + } +} + +func (nc *Cache) clear() { + nc.nodes = map[string]*cacheLeaf{} + nc.order = list.New() + // we'll let the GC sort out the remains... +} + +func NewCache(limit int) *Cache { + return &Cache{limit: limit, nodes: map[string]*cacheLeaf{}, order: list.New()} +} diff --git a/claimtrie/node/manager.go b/claimtrie/node/manager.go index 814bfc80..7081ac25 100644 --- a/claimtrie/node/manager.go +++ b/claimtrie/node/manager.go @@ -21,6 +21,7 @@ type Manager interface { IterateNames(predicate func(name []byte) bool) Hash(name []byte) (*chainhash.Hash, int32) Flush() error + ClearCache() } type BaseManager struct { @@ -30,31 +31,62 @@ type BaseManager struct { changes []change.Change tempChanges map[string][]change.Change + + cache *Cache } func NewBaseManager(repo Repo) (*BaseManager, error) { nm := &BaseManager{ - repo: repo, + repo: repo, + cache: NewCache(10000), // TODO: how many should we cache? } return nm, nil } +func (nm *BaseManager) ClearCache() { + nm.cache.clear() +} + func (nm *BaseManager) NodeAt(height int32, name []byte) (*Node, error) { - changes, err := nm.repo.LoadChanges(name) - if err != nil { - return nil, errors.Wrap(err, "in load changes") - } + n, changes, oldHeight := nm.cache.fetch(name, height) + if n == nil { + changes, err := nm.repo.LoadChanges(name) + if err != nil { + return nil, errors.Wrap(err, "in load changes") + } - if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block - changes = append(changes, nm.tempChanges[string(name)]...) - } + if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block + changes = append(changes, nm.tempChanges[string(name)]...) + } - n, err := nm.newNodeFromChanges(changes, height) - if err != nil { - return nil, errors.Wrap(err, "in new node") + n, err = nm.newNodeFromChanges(changes, height) + if err != nil { + return nil, errors.Wrap(err, "in new node") + } + // TODO: how can we tell what needs to be cached? + if nm.tempChanges == nil && height == nm.height && n != nil && (len(changes) > 4 || len(name) < 12) { + nm.cache.insert(name, n, height) + } + } else { + if nm.tempChanges != nil { // making an assumption that we only ever have tempChanges for a single block + changes = append(changes, nm.tempChanges[string(name)]...) + n = n.Clone() + } else if height != nm.height { + n = n.Clone() + } + updated, err := nm.updateFromChanges(n, changes, height) + if err != nil { + return nil, errors.Wrap(err, "in update from changes") + } + if !updated { + n.AdjustTo(oldHeight, height, name) + } + if nm.tempChanges == nil && height == nm.height { + nm.cache.insert(name, n, height) + } } return n, nil @@ -66,17 +98,13 @@ func (nm *BaseManager) node(name []byte) (*Node, error) { return nm.NodeAt(nm.height, name) } -// newNodeFromChanges returns a new Node constructed from the changes. -// The changes must preserve their order received. -func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) { +func (nm *BaseManager) updateFromChanges(n *Node, changes []change.Change, height int32) (bool, error) { - if len(changes) == 0 { - return nil, nil - } - - n := New() - previous := changes[0].Height count := len(changes) + if count == 0 { + return false, nil + } + previous := changes[0].Height for i, chg := range changes { if chg.Height < previous { @@ -95,15 +123,37 @@ func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) delay := nm.getDelayForName(n, chg) err := n.ApplyChange(chg, delay) if err != nil { - return nil, errors.Wrap(err, "in apply change") + return false, errors.Wrap(err, "in apply change") } } if count <= 0 { - return nil, nil + // we applied no changes, which means we shouldn't exist if we had all the changes + // or might mean nothing significant if we are applying a partial changeset + return false, nil } lastChange := changes[count-1] - return n.AdjustTo(lastChange.Height, height, lastChange.Name), nil + n.AdjustTo(lastChange.Height, height, lastChange.Name) + return true, nil +} + +// newNodeFromChanges returns a new Node constructed from the changes. +// The changes must preserve their order received. +func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32) (*Node, error) { + + if len(changes) == 0 { + return nil, nil + } + + n := New() + updated, err := nm.updateFromChanges(n, changes, height) + if err != nil { + return nil, errors.Wrap(err, "in update from changes") + } + if updated { + return n, nil + } + return nil, nil } func (nm *BaseManager) AppendChange(chg change.Change) { @@ -220,6 +270,7 @@ func (nm *BaseManager) IncrementHeightTo(height int32, temporary bool) ([][]byte } if !temporary { + nm.cache.addChanges(nm.changes, height) if err := nm.repo.AppendChanges(nm.changes); err != nil { // destroys names return nil, errors.Wrap(err, "in append changes") } @@ -255,6 +306,8 @@ func (nm *BaseManager) DecrementHeightTo(affectedNames [][]byte, height int32) ( return affectedNames, errors.Wrap(err, "in drop changes") } } + + nm.cache.drop(affectedNames) } nm.height = height diff --git a/claimtrie/node/node.go b/claimtrie/node/node.go index fe6db947..ff45fc11 100644 --- a/claimtrie/node/node.go +++ b/claimtrie/node/node.go @@ -110,7 +110,7 @@ func (n *Node) ApplyChange(chg change.Change, delay int32) error { } // AdjustTo activates claims and computes takeovers until it reaches the specified height. -func (n *Node) AdjustTo(height, maxHeight int32, name []byte) *Node { +func (n *Node) AdjustTo(height, maxHeight int32, name []byte) { changed := n.handleExpiredAndActivated(height) > 0 n.updateTakeoverHeight(height, name, changed) if maxHeight > height { @@ -120,7 +120,6 @@ func (n *Node) AdjustTo(height, maxHeight int32, name []byte) *Node { height = h } } - return n } func (n *Node) updateTakeoverHeight(height int32, name []byte, refindBest bool) { @@ -340,3 +339,28 @@ func (n *Node) SortClaimsByBid() { return OutPointLess(n.Claims[j].OutPoint, n.Claims[i].OutPoint) }) } + +func (n *Node) Clone() *Node { + clone := New() + if n.SupportSums != nil { + clone.SupportSums = map[string]int64{} + for key, value := range n.SupportSums { + clone.SupportSums[key] = value + } + } + clone.Supports = make(ClaimList, len(n.Supports)) + for i, support := range n.Supports { + clone.Supports[i] = &Claim{} + *clone.Supports[i] = *support + } + clone.Claims = make(ClaimList, len(n.Claims)) + for i, claim := range n.Claims { + clone.Claims[i] = &Claim{} + *clone.Claims[i] = *claim + } + clone.TakenOverAt = n.TakenOverAt + if n.BestClaim != nil { + clone.BestClaim = clone.Claims.find(byID(n.BestClaim.ClaimID)) + } + return clone +} diff --git a/claimtrie/node/normalizing_manager.go b/claimtrie/node/normalizing_manager.go index 2f6c4cfe..604fa34d 100644 --- a/claimtrie/node/normalizing_manager.go +++ b/claimtrie/node/normalizing_manager.go @@ -34,6 +34,7 @@ func (nm *NormalizingManager) IncrementHeightTo(height int32, temporary bool) ([ func (nm *NormalizingManager) DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) { if nm.normalizedAt > height { nm.normalizedAt = -1 + nm.ClearCache() } return nm.Manager.DecrementHeightTo(affectedNames, height) } @@ -110,5 +111,7 @@ func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int3 return true } + + nm.Manager.ClearCache() nm.Manager.IterateNames(predicate) } -- 2.45.2 From 6728bf4b08d86be161f7edba402ff581b6c431f2 Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Fri, 14 Oct 2022 13:38:27 -0400 Subject: [PATCH 456/459] error properly when lbcd fails to connect in HTTP POST mode in the case where you're e.g. trying to connect to an invalid address, the err vars in handleSendPostMessage() were being shadowed inside the for loop. if c.httpClient.Do() returned an error, that error never got returned upstream. then ioutil.ReadAll(httpResponse.Body) would get a nil pointer dereference. this fixes that case. --- rpcclient/infrastructure.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index 9b93d739..87fe9ec9 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -774,7 +774,8 @@ func (c *Client) handleSendPostMessage(jReq *jsonRequest) { tries := 10 for i := 0; tries == 0 || i < tries; i++ { bodyReader := bytes.NewReader(jReq.marshalledJSON) - httpReq, err := http.NewRequest("POST", url, bodyReader) + var httpReq *http.Request + httpReq, err = http.NewRequest("POST", url, bodyReader) if err != nil { jReq.responseChan <- &Response{result: nil, err: err} return @@ -786,7 +787,8 @@ func (c *Client) handleSendPostMessage(jReq *jsonRequest) { } // Configure basic access authorization. - user, pass, err := c.config.getAuth() + var user, pass string + user, pass, err = c.config.getAuth() if err != nil { jReq.responseChan <- &Response{result: nil, err: err} return -- 2.45.2 From f513fca6a7b858b22f33a3a076a50e294d68c2af Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Thu, 13 Oct 2022 19:50:12 -0700 Subject: [PATCH 457/459] lbcdblocknotify: reorganize the code with a few updates 1. Fixed a bug, which reads certs even TLS is disabled 2. Persists Stratum TCP connection with auto-reconnect. (retry backoff increases from 1s to 60s maximum) 3. Stratum update jobs on previous notifications are canceled when a new notification arrives. Usually, the jobs are so short and completed immediately. However, if the Stratum connection is broken, this prevents the bridge from accumulating stale jobs. --- rpcclient/examples/lbcdblocknotify/README.md | 39 ++-- rpcclient/examples/lbcdblocknotify/adapter.go | 20 ++ rpcclient/examples/lbcdblocknotify/bridge.go | 172 ++++++++++++++++++ .../examples/lbcdblocknotify/lbcdclient.go | 53 ++++++ rpcclient/examples/lbcdblocknotify/main.go | 147 ++++----------- .../examples/lbcdblocknotify/stratumclient.go | 56 ++++++ 6 files changed, 366 insertions(+), 121 deletions(-) create mode 100644 rpcclient/examples/lbcdblocknotify/adapter.go create mode 100644 rpcclient/examples/lbcdblocknotify/bridge.go create mode 100644 rpcclient/examples/lbcdblocknotify/lbcdclient.go create mode 100644 rpcclient/examples/lbcdblocknotify/stratumclient.go diff --git a/rpcclient/examples/lbcdblocknotify/README.md b/rpcclient/examples/lbcdblocknotify/README.md index 55fc19b0..ea1fc777 100644 --- a/rpcclient/examples/lbcdblocknotify/README.md +++ b/rpcclient/examples/lbcdblocknotify/README.md @@ -1,15 +1,21 @@ -# lbcd Websockets Example +# lbcdbloknotify -This example shows how to use the rpcclient package to connect to a btcd RPC -server using TLS-secured websockets, register for block connected and block -disconnected notifications, and get the current block count. +This bridge program subscribes to lbcd's notifications over websockets using the rpcclient package. +Users can specify supported actions upon receiving this notifications. -## Running the Example +## Building(or Running) the Program -The first step is to clone the lbcd package: +Clone the lbcd package: ```bash $ git clone github.com/lbryio/lbcd +$ cd lbcd/rpcclient/examples + +# build the program +$ go build . + +# or directly run it (build implicitly behind the scene) +$ go run . ``` Display available options: @@ -30,19 +36,30 @@ $ go run . -h -stratumpass string Stratum server password (default "password") -quiet - Do not print logs + Do not print periodic logs ``` -Start the program: +Running the program: ```bash -$ go run . -stratumpass -rpcuser -rpcpass +# Send stratum mining.update_block mesage upon receving block connected notifiations. +$ go run . -rpcuser -rpcpass --notls -stratum -stratumpass -2022/01/10 23:16:21 NotifyBlocks: Registration Complete -2022/01/10 23:16:21 Block count: 1093112 +2022/01/10 23:16:21 Current block count: 1093112 ... + +# Execute a custome command (with blockhash) upon receving block connected notifiations. +$ go run . -rpcuser -rpcpass --notls -run "echo %s" ``` +## Notes + +* Stratum TCP connection is persisted with auto-reconnect. (retry backoff increases from 1s to 60s maximum) + +* Stratum update_block jobs on previous notifications are canceled when a new notification arrives. + Usually, the jobs are so short and completed immediately. However, if the Stratum connection is broken, this + prevents the bridge from accumulating stale jobs. + ## License This example is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/rpcclient/examples/lbcdblocknotify/adapter.go b/rpcclient/examples/lbcdblocknotify/adapter.go new file mode 100644 index 00000000..b12b0d90 --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/adapter.go @@ -0,0 +1,20 @@ +package main + +import ( + "github.com/lbryio/lbcd/wire" + "github.com/lbryio/lbcutil" +) + +type eventBlockConected struct { + height int32 + header *wire.BlockHeader + txns []*lbcutil.Tx +} + +type adapter struct { + *bridge +} + +func (a *adapter) onFilteredBlockConnected(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) { + a.eventCh <- &eventBlockConected{height, header, txns} +} diff --git a/rpcclient/examples/lbcdblocknotify/bridge.go b/rpcclient/examples/lbcdblocknotify/bridge.go new file mode 100644 index 00000000..db5e8cc0 --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/bridge.go @@ -0,0 +1,172 @@ +package main + +import ( + "context" + "errors" + "fmt" + "log" + "net" + "os" + "os/exec" + "strings" + "sync" + "syscall" + "time" +) + +type bridge struct { + ctx context.Context + + prevJobContext context.Context + prevJobCancel context.CancelFunc + + eventCh chan interface{} + errorc chan error + wg sync.WaitGroup + + stratum *stratumClient + + customCmd string +} + +func newBridge(stratumServer, stratumPass, coinid string) *bridge { + + s := &bridge{ + ctx: context.Background(), + eventCh: make(chan interface{}), + errorc: make(chan error), + } + + if len(stratumServer) > 0 { + s.stratum = newStratumClient(stratumServer, stratumPass, coinid) + } + + return s +} + +func (b *bridge) start() { + + if b.stratum != nil { + backoff := time.Second + for { + err := b.stratum.dial() + if err == nil { + break + } + log.Printf("WARN: stratum.dial() error: %s, retry in %s", err, backoff) + time.Sleep(backoff) + if backoff < 60*time.Second { + backoff += time.Second + } + } + } + + for e := range b.eventCh { + switch e := e.(type) { + case *eventBlockConected: + b.handleFilteredBlockConnected(e) + default: + b.errorc <- fmt.Errorf("unknown event type: %T", e) + return + } + } +} + +func (b *bridge) handleFilteredBlockConnected(e *eventBlockConected) { + + if !*quiet { + log.Printf("Block connected: %s (%d) %v", e.header.BlockHash(), e.height, e.header.Timestamp) + } + + hash := e.header.BlockHash().String() + height := e.height + + // Cancel jobs on previous block. It's safe if they are already done. + if b.prevJobContext != nil { + select { + case <-b.prevJobContext.Done(): + log.Printf("prev one canceled") + default: + b.prevJobCancel() + } + } + + // Wait until all previous jobs are done or canceled. + b.wg.Wait() + + // Create and save cancelable subcontext for new jobs. + ctx, cancel := context.WithCancel(b.ctx) + b.prevJobContext, b.prevJobCancel = ctx, cancel + + if len(b.customCmd) > 0 { + go b.execCustomCommand(ctx, hash, height) + } + + // Send stratum update block message + if b.stratum != nil { + go b.stratumUpdateBlock(ctx, hash, height) + } +} + +func (s *bridge) stratumUpdateBlock(ctx context.Context, hash string, height int32) { + s.wg.Add(1) + defer s.wg.Done() + + backoff := time.Second + retry := func(err error) { + if backoff < 60*time.Second { + backoff += time.Second + } + log.Printf("WARN: stratum.send() on block %d error: %s", height, err) + time.Sleep(backoff) + s.stratum.dial() + } + + msg := stratumUpdateBlockMsg(*stratumPass, *coinid, hash) + + for { + switch err := s.stratum.send(ctx, msg); { + case err == nil: + return + case errors.Is(err, context.Canceled): + log.Printf("INFO: stratum.send() on block %d: %s.", height, err) + return + case errors.Is(err, syscall.EPIPE): + errClose := s.stratum.conn.Close() + if errClose != nil { + log.Printf("WARN: stratum.conn.Close() on block %d: %s.", height, errClose) + } + retry(err) + case errors.Is(err, net.ErrClosed): + retry(err) + default: + retry(err) + } + } + +} + +func (s *bridge) execCustomCommand(ctx context.Context, hash string, height int32) { + s.wg.Add(1) + defer s.wg.Done() + + cmd := strings.ReplaceAll(s.customCmd, "%s", hash) + err := doExecCustomCommand(ctx, cmd) + if err != nil { + log.Printf("ERROR: execCustomCommand on block %s(%d): %s", hash, height, err) + } +} + +func doExecCustomCommand(ctx context.Context, cmd string) error { + strs := strings.Split(cmd, " ") + path, err := exec.LookPath(strs[0]) + if errors.Is(err, exec.ErrDot) { + err = nil + } + if err != nil { + return err + } + c := exec.CommandContext(ctx, path, strs[1:]...) + c.Stdout = os.Stdout + return c.Run() +} diff --git a/rpcclient/examples/lbcdblocknotify/lbcdclient.go b/rpcclient/examples/lbcdblocknotify/lbcdclient.go new file mode 100644 index 00000000..91580fd8 --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/lbcdclient.go @@ -0,0 +1,53 @@ +package main + +import ( + "io/ioutil" + "log" + "path/filepath" + + "github.com/lbryio/lbcd/rpcclient" +) + +func newLbcdClient(server, user, pass string, notls bool, adpt adapter) *rpcclient.Client { + + ntfnHandlers := rpcclient.NotificationHandlers{ + OnFilteredBlockConnected: adpt.onFilteredBlockConnected, + } + + // Config lbcd RPC client with websockets. + connCfg := &rpcclient.ConnConfig{ + Host: server, + Endpoint: "ws", + User: user, + Pass: pass, + DisableTLS: true, + } + + if !notls { + cert, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) + if err != nil { + log.Fatalf("can't read lbcd certificate: %s", err) + } + connCfg.Certificates = cert + connCfg.DisableTLS = false + } + + client, err := rpcclient.New(connCfg, &ntfnHandlers) + if err != nil { + log.Fatalf("can't create rpc client: %s", err) + } + + // Register for block connect and disconnect notifications. + if err = client.NotifyBlocks(); err != nil { + log.Fatalf("can't register block notification: %s", err) + } + + // Get the current block count. + blockCount, err := client.GetBlockCount() + if err != nil { + log.Fatalf("can't get block count: %s", err) + } + log.Printf("Current block count: %d", blockCount) + + return client +} diff --git a/rpcclient/examples/lbcdblocknotify/main.go b/rpcclient/examples/lbcdblocknotify/main.go index 9b672a59..27cdf329 100644 --- a/rpcclient/examples/lbcdblocknotify/main.go +++ b/rpcclient/examples/lbcdblocknotify/main.go @@ -1,136 +1,63 @@ -// Copyright (c) 2014-2017 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - package main import ( - "errors" "flag" - "fmt" - "io/ioutil" "log" - "net" - "os" "os/exec" "path/filepath" "strings" - "github.com/lbryio/lbcd/rpcclient" - "github.com/lbryio/lbcd/wire" "github.com/lbryio/lbcutil" ) var ( - coinid = flag.String("coinid", "1425", "Coin ID") - stratum = flag.String("stratum", "", "Stratum server") - stratumPass = flag.String("stratumpass", "", "Stratum server password") - rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server") - rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username") - rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password") - notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled") - run = flag.String("run", "", "Run custom shell command") - quiet = flag.Bool("quiet", false, "Do not print logs") + lbcdHomeDir = lbcutil.AppDataDir("lbcd", false) + defaultCert = filepath.Join(lbcdHomeDir, "rpc.cert") +) +var ( + coinid = flag.String("coinid", "1425", "Coin ID") + stratumServer = flag.String("stratum", "", "Stratum server") + stratumPass = flag.String("stratumpass", "", "Stratum server password") + rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server") + rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username") + rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password") + rpccert = flag.String("rpccert", defaultCert, "LBCD RPC certificate") + notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled") + run = flag.String("run", "", "Run custom shell command") + quiet = flag.Bool("quiet", false, "Do not print logs") ) -func onFilteredBlockConnected(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) { - - blockHash := header.BlockHash().String() - - if !*quiet { - log.Printf("Block connected: %v (%d) %v", blockHash, height, header.Timestamp) - } - - if cmd := *run; len(cmd) != 0 { - cmd = strings.ReplaceAll(cmd, "%s", blockHash) - err := execCustomCommand(cmd) - if err != nil { - log.Printf("ERROR: execCustomCommand: %s", err) - } - } - - if len(*stratum) > 0 && len(*stratumPass) > 0 { - err := stratumUpdateBlock(*stratum, *stratumPass, *coinid, blockHash) - if err != nil { - log.Printf("ERROR: stratumUpdateBlock: %s", err) - } - } -} -func execCustomCommand(cmd string) error { - strs := strings.Split(cmd, " ") - path, err := exec.LookPath(strs[0]) - if errors.Is(err, exec.ErrDot) { - err = nil - } - if err != nil { - return err - } - c := exec.Command(path, strs[1:]...) - c.Stdout = os.Stdout - return c.Run() -} - -func stratumUpdateBlock(stratum, stratumPass, coinid, blockHash string) error { - addr, err := net.ResolveTCPAddr("tcp", stratum) - if err != nil { - return fmt.Errorf("can't resolve addr: %w", err) - } - - conn, err := net.DialTCP("tcp", nil, addr) - if err != nil { - return fmt.Errorf("can't dial tcp: %w", err) - } - defer conn.Close() - - msg := fmt.Sprintf(`{"id":1,"method":"mining.update_block","params":[%q,%s,%q]}`, - stratumPass, coinid, blockHash) - - _, err = conn.Write([]byte(msg)) - if err != nil { - return fmt.Errorf("can't write message: %w", err) - } - - return nil -} func main() { flag.Parse() - ntfnHandlers := rpcclient.NotificationHandlers{ - OnFilteredBlockConnected: onFilteredBlockConnected, + // Setup notification handler + b := newBridge(*stratumServer, *stratumPass, *coinid) + + if len(*run) > 0 { + // Check if ccommand exists. + strs := strings.Split(*run, " ") + cmd := strs[0] + _, err := exec.LookPath(cmd) + if err != nil { + log.Fatalf("ERROR: %s not found: %s", cmd, err) + } + b.customCmd = *run } - // Connect to local lbcd RPC server using websockets. - lbcdHomeDir := lbcutil.AppDataDir("lbcd", false) - certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) - if err != nil { - log.Fatalf("can't read lbcd certificate: %s", err) - } - connCfg := &rpcclient.ConnConfig{ - Host: *rpcserver, - Endpoint: "ws", - User: *rpcuser, - Pass: *rpcpass, - Certificates: certs, - DisableTLS: *notls, - } - client, err := rpcclient.New(connCfg, &ntfnHandlers) - if err != nil { - log.Fatalf("can't create rpc client: %s", err) - } + // Start the eventt handler. + go b.start() - // Register for block connect and disconnect notifications. - if err = client.NotifyBlocks(); err != nil { - log.Fatalf("can't register block notification: %s", err) - } - log.Printf("NotifyBlocks: Registration Complete") + // Adaptater receives lbcd notifications, and emit events. + adpt := adapter{b} - // Get the current block count. - blockCount, err := client.GetBlockCount() - if err != nil { - log.Fatalf("can't get block count: %s", err) - } - log.Printf("Block count: %d", blockCount) + client := newLbcdClient(*rpcserver, *rpcuser, *rpcpass, *notls, adpt) + + go func() { + err := <-b.errorc + log.Fatalf("ERROR: %s", err) + client.Shutdown() + }() // Wait until the client either shuts down gracefully (or the user // terminates the process with Ctrl+C). diff --git a/rpcclient/examples/lbcdblocknotify/stratumclient.go b/rpcclient/examples/lbcdblocknotify/stratumclient.go new file mode 100644 index 00000000..449135ce --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/stratumclient.go @@ -0,0 +1,56 @@ +package main + +import ( + "context" + "fmt" + "net" +) + +type stratumClient struct { + server string + passwd string + coinid string + conn *net.TCPConn +} + +func newStratumClient(server, passwd, coinid string) *stratumClient { + + return &stratumClient{ + server: server, + } +} + +func (c *stratumClient) dial() error { + + addr, err := net.ResolveTCPAddr("tcp", c.server) + if err != nil { + return fmt.Errorf("resolve tcp addr: %w", err) + } + + conn, err := net.DialTCP("tcp", nil, addr) + if err != nil { + return fmt.Errorf("dial tcp: %w", err) + } + c.conn = conn + + return nil +} + +func (c *stratumClient) send(ctx context.Context, msg string) error { + + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + _, err := c.conn.Write([]byte(msg)) + + return err +} + +func stratumUpdateBlockMsg(stratumPass, coinid, blockHash string) string { + + return fmt.Sprintf(`{"id":1,"method":"mining.update_block","params":[%q,%s,%q]}`, + stratumPass, coinid, blockHash) +} -- 2.45.2 From 4c39a9842c453940e8782839bfd5e4ef5c8aeaae Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Sun, 30 Oct 2022 23:55:49 -0700 Subject: [PATCH 458/459] rpcclient: update rescanblockchain support --- btcjson/walletsvrcmds.go | 6 +++--- btcjson/walletsvrresults.go | 4 ++-- rpcclient/wallet.go | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index 56369a82..1549d3d4 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -977,8 +977,8 @@ func NewImportMultiCmd(requests []ImportMultiRequest, options *ImportMultiOption // RescanBlockchainCmd defines the RescanBlockchain JSON-RPC command. type RescanBlockchainCmd struct { - StartHeight *int64 `jsonrpcdefault:"0"` - StopHeight *int64 `jsonrpcdefault:"0"` + StartHeight *int32 `jsonrpcdefault:"0"` + StopHeight *int32 } // NewRescanBlockchainCmd returns a new instance which can be used to issue @@ -986,7 +986,7 @@ type RescanBlockchainCmd struct { // // The parameters which are pointers indicate they are optional. Passing nil // for optional parameters will use the default value. -func NewRescanBlockchainCmd(startHeight *int64, stopHeight *int64) *RescanBlockchainCmd { +func NewRescanBlockchainCmd(startHeight *int32, stopHeight *int32) *RescanBlockchainCmd { return &RescanBlockchainCmd{ StartHeight: startHeight, StopHeight: stopHeight, diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index fbfbd1e5..83ae269d 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -319,8 +319,8 @@ type ListUnspentResult struct { // RescanBlockchainResult models the data returned from the rescanblockchain command. type RescanBlockchainResult struct { - StartHeight int64 `json:"start_height"` - StoptHeight int64 `json:"stop_height"` + StartHeight int32 `json:"start_height"` + StoptHeight int32 `json:"stop_height"` } // SignRawTransactionError models the data that contains script verification diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index cfd202da..10da4439 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -2062,14 +2062,14 @@ func (r FutureRescanBlockchainResult) Receive() (*btcjson.RescanBlockchainResult // returned instance. // // See RescanBlockchain for the blocking version and more details. -func (c *Client) RescanBlockchainAsync(startHeight *int64, stopHeight *int64) FutureRescanBlockchainResult { +func (c *Client) RescanBlockchainAsync(startHeight *int32, stopHeight *int32) FutureRescanBlockchainResult { cmd := btcjson.NewRescanBlockchainCmd(startHeight, stopHeight) return c.SendCmd(cmd) } // RescanBlockchain rescans the local blockchain for wallet related // transactions from the startHeight to the the inclusive stopHeight. -func (c *Client) RescanBlockchain(startHeight *int64, stopHeight *int64) (*btcjson.RescanBlockchainResult, error) { +func (c *Client) RescanBlockchain(startHeight *int32, stopHeight *int32) (*btcjson.RescanBlockchainResult, error) { return c.RescanBlockchainAsync(startHeight, stopHeight).Receive() } -- 2.45.2 From a0ff51b84acc553c9e9568e80c7873c03e24d679 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 23 Nov 2022 08:41:31 -0800 Subject: [PATCH 459/459] claimtrie: allows '*' in claim name --- txscript/claimscript.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/txscript/claimscript.go b/txscript/claimscript.go index 4d3a8236..694cc970 100644 --- a/txscript/claimscript.go +++ b/txscript/claimscript.go @@ -206,7 +206,7 @@ func StripClaimScriptPrefix(script []byte) []byte { return script[cs.Size:] } -const illegalChars = "=&#:*$%?/;\\\b\n\t\r\x00" +const illegalChars = "=&#:$%?/;\\\b\n\t\r\x00" func AllClaimsAreSane(script []byte, enforceSoftFork bool) error { cs, err := ExtractClaimScript(script) -- 2.45.2