{"credit":"Taylor (gtmcknight), github.com/gtmcknight/amm-sim@4812a6382311624e1506aca131ca35c378f930d9 research/solved: the solved policy, replica2.py and the release engine wheel (sim-6b6921f8) this core is proved against. Engine: benedictbrady/amm-challenge@6b6921f8d463314aa7c96234e1be25a25245f704. Kit: identity-md-launches/goal-3178-build-shared-evaluation-kit@45e7563d1a29ffca9d608fdf60c90bf2624d2d01.","item":"r1 (b-core): engine-faithful fast simulation core, enginecore.py","ready":true,"summary":"enginecore.py reproduces the Rust engine bit for bit: 128 of 128 submission edges identical (constant 30/30 and 25/45 bps, seeds 9700000..9700063), every log line of a logging-patched engine build identical on 4 seeds x 2 policies, and a moving-fee contract identical on 8 seeds. One difference beyond the known list was found and ported: the engine takes exp for retail sizes from the libm crate, not the C library.","parity":{"n":128,"max_abs_diff":0.0,"max_rel_diff":0.0,"bit_identical":128,"within_1e9_rel":128,"worst":{"seed":9700000,"policy":"const_30_30","engine":346.0273756163182,"enginecore":346.0273756163182},"worst_note":"all 128 differences are 0.0; the row shown is the first","seeds":"9700000..9700063","policies":{"const_30_30":"bid 30 bps, ask 30 bps","const_25_45":"bid 25 bps, ask 45 bps"},"mean_edge":{"const_30_30":{"engine":337.9826448365718,"enginecore":337.9826448365718},"const_25_45":{"engine":345.4532596083489,"enginecore":345.4532596083489}},"engine_after_swap_peak_gas":{"const_30_30":22606,"const_25_45":22614},"engine":"kit engine_eval.run_batch(seeds, Strategy.sol): release wheel amm_sim_rs 0.1.0.post1 (native sha256 ff88b6353c2aad7342f0a26194f7347e78b9c3b38d683a7449006d423978cd14), solc 0.8.24, each seed one run_batch(X, VanillaStrategy, [config], 8)","configs":{"compared":64,"mismatches":0,"what":"enginecore.config_for against the kit config_for, 12 fields"},"engine_seconds":34.32,"golden":"tests/golden.json in code_zb64 holds the 128 engine edges as float.hex; tests/selfcheck.py re-checks them offline: {\"edges\": 128, \"mismatches\": 0}"},"dynamic_policy":{"rule":"init 30/30 bps; afterSwap: n = ++slots[0]; bid = 20 + (timestamp % 5) * 4 + (isBuy ? 7 : 0) + (n % 2); ask = 25 + (timestamp % 3) * 6 + (amountY >= 5e18 ? 9 : 0) + (reserveX >= 100e18 ? 3 : 0); bps","seeds":[9700000,9700007],"n":8,"max_abs_diff":0.0,"bit_identical":8,"mean_edge_engine":354.0510493372243,"mean_edge_enginecore":354.0510493372243,"peak_gas":45429,"callbacks":76743,"refused_fee_returns":0,"note":"extra, outside the 128: one contract and the same rule as an enginecore policy (tests/parity.py)"},"step_logs":{"compared":{"logging_patch":{"what":"amm_sim_rs built from the pinned source with tests/logpatch.py (eprintln only) and run on seeds 9700000..9700003 for both policies; every line compared with enginecore as exact bits: price per step, each retail order (side, size), each arbitrage (pool, side, amount_x, amount_y), each TradeInfo handed to afterSwap for both pools (WAD integers), each retail fill, and both pools reserves and fee buckets at the end of every step","runs":8,"lines":{"afterSwap_TradeInfo":{"engine_lines":178258,"mismatches":0},"arbitrage":{"engine_lines":55381,"mismatches":0},"end_of_step_reserves_and_fee_buckets":{"engine_lines":160000,"mismatches":0},"orders":{"engine_lines":63782,"mismatches":0},"price":{"engine_lines":80000,"mismatches":0},"retail_fills":{"engine_lines":122877,"mismatches":0}},"patched_build":{"toolchain":"rustc 1.99.1 (58cf8f9c3 2026-10-13)","cargo_lock":{"libm":["0.2.16"],"num-traits":["0.2.19"],"pyo3":["0.22.6"],"rand":["0.8.8","0.9.5","0.10.3"],"rand_core":["0.6.4","0.9.5","0.10.1"],"rand_distr":["0.4.3"],"rand_pcg":["0.3.1"],"revm":["18.0.0"]},"submission_edges_equal_to_wheel":"8 of 8","note":"own build with a current toolchain and freshly resolved dependencies, not the release wheel"}},"wheel_step_output":{"what":"LightweightSimResult.steps of the release wheel (fair_price, spot_prices, pnls, fees of both pools at every step) and its totals (edges, pnl, arb and retail volume, average fees for both pools) against enginecore, same 4 seeds x 2 policies","runs":8,"step_fields_compared":560000,"totals_compared":96,"runs_with_any_difference":0}},"first_divergence":null},"finding":{"what":"With every difference of the 8b18deed list ported and C-library exp everywhere, the 128 edges agreed only to 5.9e-11 relative (16 bit-identical, max abs 1.84e-08), and the first step-level divergence came between step 239 and 4930. Cause: retail order sizes one ulp off on about 7% of orders (38 of 540 one-order probes), because rand_distr 0.4.3 computes LogNormal exp through num-traits built with the \"libm\" feature (std_math is off by default). With _libm_exp all 128 are bit-identical.","why_it_matters":"a one-ulp size leaves the submission fill unchanged most of the time (the split is quantised by ulp(10000)) and moves the normalizer fill, so it is invisible to a policy on most fills but breaks exact-arithmetic tests against the rival; any exact rival carry or split test tuned on a replica with C-library exp sees wrong last bits","probes":"engine wheel run with n_steps = 1..1500 and gbm_sigma = 0 one-step configs on seeds 9700000..9700063 (diagnosis only, not evaluations)"},"ported":[{"what":"k recomputed from the stored (rounded) reserves at every quote","engine":"amm_sim_rs/src/amm/cfmm.rs:131, 152, 180 (used at 133, 160, 189)","done":true},{"what":"arbitrage sizing with k = rx*ry of the moment, sqrt closed forms, 0.99 cap, quote, profit test, then execute (which quotes again)","engine":"amm_sim_rs/src/market/arbitrageur.rs:36-47, 55-89, 105-138","done":true},{"what":"reserves updated by increments, fee kept in a separate bucket (net = amount - fee_amount)","engine":"amm_sim_rs/src/amm/cfmm.rs:207-210, 238-241, 269-272","done":true},{"what":"execution order: price step, arbitrage on submission then normalizer, then each retail order filled on submission then normalizer; afterSwap applied before the next quote","engine":"amm_sim_rs/src/simulation/engine.rs:136-162; amm_sim_rs/src/market/router.rs:196-218, 221-244","done":true},{"what":"router split (same operations and order as router.rs), 0.0001 threshold, total_x = size / fair_price","engine":"amm_sim_rs/src/market/router.rs:40-75, 82-117, 188, 221","done":true},{"what":"truncated WAD integers at the EVM boundary: TradeInfo amounts and reserves to the callback; the routed amount the edge uses goes through the WAD round trip; fee WAD to f64","engine":"amm_sim_rs/src/amm/cfmm.rs:213-219, 244-250, 275-281; amm_sim_rs/src/types/wad.rs:33, 39; amm_sim_rs/src/market/router.rs:203, 214, 228, 239","done":true},{"what":"fee clamp: a returned fee above 1e17 makes decode_fee_pair fail and the fees in force are kept (at afterInitialize the engine errors); clamp_fee then never changes a value","engine":"amm_sim_rs/src/types/trade_info.rs:116-132; amm_sim_rs/src/amm/cfmm.rs:81-82, 293-298; amm_sim_rs/src/types/wad.rs:71-73","done":true,"note":"transcribed; the refusal path was not exercised against the engine (the kit engine_eval raises on bad_return)"},{"what":"random streams: Pcg64 seed_from_u64(seed) for the price, seed_from_u64(seed + 1) for retail; ziggurat StandardNormal; Knuth Poisson; LogNormal; Standard f64 side","engine":"amm_sim_rs/src/simulation/engine.rs:54-69; amm_sim_rs/src/market/price_process.rs:39, 48-49, 63-65; amm_sim_rs/src/market/retail.rs:51, 56-60, 77, 87, 90","done":true},{"what":"NEW, not in the differences list of artifact 8b18deed: LogNormal size and Poisson exp(-lambda) take exp from the libm crate (rand_distr 0.4 reaches generic float math through num-traits with feature \"libm\"), not from the C library; ported as _libm_exp (FreeBSD msun e_exp.c port). The price step uses f64::exp, the C library","engine":"amm_sim_rs/src/market/retail.rs:56, 60, 87 (rand_distr-0.4.3 src/normal.rs:192, 314; src/poisson.rs:75; Cargo.toml num-traits features [\"libm\"]); amm_sim_rs/src/market/price_process.rs:65","done":true},{"what":"config draw as the kit bootstrap/smoke_engine.config_for (numpy default_rng(seed): mean size, arrival rate, sigma)","engine":"amm_competition/competition/match.py:100-122; amm_competition/competition/config.py","done":true},{"what":"edge: -profit per arbitrage, amount_x*fair - amount_y or the reverse per retail fill; volumes, per-step capture, pnl, average fees","engine":"amm_sim_rs/src/simulation/engine.rs:142-162, 164-205, 222-261","done":true},{"what":"gas: afterSwap limit 250,000, out of gas or revert keeps the fees in force","engine":"amm_sim_rs/src/evm/strategy.rs:32-33; amm_sim_rs/src/amm/cfmm.rs:295-298","done":false,"note":"the callback is native numba; no gas model"},{"what":"single-pool and more-than-two-pool routing","engine":"amm_sim_rs/src/market/router.rs:145-178, 250-264","done":false,"note":"unreachable: the engine always runs two pools"}],"rng":{"generator":"rand_pcg Pcg64 = Lcg128Xsl64: 128-bit LCG, multiplier 0x2360ED051FC65DA44385DF649FCCF645, XSL-RR 64-bit output; in enginecore as two uint64 limbs","how_seeded":"SeedableRng::seed_from_u64 (rand_core): eight PCG32 words (mul 6364136223846793005, inc 11634580027462260723) fill the 32-byte seed little endian; state = words 0..3, increment = words 4..7 | 1; state += increment; one LCG step. Price stream: seed_from_u64(config.seed). Retail stream: seed_from_u64(config.seed + 1). Config: numpy default_rng(seed).uniform for retail_mean_size [19, 21], retail_arrival_rate [0.6, 1.0], gbm_sigma [0.000882, 0.001008], in that order","distributions":{"price":"z = StandardNormal (ziggurat, 257-entry ZIG_NORM_X/F tables, u from bits >> 12 in [-1, 1), tail by two Open01 logs); price *= exp((mu - 0.5 sigma^2) dt + sigma sqrt(dt) z) with the C library exp; one z per step","arrivals":"Poisson(max(rate, 0.01)), Knuth product method (lambda < 12): p *= Standard f64 while p > exp(-lambda), exp from the libm crate; drawn once per step, first","size":"LogNormal(mu = ln(mean) - 0.5 * 1.2^2, sigma = 1.2): libm-crate exp(mu + sigma * z), z a ziggurat StandardNormal; per order, before the side","side":"Standard f64 (53 high bits * 2^-53) < 0.5 is a buy"},"crate_versions":{"engine_cargo_toml":{"rand":"0.8","rand_pcg":"0.3","rand_distr":"0.4"},"release_wheel":"not known: the repository has no Cargo.lock and the wheel carries no rand crate version strings (it does carry revm-18.0.0 and the compiler commit /rustc/58cf8f9c35b355199727627d07ae34a4e2846d67, the same commit as the toolchain of the patched build here)","transcribed_from":{"rand":"0.8.5","rand_core":"0.6.4","rand_pcg":"0.3.1","rand_distr":"0.4.3","libm":"0.2.8 (exp.rs differs from 0.2.11 and 0.2.15 in formatting only)","num-traits":"0.2.19"},"patched_build_cargo_lock":{"libm":["0.2.16"],"num-traits":["0.2.19"],"pyo3":["0.22.6"],"rand":["0.8.8","0.9.5","0.10.3"],"rand_core":["0.6.4","0.9.5","0.10.1"],"rand_distr":["0.4.3"],"rand_pcg":["0.3.1"],"revm":["18.0.0"]}},"checked":"tests/selfcheck.py: {\"draws_each\": 20000, \"mismatches\": 0, \"seeds\": 6} (raw u64 and StandardNormal against a Python big-integer transcription); the engine comparison above checks the rest"},"policy_callback":{"init":"init_fn(initial_x_wad, initial_y_wad, state, params) -> (bid_fee_wad, ask_fee_wad)","swap":"swap_fn(is_buy, amount_x_wad, amount_y_wad, timestamp, reserve_x_wad, reserve_y_wad, state, params) -> (bid_fee_wad, ask_fee_wad)","types":"the four amounts are float64 holding the exact integer trunc(fl(value * 1e18)) the engine encodes (it can exceed int64: reserve_y is about 1e22); wad_split(w) gives exact (mantissa, shift); fees int64 WAD; timestamp int64; state float64[n_state] zeroed per run; params any array","delivered":"const_policy(bid_bps, ask_bps)","api":"config_for(seed); run(seed, policy, steps=False, events=False); run_batch(seeds, policy) -> float64[n, 25], column 0 = edges[submission]; compiled entry run_one(seed, sigma, rate, mean_size, n_steps, init_fn, swap_fn, params, state, out, steplog, evlog)"},"runs_per_core_s":209.4,"speed":{"unit":"warm runs per core-second (process_time), one process, 64 seeds, constant 25/45 policy, median of 3","all":[208.7,209.4,214.5],"note":"shared machine; not optimised: a run is 10,000 steps and about 22,000 trades with the engine divisions and square roots kept as they are"},"code_zb64":"eNrtvWt7G8exLprP/BWzmSchYIHQ3C+U6RPalhw9y5J1JDmxw8NgDYABCQsEsABQJJ34v5/3reqZ6RmAF3utODt7h48tcnr6Wveq7q4p5ufTeTFarIr+8vY3/5gfFz9xGMpv/DR/e16YeFFZpuWeG4bxbxz3N7/Cz9V6k68w/G/+7/zZ398vbBJwDh19Ppzk083F5GrmTPL1xllPL69m+Wa6mDus6UwWK2dzUThv8lU+np5fOievXjmji3w2Q/Oiv7f3xaoYTzdHzvv8doa6nfPN5ejDfHp+sen2nHN0fTXsjxaXT+vyp/nl5SHG+UOYen4eB6kfeF7sh4UXuXE+yr3AG+VBNAqSdJIF7jjbWxXrIl+NLp6uF7OPxdjpmN/LxWw6uu05q2KJP3If6+rJbLmUw3WxuVo61xdFMUPhdK0Lwu/lasHW+Xk+na83XSzizxf5RutM10dO7syvLoe5s1nl8/VoNV0KOBYT6fotCMmAzhkWcyx+tBkCNreyrAoyf9iLh3Hme5N0HMZB4IV5noyy2A+wzGHhR7kf+WE0SdzQ6aDhAPAYrNYA2QL9Al7L6QxTHKE3Z1msnNXV/GjPsbDzVKfQX60dFG+KpTNbLJZHWNt0VEhBz8lXwynWcF6gU2d9NbycrtdcCZYxd+aL1WU+m/5YrAi/TT6dof87fharcYGBVourDeE2Wi3WawHG5noBJCxm6x5neSjzGOXLzdWq6DnFGCPnc6Bpzr4v89WHYvNUJjgACkbFeo3p98oXOgldEPvWBR6sncX13AEmxotLrGtV5Jdrp/NmdB6HzvHdU/56dO756XfrGaqti2KMeV+DGOXvwWS1uBxcxWGHT12Zo/zpPHG87jPnx+n5+dUq39zd+7sN2uSr8WsBYs/5j/kV+n6zAIAX857z9eK8fFPWdCaYSMlM6+m4eHbP3MvmMjPTq7PJPwAoN0uHs5duZtPhpTPCRAHs5WJF3FwUIPF8fXffAzYaoBtllJpcpH/F6hfseZWvbg/WXfQE8nw6mlxeKmqqnw8gGxKq0EQ1p/UGTDZ2yLGrj+gPfFV8LFa3zn9dLTjP6sXVcoyJj++e6fDWmc5Hq+KymG9AJZMCjT4Uyw1KwaHrYplz5c7wagTqqemrIvqrlUx4NFusi/EhQA/ymf44nZ8rIXxwjp3VjfOJg7kZ1r5ccKxeOVXQ6GSKx+KmGGGR9RDCB6saHOCCQ3KBs4YYQgO3T32HLrHYi8Vs3LOZbzKdkbMn09Was97cLov10+t8LKygT5j+uBhM55OFFBYfL5+C8LHY81sdNL9cXAEoQh4VQA1XLhSvIhnvBm6OmpApI6LA+fPJlwAqugeTPwNswYlXqzknWYCYhhCWjld4CUXnqphcrSkDMDLGuXsAQRcwBbiDwHJQpeCuMwbNYHF4PVjm0xUE3noBHOWXS5Y5cxKLAwwW672XG444X2yMbjlY24JepsCXXO6H6QZvQagU/EcoAs4xIKj6PyBMIeTz+UYajFf5tRDrHkQ8OjECBSrgjUBMJO4wH31wOtfUCfkEmH53nS85lQv0AHnRd95D7KmKmACGFMdrSufpfLoZTOYd/p7ms8HNAHjtOeXjrT5iMkJdIN/Lddc5/MzpDKdjgYi8z9cfygdy3xqDS6frwfAK6k1xX/ZtnkzXm+llge4vlxWflfXKx8YcLOw9bjbvqVoXV6uaAGkhzBb5BsKNlE7uEtl9k482JU0ppXUms87HfHZVgOVATWm3a0l5/CJZrPc6f87HR0cinyEwn0mVshtgIHfGi6vhjHJrMb4abYR67AmA5jY6+oywAsbxPMrnKBtBwO+hrzg8qsEhnQ7Bz5iT7wO134JwsNaBsHKnKyK7uZrZ9HK47jsvSOBcv3RJHtrrBK4zXK4hWIIBJED7f/T+nwL4/9SllPPOV6v81oEiXpCxNkaM5qsN5VKRjy6o/Z0O2U3ZGqROMQsZB/b5T0Xdf2Kxt4YopUPiPB9D889u+86XxWwKxipNpmkBK6fiC7IqGODkzUspnEzPB1i16sZnWm2gAwtpYIVKFvgD7zE3qdqrrDFqk/Xxi3y2BomBn0Eo+qS1B8N8M7qQNuuyEXnqwrJ70GYluGF9WESdfr8POw1G7N70kqoOonhzsVc+KC9Dps2Xe6KJFA7l2x+mG9ipb59/+fI9cNPZ/wWm6r7FK/uPtVudlt263917/vqrl6+fYxb799mOjzUd9/f2fkupNyDgis1UDMPm30QnpOWR8/nJu+dfY+zBu+fv3798/dU74Y6q9E8nb1+evP7i+d7rwbv3z9+8wxQ9Oml7L1+/fP/y5OvBm7cvv3iupf269Lutku/Llij76vNXg1ffoqB8+JII8PDw9vn7k5dfDz7/9nt0/M3nUiUqS9+9/Aum+fKrVydS29979fzktZa+PXn9FWfR8bK+23N89NXdO3n79uWfMPTbk/dWDbcf9xx5L13ZLzC7NPVVUWOuaXdv79XJd4MXz58PqAuPQUd9YeuOt83GwspKCb91VHEfecne62/evjr5GnN8u6uf4I5efuv8KZ/DIsjflQoepHLkQJB84nz+5t3eq5evByevvvn29XuFIu2KB39+61QWypGXpnt733z7fvDi5fOvv3wn9E/DfFCbJPs9R4tql4BFsNpblVhi12lp/32YXoOPi9nVJfVMs2nj1X19qBdwVzftt/fO5uP5oFRlrcngTanX7Df39dCEjd1D881kOoeqh0+9GohtvWuFpWZur61U0ffNqW7dHLdufR9MSutm3RpbLM61BWH1+LRALD5ZqhqG6+1+qUK2FiSFbQxSAV5Jx6IZBqvF9RpykTLHJlEbgGi0XGza/bDofoJtG6db9AshvJs+HqaNn4vGnSDa6nMnxP5bGK/GbVGpDmQVdqFJvoEhBnxIwME4PWNHSMPpfJhCW7h1SAGi1YQNxKNRJ1oiFVooBGSa+T0JEmCEQw/msBiywLIEENg7DP6r27XzHUyW/HpQGriooZ3Aa6OV5XxvrASxQD+hRQqDAYJgvqahlKN7nSuXQMPMmIHOXYa8ccfxkrPr7z3/0/PXDTlZmdMEGVciVIa6Hdfy6HqeFUvpbmPA2dcVC2VZxrv1fFs+N6z2JpKlYLvvJqPY8Gs93zb6b/S9s18hm5pWQCAAMMMwg/EUXhOUUdgPnPVq9LQMlww2OUxzxnSczl9efjWgRhy87TnV399Zf7+AyTVaLKdAAxx9jbLt8e1bms/9OAq9yE/TKIipoJMs3vvLd6pQxbrtnMqUg37muUmUZFEWBYmb9baaSlEYZn6S+lkaxW4WhxHLAt/1wzAJgjTIvDhmkQ+zKoncyHfDxPWznhnCC5M0zfw0i7zEk7ZuGkR+7KEL1/ODQIowQJAkmZfEaRxEIWyTfpaksRv4SZambspRURSEQYwaie8maRT6OobfT7PQ8z2Xc4adl7JqGiVekCYBVu9jKGme+n6aJEEWp35kipLMha3oJSFsA3QpTRMsM0RBhEmhSVyOkgR+DLhEmRv6qZ9IVTfKgiCOMK5nWsepG3lhHAY+Ju37UhTFfhq4AUAdRYCblAU0f4MsiPHCD6tBAHUgJfLSME2iMJVJRgBeEmVYtxtnmRbFmQs4AY4plx1LGfDkexghABBiV2YTBVhX5AcoT4GAcpTI86IQPzDAoyD0A1YNsyDCLAHJGBByZX1hEnthlgFkceaFgdaLMh8oTPDINWhZ6CfoyUu9DHON03Kc0I8x6Sxl34kvsww9z8XqgJwMw0SymgDrC9EXUO6GqSv1AmDdB/YxazfWplinDzqNYhBS6qUVzILIy0ATfgISUlAEQYLePcAwAzg8gTigDGrA2GlMd0CKPFiyIAZgMVNQ+1mSgCbDNHNBNVk1BJCZgpNAp76fhTIG/kTzLHNBIqki1Y+ymIyEOQMTggAfTJIQJVkYAahaFgBUYB3gKwWZVGMAbQAqKA9E6UaCANJmFMcgOEwTCJMyFzQURWEs7Cg9YlGYR5LQoSJzSFmCpYASQfFpDEyXw4BdY8wwdcmFuhQQTeolRB6mGiuavTAClmNMJ4x9N9B6mGCaeCmgAfqWEj90AS8POEf7qCIw0AVK6NoR9zJtzw1C8FlExoRQYJGbEVExqQhodWVcDBoAdxn/iSIZxE0AMNeHYPBikEgFMEw1icEloBqwRSyjuJBfbpIFHiCTxoJTNwxRB72BCRJdHNYOmYJeE/A4RISU+ZxZht643qAaBD1hlkEItg8ST6u6CdYNZgHcYhKO1wcBgWBC9BCB3SGaWJaClWNUjj1ZtZa5IN4UpA+KA2PoMChPPJ+UyaknIFCpC2zCFY7DLISE0C4xZVQCy0ICEa4oCsHNGJPbh0mkRRBJgDGlFIgvq8bwU5G4QIILLOp8vCwiVOIo8yAeUy1Dh2FE6KKJrwO7pFUwPoRSGMYyDMQuABD5IFDguhwFqwhC0ggkC/hRa4I4yNqxD9IGXWoZwQjpC6Hmg1qkDKDH8iHSsiQOfJkhRgQvgkUTEGmY1uNAxkWQ2ZwYRIe2D0CELpBCXvPTWMtQI8M6IdRA+loGZZWAKsBqoPtAVojOE8gKwIvcksTVOC4BDvBAKsSZwhzSBaokSklYGMrXMgANsg5UC8UmJWnoCmRRy8d6pAwQiaFRQdpg96gcBHovA/lA2IL1E1kLRS/4j5ik4BeYJQQMdBfmCeEvhJeEUNkpFXSSgVqkCDoZ2hFKCQwcV+hPsDhA2hP0AzxSFVoc1OlSPCVJpINAUUO0oBRkG7pahoWBaCNqINeNtYjiIyVrcarlKJAtEOUxRDLIJVDmiCG9IDCgVgHDKE20DNIT8wBoQGOBTDzGzKlWoJNBe66AGhgjBiHNoXegAqtxQBAhVQR0SJJmOg4kWhISj0BaaMYGIfuUyKDgIHZ1HEhEN6bSAEzwo2VYNDASEw++Xw1DzgNFUYFDyOmUQKL4GyuF1AqU16G3E8azMAa4KdAlQuVD04E1fapWFoG4YJQAUyEMKNhA5TBQ8WB9soTvlTNHE6hKqiNQXeLJ0FEC1YVqPgeBUpEyCkuIKXAdtbm2hWKnioDuh5zLKqhFwuxZCgMBdKpVoeygAolID9aNKfNBPHiEbsPYgm+8w1ohx8IgRZ8CNPQObQwuhix1KyuG5dQvLjQRIKdEGYGeIFthKADJma+roQwFXmOQb6QESaID0cNY8XwQm8wG8g9KAR1AckBuVaQGCQ9jIsyABTKBdAkBARpyYbEAFoagweqgISwXGIOU1z5jkC34NwVd+boYMALmQZPIBWUlaTUMWC2F5IOSBdcqpYZi1YJmfJocmQ4D+AN/PgQkbGrhYdB7BLUAWiaHqSwMyavQtUQixGG9Guh6qFWaebDXzJQ8sifEF2CM5jqMCyiA20GMoDNPV+PCbASeQHwxCYtlAANUIaBO7CY1qYF8MADgAQoGIrUumBHmAKAJQaUETQOP1jaA7gKVMgy7JwPDBgYBpFrkUuzAtAImYVxVo4CEQhFdrKsSA5QEIoKqgGmCLgItAw/DvAADQKb5smpqqEyoDyyZBtoWFA+qALTJkGFF0JAqsKAhFH12KjU90ie4ELYPeFSKXGrXTGwkULEpw6iAM12M0DCsTxMY6IS6B7nVKoByB3iB3E7plQgaIW6h88HdCUAXqApB73ADQPVxDDI1fcawW4DwxOV8VArAToQpk1IIoTSshI0P+QVhAeaBMoY8kLogpjShwoDWUKoC9jgPqGlwGGavZV5GoxG0DpEu2PKBd0horAZs6laYQe9QlwG9CwgX1YfAvEdjCMIFmtLTxcAVENlLhRGrRgPVkgtB/AlNHy2CTRFFVDg0LyqYwb5w6TRAIqegf4EFlSsewCYg9VQXQzhQ8oHqMVhgyuCRgdBIwZGhRyq8lEZpQJujJjRIe4Ajot1HySsww4wpRUPqT1iG2mdA2wPMGVOY6HRguWCVET1AsKfA0YPlgkVCi9B4rZgGoM7gkcDkYB+qbcgyHDQTWZ7KLGGRw56hPAM34r2U0SKCVKIhB9dQ6wEHwDyqQ6/CjirHoakLnRsT56lYmyiDqsO0AXX612oIUCNlshIfU1Ix6dKPobMQ0YxKBGF0VQEGj+PTxq7GgbyGZQ9pA9qGEpO6fkIHDhQIfonUXHW9jC4c4IFaMNa0DNCCrUIBQRkqZWAjDA13C75cVloDLsxiUAacVojjLBOlgTJwJYwcaGmANKRZ5NLZT0hEDD1goqmWuQwxAPQwmMVTcWkSA4xQQb6YiX41DpxgKCCXHgw0SSJ1QzEFaa5SbenYAWxziCuXHJFROqCMjhNgEASyTaRj06OCxEd1CIOoGgaOBn1KegOJae2K9CHTQWSQ81wYxhADamQBJNR1KEvBXfjJaK14rswGpgBgDh8JMjDMSvWJcpjeZHhqcDSTcaCfKRZQnRrSFWik9OFBVJgNbJZAVg3VDk0X0HCjlyerQe+RR+Md86OXUY3jUTTDuoR0BFgFE9DbmQ8ZAMIE5kMZO2GQIyMa6Or50idUkBiOYCtwmI5DBxRiCnPxxJQrx6EtB28FQ3ASgewdQaRBrIBVAD96n1IGWDNeAyaBkklljQn9XtiXLj1y4SiUgZnprWB9YD0/qcYBK1DyekRJGgrcYW9BtqQMYZEMZBzwEmUpDU8QcSx9guxRQGkDK0fBC5qjjQdRldLmycphoDaAWVh69Ox9JcwYcozMLKQuVhTKXJonkGUYBDaJTAfTiuldQG0G7EPKKLjg3ydkySQohwFaPUY/INrp/QqEwYP0oMgEIk2kDBrYpzEIuQhEyTBw02lLxAxMQdKbwpj+PFAJPNG9qvADGmfECbZnSozEsiI6uCm9HmCX0TFZEiv6HgaDxIXNJdCErqSb6WV08aJM4QGx4onXBD6HiKo4CD64T0KmPwV1KYtye3tnPWfM4zvH82Xf7Ox39/7yYjtmKbt48CsZ1xBJFyusGUuEBCAEYBHStdZSFGZi1FAuByps0AEsc0CR4ILMS8xmJn2ykKEayLyQrnQ1IqMTjMcxQOCrJHFdrBBmCwwxgB8cI7CADeTDiaORnFF0aZlHs5e+akIZqIQAag7pV9IEYAzCrajYJdbhwkCBQjH6rpkeFSUGJQNCzKemE0pvYES6D5Q7YBTAenFJhzQLJZzKUsaSXKgmlw5I5leyEwTGIBasGHA4JJLKEYZD8AxQYaHQMlGspZB1MB/BuYzRBJ4ZkRGHjL5pykF12TCOAQtIrMyn61WxDweCk+UxIkblr5WBNNAxbCQI3cA1hTRQfQaXoDI8MxY40eUiGJiCalHgQNoFMbiNcRCqkmos2B8prWhGqWH1KFUwgMHgkh/Rvo4CXVrI8CKtWQAQvBwr2KB5PfCz2KIAqwp4kAPZGoYYBgWH1WuLGKZi+INhGiNa6J6gO4a8oRQYJ9DSmLIfYs2llRLqkiNaQhlVLYNimUEzzWD6yyQZhu4qCQ58MoIC7UOCTlIdL4YXRcOddEglqoWwgblYaHxiPNPCjKqBogLc4KrepLOQMJjgUpN7WU2Y0ISgdJAPBDQEsnaRAD0qmjOgNNO1YSohlQalF2OhUpiKI8HYLZRdEplC6MSABE1+qELHfAFFAilDJzsmALU2zRsMw+AkJICiE9qH/gSEIk1Glakug1jQ3qnoNzcxhYHEUyCqKFHjmgUyhuhBCFh6QEtAayeZbEBQI9IrZSHVL+w1Gqxged/1tdBnXBQ+DEYni2khg44+bUxfQvflYBopwLQSqI/EV9VJ/00cR2AMCDX9gmMzkj+sWYZ8tSZwAsFKHxA6I1LYMgLITjEYow6uVw0GEyAlCUtoWQW2yAtuHMDEBuyVPjxfnEefGpU7GFoGwosZbvBJUypePGIFMpPmPrRVXIlJj8zDqDOtZ9+odMCTwRYYq4AhYKz9wiNimAY0Cu2UmH7hk9IsZnSMxohCgI54RHiDZuAfVGOFdNvoBFEOJJ6pzBiWTzoDlpNMERbSxAX8oGMxKxWmMFwgbeAQMHLPIIsWAkLwWD1htySu6J7hcZpvYSIelUpCjwYGDRPgJ6IVIoVo7JGgYS8Ad0q0XkzWAPfSVoLZrquloUJQJkScW0t/j5F0WKQhtyoiV0nRo+KJaN0zwBnFOhiWDu4EddN6zFSKcVCRVrQMQfs6GGBBOykkugO3xhjNfcCKwWNgR+vSJIcK9amyoM8VYSmVGXDATT6YhjqpjKoY0wfXQLSqzIawh13v0lzkFljFzh6sVEBPRCjcNZ0rnXyf0VqRS0LIMAdpPft0sui3BFpIsx34ZrTOVz1AE8ilqyQRk6yiDJ8hXQlwQcMwGC+VPfFrYPSQnODraSEoEASLKXBUUxH0iDJ4oxEjw7Im6saMwSF4zFBuFSP7jNPQMkI3oES1e3wOQxGKl9yD0EI4NaEne6t0n7UwoL0Uki5gEqWRr4UMWoBfqYij2rKFFI24vxKK5xOoMQgZzE0OiGnVcFrGiIpLdzwwbOHzHFzGfVWXEVk1gX1uPjHKBwFPDFYD0QbyyPjQrVAqWpliBsQES5/hPoMATEg8BTK4WRK0IdwjilfwjwFezBESqriU0fV6JMCYUguowgQ9lQwgHuohhgBjA1AAQiJ80FVxoiKQwfSIxjbESgIuMhUZaKLBAQEMeqrGAXw9WifQKFBKOgwokDKVkhU2nEIOWgQjcaePOkBp3KcnhxqozqCdFoHZYJ7BaGPA11oQyRl4ZzyQzoqMhBkFHjdQGasBDWgZ1BcYmszLIKKWyb6Ox81I8K/CHbYijFduzoEXCU8zUoBVslcv4jaJq8IawIXgh4AQw0udTkbHfAahMzXMdCifdj3EIkZJVMzSDYUxDoXrsWpF4bDE6KZDN3ObOdHZA7cStoUj5xm2oRnt0fnC8JT9UgbqpImViFMQqeFEwQi9yh1ASELCqBwp5L4iFsmZRkphIFi0JnED9qkSMzGT0FYkjUOnmIr0NqG5qDwzV8soxLn7xoAWIyfVSNxNBU+k3FQy9gpdoogUD6QyHK2uDlQiZxDTFS7RmVDlAfmMMmcG8AnPEzCYFtIirFQvi1I6o9xVhSjTaXFbDGIQpOgxXKXDc/uWnAwaCU2kI5A4E8xMei4wGUxhzI0Yj3v59EaqoTL6hAAqUMW9z0QdONAxrLWMqhreqZYl3FJg6Bisn6guCmmGCkZgqxv3nDEWzJtIZBy+kuMwbYloDMRzFDpViBG0Srhr49F60jKQLZjI426u65p6dEa4QYviUHHMiYQhjSlq77C2kuCXZ2KgAEeZr9wYijXgcvMC3p/an1TCsM9j0gX8PHVTGTx0Gddg9NsLVTVR+3GLhUdMuJ1ejRRxBzqVsxQMTGtlhpOoHcgRvuIOzxLpA4XxwEpqnGpubfKwAeYGS1dbJ4yyRgxvAV2BX6+K8fmQYR/IvlTdEWh67r9wBxY4ybSDlPtlPl1LxnkVfCQmHiuB8wPaNDAFC8jeOP0L+Cr1SBnjdjwnIpvfGmig/0he8CjlfBM94A4qQ3fc5VB9RaiFPCYtu9qx1uP+Z8LDBXRb6yAFDD4An9tUUJM6J3A9jwHRRw/pR2gZ5BdWJcZhqgSKifPUiEtDhTJSy+C6gm64QwHrploO44oeT/fQ+Q2V7iKGVWQLjw67kgO3p8Gb8FjhbBtXHdor4z4Rg6FwHrQeT5xA+gYwEwC2ej2YCfcFGZICNWld6oiEEROexPEURMCAhIghNk1sBHCl6mb8mOpSyyBPIsaEPDqzdSCR2+aMkDC6yp0IqZsxsoG6DKioX8vAL7c7IKkpx0w1MB6tFhjr4HQNaLkS9IOycCnTqmG4OcNtbyp7TF0DYtxxcCmpMu5UpFpGKRtwP0K8HSljSJPBRp5ZkiA8y+CaAhTc/ubuch0Rox3I4sxVkUazjJsTsDlhy2caTqMLEUqwEyJey7j1nMrhn9A3oSPao7zv7FLDVFs9EqGj9wuMg2FClb3UOFQj+AcLMmE7aJKYYYeMRy/UjZdTMNCMDMGCkj2NDFLdezQEaLRUqojRBtl4olHoq9KjLQR7EpWJLTU4AGuXtg4kBInL0zLuUlO7B9xgDDVaSRsHJh6EDhyfCjkJhQu3yWOGk3U9ElII6YjQMfRMBBQExLM6NERcVexQQtxcJXt6DNBrRJXGA0wiMahq5xZsB1SH3GjnFo/WpY0B7UbnIzG6OQEVcGQGTGiRaxlj0TA0Um5yhSbKK5Y5w2wxnbZqHCwvpCaIeVZN8UsOk4MMDMBnJqKbxbROAzlGFynO0X0q27wMTKaqlgAcmuskDsiqLKuj1jT8iAy1DTTCbfaPACiGQ00knAeiMl/0h0bdYOLQoWYMAO6bioeUog2GXEoa9msri/o4oHyAZmUQTOry+AOjVjwMlKmqTGkO8bAS8MU9Po32M3ajLgcUoEbwGeHiZlPGLct6i4TOdMwDh7S5fd1UwHJ5AAMOWMqNDd268OUwEY8Q8NSZ2eKQE3fw7APX7Jpwiw1cSO8SeKyglnGTw5NQP7cpdXfnjsDr3uBbjbxeyf2LvcFfnr/9BiWDbztud2/wjdzBwYOHh1eBb97cvDA/KH3neaaKJ0+mjufLU2qeUj75iT75CZ8C0y6QdmXfgbSLTLtI2kWZecr4FAf6FAfyFJonLGbw4kU9QU74268Hf3xZFvFMyPMv3ch78UUcfXkSdvUGCE/qLkfnzlIuQstVkNBBy/cv33z98vnbnnMxPb+QU9uzxbVeatOevy7hdAP7KfryBUTviy++wK8IQ7/54qvAZ7VyrjAwKJJoJ9BFdyNreLlvP5sOOThcrEPQUdnDy9dflNCNGZ93KaBjcT19rv/9n7+JCA8KQFASmCxhuM7vu3to+yd5B+w7T3fWeBN51XtKy0StgJReqr73q/ci0rnlQd8DJgfff/Pm+evBu28/N5UO5WgjY66MKoglXBx6MTtHbZ6LPsRP6476kQUDSN/mxfNejR+YvvZldX1DXuu1Tlvv7f1BbrKNi4kzuLyaXUw7ec8Zdo+EPXIXk82d3zskZy3xpOSzzxxSoRQNWWloVxp6UmJXWrrSFW8gDV1T4lUlnpZ4Usez6gi7aInWuZyOeYqe3Znuu84TPntmAvqInsyjtNIrJtKdqdxo7DU74xjl814DQLyE2FlvDHR+qzdeMR/9/YnFCeinumeOHhdjx/8rsNF9hrpocCotBhdTc2t2MFvwSu9ISvh7tjiTMS6m0v2pq4+zhT56+jiXZ/zziWO4TIullUEnezYvuTq8qirjsW77x5cKKumSHT/hQIEONMpXK96uEIknJdOJVP2UVY+qk/5VPchCKZSps0OMKx36Z/gt1cr3Ht+jrxaoQdkAdU9IvAL4OzzwPsDb+fnRUYP4j5yCdysdkQTO9WI1XssdErkQEviHw1tgSK+UzqabzYy3g8fTfK6zIFQLkzfgWmV8cbnc3HbAMJW8V1ri/Y4pb46Akc6LTtqtVy/dEJ61QHvi1LKpqnfDip1OZ61kBnnv/NVZd/UJ8t7mJcHJYiM9y/soq8qvT6dn0tONvEO1rvN3h0+ffopS0ROHWvx7krPX7Tb6FlRfE0FodU1EoJ2SfUV718SYvA5ar5VMOf71aWjqRHUdTkVUork9KIgikI+EM/DWq7oxI8Wml6Q1UtlYOIWNjwzHPTmuueyZXBHudM3KfGWMJ2aad1Mxq37qPIqIhYbNfHcRMboqn30+a9WyKCiLzGwqadIk/Hlxs9E0IqWcqSs+LBGUVFBHaSXdcY1TQYf3nq/TvVnPtM1fHTM1Iy87fNMgrFlJWbAkLMqCddFaxXkx5117W1iWKsjKXgJWmpB1oXnFcBhON+Qf/6+HPHoDHjt1YY81ZLhR1J84tWHWacDM8JTXmtBiWcxdb+d8vpFX9WzA7IuB9D1gUg/mNVnMQWEw8rDojod/nr959/Lrb14/9bsyzc7WNDtU8U8emiT0DaVF5LPjykBo65yxuVLXnnytxVupY46cq810JnemymtUnfXt5WWxWU1HvCO3uuIlf+1VahWrxWCUrzX1xvXFFOLxPSrVPCGYOW5SZ/Vyal9KlpogChqVZYUrSgm/DRGp2QSER0AEfbcWlWh5hXd/+Q6yrh5w4uTDdeemC87lG6bYOTtq3DczeLix22Cex47brHdzYy6P24W3t+Z6uV2oYDnkMj5hjU/Z9hP8c7R10e1mQFjVJLdV4fahCjItpiPozxbnnZtBF3ahXGTb7urWrnk7aPaFVV9hpljL9ixLEN0A5tt9m7d6e+4QtWxI/uWFATrtJT6csY+yUJBpSQBMQCYIRuocCszUyu3egTIav3UaIt6t9/vANa8Fsp+n6EcT20C1v1gVxefvvnQu11dzpyCv9keSt6jf5pEVs14Ua82QgRHYFe94kgox2YK8IbWnwyvJvsJcO4sriKX51eXhZpWzomT54bj7nOC+Myly5qVyOnz5Rb46X/Q3i8vZM/S/T87lIPu8HbqYTHgnESydX802mqGmSsl0sJYcTFZiJi3pHM7yy+E478rVU0klVuaGYY4GK1eNlV2p77zcYCGTCbNrSeKKc7wbmTGmc83yxLRsYEAm8dJUJcnvCAxz0Za3Y9d9jNFOrCWpbNYiJ4/Y3Xi6KjQtCthjdMGVtqezN/j6tS+eZdxnOD3hGfhYAlMe3EC3OHQ9qSM+Iq/UpDwr5HPHlPFFF24cPCP10VBNKoWhz1PrIQ85MDLIKwLFExeVnr9RNy1u/Lhe5gaJDvX8DfsAIyfVD8N5Ga+eYSQ3YJVA5ht7AXeYMB+GNUKepWEnEWvQlz7k5YpAzwkxNsQtmkCWFLNKhCohd/A9CXu5USI+rRtkqJECvNR6hzRWnU2x3siVYyVu5h3RxDby4si5uHE+c/5I+P795u/OZ8cikTudP0p2MWrlgLqItY63q/3RVIALPPjjydcvBgpG4YROfZLMvQkm49gvwkDr20EQYwL3P06L644VFIEdIt160T2dTtzcH/o/v9P3L19/v7vLIpD0jz+/y89ffrWzR1BS7Af+8Gf22FDVZRY0KCbjP1OKq6YqzU0ybAflsG9lMpYMNPKvEpU3XdtsM/hM3LQfZA5sldf56yPpTgQbvSLlduYl0vxHmqilHDkX2rAo4KihT8u3isijtha5uUuLfLCVf8miFPFPnEO3HzXVUTFbFz+ri0YP260fPbFD72dPxGohNjfVpGW9fBAtJ6Ktqqe+8446xjEvLRr0d1ja2sXMhj4pvp5XYz5uez7NYUtzpbkyQ1NqjWoLMS1EC6tTZJYmxkxHxOeT+sG3HwL7ISwfKOfgWOrsbk10C2YB342g6MXwO3RGXVmzhCAqbvjQssjMdG/32vwwG5MjoGY+tHhuPDwfaHDMJIyaG47a399/wXR4Dj31awc2K6WrpHhshQ6shI0T06JpT0smCDBXsb5gJs0+M0apU2eHCsKtUEEdxBh8q4NoeW43mz8UYZhbIiJXj3/bDL9rqB+3h6rC2Q+M9aMZq+mA2JjJe86PdaSSyYlgSRBut07HTkF4JNkMsm4DcXjV+Vj5M40MbUdOM6kbleFUjk+Y9IKSb3RxTR+SrsuzOrlgvhb5J7nVzEKroM5H019JfNfO/zp2rreIr2QkqSFcKWFjAOra+RQqX5+3ml3bkLFkQMW/1y0fuU4Id12T7HOZeecyn29gBwLA64vphObicAHDUzrqqRHKTCXHtPy1JvWW1O0JTnN5/xnFQkmtsp5PnTumb02ztyVzLntOUXoZYANw4nV3b1fjS8oDGcDuBV4TXPxuTSp28k/JiwkD58Od6T57JtknM6c0SEgyPMKBOjfwwwrP29pgG6nnMKS8HVVKJ9A8njfljEyTGVcGN53VTc9Z3Ur20Dp1YvfI1tZmdUeelx16oVfp4DINzafHd02zV831HGCiqKjWqdsGGLWSn1rlMZ3NC81+U83gE228V+oZk7bUVL4erG608Ik2rcsp4j9ArmsllfoDehDHzHp6aCqVM9RXn+2coLzr2VPC2vZ2rWAHKtbFbPYIXFioCJNDL87uQAX5uyr6jCu/H55tkP0PI6uG/2E1rXtRQCSx2Lw/dGoU6KvHjLtZbJhSVLphm6cWjZj6pkqvqnuodXeh6IYpHwe3O3F0W+PIQlESHXpZ0kLR4+b+D0aIQreakc09FUrwzxMDjQYWK1Rp+U3JLTclt9yUM7q5h1tuGtxy+1hukfRVnSksp+m8yu0K9PWcJYMQV6sRkPJdz/m+57z4HP+f9JwTPJ7g2WSJbWWX7TkjdlB8nC3Oa8VVinOT4kslZZnhq1vlOzZs68C67jXraqwVloPfZVBCUh9PdZdeUotraueBpACuUl7XGZA7Gtzr9p23mk/O6ZTZxnpGCP29otm/KzC7lW4UNFUhRkHm9+UTzVSuQizVR6RJLInZd91D30/36pif4I854BQJJM5dauXF5xi6xFTXdtJ0HW2CtUhA86M2QpdNwa8cYCZQ1flOTb2WtOfPibx6cryr1femFWWAzKyeapmNjUHk2nitp1GXsVazMdR+o0wcpBID3tHj4R94h761W1ZJrl0YaGmTFyd3oaAkoZ+PBMlOVwnNe7Fw6NwJalvACIK+vxtBFRpkRg/jwcyuhQm7VJxL57E/Fi5i/9DPrLD+3bzQVhp3o+LmF3LD7aO54VDH+Aeiodl/fruNGUVCXS+/oS8j7lNuwkr5bV10awzzuhaXYwrret9XhRDm3N3E1NVKnaMKy8JK+s1hU4u0768v8mWB2jW0pfwUKkI2SDfb5bIxqmpm+6Xukm6Xy1Yp9TU3bRR6pLwGJqvKISsDKttvInlzu+NNrAje8SZRBO94k/LNcrs80/F3LN3V8Xe8Eag0trTqdwKU73e/E8Cc3NFQAHFStVQk0pZjjHivuQf2M9k3C8C+4n9bHxGAcxMfetY5BY7oWaQkG4c9CXdsJZy/ue4RNWKIrPiw4kMzjb3N7ENxZiVIk9d/Dsn+dpZlfd8sbMoGaFc9kWJtRHJ3rYoMVBVPtirmWxW344gEgq9AuBe2+s0CZ5JPZ/B+d3/ZwLbuqEol5X7DvCtTmWvs63zIb76cX+b8TMtq+hFyWz/kcVnk8wE3deCVy3GCda/8sIBl5pX23VYif8cRcc2GILYt2++beZVyX5LK7/qgzFEYH/peBvvsxZQ7SBTdnLVTp5HuViMw26p+bqRj5fDVvPn5mjGPW00IL5GhjXORr6WJmZn87XTs1KtdZzb9UFxP10Vf+i2NRFjM6NPjB33mJUQMxCWbflHYHxS4XlzNxuZzFZI7v/rSwGq1WK1re5IT/aEOq2Gxley0ImwoPv3hzIrdtpoJHnY1lBfNpttbdUdBchj55nMe5is4R2FwmChzjlfTCdVux+RTP2SsnX5NSUP234xja6p1aftxwRMjdk0JDa3/a7XpaDWjcJb3B0hXq8cEUFfLdlTTlK/qch60+ub1c3P6J7+UaNVNp8kFTAygNYqb5UBr1Zs23GvtWtnO693jpe7JEn5JtGNX+Cn70EAZ+MwMbbFcPe763LzdSkpv17q8Gszm9q4+++pWGEIn/GdP6n5nQ9DfDvB+/8D7F58/VOHkgQonZgqMxK53Vvj+gQryTaf7q+Sr4ccHqoDIH6oyurocPlwlf6jKfGPXiOpIZ7eiHs193vhGT5UmvVd98MYImp75FlbPaci+VmzetwSAMVGrDya0LdTquwl7TUWexIdpVH47BrRpDvD29KRv+akZsRCrviGWGwXfd3fq6XJvc+hamtr6G+W7dHW7tCUe/dIU3IrW7t2lzN2Gkt6lxVs1PtfTe1aN7c8utPv8GS30JLN8EqtGjHz4wpx/BNB1u8NCKDi8+Y2MJy2czkkqx6XCrJRERTgba1NHNb4F2d8Cotv6Aj5anNTbP629n9Wytsd0NZ8c13vVqk2eiGb4xPnRqkqjmdX3rNH9vtP8otZREB1K8tvGN624F9epLQgvtLZk72GO7YBOVXrbNq1FKC8XJnj91FndtPeX5e2nznL3brEdcWx9qYoO30l7LDsyWQUkt2q0YpM0UZY7Hd3K6FzMN9P51XZPDC9WR8lEPzMY2dHeP3GW3e2jZ1aq/CpCebNrinduZjxqZqN8WcKP+dB2DcAqn1bD7O7fmi2qb1Wpgj6DyZ3BnubWwa6J3Bf0eXCh+sW35tbLEnBtR1us8UyTXzTc4gMWS7uqjvx69fLKwK/Eih8V9d17yE3cERXetabFhzsQCM1uYid3QaS0EUy1QwVP6zxHyaqf/UJW/fyfzao3g4/T1eYqn7XY1Ww1gG2X3R38rbRfNz5sy7AWl2gLe2fnf5StTZTbZrf7Nk13TeDuKPfjeU37OGzw3K/Aae6/CKc1I+4P8JmluIO+5Utys851nc5d3yl11PupjvvzA6WwHe3PSLmHfpjaoc6r2aZ19Hq5bBmAeg4bxZ+VblxzudIA/1hnkFerbis+bAYyfzxpDDAf5KVjqucXTK1D/fCXbYEMFraZhWYtM0S+MmM7meraPVEfrmFerbp6ybE6lX/k8cJ54IWNHjWSbK8MKrL14bOteFTQCsrtiPNa9HNfvNde/Kheu13dO+vupr8qUjk623G8/r5o8u6osn9fDxJFPfTuq2JHmXeGmB8KAe8OBa9Lv8rGQCsQW8l8T8xUt4mDW0/M1FbpjS91vVZdX+p6W1jEirbRYH/ELXQPk0i/LisienO9GEAnbH/m99yrNKB4U9sVfLuCt11Bbo3WOu2GFzrP+c+tt8P+9JuVeRT0nP/c+jvFHevfI75v8104qd4O7yLFnQdERXjoldSnGHjn+/kV40orHpO85fFJmTsnwAjOrbezzbggO57z6OVKlruzFhYrFe9ZbWPF5i7xTl68c3lVD1zHUw5411zE3UdVOa7QfaA3946J0GzjVD9FtUcs6W4kSi8A8E6bRmZZf/Zw90DU5+XZDKPS+TXIHlqXytz7n1PmP0OnP6DXy+CX2cbbAYGGci9r8S6bBHb0LIQJV3TvspQA5F8EQk9BOPzXAKFuX90O7wdhWeuxINzNbbYwTv1Dz0uMNBb/tBTH5Umrm5qp68+zOR3f3yFCt1os7xXqnz8k1D/fJdSHTaF+Wwn1mx0zGjaF+m0l1G92C/Xh/UL9Jq8OJtzsrvDL5PqQcn34oFy/qeS6mQNF+82vINrtdf9i6X7zeOl+87B0v3lAupez/RQ1H7ewuxFa9gVg7xTzN48V87dbYh7/3fzvL+blgIhInFtb4jxGLeS3j1ELN7mJTuU7A1M3w18GYE8BPPw/E8DeowCstQDBCsCWYx32nTrQ7fv+oR97DGjycqmE7x8b+OYWl/Hft0Na3NwqX560LlRvNJfHecuB1f2F043xyZqK5IG5tDqgCJwa148j6iaWPorvJZtXT7fD9q1+grKfjpxtEng+kcaSvuXEKpTTMF1K53qb5a71yWmhbV1o1ZBTQ9su0M+DQoJphZje9GzXDkWrcmpX/v6Bypld+eShrj23UV06N7uF1pZLGhz6bvTQdiR36qQbEz1qbuFto0tMl10oMy/uRRv7DMs+TUyr8TIuXwpztl4Son656pJZnjYu7JjtskazrNUsf1wzL7DbfdeejBfaryv8yisJYOjOWVUmh9P0lFVdmJaFrlWYlYVBXei7ZaFvFXqGWqzWvm9Iwi4Lz5oBo/LQefO0Oc8j8XiOnMrg/vf0nCmnuFn86ONH84HZXsa45a5leTDIOoogSTei7o7jBB8fW7PM31Tt5VdD77onZ5/M4ep2ncyxz2OtT384EwjI75Ue2VE4yB+/7CSWQYjpvHkiq75hNS5m048Fb1EtF7PpaMobVqPFHP3NN3LYzMaavBhwFh1zNEC/Fd0rTwrol6Lb2/5HjdxaUgZglK9Jo9uDcIX1IUDrw9X1xQZ9qj6T3XMa36+uHxtz2ttpDjxqivXkBFS3HX6/fUi88JPtw2rjfH9/v3MXpvRoWgVg9PAUjfVU3zkQwbNlzvXFYlY4w3w9XfNI0Xyzrs6LaS+Nz7rgfTkTOpSe+8knzIXJ4nJeVbF9Xd0+XqXrrtHbs7BQTr2mmeXt5mIxlzB9BZXJ9JznsTtWFi7MmR9M/zDdHKyd4WKxWcPGWz5dXy4+FAOjOuqWTudVvhldvL2az+HpAu/TGfPX8bXe4wC3YFHjorwzD8dkWeXJGKzm5+aA13iVX6/N7sPAOlxlSponveqjaZLvIt/oCZvm2b+OdVxyZy/twaz7InMjYDQ9X7893WOZc3UkbGD2AfC6fzWfYtmXnU9ePT95rQfA3p68/socXVupQGpUPHn79uWfTr5GtfeNurrAVmU5TNboUYlAMx7oYb6eeeJg1UO9SsMTEGXmWKnyxfFroEpFzvrYHK0vQNqb6slIz2PeUTXC7RhLfP/8zbvmYVF0bd3TGU9HG16xrk+C1gdBmedAhlWhbh5rRNzFkNSdMmvZ5DN/rcWpZQdqbza4PoCSCFwLsqXeshHY5ohSPdo6ZFbMO41Drdtax9Jl2qa0HiQcKn/oZkTPYW/2Gdj79Z3pLWV+LNPjEycO2a2iqtFv44Dsf0s9lmqvOr+p4OndAUnrbnBpNt2jBVvmeGkabGu/+roESarz43TZsWmKp3A3QPZ60ynTFRjmWPGoXqfESxMHQm94q5s8R5S/xh7qnrXhKnVr9hkMKfpKU6jBRY9jFcosHhO8kjOCktHjcjmdoYiHCatrcDJMzVAGM84pcSyDdxXfFlWePdOjjIvZ1SWMuDJvj3X8Sg5lWkecVwWzKsmJa75anx7UlQ/O/tEMyVUwbybBb7StnJeXF+a+w+S8oUBtXt1qsSO9b5/5HWDQdWywBRWLrxscdg9odzBSbRZX0zNE0c4yI23ztZw5OL9aXK21NtZ2ekQXvNu2dO6r7p090J9/1t3Fiq0hHmup2xzFAjACcD0YzPPLYjCgp78/ABSm88Fg31zYvyRNOetbc+BVTvwdi42DMkDqnMGVrqRpJMBNWZc3+JViMqaHct3q5lKjqb+7qa9NdV99KAllG82C3c0CbRboYDTvWu3C3e3CRju5mnBsSQd1KGTpPQOBJ86829uyScUe7dbuCM8Rk6Ap5u7shMNZ7gn8Sc6Yps1y1TFWAD0Y9Pubn/8juameghqmm9v+8vY3/4gfojcOQ/mNn9Zv+RR4WablHr9W8RvH/c2v8HMF+l9h+N/83/kDod8iAefQ6AumqOZzfg6GX2uSurcAl3mteX2ZEU9+8yg4hY8U4Hd/b+8LaL7p5sh5n9/O6Eacby5HH+bM8QuyPp9uLq6GcDMun9blT/PLy8P19PIPYer5eRykfsAvEYUFv0eRj3Iv8EZ5EI2CJJ1kgTvO9uhK5qvRxdP1YvaxGPed59UtJvhti+qqx6byd3T2gwJOAlfXQSmV8iV+hVHBXHHjLib/AjNmVq7KJTzkKUNK4ZXkdwncp4HriJMpl9v96GkY8bl0HYVnRc+aCLI17pZl8W5D++r8to9ldCuIW3ioWvBmveh5iOSmlFcN2zGOTClX+335g59JqWGwHq2KYj6FCySNnlGJX/BRErh4bs933R5aOVdyYFHwCttp7VjmBLpZXMMlL1aH8h76YskbYV8TkdeSyvnd9PKtHLzqqzUGD4HtV8WsyCFPry+KYtaKtNYboz05DKp/0/aaz9Y9p8odIMl0mGEA5szGZJfhIF1nObtaS0ZI2WpqnYXpCEKkN16wG1p3q3jw/eqSJxvRWQ7LiWPtwgXhZwBCk645ANen0vtQwHKoWNFok/Oe+R+NzZSzg3MCfUm8HklTAUllqM0Xey01Pp5+nI55RlSvm9CbYorsNd3i0iWvaE0Ix/LjbUZu+f79O3x/dHu5+CiUAepX+9VwwPXFYq1AYpVCUxpN158zLGSFfjQm9H0V9PnOXPBkhiBAea91UBN1i1WvMVVSOvh5VpSpoarFGSu0V/JECfjx7dyGe4sEFLoUWZB5mzpnkeenTWYXWoEz8PaKwR8GVUrQYQ4fp6vFXHPD98lPxOFTFPfXF8L5JhSzJVwP2fxTEToXxegDuOYzFF4vVh+cT8fTFR/ojZoWP6xBYDTMjZ0FiwRv1kX5LO/N34t1+RdQejXa7Fm2mflT8y/98flbfuZise4vuZ2PUWnfdcrnfLjm785gANKC2QfDgsaQvAMYitWG0dh2a3bK9FjvvuE3IA4ODp4+dd69+fK7w6/Bv2h1+HIMYE0n02J15Lx6+X4P738FBeG0FYSMa2N5uVosJjVZk1Ga+k9R4XSUaWuXCVpiCRK+RBnIcMw6f3X7ad8Pn+2VAP/byatXpWz/HDLvJyW3/f7T1gsK/v1nVbOX1uue8547sC/nk0Xd3K5g2u5VayhfUNS0xnH+JtxAX8WPYmd5NQQH1WHPz19+Cez9bux84nz+5t2ze+uevPuPRl01a01yWyefgJFfVtfUOqaXXtld1yluUGMOWbZk+l2IkNWKLFZe3d3R4m/tK2QdzLfHiXR1qj/tmsQ7BqwrEIrfPc43+a8ygfNi85rc8fBgzFoMMXtZXC5WtztG2heiHfxujP/2y8F+2gOjSfj3+Q2QrCJFfblSWlGqiSA7MpehRZJKQJVie/1ouW3SFVeS2xLWvGddEZ9U2i2o+3tffv968Pbbryl+Ogf0Sp3KjnpWY+tIHMEnT9YzqCf4Ns+Mj+dLVspqks7vnIgRdG7BdWQFzv/jJM6R43adg4bQP0CFOar73WfG7fOjdlcBu+LGY8csnRcfo8JL0WmmnT6h8jBaDC8919XXgbx+xlUcdGWN/wpS8JUo9v+eDOwZU2ZtRMy/skz8lUVX4KrgZIhM//oFQszZWJP5efMoxTpZrWQ0nm5/VucoKEuPnfmzrXbDmiH7u1ly028xZc2FW73lNU/2d3Plpn8fX27693HmFvCHJezze0H/Pyi+v7ydvyGXbcluRpphsJZhom4jrqZbaRCncz22I6SOwmFe1fjB3KOj62nnPgZRfeJ4/OYZ3/6hqleO9ws3i3flDA1cYkl84e2yu8b/R+0jb09Xc22YDEn2LSEbXmWl+vTH8AGNk2zlNrIovE4I9YCyyew0iQOT8lXI2+ozkI812Yu3qNzUuxM7w23k5A3cmAYlUfQq9PTqcLlnpUgwRCt56W+aG/TqecAzGH3oHHw6Pug5N9VuSjGzP0w2NnnVeYh92G0lQZTDtI2DZWPnqaYDYRPoRf4edsu+GZIuOUcuJZd+Uv9kdX5FL+0Nn1bm20Lwd/PxeJCbd50D8coOSFD/dTWFOj5mqp4769JZe3Rl2GKPriv+K2rLjsKUxyBNMOfYBHPubDnf2apKvbHdoI5N7Gx5d8PKt97ZLq3TY6OtoICt1wbw9/iRpdeZ94EKEyPHu8v8A6yjFZDeJ9iZcXIKM3jxwYKkkYRWgM0uhq00gK00WK23K4ttyu2w0V5jk0p2GDUin/dNTN78AXbM+/NulTFDTkopN/qCo9Y+lS028yko+d0tYH/5/AbS92C+0ODpdtgNJH3rDAtHkoxcFKviQEcszwJxJ61zoBsMgYv/DmhHyHZbzylf+NEgjPCC3xIPo251OtBEiso9t8GQiaidOoFRPXvrk1o8G2iFMM0JkI51XG5rp5hNRv3GLl59eI5WeGfUr895HB+b8xD0IEb9Hec5WEV+N2pYu/vHMmxr80srl5vpxzIns1Fr3pVqz6T4kBrbaT7aPVa6s9Xiu9b729b773f2RjhcXpmqJqFT/Wa8sd6YFE7tHgw4CIkaomiylajovta8RghvYNhsW15LNXWFZomuGp0lGUHFipOw+GAMD7Nbdqo7vIaC1taFA6JloDG5uh6pkGGlnlNum5Ekq4Nw9W4YvwBUh7J+WEAPlJJC2x/YHsGBRX+WbGnHsvjQ3Slq5PYyHWZ++EnqYYTrA8lvP2mGsif9a/hMRYeu4O+cavuvXpGVuIMrp3nQXxarycA41h3rsxlyWOneHQSZs91A4fxkZ8fMXVGjjkJQsL3VqXLvnXuY1j4mID0qtzLLxvPznnTeOk2dryn7neL0gBUP5AB5M0ZLmunnS4B4LEeLzIGs6gCGYlbXeIx+GN84OOtZQv1YN0ZHpzv229sn+xVUF8WNaVR12O2jsEMnPF9zGHHExDAaLIv8wwDFGPX+3quUUdSTmI+XnHUt6P3W2lupAtGyCdDeXtEb7GsLa2PRAi2ZLIdLOk1iaIr006NctmMGeoyinXZ1LWlOSpVpkYToRBlVgOpYz3JK4XS3dgBa0tbV/UrBFuu+WVa3fSJfTwfNeDCoos3OfRRZHmvTJIvmVFuTce0DCjyx0rxMP5hMi5lof3fr9kBtE/RbR8SrZE0D+RAsoVzAPysoczrtpE11uiLJ+9S3Nri282DMtQ73vXYkPNGX3H1pnuLZ7ifHiuXo/kG9t3bQk9b2XtvsVJZwP790DmTK1oDcpWvOoO7Le0xfmiwBOmtl+rIKrL78B/oCmJrTWs7vmlbwiK4as2JXu2cVPtAVT/8ynXBjZpNCDjCXfUQP9MGjwrv68Kw+4rMdWaDka5gqKm96zq0oUBLD7qtTFf1vpZmwbhgp90zXeuBLcsLRCVS5edPt8nMsVslt955bhyUnqoAHpxzLUmQWx5OGiC/73yHhb1sL101fpXdK8SbYVv0dB9/EYJa6DaxXdW3U34mqHRS4Iu/uGGqLvkzFR46Tr4YD3aoe3LYHtN+1R35ch62JNTt85AyNKXnXJFuvHz3PdretqW51+1h4foTluotPsXo9CTDYFrP32RXa5U62vbdL77GzbOOo0aW96sfP8vFdemfbHGccyNMPInNg4n6UQ/vKitOJLRI+bgkJHsX9gE637+wZr+BhS1A1v5zaMyeRpbkKNDGKcsZeShH3uBupIp8GY97BOS/mIwgcjQPosupeOayWdR/XselgTrhNIfNkRwh24rGB5ON6qSWhXtBVA5PAPNDng7Puz+7J8JAeLqk7bBT/kn5rOh80DWLpvioaNCRBt1vGKy6tnSpz4uO+ox4osy08Bmn6EtKUep/ZX6u7z388QJuD/w0cSLOfWLcfl2Gqyp6vVnf2KJdxvNNn3OUHljXtDQprIsL1DMVWPhNz7NWulx7atn3D2imsp6r4Evbm5vRxuUmsJwzXx6c6C7GazJ+H3hmv3wnzjctT3Jf5zQCTGfDLuccMFo/Hu0m1yXbrq0v5kLXl+NEltUTUg2vZPYwEpsSwMHYMR6ohJd2pw3DOW+pcC/98VF9iArE/a4Z1Si+ZlOlS/t7ZZ+nECqzu8m+b09zZT5OlOSnxc1vT6VZJk0XjmJ0zqwkvt7aaVBJgvQSOj5zrfHWp1yhM0tte+ceAUQ5GHcfTfM6DhkEZLq2CkLXTaOKhGpHaCnucHvHjsahqYtbL8uZCHZoa1PdIA8vErcM41qTsMM6OEEs1Tj1WqfDqGwpM+LqjY4ZxuvYsIaJWm46BGtlgXTLoCmSnxzbJotWTnGc0lCNH0Rl6KW8Hix19yn0bq3XvUY0hQcW4J2UpnLgYOcoOOvhQ3B7rZ7Gd6RHPVMzW8oUYmbHcGzczMEFBEQ31tt1x1dcunmcf5gU6rl9wFIt+75AB1kprKXD/iq1OKdmn84FXZBxbepUknF5xmEmjG2nUnInA6ri2btjnqRSelSGyyt5pvNOyO0JQRuQ0GtQ4tITIjhpmmXW/lfTRaXbU7GqixRqU67YJrgEu2cqsJ08gszvSeN6f9/Z2mxDNPnWCP6ff7nbIRhcx6Ck3l7Fla9WVfLQXLaR0elDLxgcn0H3caEbX1arO1nRmDwXG0SWFB6w9E3AvX7UMUqMSt+LBgNwco6z4kddOWdhz+OFxnpiH3F8N1GIzdVSuSLDBs/prVR5AAxyfaosb1qyJXTuwaBTaPr+cjowsPsajMdcZBD227H69+iL0qcir7aa8L/HBHYYTD8T2x1eXy07ZyaQnl5Pnm2OT1Epv0FQV152/fTiCx2K7LsbxgPV1ue509TPH3NXAK/ihmBDtwmrSB92f+B2+1WYAwWaCjt3WZlq9rPZVHmsi6zu6KTfG9RQAOzk9aMgvpbZKLOqWubd9e+ugvL11cFTtxxbcidQN9F90g+jfP//KP3o+fV3MJnJ29B9yBez++1+em7he6/6XF7rJv+9//ar3v2wSgIW4mExmvEclRXJzp3kgtDNfVPfA8Oe82NBp7v6Tbn3t7Xl9560kcnD0U/Jy3Hk4PT+EiC3Oi5XzxtzHgDW6Hq2mSznfh2XJR4LE9W18UV4vBvHdcnROWfn16Nzz0+/WM7zrXPFUNY/EXlwWEMDUQaZ/5gS549IQIHQ4m14Ozfm9j8VKT9BikD05M/PFXXPkpuCP0/Pzq1W+aX/Y3r4pU90t5yfu9/y+89VixpyE5vy3IvpcyuRmiXOxYMS/cUy8fc2v/jA7b8rt3XWRrVffC9AT3YRffSeuPIa7NmbN1u006nF2Lu4s912f2Ud0LjkfXnhdjK9GhbnuRTcQWlCvg003fbmoc9S8eGNTtX2Pxr43w5yWO+7Q3K7/sTdl7jiIpAnE/ys/cp6Hrr+394qYOXY6Hj8Pj7/p9Hl7r0CFZSE/WiRl3379nruXN34Qu8+/dCPvxRdx9OVJGAZp9OWLOMxefPEFfkWwC0azfA2aHZ3H4VF1KnMgx/8Ggw6hpoiyT1GagJPzewejW4ea+EXK4cFBM6t67SCn7YTqnPiaxx+DOPSC2PeDNIwTMLbLY5Lg/CCMUtf1kxDvYjfxQRzNMSWbpG7y8OzVZw4ztv7VAePhbz9hdffmhflpnSygPyltouYHS26kuxt5hVpd5+8OnwDfTifw6TOz8PdO4HW79w0AcDBHYH+zGAxvQYT8JtrBbLrZzAoreHhtMiH0Rd5oRTQ9ZdqP6ZH8C1ikZ1bbdva20IqglWk+rnnKFRO/ZqpCJQ3Lv5hNQJU8x4X3vqkXlPW4YK9ZuexVz8Yy5b3pQvDhWR9GNtWLZRV7KDQDh5CSTUTNfuunTxwh3x1jVP3Ni5sNRfMdfcrgLTzX/ZNI/Dpx6816Jvhu1iAn/dVq1aa78vR4h80bdDJTQgFXVoQCmdYtO6jWUCb9by2h7FiGrtYp5Ox5PKsrnz5/ahg+CroWmOkQud5dPbLdk90d++zY78s58cPIpxAxX1inEBNBrN8JLZbr6QwiVbLVNhBcffugNbp+4IEeTJP3GU0p8VLPppn33tGgi2Gxxrsr4szXFUmd7WV4XEbQymVL3r7i19b1fM+o/5f6i7p2GvohzzM7nzbrUSbt+h5C+U33di/m86zbH4fhJvytZmTu7Uy3q1A7lLWw6qdow/zKd3w36WZQgtKQwO50qbePq3ZzY3+u8GbAuAkh8PKrwdvd/d7aDW4H3TshxGy/ZVeE0BVWVh3srl4comIbljUiXpSIIO4bxWfdas+hUZFkIcsueY6Yrb52diiQNSR9D3JNGjWaEANjWXbmx3LS1zTbOjxLHclAgSufbQr9XmnslH8wnzqpNWZqSc+HurNmkPfku21YymA8PDdjcmVbiZnmlrhDC1HmVk4rXcZEQrg267fU89xSI+YAJ0NtjEzcyFbtrcZyzAkS7nvkVQ4mCel3HzWPH3Uilsx47FRu9BiezMX82Z7Rj80Z/diMm1Sh1fVx3NMsdAOmdjiG8W1F1DBkt4FvtZTLewW7tgppykFFWyb1QeNTimVl2Qhc67bglozW6X2YLpfF+JhHwrfsdNMpN/QkWgRiH3eqDcRu966z6+enB7qLXUaRWwVMgX56YLYOD8qwu03Q8wZpawyzPnNH8J+biOeUO85lxMxaox7//e8dLl31nIvW4VL9VvB5GRCW4PSahzgPzk45zbbEnm+fa6rki6TPqYnsYlscGGr0dnytioxy8Orlu1cn77/440F56njd2+4bi9gmS5n33YRoX2yx8qKNxMc+BgS/ePv8y5fve6XXe9yUVPS4hYyOmxRdJVo7PbjOxwP9ZsHiA8OIorUrjEs0tOOJqyaSKk7SDHIs60eiwyDMUNrjBofn91p55i9zXg1ZX+hXijHZaizKM0nR/dEWHjum83saaQQx++rS+JH9QnbZlf0ZPn5kFk1+teGO+K7khtsZWNVLCDKwARnI56BGhcZVXZMlBLUUgCD08wJotyr2eFPruHl2tGrVXNR2TBfT+GdFbFXWQINLEpJ/TAaoB+J/UeyF7fifn3j/jv/9qvE/iwRgTzVS0+hH26sz4VAAxbygHBqu8vGtRO9GF/lsBlFc/CEexpnvTeCQk/w3F8WeXDUb3uoxdt2lmq41sEUbnvkaZWenEWD8pwUSW5lbbLAoMD6tIfF0vRp9Vqbm0UsNInxm8//lMHoq94LHxWrV7VUZlsjo9w0CNSnpYT6TdDAKGckQeTWd2ZfZ+usFqthnk/BI5fiZ439GoN43iNkrdD5FYdXsU5OrGH+Z9MRc20KTaR0oorYDm3t7X6PcrFZ0niSYxJQxe/jD4qdBiUAF9hx+M9oEZKVwXIymMAVFZ7xxNiZ7/MM/clKl9fnjKgJwwo4Wi5mkQa4/H1nesS0/GGlEtFPcFKMrSQdUfs8YfXyDPqS53Ct74Jwbs4SZHFJyRK4M2ZqPPrzX2Zibwtvzqe8FVzd865vNHKC+9n8BnsJMN4s6KQAGeFsumNSBMdZ179Yw9mQXsmAzZyaQQi/vyl52zYIHQVEgv9BVM/uW5gQbN5Z9R6z1vhxFe29oQj1/B5Ws1+cPQOlXs5xR8KfVBw0OjpzTvfoQq42IWbGxP6x0vJNAnv1/8wPrkEGjg4p7O/tvnL/95PztyPXim5/25Zsndc8S2+O5kK70Zm2LN+djjExO693isujwMLXed+nqdw+qz2cbGhygrAMk9hpp0DbkpyvGpv52z9x3rOFE1vCTtZL2b11ZPa8+KUgtWKuQjNCzM6ocNFooodVAaXWo5HfHa+XFxwKUkDSJz47L1N5y2HVFJ1/u3JhDqvfjWZKWU/5oZXotvBT3Nxt43zQhp5BaGFjw948NOnB+um/ickOIE9WzIuQ+c2r3QZxaU3p7Jz51dtKjhcL6WYVCE4fl2230Nd7cPhY5cvS6v7xaX8gp7AcRgHkRGvxAWo0AYth8Z7irF9HKvB5Eqb6e4PWkep2PRlciJfRcoVSzl2nB7939zNBiCvStYFw1gLNqkLI90qRRb3J7F3mYszAHGOHpaMIV7hJqk7lztRyTomVVv7+82ji6LyPokcjskfP7SjfcLR0sCLy3KKj+b79nIrI11Wjgt8zOYRVV9LLKr9sA2K52W1azXlnpPKzSSunsaFGpIX1nkyFg+ZNxlZcaW1iNjAcqZ7OKWc+RmARJzeiX7SDFrtAOOmIsyTqcuSlu6MfWcRdMDC5sM1qRz0cXC+bEGksQUIbaef2VvfXlQm5H24j76PXkOGTP9NO6aaETkJarYjnLR0WnGk9+MznB2Iq7tQ6ZmwPl7KDbOoV0IOArxpKrYqYZsWXy3fvSfRz8jhxz4PyuTPxxNTepP/5fuWLYTgZSXRST+57lJyrEFu1IOk39WkEVCTp6KGtEe0f24R3abvfeNBB33z2Vmf3S66diWMGusW/8HDGJv3255sjxftqrz+7rqcMPPefUnDiVO/AHb06+ef/23UF9wEzOaVCZEdnMol/T20TigbCbNOrStb8WNhEHbcIdQz3cLc/EO1tolm0pwRO3ExmMcA6O2uczT9nDWXlkeXLqHZkAxyWn9bhV/Jm7IuU32kRXWt/pme36SA87Pz14c1ANfApi69AxFDLlvUi5y3rW5M4p/LDL5h3dzkHjhpaNj/btRR303Y5B55eMpZ5aY1ffCMPvkX00v9q81ZmRWmUn+55p1OJMpv6xeeCccyAHaxLw6tWH6bxMi77ipS0b9fru2PF3re8ba308YwkNcKBHW4MzDVMd8OumB73ybHTWALPeJJlvpnPrg19zfndTlnqqE/LPrFi/8YyOmY6WZ80Dqzud03trTnOYx1A1V8VBO//SwYQfMVHBY0ASnnW79nMkz5v7LjDVleNWY17d3w3I1nbfb52T1VAzHx+pG7mPSe7zYr8mqj159Ypf91473z2rHbTp2nxzkQwgn8m83YGekyZ6BBolihrA2EJS9bfXZIztT41WXR1VWQrQmVrLR7VrCW3cs9xYK9M2/Xw5DQw1Pt3+cq2u5O2OlQhed0464sfa/tymNJl7A/IEQHuid0/Nmj9W8zMmWpKamV2os9sFYspIYk1uYpweRXpqPDdCV16dlZPnBE14wnzX44K53xa2nhLdoteky1sS1S3q8rtF1X0BkwhIsoYe2GlIur3tC476XRMJ5Rz/7Sed/Swf6j0QGeDN8UGZP+Dk+KDyYPH4zfGBuR7Yc94fH1ThiUFloOLF2+PyKqEkrT7YxYbvjg8A6MFiMjBnptX6H/AoHu8NDa9GH4rN2pKKDYXS2Egd6g240w9nPUXlh1rozM2lVb2jsXufk9nKuOHMgwFUjDm3mvnHsLFtsTw9EKAdnJ0quDDOWQkycyVCmzcuXmhHjZ0fmVRDwug0dSdhWe7e1TgDWZnb+E0O/oHyFmZep/ODfvgOdiWX1m0qP2uV/DSsgEFmNO+UEzbLbaXwuGMuZs0Ui8cVKPT8/c3xD4/+Eqx1lSQ//UG+0fOD86ljUFB9p+cX9CeAH7b6HHbtb/9U67Pur7YyCeg+I1Zb32DeSjZQ7vo1P1K0tL7M9YGp9jAIbNZelUC1cezOfGtLThSYFOfGTJdw8NjpaHNzjpOR1tH4djYdSgJeO1QMD5St5dtITF/PoHT1wZ8d9jVzsN31TsfsPjbHWp2Q7d6UNVUG2b1/SB4aAlXusOw9mIKmfWrASNRygselbzHM18VO56Nayo7rkpeLMa+4bvVhLbXyVbZb76BDkwdjd2YLs/G8u5/axNzVTyN7gvbTfXh7kh/eqj/7IzWEYg8azjb9dOsLP6omZzvacuPhnvsy4pfVHfUc6wNA1kN41mt+5ketwJ07wk1jaGvE0lltjNr+9FBv66NCjxv/n3f/wzpr8qvv/+KVH2/t/8b+v/d/f42fv+3rWZL9o/1fMf/4fm//+iLnoCptaqF1Vu4i2VcQOvrJjZ3XDqx9abfv9d3+crHeeJpDrflN18YHfMoDOpRsmE19Kmr/qDytt28ORu0fxWFvvzzktH8EkNVpN/ePTgO3F7hnvX0r5yZK/agXRmc/9fbbB5S2O9h3b7x+lLuJ63tx7o6G8fJJikmxGCBMk3FQuKOxG9TFQ4A5nmSTJMiHI6v2eBSPwkmQhZ6b1MVxFuRJEUwiz43yutgLhnk4Gg8Dnrivi5NkHCduMk6juEjt4skw8kajaByMrNr50HfzoRsmfhxb847yaOz7rheN8nFWF6dF5kfjcOSPstiaSTRx3dEkwYC579kTDMJ4koZ5GvnW4sMgjrwwn8R+HFjFHmaYxX46joJwUhdnRRK5SepHRRYl9nLCIirCJB7GI9fupBgHwyBzfT8ZW0PGaQhBNQrzYGQtxxtNwmE4HibDdGItPozc4dDzh9k4n1gzAf0ViT+JJ+PQx5BJufjAm0Som8WTiW/N2w8SNx4XeTYJLVCFWRIlPlCQZyMLO94E2AyCNM/HiUUQcRT7WeYP/VERWBNMgokXAcsB5m3VTr1gkkcxGoxsFIeTNIlTwCspvKHVd5EMx1GepwHIysJlMR7lo2Eau5O4sGr73jjyknSY5vZy0mA0LEaZn06KaGwTRJCAIdLROHZDq/YwDtFDMgm8zCoO3MDL/XAy8ovUptgJhnOjYZ4Ohzao4tHYc71RnIFw7QlmeeFN3Mlo4lsTTOI8L8CcBWixsIeMwWNu6qaRaxPE0MuS3J/k4GML8+4wB+YLf5TmhdV3DH7NinziZuHILsbsvOEQdDLJbMyPMI9xOPHG3ti3YTLJs3jku0E4tnjHBdeA5oss9jKrtpuO08RPigIMHtuEPB4FbhGlyTCxmCTwxoUfRFzo2KaTPIFQj71hhHKrk2gSQuKnoEDXYimw0sTLh0kcB/7QZpIMnbsT0LlvQTDx4hCEMgRp2aSJvif5eJSmWI1VnAwzCpMC2sYWBcN0mAVZFoxARhadxInv+WEYhXmcWEP6aRoALNFwEtm1Qzf1XT91J8ByaEu2ZDwZjUNIGxV4W6Jfx3ILbzwZJ14B9rY69VJvmGe+B8FuwX/kR27hFiM3LWxAh/HIK8ZpGqbj3GZfHwQZphPfS+xiLw0moKUkHw5tsZP6cRgXoziFaLSwBQE/TNiDG2UWtoaJFxRZ4WXx2AsaNFlQkKI0tWgyA8qDSeCPJl6jdhxD8oVxmAShLc/BYe4ojdIhmNJaZToG1w3jGBLJt2kyijCbJCpGNp/mCQhnPCzGkFTW4lOgKnJhjkTFxNZxBRg9ygIPosFaZQhlMAzCAB3ZuPVdSIbIh8Bwh7bCGUZjKDKo4NS3CTsq3DhNRwB3aJFTlPpQiGMfOE2tTrIhBNHID+Ik9GxJ53sR0Jl70TC0akP4j4eeGxdDzxaXMWRrwVWmbmBJI5DBJPeD3IUSGDXE5cj1MzfJitACbJQkceQPg2js2ctJQKt+AsUNDZPZxkMY+mEyijGELS6TsZ8EcRH7UWKhOB1FyahI0iBrmAMx9Fs6DPBq4llDZlASIEsv8XxbrULUDiFGRlk+KmwUJy7EbgIbJ4wjG8VRNsmDcT4KR/aQUMnDeAz7M7DRkAYR7CAocqhKi0lQB2hLkiQaRhYEfQ80AnUT5dD0FuYnGUg7jocjiDV7lWECOnEhFj0L3nHuZ0MwWhS6mQWqyB3HuQfVGsOGsmACXQCAjLJRFI9twV3kIFn8ByVtFVOEJmEGgRRZxb4fhGEaT9x8lNr2YRxBdvtQUuO8aAzpD2EijbPxxLaFwKoJ/g/82Ctsss+CGKLEg1i0JVs+9IJRkeK/zJbQSTxKJpEfu3lm6wpoxImfTdwosIs52DgJYfkA7JZ4hLk79GPiaGSTvRuGgCpsBxgVtm4G+7oYGAabrXAgXeIE9i6Ej4006HyobN8F2QoNnv3007/zQvz7598///75P//n/wc2meID","code_encoding":"base64(zlib(tar)); members enginecore.py, tests/parity.py, tests/selfcheck.py, tests/logpatch.py, tests/golden.json","code_members_sha256":{"enginecore.py":"0e34b1320895d2b4c630c56c2aa174503660258b4aa41ee362b4e5f93e52638c","tests/parity.py":"427cc1fcae322545c27c1323eeb18c9b63b29804844f93d1842998ad88143bc3","tests/selfcheck.py":"e3f2000df9b12c1a80d757cb008efbce7ab66a6efcb80b5c1615c2a614f5272c","tests/logpatch.py":"02a4fa381f483d52cf22c603874bac2b90755e555d334c48f24ac8de6134c13e","tests/golden.json":"dcec491da135a6a6b5b4e3385e5146effec6dadd2caaffc73a816081455c4740"},"source_sha256":"0e34b1320895d2b4c630c56c2aa174503660258b4aa41ee362b4e5f93e52638c","source_sha256_of":"enginecore.py","environment":{"python":"3.12.16","numba":"0.68.1","numpy":"2.5.4","llvmlite":"0.50.0","platform":"linux-x86_64","setup":"kit setup_fast.sh --platform linux-x86_64, exit 0"},"run":["S=$PWD/test/scratch; K=https://raw.githubusercontent.com/identity-md-launches/goal-3178-build-shared-evaluation-kit/45e7563d1a29ffca9d608fdf60c90bf2624d2d01; E=6b6921f8d463314aa7c96234e1be25a25245f704","for f in README.md setup_fast.sh engine_eval.py score.py bootstrap/manifest.tsv bootstrap/pins.sh bootstrap/deadline.sh bootstrap/verify_env.py bootstrap/smoke_engine.py bootstrap/smoke_replica.py docs/engine.md docs/setup.md; do mkdir -p $S/dl/kit/$(dirname $f); curl -sS -A Mozilla/5.0 -o $S/dl/kit/$f $K/$f; done","timeout 470 bash $S/dl/kit/setup_fast.sh --platform linux-x86_64 --cache $S/cache --scratch $S/ks --deadline 420   # exit 0, engine wheel sha256 verified by the kit",". $S/ks/env.sh","# copy this file to result.json, then unpack the code into $S/work/pkg:","python -c \"import json,base64,zlib,tarfile,io,sys;tarfile.open(fileobj=io.BytesIO(zlib.decompress(base64.b64decode(json.load(open('result.json'))['code_zb64'])))).extractall(sys.argv[1],filter='data')\" $S/work/pkg","python -B $S/work/pkg/tests/parity.py --kit $S/dl/kit --work $S/work/sol --out $S/work/parity.json --n 64 --step-seeds 4   # 128 edges, wheel step output, moving-fee check, speed","python -B $S/work/pkg/tests/selfcheck.py   # offline: streams against big-integer reference, 128 golden engine edges","# logging patch (cargo was not installed; a toolchain was put under test/scratch/rust):","export RUSTUP_HOME=$S/rust/rustup CARGO_HOME=$S/rust/cargo; curl -sSf -o $S/rust/rustup-init.sh https://sh.rustup.rs && sh $S/rust/rustup-init.sh -y --profile minimal --no-modify-path --default-toolchain stable; export PATH=$CARGO_HOME/bin:$PATH","curl -sSL -o $S/dl/engsrc/e.tar.gz https://codeload.github.com/benedictbrady/amm-challenge/tar.gz/$E && tar --no-same-owner -xzf $S/dl/engsrc/e.tar.gz -C $S/dl/engsrc   # sha256 fa91b175c4b0db13fa44657903f55f664c80fb34796172c94d57ebebba71ec9e, the kit manifest value","cp -r $S/dl/engsrc/amm-challenge-$E/amm_sim_rs $S/englog && python -I $S/work/pkg/tests/logpatch.py patch $S/englog/src && (cd $S/englog && PYO3_PYTHON=$S/ks/venv/bin/python cargo build --release) && mkdir -p $S/logeng $S/logs && cp $S/englog/target/release/libamm_sim_rs.so $S/logeng/amm_sim_rs.so","for pol in \"30 30\" \"25 45\"; do set -- $pol; for seed in 9700000 9700001 9700002 9700003; do python -B $S/work/pkg/tests/logpatch.py run $S/dl/kit $S/logeng $S/work/sol/const_$1_$2/Strategy.sol $seed 2> $S/logs/eng_${seed}_$1_$2.log; python -B $S/work/pkg/tests/logpatch.py compare $S/logs/eng_${seed}_$1_$2.log $seed $1 $2; done; done","# enginecore alone: python -B $S/work/pkg/enginecore.py 9700000 64 25 45   (seed0, n, bid bps, ask bps)"],"not_done":["No QLX5 or LEAN policy is ported onto enginecore: constant-fee policies only (plus the moving-fee test rule in tests/parity.py). No re-tuning, no contract, nothing submitted.","The fee-refusal path (a returned fee above 1e17 keeps the fees in force) is transcribed but was not run against the engine; gas and out-of-gas are not modelled.","The logging patch was built here from source with a newly installed toolchain (cargo was not at hand), so it is not the release wheel binary; its submission edges equal the wheel on the 8 runs. The release wheel itself was compared through its per-step output only.","Crate versions inside the release wheel are not known.","Bit-identity was shown on this machine. The price step uses the C library exp on both sides, so on a host with another libm the engine and enginecore move together, but tests/golden.json (recorded here) could then differ.","Whether the exp inside the ziggurat acceptance test and the ln in its tail are the C library or the libm crate was not separated: they only decide a comparison, and no draw differed in any run.","Only seeds 9700000..9700063 were used; no seed from 10,200,000 up. Speed was not optimised.","Paths the two-pool engine cannot reach (one pool, more than two pools, exp beyond |x| >= 708) are not ported."],"sources_checked":"20 of 20 quotes found at their URL when this file was written"}