Simple Crypto - 0x07(2023 HW - Oracle)

Simple Crypto - 0x07(2023 HW - Oracle)

Background

POA/RSA

Source code

:::spoiler Oracle.py

from Crypto.Util.number import bytes_to_long
from Crypto.Cipher import AES
from random import randbytes
from secret import aes_key, p, q

def pad(m):
    length = 16-len(m) % 16
    return m + chr(length).encode()*length

def unpad(c):
    length = c[-1]
    for char in c[-length:]:
        if char != length:
            raise ValueError
    return c[:-length]

def asymmetric_encryption(message, N, e):
    # encrypt message with RSA
    # message must be 16 bytes
    # padding 100 bytes random value
    padded_message = randbytes(100) + message
    return pow(bytes_to_long(padded_message), e, N)

def symmetric_encryption(message, key):
    # ecrypt message with AES + CBC Mode
    # message can be arbitrary length
    cipher = AES.new(key, AES.MODE_CBC)
    ct = cipher.encrypt(pad(message))
    iv = cipher.iv
    return iv, ct

## Alice: This is my public key.
# p = getPrime(512)
# q = getPrime(512)
N = p * q
e = 65537
print( f"{N = }, {e = }" )
# N = 69214008498642035761243756357619851816607540327248468473247478342523127723748756926949706235406640562827724567100157104972969498385528097714986614165867074449238186426536742677816881849038677123630836686152379963670139334109846133566156815333584764063197379180877984670843831985941733688575703811651087495223
# e = 65537

## Bob: I want to send message to Alice! But my message is too looooooong......
flag = open("flag.png", "rb").read()

## Bob: Oh! I can use symmetric encryption.
iv, ct = symmetric_encryption(flag, aes_key)
encrypted_key = asymmetric_encryption(aes_key, N, e)
encrypted_iv = asymmetric_encryption(iv, N, e)
print( f"{encrypted_key = }" )
print( f"{encrypted_iv = }" )
open("encrypted_flag.not_png", "wb").write(ct)

## Bob: Ha ha! Now no one can decrypt my message except Alice!
# encrypted_key = 65690013242775728459842109842683020587149462096059598501313133592635945234121561534622365974927219223034823754673718159579772056712404749324225325531206903216411508240699572153162745754564955215041783396329242482406426376133687186983187563217156659178000486342335478915053049498619169740534463504372971359692
# encrypted_iv = 35154524936059729204581782839781987236407179504895959653768093617367549802652967862418906182387861924584809825831862791349195432705129622783580000716829283234184762744224095175044663151370869751957952842383581513986293064879608592662677541628813345923397286253057417592725291925603753086190402107943880261658

::: :::spoiler Alice.py

from Crypto.Util.number import long_to_bytes, inverse
from Crypto.Cipher import AES
from secret import p, q

import signal

def alarm(second):
    def handler(signum, frame):
        print('Timeout!')
        exit()
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(second)

def pad(m):
    length = 16-len(m) % 16
    return m + chr(length).encode()*length

def unpad(c):
    length = c[-1]
    for char in c[-length:]:
        if char != length:
            raise ValueError
    return c[:-length]

## Alice: Okay! AES with CBC mode. I know it.
if __name__ == "__main__":
    alarm(300)
    N = p * q
    e = 65537
    d = pow(e, -1, (p-1)*(q-1))
    while True:
        try:
            encrypted_key = int( input("Give me the encrypted key: ") )
            encrypted_iv = int( input("Give me the encrypted iv: ") )
            ct = bytes.fromhex( input("Give me the ciphertext: ") )
            
            # decrypt asymmetric_encryption()
            aes_key = long_to_bytes(pow(encrypted_key, d, N))[-16:]
            iv = long_to_bytes(pow(encrypted_iv, d, N))[-16:]
            
            # decrypt symmetric_encryption()
            cipher = AES.new(aes_key, AES.MODE_CBC, iv)
            tmp = cipher.decrypt(ct)
            pt = unpad(tmp)
            print(f"OK! Got it.")

        except ValueError:
            print("I do not understand.")

        except:
            print("Bye~~")
            break

:::

:::spoiler 加密的圖片檔案(Hex Ver.)

1
40f5f626751e1cef63258af7fd12256a58b9718a862aede0e2302f0ca97123248fa765feb74e8032913ae2b24432450a379ff8d0e884aceec7e67b3212d4de9997a59e0fbbf24369cf1f588715423d254fb2c271d1b75588cf264fe28f9105293740b0472e38eee7190d7c72fcabac3a6cedd6ac74e685b837479822020e5845ee0fa11bf76d4104100bb76120b115c9ddc241d12f7f4bfa76171b01d1e19930fc086f3f15bca689660b7f29b179c120ca90c9ec8278b6cd1e8f96aced7ce8442134f011dea66d8882cbd3495d726fbf2ae55081b4e95b2053c973e7799e489447106bb4c83eaf3f6f3ff2be4ac086dd7b2d70cd03d5ecc6ce4230f6ab416a3f5bcf3dd9adaa72f9f3e7c2d12d2c89d6c85256064d7c2778042bbe4dcfd87c52c94556421e9e4fc3d85133f6aa263df1e8b92cf8f696dba76b77990593c16219e6149a5d2c19b2da9e60c8a21f77a208ab071f94a17baa572e51cc8044832ad54d65127d9432dd8c7c390316fe2944efb2cbea04342517971aa5045eca679986664d5f767b52986db564937cbc4b58fd786cdda69f2c0eb92972d7560b3418137438580d41cc2838dc7691bdf3c2a6701253505ebfa76afb05a50103e14d1c71bc1d062ed4a570ad2710db31f70cfb39943814439e5af5d30ad84d6c10b9cb8acbb66d7c636b683a49bb033f47a70ce4df52bdd830964303f895b943dd34412abd0a091b8d4abcdede96e03cfa903d52a6c5f3d9b997e610875238473d7fa9e79c1293ca33e3f7e2078c959e8d5e3b52a966339166f5b16deb8e3cea45bd65152c49076129f115a41f86d4cf7fabf920aa01eb4bb265543b7055f77eb82089a6ba54352f862c809a68fa527f5732b9e923146ec736f3b8bfc1f06ed999809a00f46d73da1dd1fc8b17e83fe2917915029f9d7fceaaf5d44d43728af9c47d1be0ff0a8bb69e92500285e31e07b59aef88994d0db2f795a388d28b2068e5dc9e1e4fe9431fdf36a28d7dc14badc67b3415f17d2ed68e6be090b0a5bb5b6081f20400bc7b3a23603551ee002f8f1c27298209f052b8185fd3b0334ede532a81b606373bec8adf9c6647ec11bfd0f82370743bb3f215c9dfd051e0af77ec2be5b959445fb9dd6b9934b10ee119c6845b73e0957a055558c7f3c1f7aaa7ab4bd51b90bcc2aa61a99fddc4c2957d903b57a0ff0740dfabd4b158569877dfcf96f73a5b6ba9dfe2c313909df17f357ccb4a456f461fb506cb8e1dbc4ea4a407d3ba7a5b7a99239be329f4bfba2d0fabf841a2ec73249c1da3cdbcb9354d247238eb1a2a726257b263ead9183bcbaaf26723bc45fa74bed1257b90d201b1515e23b17e911f5a4ab926cd99df7cd6bc7e38fdf79409307ac0070bc4573eb1df87459a818443f43ab00cb62940e9eddf588bd04e8e637e0d37bb5b70429943e47dbc04debba60842992320b4362557c89c407072843da3fb23d4a6add00c95d8eb4bcf57f102a84387fb25c2af8ca0345da7a71860b671974ac4dae0ea3c49df226a3020b1ed1351a98618d01dc318806be6febec9df2172ff34c793c14ae6cf994e16899c55405a055626f45b9b00dabe21a38b991fe9ca63bc3c34ebf07ddb1e10074d2ad8dc13ca6c00346f8187afef33242f2be2cfdf43edb1e7e0ba9c25a6e10f0594ab808f6161f17eadb40480c245fef050e34d7dad3db79912cafd9aa6981e575d7b37b653c9d6f8a510e297c2b749c440efa113ed882d626669662899ae13ffd536d399365787363043d1446b10e7bde451f3ce963dfcffaef1e6585188c008198031a663a3066e05184f30988a7361eef1c9da3c2a6a948883690d31fbc1bff4da6264875236f85b41b513337ff48f40f9b0820c9ffc56827ac34e4c43fe19425de4c5fed22fbcd9fcfb454a7de4763617cf3ef71102c3e0e87188646bcf7901d5531be92e79ee645c42faa43dcf8972a89acbba2a4593e5e1d5f468e4880fba324af0026ac30a5af85885446f330a7a558088efbfcf661d895fcb9f1d85f15075717d9f5485dd239d444f3c301db14457960678a5a7000583e58883e0e000574a02513f0d4b558303299236fff591c01feb50af892287570fa7d7f9e22028cfd99be299af5ae404d2d35f40cc2ae5549b780d360b736f5c5fec06500fe71e49c7267426407f44ae68ee62d286f8281166cd37d41b7494dccdc7ff6bdc2caf8be938d5e3428a0d096a70e85eaa834da4c8873f013383e5643aced935c8e3a65bbc61f39ace3316545dccea578c6f675dc1f5afb1f22d3e3646085df9c3906849433ee5fe4dc96026f7d614a57c7d08aec1a110de21bb0f001b5559e129d89bf70c20ca3a3eeae565d8ea4ddafdcfcd48fe3837887939ec0510dde0562eaed35690218bb0821f33a8ca0ad60f95482ff456766a4fe60d72cc902a3b1c81e688f495a960b5bb69fac0954b743b6a865dfd686f41c89f91ade3dacab1fae710ecd4590c76808ddc13a7dd9f88958ba08206a42427277f93645d476234f9c8fe93678b414a55a1293d30d43d7e5762285dee5c8840c1a50122be7f88501339ca4a7b4e5bb38a16a5305b6d14fae55efcd664b4d05429a6e46d51b5db947cb79db90beeedf2970a2d95a482c2e06cb5f3eaa6e7e65ea011dcbc430e6a34a217271443ed5a0ef093299cd3c808c9441d12ad142870e2fd0443f764d5906897fbdb1d85e1369d105b398b7c6d258f598c3d2132a98fbe5be36f22b7afa7d02540019188465b0a9dbe85431e330ddcd48704461ede253b9c279c53272d315a3d68c7ac20c78b1f49257898a5e01dd370735af787459d1f908ed9f7a9af4f75aca59a2e44755690360a126c14247a86a68635748b3b1496b88c281eab80003cfd29dd2cf157a7f2eb82b24745415a014f5576fd2a7d1ed969717e22091caa193604e9eaef986dffca65fc9547493557864c7fff379271d77a7c4dd22af12988ace08517a5caaf4d44a0609aa40f24ed7cc6433afdfecb9e905e3604e845bbdca44cb418e381a8551e7bed15025e614ed26502df60a805b96e7ab4708c1ad8ce14a71c2449f5e7a1fdcde8b1100b44989da4a0d717fc49f0a58168c0c215793fa4685269e2c988f067b4e04ee846e5102efc69679af3b4c9aabe23f86b92e70650dd840f6a81f170c4c152db2a7be20905a292bc589a3ef0dfc6cdc470e843c9e2f40dd0243c597283c61d114339079457d8519e1dba0fb42958077882f1fe71b2b2aa376e8f029486841dae4745c2efd90c53bd548c1fb4ce11fc07de7277a965be3733fb33d6de47f70cd654708de0a8665133d22539979acb93fa2084460594c89cbb2813318f9cfe6e983139f51564cfdc99a269393e0bb2831255de6bdde0b307e9bb6cfb72f480981ff200695edc263cda6575ca7727ded4aa16c4737e0699ca2e168862fabbbcf8efe73df7096f4c9ef67bc7b8c61b6baaa8e0186ad7cb264e9607e50f3fcb0da46a567148c2a75d505d40e2eaee362b3892193403afec95a3af34fa9cdc1041132b01a6d425d8b81e44635840bc93280bd5e6ef4c110377b80574e680a7f8381efff57096d2da258a4f7285193099e2140d69c7ac07e1d526ba819c8c5d3a76d28541f6211f8ae798d18ba3e94113d7bc74bc12a6972c9e618c1478b92abee490cad02a3fe03d1d2fec0786250740720bf29237ffabe279f276a14c28ee419191baecc4f7b178542437bcfdc160566f5b0c63a1ec95bf87180a21d8d24f352702f40e307819120593fda4f7c6bd945db6694203227e4340b75ae75ee83a5f3192505e7e41d3b7a9968b42d519e2c59d45595dfde2348df23fc58f54b1bd87e11994fac49bc7b9102f4890220efac20e68e17852d04416d5536ab666fb05aef79340b14493f8034fdca5a9284401fc2017435f3bbb96c9d0b0819c5217e512ff5003a28e90e62c4d4dd4ee0e0daf00aec14132d58f1ce474a1f27c354007a58d553ea654987e3e00376f5ae5148c1aaf1c48663f38ef60298a8a89efca568aeeb1e26b7cecd69d9612ce381357460c373fce92df778d809048394c971514c4b6602a2a69e64d87dbfcbf83ddc385cfb5c73a91729a3411056ee94d6cfa9f5e1177048404e40b8c558cbf6e601a59c05a933b26e09ac30ba77146c5c5085af910e71fde88c8312c81ea3c1c4433071ed96d6a46a70880b51d66863208508ac21e452c6d209365523ba773e01e12b81afd5ab34c883e8d37bcf7e9b65920e8643321b4a33b46e25d842eabf5ad9b754b189d16f47d9f40b8217201f4e52434bf1f1c5c00c586598208cefef3d5a63bce7c16a6daaa2677a2971b0dbe02762dc4f79a7105ae4afdd78e88a49e65d5976fd12bf3d78293d82191ed654d73a2154619768bcc1d6c6134aefa40613c20d004d043422f76349c564e8f011c3d82960e84e50357ca08ec5c0421cb0797d693dc9f9bab203e95c4292b1e7969879aa0b8108f627b550028c41affd68d440b35fb9a9cad503b96b178c4695d6dbebf31d94361b88b6801b1309f11b8eaf33c989f18eb2706c6505239711cb9cb39cb4e537c606ed46615b5e434375b3fc33135640cab3da39b600c3d1eb900182130e88b8357a042b75c9df29b4eba1266328073656b08098baf437af5999d19399e535ad43da43634c667140ddeec7647219ef79c08d5910dec964a598b4f2844cb0b6a364eb393770cbe54dc6120858f24116e3cc9ed91a0914151284ad7eddb7a7618164b919d5f129bfc62d8d58f9ac2b6e36cf5494d1d0bcc343007970f77f8a01b3c998f5bd1aa6cdb83f0455aa119b5b933c897a297a1ebe0ee27f2c2907ae2305f1f9ef3417ef1b881ea6583bd903923f8572bc5006672a5a1c8c37c716096b8f4e91b02af8ea05f2afa2fa51005f8b17819ce84d61cb792c0734a407d0b1cd06de506ebc517386e332724ae44bdf9a42b043c493374e7b77d0d896c40daf3050b9f704e5ae615a97e26a8b72a8c55cc7374d4e4ce26d3947bf3e098dde0098b4fea88dc9e2679f77944e4244155f1a32f018832a016204d280841eba1056eb5888df3521dd8b503ed6af320040ae043809dd95a68fd5da5032db9b02cd95042707fa30156a633b41745efc658b6347486c375b94ca6a5353e9772802223e163c3d91e82b9a67def7124bc55260f815c7bae25614cff05d160dd42b2861978f37fecf495d0b029d6c1e21b37b6ea48ecd8900746cd5fec944849d62dab0161fa954ce11824f48f7f56dd74bf6c7b8cb7ca3717dd73423f51a7a4c46a661967796b30b75a6faa2f68acb599fc1a61ae170aa7340deeab36d121235bd45dd300ca44512e2aa9cc7cbe59717890fff87b048b3f2d98d03ad8f4a420a30d9bb60b06866f94a8132fa31b2c8d56c3c025b2b1dcc5c99d143d51ec3204c003135759d7b6cf3f06675f05f3fa2f7cb8026de15c8e55331b34fa777bfb3b5c697d75a5f3b38f7446a0a6688bbad6e684501c3e529fe19c9c143ecf69cc2359764b2fffdec60d843ebf6b77b72498380dc8c80a7f55110216d271225754469ec5c4a901092572e264971b873ce12fce412f31d4e52a4448fbcbbaedaf1e96ac3b7ef0e775502cf6c47ac6957008d9aa5ee08f5c4d057471029cbe020699245db91249e52dae6d97bdddffa1a1f1e91f16c85d402362a04e3b9dee0e083b42570870eba8c684cb35b70ec18a0b54c6f6b1e3dcf2c4ca34fffe4c707c748c8f301a0affe58224eefca1094fe88ac94d732624adb562e5ca01c0efa740b0a005c41fbaa4898587503514ea2fe636fc0e30fdaa51182df608ce158803a2821172108d04bf63acf6ee451d12342353aea013ff0b99db93fe8eb4df4dbab6cdb2295424fed3da9fb95b50bdc21fb888006a88020af061571f665954a5fe6fedd8e622e82011f5ed3b030a1b8dbda688c0c1bc35cb6c7a0de1caa002be156b9c66b37ef37920f24f6cbe8ed5e719e2c575ac1a5ec3dadda625b75b84628de942ba57f0fdf2a75796215846fd417415e9693c421c0030ebc9ad1ef3667d4ada96ee4825b1207b5e9c2e35367a5f1fe64b35fe656968dcb1d1385c0967c67204d528e8f24ac6f2309744c8ec8966994e8112c04aab406576321affe1a1a6532211093dab4fdc247bc114cd9182aeafcf53f704461185eac465dfe9a1b0c73d7615b7ae6aee31cc8d74539983748a73dcc869a5a2fdac8edaeb68d063dd77b6a9be06fbdb9e0e67734055c258445e081e60d38493e8244d1fc5c3878c8658db2b61393ed72d80aecc9a96f85a4e61d1612406f9df75adedb02bda729b5c795e06e121c5fecf604abbecc6b66e46b5df91bf902b21cbf7a84f4d72b572c799bf20b70601aba8eea9f4396c33d1bf6b34d9a1d904e8d9553567e291039df4f4a38dde0fa322a367d819d62f2a02c3fa5964c9ccc794deb3c83b9cb781c8fe40ca122e89fcfd5ffe75cacaf06d69b8e338d950f3582c9def800c5644293dfe25a804e77c2ecd894739b62350ed936705402a778b1200734baba7ea70c3dae27f39846ac0290ea89d424f35d4181d5f149308973f7948dad3b06062a59f7f8f66b4f3fb07b2b5b0273b5ddeabc55ba067934486e9ce10bdb8b07be0e16f1db7b017aad8675b0e15245d6321acc3ed1e2649f8796d772284c62da10b2c57bffe731ec69d457bc87e1dbce4b31de0febfc9af17b6c349a9fa35560b36a890202ad2678da935e17d8e1513ad045b7be4aaad6db2acb81a18afd6110f2b3699d4a8ac3571171d6087026a2818d04ed0f85b3e26192dabb10fb28bfe2bfb749148693846358e036723e9943fee7b787f2e075cede0db6ddd768e06a8642a0d5db35cbb6ab07432bbde3390778f4c5a3cc3a75964e97357b6a8cbdef290add14bbcfb384f25f129840081d59db1a755a0eac89699d93459ccd2cd7e06429855db96a4da6b5a8679a81d461c9425a7dc788aa561c10122841f5abe7c305abd9630e915272e7bda500a957e43b3d53e868d51e2abc3cfacf148615c19fd7237479a566b57c9b1228ea24db95f40418008e6052eaab036888c61d094bd08dfe6f8a05a9971f50d68bbdaa34601fdb6779d6c9b552fd9bd6b595f41897769f947a0662e1569393c436136ab040b3e7041885c93729293f58ec446504efe779621e70fc6ded87c4017f3a113e026d4a425e6f4dad72b1df642a2341ccd1fdbdcc70218a560a870de32782f47a72f87c4f4e7bd782f722efe53f397ed63c35ac0e4bc93bd3ee5b42427d633c7eee757a21673451fa4249fcd7b51baa094ae39aa4f4ecc10febe668f28b40a09aad23a2672002b763ad2e5050123f13df3af4ed8350d897e080eef039f7048e2a8ea80aae6f4bf729a17d45bcfbfcf8ff740920206052490855cae991a1ea51a23f1524a4e83dd9123806348722d71758a196bc95eaad567c7ab683cc46d6493eaed0777d6a51a2096c4012aca65274dc23ddeab30d5cacf70d81505f6de7977dcafc0cb91aaefdbeb48a81dd011970fd8c1d7f2568e6ae4918639d5e28e0018a785ace44a77ff3982350de06141b30a61b8786b65e196ff2a2f51cd9331e776a0f154370ad3371255c86ff32a3a7beb6b76145147c73ecd1b9127c305367b99ee24a4660b965611c1922c98acdf39e2461993ee335bb62a5971146cb7717f6f4979268b78967ab0e9fb913f6a578475dc32147cfc758ce208643e3ee8084b0a2b4145de292239299d08bbb18512d1b2e56811300b39e9bd71ae6a79a3f55eb88fe5c03ff3a83dbf2cf137acb387b46755095c6b80d1d45703a2743ee699ee7cba0c436f85859a2da933e0665ab938f93f2a4485c791c6092c5d17d99db893776658c6509f5d5c56aaeb9955e7098544bad296fc8b45beaed52c19521cf4a0b88b03ec1737d9d531eaec3735fbf68a456d1ae7d7187be7f67cdf405712732f9d2d2d2585da055e2353a04c0127a742fd6aebd51c4d71c89d6430cbc3193d227dd317c741b25a6668603343a7d39603493b0c7cd3ec03ffa349d41c2edb72d3f60833a7d60dc51c2cced86b42fea32fc89ed795608c25e62a301e6178d98dcbc4106660dfcb76f6d428812ff3ffdfa22f47fe60b7208b2c04feb445e8590b806c1d0624c00273ec1cc060ca375e0b14cd82fa44ba94f7347dc6461d30d3ed5ab5fc9bba9d94dfb2c57bc534d2072a9802e7d8f93db3f17a9e5fc92112fd1b92ae87fc0d21b0ba32788f1cb17b381893c6d8d36463fa9c43a94b2838e94ed5c7cd6a029abf7d823c74cebf7ef4ce97fec3bafdf950a95a6a9b18923f0bf828b8195dc94e67cbb5248dfc4447eefacdcfe0780c9ab7db390443ea44fecd0bc3dcdf491eb85bc2f180700ee3b37b2df5975aa461d12b98dde8b70aa799fb6ac35bf675344b76ecc0c54f802e3dba44096ed8723b5a4b8c3064f9a8879f896c6afed1e86530f16d2d7035bd2c1cf4fec1b38177ca1d7a5718e33e2e5b03b28975a2151830014b45dc242abebc767dd645b171baa2e2dd95bce859eb43abbc42f4f24c45adbe562c47cc75b00e2c0bf796117ff4006ec6c23bf160ebb94ed21eeaa21ddd55ac01f3e27efaef8fe943c4cc50628d4eeb9a28b80fb42d67578cf2e735216193508cb616ebc4c9ad547b6525529a695df592881ae71c56d4f7c4ec4937a574da4e35411c81fa542352390045b02e115d8f21e5b1c8901388c4f0a013474ba3321d4c26a419f9e472e1ba9a517c5186550467757c301f6329568af5de6c100112f564247bcb88d9f5c282c5e2291a993ddeb2f1f74b87351ed903c88d842c4040a96938541fa06b4e49944457e377aed2feee50653df1c81a388611478dcfb278cf8b65b18e551585190fef176ca704bfa7613b9dc908dfd73c31e12433ae4ad95e5c871dfb037391c20248edfd3fa01788fe94dabcdb54b5cc147138ce50afb1b9cb41c8d79c751009c0f9fdc8a4cce9ac723ea459f780d13f956906e750e88710ff87b89d52482c10b6a8676ecc73a0063a6446fa6427837157dc3b9f820174f0c81b35831902bc752832cd1e925aaa48862ce617cb35e80dd9ff1879272332829f105ebe8d8088430662941d1b4cb1e84e51d2b6db925c81f02dc452a760ee08ede40485dae50efaaf5243594019028a78620f2602b5555b292c5191458cd6c1bfc0011b6d9f8df80979e3a9d9a162c6e8f228dd907ecdb6253075343637117037039532ad2750ceb2859390ff7f12bb46ea0d35cf38a7624b066df3ddf377689018f0f29a02e78df554e127d11c5f96ddd83b5e15ec2fac321217fbbb1d51f3c61b331692fc795eacbfc2a13b5021713fbfc88fe2e26a508acc9c3587156023538922dc20e16d29139b8816cc7323a4d47cc3499bb83e2150105053e8a50ce15eaddfa72d5ced83c2492297cc7beec07f7d9be854029fbe94d137c85043f47a71c05c902f405a00760a8556b5a332c6dfbbe0313f2cc6d1fbf223e1e2990644de12af0cba99796f8c2feb8d1751fd3afa1f67199ff41247ccdabba336d7cffc9ebaa67d41785a0a7d4b09c2199ab42d55b4d7b5e39921dea1ab781267acfe3c7a3889b53f115f2c9edee60513d5f6af1b2539573a21c5d1524fced7fa681ff194bdabcc5ae30d51b5d0d6046045167ab82a4a6e1967b0494d9f5230f5420a347d662c849f7ca9758efc14ca6bff4a07c660846a144164a5cc9f3e703b925ef0cd1e4f2f64582c6e49a8299ba7f4d8a3d87f4135ee012d92bf7b1a9898737816e7eb93bc440a1c46cd0b4967bec871f999954cce20b19c52fdaa0b7e50f25559c9c72495fd661bef2761b0394490b17f42ac242bbdea7f120cba7699d40d7c78932cf07e1d22f6f7e90d4f2cb86bb7836f5ced37889a231e6bf00f4495d9ee0cac76b71f72bcc458017b0737b0d54cfad28113d4322d2f0b977a71765713014ad9868fd88217c3a107ef43df014ba116d0f656afee47b3bfa8eee95b581734ca8fd5717096d0c9a577d6ef0e6c3a72145abc0580ee076227631d65c390045d9e4e273b3a2c9a487d6b017e551f2cab867aa1dfb5fb0ba0d612f17fbb9979e656c3f4a67cc4225faebc94c5422c618f898d3896710822c0a39f40f3b3908a5d5d93bb495affc151c9023e572281c1f17a42dbc6d65555e91c7b33a8a5763f30e74b22e2da7eef644c997ec83d39d0a7c8685850cefeaabf8a48ec7840fadefe9758dca0908d7950c929c99abd39eeb8187e537ac42fc69b3bad91e25cfe17eaabde505d88992451db4e16ac828f5997baad89fef60137d6312167bb3eb63fba40752c7811a54c6da94e02edb57e27837a4fd8f938c2d242424ccfa73f2b5895c013621fcbe8ba097314af433884dc0c4afcde15f11a8d9aca5cedefc0a20debeb04d0a86252b99641192d31e61bc4abb9e89e8fad7f538e26c37bcc891cb881171c8e43f4b6a4d4c4eb860cf653c495db658773293170ce4f0bf13352af6268470badc2700546126db0eacb2b06ee64024c8ed97a8a8c2ada8ee0c4c45a60165a69cde615dcb26171a5e33436a98bc47274c5345798e97cf70919546ab38e78af1f88c9e99f37cfe5e1367efd727ea0faddb0340a9d7efd8155b075f74e6277e36f4064b04ddf860963519d106254b0a7632fae1a4bce4068bd6ac0ce630b6912e3ff37cffaa3e6ed761ca8ed5874cad5a8579ba06b30d6c0471d0bad80308ee30a01a92a767e3bcb396e4a9d337939bece883a7142096b0edb8d5bd74734d41aea7c5ae822feaf965f5ff338e3c80875ac0fbbcdcf8a4d37c8de0688daa484f1afbe7737cc29b55bb1f5767013fb933c9622a0d9b686f365f98114c532cbc423425a6aba216076907c58b34389d255337aa63d498dbe79667ff096d9a23e14c5e548c8a7a174cfbfb4bba8226568239f44a1ef87d700cd197e1f0741c8df181c6f001e07c55489d87f46827ede3137bb9b302fe9eb57a6dda19015aefc1814a03fdb2340de56e9357782954a8d28b0d586e625408b7bad89f4fd6d891f3d9b7c5ad0daf6b5c32e80ecbb67e555bc86f6398d4412c60de29d1699c719648ef44f0dbe024584cee49de5a87c4e90ce267d41cce45fdc9c4bfb2059923b4c1223264ac4ac93265079720298659c0c8b9fa7337b2cdec8219fcb2d90f862a4377b7a1574894bfcc69eb7e24683f20b7fcf920e677698d730acfe5a36063fabf270f0c867a041048cd7362f032acf117fd8863502c8f16c3a7c895afbf75218267571e7602da7de18a8c501e23f4c026d93853317b57f58999f8090f2ac8a0de7a73f8de3a288c2f90ba059257e3e6dbb97eb812b621ccf77c9058c9e7481a6e6f5eb9205369debdde8a22fece58aff92e5265c924122128aae114c901411fdb75ac23c4fc29e5b7c63a9e325087593b135fe125685b37980c40d1bec0f98f696c57fb74c1bd49479c016f2b646ed0fce1bc96ed7b768dfbbe015dfc17182e1cfd10cfbf01f064df228fd0fb7cb0d5a479f8c355f27c4823d8f1d42ae2f69f105dd8373f8acea476507c927c1771b60e00045db0640589607a6ac9de8030a375825bdcfcce1eefa618e2a32e82e3d4bc9d646fbee899fb16722c19d40864becc1b1fc72dd4e5c4f35d5445bdc5e02329a6bfc63babdffdc762dd6a1f3e378e9e08d6868cbd2be0561ff3beb8d75a4e815476f23e90f55aff6a70a94a4f33ee9f155cf3992598f4c0a6ccf056ed19b89e3d4587f169258908df7b2e6bb4f3ccdec0cee70225907d90a5c25d3b8a575696241931b9e74aaeb8ed21203db30fd7e928bc6c024a594670a6601b06426d1261bc17afd6b0e3a923ff2793ba44c32971b4819fc1b121f29029f26862a4d06bb113fc9c1ba3633ef46f9f5f07445921961a853b2d940381d4da49e03e4cb1c5ce29097e70944427d8ef7f3979cdc28a5e1eeb5f4aba271a7d36390197fa74ffe882d848552b194ff340e12ef610ed8acb2b8c4b90cf93c2ad21193b7a8db7dc4d8b25f662820238611e7aeb0a4ad9100e2beebd8e60c45a493be162eda193a778a32272244a2bd5d43bfa271335f20adfca83b6d767b8c8bbbe2b776799c84982cc41a42ec7506a4cdffa2a8a7e1a2191200b0e5d1a1b33e5207902aa88a2de0df282f8bba3fa771c194e504b849280932af0f6483cabe42bda2e6147623cccbcafb0d2ad4636e2ff369aa4037c7d3ec70be75e2d5f1ccc9ca3de16882d916e8bd51dc23c9943a68572cbc0eda53a07db519044b0cbdd8dca7d4f882c1fc6a887a18ec33ab39c3807100c47f354755f51338fa9dec0a78cfa2360798755c01940104804288cb7f9c1383b3cb88f91744017a7ad8b16d652392c09934250d5e30fa6b1fe9b3f8c47c5545803e224a1ea5c4c323c62020eeae17c401a1ef7fdcacf66aa802398803dd364037276a3d077a1d3f795634dfe594803a4e0e5ebea3d384d03629a0436008e5bf53dedd7ffdb412652a06f1a858ae41dca94eba54236e6800ee77d7ea6883f47d034305af968e69697565b619024b33fd7b22b9baca15ce759e974b270e8d2c0b6b6aeaca40d68f5f3f77ca20a92bdcfd7524dfe925ae3c8f8954aed94ebc223777b802427b207a768572a0a6137bcd2cd06b929b6e314d009b121621a7e1a0f8d3d12237cefe482b1c49247f10fc77ffa6fcf30390a161322f00075e984c44a118c81d43eb7ce1d463f105e7ec06dcba11eb722242b5cc9b2cea51cb0bac65c79c8fcf637ba9d886b791be23b10589347ce73830e137ce14a5d4dffcce1604890af65debb805f0aa345de3412461e6ceedde473dcacefb50de54886a4b96d56cb312a0337797da7877a3b0869463cca96884ce4acf18976d966e4e03b670d3f8ca3bf7db22d21deeed74c2c733d6ec0cbbc54633687a630838c5300bf7cb6c2963359eba7e0dd0c8db9a713195653481688de5430ff1540bf64233d7696e5d797f39dc653f1456e847a342f059af532d580bb9cb3f48c09fc8772eccb4a3657e6388a068d642e1758119cd4287a841827ea1c22e077d6e430cc5db0473b9282f516919308fca8a747878ee02eb4e08329f5495f9600bb3af38cfff028603ce8af5795eb004796fe4146f92a95d4470e9587a2be72992a494ea7150904c39f645502e72c74b90ebab9e50414b2d1847a31a7c19c458bdf8799d6131cef83166e1f8e8515c82b034a4c3ad97f3de63ebb8f0a3dbf201d2b41e9e0102015153edf84b364d88ed8a93081843355b4eace73be0b6b9a1e89b5074bdd4bb43af1d915092372cff77088a6cf80e611717d389379c576b2ef9ba8de70cb17a1ff09565c77111a7727f9e35710c3b470954a286d34fe48cf7669ae02bf99e573830d152b60a89a741065556e4acfb6f7a2f708434b1a281e0a5ad34bd658acbfe7dc83797973cafcd4f2759b9d5c8f608a780769f70c0f4a83226891d8f4098f1897a719e0b7d8a7b3b26ccc5b6698032fe5e47a05959db8ea2da318cc8cda498357b1ffd2d0d996a122c6c5aaebf5406460bed9594e293204e054cee3138c769bd0cd7d5cb9eefda4d8ef0f9d9a070db4c75593ac42c518aa36f4b4810ffdd9c1c7e9819bdc7bdf3bfe63c7ae92e7e2a9eb8671769218b094a3efa59f853276608d9a6509720027e264b013ebd0e2b4675c46578530d53c585e10c6b35ae87fea9fa2454347d325245e596d46fa0ec808b86ac2555a0f1a495ac9ff98cb5be11282ebbc64b2a03c1015e72921e558fb67705edddac2894c30f71bdd1ea7e172d417a97f958c5d87c96f0c07d4f02ba2b32b5dd0e4dc879668af4e8edda061fa110ef9552f3d554c8c2ee3586394a19f86847b27c4324a70714744200d5ecc01a9bc0c8705632af0684e7310d0fd3539ccea586f304e97e73199c0ccd91618753495d9b27781a91a078d53fba4e704f9db258d18a96f33acda7d3d3d80abc3b70fdd83a1501f8e9c1929cdbb880a6359e2cc2fa2746ebb6ac55999a01244853cdf4772ac3922382e97cb6ef9bb1d26c8846dabe377f607f0b693a1a17bd42a631cf851f30bc6718fe7059265973140c2c960d29b07cc115f4cc2c9039b7d6fdc3bfb30816e4101af6a691376fd43f0c69debd71268c02e613a65de855312d281a804ca4086800902332cdd28a1f61e466e67962e66cdc6ff7c3a1e676e31de4955c9ca86e9b376fc3de7d6bca494e416e1774337de1a2eff6e74c43394233f552e5588970682872c31406acbe10ef12c332a68cd2f7f20d6288fb19305a2aa2528f4c36e25ae5d32e505e5cbe3795e0f9f70d8287538c37473c63cf6abd8cef9c006978ed0f865399ed6d545483b0c8d318e85145f5b1b95055520a310de9fda306eab7fab033ec7fa164bd10ac870cfa80a91fc918f267b591588d3e6c334b6c0123dd1a879f02132de153f37d37d9f833cf76492ad15d9839a49ea6166f4afd36b87a62ad10d73c93eb0ac2bb45a6e9d8bd6f54768e681371e73de80b09a0ea6c90b9d11aae775445ea9a1a3bdbe2b05e4d13111ae8f9c8239a0f4a9dd0a28a4eff968a5f1a25583128dbeb99c1adcc02a979eb4106fff3d3297cb1c8a7af9ccc581dcb5249c86ebbaa2923787bfdbd949eef6f124bbe94cb17ffd091cc519573322aecda28a894efe3294271825e078ee29f6360e1ddb140a89feaaa80618e324f2bafc29b15c4134eb9eec6c3860e502cdf36912e7a7137c8c270429c0421b74e2b9e37efae5272337ed28ba8f734b343503dbc22d8ea2d061513f515cc26c2d4f63373d7560ba3e3e4816f2106faddd051644d8f39a046cdbbddc953c80ff487e484b7d52be904cdd2f46615620fb4677c230547ea1331d654ffdf1183a2366c12df449116c869f8575780984c5ed8b54b2a49fe4aa9ee8713d98f4fd2ef35bd9b9fbdd8b8f1c38a46beb876d3abda48218b289621c64392fe42583ee6f5bf887f595d12714334bf5c230490ad2e5a607e05b332e12336cb4f61f9195552740254cb2bc181f3e0fa99fceb93cf04f8be918ae1c7bc8caa38c337d656fd671227f69eda489bb611e2d5ab871a54b74ecbe138bb5ae333219fc0793e55d9fbc9e0d03743a78e0baca303b50341899ebb09d60febf5cbeb37bf70996b4cde1f417d46e2208600bf35876366fd5d3166f10957448e6263203fe9509987e84186a3e8d62b248da54a85b77adef39b518d5635defda07c4351a7971ffd2147a9fc1c30410794dcd064138c1f3a0c259294bec6b744f78e291731b58286a38cdcdc2f7a485597d3c2f3821906d718e4d201d5e6bcdeb151f75ad933ae06bbdb649e3b35da28c75106a93b04fa1f0ace560d1871d653838dbd763f341184a7be434f6a23643d764f0a311df3a6b364583fa3ba54d6be850e2c6761636c7538f6f1eb35406b4cd75287b6584866aebcf2b87d85d7fa85c7d90c66595c1656a97c8127ba755a2f0716ea8317966f0021c4911e0bd77876d6778ddee435226626020774c38a7def50cae1c258a1f2e939fabb00fdc912838810217f223ceb003421cd210de481d04392b7560626e5f9bef5b82fa4c4d04008496ce90119892cc8d8fa284ab89590e914d7b668e250a82ad43ddaea514f68ba954998201df55997e8a5cb3e9373f5ab965e8f8e1dd3050e337bd29fda8df4a8a9aff6400e7ad0c2b42d49fe9b2bc4bb2d15d30dd1c0409777f9e4dc6d4c8919a572376f70dcac75ab783f9ec85e5b31948ba9c57faefb822e3c84a90bebf6954aab1657be25a9167d233ab1b02536df8fc6b691fb425a8f068bbf1f354069473e50835c5dd4cddb35eded0de55ef7a9cb12b3ebc229b6e0a0a53dcfbbdc272ece492c2010a520fd2f680fc67ef2806950f89c9ab1102503d3c7fdd8b3c8c3512ad595ce42f2672ed7292339b010af2cdda5721cbe615404c20aedce12fdbc15e619e1b3833228b3d6a6d7275ab50ef64091b580f481cdb4f03d17ce1d32be7ab4e60e48d662c897f36fa39208c78b0b6f684e6c9758d60f25997bae1fcecae8f4d60b98155a770ab2d958460e7574b00d87542113dae722193f772d2b254436ab83a486e78dc7ae5937e23329533912f78c9f5fe042a6b921994bea58b941091919bc09add9885c07268d7744c8f6cf018a6b812dfd905c55147e426b48fa3e0950a4bb3bd4dd1075bebe52968192abc847c9b4e7b9c6133e467b3454498ba8b83b2914d3abcb10e2afdd61ce31c1db512b305c639fdd7e923ed06825788e4e8b412113a93a371124bce4f7c44d2c9dacb20f64760f4f796b9cb0a9aef4db593494f12f36b5a49ff7b7a47a7a08295a20a1cec35ac388392a31fecbe9bf7981069a0da56394cf5fe88a00dbf01225c13e26dc80f4e3bd5bc187e4820f82951dc4e4fab6b04431ee14176a090b85b818bd8e0817b6e59c12e915f8d4b13484a06d3e802c88203251c2c6c940f73ae6905329cd373e0a092ec3fd9cc2f51d8902d903041b5c2cba1f11e67ab24bd310754495a87e2ae1ab29d5e974dc0b3025355db62b52b900137d8646203ac1af7f996468c8e4cafd0cf6206ac11eb5b522757143745a8dc9065097cbb0e49c5a5fc5ac6e572479b7407efa1a4c77143e35ef7f07efa431863420a3826415d3caa79f6968ff9d2400af3d6440e3a44a87ceb569d47cf7168a09e9241449b2604f1f2183956e9ad963f9fcdc7bfedfd7bb085756dd9714ac959bc8364211b47da1a842a198e1c23b68c3f6f0dd5c3a4666cb96ba7e870a2505727a7cb262b4592ae7eb586c61372db63c4bcf39cb422581d9c36fc8d94aeb3d7df30f2a37cbebda3881eb1a72c7fed2838d8540bb7738cfae9e35c4e38835252b091aa6af770dea0b0a6e0f66506b8df9e464979531b24b7c7acccd759700e720db8540f21d114bf2ba9c5b1f595a7ea89042b76ffc006f50361eaaff37b686b29df08d6f70f5d19134c0e87d97c536faae868f0d960b11a99624bd0d67f24bf9d6ce243a877f37a10867808f95788e0b9a22894f220eda57eade6d7c87b4733087b48d374563f8833b7579677244b1499ef3c164e5c5aed5c6c9510a61cee239a34f4f3b97d3f37d3b074d001c9dc0d96b6492dba706bdecc783499ad19f0cb14b09469222c1b83e58c515f10a15642cc0af520c21d3f8e3c840906fb06eb37c4d9aad1276ec7b5c9926c35472e1933d0e9456151b4c43b1d03b50f4e52c5d8b3b3f9f465847bdbc505f602653f14ea2b9ff40d8d2e929560c656901979349322523ca685506fca4f0c76e25b461348a02adbff01e02120ce2a5892173c9a1779e4e86a29fb39a458c7df4327bd29c20fd3bc9cd60284104f63f30907948a923f5be1b10eed24e09fe56ece22c0b915c2ad59635ad84db067e9b0a6d84ba6e42a4692d98e1cdfea9edd5043c112fb1f54d63710ff73e4360d495db288bc20fa4cba11f64d53027606c6d9ec614a26ed598a7320cb9ef65934a830c4a8f26d123cf75edbc791daebc9ef84d7add8889791417273faea0dd3cc6281b38fb378915201c0e03839682bdb6dfe03b3e3a2840ff5410d30bc523d7db616e2dd2f877c103b259af504884b82888590e9e81df6b5ab5751a1c477a2a88af934e1f1ed74cebc4e9f4b9861f023032ebde3d4943c52a37051f42145a33ceb2506d10d7d3c8010972123562e357bebfd169eaf3fdce351b8f628b9a9774ca9f2646ccece0b912c8ccff56f507dafeb19d165105f6684e7f9948befa666d06d9fb2a8c0f924d77a4f38e4c7e71d1e359ba8b0d9d2222754d21d2beede6d49a0d4485e93a2b4a83142e3e2ee74c5944b399624ccfd675b14dc9f828e131741afab4433061836ab18db52581721cde70b366f7ee36fa61da83f91ce59629365576ce7b34b2f056a22aabcf640c3e0fa1e93727e75fb56c0107abe4b6e8e6ea15d84f432abe1c8e371e2649e5ee90dcf2ad69b4d33cd75a8e73d216c9c8e811257bd5dcf33e9d2ca92fd32f0844fefda716ccb21b897a40c941fc516b48c75db3db09705a5e0f81164d691cbc31946f29affa62dad368dc35eaeb409dacd0c5f139a5907f3cc2842dd86573a5503beb2ce43b97149a37f52f1daaa5f132f11f0b44944c318b9bc1e6672a837c7f6f307a56437cb72a1ed4ff61e437fe06826e285353636a26dd70030d368632df9859c81643714791b9552457aa71033e99db2b4d1ed785187b2ffce2b128f9484db73ab21defcd9b16e855a5e15d30b1d15c7c6c75fd7f4feba4cd02ef15e414cc3c8b122804786d326e852a9863e5f9ddcdf5b25e65ea2c91017a5e1a6b083458234da2ff17e8fe28849a87d60e6017622535d56f49ebe239e7715abeee1890e1b48c5e1e5789916eef09991258b5f10778e73609f9701cb92a6239a6bd82ed9dfe2f32fbda50cc1d4371e6742ea61704a863452d9e5eb0483227baab8d430e1ddb398aa0ed3ba839e5415c432c05895659fd0e74d04f7b4270dce4155e68d23b9a2599ed9ca98d4fce40220bae08a264db0bf8b6e30f4a037eacac3c039d0087396080a0ac026d5558d51f2d9e2c76790aa83f4c5bd21c8139c9a5b4b6d7e4bba765b9efe4aefa1d2c510119490c6b9d1060c5330577f2360700d90e54849b58b57f4e90ae93b7bd0dfe20337154d9d4ecec799b29640edd260c89d1b0a755a9b49e66f372aac9c489fa30442ba91a93df172eca43e9b3bbd2a46cd03f2e88d141309a1c318926493df6901f6f9207aeeaaa41d659fab047947e9e99dd3fa21531c3c0539630a32072d6a424c3356ff9e6477539aee82caf8b8965de77717f0d7fd28aa7c569feba8624f6255efeb06c2122ea91f10f60af873ba3787949ef80b97528cf558071f6b10693d34d0b3fdcb1efc8abf675ff61050ed7f2abfff055eb3fcb2151aee5a010e2f8f3d238973d7a8fa082cf810a63f797a5524e3e6a2cf8b00b7ee894dfcc22cc08b67fb5e751ab68dd24a3937a23498a1fced439b17cb48724efe9842c2cd3b6baf34d61be171431e9ef1a4d8005cc4fa0ff6de5baa8b491d4e55f358962e0cd79cec0288c10ab67afc43fa0e0f8cffe243970b7a3ebb2ee8e1b01a1435bb09462e8e02d133f5cd891557bb526e69401edfc870b8c824f41f8180c2213223592d3171357a03ef018db258e67b516ed1a442dd956c289c9349a72a8225a1ca42f32bb60e1989e84052c2973efc50f7c95a276ee4e8021cdb64d5ae39ccf786ef23dc1b114be21bab4dc88a260b80bcbdc6976da1e589145e658c23e0f996e8da4fbbffca2dc230c342665e33dc93b9b4e792d0169e1a4e3249434c73bf68cd52ba6106c504ef43583425857ebbf33caa93322bff82cdf2aa2d482427f7228433ddaeac0b1637e735f7552114423eb9aecdab54193473d6a7b7eec26c0407fcd67ac28ab4a4dc48bd19865eebacd7fded715908a29d1b8c0cfe10962b32cb16441e43467ed0bc1fb6b5c18dcfe0e418c0f78ab413705b82a239715d6af7f264b1b75dae5e22e90ed90d3a58bdb9d41e7379b90cf96d6226633fc48b9440092fbaa911058a771fd39818c38268f62d5bd7e8a749c0e2002c6f55a43598235572c6f53164d55102ae86a09f8a28456fdccce9b70670692467dbf8f8c624c6f51020ab5e006b564dbf9ccc811c0d62d162149da4e4bf770b90c849bbe88c319f27b0db14e3337a4e9f430b29621769608f4d6db7b19df896ca4354175536ddc9c2b9d2872b8ea9b0051193067933324c5275da3462f818c9c20ef0f55d2de05a2cb2e6de4fea72bcf2df63ccaef9105abed3fad4601b1cf5586a795c775bb3cc7551340c2d08a70d743640abb226f18fce73255dc6be0a855355732a273285cdcc15b1ef74def920c50d36f9772822d8fce54d02f81f2b4ff36acdc8f4fb29743a0c799a2d5ce237008a0f88e941b9dbaf7ab1bec5dfb54853336223b67d08ff13784af63db0664b513d45205a8fc19cb24e8bb905bc43e8eb503010a06e8d570e3cc61e65fe5e24805c91c82dcec017d7b0a8b9020c1ebf1f113decd92f2195da0f24a13d27dddeab9e06544eae2a90b764633f343d97ac943d11ef7ea0dcc3aa3fe841bd5d252072e647e22521f6d45e60567958e2a2dd93a4aa68b3e4dcd31b49755ea51468656ddbe5006983079ba6742683cb15782193356da0e52683f13a1d5e353cdc37e7227dbf0e80015a3663c17b9480c47437ef831978075a1b3c60e65f588b990ddcafbebbb0d6ebd182b15e071ec438ec5d4c9c7b2d134a411c8f8d038d6d03b5e1cda9aa61ccedd1f67824df22630462b20c2f63fb86369024a8dfae8f8305407441bf0312b4cc0884aa2557dd3be4402402d744a22d20905a8a775f48ffe4f77d2abcc4a508c2021084be6883ab11cebbc91ca90a5b1538fedf076fbca8b8e3ef49649544e95b503b56daa6b63129173c1ffa577f6d1b86b94583abdf456ba7e8c535448682c9cb764f211fadeafd4c9c67806e1b7f4b5b4a49219642e78c4054f13fbf66775c5f326fd755bccf41f369305335d927cd101e4b754f9f0403df00179ad3ce31adea553446d5801b7abe1cb2d4f1d4515684a8ae789f810bc467e7cab49db492dc13aaaa9231d4fbe969c4699a4a7b17620ad49a579f4130de8648c2d470d6597c63bdadbd0f99b91901427e1ec0be3a59cf238cda7a49ef57d91245159aa58b313e7e93141cd922216d9b087d1a94da82f81d6afe49dbd421c8e6eec7b6f2b42c81b36c7bbc2cc948a8b3203eefdffb48514edd2e9d19c7ff65a5b3d7f43ca22b99c5db06c56e619fb007470272b47b26e16a62dd91ed07757b0c341911343ee2fe21ab86d4c10a59dfe147564633b3e4f144e72b8bfc3dc78b018657c6122dda1da26c14b76b9ef993c0e70c6ab2e1efebe85589114b46c0597797a91c6636c9e1b937b683999d2bb646f6019e8c5b2f0e45a5e6c09298c05f2dc23c8d312d36bc41a4ebb1b8c3b5aef5680f9759fb61a005db05258fae7d93abcf7c4185db75bae22bb4c0ff86897b330b19883d1ec4fdc11e8a6a4b64220c6e107c08ad89fdc50c093bb2d1657483fdad37c448860e2c4322d0ea28fc546f8d7a1f69e82bfa1a9e80109198481d25ad85788e2feecfc72f3b3e8d0cd3a083da265fd85dc2adc50c95d034f7ec3c4ea939c70a5c37c8ac7721c281286b07c69687ea0404cc8fa61ee3b8687d56cd1c6300f1524236ac64ccaf97c21a265953880c6bb0e3d5cb74022352f92ad4427495bc76232c099b12a06f70e3489176a51060ce69bdf04d5593c551f582cf73fdfa2612924ed625c334ad142d7d6b6eef28be64ac70338689dce63196ccb30a4b3874b4ee05aaa7f60270d94fbe7633ec15e6abc46809b792c3341f0128a0af187a5b4330de022c74005b2876f15d2b3695aaedab46f69ee06e086cffe0036a272779b987ce92aa2d9fa31ef890363250b14fc90dd5998347d19e90aad1da2f28597bc73f1da61cf937e0f14b5f86bfd9783a3b3460df90521d0765df7d61c896f044c3971d18092afa183c522ef7f98e3e4ab1f6db6b7bef3bca696195c6207e795442534b7038c6a36f9217e4907e4914a3d7641859e1e8081900843c596d2e5f8946fce935cebd9a79ca4fef933f3948946d02eebb9ff41407c55ed4a3fe10c3386831278ff5eb6098de5e0fe01a5e4cb169af908ac1c97c79e88f561c4835752eb32a355c1558f71ed758024ae3b933158ebdbfa1049579908dcdc5e9913dd54a466a680eaa204324248896d87bb959f8475b387321194bcaa724b663e6c991dedcdc1936ee98d1da51e9f6d81bc28aef51c525bcb03d4f9213893b120f0042fb2f13ea36778a55373ee53fe6728c10d10d4447e9ebefd9ba21eda6e0f6b58d1a5e7a7ced24e0032ee09c27aaf7738b92e5c2cc492ba4a4901989894c07183232395cdef4a862428bba13730482da847fab1f851613f2ad644d220fa445124ce91878662b7f6f9b52922c0c8119f7ced3dbd985516e218ae812c418ed2c7d25be46808e4f48832c08e4d48fd5e7e89233fce9e9730d16cd0acb0572acb89968f75853676667e45f80ce379b16780b0b5c5d2b73ff801dd83b16b503b625d53432b0fdb460e08afadaa5c09973acb4b064d7f707d7568b09a03b925cfef4353eb65a26432375e7422aa23b8bfa9f959ddf6f8b257176f3010be8aeead5db28390ad85b69c8164854c44fee68e7eaf1a09fce8c17ac1a88fe43bf0e708b5e081cafe898c0071f1cd8303ea22410db50884f11cd694e4af9655c27bc7cad2554c4db3e67583c42740d920132ce5f17f9e80340df01f6911f0c6860b32542cbf177f3e485e9fdd191c870c57088928fc095dbab4a100b0de0ecfea42f21a9afd3b3aa97bd417338cc07b3ed0983b9e92cc231fdc2982f4d753f58f59a1c17405cf52637445178f2ae396eee0b32b4afad3fec0381f2d38f18601b7842ed25d91433ea4c198248168e1d9686baf8a327790b81c9e6b8a38310d5579d92e52dd00cb0de7c84c8ffba257b50b3ba4464ef775891233b6d55a7e923625e12ec8e7e3427b5228a01351a66a48d51af2192b0966a8b2b40e1b91b71ec5179a1231ddefe06f56438f13493d94e86fa25dfe465e385341f812dc194396e312efa59171ba331c9547a6c603cca17bf5808e2b31dafb164309e85080b7653ae63447437ca96ef1afc7849fb121fd5e15d8c7c925804cbfbd87e708ad50470542770fd0124aca7b189726d26ac81e6a07dc60cc8e1e99af96adb7b3f724f6f4c70b4699f1caa85e8efa319b93728984e9b43eb1dbe90882bbddaebe81751319f2d56aa8e8c409d3f4db1f11f3235f129cc3a11c4cbeafec35a5cf2fdf89aa13f01c4bde4ad5c4fe7b5128bc2eb1aafeec476d3e36c40e67641a0cca02fb84f818f955e508a8ce67a787c5a725a1b3338c48b1839d99f4f2c302155c13e6146eb0dc81f1aa5f253ec34016979b6b5d2159a2ff08fb0bea83ce1711650883d365a03c2fefd46ef782b17f05e66ddc04be1640d41d9809f9f42d7936e6c67d500d6f3eac4c2fbc785f5e4f463287b03ede21b249e9da66246d6972e566287b271cca7d0ee7f275aae4cb051caa6b3215d891f72636ec8fb7ff8643634fe94fb02068559ab2a537dc08310dfbca41f3362c164e9c81e5c5b8d6c8a07a48a8757892dcb6478c94b7646007c6dbaafd7dc6f97b17c60770a4e5e029c70a294a8251a464c66a9c1dd43a40b369adc98cfabc8608bcb9396924c884ace24842d25f2f5196e728f23cdfc1a7b73b85fd1dec3b927d0a9134f37883d649640a775f72b69360a7ac52b8bc006c86dc085c45d701a051bad4b243afdf769f2d2819037ea4bd9f46f66096af684bbea143ced929faa4cc4b178e0ff35425a195c3b24adf5d8d301af91ea4ce80cc9a2bfd40b7d5f494ab47dd12f04a4aded508ad9f24f6c62b0fd4a12662ad59f444b1ca4daae12a3dd5c39b60c2f78c6ff9de5d2f70003a3a01dbfa5ef81e3d91d395366f96d0d81117c6986080a5a50ffb069417fe0439869202827cf598a2c472f575df52a60cbae1f6608fedf6f76b4d3e39eb0b02367051630cf3efa20b8e36ba5b820a01b34251f5e7844c386c59c9c7ce9bbec724320b0fecd801d09757bbf531f7d10dcbe9de46ed8945b070541b052932741a63d48c553a042d0295c8199faa1b14748fc5b951b8cb95930375ec2aa35747fa8cf728d447bb8f583a62ebada9d719692ddc677b58c591f2d4d4732d35c7b9c924da37279c520469e5c4a56a1faf2ffcf38bdd8953be8e6946e4fca7f79c5634b7b5213a6ce73527e7b3293c76a505c5b182e118ea7cca9fa7d69a9a520be5c0eec6175e8d426b300aa4755d26e02fce23f9eba4b73212e35335c008910ce19c7cfa58f794594636b26294c43f72ab70cad396737e28f2206f2601434a565df1ce8af538958b2189ab051099db2cbab9df43acf2565d19160fecad6647a36ab2d6718e02c747502395000af879ec0cc385ec2170da02d878e7ce3eb9df4097cf0f6fa74688389ace56c2d990e36fdc80557b0c28c4d0daa14485ea8ce7a6008047c00a7dcc56e8e08772a0afb8baf05cd381127c80aa052c433211072ab48958f1c6a69eafe14d0510787f6718b62444471d0594f04d90ae5c1c1610b46d4b060815b1635f31469a78266d930a42569fb214cb9306f1a586ed5c3359bdcd328f6d3f4c7b1bec076fff607ccb800e7a6287d50b8ecf6a2f6ac04092608fbc8db9df0c65b62b72049b8d0ae377a0bb6aeacb5d2e42a3b1d5f0b38fc6fbf91b47d5165adc972d6070442ac1f5409102854725cfb20023f53af504b9b412f10882c2b09f6ed5a2b2aa1f4a42acc15e73ee00bf07edd19577fc3d89932fec543942cd03ff70e6d0c83877b1825912b340c506778b08d5c3c353703c1cffd37611af955854e999e65947c06b48a92a338a5a730e483fe5d7a2caf079331b466262318d0c3c63fd813bff957be19a447ddef0c35c8c44b47a77d3ce51d64d52b469591bf5a520239180ff7cbf6cc15b29465a1366264ee27507bdcbe0b485200a6f66aa1d751a5eb6acaede34174663877bc3d05db4cc46eb6b9e33d8480cd0b5706cb480d0cb9cac9bbca6383934a18eca9c898b9211f1c16e64713c5913c725512080b45d199f31b13a5ee6001dbd0304fb288bcc86a8d93cc03257a7bfdc3517c28143d95b98cb33dcfa54709f4fd61d867dca2ffa1d1b37fd9baba3bc2dcfa84e975b390b69ae09c7b2bac2593c3daa05c050654bd62a4adfdd43489381574ce267a58047db9c328cbe6c581e9c79af43d681298ea233203c86e47d65010d2f041a6b1e0ba476d859bf5b2fb0388ae3f7241608cd10d1736c070ab1dd88a0ad6ddfa6ee257194864437ffa224aa34e00feb0985f7c663e295fc7344898c6a3a1aa6bab6329f8b50fc2527b04eccad40e3202dfffb1980f41aada20bb20517490d68bc6b71ce487618abc13cd51d8ea88c18573182e5c1c709556d80edd2c28e617d09b6ef724e22b6c00ea72b07bbe3d1a03f6f0538be1bd572d0bb16bdf79a02d8157bb7b656c15edcdc97c271d8cfd585458a5d92a165cfe829bee5aa6218c41cdb49f9e81bdcacc85d7a476b76c148899dae717ce35094deed20effb8550220e615bdf8333ccaaf2159745f8f555183a63a1cd135fa8f8216d48c941e4f543af7fe1c930347a863d8a62f2dad1c00660df68e726317994c68562e87d673ead62ec004a454fa75b8cf792fa3f6e9e9d05fdb61703717ef52ef65680659852ad4366f2e7f819ff2a26572c9eec1d1e5737bc214cc18b1f586ce180fed190ff82da09af43f825c2120f78ad7ba6d25479f6ffc9e4f256d64b524b1f0e5ec0a58b59a22b46cc549aa53c9501708982c52da927dd4d93fbe5370bb0c1b086cf9ce16957edf739151c8c0294a3705b8025334404994b579488614c14e7522802b549bd5136dc275120687cd92b78f7f61eaef84057fabec95294a64883d0f00489098cf798b1b348ad101d0a039d0c800c90e4c8b4b9ea6f9ffeb39f9d8f170f68c5ff15e59f51ed6565a60acd259e78867148852c9f5834d7292a92f2e2315bb3db03945afe80dfb43e6882350c35a3d3cd5bf77091b36907e715f1271f67928c60f4dd4b8cc5c7af820fa3fb0c344b811ddfa89b73d9ed3676375f83f6185da1b25719e78f71ac042ae67e776d3c33c88986d07cd9a1724da94d47b9482087aaf01f45a455ef866c02bdb928a8b06bd762e2299fe5616404e3c27a7028f79a14f62e244e3961f8fca4ae257366ee7fe506ece07adce41abf55a17cd5f4763682b867262092f1a640a1b4315e82971527b3f2cfaa4fdf84df228d80d769081683a9c701b0ed597cee06323b70583c3c5bad1a2eb5a699e655a4fac50fcdd0225ab19e850be7217a42d1b8f4d53f1b5eb33965d517b8ab9a9bcd4f128910d302e073ee6a9f318bd2526b056cf8a1eebd07d9fc312c08633643b0d559c4f2ee3b387d444347631fb110a20adab3b7cdd35ecd98ac80daca1a8ed1063ab644d1e651d709774c71ff00016367bf5658c730ed28aafdee4a437b97bacc0ef5910685ce3348cd8e924308a6ba071c4fca4a9c227a342940572c8c3d4c13ab7dad155498aee1155751085db4f6b5d8bfce7b61533ccf6e04e7344e578c8bdc14ca2294e8f96963a1308137e454a083e64d269933aae03a11e66bc7e269155e70bcbafe4617cdcfd09e20cd6e3f68f03bce7247ff42ede959efcdd1291ed40b81ec2bfde98d9a388c06896a3d31a5241ed523fce724e14053dd14da7a912f30cbe383600ae4ea6690030f034fdb0ef1ab88e0422bd92df06f89810cab1d60123edf71c08aafd773c38de96a1144e544c810e9c31008aafd4387d3549fb6ef502c88fd312b0b54377b69151e4c0b9f9ae59a7a3f362190553c05d0099f24f385ea633730646b4b7e7ebe9812c3e97fcdf0ffd6d9061bb66e457a5504b65de9035e70e165be6b5673e6f726917867722eee79d26be44aa3d272b34cbb6ca9b47500ae791325f87cfa13e235ab54adf58c1ae758391b47043755a865d72f9fc5adfb9d013a1df216e60e8416db3ce5f04e296ecfe47068cb75bcedb2107b3f7e143f4dd88bee23eaab6e800e3301223a96bac203bbe4826d497e4d5f86dd7c0853f7ba4b52cb7aff74a6b1a7b82029f1d26ac84b38217d6eec979c3fe8e9d046f272fa07315d48f5876103f64ff90fe2db18935f052888f5dad0eb42a846098957a58fdd76b539a080ecfd3ee7730db236806d51031e5567a04ad6ade17634cfe84c1c57aa44671da2bde1683bc1292f06e274cfb95b0eb8d20afb2ded9e00438ae57b8b33ca6d89a1cba6fcbd98b162d28abc25d5bc69bd46c7affd20acef975d67f62abe579ae5badfb2ebe62902cf8059346b447631ad9f011ff1f6945ea87f44087988bb72463bf4667bd7c249828d121bc4299a3a0ec6e2ddfb33455980809cdd0be7cb0feeeb4ac5555aed0aea8d4be238408651749850d7d7fba8fde2ec955940496a075dacd43724023c4be02cc367ae1a7db83239959e06d29b5241ae5f28dbbdc2ec409ade717831b155668b7327b5d473d7cad1ec11b0e377b31d09f0ae2bdf56a5e12e990bfa783c5823babc86f410c92e6f41dd9f0238835463a68705df311e5453252b44a7076fc236132330449e1de2d34fed180b63934a3e2f1993d09bdb9d5f14ee4eedb59450ac78deecb9edd313f450026ea97f12e37975463613ddbea799c2f8a01f1e53c786d6dda60a5d2c98bf8fafa86c23ff21cef6ee4efa12fef6c62095c96c4ece10d4824940816ba1a2ab7a6b0fa96a54b6217aeda27ed4573628a3a6fe78427e7833a76d19e6fd88bb134682ee5e5da18a82954612b136eb0dde6c68e33118a1c0e51de5d33be3d54e70a1d9b476c2950966dd28e801a047e392ad28a22af7b45e25f04fad5c4dec7a2f2eea1c22c35eb5aae6cf387e145f895f21aec5c55c5d96573471a289ea7935d1e6f15b2d0bd0b726ca1167a7e5eb7f77f772127107b35907e0002d33cfce5a20fa66b81017aae9431acb54279dcaf92eb687622e1543348f84839bbae41b1218b81df15d1ef90894d437c135f18dfb91202b545e3fb62052b9fb19d30def917455c9e33368bc542be0f7f552f96bcfe0a824251b27c72eedf21f37d2330538c67c456a57934878c60f4f3319bd85448b1fd2a48ebc572e45343023d99826817dc646c003f1393a435a5bd69797cc6acff27898453c1a5f86596b9cd3416e4b3d3b2c72c095f529e8e5e5bf2fd472cd6708edb28e2470f065c7d121b014084a5b3b318c7cd8152dc677ea2f222b3db528b3bb9f92136044a19fd1c8b5aa00a550bea37cefbc934fb7f38dcd273a528b837c268c9b75fcd0bacf7d92c10f865f8d72c09b79bbae2369de947f9a1775645db745cc6aaa18278a6bafde835260cab2aa94f76d492436a47395b2c7bdc454c426a52ae025336f0f78905783664f0d60ec88fa161b4ccd523ccf04da3aaf3f67f6bf8913e4d61a288601ae11772cd4af662252ce70ce6fc3c9ab027ea29478442c58a8c88fccf5c25bab05d1b01aeb17aa63ebfe8c21951ad799f3df449337ec276c062eae1cbae5f92b54a69d59c2e908ac44109792113d4b983e24eba853f05d9552edf2ca381bb5b24d51cf16e77c15587e7fbf1cf41068ad3b4a557841bce62329fc3efe0999e9791069faf3ddcd485a6205c6552a7851de8f670ea6ba498cc652795da1b0757ee69662b6c94a4f7ed9da71726a0442664e42f3a453d836c8929a68484586757db1314a82180ad08fc2297f77c3e8e3730c53eabca0cb7623911a9920a9363cd910ef3cd97829450b15a6c1da70c80813beb7e9e584aafbbf6d3c3aff01bc4c69546f1cd956b41ebe05996ec820b280d03fe46f05ba2afb555b36d2e9a9e59cd344edc7c894b24cbbdb5743684fb5e03f6a07cf78d0a3f1a3efff55442bed09dd1a8344147420bb727d6f271c061a5f0c6906c8b1eb471b7ec05f3474455609a6465a6992abe5ab53bfd1e42feddde12d9e93340684f507dd9071e302770476186f5b0d6f95e48d74506c5ddb320f4d792ed65afdcdd6ea4703c9f6051b380cf35a19d755092493008c9cf1e0a384ba24bb7b4979307cc5e3b40c1f20e3ccb4d323bbbf2625e11b05e27cb6ecf503e806da4125d5838c4c2de6b9fe1076a2a36c815b3d47b7f2cc55a13489dff677e50fcfa254df65800383b2169ec1d02858a04156012a208705c201bab92cea1b5be69bc4fabb6cf50e4f05a66eec7479e35d9d513e2910ae95e26c3e9fb978f78cccddaf0eeee7676ad8b5720fb4a7c658ae79257fd9b2c76200570f2fd2d8a11e1fe5048647acc1987370097aea458e8fc3b24fb11bc82f8ed51b8012826862e8ff3d1afeecd4badbbb64bf41c69533801ae8e475c8851aaa5c1ea1a22f94f8c471bf6514dec6b982ba5adc07f8ff98ddfed6135fc6bdf1780f306bc6bc5442f88ffb6855e4381bd186e527499e158ad45bf14706c0c4513c37ad2afe1b16f13f288fc16cbda2edc3a79d601e07f98b57c4ad5c95c99b90090aaf82a421ff97bc428e1d362df55bbbbf6fa125bb7e03ec3d5632e4e3ff0ee4103844fb7bd98730394f646f0c926285773c5a8075332b6a317adf407f961f44bcac9bf1f958684b7550302b05f973c06247c3cb2105e98e8efa28b63c6044191b5554e184f48ab3e78082abb007e8cbd21dd032262b57a7c7dbab0f9336c9eb64afe47071052f006e13879a290a98fd318146c03efda6d83e02a0f58fb3e5ca297265ce8b044b7effb8ecdbc53a1a68dbc0a0c099fd5364b0f05b0fecaf6f041bd0b9509bc5c8449e242141bbc4d02630890e3eede21cd5a490aa5e9e9159a697c4866819303573bfbe8daa18bdd3c4b4e7e3a13cc97bd79a5b6efe7cd19fe1d80726dad27d8b8f84f2abf772d9cf89bec8f17d4c109f151686235bb615423bf59b7c3ee93fd5ac593e585fd1f8b9b48cdad99bc13e02a62b6de071f5af426884ae6a512a91185f3230f883ee781e7e41bdbe0c1454abb47aedd28b1500a305583be5f39a2a2c22f7318737eedb6c57c5182b3d8a2c734828e32b881fce78898212a9a259ed419529e063c16263597ca6303fa6e9dae1660deadaa02bf750ed696a4ebb11c067c9abfd4c9116bb1fe444d120ee82c915dcf5ec36bfcc4430d12558fa60d1cb0d2e15d3c6f643238df4aded2a0e029f777b97fd218a7f0c6f95909f9f83edaa01f5725a585364c15b33261ef9f2e1faeb886299971b8b5ab5c9088ccae3dd718e4563774370c41ac75506f43bc8960094978bc168c125646ab24d3ccbda34d680e311cef6350a40a6289a351740f43ad4051c86ee50e33504f09f59b2ff8239c110b851a497a649c3b035d05de5ad0b195df868926218d53a6c1da3c12a669a8cdb3be5593d7cb748a2f06203888c20f1bf61f8fc09e38ad3c65bce4422b403f37d162d0ee6071f40a61d56eb2a2ddbd8050f7f4dffb860a40a934ec7191523d425b3645d47abb2ddac667b2c2c840cded5721c0fb2058cf2d102130827adf52caaacad83290d52472f50e6401a7f615ab3aec6359e6732a115c44174178d32eaac565c9c1acb94f0af546a5db0b06feb987e85014ecb767d2799396b54f7d962da98a75e8d48cae176e421bc65fb22355eb56474124d2f1ae561b9c1f64d55e39adde0424438a8e07d177821d4e283633079170a90328b22c5e250fb228749a20281894c6b67b6a1d648da990ef042c368be41e3d9b0e7e62a774e5a60c44e04de4fd77d2706848b35ce7b19b6de9aa8505986f48c26738d48078f787bbd117f48f950b974adb6a0b70081cc5afd2efc2428a1f61d56fee3d58d33d91a790560ea95b8aae88685b82c9a80f4cc2c8ffe4275822f1bc5bf844a6e26af857aa3deed204a841cdaf3b62e285349a95934e762900ced7425e6053fec49ad3f4400bbbf9c65673f585edb5669b0c960f21a450dfd1f602cc64658d09e29d74a167033b4992fc70026fe2a4a704c23c86054a0e7743a1973b0e14bbec888915423142886ce365229234a0f93d7012432f9973a2cfebacc81f376a84d4a3cfc481b3feaffc214fc8efa41244dc04b080a5c1684dbdae347be092d0095929a3ce6dbc4ba5bf9f385c31a303e243cf29274cdca9f9a7df31ac88f88652698a12e051f144125b40e1a3725db2bce563135e6535db2e48b989e2d9b835420e8836c3739aa5362131408629f8f027bf61a9575e213b9d93e0b48cfc6620de241a4fbb8622e186a5d1bcbc4781426b117dc727b5d6fcd893e57f25866cf55391be0918f02672ed6fec4ff6eb254358d8e74605de672cdc7ccd2f3d541392c2852cd5e4f5b12f4d5ea15180b9c3cfc322c79da456cbbab7c8c5179962c33e91af9879ff0b0115fe65d0ae58384faba11b1f228297ffb34ce8e82de47f1499715d5581d145bbf62cc79e6b2ca117869a078fde7478b8e782c1d856f588d832465f94aba14255b9a2338cedf3df55264895048366a9660cc2b5e15f89fe24206b16ba55432e55f86a6024b2c234894f8d0ae3afa8b45799c9d3664f5e13e9f05d31c67539bc86c6292c507e6ab551ea20d3981906a70075ed0792c5e9142423bbcfbc250efce4f7f9ed81dde3c882dbe2320a850d04ddb2d347a90c4a0faa6d58f89e6c15f8d18d3fad7f2b286bde7361f2dfac872651ffac8fd9a14b31f8209ceb9d41b9d54425d2aa512d0d07c0708a9856994862245fdd0fb2d6649c8611966840bef733357134d03a0ad8a2fe0c99fde115f85c74a1065477d1887357b0f8b9bf3e057605ce34bdbe6f4ecb018169c65f0839fb13320ea06478eeb240818664bf766a9023d80bbf6c67668cf9a90ae9828db87a7d66f05b575b5d8436f010a254dec2046cb4eb974a3748bd9a90fe98b499856dea5ac4632d30ab19728984132fdbc450bf777fcc59413a676a3087dac5e15384f5eb17a65f6d6692f7fce7c1db39b2c5a2b9ac72b5e49ae39a57f0b083674389ee02f133c8bf1cee4e1d28598fe4af5c5a9b9b669f06de215905ce71031399c19f5d9e23f6a7f2550f550e5c497cecd2aea126cbfee5cab21cbe165fd1ea50c70cbd877c41dca39533ea6b8e8829bbe7f8b30f637873a8792eb6c46e69e513bbe1b6ddcbe2d014f4118b0c381449ac04b94bd40eb71800bac1492921c313572baef1946cfba5d53f51491ce0ffa9c48fa5722f47c20a094f9ac17578afb16f95bfbea1e6ebc69a6f03bdb0f81a89ef97855376232d839c7dc8118ff260869050658b5724e6d9700bf91dc2706a933e6c73935c7ae845b40dc041ee988cb966ed0f9253ee54be24a4390f70be07a062adfaa7fc6a5438aced6c77494a21ccb08bcb0e0993afce7dbad3bdf614e7ebbe820c9d994d2a0fbc5c818d1a42750695f57d888af6dbe79fec15a876bd94cbcc61e8b41ebcde38e7491f9f86f3da1cd33d0bea0f228ef4ecfd20e4a16ff6c99dd5567d9cb1bd529de409043c1596759bdef6bec280d0efc8e581ed5c3cd7b8909de16c708a5b424621fdff4411891d6610bcadac7b5995a6b5fe2e7737dc4b2c6a008a9bb604ad8e7053a287b3ac725a8bfbf08cc0ac921a6ab96c261b475c361b35070c77f84de8ef4f8953539002936131c171131e840bde1cfca4d3bc8f7d40b047124cabca8036a068211e67f14320b45103a46072d5e2c5fe46f4123ee049fdbf42b37e493f186fa3aafee19147cca20c60774edd395f5c4f5cd9df56358fe42a827b40c18fdd1afe2499fdea5381b76be8f0a0fe9ac7fa698df091e574ba87a67e4735d65197ff76ff9f0af300830816e843b3e8c40ba1d6cff59c916894ea54f64fb09369da723a473123a520a63b14b07014afdc1754f81e3a39613237289af0d040ee0e9138a497b9a6d752490832b6d0d1b36397a7e801cddb3aa346c05f4b7525a33dd5fce3bdea73f40c9b6c7eb59c52cb5bdefa644e90e62f2263a37af83c94c337451c9be59779af3d85c8340143031635379036416b2a2dc090d95f97f30898f419a5621c7331bdb41d547458839f7154766a99fd365800dec9e4dc0b611ee7df9927f35ca152854d55b03585f18be7d25c869000fdb28ea5b62afbf71a0e609a9ff2ec4e180b040e3793794ce670bf5cd11733899cee1738bc008958c635a8fd85c4d01a4cf0765d4aeafc0638310a800ed3ad999cc16cd6523e1eda050d08ce7f8be7fc458e43ad1fd113b8cd1ab9e8e377e7d4515e8526ceddaaeafee0c9978508c39ed76781f7869981102ac25434273b2b0503259f5975a785c2b9ac11db82dd4b56f258ea0837406d6d848cbde2e8480a50bd4f495f829bcf8d9be5624f9c8cac889b4e6754e7c6ca805feace01ce7eaf29d5dabed29025ad406bae217cc855e9a32879aac4ca33b7d0079fe6f2c87e300348988ebead0edd1b066aae6ab27d2edd3e0688a4a5b9cbbc88b4242dbe844e5bff27de8bf827ec3575b82bc4c9c0a302cf7026a11c18d1b2a38b8081eef9c244827b9d65e7585b9ea29072b74c04dea95998c9acc23331bbe07227e4aff3acfe060fe355e3bb2f55d98c7d771b529383a964a4fb7d6b84579b0b35932498ae029bf8259d920bc30deb012782120d3f290fa43f9f25ce2de760295fd0ca9e74526145f473e9ac593e66e52afcaf4cfdd12a907a8b7c555b37a26c200652630983a4436af90f21348f8dc6096575bac97e3345f1eea5876f9bb5dad43d29916b0b859a7ac4ed9e964408a8b8ce7246861bd3fc588dcfc98317f2efae4e5da6c6160f09c996f83014cb8c41c0d78abd5b5cc064df40220feef4048f38780471cb2c031a50d18e8d1c8201e19e4e4040b6321b91f7159ea12f5305f6ee5606c54d99b2d3f7b34694a2c5175cfe337863040c61dd10d2fbd6495f1fa723c71e4e529f5abd1421d7f23db7a68063c9a5e4447d87103028a24af4dfb40d186684379a0d7c4b949e7d32b00544e3c1228a0cf76a21b9e1a3c5c99ca5a1ff6451669253d4f0928fa18ab5193e14a873206cd1c5e6be411eba3298456ade5e2f99950b64841b071da7f3d9e7aaec6b109a59bc25548b5643923f131466a10a5699f1a7a744a03502b1f2f6da31df25a99990b6afc965a020518b5524b1c7bac05c598c6621b284005b91f1d4edaaecf5b6cc8e8d882b2f1f047b0b92b583caba759bb2b69db72b7c6df74ec8065cc9ccc6adc5b22d6771087fdb7d6c08a8a559cc49dc37fbdecfa5641e347eaa28a2176addf401d158c4469d18eb18d542e213148b0673944da95762db9e9c7f172173934bb2aea38edc8ecc1d682cd93fef2a664990caa01220aff8b767ec0f85b807d6609b2c305810c02abf0874c140edbd1d4185cc7a6525cdf1785b30246092ad710a6a6a036c452527a09e64e95e4ef0be85476c180ec466b49102558fed62d36b5fabe385a4d21d8bffc46afbeae7a7551a68288068ec79f113f4697262ba6a0c8cf5f7b576cca88c5faab228fe59258de6c9ce58f6be41ece9e108c0816a648404789e280ed47d23a293b70bfadcd0f66a4c36be9a2d8b7d3f4fe6a82e2963b5be82aef931c19952eb4b39593d71866fe811523adc34b15619a7ebc8739ca35d36d04bfaa076c63b206951e669af1cd58efa229f88e348d438f2c761d4a670ea601acd90d0c5aa30a976cd09e4d25fa7a74e461e22179e0eb63165c7f6989d7af66092b58769d389786ea46358c5865df24ef9fa2f4417a370b691922f70922ac57aec8fd187fe25d2362f3d3cc08a738ef084d9af42736d5cb1192e572df05578987de7125a2e5b1cd9e1a0217413d92892014a34778f62163ebb70232015c1db4030fdf2db79cdbe568f1cda688b24db7a125a7db45f8d038a563033af260d3bdcccb2a791b069a05a736c3cff9022f884973176d4ccbe7ee0339706567b8826f1eeb973a9f762e716560dad6ff9ccd740cc33f692bd14a16cad9dc3161d4d2296f158f4cae8ae8d475f4e9817a1985426285168a25b9d6ee6d3114efa3f92032fec0a0afedf3c24032ab9c9042e0fb524b81ec33f9804a78d84577cb7e6a475bc38eff4bc37e12cabaa84ed13a69933576008af73c248c171518c2163d81616c6539ed3b4d34ead364819e102dc57766a9404c3484c1fc2bc0efa65d504be2889faf5d1b55d951d0903ba5bc610205b18399bd75de140e8f443d1544ffe2854711f6630eb5a86c5b6cf74a062d95e7b574b0a06bb1aad79db38e242410ac4d1178cbda06767a5e58ad6075ebb693bc7f0838c20b157412d5c7b16803107ce1ad747f8f92efdc2e3469dce2f0f0322f3f99361e81566ce95bfcf3b9f9b66136e93515d658b9778326bdb4cf692e0ed6e0e450ab21548f42f4fdae7214e10a6ddd036782a3c099e25133306d724d8b1c6446da25ac2aaad48e1cac56a33a0c49fb45204b2cc8189002eedcee6668dda89f7d2f42ba6ae141e8d462d76631039769ed3b1688513677d8244f80a795238d6735a8087c86b96cf0cfe2c801849175dadfc62f844d5ed5858fc3df3987972c65709d68c35893e8c67554d2b7682d5f6c064632ce25f95ff9184a9b391985ae667f560292919d11363e7066a85b4906a2a4680b80855f4a81ec51857ca4432dab2d37f734e684934944f2eb352aabc1305400375478150f25daf155e11dbbbfa82a6244278b844732eccab2cd54c513da19db64aa4068fbc8ce7ef9a25b3d3d42c734e3ce4ded9d6c04e4db993be75b3134925c30e3bc47a4a6a05cd0e171e85943d7b490e434ba2c27f32150dbf421d4b74b45f8553194609c914368965651ca60e6e41a6525da08ebd32e207350195e022139a1278f74f4c050a8d0c4102c10b2f4b2c7ef4a3852251e2e32e40eac95c4265e9d5ea78bc964a4af5882e5484250690994aa6180c4e7593b3a70487cbe27d707ecd6a31127f97436a50aac88b6a933d55774ebe6b029822fd0bd5f25b1331b1bce236b3c9752d0787be33a4e2b421024b0306162db8364745fb4bba3575625a323144ac2484e9bb2a9a708038563e4bddffcd1a04fbf8e6a30a82fe9553185562ab0ac1ea9500a644d38ce6864a8678b36657e7194c28af5e6a46740ee46c8dbeb14aa98197a4c1656c58de7f2243c310047176e96ae7a46d96ae5b2be9a5e054dee98c9ffe823c622023b2f448621bbe4a82a9d94b8210a8a1142c34739a6730d8bed13384356503cd29c5a90c549c36efd55478fa303c204143f28efc0f51b37af1b20dc694592ee15652c7f7c32a2ed74d0cdb617397c8061800fdd63c25598f5479432d1eeedba75c77445eb2053848d200909476f8b84d4da0620b3cd3254119334b12fc32242ed24cb1e94c42f0182a2467e7b2714a59b49ee4d5b7fdf298765ce4318eae35d0d4970bde878e530152530760c8eaf22ca35bd2438ed6392850e3c940210353a37f139d16466b2293ff7b00b7c140f921d19a524f5d876795a0730b33652d0af0c00b6b04c1e8d3f4b554f80b940589368f961049d83cd57ba834477ce4085a694ef30a3eac91cf3729ffe8a51cde66d2bb780dbba8025aa70db7fe413cc2c7645bb3f27a75640d7a6105d970eb86ace5cf86d32a05772d2ffc92f7238565d23c128d1904441b43afa5b38077dc1329479e9c958c6c4a44478a0cb0ff096dc0ab3ae3d7aba2e0e20434e02a16cb797df2147e6c20e48b6795a8ccf341ad3beba502b638941ebb1c390f1474c74ef701a5be6066b93c2f54146b4351f594c67312e36c5f14497a63017bb17732a2bcf6b3335665241daf78b077f63090725a571bf694a93743783ce37f23dbc9a1f5d5f7957b49400e2cfa80f8d09751ed51d7dfbdef36337b840abbd35a79a2563be94e2b75bf65c57986310d21b41fe746ed843d83dd19b8a1c0cb5f805c39827b60fda24b98daa8d14143c9803fe5d8d70289314e74e3836ac5d524edb8d46420ceeb5d506b20608323b28f7d55d24c829a4b17cd564a2d7e5ce4c7d9dd1ec07ac4f4991e1412716731135afe1f6cc1f1afb58d1283f47b119d24b5e4cc29d8892c6a9260ce055eed43ad9cd6b0ee9d0e031f831eaa1ca959bb75ffecbe115b89baefcb757ff02fc760120927068a42b047b4d6f33c4ec0ae0393828ac9e0a4269f78d70b5c7adc4fbf5de56f74ca77c07907b484a76d6ca9de34811a5517b5583a56f2ab2a169ce9bc7260a9ab07610e2388b338b2775ab437cd5fd29468e50baab29bcb66ba19e1f712022785fc105c0c8bf9f4da8876f25808b342152d767cffeff3747ddcdb68d57beb8863044c304560a1e13cac8e38c80824c23e12dd4ed10dbdfac66f99e445f7c6a3889d84d37e5f3581e9947cad542851e0a8c2a4648645a06f34278550f7c4279d3e11a93e360973b1344b2d932b73a3a3eae1dcbafb184545b03a65889db30c71623a8a4f7d2b3c06b8087af373280545ac450c892b3ce64b8f68942fcf585782352618efe836d2ac4c08160ac4a461b931ae6e37ee16085795ed46fe193784f7598659c7d57f83184a121bad3cd4d5447aa871a87ffab607e2e5a7e5a7d3ee9cfae8e5ac9f80d9dc9a360b6936384b8cd5883e0503b28898e42f2fa70e3f1f4f2869f733c543cc44e59579d466435ba6ba3fb3289b20327ce3d643935d1f9206f946c7d6446730a4e880a51dca57310f9b1372648b5d10142aedb7ab08fddaf6755339788ef64c3604f6f619c12c912bc66c3724857feec74325be17ac5bea64cac395c879dc845ba7aa868cb9434d120f143d3ab7a585144182f5c3bf56b0c8d36dee1e0099e62a4c410a2f0b7db74de451c5dfdbe7dc2328a29d40c18d0185a96e493fc181353c31c071bb789e017fbb63d54d8c726a3a57bad3889ca2004889a3b37c7bf2760aedc969d73b0d236ca5657736f74f508be4540c7176714924f6428756175839cb748f13d4ddb81a648ea59c64a72a2f4341acff69c39490d25149924e52d1ede9750b894204274e078f9385752642d5ec4e67a3645a7856402662e5b3134f1b5d26ae8d4501c2dd23c67b917fce9fc2e8d0e17a327b7503a27555e942d1519ba892538597d29ded2fdb1d5e894ba62634de30d354835b8b40c3529cdef02db0e5c6e6efca95198e040b8e7c4a6faf4d5e9384dd8bdb0c32a366dfa321268c7512df3da246d644f39c487c466318f043fbdc07c8a41e2fb0d032e2ccaaa796e80bda51cf6815c673129fb805b5c3b963999d34f7de7fa3875e39494e03fef7b62dc17f08f7017a6799eee4e3fd41476d79cf8afb9e1fea65b16408aaf5c5a4b18b121b78d6eaf225e26992f5c24bf743399a16aa160fa4b2b80367a1abd526bc67a00d65496f01da58acbd7a32db691a595474f5a291bf009facda7e151f9d1ac8d1f6f11eff8ddf3b3f67166b2c29bf14a08e8ce4d7468922f180f1ecd8e58ca5621e0ec601087f1cc83c0098e01bdfd6e05c15250662b7bd781d469432149dd139d992c9e0d3ced21216655f6ce8fc3dc435a280575878750447067660eaee64d1845f955ba5bea597ba6e89e61afc4a8129f0ca5eaa1baf34c09a9b61e0d4681dca22586d9e37a35d2940099162499204d6057f4c57984a9157a44f69fd78bea6323b56af3d3ab6ce917d7ce5d4ae276d818c1ae73f822251404395fcd6d6e2dc3824796c1d18d1ccaeb33a29f10592468504c0de13ff6ecdbbe3bcc9b4df7f68c86f1f4c4f10aa5645391fb4e501686de2860605436a32c664a0ced55f7aeb960df4ec8df0e82b416ab537c7e2aa2c74661c199f4cb3cb13f5e9a713aa02581ab2e560eefac775de48d595325e5e980ddb9e85e67ec6680e2c00a25ddebd62a4ed61fbd1291fea26774a09c753c0d8202a8927a2e9068788492266189e8ab99897398cd48522d2156fd0ffec675e171666a11d673af99943d48954e3d6e226624662ad4c7975fa5e597e3eacdd256cb75cbba1648c5a8cd65259a67a96ffee727bc4684b402a1efd50a2ca1342b68b365cb4af1c83f8dd6312de4fda0aa38ff50338331bef460dfeeb42a72187b666aecc325290abe2cba53dbe39214496618d93c392b72ad49077e55c16f4fdd3e1851753ae1a7109d5eb6dff285a37aa13100d169f09ad5552744a66b54589903e272a5ca24f2e2dc904ac12da1a8fe317ed296137889ee2c3c20f2347cee71deae186e0b74f03c9e96f9eb511ca8392dbb30059fa1c2d35d4b54175c82a0d69cb1f4cdbe8a167cf362280a34ac9e55402808a558ff8a317f337bb776b08769847c73ebcd2f56f19d76fdcb3753a0aefb1f0a88555fcf596d5711705e9db1deab43699ec798366778dbcc19cad1fa89ad23604fb2161438b453d29d301095ec8e3e08c582027769ab3eab764bb1f6e23cdffae882ff219cab57aaf0274417fe5a770743bc70b696fb7042d325c70caff8729c8b3ff5e0b4ec58d092b2221e2c3b4d00d014629078a695468275a0febca734bcacd2573bc1b81da3d649dd1b5bfa0cd2a0e5a842bea6e084d09bfff3aa9c0d2871e0073c5aadcf736d4415b7bd07a1c63659ac2f6d3a173b8853fc96068e41259bc062cb2481be3c4dadb2c1c1793123907731e8eef4685c86c88dc798bf72312006ad8972abcb487e3a1066c63b2b8eaeea171d964fc13d0b03610a7616f64b0a8c43ddf00fc8b1f16238993d2987a2efbbbaaeb4f70cd9bbe1ffae2070a193a418fb90fbf5b809a5b47e085904c25cbf527d12738c74f9092f63baba82560f6baf52bcf9e3a3937168ca3701cd87edd2e70cb257504a79b36fd1b811d39cdc3d9649049181772f233b59bb07b72045416c1a10a8a041ca7f169865159b28647bd5c436af2f10b0684584421dce61c1c6f09b2de84f8b00e3b0009b016d0f7ed6a72a7c802609f31bf827b88ee945318af1f9f370f0492016b29be521a6c930068ce9926a31fc2403e9bf86fe478b5dbcfa24eb7deefc505f3b0ab0e43b9f31c199681f456bc54b9e8dba05e7ed78dbd45bfbe054da5abb240d1bc432e1666dadf18be1ea44324507b903556447ac6935b41bf834e7b08f480c60883c9017116dc9cd559718b8d5d753057932c0252aba2646dc2890c0ce01e81dfb1c981aaa74ca54575103340ae73304b3e3070a29c0e78447c31dd0fb1031083f337932c3d88abbba514dac0d70b0660dfc61b41dd40960ac9fa04861ce99fffdb9783ab2f9ead5054c1f0a1370056add0764d801c617fc80642ea199a6b8f2a9498212ae220c3ce1fe8dd90f3984bcdc55bad3d4e04e0a616273b0232c3e0a0da7cb9027aa10ce405bb99712fd13d9905d234504c1c95c6e5fa6c7f18922a88959fc40f7a4e8866cc98dac4aa1aa1c88319a4823883aaebe1e661406968023f038dc5b1d8479a20e5beb0ab971b1000be0b2353293b5727db885f90ef3ce87bab2650aaa3cf6ea3b9fd6a5ea670fe79b94dae52d127fdedd9c8b29735d6cb1b4b471eb6ed4583fef89bd207469731c9c73cf3018436f8129c7a23835c59bb4b8096021e2421314ed6329cc3f86737e9a38b30a88efbb5e720988cbaf9a549ea688aa964e7b5ef1b57225fb95bd90d6dd94fccbff2bf57eed1cea0f5155352bd2dd5b10295e0fc7e2145b5fc01a010371d761c8113dd4b8a34f794891a6508523c0e89f67408453cbe8fc6477cc285cfdea4792b8b223e0a4d3f48192bffa41376903663de169bc64050e35de2534a4c2cb33627b81896f4001cf5b779a033139fe9c30957447778a240086b1c8ce524cfb7bc6c4d554b654e56cc71810fb091a62f95588cb5d6e06d1c76f16ee2b78dc97dedefe03223e08354be7fe9dbbd52e6d702a586b4fdfd9603fe214fcdd2dc5c797a45b58d347c8b0f14b0c7705f181868a904e94cbda99ecd6f9070993f150bd22d2ff4a71f3a68f2e3d3c282a7f30d1f517e2177c2dde66f0a19d1874ed4c28468f8610b5eff289dd73ae5a8c907455539bf1025c28ecfee5352ba98f8575bce7f49f73f4a8866a45c1afd736c1f0d15b4da1329dd652211b62ad289cb853012bb3d000db38d9b1a444109c1ac9b8a044e956be77c092d919503cf6fb3525f8ba2a3713907b8e254bced11ebb55cde5dd31318ad3b47369bf3025bd6150bc7ff70b6aea117fd67d74747f78e360e67c3f56423f6270d5b3e7fc0e9f9b5bf13893e1a8c85d1bb459bc3bd9ec07fa6cc73152b58435d55ec8b55fdf3ff0ae10e76b282145741edb6055e89daa8fe384143fa69102934f7874a4a28977214159f8849fb93596d01b811c8cb01f386cb667f18e705487cfa0008d3bd2decefde010fa60650d38aa417d804b008e7d4179ba67b916b05ff9511c7b315d58d3e7390328b9a230a23d9b427fb64b4ba9c21bf99dcbbebd1b3aa32c31b1024779d53f9b489f5eb05587c972de76323f83b4a9d726c7b98d9fa4da7f7a69d219dab287e75c5ec46a5f0aa55fdb6dfd79c0b735f1c8213245b79f117a0c4003b500265054c006dcbe157fdf0c8f230a82d63e24cb891c89537e17362297bf3531cc5bebd25f4d9d2684206fa34c1774abe8ffb5eae859ce5a1d32c271c688d0fedef77c2acd94a743c16601e9cb6d53d82e6ee708619710beac8385d4eaaa9b03e6fdad2f9a3504036e7677d779ccd6333b101a1504ff4990218306e9f94ade8dd2a82d033bc95f66053ee38bbf2926bcac6e4d954644a9862f797dfde7d063e42d9941575aa274a9e68875fb7da6112ad9a6e997ccefff8ff5b6fc5b0efa4dc1a22e96b33f14002f9a58586f5fff83d732126783d9074057fd6cad678194287e88cbc5bcef877ed8b310a8a26d5eef88670097ab406b22df07e006d0aa4884d2cfe296489d5a9677c60eb3da0cc83cc11786d90101fa0ffcf225e3df61a913b79a7cf8f5377d65377af2aa6792a9ba0d31c4eba9e042b825872b8bf183feb83c4fc783d90f35c164d22d025754be6c2c040053e3958aacdcd73d82f852ede0c49eaf6406b822fee879627e1544b3c42736a3442d06925d97b0734c95679909c35337bc83391a71a0923ebceb8b5ac70d339a2a38d49eabbb5510205ef2a4fc17cc5c0c7bcf34a2642f840a6590d28e12517500340e848a55591d41bbcb6ec6c8cf22390ad7aaaaf58c5d093f40eb6648544292860ed375bf2445514066ca667d47506f61755686243bb7830f4c1e28275251c0b31ce94fdbf6b12ad8f92b776b9f679f4a8794d09eb27c06d09f7fb4ed604d7bd48e12dd016f6ca031147751953fc871f5ee9431998e0b1b6ea56870dccdf6a14341d3285f8089b3e52a9b2daf27d019de3b3167faac881bed331527cd2be531abbd195b9b22f7a93c37a631cbbe81ec920ffe183b5a49150674c14b73489c2b88db936cf9157deeb94f133008c25d7ff8e1a55e3631b2183f0f50e0d5deb8cc1bcec606ba90f154782b6003c282025dc6815481a8dc4e6c759bbc4fd3a4886b7d5317150305928ab5a15af6b1d019e83f5e8c2a37a128ecbd98bc5481fc96786d8df59a3ca0dd61ecd0b252c6119133eac0344eebb168513c3e11b3a32a00ef12fbe25331f4898a26a0759c1d5f021b2a94021ac2ee084c7dd0c1d2a33be33a9c592ea13dcaa4ef99e7ae81d8c812e0793f091e14960f532ae9a68d4589b1c0988df8cdaaafdb9053844d9dd3df4e84039c81512c92422e0649bd2205b3a62fdaaa3f094d57c2cf802462b9cb64b80b73d8d0af9ee78fe9e77e1b1bdf470636f7741a15a9a2b87fc058434b668bd04fe276e539bbb5d404882bcaa39e96daad38ecb69ff85ed56f6de2e667aef687eab6ba6225d676a39e452eef874a722cf5ad5c15b7e16ffd28449ffa60f4b95cf20e3a16a05dea7081d9ed481f16374da53434a8ba6b0b95dd726dc4643e1e8d533473da027c4d4ea67143693d5dcbacebbf8940dcca05f881942af07a00b9aea74475ead313545ba4cccc4e12306c0234431c485b2eff4402ee99d5be63f4632b2db537f896e4b33895663e12d69e6bf7b962caeb1addd58c09c985d547f50abe391bbfbe5553581cedf6ad1a0042ec870cd0eaae4867172142ada681ebfa115cdb48c90a0328b2373dce188eb6919eb997b05b5add3a63a9a0cce056220603bc3dc6d3fc6868d929ac42c983d07feb23f07a00de278489731b35ad0f51bd4e8930b26b3ba0bfacc2d7081a05cecf80613b8f3428d00a41131e314ceb32da43f276a480cc8786e905c35b758d15b6ff78bda1c89163431a40d521194288cb7507375e055b7999c0bf3bd324eaa0676894be09a9c6c78af13063cf60d65c645d9e0d9fc87bb8e845d110c46af5130cdf937ca1d116d5023910ed1e9cd98ee5e21e50fa224d1ad70cd99354ff427bc8172b8465892aac7fbf89defc1e8b1db131afb73018837afa0cecdfad7c16293c6e6bf79b8b476c2ccc14f40dad51b4eee7ccd7437eeba2650e4f4e9f80685d1d4599a3c09fd53946869fde42a9efcf8763b032bd2202b44b60afe1c8161fea23c46807ea2cf455067ce5e5e47dce8e34149e8ab00194c8b1a96e793cce4e78c74fa61f833425543b382e1e71868dabcf47787c943e32bf2b8b3b4ce4878175548f571909dcbc39375518a0ff3a3224dee05243902f69f557e019512b97c48452fbe1b4d19064f0f9747aee0d07fb1034a1cdb21c0012211c82a16f10dfb163a82e9856832c5c3fb61c5509c2190c3cf601f01e131a5283f8353455843cdcfde96c537153d7fe01218c87764bbf948627fe7fb4e8360ee987bef3672183fecc90b4156de26fdc2d32bec56c7ae5afd5f6da0d9b394a1ccefccba654dd70ebe4820925cdc38423ac39e799169c01b7e6cde0c364050398d2d4c605b887104ddfa23384409cbcf20b5894976ef003c4606d1c014602d3ccc5287822773eb1e4cfc1e6385e101c233973695a3a4d9126c18c3a6246b173efa676e65a5321eea1d88098b77f9e81219aec4c9c8f140bf22fe214234de3410c450c2e810287217aa7272eabc7aef861b90b79fc08d157a21b247ae3f8d2db87dcb3e6f54bb3b9e199d18a65b39a911d2da5c88cf967ae196d69c5ccf2bed490b91cc421571445f49688f4ff7699c50ac63e3e61f6c6e3a108ba8f852105a412cd8be36203eb13cee7d9d4cf109961850ec4b723937cf9300651138028fe97ee775e313ca813a6ac62db5d94c3f3381188305f4b393403deafb90a3c3a2243938829accffd73f99da1459b1b9fb2cbab228c0cdf92a8b8292edbb1dff9bb73c04e6020fabafa947259d942a173621807621a90a45c992980a5398b3e92449850271a8c8c0b3192dfc0c544d15a8cf047751e5ada56d576696b0ed29409347671cc35354da9ea402656b2ca14497469ea8bb92628cd2999f9a7faa4d73f763e07a17747e7063b012c13ae8b5c0ab6b2a4f63813fb543922d3c20c960ad2e4336907a16d2b2571731a92dc35a0798845483c7742232cbdd2916181d67212e05d374c2fd3151bfebf4c8df3083ad3f8f7c7f21127f41c54cede27c19141fa25513bdd8b40b702b467e75d9f2b807eb69ad13a8ed5674bb64bc0b47c89553a7b9a3745e7bc0bc2e7fce601ae5413985948d875845606a1982fcd6be493a0c32b789541173ac2721ebc21f76d2f5b561da948b1db83b4333952de07bc7d9bd8f06c526ee24b779ef311fcc2d29f6cb6ace789f3d04111825085ea73e8e76801e8197d4ce3af6273683c5455e2bc235c5f3f497f4c8d4bdeab8cf060db9f6f098cc9d5b9931fa2503f735387aafaba863a46a0e201cd65c5a43fdddaa0ae5e73a5932a24aa9790a2f0e180adf248895cbe73bbde45139dc92a365cc3d81914e617604df400ef024fc6129c5b53787b17841ade0131c3979e814a7bbf36b64ff84f7430d8766f147cd7189a0f46c06983fb20276d32dc9377ffd0b29572a1f7931bcd8aa1facb7fa45adc029e2cca5b3e14e0e60a0163a5d4fff409400e473c73ddd3d6865ded19fa1f030b6c2b72b9fae42d567d8a6d88cddef5c7e96f4202d733973252d9328dfe48c64e0040932c788d418dc60494f67964232aa9b13c2174b08d2a30d4befff41150cadf18289e6780399e52435e9c1a716f8bd2722a7486efedd0e72913f61651687716395fa710b8c74bafd225e433b56158cf196260e40b295b7ca5438df95d521a8622a8fae89ab7aadd7ab3cfbd797b602447d38f5a811bee528b7490b579445ab4ab1fdc77bfa9caba7e6d7a11dead79fc176f39207fb2d31d313081a7cd3b46ed71ba2d79dc414ce6695450285905300cdae4e6aa6b2385ec3d8dee1a1857c832cf4f1827b49a1edee7f8583aca9b31fe5e634a2beb27aad19070fd85235702364710f8656b1e5b852e0ed5b7628630f5ac46514ed4bc3fd44624faaf1f74cfba05c792a0f161cbcf29cdcfe3c1ffcb583f4ecd2e89b109218dd6071d1ffd8367220b4df9bb1a8a011ed957b0a63366c9164d9a1cd1af35dd4f304ad9d82d1d74036a0c1230bdaf1ba9ab6466cbbd7812888bbb73c49d54460254cdeb4181ef062c2ab353924937e84dee1b7f29f9f2cc5ee2b74b314a3241ee2751f1c1a5661be9c68a9fa2f2a3128f829c11b6037f43a4944cff3811cfed2ec75460c40d718262d692b3cc9c58b1c051fd33b82f8fce59d4f678e6023b2270c670c9dae7b39a53a1f6d90c93f0186d951c75306c39ec25dd97a525659d33fbf2e8082237126e016c245b25ca720c40e9e257b0cc8319d489fab3bc15cefb91b753d4f8e1505a326f331eb5154fcf4651b528cdf7e1e7499131d35112006409b4a7d381fa93bd87cebb2460ebc2cae7543f1f83b488d9f2988f9f9e4801ac244a4d699fdde3071a9373562f25a6e6117e8e9d2e4e4c67de905674a21c6a1a1f80c93b59035f77dd0db4cf40cd0a8fa9041d10c0ed2ef0293d7d365be83361e75f4c3cbd7d3b2f0a32dc76f6a0b22670893ffc4e27f2aab59270afb81061932ffbc7f83b31941830706adf1db9c59bc86b37e9850bb979297528de0abdd6177907afcbe79bddec56000fccdb14a53955ac58ffe7ea0c42f0b24f5165da79d04a30db0b8d032e0c091ed83278919ea2b0d2b6c363355381c29439143dc8b495d4131373ca487b2ba708d0a84852e71ff8948df020d6f900dd6aeac6a072724c7b354e87daf11d94aaf6416f8dc335fd7253d7a9a36749ab3fe8a9bf6921737fc9f50e6d7b5ca401db4b5804deb270326cf005b21f303a3e45da948ec990f6b31be468f5927baf09500c25d2d2a659ec3d60c91f42479844ee2574cdd13442ef42a42968ae8e06e2a0ff897ae39890dfd3c6793d3cc484c43c81d5e6b187d2382bf5cb6f826a01a962864827eb1ea47ad26e2a46cdd4ef79a5359989bc7cd1a7715c604b641ba079d9520d78969f72802ba6eb9e3ff6b9589f1936490e3c7e460d2dcb5f8ecbc24f44d8e97af73880dd241417354c4e34dd6a62ceebe27ceb0a6fad16da90564c0ec6b93f898452925d64af8191b05cc53de3e26baba02360818fb4f6f6201d056c84064fa3133e7ca2a2e3a3ed0d6d65f8ac389d703f46a6dce2c25ee16054e0861d16370b650e1e112af1918302f227976c38feb64ecd3467f2b9022abd05f766967826f15fcef661bf4daa949b7a937128c2e3dc981a031097c08971a6cb0a6f9fe936e4d1b6082283e612e939df7628569cd3c93fb865c26bbad36afd8f1689a1207fb28d04044d21d561b97bf25bfda8786c9d02e703fe14232a751002d2cf86592eaecdd66a4cd86b8c1ce3c3afdd98f055a40f25d14b6875d67291e114f1b19964b0dac1a6253a9c5f7beaa76ff118ccce19b269386fac89b756f0034899867aa1535973bf9dcfa1899f39ed538a0c055b33f4141223f5206aae4fe29a963968c34205dec9ed027329e8c1b9a0e21ba6bcdf3d323bef806a7fe4bf87234b4d053dfff68998ab39be49dff1c642c095502ad5dda3b0e420f7a1685b7b5d1a1b1033167b7251f55e51722fdd9a233a4ccf6426437a644b3698865bf2264a91ff4a5c64578da4eeee0ed3ae146da8b3c66399d9973bb1e4b8c661937de8e491db8bbf56cf1ecaa7c387b7589e895f7d396e802ba7a803aebc115e47f64fef4fb10f9b128c3d104f2774ced9a4b6342a570588fe0e0c066b865486a0e510f55fa855e6889f899ed2e676af242720a444f896b3876e1833cf2bbd7f1e1536664e4a4421c3516cba260e2ab150cbf98f6888a13db57f1413db75c38ea19b846fe78679ad812abe3c2a1d70fcf3a0ee27b5b563b12b8ace14667aaa22cdac59398b5123e55bc199af4891624249143ea82f0ff2ec9049184652924e0df13e09b02a6df61e563dfbf6f08c6722ff3f41501448f794081193c85e65f9e8d1197f276a1dc2329c46c10d431b583633d74f4f3424b6114056eab26581add008f8d73e9c920c7cfb5e37aae1527866563638ca0d7735ee45f423e8337b20e35cf9d6bb0d62e7ed63cf96746471e7d1cf32741773effe48242369f82e476046d4477285bebbe3e153178898dd8e35831e36bf5674f31f76b27959b4d53ff5cb3118365b854d7f3251527f0df5f7512f11b73293dfe019bb7040ede8eb6d7affdd0e0463b1519ce6d127a3762d9aabfd33d2cc4f09178826e118d56bbad0eed14fd5d6e56db3dd1e69766da01318d613a97edb3fb759d650a74cfb784c9e370c6df5d36ec813c51d2677ab4d6e84a3e2e14de12b1888cd7e79f6863ebc28f4cdc0b50c7b91345285811abaf4a02d776661a37079cc705362818e1f56ca308685c8909c15752def302f3174b04b348794bddb2902ca87f969bcd5096d5f3560eeef34b9592ed4c688618e990ff5f455033ded78498b5afe2a3625968ee1dfde80a1be6d56bef4bd2c80a995c65e97395502a17eadfea93383a3e648611b89f7998207233244f61d260b155169de8aa230fea866915f5e8c48652a7870231c0c32df613ff69994750c8c95345b7b73548440036074294f704edc34a6aab186387120b9678e2c61d083bddb9cfd29e56415842c43e74cb4780f64936cd6159b757b8ed83881e55ecf998fb34c76d384009592f78cc39a9c092d330f6f946e13535ec1fca3de286a84880575380fc62c08084e9965a5285c49e709d590f9d361a72c40f43e2881adb777c2c6c4a72775c59fc127a95add59bba629c805b21e767b6bd5a8cea1de708d9f6232d1cc58dbe0a2a67397570545c205fea3ba3b082fcaf5a56f4df348b90ceef1725a2a4263d016985c19d5b32442ccdeeddf0d65f795042a2a6bc3b65637be3a439b272fc8efa5e14341ac5b1f703c3213595020ce50009579f2bbe471e17aba1deb52dbe5daa76fec927aad926faba08ed9dc6d3842040f767caab36c5cae6df75e27f33009530916bb4361193eabc6da756d1b7039ec93697ca71f88e2d8cbb1af4a8cabfe1eda019cd5049266e915d5869990187fb4e41359a2b523b0eaa4b66416c62be049e3213a6e4b1a61abb96c3ef4ed733d9b77787da534c501da47a2b98c5acdafe93a769798f61b1393dc3fdc730b21f4d0e96e71d723291b96336b1cafa6e42d871c5c5427daef46a7bf44a539b2a98cc69b03cb3d7c3c08b9f4bc373dae24413d29b4a1711481b3c4a8fd867fa099446b25886e8fb447dea5fee6b2e64f84dfb39b6f6abb9401c1741b19bda7a069652377326e3a1855f348e4df4012c3a69d1f069e27b7778eee1150b464ddbf97fbe33e61d1271a7f966bfe5c55ed61f03034ec557f45bb1ab358eccf47354f081577a98f6efe655973c033770e1b31c1e3a23d1ab6782be34fd25a9856d65d4ab198fe88d3b96929f23dff7169c13eec9a40b93381e014ad6b63286a3c2ef96735b2bd05ad29f60630029ed723c14095c201201e276092ede52fbd487ed0abd1e59a1dfee751255d28a77bcc34d314ae146d5a23f3f57b9b940152b39e0899207be401abb460ff5a2adbb0b5978a8e976c0fec054ed59121a4036db6257db3c11c951690186542ee6a5f0f29fa0b71456273dad746af09113b24726bf5c444573b9931750d5dd4c77391d27fa1ce4464eb693e6f5f1b68448120785f4cc2382b9dac2ec8358bea04dd91eec7fbdbd3d6a9ba125fd714749db4c3163775b7f5bb4570692bcd7e9ab7860470bee2c64205bda90382bd47b8abf1c173a450bf56dc73f7f56a3354c7144af9c3bcdaa55604b15c7b2aee10dfbf8fa073d4b69d91ee6583b96f3820077323565eb139051ec59c01dedd408dfe3ac8db2d9bc9f2cf867d6091d28ee9d625148e22e641e61b3616f8696c13891077c6f7e0ea306ce97a03293a546ea7aaac3eb37e042563ef71ab1a8ea4b3fd5073b3c82c7363a0eb4ff64a7767ba1f2234df42378b392e38b9d69c2d9317fa200d069c190e0f9f8ada7cbbebf3bba4a2d3b68dd4482c2a4a6bc38931073ab0ec92c8bb080508a1791e512ea204495b4be97af8f7574f16ae1fb1e819d016da2cd2b84199f47f5fc6d1385eedcffc8be17e44c4e2d83979fbbb6361c8bf1925fe9382b98c7003796aa9c7eb53ed52d0094fd3465303c9bf31ebc616862573b56914d61e37cc34fce9a30d97958f65969b3255b0a09093f05bd73fbf12b1e38aea58a2044f88c993005ed65d20aa558d75a239f7a09e7f17e381d1b325cfadf06899023fb23b3633795eed26b6e8776690514229ef7c4ec9348458a707d24591c20cf3494d884e3a7f118d89a2a830ba22bdd16e4ed7d30df148889d28aae68fa8f5d6cc31ac503796efba65dbf734164470c250352631ae9959c84f8ffa42cfefaa69d14ef26bcedac2fe262f9db9a9a2a609501366af49c8c66d75a5635f62594d85ad27404bf060ce1cbedb45a8cfa1e27cf6d41961c5dc4edde0bbb5869f42615b0d220e769887a3671f52ce0912c81992734499ca042f0270644911af6ee09f3a0b416f4fb62d800053a04ab0d2f199708ee23ac7902163be8960390b54f5d3a7fe76ad8eda3ae5272a11c23364baf2934001237baa1fcce6c5c068ad4af279e4c802907c68734a26e4c474d583b6fd7813700d0bc98e0019a11a20b07407ac092fe84d00efa1e22f7924a5046a087f3b0ca226ad90646f648aafea99662d915be62432beb34fcec40957a53f2ed73b648c731b1281513b32670d77710b7d6247fe47b3dae155d0ea7528b90915831d5a650160a96acc44ee95cf3011c869912fd1c0a34746a0cc46d44b64cf71d200b3b5f27f868b4945530648582fbff5078a338916598cf8b86553f00e9bb3da6e7e97c6cbab53eae15f61fbbd06750a9c623513a63f47ca242803c2d1fc7e43d5008bdaae4ff0be775fd38fe22dd04c5c6815db94d6fa3995a7b45abd7c7a338980fa21e4fb6be3a23c84f52d76b8d9b5ad6409c227141b81fc6e78fcdf109f43c85c8faba90e8acbbf77db9891ba5f3175b2dc898df922c74caee969db8b2432faa047659974ffcf6796d10310bb2d236a2ef5f25e27af7ce2ed00aa821364d3de13482607313b0fcf7a3a7f618f8aebc0c344718042e0d1ecd075ceb18bf21f2b211a5b675943ea00b5287e2aa308d4c235003dcfb0ff077332ecc36de3f3e273c9563a92cfef64c569544cea989657dc9feab1affb6fa754a454c221b13c3707db821a0d198cc40e99abc858fe6c6a4163efa11bdd5407c8596fc085b1b6562ba18dbbcaf638bd2872cd4c85a1f586644dc79b57ed210c2cc4faff95aa62c84ea6577ec555b0599e9ac60eb49ae34fd06509da413b649dd2cb265c3fb4324469b22a811505fb65470199df2e74e6ef704a6c7874a7217b3848f414b53021170b876bb24301d81c32308495c66ed5a447682a8593ff864d7bccb8da652fcca587d86f4b70bd155b3b5d9292369f5ada8e3e289329e046af60a231a2f49f40c48f807b63a833e2b514fd35d20f35418dc071cf8e91019893d536d8fbcd6fc7d524258aba3605840128f60b7ad27db93d48121b853d376420168f392425cee230a263bb5022124d5d7cb71d9b8b7a03e28f3622a241f424d1c9e9aa6db74fd2ec721c879a87375f44f7ce3884713fc8f3386634aa14dd7c836d36119a3d4b70f63cac16bb5c36211ade0d50aeffefc4d340bcfbccc55711a448006fa65c0f5a04115b86c0d62a6d7171af3b219472f8c1c4353991f9ababc8e1a7459570b8bebc64dc2e57d0b181c76ab41b7e979957e50ae9357b9983685ad70932fc7313a10df37672087d01ec4cb8a47afba5401bd991725365528e303aa5f38a10f45b19c5f6288eaf03b934e5cecd9c26913d083c86f57f72c9786b829d4740dda0128815133d98b3617a454b879bd95f22e5a8d96d42738a7bfa636018c8f7ffaa27c6b687cfae17f1fee833431b6ea3e066983dde21364122a07bf3bfddfee3e0d123b7379f2f5252e8c4c9bca1171b8130fa4a22e33d70f01c75c44e9ba6a004ba45840e595a44123a41621b7581666441b27fd6a1cff25acd52853c90adf376bcdfce573ae55e972136b4ab6f7da1644472c5c66b3849faaa05e50657782380bdf0e4d6f76b4d4ba67724d3f8e06ebea27b7a1966408381455fe67daa96724bd35d763b5e4b9474510c545bab3a6f9ce1d4103658c9638bd060a299310f2853c36778be3ec298713defa432f378c0987ec5a9141c51761d465d96c7d8cc0f3135ba2a08c1c0e43717b7222df924a0c9060eca322857da4f166cdcd68eae4ffcee7535db42c2e1939c70cab27d508ac3f55d1bb4634992a9fae200e576c686b551c770b4e6081e328ce660c6f53243a45dc8e510056e9349e7821450cbe776f6d333748c98aa203603d791bee4dbd03158fd05f8108474b5f3395e3143fac8b11f94ac1eafc2d35a4d81e25b7a57e5b7a6da32cbe3b72317efb33fa3112c3b5a78ec98a572fd3d31cc112bef0e127ee102bd2949dbaf84c36c6dce92d93936cea89032f6c503576ed38c481f95e918656d313494fec05de71475dd1208ef6cd98e72a965e3fd25f8c589116a900bae0ea13b21a7e571003af9a790d08c13d45a037713320a094cbcaec31732f06c5f7d5c65c3c943e3e7c4da469d67ad4b6147e49d8da6e367a62f36c740228e02eed007930f11a9904b50bc55ba43f112d62a02bc3936c17a458025488bc6f7de50ad8a9958b30312a0f7d2d845d7b02f83e2a38e4c593b00efdcca22cc172fa0732b4642b6f2f4e0223a9209e16c3ef01dcde9d31505ae6216ed21fc4c2ab1fbb0557c8606f683d712e74c2755f5d196f02a0d9eafbad49df15748b92e25476cc6b31c028b7cda515f8f984eb2c3a7c95eb5e33e644854eff89399fa24b0c73fa2cfff348be3b9228e115083ab8df20af0f8b0ed165e4d1b97e3775c77573fb09343bce2ce7b21fc14ed875d5de0cde9586a76f47fde3aadff9f35261089add2b1456d6fc30b35cf54bc660ef0ae2912eabd445dbbe47f6fe6a1a40fe11babced73b1d87e8fec965b32101bb6ca85b03544a6a2b65ab85413bb5d47756ba0011c69b2a7b79df7ee6e11e8ebc895e04bf5a852d72d5e8e634bd80441285a1253bdc458258aae20b17f3032798613a315b58aa5bdd9b91de8afc93dc489a0fdbdc4afacce3d29a621cb4d9d7a8cee840ee64dcb3d65adc110e6c0ab3375be4b8d2dc9d524b945d32d7a443e10b5018433ef55ca6f97c0dce133e907a374499845cd51737cd7332a0c768dd4f97000b4e29fa3c9e2b7370ef260171dcf17ce6dd58461960e1194ad28f90c5bd9ff1678704ce09bdb1ba6842753b2e5f0bac9f990b44b7bdd4f7ed06209eaf5a96c2c4800057684c9ebdf9277d52c05120f673bebbdb1a614a5b2557c202ba3a1ffdd3bb3eda18fcd5073dd1379a65e896eef88e4d3576f50116142bd6eb4bae3344371cb24eabce704d1816af20670b340b48744a2dad59eef80921411a28e98a868f776f2a4f9e1f929e2643ccc0a1c11e19551eec7e6272de14b843e27bff1fc5c634fe57f8c1044083811f107b08a10f9804cb25a53bb0edb99c1e63e415db6d98263d8dbe929b58a20ab656f1a19a046aa20d8f7a1b6877ac558f5e0d6e353127637c54b02b9d2e19727fecaff8eb072a8af183b256b0e13eaf54ecc99825a03570d67c0b3416b97bf080e9a38a75c43cdb77f69fd31003c49d57b8bade320f9564478e8a789ee778952a79903baebf6f01f00dc8dde752005b025731a4777168dc5efb7b91a4c177f87a43c6c8c09ab5cb7fb40984c9f7e7a58dd525c2e71daf47db49d04e1a145871ea5b6a0ebf0302946ff0bacc2ec5b09cb2a25358c546863aac4c23ba0562f9371346e0cced17c1f32957043f25c5ba84a1017802871f57d1c8a361b983e4800b1df04d722db7a2a5fbc6b3316c6425bebd1328e24de4ca3a822b86858b3d5d52d98b76237b642295525dde25c914d0e6fa8c7d3ac2dfa5f9ab5388a360a30d4aa488255f35dc940ea4ca7b9c05246b3d27e129bb0946b35f5ffc1296392c2e71d664b4a350d8e0d952b1c8a2a5e38e08a1d7f428518778e1723495b2c871561b8e1252928e8d6a7fd65242967ae4e4b8a7fb4d8c9902db02388a7440407715d28ca821810b30b4e797ff35fad77da6005994c8ef530e364fb2f90dc252df88e7377873450cbf875a78ef6d0c3bcf0fd1243577eac5978ca8b4d7a839638d132858dd2a1635d0a110b9d4efc2a15001f1e92dcabfb710611ccca0a0fb7dcc1ec00bc95ab674e05fb15cbf4783b198be7c15f0024f98015e4e98c2418e1827210103a83ce74e27e39bed7c6f8a26ff20e36ce4632b56b404acbdd5fc1ebc8e16f0001cb3818a0c3898cdc938906fecf71c264049cadb811d2658e7fafdd50d94019051e566a63ae49f3668021afcbdb673c35798d0e3e280edb0b8ab86c505e4a2ad2a28f9cd661bfdf51be879d18b69a4e0a2b2ae898f288e914c8e6ad78ca502125b379fd0b08c656473e5f2979f6c0757ee3658a595e659c2d6075164e8df4f0bd0d99ea164366cc7b57637eac244c90797a3edd2f2ba17a010dc28870efa0944d38b0465e26b0dbd046e4eb933e07026cc122e971c741364c2a4ec9e060439ef655ff52f2a74cee79f991a0a5250d3896b1aebe8e6a91d38fd84fbd2daa33a62ad77bad6c863143a983f711b42290b29dcc0bb094e248c925dda0484e1c5b4a08447ce217702ea1658246545367e349580159eea226082bf42dc59b31a0c06323154a85c79e9f19382b1af6055dd0c28225255ad73a8978d4b43405db3540713042c6e2a7e39f02f6ba89d29700efcd9e1ebd77521049c155a59c7020722aff04f3992787a847a31df065fe9d2e39ee09ac1c1c01d17831c22afa63edd58ae50e460ff96eb2fd359c39a4c991423de4da55aaf8572baea9e57c7147848135ae91bb83193ee9e33513433aed1e8e75f18338917b06cfbed005d045f03d65435e2374b4829c0a63c848d7b71910922c885e91c41ead3dd9bb2

:::

Recon

這一題真的非常難,而且要通靈很久,首先Oracle.py的工作是把一張flag image用AES加密,並且把AES會用到的key/iv都用RSA再加密,然後通通傳給Alice,而Alice.py的工作才是本次作業實際上的Oracle,他會吃key/iv/ciphertext,前兩者是decimal,後者是hex形式,一開始可以先試看看把這三者傳過去,理論上只要格式對了就會回傳OK! Got it.

encrypted_key = 65690013242775728459842109842683020587149462096059598501313133592635945234121561534622365974927219223034823754673718159579772056712404749324225325531206903216411508240699572153162745754564955215041783396329242482406426376133687186983187563217156659178000486342335478915053049498619169740534463504372971359692
encrypted_iv = 35154524936059729204581782839781987236407179504895959653768093617367549802652967862418906182387861924584809825831862791349195432705129622783580000716829283234184762744224095175044663151370869751957952842383581513986293064879608592662677541628813345923397286253057417592725291925603753086190402107943880261658
enc_png = open('./Crypto/HW/Oracle/encrypted_flag_d6fbfd5306695c4a.not_png', 'rb').read()

r = remote("10.113.184.121", 10031)
r.sendlineafter(b'key: ', str(encrypted_key).encode())
r.sendlineafter(b'iv: ', str(encrypted_iv).encode())
r.sendlineafter(b'ciphertext: ', enc_png.hex().encode())
print(r.recvline().decode().strip())

解題的手法經@Yaan的小提示,完整如下:

  1. 首先我們手上可控的地方,就是key/iv/ciphertext,一開始的想法是,由於此次的flag是一張png,所以一開始的magic header一定都一樣,所以可以透過這個magic header推測出IV是多少,但這樣的作法卻沒辦法知道key,所以這個方法行不通

  2. 正確的作法是控制key/iv,變成自己設定的東西,然後試圖加密plaintext(同樣也是自己設定),然後把自己設定的ciphertext/key以及原本題目給的encrypted_key或是encrypted_iv丟到oracle,要解密的部分(也就是encrypted_key/encrypted_iv)就當作是iv的部分輸入,這樣神奇的操作如下圖所示
  3. 為甚麼這樣可以解出我們想要解的東西?那就要取決於如何控制plaintext/iv,key可以隨便控,而plaintext則是從零開始,iv也是全部都是零,這樣的好處是pt用AES加密前的部份是我們知道的,換句話說,在解密的時候和iv XOR前的數值也是知道的,此時我們可以從oracle output知道padding正確與否,我們又知道和iv XOR的數值是多少,則我們一定可以利用POA的方式推出原本的IV是多少
  4. 舉個例子 若 encrypted_iv=b'0123456789abcdef' $\to$ unknown(也是我們想知道的部分) self_pt=b'0000000000000000' $\to$ self defined self_iv=b'0000000000000000' $\to$ self defined 則我們開始改變self_pt的最後一個byte,也就是b'0...00',b'0...01',b'0...02'…,讓他和encrypted_iv進行XOR之後判斷padding正確與否

    如果padding正確也就代表目前的padding結果是0x01,而此時的self_pt=b'0...0e',所以想當然encrypted_iv=XXX...f,而換到下一round,我們也改造一下self_pt,首先原本最後一個byte(0xe)要改成$0xe\oplus 0x2=0xc$,因為下一round的padding必須要是0x0202才會正確,然後我們就可以改變倒數第二個byte(一樣從零開始),也就是b'0...0c',b'0...1c',b'0...2c'…,以此類推就可以得出真正的IV是多少了,而encrypted_key的做法也和IV一模一樣

Exploit

:::spoiler SpeedUp Version(只考慮同一個byte只有一種可能的版本)

from pwn import *
from Crypto.Util.number import long_to_bytes, bytes_to_long
from Crypto.Cipher import AES
from random import randbytes


def unpad(c):
    length = c[-1]
    for char in c[-length:]:
        if char != length:
            raise ValueError
    return c[:-length]

def asymmetric_encryption(message, N, e):
    # encrypt message with RSA
    # message must be 16 bytes
    # padding 100 bytes random value
    padded_message = b'\x01' * 100 + message
    return pow(bytes_to_long(padded_message), e, N)

def symmetric_encryption(message, key, iv):
    # ecrypt message with AES + CBC Mode
    # message can be arbitrary length
    cipher = AES.new(key, AES.MODE_CBC, iv)
    ct = cipher.encrypt(message)
    iv = cipher.iv
    return iv, ct

def compute_know_part(padding_idx, known_key):
    if known_key == '':
        return b''
    known_part = b''
    for i in range(len(known_key)//2):
        known_part += bytes([int(known_key[i*2:i*2+2], 16) ^ padding_idx])
    
    return known_part

def construct_payload_and_verify(i, known_part, enc_self_key, encrypted_key):
    # candidate = []
    for byte in range(256): # 每一個byte要猜最多256次
        # 自己控制
        self_pt = b'\x00' * (15-i) + bytes([byte]) + known_part
        log.info(f"self pt = {self_pt}")
        _, self_ct = symmetric_encryption(self_pt, self_key, self_iv)

        # 連線oracle並驗證
        r = remote("10.113.184.121", 10031)
        r.sendlineafter(b'key: ', str(enc_self_key).encode())
        r.sendlineafter(b'iv: ', str(encrypted_key).encode())
        r.sendlineafter(b'ciphertext: ', self_ct.hex().encode())#enc_png.hex().encode()
        res = r.recvline().decode().strip()
        # log.info(f'key = {enc_self_key}, iv = {encrypted_key}, ct = {self_ct.hex()}')
        print(res)

        if res == 'OK! Got it.':
            tmp = hex(byte ^ (i+1))[2:]
            if len(tmp) < 2:
                tmp = '0' + tmp
            return tmp
        r.close()


# 題目給的資訊
enc_png = open('./Crypto/HW/Oracle/encrypted_flag_d6fbfd5306695c4a.not_png', 'rb').read()
N = 69214008498642035761243756357619851816607540327248468473247478342523127723748756926949706235406640562827724567100157104972969498385528097714986614165867074449238186426536742677816881849038677123630836686152379963670139334109846133566156815333584764063197379180877984670843831985941733688575703811651087495223
e = 65537
encrypted_key = 65690013242775728459842109842683020587149462096059598501313133592635945234121561534622365974927219223034823754673718159579772056712404749324225325531206903216411508240699572153162745754564955215041783396329242482406426376133687186983187563217156659178000486342335478915053049498619169740534463504372971359692
encrypted_iv = 35154524936059729204581782839781987236407179504895959653768093617367549802652967862418906182387861924584809825831862791349195432705129622783580000716829283234184762744224095175044663151370869751957952842383581513986293064879608592662677541628813345923397286253057417592725291925603753086190402107943880261658

# 自己控制的資訊
self_iv = b'\x00' * 16
self_key = b'\x00' * 16
enc_self_key = asymmetric_encryption(self_key, N, e)


# Try to POA Key
real_key = ''
for i in range(16): # iv共有16bytes
    known_part = compute_know_part(i+1, real_key)
    real_key = construct_payload_and_verify(i, known_part, enc_self_key, encrypted_key) + real_key

# Try to POA IV
real_iv = ''
for i in range(16): # iv共有16bytes
    known_part = compute_know_part(i+1, real_iv)
    real_iv = construct_payload_and_verify(i, known_part, enc_self_key, encrypted_iv) + real_iv

# Final Testing
test_key = pow(int(real_key, 16), e, N)
test_iv = pow(int(real_iv, 16), e, N)
r = remote("10.113.184.121", 10031)
r.sendlineafter(b'key: ', str(test_key).encode())
r.sendlineafter(b'iv: ', str(test_iv).encode())
r.sendlineafter(b'ciphertext: ', enc_png.hex().encode())
assert r.recvline().decode().strip() == 'OK! Got it.'

# Final Decrypt Flag Image
# real_key = '49276d5f345f357472306e395f6b3379'
# real_iv = '4ba3cb1c134651c3bb5cd6e381c2909b'
real_iv = bytes.fromhex(real_iv)
real_key = bytes.fromhex(real_key)
cipher = AES.new(real_key, AES.MODE_CBC, real_iv)
pt = unpad(cipher.decrypt(enc_png))
open("./Crypto/HW/Oracle/decrypted_flag.png", "wb").write(pt)

::: :::spoiler 有考慮同一個byte多種可能的版本

from pwn import *
from Crypto.Util.number import long_to_bytes, bytes_to_long
from Crypto.Cipher import AES
from random import randbytes


def unpad(c):
    length = c[-1]
    for char in c[-length:]:
        if char != length:
            raise ValueError
    return c[:-length]

def asymmetric_encryption(message, N, e):
    # encrypt message with RSA
    # message must be 16 bytes
    # padding 100 bytes random value
    padded_message = b'\x01' * 100 + message
    return pow(bytes_to_long(padded_message), e, N)

def symmetric_encryption(message, key, iv):
    # ecrypt message with AES + CBC Mode
    # message can be arbitrary length
    cipher = AES.new(key, AES.MODE_CBC, iv)
    ct = cipher.encrypt(message)
    iv = cipher.iv
    return iv, ct

def compute_know_part(padding_idx, known_key):
    if known_key == '':
        return b''
    known_part = b''
    for i in range(len(known_key)//2):
        known_part += bytes([int(known_key[i*2:i*2+2], 16) ^ padding_idx])
    
    return known_part

def construct_payload_and_verify(i, known_part, enc_self_key, encrypted_key):
    candidate = []
    for byte in range(256): # 每一個byte要猜最多256次
        # 自己控制
        self_pt = b'\x00' * (15-i) + bytes([byte]) + known_part
        log.info(f"self pt = {self_pt}")
        _, self_ct = symmetric_encryption(self_pt, self_key, self_iv)

        # 連線oracle並驗證
        r = remote("10.113.184.121", 10031)
        r.sendlineafter(b'key: ', str(enc_self_key).encode())
        r.sendlineafter(b'iv: ', str(encrypted_key).encode())
        r.sendlineafter(b'ciphertext: ', self_ct.hex().encode())#enc_png.hex().encode()
        res = r.recvline().decode().strip()
        # log.info(f'key = {enc_self_key}, iv = {encrypted_key}, ct = {self_ct.hex()}')
        print(res)

        if res == 'OK! Got it.':
            tmp = hex(byte ^ (i+1))[2:]
            if len(tmp) < 2:
                tmp = '0' + tmp
            candidate.append(tmp)
        r.close()
    if len(candidate) == 0:
        raise ValueError
    return candidate

# 題目給的資訊
enc_png = open('./Crypto/HW/Oracle/encrypted_flag_d6fbfd5306695c4a.not_png', 'rb').read()
N = 69214008498642035761243756357619851816607540327248468473247478342523127723748756926949706235406640562827724567100157104972969498385528097714986614165867074449238186426536742677816881849038677123630836686152379963670139334109846133566156815333584764063197379180877984670843831985941733688575703811651087495223
e = 65537
encrypted_key = 65690013242775728459842109842683020587149462096059598501313133592635945234121561534622365974927219223034823754673718159579772056712404749324225325531206903216411508240699572153162745754564955215041783396329242482406426376133687186983187563217156659178000486342335478915053049498619169740534463504372971359692
encrypted_iv = 35154524936059729204581782839781987236407179504895959653768093617367549802652967862418906182387861924584809825831862791349195432705129622783580000716829283234184762744224095175044663151370869751957952842383581513986293064879608592662677541628813345923397286253057417592725291925603753086190402107943880261658

# 自己控制的資訊
self_iv = b'\x00' * 16
self_key = b'\x00' * 16
enc_self_key = asymmetric_encryption(self_key, N, e)


# Try to POA Key
i = 0
real_key = ''
known_part = compute_know_part(i+1, real_key)
candidate = construct_payload_and_verify(i, known_part, enc_self_key, encrypted_key)

i += 1
while(len(real_key) != 32): # iv共有16bytes
    for candidate_tmp in candidate:
        known_part = compute_know_part(i+1, candidate_tmp + real_key)
        
        try:
            candidate = construct_payload_and_verify(i, known_part, enc_self_key, encrypted_key)
            i += 1
            real_key = candidate_tmp + real_key
            break
        except:
            pass
    if len(real_key) == 30:
        real_key = candidate[0] + real_key
        break

# Try to POA IV
real_iv = ''
i = 0
known_part = compute_know_part(i+1, real_iv)
candidate = construct_payload_and_verify(i, known_part, enc_self_key, encrypted_iv)
i += 1

while(len(real_iv) != 32): # iv共有16bytes
    for candidate_tmp in candidate:
        known_part = compute_know_part(i+1, candidate_tmp + real_iv)
        
        try:
            candidate = construct_payload_and_verify(i, known_part, enc_self_key, encrypted_iv)
            i += 1
            real_iv = candidate_tmp + real_iv
            break
        except:
            pass
    if len(real_iv) == 30:
        real_iv = candidate[0] + real_iv
        break

# Final Testing
test_key = pow(int(real_key, 16), e, N)
test_iv = pow(int(real_iv, 16), e, N)
r = remote("10.113.184.121", 10031)
r.sendlineafter(b'key: ', str(test_key).encode())
r.sendlineafter(b'iv: ', str(test_iv).encode())
r.sendlineafter(b'ciphertext: ', enc_png.hex().encode())
assert r.recvline().decode().strip() == 'OK! Got it.'

# Final Decrypt Flag Image
# real_key = '49276d5f345f357472306e395f6b3379'
# real_iv = '4ba3cb1c134651c3bb5cd6e381c2909b'
real_iv = bytes.fromhex(real_iv)
real_key = bytes.fromhex(real_key)
cipher = AES.new(real_key, AES.MODE_CBC, real_iv)
pt = unpad(cipher.decrypt(enc_png))
open("./Crypto/HW/Oracle/decrypted_flag.png", "wb").write(pt)

:::

:::spoiler Flag Flag: FLAG{Rea11yu5efu110rac1eisntit?} ::: SpeedUp的意思是只考慮一個byte只有一種可能的結果,換句話說,256種可能中只有唯一解,而另外一個script就考慮的比較全面了,有可能在256種結果中,有另外一種可能導致padding正確(雖然機率很低)

Reference

CTF - AES Padding Oracle