From c7635a4a5db5de593faaca54dcfd2bf77489e37f Mon Sep 17 00:00:00 2001 From: Candle - the privacy friendly smart home <39312291+createcandle@users.noreply.github.com> Date: Tue, 11 Feb 2020 22:06:10 +0100 Subject: [PATCH] 1.0.6 --- .../Candle_receiver.arduino.avr.nano.elf | Bin 0 -> 99932 bytes .../Candle_receiver.arduino.avr.nano.hex | 945 ++++++ code/Candle_receiver/Candle_receiver.ino | 105 + .../Carbon_sensor.arduino.avr.nano.elf | Bin 0 -> 158800 bytes .../Carbon_sensor.arduino.avr.nano.hex | 1419 +++++++++ code/Carbon_sensor/Carbon_sensor.ino | 812 +++++ .../Dust_sensor.arduino.avr.nano.elf | Bin 0 -> 159236 bytes .../Dust_sensor.arduino.avr.nano.hex | 1404 ++++++++ code/Dust_sensor/Dust_sensor.ino | 607 ++++ .../Signal-hub.arduino.avr.nano.elf | Bin 0 -> 163240 bytes .../Signal-hub.arduino.avr.nano.hex | 1547 +++++++++ code/Signal-hub/Signal-hub.ino | 2830 +++++++++++++++++ .../Temperature_and_more.arduino.avr.nano.elf | Bin 0 -> 173252 bytes .../Temperature_and_more.arduino.avr.nano.hex | 1610 ++++++++++ .../Temperature_and_more.ino | 1181 +++++++ 15 files changed, 12460 insertions(+) create mode 100644 code/Candle_receiver/Candle_receiver.arduino.avr.nano.elf create mode 100644 code/Candle_receiver/Candle_receiver.arduino.avr.nano.hex create mode 100644 code/Candle_receiver/Candle_receiver.ino create mode 100644 code/Carbon_sensor/Carbon_sensor.arduino.avr.nano.elf create mode 100644 code/Carbon_sensor/Carbon_sensor.arduino.avr.nano.hex create mode 100644 code/Carbon_sensor/Carbon_sensor.ino create mode 100644 code/Dust_sensor/Dust_sensor.arduino.avr.nano.elf create mode 100644 code/Dust_sensor/Dust_sensor.arduino.avr.nano.hex create mode 100644 code/Dust_sensor/Dust_sensor.ino create mode 100644 code/Signal-hub/Signal-hub.arduino.avr.nano.elf create mode 100644 code/Signal-hub/Signal-hub.arduino.avr.nano.hex create mode 100644 code/Signal-hub/Signal-hub.ino create mode 100644 code/Temperature_and_more/Temperature_and_more.arduino.avr.nano.elf create mode 100644 code/Temperature_and_more/Temperature_and_more.arduino.avr.nano.hex create mode 100644 code/Temperature_and_more/Temperature_and_more.ino diff --git a/code/Candle_receiver/Candle_receiver.arduino.avr.nano.elf b/code/Candle_receiver/Candle_receiver.arduino.avr.nano.elf new file mode 100644 index 0000000000000000000000000000000000000000..e1cd65deb58f3f8c7fba2285c49749749d6b1826 GIT binary patch literal 99932 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 literal 0 HcmV?d00001 diff --git a/code/Candle_receiver/Candle_receiver.arduino.avr.nano.hex b/code/Candle_receiver/Candle_receiver.arduino.avr.nano.hex new file mode 100644 index 0000000..b5f155a --- /dev/null +++ b/code/Candle_receiver/Candle_receiver.arduino.avr.nano.hex @@ -0,0 +1,945 @@ +:100000000C94E4010C9426100C94FF0F0C940C0239 +:100010000C940C020C940C020C944D100C940C02D9 +:100020000C940C020C940C020C940C020C940C0218 +:100030000C940C020C940C020C940C020C940C0208 +:100040000C94B50F0C940C020C94830F0C945D0F60 +:100050000C940C020C940C020C940C020C940C02E8 +:100060000C940C020C940C0200407A10F35A00A07D +:10007000724E18090010A5D4E80000E87648170071 +:1000800000E40B54020000CA9A3B000000E1F505B1 +:10009000000080969800000040420F000000A086FB +:1000A00001000000102700000000E803000000002D +:1000B0006400000000000A000000000001000000D1 +:1000C00000002C76D888DC674F0823DFC1DFAE59EB +:1000D000E1B1B796E5E3E453C63AE651997696E87E +:1000E000E6C28426EB898C9B62ED407C6FFCEFBC02 +:1000F0009C9F40F2BAA56FA5F490055A2AF75C932D +:100100006B6CF9676DC11BFCE0E40D47FEF520E662 +:10011000B500D0ED902E0300943577050080841E45 +:10012000080000204E0A000000C80C333333330FA0 +:10013000986E12831141EF8D2114893BE65516CF3D +:10014000FEE6DB18D1844B381BF77C1D901DA4BB49 +:10015000E424203284725E228100C9F124ECA1E5FE +:100160003D2725753B25753B25753B25753B25753D +:100170003B25730A00000000080002010000030490 +:10018000070000000000000000637C777BF26B6FCB +:10019000C53001672BFED7AB76CA82C97DFA5947B5 +:1001A000F0ADD4A2AF9CA472C0B7FD9326363FF742 +:1001B000CC34A5E5F171D8311504C723C3189605D1 +:1001C0009A071280E2EB27B27509832C1A1B6E5A2C +:1001D000A0523BD6B329E32F8453D100ED20FCB1CC +:1001E0005B6ACBBE394A4C58CFD0EFAAFB434D33A4 +:1001F0008545F9027F503C9FA851A3408F929D38BE +:10020000F5BCB6DA2110FFF3D2CD0C13EC5F9744A6 +:1002100017C4A77E3D645D197360814FDC222A906C +:100220008846EEB814DE5E0BDBE0323A0A4906245B +:100230005CC2D3AC629195E479E7C8376D8DD54E39 +:10024000A96C56F4EA657AAE08BA78252E1CA6B4D5 +:10025000C6E8DD741F4BBD8B8A703EB5664803F659 +:100260000E613557B986C11D9EE1F8981169D98E86 +:10027000949B1E87E9CE5528DF8CA1890DBFE642ED +:100280006841992D0FB054BB1652096AD53036A576 +:1002900038BF40A39E81F3D7FB7CE339829B2FFFBD +:1002A00087348E4344C4DEE9CB547B9432A6C22308 +:1002B0003DEE4C950B42FAC34E082EA16628D92478 +:1002C000B2765BA2496D8BD12572F8F66486689888 +:1002D00016D4A45CCC5D65B6926C704850FDEDB947 +:1002E000DA5E154657A78D9D8490D8AB008CBCD3A1 +:1002F0000AF7E45805B8B34506D02C1E8FCA3F0F45 +:1003000002C1AFBD0301138A6B3A9111414F67DC03 +:10031000EA97F2CFCEF0B4E67396AC7422E7AD352F +:1003200085E2F937E81C75DF6E47F11A711D29C5A2 +:10033000896FB7620EAA18BE1BFC563E4BC6D27917 +:10034000209ADBC0FE78CD5AF41FDDA8338807C79A +:1003500031B11210592780EC5F60517FA919B54A5D +:100360000D2DE57A9F93C99CEFA0E03B4DAE2AF599 +:10037000B0C8EBBB3C83539961172B047EBA77D688 +:1003800026E169146355210C7D000000002500283A +:10039000002B0000000000240027002A00040404B1 +:1003A000040404040402020202020203030303031E +:1003B00003010204081020408001020408102001FB +:1003C000020408102000B01311241FBECFEFD8E0A4 +:1003D000DEBFCDBF11E0A0E0B1E0E0EAFAE302C089 +:1003E00005900D92AA35B107D9F724E0AAE5B1E04E +:1003F00001C01D92A43DB207E1F711E0C4EED1E0C7 +:1004000004C02197FE010E94301DC33ED107C9F7E9 +:100410000E945D140C944E1D0C94000090E0FC01B1 +:10042000EF54FC4F249183569C4FFC018491882308 +:1004300099F090E0880F991FFC01ED56FC4FA591B3 +:10044000B491FC01E757FC4F859194918FB7F894D4 +:10045000EC91E22BEC938FBF0895DB01FC01242F7C +:100460003C91308311963C911197318312963C91C7 +:100470001297328313963C9113973383245014962A +:100480003496243068F72CEF240F2695269530E01B +:100490002F5F3F4F220F331F220F331F4370DB01AB +:1004A000A20FB31FFC01E20FF31F415018F08D9112 +:1004B0008193FBCF0895AF92BF92CF92DF92EF92DC +:1004C000FF920F931F93CF93DF936C017B018B01FE +:1004D000040F151FEB015E01AE18BF08C017D1074E +:1004E00059F06991D601ED91FC910190F081E02DD8 +:1004F000C6010995892B79F7C501DF91CF911F912D +:100500000F91FF90EF90DF90CF90BF90AF90089544 +:10051000FC01538D448D252F30E0842F90E0821B09 +:10052000930B541710F0CF96089501970895FC018E +:10053000918D828D981761F0A28DAE0FBF2FB11DE6 +:100540005D968C91928D9F5F9F73928F90E008953E +:100550008FEF9FEF0895FC01918D828D981731F0F8 +:10056000828DE80FF11D858D90E008958FEF9FEF4C +:100570000895FC01918D228D892F90E0805C9F4F22 +:10058000821B91098F739927089587EB92E00E944F +:10059000B90221E0892B09F420E0822F0895FC01A3 +:1005A000A48DA80FB92FB11DA35ABF4F2C91848DD4 +:1005B00090E001968F739927848FA689B7892C9331 +:1005C000A089B1898C91837080648C93938D848D84 +:1005D000981306C00288F389E02D80818F7D808387 +:1005E0000895EF92FF920F931F93CF93DF93EC0147 +:1005F00081E0888F9B8D8C8D98131AC0E889F989CA +:10060000808185FF15C09FB7F894EE89FF896083CC +:10061000E889F98980818370806480839FBF81E04D +:1006200090E0DF91CF911F910F91FF90EF9008958F +:10063000F62E0B8D10E00F5F1F4F0F731127E02E6A +:100640008C8D8E110CC00FB607FCFACFE889F989A2 +:10065000808185FFF5CFCE010E94CF02F1CFEB8DD7 +:10066000EC0FFD2FF11DE35AFF4FF0829FB7F89476 +:100670000B8FEA89FB8980818062CFCFCF93DF9394 +:10068000EC01888D8823B9F0AA89BB89E889F989AA +:100690008C9185FD03C0808186FD0DC00FB607FCDF +:1006A000F7CF8C9185FFF2CF808185FFEDCFCE0112 +:1006B0000E94CF02E9CFDF91CF91089580E090E0D2 +:1006C000892B29F00E94C50281110C940000089525 +:1006D0002FB7F8946091AF027091B0028091B1028F +:1006E0009091B2022FBF089508958091480281FD34 +:1006F00004C08160826080934802089588E19FE091 +:100700000FB6F894A895809360000FBE9093600098 +:1007100008950F931F930E94680300913202109175 +:1007200033022091340230913502601B710B820B31 +:10073000930B683E73408105910558F00E94680351 +:1007400060933202709333028093340290933502A7 +:10075000A8951F910F9108950895FC0183818770DA +:100760008860838384818F71806284836783CF01F3 +:100770000895E0913602F0913702309721F002801F +:10078000F381E02D099408959C01809136029091A7 +:10079000370282179307F1F0909140029F71909376 +:1007A00040023093370220933602E0913602F091F6 +:1007B0003702309721F00190F081E02D09950E94D9 +:1007C0006803609338027093390280933A029093E1 +:1007D0003B02089580914002805E80934002E5CF05 +:1007E0000F931F930E946803009138021091390201 +:1007F00020913A0230913B02601B710B820B930BEC +:10080000209141022077203779F000E117E220E0C3 +:1008100030E0061717072807390758F481E191E0FF +:100820001F910F910C94C40300E61AEE20E030E013 +:10083000F0CF1F910F9108958091400284608093C2 +:10084000400280914102807880934102E09145020C +:10085000F0914602309709F009940895CF93DF9301 +:10086000FC01EB01DA019C01205F3F4F88819C91E4 +:1008700089278083898111969C911197892781838B +:100880008A8112969C911297892782838B81139675 +:100890009C91139789278383349624961496E217A4 +:1008A000F30721F7DF91CF910895FC01DB019C0153 +:1008B000205F3F4F80819C918927808381811196A1 +:1008C0009C91119789278183828112969C9112971E +:1008D00089278283838113969C9113978927838329 +:1008E00034961496E217F30729F708958091790357 +:1008F000829586958770813019F480917C030895E4 +:10090000811105C08CE793E00E94EB16089580E00A +:100910000895E0E4F2E08081877F8F7E80831092EB +:100920003C0210923D0210923E0210923F020E9441 +:10093000680360932E0270932F028093300290938D +:1009400031021092060210920702109208021092D1 +:10095000090244E050E070E060E08AE292E00C942A +:10096000BF1C0F931F93CF93DF93EC01E0E0611561 +:10097000710551F0FB0101900020E9F73197E61B6A +:10098000F70BE931F10500F50E2F10E08B81877030 +:10099000980193E0220F331F9A95E1F7822B8B8306 +:1009A0008C818F718C83EE2329F0A801CE010796EC +:1009B0000E943F1DFE01E00FF11F1782CE01DF9163 +:1009C000CF911F910F910895E9E1DECF91E59CBD94 +:1009D00091E09DBD2998E3E2F0E03197F1F78EBDFB +:1009E00000000DB407FEFDCF8EB5FB019FEF415017 +:1009F000C8F0222361F09EBD00000DB407FEFDCFBC +:100A00008EB56115710599F380833196F0CFDF01C2 +:100A1000119680818EBD00000DB407FEFDCF8EB50E +:100A2000FD01E5CF299AE3E2F0E03197F1F708956F +:100A3000CF93DF931F92CDB7DEB7698320E041E00B +:100A4000BE016F5F7F4F0E94E6040F90DF91CF9150 +:100A5000089580914102982F9077903759F0982F00 +:100A600092959F709F5F97709295907F8F78892B5A +:100A700080934102809140028B7F8F7E8093400261 +:100A80002A986CE080E20C9418056FE080E20E94E6 +:100A90001805609108016F3F19F08AE20E9418055D +:100AA0002A9A089521E041E070E060E00C94E604A9 +:100AB00020E040E070E060E00C94E6042F923F926A +:100AC0004F925F926F927F928F929F92AF92BF925E +:100AD000CF92DF92EF92FF920F931F93CF93DF930A +:100AE000CDB7DEB7A2970FB6F894DEBF0FBECDBF6D +:100AF0007C01FC0102818091400280FFFAC080E00D +:100B00000F3F09F0D1C11FEF80912A02F7018083C6 +:100B1000038102FD01C1069506950695095FF091D6 +:100B20002D02F9A3F170FAA3402F013208F040E240 +:100B300050E0B7018AE092E00E94361D10929004C6 +:100B400010929104109292041092930410929404C3 +:100B500010929504109296041092970410929804A3 +:100B60001092990410929A0410929B0410929C0483 +:100B700010929D0410929E0410929F04109288047B +:100B80001092890410928A0410928B0410928C04A3 +:100B900010928D0410928E0410928F04B0E19B2E5F +:100BA000013110F000E2902EC92CC294FFE0CF2258 +:100BB000D12CAAE0AA2EA2E0BA2E7E0181E1E80E95 +:100BC000F11C0BE1B50180E994E00E94550480918D +:100BD000960390919703892B09F41EC148E953E0CD +:100BE00060E974E0C7010E942E0488248394482D94 +:100BF00050E08091960390919703481759070CF0A5 +:100C00008DC09701DE0111966FE0362E7AE0472EF7 +:100C1000E5E05E2EF701E50DF11D708084E0850DA5 +:100C20008F70582EF701E40DF11D808194E0940D32 +:100C30009F70492EF701E30DF11D908164E0630D73 +:100C40006F70362EF9016081E62FF0E0E757FE4F16 +:100C50007491E72DF0E0E757FE4F6491E82FF0E044 +:100C6000E757FE4F8491E92FF0E0E757FE4F94914C +:100C7000672E660C77FD6026E62FEE0F67FDE027F6 +:100C8000282E220C87FD2026792E770C97FD7026C2 +:100C9000F62FF827F927F625FE27FC93F72FF827DC +:100CA000F927FE27F2251196FC93119767279627BF +:100CB0002926272412962C921297862768267624B6 +:100CC00013967C9213972C5F3F4F1496EA16FB06FF +:100CD00009F0A0CF94E0440F551F9A95E1F74856CC +:100CE0005C4FBE016F5F7F4FC7010E942E0483944B +:100CF0007ECF10912B02002309F406CF0F3F09F499 +:100D000002CF802F90E003960E94CF1C182F8F3FB8 +:100D100009F0FACE102FF8CE00E201CFE989F0E019 +:100D2000E757FE4FE491E98BED89F0E0E757FE4F7E +:100D3000E491ED8BE98DF0E0E757FE4FE491E98F08 +:100D4000ED8DF0E0E757FE4FE491ED8F8A89EE8953 +:100D5000F0E0E757FE4FE491EA8BEA8DF0E0E757C9 +:100D6000FE4FE491EE8BEE8DF0E0E757FE4FE491FD +:100D7000EA8FE82FF0E0E757FE4FE491EE8F8B8982 +:100D8000EB8DF0E0E757FE4FE491EB8BE82FF0E0BE +:100D9000E757FE4FE491EB8F8F89EF8DF0E0E75737 +:100DA000FE4FE491EF8BE82FF0E0E757FE4FE49120 +:100DB000EF8F88A1EC8DF0E0E757FE4FE491E8A3B8 +:100DC000E88DF0E0E757FE4FE491EC8FEC89F0E01E +:100DD000E757FE4FE491E88FE82FF0E0E757FE4F2A +:100DE000E491EC8B84E0440F551F8A95E1F7485657 +:100DF0005C4FB70180E994E00E942E0440E160E975 +:100E000074E0C5010E942D02F0E1AF0EB11C81E03B +:100E1000C81AD10809F0D6CE2A9883E092E001974B +:100E2000F1F76EE080E20E9418058BE891E00197EF +:100E3000F1F7612F8AE20E941805612F80E30E947A +:100E4000180581EE0E9458051F3F19F0EAA180EABB +:100E5000E11180EB20E0492D6AE072E00E94E60497 +:100E60002A9AF12CE12C8FEF0E945805082F8073ED +:100E700021F4F1E0EF1AF108B1F72A9860E387E274 +:100E80000E94180504FF03C081EE0E9458050E94CD +:100E9000450505FF02C081E089A381E01F3F09F0FD +:100EA00080E099A19170892BA2960FB6F894DEBFCD +:100EB0000FBECDBFDF91CF911F910F91FF90EF90AB +:100EC000DF90CF90BF90AF909F908F907F906F906A +:100ED0005F904F903F902F9008952091400222FD07 +:100EE0000C945E0580E00895CF92DF92EF92FF921E +:100EF000C0900602D0900702E0900802F09009022C +:100F0000C114D104E104F10431F50E946803609337 +:100F100006027093070280930802909309021092D0 +:100F200055038FEF8093560380935A0384E1809397 +:100F3000590380915803807E83608093580367E54E +:100F400071E084E593E00E94B104FF90EF90DF90A0 +:100F5000CF900C945E050E9468036C197D098E0980 +:100F60009F0961387F448241910578F6FF90EF90A8 +:100F7000DF90CF9008958F929F92AF92BF92CF92C1 +:100F8000DF92EF92FF920F931F93CF93DF93CDB732 +:100F9000DEB764970FB6F894DEBF0FBECDBF8E01EB +:100FA0000F5F1F4F80E1F80111928A95E9F760E128 +:100FB00070E08BE291E00E943017AC016BE271E0CF +:100FC000C8010E94361D8AE090E0909397038093B9 +:100FD000960340E1B80188E993E00E942D0250E0B9 +:100FE00040E080E190E0FF24F39430E1E32EBE0185 +:100FF0006B5E7F4FEBE1BE2ED82EFC01EC56FC4F12 +:101000009E012F5E3F4FD901C190CD92A617B70721 +:10101000D9F7DE1020C0D988F0E1EF0EEA89F0E0C0 +:10102000E757FE4FE491EF25E98BEB89F0E0E757B6 +:10103000FE4FE491EA8BEC89F0E0E757FE4FE49134 +:10104000EB8BED2DF0E0E757FE4FE491EC8BF7FED4 +:1010500010C1FF0CFB24FC01E856FC4F4F01F901C5 +:10106000A1909F016401C81AD90AC40ED51EF601C9 +:10107000D080DA24F401D1924F012A173B0779F787 +:1010800004964C5F5F4F803B910509F0B5CF80E13E +:10109000F80111928A95E9F7229A219A2A98299AB9 +:1010A0001FB7F89480910502811146C087EA93E04A +:1010B000FC0124914BEB53E0FA013491E22FF0E074 +:1010C000EE0FFF1FED56FC4FA591B4912C913223EA +:1010D00021F5EFE7F1E02491FA014491FC019491AC +:1010E0009923D9F0222359F0233009F4CFC008F016 +:1010F000C2C0213009F4D0C0223009F4D1C0E92F98 +:10110000F0E0EE0FFF1FE757FC4FA591B4918FB7AA +:10111000F8949C91492B4C938FBF8AE00E940E0259 +:101120008CB580618CBD8CB580648CBD8DE00E94D7 +:101130000E028BE00E940E02809105028F5F809369 +:1011400005021FBF2A986EE080E20E9418058BE41A +:1011500096E40197F1F763E083E20E9418056FE5DA +:1011600084E20E9418056CE485E20E94180567E09D +:1011700086E20E94180564E08DE30E9418058DE167 +:101180000E945205843041F063E780E50E94180513 +:1011900064E08DE30E94180586E00E9452058730C6 +:1011A00009F08BC085E00E9452058C3409F085C09F +:1011B00062E082E20E94180560E081E20E94180568 +:1011C00063E08CE30E9418058FEF8093030120E019 +:1011D00045E063E071E08BE20E94E60420E045E038 +:1011E00063E071E08AE20E94E60420E045E063E00B +:1011F00071E080E30E94E60482EE0E94580581EED1 +:101200000E94580560E787E20E941805809140021D +:1012100080618093400280912D028E7F80932D0209 +:1012200010922B0210922C0210922A0210920801A6 +:1012300063E082E20E94180561E081E20E941805E5 +:101240000E94450589E091E00E94C40364960FB6B0 +:10125000F894DEBF0FBECDBFDF91CF911F910F91EC +:10126000FF90EF90DF90CF90BF90AF909F908F90C6 +:101270000895FF0CF0CE2730B1F02830D1F02430A3 +:1012800009F03DCF809180008F7D03C08091800068 +:101290008F778093800033CF84B58F7784BD2FCF35 +:1012A00084B58F7DFBCF8091B0008F778093B000A5 +:1012B00026CF8091B0008F7DF9CF8DE091E0C4CF33 +:1012C0000F931F93CF93DF93EC018C8182958695CA +:1012D0008770A9F44B8146954695469550E0BE012E +:1012E000695F7F4F82ED91E00E943F1DEB81E695A3 +:1012F000E695E695F0E0EE52FE4F10820AC081308E +:1013000009F044C08F814AE062ED71E090E00E94F4 +:1013100062178C8122ED31E03F932F939D811F92C4 +:101320009F9384FB992790F91F929F9387701F9238 +:101330008F938E811F928F9389811F928F9382E664 +:1013400091E09F938F931F9288E78F93CAE5D1E036 +:10135000DF93CF930E94D51709900020E9F7AE01E3 +:101360004B5551406AE571E087EB92E00E945B02C9 +:10137000EDB7FEB772960FB6F894FEBF0FBEEDBF85 +:1013800081E0DF91CF911F910F910895823031F468 +:101390004AE062ED71E08F819885B9CF833041F4E6 +:1013A0004AE062ED71E08F8198850E94BB17B1CF52 +:1013B000843051F46F81788589859A852AE042EDE1 +:1013C00051E00E946D17A5CF853051F46F8178856B +:1013D00089859A852AE042ED51E00E94991799CFBC +:1013E000873051F1A2EDB1E09E01295F3F4F40E00F +:1013F000EB81E695E695E6954E1780F5B901F90182 +:101400008081082E000C990B54E0959587955A958C +:10141000E1F78F708A30F0F4805D8C932F5F3F4F3F +:10142000FB0180818F708A30B8F4805D11968C93B7 +:1014300011974F5F1296DCCF2B85293008F028E0FA +:101440006F81788589859A8502ED11E042E00E94DE +:10145000CD165FCF895CE1CF895CE8CFF0E0EE0F7D +:10146000FF1F49CFFC012281211102C00C946009A9 +:101470000C946D07E4E5F3E0118212828FEF86830E +:1014800082E185838481807E848365E371E0CF017E +:101490000E94B1040C94320A0F931F93CF93DF93F1 +:1014A00090917A03C0917603C111B5C09D3059F473 +:1014B00088E198E00FB6F894A895809360000FBE7D +:1014C00090936000FFCF9B31A1F09630C1F49091D2 +:1014D0007C0381E0992319F09D3409F080E080932A +:1014E000470241E050E063E071E087E492E00E944F +:1014F000D71C81E0DF91CF911F910F910895933117 +:1015000019F40E943A0AF5CF923171F50E946803EE +:10151000009138021091390220913A0230913B0239 +:10152000AB01BC01401B510B620B730B10925503B6 +:10153000109256038FEF80935A0386E180935903EC +:1015400083EA809358038091570387708062809369 +:10155000570340935B0350935C0360935D03709368 +:101560005E0384E593E04EC0923019F2913011F59C +:1015700080E090E0892B09F4BCCF809179038295BB +:1015800086958770853059F460917C0370917D0356 +:1015900080917E0390917F030E940000AACF811169 +:1015A00005C08CE793E00E940917F6CF60E070E079 +:1015B000CB01F2CF9A3049F580917C03833409F056 +:1015C00098CFC3E0D0E06FEFCE010E94E71C2196D8 +:1015D000C33081E0D807B9F7109255031092560333 +:1015E0008FEF80935A038AE08093590380915803C8 +:1015F000807E8360809358036BE371E084E593E021 +:101600000E94B1040E94320A74CF81E09C3109F437 +:1016100071CF80E06FCF9A31E1F70E94760410928B +:101620005503C09356039FEF90935A039BE1909309 +:10163000590390915703977098609093570393E2E2 +:101640009093580391E0823008F490E090935B030C +:1016500088CF2F923F924F925F926F927F928F929C +:101660009F92AF92BF92CF92DF92EF92FF920F9331 +:101670001F93CF93DF93CDB7DEB7E9970FB6F894FA +:10168000DEBF0FBECDBF8091400284FFFDC30E942C +:10169000680300912E0210912F02209130023091A8 +:1016A0003102601B710B820B930B613A7B4B8D40B7 +:1016B0009105A0F00E94680360932E0270932F02A0 +:1016C000809330029093310286E00E945205873069 +:1016D00009F4C3C18DE091E00E94C40336E03BAB46 +:1016E0001BE187E10E94520580FDCEC34BA941500A +:1016F0004BAB442309F4C8C321E041E070E060E053 +:1017000080E60E94E604082F813220F082EE0E94DB +:10171000580500E021E0402F65E773E081E60E9474 +:10172000E60460E487E20E9418051092900410928B +:1017300091041092920410929304109294041092C7 +:1017400095041092960410929704109298041092A7 +:10175000990410929A0410929B0410929C04109287 +:101760009D0410929E0410929F041092880410927F +:10177000890410928A0410928B0410928C041092A7 +:101780008D0410928E0410928F04013108F46CC104 +:1017900082E090E09AAB89AB25E7222E23E0322E3F +:1017A00029A93AA9215031093AAB29AB2F3F3F4F24 +:1017B00009F478C140E1B101CE0181960E942D0269 +:1017C00040919603509197034115510509F46AC160 +:1017D00094E0440F551F9A95E1F748565C4FB101CC +:1017E000CE0141960E942E04E989F0E0E757FD4FB3 +:1017F000E491E98BED89F0E0E757FD4FE491ED8B43 +:10180000E98DF0E0E757FD4FE491E98FED8DF0E0D1 +:10181000E757FD4FE491ED8F8E8DEA8DF0E0E757AD +:10182000FD4FE491EE8FEE89F0E0E757FD4FE49134 +:10183000EA8FEA89F0E0E757FD4FE491EE8BE82F5D +:10184000F0E0E757FD4FE491EA8B8B89EB8DF0E0F8 +:10185000E757FD4FE491EB8BE82FF0E0E757FD4FA2 +:10186000E491EB8F8F89EF8DF0E0E757FD4FE49126 +:10187000EF8BE82FF0E0E757FD4FE491EF8F8C8975 +:10188000E88DF0E0E757FD4FE491EC8BEC8DF0E054 +:10189000E757FD4FE491E88FE8A1F0E0E757FD4FEF +:1018A000E491EC8FE82FF0E0E757FD4FE491E8A3D7 +:1018B000009196031FAA1EAA8FEF800FE82FF0E079 +:1018C000F9AFE8AF015009F4D4C048AD59AD2EA925 +:1018D0003FA9421B530B84E0440F551F8A95E1F743 +:1018E00048565C4FBE016F5E7F4FCE0101960E944D +:1018F0002E04CE0101967C019E012F5E3F4F3DAB31 +:101900002CABA5E0B0E0F701908181813281238189 +:10191000792F770F97FD7127B82EBB0C87FDB12665 +:10192000C32ECC0C37FDC126622F660F27FD612721 +:10193000472F440F77FD41274B2C440CB7FE04C0C2 +:101940005B2D550F452E41269C2C990CC7FC9126EA +:10195000A62EAA0C67FDA126D42EDD0C47FF04C0DD +:10196000542F550FD52ED126542D550F47FC5127F6 +:10197000F92DFF0F97FCF127EA2DEE0FA7FCE127C9 +:10198000792E7D24582E5526832E8F26622E6E2684 +:101990004D2554259F26AE26E32FE727EB25E42788 +:1019A000E525E925E625F0E0E757FD4F3491ECA960 +:1019B000FDA93083E22FEB25EC25E725E527E82577 +:1019C000EA25F0E0E757FD4FD490FD01EF70FF27C7 +:1019D00021E130E02C0F3D1FE20FF31FD0829C2548 +:1019E00096274927542695246924E62DF0E0E757E9 +:1019F000FD4F6490FD013596EF70FF2721E130E047 +:101A00002C0F3D1FE20FF31F6082E82FE727E62728 +:101A1000E7255E27E52FE825AE26EA2DF0E0E7571B +:101A2000FD4FA490FD013A96EF70FF27E20FF31FE0 +:101A3000A08294E0E90EF11C2CA93DA92C5F3F4F38 +:101A40003DAB2CAB1496A531B10509F05CCF8EA946 +:101A50009FA901969FAB8EAB35CF85E00E945205C2 +:101A60008C3409F037CE3ACEE1E0F0E0FAABE9ABE6 +:101A700093CE48E953E0BE016F5E7F4FC1010E94E3 +:101A80002E0460E974E0C1010E94550440E1BE01EA +:101A90006F5D7F4F80E994E00E942D0290E1290E56 +:101AA000311C7ECEF09078038F2D8370823009F048 +:101AB00018CEC090790300917A03E0907603A0904D +:101AC0007503B090770380912A02E81631F08E2DCD +:101AD00090E06A2D03960E94E71CEC2DE770CE2E55 +:101AE0008091410280688093410290912A02B9124C +:101AF000C9C080917803282F2695269526952A31EE +:101B000008F029E1F8E02F9F900111248770822BC3 +:101B100080937803EF2DE695E695E695EA3108F097 +:101B2000E9E1F0E0EB58FC4F17828091790383FFE5 +:101B300015C021E2E5E7F3E0A4E5B3E001900D92E2 +:101B40002A95E1F7877F806180935803909355032E +:101B5000E092560384E593E00E946D07809179033B +:101B600084FD82C023E0C2127FC090917A039F302F +:101B7000E9F018F0923108F4B4CD083109F03FC013 +:101B800010925503E09256038FEF80935A0389E138 +:101B90008093590380915803807E8360809358031B +:101BA00061E084E593E00E94AD0357C09091760315 +:101BB00010927603909377039FEF90937B03807E40 +:101BC00083608093790367E571E085E793E00E9485 +:101BD000B10480917803877080618093780380914D +:101BE00079038F71806C8093790381E080937C030B +:101BF00010927D0385E793E00E94320A72CD09318D +:101C000061F48091400283FF6CCD877F8093400216 +:101C10000E9476048093420264CD0E3109F461CDB6 +:101C20000D31F1F410925503109256038FEF80930B +:101C30005A038FE18093590383E480935803809182 +:101C40005703877080618093570380E09FEF9093E4 +:101C50005C0380935B0384E593E00E945E0541CDC5 +:101C60000E944C0A81113DCD85E793E00E946009F6 +:101C700080E090E0892B09F434CD85E793E00E9461 +:101C800000002FCD3FEFB312E7C043E0E413D2C012 +:101C90008091400282FFCBC0073009F0C8C080911C +:101CA0002B02E81609F41DCD0E94680340903C0207 +:101CB00050903D0260903E0270903F026419750999 +:101CC00086099709603177428105910530F180914D +:101CD000400283FB002700F983FD03CD90912A0287 +:101CE00091114AC01092420280914002877F8093F6 +:101CF0004002009142020F3F09F4F3CC0E946803B6 +:101D000060933C0270933D0280933E0290933F02A9 +:101D100080912C02801300932C020E946803609330 +:101D20003C0270933D0280933E0290933F020E94DA +:101D300068034B015C0123E09222AA24BB240E9489 +:101D400076132B013C0181149104A104B10409F024 +:101D500062C010925503E09256038FEF80935A03AE +:101D600088E08093590380915803807E836080933C +:101D7000580360912C0215CF886080934002B09286 +:101D800042021092550310925603B0925A0388E112 +:101D90008093590380915803807E83608093580319 +:101DA00061E084E593E00E94AD030E945E050E941D +:101DB00068034B015C0110927A030E946803681962 +:101DC00079098A099B09603D77408105910508F0F2 +:101DD0008BCF011189CF0E94290BA895809179039F +:101DE0008770833051F701E080917A03893129F3BC +:101DF00000E0E3CF31E0831A9108A108B10848EE72 +:101E0000440E43E0541E611C711C81149104A10412 +:101E1000B10409F498CF0E947613641975098609F4 +:101E20009709683E73408105910520F78CCF0830F3 +:101E300009F457CC80912B02A8120AC0E91641F090 +:101E40008091400282FF04C085E793E00E945E0516 +:101E5000F3E0CF1209CF45CC8091400282FF41CC04 +:101E600023E0E2130EC088EE800F823050F40E940F +:101E700076048E3F31F061E0680F85E793E00E94C1 +:101E8000AD0385E793E0E9CEE9960FB6F894DEBF9F +:101E90000FBECDBFDF91CF911F910F91FF90EF90BB +:101EA000DF90CF90BF90AF909F908F907F906F907A +:101EB0005F904F903F902F9008951F920F920FB612 +:101EC0000F9211242F933F934F935F936F937F93C0 +:101ED0008F939F93AF93BF93EF93FF9387EB92E022 +:101EE0000E94CF02FF91EF91BF91AF919F918F918F +:101EF0007F916F915F914F913F912F910F900FBE06 +:101F00000F901F9018951F920F920FB60F921124E9 +:101F10002F938F939F93EF93FF93E091C702F091DC +:101F2000C8028081E091CD02F091CE0282FD1BC0FB +:101F300090818091D0028F5F8F732091D1028217A0 +:101F400041F0E091D002F0E0E954FD4F958F80938D +:101F5000D002FF91EF919F918F912F910F900FBE23 +:101F60000F901F9018958081F4CF1F920F920FB69B +:101F70000F9211242F933F938F939F93AF93BF930F +:101F80008091AF029091B002A091B102B091B202E3 +:101F90003091AE0223E0230F2D3758F50196A11D95 +:101FA000B11D2093AE028093AF029093B002A09334 +:101FB000B102B093B2028091B3029091B402A091A9 +:101FC000B502B091B6020196A11DB11D8093B30276 +:101FD0009093B402A093B502B093B602BF91AF91B3 +:101FE0009F918F913F912F910F900FBE0F901F9057 +:101FF000189526E8230F0296A11DB11DD2CF1F927E +:102000000F920FB60F9211242F933F934F935F932C +:102010006F937F938F939F93AF93BF93EF93FF93B0 +:10202000E0911701F09118010995FF91EF91BF918F +:10203000AF919F918F917F916F915F914F913F9160 +:102040002F910F900FBE0F901F9018951F920F9217 +:102050000FB60F9211242F933F934F935F936F937B +:102060007F938F939F93AF93BF93EF93FF93E091F1 +:102070001501F09116010995FF91EF91BF91AF9174 +:102080009F918F917F916F915F914F913F912F9190 +:102090000F900FBE0F901F9018951F920F920FB6C2 +:1020A0000F9211240F900FBE0F901F901895DB0117 +:1020B000FC0158E0149744E018960E9001924A955E +:1020C000E1F75A95C1F708958F929F92AF92BF9210 +:1020D000CF92DF920F931F93EDB7FEB7B8970FB66D +:1020E000F894EDBF0FBEFEBF9F938F9331968F0183 +:1020F00049015A016B01C801AAD2BB2011F4AA20E0 +:1021000059F0C801B601A1D030E4C30ED11C32E0B1 +:10211000931AA108B108F1CFC801B601A40115D0E6 +:102120008F919F91B801C3DFEDB7FEB7B8960FB698 +:10213000F894EDBF0FBEFEBF1F910F91DF90CF90BF +:10214000BF90AF909F908F900895523090F09F93E2 +:102150008F937F936F935F934F9377D04F915F915E +:102160006F917F918F919F91525030E4630F711D59 +:10217000ECCFEDB7FEB70FB6E054F040F894EDBFEA +:102180000FBEFEBF3196242F26952695269550FB2F +:1021900025F9DB01222329F0122E0D9001921A94C9 +:1021A000E1F730E8032E37E0342329F006943A951E +:1021B000E9F73C91032A01922395293308F421C0C1 +:1021C00030E4321B19F011923A95E9F7FF973197F5 +:1021D000BF01FF93EF939F938F935F934F9335D0FE +:1021E0004F915F918F919F91EF91FF91DC019196BB +:1021F0003C9132503D9326E03C9130403D932A95EE +:10220000D9F738E3321B21F0112411923A95E9F7FE +:10221000DC01909638960D90040E02920D90051EEA +:10222000029236E00D90011C02923A95D9F7F89788 +:10223000BF010BD0EDB7FEB70FB6FF963196F894FD +:10224000EDBF0FBEFEBF112408954F925F926F92B3 +:102250007F928F929F92AF92BF92CF92DF92EF9236 +:10226000FF920F931F93CF93DF934DB75EB79A0101 +:10227000FB0140525140DA010FB6F8944DBF0FBE3A +:102280005EBF2F933F938F939F93119640E171917F +:102290006191319121912D933D936D937D934A9559 +:1022A000B1F740E3142EFD01FF9731970191119191 +:1022B00021913191C190D190E190F1906D2D7E2DC1 +:1022C0008F2D9C2D41E0E9D14B015C01B701C60186 +:1022D00042E0F9D186269726A826B92673E0F6941F +:1022E000E794D794C7947A95D1F78C249D24AE2493 +:1022F000BF24080D191D2A1D3B1D648D758D868D0B +:10230000978D060F171F281F391FC0A8D1A8E2A854 +:10231000F3A8B701C60141E0D6D15C014B0142E010 +:10232000D2D186269726A826B92672E0F694E7949D +:10233000D7947A95D9F78D249E24AF24080D191DC2 +:102340002A1D3B1D0D931D932D933D931A9409F067 +:10235000AACFFF91EF91EF93FF9390E211901D921E +:102360009A95E1F79097ED01EEE4F5E2BA9590E4E5 +:10237000192E4C885D886E887F88688979898A895A +:102380009B89C88CD98CEA8CFB8C46225722682208 +:1023900079226095709580959095C622D722E82283 +:1023A000F9224C245D246E247F24F888C988DA88B9 +:1023B000EB88B601C70142E070D14B015C01B60168 +:1023C000C70143E080D186269726A826B926B70103 +:1023D000C60141E078D186269726A826B926480C62 +:1023E000591C6A1C7B1C8C8C9D8CAE8CBF8C480C41 +:1023F000591C6A1C7B1C8D909D90AD90BD90480C23 +:10240000591C6A1C7B1C85909590A590B590480C32 +:10241000591C6A1C7B1C688179818A819B818C8014 +:102420009D80AE80BF8086229722A822B922C884D0 +:10243000D984EA84FB846C217D218E219F2186260C +:102440009726A826B9266C817D818E819F816C217B +:102450007D218E219F2186269726A826B926C88011 +:10246000D980EA80FB80B601C70142E02CD18B0104 +:102470009C01B701C60143E010D106271727282782 +:1024800039276F2D7C2D8D2D9E2D42E006D10627FC +:10249000172728273927080D191D2A1D3B1D5CE128 +:1024A0006C969A919C835A95E1F7C888D988EA88F6 +:1024B000FB88C40CD51CE61CF71CC88AD98AEA8A9A +:1024C000FB8A040D151D261D371D088319832A83D9 +:1024D0003B831A9409F04DCFFF91EF9158E00081B2 +:1024E0001181228133816991799189919991060FA6 +:1024F000171F281F391F01931193219331935A9568 +:1025000071F7319652E066E04081450F41935527BF +:1025100028F44081451F41936A95D1F75F914F910F +:102520000FB6F8944DBF0FBE5EBF1124DF91CF915F +:102530001F910F91FF90EF90DF90CF90BF90AF90E1 +:102540009F908F907F906F905F904F900895982FFD +:102550008A4291443771CFFBC0B5A5DBB5E95BC2B8 +:102560005639F111F159A4823F92D55E1CAB98AA5D +:1025700007D8015B8312BE853124C37D0C55745D81 +:10258000BE72FEB1DE80A706DC9B74F19BC1C169FF +:102590009BE48647BEEFC69DC10FCCA10C246F2CD7 +:1025A000E92DAA84744ADCA9B05CDA88F976525124 +:1025B0003E986DC631A8C82703B0C77F59BFF30B3B +:1025C000E0C64791A7D55163CA0667292914850A31 +:1025D000B72738211B2EFC6D2C4D130D3853547327 +:1025E0000A65BB0A6A762EC9C281852C7292A1E85F +:1025F000BFA24B661AA8708B4BC2A3516CC719E8D7 +:1026000092D1240699D685350EF470A06A1016C1B1 +:10261000A419086C371E4C774827B5BCB034B30CEE +:102620001C394AAAD84E4FCA9C5BF36F2E68EE82C3 +:102630008F746F63A5781478C8840802C78CFAFF7A +:10264000BE90EB6C50A4F7A3F9BEF27871C6DC0122 +:10265000E0E6F6E268E275917D936A95E1F7089508 +:1026600067E6096A85AE67BB72F36E3C3AF54FA523 +:102670007F520E518C68059BABD9831F19CDE05B4F +:102680000000000000000000483038F0592F982F5B +:10269000872F762F652F4850F7CF552788944423EE +:1026A00039F0661F771F881F991F551F4A95C9F774 +:1026B000652B0895483038F0562F672F782F892FD3 +:1026C000952F4850F7CF55278894442339F0979594 +:1026D00087957795679557954A95C9F7952B0895EE +:1026E000AB01692F782F852F942F08953FB7F89469 +:1026F0008091B3029091B402A091B502B091B6025C +:1027000026B5A89B05C02F3F19F00196A11DB11D4C +:102710003FBFBA2FA92F982F8827BC01CD01620F88 +:10272000711D811D911D42E0660F771F881F991F43 +:102730004A95D1F70895CF93DF93FC01108211825F +:102740001282148215821682DC0117968AE1ED014D +:1027500019928A95E9F782E08383DF91CF910895FA +:10276000CF93DF93CDB7DEB728970FB6F894DEBFCF +:102770000FBECDBFE7EBF2E01382128288EE93E04A +:10278000A0E0B0E084839583A683B7838DE191E0D8 +:102790009183808385EC90E09587848784EC90E03A +:1027A0009787868780EC90E0918B808B81EC90E01E +:1027B000938B828B82EC90E0958B848B86EC90E0FF +:1027C000978B868B118E128E138E148E83EB94E072 +:1027D0000E949B1398E09E012F5F3F4FD901E92F84 +:1027E0001D92EA95E9F7E8E8F4E081E08083118240 +:1027F0001282138214821582168217821092970316 +:10280000109296031092A1041092A0041092A304B7 +:102810001092A204E8E9F3E040EFDF011D924A952F +:10282000E9F7888748E0F901A0E9B4E001900D924A +:102830004A95E1F748E0F901A8E9B4E001900D926A +:102840004A95E1F78093A40482E08093A50483E095 +:102850008093A60484E08093A70485E08093A80475 +:1028600086E08093A90487E08093AA049093AB0448 +:1028700089E08093AC048AE08093AD048BE0809380 +:10288000AE048CE08093AF048DE08093B0048EE0C2 +:102890008093B1048FE08093B20485E793E00E94B7 +:1028A0009B1384E593E028960FB6F894DEBF0FBE25 +:1028B000CDBFDF91CF910C949B13CF93DF93CDB716 +:1028C000DEB7CA55D1090FB6F894DEBF0FBECDBF33 +:1028D000789484B5826084BD84B5816084BD85B5FB +:1028E000826085BD85B5816085BD80916E00816007 +:1028F00080936E00109281008091810082608093AD +:1029000081008091810081608093810080918000AE +:102910008160809380008091B10084608093B100D9 +:102920008091B00081608093B00080917A008460D3 +:1029300080937A0080917A00826080937A008091FF +:102940007A00816080937A0080917A008068809319 +:102950007A001092C100A89580E090E0892B11F0D8 +:102960000E940000E091C702F091C80282E08083DB +:10297000E091C302F091C4021082E091C502F0918F +:10298000C60280E180831092CF02E091CB02F091E9 +:10299000CC0286E08083E091C902F091CA02808176 +:1029A00080618083E091C902F091CA0280818860D1 +:1029B0008083E091C902F091CA028081806880839F +:1029C000E091C902F091CA0280818F7D808380915D +:1029D00048028D7F8093480280E090E0892B11F0BF +:1029E0000E94000040E250E063E671E0CE010196F3 +:1029F0000E94BF1C40E150E06CE871E0CE0181967E +:102A00000E94BF1C49E050E063E871E0CE01C1962E +:102A10000E94BF1C41E050E06AE171E0CE01865A9D +:102A20009F4F0E94BF1C28EC31E040E050E0BE0107 +:102A30006F5F7F4FCE01CA960E94641041E050E064 +:102A400063E071E087E492E00E94BF1C6FEF81E0D9 +:102A500090E00E94E71C809141028F7880934102B0 +:102A6000109237021092360281E191E00E94C40375 +:102A700085E793E090934602809345020E946803A5 +:102A80000E9468030E94B9030E94290B80914002B2 +:102A900082FB882780F9A895882391F3109255032B +:102AA000109256038FEF80935A038EE08093590360 +:102AB00080915803807E8360809358036EE371E0B9 +:102AC00084E593E00E94B1040E9460090E943A0AE2 +:102AD0000E947E03A89570E0E72E70E0F72EE0E0FC +:102AE000CE2EE0E0DE2E77247A94A89587EB92E054 +:102AF0000E94B902892B09F4ADC087EB92E00E94D5 +:102B000097029091AD02933608F033C1E92FF0E0BF +:102B1000E75BFD4F8A3009F027C11082AE01465CA9 +:102B20005F4F68E571E089E492E00E943B17A12CB9 +:102B300010E000E0B12C812C912C009709F485C0A5 +:102B40000630110509F498C00330110509F44AC094 +:102B5000B4F401301105A9F102301105B9F10E9458 +:102B6000EB168093B5040F5F1F4FAE01465C5F4FBD +:102B700068E571E090E080E00E943B17DECF043012 +:102B8000110509F43FC00530110549F724E0FC01A7 +:102B9000A21249C08081882331F38A33C4F580535F +:102BA0008295807F91819A33C4F59053A1E0B0E083 +:102BB000AC0FBD1FAB0DB11D890F8C93B394329632 +:102BC000E9CF0E94EB168093B904CDCF0E94EB169B +:102BD000A82E8091B704887F9A2D9770892B8093B7 +:102BE000B704C1CF2091B704622EE89463F80E9425 +:102BF000EB16892B29F088E0682A6092B704B3CFDE +:102C000080E0FACF0E94EB168093B804ACCF8136F7 +:102C100014F08755C5CF8753C3CF913614F097551D +:102C2000C5CF9753C3CF01900020E9F7E81BE250CE +:102C3000E80FF92FF11D20812D3009F41082208139 +:102C40002A3009F410824C018ECF05301105A4F40E +:102C50001092AD020E94B9030E94290B0E948903C1 +:102C6000C114D10409F441CF0E94C502882309F49C +:102C70003CCF0E94000039CF1092B4041092B304EC +:102C80008091B7048F7E8093B70494E0A91266C048 +:102C90004B2D4A3108F049E19091B604977050E00D +:102CA0009A0163E0220F331F6A95E1F7922B90930C +:102CB000B6048F71806C8093B704BE016F5F7F4F45 +:102CC0008AEB94E00E94361D1092AD0281E2E3EBA4 +:102CD000F4E0A5E7B3E001900D928A95E1F78091C9 +:102CE0007703811155C08091790383FF17C091E26A +:102CF000E5E7F3E0A4E5B3E001900D929A95E1F7E2 +:102D0000877F8061809358031092550380917603EA +:102D10008093560384E593E00E94600980917903D3 +:102D20008770833061F580917A03823029F51092A3 +:102D300055031092560370925A0380935903809161 +:102D40005803807E83608093580365E371E084E5D7 +:102D500093E00E94B1040E9460097CCFB40183EB30 +:102D600094E00E94B104B0CF80839F5F9093AD0246 +:102D7000BDCE1092AD02BACE0E944C0A6BCFE114C8 +:102D8000F10409F467CF85E793E00E94000062CF69 +:102D900085E793E00E946D075DCFEF920F931F933D +:102DA000CF93DF93E80134E047FD34E1042E000CBB +:102DB000550B57FF03C0519541955109E32E022F42 +:102DC000242FAE010E94DF19CE01DF91CF911F9118 +:102DD0000F91EF900895FC0188279927E89421919D +:102DE0002032E9F3293010F02E30C8F32B3241F0B5 +:102DF0002D3239F4689404C00E949117820F911DFE +:102E0000219120532A30C0F31EF4909581959F4F55 +:102E100008951F93FC0199278827BC01E89411911C +:102E20001032E9F3193010F01E30C8F31B3251F0A4 +:102E30001D3249F4689406C00E947C17610F711D11 +:102E4000811D911D119110531A30B0F33EF49095ED +:102E50008095709561957F4F8F4F9F4F1F9108957B +:102E6000FC016150704001900110D8F78095909559 +:102E70008E0F9F1F0895FA01A191B081009719F458 +:102E80001097E1F0CD01DC01CD010D90002011F48F +:102E9000C00113C0FB012191222319F02015D9F79D +:102EA000F3CFFB012191201519F41E92119606C053 +:102EB0002223C1F70D900020A1F7D001FA01A193C0 +:102EC000B0830895BB274A3031F4992322F4BDE240 +:102ED000909581959F4F0C94BC17BB272A3051F4D5 +:102EE000992342F4BDE290958095709561957F4F4E +:102EF0008F4F9F4F0C949A17592F482F372F262FFB +:102F0000660F771F881F991F660F771F881F991FED +:102F1000620F731F841F951F660F771F881F991FED +:102F200008957AE0979F902D879F802D910D112411 +:102F30000895BB27FA01A62F621771058105910537 +:102F4000330B30FB66F0AA27660F771F881F991F87 +:102F5000AA1FA21710F0A21B63953850A9F7A05D15 +:102F6000AA3308F0A95DA19336F7B111B19310828D +:102F7000CA010C94211CBB27FB015527AA27880FE7 +:102F8000991FAA1FA41710F0A41B83955051B9F7DD +:102F9000A05DAA3308F0A95DA193009779F7B1115C +:102FA000B1931192CB010C94211CAEE0B0E0EBED9B +:102FB000F7E10C94071D0D891E898F89988D2EE0ED +:102FC0002C831A83098397FF02C080E090E8019761 +:102FD0009E838D83AE01455E5F4F698D7A8DCE01F4 +:102FE00001960E9405184D815E8157FD0AC02F8110 +:102FF0003885421753070CF49A01020F131FF8018A +:1030000010822E96E4E00C94231DABE0B0E0EBE0E0 +:10301000F8E10C94F91C7C013B018A01FC01178248 +:103020001682838181FFC8C1CE0101965C01F70140 +:103030009381F30193FD859193FF81913F01882353 +:1030400009F453C1853239F493FD859193FF819141 +:103050003F01853229F4B70190E00E94311CE7CF8F +:10306000912C212C312CFFE1F31538F08B3211F12A +:1030700090F4803209F1833229F137FC3CC020ED15 +:10308000280F2A3050F536FE20C08AE0989E200D89 +:103090001124922E06C08D3291F0803371F768941E +:1030A00030F8F30193FD859193FF81913F018111E8 +:1030B000DACF21C0689431F8689432F8F2CF68947E +:1030C00033F8EFCF689434F8ECCFEAE02E9E200D71 +:1030D0001124222E689435F8E4CF8E3229F436FC80 +:1030E00004C1689436F8DDCF8C3619F4689437F84B +:1030F000D8CF8836B1F2982F9F7D95549330E0F069 +:103100008336A1F18337C1F1833509F063C028010B +:10311000F2E04F0E511CF801C080D180692D70E0A3 +:1031200036FC02C06FEF7FEFC6010E94161C4C01F7 +:10313000689437F882010AC00C5F1F4FFFE3F983E0 +:1031400088248394912C6501E89437F833FE2DC0D0 +:10315000522C8114910471F5552009F468CFB70100 +:1031600080E290E00E94311C5A94F6CFF8018081F1 +:1031700089830E5F1F4FE4CF2801F2E04F0E511CF0 +:10318000F801C080D180692D70E036FC02C06FEF7D +:103190007FEFC6010E9430174C018201D5CFB701E5 +:1031A00080E290E00E94311C2A942814190409F04E +:1031B000B0F7CECFF60137FC859137FE81916F01D4 +:1031C000B70190E00E94311C51105A94F1E08F1A1F +:1031D0009108BFCF843619F0893609F077C0F8011D +:1031E00037FE6BC060817181828193810C5F1F4FBC +:1031F000F32DFF763F2E97FF09C09095809570952F +:1032000061957F4F8F4F9F4F689437F82AE030E0E9 +:10321000A5010E94611CC82ECA188C2C432C36FEB6 +:103220000CC0E89440F8C91440F434FE05C032FCE8 +:1032300003C0F32DFE7E4F2E892C44FE95C0FE0167 +:10324000EC0DF11D8081803309F087C0242D297E8B +:10325000422E842D8870582E43FC95C040FE8FC0AE +:103260009C2C821418F42C0C922C981844FE91C0BB +:10327000B70180E390E00E94311C42FE09C088E75C +:1032800090E041FE02C088E590E0B7010E94311C49 +:10329000C91408F48AC0CA94D12C9FEFC91AD90A5C +:1032A000CA0CDB1CF60182916F01B70190E00E940D +:1032B000311CAC14BD04B1F74FCF60817181072E72 +:1032C000000C880B990B0E5F1F4F92CFD32CE89404 +:1032D000D4F82AE030E0853739F1232D297FD22E2A +:1032E0008F3601F148F48835A9F0F701868197817E +:1032F0002B96E2E10C94151D803749F08837A9F729 +:10330000D4FE02C06894D2F820E130E00DC0689489 +:10331000D4F8F6CF34FE03C0822F8660D82E20E189 +:1033200032E002C028E030E0F801D7FE0FC0608133 +:103330007181828193810C5F1F4FA5010E94611CE6 +:10334000C82ECA183D2CE89437F867CF6081718188 +:1033500090E080E00E5F1F4FF0CF42FC02C08394EC +:1033600078CF8394839475CF842D867809F471CFB8 +:10337000F6CFB70180E290E00E94311C8394821462 +:10338000C0F3512C73CF522C5818821408F46ECF0E +:10339000F8CF842D867809F47BCF8BE241FE80E262 +:1033A00047FC8DE2B70190E071CFB70180E390E078 +:1033B0000E94311C9A946CCF8FEF9FEF99CFA9E0B8 +:1033C000B0E0E5EEF9E10C94FF1C6A01F22EB02E9C +:1033D000102FFBE3AF2EA01608F41BE31F5F012F95 +:1033E00027E0AE014F5F5F4F0E943E1BBC01898109 +:1033F000982F9970913009F43FC09BE2E1FC04C022 +:103400009E2D9170E0FC3AC05E2D5071E82FE8705F +:1034100083FF46C084E0911101C083E0EF2DE81BDB +:103420008F1508F0E0E0D6018E2F20E2552351F1F0 +:10343000992329F0D6019C93C60101966C0196014F +:103440002D5F3F4FE2FE24C08EE4D6018C9391E4C1 +:1034500011969C93119712968C93D9018E2F90E21E +:1034600081111BC0E20FF32FF11D10828EEF9FEF31 +:103470002996ECE00C941B1D9DE2C6CF90E2C4CFD0 +:103480002D9381508111FCCFCE0ED11CE0E0D0CF26 +:103490008EE6D6018C9391E6DBCF9D938150E0CFF1 +:1034A000482F447082FF3DC084E0911101C083E049 +:1034B0008F1510F4EF2DE81BD6018E2F20E2552337 +:1034C00009F1992329F0D6019C93C60101966C015C +:1034D00096012D5F3F4FE2FE1BC089E4D6018C931D +:1034E0008EE411968C93119786E412968C93D901F1 +:1034F0008E2F90E2882309F4B5CF9D938150FACFA7 +:103500002D9381508111FCCFCE0ED11CE0E0D9CF9C +:1035100089E6D6018C938EE611968C93119786E6F8 +:10352000E4CF9B0177FF02C030E020E0A1E0B0E0F3 +:10353000911102C0B0E0A0E0F9013196AE0FBF1FBB +:103540008B2C912CBB2009F461C05401EFEFAE1A13 +:10355000BE0AAA0DBB1DFA161B0619F014F04F2D5A +:103560004A1B511188C0E3FC59C07601A42FB0E278 +:10357000A1114FC0C40ED11C992309F45BC040E0D7 +:10358000D6011196F60190836D01552309F448C0C8 +:10359000012F060F9A81582F507184FF03C0913379 +:1035A00009F4015010160CF047C0093008F008E08B +:1035B000EEE2FE2E5B01A01AB10885019194819480 +:1035C00091082F3F320729F4D601FC92F60131967B +:1035D0006F016217730794F1021713077CF5DB0183 +:1035E000A21BB30BAA24A394B12CAC0EBD1EAA0D32 +:1035F000BB1D11968C9121503109D60111962815C9 +:103600003905F4F0F60180836D01DBCFB12CA12CDC +:10361000A0CFF701B1937F01A150AACF9111B0CFF4 +:10362000D601942F50E302C05D9391509111FCCFCD +:10363000C40ED11C40E0ACCF01E0BACF80E3DBCFB9 +:103640006217730731F4963388F4953311F45523D8 +:1036500069F0F6018083FD01842F90E2811108C09A +:10366000A40FB11D1C9290E080E002CF81E3F1CF66 +:1036700091938150F3CF911183CF8ACF283008F0F6 +:1036800027E03327DA01990F311D87FD91600096FD +:103690006105710539F432602E5F3D9330E32A9560 +:1036A000E1F708959F3F30F080387105610509F01A +:1036B0003C5F3C5F3D93913008F08068911DDF9343 +:1036C000CF931F930F93FF92EF92192F987F9695A8 +:1036D000E92F96959695E90FFF27EE53FF4F99270F +:1036E0003327EE24FF24A701E701059008940794EF +:1036F00028F4360FE71EF81E491F511D660F771F6D +:10370000881F991F0694A1F70590079428F4E70EE7 +:10371000F81E491F561FC11D770F881F991F661F6E +:103720000694A1F70590079428F4F80E491F561F38 +:10373000C71FD11D880F991F661F771F0694A1F719 +:103740000590079420F4490F561FC71FD81F990FE3 +:10375000661F771F881F0694A9F78491109517702C +:1037600041F0D695C79557954795F794E7941A95E4 +:10377000C1F7E8E6F0E068941590159135916591F0 +:10378000959105907FE27395E118F10A430B560B72 +:10379000C90BD009C0F7E10CF11E431F561FC91F0A +:1037A000D01D7EF4703311F48A95E6CFE894015071 +:1037B00030F0080F0AF40027021708F4202F239591 +:1037C000022F7A3328F079E37D932A95E9F710C028 +:1037D0007D932A9589F60694979567953795179561 +:1037E0001794E118F10A430B560BC90BD00998F056 +:1037F00023957E9173957A3308F070E37C932013C0 +:10380000B8F77E9170617D9330F0839571E37D937D +:1038100070E32A95E1F71124EF90FF900F911F912B +:10382000CF91DF91992787FD90950895FC01059030 +:10383000615070400110D8F7809590958E0F9F1FB2 +:103840000895DC01FC01672F71917723E1F732972E +:1038500004C07C916D9370836291AE17BF07C8F36B +:1038600008950F931F93CF93DF93182F092FEB0128 +:103870008B8181FD09C01FEF0FEF812F902FDF910A +:10388000CF911F910F91089582FF14C02E813F8127 +:103890008C819D81281739073CF4E881F981CF019B +:1038A00001969983888310838E819F8101969F83DF +:1038B0008E83E3CFE885F985812F0995892BA1F3C4 +:1038C000DACFFA01AA27283051F1203181F1E894AA +:1038D0006F936E7F6E5F7F4F8F4F9F4FAF4FB1E003 +:1038E0003ED0B4E03CD0670F781F891F9A1FA11DFE +:1038F000680F791F8A1F911DA11D6A0F711D811DFF +:10390000911DA11D20D009F468943F912AE0269FC3 +:1039100011243019305D3193DEF6CF010895462F22 +:103920004770405D4193B3E00FD0C9F7F6CF462F03 +:103930004F70405D4A3318F0495D31FD405241936C +:1039400002D0A9F7EACFB4E0A69597958795779529 +:103950006795BA95C9F700976105710508959B01B0 +:10396000AC010A2E06945795479537952795BA9539 +:10397000C9F7620F731F841F951FA01D0895DC01F6 +:10398000CB01FC01F999FECF06C0F2BDE1BDF89A6A +:10399000319600B40D9241505040B8F70895F9990E +:1039A000FECF92BD81BDF89A992780B50895DC01BC +:1039B000A40FB51F4150504048F0CB01840F951F14 +:1039C0002E910E94E81C41505040D0F70895262FB8 +:1039D000F999FECF92BD81BDF89A019700B4021605 +:1039E00039F01FBA20BD0FB6F894FA9AF99A0FBEB3 +:1039F00008952F923F924F925F926F927F928F9293 +:103A00009F92AF92BF92CF92DF92EF92FF920F936D +:103A10001F93CF93DF93CDB7DEB7CA1BDB0B0FB677 +:103A2000F894DEBF0FBECDBF09942A883988488834 +:103A30005F846E847D848C849B84AA84B984C884CA +:103A4000DF80EE80FD800C811B81AA81B981CE0FC1 +:103A5000D11D0FB6F894DEBF0FBECDBFED010895A6 +:103A6000EE0FFF1F0590F491E02D0994FB01DC019E +:103A700002C001900D9241505040D8F70895FB01CB +:103A8000DC014150504048F001900D920020C9F7F0 +:103A900001C01D9241505040E0F70895F894FFCFC7 +:103AA000FFFFFF00FCE1A8A8FF1C0474072905F034 +:103AB000038904BB077403740300000000F1025B78 +:103AC0000288023E03B9029702AB02736D61727401 +:103AD000686F6D6500322E332E31004F4B00476109 +:103AE0007465776179207374617274757020636F87 +:0A3AF0006D706C6574652E003B00DC +:00000001FF diff --git a/code/Candle_receiver/Candle_receiver.ino b/code/Candle_receiver/Candle_receiver.ino new file mode 100644 index 0000000..2637185 --- /dev/null +++ b/code/Candle_receiver/Candle_receiver.ino @@ -0,0 +1,105 @@ +/* +* +* The Candle receiver acts as the bridge between the Candle devices and the Candle Controller. +* +* It only allows communication with other Candle devices that use the same encryption password as it uses itself. +* When you install the Candle Manager, a random password is generated for you. If you ever want to change the encryption password used by your network, this can be done in the Candle Manager settings. +* Be warned that you will have to re-create this receiver as well as all your devices, since they will all need to have new code with the new password in it. +* +* If you have already installed the MySensors add-on, please temporarily disable it before creating this receiver. Otherwise the MySensors add-on may try to connect to it during the creation process, and thus disrupt it. +* +* +* SETTINGS */ + + +#define RF_NANO // RF-Nano. Enable this if you are using the RF-Nano Arduino, which has a built in radio. The Candle project uses the RF-Nano. + +/* END OF SETTINGS +* +* +* +*/ + + +// Enable MySensors debug output to the serial monitor, so you can check if the radio is working ok. +//#define MY_DEBUG + +#ifdef RF_NANO +// If you are using an RF-Nano, you have to switch CE and CS pins. +#define MY_RF24_CS_PIN 9 // Used by the MySensors library. +#define MY_RF24_CE_PIN 10 // Used by the MySensors library. +#endif + +// Enable and select radio type attached +#define MY_RADIO_RF24 +//#define MY_RADIO_NRF5_ESB +//#define MY_RADIO_RFM69 +//#define MY_RADIO_RFM95 + +// Set LOW transmit power level as default, if you have an amplified NRF-module and +// power your radio separately with a good regulator you can turn up PA level. +//#define MY_RF24_PA_LEVEL RF24_PA_MIN +//#define MY_RF24_PA_LEVEL RF24_PA_LOW +//#define MY_RF24_PA_LEVEL RF24_PA_HIGH +#define MY_RF24_PA_LEVEL RF24_PA_MAX + +// Mysensors advanced security +#define MY_ENCRYPTION_SIMPLE_PASSWD "smarthome" // The Candle Manager add-on will change this into the actual password your network uses. +//#define MY_SIGNING_SOFT_RANDOMSEED_PIN A7 // Setting a pin to pickup random electromagnetic noise helps make encryption more secure. + +// Mysensors advanced settings +//#define MY_RF24_CHANNEL 100 // In EU the default channel 76 overlaps with wifi, so you could try using channel 100. But you will have to set this up on every device, and also on the controller. You can even try 115. +//#define MY_RF24_DATARATE RF24_250KBPS // Slower datarate increases the range, but the RF-Nano does not support this slow speed. +#define MY_RF24_DATARATE RF24_1MBPS // This datarate is supported by pretty much all NRF24 radios, including the RF-Nano. +#define MY_SPLASH_SCREEN_DISABLED // Saves a little memory. + +// Enable serial gateway +#define MY_GATEWAY_SERIAL // This is the main function of this code. It tells the MySensors library to turn this device into a gateway for MySensors network. + +#include // The MySensors library, which takes care of creating the wireless network. +#include // The watchdog timer - if the device becomes unresponsive and doesn't periodically reset the timer, then it will automatically reset once the timer reaches 0. + +// Clock for the watchdog +#define INTERVAL 1000 // Every second we reset the watchdog timer. If the device freezes, the watchdog will not re reset, and the device will reboot. +unsigned long previousMillis = 0; // Used to run the internal clock + + +void setup() +{ + wdt_enable(WDTO_2S); // Starts the watchdog timer. If it is not reset at least once every 2 seconds, then the entire device will automatically restart. +} + + +void presentation() +{ + // The receiver does not have any extra children. +} + + +void loop() +{ + if(millis() - previousMillis >= INTERVAL){ // Main loop, runs every second. + previousMillis = millis(); // Store the current time as the previous measurement start time. + wdt_reset(); // Reset the watchdog timer + } +} + + +/** +* The MySensors Arduino library handles the wireless radio link and protocol +* between your home built sensors/actuators and HA controller of choice. +* The sensors forms a self healing radio network with optional repeaters. Each +* repeater and gateway builds a routing tables in EEPROM which keeps track of the +* network topology allowing messages to be routed to nodes. +* +* Created by Henrik Ekblad +* Copyright (C) 2013-2018 Sensnology AB +* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors +* +* Documentation: http://www.mysensors.org +* Support Forum: http://forum.mysensors.org +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +*/ diff --git a/code/Carbon_sensor/Carbon_sensor.arduino.avr.nano.elf b/code/Carbon_sensor/Carbon_sensor.arduino.avr.nano.elf new file mode 100644 index 0000000000000000000000000000000000000000..bfdeed7c5b6930fd305d1b7e7afacaa73f45b30a GIT binary patch literal 158800 zcmcG%30zZ0*FSzIVF>~WxZ%PQ772R*ty`^tyR9u~wQ8#+C@8o93RZ2cBm@)`BsUAV zRkXFOOP^NTTCLU^yV_QacGc=rFNg|=5-Jw03;*xjn?Te)@B6%;&;N&?d+*FSXU?3N zIdkUB77NBs8b=6W?0+KWdBz?a1mLbL5#x;SAV$uJnJ~tik@9$>JpsN=(}jo9iSW?$ zt7p)Fn#b)#kUlOHWP5^U0tP&N=wFJs3-4j9ck(bM26`C#;+gO8TtwKz`G0>ba)IUz ze3#q8kEeV87xk`$pP0n*o^sKS6Tf%Y6r5{4pSbg#52ByTST0Y`$je%qkuJ|)nwFin zI4dtND<@l?m!FoOFkI%`MXUxsaVMdOWFU^>nk@ZSe_I&x`jJ&+G`5DaIRm)%d zb79Wcv1ESagWvYP@_pfVum3%By!Br{zxlz|olDIJ?;An~C$yg&^!DY}C1>M$Iei=a zWuHpt&92?mb=MRhE_2gH_3NMg;`S*|{`yh)C1ug`XPE2qd;4En@WbcBo}M(ra=K;D z-OFde`K)5-ap?488T)C%*@Jb=>^1#-m4bYSkE@uijn#RQl|`c`8lv zg`fys$+#Pbdj9dU`*|*Yc(;izA+x^t>Ag9usea|v6GIl4|MJ}KMK829WxV>nm z^*nZERA$nqXxYB0M|zJ=j+dvTJUg5Tls}g&AD#T%b7MzOotXR_Gdd?bJ7aD>t=1g* zeAMOgw3UI(=%gv5fMghFSGkI61O8I+xZ+>W0{jb!D2V7D+(VK+XYj-qH6JVoFlXAmfG5)qLT<(|lhT_ucs>eLm91z}^x3>`XV%$P8|!U~2? zojSD-BU$Yx>a%m_))fU3C#Mz6nAZ~_U*c0tfmhfVR41xw74lfIiehQnq4)ZPg!G}$ zJqnXd0GALar-U&fBN7wkt9&7!?})_M#1Uh{z+sY3r&~29ed?q!jASsHhgps%X|RN$ z;)zCt28WKwWcsQTnF$$-7Ue|AC(6?n%hTj@)0WPmy(=R-FJ~!}oST)6&c=)upy^pT zE3(ovm@#SjX%F>ACN3t{PGn1(o4Xh~H#%qO(q*|+%hHjCDq&7`v_N5pOw5z#XJ$Y( z<88Uh=h{^>ftixAWLZXDKJC$zfqdT5oW+i$i*wSKEy`eGn5lT?G2`%_&O8T;kcL7n z7nB>>LCI}d@M4TgOJ`DYX!)LD#^>auGvk+Lq~$ZugOKJ#MR_G{(K2dYrl)1)$HXwB zlEyG8$;ngr6v@eBnDJA_CQW6=Bu!0{kDW3Fh|v?qj($cyed3g{j9mWO>-3*|T-rjR zV0Lcv?0~fN^sIbp#?t2HXDpS^$yt`2o+qE1nK5@EGF_CGm!G;gZAE7=D;vSi#0#?W zX(A!%;+$797H4GV%jc!d&Cgj1I((O=E zG`{uu!t;$cEe~a1o|c^ty@BP*$j(>_>qYa=;B_RXvjVcRqfv=+j2iQ4Q|9L6qn@&8 z)jWd9#vp^r5gI)Y%=6^g(4je5^XDV4oTc)-#n2}N^E1=3`9TKty*MK+Z`o45?(<@p zhgk3&Y^nJq5F=~xvc>Xww4MKn_@N9So+I@Xbbz#_d@a}oPs>hQv@$O%PoB1va_kab zo-zdiI=;#=D^H-Edk z>e8^nEy|9ygEovF^VJ`XKTLhi82`=}!B5?oWO5(%_m|H}Vs^|6I~VfdD=)n{aq;>y z1D4+YD}7Do#@;{goON<`#wYqkxf4?EU;p&?mwSzy{%-jjMY^+lnX=D*>egOA!}-uh zV_i;1`B!|OAQK(`;Ha4NShsLE>z$N5|3XvMpO#bBkFVrazLy_#^vWF3mYON4lra=l$=!F!Gsieq1TveBS(EMa_$C0sr1Lu*CJ-xc%L|W-8Rp zsjA5ZyZat^+B5p{tJQ|@wzh2No_zNGh+F$kTstyC`~0RfpGc?GhnN2vTAS5#?zBLU z*BP;gEOy|C1oM|CE!La&I$)fc5Jtg7&;T{k3?p`Or4jpIFcZpz^N|7Y{vsJC+nh`=x1Vde(SBKEcGh|7cMjk0dagZ$ z+u5|ABW6GS&V&zLYukHrU*7ncb20~3Js?u!*O6b0JmdOZyVPh3^)NO>dcf)A>i^`n zm+mhu?iw_k0>fb3oSgfusGk9&-S$d#!4d8EuRmUbe`NJA<7YKtk%171nXTDr|ph!_o{ep4}5!64b+CD^sF3I84{b>9@P>e z3pItBVmW1MLUNF7U;uqa=bk5T%03FXN9trZ1CmnuSj$P&@-gKDl(AfqQpXkcH@Hvr@v>SfB_>iuv21x^`9_~K>zn28%Z@4c`^~N_ zWA)|LsnvP<3LPggRkT#MbkW6G3(Fg1t$xMj595N$OTk?|t2()`KkHVJw@D!}sq6Ke z)Of`?kSmRJYm;+@O3G(v`7YU~$mgvWk0nR3Mc_j!DSc7JJEaFpqYSj=%UEr$I=#$b zC@(7C*u%yAaCVRoOsFwPR~i{^l^Xwa)_BvtATeoUHP)~;P3$IXVeD?J#IzRglGyL8MX~$a z)U2ARcpcp7ce&c227S?iiseN|`S0s@EoycjkJ$$dAAbD~FJ&0?;SOn@@mF#Ydxvn- z{!0EC-})E+O8$yH8N9=)@kWnyX;xaf8?ugohUtGLzs-KkHnZ1*X$`uysrgzIB>vkX z=>PxBbGNm(@?owwkQ?P%fm&>4y}c#o)22UyFBmG02`wZs{SkSamsZE!<7EtCi(aTq zzDJ7KlHl*GI<7>v34QX)Oo7imLOFiT{>-L%d-57k#>!2F!DWULO;~UkT3@K;IkA)5 zXv>XY3zce<7Wf8DOk|5ikRv8C3KBF~5jt}V`HWkO#o zsodeW-!I|VVdZY+MrDcOGg3q5$d>qN{8+zH+&tOxfRcbs0Z*IGw4(>(uJ>DcXFpYi8e-ZtL8(xMhyaOVl{C&gz?i+!y`MNNOdml9C%G zQZ2X9e~0gW-+D_2tcJahSL-U!&y|o@#SRkXvQLQA>|n?}M5H_>F-c5i=~21Wu))y1 z3bx{remJ?3TFNO^DX>2&RU4H$lkDKjl~L@=Ro#`{a|7?IOt+14jdyV0*04yq_9_Xi zYHbhW#wk;{SdFTqpLu9xtPOgYEHlkF1*Vj?dk1T*YE5adS}Qv?tFoNk$`YiaavZmW z2VbxZ3%+d8X-d)d50{jdQjQXKSu|CBE^OHwkrES?Tw-#h|J0#oN*}5j%0n1Qlz9Uc zas%bqWl>dz&lolP8MC(Io<+xg%4{sqVYGU93}`05#q<*vy{+oFVQn`&IQVH7OGSevdj7k?vLq|C{c z8fztslygiuxvI1iMBwNF*gc}q&`~zjG{HK$G2(AwRcE-Wx6h| zatvD^(;C&zwMbiipXY8FuNq&39F2u{$e_xpY#b!a@R?xUfRXtgxr|Xe+b6)qqbDx4aYw34@`d0B>?V2byYEQ^p#{E%oQKg!py(QK)<|Lj@Q#t{$ z73TGt;prMjU-OfZEkNT#k#5%)#n>2gg_siE!lc!mmdfs)K z*mgDA$~i}g%v6868SC0t$I#T8(!y9x+Zef9+i>$zV+FS&h|*no@vr23-TY{wrap1) z3RSe6=y$eTjb(gp7&j$mYQH3JVxAmzo1{g>a&m57?>OriHbfTZH`f?fdE26rE{R#< zdy}N=>b6-t4NMwBj3M}o>9k~TDUt7*ZHEaIpJq&GW&+{kaUzX9v zLd!s-#IvtoN6QEOj&*y*GACMYp*Hc4Q}>8gvo^OxrPUT`Dwe3{6lv$9{Uj!i<%pH7 zC9ze3R+0K9JYhGZ#6ca_v)xRTugXwIat)V=+E7n)hRcvcjkM~Q)ku5U zBIHiox{PIODspF@G$mtXRh?SL9tegAeS2H zDstDv%B>}}EJrB>{zWRvpJLT3)P`%2?gGmGZils6+rcLQgTZSsLT1xP~jv0(2jT|0j6VY_|z@vN$oF?*VHt@O7RFtP(0-9?( z&!r7qsE=`vTqD1etwfIgR-)O;mMYX*3`~_fWzId9{mw()_X>f}@Cz(@NKAAw6ad@lPqEj9iSd6y6!BX4Yv ztNMV9>p$IH7`g14NG1P_2y>Nm=Vp?9bqOcL278pr-UtvRvRmmEhxs10%{!{P?B*)+ zH~E3|eKROl(iXvOAhOv3$%Qd&)c&X)QOC&J#0ZPup zOzJz^E!(ZYEdoBC)HuUKEo1r8QH}1f`IACRzDG96=D9C-U*6$m7V2WB$A7As2wQE< z@VH^wOO^}i?t2(_dPG29W_bLkagKVy?~yH#WMgDn!xD~qFyqK{(qKGzTiKG(l6*Dw z>eu9B9LoK(#v)a#ICVP$9$1jY(0{{AN$tU1%i0sqb zw=E02&RJ}jW&v|FZ0-G<7TWK3qg5#F(JO15@-t|BFPA(Nskmf{x8C|pu}I24*^@v<080&$&V6o4lwRBxO;zqjGMb|+ElN~`4}@vc;B98=xLND;o-&QItY0eaf+v$S$9iTj-7 zq!uJgjp0(6POuZy@?-9@TsLHN*eOOVS*CrTD7YVI&9h%XNG#Vl&P2gi>vwc73u{Z5T%8a)mrDjnnX7sj)=5h_1b0 ze&QCP!KfiI1wuC35+0CD&Lwt+?Y?C*;rOS z&@j4cAk<|uDR0t2?y(*kPHp&_lxd1OT+CX)Xl;4`Ual#O{jP0;MvK)BYPGCV7M6mT zb)3#Hkfb%_+WLRGvzi@9?CEMegw|007k)Nv%{Lva_@NjzM$x-Ot?i-de*e0;w~7Ai zn`&hfM0eh5&HekWB&Bz}#F|)_!WB2Mkp6U}m;Q{Cm;OgQKjHZq&o6j>#q%4Uvv|(o z`5n)BJQwi%8_yqjF5=Bbmh(c_{8hab7|M}IXVk$ za4!kb8Ye`jaCVvrJ~LfCtgo6kl0VP`a=5`UuX594E_2Vt+$Qy&t$w-cBCg1@B6kAf zml0QMjGW1{I(H`Gmk`%!(z&^wIk|&l?huvc3SBdLz9TuGrG6_7rLzq-SP|Q33mMt@ zG4ni@-(L`NMR`Lu|9;beu$Ul^wf7@JR>my%sJj1Z$Y09aiaUzG20T#QGqm&J2Z}!j zcvs#tcvsC=R4T$l6(QX#qx9XY)+jPVUkT|^xk}%oDhj?w&&qB-{axLx+bu?JjBHu} z)!*?`W+e-~Rj324aka&(u9u||6Lu-?;WA~eu0S8DgI#t-y1<)g8dzjF<-=Cfy##!ESVDFJY?QJfndLQu)NmEhF zC@+{3nXZ+y7l|CaX7Rk}Xeq3GeBJmH#?XcstjEN(6Rclp`xOSX_-og5<*>o()ml}V zc5z)k@5TM;DMflamA|&kfhOxAn)EBMm6+*EjnDTUUptkX%V`mw>+J}iz)j`m)fPSm zPXs)@uJ|!Hwc3Mht0vUjl9;-7Lue^HE_LT_+e*+8^0)CpVTFTyDtKJfrXP{g(MFvn zj4DIR7cw+5-jOiMT&x4&4F?OV2>`3Z087oe6kLUBY#>0YjCHw z^U90uowid53%1h+=WVAAUa_H^+DjpJqk`H|A>4!=6nppvZwGDg^@8mbVuJ0og>AM| zhzYjS7Op5OrS?*YHLs_3R0zXf?y!fOdE04&zr~=u0ek%SRJ5pNyOjI5Pe0i80ZDOd zt1(ab*UW$2*xj-Fx&Eo{>3l6L=o(92E=WE_2wxN12wh`Z$=A#qd&~B|&F#Z3piZOF z#A|{zE0xP-Rri-D4#gb72)94<%b1fML+&3Bouiy5Q`}Eej8~44Ex(_ncqVF$$H50q z=9i+U$;QScg>H@7{4 zWq?o@gV^TX_jku?>y+09G!M8s;Ig7&K$8vkv+h1=$?Z@C*2Z#CvZn&*-skDUtph3* z6BScKO(9t!SE27aa~@=;n!+`fgn{4zuK|h?Qr#!b88o5TS zU`FkJYBwFfpV}L>w`b+sar>R!tg|c|c31BvmDPJU?0v$r1NC}%@9w=@Pf?Es<2l;k zIQn;kJ00a{Nam4P3;67UWWf^}?5wK|m&W<7Jr&D-D%L8sxrJCo3_K-g4~ySazMI<= z!>~uhR^36dn*Bta$R2{%bdBgTsm-UBePWMSj%$^|it@TRiM6y=#|_E-j6Bcp@zB-Q z!I80sPsQt|ZpFToPhl|j9yN7WuHEF`Zu|%fSDt!0CMybX0LrjQoM@;NTlH1q;zk2( z(JXHrq%hup>iA8rrTg&XYDf~;5+)1A`oZZMr`Y3Ijrk1n3@4>NeXSJvm3?K{;Lfe#cHm) zMQ3HiP?77=# z2x^S4y1VK-YQsemR7F{2sqqrP3L*-Yt$Wb$)wQ|%kQSME!}VudUuOzl+MP7mU9crxmm1ja;Swlv=%B_Sne(EL&&!kT;33GH*6E{1Glpl zO)R-Z=kvkv>pwrK$0~YNt_iiGLdkO3&rz4hpfP5#6nn?-pJctA&E>qtyb$)6MTL3b z59CkFx>&ci?I+97I&Yj5>Ws)Xo?I9AUAyUIGPF#8(!lNR5dlA`iRj_Axq`mrq*I)m zwfH3Up-OvbPSVxOyxbDSCWX}aimSbSscsAHTl|>jsF1Sul#o8{Gl|Ff@0XU;|N zm&SC*?9p~sg09}3g?G2xm9DXP>5qubXvN*Gi~7Fqw!y91O=Vj-)wLb>_A>9nYUf|@ z1^V??qvv6dA$DT>am<5`h|7CivRty1DXDirJsIk8KE88HcWmu>Ip&htYo+r#=Pk~$ zZCyFE{KFn?*NO=C2AngSyF9X@8?;}K^-%LO%GPkZ4%1n#ild%aFV{4VdN93Q=Wr#q z?^^!rr8kPpE~yO$=;xG`c3Y#u1&|?xXFFR*5X~ya)veHI$LP1 z_>wJDBKG1K&ckO$TRXqXlFq6ds7$pIdN$&w#Y?{)9M_3e^>#SJt`)nO=s%K@$gUA5 zrO2`7AYkQg4K1yl)lebk3>(Cl_aRo#-d4t89sG>hOJ6F^X|nV2(wB)7J5x&C(ps>p z$LCFF^-ZL(<1_PmzIWQ!2~^jYclxqk`c;tYH9W84S&3%_p5@~5Miy%XtI@+=M~_%6 zu7vd-Z;rke%f%X2h~gB0gkME?r8ugNhF2l{8v1i4Q^akIonVdQw!s$1avGdp zDv=F0HDMh@ZOCMzufzhMVvWRiTWqW~3g5~&FDu<~i8U+(mwa)!lF~@5bFsfhQ*TCU zwc!=?P%6)AF`Z|r+1C(Wg<1N0D_dNuHkIO( zf|@N5)3x{llus%0(#MK4R}3g)Jgjz{h-34`R(6>f`|<26;HcInvT-CS#oi)Pw>iyS z^;%N9sqRrLYWIt&A5T5|QgO6peKWO+V?D-Mw#6p4g{8!~38jfZX*OD75O25qrxjlN zY7<>ynd9I;tJy)M1m5yA=)oYOMNZ>T3j?t-HX41hM5Q*2MlFpI(>)}$VGJzbcri** zPqi`sq4^43^C<}~ZSBr^83u?KUdrbxYAMy9o~lP^UvZVQKVg6AXQF%}i5uklnbphS zgj_^4mvps3gfOvOpEqZnl9~@3bJarOoa+PTIl6&5ruUdfgk%&ivMeUP`+w5o@Dw= zY*iWJJ9#f^K_B5)hV5%(RJQ*scWUL}A7h8^EOzM5p$2~^)Y6*!o#|HB?Pj+svWB>g z?2#DgjGfiC%r8}j->{=~mZ%Nqu%q=mB>M$^)UWW9b%tL7{e_&Y%C|c1u~gis;_CqG zWw77BkXX4A8#5tQ7YQMv3$piSQ1-#8y z8L}|4FMvH+2#s7MwsWuQaQm9pl3JG~*69|Ax9b*)_vsdi?Pqz^x(vYQ0X`q_OtF2e zxc%q4V(OD!{-W@TAcdFVXTlhMB8#bY>ukB7P=7x|f*P#p3E_$-*hG)E^Vp;N5$hPg z;TuaTQq_i7GVfYf%0xhg_4uxpe#d&JsfuCUvdkF`U8(GO(EMOwh*}p#bh>D=T^B?4 z>69c<7e-Qa;Y6j2Ai26o@)pq(Vb5W81l0@bo9u?PN5e{jy<2H4v1PJtp9Q-q9evDZ z{V8%kVJh5Nzo4=Dt#!))hmcvFDE*EAla@DBK!2gM1@l4q6S=J7>^S7 zP1w`?DokYvgO-IupCX`Tkwj&PLOdGr7{rzTn1+{*4TA=UlSDRxq_B~^oNGIhzcA~= zAX7MGihxX!WbI`^Cl@!r(%BO7N7AZTd>b2u7?lYwSxU$!?K!>E4>CAN_5 zhSOx9;SBaz0OyWfQyY8%_XFG?@PL1;5tZS4)Y=cIwUeN&fs{Y;k_|tOcB`LM`$GNW zxzin_+5CQ%{p4B_cCtCeyQC7O>(A?eu>18@n4OE%cr8L@_y&1>i@Z)CukXm>mSvqa zt73s;fn$MVzvF9(@(iNdgPuwG(pIM}n0=!wosiEhkL>0yn2PlUFF)||2d@C0mmIKI zz!CvV0nENTNBL!3>q=|qN6YfKOu^xgm7$?4?c?;fJmx%v4}n|*AXg~lQt)!kzv`G? z4tyZ+LBI#|c(d*sa$5H-;dCd6Rrj4uBLpewo~4KN=(J1vzzj{jXgx>Mfln|ByyRZX{aZ$ z062}e$eigwGw1&>OOcq?7q1yQ%&NXD*mG%1KufQh2jt1h2xu~0K?%d^hMHs9Qdx{o z0?x*3Oq)yjx&0+0cg5mSj7vry-tJyXMp0fYk$L;Az2DE&c2W*Y6AMd|2uqU!OVgzR zv)au1D70cUS}_K#s3hy^s<=06*50V(s%z~1d5XnekB&B!YQI_s>!E}7(7}4>&e+Z< ztVa7mTMf`w1GLqk;NkXOqcT8K4bW5rG}RCc9^Zq<58!bUJZclN<$Sc?6{FvcKD8F_ z#8cS`$u0S=ecM#f^Yy2GAQjWt#C7rdB#E``)T2HR?J0{c2~g@G3BJLC+GSi(LMvD8 z>e05~R0d*YPX=*%#O9uwgILMP(VP*nS*I3r=u1ys<+dR@XEz^%nJ0 z3e<@mwh(KFzgtRZ>8)pL1n%(`qkRkQ0N-dX{-!+ zJ+ksPr*q|vt{kqfrMn{3S{+aE#ys*ODdc$xyBqY3FzG+I@L;b^nrugmFW)iO6-GUr9xeMn|Nc@wXt1Qo6D`^M>SK}dt^c55`O>tbmThtNIJt= zc=ErA6KfBV((81dFxWW--i8|MyB#4njq=*Mn9s>VtS>)V`%%o<7@TdJaxWR{{4XaY zpCiY0HTrja4#I-};UzbpE3wwLNa-Giu#?;}pmF`R&REm>u07jp>#t)4T%c-R-~Pa2 z?(n!9a*tdE?__d^?9f${baJBKxo%%cfARl|oL2uH(nikclSzcnlddbP*jTCWz?DN`i>?!it1&tTN-YBU&fUBCNEZ@oHO zwwkSA3)mbsl}%<7SS2gd$v&6q0(5;$j=U%bnwn!%L{@gPNUh=67Z92*D!kv{tkbC3 znIf$G=gHX@MTPvWjhP}V$IZH*Y^qQjW{PNTG$%*?YE9cC^4jIZx(#lXJR#bS+a>#O zyCjw!C<^9+Wzj=s+!F4?$PELr76mE;s0^So3_*=Pe1}G$R2u*_;AV{hH){+}itJ^6 zxU8WK!7>ql)8@xVWcsH%Kr6aWoZt zXpUv9skAh*%S=OE2jy%NbnHsxe%jN~wlp(@&u6^jG`2K-b?+}5<1){4QTIs2Cl8W@6I%j{8elQ0~ zd_~CNT>EYCcRwwZpraCJ{cR=i4w0CW|ChTa&mMgF;AV1{Bu<%}_&cHN!q1{*UOq;x z747}rm5H@W*fchd4P>JYPZ<^)UN<~#+TWgdsb|c6Ld!;2Z{XtC0`e|q$_ZM!f{AT>t_$uzmm4&gv38etLQ?OjmWC)Lp$@f7qm}?;A6zWOhk*NkK_w z>B`b|rCUl*l$|SUD!W@YE@*mCX3)wYl_}SxHt9^?1pOA&5OgPKQpoI(?2v+x+a=$X z{9bacu`+wST=$0VU%I0@ zd%Rd@(!H%a&>7FvtkkU2Y|)gd-%!7=KBit1R28%<=+mGRMdyl|itZLI3Vc0qLtu5F zy`~pwUdK(pYR#kY6Y6v7CiPvlAam52^*C`)WgN|UopDk4D8dxO6gknWqRXSV;Z~qa zC(PbPvuYPrZf3V?=^prrl5-_ZC3j1{^7zH~if_B`iFN1JHLbh5&dIZvU#Q;@KZ&-l zHbVQPmbSvPd@Ic07>&0kNHb8A#ja#a*-fmyt%$cm z(-dKC2n8e=7C>X@xY(tq-XRw|PxT0UcgJj}~^8J+5cTOWN+A7srKs`MSrn{Mnx`eX#!z^}8+?w&b^NIet8A zOZ}ShpSOJT#&Oxn9UdV$QH{}iit?YnuzTOE-%IYiGG+3}jf=mD+jT-A-uG?6%wsp* zxo^g^@BT7*?)NV9!^3+PcRQ#U8rVPP-r}fddw33gerjH~j3eC^yb|->7n!11Jt;vhN?c1O~6XLSz*WxFnZMoYQc=bNMv#(^)5dTTbCnyelwr|i! z9=^k#-gEZ3bTcO=^G0Dse$L#tSM*$QqDUh8w(ReY&vn-prR;2f>(1wYu2}NT z1ybK|r#`c88T&eFuoiZC{uQ?c#qZBQvh-&5h~c-A-!7OUom`gbyk+k>Z9v}|?j`&0 z15Ah=YMqH&u4|RAC^M83Qra!k6eY$n!NaWc0)%_6({OJ4yY>v+j-<3NDCa9zC`*;5 zhiI!X8ZF1Y%;_ddYXa?Fk_EbAr4jeSE&TlvuR`y_?u9)IdlmLByg+;^*VSGpeR*HL zkke{u8+YyeI?e*Z9A*Jt`q9`M8ztI!V|$;qm?>QUnA@nN`xw-U-66XlihCI@JLyrXD^7HO@T!v$?*=Cm-i=O`csDs! z;eE{sb3~_7%;l~-t;73<(|WvHoahd+)u|lsR;LYk|LIhL_f03^tbk;IFwc_=@X~7` zX(666Jmq*Q@NB@N!|at67hR>btie1>4Olv!xni?ELws64Pt57(i>>-hap4t8GY2$j zzzaLKT|2qM zuhU!M#jKIl8S;?NQn7tMo$}M%cQWHl3(ut&+Gnx&vW-W!xYmIOy#X)q$OVrav9KE{ z86fPZi8#hERxIp2N(Rss$pPZ^b!tP1SlB<53}CPdQVfV#EUa0e_OOOg0Z5%F?0=X^ z2t9-DpngB?j2pFh!X3>O#-am-s-mMs2Q+vWBV3HP25&W+&0w}|$i^7}4Wni?3|$!z zLKIFzYMw%k(0--}u>A<_<6-*{dX<^H2qBrDbAbF zGYxblg0|2_eka0?p=agiUZJNw>3O-@@Wk2_ZV`Walb$%N4X68WbNTpjKAwd5f?7(y z=EZ8*y3X#@hUc`(QlzzTzKZiIe2PmIJZA4TuppFo*j>%Ggwa9*5nszW$`BE|U={Hlcy z>E(@^BUpWME(u4YIhP=yGQYBxYf%a zmriAXGzLgxfHa0txchmJ(6dSn#z0mc-*_`T*2@|bd*Wtfe3CUfepp+k(aDUn>tTg5 z)(;fVN5q(SNGk+VA`jPytThm=~0p~PQ5+_*cujVlF z@7n3Fz8lOW6Q?Ip5G z@TR7Dl4-I%?p(uzmfpR6TpC>OxSFlqd-rgucfIAh(K@Gpo_mqI$$eN`x6m}J za6>Y%O=9X6>ejX+@g1ygYVb=Nv@C5Rc^4?XL#n5zByP60T1$eTw$c&jNPyrO zv1r5H?b{M2JF9Inoexh!dSEn9te-K#$?X%ZV)t&13YTRy8 zp`EH*)XfqT6VlB{>#C27n~M;m_0`kG88NpQu@O5*Z6(1|tVd*tZO0;MJ2`c>lf*Rr zzHSD+3p3N2ny|z=-c%y1y1OYL&03wX(z+J6Wd&Z-0{*m&Gqqlnn1!4+1+-e$n3g!F zIZJSNxxsiuF;B5v@dKf4cma1^?~yy39#~w=e;%zpdV6zRCG)W-ueXPww-lp4ssVhH zLVbYJ@01h)YvV8LQaD|RN0k+R52fmaQ8gmu>2?;^Zwp^XS3{c ziOD&p>aKqqW0V@>Bc|VXJx%Y^y519?ey+^}kQ7s*Db^HdN=QylPDQ_cxbIPI$%%No zTIcyOo}JZdPu7q2hl3p+u#MC{(%(jsn0D0li`movNdNo9)4T^Qc_W}B;7y;8T&ZTt zt#9`K$i3eEmb=~a?Ptttx6cZxtv!mn9}?4>xa;vzwVAwCo$IMVF09{&ogs-SWyTT3 z9-N!3jCfRchqYBF^lb}8X)42|ZJg=qU8>2AINx|Ee8$bgK6702T#H;ykYi=rJGVTH zzw=b?F^84gqut4;FcKcPUA!IlOga=Z`){(&Oh{=<8JXGIueUYvO=YlhkaCP-M(Rzp z@eq^3^sdR8_&j{^)olU254+ECr+x0Ql}*`U?U30u_=|R_`LGN<0aj%~o8ZAyo!yoo zvF@`NphptxCdCaI_3nAwVk^`3@EPcjo5B;V;ccl2;k@=w#xEM3=ldlsPv*@{!TWDc z3ubSc`cHGGH8RJCmTsuE8f)D2F6fwmJpsFKK5<$aGu+BG#Gj_U>57T*{k}c&^aEx1 zX~C`>2?+HW;yS@~uj{@BH|r61bu`vl6owh8$-}L*=dJi3dR}$vcd$xby{^{w%RNT| z1X&KFrUhGc*!@O8Njt}vF+DQVxSuZzEwMSg#9BRlqxDneCdI+Y`>eHAyY1~~J&fAz zY2F{pqAq?9-;cgb+ls^`7%-npPOCgwaM~qB=ae)|J;`x>w<4eW(9HclxVDFPe7qBMJS@ zB8iFGD`#CBOMjJtdQZ2F^mo|km?SdO`33EtXVE{qMkxw?bd<9Hs+;heZh@6w@xSVJ z+t^|0=;&bX)$ZE0NSf&Wga2Oleg3Q57r3k3+x)+F#|-lr!_yzg2v} zvv)v8#{t&^uK2k+rh}~E=b|g=+uxyh5{-vupY*~Myz!^TLjm~ZS^f`1G)O^ATK?jU`Dp{=hvxDq`Wl2s z#I!+1$_+ne+l^s98OAVPPc!_l@mcY6xI+Ptc$Q(l;hFGcj4wVS=H*ZA>3&4rjHExT zZ2J@Nr#kUhrrRk60s+7FupK&hDuaUsU4H^T@rWIt4!lDSCc>0C7Wi6CDAN(IrAM&{!zwRIN|92;TGw@>`%fAwuBk=zNc>JJm=buo%WV0PV z9Q6~{iA6ggEMg?b?fAd{v3$on@u!jgars~U!k&K4Kk^^=r5(Qxcn^pCt^~A@yKVBVT#zl@V!vx_W&SHkqFs|V|gc1Sr4TGP36WZ4XF$3cE zgd@#yK)Q`^gnR*rI}{6lG#~K!3J{NpJjBN5C?KB6j*vruNT)hN@Do;yY^EdRQ$W04 zc7z-O#CxtIBSX?>a(q0r7j^5i$f2|BoFZm{2nT=t}sr z@xf%9kwba9ARht}c)}6#F(5&w93dY868y6x8$aK>8Xf{8qrSpy`Wj0lx&Yup@EWk1LS$3%+DwwhKF|1(P(>to$NL5{OlUZv zVNoz6j{gcnOlSld$j3$E6%$_=&4fmg(TIzK|0LoSS+6jm(d219{x{;eY3WR849`Fu zyiO#J|F#!6C~bf;03M(qp@Ybae3A_!afX*CGV4XCG~_N`9;g~;7Zi&~yz!P$VVId~ zQ6`>*1OOlV2n{7CQ#)9I7f24YsQmqrHXh+ig1C@|zMiV97ERa@$jOwtX zXhODEDAjR+>N8OM_zzS9!`vB=Q#6f`OCX_2@hCG1Eh01U`#vDMP25m&FFXPjvxVG7 zbBKN-#J>|Lp-sUsTZzayD?6X*P1945PaFa*%vg!*NN5BPrZvukWkP&`JuYRQ8G^8r z`v3~s1bush#3A$!^*MqW;(q}x86M|xa@t;0<%E)k zKY;To-pCW320`tACR)c6-2wrDr()x@5o*c^InC$sy?_ht!k{=w6Ti3$`;x~QHE0Tt~K%)EuPWEUx!n5+Rs)jv@QMLWVX+Y5rv9wFlO zRUlf*6P*UZg)Sn(7mcr<)jZw`Tze;;5t3H(D0e5go_K7vLRmYOdOA-O3xcFBBG>K@ z6FtilO#{KaE}};{Me#(hf?!P-5ijY>-Fl!pf_S{hi%=CIZ-VBdF1k9*Xe5+?nfVQf zc~bHX@IQ9Z2n|YkxewwAt^oJvBlvkgK;^_gP`sG9BHRa$t?Yb@^UWlv#b};O6bOcP z5uM|OxP%%Igm?z1>0M}AH8!nU%o8jGZdDhaR|UTPR`Oakk|!$bBH&BGRP*MHc8~3Z z2^PJFzz!nvKoio=^US+Y{qC|A7f>s|;h9VWv>(O)2}2>PA+!*pU?)-h4s>VPDO=oG z6dxi-++vHnh~l>+q3pCR?kb8u0L_t|vBf2#crVnZ>_=PNO%$&~?y{e4@ou8{c+5a# zzu4mLqWJxOi2rJfdx+v!Q~qadaZgeF14@66(B>2cOGWWwSS#7@HoTW8K9tg*x5d3h z181STxGBg!l=mPW=lvL(2s3aVCM0fII6%E0g@T`3Cy^go?HUFr3*)MWKy?6 zd_ri)=!Wr4;3jm;fv%_-w@*nwz(XIwrGAVAgggOo(xa%M&@Vz#0G{;-YTzE!h1(Xg z2=En;;53BH4nav7G7ff_wiYpfWHTij@g!o*Krgg}TLIYv&?k?i9=Ih4xN`Ch;J-bL zvlWJ~HYK?VqzDCfC@4?R^>Eok`V1F z8u%>5MiMy^$Ki2qNgOQ2;BHiJo6424o#DeBO)&+TE!wVyA$c4Ys^w= zw+I!H_djH>ky6mis}nBdT|~$nsuyn#p+bELtfh;BZ#hs@ zLG@(&UEl$d%fPmFQP48Ny&}_)y)2o;q2NS9!+31jL$791gZVu90&iK}V&@G{Cp!U^q&OK@>*qyMH_sUGanvm5AV_yN(9RF*)sv|7~)m zD_S>1O`RGUP4~>_P_clpc$)iMly>rOb}^!W2pcS@jfdF30LZW*Lex|2uYwMQ4W%hy z|YN34SQ0E_7MBmpm&Ci5Quw;{o7DcVF|oJ3GOZS zXVGe5i9)oG*#8Von)Wi291xkUeO{urYj`$V9>Z0PTX=4I3+fq!cuB z1riDUv^VP3507&))eR>62$FZ3&g0?$9@>Sksp(qdwB^B)b z`!N2{>u%@iC_~V_y9XimngrR2Nd$=FIukJSW>Z1WQ1uj(aezPDh5LZuzldVGVfcEf z3kc_J0_{#zzwO-s!ga|IfWz`75k}?~^ps*)*L}j$ZGZ$j3jSe6OQ%-|(GH z`O;dLoDCpvEndLX*jJUsM?FOT=`@-qM5QACa#&N}IYQJ+tR! zv2etd2PmYF)~$?s6-o&VQb++UvCJRw4~ZG=8W`?Rz5>%BQ&H97bv9p}8RCIf4ZmcI zk|7FoqVRfKR5XP8s^QmcQSp#sR8;s)ThwWY4~%~JEnC!i$ac!=FI&{*BhoMYK6wG^ zsG1E04u8NSRI6zQ9faB&RRIk%A}XXxi^dKoB3b}d5ep!mkilJqs}7QoiL^{rQ{ltmJm_6t7tSO--ucXm)P*kkgdRmyV;@y&s|GuMIR4G8(w2Dc&Y;5|q@dlsCdJ1Dw%?66AeKkoQ%<*HD}w zFKsbKAQ&JJYytA!E&^Hs%*qlpve#K&u7h1TzOale1|+@dw46S?a`%PeyKF)=%P2_s zHq2wh**Gv-Qh{1^iBye-9*v@lB9ZCBRFoNY3#uKNIT}QwV9}_l6t_r-iAOz)N{q}E zVoswDf^lTN5OZc^R%G$&P}=cj6TsHd$e%#`zcljmI?$W^0%%_ok!qxS2aoe9sw&J% ze^^Mr?|Dn{Nherx7f4}Egi+px5K%2Z0hvjIPEpN&;Y0TaM~y)rh`KI95XwF(ixS=t zVj|`M=0}uh$r*r2udOd4{0SM1L9*9}M1hEeLYRZZi2CStns4}#6wFusA#w;A_HrUb zOKzcy5uEj)j!{5A!Yp|eDMY;{6ocAdBnMd~O#>0c{`&(FtrDVGkW*$s!sw@UpzKY7 zwDOmDgpP+Jvd;@!K-SBa}AxZ5NTNFC*3gSb#g6PhE+)dq2ib|_v{oe&dc9Y^CuU7|5UD@dI6RS*F6Jirw) zpwV;~C1OU=+-Fnf$_J>_zN%>mX3`+(`|>?}@(~|(2)(y&Dou>GVU)foZr_Ckl#&KT zeKY#ubB0p>gl6nJ?`Z@il`7muhPVZ5z8uK14L|C)`GpPqHAB* zw(265wRcgmmsM9?SAXx%nVEZUuI2lEy?+1ve7%0Wn8|ZK&*yp0bIzP|=FH5Qxn6mu zI#T&~4q!(4p_DeWd_GRH${%JpX;Qw9qD0H9Kw{-@V3l1ypH`MrzJw;(wEP0bgWU4F zbtWyJN7Xhf?|__N9)VL(K8%9ZmtT)Or+h1ia&CDEfy^u4T~3{pk0g=>XY>zB&O4Y3>KZ0Yuvb+-itIG4J|JBa1 zaVpKz!;ZpxXw%JaQ;%+4b~N;VGGK`=cR z%{f{RQuI)wRa*i?)`-<<{sPA>vX3V^t#aIIBeRy9$=~g2(bk=2&vx7zpRpn#w(hhF z`Vb3uz6hI6_!(%EPUjnyUL`{B0J$$<4E58k#qQ?I#A}~GyavUN9iG!MLcPRqG+zT1 z?xN`N8;3!2I<6~6zQW{ikDzcH$1i?`k5A%=#&0w2gpa3^;Uzbd?NCI>G5szq%y7Nx><4DMxx9F;Z4mrN}XIqrP>WUSK)Njh|(-5qzaMM;+EF_!rphXwSp|Fcu4 zL{GF#Ipp!bVz414ia>r@&0vFV22Q{K(nRAu{E_Th>|5#fJAf*nXWi<#l7;tNJZEW$ zx5}Y;#e13$C|b+E;4R+U4ty>5qm9Rh+X)`kbTel6ak|p2y*%9pF1d`hZk|BW?I~Nd zI}vodT&MRE-7hvDf;>!9PpaG0&soF0W7(8xk{(^689~8$ zW!q>v(KVW8mVHHQiLMb0Z5lLRxhkn#WtE**CUh&4x|P1}?1XMbQn$j_U7ye$nbg^+ z!a$ZJaVv63;W5@U9qj2IW#P_p$r>TMsn>o2rV7#BzdRAzy1GBdZ*EaR%{YH}FEY?wVotT(WYW5|Uf# zDhAos!11nTnjL>&c2s(%nTooNrJgBfp=F+FiTysM{)=b%VQJ#ridmKbb%R#AehB66 z3>C=Y_#xKW5DDuoPCjjIhItxiN{)bOH1pJy(ANHy2&UEN402pysPn*|L}Bv8DA|By zK0wke(ej@cpY=|yDl}w6*4(&6(@c{`s~N$TtN#^@J-uvdfc)lJk+w5lHJoe+MF%Hg%3SYOI4d-SPECS;G=N*EJi_-~J2owj_C* z$oWeh??PqltkB&K^AZ+k*x6>;(dJ1K8AALU11g+6<_RjfpPlz5yDSDLTf#R;n8M8* z$Fie!vFmhvfZA=--SmP{IELZAO?Nv^>!PkrcQx(8&#-CJ-3HL_C!Nag_YdzPOj@~~ z1xnODBb+(%AF^}JmTGDFfA?EjiEa~`qoJQ1#^HB|iBIVem>qJINlZogo(kM@EBruq zO0WLVr}Y=Lui-&kdK@vp{Q|94=2eIb0E*9GnuZHZV=wa3#lP z>n6qR-%{KLvK{RIW(RxD-Ak4`?!$qzey3{WUSNBQS%o)$xL;u9PIkCoWZS=Uzi}6q z)4yAspw42p!!1-rw>Uv&`J%Qs(e|T-O*s^$*W3BtBk26@cD=e={tB+FOK+6Q>3146 zRXoW*9=aO!yV4}TxBn>RRHI`M3<&^2BaL?QS54x<#U;xv*#ZaF*yxy*7}9z*$yTU!TCztNm+OYXKOA@ARK zvuC9MuxBM?>rEGhp@f=6v+1Ew9uYQ z{T{W*dT8D0h$Ch@#Y@d3jOn&IQ%SVb?v^~ZMJ~~b6*Cv<6t-kbDm;TSdMk8#R?V&Q z+o)Eqn9UHkHzGSF|B>Pbz!w@R{6lf6>fdjXR+PibeTQ1lV)kI;bxh5@4UB1;MEF+I z{6?>JEhZmg%`eDflUZ2NDbd0!GYFz?L)&us7e@6CYpygy@3}G|EnO;cvMQ;qt9!S3 zGAg-(fzq6abYtjZDT04KGOKN$TvGzDT9##_3D>OEq|cdnSuwJC8g`*h4iP^*oilvV zDbdp=^E!knl|gv+9Mf~fT0M7C&uRH@0*O^vxpNt;mYUzj+SmzIOHFVC+3DObp{+>K z`le26->y7GQ*ND7LOt0sv$1})aTKeF!oTt1N72HM;)+B*MJe8V+3EaXLfaxm>zjsA zG*8hq52MfnH1i?WdbDg0m92}yE*$UJ_o|D+C#dH@yq1w9_Psryv~~6DJWpmNM{D@0 zM(P_nX^CK*5qdhF+twRRYI3Nu(`TndtL{u4;4z`XwvpCl8O)U3AA|;1s~Zq)x5)|* z?oA-AQqKITGXm!U^Fv!k!T2!jJ!kAnj{&%*qr~N(I}zbN2{RBzP@3^-@tNL>o~#FIjh8H& z(U+H@9fz@bgf|&?33_5z_0^k6IA;W@5G>UC2$_!eDU?bPe0V<@WA|2udlbN*(tV6&l!{2Qo6W{Pkj zo6Z$qGpArIIhw!QM7=Xed7OW@*Sxp=6N3q9`3 z*@XT&HY&;7tx6gNN(g$0CEKUi6vAtru>Y7{GK53L9Hd8CBJBx?8J!`<*(HgWi&(cW z2PtxZx`L?R1#~kSYV;FQavoMghHX-`5_gFACTi0?M~9>Gj^_={DWWzoFb^MO0iYvFcoBT<>Y6SIUy1{ z9C#c7$k_{Q?K5eYU9f(gU9t*J18z^qZ>w?bA~ARYYliK?nprs$yH#upFo|!YHyb+} z$;cx4ew#2^Omeoo)MM+}io+!K5=kgtP{uwKB{%J4tpp z;)s<_#&EUKBcM2w<@|Bi6N&!1JQnbz%*>TP^GEmjEXv%690vSo#9L>&^)zu(XUlQ3nP_*LO+C_7b zei53}XAb8|Q){LiU%_89R$k<`ip`E?Hv{ChA*B}jH&cmZoQXHd$~=m$>|YFpnFpwF zPRBF2SCM&uc@MlWiMOt}8-Pdj;>+=Iq4RiGVty9%HDb=04tzLUKtIb|SB|@@bnchM zF1BN+degCnrm=j%Qgq7pTCljy?HVQDBH5vC!73+nhmt=@t8;DUwMv#n8PUR39~Y3l z9nmtc(TLU$ogL9K6ONopokO>zv@8C2j_r?>7;kQ~4vj z9EyK%f_uKWH3_awDtaeZT)*mupw4WiYP*7M6e+X2dsua?RKTOa)+vxon`GK-n^9}& zw#m7zsd6QsCfQ-doOw=Wg=$JY&969{jNzlQnq2y@{gjBZwW92f&M#5IFH5xG)v{F) zkY7{f;+~!0CNgCi6}-u8Qxn_{;y#h!+N2_KD#bgTZGD2OJ^ zYma)BO8SG8Ba7MHl~CBBtSMY4XA67PXMwfoEekWB5qBLHS>tze45a;p&5kDV9#qs4 zCu@Q<<)AjFtb=4Xh~(f^j-N1fPM`a^8m%caQ`^u=vlhz7MC$r5{+fFHv|q9kSdO&T zD6VCoS&Q|gu?$vjgq@CWZi_&0>UuCzWet&m{48X%Fo%7=z``B4Ts*&WW-0V}hDohu(_g1FxxJcm&ASA-1+;=1zElxfU(dCFY8*(}*? z`fo>*ayl}6L6&N925Ie@tX^PKJ#17i7qPSFU^_*x#+NflE7nAMDIne<;^XYjHkxNz zW-#S*25R-1i05EBne82swIVa=^-kc`bq?#=R69SDDppU5U1!vlGM8>P%Qld)1GA7Nf=S!{U zB1omDr*bC7?_;cw9i&bsEj_1(T{k$r7C5m7Y`9%fbdl?+xSb)_kD64sM}}?_`c${l z^3OV0f$?#2@Ju5Ir-u#_`cwzf@~^F3?3$-TQ{9ug^{Ta~(Cc$Nmtr~dymRa#LRJf! z>tNVt81_IrCH3lmcL6@Zmb{#6U2!RCre)&m=s(D&cD0AJ`5!x1MwgI#&URFHvjrxD zv;a|btp$@w(SDfpWS49-Z)4YsMSYuW6=oHZ(;%%Bmq}@0Hcn;>Lo@rxMN5L#t>vgU z-E4dDT<18gBX4@VcOtx$M>8e;fxWWjwEzwpuASldb8} zEs!EtfIEFv6Sl9Rcuuwt0NgEG)qqy2MAx9wfl3T84NME?y3v!-$>*=>t|U)YpDqGU zW6K>|Lj>--Kp)Dvs;&uFe^Dua%>mA>1L?QO!T2LX2j$pV2YMhCmGU&qGVLvhQRK9Gwie4%Mb1)ECx~srD)Ihp z=2Iv9nX9q4#&OOy9XKIGE$t_$XJZrVhsjKK*0DW-JPF)>_Oit=cNkv}6ws8#l~5xp5?^N~dCT;X;h$|;uiP+taV3%8u1Qxdm+~~y-Qg-+qieN5*=~Sus zIcQ7STxIi|9N4Ui9A}8&Unv?RnO?ohQ?}K5zsD=l>pSL9(nqqT6g63y&Op7(qp)k) zI^g~c#Zf#U^#IfX`v<^IRCg$8Ys)78K{7TLs}6YR&K5oEds6Nkc1|&Z0;oWUN~tyz z9uh7Jg9bsVl)q6uhT3F%spsy=i-al4b!?+?)}07V<-pW19|dkdyT*xj?L*EvB}#P* zQp1#55$cxNRH(a}R7^)@I=<`JqCGFfd-A9}3&9yVlbuV39acC|JHIO~Wwv-6{EcjH zVZoh{XdmU>8%^{yP|aY%^4Lq@=rN!=8Y!p-iW8`bdiO+Zhp2=mm6EIobsSQ4v{08r zZF&>VA#C>0+6EM?4meyVUVnAK;R=Wf)O%EN{S(_{;#-NGd6iwVqpbn%tvbCO&RUG3 zL+&T#Dw`Y7Rn;Oqgzix`ZwQI!LA?VJTDDXs(H~H#?S!TCL!aq3pe)fVTjoQ^KeHuU zW8q+KjYMy-VV3CqEz@)mckS4c#p>LHq`$VIE?KlXYZDat7q~M}?|P}Y&oh8j6X0B& znBButi#(!CgVub#1}0~lNcLhF=wefutw^D(wyCa4E#=^MwaKLNcHz&YJFRr0ldQJ+kHi+8Y~@q-f!T#PqqA-L9;M%A8W63w>93S- z5PyzM>qWduEfyQjHgzz{ZJgMNSvAuiWpiDC24#4XG}lTnN3orpU{_oA&k1(2j85g@ zFzeZFOR#G!dk&@beJ6|TREjyD?X3j6n`M8KU?(fY8K!|^J?wJ`E85$%s|`kqLz%|f zk>Xf{=uXmr2-^KO*cN4@uJ8|KGY)O)smf*pUJb799rmUG&r}mW7~On% zon)rqHJS0Jcx;?#MFMUJ6x_A;}=^$ugLW%xvpc) zmW7(Nr_^8J@&~prR3)}&F0nE9Md=sMCvPV0RCcChz1jA`x6fW_*;gmnE3NB?#m=gQ zsdLI;*o|6+`o>WdWlTW$H6^)SiCRmf&sRw}B5SSh7x5jv{kJTSCgbQ{3Y2D+3yfKVj1>>06Z|K0FwY?ed|I2<7j_t|5xs z2f${ov&ray^A8`xxQ zPJuIR8iO?o$wM&AtqX0Ax67GF@1#ii8~o?en@v$0QnQR)JjnJZW%VAWlh0sx8pv5} z`Lj)~Nq#pYN6)j_m`e7?=GkA`6kD53rX^>H{0bxf zcY)267a7lt8Fez(jrqoy>AmnFS6QDG(8t`3U_Cff z@2}u6o+{oxg#VJl>^Fkx8IP<_&1XW9)se)?AaR-!i-N=+5;<>SSd3u@7TcaSnIg=t zWali}M7iDLpPjs4`n?QwE@Ei}2ciK>0^R0;3!z|%T;Iu(@bX}vuwA9aDB?YJ?w zvh#2B*c&C`jh;bzi&n(>0r^RhUtwqGRhIjd+z!-BG5VxkKen$xz829NncDg*svtgM zdQd?H#YP?%2VPBEh=(f0C-C$citL_BYzWk~XwC7VuLH|TjmB5|m8(|3)I-i?Bu@~% z@%31yf18ha+Fa(p2Y2vY-U9DD3{1yS)ai22he>(IBK&|bUh60_{b#o^t*5vU{?!U) zwTnTvR!)@4G=VoXZ5kCprAYRMTDO6eA3=t<&NNUuC%O%u9{>J2PcuqpbNb4LH&Bat z73(M_=tDa(N|UE~i=C}|TMb_Vx96ehle($7UuW(f*!6x-_93hDNe^1a;Ky?gOGm$C>R|~cx~9+H1&olLoSm0K=G!jj2E)aCZDcw&9m&1<$McR z<+RI5T2wPzw&k=-N^%az?qs(7RgQO&IUS+@VwB-g z@UPWeJ)n%rRToI9x}5sWX3l04G^gX7*1Q{U`Vs$ht)WriFRobIA+-b^uF5!{V%SpOfG|$=5Gz%& z-v}+nk5jQ@w#;9MtTK=4#&agK2aZw6PnFAH=(5*l>E)hl%RNLP7+dh5sE-@1Y7@MP z3#pBGHP4JAk4~TiyA$saghdGBdLy{wwOlPcj3Vk)jvYEU_nky4vKeONFYKDuYmHt) zyDVD^=-k)YiQ+zsAX<%VH=4a9or*8nSNy157P-V;#9=P(3)sAOryq#Zrgrp6fVBr7 z9PmcK(Z#Q~=fWf}0m6$;MElF5MYcAdO=!2t{=J8i_6gADGkhqKJx;jewE{7y19u+s z2P)AFgmTWsHKKScNKGd74|6P1B=+K;`wuu3DQCuJbJ%9%-?8`31vw6u?X?e){Vs*@ zu@*7dUi&DzZ1vjcQz$-ThzgH!*k0$_jvITsEfI12;%wgc7hoTG72C+??3zY}{$^vh zd6&Y_+bG`uUJmna+B3{sir>h)noEd_DMTd{wIA;ip-l=mV+ zvtG2EhY`Z_tD5&#_*bxb8|PpU=>x}a;t56V;-!EGM=yi*+hO@9Psf%}{%(@bGm|Au zU@D=MzwIh79yf%nFa0Jy-kT5h-^W&!l}7ev_%yR^G9C_td)y?{;ap|K_RF z@hUC~veueMz}u|mDePJXMwWkEN)GWZ=5^6GaOC4%>`K>(2Q*cU{JSx`TJNv&oM{w) zcy-llaS%(6TH4p)^6cdq^UDiq5b^#hvnp#Ro2}++CUVl(O5S+?Vd!>K-Y1NGtEs;7AevjK|8)W!8ppZFkoZn+=QofIfOSjNLi#`HR(a-6OL4Y`%b z#(xSFZF111n@u-1C#JGXJwufJcR_KV0lF4*oKGd{-=2blqr~h}k43s^-c-Yh`}9_1(8idKQ<@>XV5;z3IE^+E z*S!lG*>fB~-b@=R+%~e_wvlZye;0D2QzLT(m6wvGHRBT&TUf8Z3#0#(Ndrn z=?GjXnm)U8sDSg$qHFT7{81KFY&Og-lgUz^g%-2L9n%}kmG>W1djcE#AB>6Y%F%R? ziD!-`+2O!RLvgRV%IynkUx>8H3X)MV6Mneb=%UgJtdxsPV@ui#CeIeP2ztwO98p2w zQ_Ssnw=Yk&m|~B_tUAV;_)24Tp=f2_s$6OBUGQdS5t^sW`?9bBJmnv|BdCJ-W9Fv> z{+Pv|H2vsZTIgt0C3;_BG$EMRr*ONXM>+NPxplkTgYaQdd<|Z)107c_%DvjH0Z}q zRC0)TCbh?e-Gr>_t|(MQYLTL?302yd|sguMv| z=2dpdlaX$3`6r{#bauI)q<=E{LfL;!vj5}CB77XFQ%lPEWRN~yA@}Y+e!0I<7RA$o zEbOa3S^aVHV~UduE=AhXpC>kyLN+z9Tm6iE(KoJS=Xm=9QOOuwo8bWC+3aHz|IMLU zJs8j7np@HgJFf)DZp+T;dQ>3RMn<;CLn=j+GU?40 z(^*)_sk_BY+cn?Bu+6GvB-OP1SH))PCE_;rRWTpcJH#z!YD6x3MdCbhosKbR?o;OC zLtxkQCizpkGu38gDCI9?Iyf0(KDWG{w!&h^-7P`y8oAH-(k!lwtg?=^PFCOz_J3J{ zn`kduVHWRVzwDC|5|2XztUe*l;_Ym8XD7cdA3LiyZ1f?uaLJW_9@K1}!#XD}0Ur*{FF9|(FH{1ywQ&7`O4{dKpBT^STtGf*oGMHmh;OmEoB z|Pn_?+x?=?vs9FzV|qPFT--l zvk1+o)X!(I>ijvYHN(`JCz5j|3U`Uwg)aLWuk{%2zCajW ziXcu!ON8O=*wxCSJ%U%uR*leB!hQ(7CDbB}MyME#P%%ln!?c^n&O4Ib46%+ySSH~V zg!K~6MmP^4)^awtNeFlkoBQ%u;*IP8&k3=}y`+|!c>z_l&n$JVsIQ3{Vv)}+b#6cv z?K?~Tv#3pnKn<}-IjN<(_gJa`EUjDtLNH3bD)6=3+;9YccBt%f8Y;ZoKu!j+Wf!`M&D}ckFrqv^WD1L1Pl}Ps61Mk&!9HyCFR+ z;>90}I8Ve7iyWImd=%1d5if}!4)G!pLo9N03h`M;uZg&QpomY47-ErkQ;2Us+AHFv zb4An;kP~8&7No-J`2^CpB3^N}h&@FNvB;JWi5%o!?oDho~n?lTl)J(*y z-WKr!5ko9;V+yeVl0G}{ULE6rNB${dh(+E?A(lg`67kv|BK{;|h(!v9CkxXVQg0Ej zn;~L%R5>9Q8IeNl18Jy;*PkNdToFSoa*R*3EqpknaU$Ljxlp7q9l6mbar!;3wconm z#?!B~@C@&nNCOIg4wT`&>@{#EpO4SfE)lZAUg79p)=XUMp-}bAr0X>1aX4FrGreS% z$o)7(-&4S5u2@Ue=-VMDLq6DJNM86u9pl?#AXndGdy)dVYZ3NHn2GQogc?yR&LQPp z%q~VR&eRD_UbeHv_cIG-f$6$I*r~#D%+myHuO0eg;AHB;Qkt`*%{7r(XmtfV7OlOy z43+lkvQ9Ss1&|E3$|%q5CnH?|>DgRVU}DByt{L|rCg{pX8XH-@v3YC^^9U6-kIQWy zPUa(&MeLi{;(g4=v&iHbushMmbUh{I)lzC+&06J7tRb+^Mz&`%?{OQ~hYG??#cog8OPjx;g4i){!&o4aR+vmxVZ zHgr5-bA1XV-*bmy`gf%l=a7!r5B+?nw4EK*xSFjF8%gx~?t$iGSK>@Zf^~Y~U5W-u zt1l!-oeDZz%~kSxpbbgkJj!M-@Ajz=LpsogG>a^rGB(d~{>$Z)MUl&C2r25;G92KCnWm_{Rs6>=Ht{cf}+N(0{ zZ(o9cmUI`zr0+-M3Lj>gYgQca|BZf#a2r|}P;f(d>M6xsbKRuOUSca54Q<+dd_91J zGLRK)MYk2qqpEfTWxvMG-OFwn)SQsveGPIFh^=FxwQR+wnZ9#V>-c;awvMltpgMj) zg6jA=394gpx+sKlJXErk+-Gt^x#?t9>?JhC#^|uB>|-E~Qqgylkbw`}`%eof4j;H<^2uVTbUtv~JC>nZ3xNMvz}EDH zHo(RI?L+=%^yhS+d@o`X6EDhAwQVAnvg8Mo@{^xYVu58-On0kaoYsyvZ8^}U+amf# z58S*1S_4}A&NB;W;)8+QG3*|I70U_;?I4t%eUb=q5z5&;2f_9dd5DN`vN=MG#7Oi3 z4BH;<<8rmfJRaWK_SjZ}+M_tOm%NXckJ!{pLfP*nVao3%Q9W+cy|G_ylnthV3W}*G zDdsALwf#n-Y8sWSrk!F(#}}&NR~$?IRh-H$s^ojes7~jb!SbfhQVG=4(Bi$D783eA zpgtZg|oQN0N9`>EFd z*_`K?rMQXQh9*~l?Wa+xf3rHyG`2c)zL3Ryw&KrTY81>9%2C0*Awj`>B|*Vt9vB28 zj$f(E@vur>KK%hNi(A6TRoWjjq{)YSI#;^pCCpkr?vgmep7C4iW8C>?+1WtLI?gfq=lF6-3*_^B zxyVD_>dX3$a{l?gtWPZGZ}Vk4tGK|*o&TXsbk8=wqqk21akXywZYim+ZI;aCqs@tI znth&Sz7<*L|M(&P1Fk;zU=rVGI^Ku}_h!?2ad3y}=ENPQotpPJ9W$AVyYHBROM?4n z?d--LYkeB>J!qeKD?jk^AghRgjAo9X7zR4PkdfNnw^m96Vfd1?S1O=64LC1R3Azd zuit3Rz&`ie!l6`AtCVL3eC;4kqgeplz-Dg}UrCP(zSuUB~;-bC(O{;&Js%Eg%M0<92oF24ta~RFHc{4SLe|l=22aIK= zIfiENAgr}&YrDOcaB3ub(@#Z-CiMAKC#W`D7!O|DVT&?`x<{ z6uKf@05ZHkg3d()1|YZ_D~9a|d{hFukD4+$*$L)8#qM8n@?ange+glfY+sgsWB!so z{GAVweI!x6N8*3V;&X%s(Y~-WGfbUAVO|F4UTJnM$D$Wlb|-ej2eXsLt3_zZ)!^{a z2zLn?gD@4un~ZRxgu@ZGNSKfCfP@tYA4xb4;eQfNMQFwqjCT$~TL~8;^pl2Adn9~>py$Ni*9dP*_zB@_2~B8LSrZWo5K1MK zA#{1q+bI9|lTTteoA zSY$h?koYL1-6DQ@wTQ)&A%<8)4;CSoD(i0{>GyKouOi=w6s9ASr&to&=&lZpZ+3X+ z-hM*js_ER};nXPq+(ld5a~EuJ%X+r+ben`$yc??uGP~h_}BXqMo1SgjnS26ymp#92M!#tQ8O+6*0sjucQ!NNI4?jRU_gL zB8FHbmnTDEVR9iAi}=?=M65=Y6Jn8}Da2Ap?L@qLy@+)phFD~E3Q<>z-9^0bdJ#8^ z7-ErYQiwev4HEJG=S6%>#1MU;| zMwJs{k-;g%8IZIP*L`@rh=++7Vv!?Li1Q(>5b=?KKQ`KW~G1bR>Etw47L z)Igu?9Knr4d|r%C-R;|-(KYFFa>534d%G`dI*xVsaB(Uz>D<3H=tLJnOTBxTc7yTU z$-X;Ay)ksiml%6@GoH5Cux>S@?x8?6N>|K7%G4}NjIY?@i%e@MIbquS5M>orlc|}{ zCn4)FA}4=!TU`HN@EB%giJk*c(;@!J`7xZdla< zi=Xf}E3B;yZzltd?nY@}XXL(A&$Q%ap-j$-ObiZZrtbK}srfc+`ER=qr~+;R%L&1X zzmg(8P0VT`O%?G&_kG1T4s0o&at{R5k_V@+ri=O@**R<_YZ%m@0NAK9ECfk?(CdeZ zXHCPmpuCGMzqvOPtK>z&rI^}z_+KPww0lf~=HahO&_%%)2u|NS$>=j&R9Ep=Io}K5 zO%F1VCKFA5Z|`r7GAMyzGw32g84Qu245mm>2I4rGns>=XJGtrQ?ZJ(^5^N#bY|Xx$ z+|HrtB4-j>y-; zO2i#(`3HOUaO^_6?_wdla)#1SH+&+C@|fz zbh6Z^)u#T^NT(6R$$AK#E?l2(r1S0G2<$#?r1S00AzZB#$)c?#E5hn>A4aEFmU30D zG6b5-3Gg0j$Kq2E-VIsn~`3T-FGlM_7voe+28cZA5iYwfO7|(t!z}5;IQ2HE6iIy@l_c%noXqT(B zqDP#FXsdW;AUKp`xAMaX2)@J(e-d!U_T2RIh<=b`jLdxl(T4O6LJ-pZh&H501Hn1&9*$1aSzdR7D2x|L)|ZV^ zKUkt)WHYts4`8#Gwf+ZMMm&Zhw!|C?Jh!oG>On2IpZyON@u{v;C2zXWps%kD~8xl-Iqo92t9@QX>6i@N&_s2!FsTZvbCf^!et{?df)+KXLg zFw)Yl1A*U>(Ocb4&?vDFyEr?yHM^%VjOq6Qrox!XmfQ8<HCfm)`6h@mlQl?zkwsWZ&64ff-V!&F@kts(eyEqTmN2(-SpQ zv-_FM+U&pH`mF?6RA$hm-o6Y^+4@a{>|yLm_2TzuD8ExSTe9`ew|(DR*cWW;p;zdA zZ~LzIT{CfM-}RR6TQ>Wy_mjXC9U<{AR!y_F-)XESyLZ3EKE6OX|3hQuyEB8XX+H>4 z+B1cl_h;K@ts<@u_~c#D2Y<3)^wJrv5|8@OW6?*$^fL@&5NqYxG5>C$Jo*&|_iA?k z!K6kS?>15`XEFMm)SK18@H6Smv8ARSeq=BT`%$WdVxq<9->b0`wO;f!Ci^7PF^w=C z0D1~M;xSyf8dRp@rb;7AsB<-*2rcbL@j^6qWMnB=L<;^@O~<7?DT{3V0{`q3uK~>#wxWDfbRu=CTdDp~vQ-|lnsG36lIV>x{h`U@PL>8DEnA!@b>jK) z9#5t{(dpZW3#H>+sK+v_FwYtg;OhgtxA1OG*6;woFu?l=@9t!2+>)Q$0(`#!S8Gs9 ze_nVZZ}lArZuDj+s|oS*xgKMRRf^+b~{2%+kS795?-vk%)s&7{j~;rs8;_5%Wpu z{1vqk)9FS%rxM+NEcJP<1;p`zkEd8b!TZ2_3oW3M`oJ!I%{;@ihja9}Qhevw+v=uT zzewy=KW+DK=OWK~y^My_!kC#fPCtYS<3Abe&veF_vaNzzG5y|G``YE|T~L#EGTo>Y zspvV^%74p2e%@^@yijM#5A08KwCp7OQ)|>|F<(n6`pn9mpCqsIjeT(Up*t9>uiKDS z=Xa9uTdp404KEk`Ln5-*+y$T+UR?ydwIA&Z?mCN|D9nFdR&m(n#ZCO5RO*_N*0ou|!Ds<%!?Q;jbMa9uSE)&=J? zi^}Ja74AR@vx*ps4zr);%kcgM(tLb7 zki#wKWo$BQsoq!(D@oakdYG$E1yg3i^eSvou~~i!BUR>X4M3UKwq~>euJKiyQDy5_ zUEII1D~01*k3&6KlnQf`th@Nua=ae+RH@pUe@HdNSLr%f@YTNR6IAv(cnWI&IykEz zs-No#gBX(|N3B0{XowmCL0!4C2#vb3ee^vOwH}{OZDikC_KAMlKSB|*<_0+}5Yr$2 z_!yMEusH2keMeP&iY*z}PcDA#5b0!IO1Xc6k;!;iw7>ZjAIuPF><2a- zwFc^<3FcIJObP6sw7_;LFmZn+FulvRPHrZeJJJGs=T`z-4|Tgwf2mPm-`c?RsOkuISJrnhkU%`cELw>9+=yX z-B~c)5-|{JMDeyYRSVc(c3)NY4f&NB=TUI+>Fy)2Jq#ei@{XP<&g!aze1;GE&}k?8?Xj z--`p^$NtiH)>-IuGCRMK&JM&`m!W%wQ{v-|bc!kLYVNs*CGJ`Db+Yt9SjZAiL7H+j1i~WR6L`I&4|rqg)CrDnGyZ^0WWOtSE}pyC~Um6PQ}Al>Zkk zmn)B#GMFQtN#Fcm0pi~B2VMcWx&jpBYkopYj|LC+wYis zW=#$ZO%4uB-uoSsUDjlAXtE_RDc<#c!0(uxX-)LORa=%X0+V&W zW3t|wMD`0znjt8cTYtyoC~ML#Fv-0T;q`G;-PM8Zr@v!6!P?#(*k)zYBa~e^ZQ{2M zP;YBe08?N7U}^FBEDt1A%vRLN9gS(q_-D^8dzt2b##S`nU8~lXa&Gy4PUCZnPS@W; zZNUTu`bE&~>ALA$dX~LyZ9NV^Jyev%?h|Pq+rvyfTWM}^IMjO4m$=`j(X}QpoxTF< zTG5xfm1i}MckHjwPldWs^kwd}H2SPxq3ffLmx;dIJvEKaH((kCqjSqnsCSFL&bO@6%C*T%{EEXZY`^yJdV$;#yftAX{9M!B?+-z?2D2nmO1a>D}Q-48ovc{o1gnJ$7H89`5`pP;UuCqb7muxEh1%=1-fe+=}xe^4zzt8l_whMf}^72F%*KrfBzQ* zCrh12$HU!}S~M9uSu+C1`~E_w`w2~k28a9P!2SNepgCFR1TGf;LT6o!3S8(HD-_{r zzo2o-?B`d@m5p=<*`luvbPqPtK=)cBT^p-+SK3AXk-#x)Gy83#wk%QM=9mC0i^OvRbueWZJH`>`Zjp#cSRMw;DRKT(=>4moioDdwZ zH=wDMeSSd;Zgp&Tb8gb5@(#TEw-YW3kn0l2mH@dSft(v4Hzkm>0_2tia#DcYmOxGn zklPc;D!0Pst}^+#FL(W0FE1vLWo~cFc{PD7bq}z}TM1-IzaITWk*TtXI=+v*Z2WiR zH46I3i^hLNUSp<@JZolID-E?i@{I9oL*uoNJZ;uk&IbwPDRYKJsyH9`oX3OQrzMbk z%r};!bB53PtMPA`>3riOHyPdh%J6j3@{xIF+$}LO<;3ET! ze`nIpORBGl(>F(zmZNRrn(8lOTnJU?WwW31GJ8H$lF6;b;`_~WOpeNq%SC>e@s-}X zs5x?1GhGVZ|C-4#clumR?%u|Q+&!TBtoAsz;$F7^<%CJ^F?5f>jA_9^E`;tPJw5|c z@&UIq4+na{9haa7+?5jafO~+1oe1LiYp@64L7%ZMerz3H79WHnS7|-?=AJl`9%WyO zE;$XcFYPdjb$6m8AcV`?55OWmXhng zFyvpy+AlXmkNF4A8INv$yT~z8g$DuD~>}xS*)g>IN z_CRibcC`ygbw#L=)*Fd56KH@w%%`sz%;4{OfF<)0%At(G+*?5622f8o$Uj3EegZ<^mRayAnpVtI|t-OpTfG3|9WikuLP97U>WzPDnE)&tnQ+em0-JpZCw;5J^}sFlUx4IdZLe>d8RsdEc$Rw=dD_=zwQ$eLd}M;J(Z}cGP29grtB+~DZnY8Gnl$%Ho9(`~ zog#&4FBj#P(5gxh>R{Z$=9Q9&EJkRLP$Z!Sp$eg|TCRBW*?Qs1TLmywloJqSzycm@dvd1o?CN_D7O_9ozBZ)B=Q<)uMI3%g%fXOjzND|&+h zvY*0|=22<8m?6^YP4Mk#qXHAlJk*!CSCnE!Eb|Z-!=~w_D%4|l?9o+ zMxzn?1-5vRd-bJcvKQ(NCehU>(}>O2C)!L|uo{JtARk(kJcs}Tyc zlI9{uf**lHb8(y4<`w;4NkCc-sxAWC8h za;I<%%J4kXK(Xt!Cc%D&%lZ_#PCjegNmr!$yeIVew0w$^@LBbL@G0_gws<%9nnpg~ z4SoJcK1E6Rtoa?ETF5Q(8u{$uK84SyA&_kZ6zP_I zJ;^G)AYBi3DqFT*gswU*1@TTNu^9*6CWNaI^zSI6x3jXk$b0vpj`LULa1=Ro;I|FC z>sfkl>aoLIC#%O;=+~-Jw;A&(^Rgy2Mivch-vb-qX@$UDji6m@4<9LK=9DH36ng~R zKa9`9uK>L5YC_dczx!|tWr)3Be-}v?!fqwsv_CL0WgocH89izQcHo!X><@ab2Z`Me zy$SRjw%De9uA(<4epvAD5PU`rT79f0wyCxe<5e+gzQAjIa|HGEnz#L1ezj1kHx|QX zb^a+>*)?0SV>ONAo8T$gv?t}nw4O@j17&dGV=`zHL)@b|;y@^NVO4^W`m1_}$$>Mn z3AH(h;_#9F*mebSBzSKXZ~{Kd(Z>G#bEEKg$gos7Plqv6IbW8N>w{sg32kbw((=y+ zei^1aWd7F%vP*ICeCQ&sx$IvfYpU|-;KR_ z#=Kp@pD)HS)Q?x=EO*U?*U;5B>`Uta?EqSo?={cNwSTn;C%&4;9b4&Q;7adHx=Npw z3Hk2XB*e-Ik&25zN*ASYijK@anq(Jc_G6GwEM}T^(b~2IaFWT^!Zy38Ek-1YCR>Zz zY}tkE!^VQPf#gO+!N2OUc@(PSfo++#Pd9gwMcEeGMDZehHN@#Nw}?LXrI~Og?YnKU zy*?QAbSceiJFAWKt16{E?6*El_6}AR={L?x`?^+MPh%+U=bqC7Tx)7d``g7${*_Zp z*!Ie)kMpcCds;b8MGL!VsfxaN2vyT`6%7r9gY)sU$9%q%iRaz5ebC|uOjpp zEgbFLb7zD@y?5@PPcS)ko6YRa#(!DBi|MQ4GkzkxBk>v9SYmK~@M5zQ?-uZZR%b>o z&M!_OyXOu|WDw(#ZOVUb{G$zy>il?ZQ znXvU%Z}HYv*KzKUsFP0UApG5w*xl5fadUX4qg;IM(d(=$U8hgnfDgBtq z-N0Yn$jIFk2t06Ct2$IIV8&Fy@9>-~#qYf1F+){QK=DGhJ_O9_$)BCv9cZ+Eo$>SN zYR=gt=ToeTwu7PPK1DL#Ss5enbC8616Vm-`75nUfVc!f8bPHRs3}2!c#UnFSQoTp5 zWd5_}5-f7Ubj3X=bEWzF66K#Oh3W|LAw;cobNYPFh)}xFjM~cxkpGiso-;;2`qOs2 zPL0p9t)$9LL01o~!ze8Hu7_!G3i@H!w$cZTfWfk=@&Om11-4Gv4Z#3V?BwMj7aUAB zot_h%;mwDz?9Ci*bLc@h-;ejMl%3?spCvOjO!R3VD4j0U7Q3wT1vZ0n}SoFUHWqoNisrA*w$!m#hL9HkaZZGB4 zgrM%-TClm3w|@xg5rG9WoxJG+RmCSFJa5z+-!o3$GExPL%el{xB}In!odL+tpw>Sa zW^3#Xj-<`^F7(!0mXo&w*@C+7Zoyn9@4gV!V-O2^PTsR2sPD5_u&I;xK?v#rjs*$j z#}KRt!Ez@rAK7N42Pu{raq>EZpq`~z&~@_qhoBywSTMuMn-GF}8eqXfCvOgN!3)fs zimuXH%na|5@PO($hh@c_yfZ>m-O9IMiIaC(22!4azQ(eNYPf`^a)H0E{_3R z>H}q=FFlR0W-Xk&gF;_={9wVMPTt%Q)Ds8`c6RcPMJ{N|*}X`ws}WndGN^9~aDflB z6R?ODT6BpI>=Lj*jPreE}v|3s*%}wIv`v8 z1M;kZkLe;sD|GtL@SYPeQYN!}lWw77J?gNIbDX?E$Tl}U?XX~bCvOsR!6L ze6132wGZ?VaHg_9&j(%=(6$udIv?mMKrhkcm-|CNF9B~d@6NBj*EXTo1oXfpZf~<@ zczp#NOWnBB{9Znt@vh+b7{hSos$!K%=ZAt7jP3c|HH2k&{RAv%2T*yv9S7b5u)|xA zTZyF`q`}Uz7pRa}kG3ETfS4pS3yMhp&O|PFpqvZ3b%Haz zg$hN3*MN{kH|{Lfchq0^hXrSNt6&w}!f=(}=~;VF^cxff-*5~fBdQ6=zbGx(MlKS;!f2rA`4L+c! z>IFyS0j&3d)*e8ensb8>)B+rHKh4J!T&(_dO%?1VyyA8~p!X*W9*5DQxZYO(iva)Pw*{JIG4o;T;Ye~8v$@Vnh!OKZH~&nn zpC{`&f7y~bU6(KDI%Gxt>IF-ebzQumZpEw>3+AlsI`-&EbC#}LwnEa7Nn@)gCCN*c z9kXEZ;#pl5EL+ue-mFz~j+%9}GjiON@*$JTyH|Jb%?bYwo8O;oep82VS8o~%}r+}@xurw;XlUiHTb{O`8L_Y(N?H2sg* z{vb8}q7A%((Mdu7@W%=KV;gwpaNb|1nQZvuG?kxi;M)jXL0|aC3B0gS!*9XVX;g1ve88-0kqy3<_{t*H<`KEntvrML>?Hn&RJ9`k<23}H( z7&DqeWmGt$3%h18kL?MoUv~fO(S?I^T>3&*I?yB?h^7OvbRat&$Vms9rUSX@Kwdh~ zEFH*C2MW@G!gL^>4m3{(TBHL-=|FKhP?8RmrUNb0fwFXA>i8U`#r2Kss<>IxsdJ7?%!=PX{KX0|%u86Vri7>A>W4U`jeLH656i4mf7R zdgHjUbB8k8vc|kyq04CP^$dgvpT8xYk--4nle;IGtxUJVd{bZ!&ORi=Fmz{~zTPm% zcPmt)iD=wc3Nh|PrSP*w$yOFTi^#^PfIH9(y*zcmfL}e3BCmsW(JX@#fuE%Y)+YWr z!EsUsRh=FRMGJK)!>M8p2h)tvwn%(CVYCgh$ewIC4{7L>V-fIGQf)>SmS@*nQfX@3 zJirX94JwZ=l6A;?zd;06vrp4RIDKN>$)a^OMJ%rbEhEK{s3Nw(BvGKYc}_NGJH9Iy zmRPa3Pg0cBuoqY;*|FOAr7pKsTItuNYIomIGrDjYeF47p$ALPIYFxFM^@ZmT&5_xl z1QttR8lu8V#mo*+Dx7L~i0}2hp*cEWLsJhc3(iuaw|!u^B2)$K-;RShDBI({;|S%b zmKnCFk*Y(*GAbxsh6*=2OsG7pdG$L&knaJ79Ovw8d1+-^<$=j+%Fb?@os->%z{gex z2e>vCly;o@m>S%8+n?b~2rJaj=Abe#C%~df8#%@Gzgz zg$HJjjkQX&>LdKHL#H#76~njY10yO}uIiFLY_wr5%}yyDMXFCZswC%xPLe%oZqiZr z>@eqfNnYa!=O+)|pK5az2+vQ#+D#t4g-NG=xQjxdQLu|M>^Qu{Z)x(jl#!VuyNp&G z9J21&0+xpXg%KW^3`BM-lpJ7t#Y(6_uMEkn5=ST5QC25=vJUH-AV(c#@;j>949@XG zXw(?iQrf_|-_ni_3+C4-Py7oBeE=twWBrj=(H)oUHcB4fEEpZvrL;^kJt5IQS=D92 z5|0kLebBB>L=l9R!68T<$n}jCDm%Y#V*KWod{#Ju_vDJ1ap?tB13V zD$fpWRNXny?8p>!k8{Ixwtx5%59o=>^Lrc%bxxs8m&fynP_xfc_G#5HObD54Bsq1~TRI z=P;k_r1h0xVP9y};I2xTvYatt=#Lk^IZHy5#%ir$BiNBf5Akagc$$7j~TCrOGSS+bjwhs5s?j&rjzvK`#7=v!>Yex}LM{#J|X;3UK0 zQ)4=4{+Z48g1?xels<90?Grk+-C=kP?(9tX@MFF+kye*hDeg)%RrTJ#hAGO(3r;4O z$=Hd=J%(Rm&mEMlIhUfMlyYz{F2hdYPn+&D9mx8Ad;Iy9zM5!am{k{ikWNKsqy_%X zBu?6V(<70$-)R_%SY=~7pn8%&WIh}gAm~{%Zw2v42xtGvcH5eeb4?hYN%awS{AU5f{xZ5SEOa=mJcol&n}|;uNM3j64`Yq#n?)!lgRyCO+QK41R5htc&b z7Oa`WL+K&=r#z7Uy=+%4Teg@W{Kv&z_p9zvUDIXOswHz4_o(h&-Hk`Y_Q7{A`&@Xz z(%Fkw*U#y?dewr(zZcG=NyEGSKg@j#U|iL4_T9ZJS(0V>5eJOx5aBrBy5LyC7>78H zWlP2eKNLyE#38ID?aC796=~%M7~7?UIF2y}JCqQ^QkqiAPpLyFr75A*r6i?<5JCtg zlu|;7Ln$SM5=trj-#2sS-m|N+_Wt3)fuY<-T9($&{fO3Xocw6I9o?MG%iqa{u{}mB;%VT&?9iUc4D=6w zWJ!B}rZ;;^Uwc0seCQOR!k6JVOWKDz2Kv*(^5#S=u@Y{w z5pTG(L%>I}JsY}nsKwp^yhAcL0t%j1;f<31O#2Ytr&)&IxJ}OP92{gPh@MA4yeri_ z)YG3cdLj25Be&-U`g%HNcL#VgX;TjpY)EH%HuU7$duMl2oYE9tySzV_9U2-L%nd8S zFSrOy;d3|zJ%v!wldCG-l$go(wr@#yv=3Xh4I77+*HZ;dOniwEol?Cn4V<8?+_Ew| zJPZ$)Ebtc5$}MfyT8-4+(IX&o9o*0-Z{{E|#s{`$iNOmIt* z<1M5B)1#<$EEv_YJp;*E00O~m}EGpLW z{!CA2d#-1oA97&W?ty^|ofkG_+Pj8EdUB_2J{@s*{cI5LW2MnJ_{tb4cp+l}U#`lX z($l{XGX-2_$!RcT_-c>{Q*Z%HuPdwZo2V?uZ?duizvY$52u@UDnt@pV7yPMY_}2+x z3o27!2n9|EoDd=Y@5Lf~Oyx`wMgAlysW5!#5|`HmAu`Gm5>8c4!EbLRV}r`$@v9oD zwyDZvAS4m~enQyFq&TWW(kZM(V{tBU84(Vhh8oKvZxzkU<+tCJCFa~FCQ3={h!>ln zVyRSk({?Ff!YM#vA{-~|W|$h$of%dLZ<&bH(j*1`IX)4C=tL!1%Or7SwYgX?{23EC7uQ$gq$d#wUAvG&xo2m+LuokU3Fwc}!+7?#=TI91LU$r>XRg+}S*o43OqFzX zrIK$j{-3C?Y!KsA36K7s<;+FPgi@ky;^yjSy|K+*GgrHr%d_4##nMva!ndrmWwo0! zY9jomYQo#BT&$XL;puU+MC39lk68h>1IG!XLyg1?69(V;#1MC4Tyjv?IqE{s&$mlD zX-D8_beOt}%AYAdAoT@~R*^A2{6DIDK&OPe?bs$Gw7T?%j zxe&K+sZIVWA;Ll_q*xXuT0}u8&?me~`M7AjR7|2yruATIuz&uE7EyJ&Of#(&S>v@4 zLuOv<>lZrGsjV)N5q!LJ8TCoE9y#hd*kM5q%mwTa}4E+G%Q+=cmAD0jfo)iqM&jCYE2! zc^A2Y=(K_9%&Az|t>SFuqTYb~+ALr+CnX3c#xNZ{rArF4l7n_nlfqAllu$alvEgyf zEbR8eaDkf-(`7<&#vkC@gFsT1vxG!9(^jo5+*&JCMW#QJmI^ty=up13ayt0m((3OQ z%N!?7OPi@W`WZq$sJ-7fF`Rane;Y_;eN)>&uj@aY|pDa3lSfd zvLq_m(Wz@}7I_s?;-^%pKUP~;xccI(MO)D;+r*o$R81e!ZtZUEd~`~$jo=ZLbBrkQ z73Ef!y+j14{9-Pe^mE$&%cwXS>OERasTb&=?#|zFv>00YjaoRFgr(jWzCM;ZgTB+I zd76Za8%wU$sBMPsvPncu4(}DEQ|}M=*zy9LsmbB0A8ruC=ycMXfq@sj zva(#QypzNIUKfX?|EfJtskD2HlPc>-{C@USL`(5st^7+_bC{nx?Iwqi!(wR{uX8o2 z0hsgetuu`Ky-*xYDhK-ivo0K9Rr>UYMbM|E3C|LEz5G6|74HV)iQ!>omt_KkT&iBH z75;s71?f0a$Ar5?IjC}jj-8ckNJ#U$m$=HMW*52Mlg)2J_=~`y^bhTnbs1V%p^Vio zY?JWkO$#ln_S~#{)k|5Wr%W9i{;mok(aN+B!B%8_`lu2zOu1Y>@UpZ0Seg zIt*%=b%>uBK4FT^14E@)uv{9Q_&SX8#%2+f41aFjSgq)ZU&QXcMAiyYljs?DXcj-$ zI{3PlW}Wm$))%v^@I1)LpMujj!+DLS)J!+_(+$j0A4m0?b;L`mj3s86>MPxI0)7s`C0EED*n0_(!(41t#l{bK_EoeHg$F+eRL zt_uIX?Go1v?+_kP`dQIvmy_f^In-6k*L4Q^C+ZS!i0#5>wUPg++Vkg^h`sOB%>D(Z zalts>R+svwrZdm_vW~|(ZN7XfUir3~wbsR&6V*ap?(0%sM`G<8bg)`0BhVD7xEWH| z0m-*n;QO`L`o=ct3cjsAr}{~^pPCZx(_Zqp@G%`;Z5qs)RZg3gu!Ecu-l{&SYaN@S zv#Dys)Ujz;It5vIqoF-#S?rN!0+;)?y4-Q$-4~0t*3dLlZI4ltN2ZNZK1>tY=^PjC zw1Q}>_f_>%Et6DGn5m8p|68j<2mCSO3%YxzztV3Yud&jmj|*SaId!43D&EhQu+19~ zo0=LnNVaB2zo9aIO8BSJ|AP^uGE$>F*Z6&w8r@8<8LH|3Ku!P2U(E`)YO%kq{)mB@ zB6WtiO(bD>(HtgXY-8;crjzC)2W`$ zNB>5Vzt)lWkYbt=2BCnzQyO;kh&`Z~R>EH@4F+U>cPsYyz6>{Ken@F|D#v#eL&rgh z4=Z+uV&7HlNvmZ#iEg2)Cmh;Vxd0?{a|%#a`&FaP6uSQEmKp_pVY>`cztjrX%Gs&3 z*Nw)h;pexD-TzZ{NyvQSa_#2cP}&e@yco%_>wyHQHaIG6@F8&m^Kee+CWe2j^*v2o z;zD6F2KC|icaHGrmgZt<|EMgEedZJ_g|#W&TvH2ZyQ3hDwYdQJ(VV_3o9IyGFLYqH zMLs2bL08>XlFh5CsxQNwRa>*>rVEf*?QyQP9@Ku>k|={FR0Z)1ExxB!`D5L*M%$(3 ztVUTvt(gi@NvDm+g};9U*_ckDWkuqVmUEbi;j7Y{p;P(Stxi5|@mq9f=mmNMs}-rA z({XMJcN1AKHIbQs?x52XGrN}IA<-8-)L&^+A5~^Z{^@AFreK-KOny(h(Bs_Z<`GiI z2Gmkb3HR$dM|9yt@{-t{P^2rQ1faiab5Bapp=C<=MRkfwsjP|NPPOcm@EQ>Ulf9_* zqQ3`q!}WXWD_Z#Xi=A~@E5cCzZ*7%o8dU;h8&wKq->GY8mEgLA?#gD+0>4mLlwI4|jcS1(%O*T3N{h`*zpQ3Imi;ihC|MAr={{?UqR8xZE4j92 z8IBE~knS7#{I{CrSZud&Lm*i>2fryP_k{2k8REgdP>MAn)XgFhi(FKcu8hXG-T}iN zR6>$(>5MkPH3(W520OOnXxokEF$o>w0>`)#X)92ZDi>>0w?3@mSv^y5aFA2s9&;jQ zJt5p@rF>Z(c7mJr73zJ4RH_u!X)-0m{wzg9d)={_z#)*`-mxJDJbK3jZbnH6aqk2JJtTUN^!!0vxz7YT0;`pW^H!HNA=nmI+)dfPaq3yG>upbEj z;Uc#-jGM0&;?K(}=RuHW_&sfjid4Gwi*AarCkex=bkR{Ob$@L5hz_CVXUeGsZxNv^ zm$&r-cm^n{VnWawHq$A;*3 zRUhb(IzGI8E3*LoF{9Jwx-(_Z-MF=Dl$n5&POE5^iP&?5hq?QuFiw_58ZqkeYujj2 z>1>P^dpH?7By+JalF>k3WXOkwkW)ug?J1 z3ckoWxmFc3n4AymZ)wJ`^VZOwbVLYnh?IUm7a&#t5r{Jd=tWd+v*%* zpV77Zcu^i~gMWV^9n&rp3iK}((qAz8HA>g2(oHjrYBF&_s)N?Rid{tJBj_i-qw@~s zpTesj|<w`LR?}!pn5(_L9!_vExaWf0Gp)IN3%g zhWDxveG^9f4%4AS=0mCtbF`&Qlo!(er4F?^TH6zHI)VDQ`8AS2CN?8AZOot)YjD(g zV)*;2vp)N-5=U`MEZuBYk_|bqD@0??OM{s?j->9>I{9wkR1d434)-<=9VLmc8cXjx zQCh9;a;W|~dgNpbw^t-s5YHh(40R-7=%c}~9YgF}ior-!2%9sEyIV1A_{OHKkX~}T zJQL`b!Sk5#fDUz&!@tmVl=c)~*LkHp%SwIFz0qT9M&@E|LCwM6l1ElDy zIBGac3&pTEpwFRn!`a&{Ym#yDBKg(5oe2W#hL`N}W8SOsl3z!bCKh&{(A|J_U0-9{H7*0~5*6vb|#hOrk$qkno$@_Tu)iL7b zWaWt{S1SBlT@l!3*mQ_gJqQ;rzYT?JRbQLo=CaO zyU?dKzv5qgAw={@oq#FZYe`na)4I{2Z}6!wS=c+l3Xc^hvPB`?s!Awh{t)^t&R>|cD-@?*8@)KOQu)5BLTmZjU2 z@bN$#p-M)tiQ#VDk5M`56i?}5>ySL<(Dn{xUcAJmqXWqn5$k(O_`D7@(W3F^ik}ev z^JXaq_j;IQVt9r2c{+f=u}GZ~VpYY`PGqe?BI<_qbu8-Z6aJF_A@pL z=muBn3;>IFwu@uKyfk#AM#_D7%`_P-!b_M(_#+MX4r-~h{`jh?9`=WqW%(8-kMs?% zPZT*CZZsLq^KNu|_ul(%q>a{LH09mPIeIHTlAN)g7md!{ zryO0r&-wosK2k~l|7vyg-2b=f{OobCj7Rw8XOfd@jg?hEdD%cRU{#r}ukj;=6S@Pu2~8GSRKPHHQb^ z(;VjEnCI|I<4Udk)grbH?w6b!GNbLKdorWxqbXw9{|S5X4FB-Yr8L+f(;W7{r}pBx z_2FS0FfzJSK1F-DGH6g@*F^QY^gY#!$I^#8akP%Fg~IB`zBdb9wb=8XYQZz+!=Gc< z%(i8HuX#sUHQM-|YP5?QJqeAp{Q4|^luv8U$D`G~cWswP)`vf-E>$B(t(OutIJ!=c zL>X1fC8QmRN9jlSRSVtrp4JVInGe4%-cs5(wEc`O>*(3SC?3`K{`XX0o-QBe$G%gI z7V1*mSB{?hDF0}>)P$Dfy=|rZd`0*NMSX?ZRBPX#!T4=O>f?VxBc383{&h)>d|k9x z@x8*+=)D~mc|3ghc2%jmRvQ)8a%um4H=N4j{i=Q6<6e-Z`6cENs`UqvhrwPsG-o*y z>TO&&8hHDR>e}R2(JkVr4!L;TLo*=5dx4(^{A7&|z72dC;D#DJtZJx9T^Tmil5AuE&uume(;jD8$ce7VsAETH37+_tR2$UJoOVwnp4llzV`- zx;_=9orOa`Hf#K-d~ZVBS%{m9!0SceUARNmPRjZMW$mKfzev09rrocg-S^P$SK?`u zUM+a)bycLn9`p-xv)r@hqaD(ZBA^>96& z1L}1v(zR*2y-D1A9sMoP`RzF9cPZul9_3v|d7q=a%PH^kl(&=ezQFdhi|y%)V;gG5 z?XGU9skvfYL(TX-H4QZrt{mS`GjZ>PhMGxNO>C%n-+@UDHIuJ@-;$cCi^ol~I(Q6+ zH2VJVB5)ooM;fmrkP~r_?G@MmOvIgwIOE*`e9;kj??W8R9_0(1b~Ssv4xCFb%#KzRJ?UUVd9W9!!fpS?huOvO9p|A#Nm#kKJb-K~^_-Q=Y6| z;PeyRQVYgR8&I^K475NGJKn^MdiFJUo+jVL%Ic; zF4E2H`8eWO2ki5Cy#V|cj2F=LGWy@==zo{f|2|Lu+e!cX0{w3n{qKwPzuok|E9ifF z=zmv^vwW}qtWn+UZ>YrfYgvM(FMN`4fnr zk9f;}0=`;}??6WWHw!rJTS&TP``yXom;#2d?Zp)z9Ao4|izWz~p??ya^nh1XYILl&XI}C(v zhT}D_Ngu+Ar?^92T#r}Le-6-pu4j8Q-Y39&P zm22+FT1MRDS_Gg=buHEQqIr?E)tkZJto)_g{HXESZ1Nh?x&A-4pFjVCO!^M5hdzQn z6mtsLoWD)uo4*vDKyPIQFtK{dI~K;Qkc$}CksqsC!L z@5W#Xcxh1(tiT<%{9XFuj}vY$KKku`_IqDqzjqD$z29fQcP(}LGIhF+I(>!X z?hUkM-p!LJ_l$<9try9?mU6#Lxi?U5z9O32-GDUvkF3kJO!H-?xsJMgrLv6~;i_L8 zjfF*d{d#3ExjX)cxB@z4`B~l{|%6@^NDWYJYLf`PLuvo9L4Z z^uTura1br_b35^+)H$=~1UNx2H$R<|d)+($>2x+bI5f}~tZ8hS6RcU%+A^m>Z;SP| zBv`Y!1yOBl8&Ajv<1IQmbBD0=xwpymf*Iktu9zC zG5lQ|EXQwfCYd#Py(GskDD|2guE2ElOb3|14M9UIvetABjVsrj8#FX7VQ6hZ9B+$* z#^o$d17HE`g67pNZ6G%yu6g+?`~Y7C%MqGz3kI!0*zQpm_->_ywU}Z_tC-97chmwHfAXZHAJq&EQF1OHbte&v!iV8$=gtps>x^YYa#^?HLriOmU`nouiEO~|0B z2|PW+>5hTTL2jf!n`z{ModJ$Q9>nRg*#Kw3_Ga|syUQ~{dgEYjXto^h8Kj4@omrfJ zobDLu>dFqKbL}{%I66YNt*0-$yuUSvvnm6aZ26Lgw&kl=rI)TvuW4>hbmHvcg~5hwZq15;{tZF;%oVE_H>^mf zhetZn%hT!fMx0SQFqE#F9}Ko{=^bd#tjP9n$aNPh7NkX~zMkCTp4`gz;R}OI506#t z%$~V6*wo&W!+D)6TjA>)a~-{DlrNp55>ZJ|_{`cNoQNBwHw|2vT{F0NOLQ`-$F->^ z*V)~=GU)BhtnJA_jo}M>2A2%rtML?TA=g*}7L-fa6& z+d$Lm6*#oBJvTC(b|v8n#Y^NP#VGjjFsfiBj{6PLgPmx<={}TjV|(vNf!SM{7O!62 z7Vu!s&c4iWtai)5NG|J+R`s=PYH3L~!P8;=RS?dqch%k8(;uYQt*Wc{4{4n@oXxci zY-;MBJ&3xSJr5jpbBA-yI77NWw`MQ{FW4AIt(vEYz0OCfCA|Zk7dG|H?in6xpIu)c z^k+Bc0v@W3vp-`sn}-HEasKPlXU|{{lnUzR<3rE6p@H7s?2uX$BJFU|y88L}WOFdI*_<1)vzyr?qAG@REAhqY zo?$!+>(2&|g;TP{g*-n$b9Gy~xuKFa>!M6TP|Gc5Uf zim_ssENfbFHrnBe<*Uw?eC8G&GJ9HA@5pd>ldG{)$>M4ZbviJJ2(7KTbdSY2(mddS ztC=|8me$tgFji5vX#40Gn^v!B3+hgfbc}4D$qx4nWivdln)R6OYQHd>hUc`~v9fZ) z`DnY)_t4JF6sHBK*M4*j5S1H9_h)nbPPd!^oQAq|A@)im!)mf#crz*)=f(E)r~9&f zor7D{B!%8pS4R)ujE28*_`;@+U=uq8n0Jt!CC?8|w=}Fx3w809T(%{<0euXrA|1O> zH+;}@$u{&Q{Xuv8FnWsIQaA>V+ZLZdhXmJ01DZdK!-TU#&FG8aWO5pA%SWTrcU@Df zJIz{4x>vhD(S|J@-Dl55S*ata#12k7%zAWya^`ayN9WQ;IrP;->E<(62E&8dYzB>_ z5622;p#A{d6<*obzF}!QJ6lU>{UNGo&0u}p9j0@e(<7Oobhd9WwCmX z?B;Cel0M317a8kyYQU^n>Lc~?7|MJ?$lm% zx7ndqd?4seF7W!c_A)-;N) zBO&^*O>{As-1Q-5lv>mNLF6<6ICet~=X#;qXXbtjm)2-rf$D$kWet;x^hqlcB7({s8BL zXE8dVj}5vvEr;*6WQRw3bFfW)+z+Jt1~z8<&=f!tXKdeyX2T9{>A;Zl$f&0}tpiQ4 zzp2A@Ri_5I0h_jL)>5TAt?SkX%&sQe--#y41NCEn@+%{rzOKnwg3HkPC zyrzpN>%G&1!7w`U(Szx#rndCbH7i#5o=`BZ%UF~~mk6u&aW+&q#s?UVtgGOm@&g#q zwqSzd##|X1;7zEqp5a0V3Z!KT4b6~a)o|xfHrtQk1=DsoU3zd}Si7jcZ2RyCMiVr& zVQI(xn8c+q@!62o&I{e2^=!@~I@(9#%98IONL|@H3_ZXQdZ$g8dtrPnF%vxv)mDEl z`*-_10G&DTr%oJuMh~rCCwD4j#Jyot52Nbl7EK6Fi6rK~qOJ>XX`S~=fPZP9p^YUe&OBvY3HM_qySXSxM5!R4#Y)C5CN!$yX>Q=_a} zSHkr>J329gmamIMw%`P=XnuJnnuP0T`_mmsfEb+~#BXxdbH}uA7UVr;RN|o3c#^Fcs5&U*fbe57Tm(md?TW&{(jhJ00Wq2q*61 zl95|mo0W-g2bKxhcJvi)J_vvf)06M5Ux&~*&?jO*ko^Fv-`3~N6ze{!g_m^-Mq(*+ zJ34AkaP*5KY@L|Eu(UdLIZb9RO}#zVP`i421_!Z7=p4X`R(eY`w}M$>psnVUBbZ3% zws28{&zYdJ>lu`8udbdePW?;;yc7$6o2J@KyN-3GLmA48svaA!*uzDI*or#?{R5c1Vz_Hv)=+;M*VSHF0v0}E>d@@Ee32E!TBP0AGE{9bXX^kvAbYE z&T)D}jf?x!dD@|y^toDcE~?lw6s)Pd0jX&-I;~7L#6XC z%6T~(8`wK?aFzN%2^+Wcx8nmj&AOi?-B~nU*G&};)vXt1vDdS_ziYs^9aq+^%gJB>2kzE+U&~Qr6#$?K8jm-^#Mctb139*l9z<|4vdk%i1l^Fs`Jhu*eV<=Eh zXFP$Bt~br)1w1!5G$I3bdQOjP1@-fE{{s78EErcKoMzgZ#QF@8(uz?WEo2ZM;aT0) z1;_T5JZWj;ElWWi8RP=It7n7t`=FtT+Dty40jSY+XT){H!@*{3=xNu@1lkA4CLOl7 zbPq@toA^o+KgDAMM!fdYT}afVOqW}2Nn-tN$4D;6Phv^8%c&TO)IOB%*@!C81y;}{ zbISfs?t!Y~jT&gM3XrK*>zb9L96)w83%8Ltn+v+!P=gus23L#L2{er41{#)}4He9d zhtUD1hucxp`i&s8_)N5?fRWzcdef~m>G|C9Gg^qk4RqHk@^@Q=a?symYcy}azi5kf z-8@~5ZS;%Dtu5?1FKi|-nBp5G@i@CTG#lsJ_`n_`QXD8i7QK)Z*W>1)q+2J@)TyXjylZr(uUFlw zsTh}L+?wd^O-tfoH5V%|-GJvIO|7lE45otIf|m{zjeT%S8gnoVT9m+#2sUj*_t7%a z53T`hi(}&golSb(>28Ol#T#mL@T%jc1g8K{5?eqRqcK(MN6*u|cBOL6k^NN6-%MOo zA)Hxo;fGBHIHK(J>-gIw*;J*=Ut4`2N{1*^3Ff!b5L zbQj^2i?V1JKvAAS_80iLU#=TCgx!Vb8Xb&y=>?jkA^y)AfS1#Jj2Hhl)dg>fT z%@5!Ubt|LglP=zDAVB&aK456ZLxTYf3_Ta=dP6+dc`X!WCmekm)c=m+2Bh7DUEHEJ zk4}E+iiXx@X-=B7*fQNj_cY33J{tK8wuaFZVAi2r(677k;C8#`^EmE|utQ`AA7HA% z4H2@cN6My!IVY!vD_R$0FAjV0>=)6OqP1fBX&WPWI?HX=pmSu1k6Gx=SR)iY)Cjnh z%RUw=Wn1;@bj`YNp=R=m?eA`-(eK5pL04U)OU~tX9hcjpcF%AlHqjbvTh83ZH*GWe z3_ca%x=MR!8L8P1)nj59&EH|gp>|H-bp-N7ut#3DR_n#np5$|yT3R_IiG$08Dbl4c z-B0E4$gC67w_wR??8vxbv(tf+N3a>=yTS=fzdA$o(f`;6zwBo033?a7EVfGDKt`>fsLL>*UgC^ z<2GF&j^iF%#8x>oda5@(*og(@sOL%nCm-ri(H^|+D`0Qi8Kz4c?g_Q42KrCYuDX_c zsO}jD2P1#m+vY_0ZXX`i4Go*qbE>AJeHZ+)vqv8MWd=Tl-FZBT;9eP*I&Qtqc?){| z;hgLY%BmZCdfeWUMMsf0$Z{tdy8|lcHel#|D=-kXVF!fkRef5+g0XXwMWb&(0i+dEN1qB}&2AXiF3{Gd^#^ zz^mPtqt~B~=QG26D3g(g{xZsPYR@gpqN1;8T6JdIvchNPjp=kep>vMeZzDaXn4E*6 z1~?aX6H&Jy;nJa}U%Lx1@S#8KV2|JD73b|QB5j}B&D5Rwu`q<6jP$4nbq{Rn=-J>) zK~rE;96^VUM^2nV`8%uD;qej9Ff_&lVP&Xwq+^20c)YS_diX#dV5S+e_BC-@ra;cPOa55*s~II)xyR9sKE!W62EDH zxr!)?WgWMj8nBj=o|S&-Ha%q|ME8oqLT{P(;i(_?%G}dNdD1TBf(fO^FWUP2Xw(bZ zYQ2v8BG{+Xfyg}__m%*zOJIA&8xs9!W_Y2%x<=cC!}1h6jp^pNJ*oR4h0am2P0w%R zb_V=&jv<8dpnG4UXJ3NwMuf4!&fxN3+OA;whZ1=bwiObSc@i!!B!+nst}Y~|@+91W zP#MY0-vgAPD)>dBTk{dxA<(L08uBKEe`Dfv;?*m;V&%K`B{sy$hrzB`X&|w(Kw>3< z#LATi7wk)1xG!Ov`8ahDnWl_I7AuknGBn_I2#KJBqNqBk#z^!*gfO_eHc8+ihlB(k zc1ViABMvDe@Tfz|2|VVIF$DPcG?Z51XYmvwtVRh}fvG%Lzc10gFF}}zQZ#dZbSgC^ zQ`JbS^YBjCIjHbUgoM10D^w!0ufgz`YEgz!RyFxZ{Q6FAq4wEBsKWcDSp`x5h9qOowH+HJw~UnDZqC2F|`3C#q|1f4n4DVVq$p*&c(FY)Pp3BuId%4KOt+vw2=^Uui21N8voBW;hzNBCd~ zz8gTh6(JFHTT-&!C9K-D624Dx&4Ta)2x?M7{5!Q`1xR~L=qiQqb0zrrH*8g?PAe$k zxq@qMg!y-Eg%vov1lJj(xR`Dsg7_?fMGgrGEOtnWK%+y-2rP9-Ie}#k8AE`7F;~!Q zF^d%lras{vf~zMH-i4s*6QT(7Gc!4*w`2VJzE#Nx|?SGrC$*|<}IClJJ<1fFzANPvGc$e5I+Ap6q@ zW*x$l!DQtp%tVEi%ReV+Jwl0bwbe=}=))7Sz%4h^{-BARgUX9=_ z7ex@-tP#BN&m0T2BV`+cn1H|zhlB+9r;i0DAp33v6o$7y60n1}ZzHH^LQIIU*DM$F zb~E-tiH(}*exUaYsV`33XK4>0<^hTAjbnQ)_AFCjzz*KXTIe*)M;W?! zJ01*)pq;l99dB2j5K|(;vWVqIReu=CrwCUcZ&MLc!4*NRB%i4fmi%S#P8U*dEIe|A zYQ#_jn-m(0;U=ZV@u8f?0?=ZgKpsycc#c8zSp=&b!YsANVyRic=PgRTfanVdmYQ&s zy3kQ*i~Q9WA$U9A!OaXX-(skaE|Swe~o+Xi$af>j3vFh9dB>G=_#jyN%&;>I@z zeDe^vnhDj8L>D5MQ3z9$@exbN<~J=*;tGk_FYpa*^22I&}h~~&|@Ml1xllOq`QDVf>7<&hlS1lt1dPXbdu>sgk(?=jjP08 zLJ+4Q@UlZf0{;KcgPq5Z#blaz?%-KB*4E@XFiy<>&47N5UT^7 zo9gt5lnMlTTUVaYGU3r#uC8@V0%I3S?790ApW2tu86_!;5K_VBYd7Z!HIL#k3H;;u zegrW9fkB6a1o-Fi1+9YYIRvX}!aD?alOVvCB4|?~L=iR#@H5>CIwnE9S%R)Sp*;NQ%HS4k;t>tV7BPJm-)x z1o(&llvZJyGK<#{OcBD9z+{b@aIN54?Sv`B;(a+dL7lc@lJgbhtwX@frMO+LRNi(e z)sjqkfhUqCO#WP3EicxN~UG%m*Ome?NN$e2P`Q5(%PPX=W^0z2gTsmo@} znVl!P2w`ln>-hZ%M>OpUh?e22C2Yj97TbV)0qFj`l{qaH-ohq9+A`stpXa>;0kbXM zG6-RC>GnJUDh4`DMzebpvU7l*hfp3AN*)4jD?&2ZWq*bzNpBKftwqA$Ku~uhbgvgn z_`WFCtU$`+9v5Mr6H(~0&x86Vf;S+OsRF@Vj4%(BDDFo|n}#6XPT+Wlgam3Gk|HqO zA!P(+IHa7wi4GY60;Tb%Meh*ynP-4L)BkdE{xuZP@Fqy`w_fi8wr~l zlOpYD*6&GrbydPVI;7Cej0=YL8R88!CV31&oQc5W4hac7;gA#o9y~&}Xdcb9KSMCb zApC~ly75Q&zrA?E6jG=nr96uO6?uD2z-X>Z{^Rgh(3S_`sR$~A5YIocSTinDO#+?0 zEN)Dc40e|JiM#Ta7)*Y;Up=>Kh=0f2EDJIpISb=rp^it8Y9UbTkdVN1holHBa!6Dy zOgj_7j6(Pf!L_{-{)87#m_iDxg;MGeU>)9!A@-b@Awz}*!rRUp1tOU*Hxv2oiHP*% z)&ph6v0O3~t52@tK7<-AMi3JbXmm(OV5vh=1eQ6ZjKEnADJQVPA!7)va!3V%W`|S~ z;8{4#Cz|Uq^YakQ#)PjETy0GFPrP`-6jEqoO6f&_v3R>tz%*~<2h~p&TPRMJVX~Wr z_dMP#i`d*TZwGn5D!iZJO|!`OS#(6T#AMyVyPmfT5UBe4JfRyj!hCfd(BIq^6s)!o zMGr_G(R%tKpj(BM=54Ql=bHvB_H78_3IyJA2#zVyiyV(3SbY)xPr-G4L70gO>*r2T zic>w~r84PDhkTJo|n*GTSg?S>BGA7ui1QSEf2N4o-&Wup0 zQ}8}lG6G45galF!Nf9V_NEv|&hm;eja>y70)efm3P~(tF0uvlkMPQOc#uAw9kZJbA%DP3jv~9kk54p04-a9rhg-ZP|rkg4)e?i<2je&MrKfraT#J&xeOWqLDFQX z&QBC%me)#_8D`lg$)m@A=YvU;pU>p4NSgDRM)Qf9P$pu`#`$F9e6mclUh>JBZrw;T zBoh01+a_Q)8Fva}Hx=413PqbEOhbh*aWBtXPJ&oof>6jHf*=I0LBR8wGPEEzn({me zG_}p2nAf!k1xzHc5{xO*90_SO?xOR~#ED=HZ|f0A=3Q;H#!}q~&RY-?!2oZ}JsIpt z@y?X+y(BYZD#DiRW*46bS}Yo%#op>9L8vDvG)@SLIU0_-6r7rVxDf4qF^K&UHl}lNvT*{(cE=8eOA9UYCxU)qOHrvPXyUQ5Q z&cuvDSowEH6G`?KTB+x=Qt2%TIRZ}vz81xHG4>RRjXF4s9fvj7o-z9qr+#?a<#=F0 z&S?lmWRhkeOyt8>w(&THDgPL*$Ff>Xb=ha=2PTd`Q!&TuaB!ts8;HXk+Yy3R>(#hLV2(w*b1u&3>H(l95A!8 zc+0i|+^{lUA)(NlJPwmg6^;Qt5#S78y{O7Ogz8`uYbjhO5A!URF^dWld=)5-_Mr11dH6oSm&36wh|B)}s)852F4CZQg|#1j6D;OgUqa|k-gBg9ib zi@lq)OA#bf0+%@?B*3#k3o_;5pKmx~k^oQrBu6wj^O(;^9WhDZG2gFXuclKmM3 zD+S@h2xGAUi`UceF4HHb1}^v(6KyT`Cm+P%Owe%s{NNnUYdB*a*)-aCXOwil`wH78DRs zLnJIKAfkpyIJba^8X{qR0nw|WSOKjeQ$St}w2XlyqYQzBQAR*gQ3l0Z@FtrkqTDuw z@?e*kh%gnaP#h*QHI2he#N%nZB&C{&a5qBX`f9>iSWY5HQzJ0hAt3=Ci&)Sy$UYOn zS_WY<6?Ypv-}Vb$=7f31ZDHmymm1OMig#3)Za0FcNMMgcLIMXJ5_Lgj-;ZD_68?R` zH50;2RH({zpxh)}?%@L9n+4ZBBf_@|zFXetBTOlli&>qtI}k)!0(UwjByg8QQUvaH zNEv}|IHa7wJq{T|;9iGR5V+4Fl>`nsq>8}(4jD_}+YYHF@E`()!fM`m1~A}Le084$ z-HJi@4Di_V7{ZMRYAiyOV6ncGmyxnM&@M#{P0AZW)tQ1C_AO9OfQ)K4o6-~}xsdA1 ze-`QR;D|R0rb6+K7}X{<46e%M2~>%e?iE+S^APX|B$2m_iWi+!GzBJ3Dsfw?Aa5*i z7+k(Q>cJ*~KzYR?NI$aetSl6F7J@hkffWu339NERia@hN$_TVLq?|yTL&gv|#~~F2 z&UHv70iN8vIitF-k>IMgF`|Bk2@sl8_0e;f|Z}}*92EL zB>W(PmY>ig605FD`1^t@H(_Q`Xs!D|xnH<;Vi=pACrn9}r{j!4yhvWmP5u8;3?#<}cy`9%#Tvb+@Hj*izG6cPS<8c8g#U5OtjN9BgPuVs$8d_*y7Pp$39gOJ zq?Uu$hL8;E^Ngn~!o~5`f&bDDIUh$Tq*|KW5Hr)s;k{Sjx;*cD1)h`VU5i-xc9auvOyU^KZ>!#Zd#W(8aFdHgN~|TL3HKvN^B{1ILqY=lJ^*8)o}cUo z5UfQK&I_*PAk0LCefjO6+#y`rmlGzJNik)Z1JZAg)reB1Y05zz8V30afv*EYrROqlxa&s z!Uw&0v+O$1&O_i5(P+doLW?I6MnfC^P{c?kXBA7k6(p7}47}csWxN@|D;)K?4Z(jq zjQE{Gi}N*FLB2H9-3a2j1is;rkib0-NfEfuA!P)fK=AkXDCfHf(2F-l7uF;hzAX%0 zypaj%afG{G!1xU9ry3N8NQ5PlEjWCSTH z0e%RCNVFwIj)e#)1aIdF*vlJP3(HdvipRT3d964_v1b*=o&j_*LNYitDj0FH`L)Pg zdk~-xZxAGL&^y7`zB0NZUv&Cn-Hw~ zA^f=Dx=JC;L>BL-`pv z;tBtk7f<*t1ho$#e(cAj5#~2stV1wGNJ}Az{RoshBqYEuyD%mi(a2tnU}6c+5L~T9 zcqW1>LFha$mhk#0mQcovCCm&9D|jv_N0wp5AlDfP#e)Imbt6de2wdQhkU+0PQUv-P zQbu6VA>{;y95RML&LI^9Haet|z-EV35xB@9V+m|^NHu|N4jD&aheK)zTA}nx^REu zguE#+p6fh6B5>C|PMt$92QWGT>#bRQ;i^yPP0w#QqGwI=U5$_ou8JJlXf>dfD(-&p-=JyIfxC=`H0e@l zZUq0Wnx@mz7!7GUOQpFD{C8=Z4VK1eNVB0-8W!<>O|#z87!7IGmrC;h_#e?U8B1d{ zq{);@^COQm@l{D%=d^Bbvjt-lE7*EExC;4Y&flWeI>UMIga*hnuU zmCmFb%o7mc0X>$9(U3_`sZ1t;e_CNCMk<|2EtqF%Cef=RMnfiDr7}4g{PQ$Thbd+> zr0FP?W`bE)4tFk|U2rc-?+XikjDBNd63hbkhW$ zS7ckBz+sCq^(o(7 zpk*R-zZXlGUrf|klR?T82*`oAA0t4AuY@}UJPdR+|I@%H7jE z!X`ELL~=ca;Jbv;yajWSvP|KWwc{=4!Ac4kV^T>R zLhx-!+A5*Ny9uN%D#53;k44Qi=8M<*Ml0CaISay8A{5)48E1+zifId?jAB}xkW8q;mdJ>vcoISEN#H4mgan>;NQ%HS4k;t>tV7BP@S~mu_9Sr*h`v2Zn^A(6IwCFJ z0AgC@i;HQrf?_h$7KD<-WY7>9&KP|SNoy?9CZ-jpC0{`%t3dc9LUBz}n{EU@qnI`? zQYfayMKoGLMuQMGTp}Y@!Y%}N+WN8l!h)DZZpL&g)h*&!1M+~Sal1a5W6Bm%cNE-@fno-|Ccpug*qaqn`?~&6o>Jfyg zLHL&#FZibLC=u8GP7wSp!V$869Z@XH5u*K)mHjqX-r+YSr_-nAO>!AlbU;m#LyJ>l zSotfYq>%Fw62bbtxG`&hC7A!hF)K&91jk+AFdZ=1TK)h_FyCFkoQat;#>^_N`Y=@T z_Uv~6p9ce%2QB*&t@{#-08=5uEiL(WN!qJ2ynhA3hC0HOfwe)#(i66{2VA_#Bu}%K zr}6DQQRTo~#^PD-VZ=U*K<#<2fdst8c5$A-bVau33Cyw>6Z|~b?>UL}(8Jqg#3%90 zmv{04j&>IggOxPT#xH=hOHz08=29oU)Y~kh7r}Z^SUY%gtf9xc-B@1*D~*;2HW=y6 zh!m{?Qjnrt=NVUZMCvlqWRUt1yr)GoBCcrr182Bda-=>3n?li%lDd)qB4?n5dyn}&j%-69GrAnaMDO{(w5+)jloHIMr}nH zAMC;Fqh17wbb%wJGfSBG<4cO?F3h?LZVXvIQ;PD5IV{6>l4LpWg>u)3f|p_|^`x!A zNt=R`J{O#{IXLMe6pT^VBCucu5hSwG-;a*2M7m<}$CqS_)wX10(4@0`w$r`jXr6mwdZ zQ;M>TIV|tzq1cNE@5cZMcSPZQqvaX(lIUJ&%{+0(Df;U4-!tFS}!{j{PIV0f$ zMwED>vvo~KsZ(P?Q|>f!$q{)fj@9W+S16LF<)#?qZQbb!k9_n%a^9sYm9-WzFIM@ zKFThp#n~CHAUg`9xypm;w-eq*_QRmPQj}3lYlmqIE6B)*o`){N`e-qN>^Kl; zbVx{GsY6l(mN}%1z*!C{C$PdHV+h>r5KIg8Viuo7fRFHYoq&D3k+pDp^&C*XictC` z%5{i24}q5FeK!I&kFUY)fP%bHs@Kkm-hv<{Byg)kLISrrBt_tMhm;XG=#X*(cQ|AW zfjb>iLEtWjR1$d2Ayrm(X8uitLQf)vtc9DWhd_Bzc>R}eO%nNEN04F=c*7wffj1qJ zBJh?&$_NCfXqs{Y4}C^dAP&!kl4#Xwp{>=AZ-rgphwxL*Uy=HysWDy$ONGpX0Av^MwD8;A#-UOlI+f??B*z>fq;r>hAg~ zsO0vZDBK0~egwZSdl~p^!q#mmUv;G7QdZB#g98LV`B}g-s6#we+wtN29j-?$<{}iUVsu}X7VuFO|JA%5!1oL7qfu6LxrY&?Z4r3H zAt8ZB9g-sOm_y14JnoQk0#7((41p&dQbFJ;hg1@H+96d0o^i-n0?#_6n!s}o8AsrG zhtv=_?2z#UUU0|+0xvpbB7v73GKs(|2-sYm#QVz&1jckrue;`8y@`NRdxAwg4$&fB z0`c`y5x3PrLVag$Jz9VR5Gf`kbOepfOX_#6c9Fw|8*+k`D1KraP;c@d5H z%?QPR<@^?CWzfs>ZIa5Vs`s+yRN%Emv>Ct`A$Z!X1KKX6E-MI09SFX(&A_)6(Jlpk z1A-^5{G(`%2t0`LgLy)e5HLhd#;sOC%Z8+B2$k|i#j+X8PRtV}mpz;%d~zX+pV~#? zEe1(#Q8%J$Qm0b?kLI6&3#c2!ZGiE&BVc{ol_x-E>#CXHIRrewPvi+Ob#V(c34RNF z5Q4skQ2a#Y&H13A4Bj~1f&4BN1>?7YNgF|cPtEasisX$)U>&QhvMz~Sc|P6{yd0tQ zv|=Y>=AM3}*h8nGIU|%#TZ^XayPF4q^8pz&m;S5du8$49^3}@d$!nwwM-+FOtM0MUu)F;(cZWUs6mvJyJfV z#nO#dp!~@YHXA`|o4_20gaqmxk|HqIA!P*SIi#Gxe20u7aE3!F2rO_&C4q$wsUon* zA!7+Fc1SgWMu&_eu*@Mf1kOUhz*NKgON#`?iv@aZ1+DQDq%F$djJR772)pQDr;A7F z4@L}v7{`8a+>XFh2OT%g^)X@I5kJM8^N=rUpSSr4VX!lmCqR8bk0nG?q*y|oFOv^nu%^f@K#@pb@B%z`N*s{Z$)?%YLg46jl`LL#*ckU3V79EF%7#jgStC&2vPB? zo6ms%1x@o=OJg*o`E02)FM|IyO*3R^jD|ErrP91ke%0KP7^ynAq{IuHtf6})lR0_b z??b4@uKUhlTKEIZ0H@_iIfO6{wAwwvbVnxXu~E#HDXljdfenmz+PgZ~EMosr#9GDH z_*5JQVG>%9q7A`sqQuV;T3z1w&INuCg7-FfH_(kjiX5dM=of|5V+pr8lKr8Q(YrwJ zMJOI=NgFIdzX&wSD(0tB_agWOApU^R;S|)54>k9dD+P?{Nfw;3EFC z(BjuVVp=@Fk>_~?EG1XuEgKSELP!R2r$>CkBGTqYd^3U15n4P`BtBng@!NC67YXgu zDD6_nJz6*M+q6nHSte(W2D90tISPhtXh zk>k%1(9EH>x;*gNQ8xBbkc+(+e1m1E;If0--1&kq(bVvn(ltU^B zlslw~K!rob5~y-WHGyh}j3ZFvkQxFL95SB384j6%{N*BHfg>gfEObanV5vh=1eQ6Z zjKEnADJQVPA!7)va!3V%8yr$;`E`MCIf6Gi?~h1P3uUq!5yZd*ZgNOS;8usE2;An7 zG6J_dq@2J(hm0X`heIj|-06@?0`-eEpDI)Feh|NnQ212{QXWUZ*pSE*cw-a`DH9+K z^NYF39l?nJ=ZJ8mAi$gog<6&r{tyB_HNo37Fye3!-f9sb?^GvmrpE9#3jy!ign0rK z?VUqUbgsnX90>yR91;>(=#UhFMGh$=u-GBx1R5POhQLyXR1jF^kV*n)Ii!lf3Wtm( zu*xCT1ezT(jzEh;Y6!GBWITZ#4v8F;gi9SUN#HVvgamdwBt>A4L&^y3bx1jZs~s|i zz+NQ%Hy4k;t>v_r}XJmZit1fF$B1%c-rQc2)>hg1oOSOcPsb8`Tb$#8RQdGAJm&ko^sr-FCkMk$^r zR{*U-C>Bg%^(E*#LAwzF9XF-jt)Qth4`?HTKMWhKI0y1kFC4pij44LgWHEk)i#Hl^ zE#iDBBFlz0&07vZUX3HLTj`eU0-(JJ#VSzLdIV%U#duk`Ta-4{XvC?azsqK{Vwo?m z!o%d%)W!SLXe0V|sRGmS2tIArN^E=}NWV;AwnIV!^$tl9n1_IMMT&Qd$J>NYo4&zg zAU=UmwCOzud`pG5BHk7;Vk)@m54T721EXTIap#GDngy!SYs z!p#KZEusdl7gN=3xY$S4mzw7LrFe@>oo} zj>gBM9_=cYV{{%^>B~3zVYHj7?rB@$3S+G?;M2nN8#t6 zZrWx1{qK^$#mT4MJ8De|CJY|E>j?DoJvwzhT6yoA0UIFjCDvCE`0m5thmj`&-;m@R zqZiGBEfM&Ld@COUpB(G+Zqg4yhF!+*%P$qb*UP_DyuJKtZ?qQ6zs*a}mtyU*{Q3SA z%V(F-_k(^T!p%pBfA%PJz9egxZ%@7}V%KcgvDlt`?ZDnSFutXr@tp;}ut2-p#pjI4 z+0YS>Pi{f5i;uc)M7RmzUW7vk4?tI-09-q&bv*0N44@2JMQt^;?7s6qLmk{jY+KtP!>kzmYvx}2K&igq1 zIv0U66b^ZIB>^8To|COo={RvR`bJM)v!io{)bG(Bz~tf9Rj4-vj=*-=44{}!-rErl zAu!IaX;nHX^B_BDze2qIxC~2(zx@R_vg9z zFW}BE$}e;H*KnVJVytuc1Gw`;*T*~j-*M*$t(h<7S0QtLrJ8yX|1fZVZ+eQun}G9M z)0jC({CU9no#{r0e-1c5xqO|&{{T3rXp0>FP2k7CY?l6ez-Iw(aq&+9=XZS#KMb5- z(j|WaIVRvD{KBT;9{|peVj6xL@SVVEck-VJ{9(v5`?LYS+Kb-+d{zynlP>=O;1_uD zJAm`kpl7-G&jX(i`_mH>@Sy8~^Rtp&F8)^F{O+XL>kol*Tf_Lj2K)lVX^uNF;W4se)7@Uww`#KSiN|97;XMK1mTaDI-F>6zc% z!1<-byB+=*aDI-@@_Q9HzmK=r#gB*LNlcBcJTrjv+iOr27DTPc!rCA82BRK7dZT1f%8*9Z4MucCeF{lJdOg0KLY1b=gg1wdpd9) zV{ZDL4V*`qbHPde4&cuucHpIRwO0-}k262f#qR;m^UBY4_+J3$$>WP0{t)of5>|hS z;D^9@_Bj2G@?QWx#f$$X@W&8u<*O;jwglp7f7ag#zjH=W18^=i%-;VBoM%klf(AhSsw;F!Ve)4K=iz+je~rL-0$sn8*AJYBvt=B9 zHE^C3Hr?TO0_Ry`^Bw*j;5-&=s>6Q@{G+h1w!cL17Vue!xB94sZ=MevU7qN-2sjVT zGW^rPd9;=J`)7gkq$$gP7w{yEXZrmC@IQqtxU~5Dy}9ObjUOavoO5PBBvoc5aw{Ext2EAe5_0Q`sHj^G0*ApP|$;D-~U^-F*lb`ELW~ z19+eaiC{7ufqy27o1~u&fUihe|27x+bEq4*prl^{d<{B;O_ z-sRT^{O5q7o}}Lf{71mi9&zpn#71b(=U@ZS&oAAnnb`z`bx zTnfy9pRxQuK>Q-F{7(b_pojk(@Q=aX_%HJKk>>Av^__y8x012_CIJ6Yq)#Yw1GZt) ze?H=;1E+t{AC>{HkNEM&cfj97;ZJn&Ip9A;yylPXG~hq*^8Z8N{|@EQmn=f$4@yb?H6miW2Alfa>};AaAV36UIs=|Ag$|5Gw2Zu)z^!_@9^-qf%84FLGZIb z;@pxigUxgJT;SILZ*e%kFM1ewqr=w&=bJ}|kO9*V0q6Qt+iw_L0Xzh*0`a&ZP2&I7cJ(om99O+>IS{dsIGjMNSj2~k4RV~h?Vg$aFgD!m?(FT_`^CCObf)x?-VGAS^2qaPLIB*yoB#0dZB0}T? z$+Ey?kuAV-y!?JuUDGwwb5{PLq?@TbC3AJ@Q{wzhQ1gmpb|-N3hI&W3S3Jh~0|8H0W&@Z$#lzzDw&ym>B@e-Ze+ zfjzE*ED{U{teJyJ${K0>A3YR;OkNc zK8f|>4d8!4e{iI-PE5dmFu5+xsq^)~SM7 zucm)3rN0;0?C%}Ge8c2hDV=u_pMw2#fA~W?ro8jOX8&5inLQ4V_JN;!8-yXTe-8p{ z|2ctO(8It9?8Rxt@!(wt+)5_)hd--w8U3e=u|J;%Hrx9m@Ga;c>y!RG@SE_Tucr7b zBm7?j*80$2Ujlvy+GnDEuLB>yGsD+l<9xF*zSjbq?Y|p1+RXUhJ3^lZz7_WS9~_{$FPLy$*% z(H<9p|HAOU4+B4I*!xl77eUwd{C!~Rul3~3JRbsf414is zAs#{hD4*l;7_i=dQvcrtzG95epN!xy08gQQA+7(nz(+I=67BI7;LQHVtgiwG>3)Xt z`7<=H9=}9(*z36UAD~Yf{rw-{E5>+U^TWga|3Tp6cgyP1-ZujC{Tn9A|JXa#d?Y@J z{_%GQ9)$l~1g5=D1Jl2m*#9c0+@sj>v!CG$6E}ebCP#=9Ahc++-7w=spok+<4Lmv>5^_wD>F=r zLHSsT_OwX$MZXyduiHxwgdg2MUVd5iu02lUa;wvi+p67CEX`lt^@3!xAM9F5KMK}c zt&MZ5R@2}16SuR8{^`8v`GH76k@#IN5*ud*Oqx*l6VY|!opH2Y7$ve?W+256dVN)r zHYLq$X>!<4G#$;ZhD~ok>HH+)PA+Fm1MqJGKY1TWEb5=;_rGQ ztY7dNNmZGDn8%sKG-!C_s`pzh*s)Cy`p#Gr_~cktyF4OwESE9#@c3c9hFxZuHsY?i zy2d1!s_aI~PGj2J_ZsuvW@^G2)6|N?cBGFk_;C-zRBbC;506RN9Ft7i5YtrbCG%mY z+Aj3mC@GZlLrad$a4%J5sPZf;_oFzB#wt*5bUc@&vD!^a>Q-1?UrA@-kZi-CE4C9i z+>X~=^XrHxRB?9oVAYFbciSsM2dSGqokVUB)Bn%*nr`CNRv86QSquoZRg^fB1H6Tq zxE$0HaFf>%QQPyAM!UAUX-^HfC7(#hSdNoLI8#6JR9mv8sW@2Rk1joNwjTQ zZ>`_0dl44TjFPT`9bYw7%qWAVeBYFsUqOfIvtuMQO$k$D7}(WpJ?G4{Qx6;Rn%rc# z`r^Ifls6Zhl8Af$YQK~CbJ!3_S%{M0hTGR z$u&LjlD#n6dCMAN@~z1>$o9;@BsDK+%H_1ZndxlF?jpRoUeHj$^LzvpUK%J(A-Q%W<1hzY-HQ>f+U=`2RNe5-B6RP@+gsfp6u`D9Xd1$#TiG`D6_Gax zSGJSNchl&1{`^RhvNDEXT)DJmY0veOE?OMVLVJ#Edzx# z1>KYGtlDjxn`nn2z*t!}qOgGlYH@jSeOE;h8=(g#0vm_QXTZneRL&y#R=DE@SC<0C zl0MCQzASUfJRz1vDX3Iwx~-`1C$=-QKUI=twk|90Gwzucl`k5Sgbjyw1bUC<+=?5K z=LG^g!oX?n3A zVLp)ykwdiH9Z%5LS-I2+!`{FrGK8L>rCmSl$I6ynAF(71M9gJ9 zE3dYbA1x<8T26knocw4N^P^SFk5(~n;Ucv6gH|{QD+aE;AXPZ#0Go0TpOp1=Ln}h8z#t}zee7}udc^&@SP zN%DXy>Tz5MtwJ-*Fqf7n87bqcVV%OI-6`D7^j3 zbB!I_!iU3;B0owNUCfrBj{Gdj&ysadrP1iy>dR4IMfFv(wrp$5v9^lVR>|THVqR;L zwYt~n9hjCdDQ>4BNw7f_CLK$CW7p+xcil-5x6`aGvvf`23O9;yAD7y7XIJOCE-n?N zG#A`{D^Z{?uRzj0kO>qy6_Y8&o!YQrGup6Wr8>Jf_;8!3d`%UZT~e(;sM$ZWFtS9` z-^ER2?3du=B11SzZDYkU3cP(@s`Q8XGblXliVd=ACavEd5)VZ2SS&O0aC_t!YEKJD z+mm#oJ!08$SxfdLPQo6i-*)8UY{L7=UK%h2Hq^A6aM;0qx8G^|v5!5pE~jD(m92`v zL|$HB6D!rVGh6EU0D2#{xZR$rdo3KK5d1_74+!KA4_SXdZpA(drBv(!@gM+uHpPWY zLO)?USuZR%330u`EpxXQ;)2PG2Uc}GA0VdV5x^z*+Jabd7Is;yG@*K z2H_Y&BRH1Wz^1p0Ibi_@_(lN+0egFx4>hpk&*We)3TKR4I84ZhEZ{9eiVktJU(lFA z13B~q^#&?Aq-M>iz>N}&LYy{=0H5Yyy1pI}8E!|1!L4I~HiVaDZ_qt9A_r(cquLxz zxvqE~+@UMdX&BivR--NV`aI{jL6Q1yCqsJM)EoN1)}j~Vcrvgtc5m!%;Ih%wpX^y{ zxD9zVm(kNY*cG7+E7^7@tm9NCt)NNoqy$0twn(Fa{o zDH3ZncvmBzH&HqVnZnYMXAAcab++lXT---l2o{kvhMMY_TLa00_g}L(=q;s7|44sv zjRW4=@|m^D*4fSKm+IM;6C0on=+G*@Q=M zG|twln{V0Q?U9LKTd|r=nMAuxlXs-aRlnF5s28ePpaKAj)O694N10B!#~>(!3v`;! zlO`KoVLolV8chvwhG2VW66hJW%oJ)Y(NJl+TU9itv;Oh1Bu%=6hg6W;;Q?`jdN zr~2yu4)7HV%Hz8gH@+Y5cO3i@{^*$X ziCx9RPfdH=$g}+KZ Include Library -> Manage Libraries to add these if you don't have them installed yet.) +#include // MySensors library +#include // Serial data connection to the sensor + + +#ifdef HAS_DISPLAY + #define OLED_I2C_ADDRESS 0x3C + #include // Simple drivers for the screen. + #include // "SSD1306Ascii". + SSD1306AsciiAvrI2c oled; + byte screen_vertical_position = 3; // Used to always show both CO and CO2 levels at the top of the screen. + #define F_POSITION 66 // Horizontal position of the "F" icon, indicating it is allowed to generate fake data. + #define T_POSITION 72 // Horizontal position of the "T" icon, indicating it is allowed to transmit data. + #define W_POSITION 80 // Horizontal position of the "W" icon, indicating a wireless connection. +#endif + + +#ifdef HAS_CO_SENSOR +// CO sensor variables +SoftwareSerial co_sensor(CO_RX_PIN, CO_TX_PIN); // Receive (RX) and transmit (TX) pins. RX should always connect to TX on the opposite device. +int COValue = 0; +#endif + + +#ifdef HAS_CO2_SENSOR +// CO2 sensor variables +SoftwareSerial co2_sensor(CO2_RX_PIN, CO2_TX_PIN); // Receive (RX) and transmit (TX) pins. RX should always connect to TX on the opposite device. +int co2_value = 0; +float average_co2_value = 400; +#endif + + +// Mysensors settings +#define CO_CHILD_ID 1 // The child ID of the sensor that will be presented to the controller. +#define CO2_CHILD_ID 2 // The child ID of the sensor that will be presented to the controller. +#define DATA_TRANSMISSION_CHILD_ID 3 // The child ID of the data transmission switch. +#define CO_OPINION_CHILD_ID 4 // The child ID of the human readable opinion about the carbon monoxide level. +#define CO2_OPINION_CHILD_ID 5 // The child ID of the human readable opinion about the carbon dioxide level. + +const byte RADIO_DELAY = 100; // A few milliseconds delay between sending makes the radio happy. + +MyMessage relaymsg(DATA_TRANSMISSION_CHILD_ID, V_STATUS); // To toggle data transmission on or off remotely. + +MyMessage prefix_message(CO_CHILD_ID, V_UNIT_PREFIX); // Tell the controller what to display along with the value. + + +#ifdef HAS_CO_SENSOR +MyMessage CO_message(CO_CHILD_ID, V_LEVEL); // Sets up the message format that we'll be sending to the MySensors gateway later. +#endif + +#ifdef HAS_CO2_SENSOR +MyMessage CO2_message(CO2_CHILD_ID, V_LEVEL); // Sets up the message format that we'll be sending to the controller. +MyMessage info_message(CO2_OPINION_CHILD_ID,V_TEXT); // Sets up the message format that we'll be sending to the controller. The first part is the ID of the specific sensor module on this node. The second part describes what kind of data to expect. + +#endif + + + +#ifdef ALLOW_FAKE_DATA +// Fake data feature +#define AMOUNT_OF_MEASUREMENTS_TO_AVERAGE 5 // How many old measurements to remember. This is used to determine a good fake data range. +boolean sending_fake_data = false; // Experimental. Will allow a user to send fake data for a while. Useful in some social situations. +boolean desired_sending_fake_data = false; // If the user wants to change the state of sending fake data. +float fake_co2_value = 0; // Holds the meandering fake value +float co2_minimum_found = 400; +float co2_maximum_found = 410; +float last_co2_minimum_found = 400; +float last_co2_maximum_found = 410; + + +float co2_fakeness_range = 0; // How far of the last average the value can meander. +float fake_co2_jitter = 0; // Holds how much will actually be deviated from the average when generating a fake value. +float co2_fake_data_movement_factor = -0.5; // The odds that a new fake value will be above or below the current fake value. +float past_measurements[AMOUNT_OF_MEASUREMENTS_TO_AVERAGE]; // An array that holds previous measurements. Used to generate fake data. +byte measurements_fakeness_range_counter = AMOUNT_OF_MEASUREMENTS_TO_AVERAGE; // Current position in the array that holds a few of the last real measurements. +#endif + +// Connection toggle feature +boolean connected_to_network = false; +boolean transmission_state = true; +boolean previous_transmission_state = true; +// Other +#define LOOPDURATION 1000 // The main loop runs every x milliseconds. Normally this sensor has a 'heartbeat' of once every second. +boolean send_all_values = true; // If the controller asks the devive to re-present itself, then this is used to also resend all the current sensor values. + + + +void presentation() +{ +#ifdef ALLOW_CONNECTING_TO_NETWORK + // Send the sketch version information to the gateway and Controller + sendSketchInfo(F("Carbon sensor"), F("1.0")); wait(RADIO_DELAY); + + // Register all sensors to gateway: + present(DATA_TRANSMISSION_CHILD_ID, S_BINARY, F("Data transmission")); wait(RADIO_DELAY); + +#ifdef HAS_CO_SENSOR + present(CO_CHILD_ID, S_AIR_QUALITY, F("Carbon monoxide")); wait(RADIO_DELAY); +#endif + +#ifdef HAS_CO2_SENSOR + present(CO2_CHILD_ID, S_AIR_QUALITY, F("Carbon dioxide")); wait(RADIO_DELAY); +#ifdef HAS_CO_SENSOR + present(CO2_OPINION_CHILD_ID, S_INFO, F("Carbon dioxide opinion")); wait(RADIO_DELAY); // The opinion about the CO2 level. If a CO sensor is also present, the name of this property helps distinguish the two opinions. +#else + present(CO2_OPINION_CHILD_ID, S_INFO, F("Opinion")); wait(RADIO_DELAY); // The opinion about the CO2 level. +#endif +#endif + + send_all_values = true; +#endif +} + + +void setup() +{ + Serial.begin(115200); + wait(200); + + Serial.println(F("Hello, I am a carbon sensor")); + + transmission_state = loadState(DATA_TRANSMISSION_CHILD_ID); + + pinMode(CO2_RX_PIN, INPUT); + pinMode(CO2_TX_PIN, OUTPUT); + + pinMode(DATA_TRANSMISSION_BUTTON_PIN, INPUT_PULLUP); // Attach a push button to this pin to toggle whether or not the device is allowed to transmit data to the controller. + + +#ifdef ALLOW_FAKE_DATA + pinMode(TOGGLE_FAKE_DATA_PIN, INPUT_PULLUP); + //Serial.print(F("Toggle fake-data-mode using a button on pin ")); Serial.println(TOGGLE_FAKE_DATA_PIN); +#endif + + +#ifdef HAS_DISPLAY + // Initiate the display + oled.begin(&Adafruit128x64, OLED_I2C_ADDRESS); + oled.setFont(Adafruit5x7); + oled.ssd1306WriteCmd(SSD1306_DISPLAYON); + oled.setScroll(false); + oled.setCursor(HORIZONTAL_START_POSITION,0); + oled.print(F("CARBON")); +#endif + + +#ifdef ALLOW_CONNECTING_TO_NETWORK + if( isTransportReady() ){ // Check if a network connection has been established + Serial.println(F("Connected to gateway!")); + connected_to_network = true; + } + else { + Serial.println(F("! NO CONNECTION")); + } +#endif + + +#ifdef HAS_CO_SENSOR + co_sensor.begin(9600); +#ifdef HAS_DISPLAY + oled.setCursor(0,screen_vertical_position - 1); // The labels are shown slightly above the values. + oled.print(F("CO PPM:")); + screen_vertical_position = screen_vertical_position + 3; +#endif +#endif + + +#ifdef HAS_CO2_SENSOR + wait(2000); // Give the sensor some time to boot up + co2_sensor.begin(9600); + //wait(4000); // Give the sensor some time to boot up +#ifdef HAS_DISPLAY + oled.setCursor(0,screen_vertical_position - 1); // The labels are shown slightly above the values. + oled.print(F("CO2 PPM:")); +#endif +#endif + +#if not defined(HAS_CO_SENSOR) && not defined(HAS_CO2_SENSOR) + Serial.println(F("Please enable at least one sensor!")); +#ifdef HAS_DISPLAY + oled.setCursor(0,3); + oled.print(F("NO SENSORS ENABLED")); +#endif + while(1); +#endif + + wdt_enable(WDTO_8S); // Starts the watchdog timer. If it is not reset once every few seconds, then the entire device will automatically restart. +} + + +#ifdef ALLOW_CONNECTING_TO_NETWORK +void send_values() +{ + send(relaymsg.setSensor(DATA_TRANSMISSION_CHILD_ID).set(transmission_state)); wait(RADIO_DELAY); +#ifdef HAS_CO_SENSOR + send(prefix_message.setSensor(CO_CHILD_ID).set( F("ppm") )); delay(RADIO_DELAY); // Carbon values are always transmitted. They are not a large privacy risk, while being very important to safety. + if( COValue != 0 ){ + send(CO_message.setSensor(CO_CHILD_ID).set(COValue),1); + } +#endif + if(transmission_state){ +#ifdef HAS_CO2_SENSOR + send(prefix_message.setSensor(CO2_CHILD_ID).set( F("ppm") )); delay(RADIO_DELAY); + if(co2_value > 350){ + send(CO2_message.setSensor(CO2_CHILD_ID).set(co2_value),1); + } +#endif + } +} +#endif + + +void loop() +{ +#ifdef ALLOW_CONNECTING_TO_NETWORK + if( send_all_values ){ +#ifdef DEBUG + Serial.println(F("RESENDING VALUES")); +#endif + send_all_values = 0; + send_values(); + } +#endif + + +#ifdef ALLOW_FAKE_DATA + boolean fake_data_pin_state = digitalRead(TOGGLE_FAKE_DATA_PIN); + if( fake_data_pin_state == 0 ){ // If the button is being pressed + desired_sending_fake_data = !desired_sending_fake_data; // Switch the setting to its opposive value. + Serial.print(F("FAKE DATA TOGGLED TO ")); Serial.println(desired_sending_fake_data); + wait(500); // Wait a while to allow the button to be released + } +#endif + + + boolean transmission_button_state = digitalRead(DATA_TRANSMISSION_BUTTON_PIN); + if( transmission_button_state == 0 ){ // If the button is being pressed + transmission_state = !transmission_state; // Switch the setting to its opposive value. + saveState(DATA_TRANSMISSION_CHILD_ID, transmission_state); // Store the new preference, so that is the device is rebooted, it will still be correct. + Serial.println(F("Data transmission button pressed ")); + wait(500); // Wait a while to allow the button to be released +#ifdef ALLOW_CONNECTING_TO_NETWORK + + send(relaymsg.setSensor(DATA_TRANSMISSION_CHILD_ID).set(transmission_state)); +#endif + } + +if ( transmission_state != previous_transmission_state ){ + previous_transmission_state = transmission_state; + saveState(DATA_TRANSMISSION_CHILD_ID, transmission_state); + Serial.print(F("Sending new data transmission state: ")); Serial.println(transmission_state); + send(relaymsg.setSensor(DATA_TRANSMISSION_CHILD_ID).set(transmission_state)); +} + + + // + // HEARTBEAT LOOP + // runs every second (or as long as you want). By counting how often this loop has run (and resetting that counter back to zero after a number of loops), it becomes possible to schedule all kinds of things without using a lot of memory. + // The maximum time that can be scheduled is 255 * the time that one loop takes. So usually 255 seconds. + // + + static unsigned long lastLoopTime = 0; // Holds the last time the main loop ran. + static int loopCounter = 0; // Count how many loops have passed (reset to 0 after at most 254 loops). + unsigned long currentMillis = millis(); + + if( currentMillis - lastLoopTime > LOOPDURATION ){ + lastLoopTime = currentMillis; + loopCounter++; +#ifdef DEBUG + Serial.print("loopcounter:"); Serial.println(loopCounter); +#endif + if(loopCounter >= MEASUREMENT_INTERVAL){ + Serial.println(); Serial.println(F("__starting__")); + loopCounter = 0; + } + + wdt_reset(); // Reset the watchdog timer + + /* + // Used during development + if(measurements_counter == 10 && desired_sending_fake_data == false){ + Serial.println(); Serial.println(F("INITIATING FAKENESS----------------------------------------")); + desired_sending_fake_data = true; + } + */ + +#ifdef HAS_DISPLAY + // Show second counter + oled.set1X(); + oled.setCursor(100,0); + oled.print(MEASUREMENT_INTERVAL - loopCounter); + oled.clearToEOL(); + + screen_vertical_position = 3; // If there is one sensor attached, then new data should be shown at line 3 of the screen. If there are two, then data is shown on line 3 and line 6. + +#endif + + + // schedule + if( loopCounter == 1 ){ + + // CARBON MONIXODE +#ifdef HAS_CO_SENSOR + COValue = readCOValue(); // Get carbon monoxide level from sensor module +#ifdef HAS_DISPLAY + // Show CO level on the screen + //oled.set1X(); + oled.setCursor(HORIZONTAL_START_POSITION,screen_vertical_position); + + if (COValue == -1){ // -1 value means sensor probably not connected + oled.print(F("CHECK WIRE")); + oled.clearToEOL(); + break; + } + else if (COValue == -2){ + oled.print(F("DATA ERROR")); // -2 value means we got data form the sensor module was was not a CO2 level. For example, a response to some other command. + oled.clearToEOL(); + } + else{ + // Display CO value. + oled.print(COValue); + oled.clearToEOL(); + + // Show quality opinion the screen. + oled.setCursor(60,screen_vertical_position); + if (COValue > 0 && COValue < 450){ oled.print(F("GREAT"));} + else if (COValue < 700){ oled.print(F("GOOD"));oled.clearToEOL();} + else if (COValue < 1000){ oled.print(F("OK")); oled.clearToEOL();} + else if (COValue < 2000){ oled.print(F("POOR"));oled.clearToEOL();} + else if (COValue < 4500){ oled.print(F("BAD")); oled.clearToEOL();} + else { + oled.print(F("Wait..")); + oled.clearToEOL(); + } + } + screen_vertical_position = screen_vertical_position + 3; // If a CO sensor is attached, it's value will be displayed on top. The Co2 value will then be shown 3 lines below it. +#endif +#endif + + // CARBON DIOXIDE +#ifdef HAS_CO2_SENSOR + //int new_co2_value = readco2_value(); // Get carbon dioxide level from sensor module + co2_value = read_co2_value(); // Get carbon dioxide level from sensor module + Serial.print(F("fresh co2 value: ")); Serial.println(co2_value); +#ifdef DEBUG + if( co2_value == -1 || co2_value == -2 ){ + Serial.println(F("SENSOR ERROR -> GENERATING RANDOM DATA")); // Used during development to test even though no actual sensor is attached. + co2_value = random(500,600); + } +#endif + +#ifdef ALLOW_FAKE_DATA + if( co2_value > 350 && sending_fake_data == false){ // While fake data is not being created, we analyse the real data to look for the range it displays. + measurements_fakeness_range_counter++; + Serial.print(F("measurements_fakeness_range_counter = ")); Serial.println(measurements_fakeness_range_counter); + if( measurements_fakeness_range_counter >= AMOUNT_OF_MEASUREMENTS_TO_AVERAGE){ + Serial.print(F("Restarting min-max analysis around co2 value of ")); Serial.println(co2_value); + measurements_fakeness_range_counter = 0; + if( co2_maximum_found - co2_minimum_found != 0 && co2_maximum_found - co2_minimum_found < 30 ){ + co2_fakeness_range = co2_maximum_found - co2_minimum_found; // What is the difference between the highest and lowest co2 value we spotted recently. + last_co2_minimum_found = co2_minimum_found; + last_co2_maximum_found = co2_maximum_found; + } + co2_minimum_found = co2_value; + co2_maximum_found = co2_value; + } + + if(co2_value < co2_minimum_found){ + co2_minimum_found = co2_value; + Serial.println(F("new co2 value was smaller than minimum found.")); + } + else if(co2_value > co2_maximum_found){ + co2_maximum_found = co2_value; + Serial.println(F("new co2 value was bigger than maximum found.")); + } + else{ + Serial.println(F("new co2 values was not bigger or smaller than recent measurements.")); + } + Serial.print(F("potential min-max range: ")); Serial.println(co2_maximum_found - co2_minimum_found); + Serial.print(F("actual min-max range: ")); Serial.println(co2_fakeness_range); + } + + + if( desired_sending_fake_data == true ){ + Serial.println(F("User wants to generate fake data.")); + if( sending_fake_data == false ){ // On the first run of fake data, we try and figure out what the range to fake in is. + Serial.println(F("initiating fake data")); + sending_fake_data = true; + if(co2_fakeness_range == 0){ + co2_fakeness_range = 1; // The minimum to actually make some fake jitter + } + co2_fake_data_movement_factor = -0.5; + fake_co2_value = co2_value; // The initial fake value; + } + } + else{ + // The user no longer wants to generate fake data. + if( sending_fake_data == true ){ // If we were generating fake data, we should slowly move the fake value towards the real value. Only then can we stop generating the fake value. + last_co2_minimum_found = co2_value - co2_fakeness_range; + last_co2_maximum_found = co2_value + co2_fakeness_range; + + if(co2_value > fake_co2_value){ + co2_fake_data_movement_factor = -0.1; // By modifiying this factor to favour one direction, the fake data will move towards the real co2 value. + Serial.println(F("stopping faking, movement factor set to 0,9: ")); + } + else if(co2_value < fake_co2_value){ + Serial.println(F("stopping faking, movement factor set to -0,9: ")); + co2_fake_data_movement_factor = -0.9; + } + if( abs(fake_co2_value - co2_value) < co2_fakeness_range ){ // When the fake value is very close to the real value, the real value can take over again. + Serial.println(F("Faking has ended")); + sending_fake_data = false; + } + } + } + + if( sending_fake_data == true ){ + // We are now sending fake data. + fake_co2_jitter = (float)random( (co2_fakeness_range) * 10000) / 10000; + Serial.print(F("fake CO2 addition: ")); Serial.println(fake_co2_jitter); + + float flipped_coin = random(2); // This will be 0 or 1. + Serial.print(F("flipped coin: ")); Serial.println(flipped_coin); + Serial.print(F("co2_fake_data_movement_factor: ")); Serial.println(co2_fake_data_movement_factor); + float factor = flipped_coin + co2_fake_data_movement_factor; + Serial.print(F("actual movement factor: ")); Serial.println(factor); + fake_co2_jitter = fake_co2_jitter * factor; // The addition is now multiplied by -0,5 or +0,5. + Serial.print(F("fake CO2 jitter after movement factor: ")); Serial.println(fake_co2_jitter); + + Serial.print(F("last_min: ")); Serial.println(last_co2_minimum_found); + Serial.print(F("last_max: ")); Serial.println(last_co2_maximum_found); + if( fake_co2_jitter > 0 && fake_co2_value + fake_co2_jitter > last_co2_maximum_found){ // If the new addition (which can be negative) moves the fake data value ourside of the allowed range, then adjust it. + fake_co2_jitter = -fake_co2_jitter; + Serial.println("A"); + } + else if( fake_co2_jitter < 0 && fake_co2_value + fake_co2_jitter < last_co2_minimum_found){ // If the new addition (which can be negative) moves the fake data value ourside of the allowed range, then adjust it. + fake_co2_jitter = -fake_co2_jitter; + Serial.println("B"); + } + else{ + Serial.println("CC"); + } + Serial.print(F("fake CO2 addition after bounds check: ")); Serial.println(fake_co2_jitter); + + fake_co2_value = fake_co2_value + fake_co2_jitter; + co2_value = int(fake_co2_value); + /* + // Create meandering data effect + if( flipped_coin == 0 && fake_co2_value + fake_co2_jitter > average_co2_value + co2_fakeness_range ){ // Check if there is head room to make the fake data value change in the random direction. + co2_value = fake_co2_value - fake_co2_jitter; // There is no room to go up, the fake value should go down. + } + else if( flipped_coin == 1 && fake_co2_value - fake_co2_jitter < average_co2_value - co2_fakeness_range ){ + co2_value = fake_co2_value + fake_co2_jitter; // There is no room to go down, the fake value should go up. + } + else{ + if( flipped_coin ){ fake_co2_jitter = -fake_co2_jitter; } // If we have not reached the maximum high or low fake data value, then randomly add or subtract the addition. + fake_co2_value = fake_co2_value + fake_co2_jitter; + } + */ + Serial.print(F(" {}{}{} Fake CO2 value: ")); Serial.println(co2_value); + + } +#endif // End of allow fake data + + + +#ifdef HAS_DISPLAY + // Show CO2 level on the screen + oled.set2X(); + oled.setCursor(HORIZONTAL_START_POSITION,screen_vertical_position); + + if (co2_value == -1){ // -1 value means sensor probably not connected + oled.print(F("CHECK WIRE")); + oled.clearToEOL(); + } + else if (co2_value == -2){ + oled.print(F("DATA ERROR")); // -2 value means we got data form the sensor module was was not a CO2 level. For example, a response to some other command. + oled.clearToEOL(); + } + else if( co2_value > 350 && co2_value < 5001){ + // Display CO2 value. + oled.print(co2_value); + oled.clearToEOL(); + + // Show quality opinion the screen. + oled.setCursor(60,screen_vertical_position); + + if (co2_value < 500){ oled.print(F("GREAT"));} + else if (co2_value < 700){ oled.print(F("GOOD"));} + else if (co2_value < 1000){ oled.print(F("OK"));} + else if (co2_value < 2000){ oled.print(F("POOR"));} + else if (co2_value < 5001){ oled.print(F("BAD"));} + else { + oled.print(F("Wait..")); + } + oled.clearToEOL(); + } +#ifdef DEBUG + else{ + Serial.println(F("CO2 value was out of bounds")); + } +#endif + + +#endif // End of has_display +#endif // End of hasCO2senor + } + + + else if( loopCounter == 2 ){ // Send the data + +#ifdef HAS_CO_SENSOR + if( COValue > 0 && COValue < 4500 ){ // Avoid sending erroneous values +#ifdef ALLOW_CONNECTING_TO_NETWORK + connected_to_network = false; + Serial.println(F("Sending CO to controller")); + send(CO_message.setSensor(CO_CHILD_ID).set(COValue),1); // We ask the controller to acknowledge that it has received the data. +#endif // end of allow connecting to network + } +#endif // end of has CO sensor + + +#ifdef HAS_CO2_SENSOR + if( co2_value > 300 && co2_value < 4500 ){ // Avoid sending erroneous values +#ifdef ALLOW_CONNECTING_TO_NETWORK + if( transmission_state ){ + connected_to_network = false; // If the network connection is ok, then this will be immediately set back to true. + Serial.print(F("Sending CO2 value: ")); Serial.println(co2_value); + connected_to_network = false; // If the network connection is ok, then this will be immediately set back to true: + send(CO2_message.setSensor(CO2_CHILD_ID).set(co2_value),1); // We send the data, and ask the controller to acknowledge that it has received the data. + wait(RADIO_DELAY); + + // Also send the human readable opinion + if (co2_value < 450){ send(info_message.setSensor(CO2_OPINION_CHILD_ID).set( F("Great") )); } + else if (co2_value < 700){ send(info_message.setSensor(CO2_OPINION_CHILD_ID).set( F("Good") )); } + else if (co2_value < 1000){ send(info_message.setSensor(CO2_OPINION_CHILD_ID).set( F("OK") )); } + else if (co2_value < 2000){ send(info_message.setSensor(CO2_OPINION_CHILD_ID).set( F("Poor") )); } + else if (co2_value < 5000){ send(info_message.setSensor(CO2_OPINION_CHILD_ID).set( F("Bad") )); } + + } + else{ + Serial.println(F("Not allowed to send the CO2 data")); + } +#endif // end of allow connecting to network + } +#endif // end of has CO2 sensor + } + + +#ifdef HAS_DISPLAY + else if( loopCounter == 3 ){ // Show the various states on the display + oled.set1X(); + oled.setCursor(W_POSITION,0); + if( connected_to_network ){ // Add W icon to the top right corner of the screen, indicating a wireless connection. + oled.print(F("W")); + }else { + oled.print(F(".")); // Remove W icon + } + } + + + // The following two are updated every second. + oled.set1X(); + + #ifdef ALLOW_FAKE_DATA + oled.setCursor(F_POSITION,0); + if( desired_sending_fake_data && sending_fake_data){ // We are sending fake data + oled.print(F("F")); + } + else if(desired_sending_fake_data != sending_fake_data){ // In the transition between real and fake data + oled.print(F("f")); + } + else{ // No fake data is being generated + oled.print(F(".")); + } +#endif + +#ifdef ALLOW_CONNECTING_TO_NETWORK + oled.setCursor(T_POSITION,0); + if( transmission_state ){ + oled.print(F("T")); + } + else{ + oled.print(F(".")); + } +#endif + +#endif // end of has display + } +} + + + +#ifdef HAS_CO_SENSOR +int readCOValue() +{ + + while (co_sensor.read()!=-1) {}; // Clear serial buffer + + char response[9]; // Holds response from sensor + byte requestReading[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; + + Serial.println(F("Requesting data from CO sensor module")); + co_sensor.write(requestReading, 9); // Request PPM CO + co_sensor.readBytes(response, 9); + + // Do some checks on the response: + if (byte(response[0]) != 0xFF){ + Serial.println(F("! Sensor not connected?")); + while (co_sensor.read()!=-1) {}; // Empty the serial buffer, for a fresh start, just in case. + return -1; + } + if (byte(response[1]) != 0x86){ + Serial.println(F("! Sensor did not send CO data")); + return -2; + } + // Did the data get damaged along the way? + char check = getCheckSum(response); + if (response[8] != check) { + Serial.println(F("ERROR: checksum did not match")); + return -2; + } + + int high = response[2]; + int low = response[3]; + return high * 256 + low; +} +#endif + + +#ifdef HAS_CO2_SENSOR +int read_co2_value() +{ + + while (co2_sensor.read()!=-1) {}; // Clear serial buffer + + char response[9]; // Holds response from sensor + byte requestReading[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; + + Serial.println(F("Requesting data from CO2 sensor module")); + co2_sensor.write(requestReading, 9); // Request data from sensor module. + co2_sensor.readBytes(response, 9); + + // Do some checks on the response: + if (byte(response[0]) != 0xFF){ + Serial.println(F("! Is the CO2 sensor connected?")); + return -1; + } + if (byte(response[1]) != 0x86){ + Serial.println(F("! Non-sensor data")); +#ifdef DEBUG + Serial.println(response[1]); +#endif + return -2; + } + // Did the data get damaged along the way? + char check = getCheckSum(response); + if (response[8] != check) { + Serial.println(F("! Corrupted data")); + return -2; + } + + int high = response[2]; + int low = response[3]; + return high * 256 + low; +} +#endif + + +#ifdef ALLOW_CONNECTING_TO_NETWORK +void receive(const MyMessage &message) +{ + Serial.println(F(">> receiving message")); + connected_to_network = true; + + if( message.isAck() ){ + Serial.println(F("-Got echo")); + return; + } + + if (message.type == V_STATUS && message.sensor == DATA_TRANSMISSION_CHILD_ID ){ + transmission_state = message.getBool(); //?RELAY_ON:RELAY_OFF; + Serial.print(F("-New desired transmission state: ")); Serial.println(transmission_state); + } +} +#endif + +// A helper function to check the integrity of a received sensor message. +byte getCheckSum(byte* packet) +{ + byte i; + unsigned char checksum = 0; + for (i = 1; i < 8; i++) { + checksum += packet[i]; + } + checksum = 0xff - checksum; + checksum += 1; + return checksum; +} + + + +/* + * + * This code makes use of the MySensors library: + * + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013b-2015 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + ******************************* + * + */ diff --git a/code/Dust_sensor/Dust_sensor.arduino.avr.nano.elf b/code/Dust_sensor/Dust_sensor.arduino.avr.nano.elf new file mode 100644 index 0000000000000000000000000000000000000000..705c2284629fbafad05cb48647f383491a8012a7 GIT binary patch literal 159236 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 literal 0 HcmV?d00001 diff --git a/code/Dust_sensor/Dust_sensor.arduino.avr.nano.hex b/code/Dust_sensor/Dust_sensor.arduino.avr.nano.hex new file mode 100644 index 0000000..65c66ab --- /dev/null +++ b/code/Dust_sensor/Dust_sensor.arduino.avr.nano.hex @@ -0,0 +1,1404 @@ +:100000000C94E0030C9475200C944E200C949C20CE +:100010000C949C200C949C200C9414210C940804A7 +:100020000C9408040C9408040C9408040C94080420 +:100030000C9408040C9408040C9408040C94080410 +:100040000C9404200C9408040C94D21F0C94AC1F44 +:100050000C9408040C9408040C9408040C940804F0 +:100060000C9408040C940804AED580A83FD300403B +:100070008D142002A1C8DA12817FD9F1DB40A4A639 +:10008000AF200054002D4E6577206D61795F736558 +:100090006E645F646174612073746174653A2000FA +:1000A0003E3E2052656365697665642061636B6ED0 +:1000B0006F776C656467656D656E7400637C777BD4 +:1000C000F26B6FC53001672BFED7AB76CA82C97D54 +:1000D000FA5947F0ADD4A2AF9CA472C0B7FD9326E5 +:1000E000363FF7CC34A5E5F171D8311504C723C3E9 +:1000F0001896059A071280E2EB27B27509832C1A2D +:100100001B6E5AA0523BD6B329E32F8453D100ED86 +:1001100020FCB15B6ACBBE394A4C58CFD0EFAAFB6A +:10012000434D338545F9027F503C9FA851A3408F32 +:10013000929D38F5BCB6DA2110FFF3D2CD0C13EC4A +:100140005F974417C4A77E3D645D197360814FDCDF +:10015000222A908846EEB814DE5E0BDBE0323A0AC3 +:100160004906245CC2D3AC629195E479E7C8376D47 +:100170008DD54EA96C56F4EA657AAE08BA78252E6C +:100180001CA6B4C6E8DD741F4BBD8B8A703EB566F5 +:100190004803F60E613557B986C11D9EE1F89811E6 +:1001A00069D98E949B1E87E9CE5528DF8CA1890DD5 +:1001B000BFE6426841992D0FB054BB1631302E3046 +:1001C0003A00322E353A002000540021204E4F20B4 +:1001D000434F4E4E454354494F4E005700436F6EB8 +:1001E0006E656374656420746F2067617465776100 +:1001F00079210046494E45204455535400000005DE +:10020000072060000000000000005F000000070001 +:100210000700147F147F14242A7F2A1223130864F2 +:100220006236495620500008070300001C22410096 +:100230000041221C002A1C7F1C2A08083E080800D6 +:100240008070300008080808080000606000201076 +:100250000804023E5149453E00427F400072494930 +:1002600049462141494D331814127F102745454511 +:10027000393C4A4949314121110907364949493632 +:10028000464949291E0000140000004034000000C7 +:1002900008142241141414141400412214080201F9 +:1002A0005909063E415D594E7C1211127C7F494925 +:1002B00049363E414141227F4141413E7F494949C2 +:1002C000417F090909013E414151737F0808087FB8 +:1002D00000417F41002040413F017F081422417FBF +:1002E000404040407F021C027F7F0408107F3E4157 +:1002F00041413E7F090909063E4151215E7F0919AE +:100300002946264949493203017F01033F404040C5 +:100310003F1F2040201F3F4038403F6314081463B4 +:1003200003047804036159494D43007F4141410270 +:1003300004081020004141417F04020102044040B2 +:10034000404040000307080020545478407F284470 +:1003500044383844444428384444287F385454545A +:100360001800087E090218A4A49C787F0804047869 +:1003700000447D40002040403D007F1028440000A4 +:10038000417F40007C047804787C08040478384479 +:10039000444438FC1824241818242418FC7C08042D +:1003A0000408485454542404043F44243C4040204E +:1003B0007C1C2040201C3C4030403C4428102844F9 +:1003C0004C9090907C4464544C44000836410000AA +:1003D00000770000004136080002010204023C26BA +:1003E00023263C68001980400048656C6C6F2C2007 +:1003F0004920616D206120647573742073656E738C +:100400006F720064617461207472616E736D6973E0 +:1004100073696F6E00322E35206D6963726F6D6582 +:1004200074657273003130206D6963726F6D65742D +:10043000657273202620736D616C6C657200312EBD +:10044000310046696E6520647573742073656E7340 +:100450006F720075672F6D330075672F6D33004124 +:10046000766572616765207031303A2000417665AB +:10047000726167652070322E353A200053656E64D4 +:10048000696E672066616B6520646174612C2073FE +:100490006F2061766572616765206973206E6F7485 +:1004A000206368616E67696E672E0020004E6F20C2 +:1004B000636F6E6E656374696F6E20746F20636F17 +:1004C0006E74726F6C6C657221005700436F6E6EB4 +:1004D000656374696F6E20746F20636F6E74726FE2 +:1004E0006C6C6572206973206F6B2E002D3E20733B +:1004F000656E64696E672031302E303A20003C3CD6 +:100500002073656E64696E672046414B452031302B +:100510002E303A20007031305F6164646974696F15 +:100520006E203D20003C3C2073656E64696E672040 +:10053000322E353A20003C3C2073656E64696E674C +:100540002046414B4520322E353A2000322E3520B0 +:100550004164646974696F6E3A200057696C6C205D +:1005600073656E64207265616C20646174612061E2 +:100570006761696E2E0053656E736F7220676F69D5 +:100580006E6720746F20736C6565702E0042414465 +:10059000202000504F4F5220004F4B20202000477A +:1005A0004F4F44200047524541540046414B45447B +:1005B00000424144202000504F4F5220004F4B201A +:1005C000202000474F4F44200047524541540046E9 +:1005D000414B454400202020002020200057616925 +:1005E00074696E6720666F72206461746100417384 +:1005F0006B696E6720666F7220667265736820642F +:1006000061746120616761696E0041736B696E6737 +:1006100020666F7220667265736820646174610081 +:1006200053656E736F722077616B696E67207570AA +:10063000005F5F7374617274696E675F5F002000B2 +:100640004E4554574F524B20544F47474C4544203A +:10065000544F200052096AD53036A538BF40A39EBA +:1006600081F3D7FB7CE339829B2FFF87348E434491 +:10067000C4DEE9CB547B9432A6C2233DEE4C950BED +:1006800042FAC34E082EA16628D924B2765BA2494D +:100690006D8BD12572F8F66486689816D4A45CCC6C +:1006A0005D65B6926C704850FDEDB9DA5E1546573F +:1006B000A78D9D8490D8AB008CBCD30AF7E4580575 +:1006C000B8B34506D02C1E8FCA3F0F02C1AFBD0381 +:1006D00001138A6B3A9111414F67DCEA97F2CFCE52 +:1006E000F0B4E67396AC7422E7AD3585E2F937E8ED +:1006F0001C75DF6E47F11A711D29C5896FB7620E2F +:10070000AA18BE1BFC563E4BC6D279209ADBC0FE0F +:1007100078CD5AF41FDDA8338807C731B1121059BC +:100720002780EC5F60517FA919B54A0D2DE57A9FAE +:1007300093C99CEFA0E03B4DAE2AF5B0C8EBBB3CA3 +:1007400083539961172B047EBA77D626E169146327 +:1007500055210C7D00030C0F30333C3FC0C3CCCF80 +:10076000F0F3FCFF00000000240027002A00000036 +:100770000000250028002B000000000023002600B8 +:100780002900040404040404040402020202020214 +:100790000303030303030102040810204080010245 +:1007A00004081020010204081020000000080002C4 +:1007B00001000003040700000000000000005224B4 +:1007C00011241FBECFEFD8E0DEBFCDBF11E0A0E007 +:1007D000B1E0EAEFF6E502C005900D92A63AB10746 +:1007E000D9F724E0A6EAB1E001C01D92AF3CB20700 +:1007F000E1F713E0C0EED3E004C02197FE010E94B0 +:10080000442BCF3DD107C9F70E9427250C947B2BA1 +:100810000C940000E3E5F2E0A089B18982E08C93BA +:10082000A485B5851C92A685B78580E18C93108E32 +:10083000A489B58986E08C93A289B3898C91806163 +:100840008C93A289B3898C9188608C93A289B38997 +:100850008C9180688C930288F389E02D80818F7D54 +:1008600080830895DB01FC01242F3C913083119695 +:100870003C911197318312963C91129732831396D3 +:100880003C9113973383245014963496243068F7A0 +:100890002CEF240F2695269530E02F5F3F4F220F37 +:1008A000331F220F331F4370DB01A20FB31FFC0164 +:1008B000E20FF31F415018F08D918193FBCF089503 +:1008C0004F925F926F927F928F929F92AF92BF9260 +:1008D000CF92DF92EF92FF920F931F93CF93DF930C +:1008E00088248394912CB12CA12CD12CC12CF12CD7 +:1008F000E12CD0E0C0E06AE0462E512C612C772438 +:1009000073948091550390915603DC01ED91FC9115 +:100910000084F185E02D0995181619060CF0A3C086 +:100920008091550390915603DC01ED91FC91008478 +:10093000F185E02D099592012C1B3D0B8217930741 +:100940000CF491C08091550390915603DC01ED9118 +:10095000FC910284F385E02D09959C013327CA3070 +:10096000D10588F4FE01E954FB4F0C94442B020599 +:100970000D05C10414051B051F05180518052405E0 +:100980002F05890169012196CA30D10509F0B9CF37 +:10099000B1E0AB16B10409F0B4CFB701FF0C880B7E +:1009A000990B0E945F2820E030E040E251E40E9471 +:1009B0007E2A609347027093480280934902909385 +:1009C0004A02B601DD0C880B990B0E945F2820E0DB +:1009D00030E040E251E40E947E2A60934B02709323 +:1009E0004C0280934D0290934E02912C812CB12C9D +:1009F000A12C10E000E0D12CC12CF12CE12CD0E096 +:100A0000C0E07FCFC1E0D0E02A3A310511F4D0E058 +:100A1000C0E0D195C195D109B6CF203C310509F48C +:100A2000B2CFCFEFDFEFAFCF922F8827C80ED91EFE +:100A3000020F131FA8CF020F131F7901A4CF922F0B +:100A40008827E80EF91EF4CFC801B3010E94302BAD +:100A50002817390731F7AA24A394B12C94CF2B3A45 +:100A60003105F9F690CFC401DF91CF911F910F911D +:100A7000FF90EF90DF90CF90BF90AF909F908F90BE +:100A80007F906F905F904F900895DC01ED91FC9105 +:100A90000190F081E02D0994EF92FF920F931F9344 +:100AA000CF93DF938C017B01D0E0C0E0F701EC0F26 +:100AB000FD1F6491662361F0D801ED91FC910190D6 +:100AC000F081E02DC8010995892B11F02196EECF18 +:100AD000CE01DF91CF911F910F91FF90EF9008957C +:100AE000AF92BF92CF92DF92EF92FF920F931F933C +:100AF000CF93DF936C017B018B01040F151FEB017A +:100B00005E01AE18BF08C017D10759F06991D60130 +:100B1000ED91FC910190F081E02DC6010995892BA2 +:100B200079F7C501DF91CF911F910F91FF90EF9061 +:100B3000DF90CF90BF90AF900895FC01538D448D0E +:100B4000252F30E0842F90E0821B930B541710F078 +:100B5000CF96089501970895FC01918D828D981785 +:100B600061F0A28DAE0FBF2FB11D5D968C91928D5D +:100B70009F5F9F73928F90E008958FEF9FEF08958E +:100B8000FC01918D828D981731F0828DE80FF11D57 +:100B9000858D90E008958FEF9FEF0895FC01918D72 +:100BA000228D892F90E0805C9F4F821B91098F736B +:100BB0009927089583E592E00E94CE0521E0892BD4 +:100BC00009F420E0822F0895FC01A48DA80FB92F0D +:100BD000B11DA35ABF4F2C91848D90E001968F7365 +:100BE0009927848FA689B7892C93A089B1898C9184 +:100BF000837080648C93938D848D981306C00288D3 +:100C0000F389E02D80818F7D80830895EF92FF929C +:100C10000F931F93CF93DF93EC0181E0888F9B8D1F +:100C20008C8D98131AC0E889F989808185FF15C0D9 +:100C30009FB7F894EE89FF896083E889F9898081FC +:100C40008370806480839FBF81E090E0DF91CF91CB +:100C50001F910F91FF90EF900895F62E0B8D10E0ED +:100C60000F5F1F4F0F731127E02E8C8D8E110CC05C +:100C70000FB607FCFACFE889F989808185FFF5CFA7 +:100C8000CE010E94E405F1CFEB8DEC0FFD2FF11D9D +:100C9000E35AFF4FF0829FB7F8940B8FEA89FB89E4 +:100CA00080818062CFCFCF93DF93EC01888D882342 +:100CB000B9F0AA89BB89E889F9898C9185FD03C0BF +:100CC000808186FD0DC00FB607FCF7CF8C9185FFA4 +:100CD000F2CF808185FFEDCFCE010E94E405E9CF00 +:100CE000DF91CF91089580E090E0892B29F00E9458 +:100CF000DA0581110C9400000895833081F028F406 +:100D0000813099F08230A9F008958730A9F08830B9 +:100D1000C9F08430B1F4809180008F7D03C0809150 +:100D200080008F7780938000089584B58F7784BD8D +:100D3000089584B58F7DFBCF8091B0008F7780932D +:100D4000B00008958091B0008F7DF9CFCF93DF93ED +:100D5000E0EBF7E08491ECE9F7E0D491E8E8F7E024 +:100D6000C491CC23A1F081110E947D06EC2FF0E00C +:100D7000EE0FFF1FE858F84FA591B491EC91ED23C9 +:100D800081E090E009F480E0DF91CF91089580E068 +:100D900090E0FACF1F93CF93DF93282F30E0F90133 +:100DA000E655F84F8491F901EA56F84FD491F901CC +:100DB000EE57F84FC491CC23A9F0162F81110E9451 +:100DC0007D06EC2FF0E0EE0FFF1FE259F84FA591E2 +:100DD000B4918FB7F894EC91111108C0D095DE232F +:100DE000DC938FBFDF91CF911F910895DE2BF8CF59 +:100DF000CF93DF9390E0FC01EA56F84F24918E5791 +:100E0000984FFC0184918823D1F090E0880F991FBE +:100E1000FC01EC59F84FA591B491FC01E259F84F4F +:100E2000C591D49161110EC09FB7F8948C91E22FB7 +:100E3000E0958E238C932881E223E8839FBFDF9186 +:100E4000CF9108958FB7F894EC91E22BEC938FBF7C +:100E5000F6CF3FB7F8948091430290914402A0915D +:100E60004502B091460226B5A89B05C02F3F19F058 +:100E70000196A11DB11D3FBFBA2FA92F982F88271A +:100E8000BC01CD01620F711D811D911D42E0660FF5 +:100E9000771F881F991F4A95D1F708958F929F92C7 +:100EA000AF92BF92CF92DF92EF92FF926B017C01E3 +:100EB0000E9429074B015C01C114D104E104F10433 +:100EC000B9F00E942907681979098A099B09683EC7 +:100ED00073408105910580F321E0C21AD108E10831 +:100EE000F10888EE880E83E0981EA11CB11CE4CFA7 +:100EF000FF90EF90DF90CF90BF90AF909F908F903A +:100F000008952FB7F89460913F027091400280914C +:100F10004102909142022FBF08950895CF93DF932D +:100F2000EC018D85882329F081508D87DF91CF9149 +:100F300008959C818E819817C8F788896827E88171 +:100F4000F9810084F185E02D42E0CE0109958C8184 +:100F50008F5F8C83EBCF20913C0230913D022817AC +:100F6000390771F490913B0280913A02981741F051 +:100F7000E0913B02F0E0E650FE4F808190E0089562 +:100F80008FEF9FEF08950895EF92FF920F931F93B5 +:100F9000CF93DF93DC015C96ED90FC905D97E114BC +:100FA000F10479F481E090E013969C938E9312976C +:100FB00090E080E0DF91CF911F910F91FF90EF9033 +:100FC00008955196ED91FC91529750968C915097BF +:100FD000982F90950FB75E962C915E97122F1270F6 +:100FE00021FD6095F8942081112319F1282B20838D +:100FF000E7012197F1F728E0462F50E0308160FFAC +:101000001AC0382B3083E7012197F1F7BA017595A3 +:101010006795215089F7112381F08081892380838E +:101020000FBF5C968D919C910197F1F781E090E064 +:10103000C1CF2923DCCF3923E5CF9081892BEFCF96 +:1010400020913C0230913D022817390771F48091BC +:101050003A0220913B0290E0805C9F4F821B9109F5 +:1010600060E470E00E94302B089590E080E00895E5 +:1010700020913C0230913D0228173907B9F4909134 +:101080003B0280913A02981789F0E0913B02F0E030 +:10109000E650FE4F808120913B0230E02F5F3F4FB2 +:1010A0002F73332720933B0290E008958FEF9FEF3B +:1010B0000895FC016093BC008091BC0087FFFCCFC9 +:1010C0009091B900987F90830895DF92EF92FF92FC +:1010D0000F931F93CF93DF93EC01D62EF42E8C89C0 +:1010E000882351F0411108C084E98093BC008091AD +:1010F000BC0084FDFCCF1C8A8E010E5E1F4F8C89C4 +:1011000081111AC0EB8864EAC8010E9459088A89D3 +:10111000883011F0803139F4EE0CE092BB0064E8C5 +:10112000C8010E94590880E0F11080E48093BB0060 +:1011300064E8C8010E945908D092BB0064E8C80165 +:101140000E94590882E0F8120BC08C898F5F8C8B4B +:10115000DF91CF911F910F91FF90EF90DF90089555 +:1011600084E98093BC008091BC0084FDFCCF1C8A84 +:10117000EFCFDC01ED91FC910084F185E02D40E0A2 +:1011800009940F931F93CF938C01FC016483C08556 +:10119000C60F6C2F6F700E94B9086C2F62956F702C +:1011A0006061C801CF911F910F910C94B908FC01A7 +:1011B0002781269526952695621738F46583238521 +:1011C000620F6770606B0C94B90808951F93CF93FA +:1011D000DF93EC01142F8E81681718F4CE010E9462 +:1011E000C108612FCE01DF91CF911F910C94D708D8 +:1011F000CF92DF92EF92FF920F931F93CF93DF93E3 +:10120000EC01F62EC42ED22E1D868F8186958695F2 +:101210008695081710F00FEF080F1D2D011780F0AD +:10122000412F6F2DCE010E94E608EF2CCE1430F036 +:101230006889CE010E948E07E394F8CF1F5FEECF3E +:101240004D2D6F2DCE01DF91CF911F910F91FF900A +:10125000EF90DF90CF900C94E6080F93DC01159689 +:101260002C9115971E96ED91FC911F9700E03097F9 +:1012700079F03396E491F0E0379683E0F595E795C1 +:101280008A95E1F751960C9151970E9F002D1124EC +:10129000EFEFE20F0E0F16964C91169741501496F1 +:1012A0006C911497CD010E94F8080F9108952F9228 +:1012B0003F924F925F926F927F928F929F92AF92E6 +:1012C000BF92CF92DF92EF92FF920F931F93CF9333 +:1012D000DF9300D000D000D0CDB7DEB7FC0126856B +:1012E00037852115310509F44AC19E838D83F901A3 +:1012F0003296649031964491E42EF12CF7E0EF0E93 +:10130000F11C53E0F594E7945A95E1F7E982F9016D +:10131000349654913196E491651748F08E2F90E001 +:10132000FC01E50FF11D6E171F060CF469C06D304E +:1013300031F5ED81FE81868181111BC081E090E055 +:1013400026960FB6F894DEBF0FBECDBFDF91CF91CA +:101350001F910F91FF90EF90DF90CF90BF90AF90D3 +:101360009F908F907F906F905F904F903F902F90C5 +:10137000089560E08D819E810E94C108DFCF6A30B0 +:1013800009F0FDC0ED81FE818681882321F060E0B7 +:10139000CF010E94C108ED81FE8181898E9DE02CE4 +:1013A000112465816E0D8485882349F09781969577 +:1013B000969596958E2D891B860F18162CF08D818B +:1013C0009E810E94D708BACFED81FE812385820FCE +:1013D000877083879E199583CF010E942D09ED8127 +:1013E000FE818485813009F0A9CF6385660F660F81 +:1013F000660F6F7362876064CF010E94B9089ECF49 +:1014000089010A5F1F4F651BED81FE81718551893E +:10141000759F502D11245C83F90154912F5F3F4F2C +:10142000F9012491352F2230310508F06AC06E9CF5 +:10143000C0016F9C900D1124689FF001699FF00D11 +:1014400011240E0F1F1F512CED81FE81F481FA83B0 +:10145000ED81FE812580F585FB83862C912CAA24C5 +:10146000A394B12C312C8981381608F086C0412C08 +:10147000ED81FE818189481608F078C08B818587CF +:10148000311002C0442041F0ED81FE8145814F5F63 +:101490006A81CF010E94E608D12CC12CC61408F045 +:1014A00058C0F801EC0DFD1D7490552061F0EA1450 +:1014B000FB0449F4E72DF0E0052C02C0F595E79513 +:1014C0000A94E2F77E2EED81FE818189823081F4DB +:1014D000442009F43AC072948FE07822E72DF0E0BE +:1014E000EC5AF84F7490672D8D819E810E948E0773 +:1014F000672D8D819E810E948E078FEFC81AD80AB2 +:10150000CDCF477028E0522E541A411101C0512C02 +:10151000F801612C30E020E0661631F04491240F90 +:10152000311D63943196F8CF600E712E711CF3015A +:101530006490E29EF001E39EF00DF29EF00D112406 +:101540008E0F9F1F080F191F7FCFF72DFF707F2E63 +:10155000C5CFD12CEC81DE1639F060E08D819E8103 +:101560000E948E07D394F6CF439482CF3394080D14 +:10157000191DFFEFAF1ABF0A76CF622D20CF90E082 +:1015800080E0DECEFC018381877088608383848164 +:101590008F71806284836783CF010895E091EB01AE +:1015A000F091EC01309721F00280F381E02D099455 +:1015B00008950F931F930E9481070091ED011091F0 +:1015C000EE012091EF013091F001601B710B820B55 +:1015D000930B1F910F9108959C018091EB019091C5 +:1015E000EC0182179307F1F09091F5019F719093B0 +:1015F000F5013093EC012093EB01E091EB01F091C8 +:10160000EC01309721F00190F081E02D09950E94C6 +:1016100081076093ED017093EE018093EF01909349 +:10162000F00108958091F501805E8093F501E5CF8A +:101630000F931F930E94D90A2091F601207720373B +:1016400079F000E117E220E030E0061717072807DD +:10165000390758F481E291E01F910F910C94EC0A44 +:1016600000E61AEE20E030E0F0CF1F910F910895D0 +:101670008091F6018F70863020F088E191E00C9423 +:10168000EC0A08958091F50184608093F5018091C2 +:10169000F60180788093F601E091E701F091E8018E +:1016A000309709F009940895CF93C091F701CF3F87 +:1016B000A1F00E9481076093F1017093F201809381 +:1016C000F3019093F40180915102C813C093510229 +:1016D00084E191E0CF910C94EC0A0E94D90A613D1B +:1016E00077408105910568F08091F501803618F406 +:1016F00080E191E0EFCF877F8093F50188E191E071 +:10170000E9CFCF91089580914F028F3F21F080E182 +:1017100091E00C94EC0A0E94D90A613D7740810562 +:10172000910550F08091F501803618F48CE091E03D +:10173000F0CF88E091E0EDCF08950E94D90A613D95 +:1017400077408105910520F48091F50181FF17C054 +:10175000809150028F3F49F08091F5018E7F8093F8 +:10176000F5018CE091E00C94EC0A8091F501803653 +:1017700018F488E191E0F7CF88E091E0F4CF089584 +:10178000CF93DF93FC01EB01DA019C01205F3F4F17 +:1017900088819C9189278083898111969C911197DA +:1017A000892781838A8112969C9112978927828347 +:1017B0008B8113969C911397892783833496249663 +:1017C0001496E217F30721F7DF91CF910895FC01FA +:1017D000DB019C01205F3F4F80819C9189278083A2 +:1017E000818111969C91119789278183828112961C +:1017F0009C91129789278283838113969C911397DA +:101800008927838334961496E217F30729F70895FE +:10181000089590E080E008950E945E2BFB01019006 +:101820000020E9F73197AF01461B570BDC01ED9122 +:10183000FC910280F381E02D09948F929F92AF92E8 +:10184000BF92EF92FF920F931F93CF93DF93CDB789 +:10185000DEB7A1970FB6F894DEBF0FBECDBF7C01F7 +:10186000FA01CB0119A2223008F42AE08E010F5DA3 +:101870001F4F822E912CB12CA12CBF01A5019401E8 +:101880000E94E029F901CA016A300CF5605DD801B7 +:101890006E938D01232B242B252B79F790E080E08C +:1018A000109721F0BD01C7010E940E0CA1960FB642 +:1018B000F894DEBF0FBECDBFDF91CF911F910F9186 +:1018C000FF90EF90BF90AF909F908F900895695CCC +:1018D000DECFCF92DF92EF92FF92CF93DF936C0136 +:1018E000990FEE08FF08F7FE23C06DE283E592E052 +:1018F0000E944505EC0144275527BA014C195D09A2 +:101900006E097F092AE083E592E00E941D0CC80F52 +:10191000D91F6AE771E083E592E00E940E0C8C0FFC +:101920009D1FDF91CF91FF90EF90DF90CF900895B2 +:101930002AE0B701A60183E592E00E941D0CEC01AC +:10194000E8CF2F923F924F925F926F927F928F9249 +:101950009F92AF92BF92CF92DF92EF92FF921F932E +:10196000CF93DF93EC016A017B01722EAB019601EC +:10197000CB01B6010E942B2B6DE771E0811126C0CF +:1019800046015701E894B7F82FEF3FEF4FE75FE7C5 +:10199000C501B4010E942B2B81110CC02FEF3FEF2A +:1019A0004FE75FE7C501B4010E94582861E871E084 +:1019B000181664F02FEF3FEF4FE75FE4C701B60161 +:1019C0000E94262B1816B4F465E871E0CE01DF9171 +:1019D000CF911F91FF90EF90DF90CF90BF90AF908D +:1019E0009F908F907F906F905F904F903F902F903F +:1019F0000C940E0C2FEF3FEF4FE75FECC701B601E1 +:101A00000E94582887FDE0CF20E030E0A901C701FF +:101A1000B6010E945828312C212C87FF09C06DE2A5 +:101A2000CE010E9445051C01F7FAF094F7F8F094F6 +:101A300010E060E070E080E09FE3711641F020E08C +:101A400030E040E251E40E947E2A1F5FF6CFA701FA +:101A500096010E94122A2B013C010E94F72A4B0199 +:101A60005C012AE0BC01A401CE010E941D0C7C0196 +:101A7000E20CF31C1123C1F1C501B4010E945D28E1 +:101A80009B01AC01C301B2010E94112A4B015C0110 +:101A90006EE2CE010E944505E80EF91E115020F1BC +:101AA00020E030E040E251E4C501B4010E94BE28CC +:101AB0002B013C010E94F72A4B01B12CA12C2AE0FA +:101AC000B501A401CE010E941D0CE80EF91EC5014E +:101AD000B4010E945D289B01AC01C301B2010E94C8 +:101AE000112A4B015C01DACFC701DF91CF911F9121 +:101AF000FF90EF90DF90CF90BF90AF909F908F902E +:101B00007F906F905F904F903F902F900895CF936C +:101B1000DF93AB01BC0122E083E592E00E94A10CBF +:101B2000EC016AE771E083E592E00E940E0C8C0FF5 +:101B30009D1FDF91CF9108950F931F93CF93DF9354 +:101B4000EC010E944C058C016AE771E0CE010E9415 +:101B50000E0C800F911FDF91CF911F910F9108956F +:101B6000E5EFF1E08081877F8F7E80831092F10125 +:101B70001092F2011092F3011092F40144E050E04F +:101B800070E060E08FE492E00C947C29EF92FF9289 +:101B90000F93CF93DF9383E08093530384E080938C +:101BA00054038FE190E00E940A26EC011B821A8206 +:101BB00088EE93E0A0E0B0E08C839D83AE83BF838A +:101BC00089E391E0998388831F8A1E8A198E188E73 +:101BD0001B8E1A8E1D8E1C8E6E8D6E7F6D7F6E8F8E +:101BE0006695617081E0682784E00E94CA0661E022 +:101BF00084E00E94F806EAE9F7E0E491E88BE6E881 +:101C0000F7E0E491F0E0EE0FFF1FE259F84F859105 +:101C100094919A8B898B60E083E00E94F8068E8D08 +:101C200081FD04C061E083E00E94CA0683E08C87E6 +:101C3000E9E9F7E0E491ED87E5E8F7E0E491F0E029 +:101C4000EE0FFF1FE858F84F859194919F878E877C +:101C50008DE991E09D8F8C8F8DEB90E09F8B8E8B2B +:101C60008BE991E0998F888F8CE291E09B8F8A8F2E +:101C7000809168008460809368009C852DE630E048 +:101C8000983050F02BE630E09E3030F02CE630E01B +:101C9000963110F030E020E03C8B2B8B292F30E088 +:101CA000983008F06DC081E001C0880F9A95EAF77E +:101CB0008D8B8C8D9D8D0197F1F78A8D9B8D892B56 +:101CC00009F1E0913C02F0913D02CE17DF07D1F01F +:101CD000309739F0A389B4899C91858980958923AF +:101CE0008C938E8D8E7F8E8F10923A0210923B02D3 +:101CF000D0933D02C0933C02EB89FC8980819D8991 +:101D0000892B8083D0935603C09355030E940A0405 +:101D100069EE73E083E592E00E949C0D10926B03E4 +:101D20008CE380936A031092B9008CE08093B80032 +:101D300010925B0310925C03E3EEF3E0E590F49005 +:101D4000E5EEF3E00491E6EEF3E0E491E0935D0369 +:101D5000E7EEF3E0E491E0935E03E8EEF3E0E49174 +:101D6000E0935F03D0E0C0E0C017B8F4FE01EE0DD1 +:101D7000FF1D649187E593E00E94B9082196F4CF96 +:101D80009E3040F42850310981E001C0880F2A9527 +:101D9000EAF78ECF2E503109F7CF109262031092DE +:101DA000610360E487E593E00E94B90800915E0357 +:101DB000069506950695015040915D03415020E03F +:101DC00060E087E593E00E94F808EDEFF1E0F09322 +:101DD0006603E09365038491EEEFF1E0E491F82F60 +:101DE000319709F065C0109260036FEA87E593E0D0 +:101DF0000E94B9081092630340E060E087E593E039 +:101E00000E94E60863EF71E087E593E00E944C05CD +:101E10008091F50182FF50C06DED71E083E592E0A5 +:101E20000E949C0D40E060E587E593E00E94E60893 +:101E30006BED71E087E593E00E944C0540E066E4BD +:101E400087E593E00E94E60880911C0169EC71E04F +:101E5000811102C067EC71E087E593E00E944C05B8 +:101E600042E060E087E593E00E94E60862EC71E002 +:101E700087E593E00E944C0545E060E087E593E04C +:101E80000E94E6086CEB71E087E593E00E944C0548 +:101E900088E199E20FB6F894A895809360000FBE90 +:101EA00090936000DF91CF910F91FF90EF90089594 +:101EB00081E08093600399CF6BEC71E083E592E061 +:101EC0000E949C0DBBCFEF92FF920F931F93CF9375 +:101ED000DF93EC017B0180E06115710531F0CB01EE +:101EE0000E9418288931910518F5082F10E09B8170 +:101EF0009770980143E0220F331F4A95E1F7922B28 +:101F00009B839C819F719C83882331F0A801B7013A +:101F1000CE0107960E942128FE01E00FF11F1782D3 +:101F2000CE01DF91CF911F910F91FF90EF90089517 +:101F300089E1DBCF91E59CBD91E09DBD2998E3E26D +:101F4000F0E03197F1F78EBD00000DB407FEFDCF34 +:101F50008EB5FB019FEF4150C8F0222361F09EBD7A +:101F600000000DB407FEFDCF8EB56115710599F324 +:101F700080833196F0CFDF01119680818EBD000005 +:101F80000DB407FEFDCF8EB5FD01E5CF299AE3E242 +:101F9000F0E03197F1F70895CF93DF931F92CDB71B +:101FA000DEB7698320E041E0BE016F5F7F4F0E9492 +:101FB0009A0F0F90DF91CF9108958091F601982F9D +:101FC0009077903759F0982F92959F709F5F9770F8 +:101FD0009295907F8F78892B8093F6018091F501FF +:101FE0008B7F8F7E8093F5012A986CE080E20C94C1 +:101FF000CC0F6FE080E20E94CC0F609125016F3F13 +:1020000019F08AE20E94CC0F2A9A0895CF93C82F24 +:1020100080934F028F3F51F08093250163E082E26D +:102020000E94CC0F61E081E20E94CC0F0E94F90F68 +:102030006C2F90E080E00E949C2981E0CF91089570 +:1020400021E041E070E060E00C949A0F20E040E075 +:1020500070E060E00C949A0F0F931F93CF93DF937F +:10206000EC01E0E06115710551F0FB0101900020E9 +:10207000E9F73197E61BF70BE931F10500F50E2F73 +:1020800010E08B818770980193E0220F331F9A959F +:10209000E1F7822B8B838C818F718C83EE2329F067 +:1020A000A801CE0107960E946C2BFE01E00FF11FE4 +:1020B0001782CE01DF91CF911F910F910895E9E131 +:1020C000DECFFC012481229526952770213011F462 +:1020D00087810895211104C007960E94D32708958F +:1020E00080E008952F923F924F925F926F927F927D +:1020F0008F929F92AF92BF92CF92DF92EF92FF9218 +:102100000F931F93CF93DF93CDB7DEB7A2970FB690 +:10211000F894DEBF0FBECDBFB82E80914F02FB01F9 +:102120008083138112FDEDC0169516951695195FE3 +:10213000F0915202F9A3F170FAA3412F113208F085 +:1021400040E250E087EA91E00E94632B1092A804DD +:102150001092A9041092AA041092AB041092AC043D +:102160001092AD041092AE041092AF041092B0041D +:102170001092B1041092B2041092B3041092B404FD +:102180001092B5041092B6041092B7041092A004F5 +:102190001092A1041092A2041092A3041092A4041D +:1021A0001092A5041092A6041092A70400E2902EAB +:1021B000113110F410E1912EE92CE294FFE0EF22AE +:1021C000F12CA7EACA2EA1E0DA2E8E010F5E1F4F76 +:1021D000BBE1AB2EB60188EA94E00E94E70B809148 +:1021E000AE039091AF03892B09F40BC140EB53E090 +:1021F00068EA74E0C8010E94C00B88248394482DCB +:1022000050E08091AE039091AF03481759070CF04E +:102210007AC09801DE0111966FE0362E7AE0572ED3 +:10222000E5E04E2EF801E40DF11D708084E0840D90 +:102230008F70482EF801E50DF11D808194E0950D19 +:102240009F70592EF801E30DF11D908164E0630D3C +:102250006F70362EF9016081E62FF0E0E454FF4FF5 +:102260007491E72DF0E0E454FF4F6491E82FF0E023 +:10227000E454FF4F8491E92FF0E0E454FF4F949130 +:10228000672E660C77FD6A24E62FEE0F67FDEA25C0 +:10229000282E220C87FD2A24792E770C97FD7A248C +:1022A000F62FF827F927F625FE27FC93F72FF827B6 +:1022B000F927FE27F2251196FC9311976727962799 +:1022C0002926272412962C92129786276826762490 +:1022D00013967C9213972C5F3F4F14960A171B0797 +:1022E00009F0A0CF94E0440F551F9A95E1F74055AF +:1022F0005C4FBE016F5F7F4FC8010E94C00B83948B +:102300007ECF10E215CFE989F0E0E454FF4FE4916D +:10231000E98BED89F0E0E454FF4FE491ED8BE98D1A +:10232000F0E0E454FF4FE491E98FED8DF0E0E454E8 +:10233000FF4FE491ED8F8A89EE89F0E0E454FF4F7E +:10234000E491EA8BEA8DF0E0E454FF4FE491EE8BE8 +:10235000EE8DF0E0E454FF4FE491EA8FE82FF0E0D7 +:10236000E454FF4FE491EE8F8B89EB8DF0E0E45461 +:10237000FF4FE491EB8BE82FF0E0E454FF4FE49142 +:10238000EB8F8F89EF8DF0E0E454FF4FE491EF8BFA +:10239000E82FF0E0E454FF4FE491EF8F88A1EC8D3B +:1023A000F0E0E454FF4FE491E8A3E88DF0E0E4545A +:1023B000FF4FE491EC8FEC89F0E0E454FF4FE4919F +:1023C000E88FE82FF0E0E454FF4FE491EC8B84E0D9 +:1023D000440F551F8A95E1F740555C4FB80188EAD4 +:1023E00094E00E94C00B40E168EA74E0C6010E94DC +:1023F0003204F0E1CF0ED11C81E0E81AF10809F0B7 +:10240000E9CE2A9883E092E00197F1F76EE080E24E +:102410000E94CC0F8BE891E00197F1F76B2D8AE2D7 +:102420000E94CC0F6B2D80E30E94CC0F81EE0E94A6 +:102430002610EFEFBE1619F0FAA180EAF11180EB39 +:1024400020E0492D67EA71E00E949A0F2A9AF12C48 +:10245000E12C8FEF0E942610182F807321F481E069 +:10246000E81AF108B1F72A9860E387E20E94CC0FDE +:1024700014FF03C081EE0E9426100E94F90F15FF81 +:1024800002C0E1E0E9A391E0FFEFBF1290E089A173 +:102490008170892BA2960FB6F894DEBF0FBECDBF18 +:1024A000DF91CF911F910F91FF90EF90DF90CF9030 +:1024B000BF90AF909F908F907F906F905F904F9064 +:1024C0003F902F9008950F931F93CF938C01FC01A1 +:1024D00082819091F50190FF04C08F3F51F5CFEFBD +:1024E00004C0811116C0C0915002B8018C2F0E9407 +:1024F0007210909150029C1313C09091F6018111BB +:1025000013C021E0290F2F70907F922B9093F6013A +:1025100007C08F3F21F3B8010E947210882319F37E +:10252000CF911F910F910895907F9093F60181E0D4 +:10253000F7CF80E0F5CF2091F50122FD0C946312D6 +:1025400080E00895ECE6F3E090914F0291831282CF +:10255000868365838481807E8483BA01CF010E9453 +:10256000630F0C949B1220914F02FC012183F8E031 +:102570006F9FB00111246160FC012481207F622BD8 +:1025800064832091EA0120FD0C949B1280E0089561 +:10259000CF93DF93EC018C8184FF09C060EA70E087 +:1025A00083E592E00E949C0D81E08093E1018D81A2 +:1025B000823009F041C08E818230F1F5CE010E9457 +:1025C000611091E0811101C090E090931C0182E0C4 +:1025D0008093F6028091F302877088608093F30203 +:1025E0008091F4028F7180628093F4029093F702DD +:1025F00060E080EF92E00E94B31265E870E083E54E +:1026000092E00E944C0580911C0190E00E94690CB0 +:1026100040E066E487E593E00E94E60880911C01B3 +:1026200063E870E0811102C061E870E087E593E043 +:10263000DF91CF910C944C05DF91CF910895EF92EB +:10264000FF921F93CF93DF93CCE6D3E08FE4E82E85 +:1026500082E0F82EF701808189831A821FEF1E83A2 +:102660008BE08D838C81807E83608C8362E474E058 +:10267000CE010E94630F0E949B12F7018081898323 +:102680001A821E838CE08D838C81807E83608C8394 +:102690006EE374E0CE010E94630F0E949B1245E23C +:1026A00054E068E180E00E94A21266E970E080E0F8 +:1026B00090E00E944E0745E154E068E181E00E940D +:1026C000A21266E970E080E090E00E944E0743E0CD +:1026D00054E063E082E00E94A21281E08093200136 +:1026E000DF91CF911F91FF90EF900895FF920F938C +:1026F0001F93CF93DF93CCE6D3E00FE412E0F80111 +:10270000808189831A82FF24FA94FE828FE08D8370 +:102710008C81807E83608C836CE771E0CE010E94A7 +:102720002C108B81877080618B838C818F71806C82 +:102730008C8381E08F831886CE010E949B128FE0EC +:102740000E94AA17F801808189831A82FE8281E1A2 +:102750008D838C81807E8C8369E871E0CE010E943C +:102760002C100E949B12F801808189831A82FE82BC +:1027700086E08D838C81807E83608C836181CE0135 +:102780000E94C20A0E949B1286E00E94AA17DF9153 +:10279000CF911F910F91FF900C941F132F923F9296 +:1027A0004F925F926F927F928F929F92AF92BF9261 +:1027B000CF92DF92EF92FF920F931F93CF93DF930D +:1027C000CDB7DEB7E9970FB6F894DEBF0FBECDBF29 +:1027D00026E02BAB1BE187E10E94201080FD9BC30C +:1027E0003BA931503BAB332309F495C321E041E0D1 +:1027F00070E060E080E60E949A0F082F813220F09E +:1028000082EE0E94261000E021E0402F6DE873E088 +:1028100081E60E949A0F60E487E20E94CC0F10923A +:10282000A8041092A9041092AA041092AB0410926A +:10283000AC041092AD041092AE041092AF0410924A +:10284000B0041092B1041092B2041092B30410922A +:10285000B4041092B5041092B6041092B70410920A +:10286000A0041092A1041092A2041092A30410924A +:10287000A4041092A5041092A6041092A70401319A +:1028800008F463C182E090E09AAB89ABEDE82E2EAC +:10289000E3E03E2EE9A9FAA93197FAABE9AB31960C +:1028A00009F471C140E1B101CE0181960E94320468 +:1028B0004091AE035091AF034115510509F463C136 +:1028C00074E0440F551F7A95E1F740555C4FB10114 +:1028D000CE0141960E94C00BE989F0E0EC5AF94F15 +:1028E000E491E98BED89F0E0EC5AF94FE491ED8B3E +:1028F000E98DF0E0EC5AF94FE491E98FED8DF0E0CD +:10290000EC5AF94FE491ED8F8E8DEA8DF0E0EC5AA0 +:10291000F94FE491EE8FEE89F0E0EC5AF94FE49133 +:10292000EA8FEA89F0E0EC5AF94FE491EE8BE82F58 +:10293000F0E0EC5AF94FE491EA8B8B89EB8DF0E0F3 +:10294000EC5AF94FE491EB8BE82FF0E0EC5AF94F99 +:10295000E491EB8F8F89EF8DF0E0EC5AF94FE49121 +:10296000EF8BE82FF0E0EC5AF94FE491EF8F8C8970 +:10297000E88DF0E0EC5AF94FE491EC8BEC8DF0E04F +:10298000EC5AF94FE491E88FE8A1F0E0EC5AF94FE6 +:10299000E491EC8FE82FF0E0EC5AF94FE491E8A3D2 +:1029A0000091AE031FAA1EAA8FEF800FA82FB0E0E0 +:1029B000B9AFA8AF015009F4CDC048AD59ADEEA9EB +:1029C000FFA94E1B5F0B64E0440F551F6A95E1F7AA +:1029D00040555C4FBE016F5E7F4FCE0101960E9455 +:1029E000C00B9E012F5F3F4F7901CE0141969DABF9 +:1029F0008CABA5E0B0E0F701908181813281238129 +:102A0000792F770F97FD7127B82EBB0C87FDB12664 +:102A1000C32ECC0C37FDC126622F660F27FD612720 +:102A2000472F440F77FD41274B2C440CB7FE04C0C1 +:102A30005B2D550F452E41269C2C990CC7FC9126E9 +:102A4000A62EAA0C67FDA126D42EDD0C47FF04C0DC +:102A5000542F550FD52ED126542D550F47FC5127F5 +:102A6000F92DFF0F97FCF127EA2DEE0FA7FCE127C8 +:102A7000792E7D24582E5526832E8F26622E6E2683 +:102A80004D2554259F26AE26E32FE727EB25E42787 +:102A9000E525E925E625F0E0EC5AF94F3491ECA95B +:102AA000FDA93083E22FEB25EC25E725E527E82576 +:102AB000EA25F0E0EC5AF94FD490FD01EF70FF27C2 +:102AC00021E130E02C0F3D1FE20FF31FD0829C2547 +:102AD00096274927542695246924E62DF0E0EC5AE0 +:102AE000F94F6490FD013596EF70FF2721E130E04A +:102AF0002C0F3D1FE20FF31F6082E82FE727E62728 +:102B0000E7255E27E52FE825AE26EA2DF0E0EC5A12 +:102B1000F94FA490FD013A96EF70FF27E20FF31FE3 +:102B2000A08294E0E90EF11C2CA93DA92C5F3F4F37 +:102B30003DAB2CAB1496A531B10509F05CCF8EA945 +:102B40009FA901969FAB8EAB35CFA1E0B0E0BAABA9 +:102B5000A9AB9CCE40EB53E0BE016F5E7F4FC1013D +:102B60000E94C00B68EA74E0C1010E94E70B40E1DB +:102B7000BE016F5D7F4F88EA94E00E94320490E1CD +:102B8000290E311C87CE30919003832F83708230C1 +:102B900009F021CE20919103A22FA770EA2E009177 +:102BA0009203F0908E0380918D0340918F0390915A +:102BB000F60190689093F60190914F02491376C107 +:102BC000832F8695869586958A3108F089E190E075 +:102BD0003770BC0153E0660F771F5A95E1F7362B2B +:102BE0003093900383579C4FFC01178223FF15C03D +:102BF00081E2EDE8F3E0ACE6B3E001900D928A9556 +:102C0000E1F7277F20612093700340936D03F092DA +:102C10006E038CE693E00E949B129091910394FDC9 +:102C20003DC1F3E0EF123AC18091920321EF280FEA +:102C3000233008F4D0CD0430C1F4809193039091F7 +:102C40002601891719F08F3F09F0C5CD8DE893E073 +:102C50000E9461109FEF980F9E3F18F40E9406108B +:102C6000BACD8FEF80934F02B6CD0830D9F40091E2 +:102C7000F50100FFB0CD8DE893E00E9461108F3F19 +:102C800009F4A9CD8F5F8F3F09F4A5CD9091510232 +:102C9000891708F0A0CD01FD9ECD80935102F092DE +:102CA000500299CD0831C1F480914F0280936D0399 +:102CB000F0926E038FEF8093720389E1809371032A +:102CC00080917003807E83608093700361E08CE666 +:102CD00093E00E94C20A32C0093171F48091F5017B +:102CE00083FF79CD877F8093F5018DE893E00E9483 +:102CF00061108093F7016FCD0E3109F46CCD0D3169 +:102D000001F580914F0280936D0310926E038FEF57 +:102D1000809372038FE18093710383E48093700347 +:102D200080916F038770806180936F0380E09FEFD5 +:102D300090937403809373038CE693E00E94631274 +:102D40004ACD20918E032111AEC08D3059F488E117 +:102D500098E00FB6F894A895809360000FBE90930A +:102D60006000FFCF8B3179F48DE893E00E94611011 +:102D700091E0811101C090E08091EA0190FB80F91F +:102D80008093EA0128CD863099F49091940381E0F4 +:102D9000992319F09D3409F080E08093E90141E026 +:102DA00050E063E071E089EE91E00E948C2913CD40 +:102DB000833119F40E9476130ECD823121F50E94E1 +:102DC000D90A20914F0220936D0310926E032FEFCA +:102DD0002093720326E12093710323EA209370036A +:102DE00020916F032770206220936F036093730319 +:102DF0007093740380937503909376038CE693E04D +:102E00000E949B12E8CC823009F590914F0290937A +:102E10006D0310926E039FEF909372038093710382 +:102E200083EA8093700380916F0387708062809340 +:102E30006F038FEF91E0A3E0B2E080937303909370 +:102E40007403A0937503B0937603D8CF813001F556 +:102E500020E030E0232B09F4BECC92959695977034 +:102E6000953059F460919403709195038091960385 +:102E7000909197030E940000AECC911105C084E9A7 +:102E800093E00E94F127F6CF60E070E0CB01F2CF33 +:102E90008A3009F4A0CC8C3109F49DCC8DE893E004 +:102EA0000E94C81298CC8A31C9F795CC4F3F09F0DF +:102EB00092CC93E0A9132AC09091F50192FF03C030 +:102EC000073009F488CC043109F085CC9091500288 +:102ED000891381CC0E9481077370882799270E94EB +:102EE0004E0780914F0280936D03F0926E038FEF37 +:102EF0008093720385E18093710380917003807EDB +:102F000083608093700360915002E1CE90915002F3 +:102F1000891361CCC3CFE9960FB6F894DEBF0FBE1C +:102F2000CDBFDF91CF911F910F91FF90EF90DF9078 +:102F3000CF90BF90AF909F908F907F906F905F9059 +:102F40004F903F902F9008958091F50184FD0C944F +:102F5000CE130895CF92DF92EF92FF92CF93DF933B +:102F6000D82F0E9481076B017C0110929203C0E070 +:102F70000E9481076C197D098E099F09603D774089 +:102F80008105910590F4C11110C0A8950E94CE0A48 +:102F90000E94A417809191038770833049F7C1E0A4 +:102FA000809192038D13E3CFE3CF8C2FDF91CF91EC +:102FB000FF90EF90DF90CF9008958F929F92AF9205 +:102FC000BF92CF92DF92EF92FF924B015C010E9481 +:102FD00081076B017C010E9481076C197D098E09B4 +:102FE0009F09681579058A059B0530F4A8950E940C +:102FF000CE0A0E94A417EFCFFF90EF90DF90CF9002 +:10300000BF90AF909F908F9008958F929F92AF92B4 +:10301000BF92CF92DF92EF92FF920F931F93CF93C5 +:10302000DF9380912001882309F49EC01092200133 +:103030001092170369E574E081E193E00E94630F49 +:1030400060E00E94B31266E970E080E090E00E94C8 +:103050004E0780911C01882359F11092380340914A +:103060004702509148026091490270914A02809152 +:103070003503877088628093350380913603806EB4 +:10308000809336034093390350933A0360933B0394 +:1030900070933C0381E080933D0360E082E393E022 +:1030A0000E94B31266E970E080E090E00E944E0753 +:1030B000C1E0C093170363E574E081E193E00E94EF +:1030C000630F60E00E94B31266E970E080E090E078 +:1030D0000E944E07D0911C01DD2351F1C0933803AB +:1030E00040914B0250914C0260914D0270914E0202 +:1030F0008091350387708862809335038091360311 +:10310000806E809336034093390350933A03609363 +:103110003B0370933C03C0933D0360E082E393E084 +:103120000E94B31266E970E080E090E00E944E07D2 +:1031300082E08093F6028091F3028770886080932A +:10314000F3028091F4028F7180628093F402D09335 +:10315000F70260E080EF92E00E94B31266E970E04F +:1031600080E090E00E94DD170E94A60620911F01DA +:103170002817190691F16AE070E080E090E00E9463 +:10318000DD170E94A60621E0892B09F420E0209398 +:103190001F0160E476E083E592E00E944C05809197 +:1031A0001F0190E00E94690C80911F0181110FC0E6 +:1031B00081E08093680340E060E587E593E00E944A +:1031C000E6086EE376E087E593E00E944C056AE04E +:1031D00070E080E090E00E94DD170E94810700917E +:1031E000E3011091E4012091E5013091E6016B01CA +:1031F0007C01C01AD10AE20AF30A97018601093E4E +:1032000013402105310508F474C06093E301709305 +:10321000E4018093E5019093E60180911D01909176 +:103220001E01019690931E0180931D016FE871E0CD +:1032300083E592E00E940E0C80911D0190911E0189 +:103240000E94690C80911D0190911E01CD9784F020 +:103250006AE771E083E592E00E940E0C61E376E09C +:1032600083E592E00E949C0D10921E0110921D01B8 +:10327000A89581E08093680340E064E687E593E0E9 +:103280000E94E60880911D0190911E012CE3C22E40 +:10329000D12CC81AD90A0D2C000CEE08FF082AE020 +:1032A000B701A601F7FE0DC06DE287E593E00E942D +:1032B000450544275527BA014C195D096E097F0958 +:1032C0002AE087E593E00E941D0C87E593E00E94C9 +:1032D0002D0980911D0190911E018B30910509F4FB +:1032E000FAC0A4F48130910509F4B8C00A9709F432 +:1032F000DEC0DF91CF911F910F91FF90EF90DF9093 +:10330000CF90BF90AF909F908F9008958D30910592 +:1033100009F41AC30CF430C20E9759F78091C70113 +:103320009091C8014CE3489F9001499F300D1124B2 +:1033300020313E402CF401969093C8018093C70140 +:103340008091E201811102C4C0904B02D0904C02E6 +:10335000E0904D02F0904E028090DD019090DE01F1 +:10336000A090DF01B090E001C091C701D091C801E9 +:10337000C230D10594F0C430D1050CF0A6C3A5012C +:103380009401C701B6010E94122A20E030E040E01B +:103390005FE30E94BE286B017C01C092DD01D092E8 +:1033A000DE01E092DF01F092E001C0904702D09090 +:1033B0004802E0904902F0904A028090D901909032 +:1033C000DA01A090DB01B090DC01C230D10594F0AD +:1033D000C430D1050CF09AC3A5019401C701B60110 +:1033E0000E94122A20E030E040E05FE30E94BE2805 +:1033F0006B017C01C092D901D092DA01E092DB012D +:10340000F092DC016DE674E083E592E00E944C05E9 +:103410006091DD017091DE018091DF019091E0010A +:103420000E94870D6FE574E083E592E00E944C05F1 +:103430006091D9017091DA018091DB019091DC01FA +:10344000DF91CF911F910F91FF90EF90DF90CF9080 +:10345000BF90AF909F908F900C94870D60E276E0C4 +:1034600083E592E00E949C0D809155039091560354 +:10347000DC01ED91FC910190F081E02D61E0099576 +:103480008091550390915603DC01ED91FC910680EB +:10349000F781E02DDF91CF911F910F91FF90EF9079 +:1034A000DF90CF90BF90AF909F908F9009946AE08B +:1034B00076E083E592E00E949C0DDF91CF911F9111 +:1034C0000F91FF90EF90DF90CF90BF90AF909F90C3 +:1034D0008F900C9460046EEE75E083E592E00E949C +:1034E0009C0D0E946004892B69F46DED75E083E505 +:1034F00092E00E949C0D6AE070E080E090E00E9403 +:103500004E07EFCF82E08093680343E060E087E5F9 +:1035100093E00E94E60840914B0250914C0260916A +:103520004D0270914E0222E087E593E00E94A10CCB +:1035300069ED75E087E593E00E949C0D46E060E050 +:1035400087E593E00E94E6084091470250914802C7 +:103550006091490270914A0222E087E593E00E945F +:10356000A10C65ED75E087E593E00E949C0D43E0BA +:1035700066E487E593E00E94E6088091E2016FEC43 +:1035800075E08111B2C0C0904B02D0904C02E09027 +:103590004D02F0904E0220E030E0A901C701B601D3 +:1035A0000E945828811164C087E593E00E942D098C +:1035B00046E066E487E593E00E94E6088091E20138 +:1035C0006BEA75E08111D3C0C0904702D0904802E9 +:1035D000E0904902F0904A0220E030E0A901C701E2 +:1035E000B6010E945828811185C087E593E00E94AA +:1035F0002D0966E775E083E592E00E949C0DC7E423 +:10360000D1E00AE511E0809155039091560369914C +:10361000DC01ED91FC910190F081E02D09950C17F2 +:103620001D0789F78091550390915603DC01ED91B8 +:10363000FC910680F781E02D0995809155039091CA +:103640005603DC01ED91FC910084F185E02D099594 +:10365000181619060CF04DCE809155039091560323 +:10366000DC01ED91FC910284F385E02D0995E5CF15 +:1036700020E030E040E450E4C701B6010E94582841 +:1036800069EC75E018168CF520E030E040EA50E473 +:10369000C701B6010E94582863EC75E018162CF596 +:1036A00020E030E040E051E4C701B6010E94582814 +:1036B0006DEB75E01816CCF420E030E040E651E404 +:1036C000C701B6010E94582867EB75E018166CF424 +:1036D00020E030E040EA51E4C701B6010E94262B09 +:1036E00018160CF065CF61EB75E087E593E00E945A +:1036F0004C055ECF20E030E040EA50E4C701B6015F +:103700000E94582865EA75E018168CF520E030E034 +:1037100040E251E4C701B6010E9458286FE975E004 +:1037200018162CF520E030E040EA51E4C701B6015C +:103730000E94582869E975E01816CCF420E030E0C2 +:1037400040EF51E4C701B6010E94582863E975E0D3 +:1037500018166CF420E030E040EF51E4C701B601E8 +:103760000E94262B18160CF044CF6DE875E087E513 +:1037700093E00E944C053DCF1092E1018091E2015F +:10378000882341F06BE575E083E592E00E944C05EB +:103790001092E2018091E201882309F4B9C020E08F +:1037A00030E543EC57E46091D5017091D6018091EA +:1037B000D7019091D8010E94BE280E94F02A6B0187 +:1037C0007C01C114D104E104F10441F00E947B2783 +:1037D000A70196010E94AE296B017C01C701B601C9 +:1037E0000E945F2820E030E543EC57E40E947E2AE7 +:1037F0006093C9017093CA018093CB019093CC016F +:103800000E947B2722E030E040E050E00E94AE2999 +:10381000672B682B692B89F08091C9019091CA01AF +:10382000A091CB01B091CC01B0588093C901909385 +:10383000CA01A093CB01B093CC016CE475E083E5A1 +:1038400092E00E944C056091C9017091CA0180917B +:10385000CB019091CC010E94870D2091DD01309128 +:10386000DE014091DF015091E0016091C90170914A +:10387000CA018091CB019091CC010E94122A6093E1 +:10388000C9017093CA018093CB019093CC0166E388 +:1038900075E083E592E00E944C056091C90170914A +:1038A000CA018091CB019091CC010E94870D91E0DB +:1038B000909338034091C9015091CA016091CB01A6 +:1038C0007091CC01809135038770886280933503B5 +:1038D00080913603806E8093360340933903509372 +:1038E0003A0360933B0370933C0390933D0361E084 +:1038F00082E393E0DF91CF911F910F91FF90EF90C2 +:10390000DF90CF90BF90AF909F908F900C94B312A8 +:1039100065E275E083E592E00E944C0560914B0200 +:1039200070914C0280914D0290914E020E94870D41 +:1039300091E09093380340914B0250914C0260917A +:103940004D0270914E02BECF8091E201882309F4AE +:103950007DC02091CD013091CE014091CF01509199 +:10396000D0016091D1017091D2018091D3019091E9 +:10397000D4010E94BE286B017C0165E175E083E5FE +:1039800092E00E944C05C701B6010E94870D20916C +:10399000D9013091DA014091DB015091DC01C7017E +:1039A000B6010E94122A6B017C016EEF74E083E580 +:1039B00092E00E944C05C701B6010E94870D8091DC +:1039C0001C018823E9F091E090933803809135033E +:1039D000877088628093350380913603806E809370 +:1039E0003603C0923903D0923A03E0923B03F0923F +:1039F0003C0390933D0361E082E393E00E94B312A5 +:103A000081E08093680340E060E587E593E00E94F1 +:103A1000E6088091E101882309F44EC06CEC74E063 +:103A200083E592E00E949C0D6AEC74E087E593E0E8 +:103A3000DF91CF911F910F91FF90EF90DF90CF908A +:103A4000BF90AF909F908F900C944C056CEE74E0FB +:103A500083E592E00E944C05609147027091480214 +:103A60008091490290914A020E94870D80911C0129 +:103A7000882331F210923803409147025091480256 +:103A80006091490270914A02809135038770886283 +:103A90008093350380913603806E80933603409384 +:103AA000390350933A0360933B0370933C0381E0E6 +:103AB00080933D0360E0A0CF6DEA74E083E592E07F +:103AC0000E949C0D6BEA74E0B1CFBE016150710998 +:103AD000072E000C880B990B0E945F28A50194010A +:103AE0000E94BE28A70196010E94122A6B017C0148 +:103AF000BE010D2E000C880B990B0E945F289B01C4 +:103B0000AC01C701B6010E947E2A45CCBE016150BE +:103B10007109072E000C880B990B0E945F28A501E4 +:103B200094010E94BE28A70196010E94122A6B01EF +:103B30007C01BE01DD0F880B990B0E945F289B0161 +:103B4000AC01C701B6010E947E2A52CC6CE774E03A +:103B500083E592E00E944C0555CC1F93CF93DF93F1 +:103B60008091EA0181FD2DC00E9476138091EA01C7 +:103B700081608093EA01C4E0DFEF1AE180914F0297 +:103B800080936D0310926E03D093720310937103B0 +:103B900080917003807E83608093700362E08CE686 +:103BA00093E00E94C20A0E949B128BE10E94AA1716 +:103BB000811102C0C15011F78091EA0182608093A7 +:103BC000EA01DF91CF911F9108958FEF8093F70164 +:103BD000E5EFF1E0908198609083ECE6F3E090915E +:103BE0004F0291831282868388E185838481807E5F +:103BF0008360848361E0CF010E94C20A0C94631247 +:103C000080914F028F3F21F50E9481076F3FE9F0BD +:103C1000609326018091260190914F0290936D034D +:103C200010926E038093720383E0809371038091FE +:103C30007003807E8360809370036CE771E08CE694 +:103C400093E00E942C100C94631210922601E2CF94 +:103C50000895E5EFF1E08081897F81608083AFE4A2 +:103C6000B2E08FEF12968C93129711968C93119766 +:103C7000ECE6F3E09C9191838283868387E08583E1 +:103C80008481807E836084836CE771E0CF010E9431 +:103C90002C100C9463128F929F92AF92BF92CF928E +:103CA000DF92EF92FF920F931F93CF93DF93CDB7E5 +:103CB000DEB764970FB6F894DEBF0FBECDBF8E019E +:103CC0000F5F1F4F80E1F80111928A95E9F760E1DB +:103CD00070E08CE991E00E943028AC016CE971E061 +:103CE000C8010E94632B8AE090E09093AF03809319 +:103CF000AE0340E1B80180EB93E00E94320450E053 +:103D000040E080E190E0FF24F39420E1E22EBE0148 +:103D10006B5E7F4F3BE1B32ED82EFC01E455FC4F88 +:103D20009E012F5E3F4FD901C190CD92A617B707D4 +:103D3000D9F7DE1020C0D988F0E1EF0EEA89F0E073 +:103D4000E454FF4FE491EF25E98BEB89F0E0E45474 +:103D5000FF4FE491EA8BEC89F0E0E454FF4FE491EB +:103D6000EB8BED2DF0E0E454FF4FE491EC8BF7FE8C +:103D7000CFC0FF0CFB24FC01E055FC4F4F01F901C3 +:103D8000A1909F016401C81AD90AC40ED51EF6017C +:103D9000D080DA24F401D1924F012A173B0779F73A +:103DA00004964C5F5F4F803B910509F0B5CF80E1F1 +:103DB000F80111928A95E9F7229A219A2A98299A6C +:103DC0001FB7F8948091A601811127C0ECE8F7E0B5 +:103DD0008491E0EAF7E09491E82FF0E0EE0FFF1F06 +:103DE000EC59F84FA591B491EC91E92321F461E0ED +:103DF0008AE00E94CA0661E08AE00E94F8068CB55B +:103E000080618CBD8CB580648CBD61E08DE00E94CA +:103E1000F80661E08BE00E94F8068091A6018F5FB2 +:103E20008093A6011FBF2A986EE080E20E94CC0F0B +:103E30008BE496E40197F1F763E083E20E94CC0FF4 +:103E40006FE584E20E94CC0F6CE485E20E94CC0F07 +:103E500067E086E20E94CC0F64E08DE30E94CC0F05 +:103E60008DE10E942010843041F063E780E50E94DC +:103E7000CC0F64E08DE30E94CC0F86E00E942010FE +:103E8000873009F04FC085E00E9420108C3409F083 +:103E900049C062E082E20E94CC0F60E081E20E94B1 +:103EA000CC0F63E08CE30E94CC0F1FEF1093030153 +:103EB00020E045E063E071E08BE20E949A0F20E091 +:103EC00045E063E071E08AE20E949A0F20E045E05D +:103ED00063E071E080E30E949A0F82EE0E94261058 +:103EE00081EE0E94261060E787E20E94CC0F80914D +:103EF000F50180618093F501809152028E7F80935D +:103F0000520280914F028F3F29F488E191E00CC06A +:103F1000FF0C31CF9FEF980F9E3FD8F40E94061000 +:103F20008111F3CF88E091E00E94EC0A64960FB60D +:103F3000F894DEBF0FBECDBFDF91CF911F910F91DF +:103F4000FF90EF90DF90CF90BF90AF909F908F90B9 +:103F5000089510934F02E6CF1F920F920FB60F9263 +:103F600011242F933F934F935F936F937F938F937E +:103F70009F93AF93BF93EF93FF9383E592E00E94EB +:103F8000E405FF91EF91BF91AF919F918F917F9148 +:103F90006F915F914F913F912F910F900FBE0F90B6 +:103FA0001F9018951F920F920FB60F9211242F9306 +:103FB0008F939F93EF93FF93E0916302F0916402DC +:103FC0008081E0916902F0916A0282FD1BC09081BC +:103FD00080916C028F5F8F7320916D02821741F088 +:103FE000E0916C02F0E0ED5AFD4F958F80936C02EA +:103FF000FF91EF919F918F912F910F900FBE0F9096 +:104000001F9018958081F4CF1F920F920FB60F92D8 +:1040100011242F933F938F939F93AF93BF938091DE +:104020003F0290914002A0914102B0914202309132 +:104030003E0223E0230F2D3758F50196A11DB11D37 +:1040400020933E0280933F0290934002A09341024E +:10405000B09342028091430290914402A0914502A4 +:10406000B09146020196A11DB11D80934302909329 +:104070004402A0934502B0934602BF91AF919F9135 +:104080008F913F912F910F900FBE0F901F90189519 +:1040900026E8230F0296A11DB11DD2CF1F920F92C9 +:1040A0000FB60F9211242F933F934F935F936F930B +:1040B0007F938F939F93AF93BF93EF93FF93E09181 +:1040C0002901F0912A010995FF91EF91BF91AF91DC +:1040D0009F918F917F916F915F914F913F912F9120 +:1040E0000F900FBE0F901F9018951F920F920FB652 +:1040F0000F9211242F933F934F935F936F937F936E +:104100008F939F93AF93BF93EF93FF93E09127011A +:10411000F09128010995FF91EF91BF91AF919F9187 +:104120008F917F916F915F914F913F912F910F9060 +:104130000FBE0F901F9018951F920F920FB60F92FF +:1041400011242F933F934F935F936F937F938F939C +:104150009F93AF93BF93EF93FF93E0913C02F09155 +:104160003D02309749F0A685B7858585968D91FFEC +:1041700014C09C918923A1F4FF91EF91BF91AF915D +:104180009F918F917F916F915F914F913F912F916F +:104190000F900FBE0F901F9018959C91892361F787 +:1041A000A389B4899C918589809589238C9386897C +:1041B00097890197F1F7608D718DA685B785558533 +:1041C00038E020E0CB010197F1F7822F90E0959540 +:1041D0008795282F4C91452309F02068315091F79D +:1041E000868D81FD209580913A0290E001968F7333 +:1041F000992730913B02381799F0A0913A02B0E02C +:10420000A650BE4F2C9380933A02828D938D0197D6 +:10421000F1F7A389B4898C919589892B8C93ACCFC4 +:10422000868D8160868FF1CF1F920F920FB60F920D +:1042300011240F900FBE0F901F901895DB01FC0109 +:1042400058E0149744E018960E9001924A95E1F7D1 +:104250005A95C1F708958F929F92AF92BF92CF92D5 +:10426000DF920F931F93EDB7FEB7B8970FB6F89490 +:10427000EDBF0FBEFEBF9F938F9331968F01490113 +:104280005A016B01C801AAD2BB2011F4AA2059F02F +:10429000C801B601A1D030E4C30ED11C32E0931A9C +:1042A000A108B108F1CFC801B601A40115D08F91C2 +:1042B0009F91B801C3DFEDB7FEB7B8960FB6F8947B +:1042C000EDBF0FBEFEBF1F910F91DF90CF90BF904B +:1042D000AF909F908F900895523090F09F938F935E +:1042E0007F936F935F934F9377D04F915F916F91CF +:1042F0007F918F919F91525030E4630F711DECCFED +:10430000EDB7FEB70FB6E054F040F894EDBF0FBE26 +:10431000FEBF3196242F26952695269550FB25F92C +:10432000DB01222329F0122E0D9001921A94E1F75D +:1043300030E8032E37E0342329F006943A95E9F764 +:104340003C91032A01922395293308F421C030E4DB +:10435000321B19F011923A95E9F7FF973197BF0197 +:10436000FF93EF939F938F935F934F9335D04F912C +:104370005F918F919F91EF91FF91DC0191963C911C +:1043800032503D9326E03C9130403D932A95D9F739 +:1043900038E3321B21F0112411923A95E9F7DC0140 +:1043A000909638960D90040E02920D90051E029282 +:1043B00036E00D90011C02923A95D9F7F897BF01AB +:1043C0000BD0EDB7FEB70FB6FF963196F894EDBF60 +:1043D0000FBEFEBF112408954F925F926F927F929D +:1043E0008F929F92AF92BF92CF92DF92EF92FF9205 +:1043F0000F931F93CF93DF934DB75EB79A01FB01E5 +:1044000040525140DA010FB6F8944DBF0FBE5EBF67 +:104410002F933F938F939F93119640E171916191F8 +:10442000319121912D933D936D937D934A95B1F7F1 +:1044300040E3142EFD01FF973197019111912191D5 +:104440003191C190D190E190F1906D2D7E2D8F2D05 +:104450009C2D41E0E9D14B015C01B701C60142E06E +:10446000F9D186269726A826B92673E0F694E79414 +:10447000D794C7947A95D1F78C249D24AE24BF2479 +:10448000080D191D2A1D3B1D648D758D868D978D18 +:10449000060F171F281F391FC0A8D1A8E2A8F3A82C +:1044A000B701C60141E0D6D15C014B0142E0D2D157 +:1044B00086269726A826B92672E0F694E794D79424 +:1044C0007A95D9F78D249E24AF24080D191D2A1D35 +:1044D0003B1D0D931D932D933D931A9409F0AACF84 +:1044E000FF91EF91EF93FF9390E211901D929A95B7 +:1044F000E1F79097ED01ECEDF6E4BA9590E4192E12 +:104500004C885D886E887F88688979898A899B89CB +:10451000C88CD98CEA8CFB8C4622572268227922DF +:104520006095709580959095C622D722E822F92251 +:104530004C245D246E247F24F888C988DA88EB88AF +:10454000B601C70142E070D14B015C01B601C70161 +:1045500043E080D186269726A826B926B701C60152 +:1045600041E078D186269726A826B926480C591C02 +:104570006A1C7B1C8C8C9D8CAE8CBF8C480C591C8F +:104580006A1C7B1C8D909D90AD90BD90480C591C71 +:104590006A1C7B1C85909590A590B590480C591C81 +:1045A0006A1C7B1C688179818A819B818C809D80BB +:1045B000AE80BF8086229722A822B922C884D984DF +:1045C000EA84FB846C217D218E219F2186269726FB +:1045D000A826B9266C817D818E819F816C217D21E9 +:1045E0008E219F2186269726A826B926C880D980A5 +:1045F000EA80FB80B601C70142E02CD18B019C010F +:10460000B701C60143E010D106271727282739270D +:104610006F2D7C2D8D2D9E2D42E006D1062717276C +:1046200028273927080D191D2A1D3B1D5CE16C96B2 +:104630009A919C835A95E1F7C888D988EA88FB88C3 +:10464000C40CD51CE61CF71CC88AD98AEA8AFB8AE6 +:10465000040D151D261D371D088319832A833B83EE +:104660001A9409F04DCFFF91EF9158E0008111812C +:10467000228133816991799189919991060F171F50 +:10468000281F391F01931193219331935A9571F784 +:10469000319652E066E04081450F4193552728F45A +:1046A0004081451F41936A95D1F75F914F910FB6B5 +:1046B000F8944DBF0FBE5EBF1124DF91CF911F91C3 +:1046C0000F91FF90EF90DF90CF90BF90AF909F90B1 +:1046D0008F907F906F905F904F900895982F8A42AF +:1046E00091443771CFFBC0B5A5DBB5E95BC2563944 +:1046F000F111F159A4823F92D55E1CAB98AA07D85C +:10470000015B8312BE853124C37D0C55745DBE727E +:10471000FEB1DE80A706DC9B74F19BC1C1699BE4FE +:104720008647BEEFC69DC10FCCA10C246F2CE92D8E +:10473000AA84744ADCA9B05CDA88F97652513E98B2 +:104740006DC631A8C82703B0C77F59BFF30BE0C6B9 +:104750004791A7D55163CA0667292914850AB72747 +:1047600038211B2EFC6D2C4D130D385354730A65E4 +:10477000BB0A6A762EC9C281852C7292A1E8BFA2BB +:104780004B661AA8708B4BC2A3516CC719E892D123 +:10479000240699D685350EF470A06A1016C1A419A6 +:1047A000086C371E4C774827B5BCB034B30C1C39A5 +:1047B0004AAAD84E4FCA9C5BF36F2E68EE828F7464 +:1047C0006F63A5781478C8840802C78CFAFFBE907E +:1047D000EB6C50A4F7A3F9BEF27871C6DC01EEEEE3 +:1047E000F7E468E275917D936A95E1F7089567E6CD +:1047F000096A85AE67BB72F36E3C3AF54FA57F52EE +:104800000E518C68059BABD9831F19CDE05B00006E +:10481000000000000000483038F0592F982F872FF3 +:10482000762F652F4850F7CF55278894442339F0C9 +:10483000661F771F881F991F551F4A95C9F7652B5B +:104840000895483038F0562F672F782F892F952FED +:104850004850F7CF55278894442339F0979587958A +:104860007795679557954A95C9F7952B0895AB01AC +:10487000692F782F852F942F0895CF93DF93FC0114 +:10488000108211821282148215821682DC01179620 +:104890008AE1ED0119928A95E9F782E08383DF913D +:1048A000CF9108950F931F93CF93DF93CDB7DEB7CA +:1048B00028970FB6F894DEBF0FBECDBFE3E5F2E058 +:1048C0001382128288EE93E0A0E0B0E084839583A7 +:1048D000A683B7838EE591E09183808385EC90E099 +:1048E0009587848784EC90E09787868780EC90E0BA +:1048F000918B808B81EC90E0938B828B82EC90E0AB +:10490000958B848B86EC90E0978B868B118E128E24 +:10491000138E148E28E0CE010196DC01E22F1D9249 +:10492000EA95E9F7E0EAF4E011E0108311821282DF +:10493000138214821582168217821092AF0310928E +:10494000AE031092B9041092B8041092BB041092F6 +:10495000BA04E0EBF3E030EFDF011D923A95E9F79E +:10496000188738E0FC01A8EAB4E001900D923A956E +:10497000E1F738E0FC01A0EBB4E001900D923A952C +:10498000E1F71093BC0402E00093BD0483E0809340 +:10499000BE0484E08093BF0485E08093C00486E079 +:1049A0008093C10487E08093C2042093C30489E00C +:1049B0008093C4048AE08093C5048BE08093C6048E +:1049C0008CE08093C7048DE08093C8048EE08093D0 +:1049D000C9048FE08093CA048DE893E00E943D24CF +:1049E0008CE693E00E943D24E7E5F3E01382128217 +:1049F0001486158617861686108A118B80E791E03B +:104A00009183808382E393E00E943D24E2E3F3E01C +:104A1000168285E2858381E193E00E943D24E1E1F5 +:104A2000F3E016828BE2858380EF92E00E943D24C2 +:104A3000E0EFF2E00683058328960FB6F894DEBF18 +:104A40000FBECDBFDF91CF911F910F910895CF93EE +:104A5000DF93CDB7DEB7CA55D1090FB6F894DEBFE4 +:104A60000FBECDBF789484B5826084BD84B581606B +:104A700084BD85B5826085BD85B5816085BD809129 +:104A80006E00816080936E001092810080918100A1 +:104A90008260809381008091810081608093810099 +:104AA000809180008160809380008091B10084605B +:104AB0008093B1008091B00081608093B0008091BC +:104AC0007A00846080937A0080917A00826080937B +:104AD0007A0080917A00816080937A0080917A00D8 +:104AE000806880937A001092C100A89580E090E0E1 +:104AF000892B11F00E9400000E940A048091EA01B3 +:104B00008D7F8093EA0180E090E0892B11F00E9474 +:104B1000000040E250E063E671E0CE0101960E94A1 +:104B20007C2940E150E06CE871E0CE0181960E9462 +:104B30007C2949E050E063E871E0CE01C1960E9413 +:104B40007C2941E050E06AE171E0CE01865A9F4F36 +:104B50000E947C2928EC31E040E050E0BE016F5F0C +:104B60007F4FCE01CA960E942B2141E050E063E0C6 +:104B700071E089EE91E00E947C296FEF81E090E086 +:104B80000E949C298091F6018F788093F601109203 +:104B9000EC011092EB0181E291E00E94EC0A8DEAB7 +:104BA0009DE19093E8018093E7010E9481076B01EA +:104BB0007C010E9481076C197D098E099F09603173 +:104BC000774281059105C8F00E94C60DA89500E0C6 +:104BD00010E0A8950E94CE0A8091F50184FD0E9404 +:104BE000CE130E9405180115110599F30E94DA05EC +:104BF000882379F30E940000ECCF0E94CE0A0E9425 +:104C0000A4178091F50182FB882780F9A89581116E +:104C1000DBCFCFCF0F931F93CF93DF9382309105DC +:104C200010F482E090E0E091CD04F091CE0430E009 +:104C300020E0B0E0A0E0309799F42115310509F4A7 +:104C40004AC0281B390B24303105D8F58A819B8155 +:104C50006115710589F1FB0193838283FE0111C007 +:104C6000408151810281138148175907E0F04817AC +:104C7000590799F4109761F012960C9312971396B6 +:104C80001C933296CF01DF91CF911F910F91089520 +:104C90000093CD041093CE04F4CF2115310551F0CB +:104CA0004217530738F0A901DB019A01BD01DF016A +:104CB000F801C1CFEF01F9CF9093CE048093CD04DA +:104CC000CDCFFE01E20FF31F819391932250310962 +:104CD00039832883D7CF2091CB043091CC04232B68 +:104CE00041F420912D0130912E013093CC0420937A +:104CF000CB0420912B0130912C012115310541F479 +:104D00002DB73EB740912F0150913001241B350B38 +:104D1000E091CB04F091CC04E217F307A0F42E1B32 +:104D20003F0B2817390778F0AC014E5F5F4F24170F +:104D3000350748F04E0F5F1F5093CC044093CB04CF +:104D4000819391939FCFF0E0E0E09CCFCF93DF93EE +:104D50000097E9F0FC01329713821282A091CD04F2 +:104D6000B091CE04ED0130E020E01097A1F4208155 +:104D70003181820F931F2091CB043091CC042817EE +:104D8000390709F061C0F093CC04E093CB04DF91C4 +:104D9000CF910895EA01CE17DF07E8F54A815B81DC +:104DA0009E0141155105B1F7E901FB83EA83499161 +:104DB0005991C40FD51FEC17FD0761F480819181D3 +:104DC0000296840F951FE9019983888382819381DC +:104DD0009B838A83F0E0E0E012968D919C9113977B +:104DE0000097B9F52D913C911197CD010296820F54 +:104DF000931F2091CB043091CC042817390739F642 +:104E0000309751F51092CE041092CD04B093CC049B +:104E1000A093CB04BCCFD383C28340815181840F44 +:104E2000951FC817D90761F44E5F5F4F888199813C +:104E3000480F591F518340838A819B8193838283CA +:104E40002115310509F0B0CFF093CE04E093CD04E5 +:104E50009ECFFD01DC01C0CF13821282D7CF8F928B +:104E60009F92AF92BF92CF92DF92EF92FF92CF9339 +:104E7000DF93EC01688179818A819B8161157105DD +:104E80008105910521F464E279ED8BE597E02DE150 +:104E900033EF41E050E00E94AE2949015A019B01E5 +:104EA000AC01A7EAB1E40E94CD296B017C01ACEE14 +:104EB000B4EFA50194010E94DB29C60ED71EE81E9F +:104EC000F91EF7FE06C081E0C81AD108E10880E8A3 +:104ED000F80AC882D982EA82FB82C701B6019F77AD +:104EE000DF91CF91FF90EF90DF90CF90BF90AF9088 +:104EF0009F908F9008958F929F92AF92BF92CF9282 +:104F0000DF92EF92FF9260913101709132018091B6 +:104F1000330190913401611571058105910521F4EA +:104F200064E279ED8BE597E02DE133EF41E050E06D +:104F30000E94AE2949015A019B01AC01A7EAB1E4E4 +:104F40000E94CD296B017C01ACEEB4EFA501940168 +:104F50000E94DB29C60ED71EE81EF91EF7FE06C00A +:104F600081E0C81AD108E10880E8F80AC09231014E +:104F7000D0923201E0923301F0923401C701B601C0 +:104F80009F77FF90EF90DF90CF90BF90AF909F9072 +:104F90008F900895609331017093320180933301B3 +:104FA000909334010895FC0188279927E894219172 +:104FB0002032E9F3293010F02E30C8F32B3241F0C3 +:104FC0002D3239F4689404C00E945028820F911D3C +:104FD000219120532A30C0F31EF4909581959F4F64 +:104FE00008951F93FC0199278827BC01E89411912B +:104FF0001032E9F3193010F01E30C8F31B3251F0B3 +:105000001D3249F4689406C00E943B28610F711D4F +:10501000811D911D119110531A30B0F33EF49095FB +:105020008095709561957F4F8F4F9F4F1F91089589 +:10503000FC0105900020E9F7809590958E0F9F1F49 +:105040000895FB01DC014150504048F005900D925D +:105050000020C9F701C01D9241505040E0F708956B +:10506000FC016150704001900110D8F78095909537 +:105070008E0F9F1F0895592F482F372F262F660F09 +:10508000771F881F991F660F771F881F991F620F50 +:10509000731F841F951F660F771F881F991F089520 +:1050A0007AE0979F902D879F802D910D1124089570 +:1050B0000E949A2808F481E00895E89409C097FBBB +:1050C0003EF490958095709561957F4F8F4F9F4FDF +:1050D0009923A9F0F92F96E9BB279395F695879523 +:1050E00077956795B795F111F8CFFAF4BB0F11F4E6 +:1050F00060FF1BC06F5F7F4F8F4F9F4F16C088238D +:1051000011F096E911C0772321F09EE8872F762FC2 +:1051100005C0662371F096E8862F70E060E02AF003 +:105120009A95660F771F881FDAF7880F96958795EF +:1051300097F90895990F0008550FAA0BE0E8FEEFC4 +:1051400016161706E807F907C0F012161306E4074B +:10515000F50798F0621B730B840B950B39F40A2644 +:1051600061F0232B242B252B21F408950A2609F422 +:10517000A140A6958FEF811D811D08950E94D12821 +:105180000C9442290E94342938F00E943B2920F0D7 +:10519000952311F00C942B290C94312911240C9493 +:1051A00076290E94532970F3959FC1F3950F50E023 +:1051B000551F629FF001729FBB27F00DB11D639FC9 +:1051C000AA27F00DB11DAA1F649F6627B00DA11D6F +:1051D000661F829F2227B00DA11D621F739FB00D15 +:1051E000A11D621F839FA00D611D221F749F332785 +:1051F000A00D611D231F849F600D211D822F762F1E +:105200006A2F11249F5750409AF0F1F088234AF0FA +:10521000EE0FFF1FBB1F661F771F881F9150504066 +:10522000A9F79E3F510580F00C942B290C94762908 +:105230005F3FE4F3983ED4F3869577956795B795ED +:10524000F795E7959F5FC1F7FE2B880F911D969507 +:10525000879597F9089597F99F6780E870E060E077 +:1052600008959FEF80EC089500240A9416161706FF +:1052700018060906089500240A9412161306140647 +:1052800005060895092E0394000C11F4882352F0AA +:10529000BB0F40F4BF2B11F460FF04C06F5F7F4F62 +:1052A0008F4F9F4F089557FD9058440F551F59F049 +:1052B0005F3F71F04795880F97FB991F61F09F3F03 +:1052C00079F087950895121613061406551FF2CF2C +:1052D0004695F1DF08C0161617061806991FF1CF7C +:1052E00086957105610508940895E894BB276627A3 +:1052F0007727CB0197F90895DC01CB01FC01F999DF +:10530000FECF06C0F2BDE1BDF89A319600B40D9211 +:1053100041505040B8F70895DC01A40FB51F41502B +:10532000504048F0CB01840F951F2E910E949D297B +:1053300041505040D0F70895262FF999FECF92BDE5 +:1053400081BDF89A019700B4021639F01FBA20BD4A +:105350000FB6F894FA9AF99A0FBE0895052E97FBA6 +:105360001EF400940E94C52957FD07D00E94E02931 +:1053700007FC03D04EF40C94C52950954095309508 +:1053800021953F4F4F4F5F4F0895909580957095B1 +:1053900061957F4F8F4F9F4F08950E94022AA59FCE +:1053A000900DB49F900DA49F800D911D1124089520 +:1053B000B7FF0C94CD290E94CD29821B930B089531 +:1053C000A1E21A2EAA1BBB1BFD010DC0AA1FBB1F09 +:1053D000EE1FFF1FA217B307E407F50720F0A21B7B +:1053E000B30BE40BF50B661F771F881F991F1A94E8 +:1053F00069F760957095809590959B01AC01BD0112 +:10540000CF010895A29FB001B39FC001A39F700D6B +:10541000811D1124911DB29F700D811D1124911DBC +:1054200008955058BB27AA270E94292A0C94422984 +:105430000E94342938F00E943B2920F039F49F3F24 +:1054400019F426F40C9431290EF4E095E7FB0C9442 +:105450002B29E92F0E94532958F3BA1762077307C3 +:105460008407950720F079F4A6F50C9475290EF4BD +:10547000E0950B2EBA2FA02D0B01B90190010C0164 +:10548000CA01A0011124FF27591B99F0593F50F47C +:10549000503E68F11A16F040A22F232F342F4427D4 +:1054A000585FF3CF469537952795A795F0405395CC +:1054B000C9F77EF41F16BA0B620B730B840BBAF09C +:1054C0009150A1F0FF0FBB1F661F771F881FC2F707 +:1054D0000EC0BA0F621F731F841F48F4879577951B +:1054E0006795B795F7959E3F08F0B0CF9395880FD5 +:1054F00008F09927EE0F9795879508950E94922AB4 +:105500000C9442290E943B2958F00E94342940F013 +:1055100029F45F3F29F00C942B2951110C94762922 +:105520000C9431290E94532968F39923B1F3552330 +:1055300091F3951B550BBB27AA27621773078407A6 +:1055400038F09F5F5F4F220F331F441FAA1FA9F33C +:1055500035D00E2E3AF0E0E832D091505040E6952A +:10556000001CCAF72BD0FE2F29D0660F771F881F8B +:10557000BB1F261737074807AB07B0E809F0BB0B7E +:10558000802DBF01FF2793585F4F3AF09E3F510592 +:1055900078F00C942B290C9476295F3FE4F3983E25 +:1055A000D4F3869577956795B795F7959F5FC9F77B +:1055B000880F911D9695879597F90895E1E0660FFC +:1055C000771F881FBB1F621773078407BA0720F075 +:1055D000621B730B840BBA0BEE1F88F7E0950895DE +:1055E0000E94F72A6894B1110C94762908950E94BC +:1055F0005B2988F09F5798F0B92F9927B751B0F0E1 +:10560000E1F0660F771F881F991F1AF0BA95C9F746 +:1056100014C0B13091F00E947529B1E008950C9446 +:105620007529672F782F8827B85F39F0B93FCCF3F9 +:10563000869577956795B395D9F73EF490958095C3 +:10564000709561957F4F8F4F9F4F08950E949A28C4 +:1056500008F48FEF08950E949A28880B990B0895FB +:1056600097FB072E16F4009407D077FD09D00E940F +:105670004A2B07FC05D03EF4909581959F4F0895E5 +:10568000709561957F4F0895EE0FFF1F0590F4917F +:10569000E02D0994AA1BBB1B51E107C0AA1FBB1F29 +:1056A000A617B70710F0A61BB70B881F991F5A95AE +:1056B000A9F780959095BC01CD01089581E090E017 +:1056C000F8940C947B2BFB01DC0102C001900D923D +:1056D00041505040D8F70895FB01DC014150504043 +:1056E00048F001900D920020C9F701C01D92415071 +:0A56F0005040E0F70895F894FFCF52 +:1056FA00FFFFFF00FCE1A8A8DD0F180B001E830BBB +:10570A00E51D540B420B380B291E9D0B013C000171 +:10571A0001B00D4B1EFFFF8D078D070000CF0480DF +:10572A00000100000000000000C4077005090CC356 +:10573A000720083808AB07AAB406010000000000D9 +:10574A00000000000000FFFF05AB00000000060695 +:10575A0070059D055306CE05AC05C0050000000086 +:10576A0057097005090C080C65080D0A006E616E70 +:10577A0000696E66006F766600322E332E31006C39 +:10578A006F6F70636F756E7465723A00736D6172D4 +:06579A0074686F6D6500EC +:00000001FF diff --git a/code/Dust_sensor/Dust_sensor.ino b/code/Dust_sensor/Dust_sensor.ino new file mode 100644 index 0000000..fa180fb --- /dev/null +++ b/code/Dust_sensor/Dust_sensor.ino @@ -0,0 +1,607 @@ +/* +* Candle fine dust sensor +* +* Often the air in our homes is much dirtier than the air outside. This fine dust sensor can help you gain insight into the quality of he air inside your home. +* +* It is built around the SDS011 fine dust sensor. It's used here because we can directly connect to it without needing to solder anything onto it. +* +* Sensors like can output 'particle count per cubic meter' or 'micrograms per cubic meter. This sensor does the latter. +* +* The most popular particle size to measure is 2,5 micrometers. These particles can enter deep inside your lungs. Some dust sensors can also mearure other 'bins', such as 1, 5 or 10 micrometers. This sensors can also give us the weight of the 10 micrometer particles. This weight includes the weight of the smaller sizes particles.. +* +* +* SETTINGS */ + + +#define MEASUREMENT_INTERVAL 60 // Seconds between measurements. How many seconds between measurements? Recommended is at least 120 seconds. The minimum is 15 seconds. + +#define HAS_DISPLAY // Did you connect an OLED display? If you have connected a small OLED dislay it will show the latest measurements. + +//#define SHOW_DATAVIZ // Show a basic datavizualisation on the display? This vizualisation is experimental and far from perfect, but might be fun to try. + +#define ALLOW_CONNECTING_TO_NETWORK // Connect wirelessly. Is this device allowed to connect to the network? For privacy or security reasons you may prefer a stand-alone device. If you do allow the device to connect, you can connect a toggle switch to pin 6 to change the connection state at any time. + +//#define ALLOW_FAKE_DATA // Allow fake data to be sent? This is an experimental feature, and requires you to attach a switch to pin 5. It's designed to make the sensor less intrusive in some social situations, allowing you to pretend you are not smoking/cooking. + +//#define MY_REPEATER_FEATURE // Act as signal repeater. Should this sensor act as a repeater for your other devices? This can help the signal spread further. + +#define RF_NANO // RF-Nano. Check this box if you are using the RF-Nano Arduino, which has a built in radio. The Candle project uses the RF-Nano. + + +/* END OF SETTINGS +* +* +* +*/ + +//#define MY_DEBUG // Enable MySensors debug output to the serial monitor? This will help you check if the radio is working ok. + + +#define AVERAGE_HOURS 1 // Averaging period. Over how many hours should the average be calculated? If the device has been on shorter than this period, it will show the average until then. + + +// PINS +#define DUST_SENSOR_RX_PIN 3 // Dust sensor RX pin. Connect this to the TX pin on the sensor. +#define DUST_SENSOR_TX_PIN 4 // Dust sensor TX pin. Connect this to the RX pin on the sensor. +#define TOGGLE_FAKE_DATA_PIN 5 // Pin where the toggle switch to send fake data is connected. +#define CONNECT_TO_NETWORK_PIN 6 // Pin where the toggle switch to allow connecting to the network is connected. +#define RANDOM_SEED_PIN A7 // Pin to use to create more random variables. + +#ifdef RF_NANO +// If you are using an RF-Nano, you have to switch CE and CS pins. +#define MY_RF24_CS_PIN 9 // Used by the MySensors library. +#define MY_RF24_CE_PIN 10 // Used by the MySensors library. +#endif + + +// Enable and select the attached radio type +#define MY_RADIO_RF24 // This is a common and simple radio used with MySensors. Downside is that it uses the same frequency space as WiFi. +//#define MY_RADIO_NRF5_ESB // This is a new type of device that is arduino and radio all in one. Currently not suitable for beginners yet. +//#define MY_RADIO_RFM69 // This is an open source radio on the 433mhz frequency. Great range and built-in encryption, but more expensive and little more difficult to connect. +//#define MY_RADIO_RFM95 // This is a LoRaWan radio, which can have a range of 10km. + +// MySensors: Choose your desired radio power level. High power can cause issues on cheap Chinese NRF24 radio's. +//#define MY_RF24_PA_LEVEL RF24_PA_MIN +//#define MY_RF24_PA_LEVEL RF24_PA_LOW +//#define MY_RF24_PA_LEVEL RF24_PA_HIGH +#define MY_RF24_PA_LEVEL RF24_PA_MAX + +// Mysensors advanced security +#define MY_ENCRYPTION_SIMPLE_PASSWD "smarthome" // Be aware, the length of the password has an effect on memory use. +//#define MY_SIGNING_SOFT_RANDOMSEED_PIN A7 // Setting a pin to pickup random electromagnetic noise helps make encryption more secure. + +// Mysensors advanced settings +#define MY_TRANSPORT_WAIT_READY_MS 10000 // Try connecting for 10 seconds. Otherwise just continue. +//#define MY_RF24_CHANNEL 100 // In EU the default channel 76 overlaps with wifi, so you could try using channel 100. But you will have to set this up on every device, and also on the controller. +#define MY_RF24_DATARATE RF24_1MBPS // Slower datarate makes the network more stable? +//#define MY_NODE_ID 10 // Giving a node a manual ID can in rare cases fix connection issues. +//#define MY_PARENT_NODE_ID 0 // Fixating the ID of the gatewaynode can in rare cases fix connection issues. +//#define MY_PARENT_NODE_IS_STATIC // Used together with setting the parent node ID. Daking the controller ID static can in rare cases fix connection issues. +#define MY_SPLASH_SCREEN_DISABLED // Saves a little memory. +//#define MY_DISABLE_RAM_ROUTING_TABLE_FEATURE // Saves a little memory. + + + +#define RADIO_DELAY 150 // Milliseconds between sensing radio signals during the presentation phase. Gives the radio some time to breathe in between working, and time to listen to a response. +#define LOOPDURATION 1000 // The main loop runs every x milliseconds. It's like a second counter on a clock. + + +// LIBRARIES (in the Arduino IDE go to Sketch -> Include Library -> Manage Libraries to add these if you don't have them installed yet.) +#include // MySensors library +#include // "SDS011 sensor Library". Makes it easy to talk to the fine dust sensor. +#include // Watchdog library. Resets the device if it becomes unresponsive. + + +#ifdef HAS_DISPLAY + #define INCLUDE_SCROLLING 0 + #define OLED_I2C_ADDRESS 0x3C + #include // Simple drivers for the screen. + #include // "SSD1306Ascii". Simple drivers for the screen. + SSD1306AsciiAvrI2c oled; +#endif + + +// SDS011 dust sensor details +float p10 = 0; +float p25 = 0; +float average_p10 = 0; +float average_p25 = 0; + +SDS011 my_sds; + + +// Mysensors settings. +#define CHILD_ID_DUST_PM10 0 +#define CHILD_ID_DUST_PM25 1 +#define ACTIVATED_CHILD_ID 2 +MyMessage message_dust(CHILD_ID_DUST_PM10, V_LEVEL); // Sets up the message format for actual dust messages. +MyMessage message_prefix(CHILD_ID_DUST_PM10, V_UNIT_PREFIX); // Sets up the MySensors prefix message +MyMessage relaymsg(ACTIVATED_CHILD_ID, V_STATUS); // Toggle message + + + +// Other +unsigned long lastLoopTime = 0; // Holds the last time the main loop ran. +int loopCounter = MEASUREMENT_INTERVAL; // Count how many loops have passed. +int measurements_counter = 0; // Used by averaging function. +byte vizPosition = 30; // Used by the experimenal data vizualisation option. +boolean send_all_values = true; // If the controller asks the devive to re-present itself, then this is used to also resend all the current sensor values. +boolean received_echo = false; // If we get a response from the controller, then this is set to true. + +// Fake data feature +boolean sending_fake_data = false; // Experimental. Will allow a user to send fake data for a while. Useful in some social situations. +boolean desired_sending_fake_data = false; // If the user wants to change the state of sending fake data. +float p25_fakeness_range = 0; // How far of the last average the value can meander. +float p10_fakeness_range = 0; // How far of the last average the value can meander. +float p25_addition = 0; // Holds how much will actually be deviated from the average when generating a fake value. +float fakeness_proportion = 0; // How these two values relate. if one goes up, the other should also go up, but in proportion to it's own fakeness range. + +// Connection toggle feature +boolean desired_connecting_to_network = false; +boolean connecting_to_network = true; +boolean may_send_data = true; + +void presentation() +{ +#ifdef ALLOW_CONNECTING_TO_NETWORK + // Send the sketch version information to the gateway and Controller + sendSketchInfo(F("Fine dust sensor"), F("1.1")); + + // Register all child sensors with the gateway + present(CHILD_ID_DUST_PM10, S_DUST, F("10 micrometers & smaller")); delay(RADIO_DELAY); + present(CHILD_ID_DUST_PM25, S_DUST, F("2.5 micrometers")); delay(RADIO_DELAY); + present(ACTIVATED_CHILD_ID, S_BINARY, F("data transmission")); + + send_all_values = true; +#endif +} + + +void setup() +{ + my_sds.begin(DUST_SENSOR_RX_PIN, DUST_SENSOR_TX_PIN); + Serial.begin(115200); + Serial.println(F("Hello, I am a dust sensor")); + +#ifdef ALLOW_FAKE_DATA + pinMode(TOGGLE_FAKE_DATA_PIN, INPUT_PULLUP); + Serial.print(F("Toggle fake-data-mode using a switch on pin ")); Serial.println(TOGGLE_FAKE_DATA_PIN); +#endif + + +#ifdef HAS_DISPLAY + // Start the display (if there is one) + oled.begin(&Adafruit128x64, OLED_I2C_ADDRESS); + oled.setFont(Adafruit5x7); + + oled.ssd1306WriteCmd(SSD1306_DISPLAYON); + oled.setScroll(false); + oled.setCursor(0,0); + oled.print(F("FINE DUST")); + //delay(1000); +#endif + + +#ifdef ALLOW_CONNECTING_TO_NETWORK + // Check if there is a network connection + if(isTransportReady()){ + Serial.println(F("Connected to gateway!")); + +#ifdef HAS_DISPLAY + // Show connection icon on the display + oled.setCursor(80,0); + oled.print(F("W")); +#endif + + }else{ + Serial.println(F("! NO CONNECTION")); + } + +#ifdef HAS_DISPLAY + // Show data transmission icon on the display + oled.setCursor(70,0); + if(may_send_data){ // A small "T" icon on the screen reflects that data transmission is currently allowed. + oled.print(F("T")); + } + else{ + oled.print(F(" ")); + } +#endif + + +#else + Serial.println("This device will not connect to the network.") +#endif + + // Place labels on the screen +#ifdef HAS_DISPLAY + oled.setCursor(0,2); + oled.print(F("2.5:")); + oled.setCursor(0,5); + oled.print(F("10.0:")); +#endif + + wdt_enable(WDTO_8S); // Starts the watchdog timer. If it is not reset once every few seconds, then the entire device will automatically restart. + + //my_sds.wakeup(); +} + + +void send_values() +{ +#ifdef ALLOW_CONNECTING_TO_NETWORK + + send(message_prefix.setSensor(CHILD_ID_DUST_PM10).set( F("ug/m3") ),0); delay(RADIO_DELAY); + if(may_send_data){ + send(message_dust.setSensor(CHILD_ID_DUST_PM10).set(p10,1),0); delay(RADIO_DELAY); + } + send(message_prefix.setSensor(CHILD_ID_DUST_PM25).set( F("ug/m3") ),0); delay(RADIO_DELAY); + if(may_send_data){ + send(message_dust.setSensor(CHILD_ID_DUST_PM25).set(p25,1),0); delay(RADIO_DELAY); + } + send(relaymsg.setSensor(ACTIVATED_CHILD_ID).set(may_send_data)); wait(RADIO_DELAY); + +#endif +} + + +void loop() { + // Send all the child states to the controller. This will initialise things there. + if( send_all_values ){ +#ifdef DEBUG + Serial.println(F("Sending all values")); +#endif + send_all_values = false; + send_values(); + } + + + + +#ifdef ALLOW_FAKE_DATA + boolean fake_data_pin_state = digitalRead(TOGGLE_FAKE_DATA_PIN); + if( fake_data_pin_state != desired_sending_fake_data ){ + desired_sending_fake_data = fake_data_pin_state; + Serial.print(F("FAKE DATA TOGGLED TO ")); Serial.println(desired_sending_fake_data); +#ifdef HAS_DISPLAY + oled.set1X(); + oled.setCursor(72,0); + if( desired_sending_fake_data ){ + oled.print(F("F")); + } + else{ + oled.print(F(" ")); + } +#endif + wait(20); + } +#endif + + +#ifdef ALLOW_CONNECTING_TO_NETWORK + if( digitalRead(CONNECT_TO_NETWORK_PIN) != connecting_to_network ){ + + //connecting_to_network = !desired_connecting_to_network; + wait(10); + connecting_to_network = digitalRead(CONNECT_TO_NETWORK_PIN); + Serial.print(F("NETWORK TOGGLED TO ")); Serial.println(connecting_to_network); + +#ifdef HAS_DISPLAY + if(!connecting_to_network){ // If we should not connect to the network, remove the W icon. + oled.set1X(); + oled.setCursor(80,0); + oled.print(F(" ")); + } +#endif + wait(10); // Avoid bounce + } +#endif + + + // + // HEARTBEAT LOOP + // runs every second (or as long as you want). By counting how often this loop has run (and resetting that counter back to zero after a number of loops), it becomes possible to schedule all kinds of things without using a lot of memory. + // The maximum time that can be scheduled is 255 * the time that one loop takes. So usually 255 seconds. + // + unsigned long currentMillis = millis(); + + if (currentMillis - lastLoopTime > LOOPDURATION) { + lastLoopTime = currentMillis; + loopCounter++; + Serial.print("loopcounter:"); Serial.println(loopCounter); + if(loopCounter > MEASUREMENT_INTERVAL){ + Serial.println(); Serial.println(F("__starting__")); + loopCounter = 0; + } + wdt_reset(); + +#ifdef HAS_DISPLAY + // Update the second countdown on the display. + oled.set1X(); + oled.setCursor(100,0); + oled.print(MEASUREMENT_INTERVAL - loopCounter); + oled.clearToEOL(); +#endif + + + // schedule + switch (loopCounter) { + + case 1: // On the first second + //if(MEASUREMENT_INTERVAL > 29){ // Only uses the sleep-and-wake functionality if there is at least 30 seconds between measurements. + Serial.println(F("Sensor waking up")); + my_sds.wakeup(); + //} + break; + + case 10: + Serial.println(F("Asking for fresh data")); + my_sds.read(&p25, &p10); + break; + + case 11: // On the 11th second (after the fan has been spinning for 10 seconds) + Serial.println(F("Asking for fresh data again")); + while (!my_sds.read(&p25, &p10)) + { + Serial.println(F("Waiting for data")); + delay(10); + } + +#ifdef HAS_DISPLAY + // update the display + + oled.set2X(); + oled.setCursor(0,3); + oled.print(p25); oled.println(F(" ")); + oled.setCursor(0,6); + oled.print(p10); oled.println(F(" ")); + + + + // PM2.5 levels based on opinions of Dutch scientists and the World Health Organization. Keep your yearly average below 10. + oled.setCursor(70,3); + if(sending_fake_data){oled.print(F("FAKED"));} + else if (p25 == 0){ oled.clearToEOL(); } + else if (p25 <= 3){ oled.print(F("GREAT"));} + else if (p25 <= 5){ oled.print(F("GOOD "));} + else if (p25 <= 8){ oled.print(F("OK "));} + else if (p25 <= 14){ oled.print(F("POOR "));} + else if (p25 > 20){ oled.print(F("BAD "));} + + // PM10 levels based on opinions of Dutch scientists and the World Health Organization. Keep your yearly average below 20. + oled.setCursor(70,6); + if(sending_fake_data){oled.print(F("FAKED"));} + else if (p10 == 0){ oled.clearToEOL(); } + else if (p10 <= 5){ oled.print(F("GREAT"));} + else if (p10 <= 10){ oled.print(F("GOOD "));} + else if (p10 <= 20){ oled.print(F("OK "));} + else if (p10 <= 30){ oled.print(F("POOR "));} + else if (p10 > 30){ oled.print(F("BAD "));} +#endif + + if( MEASUREMENT_INTERVAL > 29 ){ // Only goes to sleep if there is a long enough interval between desired measurements. + Serial.println(F("Sensor going to sleep.")); + my_sds.sleep(); + } + break; + + case 12: // On the 12th second we send the first bit of data + received_echo = false; // If all goes well this will be reset to 'true' when the controller acknowledges that it has received the first message. +#ifdef ALLOW_CONNECTING_TO_NETWORK + + if( desired_sending_fake_data == true && sending_fake_data == false ){ + + if( average_p25 != 0 && p25 != average_p25 && average_p10 != 0 && p10 != average_p10 ){ + // We have good enough measurements to create fake data. + + // Determine the fakeness range: how far from the last average newly generated values may meander. + /*if( p25 > average_p25){ + p25_fakeness_range = p25 - average_p25; + } + else if ( p25 < average_p25){ + p25_fakeness_range = average_p25 - p25; + } + + if( p10 > average_p10){ + p10_fakeness_range = p10 - average_p10; + } + else if ( p10 < average_p10){ + p10_fakeness_range = average_p25 - p25; + } + */ + p25_fakeness_range = p25 - average_p25; + p10_fakeness_range = p10 - average_p10; + + if( p25_fakeness_range < 0 ){ + p25_fakeness_range = -p25_fakeness_range; + } + if( p10_fakeness_range < 0 ){ + p10_fakeness_range = -p10_fakeness_range; + } + //fakeness_proportion = (float) p10_fakeness_range / p25_fakeness_range; // Usually the p10 values will be slightly bigger. + fakeness_proportion = (float) p10 / p25; // Usually the p10 values will be slightly bigger. + + randomSeed(analogRead(RANDOM_SEED_PIN)); // Creates better random values. + Serial.print(F("Starting sending fake data. \n-P25 range: ")); Serial.println(p25_fakeness_range); + Serial.print(F("-p10 range: ")); Serial.println(p10_fakeness_range); + Serial.print(F("-proportion: ")); Serial.println(fakeness_proportion); + if(p25_fakeness_range != 0){ + sending_fake_data = true; + } + } +#ifdef DEBUG + else{ + Serial.println(F("Measurement not useful for intiating fake data.")); + } +#endif + } + if( desired_sending_fake_data == false && sending_fake_data == true ){ + Serial.print(F("Will send real data again.")); + sending_fake_data = false; + } + + if(sending_fake_data){ + p25_addition = (float)random( p25_fakeness_range * 100000) / 100000; + if( random(2) ){ p25_addition = -p25_addition;} + Serial.print(F("2.5 Addition: ")); Serial.println(p25_addition); + p25_addition = average_p25 + p25_addition; + Serial.print(F("<< sending FAKE 2.5: ")); Serial.println(p25_addition); + send(message_dust.setSensor(CHILD_ID_DUST_PM25).set(p25_addition,1),1); // This message asks the controller to send and acknowledgement it was received. + } + else{ + Serial.print(F("<< sending 2.5: ")); Serial.println(p25); + send(message_dust.setSensor(CHILD_ID_DUST_PM25).set(p25,1),1); // This message asks the controller to send and acknowledgement it was received. + } +#endif + break; + + case 13: // On the 13th second we send the second bit of data, and check the network connection. +#ifdef ALLOW_CONNECTING_TO_NETWORK + if(sending_fake_data){ // Now creating fake data for P10. It should generally move in the same direction as the p25. + float p10_addition = (float) (p10_fakeness_range * fakeness_proportion); // + (p10_fakeness_range / random(4,8)); + //float addition = (float)random( p25_fakeness_range * 100000) / 100000; + //if( random(2) ){ p10_addition = p10_addition ; } + Serial.print(F("p10_addition = ")); Serial.println(p10_addition); + p10_addition = p10_addition + average_p10; + Serial.print(F("<< sending FAKE 10.0: ")); Serial.println(p10_addition); + if(may_send_data){ + send(message_dust.setSensor(CHILD_ID_DUST_PM25).set(p10_addition,1),1); // This message asks the controller to send and acknowledgement it was received. + } + } + else{ + Serial.print(F("-> sending 10.0: ")); Serial.println(p10); + if(may_send_data){ + send(message_dust.setSensor(CHILD_ID_DUST_PM10).set(p10,1),0); + } + } +#endif + +#ifdef HAS_DISPLAY + oled.set1X(); + oled.setCursor(80,0); +#endif + + if( received_echo == true ){ + Serial.println(F("Connection to controller is ok.")); +#ifdef HAS_DISPLAY + oled.print(F("W")); // Add W icon +#endif + } + else { + Serial.println(F("No connection to controller!")); +#ifdef HAS_DISPLAY + oled.print(F(" ")); // Remove W icon +#endif + } + + + break; + + case 14: // Calculating averages + // Still thinking how to optimally deal with outliers and/or early mis-measurements: + if(measurements_counter * MEASUREMENT_INTERVAL < AVERAGE_HOURS * 3600){ // This limits how strongly the old values influence the new average. + measurements_counter++; + } + + if(!sending_fake_data){ + average_p25 = average(measurements_counter, average_p25, p25); + average_p10 = average(measurements_counter, average_p10, p10); + } + else{ + Serial.print(F("Sending fake data, so average is not changing.")); + } + + Serial.print(F("Average p2.5: ")); Serial.println(average_p25); + Serial.print(F("Average p10: ")); Serial.println(average_p10); + + // Data vizualisation experiment +#if defined(HAS_DISPLAY) && defined(SHOW_DATAVIZ) + // This is an experimental way to show a basic datavizualisation using only the characters available in this display library. + if(vizPosition > 60 ){vizPosition = 30;} + //Serial.print(F("Dataviz x position: ")); Serial.println(vizPosition); + oled.set1X(); + oled.setCursor(vizPosition,1); + if(p25 < 1 || vizPosition == 1){oled.print(F(" "));} + else if(p25 < 2){oled.print(F("_"));} + else if(p25 < 3){oled.print(F("/"));} + else if(p25 < 4){oled.print(F("4"));} // This one isn't perfect.. + else if(p25 < 5){oled.print(F("+"));} + else if(p25 < 6){oled.print(F("t"));} + else if(p25 < 7){oled.print(F("~"));} + else {oled.print(F("'"));} + vizPosition++; + oled.setCursor(vizPosition,1); + oled.print(F(" ")); +#endif + break; + } + } +} + + +float average(int measurements, float old_average, float new_value){ + if(measurements < 2){ + return new_value; + } + else if(measurements < 4){ + return (old_average + new_value) / 2; + } + else if(measurements >= 4){ + float totally = (measurements - 1) * old_average; + return (totally + new_value) / measurements; + } +} + +void receive(const MyMessage &message) +{ +#ifdef ALLOW_CONNECTING_TO_NETWORK + + + if (message.isAck()) { + Serial.println(F(">> Received acknowledgement")); + received_echo = true; + } + + if (message.type == V_STATUS && message.sensor == ACTIVATED_CHILD_ID ){ + may_send_data = message.getBool(); //?RELAY_ON:RELAY_OFF; + send(relaymsg.setSensor(ACTIVATED_CHILD_ID).set(may_send_data)); // We echo the new state to the controller, to say "we got the message". + Serial.print(F("-New may_send_data state: ")); Serial.println(may_send_data); +#ifdef HAS_DISPLAY + // Show connection icon on the display + oled.setCursor(70,0); + if(may_send_data){ // A small "T" icon on the screen reflects that data transmission is currently allowed. + oled.print(F("T")); + } + else{ + oled.print(F(" ")); + } +#endif + + } + +#endif +} + + + +/** This device uses the MySensors library: + * + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2015 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + ******************************* + */ diff --git a/code/Signal-hub/Signal-hub.arduino.avr.nano.elf b/code/Signal-hub/Signal-hub.arduino.avr.nano.elf new file mode 100644 index 0000000000000000000000000000000000000000..1abeccb0e8dc619db3f978c115fe1a4961564c69 GIT binary patch literal 163240 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 G-~R{8##3zo literal 0 HcmV?d00001 diff --git a/code/Signal-hub/Signal-hub.arduino.avr.nano.hex b/code/Signal-hub/Signal-hub.arduino.avr.nano.hex new file mode 100644 index 0000000..ffd3825 --- /dev/null +++ b/code/Signal-hub/Signal-hub.arduino.avr.nano.hex @@ -0,0 +1,1547 @@ +:100000000C941C040C945E260C9437260C948526C4 +:100010000C9485260C9485260C94FD260C9444049F +:100020000C9444040C9444040C9444040C94440430 +:100030000C9444040C9444040C9444040C94440420 +:100040000C94ED250C9444040C94BB250C9495253C +:100050000C9444040C9444040C9444040C94440400 +:100060000C9444040C9444042D416464696E67202C +:10007000746F20706C61796C697374002D526571B6 +:10008000756573746564207374617475733A2000C8 +:100090002D41636B00494E434F4D494E47204D451E +:1000A000535341474520666F72206368696C642032 +:1000B0002300637C777BF26B6FC53001672BFED723 +:1000C000AB76CA82C97DFA5947F0ADD4A2AF9CA4E1 +:1000D00072C0B7FD9326363FF7CC34A5E5F171D851 +:1000E000311504C723C31896059A071280E2EB273F +:1000F000B27509832C1A1B6E5AA0523BD6B329E362 +:100100002F8453D100ED20FCB15B6ACBBE394A4C41 +:1001100058CFD0EFAAFB434D338545F9027F503CC1 +:100120009FA851A3408F929D38F5BCB6DA2110FFED +:10013000F3D2CD0C13EC5F974417C4A77E3D645DEA +:10014000197360814FDC222A908846EEB814DE5E77 +:100150000BDBE0323A0A4906245CC2D3AC629195CB +:10016000E479E7C8376D8DD54EA96C56F4EA657A07 +:10017000AE08BA78252E1CA6B4C6E8DD741F4BBDA8 +:100180008B8A703EB5664803F60E613557B986C155 +:100190001D9EE1F8981169D98E949B1E87E9CE5572 +:1001A00028DF8CA1890DBFE6426841992D0FB0541C +:1001B000BB1648656C6C6F2C204920616D20612056 +:1001C0005369676E616C204875622E0021204E4F86 +:1001D000434F4E4E454354494F4E00486900436FCC +:1001E0006E6E656374656420746F206761746577F3 +:1001F000617921000402FFFFEF030402EF446574FC +:1002000065637465642020005265706C61792020FC +:10021000202000446576696365207374617475738A +:1002200000312E31005369676E616C2048756200A1 +:100230002C005061747465726E3A20002020444591 +:10024000433A2000203E204845583A2000580031CB +:1002500000300043616E6E6F742068616E646C657F +:100260002074686973207369676E616C002C005399 +:1002700069676E616C2073746F726564204F4B0008 +:10028000207E7E3E2000456E6F756768207370612A +:100290006365206C656674005F5F53746F72696E8E +:1002A00067003E00656E746572696E672064656CF8 +:1002B00065746520414C4C206D656E7500656E74EB +:1002C0006572696E672064656C657465206C617326 +:1002D00074206D656E7500656E746572696E672059 +:1002E0006D656E755F6E657700042000FFEF5F5FE0 +:1002F0004D454E55004D4F52453E002C204F6666F1 +:10030000002C204F6E002D416464696E6720746F6D +:1003100020706C61796C6973743A0045524153499D +:100320004E472053544F524544205349474E414C69 +:10033000204441544100030600EF2D6E65772023D1 +:1003400000506C6179696E67207369676E616C201B +:1003500066726F6D20706C61796C69737420230014 +:100360004C6F77207175616C697479207369676E61 +:10037000616C004E6F20726570656174696E6720F4 +:100380007061727420666F756E64004572726F7270 +:100390002073746F72696E67207369676E616C0099 +:1003A0004572726F722073746F72696E6720736921 +:1003B000676E616C004F4B0046696E6973686564D7 +:1003C00020636F7079696E67004E6F7720706C6183 +:1003D0007920746865204F4646207369676E616CAA +:1003E00000204E6F7720706C6179204F4646207355 +:1003F00069676E616C0053746174652000446574B4 +:1004000065637465642061206B6E6F776E2073691D +:10041000676E616C004D4154434800436F6D7061DD +:1004200072696E670020746F200053454E443A2075 +:10043000546F67676C6520004D6174636800071135 +:10044000204F4E2020EF0711204F464620EF071186 +:1004500020504C4159EF44656C6574696E67206C9F +:100460006173742073746F726564207369676E6161 +:100470006C004F4B005245504C4159494E4700418A +:100480006E6F6D616C7920696E7369646500506C84 +:100490006179696E672E2E005F5F7265706C61799D +:1004A000696E675F0007117700200000EF07114DAC +:1004B000454E5520EF04200000EF07114D4F5245E7 +:1004C0003EEFFF43414E43454C000000000000005A +:1004D000000000000000001E4E6577207369676E03 +:1004E000616C000000000000000000002844656C02 +:1004F000657465206C6173740000000000000000EA +:10050000003244656C65746520616C6C000000000D +:100510000000000000001F44657465637420736967 +:100520006E676C6500000000000000204465746583 +:100530006374206F6E202B206F6666000000000041 +:10054000215265706C61792073696E676C6500007B +:100550000000000000225265706C6179206F6E20EF +:100560002B206F666600000000001F5265616C6CF6 +:10057000792064656C657465206C61737400001F7C +:100580005265616C6C792064656C65746520414CC2 +:100590004C0000000150726F63657373696E6700F1 +:1005A000000000000000000000025369676E616CEB +:1005B000206D6174636865642100000000000352CF +:1005C00065706C6179696E672000000000000000B2 +:1005D000000000045369676E616C207761732073BB +:1005E000746F72656400000005426164207369677E +:1005F0006E616C2074727920616761696E064F7557 +:1006000074206F662073746F726167652073706108 +:10061000636507506C617920746865207369676E43 +:10062000616C000000000008506C6179204F4E2082 +:100630007369676E616C00000000000009506C6116 +:1006400079204F4646207369676E616C0000000098 +:10065000000A44656C65746564206C617374000005 +:100660000000000000000B44656C65746564206147 +:100670006C6C0000000000000000007468726F776E +:10068000696E672061776179206C656674206F768A +:10069000657220746F7563685F73637265656E5F02 +:1006A00073657269616C20627974653A00546F7584 +:1006B00063682073637265656E20646964206E6F81 +:1006C0007420726573706F6E6420746F20636F6D39 +:1006D0006D616E64000306FFEF52096AD53036A5DE +:1006E00038BF40A39E81F3D7FB7CE339829B2FFF69 +:1006F00087348E4344C4DEE9CB547B9432A6C223B4 +:100700003DEE4C950B42FAC34E082EA16628D92423 +:10071000B2765BA2496D8BD12572F8F66486689833 +:1007200016D4A45CCC5D65B6926C704850FDEDB9F2 +:10073000DA5E154657A78D9D8490D8AB008CBCD34C +:100740000AF7E45805B8B34506D02C1E8FCA3F0FF0 +:1007500002C1AFBD0301138A6B3A9111414F67DCAF +:10076000EA97F2CFCEF0B4E67396AC7422E7AD35DB +:1007700085E2F937E81C75DF6E47F11A711D29C54E +:10078000896FB7620EAA18BE1BFC563E4BC6D279C3 +:10079000209ADBC0FE78CD5AF41FDDA8338807C746 +:1007A00031B11210592780EC5F60517FA919B54A09 +:1007B0000D2DE57A9F93C99CEFA0E03B4DAE2AF545 +:1007C000B0C8EBBB3C83539961172B047EBA77D634 +:1007D00026E169146355210C7D00000000240027E8 +:1007E000002A0000000008000201000003040700C6 +:1007F0000000000000000000000000230026002987 +:100800000000000000250028002B0004040404045C +:1008100004040402020202020203030303030301AD +:100820000204081020408001020408102001020484 +:10083000081020003B2A722C11241FBECFEFD8E0F5 +:10084000DEBFCDBF11E0A0E0B1E0EAE2F0E602C019 +:1008500005900D92AA36B107D9F725E0AAE6B1E0D6 +:1008600001C01D92A63CB207E1F714E0CBE1D4E051 +:1008700004C02197FE010E94EA2FCA31D107C9F7AF +:100880000E94932B0C9408300C940000E8E4F3E0F1 +:10089000A089B18982E08C93A485B5851C92A68538 +:1008A000B78580E18C93108EA489B58986E08C93FE +:1008B000A289B3898C9180618C93A289B3898C9130 +:1008C00088608C93A289B3898C9180688C9302880C +:1008D000F389E02D80818F7D80830895DB01FC0109 +:1008E000242F3C91308311963C91119731831296BD +:1008F0003C911297328313963C9113973383245083 +:1009000014963496243068F72CEF240F26952695FC +:1009100030E02F5F3F4F220F331F220F331F4370F2 +:10092000DB01A20FB31FFC01E20FF31F415018F0CF +:100930008D918193FBCF0895AF92BF92CF92DF92BA +:10094000EF92FF920F931F93CF93DF936C017B0184 +:100950008B01040F151FEB015E01AE18BF08C01715 +:10096000D10759F06991D601ED91FC910190F08188 +:10097000E02DC6010995892B79F7C501DF91CF914B +:100980001F910F91FF90EF90DF90CF90BF90AF90AD +:100990000895FC01538D448D252F30E0842F90E085 +:1009A000821B930B541710F0CF960895019708956A +:1009B000FC01918D828D981761F0A28DAE0FBF2F33 +:1009C000B11D5D968C91928D9F5F9F73928F90E089 +:1009D00008958FEF9FEF0895FC01918D828D9817F8 +:1009E00031F0828DE80FF11D858D90E008958FEF35 +:1009F0009FEF0895FC01918D228D892F90E0805CFE +:100A00009F4F821B91098F739927089588E493E083 +:100A10000E94FA0421E0892B09F420E0822F089536 +:100A2000FC01A48DA80FB92FB11DA35ABF4F2C9163 +:100A3000848D90E001968F739927848FA689B7895A +:100A40002C93A089B1898C91837080648C93938D51 +:100A5000848D981306C00288F389E02D80818F7DF4 +:100A600080830895EF92FF920F931F93CF93DF93AC +:100A7000EC0181E0888F9B8D8C8D98131AC0E889DA +:100A8000F989808185FF15C09FB7F894EE89FF89A9 +:100A90006083E889F98980818370806480839FBF47 +:100AA00081E090E0DF91CF911F910F91FF90EF9047 +:100AB0000895F62E0B8D10E00F5F1F4F0F73112757 +:100AC000E02E8C8D8E110CC00FB607FCFACFE88992 +:100AD000F989808185FFF5CFCE010E941005F1CF05 +:100AE000EB8DEC0FFD2FF11DE35AFF4FF0829FB706 +:100AF000F8940B8FEA89FB8980818062CFCF0F93B6 +:100B00001F93CF93DF938C01D0E0C0E0F801EC0F8E +:100B1000FD1F6491662341F088E493E00E94320552 +:100B2000892B11F02196F2CFCE01DF91CF911F9149 +:100B30000F910895CF93DF93EC01888D8823B9F04E +:100B4000AA89BB89E889F9898C9185FD03C08081D8 +:100B500086FD0DC00FB607FCF7CF8C9185FFF2CF55 +:100B6000808185FFEDCFCE010E941005E9CFDF9196 +:100B7000CF91089580E090E0892B29F00E9406052E +:100B800081110C940000089590E0FC01ED51F84FA4 +:100B90002491FC01E15EF74F3491FC01E55FF74FD2 +:100BA000E491EE23C9F0222339F0233001F1A8F4B7 +:100BB000213019F1223029F1F0E0EE0FFF1FEF5F35 +:100BC000F74FA591B4918FB7F894EC91611126C0BD +:100BD00030953E233C938FBF08952730A9F02830ED +:100BE000C9F0243049F7809180008F7D03C0809147 +:100BF00080008F7780938000DFCF84B58F7784BDAE +:100C0000DBCF84B58F7DFBCF8091B0008F77809351 +:100C1000B000D2CF8091B0008F7DF9CF3E2BDACFDC +:100C2000CF93DF9390E0FC01E15EF74F2491855F65 +:100C3000974FFC0184918823C9F090E0880F991F99 +:100C4000FC01E752F84FA591B491FC01EF5FF74F1B +:100C5000C591D49161110DC09FB7F8948C912095E6 +:100C600082238C938881282328839FBFDF91CF9193 +:100C70000895623051F49FB7F8943C91822F80958B +:100C800083238C93E8812E2BEFCF8FB7F894EC91D0 +:100C90002E2B2C938FBFEACF3FB7F894809140035F +:100CA00090914103A0914203B091430326B5A89BC4 +:100CB00005C02F3F19F00196A11DB11D3FBFBA2FEE +:100CC000A92F982F8827BC01CD01620F711D811DAE +:100CD000911D42E0660F771F881F991F4A95D1F733 +:100CE00008952FB7F89460913C0370913D03809173 +:100CF0003E0390913F032FBF08950895209139033B +:100D000030913A032817390771F490913803809194 +:100D10003703981741F0E0913803F0E0E950FD4FB8 +:100D2000808190E008958FEF9FEF08950895EF92EE +:100D3000FF920F931F93CF93DF93DC015C96ED90AE +:100D4000FC905D97E114F10479F481E090E0139652 +:100D50009C938E93129790E080E0DF91CF911F914A +:100D60000F91FF90EF9008955196ED91FC9152975D +:100D700050968C915097982F90950FB75E962C9126 +:100D80005E97122F127021FD6095F8942081112337 +:100D900019F1282B2083E7012197F1F728E0462F4E +:100DA00050E0308160FF1AC0382B3083E701219773 +:100DB000F1F7BA0175956795215089F7112381F0F4 +:100DC0008081892380830FBF5C968D919C910197D0 +:100DD000F1F781E090E0C1CF2923DCCF3923E5CFC3 +:100DE0009081892BEFCF2091390330913A03281756 +:100DF000390771F4809137032091380390E0805CCB +:100E00009F4F821B910960E470E00E94B42F089507 +:100E100090E080E008952091390330913A0328173B +:100E20003907B9F49091380380913703981789F006 +:100E3000E0913803F0E0E950FD4F808120913803C4 +:100E400030E02F5F3F4F2F7333272093380390E01C +:100E500008958FEF9FEF089590E080E00895FC01E2 +:100E6000838187708860838384818F7180628483AB +:100E70006783CF010895E091E802F091E90230978D +:100E800021F00280F381E02D099408950F931F93C0 +:100E90000E9471060091EA021091EB022091EC028F +:100EA0003091ED02601B710B820B930B1F910F9120 +:100EB00008959C018091E8029091E90282179307BE +:100EC000F1F09091F2029F719093F2023093E90257 +:100ED0002093E802E091E802F091E902309721F0D6 +:100EE0000190F081E02D09950E9471066093EA025D +:100EF0007093EB028093EC029093ED020895809141 +:100F0000F202805E8093F202E5CF0F931F930E945E +:100F100046072091F3022077203779F000E117E2AD +:100F200020E030E0061717072807390758F48FE14B +:100F300091E01F910F910C94590700E61AEE20E002 +:100F400030E0F0CF1F910F9108958091F3028F70E0 +:100F5000863020F088E191E00C9459070895809143 +:100F6000F20284608093F2028091F3028078809391 +:100F7000F302E0919A01F0919B01309709F00994F6 +:100F80000895CF93C091F402CF3FA1F00E94710663 +:100F90006093EE027093EF028093F0029093F1025F +:100FA00080914603C813C093460384E191E0CF913A +:100FB0000C9459070E944607613D774081059105D1 +:100FC00068F08091F202803618F480E191E0EFCF72 +:100FD000877F8093F20288E191E0E9CFCF91089575 +:100FE000809144038F3F21F080E191E00C945907F8 +:100FF0000E944607613D77408105910550F0809140 +:10100000F202803618F48CE091E0F0CF88E091E0B5 +:10101000EDCF08950E944607613D77408105910517 +:1010200020F48091F20281FF17C0809145038F3F29 +:1010300049F08091F2028E7F8093F2028CE091E081 +:101040000C9459078091F202803618F488E191E0FF +:10105000F7CF88E091E0F4CF0895CF93DF93FC01C0 +:10106000EB01DA019C01205F3F4F88819C91892729 +:101070008083898111969C911197892781838A8128 +:1010800012969C911297892782838B8113969C914B +:10109000139789278383349624961496E217F307CF +:1010A00021F7DF91CF910895FC01DB019C01205FC6 +:1010B0003F4F80819C9189278083818111969C91EB +:1010C000119789278183828112969C911297892793 +:1010D0008283838113969C91139789278383349607 +:1010E0001496E217F30729F70895ECEAF1E08CE291 +:1010F00091E0DF019C011D9221503040E1F71092F8 +:101100002D0110922C018BE291E090932B018093A2 +:101110002A018FEF809329011092AB011092AA014E +:101120001092A50181E0809328011092A4010E94F1 +:101130004C066093A6017093A7018093A801909339 +:10114000A90108958F929F92AF92BF920F931F9320 +:10115000CF93DF93CDB7DEB7A1970FB6F894DEBF7C +:101160000FBECDBF19A2423008F44AE08E010F5DD8 +:101170001F4F842E912CB12CA12CA50194010E940B +:10118000C82FE62FB901CA01EA3044F5E05DD80165 +:10119000EE938D01232B242B252B79F790E080E013 +:1011A000109769F0FD0101900020E9F73197AF0138 +:1011B0004A1B5B0BBD0188E493E00E949C04A1964E +:1011C0000FB6F894DEBF0FBECDBFDF91CF911F9158 +:1011D0000F91BF90AF909F908F900895E95CD7CF0B +:1011E000CF92DF92EF92FF92CF93DF936B017C015E +:1011F0006DE288E493E00E943205EC0166277727D0 +:10120000CB016C197D098E099F094AE00E94A20852 +:101210008C0F9D1FDF91CF91FF90EF90DF90CF90CB +:101220000895BC01990F880B990B97FD0C94F00859 +:101230004AE00C94A20842E050E068E571E088E4DE +:1012400093E00C949C04CF93DF930E947F05EC0104 +:101250000E941B098C0F9D1FDF91CF9108950E9462 +:10126000460482EB91E00C942309CF93DF93682F1F +:1012700070E090E080E04AE00E94A208EC010E9449 +:101280001B098C0F9D1FDF91CF91089588E494E096 +:101290000E94F306892B51F088E494E00E940B072A +:1012A000682F88E493E00E943205F0CF0C941B096C +:1012B0001F93CF93DF93EC01162F0E944E2E181729 +:1012C00039F0612FCE01DF91CF911F910C94782ED0 +:1012D000DF91CF911F9108950C944E2E91E59CBD06 +:1012E00091E09DBD2A98E3E2F0E03197F1F78EBDE1 +:1012F00000000DB407FEFDCF8EB5FB019FEF4150FE +:10130000C8F0222361F09EBD00000DB407FEFDCFA2 +:101310008EB56115710599F380833196F0CFDF01A9 +:10132000119680818EBD00000DB407FEFDCF8EB5F5 +:10133000FD01E5CF2A9AE3E2F0E03197F1F7089555 +:10134000CF93DF931F92CDB7DEB7698320E041E0F2 +:10135000BE016F5F7F4F0E946E090F90DF91CF91AA +:1013600008958091F302982F9077903759F0982F35 +:1013700092959F709F5F97709295907F8F78892B41 +:101380008093F3028091F2028B7F8F7E8093F20232 +:1013900029986CE080E20C94A0096FE080E20E9442 +:1013A000A00960912E016F3F19F08AE20E94A00906 +:1013B000299A0895CF93C82F809344038F3F51F00B +:1013C00080932E0163E082E20E94A00961E081E245 +:1013D0000E94A0090E94CD096C2F90E080E00E943D +:1013E000662E81E0CF91089521E041E070E060E059 +:1013F0000C946E0920E040E070E060E00C946E090F +:10140000E2EFF2E08081877F8F7E80831092EE0290 +:101410001092EF021092F0021092F10244E050E0BC +:1014200070E060E084E493E00C943E2EEF92FF9233 +:101430000F931F93CF93DF93EC017B0180E0611545 +:10144000710531F0CB010E94DA2C8931910518F534 +:10145000082F10E09B819770980143E0220F331F03 +:101460004A95E1F7922B9B839C819F719C838823F3 +:1014700031F0A801B701CE0107960E94E32CFE01CE +:10148000E00FF11F1782CE01DF91CF911F910F91D5 +:10149000FF90EF90089589E1DBCF0F931F93CF93D7 +:1014A000DF93EC01E0E06115710551F0FB01019063 +:1014B0000020E9F73197E61BF70BE931F10500F55C +:1014C0000E2F10E08B818770980193E0220F331F5D +:1014D0009A95E1F7822B8B838C818F718C83EE231D +:1014E00029F0A801CE0107960E94F92FFE01E00F16 +:1014F000F11F1782CE01DF91CF911F910F910895B7 +:10150000E9E1DECFFC012481229526952770213068 +:1015100011F487810895211104C007960E948E2C32 +:10152000089580E00895CF92DF92EF92FF921F938B +:10153000CF93DF93EC0185E990E00E947F058E81D7 +:101540000E9435098C8184FF0BC080E990E0DF9117 +:10155000CF911F91FF90EF90DF90CF900C942309D3 +:101560008D818230B1F58CE790E00E947F05CE013D +:101570000E94820AC12CD12C7601C394811103C030 +:10158000C12CD12C76014AE0C701B6010E94A20805 +:101590000E941B098E818A508A35D8F4809191016E +:1015A0008630B8F488E690E00E94230920919101EA +:1015B00011E0120F10939101CE010E94820A9E81C8 +:1015C000212F30E025573E4F81110BC09950F90172 +:1015D0009083DF91CF911F91FF90EF90DF90CF909C +:1015E0000895955AF4CF2F923F924F925F926F9247 +:1015F0007F928F929F92AF92BF92CF92DF92EF92A3 +:10160000FF920F931F93CF93DF93CDB7DEB7A297CF +:101610000FB6F894DEBF0FBECDBFB82E8091440345 +:10162000FB018083138112FDEDC01695169516956A +:10163000195FF0914703F9A3F170FAA3412F11321A +:1016400008F040E250E08BE691E00E94F02F10920B +:10165000A3051092A4051092A5051092A60510925C +:10166000A7051092A8051092A9051092AA0510923C +:10167000AB051092AC051092AD051092AE0510921C +:10168000AF051092B0051092B1051092B2051092FC +:101690009B0510929C0510929D0510929E0510923C +:1016A0009F051092A0051092A1051092A20500E2DC +:1016B000902E113110F410E1912EE92CE294FFE00C +:1016C000EF22F12CABE6CA2EA1E0DA2E8E010F5EDE +:1016D0001F4FBBE1AB2EB60183EA95E00E94540890 +:1016E0008091A9049091AA04892B09F40BC14BEABB +:1016F00054E063EA75E0C8010E942D0888248394B1 +:10170000482D50E08091A9049091AA0448175907E8 +:101710000CF07AC09801DE0111966FE0362E7AE067 +:10172000572EE5E04E2EF801E40DF11D708084E0A7 +:10173000840D8F70482EF801E50DF11D808194E035 +:10174000950D9F70592EF801E30DF11D908164E015 +:10175000630D6F70362EF9016081E62FF0E0EE54D4 +:10176000FF4F7491E72DF0E0EE54FF4F6491E82FA6 +:10177000F0E0EE54FF4F8491E92FF0E0EE54FF4F7C +:101780009491672E660C77FD6A24E62FEE0F67FDB5 +:10179000EA25282E220C87FD2A24792E770C97FD26 +:1017A0007A24F62FF827F927F625FE27FC93F72F42 +:1017B000F827F927FE27F2251196FC931197672742 +:1017C00096272926272412962C9212978627682678 +:1017D000762413967C9213972C5F3F4F14960A172A +:1017E0001B0709F0A0CF94E0440F551F9A95E1F72D +:1017F00045555B4FBE016F5F7F4FC8010E942D08AA +:1018000083947ECF10E215CFE989F0E0EE54FF4FCC +:10181000E491E98BED89F0E0EE54FF4FE491ED8B1C +:10182000E98DF0E0EE54FF4FE491E98FED8DF0E0AB +:10183000EE54FF4FE491ED8F8A89EE89F0E0EE548B +:10184000FF4FE491EA8BEA8DF0E0EE54FF4FE49114 +:10185000EE8BEE8DF0E0EE54FF4FE491EA8FE82F2F +:10186000F0E0EE54FF4FE491EE8F8B89EB8DF0E0CA +:10187000EE54FF4FE491EB8BE82FF0E0EE54FF4F76 +:10188000E491EB8F8F89EF8DF0E0EE54FF4FE49100 +:10189000EF8BE82FF0E0EE54FF4FE491EF8F88A13B +:1018A000EC8DF0E0EE54FF4FE491E8A3E88DF0E01A +:1018B000EE54FF4FE491EC8FEC89F0E0EE54FF4FD3 +:1018C000E491E88FE82FF0E0EE54FF4FE491EC8BC9 +:1018D00084E0440F551F8A95E1F745555B4FB801E9 +:1018E00083EA95E00E942D0840E163EA75E0C601B5 +:1018F0000E946E04F0E1CF0ED11C81E0E81AF108DD +:1019000009F0E9CE299883E092E00197F1F76EE0C3 +:1019100080E20E94A0098BE891E00197F1F76B2D1E +:101920008AE20E94A0096B2D80E30E94A00981EE4B +:101930000E94FA09EFEFBE1619F0FAA180EAF11140 +:1019400080EB20E0492D6BE671E00E946E09299A38 +:10195000F12CE12C8FEF0E94FA09182F807321F4EB +:1019600081E0E81AF108B1F7299860E387E20E9464 +:10197000A00914FF03C081EE0E94FA090E94CD095C +:1019800015FF02C0E1E0E9A391E0FFEFBF1290E094 +:1019900089A18170892BA2960FB6F894DEBF0FBE85 +:1019A000CDBFDF91CF911F910F91FF90EF90DF900E +:1019B000CF90BF90AF909F908F907F906F905F90EF +:1019C0004F903F902F9008950F931F93CF938C01CA +:1019D000FC0182819091F20290FF04C08F3F51F58B +:1019E000CFEF04C0811116C0C0914503B8018C2F00 +:1019F0000E94F30A909145039C1313C09091F30247 +:101A0000811113C021E0290F2F70907F922B9093AA +:101A1000F30207C08F3F21F3B8010E94F30A882325 +:101A200019F3CF911F910F910895907F9093F30236 +:101A300081E0F7CF80E0F5CF2091F20222FD0C94F7 +:101A4000E40C80E008959091440390936804109210 +:101A5000690480936D0460936C0490916B04907E94 +:101A600090936B048F3F11F44BE551E0BA0187E688 +:101A700094E00E944D0A0C941C0D20914403FC013B +:101A80002183F8E06F9FB00111246160FC01248183 +:101A9000207F622B64832091E70220FD0C941C0DB3 +:101AA00080E008951F93CF93DF93CDB7DEB72B97D8 +:101AB0000FB6F894DEBF0FBECDBF0E944B158091CC +:101AC000440380936804109269041FEF10936D041F +:101AD0008BE080936C0480916B04807E83608093A4 +:101AE0006B0465E272E087E694E00E94160A0E94A9 +:101AF0001C0D809144038093680410926904109334 +:101B00006D048CE080936C0480916B04807E836014 +:101B100080936B0461E272E087E694E00E94160A0B +:101B20000E941C0D60E971E080E090E00E948C1240 +:101B300080914403809368041092690481E080934B +:101B40006D0484E280936C0480916B04807E8093AA +:101B50006B0463E172E087E694E00E94160A0E943B +:101B60001C0D60E971E080E090E00E948C1268E05A +:101B700072E0CE0101960E94D32C1AE08091A3015D +:101B800090E009961817190609F094F487E2810F7E +:101B90008887AE014F5F5F4F63E0812F0E94230D66 +:101BA00060E971E080E090E00E948C121F5FE6CF58 +:101BB0006DEF71E0CE0101960E94D32C14E6809166 +:101BC0009D019091A301891B990B8D599F4F181767 +:101BD000190609F094F48DEC810F8A87AE014F5FEE +:101BE0005F4F60E0812F0E94230D60E971E080E08B +:101BF00090E00E948C121F5FE2CF81E080931C0175 +:101C00002B960FB6F894DEBF0FBECDBFDF91CF91FC +:101C10001F910895FF920F931F93CF93DF93C7E611 +:101C2000D4E004E413E0F801808189831A82FF2460 +:101C3000FA94FE828FE08D838C81807E83608C831A +:101C40006AE571E0CE010E944D0A8B818770806148 +:101C50008B838C818F71806C8C8381E08F8318865D +:101C6000CE010E941C0D8FE00E9459124AE551E0FE +:101C700061E18FEF0E94230DF801808189831A8230 +:101C8000FE8286E08D838C81807E83608C8361817F +:101C9000CE010E942F070E941C0D86E00E9459125F +:101CA000DF91CF911F910F91FF900C94520D2F92C5 +:101CB0003F924F925F926F927F928F929F92AF92DC +:101CC000BF92CF92DF92EF92FF920F931F93CF9329 +:101CD000DF93CDB7DEB7E9970FB6F894DEBF0FBE3E +:101CE000CDBF26E02BAB1BE187E10E94F40980FD0C +:101CF000C1C33BA931503BAB332309F4BBC321E043 +:101D000041E070E060E080E60E946E09082F8132B9 +:101D100020F082EE0E94FA0900E021E0402F68E8FE +:101D200074E081E60E946E0960E487E20E94A009E7 +:101D30001092A3051092A4051092A5051092A60575 +:101D40001092A7051092A8051092A9051092AA0555 +:101D50001092AB051092AC051092AD051092AE0535 +:101D60001092AF051092B0051092B1051092B20515 +:101D700010929B0510929C0510929D0510929E0555 +:101D800010929F051092A0051092A1051092A20535 +:101D9000013108F463C182E090E09AAB89ABE8E8D6 +:101DA0002E2EE4E03E2EE9A9FAA93197FAABE9AB71 +:101DB000319609F471C140E1B101CE0181960E94D2 +:101DC0006E044091A9045091AA044115510509F4EB +:101DD00063C174E0440F551F7A95E1F745555B4F99 +:101DE000B101CE0141960E942D08E989F0E0E75249 +:101DF000F94FE491E98BED89F0E0E752F94FE49176 +:101E0000ED8BE98DF0E0E752F94FE491E98FED8D2C +:101E1000F0E0E752F94FE491ED8F8E8DEA8DF0E01E +:101E2000E752F94FE491EE8FEE89F0E0E752F94F77 +:101E3000E491EA8FEA89F0E0E752F94FE491EE8B02 +:101E4000E82FF0E0E752F94FE491EA8B8B89EB8DB4 +:101E5000F0E0E752F94FE491EB8BE82FF0E0E75226 +:101E6000F94FE491EB8F8F89EF8DF0E0E752F94F56 +:101E7000E491EF8BE82FF0E0E752F94FE491EF8F18 +:101E80008C89E88DF0E0E752F94FE491EC8BEC8D12 +:101E9000F0E0E752F94FE491E88FE8A1F0E0E75273 +:101EA000F94FE491EC8FE82FF0E0E752F94FE4911D +:101EB000E8A30091A9041FAA1EAA8FEF800FA82FE4 +:101EC000B0E0B9AFA8AF015009F4CDC048AD59ADED +:101ED000EEA9FFA94E1B5F0B64E0440F551F6A95E6 +:101EE000E1F745555B4FBE016F5E7F4FCE01019616 +:101EF0000E942D089E012F5F3F4F7901CE01419630 +:101F00009DAB8CABA5E0B0E0F7019081818132817F +:101F10002381792F770F97FD7127B82EBB0C87FD92 +:101F2000B126C32ECC0C37FDC126622F660F27FDCC +:101F30006127472F440F77FD41274B2C440CB7FEF8 +:101F400004C05B2D550F452E41269C2C990CC7FCD7 +:101F50009126A62EAA0C67FDA126D42EDD0C47FFE4 +:101F600004C0542F550FD52ED126542D550F47FCA4 +:101F70005127F92DFF0F97FCF127EA2DEE0FA7FC53 +:101F8000E127792E7D24582E5526832E8F26622E0A +:101F90006E264D2554259F26AE26E32FE727EB25F9 +:101FA000E427E525E925E625F0E0E752F94F3491ED +:101FB000ECA9FDA93083E22FEB25EC25E725E527E9 +:101FC000E825EA25F0E0E752F94FD490FD01EF70E3 +:101FD000FF2721E130E02C0F3D1FE20FF31FD082DD +:101FE0009C2596274927542695246924E62DF0E060 +:101FF000E752F94F6490FD013596EF70FF2721E11C +:1020000030E02C0F3D1FE20FF31F6082E82FE7271F +:10201000E627E7255E27E52FE825AE26EA2DF0E046 +:10202000E752F94FA490FD013A96EF70FF27E20FB7 +:10203000F31FA08294E0E90EF11C2CA93DA92C5FAE +:102040003F4F3DAB2CAB1496A531B10509F05CCFE9 +:102050008EA99FA901969FAB8EAB35CFA1E0B0E0D2 +:10206000BAABA9AB9CCE4BEA54E0BE016F5E7F4F8A +:10207000C1010E942D0863EA75E0C1010E94540865 +:1020800040E1BE016F5D7F4F83EA95E00E946E04E0 +:1020900090E1290E311C87CE30918B04832F837001 +:1020A000823009F021CE20918C04A22FA770EA2E55 +:1020B00000918D04F09089048091880440918A04F5 +:1020C0009091F30290689093F30290914403491326 +:1020D00076C1832F8695869586958A3108F089E1A9 +:1020E00090E03770BC0153E0660F771F5A95E1F717 +:1020F000362B30938B0488579B4FFC01178223FFAC +:1021000015C081E2E8E8F4E0A7E6B4E001900D92A2 +:102110008A95E1F7277F206120936B044093680440 +:10212000F092690487E694E00E941C0D90918C0463 +:1021300094FD3DC1F3E0EF123AC180918D0421EF8F +:10214000280F233008F4D0CD0430C1F480918E04E0 +:1021500090912F01891719F08F3F09F0C5CD88E8BC +:1021600094E00E94820A9FEF980F9E3F18F40E940D +:10217000DA09BACD8FEF80934403B6CD0830D9F495 +:102180000091F20200FFB0CD88E894E00E94820A3C +:102190008F3F09F4A9CD8F5F8F3F09F4A5CD9091B2 +:1021A0004603891708F0A0CD01FD9ECD809346031C +:1021B000F092450399CD0831C1F480914403809396 +:1021C0006804F09269048FEF80936D0489E1809335 +:1021D0006C0480916B04807E836080936B0461E06B +:1021E00087E694E00E942F0732C0093171F4809194 +:1021F000F20283FF79CD877F8093F20288E894E032 +:102200000E94820A8093F4026FCD0E3109F46CCDE6 +:102210000D3101F5809144038093680410926904A4 +:102220008FEF80936D048FE180936C0483E480933F +:102230006B0480916A048770806180936A0480E0F7 +:102240009FEF90936F0480936E0487E694E00E9462 +:10225000E40C4ACD209189042111AEC08D3059F48F +:1022600088E198E00FB6F894A895809360000FBEBF +:1022700090936000FFCF8B3179F488E894E00E945E +:10228000820A91E0811101C090E08091E70290FB09 +:1022900080F98093E70228CD863099F490918F04DD +:1022A00081E0992319F09D3409F080E08093E602E3 +:1022B00041E050E063E071E086EE92E00E94562E2D +:1022C00013CD833119F40E940A0E0ECD823121F50F +:1022D0000E944607209144032093680410926904E9 +:1022E0002FEF20936D0426E120936C0423EA2093C2 +:1022F0006B0420916A042770206220936A04609323 +:102300006E0470936F04809370049093710487E659 +:1023100094E00E941C0DE8CC823009F590914403B2 +:1023200090936804109269049FEF90936D048093DA +:102330006C0483EA80936B0480916A0487708062E6 +:1023400080936A048FEF91E0A3E0B2E080936E0483 +:1023500090936F04A0937004B0937104D8CF813030 +:1023600001F520E030E0232B09F4BECC9295969540 +:102370009770953059F460918F047091900480911A +:102380009104909192040E940000AECC911105C07E +:102390008FE894E00E94AC2CF6CF60E070E0CB01B7 +:1023A000F2CF8A3009F4A0CC8C3109F49DCC88E8B6 +:1023B00094E00E94930A98CC8A31C9F795CC4F3F9C +:1023C00009F092CC93E0A91350C09091F20292FFD1 +:1023D00003C0073009F488CC043109F085CC909112 +:1023E0004503891381CC0E9471064B015C01A3E077 +:1023F0009A22AA24BB240E944C062B013C01811482 +:102400009104A104B10429F58091440380936804E8 +:10241000F09269048FEF80936D0485E180936C04E2 +:1024200080916B04807E836080936B046091450390 +:10243000D7CEB1E08B1A9108A108B108E8EE4E0E94 +:10244000E3E05E1E611C711C81149104A104B104BF +:10245000B1F20E944C066419750986099709683E15 +:1024600073408105910528F7CACF909145038913E0 +:102470003BCC9DCFE9960FB6F894DEBF0FBECDBF23 +:10248000DF91CF911F910F91FF90EF90DF90CF9050 +:10249000BF90AF909F908F907F906F905F904F9084 +:1024A0003F902F9008958091F20284FD0C94570E76 +:1024B0000895CF92DF92EF92FF92CF93DF93D82FC0 +:1024C0000E9471066B017C0110928D04C0E00E9495 +:1024D00071066C197D098E099F09603D7740810561 +:1024E000910590F4C11110C0A8950E943B070E946D +:1024F000531280918C048770833049F7C1E080913A +:102500008D048D13E3CFE3CF8C2FDF91CF91FF901C +:10251000EF90DF90CF9008958F929F92AF92BF92ED +:10252000CF92DF92EF92FF924B015C010E94710605 +:102530006B017C010E9471066C197D098E099F094F +:10254000681579058A059B0530F4A8950E943B071C +:102550000E945312EFCFFF90EF90DF90CF90BF908B +:10256000AF909F908F900895CF93C0E088E494E05F +:102570000E94F306892B51F4CA3F41F0CF5F61E01E +:1025800070E080E090E00E948C12F0CF88E494E04C +:102590000E94F3061816190694F46AE070E080E0D1 +:1025A00090E00E948C1288E494E00E94F3061816D2 +:1025B000190664F488E494E00E940B07F4CFCA3F44 +:1025C00029F48DEA96E0CF910C942309CF910895D8 +:1025D000EF92FF920F931F93CF937C0188E494E0D6 +:1025E0000E94F306892B11F00E9446096EE788E4E9 +:1025F00094E00E949706C0E087010C0F111DF801BE +:10260000649188E494E00E949706F80104910F3EDB +:1026100009F4C0E1CF5FC03178F3CF911F910F91E2 +:10262000FF90EF900C94B4128091E502811104C0E8 +:1026300085ED96E00E94E8128FEF8093E502089501 +:102640008F929F92AF92BF92EF92FF920F931F9340 +:10265000CF93DF9300D0CDB7DEB788E494E00E943B +:10266000F3069A83898389819A8105970CF4D0C0F7 +:1026700088E494E00E947E068E3709F0B1C010E035 +:10268000E12C01E0FF24FA9488E494E00E94F30630 +:10269000892B09F4BDC088E494E00E940B07EE206A +:1026A00069F0E12FF0E0E352FD4F8F3E61F080834F +:1026B0001F5F183008F017E0EE24E3948E3721F7FF +:1026C000EE24E394E1CF10828091DD02863009F0A0 +:1026D00081C08091DE02873009F07CC06091DF020A +:1026E000862F90E0982F88276091E002680F792F5D +:1026F000711D60557109072E000C880B990B0E9403 +:10270000212D2DEC3CEC4CE650E40E94F32E4B01C5 +:102710005C0120E030E0A9010E941A2D70E060E029 +:1027200087FD10C020E030E040E753E4C501B4016C +:102730000E949B2F60EF70E0181624F0C501B401D1 +:102740000E94652F7093DC026093DB026091E102CE +:10275000862F90E0982F88276091E202680F792FEA +:10276000711D64567109072E000C880B990B0E948D +:10277000212D23E333E343E350E40E94F32E4B0186 +:102780005C0120E030E0A9010E941A2D70E060E0B9 +:1027900087FD10C020E030E040EA53E4C501B401F9 +:1027A0000E949B2F60E471E0181624F0C501B4016B +:1027B0000E94652F7093DA026093D9028091E5023E +:1027C00081110BC085ED96E00E94E812F092E502BF +:1027D0000E94460910E0E12C57CF0093D802F6CFB3 +:1027E00088E494E00E940B07182F8BE796E00E9484 +:1027F0007F05812F0F900F90DF91CF911F910F9147 +:10280000FF90EF90BF90AF909F908F900C94350900 +:102810000F900F90DF91CF911F910F91FF90EF904C +:10282000BF90AF909F908F900895EF92FF920F937B +:102830001F93CF93DF93CDB7DEB728970FB6F894E9 +:10284000DEBF0FBECDBF2EE7298326E02A8323E11A +:102850002B8321E02C832AE02D832FEE28879E8373 +:102860008F838E010F5F1F4F7E0189E0E80EF11C00 +:102870000E151F0541F0F80161918F0188E494E085 +:102880000E949706F5CF28960FB6F894DEBF0FBECC +:10289000CDBFDF91CF911F910F91FF90EF900C94DE +:1028A000B412EF92FF920F931F93CF93DF93CDB7A4 +:1028B000DEB728970FB6F894DEBF0FBECDBF9EE7F8 +:1028C000998396E09A8391E09B839FEE98871C8280 +:1028D0008D837E836F838E010F5F1F4F7E0189E0A2 +:1028E000E80EF11C0E151F0541F0F80161918F01F2 +:1028F00088E494E00E949706F5CF28960FB6F894E6 +:10290000DEBF0FBECDBFDF91CF911F910F91FF9022 +:10291000EF900C94B412FF920F931F93CF93DF9319 +:1029200095E1899F800111240D531B4FC8010E941E +:10293000DA2CF82E6EE788E494E00E94970662E0B5 +:102940006F0D88E494E00E94970661E188E494E0CA +:102950000E949706D0E0C0E0CF1550F4F801EC0FCC +:10296000FD1F649188E494E00E9497062196F4CFBD +:102970006FEE88E494E00E949706DF91CF911F915B +:102980000F91FF900C94B412EF92FF920F931F934C +:10299000CF93DF93CDB7DEB760970FB6F894DEBF65 +:1029A0000FBECDBF9EE799839EE09A839CE29B83F6 +:1029B0009FEE988B1C828D837E836F831886498758 +:1029C0001A8622502B871C860D87FE86EF868E0185 +:1029D0000F5F1F4F7E0181E1E80EF11C0E151F05F0 +:1029E00041F0F80161918F0188E494E00E9497061C +:1029F000F5CF60960FB6F894DEBF0FBECDBFDF9166 +:102A0000CF911F910F91FF90EF900C94B412EF9221 +:102A1000FF920F931F93CF93DF93CDB7DEB72C9721 +:102A20000FB6F894DEBF0FBECDBFFE01339626E091 +:102A3000DF011D922A95E9F72EE729832AE02A83F0 +:102A400023E22B8320EF29872FEF2A872B872FEE76 +:102A50002C879E838F838E010F5F1F4F7E01BDE009 +:102A6000EB0EF11C0E151F0541F0F80161918F016D +:102A700088E494E00E949706F5CF2C960FB6F89460 +:102A8000DEBF0FBECDBFDF91CF911F910F91FF90A1 +:102A9000EF900C94B4122F923F924F925F926F92EC +:102AA0007F928F929F92AF92BF92CF92DF92EF92DE +:102AB000FF920F931F93CF93DF9310929D018FEF9F +:102AC00091E09093250180932401C0E0D0E0C09074 +:102AD0002401D090250186010F5F1F4FC8010E947D +:102AE0006C09882E8FEF880D8E3F08F02CC19090D6 +:102AF0002601A82CB12C29E2921220C0C8018A0D0F +:102B00009B1D0E946C098F3FC9F486E594E00E94EA +:102B10002309C0912401D09125012196809124019F +:102B20009091250101968A0D9B1DC817D9070CF0BD +:102B300020C16FEFCE010E945809EFCF80919D0117 +:102B40008F5F80939D01C60102960E946C09582EEA +:102B50008071482E54FE13C0CF5F93E099124DC090 +:102B6000809127018C130BC010932D0100932C0131 +:102B7000CA0CDB1CD0922B01C0922A01D82D809167 +:102B8000240190912501A80EB91EB0922501A092B2 +:102B90002401809126018F3F09F099CFD11197CF61 +:102BA000411095CF53FA222420F8312C6090230154 +:102BB000712C062D10E004551E4F7214130411F0F1 +:102BC0000CF085CF98016501769CC018D1081124BE +:102BD000C01AD10A8CEA91E08217930709F4CBC09E +:102BE000F90142904F01C601820F931F0E946C09A8 +:102BF0009401481679F37394E0CFEDEF9E12BFCFA6 +:102C000020919C01220F220F2C1708F0B8CFCC2E58 +:102C1000D12C30E02C5F3F4F2C153D050CF4AFCF8D +:102C2000F1E0CF1AD10823E0C222DD24C6010196CB +:102C3000E5E3E89F4001E99F900C11243401F3E1A2 +:102C40006F0E711C8FEEE82E8BE7F82E01E110E07D +:102C500025E330E053FC1CC040EF50E0B40190E0AD +:102C600080E00E94C414B30183E190E00E945114FB +:102C700080919C0124E0829FC00111248C0D9D1D38 +:102C800001960E9415148EE494E00E94E81277CF1A +:102C900048E750E0B40190E080E00E94C414B30122 +:102CA00083E190E00E94511480919C01E4E08E9FAA +:102CB000C00111248C0D9D1D01960E94151486E4FF +:102CC00094E00E94E81225E330E048E750E0B401C8 +:102CD00088E790E00E94C414B3018BE890E00E9462 +:102CE000511480919C01F4E08F9FC00111248C0D40 +:102CF0009D1D01960E9415148EE394E0C6CF2D59B8 +:102D00002C1B2093EB03977098609093E8038F71CE +:102D100080628093E90381E0711080E08093EC038E +:102D200061E085EE93E00E943D0D8093A20160E991 +:102D300071E080E090E00E948C1282E00E941B17FC +:102D4000D0919D01C4CEC093A3018D2FDF91CF916F +:102D50001F910F91FF90EF90DF90CF90BF90AF90B9 +:102D60009F908F907F906F905F904F903F902F90AB +:102D70000895D1E0EACF88E394E00E9423098AE233 +:102D800094E00E947F0580919D018C1B990B8D59C9 +:102D90009F4F0E94110985E294E00E947F05872DD4 +:102DA0000E94350920919D019091E8038091E903EB +:102DB00053FCA5CF2D592C1B2093EB038F718064FE +:102DC0008093E903977090619093E80381E090E02D +:102DD0009093ED038093EC0361E085EE93E00E9415 +:102DE0003D0D8093A20160E971E080E090E00E94D7 +:102DF0008C1260ED77E080E090E00E948C12809170 +:102E00009D018D598C1B8093EB038091E9038F7199 +:102E100080648093E9038091E803877080618093E8 +:102E2000E8031092ED031092EC0361E085EE93E06D +:102E30000E943D0D7CCFEF92FF920F931F93CF9393 +:102E4000C82F0E9446090E941413CF3F09F046C0C4 +:102E500085EB94E00E94E8122FE1E22EF12C0AE1CA +:102E600010E025E330E048E750E070E060E090E0FB +:102E700080E00E94C41463E170E083E190E00E946E +:102E800051148DEA94E00E94E8128DEF80932601A0 +:102E90000E944B15C09326018091A301853050F00C +:102EA0006CE171E083E190E00E9451148AEB94E0C0 +:102EB0000E94E8128091A201882309F4C7C063E14F +:102EC00070E082ED90E00E94511485EA94E0CF9189 +:102ED0001F910F91FF90EF900C94E8128EEF8C0FE2 +:102EE000823008F058C062E370E080E090E00E9419 +:102EF0008C1290E8E92E9CEFF92E10E000E027E319 +:102F000030E040EF50E069E071E090E080E00E9446 +:102F1000C41462E370E080E090E00E948C126CE1E7 +:102F200071E083E190E00E94511462E370E080E080 +:102F300090E00E948C12C23029F58BE00E948B1425 +:102F400060ED77E080E090E00E948C12F12CE12CA3 +:102F500010E000E027E330E040EF50E069E071E08E +:102F600090E080E00E94C4148091A301853008F4B1 +:102F70006DC06CE171E083E190E00E9451148AEB36 +:102F800094E0A5CF8CE00E948B148091270190E003 +:102F90000E941514D5CF809126018F518831E0F41D +:102FA00085EB94E00E94E8128FE1E82EF12C0AE014 +:102FB00010E025E330E048E750E070E060E090E0AA +:102FC00080E00E94C41463E170E083E190E00E941D +:102FD000511480E00E948B1468E470E083E190E07B +:102FE0000E945114C13211F0CF3141F480E1CF91F0 +:102FF0001F910F91FF90EF900C948B148C2F8D7F6D +:10300000803211F481E1F3CF8AED8C0F823010F41D +:1030100082E1EDCF8DE0C43061F08EE0C53039F350 +:103020008FE0C63031F083E1C93219F0CB3071F452 +:1030300084E10E948B1468EB7BE080E090E0CF910C +:103040001F910F91FF90EF900C948C12CF911F91D4 +:103050000F91FF90EF9008958F929F92AF92BF9241 +:10306000CF92DF92EF92FF920F931F93CF93DF9354 +:10307000C82FE62E88E994E00E947F058C2F0E94DD +:10308000350983E080932601C0932701109229011E +:10309000CC2309F48EC10E944B15D82F882309F444 +:1030A00079C18091A301882309F474C18C2F90E029 +:1030B0006E2D83569E4F0E94662EC75FC0930C04F0 +:1030C00080910904877088608093090480910A04C4 +:1030D0008F71806280930A04E0920D0460E086E0C4 +:1030E00094E00E943D0D60E971E080E090E00E9474 +:1030F0008C1281E080932D046EE874E087E294E006 +:103100000E94160A60E00E943D0D83E00E941B179A +:103110001092DD021092DE021092DF021092E002A5 +:103120001092E1021092E2021092E3021092E40285 +:1031300000912C0110912D01C80101960E946C098B +:10314000F82E8170A82E8093A10181E09F2D9470AC +:10315000892EF2FE80E08093A0018CEF8D0F80938A +:103160002901C80102960E946C09C82F8093DD02D4 +:10317000C80103960E946C098093DE02F5FCAAC088 +:103180008093DF02C093E002D4E0EF2DE0749E2E26 +:10319000C0E0F6FE17C0809129018250809329017A +:1031A000C8018D0F911D0E946C098093AC0181E0D4 +:1031B0008D0F800F912F911D0E946C098093AD019E +:1031C000DE5FC2E0BF2CBB1CBB24BB1CF1E0BF1206 +:1031D0001DC080912901825080932901C8018D0F63 +:1031E000911D0E946C09EC2FF0E0E455FE4F8083A6 +:1031F00081E08D0F800F912F911D0E946C09E1E0FD +:10320000EC0FF0E0E455FE4F8083CE5FF3FE05C087 +:1032100080912901869580932901C0902A01D09040 +:103220002B012091290130E06E2D70E06F5F7F4F00 +:10323000629FC001639F900D729F900D11248601C3 +:10324000081B190B0F5F1F4F821B930BC81AD90A5B +:10325000C016D1060CF44FC0DC2FF12CE12CC801B4 +:103260000E946C09AD2FB0E0A455BE4FE82FF0E0EE +:103270000E2C02C0F595E7950A94E2F7E170FF275E +:10328000EE0FFF1FE352FD4F80818C93C8010E9417 +:103290006C09A1E0AD0FB0E0A455BE4FE82FF0E0FF +:1032A0000E2C02C0F595E7950A94E2F7E170FF272E +:1032B000EE0FFF1FE352FD4F81818C93DE5F8FEF96 +:1032C000E81AF80A98E0E916F10449F6C05F0F5FC2 +:1032D0001F4FBECFC80104960E946C098093DF0285 +:1032E000C80105960E946C098093E002D650D093E5 +:1032F0002901D6E04ACFA110C850882051F08FE7AD +:1033000094E00E9423099110C250E1E0BE1201C076 +:10331000C25085E794E00E94230948E0F42ED0E0F3 +:1033200052E3E52E0CEA11E020E0C8018C5A9140EE +:103330008C179D0714F52223D1F060E084E00E94F1 +:10334000C40520E0F80181918F018E9DC0011124F8 +:1033500090939F0180939E018230910534F3880FF2 +:10336000991F880F991F05970197F1F7DECF61E04C +:1033700084E00E94C40521E0E5CFFA94F110D2CF99 +:1033800060E084E00E94C4056CE271E080E090E0BF +:103390000E948C1281E080932D0462E774E087E242 +:1033A00094E00E94160A60E00E943D0D8FEF80932A +:1033B0002601DF91CF911F910F91FF90EF90DF9049 +:1033C000CF90BF90AF909F908F90089562E083E080 +:1033D0000E94100661E084E00E94100660E084E034 +:1033E0000E94C40560ED77E080E090E00E948C12BE +:1033F00010926304109262041092610410926004AF +:1034000010925F0410925E048DE991E09093650440 +:103410008093640490915404963108F047C02DEBDA +:1034200030E030935F0420935E042BE931E0309369 +:103430006104209360042CE231E030936304209314 +:1034400062042091680084E0983048F031E09E30BA +:1034500008F430E081E001C0880F3A95EAF7822B4A +:10346000809368002DE630E0983050F02BE630E095 +:103470009E3030F02CE630E0963110F030E020E065 +:1034800030935C0420935B04292F30E0983008F0DF +:103490006BC081E001C0880F9A95EAF780935D04C4 +:1034A00080916404909165040197F1F78091620422 +:1034B00090916304892B49F1E0913903F0913A032B +:1034C00084E0E834F80709F1309739F0A389B4892A +:1034D0009C918589809589238C93809166048E7F49 +:1034E00080936604109237031092380388E494E0C6 +:1034F00090933A0380933903E0915B04F0915C046C +:10350000808190915D04892B808360ED77E080E07D +:1035100090E00E948C1285ED96E00E94E81289EFFF +:1035200091E00E94E81284EF91E00E94E8128091FD +:10353000F20282FF26C08EED91E00E94230981E015 +:103540008093A20180932D046BED71E087E294E0FB +:103550000E94160A60E00E943D0D8FEF80932601C5 +:103560000E941B170C9475089E3040F428503109B6 +:1035700081E001C0880F2A95EAF790CF2E503109DB +:10358000F7CF8CEC91E00E9423091092A201E5CFC5 +:103590002F923F924F925F926F927F928F929F9263 +:1035A000AF92BF92CF92DF92EF92FF920F931F9351 +:1035B000CF93DF93CDB7DEB72C970FB6F894DEBF6D +:1035C0000FBECDBF8091A5018111EFC08091A601F2 +:1035D0009091A701A091A801B091A901892B8A2BF4 +:1035E0008B2B51F40E944C066093A6017093A701A7 +:1035F0008093A8019093A9014B99FECF0E944C069D +:10360000609396017093970180939801909399012C +:103610002091A6013091A701621B730B70939F014B +:1036200060939E01CB01855691098B3B9D4408F028 +:1036300080C02091AA013091AB0137FD0AC0F90189 +:10364000E455FE4F633A40E3740708F46BC089EF1A +:1036500080832F5F3F4F3093AB012093AA0180916D +:1036600028018823E1F180919E0190919F014B995F +:1036700004C0803355E79507D0F30E944C06609351 +:10368000A6017093A7018093A8019093A9012091AE +:10369000960130919701621B730B70939F016093A9 +:1036A0009E01CB01855691098B3B9D4408F05CC07F +:1036B0002091AA013091AB011216130654F4F901BE +:1036C000E455FE4F633AB0E37B0708F446C089EF48 +:1036D00080832F5F3F4F3093AB012093AA018091ED +:1036E000AA019091AB018A3291401CF081E0809355 +:1036F000A5012C960FB6F894DEBF0FBECDBFDF91AB +:10370000CF911F910F91FF90EF90DF90CF90BF90DE +:10371000AF909F908F907F906F905F904F903F9071 +:103720002F900895CB0162E370E00E94A02F608388 +:1037300090CF1092AB011092AA011092280181E063 +:103740008093A5010E944C066093A6017093A70187 +:103750008093A8019093A90182CFCB0162E370E02E +:103760000E94A02F6083B5CF60337547B0F081E031 +:103770008093A5018091AA019091AB0197FF04C0AD +:103780001092AB011092AA011092A6011092A7010B +:103790001092A8011092A901A2CF1092AB01109231 +:1037A000AA0181E08093A5019ACF1092A5010E9401 +:1037B000201300912801002309F496C58091AA01E5 +:1037C0009091AB01813691050CF48EC580912A0150 +:1037D00090912B01FC01E455FE4F2081211104C082 +:1037E000019780339105B4F790932B0180932A01C0 +:1037F00020902C0130902D0180902A0190902B0177 +:103800005401A218B308C5016AE070E00E94B42F09 +:1038100019861A8610E09B01770F440B550B2983FC +:103820003A834B835C83A5010B2C000C660B770B52 +:103830004D835E836F837887F101E455FE4FD12C71 +:10384000C12CCF018C5A9140881699063CF0819189 +:103850008113F7CF5FEFC51AD50AF3CF11110BC053 +:1038600062E0C616D1040CF452C0F984F092A401AF +:1038700080E693E029C372E0C716D1041CF0898565 +:103880008F5F8987113009F442C00D2C000CEE08BF +:10389000FF0869817A818B819C810E94212D20E023 +:1038A00030E040E05FE3A7EFAA16AFEFBA060CF4F2 +:1038B0009BC00E94872E0E94652F6C157D058E058A +:1038C0009F052CF56D817E818F8198850E94212D29 +:1038D0002DEC3CEC4CE45FE30E94802D2B013C017D +:1038E00020E030E0A9010E949B2F20E030E040E082 +:1038F0005FE387FD7CC0C301B2010E94872E0E9456 +:10390000652FC616D706E806F9060CF40A871F5F6E +:103910001F3F09F091CFF984F092A401FA84FF20AF +:1039200009F4A6CF29852250223108F0A1CF1092A8 +:10393000DD021092DE021092DF021092E00210927D +:10394000E1021092E2021092E3021092E402662475 +:103950006A944AEFA42EB12CF0E0E0E0512C7724D9 +:10396000739490E080E000E0C72CD12C482F50E009 +:103970005E834D832A2D30E02C5F3F4F241735079F +:103980000CF478C09401A40170E060E022153305C6 +:103990009CF1D901A455BE4FFC908F1122C06F5FDE +:1039A0007F4FB1E07B16E1F09230D0F06A307105C4 +:1039B000BCF47401A3E0EA1AF1084E155F0584F423 +:1039C0007A01E21AF30AB1E3EB16F1044CF06E143B +:1039D0001F0431F02CF0642E621AA82E4A0119013E +:1039E000A90121503109D2CF0E94862E64CFC30194 +:1039F000B2010E94862E83CF61157105A9F121E0E5 +:103A0000290F309771F1002361F1081750F5AD814E +:103A1000BE81A01BB109CA16DB061CF19101245519 +:103A20003E4F6E177F0774F4F9019F012C5A314005 +:103A300082169306ACF021918213F7CFDF01119724 +:103A40000C93F3CFF9019F012C5A31408216930653 +:103A50003CF021910213F7CFDF0111978C93F3CF44 +:103A6000292F082FB82E02C0292FBF018F5F922F58 +:103A7000FB017CCF951509F440C03AEFF32EAF144B +:103A800011F0953038F029E02B1520F4592E35E04F +:103A9000731267CF30922D0120922C0190922B014E +:103AA00080922A019093A40160922901A0921E01A4 +:103AB0003AEFA31267C0809126018F51893008F038 +:103AC00010C4C401821993098E3391050CF409C402 +:103AD000811542E094071CF495958795182F80E294 +:103AE000482E212F30E0842D90E003968217930713 +:103AF0000CF084C054E0450EF6CF7394C4CF2F5F12 +:103B00003F4FBD81B23008F474C090E080E09F0167 +:103B10002C5A3140821693063CF03191D6012C91FB +:103B20003213F5CF0196F3CF40970CF0DAC382E35E +:103B300092E00E947F05F801E455FE4F6F01D60127 +:103B40006D916D0170E090E080E04AE00E94A20873 +:103B500080E392E00E947F05C601801B910B8C5A86 +:103B600091408E159F055CF30E941B09409229012C +:103B700010932D0100932C010E0D1F1D10932B018E +:103B800000932A0160912901362F36953250809199 +:103B90002C0190912D0170E08C01060F171FB0E0F1 +:103BA000A0E019821D826C01E4E0CE0ED11CC81683 +:103BB000D9060CF4E3C0AC01612C512C412CF12C42 +:103BC000912CB12C812CA12C19821D8240175107F8 +:103BD0000CF084C0FA01E455FE4F20812A1145C043 +:103BE000E180E81042C0F981FF5FF9834E5F5F4FCB +:103BF000EDCF0F5F1F4F15C0BCEF4B0E60E3641598 +:103C000008F06FC3F101E455FE4F9F0181016F0180 +:103C1000E42CF12CA4014E195F09570171E0A71A99 +:103C2000B1084017510744F3C1011D8248175907D5 +:103C30000CF465CFDC01A455BE4FBC87AB87B9013E +:103C4000712CDB015D90BD01AB85BC856D90BC879F +:103C5000AB87561008C073944710F3CF6D816F5F28 +:103C60006D838A0D9B1D0196E1CFB21207C0E180E2 +:103C70009E1004C029812F5F2983B8CFA11006C0F0 +:103C80008180E981EF5FE983A22EB0CFB11006C039 +:103C90009180F981FF5FF983B22EA8CFF11018C08F +:103CA00041807D8073942980231680F0270C332473 +:103CB000331C7101EE0CFF1CE616F70664F452800B +:103CC0006380ED81EE5FED83F22E90CFF22E7D8248 +:103CD00048EE53E08BCFF22E7D8288CFA092DD029A +:103CE0008092DE02B092DF029092E002F092E10256 +:103CF0004092E2025092E3026092E402298023168D +:103D000008F4C6C020912A0130912B01A20FB31FE5 +:103D1000B0932B01A0932A0190932D0180932C0145 +:103D20000E941B090E941B0900912C0110912D017A +:103D3000980124553E4F790180912A0190912B01E1 +:103D400080179107BCF0D7016D917D0170E090E084 +:103D500080E04AE00E94A2088DE692E00E947F0582 +:103D6000C80187709927892B11F40E941B090F5FE6 +:103D70001F4FE2CF0E941B090E941B098091DD02A8 +:103D80002091DE0241E050E0821711F050E040E067 +:103D90009091DF029417150641F49091E0022917E3 +:103DA00020F49093DE028093E00299819695969597 +:103DB000969590932301898187701092A1011092AA +:103DC000A001882349F09F5F90932301843009F07C +:103DD00068C081E08093A1011D82812C912C540147 +:103DE0008394809123013D80381608F08BC019829E +:103DF000F12CE12C00912C0110912D01F801E455DA +:103E0000FE4F8081240135010E2C04C0440C551C4A +:103E1000661C771C0A94D2F79091DD02891357C073 +:103E200021819091DE02291352C081E592E00E9427 +:103E30007F05842D80952980282229820E5F1F4FBF +:103E400010932D0100932C012FEFE21AF20A38E0B3 +:103E5000E316F10479F62D80E22DF0E0E455FE4FF3 +:103E60003980308284E492E00E947F05632D70E007 +:103E700090E080E040E10E94A2088CE392E00E9482 +:103E80007F0589810E9435092D812F5F2D83A9CF60 +:103E900011960F5F1F4FA530B10509F456C001966A +:103EA00086CE2D80820D9927991F8430910531F49B +:103EB00081E08093A1018093A0018ECF089711F437 +:103EC00081E0F9CF83E592E00E9423093EC0909102 +:103ED000DF0289130DC091818091E002981308C020 +:103EE0008FE492E00E947F05398034283982A6CF82 +:103EF0008DE492E00E947F05842D80952980282200 +:103F00002982A2CF0E941B090E941B092090260132 +:103F10002982222D2F3F09F062C08BE194E00E949C +:103F200023090E944B15882381F085E194E00E94CB +:103F3000230981E080932D046DEF73E087E294E024 +:103F40000E94160A60E00E943D0D0E947508809153 +:103F50001C01882309F404C210921C011AE080910C +:103F6000A30190E009961817190611F00CF0C2C1D0 +:103F700027EF210F422F50E043565E4F5A8349836B +:103F8000CA010E944E2E823028F060E089819A8119 +:103F90000E94662E89819A810E944E2E10930C04F5 +:103FA00090910904977098609093090490910A0485 +:103FB0009F71906290930A0491E0811101C090E09A +:103FC00090930D0460E086E094E00E943D0D60E96E +:103FD00071E080E090E00E948C121F5FC0CF898169 +:103FE0008F51893008F0B1CF86EF93E00E947F05B2 +:103FF00089810E943509809126018652823030F4F1 +:104000009091230180911D0198134EC188E992E09F +:104010000E942309809126019AED980F923008F4AE +:1040200075C02090A1012D829091A001992319F0D3 +:10403000222D24602D83309123013983982F9D7F79 +:10404000903209F045C04D8148604D83330F3E5F8B +:1040500039838152823060F58D8180614091DF0229 +:104060002091E0023091DD029091DE02491334C0CC +:10407000231332C069816E5F69838D838091E10271 +:104080008823B1F08091E202882391F08D818064D1 +:1040900099819E5F2091E3022223A9F12091E402FD +:1040A000222389F1BD81B06CBD83E981EC5FE98396 +:1040B000298021102EC080EA93E00E94230986E027 +:1040C0000E941B1781E080932D046BE873E000C110 +:1040D00059815E5F5983BDCF81E090E0431711F0B5 +:1040E00090E080E02817190639F47D8172617D83A4 +:1040F00089818E5F8983C2CF9D8190639D83A981D1 +:10410000AC5FA983BBCF99838D83D2CF22E0298373 +:104110001D8280912401909125012980820D911D9D +:104120008115944040F686E892E00E942309809130 +:1041300026018652823008F451C08091240190916A +:1041400025010196909325018093240169810E94A5 +:1041500058098091240190912501019690932501A1 +:10416000809324016D810E9458092D80E22CF12C4E +:1041700024FE34C00DED12E024E030E03A832983C0 +:10418000C701098002C0959587950A94E2F780FFE0 +:104190001AC08091240190912501019690932501E8 +:1041A00080932401D8016C910E94580980912401C8 +:1041B0009091250101969093250180932401F801A7 +:1041C00061810E94580929813A812F5F3F4F3A83CC +:1041D00029830E5F1F4F2830310591F61982809197 +:1041E00023012980281618F580912401909125013A +:1041F000019690932501809324010E94110980E883 +:1042000092E00E947F05022D10E004551E4FD80158 +:104210008C910E943509F801608180912401909170 +:1042200025010E945809F981FF5FF983D8CF809159 +:1042300026018652823028F080919D018F5F809305 +:104240009D012224239420922D046FE672E087E2E0 +:1042500094E00E94160A60E00E943D0D80912601C4 +:104260008D7F803231F581EE93E00E9423098091A9 +:10427000230180931D0120922D0469EC73E087E2F5 +:1042800094E00E94160A60E00E943D0D8091260194 +:10429000823219F487E280932601809126018032D0 +:1042A00019F486E280932601809126010E941B1753 +:1042B0004CCE84E00E941B170E94520D88EB93E0C5 +:1042C0000E9423093324339430922D0465EB73E06C +:1042D00087E294E00E94160A60E00E943D0D8FEF95 +:1042E000E1CF83E793E0F0CD1092A50181E08093C8 +:1042F00028012DCE60E971E080E090E00E948C12F0 +:1043000064E6698380919D019091A301891B990BBB +:104310008D599F4F29802816190609F00CF5209217 +:10432000EB038091E9038F7180648093E9038091AE +:10433000E803877080618093E8031092ED03109288 +:10434000EC0360E085EE93E00E943D0D60E971E0D2 +:1043500080E090E00E948C1229812F5F2983D2CFC8 +:104360000E94710600919201109193012091940195 +:1043700030919501601B710B820B930B65367105B3 +:104380008105910508F4B5C90E94710660939201F8 +:1043900070939301809394019093950120909101E3 +:1043A0002982222011F181E493E00E947F05898116 +:1043B0000E943509E0919101F0E0E557FE4F8081C0 +:1043C00060E0853610F061E084560E942C18309031 +:1043D0009101232D21502983209391018AE393E0B9 +:1043E0000E947F0589810E9435098091E502823013 +:1043F00008F483C081508093E5028091D80288231D +:1044000009F477C90E9414130E9446098091D902C9 +:104410009091DA0265E370E00E94B42F6093270167 +:104420001092D8026111FFC08EEE92E00E94230923 +:1044300088EC8093260164E670E080E090E00E94C2 +:104440008C120E94460980E491E09093DA028093F6 +:10445000D90281E08093D80225E3C22ED12C3EE11F +:10446000E32E48E2B42E52E3A52E62E370E080E032 +:1044700090E00E948C120E9420138091D802882321 +:10448000A1F31092D8020E9446098091D90290911E +:10449000DA02B6010E94B42F60932701611137C080 +:1044A0008FEF8093260180912601833309F0B0C0FD +:1044B0008BE193E00E94230910929C018BE00E9403 +:1044C0001B1720E032E03A8329836FEF89819A81BC +:1044D0000E94580949815A814F5F5F4F5A8349832F +:1044E0004130544091F70E944B158FEF8093260185 +:1044F000809126010E941B17D8C0813009F07DCF22 +:104500001092E50286E393E00E94E81276CF89EEEE +:1045100092E00E94E81263E170E083E190E00E9483 +:10452000511480E00E948B1485E390E00E940715EF +:104530009091260180912701983C09F067C09091E5 +:104540009D01992309F43FC033E03D83FF24F39498 +:10455000813051F487ED92E00E942309E092260118 +:1045600054E05D8394E0F92E80912701823051F46C +:104570008DEB92E00E942309B092260161E06D83E9 +:1045800088E0F82E80912701833001F584EA92E0DB +:104590000E942309A092260182EA92E00E947F05F0 +:1045A00080E00E94350968E470E083E190E00E94B9 +:1045B000511489E00E948B148AE690E00E9407154E +:1045C0000E94460952CF41E04D83C0CF198208E4D2 +:1045D00010E082EA92E00E947F0589810E943509FD +:1045E000B80183E190E00E94511489818F0D0E94EF +:1045F0008B14C80182960E94071579817F5F7983A9 +:104600000B5C1F4F2D807211E4CFDACF890F49CF99 +:10461000893209F06DCF10929C010E944B1589E2FE +:104620000E941B1762CF653008F069C0CB01992743 +:104630009A83898300919C0194E0099F8001112451 +:104640008091A30190E0801B910B29803A80821514 +:1046500093055CF180919101863038F586E093E016 +:104660000E947F05C101800F911F0E941109809156 +:1046700091018F5F809391018091DB029091DC0228 +:104680008937910564F181E093E00E942309E0916C +:104690009101F0E0E557FE4F80919C01880F880F53 +:1046A000909127019C59890F80832C960FB6F8941E +:1046B000DEBF0FBECDBFDF91CF911F910F91FF9055 +:1046C000EF90DF90CF90BF90AF909F908F907F90B2 +:1046D0006F905F904F903F902F900C9475088BEFE8 +:1046E00092E00E942309E0919101F0E0E557FE4F2E +:1046F00080919C01880F880F90912701D4CF85EF7E +:1047000092E00E94230980919C018F5F80939C011D +:1047100024E0829FC00111242091A30128171906CB +:1047200011F00CF0E5CE10929C01E2CE1F93CF93D6 +:10473000DF938091E70281FD2DC00E940A0E8091D7 +:10474000E70281608093E702C4E0DFEF1AE1809125 +:1047500044038093680410926904D0936D0410930D +:104760006C0480916B04807E836080936B0462E0B4 +:1047700087E694E00E942F070E941C0D8BE10E94A7 +:104780005912811102C0C15011F78091E702826075 +:104790008093E702DF91CF911F9108958FEF80936F +:1047A000F402E2EFF2E0908198609083E7E6F4E0B3 +:1047B0009091440391831282868388E1858384816A +:1047C000807E8360848361E0CF010E942F070C9478 +:1047D000E40C809144038F3F21F50E9471066F3FE6 +:1047E000E9F060932F0180912F0190914403909301 +:1047F00068041092690480936D0483E080936C04D4 +:1048000080916B04807E836080936B046AE571E025 +:1048100087E694E00E944D0A0C94E40C10922F015C +:10482000E2CF0895E2EFF2E08081897F81608083AA +:10483000A4E4B3E08FEF12968C93129711968C93A9 +:104840001197E7E6F4E09C9191838283868387E069 +:1048500085838481807E836084836AE571E0CF01F3 +:104860000E944D0A0C94E40C8F929F92AF92BF92DB +:10487000CF92DF92EF92FF920F931F93CF93DF932C +:10488000CDB7DEB764970FB6F894DEBF0FBECDBFCD +:104890008E010F5F1F4F80E1F80111928A95E9F7B1 +:1048A00060E170E081E691E00E94F22CAC0161E6EB +:1048B00071E0C8010E94F02F8AE090E09093AA0472 +:1048C0008093A90440E1B8018BEA94E00E946E0451 +:1048D00050E040E080E190E0FF24F39420E1E22EFC +:1048E000BE016B5E7F4F3BE1B32ED82EFC01E95534 +:1048F000FB4F9E012F5E3F4FD901C190CD92A6176D +:10490000B707D9F7DE1020C0D988F0E1EF0EEA89A9 +:10491000F0E0EE54FF4FE491EF25E98BEB89F0E0F6 +:10492000EE54FF4FE491EA8BEC89F0E0EE54FF4F38 +:10493000E491EB8BED2DF0E0EE54FF4FE491EC8B26 +:10494000F7FECFC0FF0CFB24FC01E555FB4F4F01E8 +:10495000F901A1909F016401C81AD90AC40ED51E9D +:10496000F601D080DA24F401D1924F012A173B07D7 +:1049700079F704964C5F5F4F803B910509F0B5CF06 +:1049800080E1F80111928A95E9F7219A229A2998F3 +:104990002A9A1FB7F89480916A01811127C0E5E136 +:1049A000F8E08491E9E2F8E09491E82FF0E0EE0F6E +:1049B000FF1FE752F84FA591B491EC91E92321F440 +:1049C00061E08AE00E94C40561E08AE00E9410066E +:1049D0008CB580618CBD8CB580648CBD61E08DE050 +:1049E0000E94100661E08BE00E94100680916A012F +:1049F0008F5F80936A011FBF29986EE080E20E945A +:104A0000A0098BE496E40197F1F763E083E20E944A +:104A1000A0096FE584E20E94A0096CE485E20E948F +:104A2000A00967E086E20E94A00964E08DE30E948D +:104A3000A0098DE10E94F409843041F063E780E52C +:104A40000E94A00964E08DE30E94A00986E00E9414 +:104A5000F409873009F04FC085E00E94F4098C34D6 +:104A600009F049C062E082E20E94A00960E081E2B0 +:104A70000E94A00963E08CE30E94A0091FEF10933D +:104A8000030120E045E063E071E08BE20E946E09E3 +:104A900020E045E063E071E08AE20E946E0920E0D8 +:104AA00045E063E071E080E30E946E0982EE0E94BF +:104AB000FA0981EE0E94FA0960E787E20E94A009E4 +:104AC0008091F20280618093F202809147038E7F91 +:104AD00080934703809144038F3F29F488E191E05C +:104AE0000CC0FF0C31CF9FEF980F9E3FD8F40E946F +:104AF000DA098111F3CF88E091E00E9459076496AA +:104B00000FB6F894DEBF0FBECDBFDF91CF911F91DE +:104B10000F91FF90EF90DF90CF90BF90AF909F905C +:104B20008F90089510934403E6CF1F920F920FB613 +:104B30000F9211242F933F934F935F936F937F9323 +:104B40008F939F93AF93BF93EF93FF9388E493E08A +:104B50000E941005FF91EF91BF91AF919F918F91AE +:104B60007F916F915F914F913F912F910F900FBE69 +:104B70000F901F9018951F920F920FB60F9211244D +:104B80002F938F939F93EF93FF93E0915803F091AE +:104B900059038081E0915E03F0915F0382FD1BC0A9 +:104BA0009081809161038F5F8F73209162038217E0 +:104BB00041F0E0916103F0E0E85BFC4F958F80935A +:104BC0006103FF91EF919F918F912F910F900FBEF5 +:104BD0000F901F9018958081F4CF1F920F920FB6FF +:104BE0000F9211242F933F938F939F93AF93BF9373 +:104BF00080913C0390913D03A0913E03B0913F030F +:104C000030913B0323E0230F2D3758F50196A11D6A +:104C1000B11D20933B0380933C0390933D03A093ED +:104C20003E03B0933F038091400390914103A091D4 +:104C30004203B09143030196A11DB11D809340032F +:104C400090934103A0934203B0934303BF91AF916C +:104C50009F918F913F912F910F900FBE0F901F90BA +:104C6000189526E8230F0296A11DB11DD2CF1F92E1 +:104C70000F920FB60F9211242F933F934F935F9390 +:104C80006F937F938F939F93AF93BF93EF93FF9314 +:104C9000E0913201F09133010995FF91EF91BF91BD +:104CA000AF919F918F917F916F915F914F913F91C4 +:104CB0002F910F900FBE0F901F9018951F920F927B +:104CC0000FB60F9211242F933F934F935F936F93DF +:104CD0007F938F939F93AF93BF93EF93FF93E09155 +:104CE0003001F09131010995FF91EF91BF91AF91A2 +:104CF0009F918F917F916F915F914F913F912F91F4 +:104D00000F900FBE0F901F9018951F920F920FB625 +:104D10000F9211242F933F934F935F936F937F9341 +:104D20008F939F93AF93BF93EF93FF93E0913903DA +:104D3000F0913A03309749F0A685B7858585968D21 +:104D400091FF14C09C918923A1F4FF91EF91BF9131 +:104D5000AF919F918F917F916F915F914F913F9113 +:104D60002F910F900FBE0F901F9018959C91892343 +:104D700061F7A389B4899C918589809589238C9357 +:104D8000868997890197F1F7608D718DA685B78522 +:104D9000558538E020E0CB010197F1F7822F90E0B4 +:104DA00095958795282F4C91452309F0206831501F +:104DB00091F7868D81FD20958091370390E00196D3 +:104DC0008F73992730913803381799F0A0913703E2 +:104DD000B0E0A950BD4F2C9380933703828D938D03 +:104DE0000197F1F7A389B4898C919589892B8C93CC +:104DF000ACCF868D8160868FF1CF1F920F920FB658 +:104E00000F9211240F900FBE0F901F901895DB0189 +:104E1000FC0158E0149744E018960E9001924A95D0 +:104E2000E1F75A95C1F708958F929F92AF92BF9282 +:104E3000CF92DF920F931F93EDB7FEB7B8970FB6DF +:104E4000F894EDBF0FBEFEBF9F938F9331968F01F5 +:104E500049015A016B01C801AAD2BB2011F4AA2052 +:104E600059F0C801B601A1D030E4C30ED11C32E024 +:104E7000931AA108B108F1CFC801B601A40115D059 +:104E80008F919F91B801C3DFEDB7FEB7B8960FB60B +:104E9000F894EDBF0FBEFEBF1F910F91DF90CF9032 +:104EA000BF90AF909F908F900895523090F09F9355 +:104EB0008F937F936F935F934F9377D04F915F91D1 +:104EC0006F917F918F919F91525030E4630F711DCC +:104ED000ECCFEDB7FEB70FB6E054F040F894EDBF5D +:104EE0000FBEFEBF3196242F26952695269550FBA2 +:104EF00025F9DB01222329F0122E0D9001921A943C +:104F0000E1F730E8032E37E0342329F006943A9590 +:104F1000E9F73C91032A01922395293308F421C033 +:104F200030E4321B19F011923A95E9F7FF97319767 +:104F3000BF01FF93EF939F938F935F934F9335D070 +:104F40004F915F918F919F91EF91FF91DC0191962D +:104F50003C9132503D9326E03C9130403D932A9560 +:104F6000D9F738E3321B21F0112411923A95E9F771 +:104F7000DC01909638960D90040E02920D90051E5D +:104F8000029236E00D90011C02923A95D9F7F897FB +:104F9000BF010BD0EDB7FEB70FB6FF963196F89470 +:104FA000EDBF0FBEFEBF112408954F925F926F9226 +:104FB0007F928F929F92AF92BF92CF92DF92EF92A9 +:104FC000FF920F931F93CF93DF934DB75EB79A0174 +:104FD000FB0140525140DA010FB6F8944DBF0FBEAD +:104FE0005EBF2F933F938F939F93119640E17191F2 +:104FF0006191319121912D933D936D937D934A95CC +:10500000B1F740E3142EFD01FF9731970191119103 +:1050100021913191C190D190E190F1906D2D7E2D33 +:105020008F2D9C2D41E0E9D14B015C01B701C601F8 +:1050300042E0F9D186269726A826B92673E0F69491 +:10504000E794D794C7947A95D1F78C249D24AE2405 +:10505000BF24080D191D2A1D3B1D648D758D868D7D +:10506000978D060F171F281F391FC0A8D1A8E2A8C7 +:10507000F3A8B701C60141E0D6D15C014B0142E083 +:10508000D2D186269726A826B92672E0F694E79410 +:10509000D7947A95D9F78D249E24AF24080D191D35 +:1050A0002A1D3B1D0D931D932D933D931A9409F0DA +:1050B000AACFFF91EF91EF93FF9390E211901D9291 +:1050C0009A95E1F79097ED01EEEAF2E5BA9590E452 +:1050D000192E4C885D886E887F88688979898A89CD +:1050E0009B89C88CD98CEA8CFB8C4622572268227B +:1050F00079226095709580959095C622D722E822F6 +:10510000F9224C245D246E247F24F888C988DA882B +:10511000EB88B601C70142E070D14B015C01B601DA +:10512000C70143E080D186269726A826B926B70175 +:10513000C60141E078D186269726A826B926480CD4 +:10514000591C6A1C7B1C8C8C9D8CAE8CBF8C480CB3 +:10515000591C6A1C7B1C8D909D90AD90BD90480C95 +:10516000591C6A1C7B1C85909590A590B590480CA5 +:10517000591C6A1C7B1C688179818A819B818C8087 +:105180009D80AE80BF8086229722A822B922C88443 +:10519000D984EA84FB846C217D218E219F2186267F +:1051A0009726A826B9266C817D818E819F816C21EE +:1051B0007D218E219F2186269726A826B926C88084 +:1051C000D980EA80FB80B601C70142E02CD18B0177 +:1051D0009C01B701C60143E010D1062717272827F5 +:1051E00039276F2D7C2D8D2D9E2D42E006D106276F +:1051F000172728273927080D191D2A1D3B1D5CE19B +:105200006C969A919C835A95E1F7C888D988EA8868 +:10521000FB88C40CD51CE61CF71CC88AD98AEA8A0C +:10522000FB8A040D151D261D371D088319832A834B +:105230003B831A9409F04DCFFF91EF9158E0008124 +:105240001181228133816991799189919991060F18 +:10525000171F281F391F01931193219331935A95DA +:1052600071F7319652E066E04081450F4193552732 +:1052700028F44081451F41936A95D1F75F914F9182 +:105280000FB6F8944DBF0FBE5EBF1124DF91CF91D2 +:105290001F910F91FF90EF90DF90CF90BF90AF9054 +:1052A0009F908F907F906F905F904F900895982F70 +:1052B0008A4291443771CFFBC0B5A5DBB5E95BC22B +:1052C0005639F111F159A4823F92D55E1CAB98AAD0 +:1052D00007D8015B8312BE853124C37D0C55745DF4 +:1052E000BE72FEB1DE80A706DC9B74F19BC1C16972 +:1052F0009BE48647BEEFC69DC10FCCA10C246F2C4A +:10530000E92DAA84744ADCA9B05CDA88F976525196 +:105310003E986DC631A8C82703B0C77F59BFF30BAD +:10532000E0C64791A7D55163CA0667292914850AA3 +:10533000B72738211B2EFC6D2C4D130D3853547399 +:105340000A65BB0A6A762EC9C281852C7292A1E8D1 +:10535000BFA24B661AA8708B4BC2A3516CC719E849 +:1053600092D1240699D685350EF470A06A1016C124 +:10537000A419086C371E4C774827B5BCB034B30C61 +:105380001C394AAAD84E4FCA9C5BF36F2E68EE8236 +:105390008F746F63A5781478C8840802C78CFAFFED +:1053A000BE90EB6C50A4F7A3F9BEF27871C6DC0195 +:1053B000E0ECF3E568E275917D936A95E1F7089575 +:1053C00067E6096A85AE67BB72F36E3C3AF54FA596 +:1053D0007F520E518C68059BABD9831F19CDE05BC2 +:1053E0000000000000000000483038F0592F982FCE +:1053F000872F762F652F4850F7CF55278894442361 +:1054000039F0661F771F881F991F551F4A95C9F7E6 +:10541000652B0895483038F0562F672F782F892F45 +:10542000952F4850F7CF55278894442339F0979506 +:1054300087957795679557954A95C9F7952B089560 +:10544000AB01692F782F852F942F0895CF93DF9389 +:10545000FC01108211821282148215821682DC01F4 +:1054600017968AE1ED0119928A95E9F782E0838324 +:10547000DF91CF910895CF92DF92EF92FF921F9329 +:10548000CF93DF93CDB7DEB728970FB6F894DEBF82 +:105490000FBECDBF10924B0310924A0398EEC92E57 +:1054A00093E0D92EE12CF12CC0924C03D0924D0305 +:1054B000E0924E03F0924F0388E391E0909349030A +:1054C0008093480385EC90E09093550380935403B8 +:1054D00084EC90E0909357038093560380EC90E027 +:1054E000909359038093580381EC90E090935B0371 +:1054F00080935A0382EC90E090935D0380935C0369 +:1055000086EC90E090935F0380935E0310926103BA +:1055100010926203109263031092640388E09E016C +:105520002F5F3F4FD901E82F1D92EA95E9F711E06F +:1055300010939B0510929C0510929D0510929E055C +:1055400010929F051092A0051092A1051092A2053D +:105550001092AA041092A9041092B4051092B305F7 +:105560001092B6051092B505EBEAF4E090EFDF017A +:105570001D929A95E9F71887F901A3EAB5E0982FEB +:1055800001900D929A95E1F7F901ABEAB5E0982FF9 +:1055900001900D929A95E1F71093B70592E09093E0 +:1055A000B80593E09093B90594E09093BA0595E01F +:1055B0009093BB0596E09093BC0597E09093BD0552 +:1055C0008093BE0589E08093BF058AE08093C00583 +:1055D0008BE08093C1058CE08093C2058DE08093C1 +:1055E000C3058EE08093C4058FE08093C50588E8ED +:1055F00094E00E94262A87E694E00E94262A1092D0 +:105600004B0410924A04C0924C04D0924D04E09294 +:105610004E04F0924F048AE491E090934904809301 +:10562000480410925F0410925E041092610410927C +:105630006004109263041092620410926504109248 +:105640006404809166048E7F8D7F8093660481FB65 +:10565000662760F9612786E00E94C40561E086E064 +:105660000E941006E5E2F8E0E491E0935804E1E1DD +:10567000F8E0E491F0E0EE0FFF1FEF5FF74F859148 +:10568000949190935A048093590460E085E00E94BD +:1056900010068091660481FD04C061E085E00E94EF +:1056A000C40585E080935404E4E2F8E0E491E093DB +:1056B0005504E0E1F8E0E491F0E0EE0FFF1FE9505F +:1056C000F84F85919491909357048093560487E204 +:1056D00094E00E94262A81E080932D048FE280933B +:1056E0002C0486E094E00E94262A83E080930C0438 +:1056F00082E080930B0485EE93E00E94262A8AE0E4 +:105700008093EB0380E18093EA0328960FB6F89428 +:10571000DEBF0FBECDBFDF91CF911F91FF90EF9005 +:10572000DF90CF900895CF93DF93CDB7DEB7CA5502 +:10573000D1090FB6F894DEBF0FBECDBF789484B503 +:10574000826084BD84B5816084BD85B5826085BD7D +:1057500085B5816085BD80916E00816080936E000B +:1057600010928100809181008260809381008091FD +:1057700081008160809381008091800081608093AE +:1057800080008091B10084608093B1008091B0006E +:1057900081608093B00080917A00846080937A0069 +:1057A00080917A00826080937A0080917A00816093 +:1057B00080937A0080917A00806880937A001092BA +:1057C000C100A89580E090E0892B11F00E940000B4 +:1057D0000E9446048091E7028D7F8093E7020E9439 +:1057E0002F0940E250E063E671E0CE0101960E948D +:1057F0003E2E40E150E06CE871E0CE0181960E94BF +:105800003E2E49E050E063E871E0CE01C1960E946F +:105810003E2E41E050E06AE171E0CE01865A9F4F92 +:105820000E943E2E28EC31E040E050E0BE016F5F68 +:105830007F4FCE01CA960E94142741E050E063E0FA +:1058400071E086EE92E00E943E2E6FEF81E090E0E4 +:105850000E94662E8091F3028F788093F30210925B +:10586000E9021092E8028FE191E00E94590786E96F +:1058700093E290939B0180939A010E9471066B01C1 +:105880007C010E9471066C197D098E099F096031A7 +:10589000774281059105C8F00E94E619A89500E0BD +:1058A00010E0A8950E943B078091F20284FD0E94BF +:1058B000570E0E94C81A0115110599F30E9406059A +:1058C000882379F30E940000ECCF0E943B070E94DE +:1058D00053128091F20282FB882780F9A8958111EA +:1058E000DBCFCFCF8AE491E09093490480934804C2 +:1058F0008091390390913A038854944071F4E09177 +:105900005B04F0915C04908180915D048095892313 +:10591000808310923A03109239030895FC0188277E +:105920009927E89421912032E9F3293010F02E30A4 +:10593000C8F32B3241F02D3239F4689404C00E9430 +:10594000122D820F911D219120532A30C0F31EF495 +:10595000909581959F4F08951F93FC019927882763 +:10596000BC01E89411911032E9F3193010F01E30A7 +:10597000C8F31B3251F01D3249F4689406C00E94EE +:10598000FD2C610F711D811D911D119110531A3055 +:10599000B0F33EF490958095709561957F4F8F4F51 +:1059A0009F4F1F910895FB01DC0105900D9200208F +:1059B000E1F70895FC0105900020E9F780959095A6 +:1059C0008E0F9F1F0895FB01DC014150504048F0AD +:1059D00005900D920020C9F701C01D924150504022 +:1059E000E0F70895FC016150704001900110D8F774 +:1059F000809590958E0F9F1F0895592F482F372F10 +:105A0000262F660F771F881F991F660F771F881F25 +:105A1000991F620F731F841F951F660F771F881FC2 +:105A2000991F08957AE0979F902D879F802D910D63 +:105A3000112408950E945C2D08F481E00895E894F3 +:105A400009C097FB3EF490958095709561957F4FC6 +:105A50008F4F9F4F9923A9F0F92F96E9BB27939574 +:105A6000F695879577956795B795F111F8CFFAF484 +:105A7000BB0F11F460FF1BC06F5F7F4F8F4F9F4FB5 +:105A800016C0882311F096E911C0772321F09EE813 +:105A9000872F762F05C0662371F096E8862F70E079 +:105AA00060E02AF09A95660F771F881FDAF7880F53 +:105AB0009695879597F90895990F0008550FAA0BA9 +:105AC000E0E8FEEF16161706E807F907C0F0121611 +:105AD0001306E407F50798F0621B730B840B950B14 +:105AE00039F40A2661F0232B242B252B21F4089569 +:105AF0000A2609F4A140A6958FEF811D811D089506 +:105B00000E94932D0C94042E0E94F62D38F00E94D2 +:105B1000FD2D20F0952311F00C94ED2D0C94F32D18 +:105B200011240C94382E0E94152E70F3959FC1F30A +:105B3000950F50E0551F629FF001729FBB27F00D3B +:105B4000B11D639FAA27F00DB11DAA1F649F662790 +:105B5000B00DA11D661F829F2227B00DA11D621FDF +:105B6000739FB00DA11D621F839FA00D611D221F99 +:105B7000749F3327A00D611D231F849F600D211D7D +:105B8000822F762F6A2F11249F5750409AF0F1F000 +:105B900088234AF0EE0FFF1FBB1F661F771F881F69 +:105BA00091505040A9F79E3F510580F00C94ED2D87 +:105BB0000C94382E5F3FE4F3983ED4F386957795A6 +:105BC0006795B795F795E7959F5FC1F7FE2B880F0F +:105BD000911D9695879597F9089597F99F6780E8A5 +:105BE00070E060E008959FEF80EC089500240A942F +:105BF0001616170618060906089500240A941216A8 +:105C00001306140605060895092E0394000C11F4DA +:105C1000882352F0BB0F40F4BF2B11F460FF04C087 +:105C20006F5F7F4F8F4F9F4F089557FD9058440FE0 +:105C3000551F59F05F3F71F04795880F97FB991FEB +:105C400061F09F3F79F087950895121613061406A8 +:105C5000551FF2CF4695F1DF08C016161706180635 +:105C6000991FF1CF86957105610508940895E89410 +:105C7000BB2766277727CB0197F90895DC01CB0175 +:105C8000FC01F999FECF06C0F2BDE1BDF89A31964C +:105C900000B40D9241505040B8F70895F999FECFE5 +:105CA00092BD81BDF89A992780B50895DC01A40FB3 +:105CB000B51F4150504048F0CB01840F951F2E91E5 +:105CC0000E94672E41505040D0F70895262FF99931 +:105CD000FECF92BD81BDF89A019700B4021639F04B +:105CE0001FBA20BD0FB6F894FA9AF99A0FBE08951C +:105CF000262FF999FECF1FBA92BD81BD20BD0FB6E8 +:105D0000F894FA9AF99A0FBE019608955058BB2755 +:105D1000AA270E949E2E0C94042E0E94F62D38F085 +:105D20000E94FD2D20F039F49F3F19F426F40C94C5 +:105D3000F32D0EF4E095E7FB0C94ED2DE92F0E9476 +:105D4000152E58F3BA17620773078407950720F0DA +:105D500079F4A6F50C94372E0EF4E0950B2EBA2F9D +:105D6000A02D0B01B90190010C01CA01A001112461 +:105D7000FF27591B99F0593F50F4503E68F11A160D +:105D8000F040A22F232F342F4427585FF3CF46959E +:105D900037952795A795F0405395C9F77EF41F16C0 +:105DA000BA0B620B730B840BBAF09150A1F0FF0F8A +:105DB000BB1F661F771F881FC2F70EC0BA0F621F76 +:105DC000731F841F48F4879577956795B795F79566 +:105DD0009E3F08F0B0CF9395880F08F09927EE0FFB +:105DE0009795879508950E94072F0C94042E0E9482 +:105DF000FD2D58F00E94F62D40F029F45F3F29F068 +:105E00000C94ED2D51110C94382E0C94F32D0E940E +:105E1000152E68F39923B1F3552391F3951B550B78 +:105E2000BB27AA2762177307840738F09F5F5F4F6D +:105E3000220F331F441FAA1FA9F335D00E2E3AF0AC +:105E4000E0E832D091505040E695001CCAF72BD0C4 +:105E5000FE2F29D0660F771F881FBB1F2617370715 +:105E60004807AB07B0E809F0BB0B802DBF01FF2747 +:105E700093585F4F3AF09E3F510578F00C94ED2D0A +:105E80000C94382E5F3FE4F3983ED4F386957795D3 +:105E90006795B795F7959F5FC9F7880F911D969500 +:105EA000879597F90895E1E0660F771F881FBB1F5C +:105EB000621773078407BA0720F0621B730B840B09 +:105EC000BA0BEE1F88F7E09508950E946C2F689436 +:105ED000B1110C94382E08950E941D2E88F09F5702 +:105EE00098F0B92F9927B751B0F0E1F0660F771FFE +:105EF000881F991F1AF0BA95C9F714C0B13091F0F4 +:105F00000E94372EB1E008950C94372E672F782F1A +:105F10008827B85F39F0B93FCCF3869577956795B8 +:105F2000B395D9F73EF490958095709561957F4F24 +:105F30008F4F9F4F08950E945C2D08F48FEF0895B6 +:105F4000AA1BBB1B51E107C0AA1FBB1FA617B7079F +:105F500010F0A61BB70B881F991F5A95A9F78095BB +:105F60009095BC01CD01089597FB072E16F400947F +:105F700007D077FD09D00E94A02F07FC05D03EF482 +:105F8000909581959F4F0895709561957F4F0895E5 +:105F9000A1E21A2EAA1BBB1BFD010DC0AA1FBB1F2D +:105FA000EE1FFF1FA217B307E407F50720F0A21B9F +:105FB000B30BE40BF50B661F771F881F991F1A940C +:105FC00069F760957095809590959B01AC01BD0136 +:105FD000CF010895EE0FFF1F0590F491E02D099475 +:105FE000FB01DC0102C001900D9241505040D8F7F6 +:105FF0000895FB01DC014150504048F001900D92A2 +:106000000020C9F701C01D9241505040E0F70895AB +:1060100014E0CBE1D4E004C0FE010E94EA2F2196F7 +:0A602000CC31D107C9F7F894FFCF87 +:10602A00FFFFFF00FCE1A8A8B1098507E923F007F3 +:10603A00CE23C107AF07A50712240A080103FA00F5 +:10604A000A3424030002FE6401FF2B010100FFFF52 +:10605A007D067D060000000032059C04C9049A05ED +:10606A00FA04D804EC040000000097069C042C07EC +:10607A009606F3060B077E060D0A00322E332E31E2 +:0A608A000079533168596C68360044 +:00000001FF diff --git a/code/Signal-hub/Signal-hub.ino b/code/Signal-hub/Signal-hub.ino new file mode 100644 index 0000000..a46f7aa --- /dev/null +++ b/code/Signal-hub/Signal-hub.ino @@ -0,0 +1,2830 @@ +/* + * + * Signal Hub + * + * This device can copy signals from wireless remote controls that use the 433 frequency, and then rebroadcast them. It can optionally also copy Infra red (IR) signals. + * + * It can do this in three ways: + * - Copy and replay ON and OFF signals. For example, from cheap wireless power switches. It basically copies remote controls. + * - Copy and then replay a single signal. For example, to emulate a window sensor. + * - Recognise signals without replaying them. For example, After learning the signal once, it can detect when a window sensor is triggered again. Or when a button on a remote control is pressed. + * + * This allows you to: + * - Create a smart home security solution using cheap window and movement sensors. + * - Automatically turn on lights and other devices when you get home, or when the sun goes down etc, using wireless power sockets. + * - Control automations using wireless buttons or remote controls. + * + * An Arduino Nano can store 50 "recognise only" signals, or about 20 on/off signals. You can store any combination of these. If you need to store more signals you could look into using an Arduino Mega. + * + * Are there any limits? + * - This does not work on things like garage door openers or keyless entry systems for cars. + * These devices have a very basic protection: the code changes everytime you use it, so replaying signals will not open the door again. + * + * Security? + * - Many cheap 433Mhz devices do not use encryption. This allows us to copy the signal in the first place. + * This also means that your neighbour can in theory do the same thing you can: copy and replay signals picked up through the walls. + * + * + * + * SETTINGS */ + +#define HAS_TOUCH_SCREEN // Have you connected a touch screen? Connecting a touch screen is recommended. + +//#define VERTICALLY_FLIP_TOUCH_SCREEN // Vertical flip. Select this if you would like to vertically flip the touch screen. + +//#define RF_NANO // RF-Nano. Check this box if you are using the RF-Nano Arduino, which has a built in radio. The Candle project uses the RF-Nano. + + /* END OF SETTINGS + * + * + * ABOUT THE CODE + * + * The code has a number of states it can be in. + * LISTENING MODE. Here The main loop continuously listens for signals. If it detects it calls three successive funtions: + * 1. Check if signal is a signal (SignalViabilityCheck function) + * 2. Clean up the signal (signalCleaner function) + * 3. Analyse the signal to find the binary code it represents (signalAnalysis function). + * + * If a valid binary code is found, the next action depends on which 'state' the system is in. + * - If in LISTENING_SIMPLE state, then the signal is compared to all the stored signals. It lets you know if there is a match. + * - If in LISTENING_ON state, then the signal is compared to all the stored signals. It lets you know if there is a match. + * - If in COPYING_SIMPLE state, the code is stored as a 'simple' signal. This can then be replayed later. + * - If in COPYING_ON state, the code is stored, after which the system asks for the OFF code (COPYING_OFF state), and then stores it with the same data. + * - If in LEARNING_SIMPLE state, only the binary code is stored, and not the meta-data required to fully recreate the signal. + * + * The final states the system can be in are: + * - IN_MENU. This is when the system is displaying a menu on the screen. + * - REPLAYING. This is the state while a signal is being replayed. + * + * Depending on the current state the various functions can work in slightly different ways. + * take for example the scanEeprom function: + * - When in LISTENING state it compares the latest found signal to existing signals stored in the EEPROM memory. + * - When in REPLAYING state it returns data required to rebuild the original signal. + * - If called with a 0, then it does not try to recognise or rebuild anything. This is used during setup, when we only need to know how many signals are stored. + * + * __SIGNAL ANALYSIS DETAILS__ + * When it detects a signal, the code tries to find the part of the signal that repeats. + * In normal operation the signalCleaner function cleans up the signal and simultaneously tries to find the 'betweenSpace' variable. + * Often, 433Mhz signals have a repeating binary code that is interrupted by a short burst of different signals (called the 'anomaly' in this code). + * If no anomaly can be detected, then the repeating part is probably 'back to back', without a separator signal. + * In this case there is a 'backup' function, the 'pattern finder'. This uses brute force to find the signal. + * If both methods fail, then the signal cannot be copied. + * + * + * + * TODO + * - Check if signal is already stored before storing it. Then again, there can be good reasons to store a signal twice. Perhaps only check for doubles with recognise-only signals? + * - Another bit could be used to store if an on/off signal should also be recognisable. That way the remote could be used twice somehow. + * - Allow multiple quick succession touch screen events to add play commands to the playlist. + */ + + +//#define DEBUG // Do you want to see extra debugging information in the serial output? +//#define DEBUG_SCREEN // Do you want to see extra debugging information about the touch screen in the serial output? +//#define MY_DEBUG // Enable MySensors debug output to the serial monitor, so you can check if the radio is working ok. + +// Receiver and transmitter pins +#define RECEIVER 3 // The pin where the receiver is connected. +#define TRANSMITTER 4 // The pin where the transmitter is connected. + +#define TOUCH_SCREEN_RX_PIN 5 // The receive (RX) pin for the touchscreen. This connects to the transmit (TX) pin of the touchscreen. +#define TOUCH_SCREEN_TX_PIN 6 // The receive (TX) pin for the touchscreen. This connects to the transmit (RX) pin of the touchscreen. + +#ifdef RF_NANO +// If you are using an RF-Nano, you have to switch CE and CS pins. +#define MY_RF24_CS_PIN 9 // Used by the MySensors library. +#define MY_RF24_CE_PIN 10 // Used by the MySensors library. +#endif + + +// This code has an extra pattern finding trick. Using brute force it will try to find a pattern in the data. The downside is it takes a lot of time to analyse signals this way. +// This means the system might not detect a signal because it is busy analysing a bad signal. It's up to you if you want to use it. +//#define PATTERN_FINDER + +// Enable and select the attached radio type +#define MY_RADIO_RF24 // This is a common and simple radio used with MySensors. Downside is that it uses the same frequency space as WiFi. +//#define MY_RADIO_NRF5_ESB // This is a new type of device that is arduino and radio all in one. Currently not suitable for beginners yet. +//#define MY_RADIO_RFM69 // This is an open source radio on the 433mhz frequency. Great range and built-in encryption, but more expensive and little more difficult to connect. +//#define MY_RADIO_RFM95 // This is a LoRaWan radio, which can have a range of 10km. + +// MySensors: Choose your desired radio power level. High power can cause issues on cheap Chinese NRF24 radio's. +//#define MY_RF24_PA_LEVEL RF24_PA_MIN +//#define MY_RF24_PA_LEVEL RF24_PA_LOW +//#define MY_RF24_PA_LEVEL RF24_PA_HIGH +#define MY_RF24_PA_LEVEL RF24_PA_MAX + +// Mysensors advanced security +#define MY_ENCRYPTION_SIMPLE_PASSWD "yS1hYlh6" // If you are using the Candle Manager, the password will be changed to what you chose in the interface automatically. Be aware, the length of the password has an effect on memory use. +//#define MY_SIGNING_SOFT_RANDOMSEED_PIN A7 // Setting a pin to pickup random electromagnetic noise helps make encryption more secure. + +// Mysensors advanced settings +#define MY_TRANSPORT_WAIT_READY_MS 10000 // Try connecting for 10 seconds. Otherwise just continue. +//#define MY_RF24_CHANNEL 100 // In EU the default channel 76 overlaps with wifi, so you could try using channel 100. But you will have to set this up on every device, and also on the controller. +#define MY_RF24_DATARATE RF24_1MBPS // Slower datarate makes the network more stable? +//#define MY_NODE_ID 10 // Giving a node a manual ID can in rare cases fix connection issues. +//#define MY_PARENT_NODE_ID 0 // Fixating the ID of the gatewaynode can in rare cases fix connection issues. +//#define MY_PARENT_NODE_IS_STATIC // Used together with setting the parent node ID. Daking the controller ID static can in rare cases fix connection issues. +#define MY_SPLASH_SCREEN_DISABLED // Saves a little memory. +//#define MY_DISABLE_RAM_ROUTING_TABLE_FEATURE // Saves a little memory. + + + +// REQUIRED LIBRARIES + +#include // The library that helps form the wireless network. +#include // Allows for storing data on the Arduino itself, like a mini hard-drive. + + +//#define HAS_BASIC_OLED_SCREEN // Have you connected a simple OLED screen? Connecting a screen is recommend. + +// Basic OLED screen +#ifdef HAS_BASIC_OLED_SCREEN +#define INCLUDE_SCROLLING 0 +#define OLED_I2C_ADDRESS 0x3C +#include // Driver for the simple OLED screen. +#include // "SSD1306Ascii" +SSD1306AsciiAvrI2c oled; +#endif + + +// Touch screen +#ifdef HAS_TOUCH_SCREEN + +#include +SoftwareSerial touch_screen_serial(TOUCH_SCREEN_RX_PIN,TOUCH_SCREEN_TX_PIN); // RX (receive) pin, TX (transmit) pin + +#define MAX_BASIC_COMMAND_LENGTH 16 // How many bytes are in the longest basic command? +#define TOUCHSCREEN_WIDTH 240 +#define TOUCHSCREEN_HEIGHT 320 +#define BUTTON_HEIGHT 53 // How many pixels tall are the touch screen buttons? +#define BUTTON_PADDING (BUTTON_HEIGHT/2) - 7 // The font is 14 pixels high, so this calculation places it in the middle of the buttons. + +const byte howManyReplayButtonsWillFitOnScreen = (byte)floor( (TOUCHSCREEN_HEIGHT / BUTTON_HEIGHT) - 2 ); // Minus one for the menu button, and one for the 'more' button. + +boolean touched = false; // Was the touchscreen just touched? +byte visibleReplayButtonsPage = 0; // The user can scroll through all the replay buttons. + +signed int touchX = 0; // Touch screen position X +signed int touchY = 0; // Touch screen position Y + +// Basic commands for the touch screen. All commands for the TFT should start with 0x7E, but to save storage space this is taken care of in the basicCommand function. +PROGMEM const byte play[] = {0x07, 0x11, ' ', 'P', 'L', 'A', 'Y', 0xEF,}; // Places the word ' play' on the screen. +PROGMEM const byte on[] = {0x07, 0x11, ' ', 'O','N', ' ', ' ', 0xEF,}; // Places the word ' on ' on the screen. +PROGMEM const byte off[] = {0x07, 0x11, ' ', 'O', 'F', 'F', ' ', 0xEF,}; // Places the word ' off ' on the screen. +PROGMEM const byte w[] = {0x07, 0x11, 'w', 0x00, ' ', 0x00, 0x00, 0xEF,}; // Places the word 'w ' on the screen. +PROGMEM const byte menu[] = {0x07, 0x11, 'M', 'E', 'N', 'U', ' ', 0xEF,}; // Places the word 'menu ' on the screen. +PROGMEM const byte more[] = {0x07, 0x11, 'M', 'O', 'R', 'E', '>', 0xEF,}; // Places the word 'menu ' on the screen. + +#ifdef VERTICALLY_FLIP_TOUCH_SCREEN +PROGMEM const byte set_vertical[] = {0x03, 0x04, 0x00, 0xEF,}; // To set rotation of the screen to vertical. Instead of the 0x02 you can try 0x00 (vertical B), 0x01 (horizontal A) or 0x03 (horizontal B). +#else +PROGMEM const byte set_vertical[] = {0x03, 0x04, 0x02, 0xEF,}; // To set rotation of the screen to vertical. Instead of the 0x02 you can try 0x00 (vertical B), 0x01 (horizontal A) or 0x03 (horizontal B). +#endif + +PROGMEM const byte fill_black[] = {0x04, 0x20, 0x00, 0x00, 0xEF,}; // Fill screen with one color +PROGMEM const byte fill_blue[] = {0x04, 0x20, 0x00, 0xFF, 0xEF,}; // Fill screen with one color + +PROGMEM const byte text_color_white[] = {0x04, 0x02, 0xFF, 0xFF, 0xEF,}; // white text color. fill screen with one color +//PROGMEM const byte text_color_black[] = {0x04, 0x02, 0x00, 0x00, 0xEF,}; // Dark text color. fill screen with one color +//PROGMEM const byte text_color_red[] = {0x04, 0x02, 0xF8, 0x00, 0xEF,}; // .. text color. fill screen with one color + +//PROGMEM const byte resetTFT[] = {0x02, 0x05, 0xEF,}; // Resets the TFT. But has no real effect. +#ifdef DEBUG_SCREEN +PROGMEM const byte testTFT[] = {0x02, 0x00, 0xEF,}; // Test the TFT, should respond with "OK". +#endif +PROGMEM const byte backlight_on[] = {0x03, 0x06, 0xFF, 0xEF,}; // Backlight intensity to half-full +PROGMEM const byte backlight_off[] = {0x03, 0x06, 0x00, 0xEF,}; // Backlight intensity to zero +//PROGMEM const byte serialSpeedUp[] = {0x03, 0x40, 0x03, 0xEF,}; // Sets communication speed to 57600 (from 9600) +//PROGMEM const byte serialSlowDown[] = {0x03, 0x40, 0x00, 0xEF,}; // Sets communication speed to 9600 again. Oddly enough, it seems it works fastest at this speed.. + +PROGMEM const byte test[] = {0x02, 0x00, 0xEF,}; // Test message + +#endif + + +PROGMEM const char detectedMessage[] = { "Detected " }; // This construction saves some memory. +PROGMEM const char replayMessage[] = { "Replay " }; // This construction saves some memory. + +/* +The colors use this RGB565 format: +http://www.barth-dev.de/online/rgb565-color-picker/ + +white: FF FF = 65535; +red: F8 00 = 63488 +purple: F0 1F = 61471 +blue: 00 1F = 31 +light blue: 07 FF = 2047 +bright green: 07 E0 = 2016 +yellow: FF 20 = 65312 +orange: FC 80 = 64640 +half grey: 7BEF = 31727 +*/ + + + + +// Keypad +#define KEYPAD_PIN A0 // The pin where the analog keypad is connected. These keypads vary their resistance according to which button is pressed. +byte buttonPressed = 100; // The last button that was pressed by the user. +byte prevButtonState = 100; +#define KEYPAD_BUTTON_COUNT 0 // How many buttons does your keypad have? Leave at 0 if you are using a touch screen. + +#if KEYPAD_BUTTON_COUNT > 0 +boolean buttonsToggleStatus[KEYPAD_BUTTON_COUNT + 1]; // Array to hold the buttons' toggle status (if the button has an on/off signal). For simple signals buttonsToggleStatus[x] is always 0. For on/off signals this actually switches between 0 and 1. For simplicity, the zero position of the array is ignored. +#endif + + +// SIGNAL CLONING + +/* What length of signal are we looking for? This determines how many edges we need to be able to store. Here's a chart: + * + * 1 byte = 8 bits = 16 timings + * 2 bytes = 16 bits = 32 timings + * 3 bytes = 24 bits = 48 timings <- default for MINIMAL_SIGNAL_LENGTH. Cheap window and door sensors use this. + * 4 bytes = 32 bits = 64 timings + * 5 bytes = 40 bits = 80 timings + * 6 bytes = 48 bits = 96 timings + * 8 bytes = 64 bits = 128 timings <- Most wireless sockets use 8 byte signals. I have never come across a longer signal. + * 10 bytes = 80 bits = 160 timings + * 12 bytes = 96 bits = 192 timings + * + * 16 bytes = 128bits = 256 timings + * + * As you can see, getting more than 16 bytes in practice requires more memory than the Arduino Nano has. + * Ideally, your MAXEDGES setting should be 3x the size of the repeating signal you are looking for. + * + */ +#define MAXEDGES 300 // Maximum samples, limited by RAM. The findPattern() function requires more signals to work than the default analyser. +#define GRANULARITY 50 // Sensitivity. Lower can grab faster signals, but might be less dependable. Set somewhere between 50 and 100. +#define EDGES_TO_SKIP 0 // How much of the beginning of the incoming signal to skip. This is a memory saving measure. Sometimes the first part of the signal is the 'pre-amble': simple timings to help the receiver synchronise its clock. Set somewhere between 0 and 100. Default is 60. +#define MINIMAL_SIGNAL_LENGTH 48 // How many edges should a signal have at the least? ( 1 byte = 2 nibbles = 8 bits = 16 edges). + +#define MINIMUMDURATION 100 // Minimum low or high signal duration for a valid signal in microseconds. Set somewhere between 50 and 100. Helps to avoid noise. +#define MAXIMUMDURATION 20000 // Maximum low or high signal duration for a valid signal. +#define MINIMUMSILENCE 30000 // Minimum low period after a complete signal in microseconds. If there is no input for this long, we can conclude that the transmission must have finished. +#define EEPROM_STORAGE_START 512 // From which position the eeprom can safely be used as storage without overwriting MySensors encryption data. Another option woudl be to use EEPROM_LOCAL_CONFIG_ADDRESS. +#define MAXI 249 * GRANULARITY // The maximum length in microseconds that any timing may have to be precisely stored. If a timing is longer, it will be truncated. + +byte timings[MAXEDGES]; // Creates the array we use to store the timings, but that is also re-used for other things in order to save memory. +const byte metadataArraySize = 8; // The size of the array to store the serial data we're decoding in. +byte metaData[metadataArraySize]; // Holds metadata for a replayable signal. +long signalstart = 0; // Used to calculate the length of each received timing. +long signalend; // Used to calculate the length of each received timing. +unsigned int interval; // The length of a timing in milliseconds. +signed int edges = 0 - EDGES_TO_SKIP; // By starting below zero we can try to avoid the beginning of signals, which often contains a 'pre-amble': a boring pattern to help the receiver get up to speed. +byte bucketsTotal = 0; // This describes how many different timings there are in the signal. To clean up the signal it's wise to lump neighbouring timings together. +byte repeatingPatternLength = 255; // This describes how many timings the repeating part of the signal is made of. +byte amountOfStoredSignals = 0; // How many signals are curently stored on the EEPROM storage. This counts detect-only as well as replayable signals. +byte amountOfStoredReplayableSignals = 0; // How many replayable signals are stored in the EEPROM? +byte repeatingSignalByteLength = 3; // How many bytes does the repeating part of the signal take up in EEPROM? +boolean lastByteIsSplit = false; // Is the last byte of a new signal only half-filled? Signals are multiples of 4 bits, but we can only store them in multiples of 8. So a signal with 20 bits (5 'nibbles'), would still be stored in 3*8 = 24 bits. We need to know that when reconstructing the signal. +boolean anomalyInside = false; // Is the anomaly part of the byte/nibble, or is it outside of it? +byte betweenSpace = 250; // Which timing denotes the space ("the anomaly" as it's called in this code) between repeated signals? If it's still set at 250 after the analysis, the the analysis must have failed to find it. +int startPosition = 1; // The start position of a clean signal (this cuts of the first one) +int endPosition = MAXEDGES - 1; // The end position of a clean signal (this cuts of the last one, which is often truncated). +int positionOfLastSignalEnd = EEPROM_STORAGE_START; // Denotes the EEPROM position right before the position where a new signal can safely be stored. +boolean validSignal = true; // Used by the signal detection loop If the 'high' part of a timing was bad, then this is set to false. Looking for a valid 'low' is then skipped. +boolean captureFinished = false; // If the entire edges array is full of freshly received timings, this is set to true. Analysis the signal is then set in motion. +byte bucketCount = 0; // How many different types of timings are there in the signal. This is used to tighten up the signal. +boolean connectedToNetwork = false; // Are we connected to the local MySensors network? Used to display the 'w' connection icon. +byte lengthOfSignalWeAreWaitingFor = 3; // Used when recording on-off signals. The off-signal should have the same byte length as the on signal. +byte brightnessTimer = 0; // When this reaches 0 the screen is turned off. + +#define PLAYLIST_SIZE 6 +byte playlist[PLAYLIST_SIZE]; // Sometimes multiple demands to play a signal come in. This holds all the signals we should replay one after the other +byte playlist_position = 0; // Signals that should be replayed are placed in a playlist, so they can be played one after the other of multiple should be played. + +byte response_position = 0; // Used in dealing with incoming serial messages from the touch screen. + + +// DESCRIPTION BIT STATES +#define DESCRIPTION_HALFBYTE 0 +#define DESCRIPTION_DUO_RECONSTRUCTION_TYPE 1 +#define DESCRIPTION_ANOMALY_INSIDE 2 +#define DESCRIPTION_ON_OFF 3 +#define DESCRIPTION_REPLAYABLE 4 +#define DESCRIPTION_UNRECONSTRUCTABLE_DUO 5 +#define DESCRIPTION_ANOMALY 6 +#define DESCRIPTION_LARGE_ANOMALY 7 + + +// DISPLAY & STATES +// The list is shared between the display function as well as to desribe what the device is currently doing. + +// Menu states +#define MENU_MAIN 200 +#define MENU_NEW 30 + #define LEARNING_SIMPLE 31 + #define LEARNING_ON 32 + #define COPYING_SIMPLE 33 + #define COPYING_ON 34 + +#define MENU_DELETE_LAST 40 + #define DELETE_LAST 41 + +#define MENU_DELETE_ALL 50 + #define DELETE_ALL 51 + +#define LEARNING_OFF 38 +#define COPYING_OFF 39 + + + +// General display codes +#define PROCESSING 1 // Not a state, only used for display. +#define MATCH 2 // Not a state, only used for display. +#define REPLAYING 3 +#define SIGNAL_STORED 4 // Not a state, only used for display. + +// Display codes for errors +#define BAD_SIGNAL 5 // Not a state, only used for display. +#define OUT_OF_SPACE 6 // Not a state, only used for display. +#define PLAY_SIMPLE_SIGNAL 7 +#define PLAY_ON_SIGNAL 8 // Not a state, only used for display. +#define PLAY_OFF_SIGNAL 9 // Not a state, only used for display. +#define DELETED_LAST 10 // Not a state, only used for display. +#define DELETED_ALL 11 // Not a state, only used for display. + +#define NO_MORE_FREE_BUTTONS 100 // Not a state, only used for display. +#define NO_SIGNAL_STORED_YET 101 // Not a state, only used for display. + +#define STARTUP 254 // This state is only used while booting up the device. +#define LISTENING 255 // This is the default state which it always returns to. + +byte state = STARTUP; // This variable stores what the device is currently doing. It shares some states with the display output. + +#ifdef HAS_TOUCH_SCREEN +#define DISPLAY_REPLAY_BUTTONS 253 // State used with touchscreen only. + + +// The MessageDef code below comes from https://arduino.stackexchange.com/questions/49236/printing-char-array-from-array-of-structs-in-progmem-to-serial + +typedef byte MessageID; // TODO Is this used? Not really. Simplifying the message table could save some storage space. + +struct MessageDef { + MessageID ID; + char Description[20]; +}; + +const MessageDef MessageTable[] PROGMEM = { + {LISTENING, "CANCEL"}, + {MENU_NEW, "New signal"}, + {MENU_DELETE_LAST,"Delete last"}, + {MENU_DELETE_ALL, "Delete all"}, + + {LEARNING_SIMPLE, "Detect single"}, + {LEARNING_ON, "Detect on + off"}, + {COPYING_SIMPLE, "Replay single"}, + {COPYING_ON, "Replay on + off"}, + + {LEARNING_SIMPLE, "Really delete last"}, + {LEARNING_SIMPLE, "Really delete ALL"}, + + {PROCESSING, "Processing"}, // 1 + {MATCH, "Signal matched!"}, // 2 + {REPLAYING, "Replaying "}, // 3 + {SIGNAL_STORED, "Signal was stored"}, // 4 + {BAD_SIGNAL, "Bad signal try again"}, // 5 + {OUT_OF_SPACE, "Out of storage space"}, // 6 + {PLAY_SIMPLE_SIGNAL,"Play the signal"}, // 7 + {PLAY_ON_SIGNAL, "Play ON signal"}, // 8 + {PLAY_OFF_SIGNAL, "Play OFF signal"}, // 9 + {DELETED_LAST, "Deleted last"}, // 10 + {DELETED_ALL, "Deleted all"} // 11 + }; + +#define START_OF_MENU_NEW 4 +#define START_OF_MENU_DELETE_LAST 8 +#define START_OF_MENU_DELETE_ALL 9 +#define START_OF_MENU_STATUS_MESSAGES 10 +#endif + + +// MYSENSORS + +#define RADIO_DELAY 400 // Milliseconds between sending radio signals. This keeps the radio happy. +#define DEVICE_STATUS_ID 1 // The first 'child' of this device is a text field that contains status updates. +#define LISTENER_OUTPUT_ID 2 // The first 'child' of this device is a text field that contains status updates. + +// The device creates 4 virtual buttons that allow signals to be recorded even without an attached screen and keypad. +#define LEARN_SIMPLE_BTN_ID 3 // Learn to detect a single signal. +#define LEARN_ON_OFF_BTN_ID 4 // Learn to detect an ON and an OFF signal that belong together. +#define COPYING_SIMPLE_BTN_ID 5 // Learn to replay a single signal. +#define COPYING_ON_OFF_BTN_ID 6 // Learn to replay an ON and an OFF signal that belong together. + +MyMessage textmsg(DEVICE_STATUS_ID, V_TEXT); // Sets up the message format that we'll be sending to the MySensors gateway later. In this case it's a text variable. The first part is the ID of the specific sensor module on this node. The second part tells the gateway what kind of data to expect. +MyMessage buttonmsg(LEARN_SIMPLE_BTN_ID, V_STATUS); // The message for replayable signals' buttons. This is an on/off message. +MyMessage detectmsg(10, V_TRIPPED); // The message for detect-only signals. This is an on/off message. + + +static unsigned long lastLoopTime = 0; // Holds the last time the main loop ran. +boolean resend_button_states = 1; + +void before() +{ + Serial.begin(115200); + Serial.println(F("Hello, I am a Signal Hub.")); +} + + +void presentation() +{ + scanEeprom(); // Find out how many signals are stored in memory. + + sendSketchInfo(F("Signal Hub"), F("1.1")); wait(RADIO_DELAY); // Child 0. Sends the sketch version information to the gateway and Controller + present(DEVICE_STATUS_ID, S_INFO, F("Device status")); wait(RADIO_DELAY); // Child 1. This outputs general status details. + + //present(LISTENER_OUTPUT_ID, S_INFO, F("Detected codes")); wait(RADIO_DELAY); // Child 2. This outputs the ID of detected signals that were matched to signals in eeprom. +#if !(defined(HAS_TOUCH_SCREEN)) + Serial.println(F("NO TOUCHSCREEN")); + present(LEARN_SIMPLE_BTN_ID, S_BINARY, F("Recognize a single code")); wait(RADIO_DELAY);// Child 3 + present(LEARN_ON_OFF_BTN_ID, S_BINARY, F("Recognize an ON+OFF code")); wait(RADIO_DELAY); // Child 4 + present(COPYING_SIMPLE_BTN_ID, S_BINARY, F("Copy a single code")); wait(RADIO_DELAY); // Child 5 + present(COPYING_ON_OFF_BTN_ID, S_BINARY, F("Copy an ON/OFF code")); wait(RADIO_DELAY); // Child 6 +#endif + + char childNameMessage[11]; + + strcpy_P(childNameMessage, replayMessage); + + // We loop over all the replayable signals, and present them to the controller. + for( byte replayableID=10; replayableID < 10 + amountOfStoredReplayableSignals; replayableID++ ){ +#ifdef DEBUG + Serial.print(F("Replayable child ID ")); Serial.println(replayableID); +#endif + childNameMessage[7] = (replayableID - 10) + 49; + present(replayableID, S_BINARY, childNameMessage); wait(RADIO_DELAY); + } + + strcpy_P(childNameMessage, detectedMessage); + + // We loop over all the detect-only signals, and present them to the controller. + for( byte recognisedID=100; recognisedID < 100 + (amountOfStoredSignals - amountOfStoredReplayableSignals); recognisedID++ ){ +#ifdef DEBUG + Serial.print(F("Detectable child ID ")); Serial.println(recognisedID); +#endif + childNameMessage[9] = (recognisedID - 100) + 49; // ASCII character '1' has number 49. + present(recognisedID, S_DOOR, childNameMessage); wait(RADIO_DELAY); + } + + resend_button_states = 1; +} + + + +void send_values(){ +#ifdef DEBUG + Serial.println(F("Sending button states")); +#endif + +#if !(defined(HAS_TOUCH_SCREEN)) + send(buttonmsg.setSensor(LEARN_SIMPLE_BTN_ID).set(0)); + send(buttonmsg.setSensor(LEARN_ON_OFF_BTN_ID).set(0)); + send(buttonmsg.setSensor(COPYING_SIMPLE_BTN_ID).set(0)); + send(buttonmsg.setSensor(COPYING_ON_OFF_BTN_ID).set(0)); +#endif + + // We loop over all the replayable signals, and send their values. + for( byte replayableID=10; replayableID < 10 + amountOfStoredReplayableSignals; replayableID++ ){ + //Serial.print(F("replay loadState at presentation: ")); Serial.println(loadState(replayableID)); + if( loadState(replayableID - 9) > 1 ){ +#ifdef DEBUG + Serial.println(F("LoadState had big value, setting to 0.")); +#endif + saveState(replayableID - 9, 0); // The -9 is to offset the ID back the the savestates in the eeprom. So child 10 has savestate 1, etc. + } + boolean saved_toggle_state = loadState(replayableID - 9); + send(buttonmsg.setSensor(replayableID).set( saved_toggle_state)); wait(RADIO_DELAY); // Tell the controller in what state the child is. + } + + wait(RADIO_DELAY); + + // We loop over all the detect-only signals, and send their values. + for( byte recognisedID=100; recognisedID < 100 + (amountOfStoredSignals - amountOfStoredReplayableSignals); recognisedID++ ){ + send(detectmsg.setSensor(recognisedID).set( 0 )); wait(RADIO_DELAY); // Tell the controller in what state the child is. + } + +} + +void setup() +{ + pinMode(RECEIVER, INPUT_PULLUP); // 433 receiver + //pinMode(RECEIVER, INPUT); // 433 receiver + pinMode(TRANSMITTER, OUTPUT); // 433 transmitter + digitalWrite(TRANSMITTER, LOW); // 433 transmitter set to off +#if KEYPAD_BUTTON_COUNT > 0 + pinMode(KEYPAD_PIN, INPUT); // Set keypad pin as input +#endif + +#ifdef HAS_BASIC_OLED_SCREEN + oled.begin(&Adafruit128x64, OLED_I2C_ADDRESS); // Start the display (if there is one) + oled.setFont(Adafruit5x7); + oled.ssd1306WriteCmd(SSD1306_DISPLAYON); + oled.setScroll(false); +#endif + +#ifdef HAS_TOUCH_SCREEN + wait(2000); + touch_screen_serial.begin(9600); + wait(2000); + +#ifdef DEBUG + for( int t = EEPROM_STORAGE_START - 1; t < EEPROM.length(); t++ ){ + Serial.print(t); Serial.print(F(" > ")); Serial.println( EEPROM.read(t) ); + } + Serial.print(F("replay button slots: ")); Serial.println( howManyReplayButtonsWillFitOnScreen ); +#endif + + +#ifdef DEBUG_SCREEN + Serial.println(F("BC: test")); + basicCommand(testTFT); +#endif + +#ifdef DEBUG_SCREEN + //Serial.println(F("BC: serial_slow")); +#endif + //basicCommand(serialSlowDown); + +#ifdef DEBUG_SCREEN + //Serial.println(F("BC: reset")); +#endif + //basicCommand(resetTFT); // Reset the TFT. + +#ifdef DEBUG_SCREEN + Serial.println(F("BC: backlight_on")); +#endif + basicCommand(backlight_on); + +#ifdef DEBUG_SCREEN + Serial.println(F("BC: vertical")); +#endif + basicCommand(set_vertical); // Set the screen to vertical mode. + +#ifdef DEBUG_SCREEN + Serial.println(F("BC: white text")); +#endif + basicCommand(text_color_white); // Set text color to white. + +#endif + + // Check if there is a network connection + if(isTransportReady()){ + Serial.println(F("Connected to gateway!")); + connectedToNetwork = true; + //send(relaymsg.setSensor(RELAY1_CHILD_ID).set( actualDoorStates[0] )); wait(RADIO_DELAY); // Tell the controller in what state the lock is. + + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Hi") )); //wait(RADIO_DELAY); + +#ifdef DEBUG + Serial.print(F("Stored signal count: ")); + Serial.println(amountOfStoredSignals); + Serial.print(F("Replayable signal count: ")); + Serial.println(amountOfStoredReplayableSignals); +#endif + + + } + else{ + Serial.println(F("! NOCONNECTION")); + connectedToNetwork = false; + } + + state = LISTENING; + updateDisplay(LISTENING); // Show "Listening" on the display. + clearTimingsArray(); // Reset everything, so that we are ready to listen for a signal. + +#ifdef DEBUG + Serial.print(F("Free RAM after setup = ")); Serial.println(freeRam()); +#endif + +} + + +void loop() +{ + //readResponse(); + //wait(200); + //Serial.print(F(".")); + //readResponse(); + + // This part of the code checks the radio receiver pins. + if( !captureFinished ){ + //Serial.print(F("|")); + if( signalstart == 0 ){ + signalstart = micros(); + } + + // Part 1 - HIGH + while( bitRead(PIND, RECEIVER) == HIGH ){} + signalend = micros(); + interval = signalend - signalstart; + if (interval > MINIMUMDURATION && interval < MAXIMUMDURATION ){ + if( edges >= 0 ){ // The edges variable can start at a negative number. This helps cut off the pre-amble that is often transmitted, and that we don't really need. + if( interval > MAXI ){ // Very long edges will be truncated. + timings[edges] = 249; + } + else if( interval != 0 ){ + timings[edges] = (byte) constrain((interval / GRANULARITY), 0, 255); // this rounds the number to something simpler that should fit in a byte array. + } + } + edges++; + } + else { + edges = 0 - EDGES_TO_SKIP; + validSignal = false; + captureFinished = true; + //Serial.println(F("bad timing HIGH")); + signalstart = micros(); + } + + // Part 2 - LOW + if( validSignal ){ // We only try to find a low part if the high part of the signal before it was valid. + while( bitRead(PIND, RECEIVER) == LOW && interval < MINIMUMSILENCE ){} + signalstart = micros(); + interval = signalstart - signalend; + + if( interval > MINIMUMDURATION && interval < MAXIMUMDURATION ){ // Check if the timing falls within reasonable boundaries. + if( edges >= 1 ){ + if(interval > MAXI){ // MAXI = 254 * granularity + timings[edges] = 249; // A timing longer than this will be truncated. + } + else if( interval != 0 ){ + timings[edges] = (byte) constrain((interval / GRANULARITY), 0, 255); // This rounds the number to something simpler that should fit in a byte array. + } + } + edges++; + } + else if( interval >= MINIMUMSILENCE ){ // If the low part of the signal takes a very long time, it could be that the transmission is over. + captureFinished = true; + //Serial.println(F("minimum LOW silence reached")); + if( edges < 0 ){ edges = 0 - EDGES_TO_SKIP; } + signalstart = 0; + } + else { + edges = 0 - EDGES_TO_SKIP; + //validSignal = false; + captureFinished = true; + //Serial.println(F("bad timing LOW")); + } + } + if( edges >= MAXEDGES - 2 ){ // Our timings array is full of fresh data. + captureFinished = true; + //Serial.print(F("edges full ")); + } + } + + else { // SignalCapture is finished. + captureFinished = false; // Reset for next round. + boolean signalIsOk = false; + //Serial.println(F("DONE CAPTURING")); +#ifdef HAS_TOUCH_SCREEN + readResponse(); +#endif + + if( validSignal && edges > MINIMAL_SIGNAL_LENGTH * 2 ){ // The timings data is long enough. + if( signalViabilityCheck() ){ // A quick quality check on the signal. +#ifdef DEBUG + Serial.println(F("PROCESSING")); +#endif +#ifdef HAS_BASIC_OLED_SCREEN + updateDisplay(PROCESSING); +#endif + betweenSpace = 250; // Reset the betweenSpace. Might be superfluous. + if( signalCleaner() ){ // Cleaning and tightening the received signal. + if( signalAnalysis() ){ + Serial.println(); + signalIsOk = true; + + if( state == LISTENING ){ // System received a good signal while in the LISTENING state. + Serial.println(F("Comparing")); + //byte detectedSignalNumber = scanEeprom(); + //Serial.print(F("DetectedSignalNumber = ")); Serial.println(detectedSignalNumber); + if( scanEeprom() ){ // If the signal matches a signal in eeprom, then the scanEeprom function returns its number in eeprom. If there is no match, it returns 0. + Serial.println(F("MATCH")); + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Detected a known signal") )); //wait(RADIO_DELAY); + } + } + else if( state > MENU_NEW && state < MENU_DELETE_LAST ){ // States in which a signal is supposed to be copied to the EEPROM memory. + + Serial.print(F("State ")); Serial.println(state); + + // If we are looking for an OFF signal, then we should check if this signal is just as long as the ON signal we heard earlier. + if( (state == LEARNING_OFF || state == COPYING_OFF) && repeatingSignalByteLength != lengthOfSignalWeAreWaitingFor ){ + // Poor signal. Try again. + } + else { + + // Store the signal + if( writeSignalToEeprom() ){ // We try to store the signal in the EEPROM (internal storage) + + // If we are doing an on/off copy, then we must move to the next step in the process. + if( state == COPYING_ON || state == LEARNING_ON ){ + Serial.println(F(" Now play OFF signal")); + lengthOfSignalWeAreWaitingFor = repeatingSignalByteLength; // When we record the 'off' signal later, we want it to be the same length. + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Now play the OFF signal") )); //wait(RADIO_DELAY); + if( state == COPYING_ON ){ state = COPYING_OFF; } // switch to the next part of the process. + if( state == LEARNING_ON ){ state = LEARNING_OFF; } // switch to the next part of the process. + } + else{ + updateDisplay(SIGNAL_STORED); + presentation(); // Re-present the node, which now has a new child. + Serial.println(F("Finished copying")); + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("OK") ));// wait(RADIO_DELAY); + state = LISTENING; + } + } + else{ // Storing the signal in EEPROM failed. + Serial.println(F("Error storing signal")); + updateDisplay(OUT_OF_SPACE); + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Error storing signal") )); //wait(RADIO_DELAY); + state = LISTENING; + } + } + updateDisplay(state); + } + } // End of 'signal is ok'. + else { +#ifdef DEBUG + Serial.println(F("signalAnalysis failed")); +#endif + } + } + else{ + Serial.println(F("No repeating part found")); // The signal cleaner couldn't find a repeating part + } + } + else { + Serial.println(F("Low quality signal")); + } + clearTimingsArray(); + } + else{ // The captured signal didn't have enough edges. + captureFinished = false; + validSignal = true; + } + + + // If a presentation has been requested, we send the new button states. + if( resend_button_states ){ + resend_button_states = 0; + send_values(); + } + +#if defined (HAS_BASIC_OLED_SCREEN) || defined (HAS_TOUCH_SCREEN) + + // + // MAIN MENU + // + + // Once every 100 milliseconds check if the menu button is being pressed. + if( millis() - lastLoopTime > 100 ){ + lastLoopTime = millis(); + + // If there is a signal to be played in the playlist, play it. + if( playlist_position > 0 ){ + Serial.print(F("Playing signal from playlist #")); Serial.println(playlist_position); + if( playlist[playlist_position] > 100 ){ // Bigger than 100 means it should be turned on. + replay( playlist[playlist_position] - 100, 1); + } + else{ + replay( playlist[playlist_position], 0); + } + playlist_position--; + Serial.print(F("-new #")); Serial.println(playlist_position); + } + + + // Turn screen off after a while + if( brightnessTimer > 1){ + brightnessTimer--; + //Serial.println(brightnessTimer); + } + else if( brightnessTimer == 1 ){ + brightnessTimer = 0; +#ifdef DEBUG_SCREEN + Serial.println(F("BC: backlight_off")); +#endif + basicCommand(backlight_off); // Set the screen to vertical mode. + } + + +#ifdef HAS_TOUCH_SCREEN + if( touched ){ + turnOnScreen(); + //Serial.println(F("TOUCH")); + buttonPressed = touchScreenButtonPress(); // Check what part of the touchscreen was pressed. +#ifdef DEBUG_SCREEN + drawPix(touchX,touchY, 0); // Draw a pixel where the user touched the screen. +#endif + touched = false; + +#elif KEYPAD_BUTTON_COUNT == 4 + buttonPressed = keypad4(); + if( buttonPressed != prevButtonState ){ +#elif KEYPAD_BUTTON_COUNT == 12 + buttonPressed = keypad12(); + if( buttonPressed != prevButtonState ){ +#endif + + if( buttonPressed == KEYPAD_BUTTON_COUNT ){ // Menu button is being pressed, which works as cancel if the user is already recording. + showMenu(); +#ifdef DEBUG + Serial.print(F("New state: ")); Serial.println(state); +#endif + + // Sub menu for deleting the eeprom. + if( state == DELETE_ALL ){ + Serial.println(F("ERASING STORED SIGNAL DATA")); + visibleReplayButtonsPage = 0; + updateDisplay(DELETED_ALL); + for( int g = EEPROM_STORAGE_START; g <= EEPROM.length(); g++ ){ // Deleting the data stored in the eeprom. + EEPROM.update(g, 255); + } + scanEeprom(); // Re-index the EEPROM, which in this case sets all stored signal counters back to 0. + state = LISTENING; + } + else if( state == DELETE_LAST ){ + visibleReplayButtonsPage = 0; + scanEeprom(); + updateDisplay(DELETE_LAST); + state = LISTENING; + } + updateDisplay(state); + } + +#ifdef HAS_TOUCH_SCREEN + else if( buttonPressed <= howManyReplayButtonsWillFitOnScreen ){ // A send-signal button is being pressed, and we're not inside the menu, so we should replay a signal. + if( buttonPressed <= amountOfStoredReplayableSignals - (visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen) ){ + //boolean onOrOff = 0; + //if( touchX > TOUCHSCREEN_WIDTH / 2 ){ // If the user pressed the right side of the virtual button. + // onOrOff = 1; + //} + //replay( buttonPressed + (visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen), onOrOff ); // The replay function manages the required state change internally. + + if( playlist_position < PLAYLIST_SIZE){ // We only add to the playlist if there is space left in the playlist. + + Serial.print(F("-Adding to playlist:")); Serial.print(buttonPressed + (visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen)); + playlist_position++; + if( touchX > TOUCHSCREEN_WIDTH / 2 ){ // Right side of the screen was clicked, so send signal to turn on. + Serial.println(F(", On")); + playlist[playlist_position] = (buttonPressed + (visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen)) + 100; + } + else { + Serial.println(F(", Off")); + playlist[playlist_position] = (buttonPressed + (visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen)); + } + } + + + + } + } + else { + Serial.println(F("MORE>")); + visibleReplayButtonsPage++; + if( visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen >= amountOfStoredReplayableSignals ){ + visibleReplayButtonsPage = 0; + } + updateDisplay(state); + } +#else // Basic oled with analog buttons, and a signal replay button has just been pressed. + else{ + boolean onOrOff = buttonsToggleStatus[signalNumber]; + buttonsToggleStatus[signalNumber] = !buttonsToggleStatus[signalNumber]; // Remember that the button has been toggled. + replay( buttonPressed, onOrOff ); + } + prevButtonState = buttonPressed; +#endif + clearTimingsArray(); + } + } // End of checking if the menu button is being pressed. +#endif + } // End of checking the received signal. +} // End of main loop. + + + +// +// VIABILITY CHECK +// +// The signal should have a minimal level of diversity. This function checks how many different types of timings there are, and how often they exist. + +boolean signalViabilityCheck() +{ +#ifdef DEBUG + Serial.println(F("__Viability check")); + printRawSignal(); +#endif + + while( timings[endPosition] == 0 ){ + endPosition--; // If the signal has a lot of zero's at the end, remove them. + if( endPosition < MINIMAL_SIGNAL_LENGTH ){ break; } + } + + boolean diverseEnough = false; // At the beginning of this function we assume the signal is not diverse enough, until proven otherwise. + int uniqueCounter = 0; // How often a certain timing exists in the timings data. + bucketCount = 0; + + for( byte s = 0; s < 255; s++ ){ // Check how often the different timings exist. + uniqueCounter = 0; + byte samenumber = 0; + for( int j = startPosition; j <= endPosition; j++ ){ + if( timings[j] == s ){ + uniqueCounter++; + } + } + + if( s == 0 && uniqueCounter > 1 ){ + return false; + } + + // If there was at least one occurence of this timing, then increase the bucketCount. + if( s != 0 && uniqueCounter > 1 ){ + //Serial.print(F("- bucket: ")); Serial.print(s); Serial.print(F(" has ")); Serial.println(uniqueCounter); + bucketCount++; + } + + // If we find a timing that takes up more than 10% of all timings and less than 90%, then this indicates the signal is varied enough. + if( s > 1 && uniqueCounter > round((endPosition-startPosition) / 10) && uniqueCounter < round((endPosition-startPosition) * .8) && diverseEnough == false ){ + diverseEnough = true; +#ifdef DEBUG + //Serial.print(F("signal is diverse enough (")); Serial.println(s); +#endif + } + } + + + if( diverseEnough && bucketCount >=2 && bucketCount < 20 ){ // If both indicators are positive, then the signal may be usable. +#ifdef DEBUG + printRawSignal(); + Serial.print(F("Buckets @ quality check: ")); Serial.println(bucketCount); +#endif + return true; + } + else{ + return false; // Indicates that the signal was not useable. + } +} + + +// +// SIGNAL CLEANER +// +// This merges timings that are very similar into one. To do this the variable P is used to combine increasingly distant neighbouringing timings together. +// In the first loop, when P is 1, only direct neighbours are merged (for example: 5 and 6). When P is 2 it could, for example, merge 4 and 6 together. And so forth. +// When P is 2, this is also the first round that we look for the repeating part of the timings. Most signals have some special timings in between the repeating bits. Here we look for it, and point to it with the 'betweenSpace' variable. + +boolean signalCleaner() +{ +#ifdef DEBUG + Serial.println(F("__signalCleaner")); +#endif + + for( byte i = 0; i < 8; i++ ){ + metaData[i] = 0; // Set all metadata values to 0. Don't want old data messing things up. + } + repeatingPatternLength = 255; // This is only allowed to become smaller. After all, we want the smallest repeating code. + + // Sorting timings into the most popular buckets. + int previousCounter = 0; + betweenSpace = 250; + byte prevBucketCount = 0; + byte highestFoundTiming = 0; + + byte p = 1; + while( p <= 4 ){ +#ifdef DEBUG + Serial.print(F("P")); Serial.println(p); +#endif + bucketCount = 0; // Reset bucket count. + byte lastOftenFoundTiming = 0; // Reset last found neighbouring timing. + boolean foundBetweenSpaceThisRound = false; + + for( byte i = 0; i < betweenSpace + 5; i++ ){ // The "+5" is a failsafe. The idea is it will scan a bit more of the original signal, just in case we find a betweenSpacing that's even better nearby. In practise it's not that useful.. + int currentCounter = 0; + int lastFoundJ = endPosition; // The position in the array of the last timing of this type that we found. We use this to check if there is enough distance between these timings, as the betweenSpaces we're looking for act like spacers between the repeating signals. + + for ( int j = endPosition; j >= startPosition; j-- ){ // count all occurrences of this timing in the data + if( timings[j] == i ){ + currentCounter++; + + if( p > 1 && bucketCount > 1 && currentCounter < 10 && foundBetweenSpaceThisRound == false ){ // If this timing was found more than 10 times, it's probably not the between space. J has to be bigger than 5 to allow the code to grab the spacer data later. + if ( lastFoundJ < endPosition - 3 && lastFoundJ - j > MINIMAL_SIGNAL_LENGTH && lastFoundJ - j < repeatingPatternLength ){ // endPosition - 3 is done so that we are sure we have enough space at the end of the array left over to copy the anomaly data from later. + // We found it! Determining the betweenSpace is important. It means we're certain we've found the part of the timings array that is the repeating part. + foundBetweenSpaceThisRound == true; // No need to keep looking while processing the higher timings. + betweenSpace = i; + endPosition = lastFoundJ; // We remember where the signal we found starter and ended. From now on we'll only be focussing on this small part of the timings array. + startPosition = j; + repeatingPatternLength = endPosition - startPosition; +#ifdef DEBUG + Serial.print(F("repeatingPatternLength found = ")); Serial.println(repeatingPatternLength); +#endif + } + } + lastFoundJ = j; + } + } + if( currentCounter > 0 ){ // We found at least one occurence of the timing we're currently looking at. +#ifdef DEBUG + //Serial.print(F("Found ")); Serial.print(i); Serial.print(F(" this often: ")); Serial.println(currentCounter); +#endif + bucketCount++; + highestFoundTiming = i; + if( previousCounter != 0 ){ // If we also already found another timing on a previous loop though, then we can compare the two. + if( lastOftenFoundTiming != 0 && lastOftenFoundTiming < i && i - lastOftenFoundTiming <= p && lastOftenFoundTiming != i ){ // If the neighbouring big timing isn't too far away from this one, then we may be able to gobble it up (or let it gobble up the current timing). + if( currentCounter >= previousCounter ){ // The current timing is found more often in the timings array. Whichever is bigger wil 'win', and the other timing will be set to be the same as the most often occuring of the two. +#ifdef DEBUG + //Serial.print(F("Shifting timing ")); Serial.print(lastOftenFoundTiming); Serial.print(F(" (found ")); Serial.print(previousCounter); Serial.print(F(" times) UP to ")); Serial.print(i); Serial.print(F(" (found ")); Serial.print(currentCounter); Serial.println(F(" times).")); +#endif + for( int e = startPosition; e <= endPosition; e++ ){ // Loop over the dataset and change all occurences of the other timing into the current timing. + if( timings[e] == lastOftenFoundTiming ){ + timings[e] = i; + } + } + //currentCounter = previousCounter + currentCounter; // Reflect that this is now a bigger bucket. + } + else{ // Previous counter was bigger +#ifdef DEBUG + //Serial.print(F("Shifting timing ")); Serial.print(i); Serial.print(F(" (found ")); Serial.print(currentCounter); Serial.print(F(" times) DOWN to ")); Serial.print(lastOftenFoundTiming); Serial.print(F(" (found ")); Serial.print(previousCounter); Serial.println(F(" times).")); +#endif + for( int e = startPosition; e <= endPosition; e++ ){ // loop over the timings and lift the previous ones up. + if( timings[e] == i ){ + timings[e] = lastOftenFoundTiming; + } + } + } + bucketCount--; // We just merged two timings together into a single bucket. + } + } + lastOftenFoundTiming = i; // Remember what the last timing was.. + previousCounter = currentCounter; // ..and how often we found it. + } + } // End of loop that goes over all timings to count how often each timing exists. + if( bucketCount != prevBucketCount ){ // If the bucketCount changed, then we may want to comb through the timings array again with the same P setting. + prevBucketCount = bucketCount; + if(betweenSpace != 250 && bucketCount < 5){ // We found the betweenSpace and have a cleaned up signal. So we have all that we need. + p = 5; // Breaks out of the while loop. + } + } + else{ // If the bucketcount is unchanged, the current P setting is no longer having any effect, and we should try increasing it. + //Serial.println(F("Unchanged bucketcount")); + p++; // By increasing P the next iteration will be allowed to merge timings that are further apart from each other. + } + lastOftenFoundTiming = 0; + if( highestFoundTiming < 10 ){ // After one round of cleaning the signal we can exit the process here in case the signal is very fast. Otherwise we may acutally damage the timings data by merging them too much. +#ifdef DEBUG + Serial.println(F("Fast signal")); // This is a very fast signal (probably without a betweenSpace anyway). Some more expensive modern devices use this. Wireless carkeys, for example. +#endif + break; + } + } // End of while loop. +#ifdef DEBUG + printRawSignal(); +#endif + if( betweenSpace == 250 ){ // 250 is the default value. This means the previous function did not find a between-space indicator. Time to bring in the pattern finder. + if( state > MENU_NEW && state < MENU_DELETE_LAST ){ + if( findPattern() ){ // The pattern finder is our last hope. It uses the 'brute force method' to search for a repeating pattern in the signal. It can find repeating patterns when the signal does not have spaces between the repeating parts. + return true; + } + } + return false; // Signal analysis is impossible. + } + else{ + return true; // We found a betweenSpace. + } +} + + +// +// SIGNAL ANALYSIS +// +// Now that the signal is clean we can try to find the byte code it contains. We try to fill the metaData array, which describes the signal, and will be stored to eeprom if necessary. +// +// The medaData array is as follows; +// metaData[0] -> The first timing of the first repeating duo +// metaData[1] -> The second timing of the first repeating duo +// metaData[2] -> The first timing of the second repeating duo +// metaData[3] -> The second timing of the second repeating duo +// metaData[4] -> The first timing of the first anomaly +// metaData[5] -> The second timing of the first anomaly +// metaData[6] -> The first timing of the second anomaly +// metaData[7] -> The second timing of the second anomaly +// +// The code can only store two anomalous bits (which are sent in between the main repeating part of the code) + +boolean signalAnalysis() +{ +#ifdef DEBUG + Serial.println(F("__signalAnalysis")); +#endif + + //byte jump = 1; // Used by the function that tries to determine the timing duo's that the repeating signal consists of. + byte anomalyCount = 0; + byte minimumDuosNeeded = int(repeatingPatternLength / 2) - 2; +#ifdef DEBUG + Serial.print(F("Duos needed: ")); Serial.print(minimumDuosNeeded); + Serial.print(F(" (repeatingPatternLength: ")); Serial.println(repeatingPatternLength); +#endif + byte totalDuosPossible = 0; + for( int i = startPosition; i < startPosition + 5; i++ ){ +#ifdef DEBUG + Serial.print(F("_____i_")); Serial.println(i - startPosition); +#endif + memset(metaData, 0, sizeof(metaData)); // Clear the metadata array. + totalDuosPossible = 0; // Will check how many timing-duo's we can find in the signal if using the current base duos + anomalyCount = 0; + for ( int j = i; j < i + repeatingPatternLength; j = j + 2 ){ + if( timings[j] == metaData[0] && timings[j+1] == metaData[1] ){ + totalDuosPossible++; // The current duo was in the metadata, so increase the possible duos counter. +#ifdef DEBUG + Serial.print( timings[j] ); Serial.print(F(",")); Serial.print( timings[j+1] ); Serial.println(F(" 0")); +#endif + } + else if( timings[j] == metaData[2] && timings[j+1] == metaData[3] ){ + totalDuosPossible++; // The current duo was in the metadata, so increase the possible duos counter. +#ifdef DEBUG + Serial.print( timings[j] ); Serial.print(F(",")); Serial.print( timings[j+1] ); Serial.println(F(" 1")); +#endif + } + else if( metaData[0] == 0 ){ // If it wasn't in the metadata, add it to the metadata, and register that we did in fact find a possible duo. + metaData[0] = timings[j]; + metaData[1] = timings[j+1]; + totalDuosPossible++; +#ifdef DEBUG + Serial.print( timings[j] ); Serial.print(F(",")); Serial.print( timings[j+1] ); Serial.println(F(" 0 <- Duo A")); +#endif + } + else if( metaData[2] == 0 ){ + metaData[2] = timings[j]; + metaData[3] = timings[j+1]; + totalDuosPossible++; +#ifdef DEBUG + Serial.print( timings[j] ); Serial.print(F(",")); Serial.print( timings[j+1] ); Serial.println(F(" 1 <- Duo B")); +#endif + } + else if( metaData[4] == 0 ){ + metaData[4] = timings[j]; + metaData[5] = timings[j+1]; + anomalyCount++; +#ifdef DEBUG + Serial.print( metaData[4] ); Serial.print(F(",")); Serial.print( metaData[5] ); Serial.println(F(" <- Anomaly A")); +#endif + + if( totalDuosPossible < minimumDuosNeeded){ + j = 1000; // Anomaly found too soon, should be at the end of the signal, after all the duos are found. So we can skip checking this. + } + else if( (totalDuosPossible * 2) + (anomalyCount * 2) < repeatingPatternLength ){ + metaData[6] = timings[j+2]; + metaData[7] = timings[j+3]; + anomalyCount++; +#ifdef DEBUG + Serial.print( metaData[6] ); Serial.print(F(",")); Serial.print( metaData[7] ); Serial.println(F(" <- Anomaly B")); +#endif + } + } + else{ + //Serial.println(F("bad round")); + j = 1000; // Too many anomalies (the code can handle 2). Skip to the next round, maybe we will have better luck. + } +#ifdef DEBUG + if( totalDuosPossible % 8 == 0 ){ Serial.println(); } +#endif + + } + if( totalDuosPossible >= minimumDuosNeeded ){ +#ifdef DEBUG + Serial.print(F("Enough duos found (")); Serial.println(totalDuosPossible); + Serial.println(metaData[0]); + Serial.println(metaData[1]); + Serial.println(metaData[2]); + Serial.println(metaData[3]); +#endif + endPosition = endPosition + (i - startPosition); // Shifting the window a little bit, if necessary. + startPosition = startPosition + (i - startPosition); // Shifting the window a little bit, if necessary. + + + Serial.println(); + Serial.println(); + for ( int s = startPosition; s <= endPosition; s++ ){ + + Serial.print(timings[s]); Serial.print(F(",")); + if(s % 8 == 0){ Serial.println(); } + } + Serial.println(); Serial.println(); + + break; + } + else { +#ifdef DEBUG + Serial.println(F("Not enough possible duos")); Serial.println(); +#endif + if( i - startPosition == 4 ){ + return false; // What's this all about? + } + } + } + + // Switch the duo's around in necessary, so that the one the has a difference in timings is the first one. This will save a byte in storage later. + if( metaData[0] == metaData[1] == metaData[2] && metaData[1] < metaData[3]){ + metaData[1] = metaData[3]; + metaData[3] = metaData[0]; + } + + repeatingSignalByteLength = (byte)totalDuosPossible / 8; + + byte leftovers = totalDuosPossible % 8; + +#ifdef DEBUG + Serial.print(F("leftover:")); Serial.println( leftovers ); + Serial.print(F("anomalyCount:")); Serial.println( anomalyCount ); +#endif + + lastByteIsSplit = false; + anomalyInside = false; + if( leftovers > 0 ){ + repeatingSignalByteLength++; // If there is a nibble (half a byte) left over, then increase the required array length by one. + + if( leftovers == 4 ){ + lastByteIsSplit = true; + //Serial.println(F("Last byte is split")); + } + else if( leftovers + anomalyCount == 4 ){ + lastByteIsSplit = true; + anomalyInside = true; + //Serial.println(F("anomaly is inside nibble")); + } + else if( leftovers + anomalyCount == 8 ){ + anomalyInside = true; + //Serial.println(F("anomaly is inside byte")); + } + else { + Serial.println(F("Cannot handle this signal")); + return false; // The system cannot currently deal with this signal, sorry. + } + } + + // Take 8 bits and encode them into a byte. + for( byte i = 0; i < repeatingSignalByteLength; i++ ){ + byte eepromByte = 0; + for( int j = 0; j < 8; j++ ){ + if( timings[startPosition] == metaData[0] && timings[startPosition + 1] == metaData[1] ){ + Serial.print(F("0")); + bitWrite(eepromByte,j,0); + startPosition = startPosition + 2; + } + else if( timings[startPosition] == metaData[2] && timings[startPosition + 1] == metaData[3] ){ + Serial.print(F("1")); + bitWrite(eepromByte,j,1); + startPosition = startPosition + 2; + } + else{ + Serial.print(F("X")); + bitWrite(eepromByte,j,0); + } // End of bit loop + } // End of byte loop + timings[i] = eepromByte; +//#ifdef DEBUG + Serial.print(F(" > HEX: ")); +//#endif + Serial.print(eepromByte, HEX); +//#ifdef DEBUG + Serial.print(F(" DEC: ")); Serial.println(eepromByte); +//#endif + } + Serial.println(); + return true; // return if the signal analysis went ok. +} + + +// +// PATTERN FINDER +// +// Finds repeating patterns in the signal data. This is a backup function. Some signals don't have a betweenSpace. In those cases we use brute force to look for the longest repeating pattern we can find. This function takes longer. + +boolean findPattern() +{ +#ifdef DEBUG + Serial.println(F("___pattern_finder___")); +#endif + byte maxPatternLength = (byte)constrain((endPosition-startPosition)/2, 31, 255); // what length is the pattern we're looking for allowed to be? It's most likely 8 bytes = 64 bits = 128 timings, but we can't be sure in this case. To find a repeating pattern, we need to be able to have it in the data twice, so the maximum length is the timings array length divided by two. + byte searchLength = 32; + while( searchLength + 4 <= maxPatternLength ){ // Check the maximum pattern length we can search for in the current memory. + searchLength = searchLength + 4; + } + //Serial.print(F(" searchLength that we begin pattern matching with: ")); Serial.println(searchLength); + for( searchLength; searchLength > MINIMAL_SIGNAL_LENGTH; searchLength = searchLength - 4 ){ // Find repeating patterns of a minimal length, starting with a long as possible signal, and then working down. + int patternFirstPosition = 0; // Where we found an often occuring pattern for the first time. To keep things simple(low memory) we only search the first 255 positions of the array. + for ( int i = startPosition; i <= endPosition-searchLength; i++ ){ + byte patternCount = 0; + for ( int y = startPosition; y <= endPosition-searchLength; y++ ) { + boolean oksofar = true; // Starts out assuming the pattern is found, and then starts comparing. As soon as one of the timings is not the same, it sets this to false. + for (byte r = 0; r < searchLength; r++) { // We compare the selected patterns + if( timings[i+r] != timings[y+r] ){ + oksofar = false; // If the pattern is not found at this position. + break; // No need continuing the comparison. + } + } + if( oksofar == true ){ + patternCount++; // We scanned over the position in the array, and nothing tripped up the recogniser, meaning it actuallly found the pattern. + y = y + (searchLength-1); // Minus one, because the for-loop will also add one. We skip ahead and see if we can find the same pattern again straigth after. + } + } + if(patternCount > 1){ // We found a repeating pattern! + // Quick quality check. It makes sure the found code isn't just the same number in a row a lot. + int sameNumber = 0; + for( int j = startPosition; j <= endPosition; j++ ){ + if( timings[j] == timings[startPosition] ){ + sameNumber++; + } + } + if(sameNumber > 15){ // This many of the same timings in a row is a bad sign. + return false; + } + Serial.print(F("Pattern: ")); + for (int t = 0; t < searchLength; t++) { + Serial.print(timings[i + t]); Serial.print(F(",")); + } + Serial.println(); + // Update the global variables: + repeatingPatternLength = searchLength; // Store the length of the repeating part. + startPosition = i; // Set the start position of the repeating part of the signal. + endPosition = i + searchLength; // Set the end position of the repeating oart of the signal. + return true; + } + } + } + //Serial.println(F("Pattern finder failed")); + return false; // We reached the end without finding any repeating pattern. +} + + +// +// SCAN EEPROM +// +// This function has multiple uses, depending on the state. +// When signalNumber is given as 0, then it acts as a simple scan of the eeprom, and can compare found signals to those in eeprom. +// If state is listening, then it returns the number of a signal mathed in eeprom. +byte scanEeprom() +{ + //Serial.println(F("SCANNING EEPROM")); + + byte whatWeCameHereFor = 0; + amountOfStoredSignals = 0; // Reset these. Everytime this function runs they are updated. + byte amountOfStoredReplayableSignalsScan = 0; + positionOfLastSignalEnd = EEPROM_STORAGE_START - 1; // MySensors has another value we could grab to get even more space. + boolean finishedScanningEeprom = false; + while( finishedScanningEeprom == false ){ + //Serial.println(positionOfLastSignalEnd); + byte storedSignalLength = EEPROM.read(positionOfLastSignalEnd + 1); // This get the first byte of the next stored signal (if it exists), and indicates how much data it takes on the eeprom. +#ifdef DEBUG + Serial.print(F("#")); Serial.println(amountOfStoredSignals + 1); + Serial.print(F("-storedlength:"));Serial.println(storedSignalLength); +#endif + if( storedSignalLength == 0xff || storedSignalLength == 0x00 ){ // No more signals found in the EEPROM. + finishedScanningEeprom = true; + } + + // For each signal in eeprom: + else { + //if( positionOfLastSignalEnd + storedSignalLength > EEPROM.length() ){ break; } // This should theoretically never happen. But if it did it would lock up the device, so it can't hurt. + // DELETE THE LAST RECORDED SIGNAL? + if( state == DELETE_LAST && EEPROM.read(positionOfLastSignalEnd + 1 + storedSignalLength) == 0xFF ){ // If the next storage slot empty? + Serial.println(F("Deleting last stored signal")); + for( int j = positionOfLastSignalEnd + 1; j < positionOfLastSignalEnd + 1 + storedSignalLength; j++ ){ // Overwrite the last signal with 255's (the default memory state). + EEPROM.update(j, 0xFF); + } + return 1; + } + if( storedSignalLength > 0 ){ + amountOfStoredSignals++; // Update how many signals are stored in eeprom. + } + byte descriptionData = EEPROM.read(positionOfLastSignalEnd + 2); + if( bitRead(descriptionData, DESCRIPTION_REPLAYABLE) == 1 ){ // Is it a replayable signal? + amountOfStoredReplayableSignalsScan++; + if( state == REPLAYING && amountOfStoredReplayableSignalsScan == buttonPressed ){ +#ifdef DEBUG + Serial.println(F("Eeprom scan found the signal to replay")); +#endif + whatWeCameHereFor = storedSignalLength; + startPosition = positionOfLastSignalEnd + 1; // Recycling variables to save memory. + endPosition = positionOfLastSignalEnd + storedSignalLength; + } + +#ifdef HAS_TOUCH_SCREEN + if( state == DISPLAY_REPLAY_BUTTONS ){ + // The signal is replayable. If a touchscreen is attached, we show the button for it on the screen. + byte pageStart = visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen; + byte itemNumber = (amountOfStoredReplayableSignalsScan - 1 ) % howManyReplayButtonsWillFitOnScreen; + + //Serial.print(F("howManyReplayButtonsWillFitOnScreen: ")); Serial.println(howManyReplayButtonsWillFitOnScreen); + //Serial.print(F("amountOfStoredReplayableSignals so far: ")); Serial.println(amountOfStoredReplayableSignalsScan); + //Serial.print(F("page start: "));Serial.println( pageStart ); + //Serial.print(F("replayable. itemNumber: ")); Serial.println( itemNumber ); + + if( amountOfStoredReplayableSignalsScan > pageStart && amountOfStoredReplayableSignalsScan <= pageStart + howManyReplayButtonsWillFitOnScreen ){ + if( bitRead(descriptionData, DESCRIPTION_ON_OFF) == 0 ){ +#ifdef DEBUG_SCREEN + Serial.println(F("BC: 4 commands for next page button:")); +#endif + roundedRectangle( 0, BUTTON_HEIGHT + (itemNumber * BUTTON_HEIGHT), TOUCHSCREEN_WIDTH, BUTTON_HEIGHT, (int)BUTTON_HEIGHT/3, 31727 ); // dark grey rounded rectangle. + setCur( BUTTON_PADDING, BUTTON_PADDING + BUTTON_HEIGHT + (itemNumber * BUTTON_HEIGHT) ); + displayNumber(itemNumber + (visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen) + 1 ); + basicCommand(play); + } + else { +#ifdef DEBUG_SCREEN + Serial.println(F("BC: roundedRect")); +#endif + roundedRectangle( 0, BUTTON_HEIGHT + (itemNumber * BUTTON_HEIGHT), (int)TOUCHSCREEN_WIDTH/2, BUTTON_HEIGHT, (int)BUTTON_HEIGHT/3, 31727 ); // dark grey rounded rectangle. +#ifdef DEBUG_SCREEN + Serial.println(F("BC: setCur")); +#endif + setCur( BUTTON_PADDING, BUTTON_PADDING + BUTTON_HEIGHT + (itemNumber * BUTTON_HEIGHT) ); +#ifdef DEBUG_SCREEN + Serial.println(F("BC: display_number")); +#endif + displayNumber(itemNumber + (visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen) + 1 ); +#ifdef DEBUG_SCREEN + Serial.println(F("BC: off")); +#endif + basicCommand(off); +#ifdef DEBUG_SCREEN + Serial.println(F("BC: roundedRect")); +#endif + roundedRectangle( (int)TOUCHSCREEN_WIDTH/2, BUTTON_HEIGHT + (itemNumber * BUTTON_HEIGHT), (int)TOUCHSCREEN_WIDTH/2, BUTTON_HEIGHT, (int)BUTTON_HEIGHT/3, 31727 ); // dark grey rounded rectangle. +#ifdef DEBUG_SCREEN + Serial.println(F("BC: setcur")); +#endif + setCur( BUTTON_PADDING + (TOUCHSCREEN_WIDTH / 2), BUTTON_PADDING + BUTTON_HEIGHT + (itemNumber * BUTTON_HEIGHT) ); +#ifdef DEBUG_SCREEN + Serial.println(F("BC: display_number")); +#endif + displayNumber(itemNumber + (visibleReplayButtonsPage * howManyReplayButtonsWillFitOnScreen) + 1 ); +#ifdef DEBUG_SCREEN + Serial.println(F("BC: on")); +#endif + basicCommand(on); + } + } + //else { + //Serial.println(F("(skip)")); + //} + } +#endif + + } + else { +#ifdef DEBUG + Serial.println(F("-detectable")); +#endif + } + // LISTENING + positionOfLastSignalEnd = positionOfLastSignalEnd + storedSignalLength; + if( state == LISTENING && whatWeCameHereFor == 0 && bitRead(descriptionData, DESCRIPTION_REPLAYABLE) == 0 ){ // We only check detect-only signals for now. This could be changed to include all signals by removing the last check in this if statement. + // We should scan the stored binary data against the last signal we received. + boolean areTheyTheSame = true; // The code below continously tries to disprove that they are the same, and skips ahead at the first evidence that this is the case. + for( byte i = 0; i < 1 + bitRead(descriptionData, DESCRIPTION_ON_OFF); i++ ){ // Check both the on and off signals. + areTheyTheSame = true; + for( byte j = 0; j < repeatingSignalByteLength; j++ ){ + if( timings[(repeatingSignalByteLength - j) - 1] != EEPROM.read((positionOfLastSignalEnd - (repeatingSignalByteLength*i)) - j ) ){ + areTheyTheSame = false; + break; + } + } + if( areTheyTheSame == true ){ // We've compared the entire signal, and.. they are the same! + Serial.println(F("Match")); + Serial.print(F("SEND: Toggle ")); Serial.print(99 + (amountOfStoredSignals - amountOfStoredReplayableSignalsScan)); Serial.print(F(" to ")); Serial.println(i); + + if( bitRead(descriptionData, DESCRIPTION_ON_OFF) ){ // This is an on-off type detection, so we just toggle it to the correct position. + //Serial.println(F("-simple-on-off-toggle")); + connectedToNetwork = send(detectmsg.setSensor(99 + (amountOfStoredSignals - amountOfStoredReplayableSignalsScan)).set(!i),1); wait(RADIO_DELAY); // This sends the found value to the server. If the signal is an on-off version, it sends the correct value (which needs to be inversed, hence the !i). It also asks for a receipt (the 1 at the end), so that it acts as a network status detection at the same time. + + } + else{ // This is a simple single trigger-type detection. + //Serial.println(F("-simple single trigger, will go back to off by itself.")); + connectedToNetwork = send(detectmsg.setSensor(99 + (amountOfStoredSignals - amountOfStoredReplayableSignalsScan)).set(1),1); wait(RADIO_DELAY); // This sends the found value to the server. If the signal is an on-off version, it sends the correct value (which needs to be inversed, hence the !i). It also asks for a receipt (the 1 at the end), so that it acts as a network status detection at the same time. + wait(2000); + send(detectmsg.setSensor(99 + (amountOfStoredSignals - amountOfStoredReplayableSignalsScan)).set(0),1); wait(RADIO_DELAY); // ... and turn if back off again at the controller. + } + updateDisplay(MATCH); + whatWeCameHereFor = amountOfStoredSignals; // Sending back the index of this signal. + + break; // Just in case that this is a double signal, then we don't want a second loop to overrule this result. + } + } + } // end of detectable + } // end of 'is a signal' // end of checking a stored signal. + } // end of while loop, so the entire EEPROM has now been scanned. + amountOfStoredReplayableSignals = amountOfStoredReplayableSignalsScan; + return whatWeCameHereFor; +} + + +// +// STORE SIGNAL +// + +boolean writeSignalToEeprom() +{ + Serial.println(F("__Storing")); + byte signalDescriber = 0; // This will hold all the setings for this signal. The 'Description byte' is basically a settings switchboard that describes the signal. It helps to keep the required eeprom storage low. +#if KEYPAD_BUTTON_COUNT > 0 + if( (state == COPYING_ON || state == COPYING_SIMPLE) && amountOfStoredReplayableSignals == KEYPAD_BUTTON_COUNT - 1 ){ + updateDisplay(NO_MORE_FREE_BUTTONS); // Warn the user: there are no more physical buttons left. + } +#endif + // TODO?: If this is an on-off situation, maybe get the previous signal from storage and make sure that the meta data is similar? By doing a check we could make sure no rogue signals accidentally interfere with the recording proces. The odds of that happening are pretty slim though.. + byte spaceNeeded = 2; // We calculate how much space we need to store everything, and then check if it will still fit in memory. The minimal metadata length we can possibly start with is 2. One byte for signal length, and another for the signal describer + +/* + * THE COMPLETE DATA TO STORE + * This is what a stored signal in the EEPROM looks like: + * + * byte 0. How many of the eeprom's bytes are used to store the signal. + * byte 1. Signal describer. Stores settings. See below for details. + * + * The next part stores the metaData array. For 'recognise only' signals this is skipped. + * byte 3. Most popular bit-duo part A. Together they are binary 0. (only stored if the signal should be replayed) + * byte 4. Most popular bit-duo part B. Together they are binary 0. (only stored if the signal should be replayed) + * byte 5. Second most popular bit-duo part A. Together they are binary 1. (optional, depending on signal and state) + * byte 6. Second most popular bit-duo part B. Together they are binary 1. (optional, depending on signal and state) + * byte 7. First anomaly duo. (optional, depending on signal and state) + * byte 8. First anomaly duo. (optional, depending on signal and state) + * byte 9. Second anomaly duo. (optional, depending on signal and state) + * byte 10. Second anomaly duo. (optional, depending on signal and state) + * + * byte 11 and onwards: stores the actual repeating part of the signal. Each byte has 8 bits, and these 8 bits can be expanded into the original signal. + * + * If this is an on+off signal, then it will be appended, but only it's repeating signal data. + * + * + * Signal describer byte: + * bit 7. - Since there is a spacer, is it 2 bit (0) or 4 bit (1) spacer? + * bit 6. - Is there a spacer anomaly? Usually there is. No (0) or Yes (1). + * bit 5. - Can one of the duo's be reconstructed from the other one? No (1) or yes (0). If yes, then we can save 2 bytes, and must also store what type of reconstruction can be done (there are two options fo this). + * bit 4. - Simple read-only signal (0), or are we planning to transmit it (1)? If it's read-only, then we only store the signal spacer, signal description (so we can now it's a simple signal), and the repeating signal array. A normal, simple 8 byte signal would thus take 10 bytes of storage on the EEPROM. + * bit 3. - Is this a singular signal (0), or combined on/off signal (1). (The repeating signal payload is then doubled, and should later be split in half.) + * bit 2. - Currently not used. Perhaps in the future this could be used to store if a replayable signal should also operate as a recognise-only signal + * bit 1. - What type of duo reconstruction can be done? This depends on bit 5 being set to 0, indicating a duo reconstruction should be performed. If they are mirrored, then (0) is stored. Is the first duo just twice the first timing of the second duo (e.g. if it is 2&2 + 2&7), then a 1 is stored. + * bit 0. - Set to 1 if the last byte of the repeating pattern is only half used. + */ +#ifdef DEBUG + Serial.print(metaData[0]); Serial.println(F(" most popular bit-duo part A (0)")); + Serial.print(metaData[1]); Serial.println(F(" most popular bit-duo part A (0)")); + Serial.print(metaData[2]); Serial.println(F(" most popular bit-duo part B (1)")); + Serial.print(metaData[3]); Serial.println(F(" most popular bit-duo part B (1)")); + Serial.print(metaData[4]); Serial.println(F(" spacer anomaly 1")); + Serial.print(metaData[5]); Serial.println(F(" spacer anomaly 2")); + Serial.print(metaData[6]); Serial.println(F(" spacer anomaly 3")); + Serial.print(metaData[7]); Serial.println(F(" spacer anomaly 4")); +#endif + if( state != COPYING_OFF && state != LEARNING_OFF ){ // We only create the description bit on the ON part of an ON/OFF signal. The OFF part is just directly appended to the eeprom later. + // IS THE LAST BYTE SPLIT? (Uneven number of tri-bits) + if( lastByteIsSplit ){ + bitWrite(signalDescriber, DESCRIPTION_HALFBYTE , 1); // We use this position to remember if there is an even or uneven amount of 'nibbles' (a nibble is half a byte). + } + // IS THE LAST ANOMALY "inside" the last nibble, or does it follow it? + if( anomalyInside ){ + bitWrite(signalDescriber, DESCRIPTION_ANOMALY_INSIDE , 1); // We use this position to remember if there is an even or uneven amount of 'nibbles' (a nibble is half a byte). + } + // ARE WE STORING AN ON/OFF SIGNAL? + if( state == COPYING_ON || state == LEARNING_ON ){ + bitWrite(signalDescriber, DESCRIPTION_ON_OFF , 1); // We use this position to remember if this is an ON/OFF signal. + spaceNeeded = spaceNeeded + (repeatingSignalByteLength * 2); // If this is an on-off signal, then we will need to store the repeating part twice. + } else { + spaceNeeded = spaceNeeded + repeatingSignalByteLength; + } + // SIMPLE OR REPLAY? If it's simple, then all additional description bits can stay at 0. + if( state == COPYING_ON || state == COPYING_SIMPLE ){ + bitWrite(signalDescriber, DESCRIPTION_REPLAYABLE , 1); // We use this position to remember if this is a recognise-only signal(0), or if it's a signal that can be replayed(1). + if( metaData[2] == metaData[1] && metaData[3] == metaData[0] ){ + //Serial.println(F("A duo can be reconstructed. Duo 2 is the mirror image of duo 1.")); + spaceNeeded = spaceNeeded + 2; + } + else if( metaData[0] == metaData[2] == metaData[3] ){ + //Serial.println(F("A duo can be reconstructed. Duo 2 is just twice the first timing of duo 1")); + bitWrite(signalDescriber, DESCRIPTION_DUO_RECONSTRUCTION_TYPE , 1); + spaceNeeded = spaceNeeded + 2; + } + else{ + // There is no clever way to store the duo's using less storage space. + bitWrite(signalDescriber, DESCRIPTION_UNRECONSTRUCTABLE_DUO , 1); // We use this position to remember if a duo can be reconstructed (0) or not (1). + spaceNeeded = spaceNeeded + 4; + } + // ANOMALY? + if( metaData[4] != 0 && metaData[5] != 0 ){ + bitWrite(signalDescriber, DESCRIPTION_ANOMALY , 1); // We use this position to remember that there is at least one part anomaly. + spaceNeeded = spaceNeeded + 2; + if( metaData[6] != 0 && metaData[7] != 0 ){ + bitWrite(signalDescriber, DESCRIPTION_LARGE_ANOMALY , 1); // We use this position to remember that this is a double size anomaly. + spaceNeeded = spaceNeeded + 2; + } + } + +#ifdef DEBUG + Serial.print(F("Signal description byte (")); Serial.println(signalDescriber); + for (byte i = 0; i < 8; i++) { + Serial.print(i); Serial.print(F(" = ")); Serial.println(bitRead(signalDescriber,i)); + } + Serial.print(F("Storage space needed: ")); Serial.println(spaceNeeded); + Serial.print(F("Storage space left: ")); Serial.println( EEPROM.length() - positionOfLastSignalEnd ); +#endif + } + } // End of check if we're storing a single or double signal. + if( spaceNeeded > 0 && positionOfLastSignalEnd + spaceNeeded < EEPROM.length() ){ // If there is enough space to store the new signal. E2END+1 would also work instead of EEPROM.length(); + Serial.println(F("Enough space left")); + if( state != COPYING_OFF && state != LEARNING_OFF ){ + // Storing a new signal. Moving pointer to the next free space in the EEPROM. + positionOfLastSignalEnd++; + EEPROM.update(positionOfLastSignalEnd, spaceNeeded); // Here we store the length of all the data associated with this recording session. + //Serial.print(positionOfLastSignalEnd); Serial.print(F(" ~~> "));Serial.print(spaceNeeded); Serial.println(F(" (length)")); + positionOfLastSignalEnd++; + EEPROM.update(positionOfLastSignalEnd, signalDescriber); // Here we store the signal describer which holds all the settings needed to recreate this signal. + //Serial.print(positionOfLastSignalEnd); Serial.print(F(" ~~> "));Serial.print(signalDescriber); Serial.println(F(" (describer)")); + /* + Here we store the metaData array. This is how this loop works: + 0 -> bit4 (if replaying) -> metadata 1&2 must be stored + 1 -> bit5 (if a duo can not be cleverly reconstructed from the other) -> metadata 3&4 must be stored + 2 -> bit6 (if there is at least one part anomaly -> metadata 5&6 must be stored + 3 -> bit7 (if second part anomaly exists) -> metadata 7&8 must be stored. + */ + if( bitRead(signalDescriber, DESCRIPTION_REPLAYABLE) == 1 ){ // If we want to be able to replay this signal, then we should store the meta data. + for( byte i = 0; i < 4; i++ ){ // Looping over the signalDescriber and the metaData array at the same time. + if( bitRead(signalDescriber, i+4) == 1 ){ // 4, 5, 6, 7 + positionOfLastSignalEnd++; + EEPROM.update(positionOfLastSignalEnd, metaData[i*2]); + //Serial.print(positionOfLastSignalEnd); Serial.print(F(" ~> ")); Serial.print(metaData[i*2]); Serial.println(F(" (meta)")); + positionOfLastSignalEnd++; + EEPROM.update(positionOfLastSignalEnd, metaData[i*2 + 1]); + //Serial.print(positionOfLastSignalEnd); Serial.print(F(" ~> ")); Serial.print(metaData[i*2 + 1]); Serial.println(F(" (meta)")); + } + } + } + } // End of check if this is part two of an on/off signal. + // Add the repeating part of the signal to the storage. + for( byte i = 0; i < repeatingSignalByteLength; i++ ){ + positionOfLastSignalEnd++; + Serial.print(positionOfLastSignalEnd); Serial.print(F(" ~~> "));Serial.println(timings[i]); + EEPROM.update(positionOfLastSignalEnd, timings[i]); + } + if( state != COPYING_OFF && state != LEARNING_OFF ){ + amountOfStoredSignals++; // On/off signals only count as one because they would be attached to one button. + } + } + else{ + return false; // Unable to store the signal. It wasn't long enough or there was not enough space for it. + } + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Signal stored OK") )); + return true; // Succesfully stored the signal +} + + + +// +// REPLAY +// + +void replay(byte signalNumber, boolean onOrOff) +{ + Serial.print(F("__replaying_")); Serial.println(signalNumber); + state = REPLAYING; + //boolean onOrOff = 0; + buttonPressed = signalNumber; + repeatingPatternLength = 0; + if( signalNumber == 0 ){ return; } // We cannot play signal 0. Just a (superfluous) safeguard. + byte storedSignalLength = scanEeprom(); + //Serial.print(F("storedSignalLength received from scanEeprom function: ")); Serial.println(storedSignalLength); + if( storedSignalLength && amountOfStoredReplayableSignals > 0 ){ + + saveState(signalNumber, onOrOff); // We save the new current toggle state in the eeprom too. + send(buttonmsg.setSensor(signalNumber + 9).set(onOrOff)); wait(RADIO_DELAY); // Tell the controller in what state the child is. + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Playing..") )); + updateDisplay(REPLAYING); + for( byte i = 0; i < 8; i++ ){ + metaData[i] = 0; // Reset all metadata values. + } + byte eepromReadPosition = 4; // Where in the eeprom signal we are reading back the data. + byte restoredSignalLength = 0; // Pointer to where in the timings array the signal has been reconstructed. + byte signalDescription = EEPROM.read(startPosition+1); + lastByteIsSplit = bitRead(signalDescription, DESCRIPTION_HALFBYTE); + anomalyInside = bitRead(signalDescription, DESCRIPTION_ANOMALY_INSIDE); + +#ifdef DEBUG + Serial.print(F("Data from EEPROM (length: ")); Serial.println(storedSignalLength); + for( int i = startPosition; i <= endPosition; i++ ){ + Serial.println( EEPROM.read(i) ); + } +#endif + +#if defined HAS_BASIC_OLED_SCREEN && KEYPAD_BUTTON_COUNT > 0 && defined DEBUG + // Show on the screen if the ON or OFF signal is being played. + if( bitRead(signalDescription, DESCRIPTION_ON_OFF) ){ + oled.set1X(); + oled.setCursor(0,6); + oled.print(F("part ")); + oled.print(buttonsToggleStatus[signalNumber] + 1); + } +#endif + + repeatingPatternLength = storedSignalLength - 4;// This indicates how many of the bytes in the eeprom describe the actual repeating signal. + metaData[0] = EEPROM.read( startPosition + 2 ); // This duo is always reconstructed from the eeprom data. + metaData[1] = EEPROM.read( startPosition + 3 ); + if( bitRead(signalDescription,DESCRIPTION_UNRECONSTRUCTABLE_DUO) == 0 ){ // The second duo must be reconstructed because an eeprom space saving measure was used. + if( bitRead(signalDescription,DESCRIPTION_UNRECONSTRUCTABLE_DUO) == 0 ){ // The second duo is a mirror image of the first duo. To reconstruct the second duo we just take the first duo and flip it. + metaData[2] = metaData[1]; + metaData[3] = metaData[0]; + } + else{ // The second duo is just twice the first timing of the first duo. + metaData[2] = metaData[0]; + metaData[3] = metaData[0]; + } + } + else { + metaData[2] = EEPROM.read( startPosition + eepromReadPosition ); // If the second duo cannot be reconstructed from the first, then the first timing of the second duo can always be found at position 4 in the eeprom. + eepromReadPosition++; + metaData[3] = EEPROM.read( startPosition + eepromReadPosition ); // If the second duo cannot be reconstructed from the first, then the second timing of the second duo can always be found at position 5 in the eeprom. + eepromReadPosition++; + repeatingPatternLength = repeatingPatternLength - 2; // Since two of the bytes in eeprom were there to reconstruct the meta data, the actual repeating part must be a little shorter. + } + +#ifdef DEBUG + Serial.println(F("Reconstructed duo metaData:")); + for( byte w = 0; w < 4; w++ ){ + Serial.println(metaData[w]); + } +#endif + + // The anomaly can be placed directly into the timings array. + if( bitRead(signalDescription,DESCRIPTION_ANOMALY) == 1 ){ // Reconstruct part 1 of anomaly. + repeatingPatternLength = repeatingPatternLength - 2; // How many bytes in the eeprom actually describe the repeating signal is now reduced, since some of those bytes described the anomaly. + timings[restoredSignalLength] = EEPROM.read( startPosition + eepromReadPosition ); // Eeprom position here is 4 or 6, depending on whether the second repeating duo was a reconstructable or not. + restoredSignalLength++; + eepromReadPosition++; + timings[restoredSignalLength] = EEPROM.read( startPosition + eepromReadPosition ); // Eeprom position here is 5 or 7, depending on whether the second repeating duo was a reconstructable or not. + restoredSignalLength++; + eepromReadPosition++; +#ifdef DEBUG + Serial.println(F("Reconstructed betweenSpace anomaly: ")); + Serial.print(F("0 => ")); Serial.println(timings[0]); + Serial.print(F("1 => ")); Serial.println(timings[1]); +#endif + } + if( bitRead(signalDescription,DESCRIPTION_LARGE_ANOMALY) == 1 ){ // Reconstruct part 2 of anomaly. + repeatingPatternLength = repeatingPatternLength - 2; // Since two of the bytes in eeprom were there to reconstruct the meta data, the actual repeating part must be a little shorter. + timings[restoredSignalLength] = EEPROM.read( startPosition + eepromReadPosition ); + eepromReadPosition++; + restoredSignalLength++; + timings[restoredSignalLength] = EEPROM.read( startPosition + eepromReadPosition ); + eepromReadPosition++; + restoredSignalLength++; +#ifdef DEBUG + Serial.print(F("2 => ")); Serial.println(timings[2]); + Serial.print(F("3 => ")); Serial.println(timings[3]); +#endif + } +#ifdef DEBUG + Serial.println(); + Serial.print(F(">> restoredSignalLength ")); Serial.println(restoredSignalLength); Serial.println(); +#endif + + if( bitRead(signalDescription, DESCRIPTION_ON_OFF) ){ // If it's an on+off signal then the repeating part should be cut in half to get the actual length, since they are stored back to back in the eeprom. + repeatingPatternLength = repeatingPatternLength / 2; + } + // Looping over the EEPROM, with some special construction that switches which signal should be reconstructed based on the toggle state of the button. + for( int i = (endPosition - repeatingPatternLength * (1+onOrOff)) + 1; i <= endPosition - (repeatingPatternLength * onOrOff); i++ ){ + // Here we can reconstruct the original signal. +#ifdef DEBUG + Serial.print(F(" byte ")); Serial.print(i); Serial.print(F(" = ")); Serial.println( EEPROM.read(i) ); +#endif + for( byte j = 0; j < 8; j++ ){ +#ifdef DEBUG + Serial.print(restoredSignalLength); Serial.print(F(" => ")); Serial.println( metaData[ bitRead(EEPROM.read(i),j) * 2 ] ); +#endif + timings[restoredSignalLength] = metaData[ bitRead(EEPROM.read(i),j) * 2 ]; + restoredSignalLength++; +#ifdef DEBUG + Serial.print(restoredSignalLength); Serial.print(F(" => ")); Serial.println( metaData[ bitRead(EEPROM.read(i),j) * 2 + 1] ); +#endif + timings[restoredSignalLength] = metaData[ bitRead(EEPROM.read(i),j) * 2 +1]; + restoredSignalLength++; + } + //Serial.println(); + } + // If the last byte is only half used, then we should not transmit the last half byte. + if( lastByteIsSplit ){ +#ifdef DEBUG + Serial.println(F("Last byte is split")); +#endif + restoredSignalLength = restoredSignalLength - 8; // Since the last 4 bits of the byte didn't actually contain valid data, we 'cut it off' from the part that we will transmit. + } + + // If the anomaly is 'inside' the byte or nibble, then the anomaly length must be subtracted from the total restored length. + if( anomalyInside ){ + Serial.println(F("Anomaly inside")); + if( bitRead(signalDescription,DESCRIPTION_ANOMALY) == 1 ){ + restoredSignalLength = restoredSignalLength - 2; + } + if( bitRead(signalDescription,DESCRIPTION_LARGE_ANOMALY) == 1 ){ + restoredSignalLength = restoredSignalLength - 2; + } + } +#ifdef DEBUG + Serial.print(F(">> restoredSignalLength ")); Serial.println(restoredSignalLength); Serial.println(); + for( int j = 0; j < restoredSignalLength; j++ ){ + Serial.print( timings[j] ); Serial.print(F(",")); + if( j % 4 == 3 ){ Serial.println(); } + if( j % 32 == 31 ){ Serial.println(); } + } +#endif + + // Finally, play the new timing a few times. + Serial.println(F("REPLAYING")); + for( byte i = 0; i < 8; i++ ){ // Sending the pattern a few times. + boolean high = false; + for( int j = 0; j < restoredSignalLength; j++ ){ + if( high ){ + digitalWrite(TRANSMITTER, LOW); + high = false; + } + else{ + digitalWrite(TRANSMITTER, HIGH); + high = true; + } + interval = timings[j] * GRANULARITY; + delayMicroseconds(interval); + } + } + + digitalWrite(TRANSMITTER, LOW); // Just to be safe + wait(300); + +#ifdef DEBUG + wait(300); + Serial.println(F("NOW REPLAYING REVERSED")); +#endif + +#ifdef DEBUG + for( byte i = 0; i < 8; i++ ){ // Sending the pattern a few times. + boolean high = false; + for( int j = 0; j < restoredSignalLength; j++ ){ + if( high ){ + digitalWrite(TRANSMITTER, HIGH); + high = false; + } + else{ + digitalWrite(TRANSMITTER, LOW); + high = true; + } + interval = timings[j] * GRANULARITY; + delayMicroseconds(interval); + } + } + + digitalWrite(TRANSMITTER, LOW); // Just to be safe +#endif + +#ifdef DEBUG + wait(100); + Serial.println(F("DONE REPLAYING")); +#endif + } // End of check if at least one replayable signal is stored in the EEPROM. +#if KEYPAD_BUTTON_COUNT > 0 + else{ + //Serial.println(F("No signal to replay stored yet!")); + updateDisplay(NO_SIGNAL_STORED_YET); // Only useful to show this if there are physical buttons that don't have a replayable signal attached to them yet. + } +#endif + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("OK") )); + state = LISTENING; + //if( playlist_position > 0){ + // playlist_position--; + //} +} // End of replay function + + +// +// UPDATE DISPLAY +// + +void updateDisplay(byte currentStatus) // Show info on the display +{ +#ifdef HAS_TOUCH_SCREEN +#ifdef DEBUG + Serial.println(); Serial.print(F("UPDATE DISPLAY (state: ")); Serial.println(state); +#endif + clearReceivedBuffer(); + turnOnScreen(); // If the screen is turned off, it will be turned on again. + + if( currentStatus == LISTENING ){ + showTouchButtons(); + } + else { + if( currentStatus == MATCH || currentStatus == REPLAYING ){ + wait(50); + roundedRectangle( 0, ((howManyReplayButtonsWillFitOnScreen + 1) * BUTTON_HEIGHT), TOUCHSCREEN_WIDTH, TOUCHSCREEN_HEIGHT - ((howManyReplayButtonsWillFitOnScreen + 1) * BUTTON_HEIGHT), 0, 64640 ); // Orange rectangle. + wait(50); + setCur(BUTTON_PADDING,BUTTON_PADDING+((howManyReplayButtonsWillFitOnScreen + 1) * BUTTON_HEIGHT) ); + wait(50); + if( currentStatus == MATCH ){ + writeText(START_OF_MENU_DELETE_ALL + MATCH); + wait(2000); + } + else if( currentStatus == REPLAYING ){ + writeText(START_OF_MENU_DELETE_ALL + REPLAYING); + displayNumber( buttonPressed ); + wait(2000); + } + roundedRectangle( 0, ((howManyReplayButtonsWillFitOnScreen + 1) * BUTTON_HEIGHT), TOUCHSCREEN_WIDTH, TOUCHSCREEN_HEIGHT - ((howManyReplayButtonsWillFitOnScreen + 1) * BUTTON_HEIGHT), 0, 0 ); // Black rectangle + //Serial.print(F("amountOfStoredReplayableSignals:")); Serial.println(amountOfStoredReplayableSignals); + //Serial.print(F("howManyReplayButtonsWillFitOnScreen:")); Serial.println(howManyReplayButtonsWillFitOnScreen); + if( amountOfStoredReplayableSignals > howManyReplayButtonsWillFitOnScreen ){ + setCur(BUTTON_PADDING,BUTTON_PADDING+((howManyReplayButtonsWillFitOnScreen + 1) * BUTTON_HEIGHT)); + basicCommand(more); + } + return; + } + + // If we are copying a signal, show the cancel button. + if( state > MENU_NEW && state < MENU_DELETE_ALL + 5 ){ +#ifdef DEBUG_SCREEN + Serial.println(F("BC: fill_black")); +#endif + basicCommand(fill_black); + roundedRectangle( 0, 0, (int)TOUCHSCREEN_WIDTH / 2, BUTTON_HEIGHT, 10, 31 ); // Draw a blue (31) rounded rectangle, with a 10px radius. + setCur(BUTTON_PADDING,BUTTON_PADDING); + writeText(0); // 0 is 'cancel'. + } + + setCur(BUTTON_PADDING,BUTTON_PADDING+BUTTON_HEIGHT); + + // Copying + if( currentStatus == COPYING_SIMPLE || currentStatus == LEARNING_SIMPLE ){ + writeText(START_OF_MENU_DELETE_ALL + PLAY_SIMPLE_SIGNAL); + } + else if( currentStatus == COPYING_ON || currentStatus == LEARNING_ON ){ + writeText(START_OF_MENU_DELETE_ALL + PLAY_ON_SIGNAL); + } + else if( currentStatus == COPYING_OFF || currentStatus == LEARNING_OFF){ + writeText(START_OF_MENU_DELETE_ALL + PLAY_OFF_SIGNAL); + } + + else if( currentStatus == SIGNAL_STORED ){ + writeText(START_OF_MENU_DELETE_ALL + SIGNAL_STORED); + wait(3000); + } + + // Errors + else if( currentStatus == BAD_SIGNAL ){ + writeText(START_OF_MENU_DELETE_ALL + BAD_SIGNAL); + } + else if( currentStatus == OUT_OF_SPACE ){ + writeText(START_OF_MENU_DELETE_ALL + OUT_OF_SPACE); + wait(3000); + } + + // Other + else if( currentStatus == DELETE_LAST ){ + writeText(START_OF_MENU_DELETE_ALL + DELETED_LAST); + wait(3000); + } + else if( currentStatus == DELETED_ALL ){ + writeText(START_OF_MENU_DELETE_ALL + DELETED_ALL); + wait(3000); + } + } + +#endif + +#ifdef HAS_BASIC_OLED_SCREEN + oled.clear(); // Clear the display + displayNetworkStatus(); // Update the network connection icon. + oled.set2X(); // Switch font size + oled.setCursor(0,2); + + // Often used + if( currentStatus == LISTENING ){ + oled.print(F("LISTENING..")); // Call this "Scanning" instead? + oled.set1X(); + oled.setCursor(0,5); + oled.print(F("Detect signals: ")); oled.print(amountOfStoredSignals - amountOfStoredReplayableSignals); + oled.setCursor(0,6); + oled.print(F("Replay signals: ")); oled.print(amountOfStoredReplayableSignals); + + } + else if( currentStatus == PROCESSING ){ + oled.print(F("Processing")); + } + else if( currentStatus == MATCH ){ + oled.print(F("Found")); + oled.setCursor(0,5); + oled.print(F("match!")); + wait(1500); + } + else if( currentStatus == REPLAYING ){ + oled.print(F("Playing ")); oled.print(buttonPressed); + } + + // Copying + else if( currentStatus == COPYING_ON || currentStatus == LEARNING_ON ){ + oled.print(F("Play ON")); + oled.set1X(); + oled.setCursor(0,6); + oled.print(F(">cancel")); + } + else if( currentStatus == COPYING_OFF || currentStatus == LEARNING_OFF){ + oled.print(F("Play OFF")); + oled.set1X(); + oled.setCursor(0,6); + oled.print(F(">cancel")); + } + else if( currentStatus == COPYING_SIMPLE || currentStatus == LEARNING_SIMPLE ){ + oled.print(F("READY!")); + oled.set1X(); + oled.setCursor(0,4); + oled.print(F("Start your signal")); + oled.set1X(); + oled.setCursor(0,6); + oled.print(F(">cancel")); + } + else if( currentStatus == SIGNAL_STORED ){ + oled.print(F("SIGNAL")); + oled.setCursor(0,4); + oled.print(F("STORED")); + if( state == COPYING_OFF || state == LEARNING_OFF ){ + oled.set1X(); + oled.setCursor(0,7); + oled.print(F("Stored signals: ")); oled.print(amountOfStoredSignals); + } + wait(2000); + } + + // Errors + else if( currentStatus == BAD_SIGNAL ){ + oled.print(F("BAD SIGNAL")); + oled.set1X(); + oled.setCursor(0,5); + oled.print(F("TRY AGAIN")); + } + else if( currentStatus == OUT_OF_SPACE ){ + oled.print(F("Out of space!")); + wait(3000); + } + else if( currentStatus == NO_SIGNAL_STORED_YET ){ + oled.print(F("Empty")); + wait(2000); + } + else if( currentStatus == NO_MORE_FREE_BUTTONS ){ + oled.print(F("No buttons left")); + oled.set1X(); + oled.setCursor(0,0); + oled.print(F("NOTICE")); + oled.setCursor(0,5); + oled.print(F("You can only replay")); + oled.setCursor(0,6); + oled.print(F("it via the app.")); + wait(3000); + } + + // Other + else if( currentStatus == DELETE_LAST ){ + oled.print(F("DELETED")); + oled.setCursor(0,5); + oled.print(F("ONE SIGNAL")); + wait(3000); + } + else if( currentStatus == DELETED_ALL ){ + oled.print(F("MEMORY")); + oled.setCursor(0,5); + oled.print(F("CLEAR")); + wait(3000); + } +#ifdef DEBUG + else{ + oled.print(F("??? ")); oled.print(currentStatus); + } +#endif +#endif +} // End of update display function + + + +// +// MENUS +// + + +byte showMenu() // Lets the user select which state to enter. +{ + Serial.println(F("__MENU")); + //if( state == LISTENING ){ + state = MENU_MAIN; + //} + boolean stayInMenu = true; // We stay in the menu while this is true + +#ifdef HAS_TOUCH_SCREEN + byte menuOffset = 0; + byte menuItems = 4; + wait(100); + clearReceivedBuffer(); + touchY = TOUCHSCREEN_HEIGHT; + touched = true; +#ifdef DEBUG_SCREEN + Serial.print(F("touch_screen_serial.available:")); Serial.println( touch_screen_serial.available() ); +#endif + + while( stayInMenu ){ + menuOffset = 0; + wait(50); + readResponse(); // check for new touchscreen input. + if( touched == true ){ + touched = false; + buttonPressed = touchScreenButtonPress(); +#ifdef DEBUG_SCREEN + Serial.print(F("touched (")); Serial.println(buttonPressed); +#endif + if( buttonPressed == 0 ){ // No matter where in the menu we are, when the cancel button is pressed the menu is closed. +#ifdef DEBUG_SCREEN + Serial.println(F("Cancel button")); +#endif + state = LISTENING; + stayInMenu = false; // Exit menu + break; + } + else { +#ifdef DEBUG_SCREEN + Serial.println(F("BC: fill_blue")); +#endif + basicCommand(fill_blue); // Set the background color to blue + setCur(BUTTON_PADDING,BUTTON_PADDING); // Set the text cursor at the top left of the screen + writeText(0); // Display the Cancel item. All menu's have it. + simpleHorizontal(BUTTON_HEIGHT); + + if( state == MENU_MAIN ){ + menuOffset = 1; + if( amountOfStoredSignals > 0 ){ + menuItems = START_OF_MENU_NEW - 1; // 3 items + } + else { + menuItems = START_OF_MENU_NEW - 3; // 1 item. No need to show the delete buttons if there are no stored signals. + } + + if( buttonPressed == 1 ){ + Serial.println(F("entering menu_new")); + state = MENU_NEW; + menuOffset = START_OF_MENU_NEW; + menuItems = START_OF_MENU_DELETE_LAST - START_OF_MENU_NEW; // 4 items + } + if( buttonPressed == 2 ){ + Serial.println(F("entering delete last menu")); + state = MENU_DELETE_LAST; + menuOffset = START_OF_MENU_DELETE_LAST; + menuItems = START_OF_MENU_DELETE_ALL - START_OF_MENU_DELETE_LAST; // 1 item + } + if( buttonPressed == 3 ){ + Serial.println(F("entering delete ALL menu")); + state = MENU_DELETE_ALL; + menuOffset = START_OF_MENU_DELETE_ALL; + menuItems = START_OF_MENU_STATUS_MESSAGES - START_OF_MENU_DELETE_ALL; // 1 item + } + + for( byte i = 0; i < menuItems; i++ ){ + Serial.print(F(">")); Serial.println(i); + setCur(BUTTON_PADDING,BUTTON_PADDING + BUTTON_HEIGHT + (i * BUTTON_HEIGHT) ); + writeText(i + menuOffset); // The offset helps to select the right number which corresponds to a menu item's string in the messages array. + simpleHorizontal(BUTTON_HEIGHT + BUTTON_HEIGHT + (i * BUTTON_HEIGHT)); + } + } + else { // When the user presses a button while in a sub menu. + state = state + buttonPressed; + stayInMenu = false; + break; + } + } + clearReceivedBuffer(); + } + } + +#elif defined (HAS_BASIC_OLED_SCREEN) + byte menuItems = 4; // How many items are shown? Don't forget 'cancel' is always shown. + byte menuPosition = 2; // Current position of the cursor. + wait(100); + + while( stayInMenu ){ +#if KEYPAD_BUTTON_COUNT == 4 + buttonPressed = keypad4(); +#else if KEYPAD_BUTTON_COUNT == 12 + buttonPressed = keypad12(); +#endif + wait(100); + if(buttonPressed != prevButtonState){ + Serial.print(F("[] button pressed: ")); Serial.println(buttonPressed); + if( buttonPressed == KEYPAD_BUTTON_COUNT - 1 ){ // User has pressed the change button. + menuPosition++; + if( menuPosition > menuItems + 1 ){ menuPosition = 2; } // If necessary, loop around back to the top item in the menu. + Serial.print(F("changed to ")); Serial.println(menuPosition); + } + else if( buttonPressed == KEYPAD_BUTTON_COUNT ){ // User has pressed the menu/ok button. + Serial.print(F("select!")); Serial.println(menuPosition); + if( menuPosition == 2 ){ // User pressed cancel. This could move the user back to the main menu, but for simplicity, this currently just exits the menu. + state = 255; + stayInMenu = false; // We can now exit the menu. + } + else if( state == MENU_MAIN ){ // Going into sub-menu. + state = menuPosition * 10; // So the first submenu state is 30, the second submenu is 40, etc. + menuPosition = 2; // Reset the cursor position to the top position. + } + else{ // User is in submenu, so they are making their final selection for a new state. + state = state + menuPosition; // If the submenu state was 30, the final states are 32, 33, etc. + stayInMenu = false; // We can now exit the menu. + } + } + else if( buttonPressed == 0 && prevButtonState == KEYPAD_BUTTON_COUNT ){ + // Here we display the actual menu items. + oled.clear(); + displayNetworkStatus(); + oled.set2X(); + oled.setCursor(0,0); + oled.print(F("MENU")); + oled.set1X(); + oled.setCursor(8,2); + oled.print(F("CANCEL")); + oled.setCursor(8,3); + if( state == MENU_MAIN ){ + oled.print(F("NEW")); + oled.setCursor(8,4); + oled.print(F("DELETE LAST")); + oled.setCursor(8,5); + oled.print(F("DELETE ALL")); + } + else if( state == MENU_NEW ){ + menuItems = 5; // Cancel + the items below. + oled.print(F("Detect single")); + oled.setCursor(8,4); + oled.print(F("Detect On+Off")); + oled.setCursor(8,5); + oled.print(F("Replay single")); + oled.setCursor(8,6); + oled.print(F("Replay On+Off")); + } + else if( state == MENU_DELETE_LAST || state == MENU_DELETE_ALL){ + menuItems = 2; // Cancel + the item below. + oled.print(F("I am sure")); + oled.setCursor(8,4); + } + } + // Add the pointer. + for( byte w = 2; w < 7; w++ ){ // Update the position of the selection cursor on the screen. + oled.setCursor(0,w); + if( menuPosition == w ){ + oled.print(F(">")); + } + else{ + oled.print(F(" ")); + } + } + wait(1); + prevButtonState = buttonPressed; + } + } +#endif +} + + + +// +// RECEIVING DATA FROM THE NETWORK +// + + + +void printRawSignal() // Prints the entire timings array to the serial output. Useful for debugging. +{ + Serial.print(F("__printing_signal_")); Serial.println(edges+1); + for( int j = startPosition; j <= endPosition; j++ ){ + Serial.print(F(",")); Serial.print(timings[j]); + if( j % 16 == 15 ){ Serial.println(); } + } + Serial.println(); +} + + +void clearTimingsArray() +{ +#ifdef DEBUG + Serial.print(F("__Clearing_timings\n-state:")); Serial.println(state); +#endif + memset(timings,0,sizeof(timings)); // Write zeros to timings array. + startPosition = 0; + endPosition = MAXEDGES - 1; + repeatingPatternLength = 255; + edges = 0 - EDGES_TO_SKIP; + signalstart = 0; + bucketsTotal = 0; + captureFinished = false; + validSignal = true; + bucketCount = 0; + signalstart = micros(); +} + + +void displayNetworkStatus() // Show connection icon on the display +{ +#ifdef HAS_TOUCH_SCREEN + if( connectedToNetwork ){ + setCur(TOUCHSCREEN_WIDTH - 30, BUTTON_PADDING ); +#ifdef DEBUG_SCREEN + Serial.println(F("BC: show W icon")); +#endif + basicCommand(w); + } +#endif + +#ifdef HAS_BASIC_OLED_SCREEN + oled.set1X(); + oled.setCursor(122,0); + if( connectedToNetwork ){ + oled.print(F("w")); + } + else{ + oled.print(F(" ")); + } +#endif +} + + +#ifdef DEBUG +int freeRam() { + extern int __heap_start, *__brkval; + int v; + return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); +} +// via https://playground.arduino.cc/Code/AvailableMemory +#endif + +#ifdef HAS_BASIC_OLED_SCREEN && KEYPAD_BUTTON_COUNT != 0 +byte keypad4() +{ + signed int buttonNumber = (analogRead(KEYPAD_PIN) - 200) * (4 - 0 + 1) / (1024 - 200 + 1) + 0; + buttonNumber = constrain(buttonNumber, 0, 4); + return (byte)buttonNumber; +} + +byte keypad12() +{ + int analogValue = analogRead(KEYPAD_PIN); + + if (analogValue < 450) { + return 0; + } else if (analogValue < 500) { + return 1; + } else if (analogValue < 525) { + return 2; + } else if (analogValue < 555) { + return 3; + } else if (analogValue < 585) { + return 4; + } else if (analogValue < 620) { + return 5; + } else if (analogValue < 660) { + return 6; + } else if (analogValue < 705) { + return 7; + } else if (analogValue < 760) { + return 8; + } else if (analogValue < 820) { + return 9; + } else if (analogValue < 890) { + return 10; + } else if (analogValue < 976) { + return 11; + } else { + return 12; + } +} +#endif + + + + + + +// +// BELOW HERE ARE THE TOUCHSCREEN FUNCTIONS +// + +#ifdef HAS_TOUCH_SCREEN + +byte touchScreenButtonPress() +{ + clearReceivedBuffer(); + return ceil(touchY / BUTTON_HEIGHT); +} + +// Show the default interface, with numbered buttons that play signals when pressed. +void showTouchButtons() +{ +#ifdef DEBUG_SCREEN + Serial.println(F("__showTouchButtons ")); + + Serial.println(F("BC: fill_black")); +#endif + basicCommand(fill_black); +#ifdef DEBUG_SCREEN + Serial.println(F("BC: roundedRect")); +#endif + roundedRectangle( 0, 0, (int)TOUCHSCREEN_WIDTH / 2, BUTTON_HEIGHT, (int)BUTTON_HEIGHT / 2, 31 ); // blue rounded rectangle. +#ifdef DEBUG_SCREEN + Serial.println(F("BC: set_cur")); +#endif + setCur(BUTTON_PADDING,BUTTON_PADDING); +#ifdef DEBUG_SCREEN + Serial.println(F("BC: menu")); +#endif + basicCommand(menu); + + state = DISPLAY_REPLAY_BUTTONS; // This state is used to focus the scanEeprom function on displaying the replay buttons. + scanEeprom(); + state = LISTENING; + + // Show 'MORE' button? + if( amountOfStoredReplayableSignals > howManyReplayButtonsWillFitOnScreen ){ + setCur( BUTTON_PADDING, BUTTON_PADDING + BUTTON_HEIGHT + howManyReplayButtonsWillFitOnScreen * BUTTON_HEIGHT ); + basicCommand(more); + } + displayNetworkStatus(); +} + + + +void simpleHorizontal(int y) // Draw a horizontal line on the screen. +{ + +#ifdef DEBUG_SCREEN + Serial.println(F("SIMPLEHORIZONTAL:")); + Serial.print(F("y: ")); Serial.println(y); +#endif + byte command[12] = {0x7E, 0x0A, 0x23, 0,0, highByte(y), lowByte(y), 0,240, 255, 255, 0xEF,}; + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + +void roundedRectangle(int x, int y, int w, int h, int r, int c) // Draw a pixel on the screen. +{ + +#ifdef DEBUG_SCREEN + Serial.println(F("ROUNDEDRECTANGLE")); + //Serial.print(F("x:")); Serial.println(x); // top-right x-position + //Serial.print(F("y:")); Serial.println(y); // top-left y-position + //Serial.print(F("w:")); Serial.println(w); // width + //Serial.print(F("h:")); Serial.println(h); // height + //Serial.print(F("r:")); Serial.println(r); // radius + //Serial.print(F("c:")); Serial.println(c); // color +#endif + byte command[16] = {0x7E, 0x0E, 0x2C, highByte(x), lowByte(x), highByte(y), lowByte(y), highByte(w), lowByte(w), highByte(h), lowByte(h) - 2, highByte(r), lowByte(r), highByte(c), lowByte(c), 0xEF,}; + + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + + +// This function writes text to the screen. You can use the setCur function to place the cursor in the desired position first. +void writeText(byte textID) +{ +#ifdef DEBUG_SCREEN + Serial.println(F("WRITETEXT")); +#endif + byte string_length = strlen_P(MessageTable[textID].Description); + + touch_screen_serial.write( 0x7E ); + touch_screen_serial.write( string_length + 2); + touch_screen_serial.write( 0x11 ); + for( byte i=0; i < string_length; i++ ){ + char char_byte = pgm_read_byte(MessageTable[textID].Description + i); + //Serial.print("-"); Serial.print(char_byte); + touch_screen_serial.write( char_byte ); + } + touch_screen_serial.write( 0xEF ); + + waitForResponse(); +} + +#ifdef DEBUG_SCREEN +void drawPix(int x, int y, int c) // Draw a pixel on the screen. +{ + Serial.println(F("DRAWPIX:")); + Serial.print(F("x: ")); Serial.println(x); + Serial.print(F("y: ")); Serial.println(y); + Serial.print(F("c: ")); Serial.println(c); + byte command[10] = {0x7E, 0x08, 0x21, highByte(x), lowByte(x), highByte(y), lowByte(y), highByte(c), lowByte(c), 0xEF,}; + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} +#endif + + +// This function places the text cursor anywhere on the screen. +void setCur(int x, int y) +{ +#ifdef DEBUG_SCREEN + Serial.println(F("SETCUR")); + Serial.print(F("x: ")); Serial.println(x); + Serial.print(F("y: ")); Serial.println(y); +#endif + byte command[8] = {0x7E, 0x06, 0x01, highByte(x), lowByte(x), highByte(y), lowByte(y), 0xEF,}; + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + +// This function outputs a variable number to the screen. It can show negative and positive numbers. It cannot show floats. +void displayNumber(signed int number) +{ +#ifdef DEBUG_SCREEN + Serial.print(F("DISPLAYNUMBER (")); Serial.println(number); +#endif + byte command[8] = {0x7E, 0x06, 0x13, 0x01, 0x0A, highByte(number), lowByte(number), 0xEF,}; + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + +// This function reads the serial data (if available) from the screen. +void readResponse() +{ + volatile int availableSerialCount = touch_screen_serial.available(); + //Serial.println(F("READRESPONSE")); + if( availableSerialCount < 5 ){ + return; + } + + boolean savingMessage = false; // When touch message, this starts recording data into an array for analysis. + //byte metaData[metadataArraySize]; // An array to store the received serial data // TODO: use the metadata array instead. It's just as long, and their uses don't overlap. + byte metaDataPosition = 0; // The metaData array is recycled: here is holds incoming serial data. + byte startMarker = 0x7E; // Any response from the screen will start with this. + byte endMarker = 0xEF; // Any response from the screen will end with this. + byte rc; // Hold the byte form the serial stream that we're examining. + + + + byte c = touch_screen_serial.peek(); + //Serial.print(F("SOME SERIAL DATA. Available:")); Serial.println( availableSerialCount ); + //Serial.print(F("Peek:")); Serial.println( c ); + if( c != startMarker ){ + rc = touch_screen_serial.read(); + Serial.print(F("throwing away left over touch_screen_serial byte:")); Serial.println(rc); + return; + } + +#ifdef DEBUG_SCREEN + Serial.println(F("GOT RESPONSE")); +#endif + + while( touch_screen_serial.available() ){ // By not checking for this the entire buffer is always cleared. + rc = touch_screen_serial.read(); +#ifdef DEBUG_SCREEN + Serial.print(rc); Serial.print(F("-")); +#endif + if( savingMessage == true ){ // We are now in the part of the response that is the message we were looking for. + if(rc != endMarker){ + metaData[metaDataPosition] = rc; + metaDataPosition++; + if( metaDataPosition >= metadataArraySize ){ + metaDataPosition = metadataArraySize - 1; + } + } + else { // We've arrived at the end marker. + metaData[metaDataPosition] = '\0'; // Terminate the string. + savingMessage = false; + metaDataPosition = 0; + if(metaData[metaDataPosition] == 0x06 && metaData[metaDataPosition + 1] == 0x07){ + touchX = touchToX( (metaData[metaDataPosition + 2] * 256) + metaData[metaDataPosition + 3] ); + touchY = touchToY( (metaData[metaDataPosition + 4] * 256) + metaData[metaDataPosition + 5] ); +#ifdef DEBUG_SCREEN + Serial.print(F("touchX=")); Serial.println(touchX); + Serial.print(F("touchY=")); Serial.println(touchY); + Serial.print(F("brightnessTimer=")); Serial.println(brightnessTimer); +#endif + + if( brightnessTimer == 0 ){ +#ifdef DEBUG_SCREEN + Serial.println(F("Turning on backlight")); +#endif + basicCommand(backlight_on); // If the screen was touched but the backlight was off, turn the backlight on. + } + else{ + touched = true; // To indicate that a touch event has just occured. + } + brightnessTimer = 255; + clearReceivedBuffer(); + } +#ifdef DEBUG_SCREEN + // OK message + else if( metaData[metaDataPosition] == 0x03 && metaData[metaDataPosition + 1] == 0x6F && metaData[metaDataPosition + 2] == 0x6B ){ + Serial.println(F("-OK")); + } + else{ // Unimplemented response form the touch screen. + Serial.println(F("-X-")); + metaDataPosition++; + if( metaDataPosition == metadataArraySize ){ return; } + } +#endif + } + } + if( rc == startMarker ){ // Once a valid startMarker is found, we start saving the message into the array. + savingMessage = true; +#ifdef DEBUG_SCREEN + Serial.print(F("(startMarker) ")); +#endif + } + } +} + +// This function can send basic string command that don't have any variable parts in them. +void basicCommand(const char* cmd) +{ +#ifdef DEBUG_SCREEN + Serial.println(F("BASIC COMMAND")); +#endif + if( touch_screen_serial.available() ){ // If necessary, clear old messages from the serial buffer. + clearReceivedBuffer(); + } + + touch_screen_serial.write(0x7E); // Starting byte, is always the same. + byte b = 0; + while( b < MAX_BASIC_COMMAND_LENGTH ){ // How many bytes are the basic commands at most? + touch_screen_serial.write( pgm_read_byte(&cmd[b]) ); + //Serial.print( pgm_read_byte(&cmd[b]),HEX ); Serial.print(F(" ")); + if( pgm_read_byte(&cmd[b]) == 0xEF ){ // This breaks out of the loop. + //waitForResponse(b); + b = MAX_BASIC_COMMAND_LENGTH; + } + b++; + } + waitForResponse(); +} + + +// This function can be activated after sending a command. It will wait until a response has arrived (or 100 milliseconds have passed), and then allow the Arduino to continue. +//void waitForResponse(byte expectedBytes) // From the touch screen + +void waitForResponse() // From the touch screen +{ +#ifdef DEBUG_SCREEN + Serial.println(); Serial.println(F("WAITING FOR RESPONSE FROM SCREEN")); + Serial.print(F("-available now: ")); Serial.println( touch_screen_serial.available() ); +#endif + byte b = 0; + while( touch_screen_serial.available() == 0 && b < 250){ + b++; + wait(1); + } +#ifdef DEBUG_SCREEN + Serial.print(F("wait time: ")); Serial.println(b); +#endif + if( touch_screen_serial.available() > 0 ){ + wait(10); // Perhaps some more bytes will show up. + while( touch_screen_serial.available() > 0 ){ // Throwing away the response. All we care about is touch messages, and they are handled in the readResponse function. + byte x = touch_screen_serial.read(); + //Serial.print(x); Serial.print(F("-")); + } + //Serial.println(); + } + else if( b == 250 ){ + Serial.println(F("Touch screen did not respond to command")); + } + +} + + + +void turnOnScreen() +{ +#ifdef DEBUG_SCREEN + Serial.print(F("__turnonscreen() (")); Serial.println(brightnessTimer); +#endif + if( brightnessTimer == 0 ){ +#ifdef DEBUG_SCREEN + Serial.println(F("BC:backlight_on")); +#endif + basicCommand(backlight_on); // Turn on the screen backlight again. + } + brightnessTimer = 255; +} + + +int touchToX(int x) +{ + return int constrain(((x - 80) / 3.7), 0, TOUCHSCREEN_WIDTH); +} +int touchToY(int y) +{ + return int constrain(((y - 100) / 2.8), 0, TOUCHSCREEN_HEIGHT); +} + + +void clearReceivedBuffer() +{ +//Serial.print(F("cleaning:")); + while( touch_screen_serial.available() ){ + char x = touch_screen_serial.read(); + Serial.print(x); + } + Serial.println(); +} + +#endif // End of touch screen check. + + + +void receive(const MyMessage &message) +{ + Serial.print(F("INCOMING MESSAGE for child #")); Serial.println(message.sensor); + if (message.isAck()) { + Serial.println(F("-Ack")); + } + else if( message.type==V_STATUS ){ + Serial.print(F("-Requested status: ")); Serial.println(message.getBool()); + + // turnOnScreen(); // Handled by display function now. + +#if !(defined(HAS_TOUCH_SCREEN)) + if( message.sensor < 10 && message.getBool() ){ + if( message.sensor == LEARN_SIMPLE_BTN_ID ){ // The user wants to the system to learn a new simple signal. This only starts when the button is toggled to on. + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Play the signal") )); //wait(RADIO_DELAY); + state = LEARNING_SIMPLE; + } + else if( message.sensor == LEARN_ON_OFF_BTN_ID ){ // The user wants the system to learn a new on+off signal. This only starts when the button is toggled to on. + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Play the ON signal") )); //wait(RADIO_DELAY); + state = LEARNING_ON; + } + if( message.sensor == COPYING_SIMPLE_BTN_ID ){ // The user wants to the system to learn a new simple signal. This only starts when the button is toggled to on. + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Play the signal") )); //wait(RADIO_DELAY); + state = COPYING_SIMPLE; + } + else if( message.sensor == COPYING_ON_OFF_BTN_ID ){ // The user wants the system to learn a new on+off signal. This only starts when the button is toggled to on. + send(textmsg.setSensor(DEVICE_STATUS_ID).set( F("Play the ON signal") )); //wait(RADIO_DELAY); + state = COPYING_ON; + } + //send(buttonmsg.setSensor(message.sensor).set(0)); // The button will already be set back to 'off' after the entire signal is recorded and everything is re-presented. + } + else +#endif + + if( message.sensor >= 10 && message.sensor < 100 ){ // If the user toggled a signal replay button. + if( playlist_position < PLAYLIST_SIZE){ // We only add to the playlist if there is space left in the playlist. + + Serial.println(F("-Adding to playlist")); + playlist_position++; + if( message.getBool() == 0 ){ + playlist[playlist_position] = (message.sensor - 9); + } + else { + playlist[playlist_position] = (message.sensor - 9) + 100; + } + //replay(message.sensor - 9, message.getBool()); // The old way of directly starting a replay. Now it uses a playlist. + } + } + } +} + + + + +/** + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2015 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * + */ diff --git a/code/Temperature_and_more/Temperature_and_more.arduino.avr.nano.elf b/code/Temperature_and_more/Temperature_and_more.arduino.avr.nano.elf new file mode 100644 index 0000000000000000000000000000000000000000..b61dc7cdc7a90c52162c53fd30eada85ae239fe9 GIT binary patch literal 173252 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 // The MySensors library. Hurray! +#include "Seeed_BME280.h" // "Grove - Barometer Sensor BME280". A relatively new library (as of 2018), works well with cheap BME280 sensors from China. +#include // The watchdog timer - if the device becomes unresponsive and doesn't periodically reset the timer, then it will automatically reset once the timer reaches 0. + +BME280 bme280; // Create the BME sensor object + +#ifdef HAS_TOUCH_SCREEN + +#include +SoftwareSerial touch_screen_serial(TOUCH_SCREEN_RX_PIN,TOUCH_SCREEN_TX_PIN); // RX (receive) pin, TX (transmit) pin + +#define MAX_BASIC_COMMAND_LENGTH 16 // How many bytes are in the longest basic command? +#define TOUCHSCREEN_WIDTH 240 // +#define TOUCHSCREEN_HEIGHT 320 // +#define SCREEN_PADDING 10 // Used to space things, e.g. the distance of content to the edge of the screen. +#define ITEM_HEIGHT 80 // How many pixels tall a single item on the screen is. +#define LABEL_HEIGHT 25 // How many pixels in height labels like 'temperature' are. + +boolean touched = false; // Was the touchscreen just touched? + +signed int touchX = 0; // Touch screen position X +signed int touchY = 0; // Touch screen position Y + + +// Basic commands for the touch screen. All commands for the TFT should start with 0x7E, but to save storage space this is taken care of in the basicCommand function. +PROGMEM const byte play[] = {0x07, 0x11, ' ', 'P', 'L', 'A', 'Y', 0xEF,}; // Places the word ' play' on the screen. +PROGMEM const byte on[] = {0x07, 0x11, ' ', 'O','N', ' ', ' ', 0xEF,}; // Places the word ' on ' on the screen. +PROGMEM const byte off[] = {0x07, 0x11, ' ', 'O', 'F', 'F', ' ', 0xEF,}; // Places the word ' off ' on the screen. +PROGMEM const byte w[] = {0x07, 0x11, 'w', 0x00, ' ', 0x00, 0x00, 0xEF,}; // Places the word 'w ' on the screen. +PROGMEM const byte menu[] = {0x07, 0x11, 'M', 'E', 'N', 'U', ' ', 0xEF,}; // Places the word 'menu ' on the screen. +PROGMEM const byte more[] = {0x07, 0x11, 'M', 'O', 'R', 'E', '>', 0xEF,}; // Places the word 'menu ' on the screen. + +PROGMEM const byte set_vertical[] = {0x03, 0x04, 0x00, 0xEF,}; // To set rotation of the screen to vertical. Try 0x01 or 0x03 instead of the 0x02. +PROGMEM const byte fill_black[] = {0x04, 0x20, 0x00, 0x00, 0xEF,}; // Fill screen with one color +//PROGMEM const byte fill_blue[] = {0x04, 0x20, 0x00, 0xFF, 0xEF,}; // Fill screen with one color + +PROGMEM const byte text_color_white[] = {0x04, 0x02, 0xFF, 0xFF, 0xEF,}; // white text color. fill screen with one color +//PROGMEM const byte text_color_black[] = {0x04, 0x02, 0x00, 0x00, 0xEF,}; // Dark text color. fill screen with one color +//PROGMEM const byte text_color_red[] = {0x04, 0x02, 0xF8, 0x00, 0xEF,}; // .. text color. fill screen with one color + +//PROGMEM const byte resetTFT[] = {0x02, 0x05, 0xEF,}; // Resets the TFT. But has no real effect. +//PROGMEM const byte testTFT[] = {0x02, 0x00, 0xEF}; // Test the TFT, should respond with "OK". +PROGMEM const byte backlight_on[] = {0x03, 0x06, 0xFF, 0xEF}; // Backlight intensity to half-full +PROGMEM const byte backlight_off[] = {0x03, 0x06, 0x00, 0xEF}; // Backlight intensity to zero +//PROGMEM const byte serialSpeedUp[] = {0x03, 0x40, 0x03, 0xEF,}; // Sets communication speed to 57600 (from 9600) +//PROGMEM const byte serialSlowDown[] = {0x03, 0x40, 0x00, 0xEF,}; // Sets communication speed to 9600 again. Oddly enough, it seems it works fastest at this speed.. + +// Colors +#define BLACK 0 +#define GREY111111 4226 +#define GREY333333 12678 +#define GREY666666 25388 +#define GREYCCCCCC 52857 +#define YELLOW 65504 +#define LIGHT_YELLOW 65510 +#define LIGHT_ORANGE 65126 +#define RED 63488 +#define GREEN 2016 +#define WHITE 65535 + +// A list of strings stored in program memory in order to save ram. +#define SCREEN_TEMPERATURE 0 +#define SCREEN_HUMIDITY 1 +#define SCREEN_FORECAST 2 +#define SCREEN_STABLE 3 +#define SCREEN_SUNNY 4 +#define SCREEN_CLOUDY 5 +#define SCREEN_UNSTABLE 6 +#define SCREEN_THUNDERSTORM 7 +#define SCREEN_UNKNOWN 8 + +typedef byte MessageID; // TODO Is this used? Not really. Simplifying the message table could save some storage space. + +struct MessageDef { + MessageID ID; + char Description[20]; +}; + +const MessageDef MessageTable[] PROGMEM = { + {SCREEN_TEMPERATURE,"Temperature"}, + {SCREEN_HUMIDITY,"Humidity"}, + {SCREEN_FORECAST,"Barometer"}, + {SCREEN_STABLE,"STABLE"}, + {SCREEN_SUNNY,"SUNNY"}, + {SCREEN_CLOUDY,"Cloudy"}, + {SCREEN_UNSTABLE,"Unstable"}, + {SCREEN_THUNDERSTORM,"Thunderstorm"}, + {SCREEN_UNKNOWN,"Unknown"}, + }; + + +const byte metadataArraySize = 8; // The size of the array to store the serial data we're decoding in. +byte metaData[metadataArraySize]; // Holds metadata for a replayable signal. +byte screen_brightness = 255; // When this is 0 the screen is turned off. + + +#endif // End of has_touch_screen + + +#define INTERVAL 1000 // When active, the internal clock runs every 1000 milliseconds, which is a second. + + +float previous_temperature = 0; // Contains the latest temperature value. +float temperature = 0; // Contains the latest temperature value. +byte previous_humidity = 0; // Contains the latest humidity value. +byte current_humidity = 0; // Contains the latest humidity value. +unsigned int previous_pressure = 0; // Contains the previously detected air pressure value. +unsigned int pressure = 0; // Contains the latest air pressure value. +byte forecast = 5; // A number that represents a type of weather forecast + + +// VARIABLES YOU PROBABLY SHOULDN'T CHANGE +#define RADIO_DELAY 100 // milliseconds betweeen radio signals during the presentation phase. +#define TEMP_CHILD_ID 0 // For MySensors. Within this node each sensortype should have its own ID number. +#define HUM_CHILD_ID 1 +#define BARO_CHILD_ID 2 +#define FORECAST_CHILD_ID 3 +#define SCREEN_BUTTON_CHILD_ID 4 + +// Forecast variables +#define CONVERSION_FACTOR (1.0/10.0) // Used by forecast algorithm to convert from Pa to kPa, by dividing hPa by 10. +#define STABLE 0 // "Stable Weather Pattern" +#define SUNNY 1 // "Slowly rising Good Weather", "Clear/Sunny " +#define CLOUDY 2 // "Slowly falling L-Pressure ", "Cloudy/Rain " +#define UNSTABLE 3 // "Quickly rising H-Press", "Not Stable" +#define THUNDERSTORM 4 // "Quickly falling L-Press", "Thunderstorm" +#define UNKNOWNN 5 // "Unknown (More Time needed) +byte lastForecast = 10; // Stores the previous forecast. Icons are only redrawn if necessary. +const byte LAST_SAMPLES_COUNT = 5; +float lastPressureSamples[LAST_SAMPLES_COUNT]; +byte minuteCount = 0; // The forecast algorithm keeps track of time +bool firstRound = true; // The forecast algorithm needs to know if it is creating the first forecast. +float pressureAvg; // Average value after 2 hours is used as reference value for the next iteration. +float pressureAvg2; +float dP_dt; // Used by the forecast algorithm. + + +// MySensors variables +MyMessage temperature_message(TEMP_CHILD_ID, V_TEMP); +MyMessage humidity_message(HUM_CHILD_ID, V_HUM); +MyMessage pressure_message(BARO_CHILD_ID, V_PRESSURE); +MyMessage string_message(FORECAST_CHILD_ID, V_TEXT); +MyMessage button_message(SCREEN_BUTTON_CHILD_ID, V_STATUS); // Allows the controller to turn the screen on and off. + + +boolean connectedToNetwork = false; // Are we connected to the local MySensors network? Used to display the 'w' connection icon. +boolean send_all_values = 1; // Sends the state of the toggle to the controller on startup or when requested by the controller. +boolean metric = true; // Should the device show metric or Fahrenheit? + + + +/* +// A function to measure how much ram is used. +int freeRam () { + extern int __heap_start, *__brkval; + int v; + return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); +} +// via https://playground.arduino.cc/Code/AvailableMemory +*/ + + +void presentation() { + // Send the sketch version information to the gateway and Controller + sendSketchInfo(F("Weather station"), F("1.0")); wait(RADIO_DELAY); + + // Tell the MySensors gateway what kind of sensors this node has, and what their ID's on the node are, as defined in the code above. + present(TEMP_CHILD_ID, S_TEMP, F("Temperature")); wait(RADIO_DELAY); + present(HUM_CHILD_ID, S_HUM, F("Humidity")); wait(RADIO_DELAY); + present(BARO_CHILD_ID, S_BARO, F("Air pressure")); wait(RADIO_DELAY); + present(FORECAST_CHILD_ID, S_INFO, F("Forecast")); wait(RADIO_DELAY); +#ifdef HAS_TOUCH_SCREEN + present(SCREEN_BUTTON_CHILD_ID, S_BINARY, F("Screen")); wait(RADIO_DELAY); + send_all_values = 1; +#endif +} + + +#ifdef HAS_TOUCH_SCREEN +void send_values(){ +#ifdef DEBUG + Serial.println(F("Sending button states")); +#endif + + send(button_message.setSensor(SCREEN_BUTTON_CHILD_ID).set(1)); + wait(RADIO_DELAY); + +} +#endif + + + +void setup() { + Serial.begin(115200); // for serial debugging over USB. + Serial.println(F("Hello, I am a climate sensor")); + +#ifdef HAS_TOUCH_SCREEN + wait(2000); + touch_screen_serial.begin(9600); + wait(2000); + +#ifdef DEBUG_SCREEN + Serial.println(F("BC: backlight_on")); +#endif + basicCommand(backlight_on); // Turn on the backlight (if it isn't already). + +#ifdef DEBUG_SCREEN + Serial.println(F("BC: vertical")); +#endif + basicCommand(set_vertical); // Set the screen to vertical mode. + +#ifdef DEBUG_SCREEN + Serial.println(F("BC: white text")); +#endif + basicCommand(text_color_white); // Set text color to white. + +#ifdef DEBUG_SCREEN + Serial.println(F("BC: fill black")); +#endif + basicCommand(fill_black); // Set the background color of the screen to black. + + fontSize(1); // Set the font size of the touch screen to its smallest size. + + setCur(SCREEN_PADDING,SCREEN_PADDING); + writeText(SCREEN_TEMPERATURE); + + roundedRectangle(0,ITEM_HEIGHT, TOUCHSCREEN_WIDTH, ITEM_HEIGHT, 0, GREY111111); + //simpleHorizontal(ITEM_HEIGHT, GREYCCCCCC); + + setCur(SCREEN_PADDING,SCREEN_PADDING + ITEM_HEIGHT); + writeText(SCREEN_HUMIDITY); + + //simpleHorizontal(ITEM_HEIGHT * 2, GREYCCCCCC); + setCur(SCREEN_PADDING,SCREEN_PADDING + (ITEM_HEIGHT * 2)); + writeText(SCREEN_FORECAST); + + +#endif // end of has_touch_screen + + + if(isTransportReady()){ // If we are connected to the MySensors network. + Serial.println(F("Connected to gateway!")); + connectedToNetwork = true; + metric = getControllerConfig().isMetric; // Ask if Celcius or Fahrenheit is prefered. + }else{ + Serial.println(F("! NOT CONNECTED TO GATEWAY")); + } + + + if(!bme280.init()){ + Serial.println(F("! Sensor error")); +#ifdef HAS_TOUCH_SCREEN + writeString("Sensor error",12); +#endif + } + + wdt_enable(WDTO_2S); // Starts the watchdog timer. If it is not reset once every 2 seconds, then the entire device will automatically restart. +} + + +void loop() +{ + // If a presentation is requested, we also send the values of the children. + if( send_all_values ){ +#ifdef DEBUG + Serial.println(F("RESENDING VALUES")); +#endif + send_all_values = 0; + send_values(); + } + + static unsigned long previousMillis = 0; // Used to keep track of time. + static byte intervalCounter = 255; // How may intervals have passed. + +#ifdef HAS_TOUCH_SCREEN + // Check if the screen is being touched. + readResponse(); +#endif + + + + // + // MAIN LOOP + // Runs every few seconds. By counting how often this loop has run (and resetting that counter back to zero after 250 loops), it becomes possible to schedule all kinds of things without using a lot of memory. + // Maximum time that can be scheduled is 4s * 250 loops = 1000 seconds. So the maximum time between sending data can be 16 minutes. + // + + + if(millis() - previousMillis >= INTERVAL){ // Main loop, runs every second. + previousMillis = millis(); // Store the current time as the previous measurement start time. + + if(intervalCounter >= SECONDS_BETWEEN_SENDING){ + intervalCounter = 0; + }else{ + intervalCounter++; + } + //Serial.println(intervalCounter); + + wdt_reset(); // Reset the watchdog timer + + + // Clock schedule + switch (intervalCounter) { + + // + // TEMPERATURE + // + case 0: // If we are in the first second of the clock + + temperature = bme280.getTemperature(); + + if(temperature != -127.00 && temperature != 85.00 && temperature != previous_temperature) { // Avoids working with measurement errors. + previous_temperature = temperature; + + if(!metric){ + temperature = (temperature * 9.0)/5.0 + 32.0; + } + + Serial.print(F("Sending temp: ")); Serial.println(temperature); + connectedToNetwork = false; // If we receive an echo then this will be set back to true. + send(temperature_message.set(temperature,1),1); // Ask for an echo from the controller + + #ifdef HAS_TOUCH_SCREEN + displayNetworkStatus(); + + // Clear the background for this part of the screen. + roundedRectangle(0,LABEL_HEIGHT, TOUCHSCREEN_WIDTH, ITEM_HEIGHT - LABEL_HEIGHT, 0, BLACK); + + setCur(SCREEN_PADDING,SCREEN_PADDING + LABEL_HEIGHT); + fontSize(4); + + char value_string[7]; // We create a character array to hold a 'string' representation of the temperature value. + dtostrf(temperature, 0, 1, value_string); // Here the floating point value is turned into a 'string'. + + byte string_length = 4; + if( abs(temperature) < 10 ){ string_length = 3; } + if( abs(temperature) > 99 ){ string_length = 5; } + if( temperature < 0 ){ string_length++; } // Accounting for the minus character + + writeString(value_string,string_length); + + fontSize(2); + if(metric){ + writeString("C",1); + } + else{ + writeString("F",1); + } + +#endif + } + break; + + + // + // HUMIDITY + // + + case 1: + + current_humidity = bme280.getHumidity(); + + if( current_humidity != previous_humidity ){ + previous_humidity = current_humidity; + + + Serial.print(F("Sending humidity ")); Serial.println(current_humidity); + send(humidity_message.set(current_humidity)); + + #ifdef HAS_TOUCH_SCREEN + + displayNetworkStatus(); // Show or remove the W icon in the top-right of the screen. + + // Clear the background for this part of the screen. + roundedRectangle(0,ITEM_HEIGHT + LABEL_HEIGHT, TOUCHSCREEN_WIDTH, ITEM_HEIGHT - LABEL_HEIGHT, 0, GREY111111); + + setCur(SCREEN_PADDING,SCREEN_PADDING + ITEM_HEIGHT + LABEL_HEIGHT); + fontSize(4); + + // Show humidity value on the screen + displayNumber(current_humidity); + fontSize(2); + writeString("%",1); + + // Show quality opinion on the screen. + fontSize(4); + if (current_humidity > 0 && current_humidity < 30){ + writeString(" DRY",4); + } + else if (current_humidity < 65){ + writeString(" GOOD",5); + } + else { + writeString(" MOIST",6); + } + +#endif + + } + break; + + + + // + // PRESSURE + // + case 2: + + pressure = round(bme280.getPressure() / 100); + Serial.print(F("Sending pressure ")); Serial.println(pressure); + send(pressure_message.set((pressure),1)); + + forecast = sample(pressure/100); + //forecast = random(5); // Show a random icon. This is used in exhibits, to make it a bit more interesting. + + if (pressure != previous_pressure || forecast != lastForecast) { + previous_pressure = pressure; + lastForecast = forecast; + +#ifdef HAS_TOUCH_SCREEN + // Show pressure value on the screen + + // Clear the background for this part of the screen. + roundedRectangle(0,(ITEM_HEIGHT * 2) + LABEL_HEIGHT, TOUCHSCREEN_WIDTH, (ITEM_HEIGHT * 2) - LABEL_HEIGHT, 0, BLACK); + + setCur(SCREEN_PADDING,SCREEN_PADDING + (ITEM_HEIGHT * 2) + LABEL_HEIGHT); + fontSize(2); + + char pressure_value_string[6]; // We create a character array to hold a 'string' representation of the temperature value. + memset(pressure_value_string,0,sizeof(pressure_value_string));// We fill the character array with zeros + dtostrf(pressure, 0, 0, pressure_value_string); // Here the floating point value is turned into a 'string'. + + writeString(pressure_value_string,4); + + byte circle_size = 40; + unsigned int cloud_color = WHITE; + + setCur(SCREEN_PADDING, SCREEN_PADDING + (ITEM_HEIGHT * 2) + (LABEL_HEIGHT * 2)); +#endif + + // UNKNOWN + if(forecast == 5){ + Serial.println(F("UNKNOWN")); + send(string_message.set(F("Unknown"))); // Sending the latest forecast to the controller. +#ifdef HAS_TOUCH_SCREEN + //fontSize(4); + writeText(SCREEN_UNKNOWN); +#endif + } + + // STABLE WEATHER + if(forecast == STABLE){ + Serial.println(F("STABLE")); + send(string_message.set(F("Stable"))); // Sending the latest forecast to the controller. + cloud_color = WHITE; +#ifdef HAS_TOUCH_SCREEN + fontSize(4); + writeText(SCREEN_STABLE); +#endif + } + + // UNSTABLE WEATHER + else if(forecast == UNSTABLE){ + Serial.println(F("UNSTABLE")); + send(string_message.set(F("Unstable"))); +#ifdef HAS_TOUCH_SCREEN + fontSize(4); + writeText(SCREEN_UNSTABLE); +#endif + } + + // SUNNY WEATHER + else if(forecast == SUNNY){ + Serial.println(F("SUNNY")); + send(string_message.set(F("Sunny"))); + //circle_size = 50; +#ifdef HAS_TOUCH_SCREEN + //circle(TOUCHSCREEN_WIDTH / 2, ITEM_HEIGHT * 3, circle_size, LIGHT_YELLOW); // x, y, radius, color + circle(TOUCHSCREEN_WIDTH / 2, ITEM_HEIGHT * 3, circle_size, YELLOW); + circle(TOUCHSCREEN_WIDTH / 2, ITEM_HEIGHT * 3, circle_size - 10, LIGHT_ORANGE); + fontSize(1); + writeText(SCREEN_SUNNY); +#endif + } + + // CLOUDY WEATHER OR THUNDERSTORM + else if(forecast == CLOUDY || forecast == THUNDERSTORM){ + if(forecast == THUNDERSTORM){ cloud_color = RED; } + +#ifdef HAS_TOUCH_SCREEN + circle(TOUCHSCREEN_WIDTH / 2, ITEM_HEIGHT * 3, circle_size, cloud_color); // x, y, radius, color + circle((TOUCHSCREEN_WIDTH / 2) - circle_size, ITEM_HEIGHT * 3 + 10, circle_size - 10, cloud_color); + circle(int((TOUCHSCREEN_WIDTH / 2) + circle_size), ITEM_HEIGHT * 3 + 20, circle_size - 20, cloud_color); + fontSize(1); +#endif + if(forecast == THUNDERSTORM){ + Serial.println(F("THUNDERSTORM")); + send(string_message.set(F("Thunderstorm"))); +#ifdef HAS_TOUCH_SCREEN + writeText(SCREEN_THUNDERSTORM); +#endif + } + else { + Serial.println(F("CLOUDY")); + send(string_message.set(F("Cloudy"))); +#ifdef HAS_TOUCH_SCREEN + writeText(SCREEN_CLOUDY); +#endif + } + } + } + break; + } + } +} + + + +float getLastPressureSamplesAverage() +{ + float lastPressureSamplesAverage = 0; + for (byte i = 0; i < LAST_SAMPLES_COUNT; i++) { + lastPressureSamplesAverage += lastPressureSamples[i]; + } + lastPressureSamplesAverage /= LAST_SAMPLES_COUNT; + + return lastPressureSamplesAverage; +} + + +// Forecast algorithm found here +// http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf +// Pressure in hPa --> forecast done by calculating kPa/h +byte sample(float pressure) +{ + // Calculate the average of the last n minutes. + int index = minuteCount % LAST_SAMPLES_COUNT; + lastPressureSamples[index] = pressure; + + minuteCount++; + if (minuteCount > 185) { + minuteCount = 6; + } + + if (minuteCount == 5) { + pressureAvg = getLastPressureSamplesAverage(); + } + else if (minuteCount == 35) { + float lastPressureAvg = getLastPressureSamplesAverage(); + float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; + if (firstRound) { // first time initial 3 hour + dP_dt = change * 2; // note this is for t = 0.5hour + } + else { + dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value. + } + } + else if (minuteCount == 65) { + float lastPressureAvg = getLastPressureSamplesAverage(); + float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; + if (firstRound) { // First time initial 3 hour + dP_dt = change; // Note this is for t = 1 hour + } + else { + dP_dt = change / 2; // Divide by 2 as this is the difference in time from 0 value + } + } + else if (minuteCount == 95) { + float lastPressureAvg = getLastPressureSamplesAverage(); + float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; + if (firstRound) { // First time initial 3 hour + dP_dt = change / 1.5; // Note this is for t = 1.5 hour + } + else { + dP_dt = change / 2.5; // Divide by 2.5 as this is the difference in time from 0 value + } + } + else if (minuteCount == 125) { + float lastPressureAvg = getLastPressureSamplesAverage(); + pressureAvg2 = lastPressureAvg; // store for later use. + float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; + if (firstRound) { // first time initial 3 hour + dP_dt = change / 2; // Note this is for t = 2 hour + } + else { + dP_dt = change / 3; // Divide by 3 as this is the difference in time from 0 value + } + } + else if (minuteCount == 155) { + float lastPressureAvg = getLastPressureSamplesAverage(); + float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; + if (firstRound) { // First time initial 3 hour + dP_dt = change / 2.5; // Note this is for t = 2.5 hour + } + else { + dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value + } + } + else if (minuteCount == 185) { + float lastPressureAvg = getLastPressureSamplesAverage(); + float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; + if (firstRound) { // first time initial 3 hour + dP_dt = change / 3; // Note this is for t = 3 hour + } + else { + dP_dt = change / 4; // Divide by 4 as this is the difference in time from 0 value + } + pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past. + firstRound = false; // Flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop. + } + + byte forecast = UNKNOWNN; + if (minuteCount < 35 && firstRound) { // If time is less than 35 min on the first 3 hour interval. + forecast = UNKNOWNN; + } + else if (dP_dt < (-0.25)) { + forecast = THUNDERSTORM; + } + else if (dP_dt > 0.25) { + forecast = UNSTABLE; + } + else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05))) { + forecast = CLOUDY; + } + else if ((dP_dt > 0.05) && (dP_dt < 0.25)) + { + forecast = SUNNY; + } + else if ((dP_dt >(-0.05)) && (dP_dt < 0.05)) { + forecast = STABLE; + } + else { + forecast = UNKNOWNN; + } + + // Useful for debugging + //Serial.print(F("BME280 - Forecast at minute ")); + //Serial.print(minuteCount); + //Serial.print(F(" dP/dt = ")); + //Serial.print(dP_dt); + //Serial.print(F("kPa/h --> ")); + //Serial.println(weather[forecast]); + //Serial.println(freeRam()); + + return forecast; +} + + + //for (float i=0; i<=6 ; i=i+.4) { + // Calculate sun rays end points + //int resultX = sunPositionX + (int)round( sunSize * cos( i ) ); + //int resultY = sunPositionY + (int)round( sunSize * sin( i ) ); + //} + + + + + + + + +#ifdef HAS_TOUCH_SCREEN + +void displayNetworkStatus() // Show connection icon on the display +{ + if( connectedToNetwork ){ +#ifdef DEBUG_SCREEN + Serial.println(F("BC: show W icon")); +#endif + setCur(TOUCHSCREEN_WIDTH - 30, SCREEN_PADDING ); + fontSize(1); + basicCommand(w); + } + else { +#ifdef DEBUG_SCREEN + Serial.println(F("BC: hide W icon")); +#endif + roundedRectangle(TOUCHSCREEN_WIDTH - 50,0, 50, LABEL_HEIGHT, 0, BLACK); + } +} + + + +void simpleHorizontal(unsigned int y, unsigned int color) // Draw a horizontal line on the screen. +{ + +#ifdef DEBUG_SCREEN + Serial.println(F("SIMPLEHORIZONTAL:")); + Serial.print(F("y: ")); Serial.println(y); +#endif + byte command[12] = {0x7E, 0x0A, 0x23, 0,0, highByte(y), lowByte(y), 0,240, 255, 255, 0xEF,}; + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + +void roundedRectangle(int x, int y, int w, int h, int r, int c) // Draw a pixel on the screen. +{ + +#ifdef DEBUG_SCREEN + Serial.println(F("ROUNDEDRECTANGLE")); + //Serial.print(F("x:")); Serial.println(x); // top-right x-position + //Serial.print(F("y:")); Serial.println(y); // top-left y-position + //Serial.print(F("w:")); Serial.println(w); // width + //Serial.print(F("h:")); Serial.println(h); // height + //Serial.print(F("r:")); Serial.println(r); // radius + //Serial.print(F("c:")); Serial.println(c); // color +#endif + byte command[16] = {0x7E, 0x0E, 0x2C, highByte(x), lowByte(x), highByte(y), lowByte(y), highByte(w), lowByte(w), highByte(h), lowByte(h) - 2, highByte(r), lowByte(r), highByte(c), lowByte(c), 0xEF,}; + + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + + +void circle(unsigned int x, unsigned int y, unsigned int r, unsigned int c) // Draw a pixel on the screen. +{ +#ifdef DEBUG_SCREEN + Serial.println(F("CIRCLE")); + Serial.print(F("x:")); Serial.println(x); // top-right x-position + Serial.print(F("y:")); Serial.println(y); // top-left y-position + Serial.print(F("r:")); Serial.println(r); // radius + Serial.print(F("c:")); Serial.println(c); // color +#endif + byte command[12] = {0x7E, 0x0A, 0x28, highByte(x), lowByte(x), highByte(y), lowByte(y), highByte(r), lowByte(r), highByte(c), lowByte(c), 0xEF}; + + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + + + +// This function writes text to the screen. You can use the setCur function to place the cursor in the desired position first. + +// This function writes text to the screen. You can use the setCur function to place the cursor in the desired position first. +void writeText(byte textID) +{ +#ifdef DEBUG_SCREEN + Serial.println(F("WRITETEXT")); +#endif + byte string_length = strlen_P(MessageTable[textID].Description); + + touch_screen_serial.write( 0x7E ); + touch_screen_serial.write( string_length + 2); + touch_screen_serial.write( 0x11 ); + for( byte i=0; i < string_length; i++ ){ + char char_byte = pgm_read_byte(MessageTable[textID].Description + i); + //Serial.print("-"); Serial.print(char_byte); + touch_screen_serial.write( char_byte ); + } + touch_screen_serial.write( 0xEF ); + + waitForResponse(); +} + + +void writeString(char string_array[], byte string_length) +{ +#ifdef DEBUG_SCREEN + Serial.println(F("WRITESTRING")); +#endif + //byte string_length = strlen_P(MessageTable[textID].Description) + 2; + + touch_screen_serial.write( 0x7E ); + touch_screen_serial.write( string_length + 2 ); + touch_screen_serial.write( 0x11 ); + for( byte i=0; i < string_length; i++ ){ + char char_byte = string_array[i]; + //Serial.print("-"); Serial.print(char_byte); + touch_screen_serial.write( char_byte ); + } + touch_screen_serial.write( 0xEF ); + + waitForResponse(); +} + + +#ifdef DEBUG_SCREEN +void drawPix(int x, int y, int c) // Draw a pixel on the screen. +{ + Serial.println(F("DRAWPIX:")); + Serial.print(F("x: ")); Serial.println(x); + Serial.print(F("y: ")); Serial.println(y); + Serial.print(F("c: ")); Serial.println(c); + byte command[10] = {0x7E, 0x08, 0x21, highByte(x), lowByte(x), highByte(y), lowByte(y), highByte(c), lowByte(c), 0xEF}; + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} +#endif + + +// This function places the text cursor anywhere on the screen. +void setCur(int x, int y) +{ +#ifdef DEBUG_SCREEN + Serial.println(F("SETCUR")); + Serial.print(F("x: ")); Serial.println(x); + Serial.print(F("y: ")); Serial.println(y); +#endif + byte command[8] = {0x7E, 0x06, 0x01, highByte(x), lowByte(x), highByte(y), lowByte(y), 0xEF}; + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + +// This function outputs a variable number to the screen. It can show negative and positive numbers. It cannot show floats. +void displayNumber(int number) +{ +//#ifdef DEBUG_SCREEN + Serial.print(F("DISPLAYNUMBER (")); Serial.println(number); + Serial.print("Number:"); Serial.println(number); +//#endif + byte command[8] = {0x7E, 0x06, 0x13, 0x00, 0x0A, highByte(number), lowByte(number), 0xEF}; + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + +// This function outputs a variable number to the screen. It can show negative and positive numbers. It cannot show floats. +void fontSize(byte font_size) +{ +#ifdef DEBUG_SCREEN + Serial.print(F("TEXTSIZE (")); Serial.println(font_size); +#endif + byte command[5] = {0x7E, 0x03, 0x03, lowByte(font_size), 0xEF}; + //byte command[5] = {0x7E, 0x03, 0x03, font_size, 0xEF,}; + for( int i=0; i < sizeof(command); i++ ){ + touch_screen_serial.write( command[i] ); + //Serial.print(command[i],HEX); Serial.print(F(" ")); + } + waitForResponse(); +} + + +// This function reads the serial data (if available) from the screen. +void readResponse() +{ + volatile int availableSerialCount = touch_screen_serial.available(); + + if( availableSerialCount < 5 ){ + return; + } + //Serial.println(F("READRESPONSE")); + + boolean savingMessage = false; // When touch message, this starts recording data into an array for analysis. + //byte metaData[metadataArraySize]; // An array to store the received serial data // TODO: use the metadata array instead. It's just as long, and their uses don't overlap. + byte metaDataPosition = 0; // The metaData array is recycled: here is holds incoming serial data. + byte startMarker = 0x7E; // Any response from the screen will start with this. + byte endMarker = 0xEF; // Any response from the screen will end with this. + byte rc; // Hold the byte form the serial stream that we're examining. + + byte c = touch_screen_serial.peek(); + if( c != startMarker ){ + rc = touch_screen_serial.read(); + Serial.print(F("throwing away left over touch_screen_serial byte:")); Serial.println(rc); + return; + } + +#ifdef DEBUG_SCREEN + Serial.println(F("GOT RESPONSE")); +#endif + + while( touch_screen_serial.available() ){ // By not checking for this the entire buffer is always cleared. + rc = touch_screen_serial.read(); +#ifdef DEBUG_SCREEN + Serial.print(rc); Serial.print(F("-")); +#endif + if( savingMessage == true ){ // We are now in the part of the response that is the message we were looking for. + if(rc != endMarker){ + metaData[metaDataPosition] = rc; + metaDataPosition++; + if( metaDataPosition >= metadataArraySize ){ + metaDataPosition = metadataArraySize - 1; + } + } + else { // We've arrived at the end marker. + metaData[metaDataPosition] = '\0'; // Terminate the string. + savingMessage = false; + metaDataPosition = 0; + if(metaData[metaDataPosition] == 0x06 && metaData[metaDataPosition + 1] == 0x07){ + touchX = touchToX( (metaData[metaDataPosition + 2] * 256) + metaData[metaDataPosition + 3] ); + touchY = touchToY( (metaData[metaDataPosition + 4] * 256) + metaData[metaDataPosition + 5] ); +#ifdef DEBUG_SCREEN + Serial.print(F("touchX=")); Serial.println(touchX); + Serial.print(F("touchY=")); Serial.println(touchY); +#endif + + if( screen_brightness == 0 ){ +#ifdef DEBUG_SCREEN + Serial.println(F("Turning on backlight")); +#endif + turnOnScreen(true); + } + else{ +#ifdef DEBUG_SCREEN + Serial.println(F("Turning off backlight")); +#endif + turnOnScreen(false); + //basicCommand(backlight_off); + //screen_brightness = 0; // To indicate that a touch event has just occured. + } + clearReceivedBuffer(); + } +#ifdef DEBUG_SCREEN + // OK message + else if( metaData[metaDataPosition] == 0x03 && metaData[metaDataPosition + 1] == 0x6F && metaData[metaDataPosition + 2] == 0x6B ){ + Serial.println(F("-OK")); + } + else{ // Unimplemented response form the touch screen. + Serial.println(F("-X-")); + metaDataPosition++; + if( metaDataPosition == metadataArraySize ){ return; } + } +#endif + } + } + if( rc == startMarker ){ // Once a valid startMarker is found, we start saving the message into the array. + savingMessage = true; +#ifdef DEBUG_SCREEN + Serial.print(F("(startMarker) ")); +#endif + } + } +} + + +// This function can send basic string command that don't have any variable parts in them. +void basicCommand(const char* cmd) +{ +#ifdef DEBUG_SCREEN + Serial.println(F("BASIC COMMAND")); +#endif + if( touch_screen_serial.available() ){ // If necessary, clear old messages from the serial buffer. + clearReceivedBuffer(); + } + + touch_screen_serial.write(0x7E); // Starting byte, is always the same. + byte b = 0; + while( b < MAX_BASIC_COMMAND_LENGTH ){ // How many bytes are the basic commands at most? + touch_screen_serial.write( pgm_read_byte(&cmd[b]) ); + //Serial.print( pgm_read_byte(&cmd[b]),HEX ); Serial.print(F(" ")); + if( pgm_read_byte(&cmd[b]) == 0xEF ){ // This breaks out of the loop. + //waitForResponse(b); + b = MAX_BASIC_COMMAND_LENGTH; + } + b++; + } + waitForResponse(); +} + + +// This function can be activated after sending a command. It will wait until a response has arrived (or 100 milliseconds have passed), and then allow the Arduino to continue. +//void waitForResponse(byte expectedBytes) // From the touch screen + +void waitForResponse() // From the touch screen +{ +#ifdef DEBUG_SCREEN + Serial.println(); Serial.println(F("WAITING FOR RESPONSE FROM SCREEN")); + Serial.print(F("-available now: ")); Serial.println( touch_screen_serial.available() ); +#endif + byte b = 0; + while( touch_screen_serial.available() == 0 && b < 250){ + b++; + wait(1); + } +#ifdef DEBUG_SCREEN + Serial.print(F("wait time: ")); Serial.println(b); +#endif + if( touch_screen_serial.available() > 0 ){ + wait(10); // Perhaps some more bytes will show up. + while( touch_screen_serial.available() > 0 ){ // Throwing away the response. All we care about is touch messages, and they are handled in the readResponse function. + byte x = touch_screen_serial.read(); + //Serial.print(x); Serial.print(F("-")); + } + //Serial.println(); + } + else if( b == 250 ){ + Serial.println(F("Touch screen did not respond to command")); + } +} + + + +void turnOnScreen(boolean desired_state) +{ +//#ifdef DEBUG_SCREEN + Serial.print(F("Setting screen backlicht to: ")); Serial.println(desired_state); +//#endif + if( desired_state == true ){ +#ifdef DEBUG_SCREEN + Serial.println(F("BC: backlight_on")); +#endif + screen_brightness = 255; + basicCommand(backlight_on); // Turn on the touch screen backlight. + send(button_message.setSensor(SCREEN_BUTTON_CHILD_ID).set(1)); + } + else { +#ifdef DEBUG_SCREEN + Serial.println(F("BC: backlight_off")); +#endif + screen_brightness = 0; + basicCommand(backlight_off); // Turn off the touch screen backlight + send(button_message.setSensor(SCREEN_BUTTON_CHILD_ID).set(0)); + } +} + + +int touchToX(int x) +{ + return int constrain(((x - 80) / 3.7), 0, TOUCHSCREEN_WIDTH); +} +int touchToY(int y) +{ + return int constrain(((y - 100) / 2.8), 0, TOUCHSCREEN_HEIGHT); +} + + +void clearReceivedBuffer() +{ +//Serial.print(F("cleaning:")); + while( touch_screen_serial.available() ){ + char x = touch_screen_serial.read(); + Serial.print(x); + } + Serial.println(); +} + +#endif // End of touch screen check. + + + +void receive(const MyMessage &message) +{ + Serial.print(F("INCOMING MESSAGE for child #")); Serial.println(message.sensor); + if (message.isAck()) { + Serial.println(F("-Ack")); + connectedToNetwork = true; + } +#ifdef HAS_TOUCH_SCREEN + else if( message.type==V_STATUS && message.sensor == SCREEN_BUTTON_CHILD_ID ){ + boolean desired_state = message.getBool(); + Serial.print(F("-Requested status: ")); Serial.println(desired_state); + turnOnScreen(desired_state); // Set the touch screen brightness + } +#endif +} + + + + + +/* + * + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2015 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + */