Transaction Hash:
Block:
19134891 at Feb-01-2024 04:53:11 PM +UTC
Transaction Fee:
0.100043370389430225 ETH
$276.56
Gas Used:
1,850,151 Gas / 54.073083975 Gwei
Emitted Events:
253 |
TransparentUpgradeableProxy.0x5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1( 0x5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1, 0x000000000000000000000000000000000000000000000000000000000014c9db, 0xc2860d904bb60cf9ed7dd26cf307ef9925b4e99667e94cc6643e4e9823c13250, 0000000000000000000000001c479675ad559dc151f6ec7ed3fbf8cee79582b6, 000000000000000000000000000000000000000000000000000000000000000d, 000000000000000000000000c1b634853cb333d3ad8663715b08f41a3aec47cc, 60dd98ab047a035cff68a3aa38b9a0e4e4ce5d47f65083a1138a761e7e7ceabf, 0000000000000000000000000000000000000000000000000000000c9406d7c7, 0000000000000000000000000000000000000000000000000000000065bbcc77 )
|
254 |
TransparentUpgradeableProxy.0xff64905f73a67fb594e0f940a8075a860db489ad991e032f48c81123eb52d60b( 0xff64905f73a67fb594e0f940a8075a860db489ad991e032f48c81123eb52d60b, 0x000000000000000000000000000000000000000000000000000000000014c9db, 0000000000000000000000000000000000000000000000000000000000000020, 0000000000000000000000000000000000000000000000000000000000000094, 0000000000000000000000000000000000000000000000000000000065bbcc77, c1b634853cb333d3ad8663715b08f41a3aec47cc49e8bbeb90c0e841c3d07a5f, e7706e0b1d99f6164da95b042f41ce1bd6f27da0000000000000000000000000, 000000000000000000000000000000000007fef0000000000000000000000000, 0000000000000000000000000000000c9406d7c7000000000000000000000000 )
|
255 |
TransparentUpgradeableProxy.0x7394f4a19a13c7b92b5bb71033245305946ef78452f7b4986ac1390b5df4ebd7( 0x7394f4a19a13c7b92b5bb71033245305946ef78452f7b4986ac1390b5df4ebd7, 0x000000000000000000000000000000000000000000000000000000000007fef0, 0xb6d8bc3509c457bec0a2b1aa657520c3e993f74ead66fc0883dceec722903f34, 0x416a7ea61a74ebdd819eed305730a5add24cf86110250232ba8ded72c16e0738, a3de161642afa61d101bd7093d6031fe33c3d75ce6a33675fff37a163868479e, 000000000000000000000000000000000000000000000000000000000014c9cd, 0000000000000000000000000000000000000000000000000000000065ba7af7, 0000000000000000000000000000000000000000000000000000000065bbda87, 000000000000000000000000000000000000000000000000000000000123e32b, 000000000000000000000000000000000000000000000000000000000123f9b7, 0000000000000000000000000000000000000000000000000000000000000000 )
|
256 |
GasRefunder.RefundedGasCosts( refundee=[Sender] 0xc1b634853cb333d3ad8663715b08f41a3aec47cc, contractAddress=[Receiver] TransparentUpgradeableProxy, success=True, gas=1894075, gasPrice=54073083975, amountPaid=100200344552209650 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x8315177a...4DBd7ed3a | (Arbitrum: Bridge) | ||||
0x95222290...5CC4BAfe5
Miner
| (beaverbuild) | 10.224440778135325693 Eth | 10.224533285685325693 Eth | 0.00009250755 | |
0xC1b63485...A3Aec47cc | (Arbitrum: Batch Submitter) |
10.0031656546282324 Eth
Nonce: 472802
|
10.003322628791011825 Eth
Nonce: 472803
| 0.000156974162779425 | |
0xe64a54E2...80E2E4eb5 | 938.076474513933711686 Eth | 937.976274169381502036 Eth | 0.10020034455220965 |
Execution Trace
TransparentUpgradeableProxy.8f111f3c( )
SequencerInbox.addSequencerL2BatchFromOrigin( sequenceNumber=524016, data=0x005B413B35D9B806E7860040C0FB5CEAAC1205D36D3E72DB28756E82BE236706858D038800F93162FC57093619EAFA611526096BC16732494349892B94B45B0B8B934C36508481A220281607F7C7C619B275772384264069DDE7839B17178E1601EEF41029328CFF797E6E7FCEB9F7D5068CC146941346B5511F37C202B3A70C2B00A347988D3D2B307376E3B7B0F38F5F0CCFDBEDFDBBB366ECC6192173155D321AB22311C7AE88AC12F2CD64EDCC6F54C64CC63E19595923D2A1ECEC8C398073FBFE73BAA545225332242505C93C2D29914A8C105A29812325292D82B494544A083D00E75CE283E40762414FC483319F9B7D55BF2DF73633E0BF4344BB243B8827E057578356BFD78D2F4DC58A2C7DA9FFD3BA51110A21233C83443FDA4FA8328ED224088F6CC6320813A350FD1195C1A8A3A9DA1DC2A24406AD890A458956145CDF9BAB667DFD12254A748BEE1EDB1A669DEB31EEB6A7AA69BE4A1D53259AD9CF1044404C1041470711D258B18DDE57753555940009C136A8AD1807ACC38C8335F4ABA714485F9F6D21C4AE4AA237244663D0680C5A8DA19798705682312C628CA7A5AA61A324A403E35D51FF53ED68C61148C5A81B4A639C2254EA351FB808D6D1BD763CBD769C39AE3BDCDC694FD79E39CD118DF34777B8CCE1C27A773BAD55F79F7AF9034538429DA5A923BCF280862CC0A9A6A9C5E5081D41BEC03F0E484C160FECD6FA3D9A1DA2F0FCF200E85B0F9003EAA2990D08C730FF73FA9F74E15FBC68193F5BD2ABD3B74923E29F7A95D2215F3997288035404AD31DA5129660E874C0FB707F3BC5716ADBE6F794623FA7F497F91C650248A06F317E336FD7AE9F8827C5914046F9F4CC59EFFDBFADFC6B95EB6E67379C920D1AC6412589050B8A0A581AD853E6CE7FFE75EB7FED936925AF7CDD96DB9D37E8E529F7921951B90E2A16040B4591D202494C23A40389E5CD9B58E78309E600F5DD4A5E68864AF7F2EE9C010962BF5CFA2F27C5C0C0C08A9E2203034732304869654293D08136F53D94C1984088E730BC16330AD040F91F9C097383A10F20219805926F0E0606D8918EC77FA11A1251127D6C19C433ECA5F4CF302179D53A15AE45E776C1EE0A0029B701E384073606A07802E9900096ECD57C8EF1EFDC786779F86B79B926372709D042EF200A52720C840628123200C2029AAA3272D0539861AA00CDC2365466D65776DAA7DAF853A57F61AAB2FE155AB4FFB4BAD036A3537A25669F3DCF55D8C97C49300CC4A517119D40C8170FC96D97951BCF39BCC362321847FD85EB4138094D7B6AFDE0E893F8CEE79B94A1B3AADB3E8E6EAC999C80F1BC325B0C5216B7A5E80C116D97A7D1636AACA33EA6C4018DF8D83CC982048E5486374A7A21624269906037C56E579CE740975FD45C2F2853C3D12139E3128BC8210A8728FE1DBF388894595646E71A2B22BA929B2F79B0AE0102ED94837207249A9D03C5D1F6B3B86F7689291451E6D36877147EA9ECDFBDFD4456E88DDCC8D5D6CA949CB22E11E3E0B34C2885428DCB8AEC40CD73CB38E8B27F7A241CEF4F1DF36E74DA1C410379F1AE913D8B50CCB0F09759A7AE1BB5421E3F1C5D020706F2D0D0F6F7AF4C4AEE3231165EA1078CB3EB29752BE3C385450A6921807418D06E319A38CC46109D0816FAB24339028EE295C590B3FE9D8F8444CAEB6C3DE209288CF5F290B3B4EF9C9E671836FDDC466EB25698F11CA55C6C3581A066A157594C7ACC33EF0EF85B6D6034DAF33A20807A6A36F51BDA766C464F0A7F3A37ECE0C8ABB0BFB560B423B04DB11222F71C16D6842A6B344B09279AE514794ED2DD3A7337201E1D402668BCEAEB4FA0AA181DBF79B99A49203D6853C72828E916E106892995C1492C1AD1E2DF76605099000D0BBDC92A2DFEA5DE13433370A467148134C8900F5303CBC366A5B34B0389C3C1602087D0B22BB9FA30D6C3412B80D6C8B20668603406DC979E10E6AAE44CD50F77AABE590CF95D9855BC5FCCCA73DAE3C24C11C068B78AA910A01610CB964AFFC10214E4A4DA9B01809513313AA5F08B9A987F34D461675A27AEC6A38AB08A6067039C52269CCBBD89B56D8E75D14518D6696D647FC97D85DD4955139D72A9F0B7DCDEE0FF22F31DF8FE28682CC6B5D8CC81A6A02DDD821CFF43B9B34F69B8F0E34079BC654EEE64FC447FC2968A1E84AA55F77F8761BB9614109BAB12C5B98C39DE37F78380DA0E8FB2B9DEBBB19B0730472031D505CB12CB75CBA2B56B86A9B2B83E312E0190B0C70039BA7A9B49A28AF076B5966BCE46593BECFFE875149E02E197EAEF302E98885B4C7B18D4216ACB3FB7DC1F523FA52B0E6764315EA87AECFD6B5A1FE95FB2FAC68DAE5285BCD192F6702D2AF0F04BA71450DA3B0063444057C57610401835A439FAED0FF6218AB9042FE57A08C01714A7143E99FE7B9841E1E8CD212070C3ACA739E6EBDB2838A5755BE8A1FAE57A8FF42E4CB73A4AFBC006361D80534E345C6D3BCF1BF17618D0737229B91FED5C3E7A00A73CDD7EE2BC6CFEABE3C38337AFF2325FDE22EC677D84531C113679BC70BBCD13AAFCA0E03B35EDEDCB97EE42D442B3E3E38A05B3F9713366CAB5E37C48648CC3085931431BB1E0869A905C221C00988DC3A7A599DCD15459C74F4019F9FA4C9884932DFCAD25C2FDC0F1DC07BD3721102D449A7052A6B63E91DB079EE6941E8558F5B4DAB155825B11247380F116AB568EBC0EBF1E0375C5C5667DF997CA19106C4608F681FE3732841F9518361CFA177D8BEEECD677BE4971A4E680C82A166E2B270D0800A4C3819E355907B8BF03059CEDD0ECE7FB75D32C921004D2AC8E7DDD594BC403D6E071A06DC137E910C1087809935CB1FBDB1342A872C791AC7FF7C41A23BD39566ABA72070C61593AAA740407AD407F2EE6B1C44D271B65F03136F8799C8A148045853EB26FB667084F77E1557DA4B86C551188420FBDCD2C9681A8D4ECB5140F06CF314E733EF89D4F2D5948517FE9048FF6B282133504A48C145499E1CE5457574D9348A5D386FB8AC649C574BDC8900DFA96F4C63341B6BDDD270A9AC359DFED7DBB088A34B0E8FD4A0CD86A128C797F28092508EFF4B59C700BEFEE5207875BE889B038D4596DB21AF5683733327AFACF0F02B3BF5B5F28FED7BFAAF53D368F9905091FE5DEDE3A62EAD127B718176623BCF57D8B639219F1736FAE117C24DD43DFBB3131247EE6F38F4FE23E5FF6628694D426B802F0747130090A094C4564091272024B91085AF63A97BB798F003D4FADC9A79D13D2705FEE59E3B28F9D384C61DC3522CD380AB6632F7F007CA782BE00831E6D80F953172C428AC1B2C076D34CC6CC5BBA714299FA249A74F199CFD73568A3EB0D11648A1B1DE6FB610FC7A6A71B23BEADB24DE5139E75149D680ABB86DD21B3E0BFDF598785BEB62929A7D21A128A5D05BD0E8F185008752C1E37C17374485BE6159196737A060522C9ADDC1480AAEE69C6CCD3CFF4FF37D94463117074E7041E00B4F5E0A3A19D3E0EFE38D04B152D516CF36DAB0CD188D16C4EE532C59D02947611C3603E5FFEFC8A9EAA9B9BE4665947B833D5D5CE354FC961BDFA05A1389A3E887C0D8293EF8A4B42BBDD2F8A2697D8E1C0FC6A36351F20F0B624C837784F3626E6D3F0FD111379EAFFF9FDB35855091743224B5FD775EC3F358C9B107A9F327F89B49A922EDB61A5EB7C65C6D37C4267EDA2CD23375FD10C8A8DCBD31576E26AE1924B285874343317EADEC9B3FAC5449D73BCFEF3E07417C02D2881833A3383CB1A2292EBF9AB6418949CA944C4BE0B154ED746B3F135DE9BCB705DF442019CE1BA7153CD5A0F25B7B7DC85FEA0250100ADB083DFD90504F0AC0376EA210831FFD24E73E7055349CF20320AC88918831B013DD30C944F267C3E0DBE6ACF7837DA62B69127A9F0B95E9755A89B4DC94B105518330FF3E6110C45E6A1941E1FDE2B53A4EDEF9F3ACB1976697DC9A8EBD0F0A56801679008F8521D64CA1A2CB2BE54259E5ED9146830246322AC9220808179D1C02703ACA9B19F40C4CE597AD5EE5629067ABD703FA2653C6697134C394E7ED4EE57E6F3EF0036C7EEF87E2455DCC1A8EA50C01294903FC0E9D166644EA10FB3E4EBE384947668E27A530E754475F700A5775F0E8D239065CC2EF58EE3027B4040BBD25011A50B22450CA4BE11A25B1E341D91F1113463BF4AA7D45CBCE7F1881C30109EA2D6004DFD442A5822CC15CF9B850659B940A455980E4BC1DFC93E3781580F6A37F5590175395C66C45413C414A9444CDCFCBF816E883CEADCA301EDBA723D018274BCEBFA9B23395675B680D1D4A47DFA8647C56619A3655825052B3E79CFF6BFFEDBDC3767D112F486B0F6E50EB163C271C8B7A7A35D0719BFEFA796F8BD6D0E909B6B4253F42E496D4F9D525845BE976E079082878F1DADBE93C1B78B4DC6EE8043FC49351F833A88F2CF2D0F80025B0221091110A8D232010234EFE3E29F29DF7FCB63CB405EBDE6CCE7A01EE9609742E486331944472700D0CBC25813073C00036DC50615F33FEB1120888CF7D1B11201463C5ABC2B1967FB7F7CF8A1EEC641D9BF7D6F6D9E1E26F8BF7AFF2EE891ACABE60910239B872DF67B2BA8D0635756E23843484ED0B6DBFAFB5BB64C53C8CCA31BB9510B55F92856F35DC0DC40740110A96B2069E42B38E0F2B659FCD2CBE546EA5EE3C7964E662C46DF58FAD4BC576EC335B9AF9389DF7A26198E17D80F43809CFA1E2A96B34B36BAABA527F6505F55B245C0FE9F68754A1C9F429D86677211A331756086F4EDDD46F7C98D8CA2CD648BD59CCB88909122386989BC912AC847A1FB82646E6217E27E5218D987B7233E4D783E41C79B3D177310194052E41F48A99F30F0F995FE47FA47AFFC31361AA24C4FE3EA7DDE5A7CB69A3E9C1B5FCB3643C20C6CEA7FA8F21BACD45E3F091D373792FAE5799BCBB4997FE9A8FFEE7052AE9D9C542EF87E773BDB3F965671D86B74E4D7259AD904DCE8A4F5262AF27CE17AC7BF0FA6F78CCF7BAF2ACD7A94836F5317FD733867EDB22EE2C7BE0CBCC2A835A300833A1868B6DC7CA9043890CCD51817809DD88DCF893AC9D4BEACD633EEB35FB063F776C822E01A6B8B918C3CDF14BBBE20C560C1D6DA0DE91B4F13E6E8F9AFB343429798FAE8ACAEEC946B56E70F4E04ADB38B6A56799D91EBF3E8CB7368DC72F691E1ECD84D0F164BB2ED289D38FDA7488090B6893C6C520AFAFE101869EA28B8863479895B106FBE5831EECA44C5B9D26DA6E600840C77869926C7CCABF5BAE220C84586DBD6DCFB745ED921CFEC6820E28F4DB67760F041D0B845EC313868054C3DB8A481A4E8AFA610FB47941A4DF90A3E634F7430742B19F0DE574C9A5F5C5B114BBCE18C0EA3D5017AA4822E18DC68C10F0B3865913266E302EBE8F1E8401364D072ED01EFBF5C610AE26F73D3F45DDB00FA685BA7C32A3BDFFA98CFFF1810F5812D6727A41710656476AB5FA93B5E26AABF64A2D4971183E7D86DDC29FF91CA0104B7196BEBB03FA663D9BEA09B72E6B52000CC8569B8822BB76C7DC1202350E896886C039A29FC49EB8D87171ED8E8AB7B6A79EDC256FE174E972552C34405DF69D0E7C0132617DA43CD187AA6E9964914E1C172A2D36C415036549191A52ED56F98EB2DE3733A399F18E0B54354855D56C5F3EBD83F0546ADEEC79588371A735ED60989DFA6CAFA122D79988ECFC6DC17A67FC3AC0A74C87F81C1F2F83FAF01DAF2397BC997DE0287D6C748132BEC5583B1BDE612E91186EF85833AEB2B1325C9231B72CB16D2A9BEC0BA20B3473633056F906551DE54665E8316135BE7AC82F09A46F029F7F783805EF52FA153F499CD73BC8B49A3DEB4E1DDC8E7C7778D1C905DED87A18C94A865603834D4230BB70284119EA472027097BB109393516154E215C7E3CF050171A39FFE4215AB1689DB1148EAA0E85BE6D7A8FB4E5DDE60234B455A674804E02345CF32C4F4F63AF713552DC2458AA7B03D0124065390988C8B8244400E0131F721318B4E9ACCE3D76C9927E94476CA87743A3A9A344274F880D4A16F52FBBBFA2C65977B8806AF4F9C146184A543B61E664D659FDAE945584BAAEEFAE7D5DE0469EFA78DD68584A6D762AF313E822EB42CF0462B629D6594A1303E34F4D373772B28E11951096D3B22BCB84CB375FB57C353FB457E8AC7F8D246CD850AF934E4B160AE3E88A53E974B6360FD24455436370069C17E2BEF3D8FFA28E2E69CD5470B6D51C2F4E8ABC752FFC44B02D0FE4743997374C3881E82149EA923124C20D41E668DFB7BA79BBA71F3A77278709AA2BD97E660E78B5C5D54AE6B917ABB4E3F2736F67FD03582DF2DA8FB8DD285B886722B6362E65DD8F1D1ECBC46E2EF03A581C6273EEB7A7E827194AAF9DBB6BAD3F646870A8B952AA2F164AA753ADC59C3D28521AFE1E4EFBEB078FD6DADC0BDA0C54F076BDD0351B5D715657211214074D650CE0235CC4480FD31F0A7F9075043EC5EFD53E893F85121DEC2D103F7972ABB869AC4E89304A0FB1BFF4BA417BDBD1E12262C31696D4A66361324AB7F0D2EA59A5CBADE8CABC8EB4540E4185DC0189437890BF44A91BB43536A5588A6213A6FF86A2330BE057B522CABC48E9B9202764A97203736DE7862C75C223B8A563DB2A41F11E05DCF9264B13C3950015E81AEA2A0B536E117C7CBE1364298E44338581F5CBC0A9E224775FF46A4FF772D73E2A3F1756E987726677FA71F01E8136ED008934EFC57521D2D895B469714584B1FBCB0231A30E431C2702D13A6443FEC30F4B7FF6146EEF93424222C572D21D41D717E60F87C7BBC5631FB3DB4441C4FD3B2E901990B0868C66A62F074AA116C2A51DB113260B3E81DFE8D278EBFFD5F45AE245FE423095D7D55CED09EBE86A5E071625D7DC401FC518BE1650349AB114659EE35E13E611A1FDC49C9152D096F09F8E0BB28F590A83C9ACDCF3D9C345B21E02255C95BADE42A3589742532D4A76D09CA917D9FF096F07DE2FB97F70A66EECAC0B29AC1ADD4FE1A4D93FA7E43D5F5FA2D9EBC171FFB8CF6CED4C8C56E2D1A70FA18A1D3D207322012B54C9E4BC4622EF49A62D1C6EC3183E6CFE5232996060A679A109645B17680AD220FC3A714D05F9F8A269186BAD3DD02BA334867E3017126FCBD64C17C60EEA2E0B60C4A79009515C282A7908EC00D0DF55D390CF7BCB86F14E2862A721F51DF6979AED31DDBC6FFFCF7B3D6E915F5310EA5A7BB810090F9E5588E040C4D7324C730BF7EA0BBADF76F1A8EFF32806058C0B28FEC528AFB7F9F7D45DED0F280FB2DEFFBE13DE191648757DF66BD3620BEC2BFFF7F4C24FA6B7DE03FF16153DDE2C37F73F4BF1F05579A5510C209305ACF51B53CC33A48D82EACACF76A7FDCE76C6E039E23D8007170C9F20214F2AC643279EF95DC7AD78C83B80BA2CA931387BFDAA9EF6774B1687DFBA83FD049ABEAAD2FA747BAF40CBFDC161B3CD3456F06A8A2A09F533096C82106029DF39E252A835158BCEC8FD339A2EC7046802DC4A592E6CA68E9A771CF7387AC4EE746A2062315EA780AA5CEFFABB84DBD642097518D99BB0C0E101A15E871B4DFC811D51A75ADAA31A0F86C586BFB23AFBA96F89A0F2CBAC6BDAF8ADC7A3EC29DB4BD41B3CDC4B7AE9C146DE9BE232811415EF7435F630E72DDE5DE4839EF1E3E61AFA1BCDDE478670BCAB247E6C7E81A7230C0B1EB02299AFEF8ED8F9F9FC4DF1FA03673D29FAA240319BEB37039CA4003A3538E8BAF965AE4F5B737F05CF6734087E3306FDCBC3C3B583E8D7731522ACEC55D2B1E793DE1D34054C1B3D5075B6F56093B847500F8853E1852A177DDFE3FCA2B225AC6E3D00FD6C13EAD737D3F46D2DAA09B5428D9D2419004F472E9AC843DE183219F4F34BB1AB0419A6FCAD626126818FD5E3E7D4EC2B43C543A88589FEA5D2DAEBDC6E3126B21EDC0AF9668396233792F1B41F5D6E0D8B37E73DC12A68DBC9FC479E5A094F54182A84F344F83A8AF099399C253B10F9DA7FAF8FE67E08F84464016D4269C3E1AA5438966E3D953D9DD78BC85DB7F92A74D0D803D04A3AE93BAF49111970975E527EF48DBEEABFB98C49651EDF3C08FB1452F28D12031F0C77D51EBBB456CD798687E17C6E866226F58DE722F5F8EE4C95DDB8E8B066EB8975BECDF69647585F340295B28EC81F3F3D093895CFFD8D685F4569BB4E7209DD17788B576A3B3B3C4F1983418EACBA4F51FE705E01B0957E8C0E09726D89F772619304504D150082EF85F14F61ED68667D32ED389DDBC1F8D6B017621A55730F64F6E13B7EFE91E883A0987AF61B87BC22B9BF7813C6D12ABDA369FB4034B3F8D7504C88DE22759DAC5B099BEABED7EBC3C8C92B77C91BAAE09BEBBD97AF8D756BCEFB58045176B54574441F3751F2E1D6E5D8D99A96A0046D4E1BC9C9EAC152BB65682D99D5376912A947242BFF5A8D6FB34A4429B6F94C012287FC4DDB252161825ED7D06EF40E130C5C4D8D0A01212597C60E2784184CDAA954C11C9F0260A4CC8666B82CC6D0189063D16EC00574A222687355FB56A31A25A113A35FF947A9B472FF94333D01E6B8FCE866C8B88782069D610DCB0486D219EBE8431F2CB5EF2ED9FB0067EF5AAEF3E474205B6F7D4FE187995E1826794211F1D17311C87772E96B207B5825C98E9D580C991F6582EA6F40512DFCE8D993C739188144EDC1E768418EC8868A78AFF7A412117F177E01DEF7B72F86238A83363582806CD301EC014F4B5D286B05677644EFB52D72F8D384E1A6954E0D510E37AC3AF58120696ADB8940EB3647B7A3C9138D0A1D594B03EB01281BEF7DAF8526DBF734939DBA0EC0F043A6AFF8EE086CFC992FDAEFD8652C1870E309904F099713D9267F7239485089002F5261D67B543226BBBDE9E2224960FB43AFAD4044786DB7E187958FA1635DDDBF0BE3A14F3E6061A8ADE57868C7A168ACC9C0818C03164B2B38D32A740CB6BA874F547673E88506ED4C82ACC8720FDB465CF4FB211483CD7991286359D8C949CB93EAD5CF3A628935972F8CEAF865284870E12EAB8D0CFD48B6A1365FF283EA1303648960121D46FF745765FDB935B2936679FC0D116E053C2C8014E9F3603BEE6979CC81DF45291843DD9000C9617A8F98970F91FAAFFED8D093F23883B7ECB6D2A0102976C5524FA41C0C762ADC65647967F3A8E56017D2B026A4C316EB8A3DCC455D2D9CF2CDDAD862B806603A9658A53F9EBA923F546BD8F2B2BCBDFCA68C8F5A07062667C6115DF67FD19150723A367B324476CF4A3F88B0FCED72DE4054E2EBCBC5FD3B6F84D3B1DF303E91A1F5BD8799095CDC599868900210DD3DE451ACA9252573687268B218D34F5A4E6CC98DC5B86596C7DD44F386D55905BF463B8B99530C42081362B857A639059D5500AAAE4567630929B9AE24AA1A8710198831790E9169AD6842DFE79F8DDC03AAC07A37AE98FDFF7B0ED8E7F68FB35DE91920B049DB181A8A52A518AF3B07F689E4F45E2143277D0632268249E54D1CDEE73F5EF464DC1E323B879C486A7B62C7DFF0F39D75D37250EAEE9CB7BA4CEF9F4CFAC07FCA6768B7BC28C47F03BB903DF024A8DE9900A7CCDF137DF1266281EAA6DC5F87C627BD57B4020A0986A97CACE6825D371EE634A5C2879C763CC6C6B855FF02BB003EF2893C75106AAACE21539152D554EAECAE16AB8F9A5634454358583509954824109DCAA4CAF9F1A362C087F81C76BB68E60111C82476004410800916100C19EE22010E53256C39E9686D1D2A65F31A442C22226283AAF991DF6065A339819C60B928BB6D9085BA815F85431B8F7DED57EE9FE01E4272B967B00D19294D1A28F0790CAEE522070B0D14E0D2E422CA7D3EDD0A454B1B1C3399B8E83D56AAFA7A1277DF3F6A0E9CE7257E2F001AB12CB6088CD622644976753CD106EC8DDEC3C4397145C68ACC41A6AAE672A4B3F27D83D478C25EC82B04795AC49A0EBA6986BC22F51055AC0AF78A6AE0E692585F26077EDBA83B4613AD557D5A3C771752F0DC7803776DC08676405CE504BB0617DF10ADE9C7C6362989FACF6926D930D56D4B907788EE8BD4A3BDBBCBCC1C49B87EA9FF6A3ECBA403C89FB1C5222526A0D9F3D71688D108E62630B6CD999A67920B3E27D3FA7C962BF358E70BD9A3E85CA58F95C2FB6005C72888710F40891E46F5A201252D79BD8344B38EDCAB8FCB0BBBF7C16262CF1EA6F572D6A2A95F5178532D7553C75705B457BF86389C0437F3B1DC66D80087ADAEB10CC278FB11AF64E42DFB5F0AB1FCCB80472E6BEB7E9666D4E68FA33677996D67FCAD154144F0E6122037DA5684A66BB472BF5F1A751FA28616360F5F8DF8D3A898EBCCA7075735A823613160A71C27F43D10622722EB7139F9A3B5BE4914573BF1481A102393380517F4CE77B475CE4DF517FF2FF140C16AFBC200A0E745E2C435B3F391B6CE8802CCA1911DDD5E34A373040200D21C067C2972E51E5311B7B96F87E3EB3F7C620DAE0F9BE02F4AF47994B71FBFE5118C7C310B3DF57C1FF83340B7D218D61749DAF0A08B119AFF0E295BAE0D8E95ECCE89751BEB74EE9856AF44EC96CEFDDDDB5EFCBD777EB0EC5667913413D18983F960754D497242AA45F9D76B0F49C398F2F2C1A552E3F1EDBB4F3C5A9A8FFA46BF286ECE821CA956FAC00CF4E8075B66DC74E4416C635ED6AB5AD07D4855824D1904D7C520E93FADD0F3F3CB2049FEEB0F8B00EA171E14D8698E0C3EB14A06CF75AFCC6353FC57BF1938C9098D4ED652D250456CB64DC87831D58D9A7E80DC778BA53790D80F910FFA11379B9D787C3F392DBDAA128DFFE475459BE1FC2C223095C74A5F0F14577AD215521ABE2824858D17F559F6C9AF0C87E5C439831E676D8D52C679AF4F0C93BD4EACF7D1B0950DFD14E8121E6B5187A2DBFCD9C05ADF2F407023F6935C4D6D86992B02EA622B06D7CF631DA507282D6343C3542ED95770BF84C0131EAC77C9166A595FB24A84954181184C96424D0E99976055365D25D54ECADE33B70CF2068C4D0AFA511FCD61578AB8B443EA852FBCC449A4BF4182288B3C69D7D7AD625AB907F2223E4E27EB72BF4CE3A40CDAAD375D667E0C1CFB0E542D4DC8AAD2399CD34460358ADAE79525939794915299B17FA5CB7FCDFC9E0CE3D17801285801CA613AD27ABA8F476F13541C27C1754B1D8AF4BAB729A0A86F9E18C0C88D1E3E66DCF4368216B4C74EC797EEBE235B826D3330DFF70CD624C939C14DAA12AF3975B0EE8134826A1C25B711417A4E98DC99EBE96D285F2B492AF7DA06682342E07475681527538A402EB698EA062FA988EAAADCF5CB9EFD9D9E81DBB2FB684C68EE217BAA36CB4FC853BB022E5D4CD1B8C4EA9CC813506CAE215AAB295C8E81FA90AF42CE98D23B9CFD2627695F7A00D28B8AFE4E05C3D3BFA323F16E1800D913C922E16195F515F123415B1F37F1F6569661810C0B514889A3ED8D6782AB2402CC9FB8493248CEEE9B50F1DAC5D3D8D9D3458BB4AFBEB4F642FC141F91B2F97099354B3B5E9DCC257E9223EB0577BF487D73784587BE87E10E1A4663D4E3A00A60DA9F69936B4DB3D96B1D06E3CA52964BBD023C945C6D15C83C590B9A030DB350B2A9C65DCBD1EA687B40F83CDE656EEE53388E0EFBE71FC869D492991B1CA8BA5FF647A2B1E41183F5DC05C892F8F45A683BC6924BCA60F2B2E9CB44C4496E4F22448C8A756575E2C9ECAA52087A12D06766A255159DA4226EDA1AC88EC75D02582BD1901185E70C8069FEE86F0EC486E02571570424727617730292B7A7C9994737A2BB00F777C26B9E4BC83AD9B66F1E68F38E190FF442F46C806E54E9A7ADFAF2C8EA1F9F68380CCCF0AFB04F829C2B678EB6230DB66E901481CD9AD70DDEAAB4E5F335491FE5BA0E0B5EE157825536465FEDFDBBEE22DA8E0253DD688A73BBE46AB506397A6F1ADA9E7B2D3F88343D761DD6398A9FD752AEB9CE185AACD9E879590E6F5CB764092FC202564605BF4236852C7499086171BDAD34FDEE3AE9BFAEE6210D03771AA4F27E5DC6CBBEB0A3A1492EB77597BEBA9FBC478FE7DFF3C95B961A19364F7981BCEAF0FA6756A86040B1E2FF62B570937500F14CE2691DE20BA95A54927FB85783BCA142B30C0202D243E4E6305710CC843D9F04A2CF57EEBE604E4E372B9DD63A1376AB27B8F9CDD19A93D7EF5C72BED0E303C8CC718E1EF30C482CF59B1522D27DC9E0A193AC7A012384D2F6DDAECD17E31637C929F410F44414BDAB774181D0B9FB812742FACC3919EEED5EA04FD1C6151EB569F82F4C98EFD9AFD5224C88F04C30F0ED1EDC7CED587637E1D2BBE77F4323754D0AF7EAA94DA48F575BCC76F77F8499CF49E67AD5900830C95F4C745DCB6B6B8CD6C12D49807A00AC4A8926E676529443656A65A487B5A7124E4251F206F5EAB5D1C3BA29E65EF0CF5C989EB4882F322E27B5ECB80388A3B13CCE8DAFB8AA251BE95C7D984D75B22E4227F95F1E07BA9F7ACD0DCFE77800DF704C9D3E5998170A1F9666C224915277D17C54283BEE82743B6796DF3864F1DCD288D231CF2E6DC0B04705A26131945D3C1752C30646530491FB7A876DAD9644EDC1847FEDF2E1A730C34F9230125FB167DFEAA8CA224F18EF886648F15D7397F28F6549B53C6A2A8240A9290A1C017496DE844E1112742D5AC6EFAE85D8AD4A12A49C6C89DC92B2B0312D88C16373197C0028311D0BA9EF20FBDAE2B7A658F01DF290728FE96CE7E2AE80E44B8AB72FA160137E1B4031C2A0B562F26193D5C7ECEC9B0C3CAB6E153557A6821069917E03522E5D9C09783097C6D1999D2499DEB119FB39C8F43B1DE4BD87DAD80816D65AD73BA31D229BE4A0D0996EF40163857B7819F84770F5243166408CAB8BBC735FD1735B9502F4D0F0F2E6316D55B14C32E8C88585455B8993B08967879141BDE50DE3FBF7AE12E9461AD0CCA4049737AC2C544376C3F121871E2DB8C54B6267DF982AE975A5696BA1CD150CCF36522C267D322440AFE8C053420378D90A37313841FB2771292A6452A75DDC4990E2368B398E971CB0F81ADA140D820E82596BF862514FBB297017D042E26D20CEBF3259D46BD2E0807A22B1C36FE505671A6DA31C50185A462BA9CFEF8164A42720B1FAFA3B0204C9D81E0F7C2735A1BB3B657FF556851975DC3BBEB5C823F413D070721F356B576921356C61A0876FA31169A2C99211539E8C6626EAF8D2677FB6E7BF6719D6C9ED57D1D0185F3201D472A394EB0FC670D933F938DD0D173559CE0EE33A139F0739590D5AC239912281D0DA6BC193681043F024BD97D17219F2FBBB7430163E45A7C2F78C0CA314A1BE810EEB084C078B4F6A60E52CDD344C2B6479C1D6B02C8B2FC5319F4477D5066E60251141068416A9F02F01DF820B25D1133C402AF5C1391E87B0048AB0400AF9900DC5B0054A8B65C9FE4DA11B10700E76EB1C7C5D42225C2743F0E631873FCCE7FA795820CADEDFF2748A48C45AE63031D36F107B7E4ED3BF8D576207C6BE784807275B5F6A930FFFC575A4B2AD696950B81423E6D95C01186B84420826C80233F6E32FA989D0CE3112245AAFE3EB0A2244642E00F7380A816CCBFE36CD078A51D4C33B5DB3186341E9F5C94957C0F49317886128A58EA4899204EC20D14EFF35FC62BBBA71A71478AAA99667C9BB9EDF2914B5C1A022148528A0E846E022BE34307972B290D65E78F70BF1810C566FC37D5AA49428BF5D3A51C71E62266EF68AC27DCFE4B9C7C6D2A9136AFC60A41F6E0A9ED0A8A36A32B337D93BC6631E4BF449ED07778C6B2E037229A58D2D38DA3B41F6D66D4C5CC2A72D15FFB079381222F0F7FEE4FA0BB520D5A7B4C3DF8461A8CA5A931E61F045D6B83683E033976862D8F55BC33388EFF591904CBC9F188A60ED8CD5B39ECBFDB0DEAA64398E30796C1A1CE99E09206BD95D79E23EEB54F5DB1645B7BCFC95B50ACE5B71C3BA72255709E910BFFE235D59202D4D80535EF368B2E06B9B93888C22107065B91397E9555C21BAB451CF70F8D8F3EFB9C5E4706833D20209047765B7F897B89FB9CF081FFBCF77189D678C172995FF087F4D33072CB7E1F48833C1F4723867C21977D655B78F48F51B4FF492A11EDB77A3EBDF35667066C2499CC9E6060CB5A14F84D0E05325608E1CF89FF9BAC6450920C961FBD00DD9302C48F94CDC2A7653B53E1D18E5A88E169D2798806A0510D0201171890922B8412F24E4B8DF54993397D8D3673C673C64E606625D75EB9A11358E0C774F032D2A9618D880D5E8C384FC8BF9876E7248249C79CDD05ED8587DB524CFC856A4B972063C16AFAEC82BAECE8374250F15DC2FE64716FFDA603BB7C86C07D091E9C27D51D76BC939B4C134CE0D56696A5CAC5C8388EFA44F1227EE74D7E01342428406F8F62F42F43F6D820B264451FA147E42B637D709AD45E4738CE17F0D006687AEADE3F5D18772CF5E4D5C54883E370982E0F58B2999F56C6DD5D58694A47F982459EAF01975CCC2405CE791AFAB6E9BEC11A3D98A07B7675D8FE0018156C15E84C61370C282DC385D89E96953996FB9E87AAE3390E68F3EF0B4DAB113C831B5807E87A9CAB7C4266F8F77E598CF93B3CF8D5FF4B5639024B6EB63C9BAE94C6CB6E4FC636EF9A0BABE115E7F4C213CC086EDAF95C9E8CB10C45A49D13AC5ED28BF087B4EA1D105B8BBFB501BD60DBACF48C5EBBC80D9AF1F645C9C2E24D5C2A8A96B5DFC46F77E9E0A04E6D7640F125BD54555F202138C786547E8A4C5B11FD48C51CE4FDDA19E6FF1160716125A38100D87E8F579A020670AEF5F4B97461BB5F2D69274F3D158A82564390BC556AD8235111E8C3F7403764951FADE5F03DE1BF3E3DAB9C4FC2D9C0249F4D5D3AA9D3884DDB01A55835B402D1709953C8652EAAF16780FDE53C1085101B5AD781614F0E054AAC73FF46CBB03630A3A8337BB516103F21C30628E4254A3042E20D256FEC60BAB1C935E10325784320D4C9415B6F3FAFB08EFFDC348A7C45F98A4CB28D53C586DC0B7C79055EAAC59CA993C48CF9EDDF7B9488D68EAFD6D8D7D16B247BCD477CC5A32DFC59118597401FC7CD0A0D97067469C53D6687670DB09532FC99DE7CFE484518337EF8FCAB9C0E20374F8FED84BF5D0683D04E5F5B3DF90B9F393CDFC65A534D1746C63D295959345F36AE49FB3F02BA720C339D87AE3D5A9897A1B1672CE5AC92ED88768CFB3C9586B36032A552F7A7BF2359DC1C51EBCA5D274CF80BEC6F011351F5C0370E3BF82AD38D88F9F477213CD012A7732A44E4BD611E5793020FA8D1E2056606198721E6FFF01EC5998FA375749FCC774DFE571702BEA0706FAD82377B1EFCED7D08D0F918CA9B3D025802FA2E8B8F41F6E7D87F48FC807E8EB3035EB7574F8E75D5AC222C178AB610A8EF0189F3F74483FCB5347EAE22EC08E140773234F5B1A0EE870FDF814E0603E855EE4D51813F22D2B7B7A81C53CDB7B5CC402DC030277FA1663E753D93C33C6AB099958B0A42B3D1B38B5467E9DFA538B3C25E8C9DE09BD45EBF7A735663275B70102026190AF23FDEBBBF58DBD5A98639B89822784F0CD831C98C40DD0D912EFE59A0CE84A53E4078921BAFC6B0AF2C63E74AA2525C005FD954C2A71B6D23A11C7CB9B7A074566EE2C8ABAA3CF79439B817EE6AC0350F28C16CC81A881382DAB36EC9ED07BA7DD79FC2B206EC93986B8999D1D4AB983F7F7F784EF5FF7ED4A7B21D5AEAB6B2831D3DCD4BA11423B98E0E177B5C1B1D444E1445EE0BD133E4D10B4E9DCB799C24868D87027EA2A4FD13AC0A3CCA3797024E112C111C6A9ABF588B1258222317A1523E9CF468B6E2ACA4AEA5BC85436D6E23A5A88197B29BD33D96B961922118766C76D38EE923AC6429170D816E0781260415228922BB823AFF4EE7213ED855620CE7A2C5FD4F19C30BFE7CE1A4B5F261736A48F92AB2C424E865EB90EF36F968FB993AD06E842C4AE9E00D63A3D138FB2E3104DD541DFACAD74FB04DD8DD598C69EA489DE8D9F6CF68630315D72123180335E062F5B7E4C4795CE89B9004367FCB10DB5C26B3221BEFC4EE3B602602B466BA44E9F38D931D92DABF47536A817418A9BECF6B56B1CFE5036E85037807DB4345CE2B74EDF9383633AE01A889A672492D54AC10476EFB0D988FE3579B7E1E581D618B91EC0F046667287E0C866FFD84A34FF3FAFEF5038B92DDA05790A854685C559115BF3A5E2B580DEBE9BE1B7F8824BABF29472F6B273E102D03C97DAD1E3D470A2F6472BF6A7AA3579093F23073967609C43193A96225D38D23EFCFB606123256286BCCD2267E84259F0647BD25630700FEC5CF323ACA818EFDF49EF16EC0DC889B95B1A92D405D3F61000D011764873BF9B7E52724F89FE34077A8ED7F51460C9F57B94817972072577955D5E351F5DBDE0A2E9B11867E945B77D8F201A53247A0E43B0E563A530B2AE435D2E5111830E715CCF30BB7BF79F49BC7FE0B20864EC29CD4AB99F941E69C878DD5CDA8EF609A4CA6CE7F9F4A3DB4DAA10523652A80A67F01D1459FE3B06E15E0AD1E47A2A407D08E43BCA48F9EB4003F082150D835BCC163A41AF165B2247A6496E6FC1D78C93AFF80B43F5F57AF80C34A762BFACA82601B494B3D07F2F50C0E57CC793F4BBE59ACBBF922508F1B51C0DA2EB19DE1A6E402383B293578E6A5B56F978BAE2F1427C9F2B5EAEA71C95F53AE4969D2E3155BAEE03D555D541DC13C888FB0DC5684C4AF0B5892C0E6E94C4FE0E0E21B6312B7668030A4379C80341FD73EC3016350545310EA8D7AA4549124124BEAA8FC9A0813AF6E8F6E53AE4ADAF63A8584EEDC745E425E98E5F569947D41DE2B5383DDCA8532D5B9F69C7F03F1A217AADE6F270FB8D716831DA980CE68CF5D2D98133E1A39D5C81EC09EB995DE2A140A25D3DFF8E4D3485D0938C98D077E44F5969A49DE13FD2A1E1651F724564EAB3FD1E2A0A6263225643422271CF424E955A818F508EB1C8FD8BC6C234DD052BE42C8715925C9AABBB960CB29499647BBE9CA2DD0E4FDE7C0BD08CBE8F58BD87217A92B31254B09659872874FCB83DD60488516BF038E0E19ACDB13C228BC45242779F90DF2B97BFCB2C6DE5C59FE38C9A868621A92407CA4CC7B76C7CAFFC5F85B30E0128173D65009406250060A294BC450000A0CBA3AFB8CCF29F756CA54354DE6F4D6119D8F45D98D39ABB751275C3639D3FE4597393616334B5C31483678A9D64A7D901F09C226FD3C91E72F750E360F9CD5D47CF91EEF6057EE1310E1DB779F85C25C1CB54F90AE5EE5BD4091C718917B484F3FD3A93F3FDFBFCB4E168F4F451C9E1F2221A32393E0CD7AC68C4C9DAAE72BE6F578B109BD7C4E63A325298444CFFA92364BCA52F51B2E3E4B50BA7DD949B5806A52761F3DB49B9AF581D3064BBDECE97296394DD190F97E71BCFC6B70D43FE8AC83F60B14D9C40FA9534D1175361EB15752E19874093D7925A5D98CE3D3CAFE09BBFEC5327EF4C966DC209AE042F64770961D86D5EB6A5762FC8D258BF0028487899C273085D1268A53C13708C6302A47472A437D70AE4FA192256AB6A3DFDE473E79B04CF0626164D8FB64AC1A8B5F7466A381873A9B9FE1A1CBEC3F3A158C082C1BEE363F34E834291DE4852BCE3090479CF382AD6BDB74980459A5226537B515D1BFD9061BD19ECE102BDFCC0D4DE522F684D66FFD5EB57398AD09B2F708FC13D71BC0E4B35D56BCC38D4D7CA46CBFCA0B00A7543EA3089AD02468892401C0645C80C200062DA044A28CDC9FC365E615CC1DE6AD98075CA67642484CBBF6194E9D3111B25FFBEAFECE9626A584D8E0F55348E2A26E516A7C77D45A50148EE63B2B5A6921C6219E296337EC8B0A02D36103C488F14A2979922331D60064FB773BA3182D2F5A7C1FC1C45CAA643FDDC89E757D7EDD86091DC177A8AF49CA66E145459E79759455F39AAF680366BC93F82B5F247A4B4A1D23DB885C2A159FB5D21EDA88A5807669A0407C4BB2D2415E411296FA67306FEF366E4C2FEA360AC3A875865BEC1998F73B9A8C671344F6488D7553131CC7F1D096C9997275A9106CE0DC68F43D1F43FE6B3702B9CEB162FF82265D853345F4D1045B3B79B1BE8905010A2503BF1320CDD54E902130166DDCD5AAFA3D82AFFEF63C43059FE9DA5704B347DC37A0C49BEDE6D40A3338FE471C1984E42287B27F9B8AD0A5EC9521D963C302765BD2FED71F46E73BF9EFE72F647FA73E1279530C0CEB72CA8EA0DA2F76693B61B822A89DD41177EA8DAAC6739CA9B9675E4563199AB440FDBBEC713048F04357BB634B95BBC1B31491AE58D8DB67A941DE0B2049F252F140C822946C59CF6745FEB3AFFECC4C0FADE11E2E5E073A2238543DD0A9D4F4DDAB8B4071EDBD79EA5E3263B11C18BDF7AF65E44CF7771BCD51B5A68B55A2A0D3475A7AC2F5AF6564E5BB062CE88F373F3878A2F709265E058B38B139D7978164B12A71F1778B7B02EAE7F6E1067E4BDD7F164F22F72EE532AA6AD7E27D630351180930AC1868E6E8B9C816A276B3B17D825C2A12742E55E3499517F346F1AEFC56B7AFE102124B8C6E3A25B02710F864602CCE3755EBD7A81CB690EA2EB9AE3A7260E3B8CCE9A08995ECF8DF20381B6468DDBF60FC0C493E62DB849198688C9380162CDD12A052EE832933ECBEA3D71EF9201F332D2C28A050287188FB49AAB78C317B9C93B8B662EA167E3D3B39ADAE145A8DDD9989D4B7853825028B874E3FD29A1D7BABF6F54DDC5DD673FBD80E41F9930090D66901B58D7338686CFC95B23601A0C9C2DBC6FAAB5AC17271879BFD9D7DFC42D882E47D02105277B812DA3CE3FC923D1EF54ED9EE71D4B597BC23614D69D66D41A3B38E0F1A563E3232E2AA0D5D88FE570805AB74D940AE7BF8479913BF134D7A9E5E5A9E375E260D0528AF4CECEFD00905C74C40D5D692CA412234FEC086688BBD0FFC0E0001CE668E62F392C7B61F33FD46C62EBB4563360F8116573389C29333CF1FA93910D28679B877CBF155A6988E379AF871C6DA8458AC9186FE45293DA0562432E7A0A02F1C7D37B30F9D54E6F726D15E41EC658E98A785A760CC8990B1A75E533F662CAD04E3C56D940EA821C2BCB43B304115AD6F2EA572CBC75CF69ABD4E1DDF0884596017DE71CA196C8F2D490D8436936A8C6EC42A623279B31A70746C665969D279A409E1CD399C3EE028D9F20993DD92D30E119F7CAA7DA749553315C11A00C45A5CE0153E98EAF9741435FA6BA21B8A23AE0CD4FFFDA171A665FA6B834243F6DE03F472F0400D6105D231B9B8D466FBAD43D06AE5D924638742317D8E883766A28D8E5D8F8094676E5185AAEC0BB4935A442BAAD3818EBCD83B6C7F7089CB2CEEB81391AB3BAC42000097D99A4FA3A430E19328FFE4DAEE33FFF38A2AECD39583D0A62DE44E5697F7390AF1A705908A8AD22B81345D7515E38FBD65A36C3174D4D7D63C3E266E47727D9E72F358A724CA49D0360E5FA8C21EA75D4AB28B2B2A53A3D85EB3DFBA55897ACE883790021D8E5F81AC1243AC8A1F45E72D3C205343A46B0E2F55AEDFF453EDA155D7CBB881932FE8124340EBC7BE4C25CE354B794595D8C816E3EE02F5BBE5A9D1F711A44BA44E85D8759EF6AF9031068380D6B5F9321D9B4DF549E128C8676A6AFE162A99BD1F6A5B8B8E668151AA36B0AA48879178E8EDFB0381B49EE55623C55DAF96D9D4A56517F6D2D0D4F1428654AE4B1B37C6A1F2A882BB403D8FF705FA664FAAB4589CBAF0455BA576581CE85E0E08B6E7F2B35A9A995D8627696CFE14C62F2BBE285A5C0E5D5139153FD30BF05BC24DEE2317ED15F59955AEB95B53FF09AB9E5283475CC1FE68DFEE9CBF34F38CC514E739C7A03EACAAE925D0A51AA7A86067A74D434353C5DB947D86153FB533C6F609D52600321D28DE2EB8BB643BD0CDF6666684BF37DFED10E9F14641021A9D9A798DB2873BC0D621A993A9C5D59991757220A1147F591042A11FA781A9252A112C883B1A037981D86FC1C2556962C39B7981289859BCFA6D931BF84B93BE333C5E5FD5736E660AB7141EB7B844784F32E7D07A190B20A36A351F1DB2125A6EA4E707E331CAC30DB2DE08596E7364AD1A54FCFC284B421F91D925B20F31041DFB4587075A9E01E46268DE8B76E1FB8E1B53C4FC11FC6E4BAE3F84AF9849E7A0C782731747084BC98B1997CB277E9AC568A26A1234FBBF2556A6F004D1A5ED724EEBEEA27D8D1F65525454296AABC645B76F03C62B8137E74D317FE2D1C1D69BCDA585CD7EF7E7F199F8974C86722691D323ED3A0463FD880B7C551D9E1515B16B61BB1699ACE3C460800F4511231AF46A7857727E312F3FE61FE0E336EA6B8D58677737BE34B74188C8306453AA64DC6DCBFCE0CF72EF7F83D8E18915218330152C4B4B4BD4F30F894F8D0E0CE8F5AC144101ABA4DCA8FA5092812994586A7EDF9533468A9FCFEB07075264BE631746F59E5F7EA42438C36CFDC9DC315BEC78BCC80C29611DCE6611C601C9BD1486852F4AF1E35F049CE0BDDDCAE167D0BDC27E428B50F7164236057E77D05BCD75CC2743DEEB109D1CFC737FAA3C78859BD145E3A672FACFACD1304050DE64DA2BEB048FFB1ED7AB66D61BE8B8A9BC7CE58BE2FA197A1E115F7DCDDDAB531E4675B3B45C7E8FA08C9ECFDC4D97D830746F70EA28293D356B2F72CEC2F4E93EA4BBFCD7898D251E7DC778F3A5110DE7EA531D8D74AD74058A492E508FAF2A54FCEB47259E3CAEFE2726935A29EF231608446A2149D9E012BD6C92C13DBB620753B4C8B3953C9BB80FBCD09671C9F7B0666826BB3B21DF3EC33D34A62BB6D212F1D25CB40D3F44C899A1C407CF289F3423FC3051B94F262DFF9AA4BF693AE95F185DA28ACA726244C609C8F900749B1174EE39786EFEBA73798F02FDF0E7008B197B88DF1AB172BEB4060EB912C31015551A3F941246F0239F782C9152B2F08FE5338C9D999F11AB70B5ECD5382AC06B19AEFD49506992C5ED2E78C6CAABC5972DC04AB6FC88F71CB0FEABE2D1089649E88A963073DAE265AF13C5087DD2A29F058386C32CCC25B27232AE516BF7E01191B0EDBE19D2D9CE73AE035B42D50B1B3C0EB6AEEDC6D0DA98374BC0C4D2563B2EFFEC6C0A2D92A28EBA35AD74F439BD4C0D571FEA17D9A6C8CF4E769FEDCB1FC29EE90F04C6E6FA5E1FCF0E34610985A65FD3BE70CA2A66F699E1BFC1826530C4D3AC46C1002D1D3BE114BE425E7C8B0F94981923EA02FE047EDE7297A254397137AC8ADB39EB80D29C934E490CA497BB57E230BD9854CC1E76D6614F895F749BCBAC42A43ED8987A7C2CDD0D3F97908C11149F16C2C5F0912BE4A1D690910AD4B67065D34212CC298169AE4CDACA7CF207619A1BE1DA8CEDE8DB44C04AB732E12A635E12633B1CEE9D9A6C13BF7B89B81F9FD89AE669F6413FA2EB82FC9E43D585F62C2AD7F911559D06BA190A9F9F8C5C053220D9962CD0417679509A1AC05C0F03EAADF7945F577EB3FBBC3322BDCD37B9F5EF09C5D313345EDAD63560DFA541A64A4A88C668BA54FF27BEE9B5B1D5A0CB83E5E501A706A1B89EE36EA87AD5C5A2161E67E1E2B9F4C6D9E7EA81008079536C53978D4F0786F972E94C1F3DEED917BFD09FB9FCEF3954EBD1937C9D6FC9DD0426A35A3070D2C5505EF901EF133B210E65AB6BF258464C3033167D38D2C3CC57B2205F4B44A7CE05C4DC81BC87CBBF2A63962751E9207445A8BF9369A91634FF3DD74CE38D199E8D2D5A0AFEC73BAA811DE63AC1BD01058125A92E3C5FAC51855DAD911578C45FB86114433FAEDAE8269B0499D21E43B49E93C253562448D29DAF6F3B4F9ADF154D77C1118A4D69B7D7921B8AE7D91356753EF9C3DDDDB66DB88ACD7BD5762A2697F0FEE4DCFA746D8CC5A4893BE09424DDEE2CACD8D9DFE2638FF3C5F6BB42247F4C19E8B601E8C97F503009388D91AC082273EF5E7766A8C9BC393A9C790BAD2BF3F607482774602335DF682D74B6EF3246880D5ED5CC6B62F37FB168BB7E5AD3AF8B640F624793722D1852DB3B6FB5582D47128A18D2A1744AAD5FAD048F6E102DDDCF7D1004E23D47FF7073BBD0A57E3FEC3E6C4AC7A5F51E8BD8ACE7570CF9AB35BA45E99D75605BBFAB1B847BE1497E98246B29C7B8D5C5DCDF7C1349C937C5B0F9BFABAEAD949238C7356DC7A6AF9AB8AE62144BBDBB2DC8FCA42AA6C311822C7823655F02459EAD4D01E18E801822CB9BF867DD04A181057B1509F3D48738CBFCB5A9F4FC5DEB3EF12E293B8F7BCAC74CDE51105594FE3EE563740F53DDF052EAC03F611184D5CC4DA199E0F11B027B0C3104775DB852E9720763795D098EADC5CDE2C88A158DBB63497031231273722C9F35305CB24A482C5AE508B8D0937637B109ACE70E40BA529D901FAB6EC618101572B6079C6002B13B4C8B229CCC0ADE1A17B1A08ECD16138F1C15AF86FFF9EA1EFD42653694C93B301F2EB34AAC1E0E3445D2DE4D88D6476DBB3C119B6A719699EF46C6492E1C69B486D421A82859200A90BC340A3351EA6FDE634AC842C34537A1E12251D90B4F1A47BF2BE8A3501CD4A4D1933C80A0875405D8BF43DC9F9FAC71C3EFA78B080F2AE9B873D5C47A7EBD937A9FAA2478427F29D2E489AF826D8BCB885CF122208FF1ACD5D9358EA584AFE4CEC8ED782CEFF7883D07D69AF6C7E1C2F15AC329EC13F83C6180BF941A8330A5FBA3BA1D1616160BEAF60AA394020C2DE4B5C9E8766109CE107D2E999EF10B290C73C63F6A6BB18129C99ACAB6AEE0F00770A8F377DA975B8383B301112D97580589F2723A493560E7C8EDF31E151D0734C96B9AA4897D2A07B6F75DDDC091303D38087C16C7411000788CC963318BE26D5CE7D09B61EAD51F3AC1DEFD030402EA09884BF0DF90A9D8D31F59B7C3C13CC6F96B7C2439C02C15B66D7F2050CC0EE987EC3E11C6EC7645DC3C7B9E80B989D29ADA58BB258BB76585E879B21548A972F5EE1D9FF19F9CD794D6AA24B140440DD176917085DD17275662F425A25F8EB311FE5616025B804E2A385E0BC8CD46664AA8D254C81161C1F5F17AA95E81435E9930FD1F086C976C2F5FD55523598D155008748D4669C3020220FFE6599C200155E3A504082EB8F7326F0A01B1E5DC3C4918A2ADCC0B7296D49375C26B096A2F4D920BC7103302945F923118761C9ED859F3E9AA93BE4E25F1C109AF65B7C75EE68B2836665089B19A87D5F0B7C210A87B7F28D443847A88E04D7EAA148C1372974A90EE939D858C027C381DF881CD50F03A493FEA306A3969638078496C3EB23FB811207CE9B604CA7D23F151A3D4CE6503602959742FADE97C6F132AE107460542473717A8B83D752F48EF3BAB54C6D9C36D304D779DB7577003BE14D3238CBA306A2EE6CD3DD8ABB871FD100311C535DA9FCA16540ACF60C6053AC0BAE6C8B1C82AAF7324CB064611C223260060607D09176881EAC14DD49445D25864B19DB370CAF5B3354CE3FEDF70AA05BCBDDE11B7880CE8C5BAE489F36749088A7C4A250CBB934E63E70C6AA23FDC6C7579D7D0BDBBB5E8BEF1DB90D540B4C025184AFCF9E039F3816B999D4522357E7CE89185E69CFB47856D5FDCA77F1222B92C934EA6DF9F9C823C6118E863974DEAAC6DD58C0D1BA42CD922BCE2BF639F7CAE2C1B891152EC0A586B66EA89709AE997B1398ACA41ECCCF39CEBB0EBAE7865F6FF6B5F9C0C0C6A337C6F5B5175F8B66C887128A846B98AA6790ACD7BA0F2B19C03ED4647F5F87E33331F201FD2FA835817CE506ECC134F8D10FFB749EF4BFEF2D772F84C38A8333E60F147438159E88D2D152008A0417B80040CEA0BA5AEF2CE2F096B2EB7A6B8BB34257F683F8FA3D1920FCCEA150565848353C22BAD73A6587F72900AE019A8C02E857BF6838028B692B23F9DC93DBB89150D559CAFCC0307EAE5E152EE8B25028E2816D51975A033E9F1D1BFD31AE5648C0819C53D63A156A8FF947597133C2B74D70A3D2B5CE0BCAF0FC3BC79058BB28412D552F5870898C4A5DA0EC7B2F244B5603747B3C2C3E64D6FF198BCB9054679023800992F0840317BECEFA8D8420B28A4071646902F81C8BF67F33A900972342C946D24518F26DBF8760149AAF30BF10BAD67A1655C20595EA77C326FE6B335CBDFFF613DFF9959770881C0CDDE007F2B0D81CFB2874AB21A051E35E6A8C9E5ACF02114AB768A07537664BF314127B55B9F0F6C1755E310F0678686AA5D9C49DDCA2208C5870D0A105DAA100058495128E06F724A25B43B98CC4B6B683823CA7BB7FF69C32F66BACF71E705ABA79B1777F4A1BF5E226F00A185BD888A35F39514AF16D0FDD0496EFE3E896AEFE92139AC70C13FC306954D4248507313DBF3BDB69BBD02B2C2720C0F01019647A373E80885F0C300E2A3CF5632EE3160B016AEA846AAE018BE8AC9B6CD05A601300440406375001EA5AA3090262050E8F2BEEC4F9ED5E62FB0505E1857EE60C18BA69D62D099D0A6AF5D2F34EA5BDE8578D97B04191ADA42523CF8E470D6F9EB677271C17258A7211AB35EC82E5D08B07E6B12E55EC029FA91F04584B89275FC35692B3520BE508F92CC73F0AB8B8EAB8F681B72D4983BC3C432B0BD98904D65088C040040BBAC48636C0461796E9710F1A1FC57DE62310E72D3309357C31349F000103F01255246DAEF44AFB04C7D152F7586ABE546E4BEA1C4296DEFB51689C37861C5804C1265D923D19240346A120004ACF9912EED371C067AEC3FB8C456046971B3FF377ED0CCF9E0DCC279778377D95B6C0CBC3E492E44A8353430C80E537E25B7D44067A542AA686D7FBC7DBDCA37A2836CD6BE5546492CF20B7DD89067DBDE1532B918730EFC2D39583476FEC33DBA5210984950DDA0F63111EE247E6DF366DB78424801FAA11B58228DE0BB0F50E34B3AB110485CF046A31C473473398A95FF622A79ED7F4E9ECEC0CFEF201C6B854AFBFDFD0C20A836BB8C14A7EB2F0BE02210DB78D90035EF0DCC1ECEB1FF7F9A24246E1096ED83FAF53B448EA496F7979352C2FBB5654056941F640850905688CE940EA00D2154CE9F7DCF2736B7AA4519FF0EF289A3750BF11C63EDCBC6A6FBD386CA01D7B6EE5E9B871C5DE93F7109A0F14BD8BA71F588F3CF82118B398566AA0DC90061A061D1BB6A50D4E41B51F47207F853D8FCA5D04AF8F57DF0784128B370206308E3384E2ABAEB75BF680CC37DC2087B232DEC5820CA10740FB23D7DE7548C989E692E784EEDD8BE35D85E1E7932D0EB751ADBCA3731DFE5726B6381928AD4F9F5002C1015495CB28D4B4FA0EE93A20469064E265157858B04732C0EAE7DD7942028E942AE73A1B8B6585093486CF2E3105610C0AF59561DD67CDD64954E0FFDF5CA851D717F2EB88BAAF92452E3AD797CEA3E2613BC1503625020DA39E617416F7DAB20534FFAC6AA36CCE980277E5B2254E5E1C365A1496681763778C41094B7F5098B77CF3D597DA3C068A44F08FA8E3A1E6D474732D2EF2DE20F58EC34A2EA468BF6DF482025A143BF6896E638DF185BF1C66E580AB80B5C803DABC0CF7C9EE42F17042486736D15207E19457FB0F0F0C1D97FF93291BFF01978B647E164BEB11F020D2B46DE86439D93F5B8D67FDBE7586E3B0B906E5A140C62795C6CA35706222803521ABE6F71D3AABE7F32942D6CCE1A66DD6E49798195A21F043C0913EC644D4AE9CD7AFC4E738A476FF9B0C272FB53848083A7BDCE66D62E0105544FC7C3D2A09479D07902B04FA671EE9801AEF8392CEB205B436025969E38D23006E5A6F2502C499F8FA05F19E495304BF5B31A0BB731FB20367A8DBFD827C1FCED8BA0AB40B6F54F24871FB85C3532BA455D912E8857F12BE6439167F52DA4003B2619743DF5BA24623B214DDF2C5C9C99B91B8FA963F7EFC6EB3F12DC1423EFEAAA365DBEE8A669330DCD97419EA6C6D76DC128C921A061C4FCC5331527748C236AF66DFBE3EC33365AAE4207783B6356677D3F15771F3CDA1AF85B513029201051E03216A2C52992EA6906F0AB753C48FEBB34C6201F812A2E9F31F8856C85C02720BA8003F08327808AE6150C1318017AFE292BAE463ED9315289E1099C4C6E52B0E7DA17DD7994747BAF0C94E70366713FB75BA34AE75836ECCE161D3586A306E4E2B580D0C75F797215ADDC4A601DEA6A5A1516179CA0836AFFE249B95DCC5872E475C6BE6F1DC954FD6EEF3A01C927BD48AD003C4704E99AB701072C5DB2B32284038DDAF46E771A6E41779C6C5B44EA3CB77B947489592CEED32307739033C0E929A04E2882C4FA4DAA26CFD6E0AF25CD68F15B62F1236181CDFD6C0E5A05530F1FFD14E0D6A0632E87BFE50593B9BF7F06B29807EDEA21B00994CDE801E681FE0707AD1898EB5DFBB1C1BFA0ED776927145A1C0EA336F99D4DA6BCB7E1B9FD74F72CD196317530CF02A52C57C4773BFD8FEFFA8EB7B5C1086984A3122EAA96C61B10FEAC760CDD0013B28560E1F2FBA2DD0AC805E9D61EFDFFB595415859FBCE668EC07F7D5F5109A04DEFE7E67394BBE39B1A4EEED5E5F9615AB97769241A02F2511343F2ABC361E65D6F9740F1D69E9AD43CEB463BB6AD8063E6D98C39E0C6305418FFF81D685787ECBAAB86D575A0B8A60B6DED2BA0DF529992BDC8B968B302B872B0FF61A520506CD11496D60FD57146E0972906C3019FD78307BD734F3A10C30F4DB2B35E245CA590AA54E69E238DB40EAC2B2B42479238BF0913CABC7E777797E492805955A746AA8CAEF6BD9B8573EA22C8487024D3F45F4D6C7DFCE67DB8D12ACAD3D6ACB099FEAA79E407FA52D615D57097909468BA44BAD746E61E23BC9704B85F1203D1A1A16A9F8D5F29AC3A92D0B2641FA0079615ADB32D145CD8BFEF10C182D49A4812C9505959FEAAA9045F9B7327AFD2BC0BEEE374E206F5A41488FE6AB2F45396315E32A08AC04875F1BA6081FF791B4980FAE637BBC0C924E4F24CB67BE49710A8ABC0FEC99067834D0FDC3BDD29AAEAB2EB09DABC58A37A02D2B3CD3E37DBE010AD3307F1F5CD738CD141A80CEDCF80C0C93A221F4D618C401FF78FE2097953DB368EE9FC3AB0272C06F90CD68FE9600A5E2A0048BFA319252F6889F9C5B81427A0399E0EEC662F0FDFCF3DFDCBF886CF2AC4A2DC01E203409F483CD1DB4670215B36F7FB770125C847EA053752EA9D6EC85B35E7378937116C026BCD910059F78544250841679B9F83E249EFE70B99727A59AE16D4601FF6783F7D8F912D3EE9A89B5407FAFF648B231857653A0B22E13B3EE7DB62042C1D0A459A27F797DF967DF1E21200D4F0FD705067E39EE0D8CF21EA4CE4487EA294DAAF811BB0DF4F3B450445EDA651CDB335A1CD7283FA95271D2DF809DE120109CCAF7A393C1A14C50493F7A169F917EFC4F3342D667AE5F15DD5133A1FEE56DB1750082F90DD4BAF4D35D8AEC2155AEEF41DB0825DF0BB1B25252FD0BB77E1C2646BF705C4849416BE672BD58ADDE37F0D78BF8CE89B7F947083FF7A1AF1CC74041FACFB5EB310D61153D26EBE9487E6421E2CD7F24E74802CEA67CDFAC324BC611762A2B212AE0966A0240873D4B438C3252D79406290AED339563CD4F046B862347ADCA63634EA94A9033885A04B03251474BE20426443D8C4ED52B955F2DED932F39903378F341268A17263855733982F1B096C357016B6110C58A303D84939578A014F58731658536658538C6FB76D8A0CD6DA1FF6B00DF6B0D595329D0023E6FD60DDF1E8F94E55F08DE68714FC31F6E445691EF57294F1788184170D188F5B3DF29F8D023C40EBDDB7F3F19F3F4C432F249FEC5384D3978AB2A85C2B01F45EB77487EFADBFD4D6BE59514CE1832031C0D6AC12A0B59718F62AE899E33751C685778D28DEBAF2B5CD5E22561CD1123BD5DAE59A21C0FEE54F8B19D6773BCA9629161AA503ED7F42D466EC77E1317754BD4248621E1573052234E1628E084110343915631055B6493C6F53BF716CEFFA6B01765E16A8DE933EA386519E9347248DFD59A0CDEB46CF23FCF1EC7ABFC23BE9A7E2DB7240C76E047FFCCF44485419540AA3F7F6D8EDFF1CBB8179AF67F9C0C770D14B40B3155C2A27D7C29DDE829ED45120C5D06E792245EC4377966B29877F532D2A697EB0972155A9BE56BBC768FE49301806B2FDF648BF50284ABC67F7487E464A3C3A46BFAA23BEFA046C286CA7A584AB6C04F84104EA1D3C7F2AB8BACF8FAC010FE7DE050A8E0A2152FC02A4F2D7CBD2EAAEC4A454DAF7638581AEA482AA7D975DDEE69FC604A214545818988F2FC80B3402E5FD4CF0556ED5131DE00160CE60700F096A882EA67ED9B5836A529AD93DDE5527D9E1746E018693FE68BF79DC94CD05C38BFD09687948FBA7FA9CD1F10E0EBE3672546E8D2FFCE861A5716D0F77A50D829AF5988BA2963CDCFA5C485FCEA9BC423BBBC9D3F0A436C9979CEB811AFB171A18D9EA6B7EE8387EB15EBA628B5E7A19FFC882953720523270EBEE9876B95D6EE5D1EC8889FC9D44ABDEFF336E5393A72441B000A105E175DD5FAA9C2F65290F194B0978B7C03DFEDFC2F3EF662256F458B323289FA02494B2DA9C1202119308E19AA4509F8D4412A6A74BFEA5D7B753EC923378ABB6E1F943E150BE742104BA009977A6F57A84CCF474BC90251172E7CC1C69CE55AEDF028E1CD9D9DDBEB52886413DA35D0B9CB29C07FF9C99C02F036620B0A9010B02946753E2C5BF1934C2E8DDE27571BC906A7B6B36BD98115CB30D006E276D14931AAE76909F3E8F0ADFE077CF59A7F95542E0700660970180A86098903CD63E3EBF4A493ED0F953CCF7D6A54056C186EBA855E63A6C7EE74B99C817495F69CD457DDFFAC5AC6D6B3C46495873045D589344B5F81F3ED81DF35FACB195138131BC28A6E69EF1BC4E5B4006955141C03FB4607CF96BE7DA2AE5CFD33146A8990A4009A175FAE3FE15FA50103504D2B6A302FDFF84AEF441A703E75D6553410408FA440BA093D597CC84DDB53E68ECEFFBEDD69AD9A53E082AA205D0467EC266E260A26259FA140FD4420B81C9A46E9E9EEA86EF71E9270AD0390D80BEFEFEA2BFD05EAB4F809133A22AABA21743FFC0EFCB83310D0A568BA1289D607FFFCD58F5F8E5FF199AAD882563ECC47E2EC57791DDFA6FF44162DA26842D2B2B9F3ED389E5F725F56ED5143BE734ABDC5B35B9403B19BFAC75BDE227A7084D90E2DF17369A6B3D26F97B0EF742044896D224051120B7771276807D0E94632CD194FCF5F88B89CFE1FD67751092AFE1653FA3435EFAFD46B58D5DF22FE28D2C50B6B38037F86258A423D001648F623F70D84D2416C94555E91E369C1EBF3C391305258424F1A0B093AAF963E693FF5D2CB53D48D436E5776F4E4FEFC3B7FAF7C68CA93ED7297C283A1DF438C20128093E5D10A6B0511D42EAA998C57AD6BBE67B2337C2A4E63B05BE8C7009A5990DC223349655A8E732557A91A8D65CA217178FBB860406310A5B79A6DE5870074354548E35E6A31A7242533B444F20707479DFA0AA74C8FB2D944D8426C782FE04A4C877876DAE0C9A714A5BFE5E740428A222721D55443E60DF6393FB67EACB84D51F45D1E49F70227936EEF3344E6199E0485B589761371C0371026B5231246FFDC92B589EF9FA16C1BAEAA8603BE6F2C3CC2A9884249C75D7ACD571A204E8496FB50754FB67D2D648AB1FBE452F8368DD322769575AD5E649D0F6E1D13FD6B083B3AC99C40071B3052B0C4E509EE7EAA8C8E4421D5E35C88FDAEEF27681D5E431ABFA1A4387FF142D7C2607E22252A3AB8B4DB7CF9AAA572DB0897AE9ADFD8EB50B5AC1F5C72ED7899D94992F6BE7997665A7A0096A629FED9B35246F80B50EBEFF25E58F104856F4AE0A81C0B066979CFC5544518C600E2A4908C1E041FC8D96BACAE76FBE1B79290FE8EF6F4062D58DB441AC0F48148CD569BAA73F1E7B5082451EBB5615829EFB8BEEF82A8A35066426766FDE81C4E7C5A6D40C4F2D2EFA5D651737F7C14E6DE855DAA53E22FAEFF990130640A84A388461C84208255668CA875B1B1F7E2A70FBB63AE9C5783830CC05ABBAFA02F93699258DD197980A01D4E6DA014165CC99D742E90F04F22326C50538AFAB52485E7CD0D6D4FFAB950D46E7129EACEF7FA72F054DC59481E0594293561E52B9D3DE729955F4AA03A6BE76C47F7DA4162F8F8C02378762C93A005608E6106088E4A52E1EC5163F0C4DB594FF6B3C6D141A56B2798FE6CC4FB1129D87F3428FF713DD6362E7025CD39FF838F00B987EED4F7F377B16047CDADA0D266BCBCD21C2A5C6C6A47E5C52A090875995724A99FFCF93BD0B4EC705076BD40F948125748214E5F2F65AA32D52F9A406CEB306304D2394F73F21B5EBAB2E7766414792DD721D201B59B88AB50C8D4688D0098530809C645AA4B2FDE9A71F39E930B70CE52F5A05699C20688D0368BB3520AF8C3A40CC18D0492713F3D06FC6D21C8B3F131E83FA67BDCF6D3AE5CB57BAFF4BD54819037F428D0B4252EF84BE62F7C2FCA990857600553930D284061C9B344FCBE848FF902633750A44A2BFE5A8EDDEAC29BB05C53E1A3C1B8FB6A8121AF10907A6C9F21CAE638BD845BE958DCE77BD1E3C9AA4EF77BA1651DBDE42A7401F1412D741D1EB84A99F82B5F7FB0DE96E0C11918D1DB3737F07C27DBA6B306A148E46D57633E83FFC1D7A1F85A1B8716F0102813F43F1527F3B2854914E053D315BBD3FA9205F8206678F4D1F55FEE5B941015C76186AA2411495A6AE356D1C43DB1C510ED7F3778D68A14061C001B8D82705F2E9BA76677E8A3D44318EB5573C07C506FF37F4785996DC8FDAFD7956F0D699A3D7D521EF781FCD5C8F56D55B4AA390113D1590DA1EB470CE0B5D9B9A77ABFB3F7AE8C3BD55C2E2D37FED0307953E594AB78B9DD2F1803096D49BF5A4F3A386A8E8056FD9EFA483D49CEE843C1272D7F7F13590B5E9AA2DDC45242B8376D7EC8AF4649A7C6238B5D8742959A5620D5E2D64D741D4C552244BA3E041DE33F0BC561315127F29501D091C63130D6C744BF5A9948C5A89B0A035BCBD0DD57C92BFF0B043095C18B2CA7544793004FE3ED9EB00E88DDAA9074369B419FDCD6381803B5CE707DB55939E4BEC66E551B60C37F2DF77B1548BEDEF8B2BFBE2388C87D96F2A700B15D66BAD07EBB053F8CF4B03FD5D5D2BC713CAD23DC2A77E0A1DF070C227667FDB7B9CC653FB7D0D9BC0238FF602D27DE5E5246B4F6F26BFA93E50AB74D1D0373D005E68F8E49314CD73AE896234C87D1A2741B6556DB5DC62A822C6D0BC7337AFC6E79C1ACF15F30E39F943117A5821B64F5C8960B6D442185386F104A07A45F517349A95FF274041AA253987538E684EA535CA96710EF694348B1023625C1B284C212ADBECD72274A5022A7F8641651E93C632688760311F3F81136544A40B3B4060FB6A24D6699DEBD7FF989768AA4D79593367CD61A2DEBE5E8C096745701F053710A05A183F29B560E1E7E5FEAB3DBFAAF1AA714D7F496C3E84B885591D97E79079098C2F9980BFA36B06834A9F851C5D44315353003F558BC4DC7CCBF71301801C421CA57CD1D255606EE56688BA013127037EC81D6158FD7DA65D1263D279AB30452ACEECD84C033BB0FCB0EF0959965118FA7A522D5FF5E7677CE72F5FF74CE2E938E1E04F20530724EAC0E03D0858511AB289D199745D1869FB50C2F6300DB7197BBB4DAE49923C988E473A5CCE15971341E794C7B394BFB081441AA41330124147A023D291364B2E4045C8C7F98F3DC8EA6AC83BE838D9F0BC8860A84E104BBD9D64CCA1B7D03D7FE3F9CE180CEDFA1F6AE43C0690FA9BA5A83FCC02714EB55174B57061F0465B7E478D67D0462D9E61F344F2F10F3D3AD567816C7AB2209F9D2303414B0734A0F307B8388A550AEFB48D5372FD019AF270FD27C160208570904368CD690402A10ED9821E6BB8EA90A0C76E8D10C0D44EE656B776E48E628AB8FFC5E07F15FB97642353FB29F15D84BBA74D70BF29A5F93D2C2FFE6533A63C737173CB58D8DB23FE63520102444FDB648BCBA6416EB5E29943F55A9B601D95AA5EF11DC72659E9269439EBF49B1938221DA2B2F74EC37BB308476C415815F28A7CC8780F06FBB1C6572F2E0300887B361FAD02F1C6104BA9FA1CFFF23388600F007AAC0A04802257383241420FD2E736464DE21B01B1A84B2CED1207C387F838101DBABAA278517CF8D8975866473D0E451E4BD04CDDE10CFC92427033D77ECDBFFDE8F9230AAFC0759E48871E62804EC30A63CFA9E17B1187C3A410FABBB554AF293D3C907E633CC480AFFD089FD00ADF91182E14C3B9780C023F56726CF12A50FAB273E86DED2CAB143E7FCC99F38C7E41B25066549CE91E531D7174A4C9CAAB1E2DACA4F085D7CBDDADCA23BC84D9CD88778E1490A199A07B98B0144CE2F03A10A3B6564719B76B0A88FE5D4D4D526DDE9ED80CAFD479FF741E0391F4FA4637019D159B6E482B67DAFA0E1E7C2C223A195DF6E582DF8CDFA9D3148086FBF93C7B1BF4877FE84908E28B7B495D1C74D3B626B38A4D2F97C3F9A7162DEBDAA667AAC627F84F178605A65CE9D4C3A62B9EFA062CF6C1D56E972A4E44116981D402678174CCB7020C67E316284D14AB1D46E9DF57C09B328767F1D620CF5D85193A183262F3EFFC734B62AB40D6BE05873A27824B1A5E9671A3C606FE4F55ED0B11D7B793DF8C4C701EA48B1C7E342AC140A34B76C33B29AD25B74A912B6F045A360E85DACB05B02217BD480F4D657BAF3D2D40EEFCAF16F5500DEFB3DE1F08A44EF12F83AD29E79B99A9431CA2562AE4237D1766A0F873F0DBCB789201BB6809E8BABB3C5789CBE48ABFC1B162EAB806626007052ECE4F64E21688CAAC0F1D4244C1F4960AA1347EE12222F558F56E65FB48ADB7109667A88FD2696996F49A17115C2561D8688345DDAB274831F718F699E3CF714B6913FEEAA971E1246883A65F49B41E3F981E9A0CACD6FDB3FEFC553B3EF8FE3C85B8C0DF924353D0DCB25C97BA44F5AB54C527540A5C542E2430FEBEF2EF46B25BD70B5F94A7179E01E0810EE4E720A515CE93EC8BEACC678D1DD069A17E261D84C22EB72609584FF9B7018358BC098179C9D3C139725890C86BA1FD1180393809818A08ED47B482EB2FD2305421B4479BD4E7C46F9AAE95945D98B9125B9A2AEC8EACB19CB38DFCB4720090115B3B3CEAE10E47171A0A5D00637023D15EA81998DE7F8BA84AD72942B652075969DC010734839A2E2AC513381995B5D3D0666CD1D912D715DD8C2FA47F766130AB4E8CF704A5FD42FD70F27417E4D30FF5644F85C400E6C06E48D40519207EE1B33932B00320FB170B9E193456B30BE2D6FB93AE6C1436D831C2253172D4BC11566E736E8471A71D241FC15F347EC422F6120FA59D7CBDA84E444AA2F7E1421E28D29FA3D522731B17848B981E27AD76DE24E00C29B00517B8A57A99BC9836DA755D5DFFDF1EA865613343ADCF4E48FF609E66F1ACACC74ED0DC745B712EBD350C427CE1101B8222435C448662D81121D31AD161C5945992878216F7A60BA801197D3745407F254C1FDFAFC5680DBF6EF6D624CC3A538A4BD9946C6AD2164B08B0471CC034169CD0546CDDCFF32AB46CF04C9F9AD46D8A1D56A6EA5DEC41DDEB1828677FAC61488CC1CB40932880F21EAD976F2EB9D60DD4FB3A993CE0FFB6FE588EFE59CE78CBFAF28CF38A97B46BD1B6853B4D9596E88DF0B0ABD45A2E7661264635DF4707DE4CC18E3B905F660CB16D9C89ADE0E7C27140BC68D2FD7086EE93DF8E2B50265DA4D7FD1FB610A5E257B10D32D524BA821F69654BDC28FA8403EE0072A672B8830BC8E148CFD5F9EC773A1B7EC7F61BAB389EAAAC0A60C97752F3969ED417612FBFBAD4C13F1D86C8D097B5EA0482402D43B2651DBB66199E48E75B6525212A8F88147B162A508D7B56A57CE871CD351AB531B33242B4D09FC2AEFFEEA6C532BCE75CAEFF9E91DE2A86F77B0ED08C06B5A78C225C08C5086B3293D44CDB64527F18FD2FB80ABA6985C815E71E1F1046C38A7AD317E9929FB8A04A028660A6994D008BB4CF667E9318FFDC997FFADF4308501987F81286798DC600EB198D49301E5C908E4E17A0642E13201D5005FA48C9C806F04548328E529CA8026C51F690D8697D76CB7F99B5162D722F5C3A957254A83DB89094E9E03C6C4548648E463AB0B19A92B7293301E7719D9845DDE491CF5E5D6FE823FA4D0C1605F600EF206F87D634FD21A77D4273EC85337019F8535114C7BFDC8B2AEC47717450B9185B9A1BDE7565E2CBAB4794B817936ADCB78C859F7195689A8DA611F236984EEF93694F0504D767BA1E44EE512D592744ED4598779E92A71523B04471D94143FA154DB307C658F2DDC590BF15DE5941CCA5B7773E23078779C0390BF8883B59CFCCEBDD22367FFEE0A254FEF231672965B05F83294F3B0C39BC2800350099EA89E3D9F6F1C47059D34959DDE3371FFD2419758C2611C895A4206214A234D8A0F0ED35D01F4D1AE36AB6A563E1573343275F6FCFAEECBB4426BF2E633A908AFAF905AAD328FF98C1E4D1E862D6C7FEEA8718E306F3AE8A5B8AAF8818A7063E922592911743B0F597E5F4D673FFB4A85D3D907010AE08E3015EA5A6B876A588B8522CF2417A1BB35429049F888E31BEEC547FAB0B817303E9F8E968A14950C159E361274E2AD5C02DCA0BA22100EFF281033E58196A1A656EE58D0C7AE8D3EC58D5F5737D5C143CDACDE30AD3872A1CF2C88F2FA0056D1E702CC87839CE1A90EC97159F9549BC9A67846AC15EAAF9D672FFA12BC95CB8B5A44177125093FBD6A124949684524A470EE5E28450C88DAE0D9A6E76BBAB3AC023E0316209A4B129860A90AE938D857B6EF89665C3174F5AF53A50F8FB3AA0EFCC64946B09630E56593A01932339AE0BF2C0CCEDC710A1FD6D00BDAFC16D87CB12F67D7792D1D49D098375AF347D3CF2E298E942A140D13E83145B6012092F7EBB94CEC08258667E572D4C39542527925CF95DE301A733DAA32DB358F5701A4AC8D1507EEB3E60B7F75377D5B1B159190860C3DF3D9E79D18DD9CB9C88D1297F874705D69F9DC8109978E30DD54790BADCBFDEE144B1E85E7BBBFF3DFD255004AA5DBCE91F114D02F0508358BF2C23D06679578768B5351C0E8D4801C5297E069FB0B90A4753CB1AF73B70CAD60EAB2CD3DC1C97292D35F95DF093F2401E21336C93C9D71BD15A368CFE8A0D593CA1138C36DFCF757E7114B7F283754553F70F08CB0F496FB349A7AC51AB92F926D0C1D221EC6E04DE5306501FBEE76F5BA073CC2ACC69543F2F0F77B3F0F88DB0CDDFBF5EC905596306298D94EF181D012C6451E735B7D4BBE3704386A9A51ECEF9DF19C5395FE3CE63FEA89C10C620A8E480C84485569143261C75EB39872F363390CCC4270F6620C64D87692C6D25D8F479A5670FCF173DB680F17507994521A0FFF937559F53FAEBE0D67405B10A78CCCEBE199D76A106FAAD0D9BDCBA71B1DBB857D3156F3850D87C3736491F7ECC459AD2148FA3916FB7BB00BA8F76ABFDAF1AAFD10AA39A84035F64D120A1A9FC4715BDD1565EE3156392062AD9EF22EEB321ECFA3A150D930A03995EAC9B42BED5759CFD72844B1AFF99E6F627BA1ADD131AF2B333412D19964DEC801947A71B3966E651E8F1910ED10FD18199D8041AC7C85F834C5EA2727231996844E58A0BD8FD1819E56D2E08D742B9AA354DF6744AB5CBF1A499FA3CDA0B3F9BF6C98A55EE88EB1931C32D491CF98ED16DEAA6745C98F4F1A012ABBE711E55D6BE08039277E23BA1C76BE2A9C3BA72ED5075D6E1F3E8A258013616868B794E14DE8B7B266EBA20875E2AC8F63B3A4F6DAF52A39DD6FA9E530638ACB4E918BDB6DF949220E5F26CEBD71059996A4DBFEF83B0F7ADC9FFD6581BDE405F5E301C61298FB8E38C345F7D57CD3ECE1A9AB7B2FE9BCFFE50067303490490460E048946FF1B008110631E1CCF302640B6B8C4886C1931DE56A77ABF7D75F77A355CD366A4D5D264F8638E1E00E606C0FDCF1B15B5D879A090F667B55E3D64FA30EF24EB0CA062C3199CAD4ACC080E7FD74B49DDD05D995EAD9C0C9F2E50D7341E49D89A3DE23E7089EF7FA78AF86A12F8D4793A86BC73BF673A1953F998C666E370193B4B7E633CDF3F5D329EAD858C311EDCC21CF40773B5EC490BCD594B367ED45551856BACDB1B77BAA77F94FADA93A7FEDF52CEAE921F27C5B029AD73D15651B1B02B6F4007FAFF78CB6B0F664FB4F69929CA4B0A055CE4CCDF43BF8AB2548AE573A85CEDB619DF7E2DC029F5E8A98B03A2CADE382494D237BEFEC5B3AAABE64CBEC1EA9839B5FB89A5D949ACEF5A9D53E692757B262D7970F7C8FEF7B5DFA8BC9755E564C46DDCAE37B095E44A13A12530778D0E82F2D77850A5EE6A203D7CFBB9B2DF60B577AF51D2D6647179C59FF7CA947AC73C7F2A103292FCD9889A01BEC34441D8EBB2D84E9515456EC14F7CD0777672F42C67914F3771EC5FA084B1030E5EB7C92A4904FBB59C03E832961200E90F3D67B82E00DB531B78063C3D7828A3F53FB10EC1A5322E2529C477DFBA2540919997FD25A24402F172FF20DFF4E2AF4669C1C5914F274DE2FE4EFF225F50BC295D7AFB61FEA7AA8621949C73E82186658FFB21BEF1CC7DC06A3012AF726144F0F1F3E1C8C32CDB72CFC11DFCB9AAA3424C9B8FAF325744198668E52C7643A18D465F71C7F35E97A0E017A6EB4C9D4B643DA211E6166405405DCBDDBFFE86C17AE79A0CA88E3E648146D8C4E872DF306ADD637EB045FE8661E1E874CE95C8B56E234BC9BD57FF8BEB608E7B6C9C5AB508CA472BEF6F5FF302152BFAA5E1FDE15F2ADC7EFB9D891B5CA796137C8CBF82FEF19D7282A0BCCC5086891BE45ADE2678FE4EE6B7E23200843DB61B006ACA93B3245C3EACB9CDC10664EE4E598401B4417A155B19593DA411200900FA583B12A0B59CA50E720034DDB533002075681A11803A533B2F0064EE6F198F03986016E94D0022A45D225009CCFCA775026967AFA4535E3993D8A3CB1B57A9D3E17003B2C9B29DBB87474D6451C4433C2E0273CBE8DB12D32C28A0CBEBE2F61AFEAED2288A724347BAEBFFF96F6264800790D4639EAF7BA1227258953147100C0B9F2714B888FCB734171F76F08E3865A2A2450FFD3ED0C6FB576FCDC06C9FC19475DEADD1F38FC77123F06379354F766A25A0E872B35D612544E1A972D7BBEE6D41D825126E800022C4A0CC84EDC178F8DAFA2E2F81A1B11B0CB25BAF720DE508D882D7057B7BF9817A1E36C9ADDE76CBCA2B859FCBCDE77B3F5CE271D99E9A8A1F9B54DB7A5FE6B38964C0E7BC2FAAA56F6C38A7F2202E0FF22681702B6D21874FD8FBBEA2C0783BAFF73DD7ADAAB54C547B4124F40CD8B6F2802C2C57AE7C22EFF28B8F5021E0A2506C95A9413E30F98E87851F67813F16EED9259A75231EAF7DE3AAE54F7C405A46AC693D2FE59F94357B906EDC3B9FC3B86C633B7BD2E2970F8D89B348237A1D206BE3534C0B07A852C833E1017047EDF7D927F60787175961FF4B34DBFF5F96F4A2AB8224235AB200FB9B339429EBC6C4FE4060A51BB1747459D6A9066F50EC034281813D230767BEFEE8B96A5A59660E67B6221094C2F569643614291ADA36A183F9EDA69C3DA96F529A5C9EDFC3DAC48E35C61BD148EBEB1B6CFE5865615CE888FAC04D0ADDB29EAB601BB4B7AE0576352B5AB46695BFA4210FC1E3C1F3A697A40B34F5E66AB259E77D92E91255F2FF1F05BD06EE4ED47559C53EEC7314AC3A9DCB7A7E825BF3DFB8B3269E91E912D99C3F977D92C943FA399A0911D5BA5D03768C0BAE207DA71C64CCF561D60B8E4C518E04B9BA8C3A1FDD153B9DF1E45617EB53F60531E6CB8EA2AB7FF32C2101E513954045EFE7A7E89C3EE15DEA112AE1506354E95B3A09771B675601F1467C1D406032B711B0E268644C2D27E7002ABEA7B51C7142905FAB10B3664895B526BFD88F7827712D26FB631CCCA0DD3F8DE23CAF1860E594415250A06E0A2E4311E6E118D0FF6732CA599F7E4AD9A21BD430BA13643747949145B1A5001563322C2B5DEED473898FBC055936B683E491A43AFE3CDF99E31EE1B4C1141510035225548DCC4C176A2D0AABECCFC206D2AD3EC8B5830DBDDBB7E0432120E561AB13C747F68F8CA57C6C5513FF81E4D8CA85E36157E420873B889A3495B785DCA4081F04B7CAB9741498B73B4C7A9D0EC32E07422473B548F4D1AC4CB917C4334C448B5AB69A3FF11B054486412200D9F7656D1B394BF3B139B2D29409911DB3D3BE03306E93A06828894041CE38A10B30F2939626914745149D13C56F4449325105C2D402C4681285930E1BBC603E61844E4BA2A979E6C52665E41B1D88EEC7834BF8D52A0853478DFB96DF7DFC83BA583A31D055A9C12AE70D43339C241453B5F5926826AAD0AECFB29BF6464310CFE8F652292B72638466E75FAFD6FD068984A2E327F5926A39B96E823A3C05CC1524C5CB01D041ABCBA0F08F3464043A37EAAC65CD0E792C8E74A0B6104858EA6D54F3E67FC1519EEC3BD33305B8BD6CC8572950022FB5E08A1258B86D514C28E69F78E6426ECE82357D684539FE0E19A2E482A3A114D1B91CBDB2D9ADA16D52703F52BAF2585DE8DC80829CCADE60599A24069FB5D5CC8AA4420FDC2C0B8420EC79A33F65B7146D6E0F7FBF5CAF7CC1263FF775270709AA365609B5552DF11C34701D011BA31159CA3CC3E3B83253AEB77CA1343C168145B69D9E68617D68E7FFDCB70664EC19E91231433D2F24446EB6EEDD44FC380CD8CBA33CE23695B143E69C09FADFDEB98C2CF535218A153C3CEEFA5118AD121E0B89224D5C48DD8313AE8216A462670AD0ACF1EEE645B4149B9E59032FC11EBE4E38D8F901255EF3BE40480F003A6EE7DF24BA96A274551445DF11FC7771C61C97B91E75455B8C966B82CF9190051ADE266EE1113B9FA4C0169D58AB422B132DBAFBD7E1377EB6B0C93F29EE7940684F37824A36C36E63E8788A49CE3595EEC3E5F439799C360B8D5AE9CF4794377EDBFC41604979E63D4FB8735D1BB7D408C7786CFADE1F083C13AC40CFCDAE889F2AED92B4FE1C20EC70FA9565D2C198E82C980D23C3D1A401BA962DAC58C30CE16D0C2E206510D59FF5ACD93B7797F7F59CAA8F9F34BD7E4405C34072572DC2D506E132353ACA3FABC55E4FB55C9C3F1873D4868AC4E63900DBBCB184A3EF89E1FF7C1FB0EE39758847CB38720A7CD3BE83CE1115EA654D801DD7FF554BDD29717DFE4B7CA7730645A0C5BE1FA8E0BD6DF5890A11CCDE07410AC08C4E2953F8D7E2D4D902BB3869C3DB0E90E6D57C86D54512DC8CC42C365793416ABEDBEBABCE7A9CC27FB92CF209598F5C5D049320C21C10BBB5D34EEF88F3090AF21C8978DAB4F51B0DEAC1A518976B4CD3B0863F95B8BA691964B3DECAAD7C82C9283B1742C228BEAB557FB9C558ED6584913E94E80066FBE53FDE68C32B77682BA4541FA7B982F7EA6FEF674F707B38729F9BCA56AA70B78D5098FC898736795D1B4A5D3211BDBE3BD2607D9E21F8C0588C6F4D78EA415C121D9F78D19B89B07282B9ABF217FC899CC1850AA0441A6ABB9E0F1C3E40AED14A625A28C401CA52B0550DF03EE06EEACDE2F2A187662577F7A466F2EED0CA17F887E207B986D2BA4C3E45AD1E310A10F9E7B17CD8578818223547BF32A89A2861FEE5BC7C63FB94C3C54D5DC72CB0036A2623BDEE70FD0B5951CD6A6972D0EEEED245C5928EAD205F96AC5E1C765BE6A7D851B1A1D9036AFF05AB55CF1A89BA370832D27A711AAC5351E73D600315FB4C63232FE8154840E8D1B6A83726C0281703C3BF1F2684A4C5C6FA49DAD8B501AA911C8CA1A14BD207E8BD820AA1533366B802077A3A5442C3EE83A804C2CFF851566490B68AB0F71F0DDF2D2D36B9C330DFCC9D12559D0CACC884F672804E4FD06F629BA9D7E2D7AB8341E3D6F43085FB4D90FE4D05BC3D5CE63D3DA7F20095E490AB558B74B518DC54FD9C1D84D01E565B6FB4E80AF948E6CC6F57602210848342757A2234681398CB4DBE1C13E5FC649EA0C6B820A66054DB1BBE73BFE88FCAF47A82C22A82F47EF60F022C558A555357214B127CF571ADA632BB0740D481FA72B8E850D3FCF661BC0DDBE65495C6D385ACAC2E3DD7D11706172F298993824CFA6185C82191963D4BA89B64BE36BF2124B39EA98FB56E12ED4016A51AA40AB61A567AC7B6FFDB5581654213C8AC692D9EDD321529B4DBA4294DEAD0945748DF077917E9E63C60FE92E0CD60A7C5FE3BAAC2EA39E6382D43F23CFA0A8CF5C59C7139D02B7BB5DE24B97D9F1C193959193348907B73CD1784B3E8AECEDE361596E67FCB67EC5DF0B7CFC188CECDF6A74A9DE5018E45FDFED91F7D692253E9C9B396B0FBFA59FEF4336BC7EBDF55A5BF477F277E61F6AC32EAF551C39DBC3207A7BA741E34C5A8F984D7C7A2E222170D20431F598907664D08EC50BAD3011EB73F27FA0DE2B90A41F476E222D498C48951CAAABFD0E3158AB9160A888A3710FA8F32DC2871559DC6033C73BDBA57214C155D7AB0EAD914E42039667E558D180E68C8E9F37F8E30D2B6B9F938D863855F563169A9E5522E781ADCF33F5850229A81144DCC03FD916AD8D2F6491EC721A84DC1333B2347B9638A9AC79636DCE89BC925CF1597DA624FD18920685D6FD3FB7956D102234150031534A20341AFA5DFD694945A9000F437E06B84D3569846C764E3497DE47C7C9F3458DB3DF4850E7E88F8CF08FC788A14C86A136E67E0726351D02ADBDDDBD3207C47DDAC8362BD088FFB4173A06F6F5948C718DF704DD85FB24390E796A9D62B655B18C94BA11DF6E8FF19215AFDC0AFB57406CF6B0AF419A027B182F264835AEA411DED7C5C30E4A96A96B656C30FA3229E1DF5AA901C7299DB2F8BB89BDBDD1DDD1238D3D7648FABDB85A17D1A3FDBB763AC6C3E408E1331CC2485EDBFDF0F4086A0B91D9DEF1EF3E1D9D68930BAD32939B6849B3E4537B0E701C667004A5A8331FA704DD71F1219B14AC8C9EB9149FB5EBA286E1FA345771E3D76C75D58D016B2A9AE118A0E94E4F4576FA461BA05C31964E42A72C6078A837620B58846D1FA5EE8F7DFA3623862ACB9B0BF7E36FB5F48E503F403CDA81D2B4CF36FD58E92DD4907C3538ED912BC5045650090C5811BE322D3CF4342D3EE3498150A45596090185C258E2EC3D6FA08D2FC360231BEE139407FC768BB748898975141AFA3424461154DFEDC53DABAE065CF60CD2E1ADD4D70E0015FF122D07F3FF0F8B0F4569142FC425285B44CCF209858D837F0EA6038F4C5D7234659247FBE8AB5E954153526BCC6C33BA0B1B425C53DE556EB9ACE5D311350C3E5F301360E2295E52810C98275D5D6DAD9AA8B58D92E32FF53B94DE3BB75BD4175471728ECC166F67552706F530D598BF65740B9C6F29734421D123FA2EE96AEE26C4937C0E8B654C1FDF3D0B68662F6E6064820F757C5847743E2C5933F84C7DD41153EF54110EA3A82554EF76E8B8D4C62FC5E8C3557F4BF573EBBBAF4DBB99B28CC327590F4F5AE869BCD799970FFF328065A430EA6700C74B31C431AF66F351E8192AF1E4A9D8EF05659A9CD1FDDDCE548A454CBB372A0CCB9AB10220F401870CFBA758895DD3EC0E15BE7C272938072BBAFFEEB5D7873C4FEB97BC790AF1542C16F9D47439099C7099D6D1214CECA3ED4D050758EB15C6EF4922168FCBF034B19A3BAAF68F62F7A13452657FBC41A129A2D4B98C04922B4E8B570E13CB22129FE1D5AAE214309145B4785943268DBE815DDF8D56591436E96A4680AAEDAEDB54DA61368664E5ED651A39FBFC1F065A6063E1EB15C6E5F3DE98D252A38CBD3430DC94C6ADE685635138D42CE0EC4C8504FFE53C3A180C05A34837BA74E93116AF6F96EE5F434BDC865A7E06F17D72192C2EA41F571706885D0E133EE7909FA673E100AC2485B91E91D50870649B89D00FEAB5949A433A71AA6FE35EE4E0A9921DFF0DD7B827B7E9877CF6290608FA26B431561E932832BCEE046F4B8D3A0C5239E061D82E83DDED2E36B88C18FE0F117480012841890AA8610BC211418C2709E7022919E2822318658C41047F424D09048F024D3904C8C1C667138426516D2BCC83ACA9523951BDD5D8CA79BA5D6CC1A85883F61F8A484A78862E668579424C0CA7524E57C57004CCCBC4B9050B608E599F034A2723094C9D64B5A2B92C8BC2B6CCA0537727553E73ABB0AA628DA99EACA8FD8523317D0CBA23830271DFE857CCD3A25825F55CD1C6627970C9E3882CADD2460C93C520FCA5D4DA9DCCA16804653D71777455C57CE54446666FA2611545E63C9C079403A3A33F3D4024B29E73B92F2624707721348F3F5F4C70C74424495446E357D7B644D604DE68D9B3B32CA59BA022599375E0E84076E05549DAEE4DBC2D45917C864C9CE3581C2541586EE0430B0AB6D0A20070E4486EE0461D040359F253B1784C8439DB0660C0804CE00CA936929E59F583372750521746E912947761535410299930E6B265F2AF7B6B4F24CE9C90D85AC19230AC01081E8D4868B71E450BDF21A028B931AD983F1035D75BA92DFD19F79D4352E1303B97C4F2FF382432A4F94178B470C15643659C0D61150CED615E896F914C458AE937C9E2232F2146F2C18C7BA643EE5D456A467862A0E22211028DCAF3233F858DD6A95BA5C18BD5A93BBFBF7DBEDCAFF6249F97FCAA348A6F93FA0D5AFBF52CCEEFF2A126FAF616D93D8FC428B937D3E415778A9C10C2E29AB19E669B45778D4597BFDF920B9496CF571834686CC022E0E4F82024954EC2406846F1BC95F7A13E9D1CF1789480D0A18FEFDEC357A75B2258FBAAD56E1AA70CE41D6CE373BCC14DBAE6E07A7D9FFE6ADC2F164761D8B6515FB8910365E242AEC3A263AF532B17493EFFAE507BE9EB08CA0C300FA455BA2AE98CE0BE2EC733E01A684797ACE9B190E756CE59D2057219A1BBB24868CFE1558DD4FCF2CCE3C554AA9BEF984B9695481FF33B0BCF3D2600EC12B63AB5FFF0A77D922B5BB7A84E8A339EEEB976FAD5680AEDE3951BDADE3829A58A05F0817EA1225F90FE9D8789185B568D2AE3C13153F7C597E230BE6A8F1E93339B9807AC1872ED199CFD7A9BDA2F7E7A39C0745BDF837CB998A804D6197D4F659176F7BB970E780344D8C1DD3A8A0A046EF69C5BE92033E16933E99AED71DE5B41DBD67772270741422ED4E85E300877D51B14B07B89AE2BF54B53DA55DB3F854FF3135C37DCF9C54FC888F013E10D5469D68CA0BDF2B93A1CDE16F8E494E09A57D0C29894D6BFF5480BE5BD72721E25F8BB10A2AE227D5CEA7C06A8CFC44F8DC793DCB446B2B37F0557F471C6577C5880CA457180DE3F01AB5176836A650D2E3E1E3AF93F26B52AEADFBF7040433BE57ADBF5E250A224806364F563E11792D0FCBA610FED0B5DF148F62D42E2832B59B8FCE33DBDEE2F72C0280FB6F4876252145BEBE31E4DECA373CAEB9E54A0D4962CBBD69318DCEAA568C48C406AF6B9B4D2B2E64E3838895CCC010F7FD3ED5602C53FF9A50190D6DA15D8761A08CA8F44C072A115C7E3449F9C5CA4CE20EA245907F8C75621D911916A7219A91A3D534996E8C88AC1E95F1FFEFAFE85AC09CDC58C7F33E4A7CECCF67B01CF5F83F336A6CE749FAD9C3B83BADE9AB4E2FB8E14B87645295332283908A3839C0FF562CF5365E5FEE2F5654EA8CBC44F353CEB301906FF697372DA825268DAF9BC47F426E50144D20BDA35ADF63E1C453BC85760DF01A5AD63947432415E5C24FCFCF327CB5677EBFF054F3C4D4F672E662EDE33FB7454EDB9348EC9DB5AF665CC5F134DEB6FABC007CA492AB3BF695152A58A96BFC18C97E520FCD96639A969BF17AD8EA0BF6DF5A9FB34A9A62B8F2090AD4336AE0CDDD68EEB102279395CC3708E1C7304AAD024D2BFF58EA652F6F498332557F32A59ECFA09BAA8CD2C18BEAB4F907A517EEC959B4AEC0027F0750CE562C39F26565666ED7D5DB99AFDC94066590D655776012455670D2F618AE18085145E679B0FC59A88B0EB25DEEDF3EA2F8C09F48AA225343A4855D876AB3F6A968358B8FF304E3839D76547FF4D80250E1130F76EDA28F5B8F74FAA327584D8194744F75F092B645A48A676623508AADB0750203F884490CAC8C5A3803BFDC21D81374977B9E62348D48425C8C06DCE3CB6C0A5BAF2496CE4AF640B7DE11C280E6B43ED4F5D17DB301C96717EBF5376D1257943E8EE9667BA64281CD4325A43340707CDD3F242B307E384CC9E989746FF82F918AD3568737833E972A9B310B7AD62BAEEC04B0455DD843E888093201E86C8BE9FC1E83B43804BAE1EA37DFF42AD6F9457407E0D75057B4EA77EB79049A758D1CE8F712A2B32B03319AE68243B08B97EBF023C78E1C45D2317D10F481EEDC0ED2E8B37C609A4AC24EA58982DDB8CCB0D3ACB54BDE0C852DA25B548E3FD9489747D1B0FBA4432D8391F2BF579458EFD968819AD6B23B1564F326B28295C9CCC657127515A5BFE778B547BD9A0E0C917654A3E8E6C4D1B05104EBA3BB040F27A4CAF296AF92CFC048C21BBCCC41EF40337D11C2957AAE7E799C23C3B5876D25918DA9A993625E5465BE5986EE5346B50F3FF5978E2192D48A82C3AC8C0F774C42B0CF47AEAFF15AFC80DC3AEC49965030500434BC959B5F2FAB3FD99FC28C7C71DC5ED1EEEB5A0FE24BB60AE336721913057B826F5FCD55EE3605435DBC9169B6AD558A11700BD6DE01941AE973FC7997889EE7BB69AC20F226D8A3FCD43A9F533334DC0963C6C5E152D6FB526746B57D1B4902A010FF21059772299CB19684750FB8FA7283DE8093C9C06CED7DFEC266382F80B90E49778CEB8865BDA13060282F47A6BB2983F8DAFF83F0DE5B16279166618BCD86F80754BBE8F5A4AC523CA0DF89768BF25DCD6FF8FECBFCB7D2D024F7F3B2174CF578048864EB02C7AE12E591AD36023721751FAC787ADDAD46A6920D5277B90F340AD1C5E23772EB30B498A8277A258750AF9D45453906275D46606CF8C411C4383F1EDB37196542B689FFDA52CD114382A3B5E74D398C18C973F5F2A476834B48A5446F929D7BFE45FF277901A77C1F16E5B7DB98DEA7B4D94F8CB8754EAD7A0E62BD117156B04085C63C1993A6F44FD8EA2D4C6703749145689A28E2EFACC07BAD6943D0C368636D942AC515B729A385A1737189926ADFF53C9EBFAE4B25BC8130208DD59CE1AD0E7506414F2085B74D3248BCB818F89EEA5EB017E16B2FF5DB333450D31A691B0BBE249EB7CBB2230D47CFE98EED7C0ABB814606319DE6F7E203A4D59580AEB8E2CFEE921A8AE83AA1D3EF0D12CDB0287EE4EEABC5483336AC237178CA1C249020D8D66BB3696BB004A4D6B73B4CDE2D301745F934CA69C7F449F0BF6E1EE851B519DAD444049B42A7D6013253E6A2161E5D04FC7B35F04CD68CFDB53F8E3CFB8DE9547C7178678557DEAA039331FE79FEB1C376D3518F7F65869D4926103BC73F78441B3F434BC1A0990C99A31FB5E32E8501EC7536DA0507D83D3B9EFA2E43B01FCCD3A79FEE54254695344230389ABD2215997F99E56BC09DE00AEF795ED3A862C56EB70997FE171AA68EB7C573B9E4F782574E98CB1C2FE1598148FD097481DEF1A5F11021961D5662C4D4F40A96558FDC9CD5F87A2FFA97C42B3FF67FE14A40F73FB75FCB222E7ADB3572951670E37A0FD4717E85AFC8AE42B6667E9DB34C454F3D16A2A80BE64050C7FD30D530009B22EF0D67E33B5A18E272EBA8B2F7ED11AC9CD5D76900E617DA4EFAE65AB9A2D1B7FD773526E4D415A64DEE616370EF98966A99B38EBDFD47550C41B8B49BF283EEB15CFFD3A00202960BEC53EB03F0DC10E3C96A6918682052322BFE799E74F768A9195AEA2C12589FE149F5008B3A25FBEAC5165CC1E4E37FF18D9A23EE409ADD2A62AA379FF8B7019B22EE8FEAF87627D1A3B8D34B51245A4C9D12BFAAD9AA9F2E0D7763137B9E03DC88BA1E81BBC5646DA4C741FA28C00FE80B3D585F35BE6D30286499541107CACD98AA2FD7DAD36663EBF435FBD83D8806CF028704E3F76012A38CC94786960A25DD43EE84FE913253F92388E0BBACFA77AE1429BD32A13B1596CFA9E71007FD46947F406BAD22A79007827A7260B199FA43A60C846FFBEF0EF80FCEF660FECBC336ECB592B9BBFFC3C8E84A9B936099D0AF797C6E90F254FBFB20C4C6EFBFFCF421E3A2320D31E29A60ED50C796E265B03DD140B772D1D5AF02718ED0A58BF4571BCB1510B7F31EFD750E6B7EC315CF1F09267DB9454A517ACDD2288DC69AB6F94E8C6FD0DD5ACAF30B71078DBA7A5774D2627F505E64D16D314488F3864662A9E21ED5B253E5E4CEFFA965CB3EB0731B8FBD1F2144B2B698C9D43970F83D16884155A515C2227CAE5E3B91575E1E7021F276F9282CFF3661E33DDFCA23FD536825CC2A7148BC1312CF0739FABDF91EFFF4CFA5CC0AB78C71919A9B86C0D638CE9BED7F31A04819AB6798A7EDBE5955EB59DF9340211AFDB3BB9869D524E71EC1E7C3C0F87C14AC9D8C4C95A01CC6C95A16C8B79088D517C483D5748944B188FA832149636D68F4DDAE9FB007E2308516E4485F194E7F32DB64CBF2A8F33E043B671EC31171C7497892308E198CAF89F329C289B345A06A22C68FB6CB80651C321E403A1732352F708F663A2A551D90919FBAED8E0CD31B42D66BE7ECA985FD89658936D7423E53F4EE6E088E21DF6E63E8B0ADD16283847C950D33F3A5F7C201A2C394680E932CBBA4AD54D64AE8DE53BBFFF9AA661E485ED07C8A25C915D47CE5C698017F8B0F1AA916399E206A784CDD4CB648594EDC3351FA247B51DEB8FE1B3C4DF837B0C469EDB7F149F512521C44EFCE4DEF00C01F895236AF95768476F5A47F548C10A371B075A4A1057BEE6E098510200E4FACFB0A526C7B2DC18BE819D5DC8B7A447E96E6FDBB627966A2275CAA0B5AC41CE6EE4B39B0D08DE08E3879953D76C45362C4B37EDB74162BF59ED72A9CAFF794A37CE1DA7C2B31D5E1AEDEBE1C200B33832E0A4CF8C1D2BFB59D036A4A07DA0FD9F6FF73367AC24E04B7A67B545EC7899DE0E223C761409D812AB3D4791698C12D75535B47984E083E16F676DDEAA68F8E9C1DCD8311897E34B935601108A9B9B3E7770638EACF446AF5A525BDCD46BBCBE4E12FF814FADF690DE6701A4A53AD60531E2844FD355FCE79EAD5D836FD84708B8C884E25C2B7A40541797AD31EE0508F8B373E391AEE631CABF8E3086CDA96BA18E8F05E2C1820C5C04F775E83307FD89DA6EB63F34AA5B6687FC3469BAB2D31DA05ABC40CF64602D1078851B5B5CD0D189C9B02277C2F967F7860FFC2C13F6E86F3AA490B9828514E558A7E1090E44E806AD1240D90849171BDE9DA3F4F29E27DF227466BF2777A54104D7AC20528B92C559FFB5F36F0EF8F93F374BFF5589E41FC0DD24CC85B3A5E681805D13C8DD3295B81E4C8C8C59EEA4ECA48BB007510A215A50A1E518475235F040953ADB1B4D41A930DECB21963ABD93D61B5D02AB7BA9119C89900EEB6341AEF9F48C1DE793500773F2C20FF8FD381D0EEE60289617CB2C3B78584264A682E5C04BA0DCFDA440727B65DB9ADE031B38E52AD583A10E68A08E46F29EF278F48044C313AF4546434CECF9BC01061D68C9AF40D0C4ACF09419BC59F13B85B5996EBACE9878EF579A770BF6B223E46420F6633E3BCD0BD5334D261A34E213A10420651569AE72E599EFD8140B27DD1E1430288964B96FF7C4CD5A1DB0D9E0FA1C708FCB4CB76BA7F680EDD9780B09789211A308461EF7257D47E6B06ADB54BF0D1294D78B9053674C5E1AA6F19B8056C147E035B888A91E0AD052DB6B4896B2AA63FC7FF034A1CF9FF34EB4CF2C126F11D0C6B89840BCC8C9CD11744EDA0A0571709F6FD77B83728245F60F532BB17DAD2D5F40759E292A2BA98120942FAF358CD6D9E6ACD38A328FA88F980AC068A97126C9DFFAA1129E3F84070D404D47C31E8D575B8225BEDAB3E9B3EBA78415630A5E442DC320F77D2E1C19583E5675FC8F3F528ECA0F3FE9FB7B3B6D60FADF6A82C968D7C9D39E62869F31FC0722BD77366D037D51ABF90B38231D49D0E704F740B91FDD5DFBDDEF65AA42B9377424387858D7E0EC49E7016FDE295F24A1F26F4303329E2B417B70517BBBD1445B56E4043C130494EAE3C7930A86ED51664B6FCA21F253BF8BE257D802E8AC0A99562E8CC0B7BF2EC03D7315A1A7F1D83AEE0D25140650001A3B6EA531B3F7BA28F72FB49B3940D17C34A98F734623EB28ECB1710F121BEF8035D357EF7194B3639E1B1DE912D95AEFFCDE1CFA7B96DC38317FD62118815FFA025239F7DAA1F3C0E46A3D752B123B27852B1C9A0682F9B2CCA581664431EC416F70E709772298270B3D18830CAA6945D381BF07F206534F8A92C669A14D79E25F2199D2EBB58DBE6CCB461A71931CE708C8B1B3AFA989506F42241EA0ADB150E7A47CAC6FF8743C7B08FC363B8935504D17E20C2FB66492A003A49B28EA8DA94398B16523A2C39CAAFB9B1CA7BBA80C08392FC20552E33C07010D356842BF34FEF4C7B3AC13DF9C92E5801F4B98C822CEBEBDA9C83F50B5B901F0858CE6D45EF86BA385749B3C43BB1B9A48AD48889F2048347DF84C23DD234AD5DBF1D32056F2FF9E4191C419EFA5DBA3B7C734048B84D957268090C36D66E9D9A1C8021DD2AA8105A5EE56BEEC151CB1E7CFE488D0223E4CDB5E0FCAC94303E78A34AE3255B1E3462AECE1DCAB776C565B1053934E2BEA853E1FE1C17A399897EE370038290876A60002DFF2D9622D32CDED6F0143B2A8F575D9E0770F39B27CBB1582566BF78C8286CFB16660557F57F76D0DD45E1F1CAB4E651A487052EDCF5B86F1A491340262DD7020C23CA34ED83494E73F1821390104393CAEAE7BE5A2F7CE71C3AD21170EA390E586FF7D69C74A49676F812DD3D151159D779D6452AFB0F2CD1E6228D05A06F9C6A45ED2EE21611F08B1639A51C3004115EFFBFCEE595AAACC51C2C88AB3AA20739FEFF1C757D91D048D40B9CAB5E549D76F7FBBBC509A971C7225F91C1202908CC4DCA603CF99C4FC2D432D9D0B3771D08E5C2E030FFD5123B0798878D3D84F3709C927A88CC166A35C24A4F80A6248951BD602CAD240ADF6C367022654E96780040992D8CD62F9E2AC4A300C2B69CCB987CFB50A831FCB341787A36E076560E797ACA18F5C51CE181DAD352771BED586A544112987DE094B0ED34F9F5E3D0962A3811F8D307F9378065C2B945AE781882A658071783838F71560CF105478D8FB26E074644BD1FC4D1400C6423D224C1B6D13F63095F1C6E04CF14DBBCDE5DFBF8A3B3DA14403F3FD5EC5D23E02CAB02F72B78AAEA9BFED8A59BF7DFBF5B50D6D93B64FB650285AB44E12016C51B12530D519F29B18D778956961F54E18D4D38629D525E8EB21B40CEC4F550FCF744561102DEB850FF20614AD5177CA500B2D5E6034DB1AB71647E49C2CE7D179D8808DD37AA15C4A0EEE5920F9673FA2248886251BE0516674B6D0318DF36AB880D381EB8F955F36F895A815948E7D3B8FCC9618445723FFBC12852CA00DF539E4472841518EBC0D1983E6130B4E8B9E3B476CC09CE8D5EA0BDE5088D80D8D74F0E42C69DBACDD3FEAB759B84CCC0CAF1BF669C561BB743B1F8653BC8BDE8B6F0E790386381C7B4FD4E599A889596B3BA92D9F129FA3EFCB7629EF8F3E34C3F1FEAF7E51480D51B13357F283F3AD9C2CF35C594962EB23B383A69D5F2A5D1E27645C7EE31B5807E5CCB0068A31CB2EC2FE44F2FEBE1E67DE2DA191FBA70EEF5630BD2243966860F786329AC19C2B01090E85B6B394A4CA5AA9CFAFEABBF2486C36873FBD2E780E43FF632D003D7E2F347E6B62CA1297258EF22EF1D702E54E674321AC685378BEFE801A0FD8D8D843D0300A3DFA355F63CED097F97F4ED8D0B0E8C5EEDC6D36E272A000294C0AC9425F45A2E16E08970B67AB8FC79F9FD071ABFE7B4277E02EE48FACA88FB48C050746A16CAB2170ED4CC45927980BED9EC56A1BF579458883D54F7E945A4BA16D808B5265024113F9275784E4A994D3368CD8A8C214B0265F0F1425124B60B081F8A853AF13E990EEF053424BBBB16458402AAAB92C61361FB4D8464C551D605F97BEC853E639EAAC3527EF5D9E47C13580FF5EECE0B7AB540A08FF7FDF19F15759194ECD9EE80FC7F6F0A823AAA47F6F824261AD709DA764193D11F1638C099DAC3CE28A884BBBF05E831BCC32128E51EA9F181E3463E543F04432ADE49E305F8F9C20B9D1B8125C7EE642551E446DDD9C404956FDC3A4321FEC74CF8E6CACF580F8A116C68EE8D810E663AFD81C00A9D39246A4BA9F68444DBE50C42B7C469375AD48F252E48E92117862315DC61204A05866EA8A3B3D7B26C9622F13BF8374DB64AA47CD6A8EBC6E19A3E4F92D6BBE5830916AD826A25762CEEC1445B726AFBFCDF9B5EFCE6A707888BDB4EDE9729D57EA0D04FC38E4F4BCE030129875D00A8662724341724516100A1D07995960050D0847E60043124401CDEA5DD49A40903C433026D986069ED5083198997AC8CE76BF70385031F9D60F3073AB9A4616D5E3F0AB1AB803E6FC2366A680A1C9C43B962C249CCA69A3221D92A0212AD3D23A1D74A3CE8CD11C2051F8FEFDD2CEC75C5D85FCEE0035D7532AAFA5294F0806BCF96633C08884B343134688EA0D542CE810F4C077D147517010D3C8A2FBADC8AD69FEAFF6DFA1A827A5B9F48BB7578BDE7B06F21FDCA349165DB2F7B314484C24AD826B4DF9A9CC3D5A1335C8E414C823DD053D1B79C3CDCD56D415B3DB3F9AB36A7D27E736EAFC7EE8785BF547AC21E413A671A292D2B1C079FBEEB2E6B51E248B12378A08F1BF8E8970ADE0429067FAD90A4B788D2C758E3D7FF8B7F5239DD6603939F6196F01279DFF03B4F8E86DB42F7BD82C8D3816C2AA37999A6D7C189186D29653A715AE38D389D5E9FE0D19A1B195E442081C15904F8B7F8796906D8F5A3917BCF0DF26F80F1C18F36CF25326688A5C058070877F3689CECEC74B9A7C01667B6D5F9294BA18C2A9C05485FF4F0BCC733F28A285B9B9D58BF20A6EAE352381343E2988F2055ACF1672F4A9F12176D007A22B95177AA4B2700AE1D32D6AE17CEFCA17B2A471438A87C8370C151A57C46D4EE45931A617A0265A528756D9DBFCD0CE417EAF5B0B77FC822F21341F0AF0867FB3873B9D9F0C175C542D60E3A195C4898B2FBD34CA7C51BF289DA18738CB7EBEBD2FFA6F83D835E6701C3C8FF9680AE0DCF24640E9082B7B6792C9957D1920DBA36C1F8227673E3DF837440D9219843285354A2045FBD456E023A75649FE80A0CABF5C26A624F64763C5157242241C82B88DCEF74075B1161942DC0B66C05744FF4DA50FEE124E8C741B8E0219D799516F022F338E262F2DB35112FEC3AF752D85EE64F076CCE99BC4DFBD2BFE9CB4440C479F1E2674069EBE412746DC33077DEAE530AFC6B3BA87A2112B74EFE2FDA86EFF8B25009E81D012C4C325E370F15E3FFFA2B3F871178A8277824D673A14C55AC59705CE4659B4D12614715E16783331C5DE975AB9C10B7E83FD2F54F0C4069FCFF082826B4A2E5B7E3AAE3C34AA8230A35004F8516D64A6782D6566A929B5BBC4890D9363B4B8682AA87A151B9E788C5D116D883B20BB4A09C18D364CA2724463E5B7D321FA108A37F159908B0C4C74D766B02B508FB345FC57CDED8E650229F438793352C9B970000D50E0F2840C8FCF461712FA66BE15E881377E9AA9E0F625A89B25011CE205685460D8216A29C434AD1884FEA8651544C28339663CA5E34D2466494A92C774CEA730162AA2221CB1B682721780BD8404BCFE0033C9C53BF1A5D0FB708CC08CCCABCCFF5450F973C1F0780E3C2F63FE217F38462DB2E3101360B94BDB1F28A18172F729D5BB00C19C11B748B168324A3B1CA3CECA5C5F19E2C4A68175CB11C9E2BC24104F6E5AADAFAE9CA8589B603CAD0297C0D7A70A9AFC2A0CD0591EBB834BBAA45BA8D7F0BBF94252147E48CF811A8FD1EB6CEB6CA1295A74937469B2CD64F6AEE79F47C74AF8FEA17AB1085386106E4ECB9697D1DD0F93FF39CEEB2625A44233085EC25470361DC3E154F447F081B94E93FF6C930C2FD21DC5719F40361503EC4098876DFCBD9EEE0C280777022A13FF845EAD107AE1F7D451A81AFE1F9745CA6095F5CB9C007CB0698509A656044B20B9E78616087DC07B08D31EFABB032C8D82A6340FCF804699A435C2BBE0B9494543DD66EF13F2728049F23B420B3FF65304D35027801A9AEDA463455449F147C17CFA12DFB08D35A56FF424597A0D249A30A9D90D317BCDF36F024577F4283792896B968072B54B624EF6F307A4D94B514583321BE8AB546D524622D639D9FC95AC308355141DE49EC7241FDFE1F3E45B617F1A778D6901F68CFAD3C3AC67D74630C477C8790DF0F0750CC86EFB24B19AA5150313F7BA2F73E5BCA2CCED031958CB89D17D902FA90316CE08BFEBB7C228FCA17BCE4EA7E0BCADDFB46DBAA9EC77AA8CAE06396D201F72DA2867904FFD12F8764AE6920322BBAD3CB71ECF5B12AA95D741D707007F7C09BC8D8850FF7BF33414BDC0829E5FDDE6F8ADF2B0CCC281558EFEA965D21FD4603B122486DEADC3CD4714B5C170691D3B571FF48BBBD0F82B237D3AF714C3D24CC303EEF9AAED2EB686147C3D3BB657F4B837CC891FFDB561C843BC988ED3DFEF3B5050B08A24EC0285CBE11F06EE529D30DBC45FF93BFAB1E9C3A7FDC6E5C79F2D680CC04C754738842D4FAE8AF249E733915320C4D8AF7DDD00932CC6D6C6BA25827DE12BE7CE4C4F692CB4F82C36F42A05742E479BF449C349671AE848694F44A23013143666ECA710E9E91B84A8CD5F4FEDED77EFE51DD892EFCAC7EE76FDA9E7182442D5AD9ED597D494EEBB3057B7F6C965AA2F041A5B58154AD96E324507CDC800EC16B2953F3F76C6762D7B1FB51FBB3ADA5CC0CE8B5BC6154D06C34C838EE57A421FD446E5A807C33AE177B3252238C187DC71FFB4B8F3FF055F9593FFD0826F5E4F7176F8ADE96D7552DE3BE79DE61FB5E7E44FD37D3D8ABC34010F3FB1163687A85602FD74281BAD186B210878E89EE4F5270BDA3E13788ADEBFF9A9BCA04D99401CFDFB453B96C302E34A60586E860F9D4A5CE257857CE1A1B88AEDDB57FD6B2E1FA0105495B9EC6716B75C18FDF4AB96BCF3B49E67FD274322A605DC03BE4B1CDD3A3F70BAFCCF8B876430E7230267369CC9C0F24E68ED77188337F74AF9663C4180CE8C1ABA9534E9EC2A35E1F3582964638579FBB6BB2D803A3FB3D446A3B3CB630B66FF15D6E21D34343A24D71E59FB1DB715AFFE50B66F1943BDE10D45296FDF42E4B1708FC64BB4FBB9FA4F1888818743F96080973E1D52D139DEFC157719C093ED594BBE45D3E9F6AF1BEA55B79B28BB571C40489847E7FCCC8F93A6B956E899C3FA8E6869706E89BDDD660814F73A3CD2B6229D39D350725B6729DE0ACE80A60BEAFBD75D91796933923B755743D73A4FCCC4573C1FFBED85903B80B977FB927D0B14820969EF520439DF8E27B10A71291B65BDB14A7885CC0DFCBB04F7354A89D55A8CC876B037DDA6C99323B9AF22FD4AD7EE56831A31A721511B1C51174328D3932ACB49748728F6265CBD7545585204C927419E670512EC5CEC93629B3061EF6966D4176905CF450DC49D01967371211D40A4A08CD1C93FC45DE0EA496D10DBE2C9D04D9BF1D3CA0AF4C860EB5DAE6BF59B2DA8C6989B3CC1215422F7D2B90A72033CACC0FAB7A3698F88D2CA238930A8D1690A3BC5371AA36A1A346E2CD76AD8F697A3DA620FBE9D641703A5BAF7C021D755F7D70A2980FCA1DC10E03195494668153890726687FF2B27CB6E7597B833AE0349E92842025518AECD4D389CF0E850532E043C4B23B53818D63DF2C0372A51A3CDF578CBA090C67D404986490B9CB228E48AC62BA10AC5C85C2FCA477695D268C60F5D55B1A6EE03E1EEDD4F49E44B15C92762EF4FCD77B43A3780DF62EE5B3E375EE0701FF30DC3C9A8D2F49C9138D702DDF6AAF255CE7CF103C717A1E261E9C5F35A7E581B265344318B41562F8D3B2516A99E468E77F541B3B5537D3A27C6B1B2E552B7350B0F48244259AE46DC8D31BB15722F3F17C22461D2099A484BBDCCC61D5BDF6ABF9CBBE57C8BC92B793E830D574F7D2DEE69C344A1C233CB09027C3905F3FC10179A90AE2046C1A58ADA1CD0C056E0ADA1FA15B44B67FE056F023A2E2EF40688FDFAAD3EB5C8C61305A14672494370EBD10A079BEEF58B112AFBEF8B23BD553A82BCBC381B143FA8182C43938DA431CE05D9EA04181AD6C557A7DABF24909467D2BE5AEEC2C72F2CEEB931A880DD2F900B2A182062F046976242F8436C2150DBA4A2A5F05DFDCAFDDD90E3B1CC00EE53E653B5DE95D4C3F6366F92B64725CC010917F62A850DED4189B96E478F78089E7A5D78C0D25E3F9E3A6A5EE1978496FD3C7F8EBD37C1F80BEFD80B5062B7F172457A47D47BEADCB59EA0CF1123C004DF6ADE1A9C5296E211939DD9D2F184D4D85C97C8F6358E4E971E6818500EF86F83A22C85EFBD1095E1FF6CC4DD542E6136317E21B2731E1945D0B52E801AE3CF60B33507D689D6BB5DB370F613EF37D4257749D6F2A9A72CC91FD7C80CDB044C07165B003941182D69A63478CDC6CA14FD6D1F85B904521DAD6CCAB12CEC37EAA2FA36DC70B3731A6580C5311B4F51B743D0E33DC81D98B05443174F090E4A1CBD77430F2201C355AF704C73FBAF6AB863A90073C6E7A8F1AB340CFE12898773B5E8E6DBA2066C355C58D64A66F8BB105BAA4559BAAF69DA7FF1DE54C6C528B59B4C5B526740D03EE443167C7DD70D7D3895F04543B1B3C023A4BF793CEA8FE374F631E65663ECB6A73FE5CC020F68245355520D5A2F8683D85A19984CA32ABA27C39E4001EA9004DCA6A25840A1F1EE36BC49AB9E1E7AA98326FE88A0EB0BFA572B0E78B3E5467457DBFC5E76E0F8479F0FD2F8A35273254B306A7AF9DA21364E05AEBFC9F51436F656F7389AF1549A0A8E96D7A8D9EC69E4206F765B2D79041FB0D37C6E965F499626661FF50B464EED36E1BA90B40480A336AAC85A66C3EBE96E8728804FDEB0FF73FDD7D12E50FAD8B180F277401211155A9B190198C462DB862C07F47A4B9E9618534F6909E00B2FBE2F627B12D5DD3C6469A29B1175E34A6A4DBF24F7E14805D729C0BE2DE8E6A04E27F783BC41AF83BA239B2683414F91E5E29172C71FE66A822A404B91A06ADB070FB3EBC19BF61425BE028A1673C0D125DA3FE46C8B5CFB1D7F5692122FF0400F85A335D38E0D553275DD0711040730A906520C30A662011F3021149868D238177CE26685E87244D3A52DFE47CCDB481D5AF1D5399957E7BF38121958DD339931A2D072DEA409D734AEEBC49007EDC3699346BC2E65D53C44754DBD3CE60B544FDCE37936264499884D7C5D247E07CC711EF1C6BC0B4D1BB729F0304D154BB5CC8CFC5E43E3AA640C2A035BBF4ED4C4BB27903C6A9F9F5B48C34DDC51083ECB587145A7C24596F45826D38CAFCD9557887ECC20A6C2F9317B4B76B8D0DB9C9DA9BACE7CB0469F1AEB8BA887E7F20B056D5827E169FAA84325DFA794A3960B181A669B06C1EE25DA2B21486187D1B0AB4F277862FA2F4E9D9EC88ADE19F1E07CD9276F486821EAA184379D9D2FE5E43A403341D028BD2C50191687B258FE339C2B2E7A9D5C5C77103E1324749617D5667A3F26B81A5F86DC8328CE6CED745E9F78DE7EEA6E92D0888E73B28DC34317500831DE82450E3567E8C15EB8AA90E9ABB6F46C5A7A696C966B006449A325A10485419874CB11CACFC434D376ED688983020F7F07771E8D1CC503A5E7A85BFAFABE546666A7C28B5CDBA05D01BBB284E8EFC256B53FD15A2A9BB16D41DC31CB323E24E9FBFCBE751913F6CFCFFE71026E38A9C18BFD9EF9A27BA4DC3C1FE2DF616A137EDE8A9817EDD3B368F59F96298838A390CDB65D41B0DA852CF65C9A2CC50AA1285ECF368D5CFC7A04381957062E0346897DBA60D2F65355F3B39D26B63A63AF10477EA2DEAD7CB2F97DDD7F3EA356A74DC1D7F2F3676981FF219A864FF2FF7C9B92AF1FBA57C01D40FF74EA62C9E3D37336D42E0ADD490930EE03C015C403745739A369F1F7C9B83CB8B0DE880F56D5E64EBDC8011DB7F9B1848E3E6BF9720B3955B68083C982E1ADD2D5B3104756B21D55549A1BA0132646C2C611C370439ECA336C5411498210F0E30881CF284C7670580C1DF4F08E5FC21D35429E6D6FA59A53AB76A2479B704742A0A29D311AADCC1C4C141FC0439269FD4262340C33380CDCB52D97D667AD73778D08F02123BF7A570089EE20FE6E947B32878C6ED1E80D2BFAA8E53724DCC909F837C63138B2A6E0540727F47B41FADE8D1E9258703896F18D4CC6E6FD66B0FAEDE4AF8258A5FEF0B93C77F2BFD1046E74F45DEA33980866768A52AF301AE1846C3EA7A2BA923A9AEF01CFCBE9EDF994185319A90F38F28D4AB0953A2610EC50915956241CD8B13930BF5788D49ADE29EE2E0EC66114D5813C792435A1860600E006C7F99D168BF702B30E39D5EEC0BAE45EF99E6854E5333B4C8F0BB8EC62B2B6E0A545094F8F317DD03E6F170CC4B99DA01437D66C57E4EFF5A5FE421DD278418BD9D6493F3131D02A45FD89B5F9C6C00050A82FE102E3428ED83821C07E07D5F32B7C8354A1325BBFF7621E865EBB5025D289DFC633AF3CF6E07CB5015B2BB78207068D3E138F6404F84A024434CE70BFF84833F33CF6B0E4D41A47657A92ED995CDE1821DD6F73BD71585FD8782229DCF54AB18F1F75F6A5A8C0641876E231DBA8D3BA471A5A6CFF4B83597F0A880B1EAC57656FC2A4EDB016B39F806B02AA5CEEB9621C26E95CACD50CC1FB2C3DAC01EF4F4818A24A1580CE09417A566BC9F780BD90D0AF6E81A053234872F909ECBA237F79D60C15E781B35AF7A0784D90959C0FEC214C81D390D89FF44E014D08363D2E424D58253A57CF51D261D9A4C233DC42381B8ABF7CD459B9AE9B5841FBEBB3E0DDA0A36749D596EA886D68E6DDDAC2317B555C168B0941F7E2060684DFBF1B6E51FA18A6FD622577A6A6B49FE8C6797A494A7EF1CD46487FFB6E88ADFFC704AED04A762897E92D041C47640091FC8AD7DB62E9713D3FE3DD104B1B605FBE42D657A09CD892090108794ACCFCCF2926B32CA8FC96F90202BFB61D1A83BD9ECE54C48545801052BFFA369A69E13A704965B446E24ED06F3C8B3517584B76CE3A934F199C50F1544B279BD48ACCD3BB6D17A741F5C9F2A3885482F9E2770F6AC88D22FD8C34443785FF66458536159850E8BB01D740AF4333F7E9969C14AE0FF45F6158C1927A442E557EDAFFB44B67183E90B40E8CF95844B873967AF9629C9FBC436AC6B4AC2DA67EFD092386E1D09D686ED0DFD5FF1BFA4C3453396F068C612403316E1625407C2B5E6E09625BC4F9AF8037BEB80A099472B127002CA30B2413885447FBCD0EBED0D134AAA1246DEA916CF348A916A1A234946C82E546906D203317663015B3CA6D03BF5035E46E2641DBC7FF4555452BA593576E600AA8B80E61BCB53A1092D2C44F17F44E77474F32C7DB2D3FC04727D98624ED1CBD9B8562FAD2698C0764FFC8CE59C8EB4EE6B2E13B40CD28B49BF6F9D96469F15D347C5BD9A9BCBD0117AB925C58A13FE449AD37CF212FF769F69DA9E7CFC393FD76A1596DA343EFB99E8C0C9AB9BD41690727EAE5FF60F74D1F7DAE27717241769599C7A90DEC0E35A67CBD5EF0BB61ECE9C2B180951A0ACD04177F7B4B00D552F593D0C64F55074AC59C145D1E413D931D7961B4CE5EA30B54DA61ED2585B6DC281BFAAFB522876A7FAE0EE476F0CAF37D399C7931EFFA76B171227912081191E2F00092886CA547C33C55E2FD08444E9478E45ECD278D0885CBBDCB2EC238AD3E0DC280008813573F4EE61E89100D920BBF916C43A488567C07CAF50014E1C9C1347378A2DA2CC9CD42D4580202D303BF4033EBA082C5529740B9E28944675981B730CB75D9131E31B3BF3ADEC725EC520B305206284659D888FA6D262A1F1959187B4E64E7E5D4937167B1C0DFC9FBB6F80AC4E1705A63E2A18526E129D913AD541D8AFCF826D7CC3E236103D9065664B697420BEDC83705963E64F0A07C8EF17AE2C6DA42C34A5F5DBA2952E24AABA4ED9FF48614855C9410B777BBE16F7F6E2F0F84855AF53AE2661C0A9B5E1FA8D697629ABBA6DF3BF4AB0092277B2F5A01F532D76C1BA12BAC63350A01215AC785DCCFEA3A3CA4CCA7F2722C266B227AEDCA97A5BFB6EF878D91A67900E7836A8A1D45BB3667E7B082014114E9D6BBB95633F0859CBF0E854519EB9E0E4FA04D0C0D1D82115ACFD202011692841121AC9F9C072D80733460D6C6BDD174826D4C388AF0AAEFF3AF84F1AC8DC794C128334858C40D35667303BE5A9317E991D6FC739CE40F76342F224D6CD27C69426B0A46941245A45A1C2BE4E95399BED9E71A20CC6AEE08B5C5DE39B9CAFA4820C27083B5CE83CEE002123B2A61A8654A74DC089F8E53BDD0B8F24163E408B46A1F7293953E87B378A9EB553A906FCA06A990A232461DE833DBC7E6DD0B522BB0BE38C3CCFBB63F4D79693BDB06560927BB0E92CA78489D42436D1E70C4A384700119549B81AC00A581AA32404843AA64942C21614EF9653A7A319EC0315A8FEFEFFBCE407A61D971DA8FE6660FAE44F6F39FBBF3E1F247C756E75AB92E4DFAC585C677DD5C1987DF59E7C36C29A137F78E26858B84AF2A194BCE4BEDC6684E0372B79779E67D39EC7FF2A7B6E565E1E279DC10201A20AC56EE40ECEBF7BFA4BDE7BE827A083CE2821F0BEB6563220850E82A920903D7F2A37F07B7BF35D55B209D44605A0E814BAD5E4B2AD2F13097AD0091504BE66E6C642E323CB6B49C91FD62130450581CF29EFC87B1ADBF38BFE47D340C7541008F8DB3D4ED276D4384E024DD04220B305A9476D2C047746D796FA6148C3A92170FCFFE41121EECF79436F77463A13D8A486C0BFB60CFBA5F06F3FC3F27EE743500A2D04125327DBC3093FF29351C9E3997054FD241DF48116028943F983A1052BC775AC339375097077601E0415D342206DD42F0C4A9B3B4F1CD82C9F83A0525A0894579EA9677E3FC9FA5ED6EF0AB5D242A0E8F0EC6E73E8EFFFB3CFED5E64312888E46822782BB62AE9274DEDC7F24A72021423E0AB17A07B9EA2DDFA6BFD331C3FD9697272F8D54C7FF98169D3EAAD9069D4E73B905BB5D2FFF46D72024DD9A82F6F91CDA818468AC67576D8E728206F654EC555604FA5AAB74C8C87D822B1D2EB3B1624FC47B6C13A2EA82F0D5FC312A1D970FEBF97B41286FC1FB9A80C461780165FFCC8AF73FE6ECEBE7B99C286C802E203CBF8D3DE778678A400AE7A195A550A5AF8F9466A7D6AADFF3131D8E2E120B63741AE73F9AB9554E72195B80D4B76EF9FBFB4EEADC95E324461B4F8D2253C5D14D135DB8B92CF8F64A7FF5B15F692F09F12FB0D1A6484BF953B2CD2F267BED4259CC7F2EDEB2D35F7667F49977CC02DA208DB9E3C2E897D649AF8DC7F0071890C4EB9A02F59FF16FE06BE5BA11350E9EF4CC75D4AB09E13F2BF4F39A1751AC158416CF82BAAEA2F139C3CFB5B08BD67E042E012D8DB831B67BCE53BCB8E81B637E6B9643F2E2ED3A770632ACDB3435BA90776FA87AC4BD27C574F3C72DA7E1F03694613C77A4E85C44FAB8A8CBC7AA29F2FF26E043F9B800D7B07ACE3526C3077C0C8F6B272D8B491FB5AF690A00121736519D4D818FD9F45D72623EF7C35C65DABD216F2B7DBF3CBB3FA4CC0C55066DEA4D6095D9943610D59A0C831A228653C488969FB14BCF7CD9AFFB620683DA1B3F7FDC97B368C63DACF02F6B6798A50522CE35EA4EE79B82E12229111A68DDB70C1118DBBBD6162DCAC0A86043D5F6DC75A2DFC77967D19ABBD2E243C759BBB7AA2C9FF8D7D655AE7EBF9D7F4AFEB5774F56ACD1026D7262DBAE5E2BF65AD49EB31421F8CC2956A3C54467A02EAC497644CC45FACD7A26E5792A98681357425302BD4FAF16E99760224323B23CCDA5E0BDD01003C3A3F0998C12951DB9FF662792E2BDCBF530D95F6659A7E23E7F80A414BEEFBE2A53054EF236AB1AFF140693B4E1505CE0AFDC702495D0AB3170DF3857CC26189C2E6EE16597FC21023DEA7AF6716A146757470D1EC8A5866BA5A96F73CCEB2BB8D92AB236A82124E893717443EDB7CCD917E5FBBF356A4B351FB02EC3B87DC2C3C32C2A62487F5E47A93363274CA2F72EBBF107726C59ABEF191C456B04E06AA06CBC433FBBEB5EBB157147E8FDF9391505198B5707FDD816A1134AE576EE6AB43294B15B4F2359496E195C3501B8F5C1A4544CBC9478E5D164BC47B437937227D2C5B7DCE569C2EC93514E9EE883EF87ED7EDD1A7D22564C02A558B361B315A3E4E0D5D3600AD9AE91A9162DF4F8B8857EBBCEFDEF2AA50EC144A9A7FDEF559C3DD2F20914B4094B5EC7169F13F024358BEAA37D14D17DD6A50F0123E9719937E72E8B85339B46BC629DED8226A409DC0D72A3A4ACFC17C19DD773F074B7C227B321441AEF869F1D9DF2783D7BC63EE1A0B309181F4F8B66B7969E94CE1858CCAE4500960CBA2A0DBA638D9C546876C62F3DBB6685FB0BC90D8CAF3C132DA92E7F6CE597A6CD352F0781BFAACA14FEA2F891B07FB3FD7B6A8797A543526FF7E2EC776946AC04CE7CAFD08ADD846D395EF8CBAFC5D58A5EDFCD3E698F0942B8C5E52A804717563C419949AF24DF731F5C4A315BDF099D2DFC0219B70B5B6780CFDBA25B29FCABC30A82FD12ADF44AB9C6456390CC5BD97745DE9D444F7CB69953E029F3FBC2D9EBDF0ED2A12B4135A1BD9D30AE00D7BD47B9628CE5F93C14B082B0FC8EF92E90FD64BC709FA557254D520734DEA936602468109FFE71EF0442DB2153FBFF18CAC58E2012872F23C94E289FACD1370C11EAE7234C90C458440E5390D4FD4D62E3D5B761AB3A36B7522BCB9D6A415788A994E64A91974B84161BDAC4739B90CEA0FA3CE4A5A8FF33667C76781FB7A78A4EED5B48B507D7CD963AE327EEECE529C9E560FA5371E34C88F66EF1431F24D871B4F85640FEBD31C5289F823B79B8E5A0C4F619A12FDFC7B53355C2634E83EF919891BEC7D2AE574CB6A85FE8EA5454D60912346DEDB1D863F9BDAD6B2D93097334438863ED6D836640E117486820B4A6BC8030DFFB9197755827E7FF2B84FAFB8773FE8B228C600C298E4EC8DE5ACD00E6986A0EF41C2CD27DFAC83006045300453E864F90120A06044309555246E71699BA564EEB53FE3E21F292A42941A723800EB9DB529D401655686D8FC83259EF7F74541BE6583FE222B391563E08F7EDAEFA96960C937819D241C44BF44BD24DCBFB0F88CFFA26A2C80EE331DCE46B27B2475A9C92113EE0B5F929FE66E0AD5D4E1CD8E8517EC0907DC5B87453870C82C69A8C9CC307DEE2E9B65C3235C5DD44C32E218806EC643DBDAF6DF307D38E111033808A5D85B32CF7D3C4719B4FAE7944615343704203754CB3D387BF94B83C408DABB5C9B2D14BBE8C6E5F7296465A744D4498600208D2563F8BFDACDA197825BF7F65ADBE109DEE1B50081F4DF4BF196B205B3D259B42E4EE4277F7AD8B29CFAA6540F4AE80FC2AD234A5035EC45C82BDB8D58D5C93C10989E22867F38232E23958A7F3441263B4161B4183E738AA6A3728008DE8CE3FC025F46EDB7C370591777BB0A2062FC3D7B84549E3ACB7867772B8E80F4CC26D60B08EC975D36C1C70EFC4F9A02F67ED0B42928F4209B4099A2A6331BE4D28E50CC891D32E1CEB23D0053BA56ABF1695EDF2F8FF84FDD9E937BF33624D0832AA306C10710B84AE696871FBCD9BC18110FFDBDA1DEFB0C96084BCCEE28F6775DBC7BA938F837E6B25B18F29D33850DD3ED5C43338CED4B5E94817EF2EAAD217790F6D510567110F84B88799EA95223A2B58796105EE85281A7D5FF3CD768B0287968D6C3D5C7C66C962F6CBBE6FF0E8E290D9C6441F8E769FC368618B7AAC94F241B2EB709EDC1640034E8C7C452950FBA243F5AD543039EDA6ECDB3CCE80D29B2D30A050F09B66690D6F66525B6952371C968C95F3E942848DF8BEEFC4ABCB7B0C37168F2EE0B5D616542F09212E036AEC60FEEE344DD7A0321A217825CC37E271D7FC57297EFFED6102543C546983353FAE88726B6A0F57B30A282C09F79952F788A12D21682898ABE0CF382FCB1DD3F82EFE18C48A095A3FBBC141F65B2B5DA3D242DBD6E425746E64DC5E33E0AA83630AE4BA34605DAC5D3CD058B7FF81F2F1452992A02C8AB9663154368F44090D44F7CA05F3C3D5C8E06E11005BF178BAADF609F269897ADEEC345E6FB3E88A4B1E54A782DF1FD8CBF4BD2FE8D3135AF6AF8D0E91393450996C6F35CE2C4CADE092053F935B644060952F5126B6F765C617042096A63A3C8676ED3ABAE5990620C2C33BC4897E4279E7B1F81AD654121FE7F83C09017CBE2FC34BACA8B4D30D537CE0182C2F08F0B0EEB375322C3EDB99B7C4FA903D832DB903015565458BE750F571BECC88D54F00621C8613ADD718D30C7FB929E91C93EAA8D6A79B821F307A63FE68C2BB153A4DC4441344F439C82CFBB74A1517530D1AA4CDD882DC133F198B12B9AEA8CABB18A6A77F7197D10A667236D11E343A81F960F88B5B6863DAAA52C6889A0D6579462165C4B7108D7B9066F685F92E859E08B654B47FC980B31961C9EC716D91C00A4431068E6DE001DCC02BA5AA32204F851B4CED2EBEC94A2C09942BCF0258D585B3DC2DFBF16B8F7EB72E770CA684AD5504F8FD773B9214D910C9C2912CCFAA5202C570DF95AF25E955A23933FD679A916EB8724F3DDEBB894402CB2B2FF4B5B1397EFB721066853E51B7C120254B560E96001525691EDF619A66D537351A0B74E2EEF8523BA3E6634479153EA276B4BEB6634AC8DBC73A9B9E9897C9CD797DF040E1FE63B267E6BC5E5ACFF9993907DA84B4FF2CF4F033CC5BBA6183602FDC44204081AB6BF615C98A45BB58F6971574906312430E193511D5BC96AEA443F6BB33EDFE73C07F25C34AB75A6594AAC536C83509B0268788620F513E5FDEB97A1261DB0ADA64A1040AC6DA028D3E20C21BDA15622857F31BAE5C361097A02511909CFBB0C72EDAAF459CF4B2474E98220A878FBF51F4C6A68BF3AB5C900AB34272A63CC2E32A62D3FDA43B3F682714F9F78253D32F31543CF07E82E1D5BE6992AECC2924D8C1C24C9D876B710797A918BA6F365CB5D2F1DEA00659B3979FBA61DE50BA7E4C0FED5338CE3523C6A32B0B7DED5872D644EF037BE1C18A0405A8D5E0BB539026CC6C4C85FE8C8FF4535CEB10CE93E4753CE8122A8CD4C7B7CD408C5764E802D7100E65B5EDFF988012C10839B1A8B420F0717277BBC88BA9EE4B293DE6E2796DA877F5367236CFEB6787E324C55B3A78B1BE7D3387D36DFB448B37884FCD2D04E4695A1208EE7F7CA72768E646C5AF52F255B73C3191725A6553B50CCEB71671AA7D4B5C7F1E9E0E30740FB7C87DDCC719BEAB973D3217F0206DAC7E347409A37B1BA7524C203CF425E0A11F9F6D32D74291E970BCF1DC9FCFA9F8775EC384A32349C0096B75FF36EF7653ABA53B163DCD6FA18A9733CB87224FC6DCC8B897E71D31AA461BA63FCC013201620F5B9362C7D447EA0DDAA7FC9345064C23A597DE1BEB0A967781C31CD105BB9B92DFC98F5FFBA651537DFFA0CD7CB6BC534BCA0881A581754675264FA268F3197727DD2ACF170D031DDBB4CE83FA987CDE55699A73F725DE29D046E860AF0B576D61B89930BD7C2DF5BD791E90239D5087B1155BA2F028DFB3BF8B50C3999A73076415BFE511571F281ADB6FB02E759250F902705D4046D19B9F75033C3C11FF87C442FD59D2D6E0CB95FF9E7A7FDA0986D01832559E1590959C57791C65212CDB27509787730DD2B623D6F6E1097C4C36B985FF44BC0EBB3C4744B4AFFD0EA2D6ABCA0E90E440537C3017B2D84ACBFFF303550309067D47A63161CB0417C50BB5ECF9AEC3DD9B81E00B7B318C4F9DC4F3C8D1BAA394A1B7EB93F978B600F84AEA956BCB0F27D8C9A2DEA94CBF14FE79FDDA9BE48F364C890833D7BB118AD1546519C0A3E29D0CA993FBE701908D5DB23DBD69C4BFA90431E2973C2D62D3C6575A05A20170F17F9141969FC5D389C26871BAF6204350499716FEDE8B2EBD4ED0FDD4081369F253CECA004210F11E57CC876B092A3E2995ED9E4F103819C5E6E50FEC4F61D6022A708D177E6727010D016D8D44C759D52FD2019991FD3E750CD486ED9895F48FFBD75B287E3E07937CA45587A15D11442BBCE226F4AA2B932B5BB737A6937EAF469CAAB0042C774BA0B8D5360C7780B237CB2F0D9681DFAB538503A4174B05B738F66B93FE78D49249DD6B84B3063386FBDC58D94E20382AD670A7253A3E67B45D7B30ADA4DD1D419FF47E37FF897A7AC381EBFA77FC5FD0FC8008371A0248DE1EF5E805AE048CFC69A645A422234D863598C53F6A221A9C6A8AB49726D965E4F10A63C5C5818CDE5DB1408215FE6A55CDE1FBCBB74DCC01F4AF7AAE622FEF024F75DE787BAC88EFD3DFE12AADF9D1F6095BC070700F69E2E8B3F6882CB9586F70C68C65A67D14B3E95FBC5B82A8F8596981DCC15C30045E9F89E291FC2DD84CC3ABAF1FD6674F6AD19E3FA757E548C1BF21CBE6A5BAC3AD04C0168FB413B50EB26F5906A9499B49FB94540C8E3D302C130FAC9EF6AFC9A396460327CD14411EE4DA346267B4D2CB4923499DBFFC73E47A224E82F50BA59C1732E0ABDC802A7CF1E4B76262DC99F5FD70AACBF20A99D2E7E8E19CE89AA7B5E0407AD20C65469D282953F584A464A051062894A9E9C298E372F59BFF897511B10B97B4A625D01DFE0921E9AC3CB75F453345465AC3A82DD1C025CC1ABBED4472F66467A66518EEC5B1B997CE829980DCE51D103192B64DEC1590A7F9715E929A276047B6891B777111DEB6AF92D5EA7C9CBDBF1ADD44CCB21CDEC4D072FEA528082E7331F573BEF09408E41106AA7596A380D55B158D3C53045350D79A4E4A7B7E6D2C18F7AC2DC629C1C46118E0816486F3FD481686B4182FFB5236B344C3F3638C838ABE5987F1D710ADAE8D6CCBB1EB9AAEB36D68B8917A45EEF1BA0B630CD80184124E2F5071B68FCFCEC120DC477A622A14A64BCCF30322D1E710358DF11E8F4CEB86385D84F5E4A2D28A4DDCCADD459A1742DBFC28BDB00940AF274265E130CCDB373901EEDBE015AA395EE6AB077D1431243596D85596F208825DB37E079E42B20D576B9F92BFA41026C4D18106FE83DB81E4275EA7B131FFF5568BC21795DE40E95403C599F4790262E3C1746EF10063F4C167FF0B6E47F3356F7D19FDF4E7E56A17AFB8B1E43F8032AEEE257601456C8630DFE1E88D421341AC994A376E0FEEC18156A8867A82DC4B9B649522A7B72DB20D2FC82666E8BB72BDEBFC62677DAB47033D9892B2FCF4F33D8870C4D0678E8FBDA7A4AB6F03361E9CD1542CDDCF63DCAF1E1609197338C3E8168F324FA751F20857612F4BEACEBA4F7315FCD80B80AAEE86DC5956E2601411A0280CFE5535D264ADC1756839D9FAE49814FE9D73B618F4451654FE16FAEA7DCAC6A8D5610075F5D33F1A08C19673C77F1E4FEFF0685AE6D19BD422827F5D96C1172CB6596E696460A7307E519592778171B60F96EC48B2A215EB50B5CA3A2CE816088EFF495EDF4AD621E019791A9ABC80835B672233E728BFB047BF9699D61EB913A996156339B7D0C4650953E026E5BCA5E89DCBA5FF270EDAD151A02C25BC7A017DF674897CC37FFF21D9AD6BE8FFE6D96D7411CC8CB551303DD908120611D9CDB1EEA916CF9975120142F672665CAED049C67B6638CE8A78078D8A8C1C22A2B3D1CAB8A26DA35F389633DDD59BBA9AEA608188741E3BD35CEC48C6313C6002414919F08D39FD8038E5F9AE72AB4E2B8AE8C77A7E42A7D7F8DCAA84D18B2ABFC57DB79E2E5B1D55A55CC04FBE24F5CCBA59938BAAAF607AA8D522C262C6864A685CD63C0E7526F4543028D9418786880CAD8435D24939BE948F5501A6CACAD7D4C8EAACFF5CA005282D88C001A8F3516A213A1785D622DEBDA3732D1C1AF205A96DEFCA686786F3DA5208FAE59FDA9DB41AD5490E7EB2DB4601A9E098A3A160E5AB27B2E71FD71959FF9DFFD746F3AB5A8ACE750BE3AD4864A46EC6A1193FCBED02FF009D7BFD6D9EDC3FE79C7FE8F96B955C09E43F4C4650F2227F30F16E4C2D381ACD493BCDAE51CB8854D41EF41FB2DAAE0203EC453A6F3E29488E98DF9D6A73172CB40B60219C1A1A52C3F1C27B4837DD1FE90E7C9C1E3E67A58310C44A520E6419ECD973DD08521E57BD91B12F205F6EAF5ED84A74A5F4890DF40BC3427E3860DD729F18349B1584F9689280C4177A0D89020B1A1E26C77F53766DAB7BC0CB70439BD0AFE370B5D192F412B1DDE3E350DCDDF967268C28C1014BC4EED6E6CA4DB2E9CC319D4CBBA7F7A35102E36E38E5C3C8A1322B4E59B0BA23AF2D9AC8217D4900BE495D77969B4FA8C27A4F842999154C1A25F84D49C392C279BB152176064F5AE2051CEDE91465BD28F9DDEF5C52059CC09EB204FC21971FB4A657D17B1FD3F2229775C4B271032343A4920C610A978A98363CEF8FFD58BE5D84009E8F916912B9769E4722FA316DA0FA9D28603EB26C85F8A58BB64EE60E158AFA976D5C769F4F58896CDE30D36ED6B280A8394D88435DA2BE27A1EBBFBF3D11C791E6E9891C58C852C71B04F7D387D5DD2D02169211B36C90DAD6FB1CFA39EE6E6937B984D1FFD646E4574CEEB4161DCBF6E2885CD85DB82A2DCC2E12E4BBB06534F7F8D75AE86378265FB45F11FC96F7F8B8EE5B675565D96B6BA0FC386A13967E0A582496A773A3A0FB8E2E4533D72A0A1A295445432322A4409453B2DE8FADCACEED1E0858C04CBCFABAAA04B350F096744CF6731D31C2A5ED0E8EF8A3A1B859E847E96540750F5A02CFAA739F801D1F9696E8DF193FCFD20A00C11AC63F417F3066597E6A7966BEBBF0CEEAEB38D5D37A2E367A25877254336A0F7CEFB4F6C3FD60BA7CDF516FCE9E94AB2B9A4465B94AC0B8451AD3197DF7F54C1309049D9745ED5E82E2AB6CC18627969CD3EDC3717B63B90CA4811BE31EA7BA12787B09330DB5289A041BC6A1D53CC8E4B891E553DC53B61EE663C8885895C13F075050A13C890E65D4C65E36A7A9874EC7BAB496BA618ED3B4ED138B3070DE8004554DA1B2192AB27C381F3D2A04B1917FE1A0E10DB9ADA50CB40AD8538CADF23F01A41509C05BEB9E1DA5A397DFA15C410487E244D96FF8470C12D0D58B579CE3B85006BC539FF6D9ABF7DBD7AC236A92E450C0C909990AFDFE73006C55AB0154C511B9B0A40758C1C7FCEFE9DD2A1BAD275E550853B7AFC8076FF12E06799BBFE6D3D9F80DA0E6C810820C4803AC3E6349030F07D8E7C3BA6A901A96B600A57DA80787D16D81ECD4FBF69CFF551593B8A7288742129AA9B6A678B3FF3A6A8FEF26C3C31E9D637654B864C6C57F42276EBBBBAA6ADCA1C1B4E1E08480B9FAA368DAEC897DAF2BEEA2FC87FAD561776E5B00DF05BBAB263A0129BE54ED7DA68A3AB79926338FDC9744F65F807097F5D55080496053F7A13BD243339B618F104DE940ED81EA9539411E22052557EFAF0F345D80728185DF02604FEDAA9602E64181F68F8858E07F2446586806F1FDB6B41F72737A069380103EA0CD231207507AD86AF0C81C06F87B2531F9DFAE8CC95DFB3237FA0D4BCABBEFF89EFB17CDDC25438066FC4E0019F577F51ED4D77874F9E801A331B99B4A7F0FFF91DF7DC462F2FEA85B45F42A3C3F8B22BF83B866330ECE64DA6954ED3FC8BD4DEFA54C8ADA9897F3F6D8B81543556CA7E2948291285017EC3050ABEFE8606AC83804B8F081F1CD5ECDDD2364B8698042B8D210E3A9EB129B88C7F630E4A146486406AEDC009C711DDC807CC68EA31655C6E51CBEF5452A3D1E956161F3E916156059EA14A347FAF521418869F93DD69E8023F89B7AFA4055FBFEA0B84A7974BB556A40BF512E415F2103714DD69C604A9BCE162222FC02C1A937628C1CBD662C9543A86204E47E9793804C7AA3FFE138E2013945DC3660DEAA7D3D9BBB4639BB3DDA4179C5A56B92238AAB3E3C88FC83FFC35442BFCAA890B1F0BB63424818AF2244F122E8F5A9CFBAF1E678144B57ADB6B11A56A64F662A90312D61A483356D525013EFA3EEE7D9D00752F9BA610F0946A4ED9327B5394F830890F24213FDB66310252B5996183CCD90265B40C27BE50B24A1143756937386BBB21A3ED29B2ED887D0AEACE854312BDCFC20CD74E285294C2299AAA8464DF211278D92456E2A94CFC7A6A509BC0CEAD9831E89336698107304D506AFFAAF6E0B8EC8D729E86FF7C5A4A9FD6D9DD1BC1A6FB736C6E136A2D874F60021A9012A9C8AA01A7FB3A3E52BB01C2DCCE064E78F48FC64D9B3E456EFC6C105392A93302583B7055A3D0ED3C168C0AD2516E5F7E88C486CF93DEF32052B432F6B3462424E2350E2F232A00ABFD51DFF05A6E7F6AA588D514A1C006D59EB774107ECDF9F13E1DB3BD4DA4099BBE035DC147AFFBC20A16920225A936363115C542E46C1CA3469F11553239C31B88D0D1A8D9D2F4CEADD400773037588CAE7513D3AB6D3E321CFF225A3295500EE3C985AEDA6B09C84FD968FB74657C6ADD21A13A1EBBBC896D66016D39894866C3997C33FB528D2E2A521E33A0CF93D3878774F81872664037BFD179876A3CF9ADB4D051B7023B7A18DC0F5E686C160E10AED9045C7B96DA45FF5B7D2AFBEF3EF797E45C187BB05AF0DECA058B3C1A00EBCF8D8BCA7A6C63C5CFA0E6ADA0400E7748FAEF44B24D4A52A36711B469BF97BF18374853099D4BD197034DDD557BFBA92BA11C9899FFAA452752788905F949181B456401E5A0DFE989C1DB6BB51514DC465704A11F0D7CCD0F6A0F7F96B333F8BF76217DBB71CFD101233BC32BAAC6268C2E26DD489EEB5108A8832E48D98EAE3007F9F6344A5107C34BB0B9E815F5D52AE3ECDA06AC0B594ACCF6236DD09C48D07F636023CFAB3ADB96D57FC79AACC7AEC4AF4EE078CF5FB5AB277D9FD613701EB21D4D36FF052A09895C62B1AB8DFDBCB7119E86AE79A1776627989B0D8BF8C0CFE3798BA4B5E8CFA0402034735CEE01CBEDA15BEB1E12F521512AB67739EEB9784A43EFCEE4763EAA1646C625D22B8E8893F978ED3AAD05887446BB00F926BDEE032A857148069F37C638ED494DFCCABE34D7EDC84E3888A22BA0DA4DDBBEB441D0CE83AD65B05AC82096F1ED65DAE9D20416D3A82ED358C5255F7D7E6D21D3168863247EF1B23E0452A5F3C90D98B90C706725CC4650C2B962867D290DB242307FDC40AB83111B0A7780BFBD88DEE32F70FF565793574D8D07EC0811CCD2EC98C8605E68D455E922632FE820AAB5D657CB71E437F3FE7A5A4B1CCE955C897AE19C60CD4766EDD2E85C81566F864A83CEEDF860C3B41B059633DBF9293D434520AB489F0872B9F8DBD18EC6B88FD0EEFDED598418702AA5AFE6108B3E6042F8EC151644831A9F5CB5FA942A5082031DDAD17568C7D8EC3B79A05B6AE7C8F44BD209755F5D6597BC464338159B748DDAB3ACEBB1438B8B381EF0FAF9B41536A92830B070433889664F8F032FB97E81EF6F63E211032E520774A460A62974C7F3BF87F2EAB80E2B58E32C68FF0B5D2F0C8B08C34377E3F6C183AEEB13E5BCE9C57E80BD255BE43D1E002A20E455B68F3253DCF8B5EE63DE05165011DB55FE77F784928C932543B9562839ECA8C5A41DFB5661019C95D92C7DAD3C85F380ACF9EF7FED002B4ACCF84AE7AC7F4326FC9D58F206FEE93987FE6F5B478B177D1DE802CA17957761E62FE15AF49AC55E3B2F92A85C15E03E7721B5693AA992EBF0B55C71D286C43097B7C9851202BC61E7F7783A4B0DA10BCA128A9611A430323C1FB5A51057DD71100A8D88707B0DA08A75901BE4AEB686A9E134C7CA7E05F3C3C843A9106429BC5122B5909601B3040570CF89E7B028BE8F21678F464D04539A9921615C4DB50843578E07B32F3D8292A98FC8823836A57E4CB937356D35DFF144A081E8C21AB87013A7AADAB3D1A0646DCF70656ADD12A48518DA3C6BA907A4F359198273E25A17466765EC8FA6E0DC36CE95216CC8992E934070A41778F212A3B44110C4CF324B1C211C2864A7E8AB402A4E235BEA23F7BFC79551E5B046029A5DEAA9DE6EEA6D657B250BA8DA8EF17AEF93F3D8976CD966B9ADADAC40F9DC8AF19FC763DAAAB48302D2DDA2C434185F45B91C5531AC2E12D1554597A3F1EC78EAB4BCD1DCFE744BC88200087F8E28F44DC76783CC55603A08600F028CFDDC2C679DF272BD5FCAA4A585064CD067E8D722E0F933051B6D5B69C2C61BB0EA9B8FD674A1D3D73829764D3298AF06E09D62C3187B9B971ADDF2C542B54DC4162FB45CAA6F93B995E7D8FA624F19EE0512E80CDD6BCE2A30D423B2DE6B5ECF099B5788E4B741CA77E3D31ECAE1ADE65EBF6C9CB65FC3B0C5028994713EC90A131D4849AA5BF6F18DA15319D8FD8B86D9681B176B4787A6A920E75D4EFD295F5A900F0BEAFADA5C8BC46F4C1E83CE4B3CE27170E43990604C5B28C64C57A39F38D7B40F0332634DD5F76FD5008638B586A836E24AC49906C8FE5A559FC814A5D2C714E72A6CDFFD23490ED174464C5ACEF3158C82BBEF027EB8B6B67D6584D94969C5232C6105F877E15EFD5B954F950DC5E64A38753305BAA876EDCB3BC5C347FAF276CE9A25891925A530ADD015A64CDC1A0282177D9B4C9AA50F06639ED2964B408FE36F90B29827C59F6E08D3B953C84AC57DD160CC2BEADE2EC22C15E46FCE1B808727ED09CF9C33DD30E7190A5B702E453374E0045D4440952D93EBDF5417EF950C7B5FD8DACDFF9FB2607BDE25FACDE1F79C034C581EFFEA5E44F4FCE65468AC36B8881F1DB03BA3E80E6FBF7B7BECACCF2D385037AA9AF3F96739604D9D04FD7C00C0F5275EF7E093222E3192B8C1B32E935BAEBCCE92C964349DC4B2F7B10082D49D345F8109EE95640502B2C0D1B7C01748BCFEAA7464B8D965AB9FD4C7F31EEC7110A6A5EBB760FA12057CCBCD96E322BAA5E8E697986C50775BF1C428BA95017347389915BADF88B1801E33CE4A2FEA2818ADF95C1D9EBB2E8A178BC6AAB4441436FBEB61B0D6D28E1E18E8615AF55BC6F98BBE93429769668D427CC609C70275D3A578D4DAFEA6CEFE775F55DD19FA52FD8C01B2C95A2E59B806636E86CFB25A5799BB29684AFD3CEB67583040C6144D41329002C7159066C9BDA2E80D9DC0015964D57DCDD51A587FA8282D4DF3CF1703E9B6557829E9EF2FCA890F6B36D5949E1EA0958540456350EA6DDBF741476BDF3F671BB5B9585B27EEB794BE7046EAA0BD484FF8A4C2D7FC37020ADEF3A2614B2BC993504EB2D3CFB1C1B650BC656296AFFED86D1E7FDE5580784399CEEF007FAA81F4F57938937BBB42EA16FB8AF8F1F89EC73BD0EC830ABF4B6C69B3A31D0B79BE5D2FFCF73867CA73C7C2673183D29B43E3C1F5B55FBA9617C05E1B8FB14CFFA4EF190594133264D9B20713AA58CBA4811428BD8C879770C9B4FBF7C2924B368EF9454AD08189D638A1365C1A8F9307C72C1315B355C57E5DAE3822401635B86F04FD80C0AD7E2A6C4F1EA5D37FEF28D54D3EE06480D7B809AD843C2C56C551A247A553A25101456C0BD49ABEC37FE3ECFE2C151F2D7E49D0F7CDF663671FF431CEB87A8149B521BAD304E34BC3F01BF4B948D88D1252E63AA6B7ED6E103575A4E6FE5EE9A5DF1778E6342F5066EE95BD31FFAE5A93E0ECD20128A3BE4FEB0D12B00784936DF47249470816F432C85499BD6FA30E5A8F019FFF9C6E71F37B1F93CF8ADE439F1DBE6745DAAFD22207233B99FBD1B5D0A3D7EF9EEEC629486B4D7B9C9E2CB189E24AF51B4AFDD7DE7DB5B8E717A3BFF44FD95732B978F88CE3A279ECC40F733BC0C93886CC1B80686ADA348A1083011250594E2C28457A9F9EED1694A40755339883BFC711F1AC644D4B3B4485F8CD5D38155D66A68160AC179B35B07BA997AD02A9F97C10689E72C4C311AA95F0947D37F08EAF54BF85CB25B0EB4B52B005FAB4423C40FF0F9C48CB2BCFB9E4795D44EDC719E15DC3CD096B6BE5F7B2E9F10367DA34E53292B403815A9947DD8AC51B26D13E120E77798875F4BD8192C49808FFE41747F23A3055A551DEE5F9AFD809C40AA8DD5384D7FED536276A7FF64F068BEE5D13A7B9B806C796A81511025425A2005795DE6634DA2249636D9CF519347C7F7EE9B37F7A388CF11E13843AC8053076CBA2EB3CEAB7F47288674EEB7475ABD22BEC2BDB418769D1EC0950B79BF7ACD5C466D1FA640535127CB27ED2C31A1306363657BF3FED32DAC19E9DEEB54339DA1E131A9752DA516F860FA4B7758DCED626E2D08326E79A99A09BFBA3C823D0626B12B78BE266DE71965264870E7E2EFF1319BCFC58644E35E7723DFF2619B303C081185D7021FAF0E3FE9153B31534D0D5D0175D1524984AB596BDFFD7762B0A8658CE7A744FA68BBAF219BC0547D4CABC44D4F124EC683E547B06281DA227DBD1B1641F6EF0DA01017E8A97F1EF570C57011A99D1938F986729C15DAF0A59ABC1BF40FE311715CACB7041BEB6C3E15435BAA0BEEFA7E8BC4BF7E5BA3D9C908A8AA4CA799DD90F02624FB9599D1A58B2396ED7590C291317BC7101B24A9A54AEFFAE8F3993258BE801B1282D3D61AA46369DD34CB5B1D9F72F2545FF51AADC96DF171711A6A35C0ADB5100E7A74C318F8CC29C8B0E6C3981CE348E0911E9E13B41503AB1ABBA8F4E2C72F565A5D8EAB1C0F67E7E940AB3578296ED0A5D87091CFD6CF0123402689636B31BCD20E339B5A4F2653F670B2792E93830EB599AF5AFBF701E645CDC55F7375327F00B646A2BD2570EE43F6BF3083B7C8723D6273214D609FF3CB5A5C7EED1FCADAC357A4040463A2E22640652B900B8F2B2BC8BFD1F8B28C134684071E389B58D8605AB373450C9AFFD1CD474E744F52560039CC7B764D2689E807C413C5835E78C4F2FC9F8B903E415E2A165C54567A1820E2027080ABFD173B4FA1F195E7418978436A7EB3319D1611459F943E50631607DDE5A618D0D18D43D73AC9DB57F08BFCC5B873F27EEE8FA9294EC8098F84FC213CA22AC75C39E9A52A9CDBDBCA18D8455A7AC302C1567C5C7C946EFF26B641798B8F950489EEA3A77C0E11259FA91966315D54914D71E4471EBE13371F7E1563EEB530A8A0B4A3D935961AC7207BFB496906935E43663087854C7E6F94266DFAFD64C0377B0D92B7F5BA11CE28B77D4F2932423F34EDC7E23753C3661C150F03B8617502ABF93A0BBBCCD463B9EF4B0362A33230C2A9E5BA9FDFCA115C7CA98BFB2ABE5CAA7EA9A7F16D0C1E8300C210FEF0B3C792DF7220EA7B71A14A4E484CECF6A61BC635529FE8B958222DD3C58568858AB6AD52AE8FF76FF75E80F04EEFC331E61C36444CD6BF112FDF72A42AA67B4B2C434CADB7C40887E24EA0DF9067AFD857950E5353657918A7505BBA2A27C19CCAA3DB51D4BA26AC59AFC9AD7AE4F66188DF942A5A15090BB560319F12131964F8A905B55143C9BDEC21807D1CE7B6154A8E6E3C5304711811C13ABF96EC49383BC5F1954B6FCC384988C3F43FF8B96458A2D07C445A16D2BF61B9D388F8ADA1C3F94B2092D02BF590C1B5793DAAC80145A1394EAAF9404DA38E485AACCE94321B41823F432D77CD1D36817509CE98A8E73A6D26DA94F44E25E110337C1F618CBB3ECEE5A1810094F6DDEA5815B3B7FF1D072DB69D0574ABF3F0DC477A4B40F8D7B472FE6F0D302812D276054891653EDC85E17EDD6A1889DABD91D80DE514FAE1108CBCE9139293875AEEC1EB1F0438D38A64AA07DB31A636C0A6EC1BE5C3A0B0E4782B745C71E36664FE0E847BC5B5657058CB7FEF1F4239555827D9D98D0BD5F2581669262C3C7A72FAB96E3368C991505574717D69AC7903D048E59E63F3D14DB3D8CC393E98490F0F5D92B898C940CB8167354D1AC3E10F10E917AFA7CE0C63C0378CD5D75288263D386F549D42EBB2C33DCDBBC5CDD21C36DFDC0B0E1E6A8670A254492D8F304D5E06E565F4AAF12723AA151328DBE51C625B04F70FF377703A45BFFEF7BB02912BC4016EACB775DD5600382FD5F0D55BB752122CF5A216C6EC2830EA22011E2E4E7C52D555403F5995293C1EAF2BC9AA2A9440A14D77AB0A464DB517EF84FA14AD2008DFD22981ED874672782EE87C0782D02D03F8D13572357E1877749C80D493BA1385390B79A92065D6C82F88FE510266B340AFA06C11C421FC5DFDDD97AB2F3A98F77E2EA6FDFA5487D435E44DF0EED628EDAA7F401F63402C2DFD6F5CF1A26EF98A3246F96F2F6169C07BEC2DBBE1902CCAD22E1FC54F5072E06C53922616448126C2C413A7A86E29AF537278673FF988A1A85C7B17CA1B49163C05967ABFF3719B1AD5D8BFEF37E706DB55F0FB694C444A55FF9F9F3BBE77A5C8DB34E65982F55FC7F2592A1A023A41AA4E416BAEAC0E1A7A49C13104FE4E177942BCAF3ECA238A5850BDA00929EFD64C1F60EFFCDAC53311A3C05E0EC68002AFF0203C33A9CDA7249F92BDA23DE9677BB9BE4E5436C0A7F8CC831CE925414C9BC803A51641DC5D9AF3208378DC2C9F6CE97223E6B0E696B6E02DDFDE96C4F12A60EB40D371215ED016838130186114E81B284E1AADF122D411227613D9076892F6B39275DD8B0557DB640B119B32EACDA84411826AD88A65350612A3543CA35BCF5F42D24958B6BD6B6AD5325FEA702A080E3F4E0B90B72D2F7099E6B51399C5B523CDD3E1733E6ADF26A0705E064A8F764267C5E0723D2CA59CD87D6D685A5B62829AE0C4DED42761CDD568B6C6A0910CCCFC3645E3AC222816B40B5A245CBEA5AF5820F191C5488DD2B79A2F7E29B94FC0A8E656B8C6751A8BAD5B95E8AC338789B2D782A42246A3F1BA4ECD7E4A19C8C548AF999D7FAFF7D436AEF0763A13200E07830AAE5D1EC46AD151DC3965EC4DF098802869C500FEDFA9A8B3A3E48537D7020A39A62A92294C3824CC8506858D8173930EB197088A04D980D10734970BBEDD403AD2FD80825D9C2912C9976511AD2D3EE7CF6883F3E416A949F8F57116C4BC2A80596550845AD9B88F88BE49911F16B9077827920A766AE774AC80B5D0B25BBAD6606EC44103FD67A62EA92DB22CB61E7C767E335076396C55D8EB9890743134ADCCFB9AF1485CEA53A8E62B96C148093AB92B1D889AFD9531BF141841FA6E12AC5BD46492CAF4D8FC248F65B840B6258DB6C127B92928ABEC451C907DF9C747D8A980A04885DCDE061AA15AC3888EF685BD79E40FCDD00BD4F813A0DF80F9520C9780FFC7E10A4E05AC98159D9BEBA284294952490BF9C233E23517CA7D938E73E620997412B8DD41D69AE7F5CDF4F9D7891148A0BC9DF1FC014AC29E90A7261FA7A1C45367A643F98A8C3E8CBFCC35B95E19B3AD9ECA9AFB440FC69F10DC83D12A854558293C135F13712985ED3E70F2E2A59BAEEEE027188FED34CAF9AE0F1C60A68457436EDFA65870FAC6B9AA77FC6A2E1146B8676448598EBEA64D24274908907621E3173C70D87AD69CAAAAE2D489938C4C726A2D7B7379FA9B2843BB99FB84F02E93AE8B6EEA46D45FA58F389A34969224514066C12C11A7E6D46FCA8E16589230371C3A68F59F623E58E665D312AF65481C595D794030CEBE48DDF231747FE07678228BF9F7AA2A730D92976D66196E533EBC967EEA6298EC401FBE801558BBC231F60F7FD663BFE7FEC1FB75D9599FA50B679FE983F779578F365D93100CB5433C12CB0D05B8FD843F6DC44E1E1A20677406DFF4AD2DCED65B676F5F9676607D7EEE72430560423459CFA5EEFED31AA0173E02360B7B4E324CE606DE0DEFF7455F2EF9C17300E77D6B893707A5BD0BACA9CFB07CE0B6B30C48747F9BFCD6BEB753642222D14F067A6FD74F0726F4EF1C2892D375F8BBDCE7F80FE0049634FF4E3C0257EE82339B015526AD95FAEDE42868490A8BCA1B6974FAA4D5DCEB5930DEE902696CACA3C01D420363C81A1D58B72DCFCDEBCA2FA6E30E2164073544615451C7206DDAF933A052E2F5E12CE8FE8AF9A0E2BDA5DB61B99074C254587106FB964BD72D2A9A482BA007D4384467CEFA14FBFC045C68883208A7A1A38D896E21F7CAA77C9E2D062D9A08137602E441D3007D077980D4808BF1E43070040EAF04319C527B2FD0A3FD3A4941F4E5DF7C2E427A7E58E3A22AAC932B9B541CDA4C068FADDDC4C95971BB8026AF80EA2BFC779A6788B06B6D53CE8B15AF8B909957C21ABD67217A9B2FE3F520C68C8ED7AB5F26022202D04247131D6F798EE3C629D515D8D6A77F8C4909B34D68D03C145FEEE2E3C1BDA7AB073CCD9981590B71FF6ACCAA1EBE40712E0AA3914033EE6FD7C31726BB2D49B1ECB8DFC7CB9A46FDFA9D9B42AF6160D5C13A357D0EAF8FB006100BD9B01C195450FC4EA770DA9E063BEE54744F7828C7D0E9AD533045863BD21448224594536F4B9026C471AE9C96450F9C12931C62AC01A454986AC6E5E964E55BA77109E4BB82200C9C9EAB6A344623ECE7C08E354DC7D322504286A2A23C5E0E6663A53F3F25F92744075DC9543CD229595CCD9F6F89D42F82E7B24106D7AEE821C084101C3B2CEE8E07AFC0C4381052613F78A9488A2C2CF2D6843EB69E4FA6CB12C9311E228080F39FECAB9674E007CAD6E1974A73438E530F808B0A3FABCB2F7FB6396D0A85CED108E8087604D5A3D87F5D4386D9F83232B65BE94B0692303202C24398988B1CA818E90A7FA934E57A9F4DDBD83F3C63B035911A17CC921D546C833E5EFE300C53759C7F77C9C39033E02A8C8E8B97AC12E6E2DD9ACAEEE306F89D6C020BA2DD85B1230B69981AEE939FD5F9B4A0D6C55A01A3F826A259B2CE6FE686AE01ABE7C6B90151A24FE24FEA9D81B376DF268491D0A8E1B2F2966F88D86937F24A976B895ED73F3CB3735393277EDCB65731DC68ECA774FCEB1D1468C3A6F5909C6D71E6369BD96E0988F7C440A1691BB532E177C920B388694EEE9A59E2E9E8D08DD931A51B10D8D9BAD2CF32D5C2EC34B727FB699A76830BA6B0F6801CA73A6357F71F4871EA6943CB4B3884A015B6A34ED6FA1CDA090D51F1DC1B46053EAA57774A025B38CDEF52AD3724158DCD687A28FBA7070ABC158F995A1C9B71D9856FC21739358344A57AA603114E4EB94189E047A41C98ACFB4D6F33A10397D116E424800A37E30550D922B820A88530CBFAABDB9F16B909FD9FDAE45DA4A692A1A9986D8D72D7FC90890EF936DC03B0035B1605D952AED873E19843963B87B37B21B4390078D4499135507140BA2DAF3A94C148CB603082575A7010BE1226876B9A9534A579CA84EAF482C3D8F774A5704CD340709C656E196F5B9ED58ACE9BC785F0FF7C130B4AB4F4C47803031565F9EE54B30F1092222E340F8C22192D68C7B760D246D355411006414A33E103EEBD58891EAE633FC86057B57E44BA6F8099347F9088ADBF07C3E1E28644AAAB45785E3652481D6C5EF9B14C3953319EFDD151167CE894D1700EC5B68F7074CD075917062294A35B56913F9089BAD6FA89A3EB2C242992E3650861609B4F3731473CDA3EC7B821D0417F1C6B00B11BD17C8448D1CCA0CEF1B3C7E6123047D0EB9CB9071814092E564947A439ED65BECE2F6E286FB5DC309BDEB7F40636D68F0CD17F35AADBA87D79834C82C540642C3EA34B295519A9C76538390383F69E5E7563D4C9C525A0B58F953DF1B7919E75D67627675410C5E135D15058CFCCBB8A02DCD01CD167BF2F45910915A9604311A6E2AFE4504940EB870C96045EC04CCB746651F7680A043A26C61061B5A3267F0F6AE3046863452BA298CA17069872D39E2D1E113A84FA90EE353A469F05D46A55C5B33081A31F7B338306D999BE917974C83C9FCF4F0F0080634072945670A88FEDB2A8C17AB9099DFE989E476BD0CFDE4DD27B91122575EF2ADED0B047E5003B31F4CBCD600827C874B20EE3644EDCDEA1F2DAFE2CDF26B7AE0872804B96DC386D789E140C5C795C359811FEF0C3DCFFD66FA729052121BEC914453B3B1CA29D7FE0662A5E8CFC1E26FC07B2C4498A152654F3D1D0EEA8A5A01D1DF8A07BEC6563933F6D1ED2853FFCD22EB91696874668F024C8D1F7E9ECC2C62E368282FE10A4ACA49AF47D9CFD5CCD5F3D4C1215A73A9AF2FEBFEBFB70475D3C2422BC64FBB4B78A4060FE2060676B73DF7F018DB061249A73537BB147AC9242FB5881F0B3DAF04B93F22AE2DEE26C6CB426A3AAD5D551CE6C8B9829F5A6FDADB828B36E6D909928EDA29C26D0735AAC633435A2524E261574EA78872485BBCCD7B9A776AFA038143220DB411EEA895A3BF03BC5ECA1D7CCE840C2CD49915C3A4214BEE09F94C3A400102A51E8D6B986981A25F60949892C1364E526C38400C2452B6247196D2A0E70EF4A9DA2AD569F115D819B13BA126C1447DF6B40D3659DA9333EB5EC332DCB29A6EAAFC1B41091B642A8E734509CA58CB96A7125833C5106C50B09B03C31229A65374ED4BBD2393372F4131DC892E1F02FBE98CEB51981AD7CD3F32A35773A09FB8BF66AF97D367E0DC7E6A8B8C0B8BDCCA23B31E9D9CA283FEA9663B17B5BBA2D84062213AF1DA052B9618DBFD2D04A8E1068DEC31E08E7B17926007C65A6EC22B6121E3B0967FB471A2F6501F24D73051FB2DA3A54B2823B83A3D8D681FE3B30D50427CDE77036EC1049E898A7DF5582CEEB7D9F7C4E0F2F035EC1315CC16AB8893E9D306D42F3C4BC3560400D2633B9DBC6E1CB1808202EB77B88AE4AF74FCD0F14610D33778F6D82BBC2A23AA1241E5A087AF9DD942DA0E49DA7A6837655B48EF685A9DB28E5BD6EF5CFC46D3A856630E2D936468FCF732C609F7221D638FAE116B33C4C1AA44001EA292AF356D844A19D14096E48DBAB234AA43DB893BBFDD2B094332EB3E0CE1D487877644F4D2997DAB243D93AE0F8D0A26AA33C7BDBEADCDD25CCE9E309E524C75C44F10E9A8225004DDBA8C7D8BD0756CA449D4E91888E37F97FE48B93795A22693E02E9556EE979212D679C4F13E99F782285ECB9F04E7F33B1F5E617615CB9298C087224C8B2FC963A9CF3B6E0BC84914CFE0893EA44DEC000BDEF5721930B7B38E96137C4FB680CC0F52EA5CB51126759A770D0D0F08B20BC843ADDBE0268557D4AB505EA39E10EE626DAAFD23AA560C8279FCCE1BE05FDF289DAF42A66282C8EA5CA9410A1798A850453E1AC581D81013D78C7F417A3FFA975A16B4534E68BB0E7036E9851062B15B0A7E1328228700C47129925544427539D656C77DA758BCAE459C8FC1A8A286013ECF29E3E2DED9735AB7F44EA23F9A3197D721FCCEC7F06E27BE1A129EEDC13DDC9E06FD6789DCB9EB8656763C8F661A467DF6645ADCB9E3EA00830BBC1F28C78E5D1C6DCD655E7887A6201C3D81C0FD2644AE96C0B78FFFADA6C02112C9C9DBEAE992474CA1223DD23561861F4B33A021C8B387C3960583023687984055F8100B874220D65286ED84CCD7A3A8F14DC02CF38E03F86364662D80674AA90A0CD29B4C129003390589EC7AAB7294F5F4BB7F9C2BC8FC41363B736D1120739D272EE6BA1C40E67A2F059DCD089E0B518317742240BBEE8974B2E2B46013458BED7CB02823940FB56C83B44C1237635E4624D2D00489DBE0435FA510FFDE9B3257EA778DF9F5832F9E2EA882F4AF976C2553DEF59DAE835645F5585C5FBB54C2093B492F172A110DA5DC2586B41E6EBCB17E0E7D3FB3D806ACE380A4DFE5B58F2B1D0B720FEB1905F30909FBA722455AFA1A967A46AD7F5FBE769AA42FC6B2992ED5C826EE43E769F13803AE1A05B2C33E4731930887AF1351602D41FABEBB63A51FF6FFC41C1B9C9E5E6D134FC72047226E68311859FB439C64580431478C3BAC31ECDB42B8C9EB3A285C562CDDF29F7F4E68D2B01BE5D1C5519E5C2F77F5BB78675C719923F4917BEB59F4D0662A82DBDF882DD6A73DF753212B6030F7144A54AFDAEFC9D0F5FFCF3F1D53EA79F4580DC670530718E2C97F405D9E6E14D4C009B3ACFAF1B9D1E3C607534AC972E68B23ED7F3ABDA600F1E060921E6D91E82DA9CB95A4D2C81C09913D81C06996CD90168B3F81E2DC2FCD24414DBB287AE04AC13EDE313FFC03BAFFD594EC81C63C86858F653DFCD6799D6EADF453463AEDA7906F254C4CF4A9E835D3CE67C249293C1B5A8166FEF4008DE7C0E0D4AD0907D027532B9F58090E30B7F072FFBE1EDCCDDE658772AE3306A2E02F30507691DA97BBAB7188F5EE543C45EA1B3E902537DA330A8DD30270CC9FFEA3F4C712E9562BEB2800A86B806036E227BE38AB2C23C8A35E79968000DF5BFACA1E007097B0FF41D104171782319F97B56315B242C5895DB2B5379227F13295251DD06E046FA59A255613A122EC66DBD5BC6B8AF6727B01CF2B7A0FE613F75F590C79E20D2BCC047EF1A3C46C70CA98EDD42DEDE3FB4FCEED7C7029E9B75171D5AC9F704A8AD168F01823EFA2FAE593589B8697EC3811F50D442DB3F598FBDFA78684C8AB99C8ADECFA75D451564F51128A8AAA95D4F82F35806CC3909FF7AFB5E9682B7DC9F78BE0ECA4A09D6FAE5668B561E5FEF648199A2764C78820DD3F8E9AAD6073756E484343EC022BA58E0D8BD1D7DAF85FDBD1CF4F60BFC888B62D944A58765764BC6A411A5F885936844BBD94494F80F05465A82B009E0F604A9829AA3C8A064F6BD0EA5674354E7C58B8B58A34EAE8D88271F62167CE29A60909B4A31126666A092F0C9DF37DA037B18E0921BE436D83EA38429E9782CAB403906C54FE4916445C2903BBC65AF392CEC297EE1CDAB29EC2950B16C8F11C0607E4504C6CB0CCD859FC04BC100CBF80F6E51517FF08618456EDC086C79B895BA6283831760B1FB976A5DCC52915D34A5C432BD36249F089930B33B15799CED061B09A5968F09FA03A48C861673546A9C2453A6B753383E5947AF58380C1A0F3B574D73A7C84033C0E0A2B5F0D6A694FFD6FFFD0BF65164B3E543070ED807E98F7FF8BE862A6951A8F21F29E9F0A029E76B815FA286857EC0B8C9FF6EE187680603707C951CDEB7FE07479711FE7568EDC473784E4094ED7A65C65329025CBA4C6614E51CAD37B40C016627AB25AD50D0F461AE5A81B89B6BE0C11308AE0E7237521DA41B54AD9D273A0D6516F6177A23014688DA557D3DBFBDCE826AC0464473765FB709A3BCB5588C8D098C158375D4FE45E94474214944FB7A728FB6FE1D073009BC66DEA2F199DB5C23F4D422B2526B34C342A8612E37BEBC00E18B8D5AD292BC0F1EEC4F64F46348816A9814C4566B8735746EDE726580890F290CBC6A5C35013184A9896658400231AF625D63E5E96B992F082395D508A41DAC837D9FFD543B87AD918906885827BBA7AD0DE9F3BB3943648B16E08072A8BBA51603C01882506BD2D9918B3A1B69E83FDFF78D3C4C2A5D3329CD84BFBA8E466375B21CEE34F6FB4181A40E94D1B0984F555CB3CD62ECF72AFA7A511D0FD9EC942685214E2A88BA07AE7C9471CAAEBADD4BF82F6C550F5EA5C3D947C5F2F07B59033BE62F8279D89ECCEE4C32681FC0AA828A56FAAADBC6D9944213E4DE1179390ECBC2D9B18DEE6888075C84D6FE8182CD028C78E1A5A1E6B3E0378AB069128995B96F533D39B65E97758A29C84DC102E385ABED291E0B147CA7E56BC2CB965AA78F2A84DC7D17FCF68A2154E704101555E01202A8091F296CBA6CCE87C9122E1D6AE0E18D99BF2EA953ECB593E1114A5436F0F6F23A4BFB363E68158D8F30EC7C9B6D0171C4C5E830FE6C26CC0AC8046B94300AD8791AF4E59524002BD01153C8A9B00D22801509661F95C886B439178D7AD9DA82B4A0E4ED9BBAE00008A1CFD6CE7B30E689A3C4DB926FCD726317B502E02F771151A430D3D552D31A00201100A40E59A71FFA950180C0A024C6808448202641E4ADF2BD100202919B84CFAEF14B91203DF19188512857D93A9A820400A0114D481CC25FDE29564CA4CA6326D154B88B591AA134DDD9F34376CFBFCEF57FD52BC059F2865DF268AD6047F6DDFFE3AFD4CB37DC7353725CAB9FA81FE4579B5B6E8ABA338A620B33FF2AA3AEEDB7A6C5957EB6CC9D4C4F5B2E2EB28EC52BEF0743496AA8E98648FF37F301648291B0D5E3C50EDCB3EF0D561E6B3696810E64F8F707E3733DB9B79AA7EDF93F8A80E2BEFCD1E5832F16C485370201147E5D830541CC6BB58D4C095F5D3FA33674E5CDA583BB5DD1DDB79AE86E77517937C069885D2E9A6718444775F234AE53FF18DF7E39575405FC79A9FE04657714DF8915EC95A98E79FE1D74CB3CAA503FED3E7CB369963E6CC81F285880AB7ECD27903450561E1C0A8F761FDE4335FC197D3B31281267F533D1F4B5F90C154862E98BF866D459672F07A40226B79BE1BA80499C755F53B0BDDAE79635F42112BEDD8E53A33D2DE9A15CD33FC804B8DC8A32D8A16E07E4FAEC3AE125E093F651C7E75D3C54441ACF153B30ABDEA7B87C60582A54864CC4D8938DEE696D808D874A6CFF9E93648DEF14ADC96E1CB99DA3AE00219412955AD6AFBC5D88FF54F1E33F5358E7E752230C950EC7223F935C1BBA4C94B94FC121BA44D6AFC9834ED183A2B8298E8004C1E68AE99E459F7F32ECDF46073F67BDB6E05BFB9E67C7FD65242892BE291B5E7A695B9BF7EEEB2FE836F27609FD3CDF67137C9664B68C4740651D32CA816EA13E907ED8CCE0F632B40730FF9BCC6C57710B64FAE8D78A718C87D6D13193AAEEB6454179BFBAF8ED407DCB1090105512CCF19D85E5869A478C19D45F76A3C95C85DBB4921957591BA689EF032E325D3429FA7CACE51A92E1DEE75DE5FA52CE8F3B9771652E1DB6F6BA9B8C5F45FD36793BB42F8D9F3337EC4CC1A79C57785DF4EA2835FAB193B9D792785A2EA235898526ABB3B370AA93DAB851400E61092F6472D5518574FCA657D8BD7B3FC60B18F77F1AA757B01B79C7079ED51469D72B0AAACA64919A869CBFEA3163714E6C5F7C87D9BC8A795D81500FAB2E53EB6AADF549CF290F5E0F15E701B0DFC729377B94672E89DC24A1A3F99AB06009D3A7C78F81BAECCF298DBCE3E12FAD8F2FE7983F88CB05BCF83ABB3EFD77C4398EF7EF14874A549BBB9A682BFBBFCA684DBFA3B6BFD533F708582DE76B6B4F5815143C3643BA2AAE60C4420C5F1406BBE49018A652730B965CFCB8BF0BE333E437AE4C4F8404B2FBB8C46797AA5E2D40361BB2751D4446D577A27F3F3A46908F90DCDD14ED94B7CF6B55DEF2B54A351C2AEF342EC9F988E97771AB70129D2F26777D9F4E086EBFDEB652AF46F383E5AFE9455642BD4C2932D76D8F0D35DADDF07312B3DB5F3A1641ECE202E720993CFA835DF10034A34CE0A0FF51FA5EA57B8C62B68ED373F169B1C2BE79C1CD373E170AA23DD2F1711B9A75A2A79BF13763606799939EC2355052CE05DE22613FA954CD221898D45778F93F9FFBC17EA716474BA7BA8843C09B35EDB47565B0B3C340A44B5CF91D6BE62E2A649C64D6FB782125077D3CAFC7ED8F74DA5A73E6B33222FAF29DB70294920F7BA2F560568A8DEB5B30C58B696D9FE78D59A39E3F43821419D58E490A42F903353BE40927D57F3BC148FBEC97EFD66DF174155DAA8ECE0B751EB6CCCF1935D7F05650A2DD3B588116B36D8C9CB8CB15630FFDDF5CA115CF001ECFAD0971BD47A555EF1C368574766BF2BCFE67D700B24E6FB4CF58F5CD6DD546F77EF1BD0AEAD74273520D0529D5F70A9A288E41151965AF807F972E40A2DADD33546FD48455511F4B0732DE4E5BDF489605F37B95ACC6A7C198F32E6530DDC18EE3709883EB1C243822384593F3588AA29C80FF654DAD3D50C0EF3D4314DD99AA1A8F95978183DEF1F5969B6CAA689E2D47AD859FD7FD270D5B91AF2DAB49C20C255A70306B81116A025FB139A503F5FA00CDCFBA13E485CE550D796DD4361BDCA78BD24CCE90F685FD5B2FE6769D70C9E7A801F707679B9DE5F2114BBA3D941B1FBAE8657419BFD8876FD205B788734ACCFAC98ED22B296E4EF5481D0906E57F21B660DA1300F57C3E167E1C3336A00E5E6B8E4CF19389258F7E2FF3A80FF2767E3CA4126E44EAB353CA66B71D376090998E187CFC84AC174B143CEDCCA0E9BB6C4B6C2FF34E847CF79D495AF45C1C4707AEB71EBBEE69FE95BD561C494F401502B0AEB474F9F60A31C5D4C18C894EC3AE36F2A936AD5D5256ECB59FC320B4CEC8A53EE520E1D421D17EE2507DB4630E9DA4A89B676BE6484D4BC83DCDD31CFA13FB6BBB22257D4F1EB5CF5EAE67F8CA8B19AEE40093B35894F3E408504684C8A5B57562D0DBDC2CDF4FF4FBF94AF577BD9A4D7F33337890D69402847605330660BD134E1C8BD82FCC8E4D2DAFD62BC395F0437E9774CD0D98014DD078220EBBE50B93BEA805FCE30341C616A32BAA06C00F1FF28640DF543EBF2A8BBEFE62C1325AD01B9F199D93EFE6B26616C2FA87CC46BC904C4B62C2BA8CD6D9AC6827B0069958E82B180EE7B4A3D1A5F0FC155049398D46EC6BBFBD0EED10B8AB8F38892A24BD2B85F0242116A1537E068AB06DB8F90D16668007CC8C1C0AD596F72B83E2BF4C0B855DED342AF921DF976D4D651827AD8B5182948DDB50284530B476A48747D2EBAF4A1B324FBB765A1F2AC632D5A94090F34DFA4B5DB9F49A1304CC0E8BB61A5657F5296CB7D804A5D8513C3708DF76AEE70A77210FE1502E31EA3AC4C7B06FE1D2CD3781586FF4C54493FFC724A95F04BC663892096EDBD8F1DFAC04AA93378A46431AB5B062FA290F2313F191D5990569467E1020A3D9F54D98018517E15C23885731880F71D1A65C852E867A588E03F1190173D6BBF01E8A6120D5B5007E914B8A63A9778BE299DBF0A4AEC10F8B44F5A402F667892D23BDC435BEB8E7C07ECC2346A2A6B4A7F110C552F3B7EFA0B206B3DF3A7A7CA4C9506F87A4DC9A8E1E1C3CC4F2E48DB3A2C7E2AC0D93A4FDC47AC445A07D4324A8C4131D2207187AE85EADD490EC21EEECB502081AB742D3C7D1697822B34FD0891C35E70E58E998FC24F761CAC9A5D0DF6EAA76BE943E9E08F7141B503699DACE2CAC1875D8EE19B2D21F180916C39DD62D718D12DBC1DD58980C954E94CC8447823C8690BEC40733212F9B6D58075013E88E308A6A15E23018E13A83262A88B983E216690A823260397881ABC36DADA5431AB5F6E5ED2180CB2ECA80D6DEBE70ACC54D4FF552DE79631126D57DADE9C42A4FA3738B1F4E26D2DD85EBD5BC5BF10640AB6E6BDFDA9C94FA4808039D1A7B301DB2066FFBEC0F1D706F0A1A8BDF0CD6B7C55D6D9A4768413B9C9B1B52B3A999CF7AD7F074785424D3169E2BF1B9D753DE8D8BEF0FF77F389DC2E06847870A748D05C1526FD7A0A3FB12EF81503A645EBAEC29A2A1A93F2BEC31605DFA43DD1636FAE299DC8A6DDA86A07A00D807AAFBF4574EA68D6608CE7A3F0B33093718B519E9489AD0CACB7B9A9CC1F4A457D5E4903ED4D9FA79B8D256160B93CEDBFFB4B3E8465DB4828DF2391F16289475C461ADA40CB88CDD7811BCA641B6E5C1094ED8FAACEBE58497E22A3941B566F9B9461A5E50963A5E5183BB6DCF65C2D19069D005967329BBBCC6BFB335BFFA6C8D091BA8DB37793C4B1E32A440961F72EA6FD5BD5565805A07E50277111C5BD2199D05C416012A9828404E19CADD36BB86E264DA3BF771A09AEB84E1D3FE13D7AAE177E3AA5C9D0C60BA243DBE27F03013EFA95E5CBDCD3A00146707E9D3170BAD37D6456A4F01D63A02825C34F0D88EDA51ABC2D178322FDD6B40547DEE2BC624946CE6DAE1E69EADA7DB2F474F460756AFC9B3759AD59E6E88636A5869B1F893D0FCFC2CF0300C54759AA73925B1192D0421FAFB6A23E4D75046AB4D5B7EE063313D628513A85640639B6FEE50AFB039DCE44CB18E5302454F174FF22AF51F468FBCE0EBEDCEAECE798D56704ED67587780CA1990431F3D22E118C868F46B17A110326EB146BBD7CF2860D8E59883C02E7A3AE512762DC7EB4CA59692943517195C531B7A2A8726C3CF7440A45044ED10E7CE7CABB38065193C7A0DFF743E816C12ADA92C5A32283ED77D1D6DADECED1FD156193798C039E144E96C4FE735ABADE8A0027C6554EF00E1806840DA01E3A764ADCAB54B5D4E8D34C946A7800E98180E8047FD32F710033FC711E66B2A832C0D29BCD7DEFD2B82F0E6B999EBCC1F5AC95BA20DA0091CD98E8EE81B53EDDF382EE73D2E22D47C8610DE1A664141996D3AB52D9914A6391802984EB91A73292362321B6BC90B230C54D5212828D83307F29D11A7EC3222A08AB49738C0DEF00ED195E4985CA865701C2503FFAFF73986D38A87037055BA75513C25074F521A5E000CED5AB1033F7DFE05F5971B35CADBCC0A615EFDF32FA44115730E5B437EE2F87E07084FE16F03B0FD3080B766EE18FA139E29230C4AD26605B75DD224BD8878C07E89F27FD33FB0BD5F3E62438C04714A59200EE0A3B6109E8CABBF5D899176D11D6CF3660ADAF3332B6AC4F3FDC9D57E85C62B26B7BE9A22AC4B42CDE41BC8322808400CDEDECBA9AF2B21E888ACDA2E63EEA302B5F545DC43BB19EC34B9C8BA8D311A751A8CDD7F55EF650DA5F5301C06B66A073B4014E51CAD0798A383476A7F6669D6B5E6AD12A35959D628BA66BF12E9CACB8703F9A4201CCA134C867D9D6720B6F599A22D2743F8EC3DFBD990AAD9DD6BFD857CC82D4AEC87E272AA6FE19E5FC8A60F7A47EBAEA3E0FD57B1C0FDB6064E241B130004202FA7FD984F93E692FD278C0E66BD1994BABCC25E3ED935BFA6DAD67CC9F22E5B81CECD3EF74AEAC1FC26D0147DFAD90B721CE44B04EEA94CA24F8E62366C4C966C73A1D96FA7DA586E22D7884594CA33D22BEC410E3B3F216707E55C93A4486F09A25D8189C7FE141C4F59F72BB0033892FB6AED6B2D2A8F752C1D835EA0BE13CB8F9823FEDC7BFDC7945B020D38F5D6A9065C2E33B38750500A85C9333D5087A1ADFBFA39F09C800926F79927263CCDD24E71DE1FE89147963094E85778AB0516299EE35ECF0520644A40FBE37B8B40213D20601EEE58B3D182A49ED7898C3063F152A99F08E05A54637473F8200C4259AA2F0F64F3896293366EAB467F0AF7EC0DA618DD95619294C4C84DCB4110C437FDA30EB4F059E5091FBB2D571B0962B1F80A552AE627CFBB8427A12F9AD0E5FC06CA460CD5C8BD45A7884B3AF82B87641DDAB855E367E3020A75B2B8EBF998FED8935846186DAEE3D75BB278400EDAFD1B092A607AFD3D5F28F146E7184C93697962665D6A6466284ED74FBC2A1E66E96A90DB0C364073B2BC6278878BDB4E7E39EB470C23F95902BFC8A31D4F48285726147BA27C3745F0CF16C892696AF9C8088D7BAB8ACF7E6D51FEFE973349ED9BBBAFE8DD5104FFB8EE1E7A079AAA6D4EFD42E638BF986AA96A24FF10C5EF17220C079550039B11DA3F974B5DBEC094D8EBAE617F2030EB6C3280C4C5682875A4BDC5FBC96C62F5B5705427473A6CE2F0F80D3A13D90306EFB9FD08BD9BEB649E79F9697D4AEE2B8B22A3F723F4125B7735FF7878D2CCB5287B2CDF1F2BE53AB4C03CDADEE48E71F588477B76FE5AE1D7E2BFEB9B69135883BC457E76E9A68A2ACDDE3F62E02B2C9FC934B980E20832804DEAEE3369C010683EF0FB67B42BA386CC2229CB1F31747E70A33E92629C749F5392B07C4A9D443A0B36ACBCFF0FA93B235509E39DF1FFD5463F02C2FCB9F15F640C0A1AFAA02D034D37C2851B62B57222784CA25414A9235381B02573C22083B3F362D36A8C58D377808091E4A15F7628965356826B86B854EB9556416B3B9CC9E2980551F0DF5D4A45222B91B589D25B1D7398DFF22271289217C067A89435C7B534B0BE6D040857D34583FD99CFA59F0CA658BA5ECAC7EE56B6DD2E2DFB590F69FD91D71628486EE05DFA9E049A1B2E395D1CC7B595CA4631851C1D47DF62E722DB21755DC99AED115537293934E662F85B6630A0FD4550B63DDC55AE05FBBDB1DFF62FD27F4AF584546622BCED60A3A64D96FF5CBD3F5C41EA366B9F0295FAE4033557A682493C8BD8F337653C7F940F0B824360C49C77017896412790D546DA6F8AB24096C16866B3CA02F3D9FDF5EF9E4C5B3F17979FC193D0A2BFFA75C81DA9C7B325373BFCAD20EF632B153B9D651646654E19D21334983AFD77A08376246D8C75E2037128EEFCB3CFC32721517C7A3D5E074727ADE3032D921BC5C2F5BFF1060C2007A019BECBF6D2ABCE666626B9FB1C2FCA911DB3A5432076E4A6F3E2374882F32735AC4263D96A6C85FF898DAF812A119DAF7F526C4577ACEAE6652872D30D06FDAE560F9E3AB8C61D4D443BE78A66262F42D39D71827FCE3A1B460D779BE4A5D30800162CEFBD6428E2B77055EECF82C95A8AEB1420112627AB0FC16CE6B6213356AADFAC48EA16473BAD4E000E9159ABDE28F750FA8F24985D66967CC23F713E11385F0857E2FBCCF210C2E714544E20A6417D8612A1991574FA9F900346F88405F9C4E5040F90169866EE9E5631D2D6567F0A5F90E1C3DDDAA2BAF49F6248629EF9725E77BB702A4E8482C332455C8E20FCF22982CACB0586F4AD5E2AD4F45BEB0EE94CAE46B7BC8AD6CADED60C0C05AA4D1C946F8FBFBA297FE10830525DFE5F76B1A365A4375B791EE8BC14717C5776339220FDE456F82B99A74FDFF123D7CD4BCCFA133CA992A435C0BEE574C853D6F7005CD7B4F1930F496EEFEC0413169AD1EA16A74A335D504F04E58690B55E785DE96B0C03DE2552851685DDD08316E3A2A7D06748210600F27C4D665791C6642D9BCA5E23063A66AB241B7512C06646FD59BE66F8E217728B885B02AAC19F6655F20E70C8A865E73CEEA8AD2BC5DF36D2AD1A41CFF477DA0655BB3BD5C571E1EDF50F6D781C726352A4E5EF962EFBEC7C0345CCDB7688438101BBD8B761D459E890F463EB86BAE22B573B05344213D7E248DD3F7A1CF5940CB39EBCAA1082116D6DF07AD914D7ECBC571F4AE82492ACB0F6186A23A5D1594378FC60C1CD793A7000869F774E72D0F66914817B1D00AFB5551F6CFF82A038DD54AC403D67F914CEE7432F0F021B4D35ECE0338AC110FB8DBCC7251BA03409F241E10612272A83059050BAFF8F3414C6D7296148C10521C446252450830D3F00077536D54B4CFCA1EB9A8BE566B62BD14ECB8ED03CFC2027EEECFF3FB0ACC1A38786A839AE7BF379B2FD948A5F448E2CD700EF22F29EAFC24B04C0970C4AED320A5CE7C070CDD3E198C1211E9A631926E088F7D2D485B898A80D2B3074EF8D2B9D93C68FE2B03CA14CE0AAB16C9476EDEDD513BBC071B00D87617F737B1364C487B413CA6790091839BFF3AFCEAB67D2EC804985542DB8F0E09652787B975787B09C6135386688EE57F410DE045060DEA27A79FE275800F9D2A29DD52AE1AED24573E8788151B7526EC53C08D75F4E87099E24205951492818E856408DA6FCA68DC4F0F81C16DCCB692FD58AF3BF6F74D4CFF0ADA24F805914C5BDE8C768408416E1EA4873A073E0AC6BEC4E93C7842485D5C4C662D31F06CD3967CBEE77B7EB8A0103AF396624FA765A0FC479BAAE3850C79C7C3DC8E7F5EA070F1197534D4BF680133BE11EB2B537F75285DC43EE1C874E2CCE0FDBB02279A5828B06A4D6C5627DD68B64FB7374F4C09A29BB7604A2A0E04B251C19634E44941ED0CC770F2B0965ABD1C8D77E7E096355DE3C3F0A425E63A4C337602C2E51B4E003A3BB07F269D27F35708D2E2596EA155E83C26A00020012D405F973B54495D01272E2BC86B347EBFEF74A3913CB3DDB3CA3387627D41C01BA9DAD5E20D923C8FFA784557457812663DA4FA6B59B585F9C7EBD908D232C1FEF00D1F67D401C74AAE77BB1490C81A9B57405757D7CFDDEB9AF8710CFAC6CA926A22C6E9CD99D984401001D82D273D27AFEF8756FB0BC24FD61A6627D4F821FEBB21C990DCD766C841CAB4BCBD45D26012320871188A7372D0DA34D3FCD45467548EDAB7182352D168F659F043734E1F8F17FB31615952E4712CC99BA62B0E6E007716529EE32371E87335B688E94AF0851DDC2EAD796F432401D2DF56D255DC70A2BDD09D2ED3EB2FCD1AD0BBA325C2E311B8AF45E738F79BEB4730D0D48A4DAF95769564FDEF76CC48116D929DB05B89BD0EBE833A3BBC41FBE0B835C17C4FFF667CAE412F0BAF50518DBDF1B5B94A70EAB8FF4839C794EF1011652D454393009AFD551D6F54A3DF77DD4686158AA76D205FE96042A56871D93A31E10D727191D6A79027D31A58415107DF137D6724ACAD649A0A8DF8FCD1B5A0A5E9348E748EAFBC6691FE2EAE5BF8F26B93DA4AD04037D92538F21A4D07B14D7DFB174D0AF800DFCE2FF8F6BE8009EB4962D9416CE00F3B895D4BC74660CB550F0DEFAD172E354028CDF0BF6759A8C3053CBE4CAD4DA32041F5D456F220DA4480B7EFC184F49AA45FFA401193BDC5D9DB8BEDCFD02CE6EE0B5F5C4CF96FB7775EAAC088CC45FBC21E03AD657414B94B42B1FC934F9221523E00DA36F30EF39A4705357945E5E8493D024C643A771B7AA6835014FB323CD54E9CEE1C8FA559400B6CBD93F95EF6B130396D175024F8CFEE2EE6C214D39DE53D085912B7A5B766B9916B30BEE562A47EEC161923CC17B9E03407B059B69762CC728153C3B329B4B235656D74C19D9220F2AD03E8F7ED89CA0F83E4815F70ABF79F7E969AADA351EC66EB765959E71CC33A4A826B39BAFB9E5F5BDAB42ADEFBF16E0B3A516E6FA4A34720BCF74B9B59DE96B1B6FCB6F983B6A24FD59FBC503AFDA09DB2FC47FB7282C929CE92AF4B28F39C8D717BFFC3B6404D785E7F723ACDF8B18C18E4B26F151D4D089276CE710B6DABCE6DF6D4400C8A6B338D88D33D6C9A22DF7F4AEAB4D7DFB7A356AEAE377A8643B177954C42ABE5571B29F7DA5A19AB78140B81FAC55251D5CE5B1BEFD5B54DD75B679B08B7F8DAB6997C61F5D73EABEE153772F3657945039772122E74BB40E44F582EBD9D492C1FFD2176091BE9676177BE98B6A041CE2615261E4E3E65436152A92DFC9A90F40F93FDAB9368A9E24BFB7DF1B1D249354910771B0D5D3F3AB8C079DAAAE344833A3F301F0699594CD5A47A9C8A40D6AA0BC2602783D50433D1720AA5DD324FBCB645F218A823747A7BB4CB7FB9C8EC3CD3CFC8124701AAAB3ECA2E85AFBBADC75C9AB00D15EA551BF7573EDAF23A3C5432312C939879A0FF98580233A8995243A2B288DAA16EDE90B94A4AECBA6C81A636E26AFDA052F7A9B4CE0EAB8B2BBD0CA7EB2CDA9997A5997F3CAA2AB1804E9BE40FAE80AFF3DA3490B9E917D47ABC50CE9CB63083BD4CE8EFE21C7F60E185ACAE5926D98FF8016E8FD356806A03BB3E67F8090FD250C31D99F47F74A009A03E4B8FA0729B827F66C71E7EF1AB37D82F83BE5D68771D302099C194ED6EF93C42612C194A1C0553FCE9A93B680AD918475AB96BFD04C4DFA9FFA17FD26672B41AB9838F24A915491CFBF3B836E418EC19B6560DF3E7A6EBB8DE1B781F38A7D7AEB435BEAEC92DA333C990AE70BB27E630FE3E927AA29FB8C9B2EAF8A98BF919E37CD8B29CAEC972F3B21793922111CD1FB507D6489A15940E5F54F8AAE8F2EB4DE8983A6914622FCD9A7B893A529469B8244FC46EEAB2A733814588560A2BF954EFCDD586ED87DF364092F532CA59BDC4FCCF81403FB883A7AF1353C5D6B8ECA715B39AEC8D1E5BE021C9FB29579A50982906CD287B8F4A1D35673E149896D027D461FD2C4B0375CE953E50711E53DECAFC5129EC32E7C831F4AC926FF5AECBAB1750FF504666CA20C5923750AA7BD81108DD257155553A78D8D537A5784E750B200550D24A0F6F117A9B91098555F5600714544BD3D1136825982A7F8F4D20B234DC0B4FA6D079810001DED6DC5E545996CC32283C1817F1D9DE823B2DD0EA40DB90514BBFD1107CD35346462C891BC7C6682E1BB34709919BF7FE9CA056FD43230B76377978154013C01EE5BB7368D4215EDE4D7BDFEBE3BBF04B76E351ADBF34598975568E2DB82497E307320964FF3066EE1F91FC3EF555DCE08069B270FD2DDD2A21FB190AFEBC8D8B98EADDFF34B26134573AD8712BF8F96542E517F70F5EA343BCAB81B094BB6FA96F925D9C85B4B7BFD53D9A2A4815B08FC8AF7228CBEF88C0A3547A37580601EB5FA56ACCCE4A65A19BC09537BA6A7DA67885AA021B57B81EE58144265FB70CD34D3599CA21E658412302B7E0E8AFFF93D903F97BC4248D0B281B449938D73572BEB102E2E217F11D4F3F89F60C73CD9D8FFF95A355BBC9E022A25CBA87F024460864D776BDF973E95F4402C57F5EA72450493E3076FBDC5C335A424392EE03BAD4243ED667BEBDE5577C31425C0DAB00B4E67B1F38B6CBF551E63D966F3C8CA31517CF9F6026BCB65FDB1431DEAA76BAE6294815C809EF4569AA8177C3ACC39AC0AA9388D2537CC20037DF573C3D3178598D4B55184D57898061C7AB942D271B02D7C1EE80861C0A77D0E9826733B5DD41BBF121FB63E47EA12C1B5F75FB31DF89B64C2A2978CDDA0F0C7F29EBB4015FF59743466CAF7F62182CDC97FB449C8B8E7DDE9E4D77050C2601859CD0435C2CF3BC96C1B31BCCFC4F625B984ED7F3AEB8F9DA2601BC30D349E472BCE1F2ABDC5AA4DBEC7F80DFAD5EDCFB9D77902A5C6C5CC794A8FC653ABE9CF9298670D39F8685E1C03AB2E1A39EF2675E31DE71043A90D73862F0A8A632C2D022F7F3B8855117CA38AD3B027BB73B4127AAA4AB0F59B606AD1ECB407465323BC3DBB1F02B1C25E66AD664027F788B505002267B3499487B514372F2803BEEC7D74B31EFC1BFC297C72D01689918EF1E0E941CB1FB1581889B926E71BCB6C5A5EBCDDADE92721D8F4EAA928BDB077DE4794830ED01D489CB529D018889627BE7101687EA0C8B8B906A05172538EBB64FDB6070E59E7FA7E9BF4D96E3963E6DEB917F658B11DD69285EAC8BD894E5422A831D02431BBDA521BA5AE4241843753C640B59894F55021B0380884BAB79F9AB9F7CD3943938F026F9ED59FBBE6EA68C9C1F183666BC1174151C3704CBC86E15254E854F84E85B7D54DDD0310E76EEB0363F786BE644A8AB103FAB6B5CB1FE2A2FA67A1C926B049B1686C51CCEA4976F81C69B6F7F0917F470DA87DCB082368E830A515757213642BBAA5DF98D4910F1D19E535C3D48963E57E7071F5A7094C4D22193AB3C262CDEAD6041923F956F1D8C24941866E5B8920FADCEE819FE5788F9A240B929EB8D5E1E1AF631221514908B40700CFCF8F9F2ACF20BD0CE05B11242804DA93C18A230070850BA0E5C19B1E40527DBE110D28ACCE8F1E9CBF6200DA28C0EC06004469825C6ED07809B4CC82995EF0C503ACFE3EDFDC04C712E0C503002A8F80F3B47540650DA88C20D661F0801CA06308469DCE6DF60114240080700A4C1C414501603303740C208302BC9005215BE0FD53702F1680CA756D60A878B6DE75AEF11D982B02E16A539820AE1401FDBE24ECDB3C3153912A04C3E88570DE239D4E3B591103954861B54CF3EF0F585C7484BED035F906E73FA002BA7800D1FE068D3E07FA0B0BD4ED527F787558645E528AB61BCD56A60C2BDF97A8853C4ED329E738BFEC0198565D3B719E43E1AD1873EBFE4E54D19901EA9A219C86E45A4CD932EB59C8EF4949D7F35188436CD95F15377F963B396A96E5A2157017BFDC65AC596AAFF97DF966A28B2A537D81952182A329ECCCA581088BFBF307189474E3A5E39150A150EF333187AF69B20F0DEB06840DAC0049D0D0FA67A2C8F91564FDA5BE2D5DD0A190D6EE5CFD372CB8356FABFA09DA8DE05185177DDEA6B9EB52B73B03C1B0E2FA119771B672075B54AB247B4AE7551B582F810BDE26E340546D74A97BC923A15C8A9166017C5C24C3468F22A10E321F309D4ED48FE7FE5D6428BDDB8CE07FD2CC1D4926BC878BE4FB767127EBDC25463F43EBD179FAA2CB442FF31B840BEF6391210B644835C378C04728B5F69B4F6A5D012E21A90EAE2902D06E11E4752A555A20FE02E49F1E4647F1CDBCA16AE4609ACEBD94976A5AD679FC0FC15F35816EDED2E09059243BB9F7F4E0AFFAC004B4E700A391B590BD2F6B319FC811F56C176942C0705AF3557B1219D57A23CC23EA80E902D4C16F346A87795A521D702BD3F5EE9699BFC3EB3D868B641F93985C793D74B5B1D1C686BAA73921387965AD2132027914F5243F45F42843F42CE46BCC4A3AA19D2A00B71A8B60610A39A92B6818FF29A802ADE6632B26A6AC47F24B70D7833FA145A1316A060DBC24DEF45DFE7D7DEA61886B1001AE9B477620287E74AA0DBD5B87CC690198A43801A29E344D8FA39840E93237D941E076F1F4FBA968E6582277547EE45046C9C2AD42A1E343D0F347AED2D7A270DCD21B09A889F5CB52E13DD59555A5F15E8714414FF054CC5179D07BDC4F48E6E41EABD605CDF96F01688A236860FD7247006168A6ABF39EC2E5085ECC647EEE69BA5EAB09BAF114DB298A826ED0A3DA214AD7AE083578C564BFDD04BE2DD4380BA9903A03D706C8CE025760F385B1322C1D796015F95C6A9C311F06692AF4245D783A11FC58FEEEB08EC7E98918EBF356F3A151C4EDBA983B3855F194C6755AF95DFFD0C1A8171E522686E15EEEEFDAF865C7F85DDA2A52A4AE6DC8B5B9B9B02F346A21AC93278EA0DEEFE25B3B5AEAE350D78DF7F07861A9B78F9190A2FDF3916EB6625AFEA7D1CA6C593E130B2B08EF71E1E0F085932D854029E075DDB84164ACA70F95FA65B24B468CB16D71CB341975863D3B7DE889C884DEA230DFC99D03C0777BDA805C7AC94369779002D90E97FEF026F731FC97EA012AE1DAD411A0B536DF5FEEF437F30B7C1A1D6F5806C4A7B2D318CCCEBF1FC48F7850139CFF360C43AD884D6CAEB8A188F89B7608B0D5DB95E072C5E66E75DD735073029D2CCD37A33CC7F388D7306CD81D69AABFF26098B80F22B0A58D11235495EEF231B4AF39597CA4D0DC699A559678582EB50DD6486CE0A6893CA59B684CD0CA48F6DBA689045F2645B5FA648A67339C7FB6AC2E80F365688D90D7D6997E733645C452FE93527EAF13401000ECB6F0A6FD05D0A96EA79B8FCE986B020A7B7D4A8EFC0E5BB491525622AA827AEB9ABE809F2E6216676F4CF93F4A36303663B0678444736C8C9AE1D953D1B23FF425D8F89DD1D6BA671946FF8B8EA92B23EACCE1646088EA6FD2978DB159AF011484E2B2407EAA9D63D322B59BDAF625D0F2CC982AC079F8075BF13D552B38C1F1A28A4A47DEDCA62B919295EA93717901806ACF5CB8FA699D7014A8E45EF32B9A84AE1A73D7DED1EC0E5A9E1FF915DFE502343475F3DC7B1E05680347F2786DD3948C6BD476BA1F85EA0176832B3A5CF88F7FD36DDE074E7241A303EC04C839D934AFD3F702B0A688ECDFF3135ADDFB63A1A6820E5A23D171409F00694C4DA29955712D9ED883F5748813C82356928E7FF64F39511BB097B44D5838D64DD58C4B587FB42601D75751262EB8D52465B8ACBBE8388763BF57567B9D20058F362EF0BF2152FC16355D06A3E96474E8165C29D4404DE1D6DBD45C94DB834ECF9990F53C2C0EBEF68D397FBB308890922BEE8AA5BDB77F60AC9F4CCB32EE8AEB0544B1E0802E6CE874EB0165371A01E78639F0AA0575227FD47A9F27DF4860E476CFA56625BDBE4D9796BB49C1F23C3F6AB97783AFA72B6F90C3BD1FB25C9A59798A6DD1FF226D9C3699D05878CC3402E9A1367742459BDEB8AC88AB7A507288FC51F0543D86D610711671989E314377B9539DEE784A475773D73A8CFFAB88F30ABDAEDA4A1E29A5D6A395BA1913C61B3753D4BBF3D2FF9B0CE5DFA7B6CB524B9300B1FFDB4A37529A5EA6ABE331FB9849604F554BFDA9ED88BF2D0DE97139F79027EB80B3F86D9C2E22F79535F5FC5438E9CC38A0EEB8711B2636ED37AFD5020746FA2D3B86FD2C5653FE167ACEB340E952AB88833483FFC159D936FF27B4CE42D3FBCED045D7BB25AC91C9B36358FF99421A485C641567D3A7689C4B3D141B323DD0C1073F884862B0170F03E83106BE4D8622CFFE985D31780845F4E124E2F7C84A6D13E6DD1CB41E9280D7CF82C210007F3284FA4AB4CD0DA2F00AFA013086BEF705459B112567E35B4D4C1EB6CCBDB09065A1DB13194A969CF38FC83D2F20FE75CCFD7E9CF27E6524C54D19E903557C40BE403D1981F2DC864DF63CAB91B9AFC8E91E71273A117B09336B437BBADEA1F65B6899D2C8968DA2D523011FEFD9B24346E0BB5AA0CA2026406CC164E02F8085953FD76B9FDA40EB9326042D54B98D27FF0D31384840765440079C2F00EDF07BBABC5C1BF72095210C38473B29397B1642731959F5FAB0D5D8821B0DD24525C5080A698DDF116994DF0AC88566D24A4745EB4AA284EEE65C3AE76623484AC1D0F60BA723B0B247CC73E21B01D28736E8A9939190F98BA2D8A5596F52E55A0B3E87F9BC091F29E0E031D5D941718BC4349EE1824E86A5BEC60E19482C1D04AC0E222E8EBF7305C59F5FBC4A54F9195655DCC7DC0E0D918B83DA6E71E7111574627591135665AD3147C65156E457701A2D8A34A2564AD042618AC33BBED6AA931B46027B72A5F7F7CF8406A1BDCB131BCB42C3111DC8102E2E02C5E4EA918033E9E59196B2C50BF2B012D837CB0A6E0BC912C64455105D8F6F363700AC6B63A567C14767ABB09C50FFB0BF0081CD7C04FF1352C9F3083F803E5383B64D464210CE3F054249A47A2B7AABC8B35283BBA46E29B70E767F85A04987F3520C5BF7FE24DC90357A3DC32BBB86D8DE7F098099BF1A4B6F5EAB2BEF253D85D2CE740237B0A9D325FDCE3C3F4F2AA60617A27D7681364E63123197598FE6E527CAE7629552B0D6EB321D30C36C10084D03EFF74110BAA42A8A482E11CE98F0BFE475F2B0C3F13AEE452BA95E6F3761B3E194719F2CF0285A31740931FE96120CC5DCF2693679C284573C58C5A0906392DBB41DE55000C874A625EA6C64EDB7A8D3E49A227CC002D45F62677A9367BE1560ED3108EE6636914618EC5B25F15EACDC915665337B168214ADEBBC29A80714E4599A6C47C0EB2198F79CA840B6C32877C7E3E94A9EF8A81AA3DFD079DFA54C4CBEE8056424567F8463F48AF63A3E37D7E6B4E6693829C041FD47DAC347ABEC6BC19C3A8589B8515501C1BAD6CBED6D100D05392256BCEA84E6E84D37F31DCEFD968B826678F844660FD10BE5268FC3589CCC2FA686478CAB47C86B46F281DB7E4835F46B1686289E270307401D586DA28D1780F839D425B08FF46CF283E03F48E9033EE5D1525091624CFB8E6AE31C6250524449939D0D28981986D81C590D6E89801BD5487EAD6F47794E1400704D5A2DAFE6E018074FDF49E07B5FB452FDD408723B79A8ADA562D29DC12F28B95B37EADC5E56CAE954ECBBDDB60B43D595A10AB5F4D554A1C97003AC554EFC5841FEECBBA50A8E0A333ED64B3DFA1C3B18167596DACB036C057063FC9CF9E561727359452433A5298309CDC73C9715D86ADC54FE8E7A74F58BDBA4517EDA6F5F48E4822021DF9D19F9E252D9AB5846ABD42893C73573FE7B0A7BA83DE1EB66B88A8ECF2E702FB3C1BEE9512CF5406876662E92EA76F75CFC87313C90A19BA226A1184CCC0A8212E2698B40E4C2FE4961D7E9762F67CEB6E7B08501D9997D46C359B024197D240CDF4BA67A6A7061E0B1E3E81696E6DD3CA346943875A1137498B8B4BD3B3E4E03C20E13716AC29DA5D98EC4DC9A00F362D356D3600BD78BAEB09F59A5C30931D06341D0EBDDCD55A3BB35E042DEC7A63B4548EAE1D763D596CFB58B0A5E2D25B5627BE8548A2DB6C8049B8D0D9494C6EEC5B5D618013DB3970931CD3E09AC094A0737122F65006F7632CB32EE94155F92D23EDF1EC3E5E3599BE409DA95C017373DC229BE5208480BD311CAC4F15F74CF22F521C2E5F7A2699EC2D152BC383A7E9A01E1812B796FBD60A3E7787C20CF2D72F1E3739374DB2166DB83156630522A62F60AC1F623E4747D067B75C7443AF031B1299BDFACFEDD3434200E0FD8FCD1F92DD51BA5201AA40FA1C372CC7F82B9569881FAB24E7FDADD864DC58B8BB1F65222D7277FF6C96D1D27FCCBF5CCFB96B278C9759347CD2DFBEF53534AE2CF3DC9ABA397982CF708C15F2643B5CBECC4B7459F789DA4B071BEDF545EB566B84DC9B69FA06BE43EC46FAD794594948F24AFA64C21A8BF1981FC488DE8AABDFB4100B50D0AC0E847365B66CA0795FC6E88AA06BD5D16542605410C2F72350F7CF9F3B9C799912DF418396CD529E277602816F16360C8DBA793D4BC4587C70DEC89EEC898DF1A3059A576E0CCBB27811DD0512B4D75EAEB036093A0A0FE0F90E6631EEAE9E4607E1F087C9706BB84B9F9C33B9268D7177825BA6E0B26A34529487A54A603AC6712A09E647CBAC5A16C742BDF37C36FDB76B46BC6A995C1F4296D3AFC6641629F01B00AA481325B443DA1733CF5D74805C12F859ADC554927FD30E32B997565DE3BC00599BA62E44C999C167606981111C1A541F01390C77E5A21B3AEFC3B0A3421C162F4EF499347AA4398EFD06B0F7E48D6EAF8C577B3B04870AA05157F716F09BC137C929A4B259BA99E093ED66862AAF9A95A8DA78751D430957C9222FC5058BCA045B66CF0AB69B48C3945F6170E78F3CFF33CD71F78906A187ED4C65E3374A38089AB7DFAFF9C4D84EC27EA9F99515479F90234E71BFD5F4BC3F547BF14AE66F4BD6B2BB5E7E6F2A5FBD6E54C4B1EE691238C2C4805742553B27A9EA0CEE7F99E9E5D46089DA551CABF656B4D9C1647853A7A7A05E6AFAA0CC7EEC7C2D7D766831691046704F400051F2B6B5BF76F66619AD7434C0776A753CFB28BD7A83551C7C8316C04FE87D4B3B1E21AFCB730B7A7259F7828CCD706EE14B3CC05C1AA50CDF3F62F8BFC6BE72055B8381988560446DB81BEE4F9A733967166E2458A2E7826B53DC9D62D818AD8BAE7FB5FC14186CCA5B446ADDAEE64A9449943D79A6AFD89CFB57E4E4C1A1847B2A0DF7B2C3D731ADF48884B42949440E18F7283FA371D8C361903D1717B20CA2896A6794F5041ADCB4F79C528F90DBE44D2212FFC8C18C109EFC47C1C699471B8C037C4118A2CE0EC79F0C585E7B9E3C5DE9E5D9D7B15EA14016E885B27847DC38B725D6BFE2DAEAFABB1908CF403120D5B622FC6982DB059B0C58E5333D42E6C3F262C5D68718ED8CADF3F871A165CBAD3E5E3DEB48B7A85799C0BEA0BD8730BE7C59EE0B52E5631C63172E5FA1227A27679B3481F5855E140F13F32567F2203730E334CB1E8C759C289E4BD6A96ABC9599063BE52E83F27CF7540026F3AD0BDE106B2A6883CCF3FDAE8263581592B95EA8412722A222861AFAED13C3C5CC086077F098FFF09219087F876BBB550580A35418F101BFFC40B8452DFCAC98C54FCF1C370DA181784DC3DD49B83646E4816E05DB62E101049645C5000458EE9A8A76D25A883C5B22ED6D034683BA04F990E957EDAAFF066497F38931ABC0437BE4DCF3EFBBE4563EF23C7A1FC7E3A2F6D91CB3FDEE76E58BBA05B76FA330B29BDECC65F64600237BD79DC4D70B7C8901E1B7C23E9C6D7B8852BAFE952ADFC4F3F9B4ACBF9F0BD340A591EFB72142DAE3DFBB68720B6D64CA89471F3383E4E6F3E3854E1AEF35679083DC632C71232D9ED5C3A9012C604CF0C4E1568749CB1D49B42B4145AE57094CCDE3451EBB3805EA149D40A06AAD20E4B9FE4A862787F7BDA76D7DA4C284D8EDFD89FD9F0E7D3C283CFC4A6C93111FA8F16C0CA76A81C3A28324E80491359DFF9DBD1E8D8D05149FBE736F6C8B40497A1BB4BD5963E85F28A02910DE92ADDCD23A088C92C51D13BD77352C5FC572253C4D0FBF77440F31B0B9E474DCE509918DB90E821A93EB1087E8FBDC56DCF28A5DA477F828CEB67B2C2B00AD49271F0FA9FAE646F38827968916575FFFB005313EB6B617FEBEAD48A6BF638D7F444978EBBE91ECCF330834C871394DD55A4BFE4FC49C88849B1DFA9CC0EC6D935813739EA62A61740015A8391C4A28C5B96E77DDAA67BD074C659195B71AAE81C387E24B375C13939AB88EE04F7B1627FCDB7569D7A947F84FA80931F62EF1F30CD0793F940D677C74260BC2423C1D78F980B068150FA8494C2CDC5501A8554AEA914140277B14A3EA75B8D1E40D8CC9F10232D45F266C9DD6875294A89658B9F0480429964E5019BDF957733C19D18B9B1CF048CC7B3485EB6CA540228898241F1E037DD3D9D5F638BEFBB93F3A8FE0B508333FFD997C03BC3D389FF9356EF3614AA1A1A7F12AD64EB00959F31D869292F536193717EE6F732B6915DFEDDEFCB9A8C271697196422548162EE7CADE672250AAECBDB771910C7248E3028DD3FF90F640A969BD4E6501D22DB6F2720915FA65A828AB60FDB3A90B95A5F268AEC2408556535ED7FFE18E2DFDA3E3E5264065FFC1CA8BC8B390287D130CBA7F6838030533C699F2A757FEE7619C04CE5A34D929F7E35FC3D8F4C8174F37CDD87213850F321D9EC63CAE8B83F7A7378B60C49D87816AA4A4436FB0C50E0388A7B5B5B7331D496E670345F7770900ACA3E017DEF625BA7F8406CFB79AACE869EAA2F80DFB9386F9F8D4EB6B1359124A3DA2248094EC5C8E3D914C4AF6C4DCF3F7B814BF40AE6CDF251D1BC5F848CF26BDA28AE677AF6DDD7B80975ED8CEF2A1AC310582BBB5984AB0345A736C903AFD15FEA96B8D9C41588690BD2B67C6ED4F33F5F60F9B2BD8D709B8028AC86CCE3E1652ADFAFD08017D84CE1D7D6A1EAA8866B067A9404835DD0B5D07F188326CDE63A90B210E6568351685C3DBFE04CE7C92AEFA14DCFBD1379B43530E687280D6C5794B7DC8E8B2F7FC4F88FFF265A260A6DFBC20F6CE51DD38D14068683271B86EDD5D64906E244B0BE3E674BF1BACA09771CE22728C26B6E7325EE37D5F94D546D7A81C2B995D0D1D93B1739BA9F0AF1A10A534E283D2304A45B3B21688529A866F1109CCFD983B748846945D27C44C4C93A90D7E24C5B88E99D2157F78271AE4E42EB41CADFA4D9DB6E2FBED0FBAA859CE28C530E60CD1436CF10315005CE201117D053C30FBFF22D46AC6FD775C87C86CFA0EF1C82D3B06CE6EF5CC5DD171EFBB4DD634A173AC2F94C4AD7612275FD1CF293D84041715996B9D9D4899D2C961F4E69BDF75D0106B12683C8D7F330053C8DCB72D478859BE3A21CB9EE82D4870C980FE924DB5A649D292D4517958B6E7A19787538A16D15F2C7E997AB5DEAAC7B8A5BBC5F481E7C0160768D071C639988E76DDA87AE8ED444A4F48B0748D499B64BA4A95069E9F4E6454FFD9BD8F08CB24786ACA4783EC63E37E6CBC47AF1057C871FDD642A3D60126D956B6014C680D593EAE309A2F04E90F2372B8A974EBE3ADDAC31354FD44A808102C07342E529447969C5F1D88EFAC85CB4485AE0894D10DCB860D5E6FB1307FAF0BCD640E99D3AE101A409C21A770288FEBF9F935DB245AA43413EC5303F291E4FDDAB058EAD56A169E6D98E60E6D9CB21E543FB54EFF4AE2EBFD55117EB9D57CCE192D3F76DC448414D4A71C5DAC11CDAD6FE4DA3DECB852CBA394268B85CE149EE521F31C686825DA41D772842A31524F546C6AFDFABBDBE26083EE59629E1A1839B0A08FB3F2F12965A1B5B715DB358BF6F09BC8BEB29C13B1209B4211FCE205A8EE17C3F87D393B92BC6159EBFB31DB6972A15090A8544E0A9BCA7CBA8842C124E99EDE8B428E642693DCD8BE52E3745B8120CB4CE973233224F1150E29B66C32399A2AB91300FE9589B8EBA2123BC3D3D9E0F2AEB5C9AE5AD1EEA77793CAAE89A70E9BE622859865C205276C60ADF63D98AB61705B0ED9EEE25308EEC682CB78043E41681A196F95AAB3E05F3738AEEC51F764A3B787AA2E547BC7FF5DF11162E8FFFECDD3C73F227D4E610457EEC2C63805CD0E7EE50290CC527D0B9FFBE7E9247A0CA56D3DF51381F3F6F93ABE26A589EEA8FB5AED5FF5146D13A0CDE299BB993BCC17317229E609642834E52A7065B1DA9F1151A371999FDB98F50A96C01D82EE3819C685F799DB4F3782BD825AE85694D69576EBF4421C1469D13754C0EFE70D326FF1FA1A94663DC2D170FD2BF070D1A641E7DBBC8FB1D4A54C2F8FF9BC1422312A96D9C452828B05FB166276E9E93CC84885BDA99DA145520ADB1D2A7041CCEB8CFD2D4FEA5CD7E2F02EA99DCFCF21FD643C7B49C780943FE05B716807543F04324C07A6C5BCE8819E98A3B9181B6263EEC723E56090398E9B744A934E28CC6A9ED9546343EA9FDB33EF25DD83189AE10BD1CFB077C1E220339BE322D6545294307653068BF6240E295097201790D92356786F38A2E6C469AF424554D3C5B7253D9BA3DFAA85209F882AE511C5141262ACA2119E8F8DF9C08275248262900F490889CCDCED10D2A23058901B8B9BDA466772BABB81030045F593ACE2A007DB4B5E6609205F2293A13271B91BFB079AA292AA81AD46CBA60F76C44470BC0B56DC2A5C020AE49386A0084A57B9D4692FE19D9F8D796D298E68C00741C5261151978A532CB64B0B2E23230B2E6C611A334B0F8624730E20F35329EAC9ED33A2A2E73557D7FFD08D81EBA9B12E0601AFAE02F058A2805C26584862489ADF4D21C2097C8CDAB6E46DFA5122D2544567599DFF54AB72A1A675CA5EC7B969D26575185E4BFE0C18830B3E2E32B826FD7BAF68E9437CE4C4D1CE4D88FC7307715ED20E7E6DDB351B88FBDFCA3E11BFB3B70F1EF83FA134B7717C4855A442169D36E77429DB9AEE03C7E1395265E9BEF5E243ABF8C69A49A6B6E3E140829461EBF0B9AC3F4EF31E4C00CAAA6212F8C5EBC5013D8AC150B284A7642EAFAAB12A84E6028B464C3F00444D548FDA4DAE055372D4162D29C4C5538593F4FF249805BBC7AFC3766E15ACB1A1AEBA5374207925CA0DF4ABA835EDDA93871B6807AA378B246FB9F70757F87674167C30E6716B8A522A52967DE5A5F8070FD0CA05B1958E80B1ADEFF3BB66DDE7FCFA25B0ACD14B3128F08DFB7BF57599F3854ADD6B19D9FF4136F88CD3D98496EB7DB64518EDE179A760735789AEA14E7450A39A2D1FFA53C149BB550B3A078466EA31E9EF1794C8F00F1135D8D07174BF70BEFEEF3C41DB233477318C11EC6F4C5B99524BF2F754FE10E28C8675572D8AF5E44022C63A9B89599290D54FDB80634C480AF475FCF83773488248DB1D1C6893A9F0DD725414453B483EC0726264D1AC1904045D81F9AC8A5594D9BD41001392E5C4BBC727D4F03CED811B692E4FF104D81274C8F4195FF1FD987C8BF29F47E4070514500D0A0E0BB08ACDB974ECB9D90DBDB3993E56D6CA70DF82A9274EB814F38C7D93019A8B119D952E6643747C99F3029234A7EE691E83D6085653CEB0C01D4E006963B75406C60342884833AC34C889CDCCAC23F2AC84D172F31E0741770A64777919C59470C7C5E31BA37D6ECAB06C693878433820CBFC304F32F00198EEF070109E953D7EE99A507027D5DB3BE8947AF6FE8744AC8241B9EE5C89A6E5397178D8070350CA19BF8054B9A4D9E41C3374E0603D975E8871E812261E01B05B5C95E9A2DA342EC1BBD576DAC02F4EBE8DA6764BA5218DF42A412827F8531AC712C1F59F35E969F39FA3A99155C8364B096050983C03386C0001928505C60A3BACC3C2973A0290B32473EC4308F98E4621E1B37C23C4106BAF3258E8C33CFC120625EC61A98A58AF9556AF09ABBBFD6058EBD2E0FDEDDDDFD99717F2A5D6DC076FC9F3429E7983541D29FE908B54C28A408523F68295048BD319EF17785930A3B13ED33FE3266186F0FB38982BF8658E6A60B9718D44CC9A2DEF05AAEBDE0F9ADABCA5B355683CA3F52D6F9345BD079A40A6F8A6DC906D8F9F82CFB5ACE61461745FEA9EFADE86225040E6D07967AFEED2C869C7D87E3507BE9F7C557FD3CD18CA31685F20DEC96CA7CE2B788A229155D642D12C0BB57854338DADC44670B341788EACB51399AC19528F1B7C4D45AAAE08286499A0B7DD59C1E72868FF774DCCDE286C3B6A20A19C4B5B275648D1BB159726DD08482A3FFD8540D1B75588D3607D771655D7E99830FCD4ADE83A50BDD8F6A3E352648DCB78B6DA0FEA1AB3737BF843BC8377556EF8048EA8A5D6C4F1E26050190AF7132093F78A8A776A4C011A4CCA979DC6C8F51B837FBB85DEBF3CFE23ABF7B271F33B8AD58E9205DD5250B9A6AFEF598699A2688D19D8E190B1E65FE94D800E79F564EAE1AEC421F970BBD881578D0C784B72951984689CD83128E70AC0B31B096EC4C027F93D31F4CBC178950EA7B49B34D16D41C708C65A27A63B379B757964DC7348EF09EDA5687172262D05B398B5E9A653971B5A3E99BFE07CFABD36D69E1718C90246CECA7A238E5CFBE3F599F12C080AA83D9DDB0746B88091231B28B965BB8C22E88DDC480625251599D05C819B793D632CCC25F3D0563337C05D7656B17914BCBF308DAD96B88E654FA2B64FEDF11D3D7221978A4ED856DF0E103BDAA8EF157AF6C8162DCBCEDB7C89885F2EE455721B1B3F2D9D5B3981E1456F145F7C0438EDA7EDABECA748FB913B784B3FD0503B906E59FF1BD6E68F68E40DFD0B5127BB67F0C5C40FBDF155B5E2B1ED547A0A9F03AAB45C9B0FC335BB336FEE52A8E627FC57F23784B0DC2CFDACFC0A3317F0CA163F812C48C4368F5E765DAC1536F0CAABE7D8036CAB4A1CF72580249E9ED9E7FC2F06A368D06040924B06BEA596945EFF386CFE6F7C51A6B634D6C5AE425D7EDBFCA48BE212E4A5146052977C0F14E120F8593DC7E4A1F7D774BD98EF4F18266529198431EC68C9434985A7127AC63C6526EDA5EE23EA715729A62A324AC4B48294E8831A871029883E70CA6012C141C0F8FD1B8F652768ECCA204DE9E244E3160A3BDDBE040A242AD5A0CB5D587AC4C48C33F543F18CCA86A63B5382595F947F9AE3763594D87A8CF7A3B3EC61F51F60FFB88AD75BCF1245E6B887CA0F16A66C89888F8F040E65F668FE83B5CF2DFFDD1909CD30C8BEED125CE12BA6AFD5A56C2EFA22B04A0576C992DA00395582C066258EAD54BB69CBF990D1C241957E94AD1E459044ACCFE43EE8E85D924CC18C8DFBC3C12C91BB6D5A18B2391D04238EFD16A657BAF645CC2D5421EC5B142930107F73EF0921E3D04BB1A737DEE4B0271CC498E79FAF577E9A4A24326272738CFABFB90C8A067017C981D2936F7534B2920763306FC68DDFAE400AC87A32B9C52080DFD5013FF706DCB1EE1208DB3D007A1AB01D3BE39518A8C23514DE2368FE40C16FE86F71352CD2A78578BA757ED69C09DFDFB45F5FBB7BFCDBAA9BCB5CC8B0A07CAB9B6CA5E60E106E238356EDDFD08602E02653DEEE1BBA9749A635B6469BDE97214A3071A6594C8044919DD52ABC62FCD954D220B04BEA64A68C1DA0B5990CD5118CBCB5C86A4A7A4E7E3FDCB96DDDDFA509AB1A60D918247ED3EAF1EA44F7C12DED59AA8B066D60B0F63D6B55A963A236424F96BA1304B34394B61D340746595DA081B32FE368447159D60ED851A89371694E3BA9F5B5D1684C349DDBF030403120FB981E8649953CDC74EC726D23C2B23EDAE9BC6C596F33CDC624688256AF5AB4CA1E747C95B47BE82C4925B9CBD7330AF27E55FFA389F68D10757687A4354CEA11CE6C36BB028413F422C69443C58E0B18B2D0D24C9C52022F6A98DF6B2299FDE922E41D52397DCC0BCED53B95C69CFF84EC271A29A2419ED04378A63250EB945E69F28D0F5A7884C1750B5B789189AE25A65BBD521D6A15A839BEDF5FAB711A95F49C1B3CFF6598E8FB14DBBB31D101CF0E0D2D77E9A5FE5C556B806527AA575CA1A052E1A52730CF4429FE079612F230BA8FC35361ED2FFDD5C1E1C477F8AAB91D0844868F869A1556AE3431287A44E06499B270B17A4459620FD200DD311B2987E53F7FEFCD9BEA8772C597AA59638249FF08B8C3FB25708CDF005B8B9BE12490D7D2F87AA5042E2F09FC8C1BA2E2B09FC807B54BB443B284074C2D51F26C6ADD2F4C0D078E1E77BA892160F246B6993B34ED08323395138CD0E10DF2288728FE67AB65AD4DA2E55323FE3E1D8C7A97BDC209CE0BF7397310760D42C9C133F2A9009500B80E7DC3D47FD9ACE0E3A7693E67EDE4860E124A2BAEF35A626358077CD08738A0B027949281CCD6C3A0AE4C15A48F35559FBBF80A575DE8BDF8ED2A4AD4E78251555C716DDAF485AF46A0F0892FECE969FFCB03DF76DBC4B3E901B72FFF2B46D4FE71E414778B131DB2C8A470022D4D95483889CAF3333999A21246B7423B9A38F77B456CC86E27E1BA1F491AB154C3F388AA1E239771D79BBD516EF36D1F810F0C6F573005A8C86D45DBCC2F6F45A68FFA462EE8FE2A04BD6CF5DEA0A50A1C53A3580401E40416D13ADF6BBDE3C8321162F62A7A0935037A0B1C17CBB68E38B4A97726FED4B9A8A32996A1978A8122F43BB038DBBC22E528FF91F7417E04F9ED5D7AE9BA404C498AFFAEE9B61342FB0E15362EBE1C7665A27384B603FA0A9B2ABEA6511B9724C84B678BC6DA155492C7B9704F938FFA3600CF8D1C3801C295BC9A1CB6F8C91720009351773E599E7818A7E83D5772D49C50737FCC217FE314A8BD4AD29E83D5D33AF0D63387C9A6D039202B45CAF5E73149D843AB0DC3D4FC8ACD011D0C7DB13C5B4A8F6436089B4B897715BF0FE17259E1F066C2FDE5851851ADCD198B1C4E7DF05BA398093E54EFC623D93788792EEF86B7332EC993D1C22F8B690D5CBD3F67106081F10865B6A7705C435818FFFA7D537C2BE00815B17EF51B32727BB10819E660855D53367C778966314D0B906C8B1127CE12696FD81AFDF51330A21D15F95DBECC4F77E5214DDE1FADAC11F6C01A1C8BBB0275CFD4066B714C711C8E0BF05E14BA1563B0F8FDCFD820002EE3F8A13FFD7DA54DE46C2637D5B4CFD18AE14FE2B3FAE7DE57F652E98D471C234242DF1A60E1B1EA12F03395504DE78E5EDC7005F354F82EDDA8FDA64304756F8944E89A5DE4167EA8DA2931C274BFB09D010C081A6058C504E7985FD81C09EBDD6107053B4DA50B8E5E0DB572864231D92C9662A67B7C4AE09B3F618531A48425CC9CA17D3F26CE06F5DC1F2D7E04736D10C536F9CD87519296D20B9B7A585337AC601F6BF8422F2503DFFE6BC10C283C5549A5BDCC17B3E2C40FAB50527C4ABF06BC0C7B7DE34AF8B43B9AC00A0DA85800DA600F08E05808AEC265C56AB40A3EAC78DF4EEFDB439914D3E34A307802E34BFEDC06FA3E3D1587ABED3C82E8749E75AAA92619A0368D7A4DB80AF698F96C0F50D6DA637784B36239C29A1E16F6222FE2557C0348202237A75A51560BE7D9F3D3C8DE2C97282DD29017CB18A514384A72C2033523023D892CE28E68CFA2B681F255CBB9FF1155DAAC497873E871D7EBB7CA26225C5FE92F88268AFE1F562401FCE23DB8B4413FD5850354CFB414044E507711EC945F9B4A4935AD217EFA35B296BEB2DE067484E42BFDEF6C7E438D0F6FFD82C4D6C9E97391235E7BFF5F594012518EF816B702E7CAF56E32698E3CD4D1155FEA31BC51D63E0AFE7C7041AE466275F30DEE182506D971AC615EACDC967340C34B6FAEF24294EBFA90249229E8CC8569066E054C52348F0FEECAF759DD7C5753B08BF47878F8B6A8CB9EF808178A89D8F6B8192A8B6024E5960164E1EB904797B516EB5D5A8946BC1C215895ACF6B7BDBFF0FAE82B6DDF4B2CCF354ACA2756BFFEC800E12083C78BCD86CE7A648F15F5ACBBDA3CD29A1D5FDF7E1897E1250165540564ECCC50B84EB76FFA2D02A935C43D916099C2C71968F51A1E9E0D267CCF9058BD76F236BED6E80644CDE01FF862DE52DD4792CDCD7AB5B182FB11CBE51F5DC7130E7ADD8F238C2E068FED4070079097488D7BE4BD3D97F6185AD8B8EC6F681A7613DF3EA52A20FD381FCB70E7CCB94408DE4149589BBC0243A3B38036DD0E29363C702D5132C6DA81CF37D2CC2EDB7D00E300C08BA5C1FBCC2821C62B67391ACE7F0A01E13AA094179844ECF34278078F1E55B84426D9F3734A99593A3980B1FE512A2A9191429C4D3164935D0F45728044BD8EB19FA0CE429B43E4A27EDD2923B6E4E4ABDD0E9638CAF2B0BD6FB2A089E3A7293255FBEC1F7C778F83B901805A8C7D9F44A0B77AD7E6A986BCBD0546F3E3731358F994CE13B07DF0DF259600740C6671C5CDC81F1468817CF5B10DF924969B9FC130EDB9E10EABF37216343B11EA4DEF5E99A35C125C223D7A03D6B20400E6A8CB4F35A46E1837E546884CA80D21BA6C8FAEB2C3921DCCE2B7C283C4F24D87AD266998443CFA55F24EB0B3577B1F77269CDF3E1164C0073D7F18955AA6815C5CF67D3E3ED6461D5061E8930E4774E8675032ED08BCCA5191B489D886B765251B432BEED3B6C45BF164672B957A62A42966E029AD476C1FD4390FDB333F373D46D492BAA936BD5FEB8DBD38C830CB3EA24294721FA01D0E68E4F6F05AC821DDA832782CF51D7B2233526D63E4C63F5D63A47BE2712E289881918FD160E916E61AED756536B6B2055FBC85338F2A59F0F004D84F89DE98F3B40B8FE4E644386BD0D0629D9D24AC942FD9B9A924BCB5CB3312E155C595C53352A9D111B259A8D8C8E11A56ADD45D73C414D436A574920EAD76E5848A45F3DF6B141136AC07B3B6C12E5F5CBB100F96620C153CA901AB90347C0798DFFBD0F02F3B4FC1DE4EDFF201AA2E8246DC6FFF884D9A8369C180AF704B9B3C64EB6642ED7CE9827CD920454D91748D29C368634F5B6AF3B297B1D6FEAF14B137CDE34C9C49F10D426E93AC47A9BD3A99B50A63747084D223ADC4021D931344B28D0E10429C808E411BCDFD9C2654ED5BBE9A0A87FDBED10682AED678E4A3491C3F429B919AD5ED80AD61C66BA38A0A2A2C635A690F4462C57997137ABA22E82B94A4382D6CF9A875862A1693C85A6DACD7A507F5B76FFBE5C1B44B6EFF47DDE623B12B8D8245F9350F7011EBA0C266C1EC2B88C3317DDD024024026A04FC678A75D7EFDE072D9E1DD710A7D7080B5D7FE0340C1FC3F8425307C57520D63D304FC06BA2C1059A82978D6BA45F21B8B1180D2A8575326B0FEE43E5AD0BA53103DD2673B8C34DF592FCC5925BBC3F2B28E021F3D89CA1D4347A71B8C26B9621DABA821C5927DA0D2D315242B08F678B4E61948293A6F5A26927A7585FF9C2CD59DEAE8813AC9B5201F54BCD37D09AC7D9500C91B676C700FC425462A1857419A75980E9FDC3073483EF550517FE9449E65C010DC2382CC11D18313D58F82CF83A8DD0D4B27089E516C2F04A9D9F78B6D1F55FE6C3F2C04FA3046D518B1C12BCD20CAF9A013237C77590627EF2373BF8F06E4095185BD22DB811D4013F935EFBE21F3E647EF37BC77763CE0D37E2944AE2F67753B277083B1E1AFEEB2B464D0A49492C73F231E6C47D9B6520206FD83875F0AE896A729ACF5D846C17E1C7601B534A52530D10C2CF4799ADE7632A8AD2EA5ED2E35B95DF2D9391FD9242E8F3077C05621914994003F343A984882249120282397E2F9BE1FA2129C004ECE38691E3EA089B589A94D9EF9F15B8D481CD0211471795103EEAB0A3FF2F6B3B821EA63674488B6D2E98DC34E00EA419599D8A312DB16B091935B37DB88BD8C54B1C83CA644BE786CBF9588882CB7068760E91D9E6B652CEE95AD8F421208B74518F453102CB4F5E21CF00FC5073E230101326D093CB03FBD074A36D662F21D5453A80F761FBA279D3733560DD58C3EF8B274C0D53522BFAC523081885B88953A6F254A61DF24110C23193C39F9C4F02C4CA468F5D2F8B5EF111D4FA705330A4BB41E12F98B3C2BA4D3CBBE5C06CA2E529DC214FF51EEA7D8A0C66A4924CF018D753302A962B6CE8CF26867A4FB389649AC62E32983AF56C8BCA49B5B9AF022830E96FD9B82A20D39163C5942975614F39FDD1DF9A500F8EDBFC4FBE31B53BB6646198B27AD254F47385D12426D9D0E2778A67D8E0809B1AD27F2C6CCF45B6C8F2EF7A7C81C824F14E24C1DA650B086225228FF2CF651A846C021A34061A327C4749959C30876654091915242E5F65F5694F0D33DF9F18680AF0557F58FC714548E7E3081F3E81B45B65BD9C4E960FC86F8CA2B489609A57836A4C86D7B5C1FE85FBED6B02A8CE253C975B6123E75FDE6FB557D147079751333C448EE1778B54EAC99B1FC73E013F299294EEF4AB0C4D29EE771E38A13F408BD6346FFD0BFE12EF9BA9FC521CE5D75A72C6114CB6EBD033590B11A4FD5983243799E7D108AEA3DCACB6DEAD72B1D4F246482317553237437B5301D8AB9246FE2E0B499C50AEEBC7F5329297B57E7A964DBA64DC0D27DB63AC932BE81988F755FE65CE937E503DEAC1996E1D998FD7D6C1895611846D72D6F0595E01E54D197488177DE3785A999B893CA7DD0185DA3325F0DD2E9DB5C86EDE0C5EA0B02B5E0081A894591E7B8D3C3141ED1E981C6FB95DBFB682703683020A211A03FB3A3F856140ED9BF8A77D5722FE5A84C22F249EA09A8F34AC651FB168FC425EA1447D00974179B1060F7E6063A7DB035EFB53C93BC1C9959071F217C8F92BF6834CAD2DA69F3986DDC0BAB436854DE17542FD024A8BE07B97B1EDF8E8E65EA0F9F6CB3E0262B04D13E4401EC5084DED7B49627321C623D3AD3AD2298B71F6E0B6F6277325DE9D9D4A6F9E6CAA6B0597A7FAFD2D6D311287A473A874BF4A778F24B7BDD427D68B783EBCA6878EA018F6BAB09DF7561ABBF03341F6DA09983D0500C18D1C2F284351DF6E4209D86C527F3214EE8297B47BF2C8AD4A2FAAE92A92ADA30AEE2AE2D4B1FB2E7A8F8FE656107E54F58C6CDAA04BE98BB5BE7C08B45087A696C989BDD32C1A87FFDF7551135652B0888C5F8569B5265173CA7D63EAF2237E6408B96DEA8C7263B2549EEA3B4B457B4BE46C548F2BE0D1ADEE4E8B69F30BBEF57FD3479195CAA81AADD9B183A3D7BCA5330E33C089FE5BDFFFA933736CAC2F9988FE78DB44D664F8E715E95F15B5B4BBC00BBF484EDDDC0C50F2568511E32F9F0DD08A570A96163D29DC715EB2D54EB56B2A8086D5D2EB867BA31B86BAB153217A93C7E8655205A2A429F7AEE772A05CD4D1CD62097D6955007892AF7AFD8F0E8DC8A595A6943189F2E9D99ABACB3BB9ECCEA6ECD7460DC9520C744ABB54CBAF0E6796F1742504C4BD2E1DAE0E946B914F49B0C84E0537A9595AE6156DF329B504E21BD563C5E206904F7BF10693FE145E5E01CCA3B7E3FE0CB7FAEF2FCDDBC6DE72CCDD260D000501ED1213D9925A47E5ADED92BF677B2372FA7E432BD8ACA38AB69CC356EC55149C11C2368557CB4425845B19CEEA188F12F6105174E2B3F92784EB18DCFBF677EE78B19BF58171E2DFF4D872966EF16F6444BE5D991699FB1F78FD99694F3486531CE08B380FFB4FF5E33CEFA56B18D8984822B2139185228EBA8E5C5BA30BF93DDD2C31F94F387F63DAEA492AE95ABEAE54D257C5E1ADF7249885CA73D5061FF757248939E813639B446A2C58762D0C1DDD5E0445E82888EBB91F4B2EAA70324CF727C13F1941090D1FB8952CB2EC87E5F73C4A5B6A2E836320866E341B686AC12129890D0E7FFBF99B350FBB72C1E14E30D6356A6EC29A5628E3DFED85A3023193338D0CFE04EA12E0EB1CD00BA4E78B4B9DD52DAD7C20A2105C5ACE7DEBBF83F5619908A5D52C5E3FCFC74E067231EC1A1CE794B321498DF3ECE87DBD3CA7718AAC045663E003868D74D1468DC658F5BDA386E8E8004FED086A1B0E09DC0EE7E2EF16D9841E06C9BAD95E6EDBB4E768A10E4CBBE4532073498E81AB5F9D3F297D063310C15BB559EA6D487ACADF593BA4D28BBF64B54F1C1F9C4208C9ECD35BE5C017FC7A88BC4C8A31C03C4AF534374762421511862F08A85EAA13A9B80730B7B4FB02CA48B97A1897C7B5BBE5F151CD13E38971D87528F3FFC1CA23267D627BFDA9BACB02493CBFEA2C0D8ADC6486A8238411908EC4AE1D54DF5A94A3A146AACD9094F499F76629DFDBD8B610A1EEF90A230FE8290C7F9FCD9FB81AA00CC9D808F3632BCB8F169050D371B516E429A63C127E0B55E0DC952360A9811A4FD44B241335CC57E32D82D0EEACF89F8BDC1611C740108590BB8455EEC3BB6B644D7C43E5AF37F4450337E1EA63F9305153EC0815C74C51F117130B96553FB0B4186881B84E779B0B5C600104593CB40F35253C678B565242A1C5C763F29FD38650125F0CD4F72FD35F289BADCA14C7887AEED5CC7E53E780529370E14EF2461E4858F7BA35B09965A98817CFA837A267FA48EA75EBCC37E6B1EFBB7ED4792A8F1AF5269EEFEEF19554B3E389A7C0093BB351A6EA42B9B46151708141A5F69584D40C0158C17FDB7A8EB47A7F137858FD9300FD09CBCAAF0EF21D2DC271E39B4228676D042AEC21F9EB5686712F0F42CBFD9EEA35BC6D5E726FFE5827198B29A8F8E81A73D006078E1444E7A70DF65E2E89225425B3DCB9E2F695562C7A1DF6D193147118BAE1B9197902349D4B97CC7E64E707D0CCA10DC04165E312EE40417F4B3DD8839C9253F2112640DB3D8DBE3422AAEDC176102AF14B096D4480C9447980C20CCE621DB7BF678ED002185A0032E26D377CA56BCD1B772354588A3950C6C92F006C281B53F361059274788A23E872CE034AD9A45E137C7AB8A987FFC4E5CCF4E1D5C1E0029DA1BA25E1423FCD2B1A8E330448977BC76BFBBE2BDF5DA5F4A68145595472BEEF21EFA51725D2AE05C55E329DD66A344170C55E3614F4B45A533477DD295072766D0533B3A5AD541C610C9286637678333F57E587B8C5BC69F18235C201D6AFC55711FC73167BA2E0A4F5C5952978DA0A52FE4EBEB523E53FD96B1B7410C8EF79CD030668552B6A0B777C73CA928A8C4126D492FFD0FEC826058C64A22CB325C1F933A130CC00FA6F685D53399778B98A33DD52ADB2C352CA7B6B7F7E953627A70AEED6D58ECD5664580127F3A2A5E89F541F1143C3BBE681B1833E7F77FD54C33F903E417311DF91A9248D0FBC9140FCEB3166A7A05D8F4786CF346ED2347A931AE89B6DC85771281E9F24F301409A17A91F1A3B611F19C2732F325EB08365BCFFBA09012284D67CCA5C4E1D1F28F69FC2610878B8E8069B9F5698DD7B12DA9D85ADD895AFE0C8EAB6D2DBFA6FD7C8C7420B003B1E7697DF376BC9896987A6130F506D998AAA3BAAE63EAF57B38F408A1A2B6DCF3AA5DF4E8B438B97795C331296156B63674DDEFD61F874DCF6658A89320FC00B2D7F6AFBF0FEE5B0675E8DADB0B379366B0D641D9F7AEC398625B53AE928BB13887FF01256AF9A18C42902045C7E2F5C9A5CFBF1F5DE2EF4B45B171D45A0F22A06558FA301EDC845F4F0483C05F1A1D5362723FA9F61DB6BDF511BF2A0C60D406551E06B690626482906D768202B4C84F9C328961240222C57875D4FA95BEB87B9D3BA167BE05A25E63CEE523C4183D24187F56F973FDC1FB759D7BA9C386ED71FBB58C6531AD9F4FC25337265D9ACB1F5867FFA33CA3DC21E5A65A120CC2D902E1C0CDF1FE04784F4C9D1B65964D1F647317922B3FE17CB2B471D82C244554093458E0BA82141238FC55BF97938578C592DB489F80F71059991711A4BFD5EC409807474F0FDE4DA07B78AFB013DC92BDF200DFE7B7C9B8839F5A052DD3AD9B0ABE43842EE9EDECE1619DD4A2ACE010F250A9BFAF05D9D77A8D776B3B205F6013A84C4EA6E6AF0184BF6F21A8D26D4FD97D49C3FD09ABED5BB09C0D19D2E96EF72D5440453F9B6D53634749D66D6F2E84512227BD05BAB128EA58DB9FB880B7C1B8A4EAB66608FCA03E041A686209185AC2BCF857FA3EA838A20C6475CA150B5D36802689037DD94F79804D91A59E757759294830497DC90733A8E4EA688CDE0B6FAF626042E3D2008520A72B84CC13BD72F8811D41825DF0F3C6D5545F2A8CE4788E2731DD6812B3F1B6627D00A7072A874E3963ECD4DC091B286349D7A0EB0A5FE49AE26758457509074A28A637EF0B0DCA694C74928634693627EC2525D94B7DF4CC6A3E9BAED9489F03A135CEDF8C9AFDAEFB459096ABD0110C18317D3D73765AF8F84DC797747F93F93BB0F3203E26E908AE0ACB5C737FEF133699D00FA67966BBF9322BD1BA27C19BC4958C0E17A4B4D10A289B511CFD1BCB440300DF1BF822C1FBB823656BFFA36800B25E091027283908842DC309A29FF3CE1FB21432230CD29A84F4739F33D6A98A715DB8C278F5E8D1C29A75B867FD2F400E2031F1E2B2CF8D6023E0CBACC23728BA24284E97D196A3152465DC3194DFE1CF233542F8C945E46790ABCBDBA236508822FFB59B27D962C12AFA2BEBDCC2C9110A311E24A24CC68A1D1F910BC154E708C61F0BF8583ACE960CAB306579D237A08529852018B712A4FBF24204D642F426B517C52B6916E7D284D1ABA21B25D02BBB4D72F1ECF1638F0E551F16E032D84FFDDAED78524D47CE63B0EEC93E8ECDB8C515F9495411844B22B79A2F9D23790D8F78CF7FA8B061B9578CD66FC5D225ABC3D8D0385A117A060AF7384ABBAFF9CD1B3DA16451CCE5664D0A757DD5488A9F4B95BBE5104AB32DDE9AE2B68ED3CBC3C0AF915F81E12FA24CCAC5936DCB780C4726850F669127420EB0D5D9A1E4B97AB25BADD0774F63F185BEBBB4BD59947B8C9A44FDACF6753850D179198BF70EB5623AA2531698E4E4A6AB4EA97A98B50B62B3978F7881CC436AE2356C17ADADFF7B4A59784F618E6B7C7BB53A6362E3D05FCBD2C88367E81F85C9C8AD076F6EFE91B707178FE7AFEADC03DD06485EE4B57BB9AC30FF59BCDE74A2C6F8ECBD2712A725D1475294F5846603C0573D5ADEFA2818567B7079EF131F8C37B39FE5EA40057E48ACF8BDEDF4C83722A67EBF92F0DDD63F3233E0A53B59B7F5F78B1B01835847EE3A0055130677CB5AC83059328146BEE6977E94D6C55F88EFBE12C66322F3D798B2D5887741608DCBDE59EEB4ADE3C513C9B41AA59D78ABB154CEF0B91962DF6526FC33A9F757A49B66676E86BCD09C27323B215F0BB3992E6FC7E394BB755A4206A9B0CF0F9C3C03475E05DFB641BDDC0C6748E7F5114596941B0FD44B0F088813E362382AFECD515756BFA70EEBC50A904F571C68186573BB8123D1EE981B00E263EE7E1AE9E455386BE81571432DBFCF7F32099778258FF580EB7F8B6CD578D7DE0981A1C64EF85B5D50C3F0413251D949F29822C4279526CBEA45CA6FFBEE1F5B92A7F2CEA885ACFDE2EBE842F23316636BDF0C1B9D9D62D2D4C5A06A5C6D0A1B8B8BF44B6D64838E960A99497BAB6BAD041C49A68733195BCB578F0E28B0C721A22DCCF217E4022FDBE7B7A8FEF3FEFED891EE1E6B4D8FC69C523B72EB8BDF8715357FAABD8D0605B3C4FBCD6B059250BDC88DFFAF01FE0E3997D51A39EDC3AFBA943490F10AF14CAAC3FA35417F57B345469D2CE552CFB8B5BA0A3C3D73F8A4160C3392BC788410F84697F3F165822B26504851DEE75F11F2D9D5740A44D6EBE39407D87E767A8C550017BB345810CD7738922CBB2D6A269B92960C464DC4C9DF7D38271FD4743AEDC7856C727F2E07E9C2660FA19CCF833E29F456DF026F5597D3AA3E3AA51836A174895A4A0AA882C95C3D1FDE810D68B02D8AFDC40FDB4C4269E86BDEA4E4A4DA3ABBBA2BA2DF416C6CF572EF85C311E1A1161E1027CA40D04D05C35A5AC45DC7F61384854A6FFF6F3BF7300D07A44FCF02D3537AB7BBDADEDBC9DCC5CEDAD9DDDA0CA2B4C1F914B8DC74F4A15A477F66BB3CE34CD1AB852A48D42902ACEAEE3771E00F7300170B9B5C87702839A0C47CF008CCA59F21610E42982B5F547FFC38FA4E03C0FD1CADF341EA4D8A0FC14A58640EC84D651071108000108A747BBA59A532D744B96F924894AA795EEAF761581A64C2276FE9E2BAB489C7F9AD6961318455D42D5E45AA768153E62510D1210EDCE0A9A5BEC9AB534333999F5458FFFB8A0F72CF9BBFA1541AA3AF534A923EAB1957E6A4B5CB0B2A0DC7B0E673118FE8EE0DD3FBDC916A4E1A26F28BA2BC36AA94395E69A591BF6D5827CBA9E3589450090219422A866CAC087378105819A7E78E3E79E4A5FA702DBE2D972E73D26592974051D0DFA479DD08DC82E4CBB0C2AA89D72F5C9749A2F66232650EEC0CFA14FAAF430925839096EF1AFCCA3D358D0FA2158151C367B8BD05C8F57BF4A579E99DF4FA1CAED1F76A08B6087AB1D1D25E628BDE5AE69037B2789C006AF55D158FCC0652E171F496684BA28020F3008EC0399AEC702D17BCC078BD505C7B5AD04C6D0FAACBAD588C8F5D3CA758E348DB161054A594268D519368C4C2E219BB2DF1124273F356919BC76243D78501C47E86545CABDEA0F261780961C0F1CF9A5CE4F1BF419598F22BB066014F8728FC7F928687C17DB5661CAD2C8D7F809AA60FE8AB252D61F68CD89615E3A33F146CC9F139C4A87448511FE71ECA26BF50A80511669B06BED1B59C70770DF929FA4F361E6660055BB15E8CA5D529229C0E47828AD59F3547814F6DFF775E962A72EE90B3B9C88C608B69D8E867A9F85778844CC6CB87A5061015DE0342C69310675DE9529627903856D85BCE7C1C2AC3DC34BF1407D346F2BA41212F21807B04C09DCDB0038935B1EEB966B5852A1C127B40B284F6992195161BAA5D00D1A0ACB8880768D446524B0D9111038164748EA15D1B6450CA9FEDE305BC2E1607E85B2D237ECC6A2B245CFAE4755B57130C22CEEF608CD2FEB7498B347079AE32B164EA4BC4E4055D6E4264FA1172371B382125F22EAA5CA200743CF5AED27ABB9125669D6D46172DC1D758A424BB26834F2175E7752F7F70F018CE707CBA1BE6A36CADEAA1DCC4F34D1EE450275D88B7FE4C1A90C8A589BADF428A5D7FE1963662D223CE795ECB5010DB9D9B16102F6DDF4E75E5292827AAC35496BC4C6AFF5D5FBE48DC2296FC9A77EE794B70561318FDC4935D09959DDC8CEDACDF101B52761863021550E204AC79B0A589D53266584CF03E0464D122BFD14B6006A9536741E1B7792A87E3F04E0900F912FF1631BFF0472DD629D9CDC33E0A61FE5213CBA47CDA1BAE6AB20F6A3F62382B355AEAB19EFBF99B2F22401FBB399F7666EAC919AE0FD69A8F77DC943B57AEC91E1B8301ABD84D040BFDB5AB79A9579A40D9AEED3F65C81765A090B62702A7DD990FAE3DA366B19CD93D61A96F0D0566DA6A0105012F9F95F3B80BC6D42499ABB8827DC226F71E7D7A164F5B45E01531D10CF343FE94FB5EBCBADCD7C335745A74584D359F011B1F93711B1C2DF224D3D7C02F6CBD0AC6DDE382C6A5C4B0485C840F5972DEDCFA05EEC6BA41C3C02727F80D723E70B40381E863DC6DC5C78C8CDA9583C581B6C36533DDB8E270C83CA0FD38FF3A4F2761AFC4E04969CE7851D078EF94AA27076FBAA49F3BAAD76A912BBB4911F7C0D39F639B9679ECC2969043BAC9BA5FAAA345A3CCB02C20779084780DC591F0C625A03AAC3377637EE4235A93883E686029A8FD72DF9D0BFB22C8F885C813AA8D61CF0E19AF79E248681A752DA49198B9205A340E7E10F111D6D23A151504A70389563B78E9CE33276F9B0973672FDC386474B04DF43B2C9153AB1A3F74E58DBD4BB7808979DF4090824F92474A1A1AA2E8473F0F7C6A73D01E5DE978F6982744722528B152F4A40214EDCCB86BEFD854570509399E955AD5137CDA7C798552412687D1E25450201AE2D19895CCC52BF45DAEE58BF26B46EC774409CDFA4DD8745FE045EA1EC1247CD6B0998A0577DFCB70A8335EF4877D2C5C0E4F62044878763A338BA5C683581FD1F0BBAB93ED1934FA3A7FFA6F55C7672651D595FB351CED7F90DCD68560AB4AB45559FF0551BCF0BDEEFD94E1BDAA6EF980F6C477EF24B44BF2978EBCC7E692AD4FF512518F56B72B2CE8CCA35DD0E237F08D029121578769C8B4D0FD3CE45533C384E9FE9EDD113B67EEC6DFA70ECD133CAADEBCA6495C8D2AA48825DE133A79C3046938DFEC12E61F4A3C1BD2AE0074A300E68DB853EFC526A9B32872263884BD033C268204F813B048376C5FBBCE97F21A0DCEF0E3C651E4E03D44521C7674B5781BDF848038B3CA124DD29043C419A59FA3A81A7BC622F1034DFDB3779E8F6BB34B73FEC45EF0AA7DC765C97653F854984F4D4590CEE513455FD10FAD1AE2E4C8B56233688A8323CC6DD2ABDDED693F165819BD09A3263AD28CA1DAF18F73F6586506A5C651B7EE07014FE4ABB8215223D0A537CCA7160D3B86B43FA2398D894AD6A349BDD65B6AED93806A3190DA18B06582CF4BED91CC52B814CD13B7DF97C6F116427DE6BB0D4B9AF23E743696FAE195D351782D82A5499426DFA3A246E26A267257ABFE8F2117895F79949499A6244A6AC3322FBAAC524347AECB0723C2A90A6F144042AEDED6DE3DAA208A309CFB9DF293406E5B029B3ADFB4064E3D683B90B8F550D65840F6EEAC3A05FDC7CF29DF7D6ED58BE5C3C420A942CE7080FF9AB834F5939ADE4AB0C7F7B1ECC5B9EB51D65F78D5E715F2BF2EFCCEC1AA055C4BDFF627DFADD7A273BACAEA6E606BF3AB279A1D11E7063F903DA27C0B6F96EDE245A58FA2BC8BC613DECCAF2977875996341F6F4C32B7DB5BF4A6FEAAA611E2FADFBDE88D20ADD01CC150140E9E2F00098679234660D99212785624598595E80967200DF9535181C5EADAAE8E4664B52C903821479C37EDD67D5EAE838B427C624742E51399E7621A880E0A818B3A251D5C601AAED0B631F9B2A3BFD50CA2F241DD4AA56DE46E43A67E9ECD684FF423279C1E33F8C415491522648F37136DDB68FE77EB11CE5753F5DA8B2F7F96C7A58272F5F7F7002F0593A8C905B7093F480EBB6FD2A0FF399E1793DD9FDF6C722592842727E8509143D5CCCFAA31D75AB3A0C9EC677BF0DF732B2729FFC31BC6F83FB27C6E236EF3C88FA45D7BBB3A37E8D853CD9292A8341F4ECB60BEACF388CCBB1153BEBF36444F56348CF51CF322BC094DBE5F14601F49195F20BCA840092893F0394187B015BFC4FC795CFA881E651C580B1A334D265958625C7EA37DB6B46FE7155A1C48CCF044077030CE841658D4A0A2F8E91CE20473CD0735577CF0271A34577B4497630004CFF349E9DC908123F267B364F1DAE1A1BEEAEDB6DB6BC779476D86EAB7ED6ADE1419D772CF6E5AD2FD2D56F2FF65CAE7C5437E8C746F7122BAB4DB0E453544157731E8CCBA76D961A6240F35C9FA3F6CCE79CB9D797E013B80B203DA0D09D98C5ACDA6BA3D041D9CA7B57FF1728A4F86E14337E08B0278B53E9CCE83BA0A24804146C054F7E4856307BF20436F8AAA18375D12C7A9D4F4131F31041060675EA691D79350EB29AB9D96328BB23E74ECE51810D1E5288DC26064F90251B15D7BB1449FE4625268E010A7C18295EF3014956785D7FFD357602FE4775F814725F14E4752E60A32926A9D026557777E466CA22EB197E0F3422C966453F0F5492E6C632962FCE6199EDFF26C3B609F77E400ACDB3895C0D97115B78323F5A2C0B7F5E91981921D06ADDC334A4F34D4DA4187228E157A814BDF7A17DAC0972148AFEC8BDA82C17C8A993BBBEEAB20B5E9D54C1AEF50AA12946062AD0ED653EC443E6007F753389E2F1AEAA8229FB19DA7B4E269B96CD815DED862B16E3AB6E0860C366CBA056DA990073FA316D1060A1786738687626C7DF46B244D8D236B22AED31A9607CF3A8C05C03B498347E4CA7E068A20AF002FF30222512179B7041C60414D34C32FB7097FB7611EBD232A2C3624C794BAF749FFA7467CC580A8E860212186E6DF425B616B94852902A29E4E2DE36AEFF33D9AA1F81316835AF58CE928F44CE8B5311109A0C19E74084EDE1DEA473A9F58D4ADCFD6BC42873813BCBBACB613F4688652CED8052B45BBB85E848FD0AAC89E62B220657B4E4A16F33A24E3134F741AE5A0AA39E0EA602EB1D4C581990F83BF6A12EB119C002153A72D1BE34A0545E9838A4705BAD966532F8BB70BD5D7D73534B023D462036F1037B117EB7E23375BAC64ED1DB6715E30140E0D8BE99DBF614852775DBA451DDF590BA9037430B42E5452A932290CAE9ECE62D6C6899648C87AFE588A30D65D0A4131997FDF49424254E2F9AD0AAB136207CF57631C9E0A7D4CFE326753F2FAEE4ECBB16E20D345855EAAED5EA0CF91B3404178AFF30FA3EAE6BF35139D0B14F48E672EA4C28CBCF0C8CB3039E14571AA1961EA39952EBBACFC87D185258FBA5BF6AE4760CA92DD475D48CE5778E75D9AC3F60BDC9B23706AD6FE2917752FE2C857108FA0D6B2EA28D56E91238FBAFCED41B44CF4AA844BAF9E58616866F15C571B230E8052812C76436CB05821E0BF4217071704AFE065C93756E606F43BFCD83B911E652F81B20F6E107D368ABEFEA2A023EB793779EA895B4313F954C7686AED45E32BC3639403C8451D863D4BE86FE3C05861ED51F3ED97BEC9A203576FF826DE73B0DDE8ACAE3962604E4D4A8AF6A5D4114350DEB6C265778F747CFCDC41AF27861700736332A1855C64CD8DA1160926220DB19AF2201178FE30879291E603176630A298865E54B73846AC6EA5A68DAA6CEB511FD49DA5426820D5681D0B19C19D78600F557DBCFCE35D62396D1E4042131952E97DA43AC53AE31624FD041253A5F7C1A322A252A3EAF6AF4FEE8ACDC57A2EB61D9EC184EC584BB135EC88AB1EDFCD805570D5BD6DD1FC77BE1EED162A40FE3D9C53CA59312F5FEE0A8B56B90B5083A54EBC48400FA1C319F0BAA665FFC215E2E2DFD4B450F9990188BF4591455E07541F102A53456E8E3CEB9CA9B2B0F50F86076279697604B26C7C95944DC6556D35BC6D265882AA64052DF23F4FE07E64C72CFD3A745465D88E66FC70A529D86C23A06E11F6055B522BD5E41A0203AB00AC8CAE27AA315AEDEE9950AB12134DF875DF2FB8F2CEB161E321BEAD3137B82BA55BFEAE816889894E8DB37F126685A3303FF8B34A76299A3334112A537FD9EBB133898BE874803D42D0776DA9A66635143F922AFF64C0EF036A7F14F1593FDE7B1D58E48347228A56B778A6270C727ADB6435BCF714741BEAE60B2846A5D8CDD70DC1A76C8A11FFF883530F643CEB796DCA36A76CAB4B4603D466FD7934B35A95FE4AEEDE103D52BAE96D51F1082634F36C02BE700C3E1E40FC5F1593700B74DA640333F4EB75B119029595CF58225D36D954806084A171260DB2986F42B4A2EFAC4BCEB9479A8790F067CB0B2D589AB4D7359D4421668B5457FF93FA932E7CFC34BEFDFA472A3A233518FF70F6B568ABD6A850AFE0522D194C9AF95E9E224F880DDDFAC2B00927C5266876B15AD1961237EB3FF6C7586D76B120C42B50656237AF8351BC466BA702563C068293A2562CE4754D718368DC535D4F23571322F53A5D714948B6958D5E94356D89C93B452D6C95A62F7F61B720FDB55CF71E9FFE40D279100972AF9729BD398FFF1D94226C48F17FD125B9745E8530D7A10B587655BF5CD2120373993683CA739A93D9CA151D5566B66C540A0D9F9E8447021BF1860162393736FB820AD922DB77B23CDAE77F948FCED2615893A6A5389E8363F466D4F606265246CD5DC731F210B1A81CD4854777C86325558F125EEEFA58C5DDF8EFD965ABF90A242D7C0DD2660863DFCB4E2479F69737B96C8C1A3C968DC8FDF7566B21610DFA0DA623E41190D638A5DF76B108D217B8F7115F00CF533CD9E020AAB8F7CFD3A05B775C2AD2DDC17CF09F086A170C3FC8949010C23719487B931DB9025BC49E9BC80406A20FBFD994B37E8650DB491D71AE8D61BC161DBC071D54B7EF9E160924D25397CA1434C5133208CE5C286F7AEC8F08B6A182259E5878DE27A23D56A1D442CE357039FAA0EEDBDA4FC5608451B6DEDA8E4379F39250C420A8CF956E680DC54FCE4F6825A00AA782CD6412783E70FF23AE61C92EED5FFB1FE5FB31D6DF4B8BC443BD226D039D1A386392E1D604FD623F80300EF9122C9D8E4ACFA260769D3073827E832D140CC370780AE0895FA8A1F972790963ECC4AF7FA09201CF7F67144542227BF7AF3D8E3DB995A9DF6B948FA6FF622049F53C97015D9918247E6C547A713A2E9072350A50BE8A142F63E3F61D909339321C62C9F1F54A1BCBC607CDE12CC51D4BF67FF0E0917C528E3C4ECDB799FE8BA7C7C89C28FEA335B7029D78A2A9269AC05F08624A0B04B9BB21B0E40C37B63B8B15F6BFEA1C270DE077D1AB50D704C72FCFF9AF9751311F51EC0A892C90ABCE2621C0DED03FE5B3E10C7C057F3605C91DB44F5ADCA5D3F5EE53EEC8217E946B07EECDAFCEE7F6274F81839E7E91ACF903D2C7E23337F0D9030246368AA351A76405B365A79DB95B62BC2DC132F52009E4C11FD4B0E347B2F74E818EBF6E5310F96B67B35A10DFC3581097527047010AB012B67DF95EA8438EE40D2820C37D87491513D12973D2840F8EC581940078550D1E7C8290673222D5E7DE2877BBF1D51C33E309FCEC417F7772609D8FE8A9EE81A6DF041F9B316C63C9250434DE215E4A41A8D7120D85B42CFB92BFEACB50F6529B13B5AC5E6FFBA2E896D32F659FA3896642B7E6D3C96144F8C6C4BE64A1BF182261D59395C5C9BB0AA570D8609F09CD91173923040AD2C995A28A3FA50ECE73375F892042A451D7EB5DAD95DE7236F06D41FA3CC27B3FB32D9463AACCF399EE23C89328EE10614FD31B8CCF8D29BB85F0C28336CF89C5A1ECFE17D5509932FF63DAA14230FD5DBFDF7D6C9DD1883B7B5BB34F0F38949B19B85B101FAD2A020DBAD26C4153B9CB3E7DFA8BE7FAD453437C9BF7FBB6E81923E791D5264FDF540F182730664E058E4438C22EF3738BD921B13798D052F600829EC67F942DA1DC61950EF862AB7DEB6FECCAA5F8DF6402B893CDC7DF91B6400DD98876A597E4331B51427E5B5F537EEA98C83F83BB0CF92146FFA89DC6C5D3E8F0A1FF7539F5079A2F5FA539A4F50100B4479B212AFF773CA6B975ABC97A7B90884FB12A63C12043B277AC83D5DF53A5044432A2EE7C2AA95B826E8DB0FFD19B3AAA2A9AA5477C888F90B68F3CCC288E4644117B637118C12FBB8F1CA57409055D9077EF86A60CEF705D68D711E8FB3FD4231FA842C574D916C2EF8EEE02DFAB6C05A9777836D6088E654E756880F4B7BC5BE63AD2EEB5738D1999701CC897B4BBE981AB0F0E187A63E99CB142C50E28D36A0E405FF03B639F929FF8657412886E4530FB71809EED11CD1F7358DD763C53EFE56556D36039A3C3E85868609BB380B53D43A378D09CF4E965760295977C9FE00AC22974C85E98E06D4B49B5E8056EBEB1096CD3802BA8D3D7B3E00335FD4ECC222F0AE16999AC25F67540E5A2F2CEB43FBE9542B539D247455B88DBABD9CF9EB6A93A75FCED9011405E2FF1497ABCB5415FCCC85EBC93CD7C5AEC7C8D4832A8996D9B79C3FAE40D961DA607ACDAA515901B5B82BAEED57CF1D724F1610DC9C214AA20AFED44A0CC9B169A1D498C27AE6AFB32E0E1FD68BDD9DE276100D19FAFC0E005E5F64142761F865A9FC880FDB16E26D739B88FD7E4BE4B89146B5F7FA4E57F0ABE72E5A634B766055A2F04496F18DEDDEDFFC562369DA72E2E1B20A2944E087468E5562FFC492D6F5603D72B8416A901F8BD06488709A4CE16943DB15132496984AC3034DC9F25C1C1F10840EC9980F9F46359EC8FE5E3583219BE030511416238CA6F04A2976A3E514B638EC1D8DD89696ACD98AB8A5F3B85D25538E3B5226A29065A5A87D0D428506B6AFDF8EEEBDB30B785F8B477EB5C2CE35531C7FC22DA7F06C3C173F12919B57A1105ECC262D1A51E9C0C2DE3FDBCE20084F852BE41C4F628C7ADAC22E0DBEEDFC485ED60FBBF176721572AE1F03B324D4497D505B9CA128AC9E34758DE8DD9B660B4530EEA402B6051AB66D21532DAE38A6930511B09B14BFD4D69A05BB91F934C8FA749221F94302FD699D2627DF240F5C7FA84F5AD5519BC3A8DF2629A558EDFDD262B89A1C7608699FDAD0B2CA052339D00C7A03AE8B1AD68676BCF3E4EDB77B4CD10344025C04AEFA152CF37F84E9BC13F04934FA15FC676E946B88145E203192FC0D3EAC65F5FA152A5D50A84AB533A3DB2263A5577D7B5A6C0E1835641D8BEDBBDAEF879B2046F9BB7D7711A58A8486E7E8C6EB814D820E6FA338310FD5E69DA218C0411A19C742501F9FDBDC31C7CDD5E681494BAEA35BD85A7E0D5F6844261A0B64E83BA413C3546BB1F8E3DC2C737435FFA6C03D85E2C2E8D03B95F906485681DEDE83E7F5FF9FA4C37E9317B7E4A20EC1A59E5940AE87B57B432CE9A3878197D737AC11C2271A63523A496F37BC83F8647A2BCDE7BA439910952362B6BB2FE427DF052845870F13FF6BAE77A87549565CDFCB8C91F01D7E503EDE575DE6E1DA2BF03819973B9C02F044F90A57036BB1A75E8611778A865E7C225CA31EB5A130612949615D0BB99E93F7ACF4910F0822F28BBA0F5E536F822D2CB1DBAAC961A1D7680AD716D600B81E8E45609B7CC2FB732A99B812797F35DDF4F8678B8B2AD559B5763537A5BAD289F64788C86F8B6B0445BF8F06962D71CDEC1187FF8DD56D5CA5C10E5DB47C67C0D2CC255C186588E6689F36773080712884C382D5775D947528FA7B20F96D6459F6A6F17A0CE135345B21ECB1EEB38E605DAF3EF9A543DDE3100F71598FD35C26467008F4D11A7AA0629E1AA907E987A9C13D0CBF3FA660E9852ADCD89688F2495BB9EBDE01245A2A346926ABB2C8CE838C3F45C25AB3BD45B45AD18FDAD0379A83F10B8A5F1E2DC288A899818E50A21257333B1EDEB605A35BEC21D8E7B301CC56B7B02C483D281CE345DFAA1D10749A3F4478557DE60FF121BE2BBFD57C7222B246183E183DF1DB17CB76CD10015BCC4328229EAB50E7897523C27FF9F4B3D3C44D023FB1D4B8BD03E41ADFEA08110640855295EDF8CD6CF4730DEDB2ACB64E364D836D75188B591F3A243973EF5B757C015B917593F6DC98DECF30941D1E06E3C127D33AEEAF50556661D7D37C3444233B532E0CA05D7138B1B30CD9E10022B1182239D1980486EC34DED25A39951F2E6580F3BB5B09150B491F7AE815A1B52CCB7141310AF2F0F7EF80DBA1974270C56E9C486632F7519F63A32FB170D773AE087813C5988F289E2B834F829DA01A041EE4D5EFF7C497AA05BC4EBBD7E74144CCA579B107A6A3139423CCFF63FEB75D0C49763A92056FDDB6871AF8C71E4DD6731B839C9D8AB7E60AC01D1B7D1B85EE8388388F7E7CB7914906F31A0470E5C3020F5B6DFC76D9E75972BDBCFB7FDA4C76E6DB58694664097FB8288B6F105723E084B0647AC4D40A29ADB9BF017A5F88461750EBB781284E60F6956FB96129B0A41E46489CA269AA7F1B2FA12F33DD214D5AD5287F72B3BCE04322EE19EFFE5DBDA5E8895C1EBE563C238FB42A255EE0FCD6E1297BF73972F953865948D651E5D91203CAB455D6C3B2767517CDE59E8E6D47CC8DAA8DED880EF5DD7234592C274DE715951D10FDEED308B3E6FEFEE72C90AFBAA05D520E473212C5391B927F1D8FCB20E43582B3A57043D4A5CBC8EE37B852E3FFB98C653BF436AD40671013C5446D9433E64022431A6647AF2966FE5EFAF4DA9F5349D6A972A4C47ECE555BFED6DB4D7ABA3245B0EA0DD78FBD37C2105E2984A287C1EC7C5C52DCA18D289601D295AC8B896F6AEDBE81807B0567B7C6CD4B8EF343C69CD1B2A0AD96C41AFA90B0586201D0EAE76AEB85147886A63FDB1B7ECE69F846A80E3AA44756EEB4E32F23E3D6FCD12E822F6491817726F538B89F382AD06CCF38C10B6B99F7C4E95D6D8420916F0F56B243FE8625AE346A5238E318D920A68CECBB86BA6248DAC419C7A26244747FFACC501CA2C4734BAE04C630E7A6746F1DC29419B7BBC027907F6C81F9AE3AF4546718F35A9216C700C8EBE4D2000B7CC3C9DBA1F3C651CA06E615DD9FBDF27B16B04DEE094E42DBF0E050728EC193EAE6130EA156244124377A031278F562C34E2556E02E80CBC299746FCABA8E5D2D1FA08570E01A8C9F3512EDCF498243C47CB33602C71537CE8A8BCE1DE3376BE7B5C96B5E8182C425602FA2125F183DFF9E1346FF788FC57E7ADB17C3394FE556A3C3C2B3C0A3A4C289EF9FC258E7840420FC5DACE539F8E7BBC563164FF0031F63984691AD072099ADF6DFE253AB30F27950B6F1667324B43A0A55ADA8DB58CBAE38E79AED1B407D45F78E65D00480BB619E0626B208543DCB614D636040220BAB50A91A02FB00DBF162E71F6111203BF3AF887E5AE88C609DB6CCED7A102C117246C183DE87FE752736F2BDF55D2C13D02B74E4B067E79E5ADCA0B9FEC16A1E57F87C42199E7116A7EBEAF08387DDEEBDCBBAABFCCA2E58C6ADA3414FA3FBCADCC440129F549B54A9E40FB4130C83AED34DB70FD55BB08D8F9E25CE21FBB538A912B17ADC87A897EAB01776CC761EBF550B0866275BA78EACE8EB4DD6BDB29FF77935F50A24AA53128BC7B8346BAD3210A64594058BB6E4530578BCB9CE886E31574E97A0ECA4178BD02F8436A1B7B4397E773778EB3A8298FC68A95085B91A44D1FF37BAAC0724B88A0F6D4D86C6061E0BD05A2F946F85D1BE01ECE5AD68079CB13C5489110D5C74729F51C45657D45ADBF70CD6D98DA6B6885E450AD54BA8C56B906D005078F52B23DCF1A785AC788F7430874E1B000525525FA70ECF9980E7DD3B7D424A7D2502B47A05EA1BD1DB858D19AE0A630AD04657DAF45DCE47C217CAA2004BFA66680D639A761B20AAF74E837F83A8E60AA42E4561E790301997B3166D5EDC3694EC1A9E48405C919FB35A12127DDD0A1BDE2E84F9AAA194037DCF173E6D08545503F7F333AB6421E0B3DA636B7AEA0A567597BF51203D7FBF6AE458C1403181D8513EF16A9A25643269A3463893A51A0C17D53C30969850F5661D3FA6C449EE7C72ECA7E2BF188BC3953ECB1BC2145DAFB6FA163C230C5770EEF10518C631BEA409C87D01DCE6B5D3FC487BD62AFB280DBFC983ED2798299C850099BFE30713299C8A604C29DAD26793B3B77816B8EEA88991889EABFCAE59602619749AC014A8346FBA1EBDF7C36C165D3EAB0054F9F796EAFA7FBAA7975EF5FFDA273DC3BF32BAF39BEAE893E828910AF6A07241A876BBF36C4112B93B134336787CF08DB754010B992D38239DAF160B9D3186BF7DE84B2C1F1AE41493B5F2905DEAA5257408EB04F8EFE0E735ED24750162DEA9F153A4604465F8499306D3FB52F83801647DB08A165B5C5131AFA5BF1A3DD3861FE1F3CC8F598D1B040BF19BF5CA057DA07B993F582FB862E1D02DE3A0FEB39ED4B0AE5F4FBD7D67CEF982291C448079647B7EF85A6046536B110F24471B0CCC57D0B554B147CB99EAE87B5CAD11F084C9787743136538B572EC756FF93467809489EA75C7B3F8229C76051DEBFD66802BEE52FAFF83FA8E6F2F49A6F48BCF249BD17057AEE0F06B6A09DEC7BF50046CBC4B5B903231AFF786B84CDBB3CF05F703F20A0BB06B618EB4AB291143E1ABF84745F2CF654B11DDD72ACEB5662F4701019FC3063FF187CABE0FD3114B5DC73BD0B92E09B81FC8602252E1ABD02D11841F34E2ECC55A0946C79924092469D4A821B9641EDCE507745422F9F5BF5C63F59266BA76DA70E7FE8696A6CB7879FD5522D3C99CADFC400F789C4C1AC3CCE4DD4411BE16395A173ECE0DF721D99998666AD72A09D03909F6A05CCEBC020F5D5B093A9D3A0AA89C5D2EDDF9FEC8998B7E168E51EEDBB72C34827089E511CFDB3F4E76213F198A5CAA13B20ADC6D39959DDDCF1B94FAC70AC937D92BA34BD85AE9E63E3522EAFFA8FA5AC84C72183D7FA2E9A3E2B274E4F3531EB17FD5A3DDBF1A5677F20B03929C473A536B3779F1AFAFB0F167EBE324A4130DD6A05868AA6B1148B2FA316D0E6613FFD8CFA06E695806FD6EA9C0C636612B5AA99CB8407EE79037194EFBC60072CED664052BF8AB2F52873353F96DE77287E4948FBDD69C80EBEB67EBD42FAE509CABB871221BA4667338993D5C64B0E82E6BF45F7EE237C6864EC863A6579A73CEEA34B49476B677CAAB71EF98493D87483CE52002227C203BEA5357D43477435766104481BF96A9E1A199F8661CF133DEE801F0CA2D7FD0A40B1BBD5EFA413102B6348819858DA8490169B0EF1C5DBC4613E9E83FD4649FCBB2B45D47E5471785B4D853A7F66349A230A0FF0BF78F8345BB0C652BD7905A92C82D6CBDE409B595FDC82729223BBD9EBF74563ECA61DE512DF67879A97D9D6DD2571E30A9B6E4DC601CDFE9B94AD47D37C6C259633F9ACFBAE81A1DF13BE0BE44ECBBB8368EE7A67D0F1A4172C2BD59A03A5CD67DF611692D2DC2AC21AC376977D9BCA2E0F8F02B63B24A996F365FFFE1BE76A284ACAF16DE6FEA11FC7A90256BF10CE3308EE8E0E5A5B890DA50B27D045BDFFB9350BF38807C4E604410E5A6BDC9967EBFC2C3500C5D9AAF58712C605131890FB0B7C303799F52D9A8BA552D0E474D78906E6C4282C10972984565E1EE12048A0EBCF548492D4068FDC14830C69633931F6AB83DAE79A10362E28E101A48C933F1031E76DFBD901AD8039F322A04E474F3613D2D888034552B6EFB8532BC26325A4034EF0AE0D1C2B0E38DE5A99F0E231BF3DF7A916ACCD16EA809560136618EC15817511B4A70362744F08B3EB26DA5C94FFD10147F81BFBDF65F6494ED3A490A5A887CA8BBD209EC2838690959342804D136CB577B394FA7C9D840ABEBBD0D612772DA7B3D7D8C2F19BACDCE94827C88A8323DC249AAA5FA58D962F40C6F98D92499D4A7650790D1BC50DECF21FD861FCB89803C129FEC279F7D8E9DA8CCFE0609E626331B38A15A34494D3B911EA579FF2CD27B7FB41EE1907C03FBAD4738FF78848558E55E366591AA66EC3CBFCA047EB134D3106FB2AFCAEAF88BA9B7ECA5F5AB8375887D3B49A26E6FB73DDDFA076F4F92257399F7E6EC7D410A62ED1EF22A06174964A72C18E7AF8DB3068C3F7B81A8E6968DCF3758F675ACCF358C81273412D058D0F86E20FBC06EA64ACD257C23761411EFA619B91581D6A7C8504BD399D26C35D979705978BFB7ECCD2ADC655A7582ABE866F6210E44E54637465009C777C71A24FB8B02FFDEEFD452C5EA91336A2D700FFC032C0DFC7A1F806B946CD992FF8A505243D283FF1B9CA7421980B20693ED103B740E0ABE28A90A5393EF6A45DF53F984BC7405BA027F7CC8A572CF9BA71AFD8FC9F785DC13F208B26F32D6D693D50C62C4C6F0EF85B2878ADEB157583F473BD45791EF777B3B3038D5DA3EDA48C0F068852C1C2827684CD1D3E0C3A9EDD714A20A5F6A15145A54C0FE12E3774B72EE0C34AD89CB5A8A051A6CF78F6B0B6B8AAD12935F30CD2FA28CB7D20F266600784C4129E2134EB93E444F29C59ABDB807274F25C81D1FE9F2933B19BA08C61B2B167253E3B8245FF3E701867084E64C9A985F43A7A654EE96EE52AF0F9A75950D54C9E48181E05F82975C14BFBC2E704F2417E7D70A8F03470F1375D9E9B01ABFD4B1A6EDFF5959D80F59340EFAF384FEC56D211A090F49256946B2B53E9814CA6EF64235E139E174A142FDFFB17E530A2CBD2585F075EA6DB75D5464B63075A4840CA13ACC1B8D5B646A133FA597E849F1DC74C4F7065915B82F33C3F2224A6461947D0DD6CE5C80894E205EAB29C2975E01F0C29AEC91581C50E54407B24435A62C1BE5FA6D6C0B0FFC7225F2458DD0B7AE6B2183446BE6694FF0DE31060375DBF99A0F027CA83632E280769A24FB6FF216AAF124504B13114CD572C7F2760EC4F905AA6B67DC431C8F687721FEBB3D161C9AF782C151A5D38A6E76F7DCE0D2D5AFFFA4E96532E7F639B1E51E8348B975F1555D8978D3148101058FDB81C49B76AB4818C095BD138274AEB7046457B1A3945B4DF34399F6DE4ED6F04C2B5145E78188FD39386992D00BD111EC0A7263A1614BAB005C0E281021EEC9C09EE8AC770D0F7F1B9DD3E193CF1226C55DCF54A94C1029818BD9031511341CDB141DED4BF5D09EDD7C30220C4A09D9F9D9CBEC4BFF7FBC056E4FA7702FEA0FC0FF1CB2CF50AF52528AF80536268BB91C9EBABC6A3D42C40C26B6E8E3574DD128413CD52606882C7E97EA37F74CC38540F8F855EF6876392C38EAE05FCE2A4A16FEE6C0156BFEF026DC1D8904DDEFA4382EE07861282F81D5337B1E8A68F35457F58BC05C8FF0D6D9026809C3A0E23FACD7E3CBF369624ECA30D1F7B5B93496CA00C233C4ED7529DF387E515EE4A0FC66322A165170E3CAFC9F77F3932F62B85E76A5CB04F5DB12F9CDCFE6F5930731D108CE93FDACFFABF6B3CFDF79B65E58CF8F3E189B8057A52BFBA9F5F268706B2447FE728D1785E088FFDE51204C0FC82CD8EF430B305B4E00F3C8053BEEC7F6AD262463E1EAC84BFC27EECEC0FB1A0CD2EA63A7E50B405F41033C786DCD2D0849ED906F5F2BF12AFE5E4F6D571A0BFDFFBBFAD041B28C13003A8C5C20F2593F8EFBC52BCAA1FE41FADB7315400FA85DE6C55AC87E3C1BB4E5B7828A00ADBA07A657187EAE0814119E82E1581868CF131FE64B58DCAEB070544EB4557806C7ABB7BAAA180260B811637C1287A9C9E100C08F29347EDEC0F050D11C7ABCA64D6A3C74567E8C5B0443B5F97687C20840705ED609330E76C487D8EEA3588361AAE1E54429702BF62D12F801D012A2001C47A45DBA0CE0FCF065A36A180416B836193950CD349FC905B0C4B2EB0EFE6D930AF409A4DDCB71653A6E30BCEB82F8A31757D4F09A9B2153DC90D4E7B364CB714B2C671FA61F0E75EFA54BB1B56829705F855F2708619E9F89B44EBE081BF550C4482C83EEE2F7E9D744439C9AA7A2FFD4D9847CC902138C761DCD2E6C11860FB0C2E3608D8C7773B847CE2C38071B56746C506F8730B8E531BB9449EE8F831ACE503E13032EAB6B2CF0B20634D8D35C4434883D040B26845EF96A1AE22F63D596C741A59CC670C79748C10243EB1310FF7AD0750849EEFF767A171C7793B97FBBAB4E7AEF4CA2B7C02159519AFB9D66FCED4EE27D4F51B9A63C1E63E28CBBC4F0F7B5FE9E024F3512B7304B010FE3EEC6EF2681DD89F90D986542D969AD00FF9087BA2FECF8409FFAB9C2F897FF602FB37B4F5B7B1BE46E1C2E771E2ADFDF50D8CAF5F9385C4A199E3859F5B19C6E835918BA792116BC741289096B4211D945BCAA0090E50B9F804D5C4C45A9DE1FDD3D32A8501BB69289051059249EF7B6AC988D78DDD420C9B43CDD20B21A26393D73B7C42812C3E90AC2E6A060D826590EFF463F17320D9C8E131646EB4CE98C8E02B0404C118F5BFB4DAB8337A901DEC41D66468128FC7C645670032F317E1708037F807DA0592639F899CA4302E2ED6B80FFC3A932530D89F7707B1E2DEDD7B1DA182C7064124157316433C6E48B44E2C3361CC561EB12D742BBE0658176666AE6502BBA47985C591FB976460475820FDB4708F56DF0F9EAA9BAC93834321DDA485C2C91229BC2C818265F114228BA308B2588A68B23E32D89E0CA440BF5A1D0B0AB21E102411B3A37A0625E4722FCE8DCED6D28ACCAC9D2C5CB5485088847B8995DC5EDB5D47534CDF8B3D38F48B4B4E4608FAF632C2B1A46BFAE8C4B5CC5C1DED4C4501E45420450804D6FC0F7C1CF232BF8DAAFFD78CEFA0BF2855A43B98E3354B8A9821EA1818913208D4FDCB10312D1C72D4EEC216ED9D87E4AAD4AC0015264E26361C5E2064ADD7F2F14E2ECDDF2F842BD333D0CC67025F4504C2C18DF5C0243079FD2B47A63B34286B964F3BD832D2AF11DB8EE541DF846E0CD19A4C8C75FE76E1F0202D47B4D7E8B6689F5545D0CA5B9BB3842A12017CA3B6A86E489230ECE34111CFA01652D3EFA4FD6FAF02A53CE77A63A3554B0DADF5EF78E0EF50A7101DA2D20E2373BDE389970A8EB16E3B4A612FBB9298687AD3FC90220E0DFE7588735E0E10CFA6327E898E8D4E93A6712B9EF53C6A8C888897A360756FE8714529DB786BB329FE0DD175A54A6C7346C4576314804FDD8A2CA7ED40318B9F25A6D83F60D0EB3CE82507AA3DC63B7C572D808C390E09EBFF47B0508160C8EA1CAABD7FA2B1BEE1B1E6164FE84CC3152B29BBCDBB7C2E51D209A8AA0CC415F9099AE5BBF7A2F7C5C0BE726BB6A0A0879817C813DFA40ED21ACDE8F7491203941AECFF00D82F57F8C60FC939F931E6094A1443BC99E4827AB2FA5D423155703BEAAE13EF23FE1F299E38A70AB0D24EAF5EA0E975ECFF38860DC62AE26DA20EA659B933025F47AB43B45E15CFFED7CCEBE69997EDC4BD44BC7F93A816098419FD8F8CF14F0A8681043124245EE05C0BA6256796EEC73B8AFBFEA610957EFFE80F63298A0DE41A451708DB26716EE9FF29037FD6826C1C65C843AF670A0E5852F0EA0C2F242DA65764A3F2218235985123EC393751235E64550B40F851F6399838FAD502534C4A057D7FB2AC1C593D5685CBD7A957927EE3EF268892D57D4AB2299031282488906D28BDEA5294356CC7D3B79CFB9690FA0BEADF7A0718B12D77F2EB268E29F32806B67072F41B2FE2BE0422695961BA44307EAE2D7D64BB48F2D79B5320C3FD7466C726BB5920DAC5FEADCD3A471FE48323A7EB358ECF1E82B0ED2E2EF4279529AECCFADDA4F3737C3912CAAD91043D9EA5374710F08184B0DA9DCF1256178B536153FCDA363EE69C3F6702B882102A4C1B8F8A34E46CE6BE401DD65D6289700060AEAD86C1455FECFE408A7ED7C291C34EFC2604E0351041504EC2C034BF07460F2A1FC583F4E98666D61B268C632A9BEE35FD4451F553718A162290E8075C432C65A77C849A33E33CB39EAF546FE69620DDA3E089F9F1A60093E3FD7F119B8A3492A5FED7EAA9EE11988408268AD894EDD74FE5DE6C0B93EE60FC497CBFA81C7B267584EAC4F8D24C2057B3F1C7468AFE57530848C7880AA1C02AC272564AFB65F9A09F042F1746E8E0F9F32FF85A6DB12242771917C7A00B88F54E315E510EA7FECD304D58B75AC15E5F4FE2B7D9F0BFEE7E2E680E07E3B4B303A0DD1F9AC813314A758D0147DCD180F6AFAD55622EB5BBA293DBEA36C0B16DC8E68198F6868E44C094BF0A2A32887A27A8C2E9AACB4B89D15A2BDEB05A1C8A9B37B121F526DBEA66A0AB16E4E8F4617FA62C6946203026AB8AD460A44B4BE313164D50A06C3E745C610030D03115042A7E978855EE168B2D92A89B9FD1B680E91D8CDE5D8E4D9A0A5BD0505799965A2276565D1336FFD0E7815E3A808AE2478847D1310FB6A71AC50810A229CD7687AA77B9EB1D0F8AE3EDC9FF976C03D87FD78CA16438B7DE2AD54F6307C8818FABEF7ECBD60CFDAF9CA94D307159EEC7BE99B4DD9CE73D66AFFB34EDBBD70909A73E1AA82A1C163C7AB0158A95B55A8CF2F54D9800233119B45BEDECBA56E6CE14188737AA0DB9FF8F95CD381FDE0988FE6FF12CDD4623DC2F746B660D2806D6F749026B0CE8232604534F156BC8F4130D4D785E2A4F24D327BCA29011E60312D20B20A975B06AEC853164EC8CF1F5EB64154B8C8CFCA5FDB37335FC2EBC967C8C91701D24F8879F79D614D0E64A27097200E340834C3C70659FC685652FE0970440153C04033022108E834822C4C0108F85440254C3434D00B511A887831422986148C7260DA0311EB2003443A0250E5A12A00D1EDA03E88840171C742140571C742540371C5888900D432F2CF421407F3C0C023004813C1C0C23C24818C660611C016CF8A4082622300507D388301386395898478085782801B0148115385845843530ACC7C246026CC14329801D08ECC6C15E221C80E130168E12E0041E4E013883C0791C9C27C0253C5C05701D815B38B84384BB78B84B847B78B80F4319020F08F027111EC3508E85E704788587B700DE23F009075F88F01D865F58F8858013074E0254E0E01F62FD7FF80021AC20A009408A070A005408506381962074B880000C4461C40744B8800716006C0870E2E01211B030F060E12AA12E80FF14C882B40F8D31C2AFA2FAC9E11555DD28636D434F9E6A7C6C935B21532EA74A35FA0A81F0047C1E0A3563AA6CD83F7A507401485D6B335CE24445AECFAF8ACF9831069C1E5ABC350E7AE181EA972ED14EFBDA1B34B73ECFD62CD04B0CF940F762F5C3A626191B2D9EF00EAF4146434269129E1C75452E470AB87DE172F4CA4DD73B1EE61BCF0F7783A18F36A411205F24BDBE156AD9B489FF863F75F68C671A742B80F97536B2A73FFE7275B77CC4FE5215566F2F0453B8A93F13AA10DD3F84CF6C5F6D5DC729FA488D1E006D53696DEB3826F53675F4E53EDE63A74D15AC7A06226CEAE6590EBD44C2928A06381DD963EC0E25D18621E752D84517F1C1C17374B9242F13313BA08E37B5BA34DFB4098557EE534F4C08081D7CA2EBFB45958E74AF53D2D5A3074A7A5A7E9A27B3AE75AD749BC5FC313F7951FF93F856DF7FD272C67FB54C5FEAC436721E4FBA9B011A5D76AA24BACEF9EF0C3554C0704A927F04034914CE2650A69D23A61ED3BEFCE5440FDE959792D0A9E16B8C827D17CA488AB7C70226A94451C98956FFEF158B981E66C99B4E68C242BB2E440F74C45234016167AAA6E77F50883F7E6A17FDB8DE049AB1B2A9086BF31F4AEEAEAC1CD98B60B2DB0ACE15D30D756E31A4070C4A76C9AEC99EA2A1A5A190B25243CEAE0ACE9C5B82718043B3BC0CAF55AC56BBA814AB1FBFF6D3658CE20A7BD9283710279C5451E979CC630882946A35C1B1087AFCBE2B742161A887633C32C953A6BC4090ACBBE6AEFF02D67716AF594FF3C8CD3D8B6922D1197026914E215A6953D838D9A72B81BC5329979A09EE6919F3BD33FFB8337A52C42FD681E2D69232C93F3D36D4DD723CB827E903FBE5AA470306B97D1B915C08B9BA61E27E227D41D039FD86E42E87D4455C21C774863E2313D84D513E11DD165E80F8D2457F566AA2B2B7546E0300E0EA8881FBB5E6227D6DC9393BC9883759E3C3C89988FF6D53DAFB747323B6E534B56345EC7E620DD1770DD47DCC37E3CA00AB3AC86548CA110429C6A3619B416D3704BF06F74DC39999A60290C8720892ABA369131BBDEF29C1EB6EB37C1CED1F15AD46392D7570F11CE563FC4D5BDB1042C0A383E64D0719AE0750BF53F89C1B5B8AF730FDF96C9F4FB6B5475FC70748DE98AEF0F2EDCF628EF2B13718FE311E121BA52E43500718E227F9FF6E38F442A8648E18A9F4CAA93C77DC27A1835611154D85390A82087F13754161D2B75B327C3A11065DB282EB3E90240AA2C13674212BCC271809A0FEFED3017B3A2960C620D5FE438A3F4C3C4295CDE27AC0A176012D782AE388DA9E503D57F4C0A1593B740B4E07703EA10495FBDE424CF919D4B732734E4156EC8440DAA7FFF4982D00C669E36F989C079EE9DE6967A86CC1CAD0094D742850D8F5AFD437EDAD363DDB95EDC7C968D02077EC425BBF885C7981A1E43CAEEE7C33540B1F04275FE71685E66A35897129E44884480B25AFAC577DDF0810204AF12594D8D9D9991D3323287ACCB6C5F82FB83561246B394315E7E51E0FBC5FC189408D9672586BDA9D9A64F332417596B2D82F15FCF2D6A57841620EDE7B9F3767EE795FD575D3E3DFAACB01C6DA361B230BF6457F6AB9C4898D624F1C73D22600C62414BD43B7454DABAEBDEE186A45E0649F6EE878A358A6200A7B74765F8FC8B519BF728AE7D7413D27DDAD7F4420CDD3CADCC7A74B1E3A0AF4448CEBCD6EEE6A1D535553B48A573D7124BB8BFFA06B4CE689451B89A10BB85485BD5F159D8D62B56DFAFCBFC58D7667DF2E0216345197A1F6C8490242611FABEF52E545A523571D9A68DA0830E80FBAC640150F007B0DD5C2868967A4BC81367B8E1F776A886A79496CE89F24B475348C92FF02EEFC8BF3F505450ACA110AA5DEA0E8981F88E1D86A35B86F82866C8230379B22FC433771D7C62CC8173C2EA4DCC9EEABEE796787A16183DC3D0C6B709ACAC7234D27BA7369065E0258508A4977A7BAEE8B5BA84E064A138AA86ADC3CD9805AC64AFE19A8A912DEEF8BF4E31DDB59ADAEA35235AD293617BA4E422E5570E0797B7872CC8FEDBC48E1401CE0BE3E9F702E7273EFBCCE23981141C387B8FDB909C0D23D1710FB77BFE93E02AB76B63EA2D1911303A39F57B61BBB9C45AD26714C1542A254EA2882E34C512A0675F8073A1128F5F076A3B4893253E4AB5C1D53840787F8150D115DFD5C5B8D0349A1B26CB5164229CCE2EC6AC61068C124BFA3064073A20DB9944A3EA1B345EB5D442F6701205EC6BEB9F1E7A1F81A0A8FF98E3E01A4A9D54695E2DB4FE63F86EC03C2A753AE9A59C8C75ED82CC06FA4DC00DEBAEE0A4BF5C89CAA5FD459D67ACDA5A2B443FC0F2D2ED3D944AF72753139D9586489F18B80B967314D2CD683BBA15E30A3104D9A0C3397CA222EDF1823DF3F4DE2328D2E98C3E4ED156573133C9AC82CA3E4BB4D5E75B344639FFA88516FB90D8B098046FFE0F6F068E9A6758BB93A995855174A5EE972F3A60C3539FF4C24DE979DD2F341EFEE2A27FB7437CCD7E4346562452CBA9A5ADBDF0B347C23B4FCBA3316364CC46509811BBD411FEFAB40B8B1AA5B75B8645E006FA6C48E835D617D1B0DF97F5F8D0D80919B8D511E84D7B10EA56A5BA986ED1499DEF2E0AD685C8CBE34DF56EC616C1C8DC71EBA6EC81C72D85E884BEB5C72DEE6E8AB58922E3EB9A469A84E45BA4512776D97D6856C1F852D7961AA7BF0C539863DE9CBA1B3B643103F8FB3FC2477FE61AF275F93CDE2F61B708350C4AD44B4F91FA8CF8537F397E42BD8BBDB354D28D389E0AAFE073CC274766341C7B0BF7329277343E5DCDEDA8CC71B0C42A99C2AE54AAF9DDE5545B037E3D9DEB3C5E891B90A695499926F6BE7A16B5A2CD1B830D083BF0BBDAA89F25C486B704CCF74826B6E875ABC69CBEDAFA86D77ADDA83468D39C5DD26C4A5569318BAC21C15D494C5BC725B9E8852B5702FB2834B451906F9BFC449F0642A42AE8E683BC4CFFD24AC85062DB4BB5E3A60540C4360B1AA97DB547949EE87AF2952EFF29429083D3062991A58572753ABA989DC0FC8BC43865E18F33D8ECBE26D00716BBC6B0A259C7BA589ADC137835CD9ABC59A40DE4DD0F853183D892FF3ED0777489A9F7E777AA21968DEBFA35A95D7D712AA75759AD2C7E821A593E150C56B99F238EB9434D32255F44D37888414E8FBDF246F9BDFDA097FD920BB4DC958B2685D9DCC7EE3655C299AC5A3703E507774110FD52EC599866A6B68E5AFE21E1C161882AD1B72E5056DB8994ADB6E2350C753BB606F06DEF926639133EA5D161467AD01651DE2BEB85F14EFD6BB3A78D37B04768CF51D05BC927EAE2580B28EDB1E071E0A568D573DCF85B47857D133B2018009B5B8C528BC0BE9892F9F20632580B26E9E5D934AB4DF8A6B41FA236DD411BA59CF84B20D71DF54F5B1A2D4A26DAF912A68455F3801A1E4343AEF30661B761960511D4F95030EE726740BA922565BA7F2F2BD27A029433C88A340768778EBCABB65E75E15499781002E87CA32A52778B79451B6C979DF2C26811D9BF8A0439E93AF73FF7A4E7552D0A114CAA54E22E9BE3F81186BC87415B7CF20F492311A5C92757532B9AE6E593D452EBCA1D48BE38E13116D237E08A1C2F0A4F6B8C0AD064EFB4A0E002A3336AA47D04CB5010ECF9C1B0B2E36CD277A577BEA9412C46091ACE944C489FE1806933330C6AC94F1DA55AE8E1661D0768498F1159B653C08607B222C28667DF4ADA3C94A119A4A0114B9B1A3A2F5C4F765704DFFC6F700CBD2F92A57DE17828572ECD0FD1F6DBBD9461E2A75B18CF46D9309503C5158718C3C1573A7135BFB3A0FD5A652AB752AD5D7EBDF69CE1AFD1B4E07C99B149F3169E58E8D321312C6919AB715BF1D22C532E5B386D236CDB7D57E90D4479B68DC54654B64958D63BBA6F4D75C5F5506D7474CD377D00F1FF324F46A753331BCD0F3BC005616E5C73EB2C405262D12B9302175A68477DA8504A6AADF25045B59EB4AC88F7BA0C849FC33D2D9DAD1A06C93EE9E2B1EE885CA3145BDD40B56B6B67FF9528C3E776FD6596F80AA9F6507B88FBC0F35286129CF0F9C63B5CBE96A3811C8B894DFF87091871D2845084AB9044233EAA1C01E14F123FD8CE4DF1EA9501366FD656AD6FA1DB5D7AAFB5258B858D2E95CAE4F04C04EA757D3FF2AB9D823E79870A5267B48BFD0F1D1B493D0F21D4EBD9DA949B7DA432C55AE2262E59562E91D42D1AF11D9F526509E211E513529074F6D728288E5168348039CBE3B8A9AC8A945274A18DF832E1D8052CD3DD1445C1801570C860779974BA0FC433C664AB406B2AEBC431C9A38E6072D3A204EAD8E53A95B256F5B8826B7A6CF361AFC3F56629FFB74E877FE443D8A68CA135B496195B7E81DFDCC9A8AAEB3BFD083239BB93948DA3667E866C915463839DB6B8827F0B89D6A87B069784DD1837EFA7A273783D535A4E2452AC554E66FA9C8C178F79269390CCC9E9667DA3FA343EC39C9E9A6288D0FF8FC26BAEDC97685A44E3A2F363576C25D042A306E27B597DF13A9E3A5A1C2A15B3ABA3FEAB425FE6FBBE6B747FB067982BA091E8B5C79417B2609DA79677479A8BFC0E37DB652B7E79429F500602DE576B75694F513F8E98739388E127CCDDD9D7E0B558B8C177462D2650444D490589608042FA8F8E47CAA0C493DC0C207C1C93E19FA5475D1B75EA218F0E0DC32130854959C8DC2520A540B553FCB8CEA8A1F4D09A0E07552647B73FF05FC39AA4BA090989EE8C91A3C34E25F38700F3461546ACCCEC0388A67B282F82C679776C5E297A77BBEC3278224AD9782EF54E69DF298A68A2E3AA8E3584272DDC95241C8B028FBDB2E001DD9A1A7A5002495B2DB4C9AF1C4E52319629D74FC3999CFC5F97D615A05FD68EC6CF728FC560C78B329E85F1740B5F3C5A1A384D7E79906016ECCEB7AA1321C02971A9157B5A6A6257E69620D959D64CE168E369E9BB6F3041781B24678B497ADF48044E45A6192DDF11BF945CDF2D1440004CB25BBCB926BD69A5B569500BFB2FEE23B496E9E5D46B493128585590E5D343A3DC8F3CC54C0368520D70A0FCD9953C8A2018D736B24E0871BF9C2466D8809F48DD11B18D06F5F4D3ACC813792605D1D5374A7762C67678A539D3143A56051325D1B12F1CF0CA2E0CF1DAFD8FB2B598152D7F4969922D9A659D93371D590F141AAEC417CB4EF028344C13903FA271AB1AE4EE83B6AB4EE227BEE0CDEF94D668C16BAE60825842FE7313F0DA9C5068D43054E046297B8C5CD8DD92E585AFACEC459EAAC2291E10CC14532F47AF8A2953C905E1D9D2260B3CC50F4B90130ADFD281737B9DF9EFADD1BC54842893B92EC949E6CF73560F3F55E68CE162363542B01DB48D8AB2590AE4A578A38A62F4FA6B9F90CF2B3FFA0AEE843B92E1AADBA7C09C33E8A6D726A0F513FE7E3AB310A8AE6BD25F2CFEBFD452A9E15AF7A2C657F818F6DFF3E6B8A83989634C85D14CDB17F47EF0880FE252BA83B81AC42C3A97E55550A545BDB2F74ED31C3DEFEA9D8E009B828C49C2F3213DC750027FA694CD2092B24F60E3F6510CA1C38C53C8714266B66F0DE75CDD453073037D350EFDA1915F8F3CFE4A4C4F9959BA165A03FBFAAA4CC04DDB58D5152DD61E41683453AF834B881F732DF86015DF3DC42321449B827709580CE7CF5987F95415CB04F47163A4D72215123C2A69B42A0072BA406DB5EB2694E41EE6AD2EBDA8AF2874A62ECE6C36FE92FF13D49832413C2810B4B4472754553CF3F25CB28E0AD4B0FB45E3D7F4BD37AA1AAF7CA12AF3F85D10BE52C7E280E92A20465F9FA8D44C62A55659740EA0DDE88A9F771A8691E4B1CD029D2B6F4A80F89E08D6E7A1F55FDA7148F78195BA1C8CF71BE099FF5F2C419D0885C7941CD165ACA953DBBC1C4B2840A787CE8E6D0BA80529FA3398FB8AF8437BEEA7B89BF49D858721B7A1428BA6B6B7A647BC877F0A53A04DAAB9FA1425DB499E2D67336F8D7F37F95A2CB9B87B0F48D64B5D3C62FC2E8DE0EA511C59332BCE8E88AB632EB62B7D5697D16F4C7463DC14B56FDB8B2F91345DD470D5744827D9DA1EE289946FD0924D5E4C30A17850BE6EC8D8448D49497456DBC5BB7A3B1CB5FA4FF441FBCDF99F617F976C615653F095981E5D2DC764903B29FFC15B26D85F908DDB43BDD7848B801FE118BFE3406E3D84BBD2637791E973CBE5778E23B8466756A99AA321C96B92E65DF8F276022FC4F5DCC5D9CD84B95FA6B5B657FE585BEB5B65B342C138DD923754D29C3BF846464CAFE83A54B54E6EBA898340A1AF546807FC492CE0EB8028346ED4081F28886585F2B4809A93F3A7A1A5E78EBDDE26E35637804D128EC650389D82EA9FA0474BF621908, afterDelayedMessagesRead=1362381, gasRefunder=0xe64a54E2533Fd126C2E452c5fAb544d80E2E4eb5, prevMessageCount=154238916, newMessageCount=154239201 )
TransparentUpgradeableProxy.STATICCALL( )
-
Bridge.DELEGATECALL( )
-
TransparentUpgradeableProxy.86598a56( )
-
Bridge.enqueueSequencerMessage( dataHash=49E8BBEB90C0E841C3D07A5FE7706E0B1D99F6164DA95B042F41CE1BD6F27DA0, afterDelayedMessagesRead=1362381, prevMessageCount=154238916, newMessageCount=154239201 ) => ( seqMessageIndex=524016, beforeAcc=B6D8BC3509C457BEC0A2B1AA657520C3E993F74EAD66FC0883DCEEC722903F34, delayedAcc=A3DE161642AFA61D101BD7093D6031FE33C3D75CE6A33675FFF37A163868479E, acc=416A7EA61A74EBDD819EED305730A5ADD24CF86110250232BA8DED72C16E0738 )
-
TransparentUpgradeableProxy.7a88b107( )
-
Bridge.submitBatchSpendingReport( sender=0xC1b634853Cb333D3aD8663715b08f41A3Aec47cc, messageDataHash=60DD98AB047A035CFF68A3AA38B9A0E4E4CE5D47F65083A1138A761E7E7CEABF ) => ( 1362395 )
-
GasRefunder.onGasSpent( refundee=0xC1b634853Cb333D3aD8663715b08f41A3Aec47cc, gasUsed=174389, calldataSize=99780 ) => ( success=True )
- ETH 0.10020034455220965
Arbitrum: Batch Submitter.CALL( )
- ETH 0.10020034455220965
addSequencerL2BatchFromOrigin[SequencerInbox (ln:154)]
NotOrigin[SequencerInbox (ln:161)]
NotBatchPoster[SequencerInbox (ln:162)]
formDataHash[SequencerInbox (ln:163)]
packHeader[SequencerInbox (ln:318)]
getTimeBounds[SequencerInbox (ln:300)]
concat[SequencerInbox (ln:319)]
addSequencerL2BatchImpl[SequencerInbox (ln:172)]
DelayedBackwards[SequencerInbox (ln:345)]
delayedMessageCount[SequencerInbox (ln:346)]
DelayedTooFar[SequencerInbox (ln:346)]
enqueueSequencerMessage[SequencerInbox (ln:347)]
submitBatchSpendingReport[SequencerInbox (ln:365)]
InboxMessageDelivered[SequencerInbox (ln:370)]
BadSequencerNumber[SequencerInbox (ln:174)]
SequencerBatchDelivered[SequencerInbox (ln:175)]
File 1 of 5: TransparentUpgradeableProxy
File 2 of 5: TransparentUpgradeableProxy
File 3 of 5: GasRefunder
File 4 of 5: SequencerInbox
File 5 of 5: Bridge
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol) pragma solidity ^0.8.0; import "../ERC1967/ERC1967Proxy.sol"; /** * @dev This contract implements a proxy that is upgradeable by an admin. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches one of the admin functions exposed by the proxy itself. * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the * implementation. If the admin tries to call a function on the implementation it will fail with an error that says * "admin cannot fallback to proxy target". * * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due * to sudden errors when trying to call a function from the proxy implementation. * * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy. */ contract TransparentUpgradeableProxy is ERC1967Proxy { /** * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. */ constructor( address _logic, address admin_, bytes memory _data ) payable ERC1967Proxy(_logic, _data) { assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)); _changeAdmin(admin_); } /** * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. */ modifier ifAdmin() { if (msg.sender == _getAdmin()) { _; } else { _fallback(); } } /** * @dev Returns the current admin. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function admin() external ifAdmin returns (address admin_) { admin_ = _getAdmin(); } /** * @dev Returns the current implementation. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function implementation() external ifAdmin returns (address implementation_) { implementation_ = _implementation(); } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. * * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}. */ function changeAdmin(address newAdmin) external virtual ifAdmin { _changeAdmin(newAdmin); } /** * @dev Upgrade the implementation of the proxy. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. */ function upgradeTo(address newImplementation) external ifAdmin { _upgradeToAndCall(newImplementation, bytes(""), false); } /** * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the * proxied contract. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}. */ function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin { _upgradeToAndCall(newImplementation, data, true); } /** * @dev Returns the current admin. */ function _admin() internal view virtual returns (address) { return _getAdmin(); } /** * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}. */ function _beforeFallback() internal virtual override { require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target"); super._beforeFallback(); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.0; import "../Proxy.sol"; import "./ERC1967Upgrade.sol"; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. * * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * function call, and allows initializating the storage of the proxy like a Solidity constructor. */ constructor(address _logic, bytes memory _data) payable { assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)); _upgradeToAndCall(_logic, _data, false); } /** * @dev Returns the current implementation address. */ function _implementation() internal view virtual override returns (address impl) { return ERC1967Upgrade._getImplementation(); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overriden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967Upgrade { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly { r.slot := slot } } }
File 2 of 5: TransparentUpgradeableProxy
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol) pragma solidity ^0.8.0; import "../ERC1967/ERC1967Proxy.sol"; /** * @dev This contract implements a proxy that is upgradeable by an admin. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches one of the admin functions exposed by the proxy itself. * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the * implementation. If the admin tries to call a function on the implementation it will fail with an error that says * "admin cannot fallback to proxy target". * * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due * to sudden errors when trying to call a function from the proxy implementation. * * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy. */ contract TransparentUpgradeableProxy is ERC1967Proxy { /** * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. */ constructor( address _logic, address admin_, bytes memory _data ) payable ERC1967Proxy(_logic, _data) { assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)); _changeAdmin(admin_); } /** * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. */ modifier ifAdmin() { if (msg.sender == _getAdmin()) { _; } else { _fallback(); } } /** * @dev Returns the current admin. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function admin() external ifAdmin returns (address admin_) { admin_ = _getAdmin(); } /** * @dev Returns the current implementation. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function implementation() external ifAdmin returns (address implementation_) { implementation_ = _implementation(); } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. * * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}. */ function changeAdmin(address newAdmin) external virtual ifAdmin { _changeAdmin(newAdmin); } /** * @dev Upgrade the implementation of the proxy. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. */ function upgradeTo(address newImplementation) external ifAdmin { _upgradeToAndCall(newImplementation, bytes(""), false); } /** * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the * proxied contract. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}. */ function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin { _upgradeToAndCall(newImplementation, data, true); } /** * @dev Returns the current admin. */ function _admin() internal view virtual returns (address) { return _getAdmin(); } /** * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}. */ function _beforeFallback() internal virtual override { require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target"); super._beforeFallback(); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.0; import "../Proxy.sol"; import "./ERC1967Upgrade.sol"; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. * * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * function call, and allows initializating the storage of the proxy like a Solidity constructor. */ constructor(address _logic, bytes memory _data) payable { assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)); _upgradeToAndCall(_logic, _data, false); } /** * @dev Returns the current implementation address. */ function _implementation() internal view virtual override returns (address impl) { return ERC1967Upgrade._getImplementation(); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overriden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967Upgrade { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly { r.slot := slot } } }
File 3 of 5: GasRefunder
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ pragma solidity ^0.8.7; import "./IGasRefunder.sol"; import "@openzeppelin/contracts-0.8/access/Ownable.sol"; contract GasRefunder is IGasRefunder, Ownable { mapping(address => bool) public allowedContracts; mapping(address => bool) public allowedRefundees; address public disallower; struct CommonParameters { uint128 maxRefundeeBalance; uint32 extraGasMargin; uint8 calldataCost; uint64 maxGasTip; uint64 maxGasCost; uint32 maxSingleGasUsage; } CommonParameters public commonParams; enum CommonParameterKey { MAX_REFUNDEE_BALANCE, EXTRA_GAS_MARGIN, CALLDATA_COST, MAX_GAS_TIP, MAX_GAS_COST, MAX_SINGLE_GAS_USAGE } enum RefundDenyReason { CONTRACT_NOT_ALLOWED, REFUNDEE_NOT_ALLOWED, REFUNDEE_ABOVE_MAX_BALANCE, OUT_OF_FUNDS } event RefundedGasCosts( address indexed refundee, address indexed contractAddress, bool indexed success, uint256 gas, uint256 gasPrice, uint256 amountPaid ); event RefundGasCostsDenied( address indexed refundee, address indexed contractAddress, RefundDenyReason indexed reason, uint256 gas ); event Deposited(address sender, uint256 amount); event Withdrawn(address initiator, address destination, uint256 amount); event ContractAllowedSet(address indexed addr, bool indexed allowed); event RefundeeAllowedSet(address indexed addr, bool indexed allowed); event DisallowerSet(address indexed addr); event CommonParameterSet(CommonParameterKey indexed parameter, uint256 value); constructor() Ownable() { commonParams = CommonParameters({ maxRefundeeBalance: 0, // no limit extraGasMargin: 4000, // 4k gas calldataCost: 12, // Between 4 for zero bytes and 16 for non-zero bytes maxGasTip: 2 gwei, maxGasCost: 120 gwei, maxSingleGasUsage: 2e6 // 2 million gas }); } function setDisallower(address addr) external onlyOwner { disallower = addr; emit DisallowerSet(addr); } function allowContracts(address[] calldata addresses) external onlyOwner { setContractsAllowedImpl(addresses, true); } function disallowContracts(address[] calldata addresses) external { require(msg.sender == owner() || msg.sender == disallower, "NOT_AUTHORIZED"); setContractsAllowedImpl(addresses, false); } function setContractsAllowedImpl(address[] calldata addresses, bool allow) internal { for (uint256 i = 0; i < addresses.length; i++) { address addr = addresses[i]; allowedContracts[addr] = allow; emit ContractAllowedSet(addr, allow); } } function allowRefundees(address[] calldata addresses) external onlyOwner { setRefundeesAllowedImpl(addresses, true); } function disallowRefundees(address[] calldata addresses) external { require(msg.sender == owner() || msg.sender == disallower, "NOT_AUTHORIZED"); setRefundeesAllowedImpl(addresses, false); } function setRefundeesAllowedImpl(address[] calldata addresses, bool allow) internal { for (uint256 i = 0; i < addresses.length; i++) { address addr = addresses[i]; allowedRefundees[addr] = allow; emit RefundeeAllowedSet(addr, allow); } } function setMaxRefundeeBalance(uint128 newValue) external onlyOwner { commonParams.maxRefundeeBalance = newValue; emit CommonParameterSet(CommonParameterKey.MAX_REFUNDEE_BALANCE, newValue); } function setExtraGasMargin(uint32 newValue) external onlyOwner { commonParams.extraGasMargin = newValue; emit CommonParameterSet(CommonParameterKey.EXTRA_GAS_MARGIN, newValue); } function setCalldataCost(uint8 newValue) external onlyOwner { commonParams.calldataCost = newValue; emit CommonParameterSet(CommonParameterKey.CALLDATA_COST, newValue); } function setMaxGasTip(uint64 newValue) external onlyOwner { commonParams.maxGasTip = newValue; emit CommonParameterSet(CommonParameterKey.MAX_GAS_TIP, newValue); } function setMaxGasCost(uint64 newValue) external onlyOwner { commonParams.maxGasCost = newValue; emit CommonParameterSet(CommonParameterKey.MAX_GAS_COST, newValue); } function setMaxSingleGasUsage(uint32 newValue) external onlyOwner { commonParams.maxSingleGasUsage = newValue; emit CommonParameterSet(CommonParameterKey.MAX_SINGLE_GAS_USAGE, newValue); } receive() external payable { emit Deposited(msg.sender, msg.value); } function withdraw(address payable destination, uint256 amount) external onlyOwner { // It's expected that destination is an EOA (bool success, ) = destination.call{ value: amount }(""); require(success, "WITHDRAW_FAILED"); emit Withdrawn(msg.sender, destination, amount); } function onGasSpent( address payable refundee, uint256 gasUsed, uint256 calldataSize ) external override returns (bool success) { uint256 startGasLeft = gasleft(); uint256 ownBalance = address(this).balance; if (ownBalance == 0) { emit RefundGasCostsDenied(refundee, msg.sender, RefundDenyReason.OUT_OF_FUNDS, gasUsed); return false; } if (!allowedContracts[msg.sender]) { emit RefundGasCostsDenied( refundee, msg.sender, RefundDenyReason.CONTRACT_NOT_ALLOWED, gasUsed ); return false; } if (!allowedRefundees[refundee]) { emit RefundGasCostsDenied( refundee, msg.sender, RefundDenyReason.REFUNDEE_NOT_ALLOWED, gasUsed ); return false; } uint256 estGasPrice = block.basefee + commonParams.maxGasTip; if (tx.gasprice < estGasPrice) { estGasPrice = tx.gasprice; } if (commonParams.maxGasCost != 0 && estGasPrice > commonParams.maxGasCost) { estGasPrice = commonParams.maxGasCost; } // Retrieve these variables before measuring gasleft() uint256 refundeeBalance = refundee.balance; uint256 maxRefundeeBalance = commonParams.maxRefundeeBalance; uint256 maxSingleGasUsage = commonParams.maxSingleGasUsage; // Add in a bit of a buffer for the tx costs not measured with gasleft gasUsed += startGasLeft + commonParams.extraGasMargin + (calldataSize * commonParams.calldataCost); // Split this up into two statements so that gasleft() comes after the storage loads gasUsed -= gasleft(); if (maxSingleGasUsage != 0 && gasUsed > maxSingleGasUsage) { gasUsed = maxSingleGasUsage; } uint256 refundAmount = estGasPrice * gasUsed; if (maxRefundeeBalance != 0 && refundeeBalance + refundAmount > maxRefundeeBalance) { if (refundeeBalance > maxRefundeeBalance) { // The refundee is already above their max balance emit RefundGasCostsDenied( refundee, msg.sender, RefundDenyReason.REFUNDEE_ABOVE_MAX_BALANCE, gasUsed ); return false; } else { refundAmount = maxRefundeeBalance - refundeeBalance; } } if (refundAmount > ownBalance) { refundAmount = ownBalance; } // It's expected that refundee is an EOA (success, ) = refundee.call{ value: refundAmount }(""); emit RefundedGasCosts(refundee, msg.sender, success, gasUsed, estGasPrice, refundAmount); } } // SPDX-License-Identifier: Apache-2.0 /* * Copyright 2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ pragma solidity >=0.6.11 <0.7.0 || >=0.8.7 <0.9.0; interface IGasRefunder { function onGasSpent( address payable spender, uint256 gasUsed, uint256 calldataSize ) external returns (bool success); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
File 4 of 5: SequencerInbox
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import { AlreadyInit, HadZeroInit, NotOrigin, DataTooLarge, NotRollup, DelayedBackwards, DelayedTooFar, ForceIncludeBlockTooSoon, ForceIncludeTimeTooSoon, IncorrectMessagePreimage, NotBatchPoster, BadSequencerNumber, DataNotAuthenticated, AlreadyValidDASKeyset, NoSuchKeyset, NotForked } from "../libraries/Error.sol"; import "./IBridge.sol"; import "./IInbox.sol"; import "./ISequencerInbox.sol"; import "../rollup/IRollupLogic.sol"; import "./Messages.sol"; import {L1MessageType_batchPostingReport} from "../libraries/MessageTypes.sol"; import {GasRefundEnabled, IGasRefunder} from "../libraries/IGasRefunder.sol"; import "../libraries/DelegateCallAware.sol"; import {MAX_DATA_SIZE} from "../libraries/Constants.sol"; /** * @title Accepts batches from the sequencer and adds them to the rollup inbox. * @notice Contains the inbox accumulator which is the ordering of all data and transactions to be processed by the rollup. * As part of submitting a batch the sequencer is also expected to include items enqueued * in the delayed inbox (Bridge.sol). If items in the delayed inbox are not included by a * sequencer within a time limit they can be force included into the rollup inbox by anyone. */ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox { uint256 public totalDelayedMessagesRead; IBridge public bridge; /// @inheritdoc ISequencerInbox uint256 public constant HEADER_LENGTH = 40; /// @inheritdoc ISequencerInbox bytes1 public constant DATA_AUTHENTICATED_FLAG = 0x40; IOwnable public rollup; mapping(address => bool) public isBatchPoster; ISequencerInbox.MaxTimeVariation public maxTimeVariation; mapping(bytes32 => DasKeySetInfo) public dasKeySetInfo; modifier onlyRollupOwner() { if (msg.sender != rollup.owner()) revert NotOwner(msg.sender, address(rollup)); _; } uint256 internal immutable deployTimeChainId = block.chainid; function _chainIdChanged() internal view returns (bool) { return deployTimeChainId != block.chainid; } function initialize( IBridge bridge_, ISequencerInbox.MaxTimeVariation calldata maxTimeVariation_ ) external onlyDelegated { if (bridge != IBridge(address(0))) revert AlreadyInit(); if (bridge_ == IBridge(address(0))) revert HadZeroInit(); bridge = bridge_; rollup = bridge_.rollup(); maxTimeVariation = maxTimeVariation_; } function getTimeBounds() internal view virtual returns (TimeBounds memory) { TimeBounds memory bounds; if (block.timestamp > maxTimeVariation.delaySeconds) { bounds.minTimestamp = uint64(block.timestamp - maxTimeVariation.delaySeconds); } bounds.maxTimestamp = uint64(block.timestamp + maxTimeVariation.futureSeconds); if (block.number > maxTimeVariation.delayBlocks) { bounds.minBlockNumber = uint64(block.number - maxTimeVariation.delayBlocks); } bounds.maxBlockNumber = uint64(block.number + maxTimeVariation.futureBlocks); return bounds; } /// @inheritdoc ISequencerInbox function removeDelayAfterFork() external { if (!_chainIdChanged()) revert NotForked(); maxTimeVariation = ISequencerInbox.MaxTimeVariation({ delayBlocks: 1, futureBlocks: 1, delaySeconds: 1, futureSeconds: 1 }); } /// @inheritdoc ISequencerInbox function forceInclusion( uint256 _totalDelayedMessagesRead, uint8 kind, uint64[2] calldata l1BlockAndTime, uint256 baseFeeL1, address sender, bytes32 messageDataHash ) external { if (_totalDelayedMessagesRead <= totalDelayedMessagesRead) revert DelayedBackwards(); bytes32 messageHash = Messages.messageHash( kind, sender, l1BlockAndTime[0], l1BlockAndTime[1], _totalDelayedMessagesRead - 1, baseFeeL1, messageDataHash ); // Can only force-include after the Sequencer-only window has expired. if (l1BlockAndTime[0] + maxTimeVariation.delayBlocks >= block.number) revert ForceIncludeBlockTooSoon(); if (l1BlockAndTime[1] + maxTimeVariation.delaySeconds >= block.timestamp) revert ForceIncludeTimeTooSoon(); // Verify that message hash represents the last message sequence of delayed message to be included bytes32 prevDelayedAcc = 0; if (_totalDelayedMessagesRead > 1) { prevDelayedAcc = bridge.delayedInboxAccs(_totalDelayedMessagesRead - 2); } if ( bridge.delayedInboxAccs(_totalDelayedMessagesRead - 1) != Messages.accumulateInboxMessage(prevDelayedAcc, messageHash) ) revert IncorrectMessagePreimage(); (bytes32 dataHash, TimeBounds memory timeBounds) = formEmptyDataHash( _totalDelayedMessagesRead ); uint256 __totalDelayedMessagesRead = _totalDelayedMessagesRead; uint256 prevSeqMsgCount = bridge.sequencerReportedSubMessageCount(); uint256 newSeqMsgCount = prevSeqMsgCount + _totalDelayedMessagesRead - totalDelayedMessagesRead; ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc ) = addSequencerL2BatchImpl( dataHash, __totalDelayedMessagesRead, 0, prevSeqMsgCount, newSeqMsgCount ); emit SequencerBatchDelivered( seqMessageIndex, beforeAcc, afterAcc, delayedAcc, totalDelayedMessagesRead, timeBounds, BatchDataLocation.NoData ); } /// @dev Deprecated in favor of the variant specifying message counts for consistency function addSequencerL2BatchFromOrigin( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder ) external refundsGas(gasRefunder) { // solhint-disable-next-line avoid-tx-origin if (msg.sender != tx.origin) revert NotOrigin(); if (!isBatchPoster[msg.sender]) revert NotBatchPoster(); (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash( data, afterDelayedMessagesRead ); ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc ) = addSequencerL2BatchImpl(dataHash, afterDelayedMessagesRead, data.length, 0, 0); if (seqMessageIndex != sequenceNumber) revert BadSequencerNumber(seqMessageIndex, sequenceNumber); emit SequencerBatchDelivered( sequenceNumber, beforeAcc, afterAcc, delayedAcc, totalDelayedMessagesRead, timeBounds, BatchDataLocation.TxInput ); } function addSequencerL2BatchFromOrigin( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder, uint256 prevMessageCount, uint256 newMessageCount ) external refundsGas(gasRefunder) { // solhint-disable-next-line avoid-tx-origin if (msg.sender != tx.origin) revert NotOrigin(); if (!isBatchPoster[msg.sender]) revert NotBatchPoster(); (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash( data, afterDelayedMessagesRead ); // Reformat the stack to prevent "Stack too deep" uint256 sequenceNumber_ = sequenceNumber; TimeBounds memory timeBounds_ = timeBounds; bytes32 dataHash_ = dataHash; uint256 dataLength = data.length; uint256 afterDelayedMessagesRead_ = afterDelayedMessagesRead; uint256 prevMessageCount_ = prevMessageCount; uint256 newMessageCount_ = newMessageCount; ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc ) = addSequencerL2BatchImpl( dataHash_, afterDelayedMessagesRead_, dataLength, prevMessageCount_, newMessageCount_ ); if (seqMessageIndex != sequenceNumber_ && sequenceNumber_ != ~uint256(0)) revert BadSequencerNumber(seqMessageIndex, sequenceNumber_); emit SequencerBatchDelivered( seqMessageIndex, beforeAcc, afterAcc, delayedAcc, totalDelayedMessagesRead, timeBounds_, BatchDataLocation.TxInput ); } function addSequencerL2Batch( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder, uint256 prevMessageCount, uint256 newMessageCount ) external override refundsGas(gasRefunder) { if (!isBatchPoster[msg.sender] && msg.sender != address(rollup)) revert NotBatchPoster(); (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash( data, afterDelayedMessagesRead ); uint256 seqMessageIndex; { // Reformat the stack to prevent "Stack too deep" uint256 sequenceNumber_ = sequenceNumber; TimeBounds memory timeBounds_ = timeBounds; bytes32 dataHash_ = dataHash; uint256 afterDelayedMessagesRead_ = afterDelayedMessagesRead; uint256 prevMessageCount_ = prevMessageCount; uint256 newMessageCount_ = newMessageCount; // we set the calldata length posted to 0 here since the caller isn't the origin // of the tx, so they might have not paid tx input cost for the calldata bytes32 beforeAcc; bytes32 delayedAcc; bytes32 afterAcc; (seqMessageIndex, beforeAcc, delayedAcc, afterAcc) = addSequencerL2BatchImpl( dataHash_, afterDelayedMessagesRead_, 0, prevMessageCount_, newMessageCount_ ); if (seqMessageIndex != sequenceNumber_ && sequenceNumber_ != ~uint256(0)) revert BadSequencerNumber(seqMessageIndex, sequenceNumber_); emit SequencerBatchDelivered( seqMessageIndex, beforeAcc, afterAcc, delayedAcc, totalDelayedMessagesRead, timeBounds_, BatchDataLocation.SeparateBatchEvent ); } emit SequencerBatchData(seqMessageIndex, data); } modifier validateBatchData(bytes calldata data) { uint256 fullDataLen = HEADER_LENGTH + data.length; if (fullDataLen > MAX_DATA_SIZE) revert DataTooLarge(fullDataLen, MAX_DATA_SIZE); if (data.length > 0 && (data[0] & DATA_AUTHENTICATED_FLAG) == DATA_AUTHENTICATED_FLAG) { revert DataNotAuthenticated(); } // the first byte is used to identify the type of batch data // das batches expect to have the type byte set, followed by the keyset (so they should have at least 33 bytes) if (data.length >= 33 && data[0] & 0x80 != 0) { // we skip the first byte, then read the next 32 bytes for the keyset bytes32 dasKeysetHash = bytes32(data[1:33]); if (!dasKeySetInfo[dasKeysetHash].isValidKeyset) revert NoSuchKeyset(dasKeysetHash); } _; } function packHeader(uint256 afterDelayedMessagesRead) internal view returns (bytes memory, TimeBounds memory) { TimeBounds memory timeBounds = getTimeBounds(); bytes memory header = abi.encodePacked( timeBounds.minTimestamp, timeBounds.maxTimestamp, timeBounds.minBlockNumber, timeBounds.maxBlockNumber, uint64(afterDelayedMessagesRead) ); // This must always be true from the packed encoding assert(header.length == HEADER_LENGTH); return (header, timeBounds); } function formDataHash(bytes calldata data, uint256 afterDelayedMessagesRead) internal view validateBatchData(data) returns (bytes32, TimeBounds memory) { (bytes memory header, TimeBounds memory timeBounds) = packHeader(afterDelayedMessagesRead); bytes32 dataHash = keccak256(bytes.concat(header, data)); return (dataHash, timeBounds); } function formEmptyDataHash(uint256 afterDelayedMessagesRead) internal view returns (bytes32, TimeBounds memory) { (bytes memory header, TimeBounds memory timeBounds) = packHeader(afterDelayedMessagesRead); return (keccak256(header), timeBounds); } function addSequencerL2BatchImpl( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 calldataLengthPosted, uint256 prevMessageCount, uint256 newMessageCount ) internal returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ) { if (afterDelayedMessagesRead < totalDelayedMessagesRead) revert DelayedBackwards(); if (afterDelayedMessagesRead > bridge.delayedMessageCount()) revert DelayedTooFar(); (seqMessageIndex, beforeAcc, delayedAcc, acc) = bridge.enqueueSequencerMessage( dataHash, afterDelayedMessagesRead, prevMessageCount, newMessageCount ); totalDelayedMessagesRead = afterDelayedMessagesRead; if (calldataLengthPosted > 0) { // this msg isn't included in the current sequencer batch, but instead added to // the delayed messages queue that is yet to be included address batchPoster = msg.sender; bytes memory spendingReportMsg = abi.encodePacked( block.timestamp, batchPoster, dataHash, seqMessageIndex, block.basefee ); uint256 msgNum = bridge.submitBatchSpendingReport( batchPoster, keccak256(spendingReportMsg) ); // this is the same event used by Inbox.sol after including a message to the delayed message accumulator emit InboxMessageDelivered(msgNum, spendingReportMsg); } } function inboxAccs(uint256 index) external view returns (bytes32) { return bridge.sequencerInboxAccs(index); } function batchCount() external view returns (uint256) { return bridge.sequencerMessageCount(); } /// @inheritdoc ISequencerInbox function setMaxTimeVariation(ISequencerInbox.MaxTimeVariation memory maxTimeVariation_) external onlyRollupOwner { maxTimeVariation = maxTimeVariation_; emit OwnerFunctionCalled(0); } /// @inheritdoc ISequencerInbox function setIsBatchPoster(address addr, bool isBatchPoster_) external onlyRollupOwner { isBatchPoster[addr] = isBatchPoster_; emit OwnerFunctionCalled(1); } /// @inheritdoc ISequencerInbox function setValidKeyset(bytes calldata keysetBytes) external onlyRollupOwner { uint256 ksWord = uint256(keccak256(bytes.concat(hex"fe", keccak256(keysetBytes)))); bytes32 ksHash = bytes32(ksWord ^ (1 << 255)); require(keysetBytes.length < 64 * 1024, "keyset is too large"); if (dasKeySetInfo[ksHash].isValidKeyset) revert AlreadyValidDASKeyset(ksHash); dasKeySetInfo[ksHash] = DasKeySetInfo({ isValidKeyset: true, creationBlock: uint64(block.number) }); emit SetValidKeyset(ksHash, keysetBytes); emit OwnerFunctionCalled(2); } /// @inheritdoc ISequencerInbox function invalidateKeysetHash(bytes32 ksHash) external onlyRollupOwner { if (!dasKeySetInfo[ksHash].isValidKeyset) revert NoSuchKeyset(ksHash); // we don't delete the block creation value since its used to fetch the SetValidKeyset // event efficiently. The event provides the hash preimage of the key. // this is still needed when syncing the chain after a keyset is invalidated. dasKeySetInfo[ksHash].isValidKeyset = false; emit InvalidateKeyset(ksHash); emit OwnerFunctionCalled(3); } function isValidKeysetHash(bytes32 ksHash) external view returns (bool) { return dasKeySetInfo[ksHash].isValidKeyset; } /// @inheritdoc ISequencerInbox function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256) { DasKeySetInfo memory ksInfo = dasKeySetInfo[ksHash]; if (ksInfo.creationBlock == 0) revert NoSuchKeyset(ksHash); return uint256(ksInfo.creationBlock); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; /// @dev Init was already called error AlreadyInit(); /// Init was called with param set to zero that must be nonzero error HadZeroInit(); /// @dev Thrown when non owner tries to access an only-owner function /// @param sender The msg.sender who is not the owner /// @param owner The owner address error NotOwner(address sender, address owner); /// @dev Thrown when an address that is not the rollup tries to call an only-rollup function /// @param sender The sender who is not the rollup /// @param rollup The rollup address authorized to call this function error NotRollup(address sender, address rollup); /// @dev Thrown when the contract was not called directly from the origin ie msg.sender != tx.origin error NotOrigin(); /// @dev Provided data was too large /// @param dataLength The length of the data that is too large /// @param maxDataLength The max length the data can be error DataTooLarge(uint256 dataLength, uint256 maxDataLength); /// @dev The provided is not a contract and was expected to be /// @param addr The adddress in question error NotContract(address addr); /// @dev The merkle proof provided was too long /// @param actualLength The length of the merkle proof provided /// @param maxProofLength The max length a merkle proof can have error MerkleProofTooLong(uint256 actualLength, uint256 maxProofLength); /// @dev Thrown when an un-authorized address tries to access an admin function /// @param sender The un-authorized sender /// @param rollup The rollup, which would be authorized /// @param owner The rollup's owner, which would be authorized error NotRollupOrOwner(address sender, address rollup, address owner); // Bridge Errors /// @dev Thrown when an un-authorized address tries to access an only-inbox function /// @param sender The un-authorized sender error NotDelayedInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-sequencer-inbox function /// @param sender The un-authorized sender error NotSequencerInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-outbox function /// @param sender The un-authorized sender error NotOutbox(address sender); /// @dev the provided outbox address isn't valid /// @param outbox address of outbox being set error InvalidOutboxSet(address outbox); // Inbox Errors /// @dev The contract is paused, so cannot be paused error AlreadyPaused(); /// @dev The contract is unpaused, so cannot be unpaused error AlreadyUnpaused(); /// @dev The contract is paused error Paused(); /// @dev msg.value sent to the inbox isn't high enough error InsufficientValue(uint256 expected, uint256 actual); /// @dev submission cost provided isn't enough to create retryable ticket error InsufficientSubmissionCost(uint256 expected, uint256 actual); /// @dev address not allowed to interact with the given contract error NotAllowedOrigin(address origin); /// @dev used to convey retryable tx data in eth calls without requiring a tx trace /// this follows a pattern similar to EIP-3668 where reverts surface call information error RetryableData( address from, address to, uint256 l2CallValue, uint256 deposit, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes data ); /// @dev Thrown when a L1 chainId fork is detected error L1Forked(); /// @dev Thrown when a L1 chainId fork is not detected error NotForked(); // Outbox Errors /// @dev The provided proof was too long /// @param proofLength The length of the too-long proof error ProofTooLong(uint256 proofLength); /// @dev The output index was greater than the maximum /// @param index The output index /// @param maxIndex The max the index could be error PathNotMinimal(uint256 index, uint256 maxIndex); /// @dev The calculated root does not exist /// @param root The calculated root error UnknownRoot(bytes32 root); /// @dev The record has already been spent /// @param index The index of the spent record error AlreadySpent(uint256 index); /// @dev A call to the bridge failed with no return data error BridgeCallFailed(); // Sequencer Inbox Errors /// @dev Thrown when someone attempts to read fewer messages than have already been read error DelayedBackwards(); /// @dev Thrown when someone attempts to read more messages than exist error DelayedTooFar(); /// @dev Force include can only read messages more blocks old than the delay period error ForceIncludeBlockTooSoon(); /// @dev Force include can only read messages more seconds old than the delay period error ForceIncludeTimeTooSoon(); /// @dev The message provided did not match the hash in the delayed inbox error IncorrectMessagePreimage(); /// @dev This can only be called by the batch poster error NotBatchPoster(); /// @dev The sequence number provided to this message was inconsistent with the number of batches already included error BadSequencerNumber(uint256 stored, uint256 received); /// @dev The sequence message number provided to this message was inconsistent with the previous one error BadSequencerMessageNumber(uint256 stored, uint256 received); /// @dev The batch data has the inbox authenticated bit set, but the batch data was not authenticated by the inbox error DataNotAuthenticated(); /// @dev Tried to create an already valid Data Availability Service keyset error AlreadyValidDASKeyset(bytes32); /// @dev Tried to use or invalidate an already invalid Data Availability Service keyset error NoSuchKeyset(bytes32); // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IOwnable.sol"; interface IBridge { event MessageDelivered( uint256 indexed messageIndex, bytes32 indexed beforeInboxAcc, address inbox, uint8 kind, address sender, bytes32 messageDataHash, uint256 baseFeeL1, uint64 timestamp ); event BridgeCallTriggered( address indexed outbox, address indexed to, uint256 value, bytes data ); event InboxToggle(address indexed inbox, bool enabled); event OutboxToggle(address indexed outbox, bool enabled); event SequencerInboxUpdated(address newSequencerInbox); function allowedDelayedInboxList(uint256) external returns (address); function allowedOutboxList(uint256) external returns (address); /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function delayedInboxAccs(uint256) external view returns (bytes32); /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function sequencerInboxAccs(uint256) external view returns (bytes32); function rollup() external view returns (IOwnable); function sequencerInbox() external view returns (address); function activeOutbox() external view returns (address); function allowedDelayedInboxes(address inbox) external view returns (bool); function allowedOutboxes(address outbox) external view returns (bool); function sequencerReportedSubMessageCount() external view returns (uint256); /** * @dev Enqueue a message in the delayed inbox accumulator. * These messages are later sequenced in the SequencerInbox, either * by the sequencer as part of a normal batch, or by force inclusion. */ function enqueueDelayedMessage( uint8 kind, address sender, bytes32 messageDataHash ) external payable returns (uint256); function executeCall( address to, uint256 value, bytes calldata data ) external returns (bool success, bytes memory returnData); function delayedMessageCount() external view returns (uint256); function sequencerMessageCount() external view returns (uint256); // ---------- onlySequencerInbox functions ---------- function enqueueSequencerMessage( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 prevMessageCount, uint256 newMessageCount ) external returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ); /** * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type * This is done through a separate function entrypoint instead of allowing the sequencer inbox * to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either * every delayed inbox or every sequencer inbox call. */ function submitBatchSpendingReport(address batchPoster, bytes32 dataHash) external returns (uint256 msgNum); // ---------- onlyRollupOrOwner functions ---------- function setSequencerInbox(address _sequencerInbox) external; function setDelayedInbox(address inbox, bool enabled) external; function setOutbox(address inbox, bool enabled) external; // ---------- initializer ---------- function initialize(IOwnable rollup_) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IBridge.sol"; import "./IDelayedMessageProvider.sol"; import "./ISequencerInbox.sol"; interface IInbox is IDelayedMessageProvider { function bridge() external view returns (IBridge); function sequencerInbox() external view returns (ISequencerInbox); /** * @notice Send a generic L2 message to the chain * @dev This method is an optimization to avoid having to emit the entirety of the messageData in a log. Instead validators are expected to be able to parse the data from the transaction's input * This method will be disabled upon L1 fork to prevent replay attacks on L2 * @param messageData Data of the message being sent */ function sendL2MessageFromOrigin(bytes calldata messageData) external returns (uint256); /** * @notice Send a generic L2 message to the chain * @dev This method can be used to send any type of message that doesn't require L1 validation * This method will be disabled upon L1 fork to prevent replay attacks on L2 * @param messageData Data of the message being sent */ function sendL2Message(bytes calldata messageData) external returns (uint256); function sendL1FundedUnsignedTransaction( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, address to, bytes calldata data ) external payable returns (uint256); function sendL1FundedContractTransaction( uint256 gasLimit, uint256 maxFeePerGas, address to, bytes calldata data ) external payable returns (uint256); function sendUnsignedTransaction( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, address to, uint256 value, bytes calldata data ) external returns (uint256); function sendContractTransaction( uint256 gasLimit, uint256 maxFeePerGas, address to, uint256 value, bytes calldata data ) external returns (uint256); /** * @dev This method can only be called upon L1 fork and will not alias the caller * This method will revert if not called from origin */ function sendL1FundedUnsignedTransactionToFork( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, address to, bytes calldata data ) external payable returns (uint256); /** * @dev This method can only be called upon L1 fork and will not alias the caller * This method will revert if not called from origin */ function sendUnsignedTransactionToFork( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, address to, uint256 value, bytes calldata data ) external returns (uint256); /** * @notice Send a message to initiate L2 withdrawal * @dev This method can only be called upon L1 fork and will not alias the caller * This method will revert if not called from origin */ function sendWithdrawEthToFork( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, uint256 value, address withdrawTo ) external returns (uint256); /** * @notice Get the L1 fee for submitting a retryable * @dev This fee can be paid by funds already in the L2 aliased address or by the current message value * @dev This formula may change in the future, to future proof your code query this method instead of inlining!! * @param dataLength The length of the retryable's calldata, in bytes * @param baseFee The block basefee when the retryable is included in the chain, if 0 current block.basefee will be used */ function calculateRetryableSubmissionFee(uint256 dataLength, uint256 baseFee) external view returns (uint256); /** * @notice Deposit eth from L1 to L2 to address of the sender if sender is an EOA, and to its aliased address if the sender is a contract * @dev This does not trigger the fallback function when receiving in the L2 side. * Look into retryable tickets if you are interested in this functionality. * @dev This function should not be called inside contract constructors */ function depositEth() external payable returns (uint256); /** * @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts * @dev all msg.value will deposited to callValueRefundAddress on L2 * @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error * @param to destination L2 contract address * @param l2CallValue call value for retryable L2 message * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee * @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled * @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) * @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) * @param data ABI encoded data of L2 message * @return unique message number of the retryable transaction */ function createRetryableTicket( address to, uint256 l2CallValue, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes calldata data ) external payable returns (uint256); /** * @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts * @dev Same as createRetryableTicket, but does not guarantee that submission will succeed by requiring the needed funds * come from the deposit alone, rather than falling back on the user's L2 balance * @dev Advanced usage only (does not rewrite aliases for excessFeeRefundAddress and callValueRefundAddress). * createRetryableTicket method is the recommended standard. * @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error * @param to destination L2 contract address * @param l2CallValue call value for retryable L2 message * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee * @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled * @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) * @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) * @param data ABI encoded data of L2 message * @return unique message number of the retryable transaction */ function unsafeCreateRetryableTicket( address to, uint256 l2CallValue, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes calldata data ) external payable returns (uint256); // ---------- onlyRollupOrOwner functions ---------- /// @notice pauses all inbox functionality function pause() external; /// @notice unpauses all inbox functionality function unpause() external; // ---------- initializer ---------- /** * @dev function to be called one time during the inbox upgrade process * this is used to fix the storage slots */ function postUpgradeInit(IBridge _bridge) external; function initialize(IBridge _bridge, ISequencerInbox _sequencerInbox) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; pragma experimental ABIEncoderV2; import "../libraries/IGasRefunder.sol"; import "./IDelayedMessageProvider.sol"; import "./IBridge.sol"; interface ISequencerInbox is IDelayedMessageProvider { struct MaxTimeVariation { uint256 delayBlocks; uint256 futureBlocks; uint256 delaySeconds; uint256 futureSeconds; } struct TimeBounds { uint64 minTimestamp; uint64 maxTimestamp; uint64 minBlockNumber; uint64 maxBlockNumber; } enum BatchDataLocation { TxInput, SeparateBatchEvent, NoData } event SequencerBatchDelivered( uint256 indexed batchSequenceNumber, bytes32 indexed beforeAcc, bytes32 indexed afterAcc, bytes32 delayedAcc, uint256 afterDelayedMessagesRead, TimeBounds timeBounds, BatchDataLocation dataLocation ); event OwnerFunctionCalled(uint256 indexed id); /// @dev a separate event that emits batch data when this isn't easily accessible in the tx.input event SequencerBatchData(uint256 indexed batchSequenceNumber, bytes data); /// @dev a valid keyset was added event SetValidKeyset(bytes32 indexed keysetHash, bytes keysetBytes); /// @dev a keyset was invalidated event InvalidateKeyset(bytes32 indexed keysetHash); function totalDelayedMessagesRead() external view returns (uint256); function bridge() external view returns (IBridge); /// @dev The size of the batch header // solhint-disable-next-line func-name-mixedcase function HEADER_LENGTH() external view returns (uint256); /// @dev If the first batch data byte after the header has this bit set, /// the sequencer inbox has authenticated the data. Currently not used. // solhint-disable-next-line func-name-mixedcase function DATA_AUTHENTICATED_FLAG() external view returns (bytes1); function rollup() external view returns (IOwnable); function isBatchPoster(address) external view returns (bool); struct DasKeySetInfo { bool isValidKeyset; uint64 creationBlock; } // https://github.com/ethereum/solidity/issues/11826 // function maxTimeVariation() external view returns (MaxTimeVariation calldata); // function dasKeySetInfo(bytes32) external view returns (DasKeySetInfo calldata); /// @notice Remove force inclusion delay after a L1 chainId fork function removeDelayAfterFork() external; /// @notice Force messages from the delayed inbox to be included in the chain /// Callable by any address, but message can only be force-included after maxTimeVariation.delayBlocks and /// maxTimeVariation.delaySeconds has elapsed. As part of normal behaviour the sequencer will include these /// messages so it's only necessary to call this if the sequencer is down, or not including any delayed messages. /// @param _totalDelayedMessagesRead The total number of messages to read up to /// @param kind The kind of the last message to be included /// @param l1BlockAndTime The l1 block and the l1 timestamp of the last message to be included /// @param baseFeeL1 The l1 gas price of the last message to be included /// @param sender The sender of the last message to be included /// @param messageDataHash The messageDataHash of the last message to be included function forceInclusion( uint256 _totalDelayedMessagesRead, uint8 kind, uint64[2] calldata l1BlockAndTime, uint256 baseFeeL1, address sender, bytes32 messageDataHash ) external; function inboxAccs(uint256 index) external view returns (bytes32); function batchCount() external view returns (uint256); function isValidKeysetHash(bytes32 ksHash) external view returns (bool); /// @notice the creation block is intended to still be available after a keyset is deleted function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256); // ---------- BatchPoster functions ---------- function addSequencerL2BatchFromOrigin( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder ) external; function addSequencerL2Batch( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder, uint256 prevMessageCount, uint256 newMessageCount ) external; // ---------- onlyRollupOrOwner functions ---------- /** * @notice Set max delay for sequencer inbox * @param maxTimeVariation_ the maximum time variation parameters */ function setMaxTimeVariation(MaxTimeVariation memory maxTimeVariation_) external; /** * @notice Updates whether an address is authorized to be a batch poster at the sequencer inbox * @param addr the address * @param isBatchPoster_ if the specified address should be authorized as a batch poster */ function setIsBatchPoster(address addr, bool isBatchPoster_) external; /** * @notice Makes Data Availability Service keyset valid * @param keysetBytes bytes of the serialized keyset */ function setValidKeyset(bytes calldata keysetBytes) external; /** * @notice Invalidates a Data Availability Service keyset * @param ksHash hash of the keyset */ function invalidateKeysetHash(bytes32 ksHash) external; // ---------- initializer ---------- function initialize(IBridge bridge_, MaxTimeVariation calldata maxTimeVariation_) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./RollupLib.sol"; import "./IRollupCore.sol"; import "../bridge/ISequencerInbox.sol"; import "../bridge/IOutbox.sol"; import "../bridge/IOwnable.sol"; interface IRollupUserAbs is IRollupCore, IOwnable { /// @dev the user logic just validated configuration and shouldn't write to state during init /// this allows the admin logic to ensure consistency on parameters. function initialize(address stakeToken) external view; function removeWhitelistAfterFork() external; function removeWhitelistAfterValidatorAfk() external; function isERC20Enabled() external view returns (bool); function rejectNextNode(address stakerAddress) external; function confirmNextNode(bytes32 blockHash, bytes32 sendRoot) external; function stakeOnExistingNode(uint64 nodeNum, bytes32 nodeHash) external; function stakeOnNewNode( RollupLib.Assertion memory assertion, bytes32 expectedNodeHash, uint256 prevNodeInboxMaxCount ) external; function returnOldDeposit(address stakerAddress) external; function reduceDeposit(uint256 target) external; function removeZombie(uint256 zombieNum, uint256 maxNodes) external; function removeOldZombies(uint256 startIndex) external; function requiredStake( uint256 blockNumber, uint64 firstUnresolvedNodeNum, uint64 latestCreatedNode ) external view returns (uint256); function currentRequiredStake() external view returns (uint256); function countStakedZombies(uint64 nodeNum) external view returns (uint256); function countZombiesStakedOnChildren(uint64 nodeNum) external view returns (uint256); function requireUnresolvedExists() external view; function requireUnresolved(uint256 nodeNum) external view; function withdrawStakerFunds() external returns (uint256); function createChallenge( address[2] calldata stakers, uint64[2] calldata nodeNums, MachineStatus[2] calldata machineStatuses, GlobalState[2] calldata globalStates, uint64 numBlocks, bytes32 secondExecutionHash, uint256[2] calldata proposedTimes, bytes32[2] calldata wasmModuleRoots ) external; } interface IRollupUser is IRollupUserAbs { function newStakeOnExistingNode(uint64 nodeNum, bytes32 nodeHash) external payable; function newStakeOnNewNode( RollupLib.Assertion calldata assertion, bytes32 expectedNodeHash, uint256 prevNodeInboxMaxCount ) external payable; function addToDeposit(address stakerAddress) external payable; } interface IRollupUserERC20 is IRollupUserAbs { function newStakeOnExistingNode( uint256 tokenAmount, uint64 nodeNum, bytes32 nodeHash ) external; function newStakeOnNewNode( uint256 tokenAmount, RollupLib.Assertion calldata assertion, bytes32 expectedNodeHash, uint256 prevNodeInboxMaxCount ) external; function addToDeposit(address stakerAddress, uint256 tokenAmount) external; } interface IRollupAdmin { event OwnerFunctionCalled(uint256 indexed id); function initialize(Config calldata config, ContractDependencies calldata connectedContracts) external; /** * @notice Add a contract authorized to put messages into this rollup's inbox * @param _outbox Outbox contract to add */ function setOutbox(IOutbox _outbox) external; /** * @notice Disable an old outbox from interacting with the bridge * @param _outbox Outbox contract to remove */ function removeOldOutbox(address _outbox) external; /** * @notice Enable or disable an inbox contract * @param _inbox Inbox contract to add or remove * @param _enabled New status of inbox */ function setDelayedInbox(address _inbox, bool _enabled) external; /** * @notice Pause interaction with the rollup contract */ function pause() external; /** * @notice Resume interaction with the rollup contract */ function resume() external; /** * @notice Set the addresses of the validator whitelist * @dev It is expected that both arrays are same length, and validator at * position i corresponds to the value at position i * @param _validator addresses to set in the whitelist * @param _val value to set in the whitelist for corresponding address */ function setValidator(address[] memory _validator, bool[] memory _val) external; /** * @notice Set a new owner address for the rollup proxy * @param newOwner address of new rollup owner */ function setOwner(address newOwner) external; /** * @notice Set minimum assertion period for the rollup * @param newPeriod new minimum period for assertions */ function setMinimumAssertionPeriod(uint256 newPeriod) external; /** * @notice Set number of blocks until a node is considered confirmed * @param newConfirmPeriod new number of blocks until a node is confirmed */ function setConfirmPeriodBlocks(uint64 newConfirmPeriod) external; /** * @notice Set number of extra blocks after a challenge * @param newExtraTimeBlocks new number of blocks */ function setExtraChallengeTimeBlocks(uint64 newExtraTimeBlocks) external; /** * @notice Set base stake required for an assertion * @param newBaseStake maximum avmgas to be used per block */ function setBaseStake(uint256 newBaseStake) external; /** * @notice Set the token used for stake, where address(0) == eth * @dev Before changing the base stake token, you might need to change the * implementation of the Rollup User logic! * @param newStakeToken address of token used for staking */ function setStakeToken(address newStakeToken) external; /** * @notice Upgrades the implementation of a beacon controlled by the rollup * @param beacon address of beacon to be upgraded * @param newImplementation new address of implementation */ function upgradeBeacon(address beacon, address newImplementation) external; function forceResolveChallenge(address[] memory stackerA, address[] memory stackerB) external; function forceRefundStaker(address[] memory stacker) external; function forceCreateNode( uint64 prevNode, uint256 prevNodeInboxMaxCount, RollupLib.Assertion memory assertion, bytes32 expectedNodeHash ) external; function forceConfirmNode( uint64 nodeNum, bytes32 blockHash, bytes32 sendRoot ) external; function setLoserStakeEscrow(address newLoserStakerEscrow) external; /** * @notice Set the proving WASM module root * @param newWasmModuleRoot new module root */ function setWasmModuleRoot(bytes32 newWasmModuleRoot) external; /** * @notice set a new sequencer inbox contract * @param _sequencerInbox new address of sequencer inbox */ function setSequencerInbox(address _sequencerInbox) external; /** * @notice set the validatorWhitelistDisabled flag * @param _validatorWhitelistDisabled new value of validatorWhitelistDisabled, i.e. true = disabled */ function setValidatorWhitelistDisabled(bool _validatorWhitelistDisabled) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library Messages { function messageHash( uint8 kind, address sender, uint64 blockNumber, uint64 timestamp, uint256 inboxSeqNum, uint256 baseFeeL1, bytes32 messageDataHash ) internal pure returns (bytes32) { return keccak256( abi.encodePacked( kind, sender, blockNumber, timestamp, inboxSeqNum, baseFeeL1, messageDataHash ) ); } function accumulateInboxMessage(bytes32 prevAcc, bytes32 message) internal pure returns (bytes32) { return keccak256(abi.encodePacked(prevAcc, message)); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; uint8 constant L2_MSG = 3; uint8 constant L1MessageType_L2FundedByL1 = 7; uint8 constant L1MessageType_submitRetryableTx = 9; uint8 constant L1MessageType_ethDeposit = 12; uint8 constant L1MessageType_batchPostingReport = 13; uint8 constant L2MessageType_unsignedEOATx = 0; uint8 constant L2MessageType_unsignedContractTx = 1; uint8 constant ROLLUP_PROTOCOL_EVENT_TYPE = 8; uint8 constant INITIALIZATION_MSG_TYPE = 11; // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; interface IGasRefunder { function onGasSpent( address payable spender, uint256 gasUsed, uint256 calldataSize ) external returns (bool success); } abstract contract GasRefundEnabled { /// @dev this refunds the sender for execution costs of the tx /// calldata costs are only refunded if `msg.sender == tx.origin` to guarantee the value refunded relates to charging /// for the `tx.input`. this avoids a possible attack where you generate large calldata from a contract and get over-refunded modifier refundsGas(IGasRefunder gasRefunder) { uint256 startGasLeft = gasleft(); _; if (address(gasRefunder) != address(0)) { uint256 calldataSize; assembly { calldataSize := calldatasize() } uint256 calldataWords = (calldataSize + 31) / 32; // account for the CALLDATACOPY cost of the proxy contract, including the memory expansion cost startGasLeft += calldataWords * 6 + (calldataWords**2) / 512; // if triggered in a contract call, the spender may be overrefunded by appending dummy data to the call // so we check if it is a top level call, which would mean the sender paid calldata as part of tx.input // solhint-disable-next-line avoid-tx-origin if (msg.sender != tx.origin) { // We can't be sure if this calldata came from the top level tx, // so to be safe we tell the gas refunder there was no calldata. calldataSize = 0; } gasRefunder.onGasSpent(payable(msg.sender), startGasLeft - gasleft(), calldataSize); } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {NotOwner} from "./Error.sol"; /// @dev A stateless contract that allows you to infer if the current call has been delegated or not /// Pattern used here is from UUPS implementation by the OpenZeppelin team abstract contract DelegateCallAware { address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegate call. This allows a function to be * callable on the proxy contract but not on the logic contract. */ modifier onlyDelegated() { require(address(this) != __self, "Function must be called through delegatecall"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "Function must not be called through delegatecall"); _; } /// @dev Check that msg.sender is the current EIP 1967 proxy admin modifier onlyProxyOwner() { // Storage slot with the admin of the proxy contract // This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1 bytes32 slot = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; address admin; assembly { admin := sload(slot) } if (msg.sender != admin) revert NotOwner(msg.sender, admin); _; } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; // 90% of Geth's 128KB tx size limit, leaving ~13KB for proving uint256 constant MAX_DATA_SIZE = 117964; uint64 constant NO_CHAL_INDEX = 0; // Expected seconds per block in Ethereum PoS uint256 constant ETH_POS_BLOCK_TIME = 12; // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.4.21 <0.9.0; interface IOwnable { function owner() external view returns (address); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; interface IDelayedMessageProvider { /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator event InboxMessageDelivered(uint256 indexed messageNum, bytes data); /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator /// same as InboxMessageDelivered but the batch data is available in tx.input event InboxMessageDeliveredFromOrigin(uint256 indexed messageNum); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../challenge/IChallengeManager.sol"; import "../challenge/ChallengeLib.sol"; import "../state/GlobalState.sol"; import "../bridge/ISequencerInbox.sol"; import "../bridge/IBridge.sol"; import "../bridge/IOutbox.sol"; import "../bridge/IInbox.sol"; import "./IRollupEventInbox.sol"; import "./IRollupLogic.sol"; struct Config { uint64 confirmPeriodBlocks; uint64 extraChallengeTimeBlocks; address stakeToken; uint256 baseStake; bytes32 wasmModuleRoot; address owner; address loserStakeEscrow; uint256 chainId; uint64 genesisBlockNum; ISequencerInbox.MaxTimeVariation sequencerInboxMaxTimeVariation; } struct ContractDependencies { IBridge bridge; ISequencerInbox sequencerInbox; IInbox inbox; IOutbox outbox; IRollupEventInbox rollupEventInbox; IChallengeManager challengeManager; IRollupAdmin rollupAdminLogic; IRollupUser rollupUserLogic; // misc contracts that are useful when interacting with the rollup address validatorUtils; address validatorWalletCreator; } library RollupLib { using GlobalStateLib for GlobalState; struct ExecutionState { GlobalState globalState; MachineStatus machineStatus; } function stateHash(ExecutionState calldata execState, uint256 inboxMaxCount) internal pure returns (bytes32) { return keccak256( abi.encodePacked( execState.globalState.hash(), inboxMaxCount, execState.machineStatus ) ); } /// @dev same as stateHash but expects execState in memory instead of calldata function stateHashMem(ExecutionState memory execState, uint256 inboxMaxCount) internal pure returns (bytes32) { return keccak256( abi.encodePacked( execState.globalState.hash(), inboxMaxCount, execState.machineStatus ) ); } struct Assertion { ExecutionState beforeState; ExecutionState afterState; uint64 numBlocks; } function executionHash(Assertion memory assertion) internal pure returns (bytes32) { MachineStatus[2] memory statuses; statuses[0] = assertion.beforeState.machineStatus; statuses[1] = assertion.afterState.machineStatus; GlobalState[2] memory globalStates; globalStates[0] = assertion.beforeState.globalState; globalStates[1] = assertion.afterState.globalState; // TODO: benchmark how much this abstraction adds of gas overhead return executionHash(statuses, globalStates, assertion.numBlocks); } function executionHash( MachineStatus[2] memory statuses, GlobalState[2] memory globalStates, uint64 numBlocks ) internal pure returns (bytes32) { bytes32[] memory segments = new bytes32[](2); segments[0] = ChallengeLib.blockStateHash(statuses[0], globalStates[0].hash()); segments[1] = ChallengeLib.blockStateHash(statuses[1], globalStates[1].hash()); return ChallengeLib.hashChallengeState(0, numBlocks, segments); } function challengeRootHash( bytes32 execution, uint256 proposedTime, bytes32 wasmModuleRoot ) internal pure returns (bytes32) { return keccak256(abi.encodePacked(execution, proposedTime, wasmModuleRoot)); } function confirmHash(Assertion memory assertion) internal pure returns (bytes32) { return confirmHash( assertion.afterState.globalState.getBlockHash(), assertion.afterState.globalState.getSendRoot() ); } function confirmHash(bytes32 blockHash, bytes32 sendRoot) internal pure returns (bytes32) { return keccak256(abi.encodePacked(blockHash, sendRoot)); } function nodeHash( bool hasSibling, bytes32 lastHash, bytes32 assertionExecHash, bytes32 inboxAcc, bytes32 wasmModuleRoot ) internal pure returns (bytes32) { uint8 hasSiblingInt = hasSibling ? 1 : 0; return keccak256( abi.encodePacked( hasSiblingInt, lastHash, assertionExecHash, inboxAcc, wasmModuleRoot ) ); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Node.sol"; import "./RollupLib.sol"; interface IRollupCore { struct Staker { uint256 amountStaked; uint64 index; uint64 latestStakedNode; // currentChallenge is 0 if staker is not in a challenge uint64 currentChallenge; bool isStaked; } event RollupInitialized(bytes32 machineHash, uint256 chainId); event NodeCreated( uint64 indexed nodeNum, bytes32 indexed parentNodeHash, bytes32 indexed nodeHash, bytes32 executionHash, RollupLib.Assertion assertion, bytes32 afterInboxBatchAcc, bytes32 wasmModuleRoot, uint256 inboxMaxCount ); event NodeConfirmed(uint64 indexed nodeNum, bytes32 blockHash, bytes32 sendRoot); event NodeRejected(uint64 indexed nodeNum); event RollupChallengeStarted( uint64 indexed challengeIndex, address asserter, address challenger, uint64 challengedNode ); event UserStakeUpdated(address indexed user, uint256 initialBalance, uint256 finalBalance); event UserWithdrawableFundsUpdated( address indexed user, uint256 initialBalance, uint256 finalBalance ); function confirmPeriodBlocks() external view returns (uint64); function extraChallengeTimeBlocks() external view returns (uint64); function chainId() external view returns (uint256); function baseStake() external view returns (uint256); function wasmModuleRoot() external view returns (bytes32); function bridge() external view returns (IBridge); function sequencerInbox() external view returns (ISequencerInbox); function outbox() external view returns (IOutbox); function rollupEventInbox() external view returns (IRollupEventInbox); function challengeManager() external view returns (IChallengeManager); function loserStakeEscrow() external view returns (address); function stakeToken() external view returns (address); function minimumAssertionPeriod() external view returns (uint256); function isValidator(address) external view returns (bool); function validatorWhitelistDisabled() external view returns (bool); /** * @notice Get the Node for the given index. */ function getNode(uint64 nodeNum) external view returns (Node memory); /** * @notice Check if the specified node has been staked on by the provided staker. * Only accurate at the latest confirmed node and afterwards. */ function nodeHasStaker(uint64 nodeNum, address staker) external view returns (bool); /** * @notice Get the address of the staker at the given index * @param stakerNum Index of the staker * @return Address of the staker */ function getStakerAddress(uint64 stakerNum) external view returns (address); /** * @notice Check whether the given staker is staked * @param staker Staker address to check * @return True or False for whether the staker was staked */ function isStaked(address staker) external view returns (bool); /** * @notice Get the latest staked node of the given staker * @param staker Staker address to lookup * @return Latest node staked of the staker */ function latestStakedNode(address staker) external view returns (uint64); /** * @notice Get the current challenge of the given staker * @param staker Staker address to lookup * @return Current challenge of the staker */ function currentChallenge(address staker) external view returns (uint64); /** * @notice Get the amount staked of the given staker * @param staker Staker address to lookup * @return Amount staked of the staker */ function amountStaked(address staker) external view returns (uint256); /** * @notice Retrieves stored information about a requested staker * @param staker Staker address to retrieve * @return A structure with information about the requested staker */ function getStaker(address staker) external view returns (Staker memory); /** * @notice Get the original staker address of the zombie at the given index * @param zombieNum Index of the zombie to lookup * @return Original staker address of the zombie */ function zombieAddress(uint256 zombieNum) external view returns (address); /** * @notice Get Latest node that the given zombie at the given index is staked on * @param zombieNum Index of the zombie to lookup * @return Latest node that the given zombie is staked on */ function zombieLatestStakedNode(uint256 zombieNum) external view returns (uint64); /// @return Current number of un-removed zombies function zombieCount() external view returns (uint256); function isZombie(address staker) external view returns (bool); /** * @notice Get the amount of funds withdrawable by the given address * @param owner Address to check the funds of * @return Amount of funds withdrawable by owner */ function withdrawableFunds(address owner) external view returns (uint256); /** * @return Index of the first unresolved node * @dev If all nodes have been resolved, this will be latestNodeCreated + 1 */ function firstUnresolvedNode() external view returns (uint64); /// @return Index of the latest confirmed node function latestConfirmed() external view returns (uint64); /// @return Index of the latest rollup node created function latestNodeCreated() external view returns (uint64); /// @return Ethereum block that the most recent stake was created function lastStakeBlock() external view returns (uint64); /// @return Number of active stakers currently staked function stakerCount() external view returns (uint64); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IBridge.sol"; interface IOutbox { event SendRootUpdated(bytes32 indexed outputRoot, bytes32 indexed l2BlockHash); event OutBoxTransactionExecuted( address indexed to, address indexed l2Sender, uint256 indexed zero, uint256 transactionIndex ); function rollup() external view returns (address); // the rollup contract function bridge() external view returns (IBridge); // the bridge contract function spent(uint256) external view returns (bytes32); // packed spent bitmap function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash // solhint-disable-next-line func-name-mixedcase function OUTBOX_VERSION() external view returns (uint128); // the outbox version function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external; /// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account /// When the return value is zero, that means this is a system message /// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies function l2ToL1Sender() external view returns (address); /// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1Block() external view returns (uint256); /// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1EthBlock() external view returns (uint256); /// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1Timestamp() external view returns (uint256); /// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active function l2ToL1OutputId() external view returns (bytes32); /** * @notice Executes a messages in an Outbox entry. * @dev Reverts if dispute period hasn't expired, since the outbox entry * is only created once the rollup confirms the respective assertion. * @dev it is not possible to execute any L2-to-L1 transaction which contains data * to a contract address without any code (as enforced by the Bridge contract). * @param proof Merkle proof of message inclusion in send root * @param index Merkle path to message * @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1) * @param to destination address for L1 contract call * @param l2Block l2 block number at which sendTxToL1 call was made * @param l1Block l1 block number at which sendTxToL1 call was made * @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made * @param value wei in L1 message * @param data abi-encoded L1 message data */ function executeTransaction( bytes32[] calldata proof, uint256 index, address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external; /** * @dev function used to simulate the result of a particular function call from the outbox * it is useful for things such as gas estimates. This function includes all costs except for * proof validation (which can be considered offchain as a somewhat of a fixed cost - it's * not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation). * We can't include the cost of proof validation since this is intended to be used to simulate txs * that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend * to confirm a pending merkle root, but that would be less practical for integrating with tooling. * It is only possible to trigger it when the msg sender is address zero, which should be impossible * unless under simulation in an eth_call or eth_estimateGas */ function executeTransactionSimulation( uint256 index, address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external; /** * @param index Merkle path to message * @return true if the message has been spent */ function isSpent(uint256 index) external view returns (bool); function calculateItemHash( address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external pure returns (bytes32); function calculateMerkleRoot( bytes32[] memory proof, uint256 path, bytes32 item ) external pure returns (bytes32); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../state/Machine.sol"; import "../bridge/IBridge.sol"; import "../bridge/ISequencerInbox.sol"; import "../osp/IOneStepProofEntry.sol"; import "./IChallengeResultReceiver.sol"; import "./ChallengeLib.sol"; interface IChallengeManager { enum ChallengeTerminationType { TIMEOUT, BLOCK_PROOF, EXECUTION_PROOF, CLEARED } event InitiatedChallenge( uint64 indexed challengeIndex, GlobalState startState, GlobalState endState ); event Bisected( uint64 indexed challengeIndex, bytes32 indexed challengeRoot, uint256 challengedSegmentStart, uint256 challengedSegmentLength, bytes32[] chainHashes ); event ExecutionChallengeBegun(uint64 indexed challengeIndex, uint256 blockSteps); event OneStepProofCompleted(uint64 indexed challengeIndex); event ChallengeEnded(uint64 indexed challengeIndex, ChallengeTerminationType kind); function initialize( IChallengeResultReceiver resultReceiver_, ISequencerInbox sequencerInbox_, IBridge bridge_, IOneStepProofEntry osp_ ) external; function createChallenge( bytes32 wasmModuleRoot_, MachineStatus[2] calldata startAndEndMachineStatuses_, GlobalState[2] calldata startAndEndGlobalStates_, uint64 numBlocks, address asserter_, address challenger_, uint256 asserterTimeLeft_, uint256 challengerTimeLeft_ ) external returns (uint64); function challengeInfo(uint64 challengeIndex_) external view returns (ChallengeLib.Challenge memory); function currentResponder(uint64 challengeIndex) external view returns (address); function isTimedOut(uint64 challengeIndex) external view returns (bool); function clearChallenge(uint64 challengeIndex_) external; function timeout(uint64 challengeIndex_) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../state/Machine.sol"; import "../state/GlobalState.sol"; library ChallengeLib { using MachineLib for Machine; using ChallengeLib for Challenge; /// @dev It's assumed that that uninitialzed challenges have mode NONE enum ChallengeMode { NONE, BLOCK, EXECUTION } struct Participant { address addr; uint256 timeLeft; } struct Challenge { Participant current; Participant next; uint256 lastMoveTimestamp; bytes32 wasmModuleRoot; bytes32 challengeStateHash; uint64 maxInboxMessages; ChallengeMode mode; } struct SegmentSelection { uint256 oldSegmentsStart; uint256 oldSegmentsLength; bytes32[] oldSegments; uint256 challengePosition; } function timeUsedSinceLastMove(Challenge storage challenge) internal view returns (uint256) { return block.timestamp - challenge.lastMoveTimestamp; } function isTimedOut(Challenge storage challenge) internal view returns (bool) { return challenge.timeUsedSinceLastMove() > challenge.current.timeLeft; } function getStartMachineHash(bytes32 globalStateHash, bytes32 wasmModuleRoot) internal pure returns (bytes32) { // Start the value stack with the function call ABI for the entrypoint Value[] memory startingValues = new Value[](3); startingValues[0] = ValueLib.newRefNull(); startingValues[1] = ValueLib.newI32(0); startingValues[2] = ValueLib.newI32(0); ValueArray memory valuesArray = ValueArray({inner: startingValues}); ValueStack memory values = ValueStack({proved: valuesArray, remainingHash: 0}); ValueStack memory internalStack; StackFrameWindow memory frameStack; Machine memory mach = Machine({ status: MachineStatus.RUNNING, valueStack: values, internalStack: internalStack, frameStack: frameStack, globalStateHash: globalStateHash, moduleIdx: 0, functionIdx: 0, functionPc: 0, modulesRoot: wasmModuleRoot }); return mach.hash(); } function getEndMachineHash(MachineStatus status, bytes32 globalStateHash) internal pure returns (bytes32) { if (status == MachineStatus.FINISHED) { return keccak256(abi.encodePacked("Machine finished:", globalStateHash)); } else if (status == MachineStatus.ERRORED) { return keccak256(abi.encodePacked("Machine errored:")); } else if (status == MachineStatus.TOO_FAR) { return keccak256(abi.encodePacked("Machine too far:")); } else { revert("BAD_BLOCK_STATUS"); } } function extractChallengeSegment(SegmentSelection calldata selection) internal pure returns (uint256 segmentStart, uint256 segmentLength) { uint256 oldChallengeDegree = selection.oldSegments.length - 1; segmentLength = selection.oldSegmentsLength / oldChallengeDegree; // Intentionally done before challengeLength is potentially added to for the final segment segmentStart = selection.oldSegmentsStart + segmentLength * selection.challengePosition; if (selection.challengePosition == selection.oldSegments.length - 2) { segmentLength += selection.oldSegmentsLength % oldChallengeDegree; } } function hashChallengeState( uint256 segmentsStart, uint256 segmentsLength, bytes32[] memory segments ) internal pure returns (bytes32) { return keccak256(abi.encodePacked(segmentsStart, segmentsLength, segments)); } function blockStateHash(MachineStatus status, bytes32 globalStateHash) internal pure returns (bytes32) { if (status == MachineStatus.FINISHED) { return keccak256(abi.encodePacked("Block state:", globalStateHash)); } else if (status == MachineStatus.ERRORED) { return keccak256(abi.encodePacked("Block state, errored:", globalStateHash)); } else if (status == MachineStatus.TOO_FAR) { return keccak256(abi.encodePacked("Block state, too far:")); } else { revert("BAD_BLOCK_STATUS"); } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct GlobalState { bytes32[2] bytes32Vals; uint64[2] u64Vals; } library GlobalStateLib { uint16 internal constant BYTES32_VALS_NUM = 2; uint16 internal constant U64_VALS_NUM = 2; function hash(GlobalState memory state) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Global state:", state.bytes32Vals[0], state.bytes32Vals[1], state.u64Vals[0], state.u64Vals[1] ) ); } function getBlockHash(GlobalState memory state) internal pure returns (bytes32) { return state.bytes32Vals[0]; } function getSendRoot(GlobalState memory state) internal pure returns (bytes32) { return state.bytes32Vals[1]; } function getInboxPosition(GlobalState memory state) internal pure returns (uint64) { return state.u64Vals[0]; } function getPositionInMessage(GlobalState memory state) internal pure returns (uint64) { return state.u64Vals[1]; } function isEmpty(GlobalState calldata state) internal pure returns (bool) { return (state.bytes32Vals[0] == bytes32(0) && state.bytes32Vals[1] == bytes32(0) && state.u64Vals[0] == 0 && state.u64Vals[1] == 0); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../bridge/IBridge.sol"; interface IRollupEventInbox { function bridge() external view returns (IBridge); function initialize(IBridge _bridge) external; function rollup() external view returns (address); function rollupInitialized(uint256 chainId) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./ValueStack.sol"; import "./Instructions.sol"; import "./StackFrame.sol"; enum MachineStatus { RUNNING, FINISHED, ERRORED, TOO_FAR } struct Machine { MachineStatus status; ValueStack valueStack; ValueStack internalStack; StackFrameWindow frameStack; bytes32 globalStateHash; uint32 moduleIdx; uint32 functionIdx; uint32 functionPc; bytes32 modulesRoot; } library MachineLib { using StackFrameLib for StackFrameWindow; using ValueStackLib for ValueStack; function hash(Machine memory mach) internal pure returns (bytes32) { // Warning: the non-running hashes are replicated in Challenge if (mach.status == MachineStatus.RUNNING) { return keccak256( abi.encodePacked( "Machine running:", mach.valueStack.hash(), mach.internalStack.hash(), mach.frameStack.hash(), mach.globalStateHash, mach.moduleIdx, mach.functionIdx, mach.functionPc, mach.modulesRoot ) ); } else if (mach.status == MachineStatus.FINISHED) { return keccak256(abi.encodePacked("Machine finished:", mach.globalStateHash)); } else if (mach.status == MachineStatus.ERRORED) { return keccak256(abi.encodePacked("Machine errored:")); } else if (mach.status == MachineStatus.TOO_FAR) { return keccak256(abi.encodePacked("Machine too far:")); } else { revert("BAD_MACH_STATUS"); } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./IOneStepProver.sol"; library OneStepProofEntryLib { uint256 internal constant MAX_STEPS = 1 << 43; } interface IOneStepProofEntry { function proveOneStep( ExecutionContext calldata execCtx, uint256 machineStep, bytes32 beforeHash, bytes calldata proof ) external view returns (bytes32 afterHash); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; interface IChallengeResultReceiver { function completeChallenge( uint256 challengeIndex, address winner, address loser ) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./ValueArray.sol"; struct ValueStack { ValueArray proved; bytes32 remainingHash; } library ValueStackLib { using ValueLib for Value; using ValueArrayLib for ValueArray; function hash(ValueStack memory stack) internal pure returns (bytes32 h) { h = stack.remainingHash; uint256 len = stack.proved.length(); for (uint256 i = 0; i < len; i++) { h = keccak256(abi.encodePacked("Value stack:", stack.proved.get(i).hash(), h)); } } function peek(ValueStack memory stack) internal pure returns (Value memory) { uint256 len = stack.proved.length(); return stack.proved.get(len - 1); } function pop(ValueStack memory stack) internal pure returns (Value memory) { return stack.proved.pop(); } function push(ValueStack memory stack, Value memory val) internal pure { return stack.proved.push(val); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct Instruction { uint16 opcode; uint256 argumentData; } library Instructions { uint16 internal constant UNREACHABLE = 0x00; uint16 internal constant NOP = 0x01; uint16 internal constant RETURN = 0x0F; uint16 internal constant CALL = 0x10; uint16 internal constant CALL_INDIRECT = 0x11; uint16 internal constant LOCAL_GET = 0x20; uint16 internal constant LOCAL_SET = 0x21; uint16 internal constant GLOBAL_GET = 0x23; uint16 internal constant GLOBAL_SET = 0x24; uint16 internal constant I32_LOAD = 0x28; uint16 internal constant I64_LOAD = 0x29; uint16 internal constant F32_LOAD = 0x2A; uint16 internal constant F64_LOAD = 0x2B; uint16 internal constant I32_LOAD8_S = 0x2C; uint16 internal constant I32_LOAD8_U = 0x2D; uint16 internal constant I32_LOAD16_S = 0x2E; uint16 internal constant I32_LOAD16_U = 0x2F; uint16 internal constant I64_LOAD8_S = 0x30; uint16 internal constant I64_LOAD8_U = 0x31; uint16 internal constant I64_LOAD16_S = 0x32; uint16 internal constant I64_LOAD16_U = 0x33; uint16 internal constant I64_LOAD32_S = 0x34; uint16 internal constant I64_LOAD32_U = 0x35; uint16 internal constant I32_STORE = 0x36; uint16 internal constant I64_STORE = 0x37; uint16 internal constant F32_STORE = 0x38; uint16 internal constant F64_STORE = 0x39; uint16 internal constant I32_STORE8 = 0x3A; uint16 internal constant I32_STORE16 = 0x3B; uint16 internal constant I64_STORE8 = 0x3C; uint16 internal constant I64_STORE16 = 0x3D; uint16 internal constant I64_STORE32 = 0x3E; uint16 internal constant MEMORY_SIZE = 0x3F; uint16 internal constant MEMORY_GROW = 0x40; uint16 internal constant DROP = 0x1A; uint16 internal constant SELECT = 0x1B; uint16 internal constant I32_CONST = 0x41; uint16 internal constant I64_CONST = 0x42; uint16 internal constant F32_CONST = 0x43; uint16 internal constant F64_CONST = 0x44; uint16 internal constant I32_EQZ = 0x45; uint16 internal constant I32_RELOP_BASE = 0x46; uint16 internal constant IRELOP_EQ = 0; uint16 internal constant IRELOP_NE = 1; uint16 internal constant IRELOP_LT_S = 2; uint16 internal constant IRELOP_LT_U = 3; uint16 internal constant IRELOP_GT_S = 4; uint16 internal constant IRELOP_GT_U = 5; uint16 internal constant IRELOP_LE_S = 6; uint16 internal constant IRELOP_LE_U = 7; uint16 internal constant IRELOP_GE_S = 8; uint16 internal constant IRELOP_GE_U = 9; uint16 internal constant IRELOP_LAST = IRELOP_GE_U; uint16 internal constant I64_EQZ = 0x50; uint16 internal constant I64_RELOP_BASE = 0x51; uint16 internal constant I32_UNOP_BASE = 0x67; uint16 internal constant IUNOP_CLZ = 0; uint16 internal constant IUNOP_CTZ = 1; uint16 internal constant IUNOP_POPCNT = 2; uint16 internal constant IUNOP_LAST = IUNOP_POPCNT; uint16 internal constant I32_ADD = 0x6A; uint16 internal constant I32_SUB = 0x6B; uint16 internal constant I32_MUL = 0x6C; uint16 internal constant I32_DIV_S = 0x6D; uint16 internal constant I32_DIV_U = 0x6E; uint16 internal constant I32_REM_S = 0x6F; uint16 internal constant I32_REM_U = 0x70; uint16 internal constant I32_AND = 0x71; uint16 internal constant I32_OR = 0x72; uint16 internal constant I32_XOR = 0x73; uint16 internal constant I32_SHL = 0x74; uint16 internal constant I32_SHR_S = 0x75; uint16 internal constant I32_SHR_U = 0x76; uint16 internal constant I32_ROTL = 0x77; uint16 internal constant I32_ROTR = 0x78; uint16 internal constant I64_UNOP_BASE = 0x79; uint16 internal constant I64_ADD = 0x7C; uint16 internal constant I64_SUB = 0x7D; uint16 internal constant I64_MUL = 0x7E; uint16 internal constant I64_DIV_S = 0x7F; uint16 internal constant I64_DIV_U = 0x80; uint16 internal constant I64_REM_S = 0x81; uint16 internal constant I64_REM_U = 0x82; uint16 internal constant I64_AND = 0x83; uint16 internal constant I64_OR = 0x84; uint16 internal constant I64_XOR = 0x85; uint16 internal constant I64_SHL = 0x86; uint16 internal constant I64_SHR_S = 0x87; uint16 internal constant I64_SHR_U = 0x88; uint16 internal constant I64_ROTL = 0x89; uint16 internal constant I64_ROTR = 0x8A; uint16 internal constant I32_WRAP_I64 = 0xA7; uint16 internal constant I64_EXTEND_I32_S = 0xAC; uint16 internal constant I64_EXTEND_I32_U = 0xAD; uint16 internal constant I32_REINTERPRET_F32 = 0xBC; uint16 internal constant I64_REINTERPRET_F64 = 0xBD; uint16 internal constant F32_REINTERPRET_I32 = 0xBE; uint16 internal constant F64_REINTERPRET_I64 = 0xBF; uint16 internal constant I32_EXTEND_8S = 0xC0; uint16 internal constant I32_EXTEND_16S = 0xC1; uint16 internal constant I64_EXTEND_8S = 0xC2; uint16 internal constant I64_EXTEND_16S = 0xC3; uint16 internal constant I64_EXTEND_32S = 0xC4; uint16 internal constant INIT_FRAME = 0x8002; uint16 internal constant ARBITRARY_JUMP = 0x8003; uint16 internal constant ARBITRARY_JUMP_IF = 0x8004; uint16 internal constant MOVE_FROM_STACK_TO_INTERNAL = 0x8005; uint16 internal constant MOVE_FROM_INTERNAL_TO_STACK = 0x8006; uint16 internal constant DUP = 0x8008; uint16 internal constant CROSS_MODULE_CALL = 0x8009; uint16 internal constant CALLER_MODULE_INTERNAL_CALL = 0x800A; uint16 internal constant GET_GLOBAL_STATE_BYTES32 = 0x8010; uint16 internal constant SET_GLOBAL_STATE_BYTES32 = 0x8011; uint16 internal constant GET_GLOBAL_STATE_U64 = 0x8012; uint16 internal constant SET_GLOBAL_STATE_U64 = 0x8013; uint16 internal constant READ_PRE_IMAGE = 0x8020; uint16 internal constant READ_INBOX_MESSAGE = 0x8021; uint16 internal constant HALT_AND_SET_FINISHED = 0x8022; uint256 internal constant INBOX_INDEX_SEQUENCER = 0; uint256 internal constant INBOX_INDEX_DELAYED = 1; function hash(Instruction memory inst) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Instruction:", inst.opcode, inst.argumentData)); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; struct StackFrame { Value returnPc; bytes32 localsMerkleRoot; uint32 callerModule; uint32 callerModuleInternals; } struct StackFrameWindow { StackFrame[] proved; bytes32 remainingHash; } library StackFrameLib { using ValueLib for Value; function hash(StackFrame memory frame) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Stack frame:", frame.returnPc.hash(), frame.localsMerkleRoot, frame.callerModule, frame.callerModuleInternals ) ); } function hash(StackFrameWindow memory window) internal pure returns (bytes32 h) { h = window.remainingHash; for (uint256 i = 0; i < window.proved.length; i++) { h = keccak256(abi.encodePacked("Stack frame stack:", hash(window.proved[i]), h)); } } function peek(StackFrameWindow memory window) internal pure returns (StackFrame memory) { require(window.proved.length == 1, "BAD_WINDOW_LENGTH"); return window.proved[0]; } function pop(StackFrameWindow memory window) internal pure returns (StackFrame memory frame) { require(window.proved.length == 1, "BAD_WINDOW_LENGTH"); frame = window.proved[0]; window.proved = new StackFrame[](0); } function push(StackFrameWindow memory window, StackFrame memory frame) internal pure { StackFrame[] memory newProved = new StackFrame[](window.proved.length + 1); for (uint256 i = 0; i < window.proved.length; i++) { newProved[i] = window.proved[i]; } newProved[window.proved.length] = frame; window.proved = newProved; } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; enum ValueType { I32, I64, F32, F64, REF_NULL, FUNC_REF, INTERNAL_REF } struct Value { ValueType valueType; uint256 contents; } library ValueLib { function hash(Value memory val) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Value:", val.valueType, val.contents)); } function maxValueType() internal pure returns (ValueType) { return ValueType.INTERNAL_REF; } function assumeI32(Value memory val) internal pure returns (uint32) { uint256 uintval = uint256(val.contents); require(val.valueType == ValueType.I32, "NOT_I32"); require(uintval < (1 << 32), "BAD_I32"); return uint32(uintval); } function assumeI64(Value memory val) internal pure returns (uint64) { uint256 uintval = uint256(val.contents); require(val.valueType == ValueType.I64, "NOT_I64"); require(uintval < (1 << 64), "BAD_I64"); return uint64(uintval); } function newRefNull() internal pure returns (Value memory) { return Value({valueType: ValueType.REF_NULL, contents: 0}); } function newI32(uint32 x) internal pure returns (Value memory) { return Value({valueType: ValueType.I32, contents: uint256(x)}); } function newI64(uint64 x) internal pure returns (Value memory) { return Value({valueType: ValueType.I64, contents: uint256(x)}); } function newBoolean(bool x) internal pure returns (Value memory) { if (x) { return newI32(uint32(1)); } else { return newI32(uint32(0)); } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; struct ValueArray { Value[] inner; } library ValueArrayLib { function get(ValueArray memory arr, uint256 index) internal pure returns (Value memory) { return arr.inner[index]; } function set( ValueArray memory arr, uint256 index, Value memory val ) internal pure { arr.inner[index] = val; } function length(ValueArray memory arr) internal pure returns (uint256) { return arr.inner.length; } function push(ValueArray memory arr, Value memory val) internal pure { Value[] memory newInner = new Value[](arr.inner.length + 1); for (uint256 i = 0; i < arr.inner.length; i++) { newInner[i] = arr.inner[i]; } newInner[arr.inner.length] = val; arr.inner = newInner; } function pop(ValueArray memory arr) internal pure returns (Value memory popped) { popped = arr.inner[arr.inner.length - 1]; Value[] memory newInner = new Value[](arr.inner.length - 1); for (uint256 i = 0; i < newInner.length; i++) { newInner[i] = arr.inner[i]; } arr.inner = newInner; } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../state/Machine.sol"; import "../state/Module.sol"; import "../state/Instructions.sol"; import "../bridge/ISequencerInbox.sol"; import "../bridge/IBridge.sol"; struct ExecutionContext { uint256 maxInboxMessagesRead; IBridge bridge; } abstract contract IOneStepProver { function executeOneStep( ExecutionContext memory execCtx, Machine calldata mach, Module calldata mod, Instruction calldata instruction, bytes calldata proof ) external view virtual returns (Machine memory result, Module memory resultMod); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./ModuleMemory.sol"; struct Module { bytes32 globalsMerkleRoot; ModuleMemory moduleMemory; bytes32 tablesMerkleRoot; bytes32 functionsMerkleRoot; uint32 internalsOffset; } library ModuleLib { using ModuleMemoryLib for ModuleMemory; function hash(Module memory mod) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Module:", mod.globalsMerkleRoot, mod.moduleMemory.hash(), mod.tablesMerkleRoot, mod.functionsMerkleRoot, mod.internalsOffset ) ); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./MerkleProof.sol"; import "./Deserialize.sol"; struct ModuleMemory { uint64 size; uint64 maxSize; bytes32 merkleRoot; } library ModuleMemoryLib { using MerkleProofLib for MerkleProof; function hash(ModuleMemory memory mem) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Memory:", mem.size, mem.maxSize, mem.merkleRoot)); } function proveLeaf( ModuleMemory memory mem, uint256 leafIdx, bytes calldata proof, uint256 startOffset ) internal pure returns ( bytes32 contents, uint256 offset, MerkleProof memory merkle ) { offset = startOffset; (contents, offset) = Deserialize.b32(proof, offset); (merkle, offset) = Deserialize.merkleProof(proof, offset); bytes32 recomputedRoot = merkle.computeRootFromMemory(leafIdx, contents); require(recomputedRoot == mem.merkleRoot, "WRONG_MEM_ROOT"); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./Instructions.sol"; import "./Module.sol"; struct MerkleProof { bytes32[] counterparts; } library MerkleProofLib { using ModuleLib for Module; using ValueLib for Value; function computeRootFromValue( MerkleProof memory proof, uint256 index, Value memory leaf ) internal pure returns (bytes32) { return computeRootUnsafe(proof, index, leaf.hash(), "Value merkle tree:"); } function computeRootFromInstruction( MerkleProof memory proof, uint256 index, Instruction memory inst ) internal pure returns (bytes32) { return computeRootUnsafe(proof, index, Instructions.hash(inst), "Instruction merkle tree:"); } function computeRootFromFunction( MerkleProof memory proof, uint256 index, bytes32 codeRoot ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Function:", codeRoot)); return computeRootUnsafe(proof, index, h, "Function merkle tree:"); } function computeRootFromMemory( MerkleProof memory proof, uint256 index, bytes32 contents ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Memory leaf:", contents)); return computeRootUnsafe(proof, index, h, "Memory merkle tree:"); } function computeRootFromElement( MerkleProof memory proof, uint256 index, bytes32 funcTypeHash, Value memory val ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Table element:", funcTypeHash, val.hash())); return computeRootUnsafe(proof, index, h, "Table element merkle tree:"); } function computeRootFromTable( MerkleProof memory proof, uint256 index, uint8 tableType, uint64 tableSize, bytes32 elementsRoot ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Table:", tableType, tableSize, elementsRoot)); return computeRootUnsafe(proof, index, h, "Table merkle tree:"); } function computeRootFromModule( MerkleProof memory proof, uint256 index, Module memory mod ) internal pure returns (bytes32) { return computeRootUnsafe(proof, index, mod.hash(), "Module merkle tree:"); } // WARNING: leafHash must be computed in such a way that it cannot be a non-leaf hash. function computeRootUnsafe( MerkleProof memory proof, uint256 index, bytes32 leafHash, string memory prefix ) internal pure returns (bytes32 h) { h = leafHash; for (uint256 layer = 0; layer < proof.counterparts.length; layer++) { if (index & 1 == 0) { h = keccak256(abi.encodePacked(prefix, h, proof.counterparts[layer])); } else { h = keccak256(abi.encodePacked(prefix, proof.counterparts[layer], h)); } index >>= 1; } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./ValueStack.sol"; import "./Machine.sol"; import "./Instructions.sol"; import "./StackFrame.sol"; import "./MerkleProof.sol"; import "./ModuleMemory.sol"; import "./Module.sol"; import "./GlobalState.sol"; library Deserialize { function u8(bytes calldata proof, uint256 startOffset) internal pure returns (uint8 ret, uint256 offset) { offset = startOffset; ret = uint8(proof[offset]); offset++; } function u16(bytes calldata proof, uint256 startOffset) internal pure returns (uint16 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 16 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function u32(bytes calldata proof, uint256 startOffset) internal pure returns (uint32 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 32 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function u64(bytes calldata proof, uint256 startOffset) internal pure returns (uint64 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 64 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function u256(bytes calldata proof, uint256 startOffset) internal pure returns (uint256 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 256 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function b32(bytes calldata proof, uint256 startOffset) internal pure returns (bytes32 ret, uint256 offset) { offset = startOffset; uint256 retInt; (retInt, offset) = u256(proof, offset); ret = bytes32(retInt); } function value(bytes calldata proof, uint256 startOffset) internal pure returns (Value memory val, uint256 offset) { offset = startOffset; uint8 typeInt = uint8(proof[offset]); offset++; require(typeInt <= uint8(ValueLib.maxValueType()), "BAD_VALUE_TYPE"); uint256 contents; (contents, offset) = u256(proof, offset); val = Value({valueType: ValueType(typeInt), contents: contents}); } function valueStack(bytes calldata proof, uint256 startOffset) internal pure returns (ValueStack memory stack, uint256 offset) { offset = startOffset; bytes32 remainingHash; (remainingHash, offset) = b32(proof, offset); uint256 provedLength; (provedLength, offset) = u256(proof, offset); Value[] memory proved = new Value[](provedLength); for (uint256 i = 0; i < proved.length; i++) { (proved[i], offset) = value(proof, offset); } stack = ValueStack({proved: ValueArray(proved), remainingHash: remainingHash}); } function instruction(bytes calldata proof, uint256 startOffset) internal pure returns (Instruction memory inst, uint256 offset) { offset = startOffset; uint16 opcode; uint256 data; (opcode, offset) = u16(proof, offset); (data, offset) = u256(proof, offset); inst = Instruction({opcode: opcode, argumentData: data}); } function stackFrame(bytes calldata proof, uint256 startOffset) internal pure returns (StackFrame memory window, uint256 offset) { offset = startOffset; Value memory returnPc; bytes32 localsMerkleRoot; uint32 callerModule; uint32 callerModuleInternals; (returnPc, offset) = value(proof, offset); (localsMerkleRoot, offset) = b32(proof, offset); (callerModule, offset) = u32(proof, offset); (callerModuleInternals, offset) = u32(proof, offset); window = StackFrame({ returnPc: returnPc, localsMerkleRoot: localsMerkleRoot, callerModule: callerModule, callerModuleInternals: callerModuleInternals }); } function stackFrameWindow(bytes calldata proof, uint256 startOffset) internal pure returns (StackFrameWindow memory window, uint256 offset) { offset = startOffset; bytes32 remainingHash; (remainingHash, offset) = b32(proof, offset); StackFrame[] memory proved; if (proof[offset] != 0) { offset++; proved = new StackFrame[](1); (proved[0], offset) = stackFrame(proof, offset); } else { offset++; proved = new StackFrame[](0); } window = StackFrameWindow({proved: proved, remainingHash: remainingHash}); } function moduleMemory(bytes calldata proof, uint256 startOffset) internal pure returns (ModuleMemory memory mem, uint256 offset) { offset = startOffset; uint64 size; uint64 maxSize; bytes32 root; (size, offset) = u64(proof, offset); (maxSize, offset) = u64(proof, offset); (root, offset) = b32(proof, offset); mem = ModuleMemory({size: size, maxSize: maxSize, merkleRoot: root}); } function module(bytes calldata proof, uint256 startOffset) internal pure returns (Module memory mod, uint256 offset) { offset = startOffset; bytes32 globalsMerkleRoot; ModuleMemory memory mem; bytes32 tablesMerkleRoot; bytes32 functionsMerkleRoot; uint32 internalsOffset; (globalsMerkleRoot, offset) = b32(proof, offset); (mem, offset) = moduleMemory(proof, offset); (tablesMerkleRoot, offset) = b32(proof, offset); (functionsMerkleRoot, offset) = b32(proof, offset); (internalsOffset, offset) = u32(proof, offset); mod = Module({ globalsMerkleRoot: globalsMerkleRoot, moduleMemory: mem, tablesMerkleRoot: tablesMerkleRoot, functionsMerkleRoot: functionsMerkleRoot, internalsOffset: internalsOffset }); } function globalState(bytes calldata proof, uint256 startOffset) internal pure returns (GlobalState memory state, uint256 offset) { offset = startOffset; // using constant ints for array size requires newer solidity bytes32[2] memory bytes32Vals; uint64[2] memory u64Vals; for (uint8 i = 0; i < GlobalStateLib.BYTES32_VALS_NUM; i++) { (bytes32Vals[i], offset) = b32(proof, offset); } for (uint8 i = 0; i < GlobalStateLib.U64_VALS_NUM; i++) { (u64Vals[i], offset) = u64(proof, offset); } state = GlobalState({bytes32Vals: bytes32Vals, u64Vals: u64Vals}); } function machine(bytes calldata proof, uint256 startOffset) internal pure returns (Machine memory mach, uint256 offset) { offset = startOffset; MachineStatus status; { uint8 statusU8; (statusU8, offset) = u8(proof, offset); if (statusU8 == 0) { status = MachineStatus.RUNNING; } else if (statusU8 == 1) { status = MachineStatus.FINISHED; } else if (statusU8 == 2) { status = MachineStatus.ERRORED; } else if (statusU8 == 3) { status = MachineStatus.TOO_FAR; } else { revert("UNKNOWN_MACH_STATUS"); } } ValueStack memory values; ValueStack memory internalStack; bytes32 globalStateHash; uint32 moduleIdx; uint32 functionIdx; uint32 functionPc; StackFrameWindow memory frameStack; bytes32 modulesRoot; (values, offset) = valueStack(proof, offset); (internalStack, offset) = valueStack(proof, offset); (frameStack, offset) = stackFrameWindow(proof, offset); (globalStateHash, offset) = b32(proof, offset); (moduleIdx, offset) = u32(proof, offset); (functionIdx, offset) = u32(proof, offset); (functionPc, offset) = u32(proof, offset); (modulesRoot, offset) = b32(proof, offset); mach = Machine({ status: status, valueStack: values, internalStack: internalStack, frameStack: frameStack, globalStateHash: globalStateHash, moduleIdx: moduleIdx, functionIdx: functionIdx, functionPc: functionPc, modulesRoot: modulesRoot }); } function merkleProof(bytes calldata proof, uint256 startOffset) internal pure returns (MerkleProof memory merkle, uint256 offset) { offset = startOffset; uint8 length; (length, offset) = u8(proof, offset); bytes32[] memory counterparts = new bytes32[](length); for (uint8 i = 0; i < length; i++) { (counterparts[i], offset) = b32(proof, offset); } merkle = MerkleProof(counterparts); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct Node { // Hash of the state of the chain as of this node bytes32 stateHash; // Hash of the data that can be challenged bytes32 challengeHash; // Hash of the data that will be committed if this node is confirmed bytes32 confirmData; // Index of the node previous to this one uint64 prevNum; // Deadline at which this node can be confirmed uint64 deadlineBlock; // Deadline at which a child of this node can be confirmed uint64 noChildConfirmedBeforeBlock; // Number of stakers staked on this node. This includes real stakers and zombies uint64 stakerCount; // Number of stakers staked on a child node. This includes real stakers and zombies uint64 childStakerCount; // This value starts at zero and is set to a value when the first child is created. After that it is constant until the node is destroyed or the owner destroys pending nodes uint64 firstChildBlock; // The number of the latest child of this node to be created uint64 latestChildNumber; // The block number when this node was created uint64 createdAtBlock; // A hash of all the data needed to determine this node's validity, to protect against reorgs bytes32 nodeHash; } /** * @notice Utility functions for Node */ library NodeLib { /** * @notice Initialize a Node * @param _stateHash Initial value of stateHash * @param _challengeHash Initial value of challengeHash * @param _confirmData Initial value of confirmData * @param _prevNum Initial value of prevNum * @param _deadlineBlock Initial value of deadlineBlock * @param _nodeHash Initial value of nodeHash */ function createNode( bytes32 _stateHash, bytes32 _challengeHash, bytes32 _confirmData, uint64 _prevNum, uint64 _deadlineBlock, bytes32 _nodeHash ) internal view returns (Node memory) { Node memory node; node.stateHash = _stateHash; node.challengeHash = _challengeHash; node.confirmData = _confirmData; node.prevNum = _prevNum; node.deadlineBlock = _deadlineBlock; node.noChildConfirmedBeforeBlock = _deadlineBlock; node.createdAtBlock = uint64(block.number); node.nodeHash = _nodeHash; return node; } /** * @notice Update child properties * @param number The child number to set */ function childCreated(Node storage self, uint64 number) internal { if (self.firstChildBlock == 0) { self.firstChildBlock = uint64(block.number); } self.latestChildNumber = number; } /** * @notice Update the child confirmed deadline * @param deadline The new deadline to set */ function newChildConfirmDeadline(Node storage self, uint64 deadline) internal { self.noChildConfirmedBeforeBlock = deadline; } /** * @notice Check whether the current block number has met or passed the node's deadline */ function requirePastDeadline(Node memory self) internal view { require(block.number >= self.deadlineBlock, "BEFORE_DEADLINE"); } /** * @notice Check whether the current block number has met or passed deadline for children of this node to be confirmed */ function requirePastChildConfirmDeadline(Node memory self) internal view { require(block.number >= self.noChildConfirmedBeforeBlock, "CHILD_TOO_RECENT"); } }
File 5 of 5: Bridge
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import { NotContract, NotRollupOrOwner, NotDelayedInbox, NotSequencerInbox, NotOutbox, InvalidOutboxSet, BadSequencerMessageNumber } from "../libraries/Error.sol"; import "./IBridge.sol"; import "./Messages.sol"; import "../libraries/DelegateCallAware.sol"; import {L1MessageType_batchPostingReport} from "../libraries/MessageTypes.sol"; /** * @title Staging ground for incoming and outgoing messages * @notice Holds the inbox accumulator for sequenced and delayed messages. * It is also the ETH escrow for value sent with these messages. * Since the escrow is held here, this contract also contains a list of allowed * outboxes that can make calls from here and withdraw this escrow. */ contract Bridge is Initializable, DelegateCallAware, IBridge { using AddressUpgradeable for address; struct InOutInfo { uint256 index; bool allowed; } mapping(address => InOutInfo) private allowedDelayedInboxesMap; mapping(address => InOutInfo) private allowedOutboxesMap; address[] public allowedDelayedInboxList; address[] public allowedOutboxList; address private _activeOutbox; /// @inheritdoc IBridge bytes32[] public delayedInboxAccs; /// @inheritdoc IBridge bytes32[] public sequencerInboxAccs; IOwnable public rollup; address public sequencerInbox; uint256 public override sequencerReportedSubMessageCount; address private constant EMPTY_ACTIVEOUTBOX = address(type(uint160).max); function initialize(IOwnable rollup_) external initializer onlyDelegated { _activeOutbox = EMPTY_ACTIVEOUTBOX; rollup = rollup_; } modifier onlyRollupOrOwner() { if (msg.sender != address(rollup)) { address rollupOwner = rollup.owner(); if (msg.sender != rollupOwner) { revert NotRollupOrOwner(msg.sender, address(rollup), rollupOwner); } } _; } /// @dev returns the address of current active Outbox, or zero if no outbox is active function activeOutbox() public view returns (address) { address outbox = _activeOutbox; // address zero is returned if no outbox is set, but the value used in storage // is non-zero to save users some gas (as storage refunds are usually maxed out) // EIP-1153 would help here. // we don't return `EMPTY_ACTIVEOUTBOX` to avoid a breaking change on the current api if (outbox == EMPTY_ACTIVEOUTBOX) return address(0); return outbox; } function allowedDelayedInboxes(address inbox) external view returns (bool) { return allowedDelayedInboxesMap[inbox].allowed; } function allowedOutboxes(address outbox) external view returns (bool) { return allowedOutboxesMap[outbox].allowed; } modifier onlySequencerInbox() { if (msg.sender != sequencerInbox) revert NotSequencerInbox(msg.sender); _; } function enqueueSequencerMessage( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 prevMessageCount, uint256 newMessageCount ) external onlySequencerInbox returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ) { if ( sequencerReportedSubMessageCount != prevMessageCount && prevMessageCount != 0 && sequencerReportedSubMessageCount != 0 ) { revert BadSequencerMessageNumber(sequencerReportedSubMessageCount, prevMessageCount); } sequencerReportedSubMessageCount = newMessageCount; seqMessageIndex = sequencerInboxAccs.length; if (sequencerInboxAccs.length > 0) { beforeAcc = sequencerInboxAccs[sequencerInboxAccs.length - 1]; } if (afterDelayedMessagesRead > 0) { delayedAcc = delayedInboxAccs[afterDelayedMessagesRead - 1]; } acc = keccak256(abi.encodePacked(beforeAcc, dataHash, delayedAcc)); sequencerInboxAccs.push(acc); } /// @inheritdoc IBridge function submitBatchSpendingReport(address sender, bytes32 messageDataHash) external onlySequencerInbox returns (uint256) { return addMessageToDelayedAccumulator( L1MessageType_batchPostingReport, sender, uint64(block.number), uint64(block.timestamp), // solhint-disable-line not-rely-on-time, block.basefee, messageDataHash ); } /// @inheritdoc IBridge function enqueueDelayedMessage( uint8 kind, address sender, bytes32 messageDataHash ) external payable returns (uint256) { if (!allowedDelayedInboxesMap[msg.sender].allowed) revert NotDelayedInbox(msg.sender); return addMessageToDelayedAccumulator( kind, sender, uint64(block.number), uint64(block.timestamp), // solhint-disable-line not-rely-on-time block.basefee, messageDataHash ); } function addMessageToDelayedAccumulator( uint8 kind, address sender, uint64 blockNumber, uint64 blockTimestamp, uint256 baseFeeL1, bytes32 messageDataHash ) internal returns (uint256) { uint256 count = delayedInboxAccs.length; bytes32 messageHash = Messages.messageHash( kind, sender, blockNumber, blockTimestamp, count, baseFeeL1, messageDataHash ); bytes32 prevAcc = 0; if (count > 0) { prevAcc = delayedInboxAccs[count - 1]; } delayedInboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash)); emit MessageDelivered( count, prevAcc, msg.sender, kind, sender, messageDataHash, baseFeeL1, blockTimestamp ); return count; } function executeCall( address to, uint256 value, bytes calldata data ) external returns (bool success, bytes memory returnData) { if (!allowedOutboxesMap[msg.sender].allowed) revert NotOutbox(msg.sender); if (data.length > 0 && !to.isContract()) revert NotContract(to); address prevOutbox = _activeOutbox; _activeOutbox = msg.sender; // We set and reset active outbox around external call so activeOutbox remains valid during call // We use a low level call here since we want to bubble up whether it succeeded or failed to the caller // rather than reverting on failure as well as allow contract and non-contract calls // solhint-disable-next-line avoid-low-level-calls (success, returnData) = to.call{value: value}(data); _activeOutbox = prevOutbox; emit BridgeCallTriggered(msg.sender, to, value, data); } function setSequencerInbox(address _sequencerInbox) external onlyRollupOrOwner { sequencerInbox = _sequencerInbox; emit SequencerInboxUpdated(_sequencerInbox); } function setDelayedInbox(address inbox, bool enabled) external onlyRollupOrOwner { InOutInfo storage info = allowedDelayedInboxesMap[inbox]; bool alreadyEnabled = info.allowed; emit InboxToggle(inbox, enabled); if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) { return; } if (enabled) { allowedDelayedInboxesMap[inbox] = InOutInfo(allowedDelayedInboxList.length, true); allowedDelayedInboxList.push(inbox); } else { allowedDelayedInboxList[info.index] = allowedDelayedInboxList[ allowedDelayedInboxList.length - 1 ]; allowedDelayedInboxesMap[allowedDelayedInboxList[info.index]].index = info.index; allowedDelayedInboxList.pop(); delete allowedDelayedInboxesMap[inbox]; } } function setOutbox(address outbox, bool enabled) external onlyRollupOrOwner { if (outbox == EMPTY_ACTIVEOUTBOX) revert InvalidOutboxSet(outbox); InOutInfo storage info = allowedOutboxesMap[outbox]; bool alreadyEnabled = info.allowed; emit OutboxToggle(outbox, enabled); if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) { return; } if (enabled) { allowedOutboxesMap[outbox] = InOutInfo(allowedOutboxList.length, true); allowedOutboxList.push(outbox); } else { allowedOutboxList[info.index] = allowedOutboxList[allowedOutboxList.length - 1]; allowedOutboxesMap[allowedOutboxList[info.index]].index = info.index; allowedOutboxList.pop(); delete allowedOutboxesMap[outbox]; } } function setSequencerReportedSubMessageCount(uint256 newMsgCount) external onlyRollupOrOwner { sequencerReportedSubMessageCount = newMsgCount; } function delayedMessageCount() external view override returns (uint256) { return delayedInboxAccs.length; } function sequencerMessageCount() external view returns (uint256) { return sequencerInboxAccs.length; } /// @dev For the classic -> nitro migration. TODO: remove post-migration. function acceptFundsFromOldBridge() external payable {} } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; /// @dev Init was already called error AlreadyInit(); /// Init was called with param set to zero that must be nonzero error HadZeroInit(); /// @dev Thrown when non owner tries to access an only-owner function /// @param sender The msg.sender who is not the owner /// @param owner The owner address error NotOwner(address sender, address owner); /// @dev Thrown when an address that is not the rollup tries to call an only-rollup function /// @param sender The sender who is not the rollup /// @param rollup The rollup address authorized to call this function error NotRollup(address sender, address rollup); /// @dev Thrown when the contract was not called directly from the origin ie msg.sender != tx.origin error NotOrigin(); /// @dev Provided data was too large /// @param dataLength The length of the data that is too large /// @param maxDataLength The max length the data can be error DataTooLarge(uint256 dataLength, uint256 maxDataLength); /// @dev The provided is not a contract and was expected to be /// @param addr The adddress in question error NotContract(address addr); /// @dev The merkle proof provided was too long /// @param actualLength The length of the merkle proof provided /// @param maxProofLength The max length a merkle proof can have error MerkleProofTooLong(uint256 actualLength, uint256 maxProofLength); /// @dev Thrown when an un-authorized address tries to access an admin function /// @param sender The un-authorized sender /// @param rollup The rollup, which would be authorized /// @param owner The rollup's owner, which would be authorized error NotRollupOrOwner(address sender, address rollup, address owner); // Bridge Errors /// @dev Thrown when an un-authorized address tries to access an only-inbox function /// @param sender The un-authorized sender error NotDelayedInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-sequencer-inbox function /// @param sender The un-authorized sender error NotSequencerInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-outbox function /// @param sender The un-authorized sender error NotOutbox(address sender); /// @dev the provided outbox address isn't valid /// @param outbox address of outbox being set error InvalidOutboxSet(address outbox); // Inbox Errors /// @dev The contract is paused, so cannot be paused error AlreadyPaused(); /// @dev The contract is unpaused, so cannot be unpaused error AlreadyUnpaused(); /// @dev The contract is paused error Paused(); /// @dev msg.value sent to the inbox isn't high enough error InsufficientValue(uint256 expected, uint256 actual); /// @dev submission cost provided isn't enough to create retryable ticket error InsufficientSubmissionCost(uint256 expected, uint256 actual); /// @dev address not allowed to interact with the given contract error NotAllowedOrigin(address origin); /// @dev used to convey retryable tx data in eth calls without requiring a tx trace /// this follows a pattern similar to EIP-3668 where reverts surface call information error RetryableData( address from, address to, uint256 l2CallValue, uint256 deposit, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes data ); // Outbox Errors /// @dev The provided proof was too long /// @param proofLength The length of the too-long proof error ProofTooLong(uint256 proofLength); /// @dev The output index was greater than the maximum /// @param index The output index /// @param maxIndex The max the index could be error PathNotMinimal(uint256 index, uint256 maxIndex); /// @dev The calculated root does not exist /// @param root The calculated root error UnknownRoot(bytes32 root); /// @dev The record has already been spent /// @param index The index of the spent record error AlreadySpent(uint256 index); /// @dev A call to the bridge failed with no return data error BridgeCallFailed(); // Sequencer Inbox Errors /// @dev Thrown when someone attempts to read fewer messages than have already been read error DelayedBackwards(); /// @dev Thrown when someone attempts to read more messages than exist error DelayedTooFar(); /// @dev Force include can only read messages more blocks old than the delay period error ForceIncludeBlockTooSoon(); /// @dev Force include can only read messages more seconds old than the delay period error ForceIncludeTimeTooSoon(); /// @dev The message provided did not match the hash in the delayed inbox error IncorrectMessagePreimage(); /// @dev This can only be called by the batch poster error NotBatchPoster(); /// @dev The sequence number provided to this message was inconsistent with the number of batches already included error BadSequencerNumber(uint256 stored, uint256 received); /// @dev The sequence message number provided to this message was inconsistent with the previous one error BadSequencerMessageNumber(uint256 stored, uint256 received); /// @dev The batch data has the inbox authenticated bit set, but the batch data was not authenticated by the inbox error DataNotAuthenticated(); /// @dev Tried to create an already valid Data Availability Service keyset error AlreadyValidDASKeyset(bytes32); /// @dev Tried to use or invalidate an already invalid Data Availability Service keyset error NoSuchKeyset(bytes32); // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IOwnable.sol"; interface IBridge { event MessageDelivered( uint256 indexed messageIndex, bytes32 indexed beforeInboxAcc, address inbox, uint8 kind, address sender, bytes32 messageDataHash, uint256 baseFeeL1, uint64 timestamp ); event BridgeCallTriggered( address indexed outbox, address indexed to, uint256 value, bytes data ); event InboxToggle(address indexed inbox, bool enabled); event OutboxToggle(address indexed outbox, bool enabled); event SequencerInboxUpdated(address newSequencerInbox); function allowedDelayedInboxList(uint256) external returns (address); function allowedOutboxList(uint256) external returns (address); /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function delayedInboxAccs(uint256) external view returns (bytes32); /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function sequencerInboxAccs(uint256) external view returns (bytes32); function rollup() external view returns (IOwnable); function sequencerInbox() external view returns (address); function activeOutbox() external view returns (address); function allowedDelayedInboxes(address inbox) external view returns (bool); function allowedOutboxes(address outbox) external view returns (bool); function sequencerReportedSubMessageCount() external view returns (uint256); /** * @dev Enqueue a message in the delayed inbox accumulator. * These messages are later sequenced in the SequencerInbox, either * by the sequencer as part of a normal batch, or by force inclusion. */ function enqueueDelayedMessage( uint8 kind, address sender, bytes32 messageDataHash ) external payable returns (uint256); function executeCall( address to, uint256 value, bytes calldata data ) external returns (bool success, bytes memory returnData); function delayedMessageCount() external view returns (uint256); function sequencerMessageCount() external view returns (uint256); // ---------- onlySequencerInbox functions ---------- function enqueueSequencerMessage( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 prevMessageCount, uint256 newMessageCount ) external returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ); /** * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type * This is done through a separate function entrypoint instead of allowing the sequencer inbox * to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either * every delayed inbox or every sequencer inbox call. */ function submitBatchSpendingReport(address batchPoster, bytes32 dataHash) external returns (uint256 msgNum); // ---------- onlyRollupOrOwner functions ---------- function setSequencerInbox(address _sequencerInbox) external; function setDelayedInbox(address inbox, bool enabled) external; function setOutbox(address inbox, bool enabled) external; // ---------- initializer ---------- function initialize(IOwnable rollup_) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library Messages { function messageHash( uint8 kind, address sender, uint64 blockNumber, uint64 timestamp, uint256 inboxSeqNum, uint256 baseFeeL1, bytes32 messageDataHash ) internal pure returns (bytes32) { return keccak256( abi.encodePacked( kind, sender, blockNumber, timestamp, inboxSeqNum, baseFeeL1, messageDataHash ) ); } function accumulateInboxMessage(bytes32 prevAcc, bytes32 message) internal pure returns (bytes32) { return keccak256(abi.encodePacked(prevAcc, message)); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {NotOwner} from "./Error.sol"; /// @dev A stateless contract that allows you to infer if the current call has been delegated or not /// Pattern used here is from UUPS implementation by the OpenZeppelin team abstract contract DelegateCallAware { address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegate call. This allows a function to be * callable on the proxy contract but not on the logic contract. */ modifier onlyDelegated() { require(address(this) != __self, "Function must be called through delegatecall"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "Function must not be called through delegatecall"); _; } /// @dev Check that msg.sender is the current EIP 1967 proxy admin modifier onlyProxyOwner() { // Storage slot with the admin of the proxy contract // This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1 bytes32 slot = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; address admin; assembly { admin := sload(slot) } if (msg.sender != admin) revert NotOwner(msg.sender, admin); _; } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; uint8 constant L2_MSG = 3; uint8 constant L1MessageType_L2FundedByL1 = 7; uint8 constant L1MessageType_submitRetryableTx = 9; uint8 constant L1MessageType_ethDeposit = 12; uint8 constant L1MessageType_batchPostingReport = 13; uint8 constant L2MessageType_unsignedEOATx = 0; uint8 constant L2MessageType_unsignedContractTx = 1; uint8 constant ROLLUP_PROTOCOL_EVENT_TYPE = 8; uint8 constant INITIALIZATION_MSG_TYPE = 11; // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.4.21 <0.9.0; interface IOwnable { function owner() external view returns (address); }