0 <04mÖ™‰…L0e<� @æUaY}Îe¥H•ªªÒy@òº�mÂÊÚÔ^ÞîÖ J!Be¹ÜíÿÿÞÍ›gE3#ÿ ó?1ÿÿÿPUeffýÿÿfofýÿÿÿß üÿÿß 2D43# ™™™™™™™™™™™™™Y™™YYY™Y™Y™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™â™’™î©™îîë™î¾îî»»ëî»»»»»»»»»»»»™™™™™šª™©šªš™™™™©š©š©šªš™šª™™™™™™™™™™™™™••™™••™™Y™™™Y™Y™™™Y™™™™™»»»»»´»K»K»»K»»»»»´»»»»»K»»»»K»´™™ùŸ™™ïþ™™õ_™™Y•ùŸ™™ïþ™™õ_™™Y•™™+»»›»»»[»»»›»»»™»»[™»²»»»»»™»»››»»´KK»»»´››»—¹»¹–™–™i™i™™™–™i™™itg™–w™i™——™™™™ii–™–™i™i™™™–™i™™i»»K»»´»K»K»´K»»¹´»´›»´I™K»–™»K—™»»K»»´»K»K»´K»»»¹»´»™dK»™™»»™I»´»»›™»´›™»Ky™K»k›´»´»»´K»K»»»»K»´™¹K»™¹»Kik»´I»»»´»´»»´K»K»»»»K»´™™™™™™¹›™›K›™›K›™»K›¹´»›¹´K»»´K»Ýݸ™ÝÝ(›ØØ�›�ß�²ÝÝ݈ÝÝÝ���ÝÝÝØ�ý™™U™‘’Y!Q"UQU™!•™RU!™A™™‘™‘!´!´A»B»A»D»A»D´A´D´A”D™™™»»‘²‘DD‘™™™!™™A™™A™™™™™éëëžî¾ëîîîëî¾»´¾ë»´ë»»ä»›»´¹™)’™™ò/™)ÿÝ‘)ßÝòßÝòݪÒ­*‰¨"‘™™w—™yæ—™wg—ygv™yæv™yfw™™w—™™™™™™™™•™™™™™•™™Y•IiY””$Y™$"™¹"ÒI$ ¹™™™I›™™DD»D"BD"""""Ð "Ј �ÐÐÐЙ™™™I”™™D”›™"²™™""›” -B”ÐÐB™ B™™™™™™)™™"™™"™)™"")""""!""!!"!!!!"!""!"ffafafffafffafffafffafq™™™q—™™qw™™qw™™qv—™qww™qwv—qwvwD´´´´´D´D´´´´´´´ÿÿÿÿúñ*ñ*òñ*!ñ*áñ*þÚÝÝí™™»»‘B‘!DD‘±™±!™AA™A‘™™™™™™™‰ˆ™™èØ™‰øØ‰(þÒØ(ßÒÝÝÒÝ�™™»»‘²‘DD‘™™™!™™A™™A™Iaa›²gg޲vvŽ""‚ˆAD´AD´™™‘™™™™ˆ˜™™�Ž™™��˜™--ý‚�-Ý�ÝØ�ÝýÿØÿÝÿØýýýØßÝÝØÝªª¡ª!¢!"""™$"й$ ¹$ÒØ¹$" ¹D"ÐYEB ™E"Ø™E" Ð � ÐÝÐÐÝÝ� �€ÐÐÐŒ"” -”ÐÐ ” �"”ØÐ"” B›ÐÐB› B›™™™™™™™™)"™!)!!"""!"!"!"B"!!±B±"!´±B»±!D»±""!"fvbf""bfffbffwbw""!"ffbfwwrwq™™™q–™™qv™™aw—™qvg™qgg—qwvwqwgw´´´´´´DDD´D´´D´DK±K±K±K±K±K±D±K±D±K±D¹DµD•TµU•Y™’™™)’™)""™)™)’’™Y%’™Y""™)™)’’™™)�ˆˆˆ!"ª"ˆ"‚-Ñ„ˆ»ID´»ˆˆˆˆªªªª""ˆ""‚-"Ñ»„ˆ™ID´ˆˆˆˆªªªª"ˆ""Ò("�"ˆ!H»KD”™ˆˆ�؈¡ª"!"ˆ"!Ò(!�»ˆ!H»KD”ÐÐÐР݀€ÐÐ ÐÐÐ@ �”ÐÐД ”™I""™I$"™”D"™›ID¹™YDI™™U™™”™™™™™ÐÐÐÐ$- """""""$$"DDD»›™™™™™™™™™ØØB™ -B™Ð"’™"™I””™T•I”•™™”•™™™™Iߨ�ÝÝÝøØØÝÝ݈ÝÝÝ+ØýعØ��¹‚ÝÝ™‹ÝÝ""""DBDBDK²´K´´K´´K´´KDqvvvwvg$qfwgw$qvKw»$q»Dqwgwaggwqvgwqggvqvvgqwgwqwvvqwvgÿÿÿÿúñ*ñ*òñ*!ñ*áñ*þÚÝÝíK´»DK±K-!¾K½±¾D-!¾DAD»»K”D™I™™»»B!DDA™K™!K™±D™‘D™‘™‘!´!´A»B»A»D»A»D´A´D´A”D™™™™™™™™™™™™™™™™™™R™‘å™!žY™Qåž™™™™™™™™™™™™‘éî^îéYU™™•™î™™™™™™™™™™™™™™™™™™™™™™™.‘™™U‘™™ÐЀ” ��”ÐÐÐH �ˆˆÐÐÐ ÐÐØ –IÐЙD DˆÐ�ˆ ˆÐÐÐ ÐÐÐÐ � ¹¹¹™™»›™›¹™›»¹¹›¹»»™™»›™™¹™™™¹™™ÝÝÝÝݽ‹»Ý½AAOKAý´‹»ÝO$DÝýÿÿÝÝÝݸÛÝݱÝÝD´ØÝD´ØÝ¸KØÝB„ÝÝÿßÝÝÝÝÝ^ÑÝÝqÝFDѪØ-ˆ(ßýÿßÝÝÝÝÝ’™™‘™™™‘™ªš™‘ÿ™‘ÿ™!™+Ý+½+í+í+í-í+Ý+í+Ý+í-í+¾-í+½+½+½™™™™™¹™™™¹™™¹¹¹™INN™™´”™›I™›´N¾”™™™î‘åž!‘U™‘™îQéî•™!™A™™™U™‘’Y!Q"UQU™!•™RU!™A™™Y•‘™™™Q™•™QUU™!UUUUQU™"™™‘™™™U™™™™™Y™™™U™YUUUUUQU"™‘™™™™™™‘™•Y‘™UU‘™U%‘™Q™™‘™™‘™™™™™!‘!‘KK»$»»D»»D»KDKKDKDDDD”I™DD”DDô_ªDôÿ¯D„ÿ*D´±DD»KD™™I™"’™™D$’™DD”™DD”™DD™™””™¹™™™™»»K»»»»»»K»»»»ë鴻랻´éž»»ž™»»ž™»»K»»»»K»»»»¾»»»é¾´»™îN»™™¾»™™¾»™f™–™™i™––™™™™ii–™–—i™iw™™–wi™yG™f™–™™i™––™™™—giv—wywGwwwtwGwwww™f™–™™i™––™™™™ii™™–™y™i™yy–™w™™i™™™™žI™™žI™žîI›ž¾K´¾ë»´ë›»ä¹››´¹™™‘UQ™™™™™ÿÿ™ùÿ"’ÿ/!!úÿ"¢ªÿÿª©ªªš™!!™™™´K‘´KA´KA$BA""!!A‘™™™î‘å^!‘UU‘™îQéîUU!™A™™™™î‘å^!‘UU‘™îQéîUU!™A™™›™™™™)"™)BD™IDD™IDD™™DD”™II™™™™DDDDDU”IDDEDDªõODúÿOD¢ÿHDKD´»DIDD”™DD™™™”™™™™™I™™™™¹™™™™™™™™™™»»ž™»äž™»»î™»»ëž»»»î»»»»K»»»»»»»™é¾»™é»»™î»»î»»»¾»»´»»»»»»»»»´»»™fyw™™™w––wG™™yw–™—wi™ww™™yti™wG´»»»»´»K»K»»»»»»´»´»»»K»»»»»»K»»Gy™–wti™w—™™wyiitw–™G—i™ww–™G—™i™™™™™´™™A´™D´D´±»K´±»K´±»D´™™™K‘™™K™™KD‘™KDK´»K´»KD»DDDD•I”NRU”N$"™DD$IDD»»DDëîDIDD™‘™™™™™y‘Qç‘™u‘™a™–‘‘™™™™™™™™™™™™™™™™™™™™™™™é™™‘™™™a'™™™™™™™™™™™™‘™™î‘™îî™î–™‘™™™‘™Ý�™ÿŸ™ÿ»û ÿ¾û ÿîû ™ÿ™ÿ™—Y·™™yuw™W™™W•™™yu™™W™™—™™™»™y™IDD”™DD™™™™™™™™™™™™™™™™™™™I™™™™™™™™™™™±™™™A™™™A™™™A™”™A™™™A™™™‘™ù™ñ‘_™Q•ù™ñ™_™‘Q•™™™™™™™™™™™™”™™™™™™™™™™™™™™™™™™™™™f™w™™yw––™—™™™i–™–™i™i™™™–™i™™iwwtGGwwwt——w—ywy–™–™i™i™™™–™i™™itg™–w™i™——™™™™ii–™–™i™i™™™–™i™™i±KDADD�ADAD!‚"""ˆDˆDAD´DD�AD�D("""‘�Dˆ‘�Dˆ‘™™™™™™™™™™™™™™™™™™™™™‘™™‘!"¹‘¹™™™™™™™aV™™‘™á™áîîž™™™â™é‘"î.™™g‘™™f‘™YU‘QU™"‘™A‘™"A‘™’I‘™™Y™™™%‘™U‘™™™™™™™™™™YU™™™™™»™™™™D™™±™™±!™™AA™™A™‘™‘!´!´A»B»A»D»A»D´A´D´@”D™ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ33333333333333333333333333333333òÿ)ˆ�()��!2<©¡™Ÿ™Ÿ™™™™îîëîîëëîî¾ëîîîëî¾»´¾ë»´ë»»ä»»»´»‘™U•™™™Q•™™QU™™RUU"!™A™™A™‘™™™™Y™™U™™%™™‘™™‘™™™™™™™éî»›NDD´IÌÌ”ÉÅ\œ9Ã6—învìîflj˜i’™»»™îîîîùÿÿŸÉÁœ9ó?“"ò,òÁ)’‘""""""""""""""""""""""""""""""""ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»™™™™™ÿÿ™)"ÿŸòÿ*"ÿ¯ªÿÿª©ªªš™™™™™™™î™™N¾™™I”™™™™™™™™éž™éä›™™D™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™ž™™é™™™™™éž™™™›™™™™¹™™™™™™f™–™™i™––™™™™ii–™–™i™i™™™–™i™™iîîîî¾îîë¾ë¾ë¾¾ëë¾îîë¾îîë¾îîë¾îîëwwwwwîîwçww~çww~çww~çww~wîîwwwwwÝÝÝÝ}wwÝ}Ý}Ý}wwÝ}Ý×Ý}Ý}Ý}Ý}ÝÝÝÝÝ»»»»»Ýݻۻ»½Û»»»Û»Û½Û»»½»ÝÝ»»»»»îîîîî»»î¾îîë¾îîî¾î¾ë¾îîëî»»îîîîîàff"ž~w'ãq'Å\1cÆl60ÝÓ-€ˆˆ"€€!!!!™)™’™f™–™én™–æž™™éni–™–™ién™™éž™iéži™f™–™én™–æž™™éìé–™îéi™i™™™–™i™™i™™™™™™™™™™™™wùÿywùÿy™™™™™™™™™™™™îéžîž™ié™–™™ž™iéž™–éi™i™ž™–éîéžî™™™™�™™™�ÝÝÝ�ˆˆˆ�("‚�""�!!™™™™™™™ØÝÝÝØˆˆˆØ("‚Ø""Ø!Ø!»™¹»»»»»D»KD™™»»™»»»´D´D»»»»¹»™»»›™»»»»»D´»D»»™™»»»™DKDK»»»»»™»›»´K»»´K»¹»K»¹´»›»´¹›»´¹›»›I»¹”I»ww™™wy™™ww™™w™™™wy——™y——™y——™™w—yw™™w™™™yw™™w—™™™y——™y——™yw—™y——f™™–f™i™f™™™ff™™™™f™ii––™i–f™™f™i–™™fii™fi™™i–––™™f–i™f™™™––i™™i™f™–™én™™éž™fénififi™ùŸ™™ùŸ™iùŸiÐÝÝÝðÿÿ�ðÿÿ�€ø�ˆ˜‰˜‰""""™ii™––™™™™ii™™înié잙枖™™™i–éž™–™™–™i™™™–™–žî™ižÎž™™éni™æž™i™f™™éži–™™™ién™éΞ–æî™™––™™™™ii™––™Ð ÐÝðð�ðð�ðð��)’‰�™™‰ """ """Ð ÐÝð�ð�ðÿò�ðÿÿ��‰™‰�‰˜‰ """  "wp€wög€wwgxw gb`»»» »»» »3#3¼3̼øˆ"ȈˆˆÐÝÝÝðÿÿ�ðñ��™™‰�‰˜‰�‰˜‰ """  "ÐÝÝÝðÿÿ�ðð��™™�‰˜‰�‰˜‰ """  "Ð ÐÝð€�ð/ò�ðÿÿ��™™‰�‰˜‰  "  "ÐÝÝÝðÿÿ�ð�ˆˆðÿ��‰ˆˆ�™™‰ """ """ÐÝ ð�ð�ð�ˆˆp‡ˆˆpww‡ """ """ÐÝÝÝðÿÿ�ðð�ðð�p'r‡pww‡ """ """Ð ÐÝðð�ðð�ð/ò�€wwˆ€xgˆ"bbÐ Ð�ðð�ðð�ð/ò��™™‰�‰˜‰  "  "»¸‹»°aaaa`dfff–™i™–i™™–™ii–™–™f™i™–™–™f™™iûàff~ffpffpgvÀww Üww̓x‡8  àff~ffpfvpgw7Àw×ÌÌwˆ ƒ'"àff~ffpgfswvÌ}w ÀˆwÌ "r8àffþ~wàqÅ\ÀÌÌ Ü=Ó̓ˆˆ8  àffþ~wàqÅ\3ÌÌ #Ò=�8àffþ~wàqÅ\ÀÌÌ30Ó-20ƒffpwwpqwÀwÀÌs݃ȃ"ffpwwpqwÀwwÀÅ\1cÆl6Ø=Ý‚ˆˆàffž~wãqÅ\1cÆl60ÝÓ�€ˆˆ( àff~ffpffsgv7|wwÇÐww €x‡  àff~ffpfvsgw7Üw×Ì€wˆ €'"àff~ffpgfswv7Ì}wÍÀˆw "ràffþ~wàqÅ\0ÌÌ0=ÓÀŒÈ € àffþ~wàqÅ\0ÌÌ0=ÓÀŒÈ àffþ~wàqÅ\0ÌÌ0=ÓÀŒÈ ffpwwpqwÀwÀÌ3<Ó�"‚‚!ffpwwpqwÀwÀÌ|<Óx ‚ˆ"€ffpwwpqwÀwÀÌÌ<Ó�"ˆ�fnpçïpwpwQ pÌÌ pØ=Ãp("€(fnpçïpwpwQ pÇÌ p‡=Ãpˆ("fnpçïpwpwQ pÌÌ pØ=Ãpˆ"!àff~ffpffsgv7|wwÇÐww €x‡  àff~ffpffsgv7|wwÇÐww €x‡  ffpwwpqwÀ|ÀfsÝsˆ((fnpçïpwpÇQ p7f p7Ýp‚ˆ�‚°» °»»»°»»»°»» À»» ÿòÿ,"Á °» °»»»°»»»°»»;À»»ÿÿò#"°» °»»»°»»»³»» ÿ»» ðñ/ÿ"2°» °»»»°3»»À8ƒ ÀÌÌ ÿòÿ,"Á °» °»»»°3»»À8ƒ ÿÌÌ #ò?!2°» °»»»°3»»À8ƒ ÀÌÌÿ0ó/20#°» »»»»»»À8³ÀÌ3/°» »»» »»» À8³ ÀÌ< òÏ0"°» »»»»»»À8³ÀÌ3/°» »»»»3³;ƒ 3Ì ñòÁ,!!°» °»»»°»»»°;ƒ °ÃÌ 0ü/0"!°» »»»»3³;ƒ 3Ì ñòÁ,!!`Çbvü bvÇ fwb àî» NDD´@ÌÌÀÅ\ 0Ã<îî¾ëìî»Ë€ àî» NDD´@ÌÌÀÅ\ pÇ|îî¾ëìî»Ë€ àî» NDD´@ÌÌÀÅ\ 0Ã<îîv»ìîfË€ àî» NDD´@ÌÌÀÅ\ 0Ã6învìîfÇ€`àî» NDD´@ÌÌÀÅ\ 0Ã<îîv»ìîfË€ àî» NDD´@ÌÌÀÅ\ 0Ã6învìîfÇ€`úÿ¨ÿªÿ¨úúú¨¯ªª¨ªªª¨ª!"!"""¡!ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆxwîˆç~î~î~ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆw‡ˆˆwwˆˆww‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆxwîˆç~î~î~ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆw‡ˆˆwwˆˆww‡ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆèˆˆˆèˆˆˆˆˆˆˆˆˆˆˆˆèîîwxÿnwîÿîw¾kîn»fænfvgfwgvwwQcwwwˆwww‡www‡wwwwwwwwwvwwgqvw6wwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆèˆˆˆèˆˆˆˆˆˆˆˆˆˆˆˆèîîwxÿnwîÿîw¾kîn»fænfvgfwgvwwQcwwwˆwww‡www‡wwwwwwwwwvwwgwqw6wwˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆØˆˆˆÒxwÇÌvÇÌ(vÁw11733ÁÌÌ3ÌÏÌ<ÌÌÌÌÌ|w‡Ì|g�qg‚aw�33s3ÌÌÃÌüÌÌÌÌ̈ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ�ˆˆˆ-ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆØˆˆˆÒˆˆ(‚xwfÌ(vÇÌw11731ÁÌÌ3ÌÏÌ<ÌÌÌÌÍÌÌÌÌfw‡Ì|g‚aw�3s3ÌÌÃÌüÌÌÌÌÌÌÌÌ܈ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ�ˆˆˆ-ˆˆˆ(‚ˆˆˆˆ(‚ˆˆ(‚ˆˆ("ˆˆˆ"ˆˆˆˆˆˆˆˆˆˆˆˆˆÍÌÌÌØÝÌ<ˆˆ(‚ˆ""""!"ÌÌÌÜÃÌÝ�!‚ˆˆ"ˆ(""""�(‚ˆˆ(‚ˆˆ"‚ˆˆ"ˆˆˆˆˆˆˆˆˆ�ˆˆˆˆˆˆˆˆˆ(‚ˆˆ("ˆˆˆ"ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆØÝÌ<ˆˆ(‚ˆ""""!"ˆ""ÃÌÝ�!‚ˆˆ"ˆ(""""�""ˆ(‚ˆˆ"‚ˆˆ"ˆˆˆˆˆˆˆˆˆ�ˆˆˆˆˆˆˆˆˆˆˆàþÿàþÿîÿÿÿîÿÿÿîþÿÿîþÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿððððÿþÿÿþÿÿàÿÿþàPpppppðûðppp¿ðpppîîÿÿàîÿÿîþÿàîÿîþàîîàÿÿÿÿÿÿÿÿÿÿÿÿðÿþÿÿþÿÿàÿÿþàððþÿàÿàÿÿþàPpppppðûðppp¿ðpppwwpppwwpwqpwpwwðÿÿÿÿÀ ðo÷ÿÿÀ ÿÿðo÷ðoöðÿÿÀoö ÌÌðÿÿÿvwÿÿfwÿÿfvÿÿoöÿüÿÿÏÌoöÌÀÌÌ ðÿÿ0ÿÿó?0€‚ƒBCDrsrsbcRS’“QRST‚ƒBCDBCD‚ƒ@ )+,]]]]]]]]]]]]@ BC@ rsbdQ’“RSTRST’“"££"*:;c ]]]]]]]]]]]]""RS@ ££@ BC‚ƒSPc"££@ K.±.ars@ ]]]]]]]]]]]]@ @ rs…Q"£££"RSrst’“@ˆ @ "rs"£‚ƒ]]]]]]]]]]]]"£@ ‚ƒQQrs"!¶##£##"c‚ƒ„Q@ˆ rs""‚ƒ"BCD’“ ]]]]]]]]]]]]BC@ ££££££"’“QQ‚ƒ"12¹###"’“”QQQ£@ˆ "‚ƒ@ "’“""£RST£@ ]]]]]]]RS"££"d’“#rsQQQ"]@ ’“@ £££""$c£££]]]]]]]rsQQ"£"#$cBC"##@ ###"‚ƒQQ""]"£@ "PdS"£"¸¹¹¸¹34£!˜]]]]]]]‚ƒQQ"££££"¸¹¸34RS"#####"’“Q""]"£"@ c£ rs12¸¹¸¹¸¹¹’“Qc"£ "ºPc@ £££cBCD"]"@ˆ P"££££"d‚ƒ£]]]]]]]PBCD"£@ "ºP"##"efffW£‘$"rsRST@] @U P"P££££"dQrsBCD’“@£]]]]]]]RST"£££"ºBCD"##@ efffW@ ¹34"‚ƒQQQ@ˆ BCDQQQP@ "Q‚ƒdRSTd£]]]]]]]&'(Pc@ @ ºRST"£"#efffW#£"’“QQQrs""RSTQQQBC@ Q’“b @ 678######ºPc@ #efffW#@ cQQ‚ƒ@ˆ arsQQQRSdQdPP######¸¹¸¹mn@ vgv@ QQ’“‚ƒQdSbcBCD@ #########}~BCBCDS’“QBCDRST#########BCCRSRSTdSRST’“rsBCpppppppppppppppppp"BCRSRrsbc@U ccccccbQQQQrsBCBC‚ƒººRSBCpppppppppppppppppW"RScB‚ƒ@ @ £BC@ £££ccQQQ‚ƒRSº cRS @ c<R’“"@£RS""£@ €@ QQQ’“ d ¸¸¸¸ mn"BC*::;c"———————"rsc""£"BCD�££"Qº}~¡"£RS<@ žžžžž—————@ ‚ƒPP"@ RST"££@  cc@ € ¡"£c*----;"žžžžžžžž———————"£’“£""££rs@ ££"c �">.±±.>"žžžžžžžžž—————"£"£""‚ƒ"@ £"@ BC ¸¡"££$B"žŸ��žŸžž——————"&'(PP"££"££’“"£££££££££"@ RS"£¹¸¹34R"�œŸ�Ÿœž—"678PP@ £@ @ ££""@ "rsc'E˜@ ££!¶@A"�œŽ�Žœ�———————""@ £"BCD‚ƒº@'''E12¸¹"�������——————"ðñòóôò¯õö÷üüüüüüüüüüüüüüüüüüüü@ @ ""BCD"£@ RST’“dc  $'''''(£@A"�����———————"üÛüüüüüüüúüüüüüüüüüüüüüüüüüüüüPQPPP@ "££RSTQQQ"££££"mnQd@ ¸¸¸c34'579'(@ œœ›œ���ŒŸŒŒ——————@ øÕÖÀØüüüüüüüüüüüüüüüüüüüüüüüüüQBCP"BCDQQQQQQ@ }~cc ¹¹@ 5869E"œœœ›œœœŒŒŸŒŒŒ——————"Ûüüüúüüüüüüüüü×üüüüüüüüüüüüüüBCDPPPRSPQPPQ"@ RSTQrsefVW'c ¹¹¹¹ ¸ (P&'E"œœœ››››ŸŸŸŒŒŒ@ üüüüüüüüüüüüüüüüüüüüüüüüüüüüüRSTcPPQQQ@ Q‚ƒQcefVW'' ‚BCDBCEF'''''''''EBCrs œœœ››››ŸŸŸŒŒŒ@ üüüüüüüüüüüüüüüüüüüüüüüüüüüüüüQ’“efVW'''cºRSTS''EF'''''''''''''ERS‚ƒœœœ››››ŸŸŸŒŒŒ QQQQF''''''''''''''''''']]]]]]]]]]]]]]]]bc’“ @AAAAAAAAA rsBCDF''''''579''''''''HI']]]]]]]@ cbc#"rs"##"""‚ƒRSTF''577778&''''''''''']]]]M]]efVW"##"@ ‚ƒBCD""£#"’“QF''58&''''''''''']M]]]]]£!¶efVW""""’“RST"#$"##£#!¶""BCDF'''(####677779'''''']]]]]@A £@ #12¹#efVW@ ####""@ BCD¸¹¸¹¸34£###12¹@ "RSTF'''''(#####69''''']]M]]"££##efVWKb"""&''("RST"#&'577778###&''''']]]]]"£££@A efVW@ @ @ "677"QcQQ####P"F'(######cc#&''''']]]]]"efVW"@ """"""#QQ####@ " &''E#####c#c#####69'''']]]M]"BCDrsefVW""@ "@ ""QQ@ ¸¹&'''(#cc#####&'''']M]]]"@ RST‚ƒefVW""BCD@ """$@ mn 69''(###F'''']]]]]"£££’“efVW""RST&J("¨rs"£ 34"}~69'E#####&''''''''']]]]]"£)+,bdSgg""QQ@ F'(@ ‚ƒ"@ ""rsefV&''E####&'''''5779]]]M]"£*:;"""&''58"¥§’“"£ #@ "‚ƒefV&''''''J(F'''578&]M]]]"££>±>rsrs@ rs"6778@ "£@ BCD@ ’“efVQrs69''''''(F''J'(#&]]]]]@ ‚ƒ‚ƒeppppW‚ƒ"@ ¦©@ RSTQQefV‚ƒ&5779''EF'''''''''EF]]]]]]]]]]]]@ ’“’“eppppW’“@ QcefV’“&(&'''''''''''''''EF'BCRSCC&'(BC<<rs@ BCAA mnrs@ @ rsrsc S&'ERS*:;<‚ƒ"@ RS]]]]]]]]]]]]QQQQ}~‚ƒ@ @ Q@ @ ‚ƒ‚ƒ@ @  c&''(˜BCD*::--::;BC’“BCD""QQ]]]]]]]]]]]]QQQ’“QQ""rsQ"@ Q’“’“@ @ C&HIERST-------RScRST"P P "]]]]]]]]]]]]@ cBCDcQQ""‚ƒQ@A @ Q"@ @ "¡c69'58rs".>..±..>."BC"£"rs]]]]]]]]]]@ "rsRSTQQ"@A "’“Q"!¶@ Q"@ "@ ac&'(‚ƒ"##"RScQ&'(Q*:;QQ"££££"‚ƒ]]]]]]]]]@ ‚ƒQ"P"@A 12¹¹‘$"Q"@ @ "@ C&58’“"ºº"QQQQ678Q>>QQ"P@ ’“]]]]]]]]]" ’“QQQBCD""P"¹34"Q@ #"rs $@Sc&(@ @ ¡"££"]]]]]]]]]""@ QQQRST""P"£££££££Q@ "‚ƒ"¸34¸¸¸¸¸¸¸¸c&("¸¹¹#££#¹¹¹"@ ££@ ]]]]]]]]]""!¶"QQQQQBCQ@ "P ""Q #"’“"@F(""€ @  @ £]]BCD]]]]]]]]]"12¸¹"QQQQRSQ"@A  "££"Q!¶@ @ @ mnrs&'("¸¹¹#£££#¹¹¹"rs�]]]]]"£££££]]RST]]]]]]]]]@ @ QQQQQ"£££££‘£@ Q¸¸¸¸¸¸¸¸¸12¹¹"""}~‚ƒ&'(@ @ ‚ƒ]]]]]@ @ £@ ]QQ]]]]]]]]]]@ rsQ@ £"QQ @ "’“69(""QQQQ’“]]]]]]]]]""]]]]]]]]]]]]]]]]]]]]‚ƒQQ"@A QBCrs""BCD&E"£##£"QQQQQQ]]]]]]]]]@ ]]]]]]]]]]]]]]]]]]]]’“BCDQ@ £@ QQQRS‚ƒBCD"@ RSTBC69(@ QQQQQc]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]RSTc@A rsQQQQQQ’“RST@ cRSc&EQc]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]QQQQ‚ƒQQQQcc&'EbcBCRS’“]]]]]]]ºRSBCBCBCDRSBCDQQ--Qcrs]]]]]]ºpppWccºRSRST@ QQQcRSTQQQQ--<QQQQQBC‚ƒ]]]]]ºpppWrscccºQcQcQQrsQQQcQQQc*::;QQRQcRS’“]]]]]ºpppW‚ƒcrsº@ mn‚ƒQQQQQQQ>±±>cQQQQ]]]]]]]ºpppW’“‚ƒºcQ‘‘@ }~¡@ Qc’“QQQcQ@ "QQQQQ@ @ ]]]]]]]ºpppW##’“ºQQ‘‘‘@ @ "QQQQQQQQQcQ@ £@ QQQQQ¹¹"@ "]]]]rsºpppW###@ #!¶º!‘‘‘‘@ QQBCDVWefVW"  $QQQc"»¼"mnQQQBCD]]]]‚ƒºpppW#12¸¹¸¹¸¸ ¸12¸¹¸¹‘‘‘‘"RSTVWefVW"¸¸34!KQQ"´´´´"}~@ cRST""]]]]’“ºpppW"Q‘‘‘‘‘"VWefVW"12¸¸¸¸¸¸¸""eppc@"]]]]]]]ºpppWQ‘‘"rsVWefVWQQ@ @ eppcc@ ]]]]]]ºpppW@ BCDQ"@ ‚ƒmnVWefVW@ QQQQQ@ @ QeppcBCD@ ]rs]]]ºpppWrsRST"@ ’“@}~VWefVWBCDQQQQBCD@ Q˜eppRSTBC]‚ƒ]]]ºpppW‚ƒBCrsBCcrs@ @ QgggQRSTcQQRSTrsºeppcRS]’“]]]ºpppW’“BCDRS‚ƒRS‚ƒ@ QQQQ@ QQQQQQQQQQ‚ƒº@ rsc]]]]]]]ºpppWRST’“cc’“BCDQQQQQQQQQccc’“º‚ƒ]]]]]]]ºpppWQQRST&'(ºc’“pppWQQQc678BCBCD‚ƒppppppppppBCrs‚BCrsRSBCRST’"ppppRSRC‚ƒS@ BC‚ƒcRSrsQQQQ"pp++pprsQQPcPS’“@ £££@ S’“c@ ‚ƒ"@A++<pp‚ƒQQQPdScS"£££"c@ @ “@ ++< ’“QBBC@ ££@  ¹¹"@ rsS]"++<@ QRRSBCD@ @ £"¹""€@A‚ƒ]"*::;"]QQPcRST""rsrs"££@  ¹ !""�###’“]"=-"]QBC££££££££££$""‚ƒ€‚ƒ@ ·$ ¹¹ 12¹¹¹¹¹¹¸¸¸"####$QdS]">±±>"]QRS££££¸¸¸¸¸¸34""’“�’“"¸¸¸¸34¹¸¹ ""¸¹¸¹34rs]""]QQQQ£££££££££rs"@ @ SmnBCD""a###‚ƒ]######"]QQ‚ƒ@ ""}~RST@ @AQQQ’“@ @ ’“cc@@ @ @ ""'''''(@ @@rsBCc""'''''(BC@ rsF'''''‚ƒRS'HI''EdBCDmnRS‚ƒ&''''''’“c''''''JEPcRST}~BCDc’“&''''''&'''''''''''''''''''''('''''''''RST'bbdSbcBCrsRSBC HIKMNOOOOOOOOOOOOOOOOOOOOOOOOO/.-*+ * * **ð*à*à*à*ð**ð****-./////////ð++ *0* * *.///ð/à/Ð/Ð/Ð////////////////ð    ðààààð((((((''((((((((((((((((('''''Ðàð ;<>;::???????>>??>>>???>>?????5:>>;<=>????????????????>>????=<<ð<ð;ð:ð::::::::::::::::::::::::ððððð  àà <;9988888889:;=>>>>>>>>???????  @@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @ @ @              ! " # $ % & '  #p"P!0!              ƒ4ù`Œdù`ô€ dù`ù` dù`÷` d÷`õ`ù`ü`ù`ô`ü$ù`û` $÷`ù` $ù`ù` $ù`û`ö`û`$û`$ü`ü`$ü`ü`÷`÷`÷`÷`õ`õ`þ`õ`õ`õ`þ`õ`õ`õ`ù``õ`õ`ü`õ`ô`ô`ô`ô`ô`ô`ô`ô`ô`ô`ôAôáô¡ôáôAôáô¡ôáôAô�¡ôáôAôáô¡ôáô!ôáô¡ôáôAôáô¡ôáô¡ôáô¡ôáôAôáô¡ôáôATáô¡TáôAT�ô�TaôAT¡ô¡T¡ô¡T¡ôaTaôcöcøcù‚ôƒücùcÿcþcüc÷cøccþƒücþcôƒöcùƒüƒ ƒ÷ƒ ƒð÷ƒôƒþƒüƒôƒücùcôcücúcûcøcþCôcücûcúcücýcôc÷côcþccùbúb bþbô‚þbù‚ô‚ø‚õ‚ô‚õ$ü$û$ü$õ$þ$ü$þ$õ$ôDþ$ôDõ$õDôDDûbõbüBùbûbùb÷bú`ôcûCùCÿCþCþCüC÷CøCôcþCýCþCôc÷CúCüCùC÷Cúc÷côcþCüCôbüCùCôCüCûCûCù#þCôCüCûCùCûCüCþ#ôC÷Cô#þ#ôco¤�¤ž£Ÿ¤j¤Ž¤|ƒ•„¸„x„¸„8判L¤Þ¤8å�„q¨¤—¤…¤¸¤Š¤¬¤Þ„Ž¤Í„�¤ï¤ÇcùBûBüBþBô¢þ‚ù¢ô¢ø¢õ¢ô¢õ‚÷bùbûbû‚õ‚ ‚ù‚û‚ù‚ø‚õ`õ`þ`õ`õ`õ`þ`õ`õ`õ`ù`õ`õ`õ`ü`õ`ô`ô`ô`ô`ø@ø@ø@ø@ø`ø`ø`ø`ø@ø@ø@ø@÷`÷`÷`÷`õ`õ`õ`õ`ô`ô`õ`õ`ô`ô`õ`õ`ôATáô¡TáôAT¡ô¡T¡ôAT¡ô¡T¡ô¡T¡ô¡T¡õ¥ô¥õ¥ô¥ …ù…ü…ô…ù…ü…ø…ú…û…û…û…û…ü…ù…û…û…û…û…û…ý…ù…û…õ…ô…õ…ùFôfõfôfùFôfùfôfþFùfüfùfüFùfûFùFôFùFüFùFõFùFûFùFôFùFûFùFôFùFûFùFù@ù@ù@ù@ù@ù@ù@ù@þ@þ@þ@þ@þ@þ@þ@þ@õ`õ`õ`õ`õ`õ`õ`õ`ô`ô`ô`ô`ô`ô`ô`ô`ôeüeùeŒeôe‰eüeþeúeÚeºešeúeûeþeû¥Ûe»e›eûeûeþeô¥ö¥ô¥õ¥ô¥ù¥þ…‰¥ü…Ž…þ…ü…Œ…þ…ü…þ…ÿ…þ…ü…þ…ù…�…ô…‰…õ…„…ù………ù…ùFôfõfôfùFôfùfôfúFôFõFôFúFôFõFúFõFùFûFùFôFøFûFøFõFüFôFúFøFù@ù@ù@ù@ù@ù@ù@ù@ù@ù@ù@ù@ù@ù@ù@ù@õ`õ`õ`õ`ô`ô`ô`ô`õ`õ`õ`ø`ø`ø`ù`ù`ù`ù`™… "‰ �ó@‘4 ”4 ‘4 •u ˜” š¤›4 œuuþP$0�0ÎÀ?ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ªªªªªªªªªªªªªªªªªªªª¯¯ÿú¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯¯¯¯ÿúú¯¯¯¯ÿúú¯¯¯¯¯¯ÿú¯ÿú¯¯ÿú¯¯ÿúúúú¯¯¯¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿú¯ÿúú¯ÿúúúúúúú¯ÿú¯¯¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúªúúª¯ªúªªúª¯ªªªªúúªª¯ªª¯ª¯ªªªªªªª¯ªúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªªª¯ªúªª¯ªªªª¯úªªªªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªªªªªªÿÿÿÿÿÿÿ¯�¯úÿÿÿ¯ªúªªúªª¯�¯úøú¨úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªª�¯úøª�¯�úªªªªª¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯���ÿø¯ÿÿ¯ÿÿÿúø�ÿÿÿÿ�ÿøøøøøø�ÿ�¯ÿøÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�ÿø��ÿøø�ÿ��ÿø����ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªÿÿÿø�ÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�ÿÿÿÿÿÿÿÿÿÿ�ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿ�ÿøøÿø�ÿÿÿúÿÿÿÿÿÿÿÿÿÿªúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøø�ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿ����ÿÿÿÿÿ¯ÿ¨ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÿÿ��ÿøÿÿø�ÿ���¯ÿÿÿÿÿÿÿÿÿ¯¯¨¨úúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú��ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿ¯�ÿúÿøÿÿÿÿÿÿÿÿÿÿÿ¯¯*"""Búÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�ÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�ÿªªúªúªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÿÿÿÿÿÿÿ¯$DD"BDDD4úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿøÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿÿ¯�ÿªÿªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿøÿÿÿÿÿÿÿÿÿ¯$DDBD$$DDDBúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�ÿª¯�ÿªúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯JDDB$$$D"BDDôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�ÿªú¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯4DDDDDDDB$DCDüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÿÿÿ�ÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯¯J4>KDDDDDDDDD4¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿ¯øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿïìή$ãÌCDDDDDBDDD4Kúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿÿÿÿÿ¯ª¯¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊ>ÿ¾äÎîKDD´DKDKKDDC¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ªúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÿÿÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÊú¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïËÿ3´ì³³ÃüÿªªªªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏì¾»$(K»>CCD3CDCDDDDDBDôÿÿÿÿÿÿÿÿÿÿÿÿÿÏÏÌÏϬ£¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ3;;3;3;Ãüÿ:ª£ªªúÿÿÿÿÿÿÿÿÿÿÿÿú³K+B»ëãCCD334CDKDD´BD¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÌÌÌÏÏʪªÿÿÿÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿªªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌã33³3ã3ãÃÿ¯ªªªªÏúÿÿÿÿÿÿÿÿÿÿÿÿº´»´´K3CC43443BDDDD$D¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÌü¬üú¯¬£úªúÿÿÿÿÿÿÿÿÿÿÿ¯ÿÿ¯ªªúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌã3³³3³3;;ãÿ¯:ª£ªúüÿÿÿÿÿÿÿÿ¯¯ÿÿ¼»¾»»DK4D4CC43DDDD´DD3úÿÿÿÿÿÿÿÿÿÿÿÿüÌüüÿ¯ªªúªÿÿÿÿÿÿÿÿÿÿÿÿÿÿú¯ªªúÿÿÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú̳3³3>Ì3;333̯ªªª£ªªúÿÿÿÿÿÿÿÿ¯ÿúî³»»´KD4443C4CDDDDDDD4úÿÿÿÿÿÿÿÿÿÿÿÿ̯Ìü̯:ʪ¯úúÿÿ¯ÿÿÿÿÿÿÿÿÿÿ¯:ªªÿÿÿÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ̳³3;3ü>³³³³Ã¯ª£ªª£ªúÿÿÿÿÿÿÿÿÿÿÿãî¾³KDDDDDCDDDDDDKDDD4£ÿÿúÿÿÿÿÿÿÿÿÿÌÌÌÊüϪªªªªúªªúú¯ÿÿÏÌÌÿÿ¯ªªªÿÿÿÿúªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ3;3³3óÌÏ<;3;3ÿªª£ªª:ªªúÿÿÿÿÿÿÿÿÿîã¼DDDDDDDDDDDCDDDDDD44úÿÿÿÿÿÿÿÿÿÿÿÌÌÌÏÿ¯£ª£ª¬úʪªúÿÿÏÌÌÊÊÿ¯¬£:ªÿÿÿªúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿã3>;3ÌÌÏ<<;3>ÿ¯ªª¬ªªª£ÿÿÿÿÿÿÿÿÿÿÌÎ>KDDDDDDDDDD3DDDDDDDÃÿÿÿÿªÿÿÿÿÿÿÿÌÌÌüÿ¯ª£ªª:ʪ:ªÿÿÿÌÌÌÌ̯¯ªªªúÿúÿªªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ3;³ÃÌÎÌÃü<ã33ÿ¯ªª:ª£ªªúÿÿÿÿÿÿÿÿ¯ìì¼DDDDKKDDDD4D3CBDD@D4ÿÿ¯¯¯ÿªÿÿÿÿÿÌÌÌÌÌϪªª:ªª:ª£ª¯¯ÌÌÌÌÌ̪£:ªªúÿ¯ªªúÿÿÿÿÿÿÿÿúªÿúÿÿÿÿÿϳ3ËÌ<3Ì3ÃÌ<»3ü¯££ªªª£ªÿÿÿÿ¯úÿÿÿÿÏìCDD$BDDDDDDC34"$D´BD4úªªªÿ¯ªúÿªª¯ÌÌÌÌÌÌ:ª:ªªª¬ªªªÿª¬ÌÌÌ̬¬ªªª¬ú¯¯ªªÿÿÿ¯ÿÿÿúüúúúúÿÿÿÿÿÏ3;ã̼3ÿ3Ãü<3ãü¯ªªª£ªª£ÿúÿÿÿÿÿÿÿÿÏã¼DDD@DDDDD433BB3DDDDDªúúªªªªªúªªªÌÌÌÌÌÌÌÌÌÌÌÌÌ<¬¬ªÊÌ<ÌÃÌ̪ª£:ªª¬ª££ª¯ªªª¯ÿÿϪªªªªªªúÿÏ>3Ãì³ãÿã;Ã<;3着£ªªªªúúÿÿÿÿÿÿÿÿJDDDD+$DBDDD4ÃD<<ÌBD$D43«ªªª£ªªªªªªÌÃÌ<ÌÌÌÃ<ÌÌÃìÃÊÊ:<ÌÌÌÃÃ<£:ª::ª£ªªªªªª¯úªÊÊʪ£ªªªªªú?3;Ë33;ÿ3³Ã<³³Ã¯ª£ª::ªªªúÿÿÿÿÿÿÿ¯J#D´DD$$$´D3ÃÊ<Ì3BKDDD3:ª¬ªª£¬ª¬£ªÌÌÃÌÌÃÌÌÌÌÌÌÌÌÌ<ÌÌÌÌÃÌÌÌ̪ª:ªªªªªª£ªªÊªª¯£ü££ª:ʪªªÿì3³ÃÌ>3ÿ3;Ã<;3쪪:ªª:ªúúÿÿÿÿÿ¯ª¯CCDDDDBDB´D34ÌLD$"BDDD43ª£ª£ªªª£ª:ªÌÌÌÌÌÌÃÌÌ<ÌÌ<ÌÌÌ<ÌÌÌÌÌÌÌ<ÌÌÌÊÌÌÌÌÌÌÌÌÌʬªÌÌ:¬ªªªªªªÊ<³3ãÌ33ÿ³3μ3;ÎüϪªªªª:Êúÿÿÿÿÿ¯ªª¤*DKD$ " D33ÌìªÃî.²K»»K+"ÊÌÌÌ̯(¨ÌüÌϯ‚ƒ("‚ªˆ"ÌÌüÌÌ("ÌüÌüŒ³N³DDD$"¢¬ˆøÿ,Âüüü̯ˆ‚Ì,"Š"ªªúÿÿ¯úªª4JCB´DD23ÃÃÏÏÏÌÌ33#DD4DDD£ª£ª£ª£ª:::³Ã3£:Ê+²»KK»D"ªÿÌÏÿ¬(8ÿÌÏϬ"�(‚úˆ"üÿüüÿ("üÌüÏ�è³;DDDD"¢ÿˆøÿ/¢üÏÌϯˆ2ÿ,Â�"ªªÿÿÿ:»;£CCCDDBDD33ÃÌÌÏÏ<Ã3#D´CDDD££ª£ª£ª::ª£ë»>ë£:KB;33#""ÃÌ""̯(«Ì""üÏ‚ü*"¢ÿˆ"ü¬Šˆˆ(":*2üª83DDDD$"Âÿˆ¨Ì#ÂÏ,"¬ˆ‚ü*"Š"ú¬ÿÿ¯»»»3CCCDKDDD3<<ÌÏÏÌÏÌÌDD4DKKD¤£ªªªªª3»££»»»3®«.²;34#" ¨£$B££(ˆ3$B£Š‚ü?ˆøüˆ"̯ªˆ(""º(2Ê*8C"D$B$"Âüˆ"""¢ü*"¯(2ÿ,"¢�"Ìüÿÿ?»»»«:3DDDD$DÄÌÌüüüüÌÌL"D4DDDD43:ª³º;³¨º«»ë»»3:#²C34$""´3BBºƒ(D:B"£ˆB̬8È̈"ü¬Šˆ(""ƒD„«ƒ8CB3C"D"¢Ìˆ(""2Ï,"¢¬ˆ‚Ì,"Š"3øÿÿº»»»;:4CD´D$$ÄÌüÌÌÌÌüü<"DD#´DBD8;º3:³«3»»¾¾»»»ë+23<£#""„Dˆˆ„„(„Dˆˆ´‹"4´DK‹ˆ"´ˆˆˆˆ("„ˆˆDˆ8CD3CDB$B4ˆˆˆ(BD$"B4ˆ"ˆCD„ˆ"4£úÿ¿»»»;44CDD´D$4ÌÌÏÌÌüÌÏL²D4DDDDD;3³»»»»»»»»ë»»»»+‚¬¨H"""D„ˆˆDK(D„ˆˆ„DB„„ˆˆDˆ"HK„ˆˆ("Dˆˆ´„"BˆÊ3„#"BD„„„ˆBDDDD„(‚ˆHD„ˆ"33«ÿ?»»»»34DDDDDKDÄÏÌ33ÌÏ<$DD4+´D"D´»³»»»»»»3ë¾»»»»$‚ʈ("""HHˆˆ¸„(DKˆˆH„"´„ˆH„ˆ"D´HD„""¸ˆˆ„„"28ª:Š("BDDD„(BDDDDDˆ"ˆHD„("»»»úª»»»»ª>¾îîãîîëîîîîìîî+"ãÎîî¾î»»»»ë>ÌLCDDD+$"D4D$BDD$BDKDDÌÏÏÌ$ãÎîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîî¾$‚ˆB"ˆˆ(ˆˆ"Bˆˆ‚ˆ("‚ƒˆB¨ƒˆ88Bëîîîîîîîîîîîî. îîîîîî¾»»îîÌÌÌLBDDDD$@DHDD DDK$"D´DDÌÌüÌCäîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîî"‚ˆ""¨ˆ"ˆŠ""ˆŠ"¨("‚¨ˆ"ˆ¨¨¨ˆ"Îëë¾¾îîîîîîîî+"ëîîîîîî»ëîîÌÏÌLBDK´DDD4„ƒC"DDDBDDDDDÌüüÏ<²îîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîî""ªª(¨¨"ªŠ‚ª*"¢ªŠ"ªªªªª";$DK$´îîîîîîî."îîîîîîîîîîîüÌÏC@DDDDBBHKDDDDDDB@KKD„ÃÌÌÿ<"îîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîî¾"¢¬"Ê�(ʬ""ªŠ‚ÌŠ"¢¬ˆ‚ÌÏÌÏÌBKDDBDDëîîîîîî+ ëîîîîîîîîîÎÌüÌ,DDDDD$DD844DD´$BDDDDDÃÌüÌ<$ÎîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîÂÌ""ü¬(ÊÌ" ¬Š¢üŒ"¯ˆ‚üüÿü¯"+DDBD$ëîîîîîî."îîîîîîîîîî>üÌü,DDKDD$D4DHHDDD$+BDDDDÄÌÏüÌ"ëîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîî¾"¯""ü¯(ʯ""¯Š‚üÿ(¢ÿˆ"üÏÏÏÏ"‚DD43DäîîîîîîK"ëîîîîîîîîîËÌÌÌDD²DDDDDH3´4DDDDDBDDDDÃÌÌÌÌCäîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîî"¢Ï""Ì�HÊÏ""ÌŠ¢üüŒÊ¯ˆ"ªúü¯Š"‚DD43D²îîîîîî¾ëîîîîîîîîî¾ÃÌã³"BKHDKˆ(D´""4ˆB´ˆƒKƒˆ2‚ˆDƒ2ë+DCDD$ëîîîîîîîîîîîîîîîîîNÌ̾¾îëëëëîîî¾""ˆ""ÈÏÿÿÿÏüÌÌÌÌD4ÿüÌÏÌüüÏÿüÌÌ(ÈÌ̲îîî¾îîîî¾»»»»ëëëîë¾»»»»;>îîîî>³³³KK»»»î¾ëëîîîîîîîîîîîîîîë¾ë¾î¾BBëëî»î>êëî¾î¾îîëë¾N"((""ÂüüÿÿüÏÌÌÌÿLÄÌÏÏÌüÌÿÿÿÏÌ�"4ÃÌäëëëëîîîî¾¾»¾ã¾»ë»îî»îî¾KKK»»¾îî¾³»»»´»´»ëëë¾îëëîîîîîîîîîî¾¾îëîë¾¾BB»¾¾îëë¾îëëëëëëîîëN"ˆ"""ˆÌÏÏÏÿÌüÌÏÌCˆ(üÌüÌÏÏüüÌüŒ("Ê„²îîîîî»ë¾»»ëKë¾ëî»»¾¾»»¾´»´;4K»>»»»»K»K»»»î¾î¾¾îîîîîîîîîîîîîë¾¾¾¾¾+"ëîë¾î¾îëë¾îîîîëîî+‚ˆ"""ˆÊüüÿÌÏÏÌÌ*"""ÈüÌüÌüüÌüÌŒˆ"(‚´¾¾¾¾îî»»»3C;¾»»»»»Kë¾»»KK»´»»³´´´K»»K»K»ë»î»îë¾îîîîîîîîîîîîîî¾îëîKBëë¾îëë뾾¾¾¾¾î+‚(""‚ˆªÌÌÌÌÌ̬ˆˆ(‚‚ˆ¨ÌÏÌÌÌüÌÏŠˆ""‚²îëëëîî»»»³»»;´´´´D»´¾¾»´»K»KKK»KK»»»»K»»ë>3îë¾îëëëîîîîîîîîîîîî¾îë¾»ëëëë¾îîëîëîëëëîë£#‚ˆ""‚¨ˆªªÌϪ¨ˆ¨""""ˆˆ¨ÌüüüÌϬˆ(""ˆ²¾îëëîî»;;;;K»»K»»»K»´»K»´´»´´»»´»K»»»´»»î>ª¾îë¾î¾îëîîîîîîîîîîîîëëëî¾î¾îëë»î»îë¾îî»>:*ˆ(""‚ˆ¨ŠŠªŒˆˆˆˆˆˆ(ˆˆˆˆ¨ÌÌÌÌÌŒˆˆ""‚âëë»;î»»K»³K³´´´KKK»»»K»K;»»»KKK»D»K»´»»ë¾î³»¾îë¾îëîîîîîîîîîîîîîîî¾¾îëë¾î¾»¾îëë뾻룪#ˆ‚(""ˆˆˆŠŠˆˆˆˆˆ""""ˆˆˆˆ¨ªÊÊªŠŠ(""ˆ²ë¾»>»»»»4»»»K»K»´´´»»´´´´»»K»´´´»´»»»´»»¾ë³¾îë¾¾¾¾ëîîîîîîîîîîîîîëîëë¾¾îë뻾î뾾뻻33«ˆ("""ˆˆŠˆˆˆˆˆˆ("""""ˆˆˆˆˆ¨ŠŠ¨ˆ(""‚²»»»»»»´´»´´C»´´KK»K¾»»³K»´»»K»»»´K»»»»»»»´îë¾îëëëîîëîîîîîîîîîîîîîëîîëîëë¾»»ë¾¾»»»»»¾ƒˆ("""ˆˆˆˆˆˆˆˆˆ‚ˆˆ((("ˆˆˆˆˆŠªˆˆ(""‚²»»»¾»»K»´;»»KK»´´K´»³»»´»»K»´KKDK»K»»»»»N´Dëëë¾K¾¾¾î¾îîîîîîîîîîîîîî¾î»îî»»»îë¾»»»»»»«"("""‚ˆˆˆˆˆˆ‚"""""""""‚ˆˆˆˆˆˆ(""""²´»»»»K»´K»´D´´KK»´K»»»»»»»»»»´»»´»»K»»»ëK»´îî¾¾´ëë»ëîîîîîîîîîîîîîî¾K¾¾ë»»»»ë¾»Žˆ"""""‚ˆˆˆ(""""""""""""ˆˆˆˆˆˆ"""""B»»»´K»´K»´´»»K´´´K»´´»»»»»»´»»»»»»»»´´»»KD»¾ë»´´»K»»»îîîîîîîîîîîîîë¾»»ëK´KDD»KK»»»¾¾$"""""""(("‚"""""""""""""‚ˆˆ(("""""BDKKD»»KKKKKKK´K»K»KK»»»»»»»»»»»»»»»´»»»»NK»ë»»D»»KD´»ëîîîîîîîîîî´»D»KK´´´´»»»¾+‚"""""""""""""""""""""""""""""""""BDDDD´´»K»´K»´»»»»K»»K»»»»»»»»»»»»»»»´´»»DDDDDDDDDDK»»»ëîîîîîîî¾¾»»»»»»DD´D´DKDDK»»»»$‚""""""""""""""""""""""""""""""""""DKDD»KK»K»´KKK»»»»»»»»»»K»»»»»»»»»»K»»»KD´´DKKKD´´DD»»ëîîîîîîîî¾»»»»»»KKKDK´DKK´»»»»+ˆ""""""""""""""" """""""""""""""""´DDDK»´´»´»´»´´»»»»»»»»»»»»»»»»»»»»»´»»DDDDKDD´´DDKK»»»îîîîîîîî»»»»»»»KD´DDKDD»D»»»»+""""""""""""""""""""""""""""""""""BDDD»K»»»»»K´»»»»»»»»»»»K»»»»»»»»»»»»´K$DDDDK´DDKKDD»»»ëëîîîîî¾ë»»»»»»»´D´DDKK´»»¾»»$("""" """""""""""""""""""""""""""""BDDD»»KK»´K»»»»»»»»»»»»»»´»»»»»»»»»´»»KDDDKKDKDKDDDK»»»»»»îîîî»»»»»»»»KDDKDKDD»´ë»»»+("""" """""""""""""""""""" """""BDDD»»»»K»»K»»»»»»»»»»»»+D»»»»»»»»»»´»KDD´DDKDKDKKK´»»»»»»»»»»»»»»»»»D´KKDKDKKD»»»»»$""""""""""""""""""""" """"""""""BDDD»»»»»»»»»»»»»»»»»»»»KD»»»»»»»»K²»KDDDD´DDDDKDDD»»»»»»»»»»»»»»»»»»»KK´D´DD´D´ë»»»$""""B """""""""""""" "" """""""DDD»»»»»»»»»»»»»»»»»»»»KK»»»»»»»KDDKK´´´´D´DKKDDDD´»»»»»»»»»»»»»»»»»»»DD´D´´D´D»¾»»""""""°D""""" """""""""" """ """"""DDD»»»»»»»»»»»»»»»»»»»»»K´´»»»»»»DDDDKDDDDD´DDDKK´»»»»»»»»»»»»»»»»»»»KDKDDKD´DD´»¾K""""""´K""""""""""""""""""""""""""BDD»»»»»»»»»»»»»»»»»»»»»´DD´´»KDD´´´´DKKKKKDDK´DD»»»»»»»»»»»»»»»»»»»»KKDK´DKKDD´»»»"""""´»"""""""""""""""""""""""""""BDD»»»»»»»»»»»»»»»»»»»»»DKKDKD´´´DDKDKDDDDDKDDDD»´»»»»»»»»»»»»»»»»»»DD´´´DD»KKD´»»K""""" ³»$""""""""""""""""""""""""""""BDD»»»»»»»»»»»»»»»»»»»»»´DDKD´DDDKKDK´´´DKD´DDDD´»»»»»»»»»»»»»»»»»»»K»DDD´î»»KDD´»+""""""»»$"""""""""""""""""""  """"""BDDD»»»»»»»»K»»»»»»»»»´KD´´D´DKKKD´´DDDDDD´DDDD´»»»»»»»»»»»»»»»»»»»»´KK´DK»NKKDDD´‹""""""»»+"""""""""""""""""""""""""""($D´D»»»»»»»K´»»»»»»»KDDKKDKK´D´DKKD´´´´´´DDDD´»´»»»»»»»»»»»»»»»»»»»»KDK´´»»DDDDBD$""""""»K$""""""""""""""""""B" """""ˆD$D´»»»»»»»+´»»K´»»»DKKD´DD´D´D´DDKKDDDDDDDDDK»»»»»»»»»»»»»»»»»»»»»»KKDDK´»KDB@DK‚"""""B»+"""""""""""""""""""B$"""""""ˆ$D´DB»»»»»D´´»KD»»»DK´D´D´´D´D´D´´D´´´DDDDDD´»»»»»»»»»»»»»»»»»»»»»»»KDDKDK»KDDD´$"""""²»"""""""""""""""""""" DD"""""""‚DDBDD»»»»»K+D»D$$D"´DDDKKKKDKDKDKD´DDDDDDDD»»»»»»»»»»»»»»»»»»»»»»»»KDK´D´´»»DDDD$‚"""" B+""""""""""""""""""""DD""""‚(‚HD$DD»»»»»»DBD$$DDDKKDDDDKDKDKDKD´´DKKDD¾´»»»»»»»»»»»»»»»»»»»»»»»»DDK´DD»»»»DD"("""""°""""""""""""""""""""@DD$"""""ˆ‚CDH²D@´»»»D°DDD$D´DKKD´´´´D´´´´´´´DDDDDDDK´»»»»»»»»»»»»»»»»»»»»»»»»DKKDDKDD´»»DD„(""""B""""""""""""""""""""""DD"""""‚‚JD"D$DB´»»DDDB@BDDKDDKKDDDKKDDDDDDDDD´DKD»»»»»»»»»»»»»»»»»»»»»»»»»»KDDDD´´´D»´DB(""""" """"""""""""""""""""""$D$"""""(‚HDDDD$BDDD$DDDDDDDD´´DDKKKDD´´´´DDDDDD´´»»»»»»»»»K»»»»»»»»»»»»»»»»KD´DKKDDDDDDD$‚"""""" """""""""""""""""""""BD$"""""‚(HDDKDD$B@"DDDDDD´´´DD´´DDDKKKDDDDDDDD´K»´»»»»»K»»»»»»»»»»»»»»»»»»K´´DDDDK´DD$DD$"""""" """"""""""""""""""""""" DD """"ˆ(HDD´´DD$DD@D´´DDDDKKKKDDKKDDDDDDDDDDDD»»»»»»»»»»»»»»»»»»»»»»»»»»»KKDD´DKDDKDBD$"(""""""""""""""""""""""""""""DD$"""""(DD´DDDB@DBDDDKKKD´DDKKD´DDDDD"$DD´´»»»»»»»»»»»»»»»»»»»»»»»»»»»»DDKDDKDDKDDDBB$"""""" """"""""""""""""""""""""BD"""""((DDKDKDDDDD@BDDD´´DKKDDDDDDDDDDBDDK»K»»»»»»»»»»»»»»»»»»»»»»»»»»KDKDDDD´´DDD"$D (""""""""""""""""""""""""""""BD""""""(B$DKDDBB$$D$DD$D´DDDDDDDDDDDDDDDDD»»»´»»»»»»»»»»»»»»»»»»»»»»»»»KDKDDDDDDDD´DDDB"""""" ‚""""""""""""""""""""""""BD"""""‚(HDD´D$DDBBBB$BBBDDKK´DDDKDDD$D$DD»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»KKDKDDDD´DKDDDD$‚("""""Ã*"""""""""""""""""""""""BD"""""(H$DDKDBDD$$DBDBDDDDDDDDDDDD$DDDD»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»KDDDD$DDDDDDDDDD‚"""""Ã�"""""""""""""""""""""""BD$"""""(HDD´D$DBDBD@$$DDDDDDDDDDDDDD´»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»KDD$DBBBDDKDDDDD$"""""""̬"""""""""""""""""""""""BDD""""""H$DD´DDBD$D$DDBBDDDDDDDDDDD´»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»DKD$$DBDD´DD$DDD$"""""2"Ãÿ*"""""""""""""""""""""‚HDD""""""HBBDDDD$D$DBBDD$$DDDDDDDDDD´K»»»»»»»»»»»»»»»»»»»»»»»¾î¾K»»»»»´D´DDDB$BDDDD$BDD"""""ÃBÌ̯"""""""""""""""""""""‚ˆD"""""""HDBD´$$D@B"D$$BD@DDDDKKKK»»»»»»»»»»»»»»»»»»»»»»»»»»¾î¾»»»»»»»´DDDBDDDDDKDD$DD$""""2<"Ã̬("""""""""""""""""""‚ÿºDD""""""KB$DDDDBD$DDBDDD"DDKK»ä´»´»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»K»»»»DDDD$DDDDDKDDDBDD$"""B4Ã#Äü¬Š"""""""""""""""""""ø¯CBB$"""""HDDBDDDDD$D$B"BD$BD´´K¾´»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»DD»»»KD´´DDDDDDKDKDDD$D$"""‚4ÃL2ÌÌü("""""""""""""""""‚ú̃DD"""""CBBBDDDBDDD"D$D$DDDKK»»¾»»»»»»»»»»»»»»»»»»»»»»»»»»»»»KKD»»»DDDDDDDDDDDDDKDDDB""""B3Ì<"üÌÌŒ """""""""""""""‚ÊÏ$$$$"""""H$$DD$$D$$$$B$D$$BD»»»»´»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»KD´»KDDDDKDDDDDDDKDDD"D$"""„3Ã<"Â<Ã<"""""""""""""""¨ÊÌDB""""""DD$$BDBDB$DBD@BBBDD»»»»»»»»»»»»»»»»»»»»»»»»»»î»»»»»»»»KD»»´D$D´DDD´´DDKDDK$D$""""43ÃÌBÌ3Ì$ """""""""""""‚ÊÌÌ$DD"""""HBDD$$DD"$BDBD$$$DD»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»´»»$DDDDDBDDKDDDDDDDKDD$D‚"""„ÃÌÌ<Â<Ã," """""""""":ÌÌÃ"$$$"""""D$$"$$B@DB$D$$$DBDBD´»»»»»»»ëë»»»»»»»»»»»»»»»»»»»»KK»»»DDDDB$BDDDDDDDDDDDDDDB"(""B3ÃÃÏÌ#Bü3L"""" """"""""BÃÌ̃DBD$""""""DDBBBD@$DBB$$$D"$D»»»»»»»»»»¾¾»»»»»»»»»»»»»»»»»»»»»»KDD$"DBD"DDDDDDDDDDDD$DD"""B83ÌüÏL"Ì<3""""" "" ""2Ã<ÌD2$$$"""""DBBBDD$DBDBBB$$DBD´»»»»»»»»»»»»»»»»»»»»»»»»»»»K»»»»»»$DBD$D"DBDDDBBBBBDDBB$$(""433ÌÏÌ<"4<3$ """""" ""3Ìì$ÄDB$" """HDD"$$D$$D$DB$BB$DB»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»D$D"BBD$$DD"DB$$$DB$$BD("23£ÃüüÌC"43"""" """"""B<<ÃCBÌ$DB"""""H$B$$$D"DBBBBD$DDD´»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»K$DBD$DDB$$$DB$DBDD$DB$D<#"233ÌÏÏÏ<$"4D $""""""""233L"BÌCDD"""""DBBBB$$$D$$$DBBD»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»KD"$DBDD$$DD$$$$DDDD"DB²üÌ$D3ÌÌÌÌÌÏ<#"D $B"""""" DÌÌ#BÃüLBB" """BD$$D"D@BB@DB$DBD»»»»»»»»»»»»»»»»»»»»»»K»»»»»»»»»»»»»»»DDDDDDDBDDBDBBDDD$D$D4ÌÌD33ÌüüüÌÏ?"$$"""""@DÃÏ,"ÃÌÌL$D„""""CB5¹-- title: farmer lovhunt -- author: @librorumque ---replic auter MorPG -- desc: Stealth farming game made for LD41 -- script: lua -- saveid: lrqCauli1 ---translator: JennyCat(^-^) --[[ MIT LICENSE Make the farmers on the farm fall in love with you --[[ L10N ]]-- local strings = { greeting="PRESS A BUTTON", menuLocked="locked", menuContinue="CONTINUE", menuLevel="level", levelComplete={"You have won their hearts...and their harvest!", "Them are yours now...until the next harvest!", "Too fast for exes!"}, guard={"How many hearts do you need to break, huh?", "Was Farmer Dave worth this? Seriously", "Was I just...practice for you?", "You collect hearts like crops!"}, intros={ {"Welcome to the farm where romance is the deadliest crop of all! Press DOWN to scroll messages or Key A / Btn X to skip.", "Reset level with KEY X / BTN B. t Our goal is to have as many farmers fall in love with us we can."}, {"3...2...1...Bring him a heart!", "If you've made a mistake, press Key X / Btn B to restart the level."}, {"Love is the hammer that cracks every wall."}, {"No exes in sight...Let's plant some love seeds!"}, {"Danger! One ex is lurking...Don't let him catch you!", "Press Key Z / Btn A to see ex sight."}, {"OF COURSE your ex would just chill while you collect hearts like corn."}, {"love blinds exes."}, {"One wrong move and love turns into a chase!"}, {"This ex doesn't look like he's expecting us."}, {"This ex looks like he have noticed someone...Me?."}, {"That is not a scarecrow in the field...It is an ax!"}, {"Why don't we ask them for help?"}, {"They've set up a trap. Be carefull."}, {"Oh no, look! It's my ex - and he's right here!"}, {"Love is risky today."}, {"Are they having a lunch break or a secret meeting? Doesn't matter. Let's fall in love!"}, {"This should be easy."}, {"They've noticed you!", "Quick! Run on 3! 1... 2... 3!!"}, {"L-O-V-E."}, {"His stare could make crops grow.Be careful."}, {"I am the heart, I am the key."}, {"Mine ex's hobby? Ruining my love life."}, {"Ex alert!"}, {"People say love is blind...", "Reminder: Key Z / Btn A shows lines of view."}, {"Exes are like weeds - the more you ignore them, the faster they spread!"}, {"We're close to making everyone fall in love with us!"}, {"Time to end it! Quick, put hearts, and get out of there."}, {"The game is over...but love?", "Oh, love is always planting season. [THE END]"}, {"Thanks for playing!"}}} --[[ UTILS ]]-- -- random pick local function randpick(a) return a[math.random(#a)] end -- text helpers local approxcharw = 6 local function textwid(t) return print(t, 0, -10) end -- prints text with a shadow. bg=nil no shadow local function text(t, x, y, fg, bg) if bg then print(t, x, y + 1, bg) end--change shadow here return print(t, x, y, fg) end local function textwrap(str, px) local buf = {} local est = px // approxcharw local pos = est while textwid(str) > px do local l, r = textwid(string.sub(str, 1, pos)), textwid(string.sub(str, 1, pos + 1)) if l <= px then if r >= px then buf[#buf + 1] = string.sub(str, 1, pos) str = string.sub(str, pos + 1) pos = est else pos = pos + 1 end else pos = pos - 1 end end if #str > 0 then buf[#buf + 1] = str end return buf end -- prints centered text with a shadow local function title(t, y, fg, bg) local x = math.floor(120 - 0.5 * print(t, 0, -8)) return text(t, x, y, fg, bg) end -- linear transformation, takes 3 or 5 args local function lc(t, t1, t2, s1, s2) if s1 == nil then t1, t2, s1, s2 = 0, t1, 0, t2 end return s1 + (s2 - s1) * (t - t1) / (t2 - t1) end -- if function, call local function call(f, ...) if type(f) == "function" then return f(...) end end -- multi-table loop macro; preserves table order -- WARN key variable is the index in the acording table, **not the loop counter** local function _ialliter(tt, i) if not tt[1] then return nil end local v = tt[1][i + 1] if v == nil then table.remove(tt, 1) -- ok to destr, it's {...} return _ialliter(tt, 0) else return i + 1, v, tt[1] end end local function iall(...) return _ialliter, {...}, 0 end -- OOP helpers local function extend(t, Type) if Type then setmetatable(t, Type) t.Type = t t.Parent = Type end t.__index = t return t end local function new(Type, ...) local t = {} setmetatable(t, Type) call(t.constructor, t, ...) return t end -- sugar local Object = extend({}) function Object:constructor(...) call(self.Parent and self.Parent.constructor, self, ...) end function Object:with(vals) for k, v in pairs(vals) do self[k] = v end return self end function Object:is(T) return self.Type == T end Object.new = new function Object:extend(t) return extend(t, self) end local function _enumIter(e) return function(_, i) local l = e[i + 1] if l then return i + 1, l end end, nil, -1 end local function enum(vals) local t = {} for i, v in ipairs(vals) do t[i-1] = v t[v] = i - 1 end t.iter = _enumIter return t end -- memory layout local MEM_PALETTE = 0x03FC0 -- Button codes local K = enum{"UP", "DOWN", "LEFT", "RIGHT", "A", "B", "X", "Y"} -- WARN this check uses enum order function K.isDir(d) return d >= K.UP and d <= K.RIGHT end -- Direction util local D = enum{"UP", "DOWN", "LEFT", "RIGHT", "STOP", "GO"} function D.fromKey(k) return k end -- Get direction from deltas function D.ir (dx, dy) if dx == 0 then if dy > 0 then return D.DOWN end if dy < 0 then return D.UP end elseif dy == 0 then if dx > 0 then return D.RIGHT end if dx < 0 then return D.LEFT end else return nil end end -- Get deltas from direction function D.eltas(dir, scale) scale = scale or 1 if dir == D.UP then return 0, -scale elseif dir == D.DOWN then return 0, scale elseif dir == D.LEFT then return -scale, 0 elseif dir == D.RIGHT then return scale, 0 else return 0, 0 end end -- Opposite direction -- WARN hacky. Uses enum order function D.reverse (dir) return dir + 1 - (dir % 2) * 2 end local function xyToMap(x, y) return x // 8, y // 8 end --local function rectsOverlap(r1, r2) -- rect = {x y w h} -- -- F.IXME temp fix -- if r1.h2 then r1.h, r1.w = 2 * r1.h2, 2 * r1.w2 end -- if r2.h2 then r2.h, r2.w = 2 * r2.h2, 2 * r2.w2 end -- return (r2.x >= r1.x + r1.w) ~= (r2.x + r2.w >= r1.x) -- and (r2.y >= r1.y + r1.h) ~= (r2.y + r2.h >= r1.y) --end --[[ CLASSES ]]-- local Game, Clock, GameState, MapState, MenuState, ContinueState, DialogState, TransitionState, Piece, Player, Guard, Bucket, Bed, Plant, Door, Wall local game, Levels -- instances do -- main class Game = Object:extend{ player=nil, t=0, conKeys={}, checkedKeys={}, lastdbtn=-1, palette={}, nowplaying=-1, showGuardSight=false, -- DEBUG -- musicOn=true, stepByStep=false, debugRects={} } -- save cart palette into a variable for i = 0, 47 do Game.palette[i + 1] = peek(MEM_PALETTE + i) end function Game:constructor(initState) self.state = self:create(initState or GameState) end function Game:pollDBtn() if not btn(self.lastdbtn) then self.lastdbtn = -1 end for b in K:iter() do if K.isDir(b) and (btnp(b) or (self.lastdbtn == -1 and btn(b))) then self.lastdbtn = b end end end function Game:tint(f) local tr = f if type(f) == "number" then f = {f, f, f} end if type(f) == "table" then tr = function(r, g, b) return r * f[1], g * f[2], b * f[3] end end for col = 0,15 do local addr, pal = MEM_PALETTE + col * 3, self.palette local r, g, b = pal[col * 3 + 1], pal[col * 3 + 2], pal[col * 3 + 3] r, g, b = tr(r, g, b, col) poke(addr, r) poke(addr + 1, g) poke(addr + 2, b) end end function Game:loop() -- if self.stepByStep and not (btnp(K.Y) or (btn(K.Y) and btn(K.X))) then return end self.t = self.t + 1 self:pollDBtn() self:updateKeys() self.state:update() if self.state.nextState then local prev = self.state self.state = prev.nextState prev.nextState = nil end call(self.state.draw, self.state) end function Game:saveProgress(n) if n > self.progress and n <= #self.levels then self.progress = n pmem(0, self.progress) end end function Game:music(track) if not self.musicOn then return end if track ~= self.nowplaying then music(track) self.nowplaying=track end end -- factory function Game:create(Type, ...) return Type:new(self, ...) end -- Keys are things for which the game can tell whether they were checked in on the last tick -- and for how many ticks they've been checked in. They represent the duration of ongoing ontinuous process -- such as frame-by-frame animation or tween. Any unique item can be a key, e.g. an empty table -- frames start from 1; it means unchecked animations are at 1st frame -- very convenient to scale them with lc() from above function Game:continuous(key) if not key then return 1 end return self.conKeys[key] or 1 end function Game:checkIn(key) if not key then return 1 end self.checkedKeys[key] = true return self:continuous(key) end function Game:checkOut(key) local was = self.conKeys[key] or 1 self.checkedKeys[key] = nil self.conKeys[key] = nil return was end function Game:updateKeys() local conKeys, checkedKeys = self.conKeys, self.checkedKeys for key in pairs(conKeys) do if checkedKeys[key] then conKeys[key] = conKeys[key] + 1 checkedKeys[key] = nil else conKeys[key] = nil end end for key in pairs(checkedKeys) do conKeys[key] = 2 checkedKeys[key] = nil end end end do -- game state base GameState = Object:extend{} function GameState:constructor(game) self.game = game self.ttable = {} self.t = 0 end function GameState:update(game) self.t = self.t + 1 self:updateTimers() end -- a function can only have one timer at time function GameState:setTimer(clicks, cb) self.ttable[cb] = self.t + clicks end function GameState:setRepeat(clicks, cb) local loop loop = function () self:setTimer(clicks, function () cb() loop() end) end loop() end function GameState:dropTimers() self.ttable = {} end function GameState:updateTimers() local calls = {} for cb, time in pairs(self.ttable) do if time == self.t then self.ttable[cb] = nil table.insert(calls, cb) end end for _, cb in ipairs(calls) do cb() end end end do -- map state MapState = GameState:extend{ mapX=0, mapY=0, level=-1, wallpiece=nil, cloudsCount=24, clouds={}, -- WARN reuse plants=nil, guards=nil, doors=nil, buckets=nil, beds=nil, remv=nil, player=nil } function MapState:constructor(game, level) self.Parent.constructor(self, game) local lv = game.levels[level] game:saveProgress(level) self.player = game:create(Player):with(lv.p) self.level = level self.beds = {} self.plants = {} self.buckets = {} self.guards = {} self.doors = {} self.remv = {} if #self.clouds ~= self.cloudsCount then self.clouds = {} end -- TODO reduce, reuse, recycle if #self.clouds == 0 then self:seedClouds() end -- reuse this wall for all pieceAt checks self.wallpiece = game:create(Wall) for x=0,30 do for y=0,17 do mset(x, y, mget(x + 30 * lv.mx, y + 17 * lv.my)) end end for _, d in ipairs(lv.bd) do table.insert(self.beds, game:create(Bed):with(d)) end for _, d in ipairs(lv.bu) do table.insert(self.buckets, game:create(Bucket):with(d)) end for _, d in ipairs(lv.gu) do table.insert(self.guards, game:create(Guard):with(d)) end for _, d in ipairs(lv.dr) do table.insert(self.doors, game:create(Door):with(d)) end self:setTimer(1, function() game:music(0) end) if #lv.int > 0 then self.nextState=game:create(DialogState):with{lines=lv.int, returnState=self} end end local _cloudsz, _cloudvx, _cloudvy = 16, -0.03, 0 function MapState:seedClouds() for i=1,self.cloudsCount do table.insert(self.clouds, { math.random(1 - _cloudsz, 240 + _cloudsz), math.random(1 - _cloudsz, 130 + _cloudsz)}) end end function MapState:updateClouds() for _, c in ipairs(self.clouds) do c[1] = c[1] + _cloudvx c[2] = c[2] + _cloudvy if c[1] < -_cloudsz then c[1] = 240 + _cloudsz end if c[1] > 240 + _cloudsz then c[1] = -_cloudsz end if c[2] < -_cloudsz then c[2] = 138 + _cloudsz end if c[2] > 138 + _cloudsz then c[2] = -_cloudsz end end end function MapState:reset() self.guards={} sfx(63, "G#4", 50, 3, 14) self.nextState = self.game:create(TransitionState):with{returnState=game:create(MapState, self.level)} end function MapState:pieceAt(x, y) if self:isWall(x, y) then return self.wallpiece:with{x=x,y=y} end -- i == table index, **~=** loop counter @see iall for i, p in iall({self.player}, self.buckets, self.guards, self.plants, self.doors) do if not p.seethrough and x == p.x and y == p.y then return p, i end end -- stops player from pushing a bucket onto guards -- TODO how bad will be just checking it for every piece in the loop above? for i, gu in ipairs(self.guards) do if gu.isWalking and not gu:isPastHalfTile() then local cx, cy = gu:sight() if x == cx and y == cy then return gu, i end end end end function MapState:isWall(x, y) local s = mget(x,y) return s >= 16 and s < 160 end local function victorysfx() sfx(62, "E-3", 100, 1, 10, -1) sfx(62, "E-5", 100, 2, 10, -1) sfx(62, "E-6", 100, 3, 10, -1) end function MapState:guardSees(gu) for s=0,29 do local pc = self:pieceAt(gu:sight(s)) if pc and not pc.seethrough and pc ~= gu then return pc end end end function MapState:update() self.Parent.update(self) local p = self.player if btnp(K.B) then self:reset() end if btnp(K.A) then self.game.showGuardSight = not self.game.showGuardSight end for _, pc in iall(self.buckets, self.doors, self.guards, self.plants, {p}) do pc:update(self) end self:updateClouds() for bdi = #self.beds, 1, -1 do local bd = self.beds[bdi] local pc, pci = self:pieceAt(bd:gridCoords()) if pc and pc:is(Bucket) and not pc.isWalking then table.insert(self.plants, game:create(Plant):with{x=bd.x, y=bd.y}) table.remove(self.buckets, pci) table.remove(self.beds, bdi) end end if #self.beds == 0 then -- check in key => player animation starts if self.player.celebAni:checkIn() == 1 then victorysfx() end if self:goalComplete() then self.nextState = self.game:create(DialogState):with{ lines={randpick(strings.levelComplete)}, returnState=game:create(TransitionState):with{ returnState=self.game:create(MapState, self.level + 1) } } end end for _, gu in ipairs(self.guards) do if gu.isWalking and not gu:isPastHalfTile() then local pc = self:pieceAt(gu:sight()) if pc and pc:is(Bucket) then local flew = self:kick(gu, pc) if not flew then gu:turnBack() end elseif pc and pc ~= gu and pc ~=self.player and not pc.tranparent then gu:turnBack() call(pc.turnBack, pc) end end if self:guardSees(gu) == p then p.isCaught = true gu.isChasing = true if not p.isWalking then p.dir = D.reverse(gu.dir) end if self:pieceAt(gu:gridCoords()) == p then gu.isWalking = false self:discovered(gu) end return end end if not p.isWalking then self:controlPlayer(p) end if self.level == #Levels then self.player.celebAni:checkIn() end end function MapState:controlPlayer(p) local press = self.game.lastdbtn p.isPushing = false if K.isDir(press) and not p.isCaught then p.dir = D.fromKey(press) -- change facing even when can't move local infront = self:pieceAt(p:sight()) if infront then if infront:is(Bucket) and self:kick(p, infront) then p:move(p.dir) elseif infront:is(Guard) then p.isCaught = true self:discovered(infront) end else p:move(p.dir) end end end function MapState:kick(who, bu) local dest = self:pieceAt(who:sight(2)) if dest and not dest:is(Bed) and not dest:is(Player)then return false end bu.v = who.v who.isPushing = true bu:move(who.dir) return true end function MapState:discovered(guard) self:setTimer(1, function () -- fires immediately upon return self:reset() end) self.nextState = self.game:create(DialogState):with{lines=guard.dialog, returnState=self} end function MapState:goalComplete() if #self.beds > 0 then return false end for _, pt in ipairs(self.plants) do if not pt.haveGrown then return false end end return true end local _water = 39 function MapState:draw() cls(13) for _, c in ipairs(self.clouds) do spr(480, c[1], c[2], 0, 1, 0, 0, 2, 2) end map(0, 0, 30, 17, 0, 0, 0, 1, function(tl, x, y) if tl == _water then local t = self.t / 10 local f = (x + y + t) % 10 > 5 local r = (x - y + t) % 10 > 5 return tl, f and 1 or 0, r and 3 or 0 end return tl end) if self.game.showGuardSight then for _, gu in ipairs(self.guards) do self:drawSight(gu) end end for _, pc in iall(self.beds, self.doors, {self.player}, self.buckets, self.plants, self.guards) do pc:draw() end end function MapState:drawSight(gu) for s=1,29 do local x, y = gu:sight(s) local pc = self:pieceAt(x, y) if pc and not pc.seethrough and pc ~= gu then return end spr(505, 8 * x, 8 * y, 0) end end end do -- menu state MenuState = GameState:extend{ spr=353, w2=8, h=10, bed = nil, seq = nil, current = nil, growSpeed = 10, scrollSpeed = 3, growAni = nil, pattern={}, patternSize=12, variance={12, 50} } function MenuState:constructor(game) self.Parent.constructor(self, game) local seq = {} self.bed = {} self.seq = {} self.growAni = game:create(Clock) -- generate for y = 1, self.h do self.bed[y] = {} for x = 1, 2 * self.w2 do self.bed[y][x] = {0,x,y} seq[#seq + 1] = self.bed[y][x] end end -- shuffle for i = 1, #seq do self.seq[i] = table.remove(seq, math.random(#seq)) end self.current = table.remove(self.seq) for i=1,self.patternSize do table.insert(self.pattern, { math.random(0,240), math.random(0,136), math.random(table.unpack(self.variance))}) end end function MenuState:update() local t = self.growAni:checkIn() self.current[1] = t // self.growSpeed if self.current[1] == 4 then -- empty table == screen not affected self.growAni:checkOut() self.current = table.remove(self.seq) or {} end for b in K:iter() do if btnp(b) then sfx(5, "E-5", 16, 2, 8) self.nextState = self.game:create(ContinueState):with{ skip=(self.game.progress == 1) } end end end local shadow = function(x) return x - 16 end local norm = math.sin(0.6 * math.pi) function MenuState:draw() local l, r local t, sv = self.game.t, self.scrollSpeed local slide = math.sin(0.6 * math.pi * math.min(30, t) / 30) / norm map(0,18,15,10,0,t//sv%16 - 16,0,2) for y=1,self.h do for x=1,self.w2 do l, r = self.bed[y][x][1], self.bed[y][self.w2 + x][1] if l > 0 then spr(self.spr + l, (x - 1) * 16 - 8, (t // sv + (y - 1) * 16) % 160 - 16, 0, 2) end if r > 0 then spr(self.spr + r, 240 - (x - 1) * 16 - 8, (t // sv + (y - 1) * 16) % 160 - 16, 0, 2) end end end --frame -- clip(16 * self.w2 - 3, 0, 240 - 32 * self.w2 + 6, 136) -- cls(5) for _, c in ipairs(self.pattern) do local x, y, r = table.unpack(c) circ(x, y, r, 7) end -- clip() -- rect(16 * self.w2 - 3, 0, 240 - 32 * self.w2 + 6, 136, 1) -- rect(16 * self.w2 - 2, 0, 240 - 32 * self.w2 + 4, 136, 4) -- title for d in D:iter() do local x, y = D.eltas(d) map(0,28,10,2,lc(slide,0,1,240,40)+x,22+y,0,2,shadow) map(0,30,5,2,lc(slide,0,1,-80,96)+x,42+y,0,2,shadow) end map(0,28,10,2,lc(slide,0,1,240,40),22,0,2) map(0,30,5,2,lc(slide,0,1,-80,96),42,0,2) title(strings.greeting, lc(slide, 0, 1, 154, 96) + t%60//30, 15 - t%60//30, 1) end end do -- level selector ContinueState = GameState:extend{ selected=1, skip=false, transAni=nil -- ok to reuse } function ContinueState:constructor(game) self.Parent.constructor(self, game) self.transAni = self.transAni or game:create(Clock) self.selected = game.progress end function ContinueState:update(game) -- DEBUG local sel = self.selected if btnp(K.UP) or btnp(K.B) then self.nextState = self.game.menu elseif btnp(K.A) then if sel <= self.game.progress then sfx(5, "E-5", 16, 2, 8) self.skip=true else sfx(5, "D#3", 16, 2, 8) end elseif btnp(K.LEFT) and sel > 1 then self.selected = sel - 1 elseif btnp(K.RIGHT) and sel < #self.game.levels then self.selected = sel + 1 end if self.skip then self.nextState = self.game:create(TransitionState):with{ returnState=self.game:create(MapState, sel) } end if self.transAni:checkIn() == 0 then sfx(2, "E-8", 4, 3, 5) end if sel ~= self.selected then self.transAni:checkOut() end end function ContinueState:draw(game) if self.skip then return end local tk = math.min(8, self.transAni:progress()) local locked = self.selected > self.game.progress if locked then rect(120 - tk * 16, 0, tk * 32, 136, 3 + self.selected % 2*2) spr(506, 112, 52 - self.game.t%60//30, 0, 2) title(strings.menuLocked, 72, 15, 1) else rect(120 - tk * 16 - 2, 0, tk * 32 + 4, 136, 5) rect(120 - tk * 16, 0, tk * 32, 136, 13) local lv = self.game.levels[self.selected] map(lv.mx * 30 + (15 - tk * 2), lv.my * 17, tk * 4, 17, (120 - tk * 16), 0, 0) end rect(90, 7, 60, 10, 1) rect(90, 6, 60, 10, 7) title(strings.menuContinue,8, 15, 1) rect(86, 119, 68, 10, 1) rect(86, 118, 68, 10, 7) title(strings.menuLevel .. " " .. self.selected,120, locked and 9 or 15, 1) title("< ",120, btn(K.LEFT) and 15 or 13, 1) title(" >",120, btn(K.RIGHT) and 15 or 13, 1) end end do -- dialog state DialogState = GameState:extend{ currentLine=1, currentChar=1, pad=10, lineheight=8, height=40, bg=8, lines={"Hey you forgot to add a message!"}, speed=3, returnState=nil, beepAni=nil -- OK to reuse btwn instances } function DialogState:constructor(game) self.Parent.constructor(self, game) self.beepAni = self.beepAni or game:create(Clock) self:setRepeat(self.speed, function() self.currentChar = math.min(self.currentChar + 1, string.len(self:getLine())) end) end function DialogState:getLine() return (self.lines or {})[self.currentLine] or "" end function DialogState:lineComplete() return string.len(self:getLine()) == self.currentChar end function DialogState:update() self.Parent.update(self) if not self:lineComplete() and self.beepAni:checkIn() % 4 == 0 then sfx(5, "E-3", 16, 1, 5) end if self.currentLine > #self.lines or btnp(K.X) then self.nextState = self.returnState end if btnp(K.A) or btnp(K.DOWN) then if self:lineComplete() then sfx(5, "E-5", 16, 2, 8) self.currentLine = self.currentLine + 1 self.currentChar = 1 else self.currentChar = string.len(self:getLine()) - 1 end end end function DialogState:draw() local msg = string.sub(self:getLine(), 1, self.currentChar) rect(0, 136 - self.height, 240, self.height, self.bg) rectb(0, 136 - self.height - 1, 240, self.height + 1, 2) rectb(0, 136 - self.height - 1, 240 + 2, self.height + 2, 13) pix(239, 136 - self.height - 1, self.bg) pix(0, 135, self.bg) line(0, 136, 240, 136, 7) for ln, txt in ipairs(textwrap(msg, 200 - 2 * self.pad)) do text(txt, self.pad, 136 - self.height + self.pad + (ln - 1) * self.lineheight, 15, 2) end if self:lineComplete() then spr(511, 227, 125 -(self.game.t % 80) // 40, 0) end --- local frame = (self.game.t // 15) % 2 if frame == 0 then --- spr(392, 206, 100) spr(393, 214, 100) spr(394, 222, 100) spr(395, 230, 100) --- spr(408, 206, 108) spr(409, 214, 108) spr(410, 222, 108) spr(411, 230, 108) ----- spr(424, 206, 116) spr(425, 214, 116) spr(426, 222, 116) spr(427, 230, 116) --- spr(440, 206, 124) spr(441, 214, 124) spr(442, 222, 124) spr(443, 230, 124) else spr(396, 206, 100) spr(397, 214, 100) spr(398, 222, 100) spr(399, 230, 100) --- spr(412, 206, 108) spr(413, 214, 108) spr(414, 222, 108) spr(415, 230, 108) --- spr(428, 206, 116) spr(429, 214, 116) spr(430, 222, 116) spr(431, 230, 116) --- spr(444, 206, 124) spr(445, 214, 124) spr(446, 222, 124) spr(447, 230, 124) end end end do -- transition state TransitionState = GameState:extend{ fadeout=30, fadein=30, easing=function(t) return t ^ 3 end, returnState=nil, fadeAni=nil } function TransitionState:constructor(game) self.Parent.constructor(self, game) self.fadeAni = game:create(Clock) end function TransitionState:update() local fout, fin = self.fadeout, self.fadein local t = self.fadeAni:checkIn() if t >= fout + fin then self.nextState = self.returnState t = 0 elseif t >= fout then t = (fout + fin - t) / fin else t = t / fout end self.game:tint(1 - self.easing(t)) end function TransitionState:draw() if self.fadeAni:progress() == self.fadein then self.returnState:draw() end end end do -- timer thing -- wraps game time keeping methods by using itself as the key Clock = Object:extend{game = nil} function Clock:constructor(game) self.game = game end -- avoid this function Clock:set(time) self.game.conKeys[self] = time end -- if the timer isn't checked in onto the current frame, it's reset to 1 function Clock:checkIn() return self.game:checkIn(self) end function Clock:checkOut() return self.game:checkOut(self) end function Clock:progress() return self.game:continuous(self) end end do -- basic tile-bound object Piece = Object:extend{ spr=-1, x=0, y=0, w=8, h=8, v=15, -- [1/speed] time it takes to move through 1 cell dir=D.DOWN, seethrough=false, isWalking=false, walkAni=nil } function Piece:constructor(game) self.game = game self.walkAni=game:create(Clock) end -- grids coordinates change when the piece moves half distance -- to emulate another behavior use Piece:isPastHalfTile() function Piece:gridCoords() return self.x, self.y end function Piece:screenCoords() local dx, dy = 0, 0 if self.isWalking then local t = self.walkAni:progress() % self.v local dist, half = lc(t, self.v, 8), t >= self.v // 2 dx, dy = D.eltas(self.dir, (half and - 8 + dist or dist)) end return self.x * 8 + dx, self.y * 8 + dy end function Piece:isPastHalfTile() return self.walkAni:progress() % self.v >= self.v // 2 end function Piece:isOnGrid() local t = self.walkAni:progress() return t == 1 or t % self.v == 0 end function Piece:sight(dist) local x, y = self:gridCoords() local dx, dy = D.eltas(self.dir, dist) return x + dx, y + dy end function Piece:move(dir) self.dir = dir self.isWalking = true end function Piece:update() if self.isWalking then local t = self.walkAni:checkIn() % self.v if t == self.v // 2 then self.x, self.y = self:sight() elseif t == 0 then self.isWalking = false end end end function Piece:draw() local x, y = self:screenCoords() spr(self.spr, x, y, 0) end end do -- player Player = Piece:extend{ spr=256, x=0, y=0, isPushing=false, isCaught=false, celebAni=nil } function Player:constructor(game) self.Parent.constructor(self, game) self.celebAni = game:create(Clock) end function Player:update() if not self.isCaught then self.Parent.update(self) end end function Player:draw() local celebt = self.celebAni:progress() - 1 local x, y = self:screenCoords() if celebt > 0 then spr(268 + lc(celebt % 20, 20, 2), x, y - math.sin(celebt / 2), 0) elseif self.isCaught then spr(284 + self.dir, x, y, 0) else local walkt = self.walkAni:progress() local psh = self.isPushing and 16 or 0 local frame = self.isWalking and (1 + walkt % 16 // 8) or 0 spr(self.spr + 3 * self.dir + frame + psh, x, y, 0) end -- DEBUG --rectb(8*self.x,8*self.y,8,8,14) end end do -- bucket Bucket = Piece:extend{spr=320} function Bucket:draw() local x, y = self:screenCoords() local dx, dy = D.eltas(self.dir, (self.walkAni:progress() > 1) and 1 or 0) x, y = x - dx, y - dy spr(self.spr, x, y, 0) end end do -- Plant Plant = Piece:extend{ spr=357, v=0, -- just in case? haveGrown=false, growAni=nil } function Plant:constructor(game) self.Parent.constructor(self, game) self.growAni = Game:create(Clock) end function Plant:update() if self.haveGrown then return end local t = self.growAni:checkIn() if t == 2 then sfx(61, "B-4", 48, 3, 12, 2) elseif t >= 120 then self.haveGrown = true end end function Plant:draw() local x, y = self:screenCoords() if self.haveGrown then spr(self.spr, x, y, 0) else spr(self.spr + lc(math.min(self.growAni:progress(), 60), 0, 60, -5, 0), x, y, 0) end end end do -- bed Bed = Piece:extend{ spr=352, seethrough=true, } end do Door = Piece:extend{ spr=384, opn=nil, -- check callback seethrough=false } function Door:update(state) self.seethrough = call(self.opn, state) end function Door:draw() local x, y = self:screenCoords() spr(self.seethrough and (self.spr + 1) or self.spr, x, y, 0) end end do -- wall -- this is a plug to make collision code more uniform -- the game does not use these objects for tiles Wall = Piece:extend{} end do -- Guards Guard = Piece:extend{ spr=288, bubbleSpr=507, isChasing=false, chaseSpeed=Piece.v // 2, dialog={randpick(strings.guard)}, alertAni=nil, reel=nil, reelDir=1, -- 1 or -1 frame=1, reelAni=nil, isBwd=false, -- for playing the partially completed frame backwards bwdt=0 } function Guard:constructor(game) self.Parent.constructor(self, game) self.alertAni = game:create(Clock) self.reelAni = game:create(Clock) end function Guard:update() if self.isChasing then self:chase() elseif self.reel then -- if self:isOnGrid() then trace(self.reelAni:progress()) end-- DEBUG self:patrol() end self.Parent.update(self) end local function alertsfx() sfx(5, "E-5", 16, 0) sfx(5, "A#6", 16, 1) sfx(5, "F-6", 16, 2) sfx(2, "E-4", 16, 3, 6) end function Guard:chase() local alert = self.alertAni:checkIn() if alert == 1 then alertsfx() end if alert < 30 then return end self.walkAni:checkIn() self.v = self.chaseSpeed self.isWalking = true if alert % 6 == 0 then sfx(2, "E-8", 4, 3, 3) end end -- Guard.reel contains a sequence of actions that a guard performs during -- patrol, back and forth. Guard.rewind=true makes sequence loop instead -- commands: -- {T, D.STOP} : wait T ticks -- {T, (D.UP .. D.RIGHT)} : face said dir and wait for T ticks -- {L, D.GO, (D.UP .. D.RIGHT)} : face said dir and walk L squares -- FIXME reel and walk are out of sync, hence glitchy movement. Adding a stop -- frame in the reel allows it to catch up. When fixing, mind turn back function Guard:patrol() local tm, frame = self.reelAni:checkIn(), self.reel[self.frame] local len, comm = frame[1], frame[2] if comm == D.GO then self.isWalking = true comm = self.reelDir > 0 and frame[3] or D.reverse(frame[3]) len = len * self.v --[[ - 1 ]] end if self.isBwd then -- partially completed frame len = self.bwdt end if comm ~= D.STOP then self.dir = comm end if tm >= len then self:nextFrame() end -- -- DEBUG -- if (btn(K.Y)) then -- local f = self.reel[self.frame] -- trace("| " .. (self.isBwd and "B" or " ") .. (self.reelDir > 0 and ">" or "<") .. " " .. self.reelAni:progress() .. " " .. self.walkAni:progress() .. " | " -- .. f[1] .. " " .. (D[f[2]] or "X") .. " " .. (D[f[3]] or "X")) -- end end -- TODO: nested turn back function Guard:turnBack() local passed, walked = self.reelAni:progress(), self.walkAni:progress() self.reelDir = -self.reelDir self.walkAni:set(self.v - walked % self.v) self.isBwd = not self.isBwd if self.isBwd then self.bwdt = passed self.reelAni:checkOut() else self.reelAni:set(self.bwdt - passed) end end function Guard:nextFrame() self.reelAni:checkOut() self.isBwd = false if self.rewind and self.frame == #self.reel then self.reelAni:checkOut() self.frame = 1 elseif self.reelDir < 0 and self.frame <= 1 or self.reelDir > 0 and self.frame == #self.reel then -- last frame plays twice: once forwards, once backwards self.reelDir = -self.reelDir else self.frame = self.frame + self.reelDir end -- DEBUG if not self:isOnGrid() then trace("WARN< Guard frame switch " .. (self.v - self.walkAni:progress() % self.v) .. " ticks earlier", 12) end -- local f = self.reel[self.frame] -- trace(f[1] .. " " .. (D[f[2]] or "X") .. " " .. (D[f[3]] or "X")) end function Guard:draw() local x, y = self:screenCoords() local alert = self.alertAni:progress() - 1 local walk = self.walkAni:progress() - 1 local frame = walk > 0 and (alert > 30 or not self.chasing) and (1 + walk % 16 // 8) or 0 spr(self.spr + 3 * self.dir + frame, x, y, 0) if alert > 0 and alert < 30 then -- spr expression makes the last frame hold longer spr(self.bubbleSpr + math.min(3, lc(alert, 30, 8) // 1), x, y - 8, 0) end end end --[[ RUN ]]-- function TIC() game:loop() end --[[ INIT ]]-- -- position shorthand local _r = function(a) local tt = {} for _, r in ipairs(a) do tt[#tt + 1] = {x=r[1],y=r[2]} end return tt end local _grown = function(n) -- door condition return function(state) return #state.plants >= n end end local _grownAt = function(x, y) -- door condition return function(state) for _, pt in ipairs(state.plants) do if pt.x == x and pt.y == y then return true end end return false end end local _waitAfter = function(r) -- guard reel transform local t = {} for i, f in ipairs(r) do t[2 * i - 1] = f t[2 * i] = {5, D.STOP} end return t end local UP,DOWN,LEFT,RIGHT,STOP,GO = D.UP,D.DOWN,D.LEFT,D.RIGHT,D.STOP,D.GO Levels = { [1]={mx=2,my=4, p={x=12,y=8,dir=DOWN}, bu=_r{{14,8}}, bd=_r{{17,8}}, gu={}, dr={}}, [2]={mx=3,my=4, p={x=18,y=8,dir=LEFT}, bu=_r{{11,8}}, bd=_r{{9,7}}, gu={}, dr={}}, [3]={mx=4,my=4, p={x=10,y=7,dir=RIGHT}, bu=_r{{12,8},{17,8}}, bd=_r{{12,7},{12,9}}, gu={}, dr={{x=14,y=7,opn=_grown(1)},{x=14,y=9,opn=_grown(1)}}}, [4]={mx=3,my=5, p={x=13,y=9,dir=DOWN}, bu=_r{{11,5},{16,6}}, bd=_r{{10,5},{17,6}}, gu={}, dr={}}, [5]={mx=5,my=4, p={y=5,x=12,dir=DOWN}, bu=_r{{11,11},{12,11},{13,11}}, bd=_r{{10,11},{12,12},{14,11}}, gu={{y=7,x=15,dir=LEFT}}, dr={}}, [6]={mx=2,my=5, p={y=7,dir=DOWN,x=13}, bu=_r{{12,6},{12,9},{15,6},{15,9}}, bd=_r{{13,4},{13,11},{14,4},{14,11}}, gu={{y=10,dir=RIGHT,x=11,rewind=true,reel={{5,GO,RIGHT},{5,GO,UP},{5,GO,LEFT},{5,GO,DOWN}}}}, dr={}}, [7]={mx=1,my=5, p={dir=LEFT,x=15,y=3}, bu=_r{{11,7},{12,6},{13,6},{14,7},{16,11}}, bd=_r{{14,13},{16,5}}, gu={{dir=RIGHT,x=9,y=9},{dir=RIGHT,x=10,y=7},{dir=RIGHT,x=10,y=11}}, dr={}}, [8]={mx=5,my=3, p={y=12,x=17,dir=LEFT}, bu=_r{{9,9},{19,9}}, bd=_r{{14,13}}, gu={{y=5,x=14,dir=DOWN}}, dr={}}, [9]={mx=2,my=3, p={x=14,y=5}, bu=_r{{12,6},{14,6},{17,10},{17,11}}, bd=_r{{15,6},{18,8},{18,11}}, gu={{x=13,y=10,dir=UP}}, dr={}}, [10]={mx=1, my=0, p={x=7,y=7,dir=DOWN}, bu=_r{{15,6},{14,9},{17,8}}, bd=_r{{9,13},{24,6},{24,9}}, gu={{x=18,y=10,dir=UP,reel={{90,UP},{90,LEFT}}}}, dr={}}, [11]={mx=2, my=1, p={x=24,y=8,dir=DOWN}, bu=_r{{9,6},{15,7},{15,10},{16,10}}, bd=_r{{2,7},{3,7},{4,7}}, gu={{x=21,y=8,dir=LEFT,reel={{60,DOWN},{120,LEFT},{60,UP}}}}, dr={}}, [12]={mx=5, my=0, p={x=9,y=5,dir=DOWN}, bu=_r{{6,6},{7,9},{14,8}}, bd=_r{{24,3},{24,12},{21,8}}, gu={ {x=5,y=12,dir=RIGHT,reel={{60,RIGHT},{60,UP}}}, {x=10,y=8,dir=RIGHT,reel={{30,STOP},{9,GO,RIGHT},{30,STOP}}} }, dr={}}, [13]={mx=1, my=1, p={x=11,y=11,dir=DOWN}, bu=_r{{7,4},{6,10},{21,12},{21,13},{23,13},{19,12}}, bd=_r{{20,9},{22,9},{23,8}}, gu={ {x=7,y=5,dir=RIGHT,reel={{30,RIGHT},{60,UP},{30,LEFT}}}, {x=14,y=7,dir=RIGHT,rewind=true,reel={{90,RIGHT},{90,UP},{90,LEFT},{90,DOWN}}}, {x=17,y=11,dir=UP,reel={{60,STOP},{2,GO,DOWN},{2,GO,RIGHT},{60,STOP}}} }, dr={}}, [14]={mx=3, my=0, p={x=19,y=12,dir=UP}, bu=_r{{12,8},{14,8},{16,8},{16,9},{17,9}}, bd=_r{{16,4},{19,7},{20,8},{21,10},{18,11}}, gu={{x=15,y=10,dir=UP,reel={{60,UP},{60,RIGHT}}}}, dr={}}, [15]={mx=1,my=2, p={y=2,x=5,dir=DOWN}, bu=_r{{4,4},{7,6},{9,6},{12,6},{13,6},{15,6},{18,6}}, bd=_r{{4,2},{9,2},{10,10},{15,9},{15,10},{19,2},{19,3}}, gu={ {y=6,x=5,dir=RIGHT,reel={{60,STOP},{1,GO,LEFT},{30,STOP}}}, {y=6,x=21,dir=LEFT,reel={{60,STOP},{1,GO,RIGHT},{30,STOP}}}, {y=12,x=20,dir=LEFT,reel={{5,STOP},{10,GO,LEFT},{10,STOP},{2,GO,DOWN},{10,STOP},{6,GO,LEFT},{5,STOP},{5,UP}}}}, dr={}}, [16]={mx=1,my=3, p={x=15,y=4}, bu=_r{{13,7},{14,6},{14,8},{15,7},{16,6},{16,8},{17,7}}, bd=_r{{8,2},{10,11},{15,6},{15,8},{17,13},{21,3},{21,13}}, gu={}, dr={{x=9,y=3,opn=_grown(4)}}}, [17]={mx=4,my=5, p={x=18,dir=RIGHT,y=9}, bu=_r{{10,8},{11,8},{14,8}}, bd=_r{{9,6},{13,7},{15,8}}, gu={{x=12,dir=UP,y=10,reel={{60,UP},{60,RIGHT}}},{x=15,dir=RIGHT,y=7,reel={{60,RIGHT},{60,DOWN}}}}, dr={}}, [18]={mx=3, my=1, p={x=8,y=5,dir=DOWN}, bu=_r{{11,2},{11,10},{15,5},{23,8}}, bd=_r{{11,1},{11,11},{23,7},{24,6}}, gu={{x=2,y=4,dir=RIGHT,reel={ {30,STOP},{6,GO,RIGHT},{2,GO,DOWN},{3,GO,RIGHT},{4,GO,UP}, {25,LEFT},{25,RIGHT},{25,DOWN},{25,UP}, -- look around {4,GO,DOWN},{12,GO,RIGHT}, {25,LEFT},{25,RIGHT},{25,DOWN},{25,UP}, {12,GO,LEFT}, {25,LEFT},{25,RIGHT},{25,DOWN},{25,UP}, {100000,RIGHT} }} }, dr={}}, [19]={mx=4, my=0, p={x=15,y=14,dir=UP}, bu=_r{{13,6},{21,5}}, bd=_r{{8,4},{16,6}}, gu={ {x=14,y=5,dir=RIGHT,reel={{120,RIGHT},{120,DOWN}}}, {x=19,y=8,dir=LEFT,reel={{150,STOP},{2,GO,RIGHT},{150,STOP}}} }, dr={}}, [20]={mx=2, my=0, p={x=7,y=10,dir=DOWN}, bu=_r{{15,6},{20,11}}, bd=_r{{20,2},{21,2}}, gu={ {x=14,y=5,dir=RIGHT,reel={{90,RIGHT},{90,DOWN}}}, {x=13,y=11,dir=LEFT,reel={{4,GO,LEFT},{4,GO,UP},{4,GO,RIGHT}}}, {x=21,y=12,dir=UP,reel={{90,UP},{90,LEFT}}} }, dr={}}, [21]={mx=5,my=5, p={dir=DOWN,x=10,y=6}, bu=_r{{11,8},{16,10},{17,7},{18,7}}, bd=_r{{12,8},{15,10},{16,7},{16,9}}, gu={{dir=UP,x=14,y=10,rewind=true,reel={{4,GO,UP},{4,GO,LEFT},{3,GO,DOWN},{1,GO,RIGHT},{1,GO,DOWN},{3,GO,RIGHT}}}}, dr={{y=6,x=13,opn=_grown(1)}}}, [22]={mx=4,my=3, p={x=12,y=14,dir=UP}, bu=_r{{5,5},{18,12},{20,4}}, bd=_r{{8,8}}, gu={ {x=4,y=6,dir=UP,reel={{50,UP},{50,RIGHT}}}, {x=10,y=10,dir=RIGHT}, {x=13,y=7,dir=LEFT}, {x=19,y=12,dir=UP,rewind=true,reel={{150,UP},{150,LEFT},{150,DOWN},{150,RIGHT}}}, {x=24,y=4,dir=LEFT,reel={{100,LEFT},{3,GO,LEFT},{1,GO,UP},{2,GO,RIGHT},{100,LEFT}}}}, dr={}}, [23]={mx=3,my=3, p={x=17,y=13,dir=UP}, bu=_r{{4,6},{4,11},{19,5}}, bd=_r{{10,11},{14,14},{21,8}}, gu={ {x=9,y=8,dir=RIGHT,reel={{12,GO,RIGHT}}}, {x=21,y=8,dir=LEFT,reel={{6,GO,LEFT},{5,GO,UP},{6,GO,RIGHT},{5,GO,DOWN}}}, {x=25,y=10,dir=LEFT,rewind=true,reel={{2,GO,LEFT},{2,GO,DOWN},{2,GO,RIGHT},{2,GO,UP}}}}, dr={}}, [24]={mx=1,my=4, p={y=4,x=12,dir=RIGHT}, bu=_r{{8,8},{8,9},{10,8},{11,8},{11,10},{12,8},{14,3},{14,13},{15,9}}, bd=_r{{11,13},{12,7},{13,6},{17,5},{18,13}}, gu={ {y=12,x=17,v=Guard.v*2,dir=UP,reel={{6,GO,UP}}}, {y=6,x=18,v=Guard.v*2,dir=DOWN,reel={{6,GO,DOWN}}}, {y=9,x=20,dir=LEFT}}, dr={}}, [25]={mx=5,my=2, p={x=24,y=3}, bu=_r{{6,7},{8,8},{8,10},{26,12}}, bd=_r{{10,1},{10,2},{10,5},{28,12}}, gu={ {x=5,y=12,dir=UP,reel={{80,UP},{80,RIGHT}}}, {x=10,y=8,dir=LEFT,reel={{80,LEFT},{80,DOWN}}}, {x=15,y=1,v=Guard.v*2,dir=LEFT,reel={{20,LEFT},{2,GO,DOWN},{40,LEFT},{2,GO,DOWN},{20,LEFT}}}, {x=21,y=7,dir=DOWN,rewind=true,reel={{1,GO,DOWN},{4,GO,RIGHT},{3,GO,UP},{2,GO,LEFT},{2,GO,UP},{5,GO,LEFT},{4,GO,DOWN},{3,GO,RIGHT}}}, {x=24,y=14,dir=UP,rewind=true,reel={{1,GO,UP},{1,GO,RIGHT},{5,GO,UP},{4,GO,LEFT},{2,GO,DOWN},{2,GO,LEFT},{4,GO,DOWN},{5,GO,RIGHT}}}}, dr={{x=18,y=10,opn=_grown(1)},{x=9,y=2,opn=_grownAt(10,1)},{x=9,y=5,opn=_grownAt(10,2)}}}, [26]={mx=3,my=2, p={x=14,y=2}, bu=_r{{8,6},{8,10},{15,7},{20,5}}, bd=_r{{12,10},{13,5},{17,5},{18,10}}, gu={ {x=8,y=13,dir=LEFT,rewind=true,reel=_waitAfter{{2,GO,LEFT},{6,GO,UP},{4,GO,RIGHT},{3,GO,DOWN},{3,GO,DOWN},{2,GO,LEFT}}}, {x=11,y=2,dir=DOWN,rewind=true,reel=_waitAfter{{3,GO,LEFT},{3,GO,DOWN},{2,GO,LEFT},{2,GO,DOWN},{5,GO,RIGHT},{5,GO,UP}}}, {x=13,y=10,v=math.floor(1.5*Guard.v),dir=DOWN,reel=_waitAfter{{20,RIGHT},{4,GO,DOWN},{4,GO,RIGHT},{4,GO,UP},{20,LEFT}}}, {x=26,y=7,dir=LEFT,rewind=true,reel=_waitAfter{{7,GO,LEFT},{4,GO,UP},{2,GO,RIGHT},{2,GO,DOWN},{5,GO,RIGHT},{2,GO,DOWN}}}}, dr={{x=13,y=9,opn=_grownAt(13,5)},{x=17,y=9,opn=_grownAt(17,5)}}}, [27]={mx=2, my=2, p={y=9,x=15,dir=DOWN}, bu=_r{{12,6},{12,10},{18,6},{18,10}}, bd=_r{{6,7},{13,14},{17,2},{24,9}}, gu={ {y=10,x=7,dir=RIGHT,rewind=true,reel=_waitAfter{{1,GO,RIGHT},{1,GO,DOWN},{4,GO,RIGHT},{4,GO,UP},{5,GO,LEFT},{3,GO,DOWN}}}, {y=3,x=12,dir=DOWN,rewind=true,reel=_waitAfter{{1,GO,DOWN},{1,GO,LEFT},{2,GO,DOWN},{6,GO,RIGHT},{3,GO,UP},{5,GO,LEFT}}}, {y=13,x=18,dir=UP,rewind=true,reel=_waitAfter{{1,GO,UP},{1,GO,RIGHT},{2,GO,UP},{6,GO,LEFT},{3,GO,DOWN},{5,GO,RIGHT}}}, {y=6,x=23,dir=LEFT,rewind=true,reel=_waitAfter{{1,GO,LEFT},{1,GO,UP},{4,GO,LEFT},{4,GO,DOWN},{5,GO,RIGHT},{3,GO,UP}}}}, dr={}}, [28]={mx=4, my=1, p={x=25,y=7,dir=DOWN}, bu=_r{ {17,5},{18,5},{20,5},{18,7}, {19,10},{21,10},{23,10}, {20,11},{22,11},{24,11}, {19,12},{21,12},{23,12}, {20,13},{22,13},{24,13} }, bd=_r{ {7,3},{8,3},{9,3},{10,3}, {7,8},{8,8},{9,8},{10,8}, {7,10},{8,10},{9,10},{10,10}, {7,13},{8,13},{9,13},{10,13}, }, gu={}, dr={}}, [29]={mx=5, my=1, p={x=24,y=14,dir=DOWN}, bu=_r{}, bd=_r{{-10,0}}, gu={}, dr={}}} for i, l in ipairs(Levels) do l.int = strings.intros[i] end local progress = pmem(0) if progress == 0 then progress = 1 end game = Game:new():with{ levels=Levels, progress=progress} game:music(2) game.menu = game:create(MenuState):with{returnState=game:create(ContinueState)} game.state = game.menu do -- an util that prints the level template based on the placeholder tiles in the level editor. local dev_tt dev_tt = function(t) local s = "" -- performance idc local map = not t[1] for k, v in (map and pairs or ipairs)(t) do s = s .. (#s > 0 and "," or "") .. (map and (k .. "=") or "") .. (type(v) == "string" and ('"' .. v .. '"') or (type(v) == "table" and dev_tt(v) or v)) end return "{" .. s .. "}" end -- extract position of placeholder tiles and print a level template local function dev_objgen(mx, my) local o = function () return Object:new() end local t = o():with{mx=mx, my=my, int={"INTRO", "GOES", "HERE"}, p=o(), bu={}, bd={}, gu=o(), dr=o()} local w, h = 30, 17 local i_pla = 165 local i_buc = 167 local i_bed = 168 local i_gua = 166 local i_dor = 169 -- extract for x=1,w-1 do for y=1,h-1 do local i, xy, a = mget(mx * w + x, my * h + y), o():with{x=x, y=y}, o():with{x, y} if i == i_pla then t.p = xy:with{dir=D.DOWN} elseif i == i_buc then table.insert(t.bu, a) elseif i == i_bed then table.insert(t.bd, a) elseif i == i_gua then table.insert(t.gu, xy:with{dir=D.DOWN}) elseif i == i_dor then table.insert(t.dr, xy) end end end -- run from terminal to copy trace(string.format("{mx=%d,my=%d,\n\tint=%s,\n\tp=%s,\n\tbu=_r%s,\n\tbd=_r%s,\n\tgu=%s,\n\tdr=%s}", mx, my, dev_tt(t.int), dev_tt(t.p), dev_tt(t.bu), dev_tt(t.bd), dev_tt(t.gu), dev_tt(t.dr))) t.bu = _r(t.bu) t.bd = _r(t.bd) return t end -- Levels[1] = Levels[1] or dev_objgen(5, 5) -- (mapx, mapy) in whole screens -- game.state = game:create(MapState,1) -- start immediately end